diff --git a/config/relay.toml b/config/relay.toml index 05c0f98c..e45392ca 100644 --- a/config/relay.toml +++ b/config/relay.toml @@ -132,3 +132,9 @@ title = "miner" [cloud_watch] enabled = false region = "" + +[order_difficulty] + base_difficulty = "0x0000000000000000000000000000000000000000000000000000000000000010" + threshold = 20 + cal_count = 100 + duration = 2 \ No newline at end of file diff --git a/gateway/gateway.go b/gateway/gateway.go index f1e3f4ff..73e865ce 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -24,6 +24,7 @@ import ( "errors" "fmt" "github.com/Loopring/relay-cluster/accountmanager" + "github.com/Loopring/relay-cluster/gateway/order_difficulty" "github.com/Loopring/relay-cluster/ordermanager/manager" "github.com/Loopring/relay-cluster/ordermanager/viewer" "github.com/Loopring/relay-lib/broadcast" @@ -36,8 +37,8 @@ import ( "github.com/Loopring/relay-lib/types" "github.com/ethereum/go-ethereum/common" "math/big" - "time" "strings" + "time" ) type Gateway struct { @@ -85,7 +86,7 @@ func Initialize(filterOptions *GatewayFiltersOptions, options *GateWayOptions, o gateway.marketCap = marketCap // new pow filter - powFilter := &PowFilter{Difficulty: types.HexToBigint(filterOptions.PowFilter.Difficulty)} + powFilter := &PowFilter{} // new base filter baseFilter := &BaseFilter{ @@ -400,7 +401,6 @@ func (f *CutoffFilter) filter(o *types.Order) (bool, error) { } type PowFilter struct { - Difficulty *big.Int } func (f *PowFilter) filter(o *types.Order) (bool, error) { @@ -410,9 +410,11 @@ func (f *PowFilter) filter(o *types.Order) (bool, error) { } pow := GetPow(o.V, o.R, o.S, o.PowNonce) - - if pow.Cmp(f.Difficulty) < 0 { - return false, fmt.Errorf("invalid pow") + if diffHex, err := order_difficulty.GetDifficulty(); nil == err { + diff := types.HexToBigint(diffHex) + if pow.Cmp(diff) < 0 { + return false, fmt.Errorf("invalid pow") + } } return true, nil } diff --git a/gateway/order_difficulty/difficulty.go b/gateway/order_difficulty/difficulty.go index 450ccad7..50f508dd 100644 --- a/gateway/order_difficulty/difficulty.go +++ b/gateway/order_difficulty/difficulty.go @@ -19,46 +19,78 @@ package order_difficulty import ( + "encoding/json" "github.com/Loopring/relay-lib/cache" "github.com/Loopring/relay-lib/eventemitter" + "github.com/Loopring/relay-lib/log" "github.com/Loopring/relay-lib/types" "github.com/Loopring/relay-lib/zklock" "github.com/ethereum/go-ethereum/common" "gonum.org/v1/gonum/stat" "math/big" - "qiniupkg.com/x/log.v7" "strconv" "time" ) const ( OrderCountPerSecond = "o_cnt_per_s_" - OrderDifficulty = "order_diff" + OrderDifficultyKey = "order_diff" ZklockDifficulty = "zklock_diff" ) type OrderDifficultyEvaluator struct { //currentDifficult *OrderDifficulty //parentDifficult *OrderDifficulty - evaluator Evaluator - baseDifficulty *big.Int - orderTraffic int64 - triggerThreshold float64 - stopFuns []func() - calCount int64 //must be odd + evaluator Evaluator + stopFuns []func() + calCount int64 //must be odd + duration int64 } type OrderDifficulty struct { - difficulty *big.Int - ordersNum int64 - timeStamp int64 + Difficulty string + OrdersNum int64 + TimeStamp int64 } -func (evaluator *OrderDifficultyEvaluator) getCacheKey(createTime int64) (key string, expireAt int64) { +func (evaluator *OrderDifficultyEvaluator) getOrderCacheKey(createTime int64) (key string, expireAt int64) { mod := createTime % evaluator.calCount orderSection := createTime - mod orderSectionStr := strconv.FormatInt(orderSection, 10) - return OrderCountPerSecond + orderSectionStr, createTime + evaluator.calCount + return OrderCountPerSecond + orderSectionStr, createTime + evaluator.calCount*evaluator.duration +} + +func (evaluator *OrderDifficultyEvaluator) getDiffCacheKey(createTime int64) (key string, expireAt int64) { + mod := createTime % evaluator.calCount + orderSection := createTime - mod + orderSectionStr := strconv.FormatInt(orderSection, 10) + return OrderDifficultyKey + orderSectionStr, createTime + evaluator.calCount*evaluator.duration +} + +func NewOrderDifficultyEvaluator(config OrderDifficultyConfig) *OrderDifficultyEvaluator { + if "" == config.BaseDifficulty { + config.BaseDifficulty = "0x10" + } + if 0 == config.CalCount { + config.CalCount = 1000 + } + if 0 == config.Duration { + config.Duration = 2 + } + if 0 == config.Threshold { + config.Threshold = 10 + } + evaluator := &OrderDifficultyEvaluator{calCount: config.CalCount, duration: config.Duration} + baseDifficulty := types.HexToBigint(config.BaseDifficulty) + evaluator.evaluator = &LinearEvaluator{baseDifficulty: baseDifficulty, threshold: config.Threshold} + return evaluator +} + +type OrderDifficultyConfig struct { + BaseDifficulty string + Threshold int64 + CalCount int64 + Duration int64 } func (evaluator *OrderDifficultyEvaluator) Start() { @@ -67,28 +99,55 @@ func (evaluator *OrderDifficultyEvaluator) Start() { if err := zklock.TryLock(ZklockDifficulty); nil != err { log.Errorf("erro:%s", err.Error()) } else { - now := time.Now().Unix() - orderCntList := []int64{} - for i := evaluator.calCount; i > 0; i-- { - t := now - i - cacheKey, _ := evaluator.getCacheKey(t) - if data, err := cache.Get(cacheKey); nil == err { - cnt, _ := strconv.ParseInt(string(data), 10, 0) - orderCntList = append(orderCntList, cnt) - } + if _, err1 := GetDifficulty(); nil != err1 { + diffHex := types.BigintToHex(evaluator.evaluator.getBaseDifficulty()) + cache.Set(OrderDifficultyKey, []byte(diffHex), int64(10000)) } + //now := time.Now().Unix() + //orderCntList := []*OrderDifficulty{} + //for i := evaluator.calCount; i > 0; i-- { + // t := now - i*evaluator.duration + // cacheKey, _ := evaluator.getDiffCacheKey(t) + // orderDifficulty := &OrderDifficulty{} + // if data, err := cache.Get(cacheKey); nil == err { + // json.Unmarshal(data, orderDifficulty) + // } + // orderCntList = append(orderCntList, orderDifficulty) + //} for { select { - case <-time.After(2 * time.Second): - cacheKey, _ := evaluator.getCacheKey(time.Now().Unix() - 1) - if data, err := cache.Get(cacheKey); nil == err { - cnt, _ := strconv.ParseInt(string(data), 10, 0) - orderCntList = append(orderCntList, cnt) + case <-time.After(time.Duration(evaluator.duration) * time.Second): + now := time.Now().Unix() + if diffHex, err := GetDifficulty(); nil == err { + currentDiff := diffHex + orderDiff := &OrderDifficulty{} + cacheKey, _ := evaluator.getOrderCacheKey(now) + orderDiff.OrdersNum = 0 + if data, err1 := cache.Get(cacheKey); nil == err1 { + if orderNum, err3 := strconv.Atoi(string(data)); nil == err3 { + orderDiff.OrdersNum = int64(orderNum) + } + } + diffCacheKey, _ := evaluator.getDiffCacheKey(now) + orderDiff.Difficulty = currentDiff + if data, err4 := json.Marshal(orderDiff); nil == err4 { + cache.Set(diffCacheKey, data, (evaluator.calCount+2)*evaluator.duration) + } } - diff := evaluator.evaluator.CalcAndSaveDifficulty(orderCntList) + orderCntList := []*OrderDifficulty{} + for i := evaluator.calCount; i > 0; i-- { + t := now - i*evaluator.duration + diffCacheKey, _ := evaluator.getDiffCacheKey(t) + orderDifficulty := &OrderDifficulty{} + if data, err := cache.Get(diffCacheKey); nil == err { + json.Unmarshal(data, orderDifficulty) + } + orderCntList = append(orderCntList, orderDifficulty) + } + diff := evaluator.evaluator.CalcAndSaveDifficulty(orderCntList, evaluator.duration) diffHash := common.BytesToHash(diff.Bytes()) - cache.Set(OrderDifficulty, []byte(diffHash.Hex()), int64(0)) - orderCntList = orderCntList[1:] + log.Infof("current order difficulty:%s", diff.String()) + cache.Set(OrderDifficultyKey, []byte(diffHash.Hex()), int64(0)) } } } @@ -101,12 +160,12 @@ func (evaluator *OrderDifficultyEvaluator) Stop() { } } -//add ordersNum +//add OrdersNum func (evaluator *OrderDifficultyEvaluator) HandleNewOrder() { watcher := &eventemitter.Watcher{ Concurrent: false, Handle: func(input eventemitter.EventData) error { state := input.(*types.OrderState) - cacheKey, expireAt := evaluator.getCacheKey(state.RawOrder.CreateTime) + cacheKey, expireAt := evaluator.getOrderCacheKey(state.RawOrder.CreateTime) _, err := cache.Incr(cacheKey) if nil == err { err = cache.ExpireAt(cacheKey, expireAt) @@ -122,29 +181,71 @@ func (evaluator *OrderDifficultyEvaluator) HandleNewOrder() { } type Evaluator interface { - CalcAndSaveDifficulty(orderCntList []int64) *big.Int + CalcAndSaveDifficulty(orderCntList []*OrderDifficulty, duration int64) *big.Int + getBaseDifficulty() *big.Int } type LinearEvaluator struct { + baseDifficulty *big.Int + threshold int64 } -//控制订单的提交速度,随着订单的流量增大而增大 -func (evaluator *LinearEvaluator) CalcAndSaveDifficulty(orderCntList []int64) *big.Int { +func (evaluator *LinearEvaluator) getBaseDifficulty() *big.Int { + return new(big.Int).Set(evaluator.baseDifficulty) +} + +func (evaluator *LinearEvaluator) CalNextOrderCnt(orderCntList []*OrderDifficulty, duration int64) int64 { xes := []float64{} yes := []float64{} now := time.Now().Unix() for idx, cnt := range orderCntList { - xes = append(xes, float64(idx)) - yes = append(yes, float64(cnt)) + //println("sum",cnt.OrdersNum) + xes = append(xes, float64(now-duration*int64(len(orderCntList)-idx))) + yes = append(yes, float64(cnt.OrdersNum)) } alpha, beta := stat.LinearRegression(xes, yes, nil, false) return int64(beta*float64(now) + alpha) } -func GetDifficulty() (common.Hash, error) { - if data, err := cache.Get(OrderDifficulty); nil == err { - return common.HexToHash(string(data)), nil +//控制订单的提交速度,随着订单的流量增大而增大 +func (evaluator *LinearEvaluator) CalcAndSaveDifficulty(orderCntList []*OrderDifficulty, duration int64) *big.Int { + nextCnt := evaluator.CalNextOrderCnt(orderCntList, duration) + log.Infof("next order count:%d", nextCnt) + orderList := append(orderCntList, &OrderDifficulty{OrdersNum: nextCnt}) + return evaluator.nextDifficulty(orderList) +} + +func NewOrderDiff(ordersNum int64, diff string) *OrderDifficulty { + return &OrderDifficulty{OrdersNum: ordersNum, Difficulty: diff} +} + +func NewLinearEvaluator(baseDifficulty *big.Int, threshold int64) *LinearEvaluator { + return &LinearEvaluator{baseDifficulty: baseDifficulty, threshold: threshold} +} + +func (evaluator *LinearEvaluator) nextDifficulty(orderCntList []*OrderDifficulty) *big.Int { + nextOrderDiff := orderCntList[len(orderCntList)-1] + if nextOrderDiff.OrdersNum < evaluator.threshold { + return evaluator.baseDifficulty + } else { + currentDiff := new(big.Int).Set(evaluator.baseDifficulty) + if currentDiffHex, err := GetDifficulty(); nil == err { + currentDiff = types.HexToBigint(currentDiffHex) + } + addRatio := big.NewInt(3) + if nextOrderDiff.OrdersNum > int64(float64(evaluator.threshold)*1.5) { + addRatio = big.NewInt(1) + } else if nextOrderDiff.OrdersNum < int64(float64(evaluator.threshold)*1.2) { + addRatio = big.NewInt(5) + } + return new(big.Int).Add(currentDiff, new(big.Int).Quo(currentDiff, addRatio)) + } +} + +func GetDifficulty() (string, error) { + if data, err := cache.Get(OrderDifficultyKey); nil == err { + return string(data), nil } else { - return common.Hash{}, err + return "0x0", err } } diff --git a/gateway/order_difficulty/difficulty_test.go b/gateway/order_difficulty/difficulty_test.go new file mode 100644 index 00000000..defff98c --- /dev/null +++ b/gateway/order_difficulty/difficulty_test.go @@ -0,0 +1,80 @@ +/* + + Copyright 2017 Loopring Project Ltd (Loopring Foundation). + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +package order_difficulty_test + +import ( + "encoding/json" + "github.com/Loopring/relay-cluster/gateway/order_difficulty" + "github.com/Loopring/relay-lib/cache" + "github.com/Loopring/relay-lib/cache/redis" + "github.com/Loopring/relay-lib/log" + "github.com/Loopring/relay-lib/types" + "github.com/Loopring/relay-lib/zklock" + "go.uber.org/zap" + "math/big" + "testing" + "time" +) + +func init() { + logConfig := `{ + "level": "debug", + "development": false, + "encoding": "json", + "outputPaths": ["stdout"], + "errorOutputPaths": ["stderr"], + "encoderConfig": { + "messageKey": "message", + "levelKey": "level", + "levelEncoder": "lowercase" + } + }` + rawJSON := []byte(logConfig) + + var ( + cfg zap.Config + err error + ) + if err = json.Unmarshal(rawJSON, &cfg); err != nil { + panic(err) + } + log.Initialize(cfg) + cache.NewCache(redis.RedisOptions{Host: "127.0.0.1", Port: "6379"}) + zklock.Initialize(zklock.ZkLockConfig{ZkServers: "127.0.0.1:2181", ConnectTimeOut: 10000}) + +} + +func TestEvaluator(t *testing.T) { + config := order_difficulty.OrderDifficultyConfig{} + evaluator := order_difficulty.NewOrderDifficultyEvaluator(config) + evaluator.Start() + time.Sleep(1000000 * time.Second) +} + +func TestLinearEvaluator_CalcAndSaveDifficulty(t *testing.T) { + evaluator := order_difficulty.NewLinearEvaluator(big.NewInt(100), 200) + cntList := make([]*order_difficulty.OrderDifficulty, 0) + cntList = append(cntList, order_difficulty.NewOrderDiff(100, types.BigintToHex(big.NewInt(100)))) + cntList = append(cntList, order_difficulty.NewOrderDiff(900, types.BigintToHex(big.NewInt(200)))) + cntList = append(cntList, order_difficulty.NewOrderDiff(900, types.BigintToHex(big.NewInt(200)))) + cntList = append(cntList, order_difficulty.NewOrderDiff(400, types.BigintToHex(big.NewInt(200)))) + //cntList = append(cntList, order_difficulty.NewOrderDiff(700, common.BytesToHash(big.NewInt(200).Bytes()))) + //cntList = append(cntList, order_difficulty.NewOrderDiff(700, common.BytesToHash(big.NewInt(200).Bytes()))) + println(evaluator.CalcAndSaveDifficulty(cntList, 10).String()) +} diff --git a/gateway/wallet_service.go b/gateway/wallet_service.go index e5d4c7bc..77803e10 100644 --- a/gateway/wallet_service.go +++ b/gateway/wallet_service.go @@ -24,6 +24,7 @@ import ( "fmt" "github.com/Loopring/relay-cluster/accountmanager" "github.com/Loopring/relay-cluster/dao" + "github.com/Loopring/relay-cluster/gateway/order_difficulty" "github.com/Loopring/relay-cluster/market" "github.com/Loopring/relay-cluster/ordermanager/manager" "github.com/Loopring/relay-cluster/ordermanager/viewer" @@ -411,6 +412,10 @@ type AddTokenReq struct { Decimals string `json:"decimals"` } +type OrderDifficultyRes struct { + Difficulty string `json:"difficulty"` +} + type WalletServiceImpl struct { trendManager market.TrendManager orderViewer viewer.OrderViewer @@ -546,6 +551,11 @@ func (w *WalletServiceImpl) GetPriceQuote(query PriceQuoteQuery) (result PriceQu return rst, nil } +func (w *WalletServiceImpl) GetOrderDifficulty() (result OrderDifficultyRes, err error) { + diff, err1 := order_difficulty.GetDifficulty() + return OrderDifficultyRes{Difficulty: diff}, err1 +} + func (w *WalletServiceImpl) GetTickers(mkt SingleMarket) (result map[string]market.Ticker, err error) { result = make(map[string]market.Ticker) loopringTicker, err := w.trendManager.GetTickerByMarket(mkt.Market) diff --git a/node/config.go b/node/config.go index bf39d082..b10d4ac1 100644 --- a/node/config.go +++ b/node/config.go @@ -25,6 +25,7 @@ import ( "github.com/Loopring/relay-cluster/accountmanager" "github.com/Loopring/relay-cluster/gateway" + "github.com/Loopring/relay-cluster/gateway/order_difficulty" "github.com/Loopring/relay-cluster/market" ordermanager "github.com/Loopring/relay-cluster/ordermanager/common" "github.com/Loopring/relay-cluster/usermanager" @@ -84,6 +85,7 @@ type GlobalConfig struct { AccountManager accountmanager.AccountManagerOptions MyToken market.MyTokenConfig CloudWatch cloudwatch.CloudWatchConfig + OrderDifficulty order_difficulty.OrderDifficultyConfig } func Validator(cv reflect.Value) (bool, error) { diff --git a/node/node.go b/node/node.go index ebf65f0e..be94a73f 100644 --- a/node/node.go +++ b/node/node.go @@ -25,9 +25,11 @@ import ( "github.com/Loopring/relay-cluster/accountmanager" "github.com/Loopring/relay-cluster/dao" "github.com/Loopring/relay-cluster/gateway" + "github.com/Loopring/relay-cluster/gateway/order_difficulty" "github.com/Loopring/relay-cluster/market" ordermanager "github.com/Loopring/relay-cluster/ordermanager/manager" orderviewer "github.com/Loopring/relay-cluster/ordermanager/viewer" + ringtrackerviewer "github.com/Loopring/relay-cluster/ringtrackermanager/viewer" txmanager "github.com/Loopring/relay-cluster/txmanager/manager" txviewer "github.com/Loopring/relay-cluster/txmanager/viewer" "github.com/Loopring/relay-cluster/usermanager" @@ -46,31 +48,30 @@ import ( "github.com/Loopring/relay-lib/zklock" "github.com/ethereum/go-ethereum/accounts/keystore" "go.uber.org/zap" - ringtrackerviewer "github.com/Loopring/relay-cluster/ringtrackermanager/viewer" ) type Node struct { globalConfig *GlobalConfig rdsService *dao.RdsService //ipfsSubService gateway.IPFSSubService - orderManager ordermanager.OrderManager - orderViewer orderviewer.OrderViewer - userManager usermanager.UserManager - marketCapProvider marketcap.MarketCapProvider - accountManager accountmanager.AccountManager - trendManager market.TrendManager - tickerCollector market.CollectorImpl - tickerManager market.GetTickerImpl - globalMarket market.GlobalMarket - jsonRpcService gateway.JsonrpcServiceImpl - websocketService gateway.WebsocketServiceImpl - socketIOService gateway.SocketIOServiceImpl - walletService gateway.WalletServiceImpl - txManager txmanager.TransactionManager - motanService *gateway.MotanService - - wg *sync.WaitGroup - logger *zap.Logger + orderManager ordermanager.OrderManager + orderViewer orderviewer.OrderViewer + userManager usermanager.UserManager + marketCapProvider marketcap.MarketCapProvider + accountManager accountmanager.AccountManager + trendManager market.TrendManager + tickerCollector market.CollectorImpl + tickerManager market.GetTickerImpl + globalMarket market.GlobalMarket + jsonRpcService gateway.JsonrpcServiceImpl + websocketService gateway.WebsocketServiceImpl + socketIOService gateway.SocketIOServiceImpl + walletService gateway.WalletServiceImpl + txManager txmanager.TransactionManager + motanService *gateway.MotanService + orderDifficultyEvaluator *order_difficulty.OrderDifficultyEvaluator + wg *sync.WaitGroup + logger *zap.Logger ringTrackerViewer ringtrackerviewer.RingTrackerViewer ringTrackerService gateway.RingTrackerServiceImpl @@ -118,6 +119,7 @@ func NewNode(logger *zap.Logger, globalConfig *GlobalConfig) *Node { n.registerRingTrackerViewer() n.registerRingTrackerService() + n.registerOrderDifficultyEvaluator() return n } @@ -135,6 +137,7 @@ func (n *Node) Start() { //n.websocketService.Start() go n.socketIOService.Start() gateway.StartMotanService(n.globalConfig.MotanServer, n.accountManager, n.orderViewer) + n.orderDifficultyEvaluator.Start() n.wg.Add(1) } @@ -268,6 +271,10 @@ func (n *Node) registerCloudWatch() { cloudwatch.Initialize(n.globalConfig.CloudWatch) } +func (n *Node) registerOrderDifficultyEvaluator() { + n.orderDifficultyEvaluator = order_difficulty.NewOrderDifficultyEvaluator(n.globalConfig.OrderDifficulty) +} + func (n *Node) registerRingTrackerViewer() { n.ringTrackerViewer = ringtrackerviewer.NewRingTrackerViewer(n.rdsService, n.marketCapProvider) } diff --git a/vendor/gonum.org/v1/gonum/blas/README.md b/vendor/gonum.org/v1/gonum/blas/README.md new file mode 100644 index 00000000..8d0af75f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/README.md @@ -0,0 +1,79 @@ +# Gonum BLAS [![GoDoc](https://godoc.org/gonum.org/v1/gonum/blas?status.svg)](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/... +``` + +### BLAS C-bindings + +If you want to use OpenBLAS, install it in any directory: +```sh + git clone https://github.com/xianyi/OpenBLAS + cd OpenBLAS + make +``` + +The blas/cgo package provides bindings to C-backed BLAS packages. blas/cgo needs the `CGO_LDFLAGS` +environment variable to point to the blas installation. More information can be found in the +[cgo command documentation](http://golang.org/cmd/cgo/). + +Then install the blas/cgo package: +```sh + CGO_LDFLAGS="-L/path/to/OpenBLAS -lopenblas" go install gonum.org/v1/netlib/blas +``` + +For Windows you can download binary packages for OpenBLAS at +[SourceForge](http://sourceforge.net/projects/openblas/files/). + +If you want to use a different BLAS package such as the Intel MKL you can +adjust the `CGO_LDFLAGS` variable: +```sh + CGO_LDFLAGS="-lmkl_rt" go install gonum.org/v1/netlib/blas +``` + +On OS X the easiest solution is to use the libraries provided by the system: +```sh + CGO_LDFLAGS="-framework Accelerate" go install gonum.org/v1/netlib/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. diff --git a/vendor/gonum.org/v1/gonum/blas/blas.go b/vendor/gonum.org/v1/gonum/blas/blas.go new file mode 100644 index 00000000..3fda4ff8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas.go @@ -0,0 +1,287 @@ +// 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 = iota - 2 // H is the identity matrix; no rotation is needed. + Rescaling // H specifies rescaling. + OffDiagonal // Off-diagonal elements of H are units. + Diagonal // Diagonal elements of H are units. +) + +// 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 is used to specify the transposition operation for a +// routine. +type Transpose int + +const ( + NoTrans Transpose = 111 + iota + Trans + ConjTrans +) + +// Uplo is used to specify whether the matrix is an upper or lower +// triangular matrix. +type Uplo int + +const ( + All Uplo = 120 + iota + Upper + Lower +) + +// Diag is used to specify whether the matrix is a unit or non-unit +// triangular matrix. +type Diag int + +const ( + NonUnit Diag = 131 + iota + Unit +) + +// Side is used to specify from which side a multiplication operation +// is performed. +type Side int + +const ( + Left Side = 141 + iota + Right +) + +// 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) +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas32/blas32.go b/vendor/gonum.org/v1/gonum/blas/blas32/blas32.go new file mode 100644 index 00000000..fe5a144e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas32/blas32.go @@ -0,0 +1,457 @@ +// 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 blas32 + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/gonum" +) + +var blas32 blas.Float32 = gonum.Implementation{} + +// Use sets the BLAS float32 implementation to be used by subsequent BLAS calls. +// The default implementation is native.Implementation. +func Use(b blas.Float32) { + blas32 = b +} + +// Implementation returns the current BLAS float32 implementation. +// +// Implementation allows direct calls to the current the BLAS float32 implementation +// giving finer control of parameters. +func Implementation() blas.Float32 { + return blas32 +} + +// Vector represents a vector with an associated element increment. +type Vector struct { + Inc int + Data []float32 +} + +// General represents a matrix using the conventional storage scheme. +type General struct { + Rows, Cols int + Stride int + Data []float32 +} + +// Band represents a band matrix using the band storage scheme. +type Band struct { + Rows, Cols int + KL, KU int + Stride int + Data []float32 +} + +// Triangular represents a triangular matrix using the conventional storage scheme. +type Triangular struct { + N int + Stride int + Data []float32 + 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 []float32 + Uplo blas.Uplo + Diag blas.Diag +} + +// TriangularPacked represents a triangular matrix using the packed storage scheme. +type TriangularPacked struct { + N int + Data []float32 + Uplo blas.Uplo + Diag blas.Diag +} + +// Symmetric represents a symmetric matrix using the conventional storage scheme. +type Symmetric struct { + N int + Stride int + Data []float32 + Uplo blas.Uplo +} + +// SymmetricBand represents a symmetric matrix using the band storage scheme. +type SymmetricBand struct { + N, K int + Stride int + Data []float32 + Uplo blas.Uplo +} + +// SymmetricPacked represents a symmetric matrix using the packed storage scheme. +type SymmetricPacked struct { + N int + Data []float32 + Uplo blas.Uplo +} + +// Level 1 + +const negInc = "blas32: negative vector increment" + +// Dot computes the dot product of the two vectors: +// \sum_i x[i]*y[i]. +func Dot(n int, x, y Vector) float32 { + return blas32.Sdot(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// DDot computes the dot product of the two vectors: +// \sum_i x[i]*y[i]. +func DDot(n int, x, y Vector) float64 { + return blas32.Dsdot(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// SDDot computes the dot product of the two vectors adding a constant: +// alpha + \sum_i x[i]*y[i]. +func SDDot(n int, alpha float32, x, y Vector) float32 { + return blas32.Sdsdot(n, alpha, x.Data, x.Inc, y.Data, y.Inc) +} + +// Nrm2 computes the Euclidean norm of the vector x: +// sqrt(\sum_i x[i]*x[i]). +// +// Nrm2 will panic if the vector increment is negative. +func Nrm2(n int, x Vector) float32 { + if x.Inc < 0 { + panic(negInc) + } + return blas32.Snrm2(n, x.Data, x.Inc) +} + +// Asum computes the sum of the absolute values of the elements of x: +// \sum_i |x[i]|. +// +// Asum will panic if the vector increment is negative. +func Asum(n int, x Vector) float32 { + if x.Inc < 0 { + panic(negInc) + } + return blas32.Sasum(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(n int, x Vector) int { + if x.Inc < 0 { + panic(negInc) + } + return blas32.Isamax(n, x.Data, x.Inc) +} + +// Swap exchanges the elements of the two vectors: +// x[i], y[i] = y[i], x[i] for all i. +func Swap(n int, x, y Vector) { + blas32.Sswap(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Copy copies the elements of x into the elements of y: +// y[i] = x[i] for all i. +func Copy(n int, x, y Vector) { + blas32.Scopy(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Axpy adds x scaled by alpha to y: +// y[i] += alpha*x[i] for all i. +func Axpy(n int, alpha float32, x, y Vector) { + blas32.Saxpy(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 float32) (c, s, r, z float32) { + return blas32.Srotg(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 float32) (p blas.SrotmParams, rd1, rd2, rb1 float32) { + return blas32.Srotmg(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(n int, x, y Vector, c, s float32) { + blas32.Srot(n, x.Data, x.Inc, y.Data, y.Inc, c, s) +} + +// Rotm applies the modified Givens rotation to n points represented by the +// vectors x and y. +func Rotm(n int, x, y Vector, p blas.SrotmParams) { + blas32.Srotm(n, x.Data, x.Inc, y.Data, y.Inc, p) +} + +// Scal scales the vector x by alpha: +// x[i] *= alpha for all i. +// +// Scal will panic if the vector increment is negative. +func Scal(n int, alpha float32, x Vector) { + if x.Inc < 0 { + panic(negInc) + } + blas32.Sscal(n, alpha, x.Data, x.Inc) +} + +// Level 2 + +// Gemv computes +// y = alpha * A * x + beta * y, if t == blas.NoTrans, +// y = alpha * A^T * x + beta * y, if t == blas.Trans 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 float32, a General, x Vector, beta float32, y Vector) { + blas32.Sgemv(t, a.Rows, a.Cols, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Gbmv computes +// y = alpha * A * x + beta * y, if t == blas.NoTrans, +// y = alpha * A^T * x + beta * y, if t == blas.Trans 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 float32, a Band, x Vector, beta float32, y Vector) { + blas32.Sgbmv(t, a.Rows, a.Cols, a.KL, a.KU, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Trmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans 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) { + blas32.Strmv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tbmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans 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) { + blas32.Stbmv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tpmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans 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) { + blas32.Stpmv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc) +} + +// Trsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans 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) { + blas32.Strsv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tbsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans 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) { + blas32.Stbsv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tpsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans 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) { + blas32.Stpsv(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 float32, a Symmetric, x Vector, beta float32, y Vector) { + blas32.Ssymv(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 float32, a SymmetricBand, x Vector, beta float32, y Vector) { + blas32.Ssbmv(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 float32, a SymmetricPacked, x Vector, beta float32, y Vector) { + blas32.Sspmv(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^T, +// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar. +func Ger(alpha float32, x, y Vector, a General) { + blas32.Sger(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^T, +// where A is an n×n symmetric matrix, x is a vector, and alpha is a scalar. +func Syr(alpha float32, x Vector, a Symmetric) { + blas32.Ssyr(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data, a.Stride) +} + +// Spr performs the rank-1 update +// A += alpha * x * x^T, +// where A is an n×n symmetric matrix in packed format, x is a vector, and +// alpha is a scalar. +func Spr(alpha float32, x Vector, a SymmetricPacked) { + blas32.Sspr(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data) +} + +// Syr2 performs a rank-2 update +// A += alpha * x * y^T + alpha * y * x^T, +// where A is a symmetric n×n matrix, x and y are vectors, and alpha is a scalar. +func Syr2(alpha float32, x, y Vector, a Symmetric) { + blas32.Ssyr2(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^T + alpha * y * x^T, +// where A is an n×n symmetric matrix in packed format, x and y are vectors, +// and alpha is a scalar. +func Spr2(alpha float32, x, y Vector, a SymmetricPacked) { + blas32.Sspr2(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 float32, a, b General, beta float32, 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 + } + blas32.Sgemm(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 float32, a Symmetric, b General, beta float32, c General) { + var m, n int + if s == blas.Left { + m, n = a.N, b.Cols + } else { + m, n = b.Rows, a.N + } + blas32.Ssymm(s, a.Uplo, m, n, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Syrk performs a symmetric rank-k update +// C = alpha * A * A^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * A + beta * C, if t == blas.Trans 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 float32, a General, beta float32, c Symmetric) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + blas32.Ssyrk(c.Uplo, t, n, k, alpha, a.Data, a.Stride, beta, c.Data, c.Stride) +} + +// Syr2k performs a symmetric rank-2k update +// C = alpha * A * B^T + alpha * B * A^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * B + alpha * B^T * A + beta * C, if t == blas.Trans 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 float32, a, b General, beta float32, c Symmetric) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + blas32.Ssyr2k(c.Uplo, t, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Trmm performs +// B = alpha * A * B, if tA == blas.NoTrans and s == blas.Left, +// B = alpha * A^T * B, if tA == blas.Trans or blas.ConjTrans, and s == blas.Left, +// B = alpha * B * A, if tA == blas.NoTrans and s == blas.Right, +// B = alpha * B * A^T, if tA == blas.Trans 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 float32, a Triangular, b General) { + blas32.Strmm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride) +} + +// Trsm solves +// A * X = alpha * B, if tA == blas.NoTrans and s == blas.Left, +// A^T * X = alpha * B, if tA == blas.Trans or blas.ConjTrans, and s == blas.Left, +// X * A = alpha * B, if tA == blas.NoTrans and s == blas.Right, +// X * A^T = alpha * B, if tA == blas.Trans 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 float32, a Triangular, b General) { + blas32.Strsm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride) +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas32/conv.go b/vendor/gonum.org/v1/gonum/blas/blas32/conv.go new file mode 100644 index 00000000..24107906 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas32/conv.go @@ -0,0 +1,279 @@ +// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT. + +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package blas32 + +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("blas32: mismatched dimension") + } + if len(t.Data) < (t.Cols-1)*t.Stride+t.Rows { + panic("blas32: 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("blas32: mismatched dimension") + } + if len(t.Data) < (t.Rows-1)*t.Stride+t.Cols { + panic("blas32: 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("blas32: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("blas32: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("blas32: mismatched BLAS diag") + } + switch a.Uplo { + default: + panic("blas32: 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("blas32: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("blas32: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("blas32: mismatched BLAS diag") + } + switch a.Uplo { + default: + panic("blas32: 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("blas32: mismatched dimension") + } + if t.KL != a.KL || t.KU != a.KU { + panic("blas32: mismatched bandwidth") + } + if a.Stride < a.KL+a.KU+1 { + panic("blas32: short stride for source") + } + if t.Stride < t.KL+t.KU+1 { + panic("blas32: 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("blas32: mismatched dimension") + } + if t.KL != a.KL || t.KU != a.KU { + panic("blas32: mismatched bandwidth") + } + if a.Stride < a.KL+a.KU+1 { + panic("blas32: short stride for source") + } + if t.Stride < t.KL+t.KU+1 { + panic("blas32: short stride for destination") + } + for j := 0; j < a.Cols; j++ { + for i := max(0, j-a.KU); i < min(j+a.KL+1, a.Rows); i++ { + t.Data[j+a.KL-i+i*a.Stride] = a.Data[i+t.KU-j+j*t.Stride] + } + } +} + +// TriangularBandCols represents a symmetric matrix using the band column-major storage scheme. +type TriangularBandCols TriangularBand + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t TriangularBandCols) From(a TriangularBand) { + if t.N != a.N { + panic("blas32: mismatched dimension") + } + if t.K != a.K { + panic("blas32: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("blas32: short stride for source") + } + if t.Stride < t.K+1 { + panic("blas32: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("blas32: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("blas32: 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("blas32: 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("blas32: mismatched dimension") + } + if t.K != a.K { + panic("blas32: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("blas32: short stride for source") + } + if t.Stride < t.K+1 { + panic("blas32: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("blas32: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("blas32: 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("blas32: 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 +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas32/conv_symmetric.go b/vendor/gonum.org/v1/gonum/blas/blas32/conv_symmetric.go new file mode 100644 index 00000000..e385a641 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas32/conv_symmetric.go @@ -0,0 +1,155 @@ +// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT. + +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package blas32 + +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("blas32: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("blas32: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("blas32: 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("blas32: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("blas32: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("blas32: 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("blas32: mismatched dimension") + } + if t.K != a.K { + panic("blas32: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("blas32: short stride for source") + } + if t.Stride < t.K+1 { + panic("blas32: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("blas32: 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("blas32: 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("blas32: mismatched dimension") + } + if t.K != a.K { + panic("blas32: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("blas32: short stride for source") + } + if t.Stride < t.K+1 { + panic("blas32: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("blas32: 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("blas32: 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) +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas32/conv_symmetric_test.go b/vendor/gonum.org/v1/gonum/blas/blas32/conv_symmetric_test.go new file mode 100644 index 00000000..335f0fa0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas32/conv_symmetric_test.go @@ -0,0 +1,307 @@ +// 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 blas32 + +import ( + math "gonum.org/v1/gonum/internal/math32" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newSymmetricFrom(a SymmetricCols) Symmetric { + t := Symmetric{ + N: a.N, + Stride: a.N, + Data: make([]float32, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Symmetric) n() int { return m.N } +func (m Symmetric) at(i, j int) float32 { + if m.Uplo == blas.Lower && i < j && j < m.N { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j { + i, j = j, i + } + return m.Data[i*m.Stride+j] +} +func (m Symmetric) uplo() blas.Uplo { return m.Uplo } + +func newSymmetricColsFrom(a Symmetric) SymmetricCols { + t := SymmetricCols{ + N: a.N, + Stride: a.N, + Data: make([]float32, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m SymmetricCols) n() int { return m.N } +func (m SymmetricCols) at(i, j int) float32 { + if m.Uplo == blas.Lower && i < j { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j && i < m.N { + i, j = j, i + } + return m.Data[i+j*m.Stride] +} +func (m SymmetricCols) uplo() blas.Uplo { return m.Uplo } + +type symmetric interface { + n() int + at(i, j int) float32 + uplo() blas.Uplo +} + +func sameSymmetric(a, b symmetric) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var symmetricTests = []Symmetric{ + {N: 3, Stride: 3, Data: []float32{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []float32{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertSymmetric(t *testing.T) { + for _, test := range symmetricTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + test.Uplo = uplo + colmajor := newSymmetricColsFrom(test) + if !sameSymmetric(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newSymmetricFrom(colmajor) + if !sameSymmetric(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } +} +func newSymmetricBandFrom(a SymmetricBandCols) SymmetricBand { + t := SymmetricBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float32, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m SymmetricBand) n() (n int) { return m.N } +func (m SymmetricBand) at(i, j int) float32 { + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas32: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m SymmetricBand) bandwidth() (k int) { return m.K } +func (m SymmetricBand) uplo() blas.Uplo { return m.Uplo } + +func newSymmetricBandColsFrom(a SymmetricBand) SymmetricBandCols { + t := SymmetricBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float32, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m SymmetricBandCols) n() (n int) { return m.N } +func (m SymmetricBandCols) at(i, j int) float32 { + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas32: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m SymmetricBandCols) bandwidth() (k int) { return m.K } +func (m SymmetricBandCols) uplo() blas.Uplo { return m.Uplo } + +type symmetricBand interface { + n() (n int) + at(i, j int) float32 + bandwidth() (k int) + uplo() blas.Uplo +} + +func sameSymmetricBand(a, b symmetricBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var symmetricBandTests = []SymmetricBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []float32{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []float32{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []float32{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []float32{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []float32{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []float32{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []float32{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []float32{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []float32{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []float32{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []float32{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []float32{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertSymBand(t *testing.T) { + for _, test := range symmetricBandTests { + colmajor := newSymmetricBandColsFrom(test) + if !sameSymmetricBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newSymmetricBandFrom(colmajor) + if !sameSymmetricBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas32/conv_test.go b/vendor/gonum.org/v1/gonum/blas/blas32/conv_test.go new file mode 100644 index 00000000..9cff493e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas32/conv_test.go @@ -0,0 +1,620 @@ +// 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 blas32 + +import ( + math "gonum.org/v1/gonum/internal/math32" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newGeneralFrom(a GeneralCols) General { + t := General{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Cols, + Data: make([]float32, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m General) dims() (r, c int) { return m.Rows, m.Cols } +func (m General) at(i, j int) float32 { return m.Data[i*m.Stride+j] } + +func newGeneralColsFrom(a General) GeneralCols { + t := GeneralCols{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Rows, + Data: make([]float32, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m GeneralCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m GeneralCols) at(i, j int) float32 { return m.Data[i+j*m.Stride] } + +type general interface { + dims() (r, c int) + at(i, j int) float32 +} + +func sameGeneral(a, b general) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var generalTests = []General{ + {Rows: 2, Cols: 3, Stride: 3, Data: []float32{ + 1, 2, 3, + 4, 5, 6, + }}, + {Rows: 3, Cols: 2, Stride: 2, Data: []float32{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 3, Stride: 3, Data: []float32{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 2, Cols: 3, Stride: 5, Data: []float32{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + }}, + {Rows: 3, Cols: 2, Stride: 5, Data: []float32{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, Stride: 5, Data: []float32{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertGeneral(t *testing.T) { + for _, test := range generalTests { + colmajor := newGeneralColsFrom(test) + if !sameGeneral(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newGeneralFrom(colmajor) + if !sameGeneral(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularFrom(a TriangularCols) Triangular { + t := Triangular{ + N: a.N, + Stride: a.N, + Data: make([]float32, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Triangular) n() int { return m.N } +func (m Triangular) at(i, j int) float32 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j && j < m.N { + return 0 + } + if m.Uplo == blas.Upper && i > j { + return 0 + } + return m.Data[i*m.Stride+j] +} +func (m Triangular) uplo() blas.Uplo { return m.Uplo } +func (m Triangular) diag() blas.Diag { return m.Diag } + +func newTriangularColsFrom(a Triangular) TriangularCols { + t := TriangularCols{ + N: a.N, + Stride: a.N, + Data: make([]float32, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m TriangularCols) n() int { return m.N } +func (m TriangularCols) at(i, j int) float32 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j { + return 0 + } + if m.Uplo == blas.Upper && i > j && i < m.N { + return 0 + } + return m.Data[i+j*m.Stride] +} +func (m TriangularCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularCols) diag() blas.Diag { return m.Diag } + +type triangular interface { + n() int + at(i, j int) float32 + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangular(a, b triangular) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularTests = []Triangular{ + {N: 3, Stride: 3, Data: []float32{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []float32{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertTriangular(t *testing.T) { + for _, test := range triangularTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower, blas.All} { + for _, diag := range []blas.Diag{blas.Unit, blas.NonUnit} { + test.Uplo = uplo + test.Diag = diag + colmajor := newTriangularColsFrom(test) + if !sameTriangular(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularFrom(colmajor) + if !sameTriangular(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } + } +} + +func newBandFrom(a BandCols) Band { + t := Band{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]float32, a.Rows*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m Band) dims() (r, c int) { return m.Rows, m.Cols } +func (m Band) at(i, j int) float32 { + pj := j + m.KL - i + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[i*m.Stride+pj] +} +func (m Band) bandwidth() (kl, ku int) { return m.KL, m.KU } + +func newBandColsFrom(a Band) BandCols { + t := BandCols{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]float32, a.Cols*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m BandCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m BandCols) at(i, j int) float32 { + pj := i + m.KU - j + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[j*m.Stride+pj] +} +func (m BandCols) bandwidth() (kl, ku int) { return m.KL, m.KU } + +type band interface { + dims() (r, c int) + at(i, j int) float32 + bandwidth() (kl, ku int) +} + +func sameBand(a, b band) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + akl, aku := a.bandwidth() + bkl, bku := b.bandwidth() + if akl != bkl || aku != bku { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var bandTests = []Band{ + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 1, Data: []float32{ + 1, + 2, + 3, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []float32{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []float32{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 2, Data: []float32{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 2, Data: []float32{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 3, Data: []float32{ + -1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 3, Data: []float32{ + -1, 2, 3, + 4, 5, 6, + 7, 8, -2, + 9, -3, -4, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 4, Data: []float32{ + -2, -1, 3, 4, + -3, 5, 6, 7, + 8, 9, 10, 11, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 4, Data: []float32{ + -2, -1, 2, 3, + -3, 4, 5, 6, + 7, 8, 9, -4, + 10, 11, -5, -6, + }}, + + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 5, Data: []float32{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []float32{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []float32{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 5, Data: []float32{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 5, Data: []float32{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 5, Data: []float32{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 5, Data: []float32{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, -2, 0, 0, + 9, -3, -4, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 5, Data: []float32{ + -2, -1, 3, 4, 0, + -3, 5, 6, 7, 0, + 8, 9, 10, 11, 0, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 5, Data: []float32{ + -2, -1, 2, 3, 0, + -3, 4, 5, 6, 0, + 7, 8, 9, -4, 0, + 10, 11, -5, -6, 0, + }}, +} + +func TestConvertBand(t *testing.T) { + for _, test := range bandTests { + colmajor := newBandColsFrom(test) + if !sameBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newBandFrom(colmajor) + if !sameBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularBandFrom(a TriangularBandCols) TriangularBand { + t := TriangularBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float32, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBand) n() (n int) { return m.N } +func (m TriangularBand) at(i, j int) float32 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas32: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBand) bandwidth() (k int) { return m.K } +func (m TriangularBand) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBand) diag() blas.Diag { return m.Diag } + +func newTriangularBandColsFrom(a TriangularBand) TriangularBandCols { + t := TriangularBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float32, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBandCols) n() (n int) { return m.N } +func (m TriangularBandCols) at(i, j int) float32 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas32: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBandCols) bandwidth() (k int) { return m.K } +func (m TriangularBandCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBandCols) diag() blas.Diag { return m.Diag } + +type triangularBand interface { + n() (n int) + at(i, j int) float32 + bandwidth() (k int) + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangularBand(a, b triangularBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + if a.diag() != b.diag() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularBandTests = []TriangularBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []float32{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []float32{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []float32{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []float32{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []float32{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []float32{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []float32{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []float32{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []float32{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []float32{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []float32{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []float32{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertTriBand(t *testing.T) { + for _, test := range triangularBandTests { + colmajor := newTriangularBandColsFrom(test) + if !sameTriangularBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularBandFrom(colmajor) + if !sameTriangularBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas32/doc.go b/vendor/gonum.org/v1/gonum/blas/blas32/doc.go new file mode 100644 index 00000000..d01a5162 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas32/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package blas32 provides a simple interface to the float32 BLAS API. +package blas32 // import "gonum.org/v1/gonum/blas/blas32" diff --git a/vendor/gonum.org/v1/gonum/blas/blas64/blas64.go b/vendor/gonum.org/v1/gonum/blas/blas64/blas64.go new file mode 100644 index 00000000..88e746bb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas64/blas64.go @@ -0,0 +1,445 @@ +// 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 native.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 { + Inc int + Data []float64 +} + +// General represents a matrix using the conventional storage scheme. +type General struct { + Rows, Cols int + Stride int + Data []float64 +} + +// Band represents a band matrix using the band storage scheme. +type Band struct { + Rows, Cols int + KL, KU int + Stride int + Data []float64 +} + +// Triangular represents a triangular matrix using the conventional storage scheme. +type Triangular struct { + N int + Stride int + Data []float64 + Uplo blas.Uplo + Diag blas.Diag +} + +// TriangularBand represents a triangular matrix using the band storage scheme. +type TriangularBand struct { + N, K int + Stride int + Data []float64 + Uplo blas.Uplo + Diag blas.Diag +} + +// TriangularPacked represents a triangular matrix using the packed storage scheme. +type TriangularPacked struct { + N int + Data []float64 + Uplo blas.Uplo + Diag blas.Diag +} + +// Symmetric represents a symmetric matrix using the conventional storage scheme. +type Symmetric struct { + N int + Stride int + Data []float64 + Uplo blas.Uplo +} + +// SymmetricBand represents a symmetric matrix using the band storage scheme. +type SymmetricBand struct { + N, K int + Stride int + Data []float64 + Uplo blas.Uplo +} + +// SymmetricPacked represents a symmetric matrix using the packed storage scheme. +type SymmetricPacked struct { + N int + Data []float64 + Uplo blas.Uplo +} + +// Level 1 + +const negInc = "blas64: negative vector increment" + +// Dot computes the dot product of the two vectors: +// \sum_i x[i]*y[i]. +func Dot(n int, x, y Vector) float64 { + return blas64.Ddot(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Nrm2 computes the Euclidean norm of the vector x: +// sqrt(\sum_i x[i]*x[i]). +// +// Nrm2 will panic if the vector increment is negative. +func Nrm2(n int, x Vector) float64 { + if x.Inc < 0 { + panic(negInc) + } + return blas64.Dnrm2(n, x.Data, x.Inc) +} + +// Asum computes the sum of the absolute values of the elements of x: +// \sum_i |x[i]|. +// +// Asum will panic if the vector increment is negative. +func Asum(n int, x Vector) float64 { + if x.Inc < 0 { + panic(negInc) + } + return blas64.Dasum(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(n int, x Vector) int { + if x.Inc < 0 { + panic(negInc) + } + return blas64.Idamax(n, x.Data, x.Inc) +} + +// Swap exchanges the elements of the two vectors: +// x[i], y[i] = y[i], x[i] for all i. +func Swap(n int, x, y Vector) { + blas64.Dswap(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Copy copies the elements of x into the elements of y: +// y[i] = x[i] for all i. +func Copy(n int, x, y Vector) { + blas64.Dcopy(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Axpy adds x scaled by alpha to y: +// y[i] += alpha*x[i] for all i. +func Axpy(n int, alpha float64, x, y Vector) { + blas64.Daxpy(n, alpha, x.Data, x.Inc, y.Data, y.Inc) +} + +// 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(n int, x, y Vector, c, s float64) { + blas64.Drot(n, x.Data, x.Inc, y.Data, y.Inc, c, s) +} + +// Rotm applies the modified Givens rotation to n points represented by the +// vectors x and y. +func Rotm(n int, x, y Vector, p blas.DrotmParams) { + blas64.Drotm(n, x.Data, x.Inc, y.Data, y.Inc, p) +} + +// Scal scales the vector x by alpha: +// x[i] *= alpha for all i. +// +// Scal will panic if the vector increment is negative. +func Scal(n int, alpha float64, x Vector) { + if x.Inc < 0 { + panic(negInc) + } + blas64.Dscal(n, alpha, x.Data, x.Inc) +} + +// Level 2 + +// Gemv computes +// y = alpha * A * x + beta * y, if t == blas.NoTrans, +// y = alpha * A^T * x + beta * y, if t == blas.Trans 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^T * 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^T * 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^T * 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^T * 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^T * 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^T * 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^T * 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^T, +// 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^T, +// 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^T, +// 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^T + alpha * y * x^T, +// 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^T + alpha * y * x^T, +// 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^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * 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^T + alpha * B * A^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * B + alpha * B^T * A + beta * C, if t == blas.Trans 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^T * 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^T, 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^T * 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^T = 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) +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas64/conv.go b/vendor/gonum.org/v1/gonum/blas/blas64/conv.go new file mode 100644 index 00000000..17de0943 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas64/conv.go @@ -0,0 +1,277 @@ +// 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 symmetric matrix using the band column-major storage scheme. +type TriangularBandCols TriangularBand + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t TriangularBandCols) From(a TriangularBand) { + if t.N != a.N { + panic("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 +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric.go b/vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric.go new file mode 100644 index 00000000..a43b2304 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric.go @@ -0,0 +1,153 @@ +// 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) +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric_test.go b/vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric_test.go new file mode 100644 index 00000000..167de52d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric_test.go @@ -0,0 +1,305 @@ +// 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 ( + "math" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newSymmetricFrom(a SymmetricCols) Symmetric { + t := Symmetric{ + N: a.N, + Stride: a.N, + Data: make([]float64, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Symmetric) n() int { return m.N } +func (m Symmetric) at(i, j int) float64 { + if m.Uplo == blas.Lower && i < j && j < m.N { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j { + i, j = j, i + } + return m.Data[i*m.Stride+j] +} +func (m Symmetric) uplo() blas.Uplo { return m.Uplo } + +func newSymmetricColsFrom(a Symmetric) SymmetricCols { + t := SymmetricCols{ + N: a.N, + Stride: a.N, + Data: make([]float64, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m SymmetricCols) n() int { return m.N } +func (m SymmetricCols) at(i, j int) float64 { + if m.Uplo == blas.Lower && i < j { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j && i < m.N { + i, j = j, i + } + return m.Data[i+j*m.Stride] +} +func (m SymmetricCols) uplo() blas.Uplo { return m.Uplo } + +type symmetric interface { + n() int + at(i, j int) float64 + uplo() blas.Uplo +} + +func sameSymmetric(a, b symmetric) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var symmetricTests = []Symmetric{ + {N: 3, Stride: 3, Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []float64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertSymmetric(t *testing.T) { + for _, test := range symmetricTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + test.Uplo = uplo + colmajor := newSymmetricColsFrom(test) + if !sameSymmetric(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newSymmetricFrom(colmajor) + if !sameSymmetric(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } +} +func newSymmetricBandFrom(a SymmetricBandCols) SymmetricBand { + t := SymmetricBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float64, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m SymmetricBand) n() (n int) { return m.N } +func (m SymmetricBand) at(i, j int) float64 { + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas64: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m SymmetricBand) bandwidth() (k int) { return m.K } +func (m SymmetricBand) uplo() blas.Uplo { return m.Uplo } + +func newSymmetricBandColsFrom(a SymmetricBand) SymmetricBandCols { + t := SymmetricBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float64, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m SymmetricBandCols) n() (n int) { return m.N } +func (m SymmetricBandCols) at(i, j int) float64 { + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas64: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m SymmetricBandCols) bandwidth() (k int) { return m.K } +func (m SymmetricBandCols) uplo() blas.Uplo { return m.Uplo } + +type symmetricBand interface { + n() (n int) + at(i, j int) float64 + bandwidth() (k int) + uplo() blas.Uplo +} + +func sameSymmetricBand(a, b symmetricBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var symmetricBandTests = []SymmetricBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []float64{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []float64{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []float64{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []float64{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []float64{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []float64{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []float64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []float64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []float64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []float64{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []float64{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []float64{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertSymBand(t *testing.T) { + for _, test := range symmetricBandTests { + colmajor := newSymmetricBandColsFrom(test) + if !sameSymmetricBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newSymmetricBandFrom(colmajor) + if !sameSymmetricBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas64/conv_test.go b/vendor/gonum.org/v1/gonum/blas/blas64/conv_test.go new file mode 100644 index 00000000..61645317 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas64/conv_test.go @@ -0,0 +1,618 @@ +// 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 ( + "math" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newGeneralFrom(a GeneralCols) General { + t := General{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Cols, + Data: make([]float64, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m General) dims() (r, c int) { return m.Rows, m.Cols } +func (m General) at(i, j int) float64 { return m.Data[i*m.Stride+j] } + +func newGeneralColsFrom(a General) GeneralCols { + t := GeneralCols{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Rows, + Data: make([]float64, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m GeneralCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m GeneralCols) at(i, j int) float64 { return m.Data[i+j*m.Stride] } + +type general interface { + dims() (r, c int) + at(i, j int) float64 +} + +func sameGeneral(a, b general) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var generalTests = []General{ + {Rows: 2, Cols: 3, Stride: 3, Data: []float64{ + 1, 2, 3, + 4, 5, 6, + }}, + {Rows: 3, Cols: 2, Stride: 2, Data: []float64{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 3, Stride: 3, Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 2, Cols: 3, Stride: 5, Data: []float64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + }}, + {Rows: 3, Cols: 2, Stride: 5, Data: []float64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, Stride: 5, Data: []float64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertGeneral(t *testing.T) { + for _, test := range generalTests { + colmajor := newGeneralColsFrom(test) + if !sameGeneral(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newGeneralFrom(colmajor) + if !sameGeneral(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularFrom(a TriangularCols) Triangular { + t := Triangular{ + N: a.N, + Stride: a.N, + Data: make([]float64, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Triangular) n() int { return m.N } +func (m Triangular) at(i, j int) float64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j && j < m.N { + return 0 + } + if m.Uplo == blas.Upper && i > j { + return 0 + } + return m.Data[i*m.Stride+j] +} +func (m Triangular) uplo() blas.Uplo { return m.Uplo } +func (m Triangular) diag() blas.Diag { return m.Diag } + +func newTriangularColsFrom(a Triangular) TriangularCols { + t := TriangularCols{ + N: a.N, + Stride: a.N, + Data: make([]float64, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m TriangularCols) n() int { return m.N } +func (m TriangularCols) at(i, j int) float64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j { + return 0 + } + if m.Uplo == blas.Upper && i > j && i < m.N { + return 0 + } + return m.Data[i+j*m.Stride] +} +func (m TriangularCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularCols) diag() blas.Diag { return m.Diag } + +type triangular interface { + n() int + at(i, j int) float64 + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangular(a, b triangular) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularTests = []Triangular{ + {N: 3, Stride: 3, Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []float64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertTriangular(t *testing.T) { + for _, test := range triangularTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower, blas.All} { + for _, diag := range []blas.Diag{blas.Unit, blas.NonUnit} { + test.Uplo = uplo + test.Diag = diag + colmajor := newTriangularColsFrom(test) + if !sameTriangular(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularFrom(colmajor) + if !sameTriangular(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } + } +} + +func newBandFrom(a BandCols) Band { + t := Band{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]float64, a.Rows*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m Band) dims() (r, c int) { return m.Rows, m.Cols } +func (m Band) at(i, j int) float64 { + pj := j + m.KL - i + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[i*m.Stride+pj] +} +func (m Band) bandwidth() (kl, ku int) { return m.KL, m.KU } + +func newBandColsFrom(a Band) BandCols { + t := BandCols{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]float64, a.Cols*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m BandCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m BandCols) at(i, j int) float64 { + pj := i + m.KU - j + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[j*m.Stride+pj] +} +func (m BandCols) bandwidth() (kl, ku int) { return m.KL, m.KU } + +type band interface { + dims() (r, c int) + at(i, j int) float64 + bandwidth() (kl, ku int) +} + +func sameBand(a, b band) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + akl, aku := a.bandwidth() + bkl, bku := b.bandwidth() + if akl != bkl || aku != bku { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var bandTests = []Band{ + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 1, Data: []float64{ + 1, + 2, + 3, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []float64{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []float64{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 2, Data: []float64{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 2, Data: []float64{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 3, Data: []float64{ + -1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 3, Data: []float64{ + -1, 2, 3, + 4, 5, 6, + 7, 8, -2, + 9, -3, -4, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 4, Data: []float64{ + -2, -1, 3, 4, + -3, 5, 6, 7, + 8, 9, 10, 11, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 4, Data: []float64{ + -2, -1, 2, 3, + -3, 4, 5, 6, + 7, 8, 9, -4, + 10, 11, -5, -6, + }}, + + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 5, Data: []float64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []float64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []float64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 5, Data: []float64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 5, Data: []float64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 5, Data: []float64{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 5, Data: []float64{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, -2, 0, 0, + 9, -3, -4, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 5, Data: []float64{ + -2, -1, 3, 4, 0, + -3, 5, 6, 7, 0, + 8, 9, 10, 11, 0, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 5, Data: []float64{ + -2, -1, 2, 3, 0, + -3, 4, 5, 6, 0, + 7, 8, 9, -4, 0, + 10, 11, -5, -6, 0, + }}, +} + +func TestConvertBand(t *testing.T) { + for _, test := range bandTests { + colmajor := newBandColsFrom(test) + if !sameBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newBandFrom(colmajor) + if !sameBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularBandFrom(a TriangularBandCols) TriangularBand { + t := TriangularBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float64, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBand) n() (n int) { return m.N } +func (m TriangularBand) at(i, j int) float64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas64: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBand) bandwidth() (k int) { return m.K } +func (m TriangularBand) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBand) diag() blas.Diag { return m.Diag } + +func newTriangularBandColsFrom(a TriangularBand) TriangularBandCols { + t := TriangularBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]float64, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBandCols) n() (n int) { return m.N } +func (m TriangularBandCols) at(i, j int) float64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("blas64: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBandCols) bandwidth() (k int) { return m.K } +func (m TriangularBandCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBandCols) diag() blas.Diag { return m.Diag } + +type triangularBand interface { + n() (n int) + at(i, j int) float64 + bandwidth() (k int) + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangularBand(a, b triangularBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + if a.diag() != b.diag() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularBandTests = []TriangularBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []float64{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []float64{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []float64{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []float64{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []float64{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []float64{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []float64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []float64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []float64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []float64{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []float64{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []float64{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertTriBand(t *testing.T) { + for _, test := range triangularBandTests { + colmajor := newTriangularBandColsFrom(test) + if !sameTriangularBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularBandFrom(colmajor) + if !sameTriangularBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/blas64/doc.go b/vendor/gonum.org/v1/gonum/blas/blas64/doc.go new file mode 100644 index 00000000..92e588f8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/blas64/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package blas64 provides a simple interface to the float64 BLAS API. +package blas64 // import "gonum.org/v1/gonum/blas/blas64" diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/cblas128.go b/vendor/gonum.org/v1/gonum/blas/cblas128/cblas128.go new file mode 100644 index 00000000..9b463504 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/cblas128.go @@ -0,0 +1,507 @@ +// 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 cgo.Implementation. +func Use(b blas.Complex128) { + cblas128 = b +} + +// Implementation returns the current BLAS complex128 implementation. +// +// Implementation allows direct calls to the current the BLAS complex128 implementation +// giving finer control of parameters. +func Implementation() blas.Complex128 { + return cblas128 +} + +// Vector represents a vector with an associated element increment. +type Vector struct { + Inc int + Data []complex128 +} + +// General represents a matrix using the conventional storage scheme. +type General struct { + Rows, Cols int + Stride int + Data []complex128 +} + +// Band represents a band matrix using the band storage scheme. +type Band struct { + Rows, Cols int + KL, KU int + Stride int + Data []complex128 +} + +// Triangular represents a triangular matrix using the conventional storage scheme. +type Triangular struct { + N int + Stride int + Data []complex128 + Uplo blas.Uplo + Diag blas.Diag +} + +// TriangularBand represents a triangular matrix using the band storage scheme. +type TriangularBand struct { + N, K int + Stride int + Data []complex128 + Uplo blas.Uplo + Diag blas.Diag +} + +// TriangularPacked represents a triangular matrix using the packed storage scheme. +type TriangularPacked struct { + N int + Data []complex128 + Uplo blas.Uplo + Diag blas.Diag +} + +// Symmetric represents a symmetric matrix using the conventional storage scheme. +type Symmetric struct { + N int + Stride int + Data []complex128 + Uplo blas.Uplo +} + +// SymmetricBand represents a symmetric matrix using the band storage scheme. +type SymmetricBand struct { + N, K int + Stride int + Data []complex128 + Uplo blas.Uplo +} + +// SymmetricPacked represents a symmetric matrix using the packed storage scheme. +type SymmetricPacked struct { + N int + Data []complex128 + Uplo blas.Uplo +} + +// Hermitian represents an Hermitian matrix using the conventional storage scheme. +type Hermitian Symmetric + +// HermitianBand represents an Hermitian matrix using the band storage scheme. +type HermitianBand SymmetricBand + +// HermitianPacked represents an Hermitian matrix using the packed storage scheme. +type HermitianPacked SymmetricPacked + +// Level 1 + +const negInc = "cblas128: negative vector increment" + +// Dotu computes the dot product of the two vectors without +// complex conjugation: +// x^T * y. +func Dotu(n int, x, y Vector) complex128 { + return cblas128.Zdotu(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Dotc computes the dot product of the two vectors with +// complex conjugation: +// x^H * y. +func Dotc(n int, x, y Vector) complex128 { + return cblas128.Zdotc(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Nrm2 computes the Euclidean norm of the vector x: +// sqrt(\sum_i x[i] * x[i]). +// +// Nrm2 will panic if the vector increment is negative. +func Nrm2(n int, x Vector) float64 { + if x.Inc < 0 { + panic(negInc) + } + return cblas128.Dznrm2(n, x.Data, x.Inc) +} + +// Asum computes the sum of magnitudes of the real and imaginary parts of +// elements of the vector x: +// \sum_i (|Re x[i]| + |Im x[i]|). +// +// Asum will panic if the vector increment is negative. +func Asum(n int, x Vector) float64 { + if x.Inc < 0 { + panic(negInc) + } + return cblas128.Dzasum(n, x.Data, x.Inc) +} + +// Iamax returns the index of an element of x with the largest sum of +// magnitudes of the real and imaginary parts (|Re x[i]|+|Im x[i]|). +// If there are multiple such indices, the earliest is returned. +// +// Iamax returns -1 if n == 0. +// +// Iamax will panic if the vector increment is negative. +func Iamax(n int, x Vector) int { + if x.Inc < 0 { + panic(negInc) + } + return cblas128.Izamax(n, x.Data, x.Inc) +} + +// Swap exchanges the elements of two vectors: +// x[i], y[i] = y[i], x[i] for all i. +func Swap(n int, x, y Vector) { + cblas128.Zswap(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Copy copies the elements of x into the elements of y: +// y[i] = x[i] for all i. +func Copy(n int, x, y Vector) { + cblas128.Zcopy(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Axpy computes +// y = alpha * x + y, +// where x and y are vectors, and alpha is a scalar. +func Axpy(n int, alpha complex128, x, y Vector) { + cblas128.Zaxpy(n, alpha, x.Data, x.Inc, y.Data, y.Inc) +} + +// Scal computes +// x = alpha * x, +// where x is a vector, and alpha is a scalar. +// +// Scal will panic if the vector increment is negative. +func Scal(n int, alpha complex128, x Vector) { + if x.Inc < 0 { + panic(negInc) + } + cblas128.Zscal(n, alpha, x.Data, x.Inc) +} + +// Dscal computes +// x = alpha * x, +// where x is a vector, and alpha is a real scalar. +// +// Dscal will panic if the vector increment is negative. +func Dscal(n int, alpha float64, x Vector) { + if x.Inc < 0 { + panic(negInc) + } + cblas128.Zdscal(n, alpha, x.Data, x.Inc) +} + +// Level 2 + +// Gemv computes +// y = alpha * A * x + beta * y, if t == blas.NoTrans, +// y = alpha * A^T * x + beta * y, if t == blas.Trans, +// y = alpha * A^H * x + beta * y, if t == blas.ConjTrans, +// where A is an m×n dense matrix, x and y are vectors, and alpha and beta are +// scalars. +func Gemv(t blas.Transpose, alpha complex128, a General, x Vector, beta complex128, y Vector) { + cblas128.Zgemv(t, a.Rows, a.Cols, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Gbmv computes +// y = alpha * A * x + beta * y, if t == blas.NoTrans, +// y = alpha * A^T * x + beta * y, if t == blas.Trans, +// y = alpha * A^H * x + beta * y, if t == blas.ConjTrans, +// where A is an m×n band matrix, x and y are vectors, and alpha and beta are +// scalars. +func Gbmv(t blas.Transpose, alpha complex128, a Band, x Vector, beta complex128, y Vector) { + cblas128.Zgbmv(t, a.Rows, a.Cols, a.KL, a.KU, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Trmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans, +// x = A^H * x, if t == blas.ConjTrans, +// where A is an n×n triangular matrix, and x is a vector. +func Trmv(t blas.Transpose, a Triangular, x Vector) { + cblas128.Ztrmv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tbmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans, +// x = A^H * x, if t == blas.ConjTrans, +// where A is an n×n triangular band matrix, and x is a vector. +func Tbmv(t blas.Transpose, a TriangularBand, x Vector) { + cblas128.Ztbmv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tpmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans, +// x = A^H * x, if t == blas.ConjTrans, +// where A is an n×n triangular matrix in packed format, and x is a vector. +func Tpmv(t blas.Transpose, a TriangularPacked, x Vector) { + cblas128.Ztpmv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc) +} + +// Trsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans, +// A^H * x = b, if t == blas.ConjTrans, +// where A is an n×n triangular matrix and x is a vector. +// +// At entry to the function, x contains the values of b, and the result is +// stored in-place into x. +// +// No test for singularity or near-singularity is included in this +// routine. Such tests must be performed before calling this routine. +func Trsv(t blas.Transpose, a Triangular, x Vector) { + cblas128.Ztrsv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tbsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans, +// A^H * x = b, if t == blas.ConjTrans, +// where A is an n×n triangular band matrix, and x is a vector. +// +// At entry to the function, x contains the values of b, and the result is +// stored in-place into x. +// +// No test for singularity or near-singularity is included in this +// routine. Such tests must be performed before calling this routine. +func Tbsv(t blas.Transpose, a TriangularBand, x Vector) { + cblas128.Ztbsv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tpsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans, +// A^H * x = b, if t == blas.ConjTrans, +// where A is an n×n triangular matrix in packed format and x is a vector. +// +// At entry to the function, x contains the values of b, and the result is +// stored in-place into x. +// +// No test for singularity or near-singularity is included in this +// routine. Such tests must be performed before calling this routine. +func Tpsv(t blas.Transpose, a TriangularPacked, x Vector) { + cblas128.Ztpsv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc) +} + +// Hemv computes +// y = alpha * A * x + beta * y, +// where A is an n×n Hermitian matrix, x and y are vectors, and alpha and +// beta are scalars. +func Hemv(alpha complex128, a Hermitian, x Vector, beta complex128, y Vector) { + cblas128.Zhemv(a.Uplo, a.N, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Hbmv performs +// y = alpha * A * x + beta * y, +// where A is an n×n Hermitian band matrix, x and y are vectors, and alpha +// and beta are scalars. +func Hbmv(alpha complex128, a HermitianBand, x Vector, beta complex128, y Vector) { + cblas128.Zhbmv(a.Uplo, a.N, a.K, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Hpmv performs +// y = alpha * A * x + beta * y, +// where A is an n×n Hermitian matrix in packed format, x and y are vectors, +// and alpha and beta are scalars. +func Hpmv(alpha complex128, a HermitianPacked, x Vector, beta complex128, y Vector) { + cblas128.Zhpmv(a.Uplo, a.N, alpha, a.Data, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Geru performs a rank-1 update +// A += alpha * x * y^T, +// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar. +func Geru(alpha complex128, x, y Vector, a General) { + cblas128.Zgeru(a.Rows, a.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride) +} + +// Gerc performs a rank-1 update +// A += alpha * x * y^H, +// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar. +func Gerc(alpha complex128, x, y Vector, a General) { + cblas128.Zgerc(a.Rows, a.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride) +} + +// Her performs a rank-1 update +// A += alpha * x * y^T, +// where A is an m×n Hermitian matrix, x and y are vectors, and alpha is a scalar. +func Her(alpha float64, x Vector, a Hermitian) { + cblas128.Zher(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data, a.Stride) +} + +// Hpr performs a rank-1 update +// A += alpha * x * x^H, +// where A is an n×n Hermitian matrix in packed format, x is a vector, and +// alpha is a scalar. +func Hpr(alpha float64, x Vector, a HermitianPacked) { + cblas128.Zhpr(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data) +} + +// Her2 performs a rank-2 update +// A += alpha * x * y^H + conj(alpha) * y * x^H, +// where A is an n×n Hermitian matrix, x and y are vectors, and alpha is a scalar. +func Her2(alpha complex128, x, y Vector, a Hermitian) { + cblas128.Zher2(a.Uplo, a.N, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride) +} + +// Hpr2 performs a rank-2 update +// A += alpha * x * y^H + conj(alpha) * y * x^H, +// where A is an n×n Hermitian matrix in packed format, x and y are vectors, +// and alpha is a scalar. +func Hpr2(alpha complex128, x, y Vector, a HermitianPacked) { + cblas128.Zhpr2(a.Uplo, a.N, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data) +} + +// Level 3 + +// Gemm computes +// C = alpha * A * B + beta * C, +// where A, B, and C are dense matrices, and alpha and beta are scalars. +// tA and tB specify whether A or B are transposed or conjugated. +func Gemm(tA, tB blas.Transpose, alpha complex128, a, b General, beta complex128, c General) { + var m, n, k int + if tA == blas.NoTrans { + m, k = a.Rows, a.Cols + } else { + m, k = a.Cols, a.Rows + } + if tB == blas.NoTrans { + n = b.Cols + } else { + n = b.Rows + } + cblas128.Zgemm(tA, tB, m, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Symm performs +// C = alpha * A * B + beta * C, if s == blas.Left, +// C = alpha * B * A + beta * C, if s == blas.Right, +// where A is an n×n or m×m symmetric matrix, B and C are m×n matrices, and +// alpha and beta are scalars. +func Symm(s blas.Side, alpha complex128, a Symmetric, b General, beta complex128, c General) { + var m, n int + if s == blas.Left { + m, n = a.N, b.Cols + } else { + m, n = b.Rows, a.N + } + cblas128.Zsymm(s, a.Uplo, m, n, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Syrk performs a symmetric rank-k update +// C = alpha * A * A^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * A + beta * C, if t == blas.Trans, +// where C is an n×n symmetric matrix, A is an n×k matrix if t == blas.NoTrans +// and a k×n matrix otherwise, and alpha and beta are scalars. +func Syrk(t blas.Transpose, alpha complex128, a General, beta complex128, c Symmetric) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas128.Zsyrk(c.Uplo, t, n, k, alpha, a.Data, a.Stride, beta, c.Data, c.Stride) +} + +// Syr2k performs a symmetric rank-2k update +// C = alpha * A * B^T + alpha * B * A^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * B + alpha * B^T * A + beta * C, if t == blas.Trans, +// where C is an n×n symmetric matrix, A and B are n×k matrices if +// t == blas.NoTrans and k×n otherwise, and alpha and beta are scalars. +func Syr2k(t blas.Transpose, alpha complex128, a, b General, beta complex128, c Symmetric) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas128.Zsyr2k(c.Uplo, t, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Trmm performs +// B = alpha * A * B, if tA == blas.NoTrans and s == blas.Left, +// B = alpha * A^T * B, if tA == blas.Trans and s == blas.Left, +// B = alpha * A^H * B, if tA == blas.ConjTrans and s == blas.Left, +// B = alpha * B * A, if tA == blas.NoTrans and s == blas.Right, +// B = alpha * B * A^T, if tA == blas.Trans and s == blas.Right, +// B = alpha * B * A^H, if tA == blas.ConjTrans and s == blas.Right, +// where A is an n×n or m×m triangular matrix, B is an m×n matrix, and alpha is +// a scalar. +func Trmm(s blas.Side, tA blas.Transpose, alpha complex128, a Triangular, b General) { + cblas128.Ztrmm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride) +} + +// Trsm solves +// A * X = alpha * B, if tA == blas.NoTrans and s == blas.Left, +// A^T * X = alpha * B, if tA == blas.Trans and s == blas.Left, +// A^H * X = alpha * B, if tA == blas.ConjTrans and s == blas.Left, +// X * A = alpha * B, if tA == blas.NoTrans and s == blas.Right, +// X * A^T = alpha * B, if tA == blas.Trans and s == blas.Right, +// X * A^H = alpha * B, if tA == blas.ConjTrans and s == blas.Right, +// where A is an n×n or m×m triangular matrix, X and B are m×n matrices, and +// alpha is a scalar. +// +// At entry to the function, b contains the values of B, and the result is +// stored in-place into b. +// +// No check is made that A is invertible. +func Trsm(s blas.Side, tA blas.Transpose, alpha complex128, a Triangular, b General) { + cblas128.Ztrsm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride) +} + +// Hemm performs +// C = alpha * A * B + beta * C, if s == blas.Left, +// C = alpha * B * A + beta * C, if s == blas.Right, +// where A is an n×n or m×m Hermitian matrix, B and C are m×n matrices, and +// alpha and beta are scalars. +func Hemm(s blas.Side, alpha complex128, a Hermitian, b General, beta complex128, c General) { + var m, n int + if s == blas.Left { + m, n = a.N, b.Cols + } else { + m, n = b.Rows, a.N + } + cblas128.Zhemm(s, a.Uplo, m, n, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Herk performs the Hermitian rank-k update +// C = alpha * A * A^H + beta*C, if t == blas.NoTrans, +// C = alpha * A^H * A + beta*C, if t == blas.ConjTrans, +// where C is an n×n Hermitian matrix, A is an n×k matrix if t == blas.NoTrans +// and a k×n matrix otherwise, and alpha and beta are scalars. +func Herk(t blas.Transpose, alpha float64, a General, beta float64, c Hermitian) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas128.Zherk(c.Uplo, t, n, k, alpha, a.Data, a.Stride, beta, c.Data, c.Stride) +} + +// Her2k performs the Hermitian rank-2k update +// C = alpha * A * B^H + conj(alpha) * B * A^H + beta * C, if t == blas.NoTrans, +// C = alpha * A^H * B + conj(alpha) * B^H * A + beta * C, if t == blas.ConjTrans, +// where C is an n×n Hermitian matrix, A and B are n×k matrices if t == NoTrans +// and k×n matrices otherwise, and alpha and beta are scalars. +func Her2k(t blas.Transpose, alpha complex128, a, b General, beta float64, c Hermitian) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas128.Zher2k(c.Uplo, t, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/conv.go b/vendor/gonum.org/v1/gonum/blas/cblas128/conv.go new file mode 100644 index 00000000..cb62b7be --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/conv.go @@ -0,0 +1,279 @@ +// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT. + +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cblas128 + +import "gonum.org/v1/gonum/blas" + +// GeneralCols represents a matrix using the conventional column-major storage scheme. +type GeneralCols General + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions as a and have adequate backing +// data storage. +func (t GeneralCols) From(a General) { + if t.Rows != a.Rows || t.Cols != a.Cols { + panic("cblas128: mismatched dimension") + } + if len(t.Data) < (t.Cols-1)*t.Stride+t.Rows { + panic("cblas128: short data slice") + } + for i := 0; i < a.Rows; i++ { + for j, v := range a.Data[i*a.Stride : i*a.Stride+a.Cols] { + t.Data[i+j*t.Stride] = v + } + } +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions as a and have adequate backing +// data storage. +func (t General) From(a GeneralCols) { + if t.Rows != a.Rows || t.Cols != a.Cols { + panic("cblas128: mismatched dimension") + } + if len(t.Data) < (t.Rows-1)*t.Stride+t.Cols { + panic("cblas128: short data slice") + } + for j := 0; j < a.Cols; j++ { + for i, v := range a.Data[j*a.Stride : j*a.Stride+a.Rows] { + t.Data[i*t.Stride+j] = v + } + } +} + +// TriangularCols represents a matrix using the conventional column-major storage scheme. +type TriangularCols Triangular + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, uplo and diag as a and have +// adequate backing data storage. +func (t TriangularCols) From(a Triangular) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas128: mismatched BLAS diag") + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + for i := 0; i < a.N; i++ { + for j := i; j < a.N; j++ { + t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j] + } + } + case blas.Lower: + for i := 0; i < a.N; i++ { + for j := 0; j <= i; j++ { + t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j] + } + } + case blas.All: + for i := 0; i < a.N; i++ { + for j := 0; j < a.N; j++ { + t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j] + } + } + } +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, uplo and diag as a and have +// adequate backing data storage. +func (t Triangular) From(a TriangularCols) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas128: mismatched BLAS diag") + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + for i := 0; i < a.N; i++ { + for j := i; j < a.N; j++ { + t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride] + } + } + case blas.Lower: + for i := 0; i < a.N; i++ { + for j := 0; j <= i; j++ { + t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride] + } + } + case blas.All: + for i := 0; i < a.N; i++ { + for j := 0; j < a.N; j++ { + t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride] + } + } + } +} + +// BandCols represents a matrix using the band column-major storage scheme. +type BandCols Band + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions and bandwidth as a and have +// adequate backing data storage. +func (t BandCols) From(a Band) { + if t.Rows != a.Rows || t.Cols != a.Cols { + panic("cblas128: mismatched dimension") + } + if t.KL != a.KL || t.KU != a.KU { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.KL+a.KU+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.KL+t.KU+1 { + panic("cblas128: short stride for destination") + } + for i := 0; i < a.Rows; i++ { + for j := max(0, i-a.KL); j < min(i+a.KU+1, a.Cols); j++ { + t.Data[i+t.KU-j+j*t.Stride] = a.Data[j+a.KL-i+i*a.Stride] + } + } +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions and bandwidth as a and have +// adequate backing data storage. +func (t Band) From(a BandCols) { + if t.Rows != a.Rows || t.Cols != a.Cols { + panic("cblas128: mismatched dimension") + } + if t.KL != a.KL || t.KU != a.KU { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.KL+a.KU+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.KL+t.KU+1 { + panic("cblas128: short stride for destination") + } + for j := 0; j < a.Cols; j++ { + for i := max(0, j-a.KU); i < min(j+a.KL+1, a.Rows); i++ { + t.Data[j+a.KL-i+i*a.Stride] = a.Data[i+t.KU-j+j*t.Stride] + } + } +} + +// TriangularBandCols represents a symmetric matrix using the band column-major storage scheme. +type TriangularBandCols TriangularBand + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t TriangularBandCols) From(a TriangularBand) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.K != a.K { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas128: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas128: mismatched BLAS diag") + } + dst := BandCols{ + Rows: t.N, Cols: t.N, + Stride: t.Stride, + Data: t.Data, + } + src := Band{ + Rows: a.N, Cols: a.N, + Stride: a.Stride, + Data: a.Data, + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + dst.KU = t.K + src.KU = a.K + case blas.Lower: + dst.KL = t.K + src.KL = a.K + } + dst.From(src) +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t TriangularBand) From(a TriangularBandCols) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.K != a.K { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas128: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas128: mismatched BLAS diag") + } + dst := Band{ + Rows: t.N, Cols: t.N, + Stride: t.Stride, + Data: t.Data, + } + src := BandCols{ + Rows: a.N, Cols: a.N, + Stride: a.Stride, + Data: a.Data, + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + dst.KU = t.K + src.KU = a.K + case blas.Lower: + dst.KL = t.K + src.KL = a.K + } + dst.From(src) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian.go b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian.go new file mode 100644 index 00000000..455668a3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian.go @@ -0,0 +1,155 @@ +// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT. + +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cblas128 + +import "gonum.org/v1/gonum/blas" + +// HermitianCols represents a matrix using the conventional column-major storage scheme. +type HermitianCols Hermitian + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions and uplo as a and have adequate +// backing data storage. +func (t HermitianCols) From(a Hermitian) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + for i := 0; i < a.N; i++ { + for j := i; j < a.N; j++ { + t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j] + } + } + case blas.Lower: + for i := 0; i < a.N; i++ { + for j := 0; j <= i; j++ { + t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j] + } + } + } +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions and uplo as a and have adequate +// backing data storage. +func (t Hermitian) From(a HermitianCols) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + for i := 0; i < a.N; i++ { + for j := i; j < a.N; j++ { + t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride] + } + } + case blas.Lower: + for i := 0; i < a.N; i++ { + for j := 0; j <= i; j++ { + t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride] + } + } + } +} + +// HermitianBandCols represents an Hermitian matrix using the band column-major storage scheme. +type HermitianBandCols HermitianBand + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t HermitianBandCols) From(a HermitianBand) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.K != a.K { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas128: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + dst := BandCols{ + Rows: t.N, Cols: t.N, + Stride: t.Stride, + Data: t.Data, + } + src := Band{ + Rows: a.N, Cols: a.N, + Stride: a.Stride, + Data: a.Data, + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + dst.KU = t.K + src.KU = a.K + case blas.Lower: + dst.KL = t.K + src.KL = a.K + } + dst.From(src) +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t HermitianBand) From(a HermitianBandCols) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.K != a.K { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas128: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + dst := Band{ + Rows: t.N, Cols: t.N, + Stride: t.Stride, + Data: t.Data, + } + src := BandCols{ + Rows: a.N, Cols: a.N, + Stride: a.Stride, + Data: a.Data, + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + dst.KU = t.K + src.KU = a.K + case blas.Lower: + dst.KL = t.K + src.KL = a.K + } + dst.From(src) +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian_test.go b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian_test.go new file mode 100644 index 00000000..21bd3cbf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian_test.go @@ -0,0 +1,307 @@ +// 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 ( + math "math/cmplx" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newHermitianFrom(a HermitianCols) Hermitian { + t := Hermitian{ + N: a.N, + Stride: a.N, + Data: make([]complex128, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Hermitian) n() int { return m.N } +func (m Hermitian) at(i, j int) complex128 { + if m.Uplo == blas.Lower && i < j && j < m.N { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j { + i, j = j, i + } + return m.Data[i*m.Stride+j] +} +func (m Hermitian) uplo() blas.Uplo { return m.Uplo } + +func newHermitianColsFrom(a Hermitian) HermitianCols { + t := HermitianCols{ + N: a.N, + Stride: a.N, + Data: make([]complex128, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m HermitianCols) n() int { return m.N } +func (m HermitianCols) at(i, j int) complex128 { + if m.Uplo == blas.Lower && i < j { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j && i < m.N { + i, j = j, i + } + return m.Data[i+j*m.Stride] +} +func (m HermitianCols) uplo() blas.Uplo { return m.Uplo } + +type hermitian interface { + n() int + at(i, j int) complex128 + uplo() blas.Uplo +} + +func sameHermitian(a, b hermitian) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var hermitianTests = []Hermitian{ + {N: 3, Stride: 3, Data: []complex128{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertHermitian(t *testing.T) { + for _, test := range hermitianTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + test.Uplo = uplo + colmajor := newHermitianColsFrom(test) + if !sameHermitian(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newHermitianFrom(colmajor) + if !sameHermitian(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } +} +func newHermitianBandFrom(a HermitianBandCols) HermitianBand { + t := HermitianBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex128, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m HermitianBand) n() (n int) { return m.N } +func (m HermitianBand) at(i, j int) complex128 { + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m HermitianBand) bandwidth() (k int) { return m.K } +func (m HermitianBand) uplo() blas.Uplo { return m.Uplo } + +func newHermitianBandColsFrom(a HermitianBand) HermitianBandCols { + t := HermitianBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex128, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m HermitianBandCols) n() (n int) { return m.N } +func (m HermitianBandCols) at(i, j int) complex128 { + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m HermitianBandCols) bandwidth() (k int) { return m.K } +func (m HermitianBandCols) uplo() blas.Uplo { return m.Uplo } + +type hermitianBand interface { + n() (n int) + at(i, j int) complex128 + bandwidth() (k int) + uplo() blas.Uplo +} + +func sameHermitianBand(a, b hermitianBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var hermitianBandTests = []HermitianBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []complex128{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []complex128{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []complex128{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []complex128{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []complex128{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertHermBand(t *testing.T) { + for _, test := range hermitianBandTests { + colmajor := newHermitianBandColsFrom(test) + if !sameHermitianBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newHermitianBandFrom(colmajor) + if !sameHermitianBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric.go b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric.go new file mode 100644 index 00000000..ad5e0a65 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric.go @@ -0,0 +1,155 @@ +// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT. + +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cblas128 + +import "gonum.org/v1/gonum/blas" + +// SymmetricCols represents a matrix using the conventional column-major storage scheme. +type SymmetricCols Symmetric + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions and uplo as a and have adequate +// backing data storage. +func (t SymmetricCols) From(a Symmetric) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + for i := 0; i < a.N; i++ { + for j := i; j < a.N; j++ { + t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j] + } + } + case blas.Lower: + for i := 0; i < a.N; i++ { + for j := 0; j <= i; j++ { + t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j] + } + } + } +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions and uplo as a and have adequate +// backing data storage. +func (t Symmetric) From(a SymmetricCols) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + for i := 0; i < a.N; i++ { + for j := i; j < a.N; j++ { + t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride] + } + } + case blas.Lower: + for i := 0; i < a.N; i++ { + for j := 0; j <= i; j++ { + t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride] + } + } + } +} + +// SymmetricBandCols represents a symmetric matrix using the band column-major storage scheme. +type SymmetricBandCols SymmetricBand + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t SymmetricBandCols) From(a SymmetricBand) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.K != a.K { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas128: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + dst := BandCols{ + Rows: t.N, Cols: t.N, + Stride: t.Stride, + Data: t.Data, + } + src := Band{ + Rows: a.N, Cols: a.N, + Stride: a.Stride, + Data: a.Data, + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + dst.KU = t.K + src.KU = a.K + case blas.Lower: + dst.KL = t.K + src.KL = a.K + } + dst.From(src) +} + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t SymmetricBand) From(a SymmetricBandCols) { + if t.N != a.N { + panic("cblas128: mismatched dimension") + } + if t.K != a.K { + panic("cblas128: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas128: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas128: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas128: mismatched BLAS uplo") + } + dst := Band{ + Rows: t.N, Cols: t.N, + Stride: t.Stride, + Data: t.Data, + } + src := BandCols{ + Rows: a.N, Cols: a.N, + Stride: a.Stride, + Data: a.Data, + } + switch a.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + dst.KU = t.K + src.KU = a.K + case blas.Lower: + dst.KL = t.K + src.KL = a.K + } + dst.From(src) +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric_test.go b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric_test.go new file mode 100644 index 00000000..eef76f4a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric_test.go @@ -0,0 +1,307 @@ +// 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 ( + math "math/cmplx" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newSymmetricFrom(a SymmetricCols) Symmetric { + t := Symmetric{ + N: a.N, + Stride: a.N, + Data: make([]complex128, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Symmetric) n() int { return m.N } +func (m Symmetric) at(i, j int) complex128 { + if m.Uplo == blas.Lower && i < j && j < m.N { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j { + i, j = j, i + } + return m.Data[i*m.Stride+j] +} +func (m Symmetric) uplo() blas.Uplo { return m.Uplo } + +func newSymmetricColsFrom(a Symmetric) SymmetricCols { + t := SymmetricCols{ + N: a.N, + Stride: a.N, + Data: make([]complex128, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m SymmetricCols) n() int { return m.N } +func (m SymmetricCols) at(i, j int) complex128 { + if m.Uplo == blas.Lower && i < j { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j && i < m.N { + i, j = j, i + } + return m.Data[i+j*m.Stride] +} +func (m SymmetricCols) uplo() blas.Uplo { return m.Uplo } + +type symmetric interface { + n() int + at(i, j int) complex128 + uplo() blas.Uplo +} + +func sameSymmetric(a, b symmetric) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var symmetricTests = []Symmetric{ + {N: 3, Stride: 3, Data: []complex128{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertSymmetric(t *testing.T) { + for _, test := range symmetricTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + test.Uplo = uplo + colmajor := newSymmetricColsFrom(test) + if !sameSymmetric(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newSymmetricFrom(colmajor) + if !sameSymmetric(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } +} +func newSymmetricBandFrom(a SymmetricBandCols) SymmetricBand { + t := SymmetricBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex128, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m SymmetricBand) n() (n int) { return m.N } +func (m SymmetricBand) at(i, j int) complex128 { + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m SymmetricBand) bandwidth() (k int) { return m.K } +func (m SymmetricBand) uplo() blas.Uplo { return m.Uplo } + +func newSymmetricBandColsFrom(a SymmetricBand) SymmetricBandCols { + t := SymmetricBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex128, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m SymmetricBandCols) n() (n int) { return m.N } +func (m SymmetricBandCols) at(i, j int) complex128 { + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m SymmetricBandCols) bandwidth() (k int) { return m.K } +func (m SymmetricBandCols) uplo() blas.Uplo { return m.Uplo } + +type symmetricBand interface { + n() (n int) + at(i, j int) complex128 + bandwidth() (k int) + uplo() blas.Uplo +} + +func sameSymmetricBand(a, b symmetricBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var symmetricBandTests = []SymmetricBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []complex128{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []complex128{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []complex128{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []complex128{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []complex128{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertSymBand(t *testing.T) { + for _, test := range symmetricBandTests { + colmajor := newSymmetricBandColsFrom(test) + if !sameSymmetricBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newSymmetricBandFrom(colmajor) + if !sameSymmetricBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/conv_test.go b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_test.go new file mode 100644 index 00000000..8d25fd28 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/conv_test.go @@ -0,0 +1,620 @@ +// 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 ( + math "math/cmplx" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newGeneralFrom(a GeneralCols) General { + t := General{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Cols, + Data: make([]complex128, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m General) dims() (r, c int) { return m.Rows, m.Cols } +func (m General) at(i, j int) complex128 { return m.Data[i*m.Stride+j] } + +func newGeneralColsFrom(a General) GeneralCols { + t := GeneralCols{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Rows, + Data: make([]complex128, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m GeneralCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m GeneralCols) at(i, j int) complex128 { return m.Data[i+j*m.Stride] } + +type general interface { + dims() (r, c int) + at(i, j int) complex128 +} + +func sameGeneral(a, b general) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var generalTests = []General{ + {Rows: 2, Cols: 3, Stride: 3, Data: []complex128{ + 1, 2, 3, + 4, 5, 6, + }}, + {Rows: 3, Cols: 2, Stride: 2, Data: []complex128{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 3, Stride: 3, Data: []complex128{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 2, Cols: 3, Stride: 5, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + }}, + {Rows: 3, Cols: 2, Stride: 5, Data: []complex128{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, Stride: 5, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertGeneral(t *testing.T) { + for _, test := range generalTests { + colmajor := newGeneralColsFrom(test) + if !sameGeneral(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newGeneralFrom(colmajor) + if !sameGeneral(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularFrom(a TriangularCols) Triangular { + t := Triangular{ + N: a.N, + Stride: a.N, + Data: make([]complex128, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Triangular) n() int { return m.N } +func (m Triangular) at(i, j int) complex128 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j && j < m.N { + return 0 + } + if m.Uplo == blas.Upper && i > j { + return 0 + } + return m.Data[i*m.Stride+j] +} +func (m Triangular) uplo() blas.Uplo { return m.Uplo } +func (m Triangular) diag() blas.Diag { return m.Diag } + +func newTriangularColsFrom(a Triangular) TriangularCols { + t := TriangularCols{ + N: a.N, + Stride: a.N, + Data: make([]complex128, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m TriangularCols) n() int { return m.N } +func (m TriangularCols) at(i, j int) complex128 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j { + return 0 + } + if m.Uplo == blas.Upper && i > j && i < m.N { + return 0 + } + return m.Data[i+j*m.Stride] +} +func (m TriangularCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularCols) diag() blas.Diag { return m.Diag } + +type triangular interface { + n() int + at(i, j int) complex128 + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangular(a, b triangular) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularTests = []Triangular{ + {N: 3, Stride: 3, Data: []complex128{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertTriangular(t *testing.T) { + for _, test := range triangularTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower, blas.All} { + for _, diag := range []blas.Diag{blas.Unit, blas.NonUnit} { + test.Uplo = uplo + test.Diag = diag + colmajor := newTriangularColsFrom(test) + if !sameTriangular(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularFrom(colmajor) + if !sameTriangular(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } + } +} + +func newBandFrom(a BandCols) Band { + t := Band{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]complex128, a.Rows*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m Band) dims() (r, c int) { return m.Rows, m.Cols } +func (m Band) at(i, j int) complex128 { + pj := j + m.KL - i + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[i*m.Stride+pj] +} +func (m Band) bandwidth() (kl, ku int) { return m.KL, m.KU } + +func newBandColsFrom(a Band) BandCols { + t := BandCols{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]complex128, a.Cols*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m BandCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m BandCols) at(i, j int) complex128 { + pj := i + m.KU - j + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[j*m.Stride+pj] +} +func (m BandCols) bandwidth() (kl, ku int) { return m.KL, m.KU } + +type band interface { + dims() (r, c int) + at(i, j int) complex128 + bandwidth() (kl, ku int) +} + +func sameBand(a, b band) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + akl, aku := a.bandwidth() + bkl, bku := b.bandwidth() + if akl != bkl || aku != bku { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var bandTests = []Band{ + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 1, Data: []complex128{ + 1, + 2, + 3, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []complex128{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []complex128{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 2, Data: []complex128{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 2, Data: []complex128{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 3, Data: []complex128{ + -1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 3, Data: []complex128{ + -1, 2, 3, + 4, 5, 6, + 7, 8, -2, + 9, -3, -4, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 4, Data: []complex128{ + -2, -1, 3, 4, + -3, 5, 6, 7, + 8, 9, 10, 11, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 4, Data: []complex128{ + -2, -1, 2, 3, + -3, 4, 5, 6, + 7, 8, 9, -4, + 10, 11, -5, -6, + }}, + + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 5, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 5, Data: []complex128{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 5, Data: []complex128{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 5, Data: []complex128{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 5, Data: []complex128{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, -2, 0, 0, + 9, -3, -4, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 5, Data: []complex128{ + -2, -1, 3, 4, 0, + -3, 5, 6, 7, 0, + 8, 9, 10, 11, 0, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 5, Data: []complex128{ + -2, -1, 2, 3, 0, + -3, 4, 5, 6, 0, + 7, 8, 9, -4, 0, + 10, 11, -5, -6, 0, + }}, +} + +func TestConvertBand(t *testing.T) { + for _, test := range bandTests { + colmajor := newBandColsFrom(test) + if !sameBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newBandFrom(colmajor) + if !sameBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularBandFrom(a TriangularBandCols) TriangularBand { + t := TriangularBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex128, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBand) n() (n int) { return m.N } +func (m TriangularBand) at(i, j int) complex128 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBand) bandwidth() (k int) { return m.K } +func (m TriangularBand) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBand) diag() blas.Diag { return m.Diag } + +func newTriangularBandColsFrom(a TriangularBand) TriangularBandCols { + t := TriangularBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex128, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBandCols) n() (n int) { return m.N } +func (m TriangularBandCols) at(i, j int) complex128 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas128: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBandCols) bandwidth() (k int) { return m.K } +func (m TriangularBandCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBandCols) diag() blas.Diag { return m.Diag } + +type triangularBand interface { + n() (n int) + at(i, j int) complex128 + bandwidth() (k int) + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangularBand(a, b triangularBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + if a.diag() != b.diag() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularBandTests = []TriangularBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []complex128{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []complex128{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []complex128{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []complex128{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []complex128{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []complex128{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []complex128{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertTriBand(t *testing.T) { + for _, test := range triangularBandTests { + colmajor := newTriangularBandColsFrom(test) + if !sameTriangularBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularBandFrom(colmajor) + if !sameTriangularBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas128/doc.go b/vendor/gonum.org/v1/gonum/blas/cblas128/doc.go new file mode 100644 index 00000000..15398184 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas128/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cblas128 provides a simple interface to the complex128 BLAS API. +package cblas128 // import "gonum.org/v1/gonum/blas/cblas128" diff --git a/vendor/gonum.org/v1/gonum/blas/cblas64/cblas64.go b/vendor/gonum.org/v1/gonum/blas/cblas64/cblas64.go new file mode 100644 index 00000000..6164d479 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas64/cblas64.go @@ -0,0 +1,507 @@ +// 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 cblas64 + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/gonum" +) + +var cblas64 blas.Complex64 = gonum.Implementation{} + +// Use sets the BLAS complex64 implementation to be used by subsequent BLAS calls. +// The default implementation is cgo.Implementation. +func Use(b blas.Complex64) { + cblas64 = b +} + +// Implementation returns the current BLAS complex64 implementation. +// +// Implementation allows direct calls to the current the BLAS complex64 implementation +// giving finer control of parameters. +func Implementation() blas.Complex64 { + return cblas64 +} + +// Vector represents a vector with an associated element increment. +type Vector struct { + Inc int + Data []complex64 +} + +// General represents a matrix using the conventional storage scheme. +type General struct { + Rows, Cols int + Stride int + Data []complex64 +} + +// Band represents a band matrix using the band storage scheme. +type Band struct { + Rows, Cols int + KL, KU int + Stride int + Data []complex64 +} + +// Triangular represents a triangular matrix using the conventional storage scheme. +type Triangular struct { + N int + Stride int + Data []complex64 + 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 []complex64 + Uplo blas.Uplo + Diag blas.Diag +} + +// TriangularPacked represents a triangular matrix using the packed storage scheme. +type TriangularPacked struct { + N int + Data []complex64 + Uplo blas.Uplo + Diag blas.Diag +} + +// Symmetric represents a symmetric matrix using the conventional storage scheme. +type Symmetric struct { + N int + Stride int + Data []complex64 + Uplo blas.Uplo +} + +// SymmetricBand represents a symmetric matrix using the band storage scheme. +type SymmetricBand struct { + N, K int + Stride int + Data []complex64 + Uplo blas.Uplo +} + +// SymmetricPacked represents a symmetric matrix using the packed storage scheme. +type SymmetricPacked struct { + N int + Data []complex64 + 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 = "cblas64: negative vector increment" + +// Dotu computes the dot product of the two vectors without +// complex conjugation: +// x^T * y +func Dotu(n int, x, y Vector) complex64 { + return cblas64.Cdotu(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Dotc computes the dot product of the two vectors with +// complex conjugation: +// x^H * y. +func Dotc(n int, x, y Vector) complex64 { + return cblas64.Cdotc(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Nrm2 computes the Euclidean norm of the vector x: +// sqrt(\sum_i x[i] * x[i]). +// +// Nrm2 will panic if the vector increment is negative. +func Nrm2(n int, x Vector) float32 { + if x.Inc < 0 { + panic(negInc) + } + return cblas64.Scnrm2(n, x.Data, x.Inc) +} + +// Asum computes the sum of magnitudes of the real and imaginary parts of +// elements of the vector x: +// \sum_i (|Re x[i]| + |Im x[i]|). +// +// Asum will panic if the vector increment is negative. +func Asum(n int, x Vector) float32 { + if x.Inc < 0 { + panic(negInc) + } + return cblas64.Scasum(n, x.Data, x.Inc) +} + +// Iamax returns the index of an element of x with the largest sum of +// magnitudes of the real and imaginary parts (|Re x[i]|+|Im x[i]|). +// If there are multiple such indices, the earliest is returned. +// +// Iamax returns -1 if n == 0. +// +// Iamax will panic if the vector increment is negative. +func Iamax(n int, x Vector) int { + if x.Inc < 0 { + panic(negInc) + } + return cblas64.Icamax(n, x.Data, x.Inc) +} + +// Swap exchanges the elements of two vectors: +// x[i], y[i] = y[i], x[i] for all i. +func Swap(n int, x, y Vector) { + cblas64.Cswap(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Copy copies the elements of x into the elements of y: +// y[i] = x[i] for all i. +func Copy(n int, x, y Vector) { + cblas64.Ccopy(n, x.Data, x.Inc, y.Data, y.Inc) +} + +// Axpy computes +// y = alpha * x + y, +// where x and y are vectors, and alpha is a scalar. +func Axpy(n int, alpha complex64, x, y Vector) { + cblas64.Caxpy(n, alpha, x.Data, x.Inc, y.Data, y.Inc) +} + +// Scal computes +// x = alpha * x, +// where x is a vector, and alpha is a scalar. +// +// Scal will panic if the vector increment is negative. +func Scal(n int, alpha complex64, x Vector) { + if x.Inc < 0 { + panic(negInc) + } + cblas64.Cscal(n, alpha, x.Data, x.Inc) +} + +// Dscal computes +// x = alpha * x, +// where x is a vector, and alpha is a real scalar. +// +// Dscal will panic if the vector increment is negative. +func Dscal(n int, alpha float32, x Vector) { + if x.Inc < 0 { + panic(negInc) + } + cblas64.Csscal(n, alpha, x.Data, x.Inc) +} + +// Level 2 + +// Gemv computes +// y = alpha * A * x + beta * y, if t == blas.NoTrans, +// y = alpha * A^T * x + beta * y, if t == blas.Trans, +// y = alpha * A^H * x + beta * y, if t == blas.ConjTrans, +// where A is an m×n dense matrix, x and y are vectors, and alpha and beta are +// scalars. +func Gemv(t blas.Transpose, alpha complex64, a General, x Vector, beta complex64, y Vector) { + cblas64.Cgemv(t, a.Rows, a.Cols, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Gbmv computes +// y = alpha * A * x + beta * y, if t == blas.NoTrans, +// y = alpha * A^T * x + beta * y, if t == blas.Trans, +// y = alpha * A^H * x + beta * y, if t == blas.ConjTrans, +// where A is an m×n band matrix, x and y are vectors, and alpha and beta are +// scalars. +func Gbmv(t blas.Transpose, alpha complex64, a Band, x Vector, beta complex64, y Vector) { + cblas64.Cgbmv(t, a.Rows, a.Cols, a.KL, a.KU, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Trmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans, +// x = A^H * x, if t == blas.ConjTrans, +// where A is an n×n triangular matrix, and x is a vector. +func Trmv(t blas.Transpose, a Triangular, x Vector) { + cblas64.Ctrmv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tbmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans, +// x = A^H * x, if t == blas.ConjTrans, +// where A is an n×n triangular band matrix, and x is a vector. +func Tbmv(t blas.Transpose, a TriangularBand, x Vector) { + cblas64.Ctbmv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tpmv computes +// x = A * x, if t == blas.NoTrans, +// x = A^T * x, if t == blas.Trans, +// x = A^H * x, if t == blas.ConjTrans, +// where A is an n×n triangular matrix in packed format, and x is a vector. +func Tpmv(t blas.Transpose, a TriangularPacked, x Vector) { + cblas64.Ctpmv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc) +} + +// Trsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans, +// A^H * x = b, if t == blas.ConjTrans, +// where A is an n×n triangular matrix and x is a vector. +// +// At entry to the function, x contains the values of b, and the result is +// stored in-place into x. +// +// No test for singularity or near-singularity is included in this +// routine. Such tests must be performed before calling this routine. +func Trsv(t blas.Transpose, a Triangular, x Vector) { + cblas64.Ctrsv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tbsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans, +// A^H * x = b, if t == blas.ConjTrans, +// where A is an n×n triangular band matrix, and x is a vector. +// +// At entry to the function, x contains the values of b, and the result is +// stored in-place into x. +// +// No test for singularity or near-singularity is included in this +// routine. Such tests must be performed before calling this routine. +func Tbsv(t blas.Transpose, a TriangularBand, x Vector) { + cblas64.Ctbsv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc) +} + +// Tpsv solves +// A * x = b, if t == blas.NoTrans, +// A^T * x = b, if t == blas.Trans, +// A^H * x = b, if t == blas.ConjTrans, +// where A is an n×n triangular matrix in packed format and x is a vector. +// +// At entry to the function, x contains the values of b, and the result is +// stored in-place into x. +// +// No test for singularity or near-singularity is included in this +// routine. Such tests must be performed before calling this routine. +func Tpsv(t blas.Transpose, a TriangularPacked, x Vector) { + cblas64.Ctpsv(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 complex64, a Hermitian, x Vector, beta complex64, y Vector) { + cblas64.Chemv(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 complex64, a HermitianBand, x Vector, beta complex64, y Vector) { + cblas64.Chbmv(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 complex64, a HermitianPacked, x Vector, beta complex64, y Vector) { + cblas64.Chpmv(a.Uplo, a.N, alpha, a.Data, x.Data, x.Inc, beta, y.Data, y.Inc) +} + +// Geru performs a rank-1 update +// A += alpha * x * y^T, +// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar. +func Geru(alpha complex64, x, y Vector, a General) { + cblas64.Cgeru(a.Rows, a.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride) +} + +// Gerc performs a rank-1 update +// A += alpha * x * y^H, +// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar. +func Gerc(alpha complex64, x, y Vector, a General) { + cblas64.Cgerc(a.Rows, a.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride) +} + +// Her performs a rank-1 update +// A += alpha * x * y^T, +// where A is an m×n Hermitian matrix, x and y are vectors, and alpha is a scalar. +func Her(alpha float32, x Vector, a Hermitian) { + cblas64.Cher(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data, a.Stride) +} + +// Hpr performs a rank-1 update +// A += alpha * x * x^H, +// where A is an n×n Hermitian matrix in packed format, x is a vector, and +// alpha is a scalar. +func Hpr(alpha float32, x Vector, a HermitianPacked) { + cblas64.Chpr(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data) +} + +// Her2 performs a rank-2 update +// A += alpha * x * y^H + conj(alpha) * y * x^H, +// where A is an n×n Hermitian matrix, x and y are vectors, and alpha is a scalar. +func Her2(alpha complex64, x, y Vector, a Hermitian) { + cblas64.Cher2(a.Uplo, a.N, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride) +} + +// Hpr2 performs a rank-2 update +// A += alpha * x * y^H + conj(alpha) * y * x^H, +// where A is an n×n Hermitian matrix in packed format, x and y are vectors, +// and alpha is a scalar. +func Hpr2(alpha complex64, x, y Vector, a HermitianPacked) { + cblas64.Chpr2(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 complex64, a, b General, beta complex64, 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 + } + cblas64.Cgemm(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 complex64, a Symmetric, b General, beta complex64, c General) { + var m, n int + if s == blas.Left { + m, n = a.N, b.Cols + } else { + m, n = b.Rows, a.N + } + cblas64.Csymm(s, a.Uplo, m, n, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Syrk performs a symmetric rank-k update +// C = alpha * A * A^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * A + beta * C, if t == blas.Trans, +// where C is an n×n symmetric matrix, A is an n×k matrix if t == blas.NoTrans +// and a k×n matrix otherwise, and alpha and beta are scalars. +func Syrk(t blas.Transpose, alpha complex64, a General, beta complex64, c Symmetric) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas64.Csyrk(c.Uplo, t, n, k, alpha, a.Data, a.Stride, beta, c.Data, c.Stride) +} + +// Syr2k performs a symmetric rank-2k update +// C = alpha * A * B^T + alpha * B * A^T + beta * C, if t == blas.NoTrans, +// C = alpha * A^T * B + alpha * B^T * A + beta * C, if t == blas.Trans, +// where C is an n×n symmetric matrix, A and B are n×k matrices if +// t == blas.NoTrans and k×n otherwise, and alpha and beta are scalars. +func Syr2k(t blas.Transpose, alpha complex64, a, b General, beta complex64, c Symmetric) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas64.Csyr2k(c.Uplo, t, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Trmm performs +// B = alpha * A * B, if tA == blas.NoTrans and s == blas.Left, +// B = alpha * A^T * B, if tA == blas.Trans and s == blas.Left, +// B = alpha * A^H * B, if tA == blas.ConjTrans and s == blas.Left, +// B = alpha * B * A, if tA == blas.NoTrans and s == blas.Right, +// B = alpha * B * A^T, if tA == blas.Trans and s == blas.Right, +// B = alpha * B * A^H, if tA == blas.ConjTrans and s == blas.Right, +// where A is an n×n or m×m triangular matrix, B is an m×n matrix, and alpha is +// a scalar. +func Trmm(s blas.Side, tA blas.Transpose, alpha complex64, a Triangular, b General) { + cblas64.Ctrmm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride) +} + +// Trsm solves +// A * X = alpha * B, if tA == blas.NoTrans and s == blas.Left, +// A^T * X = alpha * B, if tA == blas.Trans and s == blas.Left, +// A^H * X = alpha * B, if tA == blas.ConjTrans and s == blas.Left, +// X * A = alpha * B, if tA == blas.NoTrans and s == blas.Right, +// X * A^T = alpha * B, if tA == blas.Trans and s == blas.Right, +// X * A^H = alpha * B, if tA == blas.ConjTrans and s == blas.Right, +// where A is an n×n or m×m triangular matrix, X and B are m×n matrices, and +// alpha is a scalar. +// +// At entry to the function, b contains the values of B, and the result is +// stored in-place into b. +// +// No check is made that A is invertible. +func Trsm(s blas.Side, tA blas.Transpose, alpha complex64, a Triangular, b General) { + cblas64.Ctrsm(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 complex64, a Hermitian, b General, beta complex64, c General) { + var m, n int + if s == blas.Left { + m, n = a.N, b.Cols + } else { + m, n = b.Rows, a.N + } + cblas64.Chemm(s, a.Uplo, m, n, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} + +// Herk performs the Hermitian rank-k update +// C = alpha * A * A^H + beta*C, if t == blas.NoTrans, +// C = alpha * A^H * A + beta*C, if t == blas.ConjTrans, +// where C is an n×n Hermitian matrix, A is an n×k matrix if t == blas.NoTrans +// and a k×n matrix otherwise, and alpha and beta are scalars. +func Herk(t blas.Transpose, alpha float32, a General, beta float32, c Hermitian) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas64.Cherk(c.Uplo, t, n, k, alpha, a.Data, a.Stride, beta, c.Data, c.Stride) +} + +// Her2k performs the Hermitian rank-2k update +// C = alpha * A * B^H + conj(alpha) * B * A^H + beta * C, if t == blas.NoTrans, +// C = alpha * A^H * B + conj(alpha) * B^H * A + beta * C, if t == blas.ConjTrans, +// where C is an n×n Hermitian matrix, A and B are n×k matrices if t == NoTrans +// and k×n matrices otherwise, and alpha and beta are scalars. +func Her2k(t blas.Transpose, alpha complex64, a, b General, beta float32, c Hermitian) { + var n, k int + if t == blas.NoTrans { + n, k = a.Rows, a.Cols + } else { + n, k = a.Cols, a.Rows + } + cblas64.Cher2k(c.Uplo, t, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride) +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas64/conv.go b/vendor/gonum.org/v1/gonum/blas/cblas64/conv.go new file mode 100644 index 00000000..fa5c9780 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas64/conv.go @@ -0,0 +1,279 @@ +// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT. + +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cblas64 + +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("cblas64: mismatched dimension") + } + if len(t.Data) < (t.Cols-1)*t.Stride+t.Rows { + panic("cblas64: 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("cblas64: mismatched dimension") + } + if len(t.Data) < (t.Rows-1)*t.Stride+t.Cols { + panic("cblas64: 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("cblas64: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas64: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas64: mismatched BLAS diag") + } + switch a.Uplo { + default: + panic("cblas64: 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("cblas64: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas64: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas64: mismatched BLAS diag") + } + switch a.Uplo { + default: + panic("cblas64: 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("cblas64: mismatched dimension") + } + if t.KL != a.KL || t.KU != a.KU { + panic("cblas64: mismatched bandwidth") + } + if a.Stride < a.KL+a.KU+1 { + panic("cblas64: short stride for source") + } + if t.Stride < t.KL+t.KU+1 { + panic("cblas64: 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("cblas64: mismatched dimension") + } + if t.KL != a.KL || t.KU != a.KU { + panic("cblas64: mismatched bandwidth") + } + if a.Stride < a.KL+a.KU+1 { + panic("cblas64: short stride for source") + } + if t.Stride < t.KL+t.KU+1 { + panic("cblas64: short stride for destination") + } + for j := 0; j < a.Cols; j++ { + for i := max(0, j-a.KU); i < min(j+a.KL+1, a.Rows); i++ { + t.Data[j+a.KL-i+i*a.Stride] = a.Data[i+t.KU-j+j*t.Stride] + } + } +} + +// TriangularBandCols represents a symmetric matrix using the band column-major storage scheme. +type TriangularBandCols TriangularBand + +// From fills the receiver with elements from a. The receiver +// must have the same dimensions, bandwidth and uplo as a and +// have adequate backing data storage. +func (t TriangularBandCols) From(a TriangularBand) { + if t.N != a.N { + panic("cblas64: mismatched dimension") + } + if t.K != a.K { + panic("cblas64: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas64: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas64: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas64: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas64: 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("cblas64: 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("cblas64: mismatched dimension") + } + if t.K != a.K { + panic("cblas64: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas64: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas64: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas64: mismatched BLAS uplo") + } + if t.Diag != a.Diag { + panic("cblas64: 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("cblas64: 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 +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas64/conv_hermitian.go b/vendor/gonum.org/v1/gonum/blas/cblas64/conv_hermitian.go new file mode 100644 index 00000000..76598b96 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas64/conv_hermitian.go @@ -0,0 +1,155 @@ +// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT. + +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cblas64 + +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("cblas64: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas64: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("cblas64: 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("cblas64: mismatched dimension") + } + if t.Uplo != a.Uplo { + panic("cblas64: mismatched BLAS uplo") + } + switch a.Uplo { + default: + panic("cblas64: 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("cblas64: mismatched dimension") + } + if t.K != a.K { + panic("cblas64: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas64: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas64: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas64: 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("cblas64: 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("cblas64: mismatched dimension") + } + if t.K != a.K { + panic("cblas64: mismatched bandwidth") + } + if a.Stride < a.K+1 { + panic("cblas64: short stride for source") + } + if t.Stride < t.K+1 { + panic("cblas64: short stride for destination") + } + if t.Uplo != a.Uplo { + panic("cblas64: 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("cblas64: 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) +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas64/conv_hermitian_test.go b/vendor/gonum.org/v1/gonum/blas/cblas64/conv_hermitian_test.go new file mode 100644 index 00000000..5f412647 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas64/conv_hermitian_test.go @@ -0,0 +1,307 @@ +// 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 cblas64 + +import ( + math "gonum.org/v1/gonum/internal/cmplx64" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newHermitianFrom(a HermitianCols) Hermitian { + t := Hermitian{ + N: a.N, + Stride: a.N, + Data: make([]complex64, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Hermitian) n() int { return m.N } +func (m Hermitian) at(i, j int) complex64 { + if m.Uplo == blas.Lower && i < j && j < m.N { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j { + i, j = j, i + } + return m.Data[i*m.Stride+j] +} +func (m Hermitian) uplo() blas.Uplo { return m.Uplo } + +func newHermitianColsFrom(a Hermitian) HermitianCols { + t := HermitianCols{ + N: a.N, + Stride: a.N, + Data: make([]complex64, a.N*a.N), + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m HermitianCols) n() int { return m.N } +func (m HermitianCols) at(i, j int) complex64 { + if m.Uplo == blas.Lower && i < j { + i, j = j, i + } + if m.Uplo == blas.Upper && i > j && i < m.N { + i, j = j, i + } + return m.Data[i+j*m.Stride] +} +func (m HermitianCols) uplo() blas.Uplo { return m.Uplo } + +type hermitian interface { + n() int + at(i, j int) complex64 + uplo() blas.Uplo +} + +func sameHermitian(a, b hermitian) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var hermitianTests = []Hermitian{ + {N: 3, Stride: 3, Data: []complex64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []complex64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertHermitian(t *testing.T) { + for _, test := range hermitianTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + test.Uplo = uplo + colmajor := newHermitianColsFrom(test) + if !sameHermitian(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newHermitianFrom(colmajor) + if !sameHermitian(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } +} +func newHermitianBandFrom(a HermitianBandCols) HermitianBand { + t := HermitianBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex64, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m HermitianBand) n() (n int) { return m.N } +func (m HermitianBand) at(i, j int) complex64 { + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas64: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m HermitianBand) bandwidth() (k int) { return m.K } +func (m HermitianBand) uplo() blas.Uplo { return m.Uplo } + +func newHermitianBandColsFrom(a HermitianBand) HermitianBandCols { + t := HermitianBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex64, a.N*(a.K+1)), + Uplo: a.Uplo, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m HermitianBandCols) n() (n int) { return m.N } +func (m HermitianBandCols) at(i, j int) complex64 { + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas64: bad BLAS uplo") + case blas.Upper: + b.KU = m.K + if i > j { + i, j = j, i + } + case blas.Lower: + b.KL = m.K + if i < j { + i, j = j, i + } + } + return b.at(i, j) +} +func (m HermitianBandCols) bandwidth() (k int) { return m.K } +func (m HermitianBandCols) uplo() blas.Uplo { return m.Uplo } + +type hermitianBand interface { + n() (n int) + at(i, j int) complex64 + bandwidth() (k int) + uplo() blas.Uplo +} + +func sameHermitianBand(a, b hermitianBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var hermitianBandTests = []HermitianBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []complex64{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []complex64{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []complex64{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []complex64{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []complex64{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []complex64{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []complex64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []complex64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []complex64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []complex64{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []complex64{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []complex64{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertHermBand(t *testing.T) { + for _, test := range hermitianBandTests { + colmajor := newHermitianBandColsFrom(test) + if !sameHermitianBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newHermitianBandFrom(colmajor) + if !sameHermitianBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas64/conv_test.go b/vendor/gonum.org/v1/gonum/blas/cblas64/conv_test.go new file mode 100644 index 00000000..da8d736e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas64/conv_test.go @@ -0,0 +1,620 @@ +// 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 cblas64 + +import ( + math "gonum.org/v1/gonum/internal/cmplx64" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func newGeneralFrom(a GeneralCols) General { + t := General{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Cols, + Data: make([]complex64, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m General) dims() (r, c int) { return m.Rows, m.Cols } +func (m General) at(i, j int) complex64 { return m.Data[i*m.Stride+j] } + +func newGeneralColsFrom(a General) GeneralCols { + t := GeneralCols{ + Rows: a.Rows, + Cols: a.Cols, + Stride: a.Rows, + Data: make([]complex64, a.Rows*a.Cols), + } + t.From(a) + return t +} + +func (m GeneralCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m GeneralCols) at(i, j int) complex64 { return m.Data[i+j*m.Stride] } + +type general interface { + dims() (r, c int) + at(i, j int) complex64 +} + +func sameGeneral(a, b general) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var generalTests = []General{ + {Rows: 2, Cols: 3, Stride: 3, Data: []complex64{ + 1, 2, 3, + 4, 5, 6, + }}, + {Rows: 3, Cols: 2, Stride: 2, Data: []complex64{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 3, Stride: 3, Data: []complex64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 2, Cols: 3, Stride: 5, Data: []complex64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + }}, + {Rows: 3, Cols: 2, Stride: 5, Data: []complex64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, Stride: 5, Data: []complex64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertGeneral(t *testing.T) { + for _, test := range generalTests { + colmajor := newGeneralColsFrom(test) + if !sameGeneral(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newGeneralFrom(colmajor) + if !sameGeneral(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularFrom(a TriangularCols) Triangular { + t := Triangular{ + N: a.N, + Stride: a.N, + Data: make([]complex64, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m Triangular) n() int { return m.N } +func (m Triangular) at(i, j int) complex64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j && j < m.N { + return 0 + } + if m.Uplo == blas.Upper && i > j { + return 0 + } + return m.Data[i*m.Stride+j] +} +func (m Triangular) uplo() blas.Uplo { return m.Uplo } +func (m Triangular) diag() blas.Diag { return m.Diag } + +func newTriangularColsFrom(a Triangular) TriangularCols { + t := TriangularCols{ + N: a.N, + Stride: a.N, + Data: make([]complex64, a.N*a.N), + Diag: a.Diag, + Uplo: a.Uplo, + } + t.From(a) + return t +} + +func (m TriangularCols) n() int { return m.N } +func (m TriangularCols) at(i, j int) complex64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + if m.Uplo == blas.Lower && i < j { + return 0 + } + if m.Uplo == blas.Upper && i > j && i < m.N { + return 0 + } + return m.Data[i+j*m.Stride] +} +func (m TriangularCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularCols) diag() blas.Diag { return m.Diag } + +type triangular interface { + n() int + at(i, j int) complex64 + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangular(a, b triangular) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularTests = []Triangular{ + {N: 3, Stride: 3, Data: []complex64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {N: 3, Stride: 5, Data: []complex64{ + 1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, +} + +func TestConvertTriangular(t *testing.T) { + for _, test := range triangularTests { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower, blas.All} { + for _, diag := range []blas.Diag{blas.Unit, blas.NonUnit} { + test.Uplo = uplo + test.Diag = diag + colmajor := newTriangularColsFrom(test) + if !sameTriangular(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularFrom(colmajor) + if !sameTriangular(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } + } + } +} + +func newBandFrom(a BandCols) Band { + t := Band{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]complex64, a.Rows*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m Band) dims() (r, c int) { return m.Rows, m.Cols } +func (m Band) at(i, j int) complex64 { + pj := j + m.KL - i + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[i*m.Stride+pj] +} +func (m Band) bandwidth() (kl, ku int) { return m.KL, m.KU } + +func newBandColsFrom(a Band) BandCols { + t := BandCols{ + Rows: a.Rows, + Cols: a.Cols, + KL: a.KL, + KU: a.KU, + Stride: a.KL + a.KU + 1, + Data: make([]complex64, a.Cols*(a.KL+a.KU+1)), + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m BandCols) dims() (r, c int) { return m.Rows, m.Cols } +func (m BandCols) at(i, j int) complex64 { + pj := i + m.KU - j + if pj < 0 || m.KL+m.KU+1 <= pj { + return 0 + } + return m.Data[j*m.Stride+pj] +} +func (m BandCols) bandwidth() (kl, ku int) { return m.KL, m.KU } + +type band interface { + dims() (r, c int) + at(i, j int) complex64 + bandwidth() (kl, ku int) +} + +func sameBand(a, b band) bool { + ar, ac := a.dims() + br, bc := b.dims() + if ar != br || ac != bc { + return false + } + akl, aku := a.bandwidth() + bkl, bku := b.bandwidth() + if akl != bkl || aku != bku { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var bandTests = []Band{ + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 1, Data: []complex64{ + 1, + 2, + 3, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []complex64{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 1, Data: []complex64{ + 1, + 2, + 3, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 2, Data: []complex64{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 2, Data: []complex64{ + 1, 2, + 3, 4, + 5, 6, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 3, Data: []complex64{ + -1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 3, Data: []complex64{ + -1, 2, 3, + 4, 5, 6, + 7, 8, -2, + 9, -3, -4, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 4, Data: []complex64{ + -2, -1, 3, 4, + -3, 5, 6, 7, + 8, 9, 10, 11, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 4, Data: []complex64{ + -2, -1, 2, 3, + -3, 4, 5, 6, + 7, 8, 9, -4, + 10, 11, -5, -6, + }}, + + {Rows: 3, Cols: 4, KL: 0, KU: 0, Stride: 5, Data: []complex64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 3, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []complex64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 0, Stride: 5, Data: []complex64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 0, KU: 1, Stride: 5, Data: []complex64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 0, KU: 1, Stride: 5, Data: []complex64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, 6, 0, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 1, KU: 1, Stride: 5, Data: []complex64{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, 9, 0, 0, + }}, + {Rows: 4, Cols: 3, KL: 1, KU: 1, Stride: 5, Data: []complex64{ + -1, 2, 3, 0, 0, + 4, 5, 6, 0, 0, + 7, 8, -2, 0, 0, + 9, -3, -4, 0, 0, + }}, + {Rows: 3, Cols: 4, KL: 2, KU: 1, Stride: 5, Data: []complex64{ + -2, -1, 3, 4, 0, + -3, 5, 6, 7, 0, + 8, 9, 10, 11, 0, + }}, + {Rows: 4, Cols: 3, KL: 2, KU: 1, Stride: 5, Data: []complex64{ + -2, -1, 2, 3, 0, + -3, 4, 5, 6, 0, + 7, 8, 9, -4, 0, + 10, 11, -5, -6, 0, + }}, +} + +func TestConvertBand(t *testing.T) { + for _, test := range bandTests { + colmajor := newBandColsFrom(test) + if !sameBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newBandFrom(colmajor) + if !sameBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} + +func newTriangularBandFrom(a TriangularBandCols) TriangularBand { + t := TriangularBand{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex64, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBand) n() (n int) { return m.N } +func (m TriangularBand) at(i, j int) complex64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := Band{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas64: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBand) bandwidth() (k int) { return m.K } +func (m TriangularBand) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBand) diag() blas.Diag { return m.Diag } + +func newTriangularBandColsFrom(a TriangularBand) TriangularBandCols { + t := TriangularBandCols{ + N: a.N, + K: a.K, + Stride: a.K + 1, + Data: make([]complex64, a.N*(a.K+1)), + Uplo: a.Uplo, + Diag: a.Diag, + } + for i := range t.Data { + t.Data[i] = math.NaN() + } + t.From(a) + return t +} + +func (m TriangularBandCols) n() (n int) { return m.N } +func (m TriangularBandCols) at(i, j int) complex64 { + if m.Diag == blas.Unit && i == j { + return 1 + } + b := BandCols{ + Rows: m.N, Cols: m.N, + Stride: m.Stride, + Data: m.Data, + } + switch m.Uplo { + default: + panic("cblas64: bad BLAS uplo") + case blas.Upper: + if i > j { + return 0 + } + b.KU = m.K + case blas.Lower: + if i < j { + return 0 + } + b.KL = m.K + } + return b.at(i, j) +} +func (m TriangularBandCols) bandwidth() (k int) { return m.K } +func (m TriangularBandCols) uplo() blas.Uplo { return m.Uplo } +func (m TriangularBandCols) diag() blas.Diag { return m.Diag } + +type triangularBand interface { + n() (n int) + at(i, j int) complex64 + bandwidth() (k int) + uplo() blas.Uplo + diag() blas.Diag +} + +func sameTriangularBand(a, b triangularBand) bool { + an := a.n() + bn := b.n() + if an != bn { + return false + } + if a.uplo() != b.uplo() { + return false + } + if a.diag() != b.diag() { + return false + } + ak := a.bandwidth() + bk := b.bandwidth() + if ak != bk { + return false + } + for i := 0; i < an; i++ { + for j := 0; j < an; j++ { + if a.at(i, j) != b.at(i, j) || math.IsNaN(a.at(i, j)) != math.IsNaN(b.at(i, j)) { + return false + } + } + } + return true +} + +var triangularBandTests = []TriangularBand{ + {N: 3, K: 0, Stride: 1, Uplo: blas.Upper, Data: []complex64{ + 1, + 2, + 3, + }}, + {N: 3, K: 0, Stride: 1, Uplo: blas.Lower, Data: []complex64{ + 1, + 2, + 3, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Upper, Data: []complex64{ + 1, 2, + 3, 4, + 5, -1, + }}, + {N: 3, K: 1, Stride: 2, Uplo: blas.Lower, Data: []complex64{ + -1, 1, + 2, 3, + 4, 5, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Upper, Data: []complex64{ + 1, 2, 3, + 4, 5, -1, + 6, -2, -3, + }}, + {N: 3, K: 2, Stride: 3, Uplo: blas.Lower, Data: []complex64{ + -2, -1, 1, + -3, 2, 4, + 3, 5, 6, + }}, + + {N: 3, K: 0, Stride: 5, Uplo: blas.Upper, Data: []complex64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 0, Stride: 5, Uplo: blas.Lower, Data: []complex64{ + 1, 0, 0, 0, 0, + 2, 0, 0, 0, 0, + 3, 0, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Upper, Data: []complex64{ + 1, 2, 0, 0, 0, + 3, 4, 0, 0, 0, + 5, -1, 0, 0, 0, + }}, + {N: 3, K: 1, Stride: 5, Uplo: blas.Lower, Data: []complex64{ + -1, 1, 0, 0, 0, + 2, 3, 0, 0, 0, + 4, 5, 0, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Upper, Data: []complex64{ + 1, 2, 3, 0, 0, + 4, 5, -1, 0, 0, + 6, -2, -3, 0, 0, + }}, + {N: 3, K: 2, Stride: 5, Uplo: blas.Lower, Data: []complex64{ + -2, -1, 1, 0, 0, + -3, 2, 4, 0, 0, + 3, 5, 6, 0, 0, + }}, +} + +func TestConvertTriBand(t *testing.T) { + for _, test := range triangularBandTests { + colmajor := newTriangularBandColsFrom(test) + if !sameTriangularBand(colmajor, test) { + t.Errorf("unexpected result for row major to col major conversion:\n\tgot: %#v\n\tfrom:%#v", + colmajor, test) + } + rowmajor := newTriangularBandFrom(colmajor) + if !sameTriangularBand(rowmajor, test) { + t.Errorf("unexpected result for col major to row major conversion:\n\tgot: %#v\n\twant:%#v", + rowmajor, test) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/cblas64/doc.go b/vendor/gonum.org/v1/gonum/blas/cblas64/doc.go new file mode 100644 index 00000000..bb9c70b1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/cblas64/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cblas64 provides a simple interface to the complex64 BLAS API. +package cblas64 // import "gonum.org/v1/gonum/blas/cblas64" diff --git a/vendor/gonum.org/v1/gonum/blas/conversions.bash b/vendor/gonum.org/v1/gonum/blas/conversions.bash new file mode 100755 index 00000000..96ff2272 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/conversions.bash @@ -0,0 +1,159 @@ +#!/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 diff --git a/vendor/gonum.org/v1/gonum/blas/doc.go b/vendor/gonum.org/v1/gonum/blas/doc.go new file mode 100644 index 00000000..99231c46 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/doc.go @@ -0,0 +1,108 @@ +// 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" diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/bench_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/bench_test.go new file mode 100644 index 00000000..81124fea --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/bench_test.go @@ -0,0 +1,22 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/testblas" +) + +const ( + Sm = testblas.SmallMat + Med = testblas.MediumMat + Lg = testblas.LargeMat + Hg = testblas.HugeMat +) + +const ( + T = blas.Trans + NT = blas.NoTrans +) diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/cmplx.go b/vendor/gonum.org/v1/gonum/blas/gonum/cmplx.go new file mode 100644 index 00000000..24ff57c9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/cmplx.go @@ -0,0 +1,206 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas" + +var ( + _ blas.Complex64 = Implementation{} + _ blas.Complex128 = Implementation{} +) + +// TODO(btracey): Replace this as complex routines are added, and instead +// automatically generate the complex64 routines from the complex128 ones. + +var noComplex = "native: implementation does not implement this routine, see the cgo wrapper in gonum.org/v1/netlib/blas" + +// Level 1 complex64 routines. + +func (Implementation) Cdotu(n int, x []complex64, incX int, y []complex64, incY int) (dotu complex64) { + panic(noComplex) +} +func (Implementation) Cdotc(n int, x []complex64, incX int, y []complex64, incY int) (dotc complex64) { + panic(noComplex) +} +func (Implementation) Scnrm2(n int, x []complex64, incX int) float32 { + panic(noComplex) +} +func (Implementation) Scasum(n int, x []complex64, incX int) float32 { + panic(noComplex) +} +func (Implementation) Icamax(n int, x []complex64, incX int) int { + panic(noComplex) +} +func (Implementation) Cswap(n int, x []complex64, incX int, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Ccopy(n int, x []complex64, incX int, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Caxpy(n int, alpha complex64, x []complex64, incX int, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Cscal(n int, alpha complex64, x []complex64, incX int) { + panic(noComplex) +} +func (Implementation) Csscal(n int, alpha float32, x []complex64, incX int) { + panic(noComplex) +} + +// Level 2 complex64 routines. + +func (Implementation) Cgemv(tA blas.Transpose, m, n int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Cgbmv(tA blas.Transpose, m, n, kL, kU int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Ctrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []complex64, lda int, x []complex64, incX int) { + panic(noComplex) +} +func (Implementation) Ctbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []complex64, lda int, x []complex64, incX int) { + panic(noComplex) +} +func (Implementation) Ctpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []complex64, x []complex64, incX int) { + panic(noComplex) +} +func (Implementation) Ctrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []complex64, lda int, x []complex64, incX int) { + panic(noComplex) +} +func (Implementation) Ctbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []complex64, lda int, x []complex64, incX int) { + panic(noComplex) +} +func (Implementation) Ctpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []complex64, x []complex64, incX int) { + panic(noComplex) +} +func (Implementation) Chemv(ul blas.Uplo, n int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Chbmv(ul blas.Uplo, n, k int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Chpmv(ul blas.Uplo, n int, alpha complex64, ap []complex64, x []complex64, incX int, beta complex64, y []complex64, incY int) { + panic(noComplex) +} +func (Implementation) Cgeru(m, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int) { + panic(noComplex) +} +func (Implementation) Cgerc(m, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int) { + panic(noComplex) +} +func (Implementation) Cher(ul blas.Uplo, n int, alpha float32, x []complex64, incX int, a []complex64, lda int) { + panic(noComplex) +} +func (Implementation) Chpr(ul blas.Uplo, n int, alpha float32, x []complex64, incX int, a []complex64) { + panic(noComplex) +} +func (Implementation) Cher2(ul blas.Uplo, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int) { + panic(noComplex) +} +func (Implementation) Chpr2(ul blas.Uplo, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, ap []complex64) { + panic(noComplex) +} + +// Level 3 complex64 routines. + +func (Implementation) Cgemm(tA, tB blas.Transpose, m, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) { + panic(noComplex) +} +func (Implementation) Csymm(s blas.Side, ul blas.Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) { + panic(noComplex) +} +func (Implementation) Csyrk(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, beta complex64, c []complex64, ldc int) { + panic(noComplex) +} +func (Implementation) Csyr2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) { + panic(noComplex) +} +func (Implementation) Ctrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int) { + panic(noComplex) +} +func (Implementation) Ctrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int) { + panic(noComplex) +} +func (Implementation) Chemm(s blas.Side, ul blas.Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) { + panic(noComplex) +} +func (Implementation) Cherk(ul blas.Uplo, t blas.Transpose, n, k int, alpha float32, a []complex64, lda int, beta float32, c []complex64, ldc int) { + panic(noComplex) +} +func (Implementation) Cher2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta float32, c []complex64, ldc int) { + panic(noComplex) +} + +// Level 2 complex128 routines. + +func (Implementation) Zgemv(tA blas.Transpose, m, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) { + panic(noComplex) +} +func (Implementation) Zgbmv(tA blas.Transpose, m, n int, kL int, kU int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) { + panic(noComplex) +} +func (Implementation) Ztrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []complex128, lda int, x []complex128, incX int) { + panic(noComplex) +} +func (Implementation) Ztbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []complex128, lda int, x []complex128, incX int) { + panic(noComplex) +} +func (Implementation) Ztpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []complex128, x []complex128, incX int) { + panic(noComplex) +} +func (Implementation) Ztrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []complex128, lda int, x []complex128, incX int) { + panic(noComplex) +} +func (Implementation) Ztbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []complex128, lda int, x []complex128, incX int) { + panic(noComplex) +} +func (Implementation) Ztpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []complex128, x []complex128, incX int) { + panic(noComplex) +} +func (Implementation) Zhemv(ul blas.Uplo, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) { + panic(noComplex) +} +func (Implementation) Zhbmv(ul blas.Uplo, n, k int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) { + panic(noComplex) +} +func (Implementation) Zhpmv(ul blas.Uplo, n int, alpha complex128, ap []complex128, x []complex128, incX int, beta complex128, y []complex128, incY int) { + panic(noComplex) +} +func (Implementation) Zhpr(ul blas.Uplo, n int, alpha float64, x []complex128, incX int, a []complex128) { + panic(noComplex) +} +func (Implementation) Zhpr2(ul blas.Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, ap []complex128) { + panic(noComplex) +} + +// Level 3 complex128 routines. + +func (Implementation) Zgemm(tA, tB blas.Transpose, m, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) { + panic(noComplex) +} +func (Implementation) Zsymm(s blas.Side, ul blas.Uplo, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) { + panic(noComplex) +} +func (Implementation) Zsyrk(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex128, a []complex128, lda int, beta complex128, c []complex128, ldc int) { + panic(noComplex) +} +func (Implementation) Zsyr2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) { + panic(noComplex) +} +func (Implementation) Ztrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int) { + panic(noComplex) +} +func (Implementation) Ztrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int) { + panic(noComplex) +} +func (Implementation) Zhemm(s blas.Side, ul blas.Uplo, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) { + panic(noComplex) +} +func (Implementation) Zherk(ul blas.Uplo, t blas.Transpose, n, k int, alpha float64, a []complex128, lda int, beta float64, c []complex128, ldc int) { + panic(noComplex) +} +func (Implementation) Zher2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta float64, c []complex128, ldc int) { + panic(noComplex) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/dgemm.go b/vendor/gonum.org/v1/gonum/blas/gonum/dgemm.go new file mode 100644 index 00000000..a9291d9b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/dgemm.go @@ -0,0 +1,261 @@ +// 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 computes +// C = beta * C + alpha * A * B, +// 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 (Implementation) Dgemm(tA, tB blas.Transpose, m, n, k int, alpha float64, a []float64, lda int, b []float64, ldb int, beta float64, c []float64, ldc int) { + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if tB != blas.NoTrans && tB != blas.Trans && tB != blas.ConjTrans { + panic(badTranspose) + } + aTrans := tA == blas.Trans || tA == blas.ConjTrans + if aTrans { + checkDMatrix('a', k, m, a, lda) + } else { + checkDMatrix('a', m, k, a, lda) + } + bTrans := tB == blas.Trans || tB == blas.ConjTrans + if bTrans { + checkDMatrix('b', n, k, b, ldb) + } else { + checkDMatrix('b', k, n, b, ldb) + } + checkDMatrix('c', m, n, c, ldc) + + // 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^T * B) + // Cij = \sum_k Aik Bjk, (A * B^T) + // Cij = \sum_k Aki Bjk, (A^T * B^T) + // + // 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() + // Make local copies of otherwise global variables to reduce shared memory. + // This has a noticeable effect on benchmarks in some cases. + alpha := alpha + aTrans := aTrans + bTrans := bTrans + m := m + n := n + for sub := range sendChan { + i := sub.i + j := sub.j + 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.AxpyUnitaryTo(ctmp, 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.AxpyUnitaryTo(ctmp, 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] +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/dgemmbench_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/dgemmbench_test.go new file mode 100644 index 00000000..55a44997 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/dgemmbench_test.go @@ -0,0 +1,51 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func BenchmarkDgemmSmSmSm(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Sm, Sm, Sm, NT, NT) +} + +func BenchmarkDgemmMedMedMed(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Med, Med, Med, NT, NT) +} + +func BenchmarkDgemmMedLgMed(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Med, Lg, Med, NT, NT) +} + +func BenchmarkDgemmLgLgLg(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Lg, Lg, Lg, NT, NT) +} + +func BenchmarkDgemmLgSmLg(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Lg, Sm, Lg, NT, NT) +} + +func BenchmarkDgemmLgLgSm(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Lg, Lg, Sm, NT, NT) +} + +func BenchmarkDgemmHgHgSm(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Hg, Hg, Sm, NT, NT) +} + +func BenchmarkDgemmMedMedMedTNT(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Med, Med, Med, T, NT) +} + +func BenchmarkDgemmMedMedMedNTT(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Med, Med, Med, NT, T) +} + +func BenchmarkDgemmMedMedMedTT(b *testing.B) { + testblas.DgemmBenchmark(b, impl, Med, Med, Med, T, T) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/dgemvbench_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/dgemvbench_test.go new file mode 100644 index 00000000..97899809 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/dgemvbench_test.go @@ -0,0 +1,91 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func BenchmarkDgemvSmSmNoTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Sm, Sm, 1, 1) +} + +func BenchmarkDgemvSmSmNoTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Sm, Sm, 2, 3) +} + +func BenchmarkDgemvSmSmTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Sm, Sm, 1, 1) +} + +func BenchmarkDgemvSmSmTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Sm, Sm, 2, 3) +} + +func BenchmarkDgemvMedMedNoTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Med, Med, 1, 1) +} + +func BenchmarkDgemvMedMedNoTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Med, Med, 2, 3) +} + +func BenchmarkDgemvMedMedTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Med, Med, 1, 1) +} + +func BenchmarkDgemvMedMedTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Med, Med, 2, 3) +} + +func BenchmarkDgemvLgLgNoTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Lg, Lg, 1, 1) +} + +func BenchmarkDgemvLgLgNoTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Lg, Lg, 2, 3) +} + +func BenchmarkDgemvLgLgTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Lg, Lg, 1, 1) +} + +func BenchmarkDgemvLgLgTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Lg, Lg, 2, 3) +} + +func BenchmarkDgemvLgSmNoTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Lg, Sm, 1, 1) +} + +func BenchmarkDgemvLgSmNoTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Lg, Sm, 2, 3) +} + +func BenchmarkDgemvLgSmTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Lg, Sm, 1, 1) +} + +func BenchmarkDgemvLgSmTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Lg, Sm, 2, 3) +} + +func BenchmarkDgemvSmLgNoTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Sm, Lg, 1, 1) +} + +func BenchmarkDgemvSmLgNoTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, NT, Sm, Lg, 2, 3) +} + +func BenchmarkDgemvSmLgTransInc1(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Sm, Lg, 1, 1) +} + +func BenchmarkDgemvSmLgTransIncN(b *testing.B) { + testblas.DgemvBenchmark(b, impl, T, Sm, Lg, 2, 3) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/dgerbench_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/dgerbench_test.go new file mode 100644 index 00000000..e1f85939 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/dgerbench_test.go @@ -0,0 +1,51 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func BenchmarkDgerSmSmInc1(b *testing.B) { + testblas.DgerBenchmark(b, impl, Sm, Sm, 1, 1) +} + +func BenchmarkDgerSmSmIncN(b *testing.B) { + testblas.DgerBenchmark(b, impl, Sm, Sm, 2, 3) +} + +func BenchmarkDgerMedMedInc1(b *testing.B) { + testblas.DgerBenchmark(b, impl, Med, Med, 1, 1) +} + +func BenchmarkDgerMedMedIncN(b *testing.B) { + testblas.DgerBenchmark(b, impl, Med, Med, 2, 3) +} + +func BenchmarkDgerLgLgInc1(b *testing.B) { + testblas.DgerBenchmark(b, impl, Lg, Lg, 1, 1) +} + +func BenchmarkDgerLgLgIncN(b *testing.B) { + testblas.DgerBenchmark(b, impl, Lg, Lg, 2, 3) +} + +func BenchmarkDgerLgSmInc1(b *testing.B) { + testblas.DgerBenchmark(b, impl, Lg, Sm, 1, 1) +} + +func BenchmarkDgerLgSmIncN(b *testing.B) { + testblas.DgerBenchmark(b, impl, Lg, Sm, 2, 3) +} + +func BenchmarkDgerSmLgInc1(b *testing.B) { + testblas.DgerBenchmark(b, impl, Sm, Lg, 1, 1) +} + +func BenchmarkDgerSmLgIncN(b *testing.B) { + testblas.DgerBenchmark(b, impl, Sm, Lg, 2, 3) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/doc.go b/vendor/gonum.org/v1/gonum/blas/gonum/doc.go new file mode 100644 index 00000000..3b6b4077 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/doc.go @@ -0,0 +1,88 @@ +// 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 native 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. Please 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. + +Please 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" diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/dtrmvbench_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/dtrmvbench_test.go new file mode 100644 index 00000000..371c0192 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/dtrmvbench_test.go @@ -0,0 +1,54 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package gonum + +import ( + "strconv" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/testblas" +) + +func BenchmarkDtrmv(b *testing.B) { + for _, n := range []int{testblas.MediumMat, testblas.LargeMat} { + for _, incX := range []int{1, 5} { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, unit := range []blas.Diag{blas.NonUnit, blas.Unit} { + var str string + if n == testblas.MediumMat { + str += "Med" + } else if n == testblas.LargeMat { + str += "Large" + } + str += "_Inc" + strconv.Itoa(incX) + if uplo == blas.Upper { + str += "_UP" + } else { + str += "_LO" + } + if trans == blas.NoTrans { + str += "_NT" + } else { + str += "_TR" + } + if unit == blas.NonUnit { + str += "_NU" + } else { + str += "_UN" + } + lda := n + b.Run(str, func(b *testing.B) { + testblas.DtrmvBenchmark(b, Implementation{}, n, lda, incX, uplo, trans, unit) + }) + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/general_double.go b/vendor/gonum.org/v1/gonum/blas/gonum/general_double.go new file mode 100644 index 00000000..58ded80c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/general_double.go @@ -0,0 +1,50 @@ +// 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 ( + "math" +) + +type general64 struct { + data []float64 + rows, cols int + stride int +} + +func (g general64) clone() general64 { + data := make([]float64, len(g.data)) + copy(data, g.data) + return general64{ + data: data, + rows: g.rows, + cols: g.cols, + stride: g.stride, + } +} + +func (g general64) equal(a general64) bool { + if g.rows != a.rows || g.cols != a.cols || g.stride != a.stride { + return false + } + for i, v := range g.data { + if a.data[i] != v { + return false + } + } + return true +} + +func (g general64) equalWithinAbs(a general64, tol float64) bool { + if g.rows != a.rows || g.cols != a.cols || g.stride != a.stride { + return false + } + for i, v := range g.data { + if math.Abs(a.data[i]-v) > tol { + return false + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/general_single.go b/vendor/gonum.org/v1/gonum/blas/gonum/general_single.go new file mode 100644 index 00000000..ca360a72 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/general_single.go @@ -0,0 +1,52 @@ +// 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 ( + math "gonum.org/v1/gonum/internal/math32" +) + +type general32 struct { + data []float32 + rows, cols int + stride int +} + +func (g general32) clone() general32 { + data := make([]float32, len(g.data)) + copy(data, g.data) + return general32{ + data: data, + rows: g.rows, + cols: g.cols, + stride: g.stride, + } +} + +func (g general32) equal(a general32) bool { + if g.rows != a.rows || g.cols != a.cols || g.stride != a.stride { + return false + } + for i, v := range g.data { + if a.data[i] != v { + return false + } + } + return true +} + +func (g general32) equalWithinAbs(a general32, tol float32) bool { + if g.rows != a.rows || g.cols != a.cols || g.stride != a.stride { + return false + } + for i, v := range g.data { + if math.Abs(a.data[i]-v) > tol { + return false + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/gonum.go b/vendor/gonum.org/v1/gonum/blas/gonum/gonum.go new file mode 100644 index 00000000..e65f745a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/gonum.go @@ -0,0 +1,133 @@ +// 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" + +type Implementation struct{} + +// The following are panic strings used during parameter checks. +const ( + negativeN = "blas: n < 0" + zeroIncX = "blas: zero x index increment" + zeroIncY = "blas: zero y index increment" + badLenX = "blas: x index out of range" + badLenY = "blas: y index out of range" + + mLT0 = "blas: m < 0" + nLT0 = "blas: n < 0" + kLT0 = "blas: k < 0" + kLLT0 = "blas: kL < 0" + kULT0 = "blas: kU < 0" + + badUplo = "blas: illegal triangle" + badTranspose = "blas: illegal transpose" + badDiag = "blas: illegal diagonal" + badSide = "blas: illegal side" + + badLdA = "blas: index of a out of range" + badLdB = "blas: index of b out of range" + badLdC = "blas: index of c out of range" + + badX = "blas: x index out of range" + badY = "blas: y index out of range" +) + +// [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 +} + +func checkSMatrix(name byte, m, n int, a []float32, lda int) { + if m < 0 { + panic(mLT0) + } + if n < 0 { + panic(nLT0) + } + if lda < n { + panic("blas: illegal stride of " + string(name)) + } + if len(a) < (m-1)*lda+n { + panic("blas: index of " + string(name) + " out of range") + } +} + +func checkDMatrix(name byte, m, n int, a []float64, lda int) { + if m < 0 { + panic(mLT0) + } + if n < 0 { + panic(nLT0) + } + if lda < n { + panic("blas: illegal stride of " + string(name)) + } + if len(a) < (m-1)*lda+n { + panic("blas: index of " + string(name) + " out of range") + } +} + +func checkZMatrix(name byte, m, n int, a []complex128, lda int) { + if m < 0 { + panic(mLT0) + } + if n < 0 { + panic(nLT0) + } + if lda < max(1, n) { + panic("blas: illegal stride of " + string(name)) + } + if len(a) < (m-1)*lda+n { + panic("blas: insufficient " + string(name) + " matrix slice length") + } +} + +func checkZVector(name byte, n int, x []complex128, incX int) { + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic("blas: insufficient " + string(name) + " vector slice length") + } +} + +// blocks returns the number of divisions of the dimension length with the given +// block size. +func blocks(dim, bsize int) int { + 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)) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128.go new file mode 100644 index 00000000..b759c902 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128.go @@ -0,0 +1,442 @@ +// 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/asm/c128" +) + +// 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(negativeN) + } + if incX < 1 { + if incX == 0 { + panic(zeroIncX) + } + return 0 + } + var sum float64 + if incX == 1 { + if len(x) < n { + panic(badX) + } + for _, v := range x[:n] { + sum += dcabs1(v) + } + return sum + } + if (n-1)*incX >= len(x) { + panic(badX) + } + 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(negativeN) + } + if (n-1)*incX >= len(x) { + panic(badX) + } + 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(negativeN) + } + if len(x) <= (n-1)*incX { + panic(badX) + } + 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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^H · 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(negativeN) + } + if incX == 1 && incY == 1 { + if len(x) < n { + panic(badX) + } + if len(y) < n { + panic(badY) + } + 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(badX) + } + if iy >= len(y) || (n-1)*incY >= len(y) { + panic(badY) + } + return c128.DotcInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy)) +} + +// Zdotu computes the dot product +// x^T · 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(negativeN) + } + if incX == 1 && incY == 1 { + if len(x) < n { + panic(badX) + } + if len(y) < n { + panic(badY) + } + 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(badX) + } + if iy >= len(y) || (n-1)*incY >= len(y) { + panic(badY) + } + 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(badX) + } + if n < 1 { + if n == 0 { + return + } + panic(negativeN) + } + 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(badX) + } + if n < 1 { + if n == 0 { + return + } + panic(negativeN) + } + 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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 + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128_bench_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128_bench_test.go new file mode 100644 index 00000000..af536365 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128_bench_test.go @@ -0,0 +1,41 @@ +// 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/rand" + "testing" +) + +func benchmarkZdscal(b *testing.B, n, inc int) { + rnd := rand.New(rand.NewSource(1)) + alpha := rnd.NormFloat64() + x := make([]complex128, (n-1)*inc+1) + for i := range x { + x[i] = complex(rnd.NormFloat64(), rnd.NormFloat64()) + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Zdscal(n, alpha, x, inc) + } +} + +func BenchmarkZdscalN10Inc1(b *testing.B) { benchmarkZdscal(b, 10, 1) } +func BenchmarkZdscalN100Inc1(b *testing.B) { benchmarkZdscal(b, 100, 1) } +func BenchmarkZdscalN1000Inc1(b *testing.B) { benchmarkZdscal(b, 1000, 1) } +func BenchmarkZdscalN10000Inc1(b *testing.B) { benchmarkZdscal(b, 10000, 1) } +func BenchmarkZdscalN100000Inc1(b *testing.B) { benchmarkZdscal(b, 100000, 1) } + +func BenchmarkZdscalN10Inc10(b *testing.B) { benchmarkZdscal(b, 10, 10) } +func BenchmarkZdscalN100Inc10(b *testing.B) { benchmarkZdscal(b, 100, 10) } +func BenchmarkZdscalN1000Inc10(b *testing.B) { benchmarkZdscal(b, 1000, 10) } +func BenchmarkZdscalN10000Inc10(b *testing.B) { benchmarkZdscal(b, 10000, 10) } +func BenchmarkZdscalN100000Inc10(b *testing.B) { benchmarkZdscal(b, 100000, 10) } + +func BenchmarkZdscalN10Inc1000(b *testing.B) { benchmarkZdscal(b, 10, 1000) } +func BenchmarkZdscalN100Inc1000(b *testing.B) { benchmarkZdscal(b, 100, 1000) } +func BenchmarkZdscalN1000Inc1000(b *testing.B) { benchmarkZdscal(b, 1000, 1000) } +func BenchmarkZdscalN10000Inc1000(b *testing.B) { benchmarkZdscal(b, 10000, 1000) } +func BenchmarkZdscalN100000Inc1000(b *testing.B) { benchmarkZdscal(b, 100000, 1000) } diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128_test.go new file mode 100644 index 00000000..1755e9e6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128_test.go @@ -0,0 +1,51 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func TestDzasum(t *testing.T) { + testblas.DzasumTest(t, impl) +} + +func TestDznrm2(t *testing.T) { + testblas.Dznrm2Test(t, impl) +} + +func TestIzamax(t *testing.T) { + testblas.IzamaxTest(t, impl) +} + +func TestZaxpy(t *testing.T) { + testblas.ZaxpyTest(t, impl) +} + +func TestZcopy(t *testing.T) { + testblas.ZcopyTest(t, impl) +} + +func TestZdotc(t *testing.T) { + testblas.ZdotcTest(t, impl) +} + +func TestZdotu(t *testing.T) { + testblas.ZdotuTest(t, impl) +} + +func TestZdscal(t *testing.T) { + testblas.ZdscalTest(t, impl) +} + +func TestZscal(t *testing.T) { + testblas.ZscalTest(t, impl) +} + +func TestZswap(t *testing.T) { + testblas.ZswapTest(t, impl) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1double.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1double.go new file mode 100644 index 00000000..e433fddf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1double.go @@ -0,0 +1,595 @@ +// 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 incX > 0 && (n-1)*incX >= len(x) { + panic(badX) + } + if n < 2 { + if n == 1 { + return math.Abs(x[0]) + } + if n == 0 { + return 0 + } + if n < 1 { + panic(negativeN) + } + } + 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(negativeN) + } + if incX < 1 { + if incX == 0 { + panic(zeroIncX) + } + return 0 + } + if incX > 0 && (n-1)*incX >= len(x) { + panic(badX) + } + 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 incX > 0 && (n-1)*incX >= len(x) { + panic(badX) + } + if n < 2 { + if n == 1 { + return 0 + } + if n == 0 { + return -1 // Netlib returns invalid index when n == 0 + } + if n < 1 { + panic(negativeN) + } + } + 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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 refence 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) { + var p1, p2, q1, q2, u float64 + + const ( + gam = 4096.0 + gamsq = 16777216.0 + rgamsq = 5.9604645e-8 + ) + + if d1 < 0 { + p.Flag = blas.Rescaling + return + } + + p2 = d2 * y1 + if p2 == 0 { + p.Flag = blas.Identity + rd1 = d1 + rd2 = d2 + rx1 = x1 + return + } + p1 = d1 * x1 + q2 = p2 * y1 + q1 = p1 * x1 + + absQ1 := math.Abs(q1) + absQ2 := math.Abs(q2) + + if absQ1 < absQ2 && q2 < 0 { + p.Flag = blas.Rescaling + return + } + + if d1 == 0 { + p.Flag = blas.Diagonal + p.H[0] = p1 / p2 + p.H[3] = x1 / y1 + u = 1 + p.H[0]*p.H[3] + rd1, rd2 = d2/u, d1/u + rx1 = y1 / u + return + } + + // Now we know that d1 != 0, and d2 != 0. If d2 == 0, it would be caught + // when p2 == 0, and if d1 == 0, then it is caught above + + if absQ1 > absQ2 { + p.H[1] = -y1 / x1 + p.H[2] = p2 / p1 + u = 1 - p.H[2]*p.H[1] + rd1 = d1 + rd2 = d2 + rx1 = x1 + p.Flag = blas.OffDiagonal + // u must be greater than zero because |q1| > |q2|, so check from netlib + // is unnecessary + // This is left in for ease of comparison with complex routines + //if u > 0 { + rd1 /= u + rd2 /= u + rx1 *= u + //} + } else { + p.Flag = blas.Diagonal + p.H[0] = p1 / p2 + p.H[3] = x1 / y1 + u = 1 + p.H[0]*p.H[3] + rd1 = d2 / u + rd2 = d1 / u + rx1 = y1 * u + } + + for rd1 <= rgamsq || rd1 >= gamsq { + if p.Flag == blas.OffDiagonal { + p.H[0] = 1 + p.H[3] = 1 + p.Flag = blas.Rescaling + } else if p.Flag == blas.Diagonal { + p.H[1] = -1 + p.H[2] = 1 + p.Flag = blas.Rescaling + } + if rd1 <= rgamsq { + rd1 *= gam * gam + rx1 /= gam + p.H[0] /= gam + p.H[2] /= gam + } else { + rd1 /= gam * gam + rx1 *= gam + p.H[0] *= gam + p.H[2] *= gam + } + } + + for math.Abs(rd2) <= rgamsq || math.Abs(rd2) >= gamsq { + if p.Flag == blas.OffDiagonal { + p.H[0] = 1 + p.H[3] = 1 + p.Flag = blas.Rescaling + } else if p.Flag == blas.Diagonal { + p.H[1] = -1 + p.H[2] = 1 + p.Flag = blas.Rescaling + } + if math.Abs(rd2) <= rgamsq { + rd2 *= gam * gam + p.H[1] /= gam + p.H[3] /= gam + } else { + rd2 /= gam * gam + p.H[1] *= gam + p.H[3] *= gam + } + } + return +} + +// 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + + var h11, h12, h21, h22 float64 + var ix, iy int + switch p.Flag { + case blas.Identity: + return + case blas.Rescaling: + h11 = p.H[0] + h12 = p.H[2] + h21 = p.H[1] + h22 = p.H[3] + case blas.OffDiagonal: + h11 = 1 + h12 = p.H[2] + h21 = p.H[1] + h22 = 1 + case blas.Diagonal: + h11 = p.H[0] + h12 = 1 + h21 = -1 + h22 = p.H[3] + } + if incX < 0 { + ix = (-n + 1) * incX + } + if incY < 0 { + iy = (-n + 1) * incY + } + 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 + } + 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 + } +} + +// 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)*incX >= len(x) { + panic(badX) + } + if n < 1 { + if n == 0 { + return + } + panic(negativeN) + } + 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)) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1doubleBench_auto_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1doubleBench_auto_test.go new file mode 100644 index 00000000..08296957 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1doubleBench_auto_test.go @@ -0,0 +1,1685 @@ +// Code generated by "go run github.com/gonum/blas/testblas/benchautogen/autogen_bench_level1double.go"; DO NOT EDIT. + +// Copyright 2014 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 gonum + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +const ( + posInc1 = 5 + posInc2 = 3 + negInc1 = -3 + negInc2 = -4 + SMALL_SLICE = 10 + MEDIUM_SLICE = 1000 + LARGE_SLICE = 100000 + HUGE_SLICE = 10000000 +) + +func randomSlice(l, idx int) []float64 { + if idx < 0 { + idx = -idx + } + s := make([]float64, l*idx) + for i := range s { + s[i] = rand.Float64() + } + return s +} + +func benchmarkDdot(b *testing.B, n int, x []float64, incX int, y []float64, incY int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Ddot(n, x, incX, y, incY) + } +} + +func BenchmarkDdotSmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotSmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotSmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotSmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +func BenchmarkDdotHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDdot(b, n, x, incX, y, incY) +} + +/* ------------------ */ +func benchmarkDnrm2(b *testing.B, n int, x []float64, incX int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Dnrm2(n, x, incX) + } +} + +func BenchmarkDnrm2SmallUnitaryInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +func BenchmarkDnrm2SmallPosInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +func BenchmarkDnrm2MediumUnitaryInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +func BenchmarkDnrm2MediumPosInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +func BenchmarkDnrm2LargeUnitaryInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +func BenchmarkDnrm2LargePosInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +func BenchmarkDnrm2HugeUnitaryInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +func BenchmarkDnrm2HugePosInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDnrm2(b, n, x, incX) +} + +/* ------------------ */ +func benchmarkDasum(b *testing.B, n int, x []float64, incX int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Dasum(n, x, incX) + } +} + +func BenchmarkDasumSmallUnitaryInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +func BenchmarkDasumSmallPosInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +func BenchmarkDasumMediumUnitaryInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +func BenchmarkDasumMediumPosInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +func BenchmarkDasumLargeUnitaryInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +func BenchmarkDasumLargePosInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +func BenchmarkDasumHugeUnitaryInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +func BenchmarkDasumHugePosInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkDasum(b, n, x, incX) +} + +/* ------------------ */ +func benchmarkIdamax(b *testing.B, n int, x []float64, incX int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Idamax(n, x, incX) + } +} + +func BenchmarkIdamaxSmallUnitaryInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +func BenchmarkIdamaxSmallPosInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +func BenchmarkIdamaxMediumUnitaryInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +func BenchmarkIdamaxMediumPosInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +func BenchmarkIdamaxLargeUnitaryInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +func BenchmarkIdamaxLargePosInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +func BenchmarkIdamaxHugeUnitaryInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +func BenchmarkIdamaxHugePosInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + + benchmarkIdamax(b, n, x, incX) +} + +/* ------------------ */ +func benchmarkDswap(b *testing.B, n int, x []float64, incX int, y []float64, incY int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Dswap(n, x, incX, y, incY) + } +} + +func BenchmarkDswapSmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapSmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapSmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapSmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +func BenchmarkDswapHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDswap(b, n, x, incX, y, incY) +} + +/* ------------------ */ +func benchmarkDcopy(b *testing.B, n int, x []float64, incX int, y []float64, incY int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Dcopy(n, x, incX, y, incY) + } +} + +func BenchmarkDcopySmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopySmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopySmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopySmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +func BenchmarkDcopyHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + + benchmarkDcopy(b, n, x, incX, y, incY) +} + +/* ------------------ */ +func benchmarkDaxpy(b *testing.B, n int, alpha float64, x []float64, incX int, y []float64, incY int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Daxpy(n, alpha, x, incX, y, incY) + } +} + +func BenchmarkDaxpySmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpySmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpySmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpySmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +func BenchmarkDaxpyHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + alpha := 2.4 + benchmarkDaxpy(b, n, alpha, x, incX, y, incY) +} + +/* ------------------ */ +func benchmarkDrot(b *testing.B, n int, x []float64, incX int, y []float64, incY int, c, s float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Drot(n, x, incX, y, incY, c, s) + } +} + +func BenchmarkDrotSmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotSmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotSmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotSmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +func BenchmarkDrotHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + c := 0.89725836967 + s := 0.44150585279 + benchmarkDrot(b, n, x, incX, y, incY, c, s) +} + +/* ------------------ */ +func benchmarkDrotmOffDia(b *testing.B, n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Drotm(n, x, incX, y, incY, p) + } +} + +func BenchmarkDrotmOffDiaSmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaSmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaSmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaSmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmOffDiaHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375, 0}} + benchmarkDrotmOffDia(b, n, x, incX, y, incY, p) +} + +/* ------------------ */ +func benchmarkDrotmDia(b *testing.B, n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Drotm(n, x, incX, y, incY, p) + } +} + +func BenchmarkDrotmDiaSmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaSmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaSmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaSmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmDiaHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}} + benchmarkDrotmDia(b, n, x, incX, y, incY, p) +} + +/* ------------------ */ +func benchmarkDrotmResc(b *testing.B, n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Drotm(n, x, incX, y, incY, p) + } +} + +func BenchmarkDrotmRescSmallBothUnitary(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescSmallIncUni(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescSmallUniInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescSmallBothInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescMediumBothUnitary(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescMediumIncUni(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescMediumUniInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescMediumBothInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescLargeBothUnitary(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescLargeIncUni(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescLargeUniInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescLargeBothInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescHugeBothUnitary(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescHugeIncUni(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := 1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescHugeUniInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +func BenchmarkDrotmRescHugeBothInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + incY := negInc1 + y := randomSlice(n, incY) + p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}} + benchmarkDrotmResc(b, n, x, incX, y, incY, p) +} + +/* ------------------ */ +func benchmarkDscal(b *testing.B, n int, alpha float64, x []float64, incX int) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Dscal(n, alpha, x, incX) + } +} + +func BenchmarkDscalSmallUnitaryInc(b *testing.B) { + n := SMALL_SLICE + incX := 1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +func BenchmarkDscalSmallPosInc(b *testing.B) { + n := SMALL_SLICE + incX := posInc1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +func BenchmarkDscalMediumUnitaryInc(b *testing.B) { + n := MEDIUM_SLICE + incX := 1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +func BenchmarkDscalMediumPosInc(b *testing.B) { + n := MEDIUM_SLICE + incX := posInc1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +func BenchmarkDscalLargeUnitaryInc(b *testing.B) { + n := LARGE_SLICE + incX := 1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +func BenchmarkDscalLargePosInc(b *testing.B) { + n := LARGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +func BenchmarkDscalHugeUnitaryInc(b *testing.B) { + n := HUGE_SLICE + incX := 1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +func BenchmarkDscalHugePosInc(b *testing.B) { + n := HUGE_SLICE + incX := posInc1 + x := randomSlice(n, incX) + alpha := 2.4 + benchmarkDscal(b, n, alpha, x, incX) +} + +/* ------------------ */ diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1double_ddot.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1double_ddot.go new file mode 100644 index 00000000..30c01100 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1double_ddot.go @@ -0,0 +1,49 @@ +// 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(negativeN) + } + if incX == 1 && incY == 1 { + if len(x) < n { + panic(badLenX) + } + if len(y) < n { + panic(badLenY) + } + return f64.DotUnitary(x[:n], y) + } + 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(badLenX) + } + if iy >= len(y) || iy+(n-1)*incY >= len(y) { + panic(badLenY) + } + return f64.DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy)) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1double_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1double_test.go new file mode 100644 index 00000000..45adc85f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1double_test.go @@ -0,0 +1,61 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +var impl Implementation + +func TestDasum(t *testing.T) { + testblas.DasumTest(t, impl) +} + +func TestDaxpy(t *testing.T) { + testblas.DaxpyTest(t, impl) +} + +func TestDdot(t *testing.T) { + testblas.DdotTest(t, impl) +} + +func TestDnrm2(t *testing.T) { + testblas.Dnrm2Test(t, impl) +} + +func TestIdamax(t *testing.T) { + testblas.IdamaxTest(t, impl) +} + +func TestDswap(t *testing.T) { + testblas.DswapTest(t, impl) +} + +func TestDcopy(t *testing.T) { + testblas.DcopyTest(t, impl) +} + +func TestDrotg(t *testing.T) { + testblas.DrotgTest(t, impl) +} + +func TestDrotmg(t *testing.T) { + testblas.DrotmgTest(t, impl) +} + +func TestDrot(t *testing.T) { + testblas.DrotTest(t, impl) +} + +func TestDrotm(t *testing.T) { + testblas.DrotmTest(t, impl) +} + +func TestDscal(t *testing.T) { + testblas.DscalTest(t, impl) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1single.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1single.go new file mode 100644 index 00000000..8081c814 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1single.go @@ -0,0 +1,619 @@ +// 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 incX > 0 && (n-1)*incX >= len(x) { + panic(badX) + } + if n < 2 { + if n == 1 { + return math.Abs(x[0]) + } + if n == 0 { + return 0 + } + if n < 1 { + panic(negativeN) + } + } + 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(negativeN) + } + if incX < 1 { + if incX == 0 { + panic(zeroIncX) + } + return 0 + } + if incX > 0 && (n-1)*incX >= len(x) { + panic(badX) + } + 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 incX > 0 && (n-1)*incX >= len(x) { + panic(badX) + } + if n < 2 { + if n == 1 { + return 0 + } + if n == 0 { + return -1 // Netlib returns invalid index when n == 0 + } + if n < 1 { + panic(negativeN) + } + } + 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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 refence 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) { + var p1, p2, q1, q2, u float32 + + const ( + gam = 4096.0 + gamsq = 16777216.0 + rgamsq = 5.9604645e-8 + ) + + if d1 < 0 { + p.Flag = blas.Rescaling + return + } + + p2 = d2 * y1 + if p2 == 0 { + p.Flag = blas.Identity + rd1 = d1 + rd2 = d2 + rx1 = x1 + return + } + p1 = d1 * x1 + q2 = p2 * y1 + q1 = p1 * x1 + + absQ1 := math.Abs(q1) + absQ2 := math.Abs(q2) + + if absQ1 < absQ2 && q2 < 0 { + p.Flag = blas.Rescaling + return + } + + if d1 == 0 { + p.Flag = blas.Diagonal + p.H[0] = p1 / p2 + p.H[3] = x1 / y1 + u = 1 + p.H[0]*p.H[3] + rd1, rd2 = d2/u, d1/u + rx1 = y1 / u + return + } + + // Now we know that d1 != 0, and d2 != 0. If d2 == 0, it would be caught + // when p2 == 0, and if d1 == 0, then it is caught above + + if absQ1 > absQ2 { + p.H[1] = -y1 / x1 + p.H[2] = p2 / p1 + u = 1 - p.H[2]*p.H[1] + rd1 = d1 + rd2 = d2 + rx1 = x1 + p.Flag = blas.OffDiagonal + // u must be greater than zero because |q1| > |q2|, so check from netlib + // is unnecessary + // This is left in for ease of comparison with complex routines + //if u > 0 { + rd1 /= u + rd2 /= u + rx1 *= u + //} + } else { + p.Flag = blas.Diagonal + p.H[0] = p1 / p2 + p.H[3] = x1 / y1 + u = 1 + p.H[0]*p.H[3] + rd1 = d2 / u + rd2 = d1 / u + rx1 = y1 * u + } + + for rd1 <= rgamsq || rd1 >= gamsq { + if p.Flag == blas.OffDiagonal { + p.H[0] = 1 + p.H[3] = 1 + p.Flag = blas.Rescaling + } else if p.Flag == blas.Diagonal { + p.H[1] = -1 + p.H[2] = 1 + p.Flag = blas.Rescaling + } + if rd1 <= rgamsq { + rd1 *= gam * gam + rx1 /= gam + p.H[0] /= gam + p.H[2] /= gam + } else { + rd1 /= gam * gam + rx1 *= gam + p.H[0] *= gam + p.H[2] *= gam + } + } + + for math.Abs(rd2) <= rgamsq || math.Abs(rd2) >= gamsq { + if p.Flag == blas.OffDiagonal { + p.H[0] = 1 + p.H[3] = 1 + p.Flag = blas.Rescaling + } else if p.Flag == blas.Diagonal { + p.H[1] = -1 + p.H[2] = 1 + p.Flag = blas.Rescaling + } + if math.Abs(rd2) <= rgamsq { + rd2 *= gam * gam + p.H[1] /= gam + p.H[3] /= gam + } else { + rd2 /= gam * gam + p.H[1] *= gam + p.H[3] *= gam + } + } + return +} + +// 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if 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(negativeN) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + + var h11, h12, h21, h22 float32 + var ix, iy int + switch p.Flag { + case blas.Identity: + return + case blas.Rescaling: + h11 = p.H[0] + h12 = p.H[2] + h21 = p.H[1] + h22 = p.H[3] + case blas.OffDiagonal: + h11 = 1 + h12 = p.H[2] + h21 = p.H[1] + h22 = 1 + case blas.Diagonal: + h11 = p.H[0] + h12 = 1 + h21 = -1 + h22 = p.H[3] + } + if incX < 0 { + ix = (-n + 1) * incX + } + if incY < 0 { + iy = (-n + 1) * incY + } + 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 + } + 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 + } +} + +// 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)*incX >= len(x) { + panic(badX) + } + if n < 1 { + if n == 0 { + return + } + panic(negativeN) + } + 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)) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1single_dsdot.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1single_dsdot.go new file mode 100644 index 00000000..cfe6e75b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1single_dsdot.go @@ -0,0 +1,53 @@ +// 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(negativeN) + } + if incX == 1 && incY == 1 { + if len(x) < n { + panic(badLenX) + } + if len(y) < n { + panic(badLenY) + } + return f32.DdotUnitary(x[:n], y) + } + 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(badLenX) + } + if iy >= len(y) || iy+(n-1)*incY >= len(y) { + panic(badLenY) + } + return f32.DdotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy)) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1single_sdot.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1single_sdot.go new file mode 100644 index 00000000..cf930ecf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1single_sdot.go @@ -0,0 +1,53 @@ +// 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(negativeN) + } + if incX == 1 && incY == 1 { + if len(x) < n { + panic(badLenX) + } + if len(y) < n { + panic(badLenY) + } + return f32.DotUnitary(x[:n], y) + } + 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(badLenX) + } + if iy >= len(y) || iy+(n-1)*incY >= len(y) { + panic(badLenY) + } + return f32.DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy)) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level1single_sdsdot.go b/vendor/gonum.org/v1/gonum/blas/gonum/level1single_sdsdot.go new file mode 100644 index 00000000..600c2f99 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level1single_sdsdot.go @@ -0,0 +1,53 @@ +// 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(negativeN) + } + if incX == 1 && incY == 1 { + if len(x) < n { + panic(badLenX) + } + if len(y) < n { + panic(badLenY) + } + return alpha + float32(f32.DdotUnitary(x[:n], y)) + } + 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(badLenX) + } + if iy >= len(y) || iy+(n-1)*incY >= len(y) { + panic(badLenY) + } + return alpha + float32(f32.DdotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128.go b/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128.go new file mode 100644 index 00000000..ca241752 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128.go @@ -0,0 +1,289 @@ +// 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/cmplx" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/internal/asm/c128" +) + +// Zgerc performs the rank-one operation +// A += alpha * x * y^H +// where A is an m×n dense matrix, alpha is a scalar, x is an m element vector, +// and y is an n element vector. +func (Implementation) Zgerc(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) { + checkZMatrix('A', m, n, a, lda) + checkZVector('x', m, x, incX) + checkZVector('y', n, y, incY) + + if m == 0 || n == 0 || alpha == 0 { + return + } + + var kx, jy int + if incX < 0 { + kx = (1 - m) * incX + } + if incY < 0 { + jy = (1 - n) * incY + } + for j := 0; j < n; j++ { + if y[jy] != 0 { + tmp := alpha * cmplx.Conj(y[jy]) + c128.AxpyInc(tmp, x, a[j:], uintptr(m), uintptr(incX), uintptr(lda), uintptr(kx), 0) + } + jy += incY + } +} + +// Zgeru performs the rank-one operation +// A += alpha * x * y^T +// where A is an m×n dense matrix, alpha is a scalar, x is an m element vector, +// and y is an n element vector. +func (Implementation) Zgeru(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) { + checkZMatrix('A', m, n, a, lda) + checkZVector('x', m, x, incX) + checkZVector('y', n, y, incY) + + if m == 0 || n == 0 || alpha == 0 { + return + } + + var kx int + if incX < 0 { + kx = (1 - m) * incX + } + if incY == 1 { + for i := 0; i < m; i++ { + if x[kx] != 0 { + tmp := alpha * x[kx] + c128.AxpyUnitary(tmp, y[:n], a[i*lda:i*lda+n]) + } + kx += incX + } + return + } + var jy int + if incY < 0 { + jy = (1 - n) * incY + } + for i := 0; i < m; i++ { + if x[kx] != 0 { + tmp := alpha * x[kx] + c128.AxpyInc(tmp, y, a[i*lda:i*lda+n], uintptr(n), uintptr(incY), 1, uintptr(jy), 0) + } + kx += incX + } +} + +// Zher performs the Hermitian rank-one operation +// A += alpha * x * x^H +// where A is an n×n Hermitian matrix, alpha is a real scalar, and x is an n +// element vector. On entry, the imaginary parts of the diagonal elements of A +// are ignored and assumed to be zero, on return they will be set to zero. +func (Implementation) Zher(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, a []complex128, lda int) { + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + checkZMatrix('A', n, n, a, lda) + checkZVector('x', n, x, incX) + + if n == 0 || alpha == 0 { + return + } + + var kx int + if incX < 0 { + kx = (1 - n) * incX + } + if uplo == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + if x[i] != 0 { + tmp := complex(alpha*real(x[i]), alpha*imag(x[i])) + aii := real(a[i*lda+i]) + xtmp := real(tmp * cmplx.Conj(x[i])) + a[i*lda+i] = complex(aii+xtmp, 0) + for j := i + 1; j < n; j++ { + a[i*lda+j] += tmp * cmplx.Conj(x[j]) + } + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + } + return + } + + ix := kx + for i := 0; i < n; i++ { + if x[ix] != 0 { + tmp := complex(alpha*real(x[ix]), alpha*imag(x[ix])) + aii := real(a[i*lda+i]) + xtmp := real(tmp * cmplx.Conj(x[ix])) + a[i*lda+i] = complex(aii+xtmp, 0) + jx := ix + incX + for j := i + 1; j < n; j++ { + a[i*lda+j] += tmp * cmplx.Conj(x[jx]) + jx += incX + } + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + ix += incX + } + return + } + + if incX == 1 { + for i := 0; i < n; i++ { + if x[i] != 0 { + tmp := complex(alpha*real(x[i]), alpha*imag(x[i])) + for j := 0; j < i; j++ { + a[i*lda+j] += tmp * cmplx.Conj(x[j]) + } + aii := real(a[i*lda+i]) + xtmp := real(tmp * cmplx.Conj(x[i])) + a[i*lda+i] = complex(aii+xtmp, 0) + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + } + return + } + + ix := kx + for i := 0; i < n; i++ { + if x[ix] != 0 { + tmp := complex(alpha*real(x[ix]), alpha*imag(x[ix])) + jx := kx + for j := 0; j < i; j++ { + a[i*lda+j] += tmp * cmplx.Conj(x[jx]) + jx += incX + } + aii := real(a[i*lda+i]) + xtmp := real(tmp * cmplx.Conj(x[ix])) + a[i*lda+i] = complex(aii+xtmp, 0) + + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + ix += incX + } +} + +// Zher2 performs the Hermitian rank-two operation +// A += alpha*x*y^H + conj(alpha)*y*x^H +// where alpha is a scalar, x and y are n element vectors and A is an n×n +// Hermitian matrix. On entry, the imaginary parts of the diagonal elements are +// ignored and assumed to be zero. On return they will be set to zero. +func (Implementation) Zher2(uplo blas.Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) { + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + checkZMatrix('A', n, n, a, lda) + checkZVector('x', n, x, incX) + checkZVector('y', n, y, incY) + + if n == 0 || alpha == 0 { + return + } + + var kx, ky int + var ix, iy int + if incX != 1 || incY != 1 { + if incX < 0 { + kx = (1 - n) * incX + } + if incY < 0 { + ky = (1 - n) * incY + } + ix = kx + iy = ky + } + if uplo == blas.Upper { + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + if x[i] != 0 || y[i] != 0 { + tmp1 := alpha * x[i] + tmp2 := cmplx.Conj(alpha) * y[i] + aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i])) + a[i*lda+i] = complex(aii, 0) + for j := i + 1; j < n; j++ { + a[i*lda+j] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j]) + } + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + } + return + } + for i := 0; i < n; i++ { + if x[i] != 0 || y[i] != 0 { + tmp1 := alpha * x[ix] + tmp2 := cmplx.Conj(alpha) * y[iy] + aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix])) + a[i*lda+i] = complex(aii, 0) + jx := ix + incX + jy := iy + incY + for j := i + 1; j < n; j++ { + a[i*lda+j] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx]) + jx += incX + jy += incY + } + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + ix += incX + iy += incY + } + return + } + + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + if x[i] != 0 || y[i] != 0 { + tmp1 := alpha * x[i] + tmp2 := cmplx.Conj(alpha) * y[i] + for j := 0; j < i; j++ { + a[i*lda+j] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j]) + } + aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i])) + a[i*lda+i] = complex(aii, 0) + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + } + return + } + for i := 0; i < n; i++ { + if x[i] != 0 || y[i] != 0 { + tmp1 := alpha * x[ix] + tmp2 := cmplx.Conj(alpha) * y[iy] + jx := kx + jy := ky + for j := 0; j < i; j++ { + a[i*lda+j] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx]) + jx += incX + jy += incY + } + aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix])) + a[i*lda+i] = complex(aii, 0) + } else { + aii := real(a[i*lda+i]) + a[i*lda+i] = complex(aii, 0) + } + ix += incX + iy += incY + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128_bench_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128_bench_test.go new file mode 100644 index 00000000..915a1918 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128_bench_test.go @@ -0,0 +1,49 @@ +// Copyright ©2017 The Gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package gonum + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +var benchSinkZ []complex128 + +func BenchmarkZher(b *testing.B) { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, n := range []int{10, 100, 1000, 10000} { + for _, inc := range []int{1, 10, 1000} { + benchmarkZher(b, uplo, n, inc) + } + } + } +} + +func benchmarkZher(b *testing.B, uplo blas.Uplo, n, inc int) { + b.Run(fmt.Sprintf("Uplo%d-N%d-Inc%d", uplo, n, inc), func(b *testing.B) { + rnd := rand.New(rand.NewSource(1)) + alpha := rnd.NormFloat64() + x := make([]complex128, (n-1)*inc+1) + for i := range x { + x[i] = complex(rnd.NormFloat64(), rnd.NormFloat64()) + } + a := make([]complex128, len(benchSinkZ)) + for i := range a { + a[i] = complex(rnd.NormFloat64(), rnd.NormFloat64()) + } + benchSinkZ = make([]complex128, n*n) + copy(benchSinkZ, a) + b.ResetTimer() + for i := 0; i < b.N; i++ { + impl.Zher(uplo, n, alpha, x, inc, benchSinkZ, n) + copy(benchSinkZ, a) + } + }) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128_test.go new file mode 100644 index 00000000..0649675a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128_test.go @@ -0,0 +1,27 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func TestZgerc(t *testing.T) { + testblas.ZgercTest(t, impl) +} + +func TestZgeru(t *testing.T) { + testblas.ZgeruTest(t, impl) +} + +func TestZher(t *testing.T) { + testblas.ZherTest(t, impl) +} + +func TestZher2(t *testing.T) { + testblas.Zher2Test(t, impl) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level2double.go b/vendor/gonum.org/v1/gonum/blas/gonum/level2double.go new file mode 100644 index 00000000..9b828c2e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level2double.go @@ -0,0 +1,2234 @@ +// 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.Float64Level2 = Implementation{} + +// Dgemv computes +// y = alpha * a * x + beta * y if tA = blas.NoTrans +// y = alpha * A^T * 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 is a scalar. +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 + } + if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) { + panic(badY) + } + if lda*(m-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + + // Quick return if possible + if m == 0 || n == 0 || (alpha == 0 && beta == 1) { + return + } + + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(lenY - 1) * incY + } + + // First form y := beta * y + if incY > 0 { + Implementation{}.Dscal(lenY, beta, y, incY) + } else { + Implementation{}.Dscal(lenY, beta, y, -incY) + } + + if alpha == 0 { + return + } + + // Form y := alpha * A * x + y + if tA == blas.NoTrans { + if incX == 1 && incY == 1 { + for i := 0; i < m; i++ { + y[i] += alpha * f64.DotUnitary(a[lda*i:lda*i+n], x) + } + return + } + iy := ky + for i := 0; i < m; i++ { + y[iy] += alpha * f64.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 { + f64.AxpyUnitaryTo(y, tmp, a[lda*i:lda*i+n], y) + } + } + return + } + ix := kx + for i := 0; i < m; i++ { + tmp := alpha * x[ix] + if tmp != 0 { + f64.AxpyInc(tmp, a[lda*i:lda*i+n], y, uintptr(n), 1, uintptr(incY), 0, uintptr(ky)) + } + ix += incX + } +} + +// Dger performs the rank-one operation +// A += alpha * x * y^T +// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar. +func (Implementation) Dger(m, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int) { + // Check inputs + if m < 0 { + panic("m < 0") + } + if n < 0 { + panic(negativeN) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (m-1)*incX >= len(x)) || (incX < 0 && (1-m)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(m-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if lda < max(1, n) { + panic(badLdA) + } + + // Quick return if possible + if m == 0 || n == 0 || alpha == 0 { + return + } + + var ky, kx int + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + + if incX > 0 { + kx = 0 + } else { + kx = -(m - 1) * incX + } + + if incX == 1 && incY == 1 { + x = x[:m] + y = y[:n] + for i, xv := range x { + tmp := alpha * xv + if tmp != 0 { + atmp := a[i*lda : i*lda+n] + f64.AxpyUnitaryTo(atmp, tmp, y, atmp) + } + } + return + } + + ix := kx + for i := 0; i < m; i++ { + tmp := alpha * x[ix] + if tmp != 0 { + f64.AxpyInc(tmp, y, a[i*lda:i*lda+n], uintptr(n), uintptr(incY), 1, uintptr(ky), 0) + } + ix += incX + } +} + +// Dgbmv computes +// y = alpha * A * x + beta * y if tA == blas.NoTrans +// y = alpha * A^T * x + beta * y if tA == blas.Trans or blas.ConjTrans +// where a is an m×n band matrix kL subdiagonals and kU super-diagonals, and +// m and n refer to the size of the full dense matrix it represents. +// x and y are vectors, and alpha and beta are scalars. +func (Implementation) Dgbmv(tA blas.Transpose, m, n, kL, kU 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 kL < 0 { + panic(kLLT0) + } + if kL < 0 { + panic(kULT0) + } + if lda < kL+kU+1 { + 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 + } + if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) { + panic(badY) + } + if lda*(min(m, n+kL)-1)+kL+kU+1 > len(a) || lda < kL+kU+1 { + panic(badLdA) + } + + // Quick return if possible + if m == 0 || n == 0 || (alpha == 0 && beta == 1) { + return + } + + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(lenY - 1) * incY + } + + // First form y := beta * y + if incY > 0 { + Implementation{}.Dscal(lenY, beta, y, incY) + } else { + Implementation{}.Dscal(lenY, beta, y, -incY) + } + + if alpha == 0 { + return + } + + // i and j are indices of the compacted banded matrix. + // off is the offset into the dense matrix (off + j = densej) + ld := min(m, n) + nCol := kU + 1 + kL + if tA == blas.NoTrans { + iy := ky + if incX == 1 { + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + xtmp := x[off : off+u-l] + var sum float64 + for j, v := range atmp { + sum += xtmp[j] * v + } + y[iy] += sum * alpha + iy += incY + } + return + } + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + jx := kx + var sum float64 + for _, v := range atmp { + sum += x[off*incX+jx] * v + jx += incX + } + y[iy] += sum * alpha + iy += incY + } + return + } + if incX == 1 { + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + tmp := alpha * x[i] + jy := ky + for _, v := range atmp { + y[jy+off*incY] += tmp * v + jy += incY + } + } + return + } + ix := kx + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + tmp := alpha * x[ix] + jy := ky + for _, v := range atmp { + y[jy+off*incY] += tmp * v + jy += incY + } + ix += incX + } +} + +// Dtrmv computes +// x = A * x if tA == blas.NoTrans +// x = A^T * x if tA == blas.Trans or blas.ConjTrans +// A is an n×n Triangular matrix and x is a vector. +func (Implementation) Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, lda int, x []float64, incX int) { + 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 n < 0 { + panic(nLT0) + } + if lda < n { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if n == 0 { + return + } + nonUnit := d != blas.Unit + if n == 1 { + if nonUnit { + x[0] *= a[0] + } + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + ilda := i * lda + var tmp float64 + if nonUnit { + tmp = a[ilda+i] * x[i] + } else { + tmp = x[i] + } + xtmp := x[i+1:] + x[i] = tmp + f64.DotUnitary(a[ilda+i+1:ilda+n], xtmp) + } + return + } + ix := kx + for i := 0; i < n; i++ { + ilda := i * lda + var tmp float64 + if nonUnit { + tmp = a[ilda+i] * x[ix] + } else { + tmp = x[ix] + } + x[ix] = tmp + f64.DotInc(x, a[ilda+i+1:ilda+n], uintptr(n-i-1), uintptr(incX), 1, uintptr(ix+incX), 0) + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + ilda := i * lda + var tmp float64 + if nonUnit { + tmp += a[ilda+i] * x[i] + } else { + tmp = x[i] + } + x[i] = tmp + f64.DotUnitary(a[ilda:ilda+i], x) + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + ilda := i * lda + var tmp float64 + if nonUnit { + tmp = a[ilda+i] * x[ix] + } else { + tmp = x[ix] + } + x[ix] = tmp + f64.DotInc(x, a[ilda:ilda+i], uintptr(i), uintptr(incX), 1, uintptr(kx), 0) + ix -= incX + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + ilda := i * lda + xi := x[i] + f64.AxpyUnitary(xi, a[ilda+i+1:ilda+n], x[i+1:n]) + if nonUnit { + x[i] *= a[ilda+i] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + ilda := i * lda + xi := x[ix] + f64.AxpyInc(xi, a[ilda+i+1:ilda+n], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(kx+(i+1)*incX)) + if nonUnit { + x[ix] *= a[ilda+i] + } + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + ilda := i * lda + xi := x[i] + f64.AxpyUnitary(xi, a[ilda:ilda+i], x) + if nonUnit { + x[i] *= a[i*lda+i] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + ilda := i * lda + xi := x[ix] + f64.AxpyInc(xi, a[ilda:ilda+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx)) + if nonUnit { + x[ix] *= a[ilda+i] + } + ix += incX + } +} + +// Dtrsv solves +// A * x = b if tA == blas.NoTrans +// A^T * x = b if tA == blas.Trans or blas.ConjTrans +// 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 (Implementation) Dtrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, lda int, x []float64, incX int) { + // Test the input parameters + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if d != blas.NonUnit && d != blas.Unit { + panic(badDiag) + } + if n < 0 { + panic(nLT0) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + // Quick return if possible + if n == 0 { + return + } + if n == 1 { + if d == blas.NonUnit { + x[0] /= a[0] + } + return + } + + var kx int + if incX < 0 { + kx = -(n - 1) * incX + } + nonUnit := d == blas.NonUnit + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + var sum float64 + atmp := a[i*lda+i+1 : i*lda+n] + for j, v := range atmp { + jv := i + j + 1 + sum += x[jv] * v + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda+i] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + var sum float64 + jx := ix + incX + atmp := a[i*lda+i+1 : i*lda+n] + for _, v := range atmp { + sum += x[jx] * v + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda+i] + } + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + var sum float64 + atmp := a[i*lda : i*lda+i] + for j, v := range atmp { + sum += x[j] * v + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda+i] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + var sum float64 + atmp := a[i*lda : i*lda+i] + for _, v := range atmp { + sum += x[jx] * v + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda+i] + } + ix += incX + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + if nonUnit { + x[i] /= a[i*lda+i] + } + xi := x[i] + atmp := a[i*lda+i+1 : i*lda+n] + for j, v := range atmp { + jv := j + i + 1 + x[jv] -= v * xi + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + if nonUnit { + x[ix] /= a[i*lda+i] + } + xi := x[ix] + jx := kx + (i+1)*incX + atmp := a[i*lda+i+1 : i*lda+n] + for _, v := range atmp { + x[jx] -= v * xi + jx += incX + } + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[i] /= a[i*lda+i] + } + xi := x[i] + atmp := a[i*lda : i*lda+i] + for j, v := range atmp { + x[j] -= v * xi + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[ix] /= a[i*lda+i] + } + xi := x[ix] + jx := kx + atmp := a[i*lda : i*lda+i] + for _, v := range atmp { + x[jx] -= v * xi + jx += incX + } + ix -= incX + } +} + +// Dsymv 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 (Implementation) Dsymv(ul blas.Uplo, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) { + // Check inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(negativeN) + } + if lda > 1 && lda < n { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + // Quick return if possible + if n == 0 || (alpha == 0 && beta == 1) { + return + } + + // Set up start points + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + + // Form y = beta * y + if beta != 1 { + if incY > 0 { + Implementation{}.Dscal(n, beta, y, incY) + } else { + Implementation{}.Dscal(n, beta, y, -incY) + } + } + + if alpha == 0 { + return + } + + if n == 1 { + y[0] += alpha * a[0] * x[0] + return + } + + if ul == blas.Upper { + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + xv := x[i] * alpha + sum := x[i] * a[i*lda+i] + jy := ky + (i+1)*incY + atmp := a[i*lda+i+1 : i*lda+n] + for j, v := range atmp { + jp := j + i + 1 + sum += x[jp] * v + y[jy] += xv * v + jy += incY + } + y[iy] += alpha * sum + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + xv := x[ix] * alpha + sum := x[ix] * a[i*lda+i] + jx := kx + (i+1)*incX + jy := ky + (i+1)*incY + atmp := a[i*lda+i+1 : i*lda+n] + for _, v := range atmp { + sum += x[jx] * v + y[jy] += xv * v + jx += incX + jy += incY + } + y[iy] += alpha * sum + ix += incX + iy += incY + } + return + } + // Cases where a is lower triangular. + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + jy := ky + xv := alpha * x[i] + atmp := a[i*lda : i*lda+i] + var sum float64 + for j, v := range atmp { + sum += x[j] * v + y[jy] += xv * v + jy += incY + } + sum += x[i] * a[i*lda+i] + sum *= alpha + y[iy] += sum + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + jy := ky + xv := alpha * x[ix] + atmp := a[i*lda : i*lda+i] + var sum float64 + for _, v := range atmp { + sum += x[jx] * v + y[jy] += xv * v + jx += incX + jy += incY + } + sum += x[ix] * a[i*lda+i] + sum *= alpha + y[iy] += sum + ix += incX + iy += incY + } +} + +// Dtbmv computes +// x = A * x if tA == blas.NoTrans +// x = A^T * x if tA == blas.Trans or blas.ConjTrans +// where A is an n×n triangular banded matrix with k diagonals, and x is a vector. +func (Implementation) Dtbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []float64, lda int, x []float64, incX int) { + 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 n < 0 { + panic(nLT0) + } + if k < 0 { + panic(kLT0) + } + if lda*(n-1)+k+1 > len(a) || lda < k+1 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } else if incX != 1 { + kx = 0 + } + + nonunit := d != blas.Unit + + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + u := min(1+k, n-i) + var sum float64 + atmp := a[i*lda:] + xtmp := x[i:] + for j := 1; j < u; j++ { + sum += xtmp[j] * atmp[j] + } + if nonunit { + sum += xtmp[0] * atmp[0] + } else { + sum += xtmp[0] + } + x[i] = sum + } + return + } + ix := kx + for i := 0; i < n; i++ { + u := min(1+k, n-i) + var sum float64 + atmp := a[i*lda:] + jx := incX + for j := 1; j < u; j++ { + sum += x[ix+jx] * atmp[j] + jx += incX + } + if nonunit { + sum += x[ix] * atmp[0] + } else { + sum += x[ix] + } + x[ix] = sum + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + l := max(0, k-i) + atmp := a[i*lda:] + var sum float64 + for j := l; j < k; j++ { + sum += x[i-k+j] * atmp[j] + } + if nonunit { + sum += x[i] * atmp[k] + } else { + sum += x[i] + } + x[i] = sum + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + l := max(0, k-i) + atmp := a[i*lda:] + var sum float64 + jx := l * incX + for j := l; j < k; j++ { + sum += x[ix-k*incX+jx] * atmp[j] + jx += incX + } + if nonunit { + sum += x[ix] * atmp[k] + } else { + sum += x[ix] + } + x[ix] = sum + ix -= incX + } + return + } + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + u := k + 1 + if i < u { + u = i + 1 + } + var sum float64 + for j := 1; j < u; j++ { + sum += x[i-j] * a[(i-j)*lda+j] + } + if nonunit { + sum += x[i] * a[i*lda] + } else { + sum += x[i] + } + x[i] = sum + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + u := k + 1 + if i < u { + u = i + 1 + } + var sum float64 + jx := incX + for j := 1; j < u; j++ { + sum += x[ix-jx] * a[(i-j)*lda+j] + jx += incX + } + if nonunit { + sum += x[ix] * a[i*lda] + } else { + sum += x[ix] + } + x[ix] = sum + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + u := k + if i+k >= n { + u = n - i - 1 + } + var sum float64 + for j := 0; j < u; j++ { + sum += x[i+j+1] * a[(i+j+1)*lda+k-j-1] + } + if nonunit { + sum += x[i] * a[i*lda+k] + } else { + sum += x[i] + } + x[i] = sum + } + return + } + ix := kx + for i := 0; i < n; i++ { + u := k + if i+k >= n { + u = n - i - 1 + } + var ( + sum float64 + jx int + ) + for j := 0; j < u; j++ { + sum += x[ix+jx+incX] * a[(i+j+1)*lda+k-j-1] + jx += incX + } + if nonunit { + sum += x[ix] * a[i*lda+k] + } else { + sum += x[ix] + } + x[ix] = sum + ix += incX + } +} + +// Dtpmv computes +// x = A * x if tA == blas.NoTrans +// x = A^T * x if tA == blas.Trans or blas.ConjTrans +// where A is an n×n unit triangular matrix in packed format, and x is a vector. +func (Implementation) Dtpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float64, x []float64, incX int) { + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if d != blas.NonUnit && d != blas.Unit { + panic(badDiag) + } + if n < 0 { + panic(nLT0) + } + if len(ap) < (n*(n+1))/2 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } + + nonUnit := d == blas.NonUnit + var offset int // Offset is the index of (i,i) + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + xi := x[i] + if nonUnit { + xi *= ap[offset] + } + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + for j, v := range atmp { + xi += v * xtmp[j] + } + x[i] = xi + offset += n - i + } + return + } + ix := kx + for i := 0; i < n; i++ { + xix := x[ix] + if nonUnit { + xix *= ap[offset] + } + atmp := ap[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + for _, v := range atmp { + xix += v * x[jx] + jx += incX + } + x[ix] = xix + offset += n - i + ix += incX + } + return + } + if incX == 1 { + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xi := x[i] + if nonUnit { + xi *= ap[offset] + } + atmp := ap[offset-i : offset] + for j, v := range atmp { + xi += v * x[j] + } + x[i] = xi + offset -= i + 1 + } + return + } + ix := kx + (n-1)*incX + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xix := x[ix] + if nonUnit { + xix *= ap[offset] + } + atmp := ap[offset-i : offset] + jx := kx + for _, v := range atmp { + xix += v * x[jx] + jx += incX + } + x[ix] = xix + offset -= i + 1 + ix -= incX + } + return + } + // Cases where ap is transposed. + if ul == blas.Upper { + if incX == 1 { + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xi := x[i] + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + for j, v := range atmp { + xtmp[j] += v * xi + } + if nonUnit { + x[i] *= ap[offset] + } + offset -= n - i + 1 + } + return + } + ix := kx + (n-1)*incX + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xix := x[ix] + jx := kx + (i+1)*incX + atmp := ap[offset+1 : offset+n-i] + for _, v := range atmp { + x[jx] += v * xix + jx += incX + } + if nonUnit { + x[ix] *= ap[offset] + } + offset -= n - i + 1 + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + xi := x[i] + atmp := ap[offset-i : offset] + for j, v := range atmp { + x[j] += v * xi + } + if nonUnit { + x[i] *= ap[offset] + } + offset += i + 2 + } + return + } + ix := kx + for i := 0; i < n; i++ { + xix := x[ix] + jx := kx + atmp := ap[offset-i : offset] + for _, v := range atmp { + x[jx] += v * xix + jx += incX + } + if nonUnit { + x[ix] *= ap[offset] + } + ix += incX + offset += i + 2 + } +} + +// Dtbsv solves +// A * x = b +// where A is an n×n triangular banded matrix with k diagonals 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 (Implementation) Dtbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []float64, lda int, x []float64, incX int) { + 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 n < 0 { + panic(nLT0) + } + if lda*(n-1)+k+1 > len(a) || lda < k+1 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX < 0 { + kx = -(n - 1) * incX + } else { + kx = 0 + } + nonUnit := d == blas.NonUnit + // Form x = A^-1 x. + // Several cases below use subslices for speed improvement. + // The incX != 1 cases usually do not because incX may be negative. + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + bands := k + if i+bands >= n { + bands = n - i - 1 + } + atmp := a[i*lda+1:] + xtmp := x[i+1 : i+bands+1] + var sum float64 + for j, v := range xtmp { + sum += v * atmp[j] + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + max := k + 1 + if i+max > n { + max = n - i + } + atmp := a[i*lda:] + var ( + jx int + sum float64 + ) + for j := 1; j < max; j++ { + jx += incX + sum += x[ix+jx] * atmp[j] + } + x[ix] -= sum + if nonUnit { + x[ix] /= atmp[0] + } + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + atmp := a[i*lda+k-bands:] + xtmp := x[i-bands : i] + var sum float64 + for j, v := range xtmp { + sum += v * atmp[j] + } + x[i] -= sum + if nonUnit { + x[i] /= atmp[bands] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + atmp := a[i*lda+k-bands:] + var ( + sum float64 + jx int + ) + for j := 0; j < bands; j++ { + sum += x[ix-bands*incX+jx] * atmp[j] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= atmp[bands] + } + ix += incX + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + var sum float64 + for j := 0; j < bands; j++ { + sum += x[i-bands+j] * a[(i-bands+j)*lda+bands-j] + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + var ( + sum float64 + jx int + ) + for j := 0; j < bands; j++ { + sum += x[ix-bands*incX+jx] * a[(i-bands+j)*lda+bands-j] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda] + } + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + bands := k + if i+bands >= n { + bands = n - i - 1 + } + var sum float64 + xtmp := x[i+1 : i+1+bands] + for j, v := range xtmp { + sum += v * a[(i+j+1)*lda+k-j-1] + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda+k] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + bands := k + if i+bands >= n { + bands = n - i - 1 + } + var ( + sum float64 + jx int + ) + for j := 0; j < bands; j++ { + sum += x[ix+jx+incX] * a[(i+j+1)*lda+k-j-1] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda+k] + } + ix -= incX + } +} + +// Dsbmv performs +// y = alpha * A * x + beta * y +// where A is an n×n symmetric banded matrix, x and y are vectors, and alpha +// and beta are scalars. +func (Implementation) Dsbmv(ul blas.Uplo, n, k int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(n-1)+k+1 > len(a) || lda < k+1 { + panic(badLdA) + } + + // Quick return if possible + if n == 0 || (alpha == 0 && beta == 1) { + return + } + + // Set up indexes + lenX := n + lenY := n + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(lenY - 1) * incY + } + + // First form y := beta * y + if incY > 0 { + Implementation{}.Dscal(lenY, beta, y, incY) + } else { + Implementation{}.Dscal(lenY, beta, y, -incY) + } + + if alpha == 0 { + return + } + + if ul == blas.Upper { + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + atmp := a[i*lda:] + tmp := alpha * x[i] + sum := tmp * atmp[0] + u := min(k, n-i-1) + jy := incY + for j := 1; j <= u; j++ { + v := atmp[j] + sum += alpha * x[i+j] * v + y[iy+jy] += tmp * v + jy += incY + } + y[iy] += sum + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + atmp := a[i*lda:] + tmp := alpha * x[ix] + sum := tmp * atmp[0] + u := min(k, n-i-1) + jx := incX + jy := incY + for j := 1; j <= u; j++ { + v := atmp[j] + sum += alpha * x[ix+jx] * v + y[iy+jy] += tmp * v + jx += incX + jy += incY + } + y[iy] += sum + ix += incX + iy += incY + } + return + } + + // Casses where a has bands below the diagonal. + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + l := max(0, k-i) + tmp := alpha * x[i] + jy := l * incY + atmp := a[i*lda:] + for j := l; j < k; j++ { + v := atmp[j] + y[iy] += alpha * v * x[i-k+j] + y[iy-k*incY+jy] += tmp * v + jy += incY + } + y[iy] += tmp * atmp[k] + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + l := max(0, k-i) + tmp := alpha * x[ix] + jx := l * incX + jy := l * incY + atmp := a[i*lda:] + for j := l; j < k; j++ { + v := atmp[j] + y[iy] += alpha * v * x[ix-k*incX+jx] + y[iy-k*incY+jy] += tmp * v + jx += incX + jy += incY + } + y[iy] += tmp * atmp[k] + ix += incX + iy += incY + } +} + +// Dsyr performs the rank-one update +// a += alpha * x * x^T +// where a is an n×n symmetric matrix, and x is a vector. +func (Implementation) Dsyr(ul blas.Uplo, n int, alpha float64, x []float64, incX int, a []float64, lda int) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if alpha == 0 || n == 0 { + return + } + + lenX := n + var kx int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + tmp := x[i] * alpha + if tmp != 0 { + atmp := a[i*lda+i : i*lda+n] + xtmp := x[i:n] + for j, v := range xtmp { + atmp[j] += v * tmp + } + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + tmp := x[ix] * alpha + if tmp != 0 { + jx := ix + atmp := a[i*lda:] + for j := i; j < n; j++ { + atmp[j] += x[jx] * tmp + jx += incX + } + } + ix += incX + } + return + } + // Cases where a is lower triangular. + if incX == 1 { + for i := 0; i < n; i++ { + tmp := x[i] * alpha + if tmp != 0 { + atmp := a[i*lda:] + xtmp := x[:i+1] + for j, v := range xtmp { + atmp[j] += tmp * v + } + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + tmp := x[ix] * alpha + if tmp != 0 { + atmp := a[i*lda:] + jx := kx + for j := 0; j < i+1; j++ { + atmp[j] += tmp * x[jx] + jx += incX + } + } + ix += incX + } +} + +// Dsyr2 performs the symmetric rank-two update +// A += alpha * x * y^T + alpha * y * x^T +// where A is a symmetric n×n matrix, x and y are vectors, and alpha is a scalar. +func (Implementation) Dsyr2(ul blas.Uplo, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if alpha == 0 { + return + } + + var ky, kx int + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + if ul == blas.Upper { + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + xi := x[i] + yi := y[i] + atmp := a[i*lda:] + for j := i; j < n; j++ { + atmp[j] += alpha * (xi*y[j] + x[j]*yi) + } + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + i*incX + jy := ky + i*incY + xi := x[ix] + yi := y[iy] + atmp := a[i*lda:] + for j := i; j < n; j++ { + atmp[j] += alpha * (xi*y[jy] + x[jx]*yi) + jx += incX + jy += incY + } + ix += incX + iy += incY + } + return + } + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + xi := x[i] + yi := y[i] + atmp := a[i*lda:] + for j := 0; j <= i; j++ { + atmp[j] += alpha * (xi*y[j] + x[j]*yi) + } + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + jy := ky + xi := x[ix] + yi := y[iy] + atmp := a[i*lda:] + for j := 0; j <= i; j++ { + atmp[j] += alpha * (xi*y[jy] + x[jx]*yi) + jx += incX + jy += incY + } + ix += incX + iy += incY + } +} + +// Dtpsv solves +// A * x = b if tA == blas.NoTrans +// A^T * x = b if tA == blas.Trans or 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 (Implementation) Dtpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float64, x []float64, incX int) { + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if d != blas.NonUnit && d != blas.Unit { + panic(badDiag) + } + if n < 0 { + panic(nLT0) + } + if len(ap) < (n*(n+1))/2 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } + + nonUnit := d == blas.NonUnit + var offset int // Offset is the index of (i,i) + if tA == blas.NoTrans { + if ul == blas.Upper { + offset = n*(n+1)/2 - 1 + if incX == 1 { + for i := n - 1; i >= 0; i-- { + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + var sum float64 + for j, v := range atmp { + sum += v * xtmp[j] + } + x[i] -= sum + if nonUnit { + x[i] /= ap[offset] + } + offset -= n - i + 1 + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + atmp := ap[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + var sum float64 + for _, v := range atmp { + sum += v * x[jx] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= ap[offset] + } + ix -= incX + offset -= n - i + 1 + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + atmp := ap[offset-i : offset] + var sum float64 + for j, v := range atmp { + sum += v * x[j] + } + x[i] -= sum + if nonUnit { + x[i] /= ap[offset] + } + offset += i + 2 + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + atmp := ap[offset-i : offset] + var sum float64 + for _, v := range atmp { + sum += v * x[jx] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= ap[offset] + } + ix += incX + offset += i + 2 + } + return + } + // Cases where ap is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + if nonUnit { + x[i] /= ap[offset] + } + xi := x[i] + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + for j, v := range atmp { + xtmp[j] -= v * xi + } + offset += n - i + } + return + } + ix := kx + for i := 0; i < n; i++ { + if nonUnit { + x[ix] /= ap[offset] + } + xix := x[ix] + atmp := ap[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + for _, v := range atmp { + x[jx] -= v * xix + jx += incX + } + ix += incX + offset += n - i + } + return + } + if incX == 1 { + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[i] /= ap[offset] + } + xi := x[i] + atmp := ap[offset-i : offset] + for j, v := range atmp { + x[j] -= v * xi + } + offset -= i + 1 + } + return + } + ix := kx + (n-1)*incX + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[ix] /= ap[offset] + } + xix := x[ix] + atmp := ap[offset-i : offset] + jx := kx + for _, v := range atmp { + x[jx] -= v * xix + jx += incX + } + ix -= incX + offset -= i + 1 + } +} + +// Dspmv 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 (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x []float64, incX int, beta float64, y []float64, incY int) { + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if len(a) < (n*(n+1))/2 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + // Quick return if possible + if n == 0 || (alpha == 0 && beta == 1) { + return + } + + // Set up start points + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + + // Form y = beta * y + if beta != 1 { + if incY > 0 { + Implementation{}.Dscal(n, beta, y, incY) + } else { + Implementation{}.Dscal(n, beta, y, -incY) + } + } + + if alpha == 0 { + return + } + + if n == 1 { + y[0] += alpha * a[0] * x[0] + return + } + var offset int // Offset is the index of (i,i). + if ul == blas.Upper { + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + xv := x[i] * alpha + sum := a[offset] * x[i] + atmp := a[offset+1 : offset+n-i] + xtmp := x[i+1:] + jy := ky + (i+1)*incY + for j, v := range atmp { + sum += v * xtmp[j] + y[jy] += v * xv + jy += incY + } + y[iy] += alpha * sum + iy += incY + offset += n - i + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + xv := x[ix] * alpha + sum := a[offset] * x[ix] + atmp := a[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + jy := ky + (i+1)*incY + for _, v := range atmp { + sum += v * x[jx] + y[jy] += v * xv + jx += incX + jy += incY + } + y[iy] += alpha * sum + ix += incX + iy += incY + offset += n - i + } + return + } + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + xv := x[i] * alpha + atmp := a[offset-i : offset] + jy := ky + var sum float64 + for j, v := range atmp { + sum += v * x[j] + y[jy] += v * xv + jy += incY + } + sum += a[offset] * x[i] + y[iy] += alpha * sum + iy += incY + offset += i + 2 + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + xv := x[ix] * alpha + atmp := a[offset-i : offset] + jx := kx + jy := ky + var sum float64 + for _, v := range atmp { + sum += v * x[jx] + y[jy] += v * xv + jx += incX + jy += incY + } + + sum += a[offset] * x[ix] + y[iy] += alpha * sum + ix += incX + iy += incY + offset += i + 2 + } +} + +// Dspr computes the rank-one operation +// a += alpha * x * x^T +// where a is an n×n symmetric matrix in packed format, x is a vector, and +// alpha is a scalar. +func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX int, a []float64) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if len(a) < (n*(n+1))/2 { + panic(badLdA) + } + if alpha == 0 || n == 0 { + return + } + lenX := n + var kx int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + var offset int // Offset is the index of (i,i). + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + atmp := a[offset:] + xv := alpha * x[i] + xtmp := x[i:n] + for j, v := range xtmp { + atmp[j] += xv * v + } + offset += n - i + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + i*incX + atmp := a[offset:] + xv := alpha * x[ix] + for j := 0; j < n-i; j++ { + atmp[j] += xv * x[jx] + jx += incX + } + ix += incX + offset += n - i + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + atmp := a[offset-i:] + xv := alpha * x[i] + xtmp := x[:i+1] + for j, v := range xtmp { + atmp[j] += xv * v + } + offset += i + 2 + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + atmp := a[offset-i:] + xv := alpha * x[ix] + for j := 0; j <= i; j++ { + atmp[j] += xv * x[jx] + jx += incX + } + ix += incX + offset += i + 2 + } +} + +// Dspr2 performs the symmetric rank-2 update +// A += alpha * x * y^T + alpha * y * x^T, +// where A is an n×n symmetric matrix in packed format, x and y are vectors, +// and alpha is a scalar. +func (Implementation) Dspr2(ul blas.Uplo, n int, alpha float64, x []float64, incX int, y []float64, incY int, ap []float64) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if len(ap) < (n*(n+1))/2 { + panic(badLdA) + } + if alpha == 0 { + return + } + var ky, kx int + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + var offset int // Offset is the index of (i,i). + if ul == blas.Upper { + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + atmp := ap[offset:] + xi := x[i] + yi := y[i] + xtmp := x[i:n] + ytmp := y[i:n] + for j, v := range xtmp { + atmp[j] += alpha * (xi*ytmp[j] + v*yi) + } + offset += n - i + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + i*incX + jy := ky + i*incY + atmp := ap[offset:] + xi := x[ix] + yi := y[iy] + for j := 0; j < n-i; j++ { + atmp[j] += alpha * (xi*y[jy] + x[jx]*yi) + jx += incX + jy += incY + } + ix += incX + iy += incY + offset += n - i + } + return + } + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + atmp := ap[offset-i:] + xi := x[i] + yi := y[i] + xtmp := x[:i+1] + for j, v := range xtmp { + atmp[j] += alpha * (xi*y[j] + v*yi) + } + offset += i + 2 + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + jy := ky + atmp := ap[offset-i:] + for j := 0; j <= i; j++ { + atmp[j] += alpha * (x[ix]*y[jy] + x[jx]*y[iy]) + jx += incX + jy += incY + } + ix += incX + iy += incY + offset += i + 2 + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level2double_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level2double_test.go new file mode 100644 index 00000000..42ac4798 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level2double_test.go @@ -0,0 +1,79 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func TestDgemv(t *testing.T) { + testblas.DgemvTest(t, impl) +} + +func TestDger(t *testing.T) { + testblas.DgerTest(t, impl) +} + +func TestDtxmv(t *testing.T) { + testblas.DtxmvTest(t, impl) +} + +func TestDgbmv(t *testing.T) { + testblas.DgbmvTest(t, impl) +} + +func TestDtbsv(t *testing.T) { + testblas.DtbsvTest(t, impl) +} + +func TestDsbmv(t *testing.T) { + testblas.DsbmvTest(t, impl) +} + +func TestDtbmv(t *testing.T) { + testblas.DtbmvTest(t, impl) +} + +func TestDtrsv(t *testing.T) { + testblas.DtrsvTest(t, impl) +} + +func TestDtrmv(t *testing.T) { + testblas.DtrmvTest(t, impl) +} + +func TestDsymv(t *testing.T) { + testblas.DsymvTest(t, impl) +} + +func TestDsyr(t *testing.T) { + testblas.DsyrTest(t, impl) +} + +func TestDsyr2(t *testing.T) { + testblas.Dsyr2Test(t, impl) +} + +func TestDspr2(t *testing.T) { + testblas.Dspr2Test(t, impl) +} + +func TestDspr(t *testing.T) { + testblas.DsprTest(t, impl) +} + +func TestDspmv(t *testing.T) { + testblas.DspmvTest(t, impl) +} + +func TestDtpsv(t *testing.T) { + testblas.DtpsvTest(t, impl) +} + +func TestDtpmv(t *testing.T) { + testblas.DtpmvTest(t, impl) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level2single.go b/vendor/gonum.org/v1/gonum/blas/gonum/level2single.go new file mode 100644 index 00000000..84ca967b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level2single.go @@ -0,0 +1,2268 @@ +// 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.Float32Level2 = Implementation{} + +// Sgemv computes +// y = alpha * a * x + beta * y if tA = blas.NoTrans +// y = alpha * A^T * 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 is a scalar. +// +// 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) + } + // 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(badX) + } + if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) { + panic(badY) + } + if lda*(m-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + + // Quick return if possible + if m == 0 || n == 0 || (alpha == 0 && beta == 1) { + return + } + + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(lenY - 1) * incY + } + + // First form y := beta * y + if incY > 0 { + Implementation{}.Sscal(lenY, beta, y, incY) + } else { + Implementation{}.Sscal(lenY, beta, y, -incY) + } + + if alpha == 0 { + return + } + + // 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) + } + 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) + } + } + 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 + } +} + +// Sger performs the rank-one operation +// A += alpha * x * y^T +// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Sger(m, n int, alpha float32, x []float32, incX int, y []float32, incY int, a []float32, lda int) { + // Check inputs + if m < 0 { + panic("m < 0") + } + if n < 0 { + panic(negativeN) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (m-1)*incX >= len(x)) || (incX < 0 && (1-m)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(m-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if lda < max(1, n) { + panic(badLdA) + } + + // Quick return if possible + if m == 0 || n == 0 || alpha == 0 { + return + } + + var ky, kx int + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + + if incX > 0 { + kx = 0 + } else { + kx = -(m - 1) * incX + } + + if incX == 1 && incY == 1 { + x = x[:m] + y = y[:n] + for i, xv := range x { + tmp := alpha * xv + if tmp != 0 { + atmp := a[i*lda : i*lda+n] + f32.AxpyUnitaryTo(atmp, tmp, y, atmp) + } + } + return + } + + ix := kx + for i := 0; i < m; i++ { + tmp := alpha * x[ix] + if tmp != 0 { + f32.AxpyInc(tmp, y, a[i*lda:i*lda+n], uintptr(n), uintptr(incY), 1, uintptr(ky), 0) + } + ix += incX + } +} + +// Sgbmv computes +// y = alpha * A * x + beta * y if tA == blas.NoTrans +// y = alpha * A^T * x + beta * y if tA == blas.Trans or blas.ConjTrans +// where a is an m×n band matrix kL subdiagonals and kU super-diagonals, and +// m and n refer to the size of the full dense matrix it represents. +// x and y are vectors, and alpha and beta are scalars. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Sgbmv(tA blas.Transpose, m, n, kL, kU 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 kL < 0 { + panic(kLLT0) + } + if kL < 0 { + panic(kULT0) + } + if lda < kL+kU+1 { + 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 + } + if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) { + panic(badY) + } + if lda*(min(m, n+kL)-1)+kL+kU+1 > len(a) || lda < kL+kU+1 { + panic(badLdA) + } + + // Quick return if possible + if m == 0 || n == 0 || (alpha == 0 && beta == 1) { + return + } + + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(lenY - 1) * incY + } + + // First form y := beta * y + if incY > 0 { + Implementation{}.Sscal(lenY, beta, y, incY) + } else { + Implementation{}.Sscal(lenY, beta, y, -incY) + } + + if alpha == 0 { + return + } + + // i and j are indices of the compacted banded matrix. + // off is the offset into the dense matrix (off + j = densej) + ld := min(m, n) + nCol := kU + 1 + kL + if tA == blas.NoTrans { + iy := ky + if incX == 1 { + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + xtmp := x[off : off+u-l] + var sum float32 + for j, v := range atmp { + sum += xtmp[j] * v + } + y[iy] += sum * alpha + iy += incY + } + return + } + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + jx := kx + var sum float32 + for _, v := range atmp { + sum += x[off*incX+jx] * v + jx += incX + } + y[iy] += sum * alpha + iy += incY + } + return + } + if incX == 1 { + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + tmp := alpha * x[i] + jy := ky + for _, v := range atmp { + y[jy+off*incY] += tmp * v + jy += incY + } + } + return + } + ix := kx + for i := 0; i < min(m, n+kL); i++ { + l := max(0, kL-i) + u := min(nCol, ld+kL-i) + off := max(0, i-kL) + atmp := a[i*lda+l : i*lda+u] + tmp := alpha * x[ix] + jy := ky + for _, v := range atmp { + y[jy+off*incY] += tmp * v + jy += incY + } + ix += incX + } +} + +// Strmv computes +// x = A * x if tA == blas.NoTrans +// x = A^T * x if tA == blas.Trans or blas.ConjTrans +// A is an n×n Triangular matrix and x is a vector. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Strmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float32, lda int, x []float32, incX int) { + 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 n < 0 { + panic(nLT0) + } + if lda < n { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if n == 0 { + return + } + nonUnit := d != blas.Unit + if n == 1 { + if nonUnit { + x[0] *= a[0] + } + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + ilda := i * lda + var tmp float32 + if nonUnit { + tmp = a[ilda+i] * x[i] + } else { + tmp = x[i] + } + xtmp := x[i+1:] + x[i] = tmp + f32.DotUnitary(a[ilda+i+1:ilda+n], xtmp) + } + return + } + ix := kx + for i := 0; i < n; i++ { + ilda := i * lda + var tmp float32 + if nonUnit { + tmp = a[ilda+i] * x[ix] + } else { + tmp = x[ix] + } + x[ix] = tmp + f32.DotInc(x, a[ilda+i+1:ilda+n], uintptr(n-i-1), uintptr(incX), 1, uintptr(ix+incX), 0) + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + ilda := i * lda + var tmp float32 + if nonUnit { + tmp += a[ilda+i] * x[i] + } else { + tmp = x[i] + } + x[i] = tmp + f32.DotUnitary(a[ilda:ilda+i], x) + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + ilda := i * lda + var tmp float32 + if nonUnit { + tmp = a[ilda+i] * x[ix] + } else { + tmp = x[ix] + } + x[ix] = tmp + f32.DotInc(x, a[ilda:ilda+i], uintptr(i), uintptr(incX), 1, uintptr(kx), 0) + ix -= incX + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + ilda := i * lda + xi := x[i] + f32.AxpyUnitary(xi, a[ilda+i+1:ilda+n], x[i+1:n]) + if nonUnit { + x[i] *= a[ilda+i] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + ilda := i * lda + xi := x[ix] + f32.AxpyInc(xi, a[ilda+i+1:ilda+n], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(kx+(i+1)*incX)) + if nonUnit { + x[ix] *= a[ilda+i] + } + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + ilda := i * lda + xi := x[i] + f32.AxpyUnitary(xi, a[ilda:ilda+i], x) + if nonUnit { + x[i] *= a[i*lda+i] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + ilda := i * lda + xi := x[ix] + f32.AxpyInc(xi, a[ilda:ilda+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx)) + if nonUnit { + x[ix] *= a[ilda+i] + } + ix += incX + } +} + +// Strsv solves +// A * x = b if tA == blas.NoTrans +// A^T * x = b if tA == blas.Trans or blas.ConjTrans +// 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. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Strsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float32, lda int, x []float32, incX int) { + // Test the input parameters + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if d != blas.NonUnit && d != blas.Unit { + panic(badDiag) + } + if n < 0 { + panic(nLT0) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + // Quick return if possible + if n == 0 { + return + } + if n == 1 { + if d == blas.NonUnit { + x[0] /= a[0] + } + return + } + + var kx int + if incX < 0 { + kx = -(n - 1) * incX + } + nonUnit := d == blas.NonUnit + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + var sum float32 + atmp := a[i*lda+i+1 : i*lda+n] + for j, v := range atmp { + jv := i + j + 1 + sum += x[jv] * v + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda+i] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + var sum float32 + jx := ix + incX + atmp := a[i*lda+i+1 : i*lda+n] + for _, v := range atmp { + sum += x[jx] * v + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda+i] + } + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + var sum float32 + atmp := a[i*lda : i*lda+i] + for j, v := range atmp { + sum += x[j] * v + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda+i] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + var sum float32 + atmp := a[i*lda : i*lda+i] + for _, v := range atmp { + sum += x[jx] * v + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda+i] + } + ix += incX + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + if nonUnit { + x[i] /= a[i*lda+i] + } + xi := x[i] + atmp := a[i*lda+i+1 : i*lda+n] + for j, v := range atmp { + jv := j + i + 1 + x[jv] -= v * xi + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + if nonUnit { + x[ix] /= a[i*lda+i] + } + xi := x[ix] + jx := kx + (i+1)*incX + atmp := a[i*lda+i+1 : i*lda+n] + for _, v := range atmp { + x[jx] -= v * xi + jx += incX + } + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[i] /= a[i*lda+i] + } + xi := x[i] + atmp := a[i*lda : i*lda+i] + for j, v := range atmp { + x[j] -= v * xi + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[ix] /= a[i*lda+i] + } + xi := x[ix] + jx := kx + atmp := a[i*lda : i*lda+i] + for _, v := range atmp { + x[jx] -= v * xi + jx += incX + } + ix -= incX + } +} + +// Ssymv 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. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Ssymv(ul blas.Uplo, n int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int) { + // Check inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(negativeN) + } + if lda > 1 && lda < n { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + // Quick return if possible + if n == 0 || (alpha == 0 && beta == 1) { + return + } + + // Set up start points + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + + // Form y = beta * y + if beta != 1 { + if incY > 0 { + Implementation{}.Sscal(n, beta, y, incY) + } else { + Implementation{}.Sscal(n, beta, y, -incY) + } + } + + if alpha == 0 { + return + } + + if n == 1 { + y[0] += alpha * a[0] * x[0] + return + } + + if ul == blas.Upper { + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + xv := x[i] * alpha + sum := x[i] * a[i*lda+i] + jy := ky + (i+1)*incY + atmp := a[i*lda+i+1 : i*lda+n] + for j, v := range atmp { + jp := j + i + 1 + sum += x[jp] * v + y[jy] += xv * v + jy += incY + } + y[iy] += alpha * sum + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + xv := x[ix] * alpha + sum := x[ix] * a[i*lda+i] + jx := kx + (i+1)*incX + jy := ky + (i+1)*incY + atmp := a[i*lda+i+1 : i*lda+n] + for _, v := range atmp { + sum += x[jx] * v + y[jy] += xv * v + jx += incX + jy += incY + } + y[iy] += alpha * sum + ix += incX + iy += incY + } + return + } + // Cases where a is lower triangular. + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + jy := ky + xv := alpha * x[i] + atmp := a[i*lda : i*lda+i] + var sum float32 + for j, v := range atmp { + sum += x[j] * v + y[jy] += xv * v + jy += incY + } + sum += x[i] * a[i*lda+i] + sum *= alpha + y[iy] += sum + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + jy := ky + xv := alpha * x[ix] + atmp := a[i*lda : i*lda+i] + var sum float32 + for _, v := range atmp { + sum += x[jx] * v + y[jy] += xv * v + jx += incX + jy += incY + } + sum += x[ix] * a[i*lda+i] + sum *= alpha + y[iy] += sum + ix += incX + iy += incY + } +} + +// Stbmv computes +// x = A * x if tA == blas.NoTrans +// x = A^T * x if tA == blas.Trans or blas.ConjTrans +// where A is an n×n triangular banded matrix with k diagonals, and x is a vector. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Stbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []float32, lda int, x []float32, incX int) { + 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 n < 0 { + panic(nLT0) + } + if k < 0 { + panic(kLT0) + } + if lda*(n-1)+k+1 > len(a) || lda < k+1 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } else if incX != 1 { + kx = 0 + } + + nonunit := d != blas.Unit + + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + u := min(1+k, n-i) + var sum float32 + atmp := a[i*lda:] + xtmp := x[i:] + for j := 1; j < u; j++ { + sum += xtmp[j] * atmp[j] + } + if nonunit { + sum += xtmp[0] * atmp[0] + } else { + sum += xtmp[0] + } + x[i] = sum + } + return + } + ix := kx + for i := 0; i < n; i++ { + u := min(1+k, n-i) + var sum float32 + atmp := a[i*lda:] + jx := incX + for j := 1; j < u; j++ { + sum += x[ix+jx] * atmp[j] + jx += incX + } + if nonunit { + sum += x[ix] * atmp[0] + } else { + sum += x[ix] + } + x[ix] = sum + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + l := max(0, k-i) + atmp := a[i*lda:] + var sum float32 + for j := l; j < k; j++ { + sum += x[i-k+j] * atmp[j] + } + if nonunit { + sum += x[i] * atmp[k] + } else { + sum += x[i] + } + x[i] = sum + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + l := max(0, k-i) + atmp := a[i*lda:] + var sum float32 + jx := l * incX + for j := l; j < k; j++ { + sum += x[ix-k*incX+jx] * atmp[j] + jx += incX + } + if nonunit { + sum += x[ix] * atmp[k] + } else { + sum += x[ix] + } + x[ix] = sum + ix -= incX + } + return + } + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + u := k + 1 + if i < u { + u = i + 1 + } + var sum float32 + for j := 1; j < u; j++ { + sum += x[i-j] * a[(i-j)*lda+j] + } + if nonunit { + sum += x[i] * a[i*lda] + } else { + sum += x[i] + } + x[i] = sum + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + u := k + 1 + if i < u { + u = i + 1 + } + var sum float32 + jx := incX + for j := 1; j < u; j++ { + sum += x[ix-jx] * a[(i-j)*lda+j] + jx += incX + } + if nonunit { + sum += x[ix] * a[i*lda] + } else { + sum += x[ix] + } + x[ix] = sum + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + u := k + if i+k >= n { + u = n - i - 1 + } + var sum float32 + for j := 0; j < u; j++ { + sum += x[i+j+1] * a[(i+j+1)*lda+k-j-1] + } + if nonunit { + sum += x[i] * a[i*lda+k] + } else { + sum += x[i] + } + x[i] = sum + } + return + } + ix := kx + for i := 0; i < n; i++ { + u := k + if i+k >= n { + u = n - i - 1 + } + var ( + sum float32 + jx int + ) + for j := 0; j < u; j++ { + sum += x[ix+jx+incX] * a[(i+j+1)*lda+k-j-1] + jx += incX + } + if nonunit { + sum += x[ix] * a[i*lda+k] + } else { + sum += x[ix] + } + x[ix] = sum + ix += incX + } +} + +// Stpmv computes +// x = A * x if tA == blas.NoTrans +// x = A^T * x if tA == blas.Trans or blas.ConjTrans +// where A is an n×n unit triangular matrix in packed format, and x is a vector. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Stpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float32, x []float32, incX int) { + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if d != blas.NonUnit && d != blas.Unit { + panic(badDiag) + } + if n < 0 { + panic(nLT0) + } + if len(ap) < (n*(n+1))/2 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } + + nonUnit := d == blas.NonUnit + var offset int // Offset is the index of (i,i) + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + xi := x[i] + if nonUnit { + xi *= ap[offset] + } + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + for j, v := range atmp { + xi += v * xtmp[j] + } + x[i] = xi + offset += n - i + } + return + } + ix := kx + for i := 0; i < n; i++ { + xix := x[ix] + if nonUnit { + xix *= ap[offset] + } + atmp := ap[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + for _, v := range atmp { + xix += v * x[jx] + jx += incX + } + x[ix] = xix + offset += n - i + ix += incX + } + return + } + if incX == 1 { + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xi := x[i] + if nonUnit { + xi *= ap[offset] + } + atmp := ap[offset-i : offset] + for j, v := range atmp { + xi += v * x[j] + } + x[i] = xi + offset -= i + 1 + } + return + } + ix := kx + (n-1)*incX + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xix := x[ix] + if nonUnit { + xix *= ap[offset] + } + atmp := ap[offset-i : offset] + jx := kx + for _, v := range atmp { + xix += v * x[jx] + jx += incX + } + x[ix] = xix + offset -= i + 1 + ix -= incX + } + return + } + // Cases where ap is transposed. + if ul == blas.Upper { + if incX == 1 { + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xi := x[i] + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + for j, v := range atmp { + xtmp[j] += v * xi + } + if nonUnit { + x[i] *= ap[offset] + } + offset -= n - i + 1 + } + return + } + ix := kx + (n-1)*incX + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + xix := x[ix] + jx := kx + (i+1)*incX + atmp := ap[offset+1 : offset+n-i] + for _, v := range atmp { + x[jx] += v * xix + jx += incX + } + if nonUnit { + x[ix] *= ap[offset] + } + offset -= n - i + 1 + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + xi := x[i] + atmp := ap[offset-i : offset] + for j, v := range atmp { + x[j] += v * xi + } + if nonUnit { + x[i] *= ap[offset] + } + offset += i + 2 + } + return + } + ix := kx + for i := 0; i < n; i++ { + xix := x[ix] + jx := kx + atmp := ap[offset-i : offset] + for _, v := range atmp { + x[jx] += v * xix + jx += incX + } + if nonUnit { + x[ix] *= ap[offset] + } + ix += incX + offset += i + 2 + } +} + +// Stbsv solves +// A * x = b +// where A is an n×n triangular banded matrix with k diagonals 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. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Stbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []float32, lda int, x []float32, incX int) { + 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 n < 0 { + panic(nLT0) + } + if lda*(n-1)+k+1 > len(a) || lda < k+1 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX < 0 { + kx = -(n - 1) * incX + } else { + kx = 0 + } + nonUnit := d == blas.NonUnit + // Form x = A^-1 x. + // Several cases below use subslices for speed improvement. + // The incX != 1 cases usually do not because incX may be negative. + if tA == blas.NoTrans { + if ul == blas.Upper { + if incX == 1 { + for i := n - 1; i >= 0; i-- { + bands := k + if i+bands >= n { + bands = n - i - 1 + } + atmp := a[i*lda+1:] + xtmp := x[i+1 : i+bands+1] + var sum float32 + for j, v := range xtmp { + sum += v * atmp[j] + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + max := k + 1 + if i+max > n { + max = n - i + } + atmp := a[i*lda:] + var ( + jx int + sum float32 + ) + for j := 1; j < max; j++ { + jx += incX + sum += x[ix+jx] * atmp[j] + } + x[ix] -= sum + if nonUnit { + x[ix] /= atmp[0] + } + ix -= incX + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + atmp := a[i*lda+k-bands:] + xtmp := x[i-bands : i] + var sum float32 + for j, v := range xtmp { + sum += v * atmp[j] + } + x[i] -= sum + if nonUnit { + x[i] /= atmp[bands] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + atmp := a[i*lda+k-bands:] + var ( + sum float32 + jx int + ) + for j := 0; j < bands; j++ { + sum += x[ix-bands*incX+jx] * atmp[j] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= atmp[bands] + } + ix += incX + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + var sum float32 + for j := 0; j < bands; j++ { + sum += x[i-bands+j] * a[(i-bands+j)*lda+bands-j] + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda] + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + bands := k + if i-k < 0 { + bands = i + } + var ( + sum float32 + jx int + ) + for j := 0; j < bands; j++ { + sum += x[ix-bands*incX+jx] * a[(i-bands+j)*lda+bands-j] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda] + } + ix += incX + } + return + } + if incX == 1 { + for i := n - 1; i >= 0; i-- { + bands := k + if i+bands >= n { + bands = n - i - 1 + } + var sum float32 + xtmp := x[i+1 : i+1+bands] + for j, v := range xtmp { + sum += v * a[(i+j+1)*lda+k-j-1] + } + x[i] -= sum + if nonUnit { + x[i] /= a[i*lda+k] + } + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + bands := k + if i+bands >= n { + bands = n - i - 1 + } + var ( + sum float32 + jx int + ) + for j := 0; j < bands; j++ { + sum += x[ix+jx+incX] * a[(i+j+1)*lda+k-j-1] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= a[i*lda+k] + } + ix -= incX + } +} + +// Ssbmv performs +// y = alpha * A * x + beta * y +// where A is an n×n symmetric banded matrix, x and y are vectors, and alpha +// and beta are scalars. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Ssbmv(ul blas.Uplo, n, k int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(n-1)+k+1 > len(a) || lda < k+1 { + panic(badLdA) + } + + // Quick return if possible + if n == 0 || (alpha == 0 && beta == 1) { + return + } + + // Set up indexes + lenX := n + lenY := n + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(lenY - 1) * incY + } + + // First form y := beta * y + if incY > 0 { + Implementation{}.Sscal(lenY, beta, y, incY) + } else { + Implementation{}.Sscal(lenY, beta, y, -incY) + } + + if alpha == 0 { + return + } + + if ul == blas.Upper { + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + atmp := a[i*lda:] + tmp := alpha * x[i] + sum := tmp * atmp[0] + u := min(k, n-i-1) + jy := incY + for j := 1; j <= u; j++ { + v := atmp[j] + sum += alpha * x[i+j] * v + y[iy+jy] += tmp * v + jy += incY + } + y[iy] += sum + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + atmp := a[i*lda:] + tmp := alpha * x[ix] + sum := tmp * atmp[0] + u := min(k, n-i-1) + jx := incX + jy := incY + for j := 1; j <= u; j++ { + v := atmp[j] + sum += alpha * x[ix+jx] * v + y[iy+jy] += tmp * v + jx += incX + jy += incY + } + y[iy] += sum + ix += incX + iy += incY + } + return + } + + // Casses where a has bands below the diagonal. + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + l := max(0, k-i) + tmp := alpha * x[i] + jy := l * incY + atmp := a[i*lda:] + for j := l; j < k; j++ { + v := atmp[j] + y[iy] += alpha * v * x[i-k+j] + y[iy-k*incY+jy] += tmp * v + jy += incY + } + y[iy] += tmp * atmp[k] + iy += incY + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + l := max(0, k-i) + tmp := alpha * x[ix] + jx := l * incX + jy := l * incY + atmp := a[i*lda:] + for j := l; j < k; j++ { + v := atmp[j] + y[iy] += alpha * v * x[ix-k*incX+jx] + y[iy-k*incY+jy] += tmp * v + jx += incX + jy += incY + } + y[iy] += tmp * atmp[k] + ix += incX + iy += incY + } +} + +// Ssyr performs the rank-one update +// a += alpha * x * x^T +// where a is an n×n symmetric matrix, and x is a vector. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Ssyr(ul blas.Uplo, n int, alpha float32, x []float32, incX int, a []float32, lda int) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if alpha == 0 || n == 0 { + return + } + + lenX := n + var kx int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + tmp := x[i] * alpha + if tmp != 0 { + atmp := a[i*lda+i : i*lda+n] + xtmp := x[i:n] + for j, v := range xtmp { + atmp[j] += v * tmp + } + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + tmp := x[ix] * alpha + if tmp != 0 { + jx := ix + atmp := a[i*lda:] + for j := i; j < n; j++ { + atmp[j] += x[jx] * tmp + jx += incX + } + } + ix += incX + } + return + } + // Cases where a is lower triangular. + if incX == 1 { + for i := 0; i < n; i++ { + tmp := x[i] * alpha + if tmp != 0 { + atmp := a[i*lda:] + xtmp := x[:i+1] + for j, v := range xtmp { + atmp[j] += tmp * v + } + } + } + return + } + ix := kx + for i := 0; i < n; i++ { + tmp := x[ix] * alpha + if tmp != 0 { + atmp := a[i*lda:] + jx := kx + for j := 0; j < i+1; j++ { + atmp[j] += tmp * x[jx] + jx += incX + } + } + ix += incX + } +} + +// Ssyr2 performs the symmetric rank-two update +// A += alpha * x * y^T + alpha * y * x^T +// where A is a symmetric n×n matrix, x and y are vectors, and alpha is a scalar. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Ssyr2(ul blas.Uplo, n int, alpha float32, x []float32, incX int, y []float32, incY int, a []float32, lda int) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if lda*(n-1)+n > len(a) || lda < max(1, n) { + panic(badLdA) + } + if alpha == 0 { + return + } + + var ky, kx int + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + if ul == blas.Upper { + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + xi := x[i] + yi := y[i] + atmp := a[i*lda:] + for j := i; j < n; j++ { + atmp[j] += alpha * (xi*y[j] + x[j]*yi) + } + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + i*incX + jy := ky + i*incY + xi := x[ix] + yi := y[iy] + atmp := a[i*lda:] + for j := i; j < n; j++ { + atmp[j] += alpha * (xi*y[jy] + x[jx]*yi) + jx += incX + jy += incY + } + ix += incX + iy += incY + } + return + } + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + xi := x[i] + yi := y[i] + atmp := a[i*lda:] + for j := 0; j <= i; j++ { + atmp[j] += alpha * (xi*y[j] + x[j]*yi) + } + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + jy := ky + xi := x[ix] + yi := y[iy] + atmp := a[i*lda:] + for j := 0; j <= i; j++ { + atmp[j] += alpha * (xi*y[jy] + x[jx]*yi) + jx += incX + jy += incY + } + ix += incX + iy += incY + } +} + +// Stpsv solves +// A * x = b if tA == blas.NoTrans +// A^T * x = b if tA == blas.Trans or 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. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Stpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float32, x []float32, incX int) { + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if d != blas.NonUnit && d != blas.Unit { + panic(badDiag) + } + if n < 0 { + panic(nLT0) + } + if len(ap) < (n*(n+1))/2 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if n == 0 { + return + } + var kx int + if incX <= 0 { + kx = -(n - 1) * incX + } + + nonUnit := d == blas.NonUnit + var offset int // Offset is the index of (i,i) + if tA == blas.NoTrans { + if ul == blas.Upper { + offset = n*(n+1)/2 - 1 + if incX == 1 { + for i := n - 1; i >= 0; i-- { + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + var sum float32 + for j, v := range atmp { + sum += v * xtmp[j] + } + x[i] -= sum + if nonUnit { + x[i] /= ap[offset] + } + offset -= n - i + 1 + } + return + } + ix := kx + (n-1)*incX + for i := n - 1; i >= 0; i-- { + atmp := ap[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + var sum float32 + for _, v := range atmp { + sum += v * x[jx] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= ap[offset] + } + ix -= incX + offset -= n - i + 1 + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + atmp := ap[offset-i : offset] + var sum float32 + for j, v := range atmp { + sum += v * x[j] + } + x[i] -= sum + if nonUnit { + x[i] /= ap[offset] + } + offset += i + 2 + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + atmp := ap[offset-i : offset] + var sum float32 + for _, v := range atmp { + sum += v * x[jx] + jx += incX + } + x[ix] -= sum + if nonUnit { + x[ix] /= ap[offset] + } + ix += incX + offset += i + 2 + } + return + } + // Cases where ap is transposed. + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + if nonUnit { + x[i] /= ap[offset] + } + xi := x[i] + atmp := ap[offset+1 : offset+n-i] + xtmp := x[i+1:] + for j, v := range atmp { + xtmp[j] -= v * xi + } + offset += n - i + } + return + } + ix := kx + for i := 0; i < n; i++ { + if nonUnit { + x[ix] /= ap[offset] + } + xix := x[ix] + atmp := ap[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + for _, v := range atmp { + x[jx] -= v * xix + jx += incX + } + ix += incX + offset += n - i + } + return + } + if incX == 1 { + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[i] /= ap[offset] + } + xi := x[i] + atmp := ap[offset-i : offset] + for j, v := range atmp { + x[j] -= v * xi + } + offset -= i + 1 + } + return + } + ix := kx + (n-1)*incX + offset = n*(n+1)/2 - 1 + for i := n - 1; i >= 0; i-- { + if nonUnit { + x[ix] /= ap[offset] + } + xix := x[ix] + atmp := ap[offset-i : offset] + jx := kx + for _, v := range atmp { + x[jx] -= v * xix + jx += incX + } + ix -= incX + offset -= i + 1 + } +} + +// Sspmv 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. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x []float32, incX int, beta float32, y []float32, incY int) { + // Verify inputs + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if len(a) < (n*(n+1))/2 { + panic(badLdA) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + // Quick return if possible + if n == 0 || (alpha == 0 && beta == 1) { + return + } + + // Set up start points + var kx, ky int + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + + // Form y = beta * y + if beta != 1 { + if incY > 0 { + Implementation{}.Sscal(n, beta, y, incY) + } else { + Implementation{}.Sscal(n, beta, y, -incY) + } + } + + if alpha == 0 { + return + } + + if n == 1 { + y[0] += alpha * a[0] * x[0] + return + } + var offset int // Offset is the index of (i,i). + if ul == blas.Upper { + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + xv := x[i] * alpha + sum := a[offset] * x[i] + atmp := a[offset+1 : offset+n-i] + xtmp := x[i+1:] + jy := ky + (i+1)*incY + for j, v := range atmp { + sum += v * xtmp[j] + y[jy] += v * xv + jy += incY + } + y[iy] += alpha * sum + iy += incY + offset += n - i + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + xv := x[ix] * alpha + sum := a[offset] * x[ix] + atmp := a[offset+1 : offset+n-i] + jx := kx + (i+1)*incX + jy := ky + (i+1)*incY + for _, v := range atmp { + sum += v * x[jx] + y[jy] += v * xv + jx += incX + jy += incY + } + y[iy] += alpha * sum + ix += incX + iy += incY + offset += n - i + } + return + } + if incX == 1 { + iy := ky + for i := 0; i < n; i++ { + xv := x[i] * alpha + atmp := a[offset-i : offset] + jy := ky + var sum float32 + for j, v := range atmp { + sum += v * x[j] + y[jy] += v * xv + jy += incY + } + sum += a[offset] * x[i] + y[iy] += alpha * sum + iy += incY + offset += i + 2 + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + xv := x[ix] * alpha + atmp := a[offset-i : offset] + jx := kx + jy := ky + var sum float32 + for _, v := range atmp { + sum += v * x[jx] + y[jy] += v * xv + jx += incX + jy += incY + } + + sum += a[offset] * x[ix] + y[iy] += alpha * sum + ix += incX + iy += incY + offset += i + 2 + } +} + +// Sspr computes the rank-one operation +// a += alpha * x * x^T +// where a is an n×n symmetric matrix in packed format, x is a vector, and +// alpha is a scalar. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX int, a []float32) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if len(a) < (n*(n+1))/2 { + panic(badLdA) + } + if alpha == 0 || n == 0 { + return + } + lenX := n + var kx int + if incX > 0 { + kx = 0 + } else { + kx = -(lenX - 1) * incX + } + var offset int // Offset is the index of (i,i). + if ul == blas.Upper { + if incX == 1 { + for i := 0; i < n; i++ { + atmp := a[offset:] + xv := alpha * x[i] + xtmp := x[i:n] + for j, v := range xtmp { + atmp[j] += xv * v + } + offset += n - i + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + i*incX + atmp := a[offset:] + xv := alpha * x[ix] + for j := 0; j < n-i; j++ { + atmp[j] += xv * x[jx] + jx += incX + } + ix += incX + offset += n - i + } + return + } + if incX == 1 { + for i := 0; i < n; i++ { + atmp := a[offset-i:] + xv := alpha * x[i] + xtmp := x[:i+1] + for j, v := range xtmp { + atmp[j] += xv * v + } + offset += i + 2 + } + return + } + ix := kx + for i := 0; i < n; i++ { + jx := kx + atmp := a[offset-i:] + xv := alpha * x[ix] + for j := 0; j <= i; j++ { + atmp[j] += xv * x[jx] + jx += incX + } + ix += incX + offset += i + 2 + } +} + +// Sspr2 performs the symmetric rank-2 update +// A += alpha * x * y^T + alpha * y * x^T, +// where A is an n×n symmetric matrix in packed format, x and y are vectors, +// and alpha is a scalar. +// +// Float32 implementations are autogenerated and not directly tested. +func (Implementation) Sspr2(ul blas.Uplo, n int, alpha float32, x []float32, incX int, y []float32, incY int, ap []float32) { + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if n < 0 { + panic(nLT0) + } + if incX == 0 { + panic(zeroIncX) + } + if incY == 0 { + panic(zeroIncY) + } + if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) { + panic(badX) + } + if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) { + panic(badY) + } + if len(ap) < (n*(n+1))/2 { + panic(badLdA) + } + if alpha == 0 { + return + } + var ky, kx int + if incY > 0 { + ky = 0 + } else { + ky = -(n - 1) * incY + } + if incX > 0 { + kx = 0 + } else { + kx = -(n - 1) * incX + } + var offset int // Offset is the index of (i,i). + if ul == blas.Upper { + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + atmp := ap[offset:] + xi := x[i] + yi := y[i] + xtmp := x[i:n] + ytmp := y[i:n] + for j, v := range xtmp { + atmp[j] += alpha * (xi*ytmp[j] + v*yi) + } + offset += n - i + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + i*incX + jy := ky + i*incY + atmp := ap[offset:] + xi := x[ix] + yi := y[iy] + for j := 0; j < n-i; j++ { + atmp[j] += alpha * (xi*y[jy] + x[jx]*yi) + jx += incX + jy += incY + } + ix += incX + iy += incY + offset += n - i + } + return + } + if incX == 1 && incY == 1 { + for i := 0; i < n; i++ { + atmp := ap[offset-i:] + xi := x[i] + yi := y[i] + xtmp := x[:i+1] + for j, v := range xtmp { + atmp[j] += alpha * (xi*y[j] + v*yi) + } + offset += i + 2 + } + return + } + ix := kx + iy := ky + for i := 0; i < n; i++ { + jx := kx + jy := ky + atmp := ap[offset-i:] + for j := 0; j <= i; j++ { + atmp[j] += alpha * (x[ix]*y[jy] + x[jx]*y[iy]) + jx += incX + jy += incY + } + ix += incX + iy += incY + offset += i + 2 + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level3double.go b/vendor/gonum.org/v1/gonum/blas/gonum/level3double.go new file mode 100644 index 00000000..b5001dcb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level3double.go @@ -0,0 +1,831 @@ +// 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 +// A * X = alpha * B, if tA == blas.NoTrans side == blas.Left, +// A^T * X = alpha * B, if tA == blas.Trans or blas.ConjTrans, and side == blas.Left, +// X * A = alpha * B, if tA == blas.NoTrans side == blas.Right, +// X * A^T = 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 is an m×n matrix, 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) + } + if ldb < n { + panic(badLdB) + } + var k int + if s == blas.Left { + k = m + } else { + k = n + } + if lda*(k-1)+k > len(a) || lda < max(1, k) { + panic(badLdA) + } + if ldb*(m-1)+n > len(b) || ldb < max(1, n) { + panic(badLdB) + } + + if m == 0 || n == 0 { + return + } + + 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 { + for j := range btmp { + btmp[j] *= alpha + } + } + for ka, va := range a[i*lda+i+1 : i*lda+m] { + k := ka + i + 1 + if va != 0 { + f64.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp) + } + } + if nonUnit { + tmp := 1 / a[i*lda+i] + for j := 0; j < n; j++ { + btmp[j] *= tmp + } + } + } + return + } + for i := 0; i < m; i++ { + btmp := b[i*ldb : i*ldb+n] + if alpha != 1 { + for j := 0; j < n; j++ { + btmp[j] *= alpha + } + } + for k, va := range a[i*lda : i*lda+i] { + if va != 0 { + f64.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp) + } + } + if nonUnit { + tmp := 1 / a[i*lda+i] + for j := 0; j < n; j++ { + btmp[j] *= tmp + } + } + } + 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] + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + for ia, va := range a[k*lda+k+1 : k*lda+m] { + i := ia + k + 1 + if va != 0 { + btmp := b[i*ldb : i*ldb+n] + f64.AxpyUnitaryTo(btmp, -va, btmpk, btmp) + } + } + if alpha != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= alpha + } + } + } + return + } + for k := m - 1; k >= 0; k-- { + btmpk := b[k*ldb : k*ldb+n] + if nonUnit { + tmp := 1 / a[k*lda+k] + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + for i, va := range a[k*lda : k*lda+k] { + if va != 0 { + btmp := b[i*ldb : i*ldb+n] + f64.AxpyUnitaryTo(btmp, -va, btmpk, btmp) + } + } + if alpha != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= alpha + } + } + } + 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 { + for j := 0; j < n; j++ { + btmp[j] *= alpha + } + } + for k, vb := range btmp { + if vb != 0 { + if btmp[k] != 0 { + if nonUnit { + btmp[k] /= a[k*lda+k] + } + btmpk := btmp[k+1 : n] + f64.AxpyUnitaryTo(btmpk, -btmp[k], a[k*lda+k+1:k*lda+n], btmpk) + } + } + } + } + return + } + for i := 0; i < m; i++ { + btmp := b[i*lda : i*lda+n] + if alpha != 1 { + for j := 0; j < n; j++ { + btmp[j] *= alpha + } + } + for k := n - 1; k >= 0; k-- { + if btmp[k] != 0 { + if nonUnit { + btmp[k] /= a[k*lda+k] + } + f64.AxpyUnitaryTo(btmp, -btmp[k], a[k*lda:k*lda+k], btmp) + } + } + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + for i := 0; i < m; i++ { + btmp := b[i*lda : i*lda+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*lda : i*lda+n] + for j := 0; j < n; j++ { + tmp := alpha*btmp[j] - f64.DotUnitary(a[j*lda:j*lda+j], btmp) + if nonUnit { + tmp /= a[j*lda+j] + } + btmp[j] = tmp + } + } +} + +// Dsymm performs one of +// 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("goblas: bad side") + } + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if m < 0 { + panic(mLT0) + } + if n < 0 { + panic(nLT0) + } + var k int + if s == blas.Left { + k = m + } else { + k = n + } + if lda*(k-1)+k > len(a) || lda < max(1, k) { + panic(badLdA) + } + if ldb*(m-1)+n > len(b) || ldb < max(1, n) { + panic(badLdB) + } + if ldc*(m-1)+n > len(c) || ldc < max(1, n) { + panic(badLdC) + } + if m == 0 || n == 0 { + return + } + 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 + ctmp := c[i*ldc : i*ldc+n] + f64.AxpyUnitaryTo(ctmp, 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 + ctmp := c[i*ldc : i*ldc+n] + f64.AxpyUnitaryTo(ctmp, 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 the symmetric rank-k operation +// C = alpha * A * A^T + beta*C +// C is an n×n symmetric matrix. A is an n×k matrix if tA == blas.NoTrans, and +// a k×n matrix otherwise. 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) + } + if ldc < n { + panic(badLdC) + } + var row, col int + if tA == blas.NoTrans { + row, col = n, k + } else { + row, col = k, n + } + if lda*(row-1)+col > len(a) || lda < max(1, col) { + panic(badLdA) + } + if ldc*(n-1)+n > len(c) || ldc < max(1, n) { + panic(badLdC) + } + 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] + 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++ { + atmp := a[i*lda : i*lda+k] + for j, vc := range c[i*ldc : i*ldc+i+1] { + c[i*ldc+j] = vc*beta + alpha*f64.DotUnitary(a[j*lda:j*lda+k], atmp) + } + } + 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 != 1 { + for j := range ctmp { + ctmp[j] *= beta + } + } + for l := 0; l < k; l++ { + tmp := alpha * a[l*lda+i] + if tmp != 0 { + f64.AxpyUnitaryTo(ctmp, tmp, a[l*lda+i:l*lda+n], ctmp) + } + } + } + return + } + for i := 0; i < n; i++ { + ctmp := c[i*ldc : i*ldc+i+1] + if beta != 0 { + for j := range ctmp { + ctmp[j] *= beta + } + } + for l := 0; l < k; l++ { + tmp := alpha * a[l*lda+i] + if tmp != 0 { + f64.AxpyUnitaryTo(ctmp, tmp, a[l*lda:l*lda+i+1], ctmp) + } + } + } +} + +// Dsyr2k performs the symmetric rank 2k operation +// C = alpha * A * B^T + alpha * B * A^T + beta * C +// where C is an n×n symmetric matrix. A and B are n×k matrices if +// tA == NoTrans and k×n otherwise. 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) + } + if ldc < n { + panic(badLdC) + } + var row, col int + if tA == blas.NoTrans { + row, col = n, k + } else { + row, col = k, n + } + if lda*(row-1)+col > len(a) || lda < max(1, col) { + panic(badLdA) + } + if ldb*(row-1)+col > len(b) || ldb < max(1, col) { + panic(badLdB) + } + if ldc*(n-1)+n > len(c) || ldc < max(1, n) { + panic(badLdC) + } + 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*lda+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*lda+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 +// B = alpha * A * B, if tA == blas.NoTrans and side == blas.Left, +// B = alpha * A^T * 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^T, if tA == blas.Trans or blas.ConjTrans, and side == blas.Right, +// where A is an n×n or m×m triangular matrix, and B is an m×n matrix. +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) + } + var k int + if s == blas.Left { + k = m + } else { + k = n + } + if lda*(k-1)+k > len(a) || lda < max(1, k) { + panic(badLdA) + } + if ldb*(m-1)+n > len(b) || ldb < max(1, n) { + panic(badLdB) + } + 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] + for j := range btmp { + btmp[j] *= tmp + } + for ka, va := range a[i*lda+i+1 : i*lda+m] { + k := ka + i + 1 + tmp := alpha * va + if tmp != 0 { + f64.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp) + } + } + } + return + } + for i := m - 1; i >= 0; i-- { + tmp := alpha + if nonUnit { + tmp *= a[i*lda+i] + } + btmp := b[i*ldb : i*ldb+n] + for j := range btmp { + btmp[j] *= tmp + } + for k, va := range a[i*lda : i*lda+i] { + tmp := alpha * va + if tmp != 0 { + f64.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp) + } + } + } + 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] + tmp := alpha * va + if tmp != 0 { + f64.AxpyUnitaryTo(btmp, tmp, btmpk, btmp) + } + } + tmp := alpha + if nonUnit { + tmp *= a[k*lda+k] + } + if tmp != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + } + 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] + tmp := alpha * va + if tmp != 0 { + f64.AxpyUnitaryTo(btmp, tmp, btmpk, btmp) + } + } + tmp := alpha + if nonUnit { + tmp *= a[k*lda+k] + } + if tmp != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + } + 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 { + btmp[k] = tmp + if nonUnit { + btmp[k] *= a[k*lda+k] + } + for ja, v := range a[k*lda+k+1 : k*lda+n] { + j := ja + k + 1 + btmp[j] += tmp * v + } + } + } + } + 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 { + btmp[k] = tmp + if nonUnit { + btmp[k] *= a[k*lda+k] + } + f64.AxpyUnitaryTo(btmp, tmp, a[k*lda:k*lda+k], btmp) + } + } + } + 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 + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level3double_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/level3double_test.go new file mode 100644 index 00000000..70459803 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level3double_test.go @@ -0,0 +1,35 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func TestDgemm(t *testing.T) { + testblas.TestDgemm(t, impl) +} + +func TestDsymm(t *testing.T) { + testblas.DsymmTest(t, impl) +} + +func TestDtrsm(t *testing.T) { + testblas.DtrsmTest(t, impl) +} + +func TestDsyrk(t *testing.T) { + testblas.DsyrkTest(t, impl) +} + +func TestDsyr2k(t *testing.T) { + testblas.Dsyr2kTest(t, impl) +} + +func TestDtrmm(t *testing.T) { + testblas.DtrmmTest(t, impl) +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/level3single.go b/vendor/gonum.org/v1/gonum/blas/gonum/level3single.go new file mode 100644 index 00000000..ba158498 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/level3single.go @@ -0,0 +1,843 @@ +// 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 +// A * X = alpha * B, if tA == blas.NoTrans side == blas.Left, +// A^T * X = alpha * B, if tA == blas.Trans or blas.ConjTrans, and side == blas.Left, +// X * A = alpha * B, if tA == blas.NoTrans side == blas.Right, +// X * A^T = 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 is an m×n matrix, 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) + } + if ldb < n { + panic(badLdB) + } + var k int + if s == blas.Left { + k = m + } else { + k = n + } + if lda*(k-1)+k > len(a) || lda < max(1, k) { + panic(badLdA) + } + if ldb*(m-1)+n > len(b) || ldb < max(1, n) { + panic(badLdB) + } + + if m == 0 || n == 0 { + return + } + + 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 { + for j := range btmp { + btmp[j] *= alpha + } + } + for ka, va := range a[i*lda+i+1 : i*lda+m] { + k := ka + i + 1 + if va != 0 { + f32.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp) + } + } + if nonUnit { + tmp := 1 / a[i*lda+i] + for j := 0; j < n; j++ { + btmp[j] *= tmp + } + } + } + return + } + for i := 0; i < m; i++ { + btmp := b[i*ldb : i*ldb+n] + if alpha != 1 { + for j := 0; j < n; j++ { + btmp[j] *= alpha + } + } + for k, va := range a[i*lda : i*lda+i] { + if va != 0 { + f32.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp) + } + } + if nonUnit { + tmp := 1 / a[i*lda+i] + for j := 0; j < n; j++ { + btmp[j] *= tmp + } + } + } + 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] + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + for ia, va := range a[k*lda+k+1 : k*lda+m] { + i := ia + k + 1 + if va != 0 { + btmp := b[i*ldb : i*ldb+n] + f32.AxpyUnitaryTo(btmp, -va, btmpk, btmp) + } + } + if alpha != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= alpha + } + } + } + return + } + for k := m - 1; k >= 0; k-- { + btmpk := b[k*ldb : k*ldb+n] + if nonUnit { + tmp := 1 / a[k*lda+k] + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + for i, va := range a[k*lda : k*lda+k] { + if va != 0 { + btmp := b[i*ldb : i*ldb+n] + f32.AxpyUnitaryTo(btmp, -va, btmpk, btmp) + } + } + if alpha != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= alpha + } + } + } + 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 { + for j := 0; j < n; j++ { + btmp[j] *= alpha + } + } + for k, vb := range btmp { + if vb != 0 { + if btmp[k] != 0 { + if nonUnit { + btmp[k] /= a[k*lda+k] + } + btmpk := btmp[k+1 : n] + f32.AxpyUnitaryTo(btmpk, -btmp[k], a[k*lda+k+1:k*lda+n], btmpk) + } + } + } + } + return + } + for i := 0; i < m; i++ { + btmp := b[i*lda : i*lda+n] + if alpha != 1 { + for j := 0; j < n; j++ { + btmp[j] *= alpha + } + } + for k := n - 1; k >= 0; k-- { + if btmp[k] != 0 { + if nonUnit { + btmp[k] /= a[k*lda+k] + } + f32.AxpyUnitaryTo(btmp, -btmp[k], a[k*lda:k*lda+k], btmp) + } + } + } + return + } + // Cases where a is transposed. + if ul == blas.Upper { + for i := 0; i < m; i++ { + btmp := b[i*lda : i*lda+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*lda : i*lda+n] + for j := 0; j < n; j++ { + tmp := alpha*btmp[j] - f32.DotUnitary(a[j*lda:j*lda+j], btmp) + if nonUnit { + tmp /= a[j*lda+j] + } + btmp[j] = tmp + } + } +} + +// Ssymm performs one of +// 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("goblas: bad side") + } + if ul != blas.Lower && ul != blas.Upper { + panic(badUplo) + } + if m < 0 { + panic(mLT0) + } + if n < 0 { + panic(nLT0) + } + var k int + if s == blas.Left { + k = m + } else { + k = n + } + if lda*(k-1)+k > len(a) || lda < max(1, k) { + panic(badLdA) + } + if ldb*(m-1)+n > len(b) || ldb < max(1, n) { + panic(badLdB) + } + if ldc*(m-1)+n > len(c) || ldc < max(1, n) { + panic(badLdC) + } + if m == 0 || n == 0 { + return + } + 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 + ctmp := c[i*ldc : i*ldc+n] + f32.AxpyUnitaryTo(ctmp, 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 + ctmp := c[i*ldc : i*ldc+n] + f32.AxpyUnitaryTo(ctmp, 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 the symmetric rank-k operation +// C = alpha * A * A^T + beta*C +// C is an n×n symmetric matrix. A is an n×k matrix if tA == blas.NoTrans, and +// a k×n matrix otherwise. 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) + } + if ldc < n { + panic(badLdC) + } + var row, col int + if tA == blas.NoTrans { + row, col = n, k + } else { + row, col = k, n + } + if lda*(row-1)+col > len(a) || lda < max(1, col) { + panic(badLdA) + } + if ldc*(n-1)+n > len(c) || ldc < max(1, n) { + panic(badLdC) + } + 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] + 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++ { + atmp := a[i*lda : i*lda+k] + for j, vc := range c[i*ldc : i*ldc+i+1] { + c[i*ldc+j] = vc*beta + alpha*f32.DotUnitary(a[j*lda:j*lda+k], atmp) + } + } + 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 != 1 { + for j := range ctmp { + ctmp[j] *= beta + } + } + for l := 0; l < k; l++ { + tmp := alpha * a[l*lda+i] + if tmp != 0 { + f32.AxpyUnitaryTo(ctmp, tmp, a[l*lda+i:l*lda+n], ctmp) + } + } + } + return + } + for i := 0; i < n; i++ { + ctmp := c[i*ldc : i*ldc+i+1] + if beta != 0 { + for j := range ctmp { + ctmp[j] *= beta + } + } + for l := 0; l < k; l++ { + tmp := alpha * a[l*lda+i] + if tmp != 0 { + f32.AxpyUnitaryTo(ctmp, tmp, a[l*lda:l*lda+i+1], ctmp) + } + } + } +} + +// Ssyr2k performs the symmetric rank 2k operation +// C = alpha * A * B^T + alpha * B * A^T + beta * C +// where C is an n×n symmetric matrix. A and B are n×k matrices if +// tA == NoTrans and k×n otherwise. 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) + } + if ldc < n { + panic(badLdC) + } + var row, col int + if tA == blas.NoTrans { + row, col = n, k + } else { + row, col = k, n + } + if lda*(row-1)+col > len(a) || lda < max(1, col) { + panic(badLdA) + } + if ldb*(row-1)+col > len(b) || ldb < max(1, col) { + panic(badLdB) + } + if ldc*(n-1)+n > len(c) || ldc < max(1, n) { + panic(badLdC) + } + 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*lda+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*lda+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 +// B = alpha * A * B, if tA == blas.NoTrans and side == blas.Left, +// B = alpha * A^T * 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^T, if tA == blas.Trans or blas.ConjTrans, and side == blas.Right, +// where A is an n×n or m×m triangular matrix, and B is an m×n matrix. +// +// 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) + } + var k int + if s == blas.Left { + k = m + } else { + k = n + } + if lda*(k-1)+k > len(a) || lda < max(1, k) { + panic(badLdA) + } + if ldb*(m-1)+n > len(b) || ldb < max(1, n) { + panic(badLdB) + } + 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] + for j := range btmp { + btmp[j] *= tmp + } + for ka, va := range a[i*lda+i+1 : i*lda+m] { + k := ka + i + 1 + tmp := alpha * va + if tmp != 0 { + f32.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp) + } + } + } + return + } + for i := m - 1; i >= 0; i-- { + tmp := alpha + if nonUnit { + tmp *= a[i*lda+i] + } + btmp := b[i*ldb : i*ldb+n] + for j := range btmp { + btmp[j] *= tmp + } + for k, va := range a[i*lda : i*lda+i] { + tmp := alpha * va + if tmp != 0 { + f32.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp) + } + } + } + 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] + tmp := alpha * va + if tmp != 0 { + f32.AxpyUnitaryTo(btmp, tmp, btmpk, btmp) + } + } + tmp := alpha + if nonUnit { + tmp *= a[k*lda+k] + } + if tmp != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + } + 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] + tmp := alpha * va + if tmp != 0 { + f32.AxpyUnitaryTo(btmp, tmp, btmpk, btmp) + } + } + tmp := alpha + if nonUnit { + tmp *= a[k*lda+k] + } + if tmp != 1 { + for j := 0; j < n; j++ { + btmpk[j] *= tmp + } + } + } + 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 { + btmp[k] = tmp + if nonUnit { + btmp[k] *= a[k*lda+k] + } + for ja, v := range a[k*lda+k+1 : k*lda+n] { + j := ja + k + 1 + btmp[j] += tmp * v + } + } + } + } + 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 { + btmp[k] = tmp + if nonUnit { + btmp[k] *= a[k*lda+k] + } + f32.AxpyUnitaryTo(btmp, tmp, a[k*lda:k*lda+k], btmp) + } + } + } + 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 + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/pardgemm_test.go b/vendor/gonum.org/v1/gonum/blas/gonum/pardgemm_test.go new file mode 100644 index 00000000..b88cd606 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/pardgemm_test.go @@ -0,0 +1,181 @@ +// 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 ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func TestDgemmParallel(t *testing.T) { + for i, test := range []struct { + m int + n int + k int + alpha float64 + tA blas.Transpose + tB blas.Transpose + }{ + { + m: 3, + n: 4, + k: 2, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: blockSize*2 + 5, + n: 3, + k: 2, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: 3, + n: blockSize * 2, + k: 2, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: 2, + n: 3, + k: blockSize*3 - 2, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: blockSize * minParBlock, + n: 3, + k: 2, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: 3, + n: blockSize * minParBlock, + k: 2, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: 2, + n: 3, + k: blockSize * minParBlock, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: blockSize*minParBlock + 1, + n: blockSize * minParBlock, + k: 3, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: 3, + n: blockSize*minParBlock + 2, + k: blockSize * 3, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: blockSize * minParBlock, + n: 3, + k: blockSize * minParBlock, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: blockSize * minParBlock, + n: blockSize * minParBlock, + k: blockSize * 3, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + { + m: blockSize + blockSize/2, + n: blockSize + blockSize/2, + k: blockSize + blockSize/2, + alpha: 2.5, + tA: blas.NoTrans, + tB: blas.NoTrans, + }, + } { + testMatchParallelSerial(t, i, blas.NoTrans, blas.NoTrans, test.m, test.n, test.k, test.alpha) + testMatchParallelSerial(t, i, blas.Trans, blas.NoTrans, test.m, test.n, test.k, test.alpha) + testMatchParallelSerial(t, i, blas.NoTrans, blas.Trans, test.m, test.n, test.k, test.alpha) + testMatchParallelSerial(t, i, blas.Trans, blas.Trans, test.m, test.n, test.k, test.alpha) + } +} + +func testMatchParallelSerial(t *testing.T, i int, tA, tB blas.Transpose, m, n, k int, alpha float64) { + var ( + rowA, colA int + rowB, colB int + ) + if tA == blas.NoTrans { + rowA = m + colA = k + } else { + rowA = k + colA = m + } + if tB == blas.NoTrans { + rowB = k + colB = n + } else { + rowB = n + colB = k + } + a := randmat(rowA, colA, colA) + b := randmat(rowB, colB, colB) + c := randmat(m, n, n) + + aClone := a.clone() + bClone := b.clone() + cClone := c.clone() + + lda := colA + ldb := colB + ldc := n + dgemmSerial(tA == blas.Trans, tB == blas.Trans, m, n, k, a.data, lda, b.data, ldb, cClone.data, ldc, alpha) + dgemmParallel(tA == blas.Trans, tB == blas.Trans, m, n, k, a.data, lda, b.data, ldb, c.data, ldc, alpha) + if !a.equal(aClone) { + t.Errorf("Case %v: a changed during call to dgemmParallel", i) + } + if !b.equal(bClone) { + t.Errorf("Case %v: b changed during call to dgemmParallel", i) + } + if !c.equalWithinAbs(cClone, 1e-12) { + t.Errorf("Case %v: answer not equal parallel and serial", i) + } +} + +func randmat(r, c, stride int) general64 { + data := make([]float64, r*stride+c) + for i := range data { + data[i] = rand.Float64() + } + return general64{ + data: data, + rows: r, + cols: c, + stride: stride, + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/sgemm.go b/vendor/gonum.org/v1/gonum/blas/gonum/sgemm.go new file mode 100644 index 00000000..06dd39bd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/sgemm.go @@ -0,0 +1,265 @@ +// 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 computes +// C = beta * C + alpha * A * B, +// where A, B, and C are dense matrices, 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) { + if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans { + panic(badTranspose) + } + if tB != blas.NoTrans && tB != blas.Trans && tB != blas.ConjTrans { + panic(badTranspose) + } + aTrans := tA == blas.Trans || tA == blas.ConjTrans + if aTrans { + checkSMatrix('a', k, m, a, lda) + } else { + checkSMatrix('a', m, k, a, lda) + } + bTrans := tB == blas.Trans || tB == blas.ConjTrans + if bTrans { + checkSMatrix('b', n, k, b, ldb) + } else { + checkSMatrix('b', k, n, b, ldb) + } + checkSMatrix('c', m, n, c, ldc) + + // 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^T * B) + // Cij = \sum_k Aik Bjk, (A * B^T) + // Cij = \sum_k Aki Bjk, (A^T * B^T) + // + // 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() + // Make local copies of otherwise global variables to reduce shared memory. + // This has a noticeable effect on benchmarks in some cases. + alpha := alpha + aTrans := aTrans + bTrans := bTrans + m := m + n := n + for sub := range sendChan { + i := sub.i + j := sub.j + 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.AxpyUnitaryTo(ctmp, 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.AxpyUnitaryTo(ctmp, 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] +} diff --git a/vendor/gonum.org/v1/gonum/blas/gonum/single_precision.bash b/vendor/gonum.org/v1/gonum/blas/gonum/single_precision.bash new file mode 100755 index 00000000..5213f0f2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/gonum/single_precision.bash @@ -0,0 +1,158 @@ +#!/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. + +WARNING='//\ +// Float32 implementations are autogenerated and not directly tested.\ +' + +# Level1 routines. + +echo Generating level1single.go +echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single.go +cat level1double.go \ +| gofmt -r 'blas.Float64Level1 -> blas.Float32Level1' \ +\ +| gofmt -r 'float64 -> float32' \ +| gofmt -r 'blas.DrotmParams -> blas.SrotmParams' \ +\ +| gofmt -r 'f64.AxpyInc -> f32.AxpyInc' \ +| gofmt -r 'f64.AxpyIncTo -> f32.AxpyIncTo' \ +| gofmt -r 'f64.AxpyUnitary -> f32.AxpyUnitary' \ +| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \ +| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \ +| gofmt -r 'f64.ScalInc -> f32.ScalInc' \ +| gofmt -r 'f64.ScalUnitary -> f32.ScalUnitary' \ +\ +| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \ + -e 's_^// D_// S_' \ + -e "s_^\(func (Implementation) \)Id\(.*\)\$_$WARNING\1Is\2_" \ + -e 's_^// Id_// Is_' \ + -e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \ + -e 's_"math"_math "gonum.org/v1/gonum/internal/math32"_' \ +>> level1single.go + +echo Generating level1single_sdot.go +echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single_sdot.go +cat level1double_ddot.go \ +| gofmt -r 'float64 -> float32' \ +\ +| gofmt -r 'f64.DotInc -> f32.DotInc' \ +| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \ +\ +| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \ + -e 's_^// D_// S_' \ + -e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \ +>> level1single_sdot.go + +echo Generating level1single_dsdot.go +echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single_dsdot.go +cat level1double_ddot.go \ +| gofmt -r '[]float64 -> []float32' \ +\ +| gofmt -r 'f64.DotInc -> f32.DdotInc' \ +| gofmt -r 'f64.DotUnitary -> f32.DdotUnitary' \ +\ +| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1Ds\2_" \ + -e 's_^// D_// Ds_' \ + -e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \ +>> level1single_dsdot.go + +echo Generating level1single_sdsdot.go +echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single_sdsdot.go +cat level1double_ddot.go \ +| gofmt -r 'float64 -> float32' \ +\ +| gofmt -r 'f64.DotInc(x, y, f(n), f(incX), f(incY), f(ix), f(iy)) -> alpha + float32(f32.DdotInc(x, y, f(n), f(incX), f(incY), f(ix), f(iy)))' \ +| gofmt -r 'f64.DotUnitary(a, b) -> alpha + float32(f32.DdotUnitary(a, b))' \ +\ +| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1Sds\2_" \ + -e 's_^// D\(.*\)$_// Sds\1 plus a constant_' \ + -e 's_\\sum_alpha + \\sum_' \ + -e 's/n int/n int, alpha float32/' \ + -e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \ +>> level1single_sdsdot.go + + +# Level2 routines. + +echo Generating level2single.go +echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level2single.go +cat level2double.go \ +| gofmt -r 'blas.Float64Level2 -> blas.Float32Level2' \ +\ +| gofmt -r 'float64 -> float32' \ +\ +| gofmt -r 'Dscal -> Sscal' \ +\ +| gofmt -r 'f64.AxpyInc -> f32.AxpyInc' \ +| gofmt -r 'f64.AxpyIncTo -> f32.AxpyIncTo' \ +| gofmt -r 'f64.AxpyUnitary -> f32.AxpyUnitary' \ +| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \ +| gofmt -r 'f64.DotInc -> f32.DotInc' \ +| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \ +\ +| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \ + -e 's_^// D_// S_' \ + -e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \ +>> level2single.go + + +# Level3 routines. + +echo Generating level3single.go +echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level3single.go +cat level3double.go \ +| gofmt -r 'blas.Float64Level3 -> blas.Float32Level3' \ +\ +| gofmt -r 'float64 -> float32' \ +\ +| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \ +| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \ +\ +| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \ + -e 's_^// D_// S_' \ + -e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \ +>> level3single.go + +echo Generating general_single.go +echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > general_single.go +cat general_double.go \ +| gofmt -r 'float64 -> float32' \ +\ +| gofmt -r 'general64 -> general32' \ +| gofmt -r 'newGeneral64 -> newGeneral32' \ +\ +| sed -e 's/(g general64) print()/(g general32) print()/' \ + -e 's_"math"_math "gonum.org/v1/gonum/internal/math32"_' \ + -e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \ +>> general_single.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 'general64 -> general32' \ +| gofmt -r 'sliceView64 -> sliceView32' \ +| gofmt -r 'checkDMatrix -> checkSMatrix' \ +\ +| 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.AxpyIncTo -> f32.AxpyIncTo' \ +| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \ +| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \ +\ +| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\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 diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/benchautogen/autogen_bench_level1double.go b/vendor/gonum.org/v1/gonum/blas/testblas/benchautogen/autogen_bench_level1double.go new file mode 100644 index 00000000..35e08c1e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/benchautogen/autogen_bench_level1double.go @@ -0,0 +1,292 @@ +// Copyright 2014 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 + +// Script for automatic code generation of the benchmark routines. +package main + +import ( + "fmt" + "os" + "os/exec" + "path" + "path/filepath" + "strconv" +) + +var gopath string + +var copyrightnotice = []byte(`// Copyright 2014 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`) + +var autogen = []byte("// Code generated by \"go run gonum.org/v1/gonum/blas/testblas/benchautogen/autogen_bench_level1double.go\"; DO NOT EDIT.\n") + +var imports = []byte(`import( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +)`) + +var randomSliceFunction = []byte(`func randomSlice(l, idx int) ([]float64) { + if idx < 0{ + idx = -idx + } + s := make([]float64, l * idx) + for i := range s { + s[i] = rand.Float64() + } + return s +}`) + +const ( + posInc1 = 5 + posInc2 = 3 + negInc1 = -3 + negInc2 = -4 +) + +var level1Sizes = []struct { + lower string + upper string + camel string + size int +}{ + { + lower: "small", + upper: "SMALL_SLICE", + camel: "Small", + size: 10, + }, + { + lower: "medium", + upper: "MEDIUM_SLICE", + camel: "Medium", + size: 1000, + }, + { + lower: "large", + upper: "LARGE_SLICE", + camel: "Large", + size: 100000, + }, + { + lower: "huge", + upper: "HUGE_SLICE", + camel: "Huge", + size: 10000000, + }, +} + +type level1functionStruct struct { + camel string + sig string + call string + extraSetup string + oneInput bool + extraName string // if have a couple different cases for the same function +} + +var level1Functions = []level1functionStruct{ + { + camel: "Ddot", + sig: "n int, x []float64, incX int, y []float64, incY int", + call: "n, x, incX, y, incY", + oneInput: false, + }, + { + camel: "Dnrm2", + sig: "n int, x []float64, incX int", + call: "n, x, incX", + oneInput: true, + }, + { + camel: "Dasum", + sig: "n int, x []float64, incX int", + call: "n, x, incX", + oneInput: true, + }, + { + camel: "Idamax", + sig: "n int, x []float64, incX int", + call: "n, x, incX", + oneInput: true, + }, + { + camel: "Dswap", + sig: "n int, x []float64, incX int, y []float64, incY int", + call: "n, x, incX, y, incY", + oneInput: false, + }, + { + camel: "Dcopy", + sig: "n int, x []float64, incX int, y []float64, incY int", + call: "n, x, incX, y, incY", + oneInput: false, + }, + { + camel: "Daxpy", + sig: "n int, alpha float64, x []float64, incX int, y []float64, incY int", + call: "n, alpha, x, incX, y, incY", + extraSetup: "alpha := 2.4", + oneInput: false, + }, + { + camel: "Drot", + sig: "n int, x []float64, incX int, y []float64, incY int, c, s float64", + call: "n, x, incX, y, incY, c, s", + extraSetup: "c := 0.89725836967\ns:= 0.44150585279", + oneInput: false, + }, + { + camel: "Drotm", + sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams", + call: "n, x, incX, y, incY, p", + extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{0, -0.625, 0.9375,0}}", + oneInput: false, + extraName: "OffDia", + }, + { + camel: "Drotm", + sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams", + call: "n, x, incX, y, incY, p", + extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{5.0 / 12, 0, 0, 0.625}}", + oneInput: false, + extraName: "Dia", + }, + { + camel: "Drotm", + sig: "n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams", + call: "n, x, incX, y, incY, p", + extraSetup: "p := blas.DrotmParams{Flag: blas.OffDiagonal, H: [4]float64{4096, -3584, 1792, 4096}}", + oneInput: false, + extraName: "Resc", + }, + { + camel: "Dscal", + sig: "n int, alpha float64, x []float64, incX int", + call: "n, alpha, x, incX", + extraSetup: "alpha := 2.4", + oneInput: true, + }, +} + +func init() { + gopath = os.Getenv("GOPATH") + if gopath == "" { + panic("gopath not set") + } +} + +func main() { + blasPath := filepath.Join(gopath, "src", "gonum.org", "v1", "gonum", "blas") + + pkgs := []struct{ name string }{{name: "native"}, {name: "cgo"}} + + for _, pkg := range pkgs { + err := level1(filepath.Join(blasPath, pkg.name), pkg.name) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + err = exec.Command("go", "fmt", path.Join("gonum.org", "v1", "gonum", "blas", pkg.name)).Run() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } +} + +func printHeader(f *os.File, name string) error { + if _, err := f.Write(autogen); err != nil { + return err + } + f.WriteString("\n\n") + f.Write(copyrightnotice) + f.WriteString("\n\n") + f.WriteString("package " + name) + f.WriteString("\n\n") + f.Write(imports) + f.WriteString("\n\n") + return nil +} + +// Generate the benchmark scripts for level1 +func level1(benchPath string, pkgname string) error { + // Generate level 1 benchmarks + level1Filepath := filepath.Join(benchPath, "level1doubleBench_auto_test.go") + f, err := os.Create(level1Filepath) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer f.Close() + printHeader(f, pkgname) + + // Print all of the constants + f.WriteString("const (\n") + f.WriteString("\tposInc1 = " + strconv.Itoa(posInc1) + "\n") + f.WriteString("\tposInc2 = " + strconv.Itoa(posInc2) + "\n") + f.WriteString("\tnegInc1 = " + strconv.Itoa(negInc1) + "\n") + f.WriteString("\tnegInc2 = " + strconv.Itoa(negInc2) + "\n") + for _, con := range level1Sizes { + f.WriteString("\t" + con.upper + " = " + strconv.Itoa(con.size) + "\n") + } + f.WriteString(")\n") + f.WriteString("\n") + + // Write the randomSlice function + f.Write(randomSliceFunction) + f.WriteString("\n\n") + + // Start writing the benchmarks + for _, fun := range level1Functions { + writeLevel1Benchmark(fun, f) + f.WriteString("\n/* ------------------ */ \n") + } + + return nil +} + +func writeLevel1Benchmark(fun level1functionStruct, f *os.File) { + // First, write the base benchmark file + f.WriteString("func benchmark" + fun.camel + fun.extraName + "(b *testing.B, ") + f.WriteString(fun.sig) + f.WriteString(") {\n") + + f.WriteString("b.ResetTimer()\n") + f.WriteString("for i := 0; i < b.N; i++{\n") + f.WriteString("\timpl." + fun.camel + "(") + + f.WriteString(fun.call) + f.WriteString(")\n}\n}\n") + f.WriteString("\n") + + // Write all of the benchmarks to call it + for _, sz := range level1Sizes { + lambda := func(incX, incY, name string, twoInput bool) { + f.WriteString("func Benchmark" + fun.camel + fun.extraName + sz.camel + name + "(b *testing.B){\n") + f.WriteString("n := " + sz.upper + "\n") + f.WriteString("incX := " + incX + "\n") + f.WriteString("x := randomSlice(n, incX)\n") + if twoInput { + f.WriteString("incY := " + incY + "\n") + f.WriteString("y := randomSlice(n, incY)\n") + } + f.WriteString(fun.extraSetup + "\n") + f.WriteString("benchmark" + fun.camel + fun.extraName + "(b, " + fun.call + ")\n") + f.WriteString("}\n\n") + } + if fun.oneInput { + lambda("1", "", "UnitaryInc", false) + lambda("posInc1", "", "PosInc", false) + } else { + lambda("1", "1", "BothUnitary", true) + lambda("posInc1", "1", "IncUni", true) + lambda("1", "negInc1", "UniInc", true) + lambda("posInc1", "negInc1", "BothInc", true) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/benchsize.go b/vendor/gonum.org/v1/gonum/blas/testblas/benchsize.go new file mode 100644 index 00000000..41d132be --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/benchsize.go @@ -0,0 +1,8 @@ +package testblas + +const ( + SmallMat = 10 + MediumMat = 100 + LargeMat = 1000 + HugeMat = 10000 +) diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/common.go b/vendor/gonum.org/v1/gonum/blas/testblas/common.go new file mode 100644 index 00000000..68a4c05a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/common.go @@ -0,0 +1,316 @@ +// 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 testblas + +import ( + "math" + "math/cmplx" + "testing" + + "gonum.org/v1/gonum/blas" +) + +// throwPanic will throw unexpected panics if true, or will just report them as errors if false +const throwPanic = true + +func dTolEqual(a, b float64) bool { + if math.IsNaN(a) && math.IsNaN(b) { + return true + } + if a == b { + return true + } + m := math.Max(math.Abs(a), math.Abs(b)) + if m > 1 { + a /= m + b /= m + } + if math.Abs(a-b) < 1e-14 { + return true + } + return false +} + +func dSliceTolEqual(a, b []float64) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if !dTolEqual(a[i], b[i]) { + return false + } + } + return true +} + +func dStridedSliceTolEqual(n int, a []float64, inca int, b []float64, incb int) bool { + ia := 0 + ib := 0 + if inca <= 0 { + ia = -(n - 1) * inca + } + if incb <= 0 { + ib = -(n - 1) * incb + } + for i := 0; i < n; i++ { + if !dTolEqual(a[ia], b[ib]) { + return false + } + ia += inca + ib += incb + } + return true +} + +func dSliceEqual(a, b []float64) bool { + if len(a) != len(b) { + return false + } + for i := range a { + if !(a[i] == b[i]) { + return false + } + } + return true +} + +func dCopyTwoTmp(x, xTmp, y, yTmp []float64) { + if len(x) != len(xTmp) { + panic("x size mismatch") + } + if len(y) != len(yTmp) { + panic("y size mismatch") + } + copy(xTmp, x) + copy(yTmp, y) +} + +// returns true if the function panics +func panics(f func()) (b bool) { + defer func() { + err := recover() + if err != nil { + b = true + } + }() + f() + return +} + +func testpanics(f func(), name string, t *testing.T) { + b := panics(f) + if !b { + t.Errorf("%v should panic and does not", name) + } +} + +func sliceOfSliceCopy(a [][]float64) [][]float64 { + n := make([][]float64, len(a)) + for i := range a { + n[i] = make([]float64, len(a[i])) + copy(n[i], a[i]) + } + return n +} + +func sliceCopy(a []float64) []float64 { + n := make([]float64, len(a)) + copy(n, a) + return n +} + +func flatten(a [][]float64) []float64 { + if len(a) == 0 { + return nil + } + m := len(a) + n := len(a[0]) + s := make([]float64, m*n) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + s[i*n+j] = a[i][j] + } + } + return s +} + +func unflatten(a []float64, m, n int) [][]float64 { + s := make([][]float64, m) + for i := 0; i < m; i++ { + s[i] = make([]float64, n) + for j := 0; j < n; j++ { + s[i][j] = a[i*n+j] + } + } + return s +} + +// flattenTriangular turns the upper or lower triangle of a dense slice of slice +// into a single slice with packed storage. a must be a square matrix. +func flattenTriangular(a [][]float64, ul blas.Uplo) []float64 { + m := len(a) + aFlat := make([]float64, m*(m+1)/2) + var k int + if ul == blas.Upper { + for i := 0; i < m; i++ { + k += copy(aFlat[k:], a[i][i:]) + } + return aFlat + } + for i := 0; i < m; i++ { + k += copy(aFlat[k:], a[i][:i+1]) + } + return aFlat +} + +// flattenBanded turns a dense banded slice of slice into the compact banded matrix format +func flattenBanded(a [][]float64, ku, kl int) []float64 { + m := len(a) + n := len(a[0]) + if ku < 0 || kl < 0 { + panic("testblas: negative band length") + } + nRows := m + nCols := (ku + kl + 1) + aflat := make([]float64, nRows*nCols) + for i := range aflat { + aflat[i] = math.NaN() + } + // loop over the rows, and then the bands + // elements in the ith row stay in the ith row + // order in bands is kept + for i := 0; i < nRows; i++ { + min := -kl + if i-kl < 0 { + min = -i + } + max := ku + if i+ku >= n { + max = n - i - 1 + } + for j := min; j <= max; j++ { + col := kl + j + aflat[i*nCols+col] = a[i][i+j] + } + } + return aflat +} + +// makeIncremented takes a slice with inc == 1 and makes an incremented version +// and adds extra values on the end +func makeIncremented(x []float64, inc int, extra int) []float64 { + if inc == 0 { + panic("zero inc") + } + absinc := inc + if absinc < 0 { + absinc = -inc + } + xcopy := make([]float64, len(x)) + if inc > 0 { + copy(xcopy, x) + } else { + for i := 0; i < len(x); i++ { + xcopy[i] = x[len(x)-i-1] + } + } + + // don't use NaN because it makes comparison hard + // Do use a weird unique value for easier debugging + counter := 100.0 + var xnew []float64 + for i, v := range xcopy { + xnew = append(xnew, v) + if i != len(x)-1 { + for j := 0; j < absinc-1; j++ { + xnew = append(xnew, counter) + counter++ + } + } + } + for i := 0; i < extra; i++ { + xnew = append(xnew, counter) + counter++ + } + return xnew +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} + +func allPairs(x, y []int) [][2]int { + var p [][2]int + for _, v0 := range x { + for _, v1 := range y { + p = append(p, [2]int{v0, v1}) + } + } + return p +} + +func zsame(x, y []complex128) bool { + if len(x) != len(y) { + return false + } + for i, v := range x { + w := y[i] + if v != w && !math.IsNaN(real(v)) && !math.IsNaN(imag(v)) && !math.IsNaN(real(w)) && !math.IsNaN(imag(w)) { + return false + } + } + return true +} + +func makeZVector(data []complex128, inc int) []complex128 { + if inc == 0 { + panic("bad test") + } + if len(data) == 0 { + return nil + } + inc = abs(inc) + x := make([]complex128, (len(data)-1)*inc+1) + for i := range x { + x[i] = cmplx.NaN() + } + for i, v := range data { + x[i*inc] = v + } + return x +} + +func makeZGeneral(data []complex128, m, n int, ld int) []complex128 { + if m < 0 || n < 0 { + panic("bad test") + } + if len(data) != m*n { + panic("bad test") + } + if ld < max(1, n) { + panic("bad test") + } + if len(data) == 0 { + return nil + } + a := make([]complex128, (m-1)*ld+n) + for i := range a { + a[i] = cmplx.NaN() + } + for i := 0; i < m; i++ { + copy(a[i*ld:i*ld+n], data[i*n:i*n+n]) + } + return a +} + +func max(a, b int) int { + if a < b { + return b + } + return a +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/common_test.go b/vendor/gonum.org/v1/gonum/blas/testblas/common_test.go new file mode 100644 index 00000000..852a939e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/common_test.go @@ -0,0 +1,187 @@ +package testblas + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +func TestFlattenBanded(t *testing.T) { + for i, test := range []struct { + dense [][]float64 + ku int + kl int + condensed [][]float64 + }{ + { + dense: [][]float64{{3}}, + ku: 0, + kl: 0, + condensed: [][]float64{{3}}, + }, + { + dense: [][]float64{ + {3, 4, 0}, + }, + ku: 1, + kl: 0, + condensed: [][]float64{ + {3, 4}, + }, + }, + { + dense: [][]float64{ + {3, 4, 0, 0, 0}, + }, + ku: 1, + kl: 0, + condensed: [][]float64{ + {3, 4}, + }, + }, + { + dense: [][]float64{ + {3, 4, 0}, + {0, 5, 8}, + {0, 0, 2}, + {0, 0, 0}, + {0, 0, 0}, + }, + ku: 1, + kl: 0, + condensed: [][]float64{ + {3, 4}, + {5, 8}, + {2, math.NaN()}, + {math.NaN(), math.NaN()}, + {math.NaN(), math.NaN()}, + }, + }, + { + dense: [][]float64{ + {3, 4, 6}, + {0, 5, 8}, + {0, 0, 2}, + {0, 0, 0}, + {0, 0, 0}, + }, + ku: 2, + kl: 0, + condensed: [][]float64{ + {3, 4, 6}, + {5, 8, math.NaN()}, + {2, math.NaN(), math.NaN()}, + {math.NaN(), math.NaN(), math.NaN()}, + {math.NaN(), math.NaN(), math.NaN()}, + }, + }, + { + dense: [][]float64{ + {3, 4, 6}, + {1, 5, 8}, + {0, 6, 2}, + {0, 0, 7}, + {0, 0, 0}, + }, + ku: 2, + kl: 1, + condensed: [][]float64{ + {math.NaN(), 3, 4, 6}, + {1, 5, 8, math.NaN()}, + {6, 2, math.NaN(), math.NaN()}, + {7, math.NaN(), math.NaN(), math.NaN()}, + {math.NaN(), math.NaN(), math.NaN(), math.NaN()}, + }, + }, + { + dense: [][]float64{ + {1, 2, 0}, + {3, 4, 5}, + {6, 7, 8}, + {0, 9, 10}, + {0, 0, 11}, + }, + ku: 1, + kl: 2, + condensed: [][]float64{ + {math.NaN(), math.NaN(), 1, 2}, + {math.NaN(), 3, 4, 5}, + {6, 7, 8, math.NaN()}, + {9, 10, math.NaN(), math.NaN()}, + {11, math.NaN(), math.NaN(), math.NaN()}, + }, + }, + { + dense: [][]float64{ + {1, 0, 0}, + {3, 4, 0}, + {6, 7, 8}, + {0, 9, 10}, + {0, 0, 11}, + }, + ku: 0, + kl: 2, + condensed: [][]float64{ + {math.NaN(), math.NaN(), 1}, + {math.NaN(), 3, 4}, + {6, 7, 8}, + {9, 10, math.NaN()}, + {11, math.NaN(), math.NaN()}, + }, + }, + { + dense: [][]float64{ + {1, 0, 0, 0, 0}, + {3, 4, 0, 0, 0}, + {1, 3, 5, 0, 0}, + }, + ku: 0, + kl: 2, + condensed: [][]float64{ + {math.NaN(), math.NaN(), 1}, + {math.NaN(), 3, 4}, + {1, 3, 5}, + }, + }, + } { + condensed := flattenBanded(test.dense, test.ku, test.kl) + correct := flatten(test.condensed) + if !floats.Same(condensed, correct) { + t.Errorf("Case %v mismatch. Want %v, got %v.", i, correct, condensed) + } + } +} + +func TestFlattenTriangular(t *testing.T) { + for i, test := range []struct { + a [][]float64 + ans []float64 + ul blas.Uplo + }{ + { + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + ul: blas.Upper, + ans: []float64{1, 2, 3, 4, 5, 6}, + }, + { + a: [][]float64{ + {1, 0, 0}, + {2, 3, 0}, + {4, 5, 6}, + }, + ul: blas.Lower, + ans: []float64{1, 2, 3, 4, 5, 6}, + }, + } { + a := flattenTriangular(test.a, test.ul) + if !floats.Equal(a, test.ans) { + t.Errorf("Case %v. Want %v, got %v.", i, test.ans, a) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dgbmv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dgbmv.go new file mode 100644 index 00000000..1e0a5c18 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dgbmv.go @@ -0,0 +1,131 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dgbmver interface { + Dgbmv(tA blas.Transpose, m, n, kL, kU int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) +} + +func DgbmvTest(t *testing.T, blasser Dgbmver) { + for i, test := range []struct { + tA blas.Transpose + m, n int + kL, kU int + alpha float64 + a [][]float64 + lda int + x []float64 + beta float64 + y []float64 + ans []float64 + }{ + { + tA: blas.NoTrans, + m: 9, + n: 6, + lda: 4, + kL: 2, + kU: 1, + alpha: 3.0, + beta: 2.0, + a: [][]float64{ + {5, 3, 0, 0, 0, 0}, + {-1, 2, 9, 0, 0, 0}, + {4, 8, 3, 6, 0, 0}, + {0, -1, 8, 2, 1, 0}, + {0, 0, 9, 9, 9, 5}, + {0, 0, 0, 2, -3, 2}, + {0, 0, 0, 0, 1, 5}, + {0, 0, 0, 0, 0, 6}, + }, + x: []float64{1, 2, 3, 4, 5, 6}, + y: []float64{-1, -2, -3, -4, -5, -6, -7, -8, -9}, + ans: []float64{31, 86, 153, 97, 404, 3, 91, 92, -18}, + }, + { + tA: blas.Trans, + m: 9, + n: 6, + lda: 4, + kL: 2, + kU: 1, + alpha: 3.0, + beta: 2.0, + a: [][]float64{ + {5, 3, 0, 0, 0, 0}, + {-1, 2, 9, 0, 0, 0}, + {4, 8, 3, 6, 0, 0}, + {0, -1, 8, 2, 1, 0}, + {0, 0, 9, 9, 9, 5}, + {0, 0, 0, 2, -3, 2}, + {0, 0, 0, 0, 1, 5}, + {0, 0, 0, 0, 0, 6}, + }, + x: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}, + y: []float64{-1, -2, -3, -4, -5, -6}, + ans: []float64{43, 77, 306, 241, 104, 348}, + }, + { + tA: blas.NoTrans, + m: 6, + n: 3, + lda: 1, + kL: 0, + kU: 0, + alpha: 2.0, + beta: 1.0, + a: [][]float64{ + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + }, + x: []float64{1, 2, 3}, + y: []float64{-1, -2, -3, -4, -5, -6}, + ans: []float64{1, 2, 3, -4, -5, -6}, + }, + { + tA: blas.Trans, + m: 6, + n: 3, + lda: 1, + kL: 0, + kU: 0, + alpha: 2.0, + beta: 1.0, + a: [][]float64{ + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + {0, 0, 0}, + {0, 0, 0}, + {0, 0, 0}, + }, + x: []float64{1, 2, 3, 4, 5, 6}, + y: []float64{-1, -2, -3}, + ans: []float64{1, 2, 3}, + }, + } { + extra := 3 + aFlat := flattenBanded(test.a, test.kU, test.kL) + incTest := func(incX, incY, extra int) { + xnew := makeIncremented(test.x, incX, extra) + ynew := makeIncremented(test.y, incY, extra) + ans := makeIncremented(test.ans, incY, extra) + blasser.Dgbmv(test.tA, test.m, test.n, test.kL, test.kU, test.alpha, aFlat, test.lda, xnew, incX, test.beta, ynew, incY) + if !dSliceTolEqual(ans, ynew) { + t.Errorf("Case %v: Want %v, got %v", i, ans, ynew) + } + } + incTest(1, 1, extra) + incTest(1, 3, extra) + incTest(1, -3, extra) + incTest(2, 3, extra) + incTest(2, -3, extra) + incTest(3, 2, extra) + incTest(-3, 2, extra) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dgemm.go b/vendor/gonum.org/v1/gonum/blas/testblas/dgemm.go new file mode 100644 index 00000000..f4bcddd8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dgemm.go @@ -0,0 +1,244 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dgemmer interface { + 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) +} + +type DgemmCase struct { + m, n, k int + alpha, beta float64 + a [][]float64 + b [][]float64 + c [][]float64 + ans [][]float64 +} + +var DgemmCases = []DgemmCase{ + + { + m: 4, + n: 3, + k: 2, + alpha: 2, + beta: 0.5, + a: [][]float64{ + {1, 2}, + {4, 5}, + {7, 8}, + {10, 11}, + }, + b: [][]float64{ + {1, 5, 6}, + {5, -8, 8}, + }, + c: [][]float64{ + {4, 8, -9}, + {12, 16, -8}, + {1, 5, 15}, + {-3, -4, 7}, + }, + ans: [][]float64{ + {24, -18, 39.5}, + {64, -32, 124}, + {94.5, -55.5, 219.5}, + {128.5, -78, 299.5}, + }, + }, + { + m: 4, + n: 2, + k: 3, + alpha: 2, + beta: 0.5, + a: [][]float64{ + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + {10, 11, 12}, + }, + b: [][]float64{ + {1, 5}, + {5, -8}, + {6, 2}, + }, + c: [][]float64{ + {4, 8}, + {12, 16}, + {1, 5}, + {-3, -4}, + }, + ans: [][]float64{ + {60, -6}, + {136, -8}, + {202.5, -19.5}, + {272.5, -30}, + }, + }, + { + m: 3, + n: 2, + k: 4, + alpha: 2, + beta: 0.5, + a: [][]float64{ + {1, 2, 3, 4}, + {4, 5, 6, 7}, + {8, 9, 10, 11}, + }, + b: [][]float64{ + {1, 5}, + {5, -8}, + {6, 2}, + {8, 10}, + }, + c: [][]float64{ + {4, 8}, + {12, 16}, + {9, -10}, + }, + ans: [][]float64{ + {124, 74}, + {248, 132}, + {406.5, 191}, + }, + }, + { + m: 3, + n: 4, + k: 2, + alpha: 2, + beta: 0.5, + a: [][]float64{ + {1, 2}, + {4, 5}, + {8, 9}, + }, + b: [][]float64{ + {1, 5, 2, 1}, + {5, -8, 2, 1}, + }, + c: [][]float64{ + {4, 8, 2, 2}, + {12, 16, 8, 9}, + {9, -10, 10, 10}, + }, + ans: [][]float64{ + {24, -18, 13, 7}, + {64, -32, 40, 22.5}, + {110.5, -69, 73, 39}, + }, + }, + { + m: 2, + n: 4, + k: 3, + alpha: 2, + beta: 0.5, + a: [][]float64{ + {1, 2, 3}, + {4, 5, 6}, + }, + b: [][]float64{ + {1, 5, 8, 8}, + {5, -8, 9, 10}, + {6, 2, -3, 2}, + }, + c: [][]float64{ + {4, 8, 7, 8}, + {12, 16, -2, 6}, + }, + ans: [][]float64{ + {60, -6, 37.5, 72}, + {136, -8, 117, 191}, + }, + }, + { + m: 2, + n: 3, + k: 4, + alpha: 2, + beta: 0.5, + a: [][]float64{ + {1, 2, 3, 4}, + {4, 5, 6, 7}, + }, + b: [][]float64{ + {1, 5, 8}, + {5, -8, 9}, + {6, 2, -3}, + {8, 10, 2}, + }, + c: [][]float64{ + {4, 8, 1}, + {12, 16, 6}, + }, + ans: [][]float64{ + {124, 74, 50.5}, + {248, 132, 149}, + }, + }, +} + +// assumes [][]float64 is actually a matrix +func transpose(a [][]float64) [][]float64 { + b := make([][]float64, len(a[0])) + for i := range b { + b[i] = make([]float64, len(a)) + for j := range b[i] { + b[i][j] = a[j][i] + } + } + return b +} + +func TestDgemm(t *testing.T, blasser Dgemmer) { + for i, test := range DgemmCases { + // Test that it passes row major + dgemmcomp(i, "RowMajorNoTrans", t, blasser, blas.NoTrans, blas.NoTrans, + test.m, test.n, test.k, test.alpha, test.beta, test.a, test.b, test.c, test.ans) + // Try with A transposed + dgemmcomp(i, "RowMajorTransA", t, blasser, blas.Trans, blas.NoTrans, + test.m, test.n, test.k, test.alpha, test.beta, transpose(test.a), test.b, test.c, test.ans) + // Try with B transposed + dgemmcomp(i, "RowMajorTransB", t, blasser, blas.NoTrans, blas.Trans, + test.m, test.n, test.k, test.alpha, test.beta, test.a, transpose(test.b), test.c, test.ans) + // Try with both transposed + dgemmcomp(i, "RowMajorTransBoth", t, blasser, blas.Trans, blas.Trans, + test.m, test.n, test.k, test.alpha, test.beta, transpose(test.a), transpose(test.b), test.c, test.ans) + } +} + +func dgemmcomp(i int, name string, t *testing.T, blasser Dgemmer, tA, tB blas.Transpose, m, n, k int, + alpha, beta float64, a [][]float64, b [][]float64, c [][]float64, ans [][]float64) { + + aFlat := flatten(a) + aCopy := flatten(a) + bFlat := flatten(b) + bCopy := flatten(b) + cFlat := flatten(c) + ansFlat := flatten(ans) + lda := len(a[0]) + ldb := len(b[0]) + ldc := len(c[0]) + + // Compute the matrix multiplication + blasser.Dgemm(tA, tB, m, n, k, alpha, aFlat, lda, bFlat, ldb, beta, cFlat, ldc) + + if !dSliceEqual(aFlat, aCopy) { + t.Errorf("Test %v case %v: a changed during call to Dgemm", i, name) + } + if !dSliceEqual(bFlat, bCopy) { + t.Errorf("Test %v case %v: b changed during call to Dgemm", i, name) + } + + if !dSliceTolEqual(ansFlat, cFlat) { + t.Errorf("Test %v case %v: answer mismatch. Expected %v, Found %v", i, name, ansFlat, cFlat) + } + // TODO: Need to add a sub-slice test where don't use up full matrix +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dgemmbench.go b/vendor/gonum.org/v1/gonum/blas/testblas/dgemmbench.go new file mode 100644 index 00000000..512f4eca --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dgemmbench.go @@ -0,0 +1,39 @@ +package testblas + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func DgemmBenchmark(b *testing.B, dgemm Dgemmer, m, n, k int, tA, tB blas.Transpose) { + a := make([]float64, m*k) + for i := range a { + a[i] = rand.Float64() + } + bv := make([]float64, k*n) + for i := range bv { + bv[i] = rand.Float64() + } + c := make([]float64, m*n) + for i := range c { + c[i] = rand.Float64() + } + var lda, ldb int + if tA == blas.Trans { + lda = m + } else { + lda = k + } + if tB == blas.Trans { + ldb = k + } else { + ldb = n + } + ldc := n + b.ResetTimer() + for i := 0; i < b.N; i++ { + dgemm.Dgemm(tA, tB, m, n, k, 3.0, a, lda, bv, ldb, 1.0, c, ldc) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dgemv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dgemv.go new file mode 100644 index 00000000..d18dde2f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dgemv.go @@ -0,0 +1,678 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type DgemvCase struct { + Name string + m int + n int + A [][]float64 + tA blas.Transpose + x []float64 + incX int + y []float64 + incY int + + Subcases []DgemvSubcase +} + +type DgemvSubcase struct { + mulXNeg1 bool + mulYNeg1 bool + alpha float64 + beta float64 + ans []float64 +} + +var DgemvCases = []DgemvCase{ + { + Name: "M_gt_N_Inc1_NoTrans", + tA: blas.NoTrans, + m: 5, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + {1, 1, 2}, + {9, 2, 5}, + }, + incX: 1, + incY: 1, + x: []float64{1, 2, 3}, + y: []float64{7, 8, 9, 10, 11}, + + Subcases: []DgemvSubcase{ + { + alpha: 0, + beta: 0, + ans: []float64{0, 0, 0, 0, 0}, + }, + { + alpha: 0, + beta: 1, + ans: []float64{7, 8, 9, 10, 11}, + }, + { + alpha: 1, + beta: 0, + ans: []float64{40.8, 43.9, 33, 9, 28}, + }, + { + alpha: 8, + beta: -6, + ans: []float64{284.4, 303.2, 210, 12, 158}, + }, + }, + }, + { + Name: "M_gt_N_Inc1_Trans", + tA: blas.Trans, + m: 5, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + {1, 1, 2}, + {9, 2, 5}, + }, + incX: 1, + incY: 1, + x: []float64{1, 2, 3, -4, 5}, + y: []float64{7, 8, 9}, + + Subcases: []DgemvSubcase{ + { + alpha: 0, + beta: 0, + ans: []float64{0, 0, 0}, + }, + { + alpha: 0, + beta: 1, + ans: []float64{7, 8, 9}, + }, + { + alpha: 1, + beta: 0, + ans: []float64{94.3, 40.2, 52.3}, + }, + { + alpha: 8, + beta: -6, + ans: []float64{712.4, 273.6, 364.4}, + }, + }, + }, + { + Name: "M_eq_N_Inc1_NoTrans", + tA: blas.NoTrans, + m: 3, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + }, + incX: 1, + incY: 1, + x: []float64{1, 2, 3}, + y: []float64{7, 2, 2}, + + Subcases: []DgemvSubcase{ + { + alpha: 0, + beta: 0, + ans: []float64{0, 0, 0}, + }, + { + alpha: 0, + beta: 1, + ans: []float64{7, 2, 2}, + }, + { + alpha: 1, + beta: 0, + ans: []float64{40.8, 43.9, 33}, + }, + { + alpha: 8, + beta: -6, + ans: []float64{40.8*8 - 6*7, 43.9*8 - 6*2, 33*8 - 6*2}, + }, + }, + }, + { + Name: "M_eq_N_Inc1_Trans", + tA: blas.Trans, + m: 3, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + }, + incX: 1, + incY: 1, + x: []float64{1, 2, 3}, + y: []float64{7, 2, 2}, + + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{384.4, 261.6, 270.4}, + }, + }, + }, + { + Name: "M_lt_N_Inc1_NoTrans", + tA: blas.NoTrans, + m: 3, + n: 5, + A: [][]float64{ + {4.1, 6.2, 8.1, 10, 7}, + {9.6, 3.5, 9.1, -2, 9}, + {10, 7, 3, 1, -5}, + }, + incX: 1, + incY: 1, + x: []float64{1, 2, 3, -7.6, 8.1}, + y: []float64{7, 2, 2}, + + Subcases: []DgemvSubcase{ + { + alpha: 0, + beta: 0, + ans: []float64{0, 0, 0}, + }, + { + alpha: 0, + beta: 1, + ans: []float64{7, 2, 2}, + }, + { + alpha: 1, + beta: 0, + ans: []float64{21.5, 132, -15.1}, + }, + + { + alpha: 8, + beta: -6, + ans: []float64{21.5*8 - 6*7, 132*8 - 6*2, -15.1*8 - 6*2}, + }, + }, + }, + { + Name: "M_lt_N_Inc1_Trans", + tA: blas.Trans, + m: 3, + n: 5, + A: [][]float64{ + {4.1, 6.2, 8.1, 10, 7}, + {9.6, 3.5, 9.1, -2, 9}, + {10, 7, 3, 1, -5}, + }, + incX: 1, + incY: 1, + x: []float64{1, 2, 3}, + y: []float64{7, 2, 2, -3, 5}, + + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{384.4, 261.6, 270.4, 90, 50}, + }, + }, + }, + { + Name: "M_gt_N_Part1_NoTrans", + tA: blas.NoTrans, + m: 5, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + {1, 1, 2}, + {9, 2, 5}, + }, + incX: 1, + incY: 2, + x: []float64{1, 2, 3}, + y: []float64{7, 100, 8, 101, 9, 102, 10, 103, 11}, + + Subcases: []DgemvSubcase{ + { + alpha: 0, + beta: 0, + ans: []float64{0, 100, 0, 101, 0, 102, 0, 103, 0}, + }, + { + alpha: 0, + beta: 1, + ans: []float64{7, 100, 8, 101, 9, 102, 10, 103, 11}, + }, + { + alpha: 1, + beta: 0, + ans: []float64{40.8, 100, 43.9, 101, 33, 102, 9, 103, 28}, + }, + { + alpha: 8, + beta: -6, + ans: []float64{284.4, 100, 303.2, 101, 210, 102, 12, 103, 158}, + }, + }, + }, + { + Name: "M_gt_N_Part1_Trans", + tA: blas.Trans, + m: 5, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + {1, 1, 2}, + {9, 2, 5}, + }, + incX: 1, + incY: 2, + x: []float64{1, 2, 3, -4, 5}, + y: []float64{7, 100, 8, 101, 9}, + + Subcases: []DgemvSubcase{ + { + alpha: 0, + beta: 0, + ans: []float64{0, 100, 0, 101, 0}, + }, + { + alpha: 0, + beta: 1, + ans: []float64{7, 100, 8, 101, 9}, + }, + { + alpha: 1, + beta: 0, + ans: []float64{94.3, 100, 40.2, 101, 52.3}, + }, + { + alpha: 8, + beta: -6, + ans: []float64{712.4, 100, 273.6, 101, 364.4}, + }, + }, + }, + { + Name: "M_gt_N_IncNot1_NoTrans", + tA: blas.NoTrans, + m: 5, + n: 3, + + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + {1, 1, 2}, + {9, 2, 5}, + }, + incX: 2, + incY: 3, + x: []float64{1, 15, 2, 150, 3}, + y: []float64{7, 2, 6, 8, -4, -5, 9, 1, 1, 10, 19, 22, 11}, + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{284.4, 2, 6, 303.2, -4, -5, 210, 1, 1, 12, 19, 22, 158}, + }, + { + mulXNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{220.4, 2, 6, 311.2, -4, -5, 322, 1, 1, -4, 19, 22, 222}, + }, + { + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{182, 2, 6, 24, -4, -5, 210, 1, 1, 291.2, 19, 22, 260.4}, + }, + { + mulXNeg1: true, + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{246, 2, 6, 8, -4, -5, 322, 1, 1, 299.2, 19, 22, 196.4}, + }, + }, + }, + { + Name: "M_gt_N_IncNot1_Trans", + tA: blas.Trans, + m: 5, + n: 3, + + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + {1, 1, 2}, + {9, 2, 5}, + }, + incX: 2, + incY: 3, + x: []float64{1, 15, 2, 150, 3, 8, -3, 6, 5}, + y: []float64{7, 2, 6, 8, -4, -5, 9}, + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{720.4, 2, 6, 281.6, -4, -5, 380.4}, + }, + { + mulXNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{219.6, 2, 6, 316, -4, -5, 195.6}, + }, + { + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{392.4, 2, 6, 281.6, -4, -5, 708.4}, + }, + { + mulXNeg1: true, + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{207.6, 2, 6, 316, -4, -5, 207.6}, + }, + }, + }, + { + Name: "M_eq_N_IncNot1_NoTrans", + tA: blas.NoTrans, + m: 3, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + }, + incX: 2, + incY: 3, + x: []float64{1, 15, 2, 150, 3}, + y: []float64{7, 2, 6, 8, -4, -5, 9}, + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{284.4, 2, 6, 303.2, -4, -5, 210}, + }, + { + mulXNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{220.4, 2, 6, 311.2, -4, -5, 322}, + }, + { + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{222, 2, 6, 303.2, -4, -5, 272.4}, + }, + { + mulXNeg1: true, + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{334, 2, 6, 311.2, -4, -5, 208.4}, + }, + }, + }, + { + Name: "M_eq_N_IncNot1_Trans", + tA: blas.Trans, + m: 3, + n: 3, + A: [][]float64{ + {4.1, 6.2, 8.1}, + {9.6, 3.5, 9.1}, + {10, 7, 3}, + }, + incX: 2, + incY: 3, + x: []float64{1, 15, 2, 150, 3}, + y: []float64{7, 2, 6, 8, -4, -5, 9}, + + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{384.4, 2, 6, 225.6, -4, -5, 228.4}, + }, + { + mulXNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{290, 2, 6, 212.8, -4, -5, 310}, + }, + { + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{240.4, 2, 6, 225.6, -4, -5, 372.4}, + }, + { + mulXNeg1: true, + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{322, 2, 6, 212.8, -4, -5, 278}, + }, + }, + }, + { + Name: "M_lt_N_IncNot1_NoTrans", + tA: blas.NoTrans, + m: 3, + n: 5, + A: [][]float64{ + {4.1, 6.2, 8.1, 10, 11}, + {9.6, 3.5, 9.1, -3, -2}, + {10, 7, 3, -7, -4}, + }, + incX: 2, + incY: 3, + x: []float64{1, 15, 2, 150, 3, -2, -4, 8, -9}, + y: []float64{7, 2, 6, 8, -4, -5, 9}, + + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{-827.6, 2, 6, 543.2, -4, -5, 722}, + }, + { + mulXNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{-93.2, 2, 6, -696.8, -4, -5, -1070}, + }, + { + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{734, 2, 6, 543.2, -4, -5, -839.6}, + }, + { + mulXNeg1: true, + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{-1058, 2, 6, -696.8, -4, -5, -105.2}, + }, + }, + }, + { + Name: "M_lt_N_IncNot1_Trans", + tA: blas.Trans, + m: 3, + n: 5, + A: [][]float64{ + {4.1, 6.2, 8.1, 10, 11}, + {9.6, 3.5, 9.1, -3, -2}, + {10, 7, 3, -7, -4}, + }, + incX: 2, + incY: 3, + x: []float64{1, 15, 2, 150, 3}, + y: []float64{7, 2, 6, 8, -4, -5, 9, -4, -1, -9, 1, 1, 2}, + + Subcases: []DgemvSubcase{ + { + alpha: 8, + beta: -6, + ans: []float64{384.4, 2, 6, 225.6, -4, -5, 228.4, -4, -1, -82, 1, 1, -52}, + }, + { + mulXNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{290, 2, 6, 212.8, -4, -5, 310, -4, -1, 190, 1, 1, 188}, + }, + { + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{-82, 2, 6, -184, -4, -5, 228.4, -4, -1, 327.6, 1, 1, 414.4}, + }, + { + mulXNeg1: true, + mulYNeg1: true, + alpha: 8, + beta: -6, + ans: []float64{158, 2, 6, 88, -4, -5, 310, -4, -1, 314.8, 1, 1, 320}, + }, + }, + }, + + // TODO: A can be longer than mxn. Add cases where it is longer + // TODO: x and y can also be longer. Add tests for these + // TODO: Add tests for dimension mismatch + // TODO: Add places with a "submatrix view", where lda != m +} + +type Dgemver interface { + Dgemv(tA blas.Transpose, m, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) +} + +func DgemvTest(t *testing.T, blasser Dgemver) { + for _, test := range DgemvCases { + for i, cas := range test.Subcases { + // Test that it passes with row-major + dgemvcomp(t, test, cas, i, blasser) + + // Test the bad inputs + dgemvbad(t, test, cas, i, blasser) + } + } +} + +func dgemvcomp(t *testing.T, test DgemvCase, cas DgemvSubcase, i int, blasser Dgemver) { + x := sliceCopy(test.x) + y := sliceCopy(test.y) + a := sliceOfSliceCopy(test.A) + aFlat := flatten(a) + + lda := test.n + + incX := test.incX + if cas.mulXNeg1 { + incX *= -1 + } + incY := test.incY + if cas.mulYNeg1 { + incY *= -1 + } + + f := func() { + blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlat, lda, x, incX, cas.beta, y, incY) + } + if panics(f) { + t.Errorf("Test %v case %v: unexpected panic", test.Name, i) + if throwPanic { + blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlat, lda, x, incX, cas.beta, y, incY) + } + return + } + // Check that x and a are unchanged + if !dSliceEqual(x, test.x) { + t.Errorf("Test %v, case %v: x modified during call", test.Name, i) + } + aFlat2 := flatten(sliceOfSliceCopy(test.A)) + if !dSliceEqual(aFlat2, aFlat) { + t.Errorf("Test %v, case %v: a modified during call", test.Name, i) + } + + // Check that the answer matches + if !dSliceTolEqual(cas.ans, y) { + t.Errorf("Test %v, case %v: answer mismatch: Expected %v, Found %v", test.Name, i, cas.ans, y) + } +} + +func dgemvbad(t *testing.T, test DgemvCase, cas DgemvSubcase, i int, blasser Dgemver) { + x := sliceCopy(test.x) + y := sliceCopy(test.y) + a := sliceOfSliceCopy(test.A) + aFlatRow := flatten(a) + ldaRow := test.n + + f := func() { + blasser.Dgemv(312, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY) + } + if !panics(f) { + t.Errorf("Test %v case %v: no panic for bad transpose", test.Name, i) + } + f = func() { + blasser.Dgemv(test.tA, -2, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY) + } + if !panics(f) { + t.Errorf("Test %v case %v: no panic for m negative", test.Name, i) + } + f = func() { + blasser.Dgemv(test.tA, test.m, -4, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, test.incY) + } + if !panics(f) { + t.Errorf("Test %v case %v: no panic for n negative", test.Name, i) + } + f = func() { + blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, 0, cas.beta, y, test.incY) + } + if !panics(f) { + t.Errorf("Test %v case %v: no panic for incX zero", test.Name, i) + } + f = func() { + blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow, x, test.incX, cas.beta, y, 0) + } + if !panics(f) { + t.Errorf("Test %v case %v: no panic for incY zero", test.Name, i) + } + f = func() { + blasser.Dgemv(test.tA, test.m, test.n, cas.alpha, aFlatRow, ldaRow-1, x, test.incX, cas.beta, y, test.incY) + } + if !panics(f) { + t.Errorf("Test %v case %v: no panic for lda too small row major", test.Name, i) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dger.go b/vendor/gonum.org/v1/gonum/blas/testblas/dger.go new file mode 100644 index 00000000..0a905812 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dger.go @@ -0,0 +1,163 @@ +package testblas + +import "testing" + +type Dgerer interface { + Dger(m, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int) +} + +func DgerTest(t *testing.T, blasser Dgerer) { + for _, test := range []struct { + name string + a [][]float64 + m int + n int + x []float64 + y []float64 + incX int + incY int + + trueAns [][]float64 + }{ + { + name: "M gt N inc 1", + m: 5, + n: 3, + a: [][]float64{ + {1.3, 2.4, 3.5}, + {2.6, 2.8, 3.3}, + {-1.3, -4.3, -9.7}, + {8, 9, -10}, + {-12, -14, -6}, + }, + x: []float64{-2, -3, 0, 1, 2}, + y: []float64{-1.1, 5, 0}, + incX: 1, + incY: 1, + trueAns: [][]float64{{3.5, -7.6, 3.5}, {5.9, -12.2, 3.3}, {-1.3, -4.3, -9.7}, {6.9, 14, -10}, {-14.2, -4, -6}}, + }, + { + name: "M eq N inc 1", + m: 3, + n: 3, + a: [][]float64{ + {1.3, 2.4, 3.5}, + {2.6, 2.8, 3.3}, + {-1.3, -4.3, -9.7}, + }, + x: []float64{-2, -3, 0}, + y: []float64{-1.1, 5, 0}, + incX: 1, + incY: 1, + trueAns: [][]float64{{3.5, -7.6, 3.5}, {5.9, -12.2, 3.3}, {-1.3, -4.3, -9.7}}, + }, + + { + name: "M lt N inc 1", + m: 3, + n: 6, + a: [][]float64{ + {1.3, 2.4, 3.5, 4.8, 1.11, -9}, + {2.6, 2.8, 3.3, -3.4, 6.2, -8.7}, + {-1.3, -4.3, -9.7, -3.1, 8.9, 8.9}, + }, + x: []float64{-2, -3, 0}, + y: []float64{-1.1, 5, 0, 9, 19, 22}, + incX: 1, + incY: 1, + trueAns: [][]float64{{3.5, -7.6, 3.5, -13.2, -36.89, -53}, {5.9, -12.2, 3.3, -30.4, -50.8, -74.7}, {-1.3, -4.3, -9.7, -3.1, 8.9, 8.9}}, + }, + { + name: "M gt N inc not 1", + m: 5, + n: 3, + a: [][]float64{ + {1.3, 2.4, 3.5}, + {2.6, 2.8, 3.3}, + {-1.3, -4.3, -9.7}, + {8, 9, -10}, + {-12, -14, -6}, + }, + x: []float64{-2, -3, 0, 1, 2, 6, 0, 9, 7}, + y: []float64{-1.1, 5, 0, 8, 7, -5, 7}, + incX: 2, + incY: 3, + trueAns: [][]float64{{3.5, -13.6, -10.5}, {2.6, 2.8, 3.3}, {-3.5, 11.7, 4.3}, {8, 9, -10}, {-19.700000000000003, 42, 43}}, + }, + { + name: "M eq N inc not 1", + m: 3, + n: 3, + a: [][]float64{ + {1.3, 2.4, 3.5}, + {2.6, 2.8, 3.3}, + {-1.3, -4.3, -9.7}, + }, + x: []float64{-2, -3, 0, 8, 7, -9, 7, -6, 12, 6, 6, 6, -11}, + y: []float64{-1.1, 5, 0, 0, 9, 8, 6}, + incX: 4, + incY: 3, + trueAns: [][]float64{{3.5, 2.4, -8.5}, {-5.1, 2.8, 45.3}, {-14.5, -4.3, 62.3}}, + }, + { + name: "M lt N inc not 1", + m: 3, + n: 6, + a: [][]float64{ + {1.3, 2.4, 3.5, 4.8, 1.11, -9}, + {2.6, 2.8, 3.3, -3.4, 6.2, -8.7}, + {-1.3, -4.3, -9.7, -3.1, 8.9, 8.9}, + }, + x: []float64{-2, -3, 0, 0, 8, 0, 9, -3}, + y: []float64{-1.1, 5, 0, 9, 19, 22, 11, -8.11, -9.22, 9.87, 7}, + incX: 3, + incY: 2, + trueAns: [][]float64{{3.5, 2.4, -34.5, -17.2, 19.55, -23}, {2.6, 2.8, 3.3, -3.4, 6.2, -8.7}, {-11.2, -4.3, 161.3, 95.9, -74.08, 71.9}}, + }, + } { + // TODO: Add tests where a is longer + // TODO: Add panic tests + // TODO: Add negative increment tests + + x := sliceCopy(test.x) + y := sliceCopy(test.y) + + a := sliceOfSliceCopy(test.a) + + // Test with row major + alpha := 1.0 + aFlat := flatten(a) + blasser.Dger(test.m, test.n, alpha, x, test.incX, y, test.incY, aFlat, test.n) + ans := unflatten(aFlat, test.m, test.n) + dgercomp(t, x, test.x, y, test.y, ans, test.trueAns, test.name+" row maj") + + // Test with different alpha + alpha = 4.0 + aFlat = flatten(a) + blasser.Dger(test.m, test.n, alpha, x, test.incX, y, test.incY, aFlat, test.n) + ans = unflatten(aFlat, test.m, test.n) + trueCopy := sliceOfSliceCopy(test.trueAns) + for i := range trueCopy { + for j := range trueCopy[i] { + trueCopy[i][j] = alpha*(trueCopy[i][j]-a[i][j]) + a[i][j] + } + } + dgercomp(t, x, test.x, y, test.y, ans, trueCopy, test.name+" row maj alpha") + } +} + +func dgercomp(t *testing.T, x, xCopy, y, yCopy []float64, ans [][]float64, trueAns [][]float64, name string) { + if !dSliceEqual(x, xCopy) { + t.Errorf("case %v: x modified during call to dger", name) + } + if !dSliceEqual(y, yCopy) { + t.Errorf("case %v: x modified during call to dger", name) + } + + for i := range ans { + if !dSliceTolEqual(ans[i], trueAns[i]) { + t.Errorf("case %v: answer mismatch. Expected %v, Found %v", name, trueAns, ans) + break + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/doc.go b/vendor/gonum.org/v1/gonum/blas/testblas/doc.go new file mode 100644 index 00000000..fc113147 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package testblas provides tests for blas implementations. +package testblas // import "gonum.org/v1/gonum/blas/testblas" diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dsbmv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dsbmv.go new file mode 100644 index 00000000..1a8c9c35 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dsbmv.go @@ -0,0 +1,83 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dsbmver interface { + Dsbmv(ul blas.Uplo, n, k int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) +} + +func DsbmvTest(t *testing.T, blasser Dsbmver) { + for i, test := range []struct { + ul blas.Uplo + n int + k int + alpha float64 + beta float64 + a [][]float64 + x []float64 + y []float64 + + ans []float64 + }{ + { + ul: blas.Upper, + n: 4, + k: 2, + alpha: 2, + beta: 3, + a: [][]float64{ + {7, 8, 2, 0}, + {0, 8, 2, -3}, + {0, 0, 3, 6}, + {0, 0, 0, 9}, + }, + x: []float64{1, 2, 3, 4}, + y: []float64{-1, -2, -3, -4}, + ans: []float64{55, 30, 69, 84}, + }, + { + ul: blas.Lower, + n: 4, + k: 2, + alpha: 2, + beta: 3, + a: [][]float64{ + {7, 0, 0, 0}, + {8, 8, 0, 0}, + {2, 2, 3, 0}, + {0, -3, 6, 9}, + }, + x: []float64{1, 2, 3, 4}, + y: []float64{-1, -2, -3, -4}, + ans: []float64{55, 30, 69, 84}, + }, + } { + extra := 0 + var aFlat []float64 + if test.ul == blas.Upper { + aFlat = flattenBanded(test.a, test.k, 0) + } else { + aFlat = flattenBanded(test.a, 0, test.k) + } + incTest := func(incX, incY, extra int) { + xnew := makeIncremented(test.x, incX, extra) + ynew := makeIncremented(test.y, incY, extra) + ans := makeIncremented(test.ans, incY, extra) + blasser.Dsbmv(test.ul, test.n, test.k, test.alpha, aFlat, test.k+1, xnew, incX, test.beta, ynew, incY) + if !dSliceTolEqual(ans, ynew) { + t.Errorf("Case %v: Want %v, got %v", i, ans, ynew) + } + } + incTest(1, 1, extra) + incTest(1, 3, extra) + incTest(1, -3, extra) + incTest(2, 3, extra) + incTest(2, -3, extra) + incTest(3, 2, extra) + incTest(-3, 2, extra) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dspmv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dspmv.go new file mode 100644 index 00000000..352bc4a9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dspmv.go @@ -0,0 +1,73 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dspmver interface { + Dspmv(ul blas.Uplo, n int, alpha float64, ap []float64, x []float64, incX int, beta float64, y []float64, incY int) +} + +func DspmvTest(t *testing.T, blasser Dspmver) { + for i, test := range []struct { + ul blas.Uplo + n int + a [][]float64 + x []float64 + y []float64 + alpha float64 + beta float64 + ans []float64 + }{ + { + ul: blas.Upper, + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 8, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + y: []float64{6, 7, 8}, + alpha: 2.1, + beta: -3, + ans: []float64{137.4, 189, 240.6}, + }, + { + ul: blas.Lower, + n: 3, + a: [][]float64{ + {5, 0, 0}, + {6, 8, 0}, + {7, 10, 13}, + }, + x: []float64{3, 4, 5}, + y: []float64{6, 7, 8}, + alpha: 2.1, + beta: -3, + ans: []float64{137.4, 189, 240.6}, + }, + } { + incTest := func(incX, incY, extra int) { + x := makeIncremented(test.x, incX, extra) + y := makeIncremented(test.y, incY, extra) + aFlat := flattenTriangular(test.a, test.ul) + ans := makeIncremented(test.ans, incY, extra) + + blasser.Dspmv(test.ul, test.n, test.alpha, aFlat, x, incX, test.beta, y, incY) + if !floats.EqualApprox(ans, y, 1e-14) { + t.Errorf("Case %v, incX=%v, incY=%v: Want %v, got %v.", i, incX, incY, ans, y) + } + } + incTest(1, 1, 0) + incTest(2, 3, 0) + incTest(3, 2, 0) + incTest(-3, 2, 0) + incTest(-2, 4, 0) + incTest(2, -1, 0) + incTest(-3, -4, 3) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dspr.go b/vendor/gonum.org/v1/gonum/blas/testblas/dspr.go new file mode 100644 index 00000000..25e0ee40 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dspr.go @@ -0,0 +1,71 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dsprer interface { + Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX int, a []float64) +} + +func DsprTest(t *testing.T, blasser Dsprer) { + for i, test := range []struct { + ul blas.Uplo + n int + a [][]float64 + x []float64 + alpha float64 + ans [][]float64 + }{ + { + ul: blas.Upper, + n: 4, + a: [][]float64{ + {10, 2, 0, 1}, + {0, 1, 2, 3}, + {0, 0, 9, 15}, + {0, 0, 0, -6}, + }, + x: []float64{1, 2, 0, 5}, + alpha: 8, + ans: [][]float64{ + {18, 18, 0, 41}, + {0, 33, 2, 83}, + {0, 0, 9, 15}, + {0, 0, 0, 194}, + }, + }, + { + ul: blas.Lower, + n: 3, + a: [][]float64{ + {10, 2, 0}, + {4, 1, 2}, + {2, 7, 9}, + }, + x: []float64{3, 0, 5}, + alpha: 8, + ans: [][]float64{ + {82, 2, 0}, + {4, 1, 2}, + {122, 7, 209}, + }, + }, + } { + incTest := func(incX, extra int) { + xnew := makeIncremented(test.x, incX, extra) + aFlat := flattenTriangular(test.a, test.ul) + ans := flattenTriangular(test.ans, test.ul) + blasser.Dspr(test.ul, test.n, test.alpha, xnew, incX, aFlat) + if !dSliceTolEqual(aFlat, ans) { + t.Errorf("Case %v, idx %v: Want %v, got %v.", i, incX, ans, aFlat) + } + } + incTest(1, 3) + incTest(1, 0) + incTest(3, 2) + incTest(-2, 2) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dspr2.go b/vendor/gonum.org/v1/gonum/blas/testblas/dspr2.go new file mode 100644 index 00000000..40b0cd32 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dspr2.go @@ -0,0 +1,76 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dspr2er interface { + Dspr2(ul blas.Uplo, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64) +} + +func Dspr2Test(t *testing.T, blasser Dspr2er) { + for i, test := range []struct { + n int + a [][]float64 + ul blas.Uplo + x []float64 + y []float64 + alpha float64 + ans [][]float64 + }{ + { + n: 3, + a: [][]float64{ + {7, 2, 4}, + {0, 3, 5}, + {0, 0, 6}, + }, + x: []float64{2, 3, 4}, + y: []float64{5, 6, 7}, + alpha: 2, + ul: blas.Upper, + ans: [][]float64{ + {47, 56, 72}, + {0, 75, 95}, + {0, 0, 118}, + }, + }, + { + n: 3, + a: [][]float64{ + {7, 0, 0}, + {2, 3, 0}, + {4, 5, 6}, + }, + x: []float64{2, 3, 4}, + y: []float64{5, 6, 7}, + alpha: 2, + ul: blas.Lower, + ans: [][]float64{ + {47, 0, 0}, + {56, 75, 0}, + {72, 95, 118}, + }, + }, + } { + incTest := func(incX, incY, extra int) { + aFlat := flattenTriangular(test.a, test.ul) + x := makeIncremented(test.x, incX, extra) + y := makeIncremented(test.y, incY, extra) + blasser.Dspr2(test.ul, test.n, test.alpha, x, incX, y, incY, aFlat) + ansFlat := flattenTriangular(test.ans, test.ul) + if !floats.EqualApprox(aFlat, ansFlat, 1e-14) { + t.Errorf("Case %v, incX = %v, incY = %v. Want %v, got %v.", i, incX, incY, ansFlat, aFlat) + } + } + incTest(1, 1, 0) + incTest(-2, 1, 0) + incTest(-2, 3, 0) + incTest(2, -3, 0) + incTest(3, -2, 0) + incTest(-3, -4, 0) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dsymm.go b/vendor/gonum.org/v1/gonum/blas/testblas/dsymm.go new file mode 100644 index 00000000..5e07e07d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dsymm.go @@ -0,0 +1,277 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dsymmer interface { + 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) +} + +func DsymmTest(t *testing.T, blasser Dsymmer) { + for i, test := range []struct { + m int + n int + side blas.Side + ul blas.Uplo + a [][]float64 + b [][]float64 + c [][]float64 + alpha float64 + beta float64 + ans [][]float64 + }{ + { + side: blas.Left, + ul: blas.Upper, + m: 3, + n: 4, + a: [][]float64{ + {2, 3, 4}, + {0, 6, 7}, + {0, 0, 10}, + }, + b: [][]float64{ + {2, 3, 4, 8}, + {5, 6, 7, 15}, + {8, 9, 10, 20}, + }, + c: [][]float64{ + {8, 12, 2, 1}, + {9, 12, 9, 9}, + {12, 1, -1, 5}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {126, 156, 144, 285}, + {211, 252, 275, 535}, + {282, 291, 327, 689}, + }, + }, + { + side: blas.Left, + ul: blas.Upper, + m: 4, + n: 3, + a: [][]float64{ + {2, 3, 4, 8}, + {0, 6, 7, 9}, + {0, 0, 10, 10}, + {0, 0, 0, 11}, + }, + b: [][]float64{ + {2, 3, 4}, + {5, 6, 7}, + {8, 9, 10}, + {2, 1, 1}, + }, + c: [][]float64{ + {8, 12, 2}, + {9, 12, 9}, + {12, 1, -1}, + {1, 9, 5}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {158, 172, 160}, + {247, 270, 293}, + {322, 311, 347}, + {329, 385, 427}, + }, + }, + { + side: blas.Left, + ul: blas.Lower, + m: 3, + n: 4, + a: [][]float64{ + {2, 0, 0}, + {3, 6, 0}, + {4, 7, 10}, + }, + b: [][]float64{ + {2, 3, 4, 8}, + {5, 6, 7, 15}, + {8, 9, 10, 20}, + }, + c: [][]float64{ + {8, 12, 2, 1}, + {9, 12, 9, 9}, + {12, 1, -1, 5}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {126, 156, 144, 285}, + {211, 252, 275, 535}, + {282, 291, 327, 689}, + }, + }, + { + side: blas.Left, + ul: blas.Lower, + m: 4, + n: 3, + a: [][]float64{ + {2, 0, 0, 0}, + {3, 6, 0, 0}, + {4, 7, 10, 0}, + {8, 9, 10, 11}, + }, + b: [][]float64{ + {2, 3, 4}, + {5, 6, 7}, + {8, 9, 10}, + {2, 1, 1}, + }, + c: [][]float64{ + {8, 12, 2}, + {9, 12, 9}, + {12, 1, -1}, + {1, 9, 5}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {158, 172, 160}, + {247, 270, 293}, + {322, 311, 347}, + {329, 385, 427}, + }, + }, + { + side: blas.Right, + ul: blas.Upper, + m: 3, + n: 4, + a: [][]float64{ + {2, 0, 0, 0}, + {3, 6, 0, 0}, + {4, 7, 10, 0}, + {3, 4, 5, 6}, + }, + b: [][]float64{ + {2, 3, 4, 9}, + {5, 6, 7, -3}, + {8, 9, 10, -2}, + }, + c: [][]float64{ + {8, 12, 2, 10}, + {9, 12, 9, 10}, + {12, 1, -1, 10}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {32, 72, 86, 138}, + {47, 108, 167, -6}, + {68, 111, 197, 6}, + }, + }, + { + side: blas.Right, + ul: blas.Upper, + m: 4, + n: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 6, 0}, + {4, 7, 10}, + }, + b: [][]float64{ + {2, 3, 4}, + {5, 6, 7}, + {8, 9, 10}, + {2, 1, 1}, + }, + c: [][]float64{ + {8, 12, 2}, + {9, 12, 9}, + {12, 1, -1}, + {1, 9, 5}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {32, 72, 86}, + {47, 108, 167}, + {68, 111, 197}, + {11, 39, 35}, + }, + }, + { + side: blas.Right, + ul: blas.Lower, + m: 3, + n: 4, + a: [][]float64{ + {2, 0, 0, 0}, + {3, 6, 0, 0}, + {4, 7, 10, 0}, + {3, 4, 5, 6}, + }, + b: [][]float64{ + {2, 3, 4, 2}, + {5, 6, 7, 1}, + {8, 9, 10, 1}, + }, + c: [][]float64{ + {8, 12, 2, 1}, + {9, 12, 9, 9}, + {12, 1, -1, 5}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {94, 156, 164, 103}, + {145, 244, 301, 187}, + {208, 307, 397, 247}, + }, + }, + { + side: blas.Right, + ul: blas.Lower, + m: 4, + n: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 6, 0}, + {4, 7, 10}, + }, + b: [][]float64{ + {2, 3, 4}, + {5, 6, 7}, + {8, 9, 10}, + {2, 1, 1}, + }, + c: [][]float64{ + {8, 12, 2}, + {9, 12, 9}, + {12, 1, -1}, + {1, 9, 5}, + }, + alpha: 2, + beta: 3, + ans: [][]float64{ + {82, 140, 144}, + {139, 236, 291}, + {202, 299, 387}, + {25, 65, 65}, + }, + }, + } { + aFlat := flatten(test.a) + bFlat := flatten(test.b) + cFlat := flatten(test.c) + ansFlat := flatten(test.ans) + blasser.Dsymm(test.side, test.ul, test.m, test.n, test.alpha, aFlat, len(test.a[0]), bFlat, test.n, test.beta, cFlat, test.n) + if !floats.EqualApprox(cFlat, ansFlat, 1e-14) { + t.Errorf("Case %v: Want %v, got %v.", i, ansFlat, cFlat) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dsymv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dsymv.go new file mode 100644 index 00000000..b3fd4ec2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dsymv.go @@ -0,0 +1,73 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dsymver interface { + Dsymv(ul blas.Uplo, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) +} + +func DsymvTest(t *testing.T, blasser Dsymver) { + for i, test := range []struct { + ul blas.Uplo + n int + a [][]float64 + x []float64 + y []float64 + alpha float64 + beta float64 + ans []float64 + }{ + { + ul: blas.Upper, + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 8, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + y: []float64{6, 7, 8}, + alpha: 2.1, + beta: -3, + ans: []float64{137.4, 189, 240.6}, + }, + { + ul: blas.Lower, + n: 3, + a: [][]float64{ + {5, 0, 0}, + {6, 8, 0}, + {7, 10, 13}, + }, + x: []float64{3, 4, 5}, + y: []float64{6, 7, 8}, + alpha: 2.1, + beta: -3, + ans: []float64{137.4, 189, 240.6}, + }, + } { + incTest := func(incX, incY, extra int) { + x := makeIncremented(test.x, incX, extra) + y := makeIncremented(test.y, incY, extra) + aFlat := flatten(test.a) + ans := makeIncremented(test.ans, incY, extra) + + blasser.Dsymv(test.ul, test.n, test.alpha, aFlat, test.n, x, incX, test.beta, y, incY) + if !floats.EqualApprox(ans, y, 1e-14) { + t.Errorf("Case %v, incX=%v, incY=%v: Want %v, got %v.", i, incX, incY, ans, y) + } + } + incTest(1, 1, 0) + incTest(2, 3, 0) + incTest(3, 2, 0) + incTest(-3, 2, 0) + incTest(-2, 4, 0) + incTest(2, -1, 0) + incTest(-3, -4, 3) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dsyr.go b/vendor/gonum.org/v1/gonum/blas/testblas/dsyr.go new file mode 100644 index 00000000..4c404794 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dsyr.go @@ -0,0 +1,72 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dsyrer interface { + Dsyr(ul blas.Uplo, n int, alpha float64, x []float64, incX int, a []float64, lda int) +} + +func DsyrTest(t *testing.T, blasser Dsyrer) { + for i, test := range []struct { + ul blas.Uplo + n int + a [][]float64 + x []float64 + alpha float64 + ans [][]float64 + }{ + { + ul: blas.Upper, + n: 4, + a: [][]float64{ + {10, 2, 0, 1}, + {0, 1, 2, 3}, + {0, 0, 9, 15}, + {0, 0, 0, -6}, + }, + x: []float64{1, 2, 0, 5}, + alpha: 8, + ans: [][]float64{ + {18, 18, 0, 41}, + {0, 33, 2, 83}, + {0, 0, 9, 15}, + {0, 0, 0, 194}, + }, + }, + { + ul: blas.Lower, + n: 3, + a: [][]float64{ + {10, 2, 0}, + {4, 1, 2}, + {2, 7, 9}, + }, + x: []float64{3, 0, 5}, + alpha: 8, + ans: [][]float64{ + {82, 2, 0}, + {4, 1, 2}, + {122, 7, 209}, + }, + }, + } { + incTest := func(incX, extra int) { + xnew := makeIncremented(test.x, incX, extra) + aFlat := flatten(test.a) + ans := flatten(test.ans) + lda := test.n + blasser.Dsyr(test.ul, test.n, test.alpha, xnew, incX, aFlat, lda) + if !dSliceTolEqual(aFlat, ans) { + t.Errorf("Case %v, idx %v: Want %v, got %v.", i, incX, ans, aFlat) + } + } + incTest(1, 3) + incTest(1, 0) + incTest(3, 2) + incTest(-2, 2) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dsyr2.go b/vendor/gonum.org/v1/gonum/blas/testblas/dsyr2.go new file mode 100644 index 00000000..e9069592 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dsyr2.go @@ -0,0 +1,76 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dsyr2er interface { + Dsyr2(ul blas.Uplo, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int) +} + +func Dsyr2Test(t *testing.T, blasser Dsyr2er) { + for i, test := range []struct { + n int + a [][]float64 + ul blas.Uplo + x []float64 + y []float64 + alpha float64 + ans [][]float64 + }{ + { + n: 3, + a: [][]float64{ + {7, 2, 4}, + {0, 3, 5}, + {0, 0, 6}, + }, + x: []float64{2, 3, 4}, + y: []float64{5, 6, 7}, + alpha: 2, + ul: blas.Upper, + ans: [][]float64{ + {47, 56, 72}, + {0, 75, 95}, + {0, 0, 118}, + }, + }, + { + n: 3, + a: [][]float64{ + {7, 0, 0}, + {2, 3, 0}, + {4, 5, 6}, + }, + x: []float64{2, 3, 4}, + y: []float64{5, 6, 7}, + alpha: 2, + ul: blas.Lower, + ans: [][]float64{ + {47, 0, 0}, + {56, 75, 0}, + {72, 95, 118}, + }, + }, + } { + incTest := func(incX, incY, extra int) { + aFlat := flatten(test.a) + x := makeIncremented(test.x, incX, extra) + y := makeIncremented(test.y, incY, extra) + blasser.Dsyr2(test.ul, test.n, test.alpha, x, incX, y, incY, aFlat, test.n) + ansFlat := flatten(test.ans) + if !floats.EqualApprox(aFlat, ansFlat, 1e-14) { + t.Errorf("Case %v, incX = %v, incY = %v. Want %v, got %v.", i, incX, incY, ansFlat, aFlat) + } + } + incTest(1, 1, 0) + incTest(-2, 1, 0) + incTest(-2, 3, 0) + incTest(2, -3, 0) + incTest(3, -2, 0) + incTest(-3, -4, 0) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dsyr2k.go b/vendor/gonum.org/v1/gonum/blas/testblas/dsyr2k.go new file mode 100644 index 00000000..7c8600b5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dsyr2k.go @@ -0,0 +1,201 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dsyr2ker interface { + 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) +} + +func Dsyr2kTest(t *testing.T, blasser Dsyr2ker) { + for i, test := range []struct { + ul blas.Uplo + tA blas.Transpose + n int + k int + alpha float64 + a [][]float64 + b [][]float64 + c [][]float64 + beta float64 + ans [][]float64 + }{ + { + ul: blas.Upper, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 0, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + b: [][]float64{ + {7, 8}, + {9, 10}, + {11, 12}, + }, + c: [][]float64{ + {1, 2, 3}, + {0, 5, 6}, + {0, 0, 9}, + }, + beta: 2, + ans: [][]float64{ + {2, 4, 6}, + {0, 10, 12}, + {0, 0, 18}, + }, + }, + { + ul: blas.Lower, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 0, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + b: [][]float64{ + {7, 8}, + {9, 10}, + {11, 12}, + }, + c: [][]float64{ + {1, 0, 0}, + {2, 3, 0}, + {4, 5, 6}, + }, + beta: 2, + ans: [][]float64{ + {2, 0, 0}, + {4, 6, 0}, + {8, 10, 12}, + }, + }, + { + ul: blas.Upper, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + b: [][]float64{ + {7, 8}, + {9, 10}, + {11, 12}, + }, + c: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + beta: 2, + ans: [][]float64{ + {140, 250, 360}, + {0, 410, 568}, + {0, 0, 774}, + }, + }, + { + ul: blas.Lower, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + b: [][]float64{ + {7, 8}, + {9, 10}, + {11, 12}, + }, + c: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + beta: 2, + ans: [][]float64{ + {140, 0, 0}, + {250, 410, 0}, + {360, 568, 774}, + }, + }, + { + ul: blas.Upper, + tA: blas.Trans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 3, 5}, + {2, 4, 6}, + }, + b: [][]float64{ + {7, 9, 11}, + {8, 10, 12}, + }, + c: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + beta: 2, + ans: [][]float64{ + {140, 250, 360}, + {0, 410, 568}, + {0, 0, 774}, + }, + }, + { + ul: blas.Lower, + tA: blas.Trans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 3, 5}, + {2, 4, 6}, + }, + b: [][]float64{ + {7, 9, 11}, + {8, 10, 12}, + }, + c: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + beta: 2, + ans: [][]float64{ + {140, 0, 0}, + {250, 410, 0}, + {360, 568, 774}, + }, + }, + } { + aFlat := flatten(test.a) + bFlat := flatten(test.b) + cFlat := flatten(test.c) + ansFlat := flatten(test.ans) + blasser.Dsyr2k(test.ul, test.tA, test.n, test.k, test.alpha, aFlat, len(test.a[0]), bFlat, len(test.b[0]), test.beta, cFlat, len(test.c[0])) + if !floats.EqualApprox(ansFlat, cFlat, 1e-14) { + t.Errorf("Case %v. Want %v, got %v.", i, ansFlat, cFlat) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dsyrk.go b/vendor/gonum.org/v1/gonum/blas/testblas/dsyrk.go new file mode 100644 index 00000000..99e18ebb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dsyrk.go @@ -0,0 +1,171 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dsyker interface { + Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha float64, a []float64, lda int, beta float64, c []float64, ldc int) +} + +func DsyrkTest(t *testing.T, blasser Dsyker) { + for i, test := range []struct { + ul blas.Uplo + tA blas.Transpose + n int + k int + alpha float64 + a [][]float64 + c [][]float64 + beta float64 + ans [][]float64 + }{ + { + ul: blas.Upper, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 0, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + c: [][]float64{ + {1, 2, 3}, + {0, 5, 6}, + {0, 0, 9}, + }, + beta: 2, + ans: [][]float64{ + {2, 4, 6}, + {0, 10, 12}, + {0, 0, 18}, + }, + }, + { + ul: blas.Lower, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 0, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + c: [][]float64{ + {1, 0, 0}, + {2, 3, 0}, + {4, 5, 6}, + }, + beta: 2, + ans: [][]float64{ + {2, 0, 0}, + {4, 6, 0}, + {8, 10, 12}, + }, + }, + { + ul: blas.Upper, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + c: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + beta: 2, + ans: [][]float64{ + {17, 37, 57}, + {0, 83, 127}, + {0, 0, 195}, + }, + }, + { + ul: blas.Lower, + tA: blas.NoTrans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 2}, + {3, 4}, + {5, 6}, + }, + c: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + beta: 2, + ans: [][]float64{ + {17, 0, 0}, + {37, 83, 0}, + {57, 127, 195}, + }, + }, + { + ul: blas.Upper, + tA: blas.Trans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 3, 5}, + {2, 4, 6}, + }, + c: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + beta: 2, + ans: [][]float64{ + {17, 37, 57}, + {0, 83, 127}, + {0, 0, 195}, + }, + }, + { + ul: blas.Lower, + tA: blas.Trans, + n: 3, + k: 2, + alpha: 3, + a: [][]float64{ + {1, 3, 5}, + {2, 4, 6}, + }, + c: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + beta: 2, + ans: [][]float64{ + {17, 0, 0}, + {37, 83, 0}, + {57, 127, 195}, + }, + }, + } { + aFlat := flatten(test.a) + cFlat := flatten(test.c) + ansFlat := flatten(test.ans) + blasser.Dsyrk(test.ul, test.tA, test.n, test.k, test.alpha, aFlat, len(test.a[0]), test.beta, cFlat, len(test.c[0])) + if !floats.EqualApprox(ansFlat, cFlat, 1e-14) { + t.Errorf("Case %v. Want %v, got %v.", i, ansFlat, cFlat) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtbmv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtbmv.go new file mode 100644 index 00000000..b0dee676 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtbmv.go @@ -0,0 +1,123 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dtbmver interface { + Dtbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []float64, lda int, x []float64, incX int) +} + +func DtbmvTest(t *testing.T, blasser Dtbmver) { + for i, test := range []struct { + ul blas.Uplo + tA blas.Transpose + d blas.Diag + n int + k int + a [][]float64 + x []float64 + ans []float64 + }{ + { + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + n: 3, + k: 1, + a: [][]float64{ + {1, 2, 0}, + {0, 1, 4}, + {0, 0, 1}, + }, + x: []float64{2, 3, 4}, + ans: []float64{8, 19, 4}, + }, + { + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 1, + a: [][]float64{ + {1, 3, 0, 0, 0}, + {0, 6, 7, 0, 0}, + {0, 0, 2, 1, 0}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + ans: []float64{7, 33, 10, 63, -5}, + }, + { + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 1, + a: [][]float64{ + {7, 0, 0, 0, 0}, + {3, 6, 0, 0, 0}, + {0, 7, 2, 0, 0}, + {0, 0, 1, 12, 0}, + {0, 0, 0, 3, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + ans: []float64{7, 15, 20, 51, 7}, + }, + { + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {7, 3, 9, 0, 0}, + {0, 6, 7, 10, 0}, + {0, 0, 2, 1, 11}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + ans: []float64{7, 15, 29, 71, 40}, + }, + { + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {7, 0, 0, 0, 0}, + {3, 6, 0, 0, 0}, + {9, 7, 2, 0, 0}, + {0, 10, 1, 12, 0}, + {0, 0, 11, 3, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + ans: []float64{40, 73, 65, 63, -5}, + }, + } { + extra := 0 + var aFlat []float64 + if test.ul == blas.Upper { + aFlat = flattenBanded(test.a, test.k, 0) + } else { + aFlat = flattenBanded(test.a, 0, test.k) + } + incTest := func(incX, extra int) { + xnew := makeIncremented(test.x, incX, extra) + ans := makeIncremented(test.ans, incX, extra) + lda := test.k + 1 + blasser.Dtbmv(test.ul, test.tA, test.d, test.n, test.k, aFlat, lda, xnew, incX) + if !dSliceTolEqual(ans, xnew) { + t.Errorf("Case %v, Inc %v: Want %v, got %v", i, incX, ans, xnew) + } + } + incTest(1, extra) + incTest(3, extra) + incTest(-2, extra) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtbsv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtbsv.go new file mode 100644 index 00000000..d3fad1ec --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtbsv.go @@ -0,0 +1,255 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dtbsver interface { + Dtbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []float64, lda int, x []float64, incX int) + Dtrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, lda int, x []float64, incX int) +} + +func DtbsvTest(t *testing.T, blasser Dtbsver) { + for i, test := range []struct { + ul blas.Uplo + tA blas.Transpose + d blas.Diag + n, k int + a [][]float64 + x []float64 + incX int + ans []float64 + }{ + { + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 1, + a: [][]float64{ + {1, 3, 0, 0, 0}, + {0, 6, 7, 0, 0}, + {0, 0, 2, 1, 0}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + incX: 1, + ans: []float64{2.479166666666667, -0.493055555555556, 0.708333333333333, 1.583333333333333, -5.000000000000000}, + }, + { + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 3, 5, 0, 0}, + {0, 6, 7, 5, 0}, + {0, 0, 2, 1, 5}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + incX: 1, + ans: []float64{-15.854166666666664, -16.395833333333336, 13.208333333333334, 1.583333333333333, -5.000000000000000}, + }, + { + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 1, + a: [][]float64{ + {1, 3, 0, 0, 0}, + {0, 6, 7, 0, 0}, + {0, 0, 2, 1, 0}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, -101, 2, -201, 3, -301, 4, -401, 5, -501, -601, -701}, + incX: 2, + ans: []float64{2.479166666666667, -101, -0.493055555555556, -201, 0.708333333333333, -301, 1.583333333333333, -401, -5.000000000000000, -501, -601, -701}, + }, + { + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 3, 5, 0, 0}, + {0, 6, 7, 5, 0}, + {0, 0, 2, 1, 5}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, -101, 2, -201, 3, -301, 4, -401, 5, -501, -601, -701}, + incX: 2, + ans: []float64{-15.854166666666664, -101, -16.395833333333336, -201, 13.208333333333334, -301, 1.583333333333333, -401, -5.000000000000000, -501, -601, -701}, + }, + { + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 0, 0, 0, 0}, + {3, 6, 0, 0, 0}, + {5, 7, 2, 0, 0}, + {0, 5, 1, 12, 0}, + {0, 0, 5, 3, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + incX: 1, + ans: []float64{1, -0.166666666666667, -0.416666666666667, 0.437500000000000, -5.770833333333334}, + }, + { + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 0, 0, 0, 0}, + {3, 6, 0, 0, 0}, + {5, 7, 2, 0, 0}, + {0, 5, 1, 12, 0}, + {0, 0, 5, 3, -1}, + }, + x: []float64{1, -101, 2, -201, 3, -301, 4, -401, 5, -501, -601, -701}, + incX: 2, + ans: []float64{1, -101, -0.166666666666667, -201, -0.416666666666667, -301, 0.437500000000000, -401, -5.770833333333334, -501, -601, -701}, + }, + { + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 3, 5, 0, 0}, + {0, 6, 7, 5, 0}, + {0, 0, 2, 1, 5}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + incX: 1, + ans: []float64{1, -0.166666666666667, -0.416666666666667, 0.437500000000000, -5.770833333333334}, + }, + { + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 3, 5, 0, 0}, + {0, 6, 7, 5, 0}, + {0, 0, 2, 1, 5}, + {0, 0, 0, 12, 3}, + {0, 0, 0, 0, -1}, + }, + x: []float64{1, -101, 2, -201, 3, -301, 4, -401, 5, -501, -601, -701}, + incX: 2, + ans: []float64{1, -101, -0.166666666666667, -201, -0.416666666666667, -301, 0.437500000000000, -401, -5.770833333333334, -501, -601, -701}, + }, + { + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 0, 0, 0, 0}, + {3, 6, 0, 0, 0}, + {5, 7, 2, 0, 0}, + {0, 5, 1, 12, 0}, + {0, 0, 5, 3, -1}, + }, + x: []float64{1, 2, 3, 4, 5}, + incX: 1, + ans: []float64{-15.854166666666664, -16.395833333333336, 13.208333333333334, 1.583333333333333, -5.000000000000000}, + }, + { + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + n: 5, + k: 2, + a: [][]float64{ + {1, 0, 0, 0, 0}, + {3, 6, 0, 0, 0}, + {5, 7, 2, 0, 0}, + {0, 5, 1, 12, 0}, + {0, 0, 5, 3, -1}, + }, + x: []float64{1, -101, 2, -201, 3, -301, 4, -401, 5, -501, -601, -701}, + incX: 2, + ans: []float64{-15.854166666666664, -101, -16.395833333333336, -201, 13.208333333333334, -301, 1.583333333333333, -401, -5.000000000000000, -501, -601, -701}, + }, + } { + var aFlat []float64 + if test.ul == blas.Upper { + aFlat = flattenBanded(test.a, test.k, 0) + } else { + aFlat = flattenBanded(test.a, 0, test.k) + } + xCopy := sliceCopy(test.x) + // TODO: Have tests where the banded matrix is constructed explicitly + // to allow testing for lda =! k+1 + blasser.Dtbsv(test.ul, test.tA, test.d, test.n, test.k, aFlat, test.k+1, xCopy, test.incX) + if !dSliceTolEqual(test.ans, xCopy) { + t.Errorf("Case %v: Want %v, got %v", i, test.ans, xCopy) + } + } + + /* + // TODO: Uncomment when Dtrsv is fixed + // Compare with dense for larger matrices + for _, ul := range [...]blas.Uplo{blas.Upper, blas.Lower} { + for _, tA := range [...]blas.Transpose{blas.NoTrans, blas.Trans} { + for _, n := range [...]int{7, 8, 11} { + for _, d := range [...]blas.Diag{blas.NonUnit, blas.Unit} { + for _, k := range [...]int{0, 1, 3} { + for _, incX := range [...]int{1, 3} { + a := make([][]float64, n) + for i := range a { + a[i] = make([]float64, n) + for j := range a[i] { + a[i][j] = rand.Float64() + } + } + x := make([]float64, n) + for i := range x { + x[i] = rand.Float64() + } + extra := 3 + xinc := makeIncremented(x, incX, extra) + bandX := sliceCopy(xinc) + var aFlatBand []float64 + if ul == blas.Upper { + aFlatBand = flattenBanded(a, k, 0) + } else { + aFlatBand = flattenBanded(a, 0, k) + } + blasser.Dtbsv(ul, tA, d, n, k, aFlatBand, k+1, bandX, incX) + + aFlatDense := flatten(a) + denseX := sliceCopy(xinc) + blasser.Dtrsv(ul, tA, d, n, aFlatDense, n, denseX, incX) + if !dSliceTolEqual(denseX, bandX) { + t.Errorf("Case %v: dense banded mismatch") + } + } + } + } + } + } + } + */ +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtpmv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtpmv.go new file mode 100644 index 00000000..04af1641 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtpmv.go @@ -0,0 +1,129 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dtpmver interface { + Dtpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float64, x []float64, incX int) +} + +func DtpmvTest(t *testing.T, blasser Dtpmver) { + for i, test := range []struct { + n int + a [][]float64 + x []float64 + d blas.Diag + ul blas.Uplo + tA blas.Transpose + ans []float64 + }{ + { + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 9, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Upper, + tA: blas.NoTrans, + ans: []float64{74, 86, 65}, + }, + { + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 9, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.Unit, + ul: blas.Upper, + tA: blas.NoTrans, + ans: []float64{62, 54, 5}, + }, + { + n: 3, + a: [][]float64{ + {5, 0, 0}, + {6, 9, 0}, + {7, 10, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Lower, + tA: blas.NoTrans, + ans: []float64{15, 54, 126}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {6, 1, 0}, + {7, 10, 1}, + }, + x: []float64{3, 4, 5}, + d: blas.Unit, + ul: blas.Lower, + tA: blas.NoTrans, + ans: []float64{3, 22, 66}, + }, + { + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 9, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Upper, + tA: blas.Trans, + ans: []float64{15, 54, 126}, + }, + { + n: 3, + a: [][]float64{ + {1, 6, 7}, + {0, 1, 10}, + {0, 0, 1}, + }, + x: []float64{3, 4, 5}, + d: blas.Unit, + ul: blas.Upper, + tA: blas.Trans, + ans: []float64{3, 22, 66}, + }, + { + n: 3, + a: [][]float64{ + {5, 0, 0}, + {6, 9, 0}, + {7, 10, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Lower, + tA: blas.Trans, + ans: []float64{74, 86, 65}, + }, + } { + incTest := func(incX, extra int) { + aFlat := flattenTriangular(test.a, test.ul) + x := makeIncremented(test.x, incX, extra) + blasser.Dtpmv(test.ul, test.tA, test.d, test.n, aFlat, x, incX) + ans := makeIncremented(test.ans, incX, extra) + if !floats.EqualApprox(x, ans, 1e-14) { + t.Errorf("Case %v, idx %v: Want %v, got %v.", i, incX, ans, x) + } + } + incTest(1, 0) + incTest(-3, 3) + incTest(4, 3) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtpsv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtpsv.go new file mode 100644 index 00000000..9fee545e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtpsv.go @@ -0,0 +1,144 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dtpsver interface { + Dtpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float64, x []float64, incX int) +} + +func DtpsvTest(t *testing.T, blasser Dtpsver) { + for i, test := range []struct { + n int + a [][]float64 + ul blas.Uplo + tA blas.Transpose + d blas.Diag + x []float64 + ans []float64 + }{ + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 8, 15}, + {0, 0, 8}, + }, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{4.15625, -0.890625, 0.875}, + }, + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 1, 15}, + {0, 0, 1}, + }, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{182, -99, 7}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 8, 0}, + {3, 15, 8}, + }, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{5, -0.5, -0.0625}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 8, 0}, + {3, 15, 8}, + }, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{5, -4, 52}, + }, + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 8, 15}, + {0, 0, 8}, + }, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{5, -0.5, -0.0625}, + }, + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 8, 15}, + {0, 0, 8}, + }, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{5, -4, 52}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 8, 0}, + {3, 15, 8}, + }, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{4.15625, -0.890625, 0.875}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 1, 0}, + {3, 15, 1}, + }, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{182, -99, 7}, + }, + } { + incTest := func(incX, extra int) { + aFlat := flattenTriangular(test.a, test.ul) + x := makeIncremented(test.x, incX, extra) + blasser.Dtpsv(test.ul, test.tA, test.d, test.n, aFlat, x, incX) + ans := makeIncremented(test.ans, incX, extra) + if !floats.EqualApprox(x, ans, 1e-14) { + t.Errorf("Case %v, incX = %v: Want %v, got %v.", i, incX, ans, x) + } + } + incTest(1, 0) + incTest(-2, 0) + incTest(3, 0) + incTest(-3, 8) + incTest(4, 2) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtrmm.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtrmm.go new file mode 100644 index 00000000..95cccec5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtrmm.go @@ -0,0 +1,806 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dtrmmer interface { + 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) +} + +func DtrmmTest(t *testing.T, blasser Dtrmmer) { + for i, test := range []struct { + s blas.Side + ul blas.Uplo + tA blas.Transpose + d blas.Diag + m int + n int + alpha float64 + a [][]float64 + b [][]float64 + ans [][]float64 + }{ + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3, 4}, + {0, 5, 6, 7}, + {0, 0, 8, 9}, + {0, 0, 0, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {320, 340, 360}, + {588, 624, 660}, + {598, 632, 666}, + {380, 400, 420}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2}, + {0, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {72, 78, 84}, + {130, 140, 150}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3, 4}, + {0, 5, 6, 7}, + {0, 0, 8, 9}, + {0, 0, 0, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {320, 340, 360}, + {484, 512, 540}, + {374, 394, 414}, + {38, 40, 42}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2}, + {0, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {72, 78, 84}, + {26, 28, 30}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0, 0}, + {2, 5, 0, 0}, + {3, 6, 8, 0}, + {4, 7, 9, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 22, 24}, + {170, 184, 198}, + {472, 506, 540}, + {930, 990, 1050}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0}, + {2, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 22, 24}, + {170, 184, 198}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0, 0}, + {2, 5, 0, 0}, + {3, 6, 8, 0}, + {4, 7, 9, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 22, 24}, + {66, 72, 78}, + {248, 268, 288}, + {588, 630, 672}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0}, + {2, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 22, 24}, + {66, 72, 78}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3, 4}, + {0, 5, 6, 7}, + {0, 0, 8, 9}, + {0, 0, 0, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 22, 24}, + {170, 184, 198}, + {472, 506, 540}, + {930, 990, 1050}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2}, + {0, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 22, 24}, + {170, 184, 198}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3, 4}, + {0, 5, 6, 7}, + {0, 0, 8, 9}, + {0, 0, 0, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 22, 24}, + {66, 72, 78}, + {248, 268, 288}, + {588, 630, 672}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2}, + {0, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 22, 24}, + {66, 72, 78}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0, 0}, + {2, 5, 0, 0}, + {3, 6, 8, 0}, + {4, 7, 9, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {320, 340, 360}, + {588, 624, 660}, + {598, 632, 666}, + {380, 400, 420}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0}, + {2, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {72, 78, 84}, + {130, 140, 150}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0, 0}, + {2, 5, 0, 0}, + {3, 6, 8, 0}, + {4, 7, 9, 10}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {320, 340, 360}, + {484, 512, 540}, + {374, 394, 414}, + {38, 40, 42}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0}, + {2, 5}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {72, 78, 84}, + {26, 28, 30}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 128, 314}, + {26, 164, 398}, + {32, 200, 482}, + {38, 236, 566}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 128, 314}, + {26, 164, 398}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 62, 194}, + {26, 80, 248}, + {32, 98, 302}, + {38, 116, 356}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 62, 194}, + {26, 80, 248}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {136, 208, 144}, + {172, 262, 180}, + {208, 316, 216}, + {244, 370, 252}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {136, 208, 144}, + {172, 262, 180}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {136, 142, 24}, + {172, 178, 30}, + {208, 214, 36}, + {244, 250, 42}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {136, 142, 24}, + {172, 178, 30}, + }, + }, + + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {136, 208, 144}, + {172, 262, 180}, + {208, 316, 216}, + {244, 370, 252}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {136, 208, 144}, + {172, 262, 180}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {136, 142, 24}, + {172, 178, 30}, + {208, 214, 36}, + {244, 250, 42}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {136, 142, 24}, + {172, 178, 30}, + }, + }, + + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 128, 314}, + {26, 164, 398}, + {32, 200, 482}, + {38, 236, 566}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 128, 314}, + {26, 164, 398}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {20, 62, 194}, + {26, 80, 248}, + {32, 98, 302}, + {38, 116, 356}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 2, + a: [][]float64{ + {1, 0, 0}, + {2, 4, 0}, + {3, 5, 6}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {20, 62, 194}, + {26, 80, 248}, + }, + }, + } { + aFlat := flatten(test.a) + bFlat := flatten(test.b) + ansFlat := flatten(test.ans) + blasser.Dtrmm(test.s, test.ul, test.tA, test.d, test.m, test.n, test.alpha, aFlat, len(test.a[0]), bFlat, len(test.b[0])) + if !floats.EqualApprox(ansFlat, bFlat, 1e-14) { + t.Errorf("Case %v. Want %v, got %v.", i, ansFlat, bFlat) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtrmv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtrmv.go new file mode 100644 index 00000000..8f3b6d35 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtrmv.go @@ -0,0 +1,147 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dtrmver interface { + Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, lda int, x []float64, incX int) +} + +func DtrmvTest(t *testing.T, blasser Dtrmver) { + for i, test := range []struct { + n int + a [][]float64 + x []float64 + d blas.Diag + ul blas.Uplo + tA blas.Transpose + ans []float64 + }{ + { + n: 1, + a: [][]float64{{5}}, + x: []float64{2}, + d: blas.NonUnit, + ul: blas.Upper, + tA: blas.NoTrans, + ans: []float64{10}, + }, + { + n: 1, + a: [][]float64{{5}}, + x: []float64{2}, + d: blas.Unit, + ul: blas.Upper, + tA: blas.NoTrans, + ans: []float64{2}, + }, + { + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 9, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Upper, + tA: blas.NoTrans, + ans: []float64{74, 86, 65}, + }, + { + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 9, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.Unit, + ul: blas.Upper, + tA: blas.NoTrans, + ans: []float64{62, 54, 5}, + }, + { + n: 3, + a: [][]float64{ + {5, 0, 0}, + {6, 9, 0}, + {7, 10, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Lower, + tA: blas.NoTrans, + ans: []float64{15, 54, 126}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {6, 1, 0}, + {7, 10, 1}, + }, + x: []float64{3, 4, 5}, + d: blas.Unit, + ul: blas.Lower, + tA: blas.NoTrans, + ans: []float64{3, 22, 66}, + }, + { + n: 3, + a: [][]float64{ + {5, 6, 7}, + {0, 9, 10}, + {0, 0, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Upper, + tA: blas.Trans, + ans: []float64{15, 54, 126}, + }, + { + n: 3, + a: [][]float64{ + {1, 6, 7}, + {0, 1, 10}, + {0, 0, 1}, + }, + x: []float64{3, 4, 5}, + d: blas.Unit, + ul: blas.Upper, + tA: blas.Trans, + ans: []float64{3, 22, 66}, + }, + { + n: 3, + a: [][]float64{ + {5, 0, 0}, + {6, 9, 0}, + {7, 10, 13}, + }, + x: []float64{3, 4, 5}, + d: blas.NonUnit, + ul: blas.Lower, + tA: blas.Trans, + ans: []float64{74, 86, 65}, + }, + } { + incTest := func(incX, extra int) { + aFlat := flatten(test.a) + x := makeIncremented(test.x, incX, extra) + blasser.Dtrmv(test.ul, test.tA, test.d, test.n, aFlat, test.n, x, incX) + ans := makeIncremented(test.ans, incX, extra) + if !floats.EqualApprox(x, ans, 1e-14) { + t.Errorf("Case %v, idx %v: Want %v, got %v.", i, incX, ans, x) + } + } + incTest(1, 3) + incTest(-3, 3) + incTest(4, 3) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtrmvbench.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtrmvbench.go new file mode 100644 index 00000000..c6b439e9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtrmvbench.go @@ -0,0 +1,30 @@ +// 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 testblas + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func DtrmvBenchmark(b *testing.B, dtrmv Dtrmver, n, lda, incX int, ul blas.Uplo, tA blas.Transpose, d blas.Diag) { + rnd := rand.New(rand.NewSource(0)) + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.Float64() + } + + x := make([]float64, n*incX) + for i := range x { + x[i] = rnd.Float64() + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + dtrmv.Dtrmv(ul, tA, d, n, a, lda, x, incX) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtrsm.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtrsm.go new file mode 100644 index 00000000..9623397c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtrsm.go @@ -0,0 +1,811 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dtrsmer interface { + 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) +} + +func DtrsmTest(t *testing.T, blasser Dtrsmer) { + for i, test := range []struct { + s blas.Side + ul blas.Uplo + tA blas.Transpose + d blas.Diag + m int + n int + alpha float64 + a [][]float64 + b [][]float64 + ans [][]float64 + }{ + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 3, + n: 2, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 5}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {1, 3.4}, + {-0.5, -0.5}, + {2, 3.2}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 3, + n: 2, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 5}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {60, 96}, + {-42, -66}, + {10, 16}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 3, + n: 4, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 5}, + }, + b: [][]float64{ + {3, 6, 2, 9}, + {4, 7, 1, 3}, + {5, 8, 9, 10}, + }, + ans: [][]float64{ + {1, 3.4, 1.2, 13}, + {-0.5, -0.5, -4, -3.5}, + {2, 3.2, 3.6, 4}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 3, + n: 4, + alpha: 2, + a: [][]float64{ + {1, 2, 3}, + {0, 4, 5}, + {0, 0, 5}, + }, + b: [][]float64{ + {3, 6, 2, 9}, + {4, 7, 1, 3}, + {5, 8, 9, 10}, + }, + ans: [][]float64{ + {60, 96, 126, 146}, + {-42, -66, -88, -94}, + {10, 16, 18, 20}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 3, + n: 2, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 7}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {4.5, 9}, + {-0.375, -1.5}, + {-0.75, -12.0 / 7}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 3, + n: 2, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 7}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {9, 18}, + {-15, -33}, + {60, 132}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 3, + n: 4, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 7}, + }, + b: [][]float64{ + {3, 6, 2, 9}, + {4, 7, 1, 3}, + {5, 8, 9, 10}, + }, + ans: [][]float64{ + {4.5, 9, 3, 13.5}, + {-0.375, -1.5, -1.5, -63.0 / 8}, + {-0.75, -12.0 / 7, 3, 39.0 / 28}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 3, + n: 4, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 7}, + }, + b: [][]float64{ + {3, 6, 2, 9}, + {4, 7, 1, 3}, + {5, 8, 9, 10}, + }, + ans: [][]float64{ + {9, 18, 6, 27}, + {-15, -33, -15, -72}, + {60, 132, 87, 327}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 3, + n: 2, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 7}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {4.5, 9}, + {-0.30, -1.2}, + {-6.0 / 35, -24.0 / 35}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 3, + n: 2, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 7}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {9, 18}, + {-15, -33}, + {69, 150}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 3, + n: 4, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 7}, + }, + b: [][]float64{ + {3, 6, 6, 7}, + {4, 7, 8, 9}, + {5, 8, 10, 11}, + }, + ans: [][]float64{ + {4.5, 9, 9, 10.5}, + {-0.3, -1.2, -0.6, -0.9}, + {-6.0 / 35, -24.0 / 35, -12.0 / 35, -18.0 / 35}, + }, + }, + { + s: blas.Left, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 3, + n: 4, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 7}, + }, + b: [][]float64{ + {3, 6, 6, 7}, + {4, 7, 8, 9}, + {5, 8, 10, 11}, + }, + ans: [][]float64{ + {9, 18, 18, 21}, + {-15, -33, -30, -36}, + {69, 150, 138, 165}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 3, + n: 2, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 8}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {-0.46875, 0.375}, + {0.1875, 0.75}, + {1.875, 3}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 3, + n: 2, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 8}, + }, + b: [][]float64{ + {3, 6}, + {4, 7}, + {5, 8}, + }, + ans: [][]float64{ + {168, 267}, + {-78, -123}, + {15, 24}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 3, + n: 4, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 8}, + }, + b: [][]float64{ + {3, 6, 2, 3}, + {4, 7, 4, 5}, + {5, 8, 6, 7}, + }, + ans: [][]float64{ + {-0.46875, 0.375, -2.0625, -1.78125}, + {0.1875, 0.75, -0.375, -0.1875}, + {1.875, 3, 2.25, 2.625}, + }, + }, + { + s: blas.Left, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 3, + n: 4, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 4, 0}, + {5, 6, 8}, + }, + b: [][]float64{ + {3, 6, 2, 3}, + {4, 7, 4, 5}, + {5, 8, 6, 7}, + }, + ans: [][]float64{ + {168, 267, 204, 237}, + {-78, -123, -96, -111}, + {15, 24, 18, 21}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 7}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {15, -2.4, -48.0 / 35}, + {19.5, -3.3, -66.0 / 35}, + {24, -4.2, -2.4}, + {28.5, -5.1, -102.0 / 35}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {30, -57, 258}, + {39, -75, 339}, + {48, -93, 420}, + {57, -111, 501}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 7}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {15, -2.4, -48.0 / 35}, + {19.5, -3.3, -66.0 / 35}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {30, -57, 258}, + {39, -75, 339}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {4.2, 1.2, 4.5}, + {5.775, 1.65, 5.625}, + {7.35, 2.1, 6.75}, + {8.925, 2.55, 7.875}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {435, -183, 36}, + {543, -228, 45}, + {651, -273, 54}, + {759, -318, 63}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {4.2, 1.2, 4.5}, + {5.775, 1.65, 5.625}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {435, -183, 36}, + {543, -228, 45}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {4.2, 1.2, 4.5}, + {5.775, 1.65, 5.625}, + {7.35, 2.1, 6.75}, + {8.925, 2.55, 7.875}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {435, -183, 36}, + {543, -228, 45}, + {651, -273, 54}, + {759, -318, 63}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {4.2, 1.2, 4.5}, + {5.775, 1.65, 5.625}, + }, + }, + { + s: blas.Right, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 3, 4}, + {0, 5, 6}, + {0, 0, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {435, -183, 36}, + {543, -228, 45}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {15, -2.4, -1.2}, + {19.5, -3.3, -1.65}, + {24, -4.2, -2.1}, + {28.5, -5.1, -2.55}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 4, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + {16, 17, 18}, + {19, 20, 21}, + }, + ans: [][]float64{ + {30, -57, 258}, + {39, -75, 339}, + {48, -93, 420}, + {57, -111, 501}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {15, -2.4, -1.2}, + {19.5, -3.3, -1.65}, + }, + }, + { + s: blas.Right, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + m: 2, + n: 3, + alpha: 3, + a: [][]float64{ + {2, 0, 0}, + {3, 5, 0}, + {4, 6, 8}, + }, + b: [][]float64{ + {10, 11, 12}, + {13, 14, 15}, + }, + ans: [][]float64{ + {30, -57, 258}, + {39, -75, 339}, + }, + }, + } { + aFlat := flatten(test.a) + bFlat := flatten(test.b) + ansFlat := flatten(test.ans) + var lda int + if test.s == blas.Left { + lda = test.m + } else { + lda = test.n + } + blasser.Dtrsm(test.s, test.ul, test.tA, test.d, test.m, test.n, test.alpha, aFlat, lda, bFlat, test.n) + if !floats.EqualApprox(ansFlat, bFlat, 1e-13) { + t.Errorf("Case %v: Want %v, got %v.", i, ansFlat, bFlat) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtrsv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtrsv.go new file mode 100644 index 00000000..1638177c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtrsv.go @@ -0,0 +1,144 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dtrsver interface { + Dtrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, lda int, x []float64, incX int) +} + +func DtrsvTest(t *testing.T, blasser Dtrsver) { + for i, test := range []struct { + n int + a [][]float64 + ul blas.Uplo + tA blas.Transpose + d blas.Diag + x []float64 + ans []float64 + }{ + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 8, 15}, + {0, 0, 8}, + }, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{4.15625, -0.890625, 0.875}, + }, + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 1, 15}, + {0, 0, 1}, + }, + ul: blas.Upper, + tA: blas.NoTrans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{182, -99, 7}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 8, 0}, + {3, 15, 8}, + }, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{5, -0.5, -0.0625}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 8, 0}, + {3, 15, 8}, + }, + ul: blas.Lower, + tA: blas.NoTrans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{5, -4, 52}, + }, + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 8, 15}, + {0, 0, 8}, + }, + ul: blas.Upper, + tA: blas.Trans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{5, -0.5, -0.0625}, + }, + { + n: 3, + a: [][]float64{ + {1, 2, 3}, + {0, 8, 15}, + {0, 0, 8}, + }, + ul: blas.Upper, + tA: blas.Trans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{5, -4, 52}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 8, 0}, + {3, 15, 8}, + }, + ul: blas.Lower, + tA: blas.Trans, + d: blas.NonUnit, + x: []float64{5, 6, 7}, + ans: []float64{4.15625, -0.890625, 0.875}, + }, + { + n: 3, + a: [][]float64{ + {1, 0, 0}, + {2, 1, 0}, + {3, 15, 1}, + }, + ul: blas.Lower, + tA: blas.Trans, + d: blas.Unit, + x: []float64{5, 6, 7}, + ans: []float64{182, -99, 7}, + }, + } { + incTest := func(incX, extra int) { + aFlat := flatten(test.a) + x := makeIncremented(test.x, incX, extra) + blasser.Dtrsv(test.ul, test.tA, test.d, test.n, aFlat, test.n, x, incX) + ans := makeIncremented(test.ans, incX, extra) + if !floats.EqualApprox(x, ans, 1e-14) { + t.Errorf("Case %v, incX = %v: Want %v, got %v.", i, incX, ans, x) + } + } + incTest(1, 0) + incTest(-2, 0) + incTest(3, 0) + incTest(-3, 8) + incTest(4, 2) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dtxmv.go b/vendor/gonum.org/v1/gonum/blas/testblas/dtxmv.go new file mode 100644 index 00000000..c55da3bd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dtxmv.go @@ -0,0 +1,145 @@ +package testblas + +import ( + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dtxmver interface { + Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, lda int, x []float64, incX int) + Dtbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []float64, lda int, x []float64, incX int) + Dtpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, x []float64, incX int) +} + +type vec struct { + data []float64 + inc int +} + +var cases = []struct { + n, k int + ul blas.Uplo + d blas.Diag + ldab int + tr, tb, tp []float64 + ins []vec + solNoTrans []float64 + solTrans []float64 +}{ + { + n: 3, + k: 1, + ul: blas.Upper, + d: blas.NonUnit, + tr: []float64{1, 2, 0, 0, 3, 4, 0, 0, 5}, + tb: []float64{1, 2, 3, 4, 5, 0}, + ldab: 2, + tp: []float64{1, 2, 0, 3, 4, 5}, + ins: []vec{ + {[]float64{2, 3, 4}, 1}, + {[]float64{2, 1, 3, 1, 4}, 2}, + {[]float64{4, 1, 3, 1, 2}, -2}, + }, + solNoTrans: []float64{8, 25, 20}, + solTrans: []float64{2, 13, 32}, + }, + { + n: 3, + k: 1, + ul: blas.Upper, + d: blas.Unit, + tr: []float64{1, 2, 0, 0, 3, 4, 0, 0, 5}, + tb: []float64{1, 2, 3, 4, 5, 0}, + ldab: 2, + tp: []float64{1, 2, 0, 3, 4, 5}, + ins: []vec{ + {[]float64{2, 3, 4}, 1}, + {[]float64{2, 1, 3, 1, 4}, 2}, + {[]float64{4, 1, 3, 1, 2}, -2}, + }, + solNoTrans: []float64{8, 19, 4}, + solTrans: []float64{2, 7, 16}, + }, + { + n: 3, + k: 1, + ul: blas.Lower, + d: blas.NonUnit, + tr: []float64{1, 0, 0, 2, 3, 0, 0, 4, 5}, + tb: []float64{0, 1, 2, 3, 4, 5}, + ldab: 2, + tp: []float64{1, 2, 3, 0, 4, 5}, + ins: []vec{ + {[]float64{2, 3, 4}, 1}, + {[]float64{2, 1, 3, 1, 4}, 2}, + {[]float64{4, 1, 3, 1, 2}, -2}, + }, + solNoTrans: []float64{2, 13, 32}, + solTrans: []float64{8, 25, 20}, + }, + { + n: 3, + k: 1, + ul: blas.Lower, + d: blas.Unit, + tr: []float64{1, 0, 0, 2, 3, 0, 0, 4, 5}, + tb: []float64{0, 1, 2, 3, 4, 5}, + ldab: 2, + tp: []float64{1, 2, 3, 0, 4, 5}, + ins: []vec{ + {[]float64{2, 3, 4}, 1}, + {[]float64{2, 1, 3, 1, 4}, 2}, + {[]float64{4, 1, 3, 1, 2}, -2}, + }, + solNoTrans: []float64{2, 7, 16}, + solTrans: []float64{8, 19, 4}, + }, +} + +func DtxmvTest(t *testing.T, blasser Dtxmver) { + + for nc, c := range cases { + for nx, x := range c.ins { + in := make([]float64, len(x.data)) + copy(in, x.data) + blasser.Dtrmv(c.ul, blas.NoTrans, c.d, c.n, c.tr, c.n, in, x.inc) + if !dStridedSliceTolEqual(c.n, in, x.inc, c.solNoTrans, 1) { + t.Error("Wrong Dtrmv result for: NoTrans in Case:", nc, "input:", nx) + } + + in = make([]float64, len(x.data)) + copy(in, x.data) + blasser.Dtrmv(c.ul, blas.Trans, c.d, c.n, c.tr, c.n, in, x.inc) + if !dStridedSliceTolEqual(c.n, in, x.inc, c.solTrans, 1) { + t.Error("Wrong Dtrmv result for: Trans in Case:", nc, "input:", nx) + } + in = make([]float64, len(x.data)) + copy(in, x.data) + blasser.Dtbmv(c.ul, blas.NoTrans, c.d, c.n, c.k, c.tb, c.ldab, in, x.inc) + if !dStridedSliceTolEqual(c.n, in, x.inc, c.solNoTrans, 1) { + t.Error("Wrong Dtbmv result for: NoTrans in Case:", nc, "input:", nx) + } + + in = make([]float64, len(x.data)) + copy(in, x.data) + blasser.Dtbmv(c.ul, blas.Trans, c.d, c.n, c.k, c.tb, c.ldab, in, x.inc) + if !dStridedSliceTolEqual(c.n, in, x.inc, c.solTrans, 1) { + t.Error("Wrong Dtbmv result for: Trans in Case:", nc, "input:", nx) + } + in = make([]float64, len(x.data)) + copy(in, x.data) + blasser.Dtpmv(c.ul, blas.NoTrans, c.d, c.n, c.tp, in, x.inc) + if !dStridedSliceTolEqual(c.n, in, x.inc, c.solNoTrans, 1) { + t.Error("Wrong Dtpmv result for: NoTrans in Case:", nc, "input:", nx) + } + + in = make([]float64, len(x.data)) + copy(in, x.data) + blasser.Dtpmv(c.ul, blas.Trans, c.d, c.n, c.tp, in, x.inc) + if !dStridedSliceTolEqual(c.n, in, x.inc, c.solTrans, 1) { + t.Error("Wrong Dtpmv result for: Trans in Case:", nc, "input:", nx) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dzasum.go b/vendor/gonum.org/v1/gonum/blas/testblas/dzasum.go new file mode 100644 index 00000000..ab376a4c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dzasum.go @@ -0,0 +1,58 @@ +// 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 testblas + +import ( + "math/cmplx" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dzasumer interface { + Dzasum(n int, x []complex128, incX int) float64 +} + +func DzasumTest(t *testing.T, impl Dzasumer) { + const tol = 1e-14 + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 50, 100} { + for _, incX := range []int{-5, 1, 2, 10} { + aincX := abs(incX) + var x []complex128 + if n > 0 { + x = make([]complex128, (n-1)*aincX+1) + } + for i := range x { + x[i] = cmplx.NaN() + } + for i := 0; i < n; i++ { + re := float64(2*i + 1) + if rnd.Intn(2) == 0 { + re *= -1 + } + im := float64(2 * (i + 1)) + if rnd.Intn(2) == 0 { + im *= -1 + } + x[i*aincX] = complex(re, im) + } + + want := float64(n * (2*n + 1)) + got := impl.Dzasum(n, x, incX) + + if incX < 0 { + if got != 0 { + t.Errorf("Case n=%v,incX=%v: non-zero result when incX < 0. got %v", n, incX, got) + } + continue + } + if !floats.EqualWithinAbsOrRel(got, want, tol, tol) { + t.Errorf("Case n=%v,incX=%v: unexpected result. want %v, got %v", n, incX, want, got) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/dznrm2.go b/vendor/gonum.org/v1/gonum/blas/testblas/dznrm2.go new file mode 100644 index 00000000..3742347a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/dznrm2.go @@ -0,0 +1,137 @@ +// 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 testblas + +import ( + "fmt" + "math" + "math/cmplx" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dznrm2er interface { + Dznrm2(n int, x []complex128, incX int) float64 + Dnrm2er +} + +func Dznrm2Test(t *testing.T, impl Dznrm2er) { + tol := 1e-12 + for tc, test := range []struct { + x []complex128 + want float64 + }{ + { + x: nil, + want: 0, + }, + { + x: []complex128{1 + 2i}, + want: 2.2360679774998, + }, + { + x: []complex128{1 + 2i, 3 + 4i}, + want: 5.4772255750517, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i}, + want: 9.5393920141695, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i}, + want: 1.4282856857086e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i}, + want: 1.9621416870349e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i}, + want: 2.5495097567964e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i}, + want: 3.1859064644148e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i}, + want: 3.8678159211627e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i}, + want: 4.5923850012820e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i}, + want: 5.3572380943915e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i}, + want: 6.1603571325046e+01, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + want: 70, + }, + } { + n := len(test.x) + for _, incX := range []int{-10, -1, 1, 2, 9, 17} { + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + got := impl.Dznrm2(n, x, incX) + + prefix := fmt.Sprintf("Case %v (n=%v,incX=%v):", tc, n, incX) + + if !zsame(x, xCopy) { + t.Errorf("%v: unexpected modification of x", prefix) + } + + if incX < 0 { + if got != 0 { + t.Errorf("%v: non-zero result when incX < 0. got %v", prefix, got) + } + continue + } + + if !floats.EqualWithinAbsOrRel(test.want, got, tol, tol) { + t.Errorf("%v: unexpected result. want %v, got %v", prefix, test.want, got) + } + } + } + + tol = 1e-14 + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{10, 50, 100} { + for _, incX := range []int{1, 2, 10} { + re := make([]float64, n) + for i := range re { + re[i] = rnd.NormFloat64() + } + im := make([]float64, n) + for i := range im { + im[i] = rnd.NormFloat64() + } + want := math.Hypot(impl.Dnrm2(n, re, 1), impl.Dnrm2(n, im, 1)) + + x := make([]complex128, (n-1)*incX+1) + for i := range x { + x[i] = cmplx.NaN() + } + for i := range re { + x[i*incX] = complex(re[i], im[i]) + } + + got := impl.Dznrm2(n, x, incX) + + if !floats.EqualWithinAbsOrRel(want, got, tol, tol) { + t.Errorf("Case n=%v,incX=%v: unexpected result using Dnrm2. want %v, got %v", n, incX, want, got) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/izamax.go b/vendor/gonum.org/v1/gonum/blas/testblas/izamax.go new file mode 100644 index 00000000..76798c7a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/izamax.go @@ -0,0 +1,47 @@ +// 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 testblas + +import ( + "math/cmplx" + "math/rand" + "testing" +) + +type Izamaxer interface { + Izamax(n int, x []complex128, incX int) int +} + +func IzamaxTest(t *testing.T, impl Izamaxer) { + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 50, 100} { + for _, incX := range []int{-5, 1, 2, 10} { + aincX := abs(incX) + var x []complex128 + if n > 0 { + x = make([]complex128, (n-1)*aincX+1) + } + for i := range x { + x[i] = cmplx.NaN() + } + for i := 0; i < n; i++ { + re := 2*rnd.Float64() - 1 + im := 2*rnd.Float64() - 1 + x[i*aincX] = complex(re, im) + } + + want := -1 + if incX > 0 && n > 0 { + want = rnd.Intn(n) + x[want*incX] = 10 + 10i + } + got := impl.Izamax(n, x, incX) + + if got != want { + t.Errorf("Case n=%v,incX=%v: unexpected result. want %v, got %v", n, incX, want, got) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/level1double.go b/vendor/gonum.org/v1/gonum/blas/testblas/level1double.go new file mode 100644 index 00000000..8673891f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/level1double.go @@ -0,0 +1,2048 @@ +// 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 testblas + +import ( + "fmt" + "log" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" + + "math" + "testing" +) + +type DoubleOneVectorCase struct { + Name string + X []float64 + Incx int + N int + Panic bool + Dasum float64 + Dnrm2 float64 + Idamax int + DscalCases []DScalCase +} + +type DScalCase struct { + Alpha float64 + Ans []float64 + Name string +} + +var DoubleOneVectorCases = []DoubleOneVectorCase{ + { + Name: "AllPositive", + X: []float64{6, 5, 4, 2, 6}, + Incx: 1, + N: 5, + Panic: false, + Dasum: 23, + Dnrm2: 10.81665382639196787935766380241148783875388972153573863813135, + Idamax: 0, + DscalCases: []DScalCase{ + { + Alpha: 0, + Ans: []float64{0, 0, 0, 0, 0}, + }, + { + Alpha: 1, + Ans: []float64{6, 5, 4, 2, 6}, + }, + { + Alpha: -2, + Ans: []float64{-12, -10, -8, -4, -12}, + }, + }, + }, + { + Name: "LeadingZero", + X: []float64{0, 1}, + Incx: 1, + N: 2, + Panic: false, + Dasum: 1, + Dnrm2: 1, + Idamax: 1, + DscalCases: []DScalCase{ + { + Alpha: 0, + Ans: []float64{0, 0}, + }, + { + Alpha: 1, + Ans: []float64{0, 1}, + }, + { + Alpha: -2, + Ans: []float64{0, -2}, + }, + }, + }, + { + Name: "MaxInMiddle", + X: []float64{6, 5, 9, 0, 6}, + Incx: 1, + N: 5, + Panic: false, + Dasum: 26, + Dnrm2: 13.34166406412633371248943627250846646911846482744007727141318, + Idamax: 2, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-12, -10, -18, 0, -12}, + }, + }, + }, + { + Name: "MaxAtEnd", + X: []float64{6, 5, -9, 0, 10}, + Incx: 1, + N: 5, + Panic: false, + Dasum: 30, + Dnrm2: 15.55634918610404553681857596630667886426639062914642880494347, + Idamax: 4, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-12, -10, 18, 0, -20}, + }, + }, + }, + { + Name: "AllNegative", + X: []float64{-6, -5, -4, -2, -6}, + Incx: 1, + N: 5, + Panic: false, + Dasum: 23, + Dnrm2: 10.81665382639196787935766380241148783875388972153573863813135, + Idamax: 0, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{12, 10, 8, 4, 12}, + }, + }, + }, + { + Name: "AllMixed", + X: []float64{-6, 5, 4, -2, -6}, + Incx: 1, + N: 5, + Panic: false, + Dasum: 23, + Dnrm2: 10.81665382639196787935766380241148783875388972153573863813135, + Idamax: 0, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{12, -10, -8, 4, 12}, + }, + }, + }, + { + Name: "ZeroN", + X: []float64{-6, 5, 4, -2, -6}, + Incx: 1, + N: 0, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "OneN", + X: []float64{-6, 5, 4, -2, -6}, + Incx: 1, + N: 1, + Panic: false, + Dasum: 6, + Dnrm2: 6, + Idamax: 0, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{12, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "PositiveExactInc", + X: []float64{-6, 5, 10, -2, -5}, + Incx: 2, + N: 3, + Panic: false, + Dasum: 21, + Dnrm2: 12.68857754044952038019377274608948979173952662752515253090272, + Idamax: 1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{12, 5, -20, -2, 10}, + }, + }, + }, + { + Name: "PositiveOffInc", + X: []float64{-6, 5, 4, -2, -6, 8, 10, 11}, + Incx: 3, + N: 3, + Panic: false, + Dasum: 18, + Dnrm2: 11.83215956619923208513465658312323409683100246158868064575943, + Idamax: 2, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{12, 5, 4, 4, -6, 8, -20, 11}, + }, + }, + }, + { + Name: "PositiveShortInc", + X: []float64{-6, 5, 4, -2, -6, 8, 10, 11}, + Incx: 3, + N: 2, + Panic: false, + Dasum: 8, + Dnrm2: 6.324555320336758663997787088865437067439110278650433653715009, + Idamax: 0, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{12, 5, 4, 4, -6, 8, 10, 11}, + }, + }, + }, + { + Name: "NegativeInc", + X: []float64{-6, 5, 4, -2, -6}, + Incx: -1, + N: 5, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "NegativeExactInc", + X: []float64{-6, 5, 4, -2, -6}, + Incx: -2, + N: 3, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "NegativeOffInc", + X: []float64{-6, 5, 4, -2, -6, 8, 10, 11}, + Incx: -3, + N: 2, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6, 8, 10, 11}, + }, + }, + }, + { + Name: "NegativeShortInc", + X: []float64{-6, 5, 4, -2, -6, 8, 10, 11}, + Incx: -3, + N: 2, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6, 8, 10, 11}, + }, + }, + }, + { + Name: "NegativeN", + X: []float64{-6, 5, 4, -2, -6}, + Incx: 2, + N: -5, + Panic: true, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "ZeroInc", + X: []float64{-6, 5, 4, -2, -6}, + Incx: 0, + N: 5, + Panic: true, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "OutOfBounds", + X: []float64{-6, 5, 4, -2, -6}, + Incx: 2, + N: 6, + Panic: true, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "NegativeOutOfBounds", + X: []float64{-6, 5, 4, -2, -6}, + Incx: -2, + N: 6, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-6, 5, 4, -2, -6}, + }, + }, + }, + { + Name: "NaN", + X: []float64{math.NaN(), 2.0}, + Incx: 1, + N: 2, + Panic: false, + Dasum: math.NaN(), + Dnrm2: math.NaN(), + Idamax: 0, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{math.NaN(), -4.0}, + }, + { + Alpha: 0, + Ans: []float64{0, 0}, + }, + }, + }, + { + Name: "NaNInc", + X: []float64{math.NaN(), math.NaN(), 2.0}, + Incx: 2, + N: 2, + Panic: false, + Dasum: math.NaN(), + Dnrm2: math.NaN(), + Idamax: 0, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{math.NaN(), math.NaN(), -4.0}, + }, + { + Alpha: 0, + Ans: []float64{0, math.NaN(), 0}, + }, + }, + }, + { + Name: "Empty", + X: []float64{}, + Incx: 1, + N: 0, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{}, + }, + { + Alpha: 0, + Ans: []float64{}, + }, + }, + }, + { + Name: "EmptyZeroInc", + X: []float64{}, + Incx: 0, + N: 0, + Panic: true, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{}, + }, + { + Alpha: 0, + Ans: []float64{}, + }, + }, + }, + { + Name: "EmptyReverse", + X: []float64{}, + Incx: -1, + N: 0, + Panic: false, + Dasum: 0, + Dnrm2: 0, + Idamax: -1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{}, + }, + { + Alpha: 0, + Ans: []float64{}, + }, + }, + }, + { + Name: "MultiInf", + X: []float64{5, math.Inf(1), math.Inf(-1), 8, 9}, + Incx: 1, + N: 5, + Panic: false, + Dasum: math.Inf(1), + Dnrm2: math.Inf(1), + Idamax: 1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-10, math.Inf(-1), math.Inf(1), -16, -18}, + }, + { + Alpha: 0, + Ans: []float64{0, 0, 0, 0, 0}, + }, + }, + }, + { + Name: "NaNInf", + X: []float64{5, math.NaN(), math.Inf(-1), 8, 9}, + Incx: 1, + N: 5, + Panic: false, + Dasum: math.NaN(), + Dnrm2: math.NaN(), + Idamax: 2, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-10, math.NaN(), math.Inf(1), -16, -18}, + }, + { + Alpha: 0, + Ans: []float64{0, 0, 0, 0, 0}, + }, + }, + }, + { + Name: "InfNaN", + X: []float64{5, math.Inf(1), math.NaN(), 8, 9}, + Incx: 1, + N: 5, + Panic: false, + Dasum: math.NaN(), + Dnrm2: math.NaN(), + Idamax: 1, + DscalCases: []DScalCase{ + { + Alpha: -2, + Ans: []float64{-10, math.Inf(-1), math.NaN(), -16, -18}, + }, + { + Alpha: 0, + Ans: []float64{0, 0, 0, 0, 0}, + }, + }, + }, +} + +type DoubleTwoVectorCase struct { + Name string + X []float64 + Y []float64 + XTmp []float64 + YTmp []float64 + Incx int + Incy int + N int + Panic bool + // For Daxpy + DaxpyCases []DaxpyCase + DdotAns float64 + DswapAns DTwoVecAnswer + DcopyAns DTwoVecAnswer + DrotCases []DrotCase + DrotmCases []DrotmCase +} + +type DaxpyCase struct { + Alpha float64 + Ans []float64 +} + +type DrotCase struct { + C float64 + S float64 + XAns []float64 + YAns []float64 +} + +type DrotmCase struct { + P blas.DrotmParams + XAns []float64 + YAns []float64 + Name string +} + +type DTwoVecAnswer struct { + X []float64 + Y []float64 +} + +var DoubleTwoVectorCases = []DoubleTwoVectorCase{ + { + Name: "UnitaryInc", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0}, + Incx: 1, + Incy: 1, + N: 6, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 1, + Ans: []float64{18, 13, -2, 10, 20, 4}, + }, + { + Alpha: 2, + Ans: []float64{28, 28, -8, 13, 34, 11}, + }, + { + Alpha: -3, + Ans: []float64{-22, -47, 22, -2, -36, -24}, + }, + { + Alpha: 0, + Ans: []float64{8, -2, 4, 7, 6, -3}, + }, + }, + DdotAns: 110, + DswapAns: DTwoVecAnswer{ + X: []float64{8, -2, 4, 7, 6, -3}, + Y: []float64{10, 15, -6, 3, 14, 7}, + }, + DcopyAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{10, 15, -6, 3, 14, 7}, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(0), + S: math.Sin(0), + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3}, + }, + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{12.444023964292095, 12.749380282068351, -3.7473736752571014, 5.677251193294846, 15.224018588957296, 5.076299724034451}, + YAns: []float64{3.024279678886205, -8.151889500183792, 6.160940718590796, 5.076299724034451, -0.4788089421498931, -5.677251193294846}, + }, + { + C: math.Cos(0.5 * math.Pi), + S: math.Sin(0.5 * math.Pi), + XAns: []float64{8, -2, 4, 7, 6, -3}, + YAns: []float64{-10, -15, 6, -3, -14, -7}, + }, + { + C: math.Cos(math.Pi), + S: math.Sin(math.Pi), + XAns: []float64{-10, -15, 6, -3, -14, -7}, + YAns: []float64{-8, 2, -4, -7, -6, 3}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Identity, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3}, + Name: "Neg2Flag", + }, + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 13.7, -5.8, 2, 12, 6.6}, + YAns: []float64{5, 0.5, 1.4, 3.8, 4.4, -0.8}, + Name: "Neg1Flag", + }, + { + P: blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{1, 0.1, -0.1, 1}, + }, + XAns: []float64{9.2, 15.2, -6.4, 2.3, 13.4, 7.3}, + YAns: []float64{9, -0.5, 3.4, 7.3, 7.4, -2.3}, + Name: "ZeroFlag", + }, + { + P: blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{0.5, -1, 1, 0.7}, + }, + XAns: []float64{13, 5.5, 1, 8.5, 13, 0.5}, + YAns: []float64{-4.4, -16.4, 8.8, 1.9, -9.8, -9.1}, + Name: "OneFlag", + }, + }, + }, + { + Name: "UnitaryIncLong", + X: []float64{10, 15, -6, 3, 14, 7, 8, -9, 10}, + Y: []float64{8, -2, 4, 7, 6, -3, 7, -6}, + XTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: 1, + Incy: 1, + N: 6, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 1, + Ans: []float64{18, 13, -2, 10, 20, 4, 7, -6}, + }, + { + Alpha: 2, + Ans: []float64{28, 28, -8, 13, 34, 11, 7, -6}, + }, + { + Alpha: -3, + Ans: []float64{-22, -47, 22, -2, -36, -24, 7, -6}, + }, + { + Alpha: 0, + Ans: []float64{8, -2, 4, 7, 6, -3, 7, -6}, + }, + }, + DdotAns: 110, + DswapAns: DTwoVecAnswer{ + X: []float64{8, -2, 4, 7, 6, -3, 8, -9, 10}, + Y: []float64{10, 15, -6, 3, 14, 7, 7, -6}, + }, + DcopyAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7, 8, -9, 10}, + Y: []float64{10, 15, -6, 3, 14, 7, 7, -6}, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(0), + S: math.Sin(0), + XAns: []float64{10, 15, -6, 3, 14, 7, 8, -9, 10}, + YAns: []float64{8, -2, 4, 7, 6, -3, 7, -6}, + }, + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{12.444023964292095, 12.749380282068351, -3.7473736752571014, 5.677251193294846, 15.224018588957296, 5.076299724034451, 8, -9, 10}, + YAns: []float64{3.024279678886205, -8.151889500183792, 6.160940718590796, 5.076299724034451, -0.4788089421498931, -5.677251193294846, 7, -6}, + }, + { + C: math.Cos(0.5 * math.Pi), + S: math.Sin(0.5 * math.Pi), + XAns: []float64{8, -2, 4, 7, 6, -3, 8, -9, 10}, + YAns: []float64{-10, -15, 6, -3, -14, -7, 7, -6}, + }, + { + C: math.Cos(math.Pi), + S: math.Sin(math.Pi), + XAns: []float64{-10, -15, 6, -3, -14, -7, 8, -9, 10}, + YAns: []float64{-8, 2, -4, -7, -6, 3, 7, -6}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Identity, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{10, 15, -6, 3, 14, 7, 8, -9, 10}, + YAns: []float64{8, -2, 4, 7, 6, -3, 7, -6}, + Name: "Neg2Flag", + }, + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 13.7, -5.8, 2, 12, 6.6, 8, -9, 10}, + YAns: []float64{5, 0.5, 1.4, 3.8, 4.4, -0.8, 7, -6}, + Name: "Neg1Flag", + }, + { + P: blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{1, 0.1, -0.1, 1}, + }, + XAns: []float64{9.2, 15.2, -6.4, 2.3, 13.4, 7.3, 8, -9, 10}, + YAns: []float64{9, -0.5, 3.4, 7.3, 7.4, -2.3, 7, -6}, + Name: "ZeroFlag", + }, + { + P: blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{0.5, -1, 1, 0.7}, + }, + XAns: []float64{13, 5.5, 1, 8.5, 13, 0.5, 8, -9, 10}, + YAns: []float64{-4.4, -16.4, 8.8, 1.9, -9.8, -9.1, 7, -6}, + Name: "OneFlag", + }, + }, + }, + { + Name: "PositiveInc", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: 2, + Incy: 3, + N: 3, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{28, -2, 4, -5, 6, -3, 24, 10}, + }, + }, + DdotAns: -18, + DswapAns: DTwoVecAnswer{ + X: []float64{8, 15, 7, 3, -4, 7}, + Y: []float64{10, -2, 4, -6, 6, -3, 14, 10}, + }, + DcopyAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{10, -2, 4, -6, 6, -3, 14, 10}, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{12.444023964292095, 15, -2.479518890035003, 3, 10.997835971550302, 7}, + YAns: []float64{3.024279678886205, -2, 4, 8.879864079700745, 6, -3, -9.541886812516392, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 15, -6.1, 3, 13, 7}, + YAns: []float64{5, -2, 4, 2.9, 6, -3, -0.6, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{1, 0.1, -0.1, 1}, + }, + XAns: []float64{9.2, 15, -6.7, 3, 14.4, 7}, + YAns: []float64{9, -2, 4, 6.4, 6, -3, -2.6, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{0.5, -1, 1, 0.7}, + }, + XAns: []float64{13, 15, 4, 3, 3, 7}, + YAns: []float64{-4.4, -2, 4, 10.9, 6, -3, -16.8, 10}, + }, + }, + }, + { + Name: "NegativeInc", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: -2, + Incy: -3, + N: 3, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{28, -2, 4, -5, 6, -3, 24, 10}, + }, + }, + DdotAns: -18, + DswapAns: DTwoVecAnswer{ + X: []float64{8, 15, 7, 3, -4, 7}, + Y: []float64{10, -2, 4, -6, 6, -3, 14, 10}, + }, + DcopyAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{10, -2, 4, -6, 6, -3, 14, 10}, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{12.444023964292095, 15, -2.479518890035003, 3, 10.997835971550302, 7}, + YAns: []float64{3.024279678886205, -2, 4, 8.879864079700745, 6, -3, -9.541886812516392, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 15, -6.1, 3, 13, 7}, + YAns: []float64{5, -2, 4, 2.9, 6, -3, -0.6, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{1, 0.1, -0.1, 1}, + }, + XAns: []float64{9.2, 15, -6.7, 3, 14.4, 7}, + YAns: []float64{9, -2, 4, 6.4, 6, -3, -2.6, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{0.5, -1, 1, 0.7}, + }, + XAns: []float64{13, 15, 4, 3, 3, 7}, + YAns: []float64{-4.4, -2, 4, 10.9, 6, -3, -16.8, 10}, + }, + }, + }, + { + Name: "MixedInc1", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: 2, + Incy: -3, + N: 3, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{36, -2, 4, -5, 6, -3, 16, 10}, + }, + }, + DdotAns: 30, + DswapAns: DTwoVecAnswer{ + X: []float64{-4, 15, 7, 3, 8, 7}, + Y: []float64{14, -2, 4, -6, 6, -3, 10, 10}, + }, + DcopyAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{14, -2, 4, -6, 6, -3, 10, 10}, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{7.372604823403701, 15, -2.479518890035003, 3, 16.069255112438693, 7}, + YAns: []float64{1.333806631923407, -2, 4, 8.879864079700745, 6, -3, -7.851413765553595, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{9.4, 15, -6.1, 3, 11.8, 7}, + YAns: []float64{5.4, -2, 4, 2.9, 6, -3, -1, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{1, 0.1, -0.1, 1}, + }, + XAns: []float64{10.4, 15, -6.7, 3, 13.2, 7}, + YAns: []float64{9.4, -2, 4, 6.4, 6, -3, -3, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{0.5, -1, 1, 0.7}, + }, + XAns: []float64{1, 15, 4, 3, 15, 7}, + YAns: []float64{-8.4, -2, 4, 10.9, 6, -3, -12.8, 10}, + }, + }, + }, + { + Name: "MixedInc2", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: -2, + Incy: 3, + N: 3, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{36, -2, 4, -5, 6, -3, 16, 10}, + }, + }, + DdotAns: 30, + DswapAns: DTwoVecAnswer{ + X: []float64{-4, 15, 7, 3, 8, 7}, + Y: []float64{14, -2, 4, -6, 6, -3, 10, 10}, + }, + DcopyAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{14, -2, 4, -6, 6, -3, 10, 10}, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{7.372604823403701, 15, -2.479518890035003, 3, 16.069255112438693, 7}, + YAns: []float64{1.333806631923407, -2, 4, 8.879864079700745, 6, -3, -7.851413765553595, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{9.4, 15, -6.1, 3, 11.8, 7}, + YAns: []float64{5.4, -2, 4, 2.9, 6, -3, -1, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{1, 0.1, -0.1, 1}, + }, + XAns: []float64{10.4, 15, -6.7, 3, 13.2, 7}, + YAns: []float64{9.4, -2, 4, 6.4, 6, -3, -3, 10}, + }, + { + P: blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{0.5, -1, 1, 0.7}, + }, + XAns: []float64{1, 15, 4, 3, 15, 7}, + YAns: []float64{-8.4, -2, 4, 10.9, 6, -3, -12.8, 10}, + }, + }, + }, + { + Name: "ZeroN", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: -2, + Incy: 3, + N: 0, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + DswapAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + DcopyAns: DTwoVecAnswer{ + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + }, + { + Name: "NegativeN", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: -2, + Incy: 3, + N: -3, + Panic: true, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{36, -2, 4, -5, 6, -3, 16, 10}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 13.7, -5.8, 2, 12, 6.6}, + YAns: []float64{5, 0.5, 1.4, 3.8, 4.4, -0.8}, + }, + }, + }, + { + Name: "ZeroIncX", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: 0, + Incy: 3, + N: 2, + Panic: true, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{36, -2, 4, -5, 6, -3, 16, 10}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 13.7, -5.8, 2, 12, 6.6}, + YAns: []float64{5, 0.5, 1.4, 3.8, 4.4, -0.8}, + }, + }, + }, + { + Name: "ZeroIncY", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: 1, + Incy: 0, + N: 2, + Panic: true, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{36, -2, 4, -5, 6, -3, 16, 10}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 13.7, -5.8, 2, 12, 6.6}, + YAns: []float64{5, 0.5, 1.4, 3.8, 4.4, -0.8}, + }, + }, + }, + { + Name: "OutOfBoundsX", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: 8, + Incy: 2, + N: 2, + Panic: true, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{36, -2, 4, -5, 6, -3, 16, 10}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{8.2, 13.7, -5.8, 2, 12, 6.6}, + YAns: []float64{5, 0.5, 1.4, 3.8, 4.4, -0.8}, + }, + }, + }, + { + Name: "OutOfBoundsY", + X: []float64{10, 15, -6, 3, 14, 7}, + Y: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + XTmp: []float64{0, 0, 0, 0, 0, 0}, + YTmp: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + Incx: 2, + Incy: 8, + N: 2, + Panic: true, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{36, -2, 4, -5, 6, -3, 16, 10}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{10, 15, -6, 3, 14, 7}, + YAns: []float64{8, -2, 4, 7, 6, -3, -4, 10}, + }, + }, + }, + { + Name: "Empty", + X: []float64{}, + Y: []float64{}, + Incx: 1, + Incy: 1, + N: 0, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{}, + YAns: []float64{}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{}, + YAns: []float64{}, + }, + }, + }, + { + Name: "EmptyZeroIncX", + X: []float64{}, + Y: []float64{}, + Incx: 0, + Incy: 1, + N: 0, + Panic: true, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{}, + YAns: []float64{}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{}, + YAns: []float64{}, + }, + }, + }, + { + Name: "EmptyZeroIncY", + X: []float64{}, + Y: []float64{}, + Incx: 1, + Incy: 0, + N: 0, + Panic: true, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{}, + YAns: []float64{}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{}, + YAns: []float64{}, + }, + }, + }, + { + Name: "EmptyReverse", + X: []float64{}, + Y: []float64{}, + Incx: -1, + Incy: -1, + N: 0, + Panic: false, + DaxpyCases: []DaxpyCase{ + { + Alpha: 2, + Ans: []float64{}, + }, + }, + DrotCases: []DrotCase{ + { + C: math.Cos(25 * math.Pi / 180), + S: math.Sin(25 * math.Pi / 180), + XAns: []float64{}, + YAns: []float64{}, + }, + }, + DrotmCases: []DrotmCase{ + { + P: blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.9, 0.1, -0.1, 0.5}, + }, + XAns: []float64{}, + YAns: []float64{}, + }, + }, + }, +} + +type Ddotter interface { + Ddot(n int, x []float64, incX int, y []float64, incY int) float64 +} + +func DdotTest(t *testing.T, d Ddotter) { + ddot := d.Ddot + for _, c := range DoubleTwoVectorCases { + dCopyTwoTmp(c.X, c.XTmp, c.Y, c.YTmp) + if c.Panic { + f := func() { ddot(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy) } + testpanics(f, c.Name, t) + continue + } + dot := ddot(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy) + if !dTolEqual(dot, c.DdotAns) { + t.Errorf("ddot: mismatch %v: expected %v, found %v", c.Name, c.DdotAns, dot) + } + } + + // check it works for 16-byte unaligned slices + x := []float64{1, 1, 1, 1, 1} + if n := ddot(4, x[:4], 1, x[1:], 1); n != 4 { + t.Errorf("ddot: mismatch Unaligned: expected %v, found %v", 4, n) + } + if n := ddot(2, x[:4], 2, x[1:], 2); n != 2 { + t.Errorf("ddot: mismatch Unaligned: expected %v, found %v", 2, n) + } + if n := ddot(2, x[:4], 3, x[1:], 3); n != 2 { + t.Errorf("ddot: mismatch Unaligned: expected %v, found %v", 2, n) + } +} + +type Dnrm2er interface { + Dnrm2(n int, x []float64, incX int) float64 +} + +func Dnrm2Test(t *testing.T, blasser Dnrm2er) { + dnrm2 := blasser.Dnrm2 + for _, c := range DoubleOneVectorCases { + if c.Panic { + f := func() { dnrm2(c.N, c.X, c.Incx) } + testpanics(f, c.Name, t) + continue + } + v := dnrm2(c.N, c.X, c.Incx) + if !dTolEqual(v, c.Dnrm2) { + t.Errorf("dnrm2: mismatch %v: expected %v, found %v", c.Name, c.Dnrm2, v) + } + } +} + +type Dasumer interface { + Dasum(n int, x []float64, incX int) float64 +} + +func DasumTest(t *testing.T, blasser Dasumer) { + dasum := blasser.Dasum + for _, c := range DoubleOneVectorCases { + if c.Panic { + f := func() { dasum(c.N, c.X, c.Incx) } + testpanics(f, c.Name, t) + continue + } + v := dasum(c.N, c.X, c.Incx) + if !dTolEqual(v, c.Dasum) { + t.Errorf("dasum: mismatch %v: expected %v, found %v", c.Name, c.Dasum, v) + } + } +} + +type Idamaxer interface { + Idamax(n int, x []float64, incX int) int +} + +func IdamaxTest(t *testing.T, blasser Idamaxer) { + idamax := blasser.Idamax + for _, c := range DoubleOneVectorCases { + if c.Panic { + f := func() { idamax(c.N, c.X, c.Incx) } + testpanics(f, c.Name, t) + continue + } + v := idamax(c.N, c.X, c.Incx) + if v != c.Idamax { + s := fmt.Sprintf("idamax: mismatch %v: expected %v, found %v", c.Name, c.Idamax, v) + if floats.HasNaN(c.X) { + log.Println(s) + } else { + t.Errorf(s) + } + } + } +} + +type Dswapper interface { + Dswap(n int, x []float64, incX int, y []float64, incY int) +} + +func DswapTest(t *testing.T, d Dswapper) { + dswap := d.Dswap + for _, c := range DoubleTwoVectorCases { + dCopyTwoTmp(c.X, c.XTmp, c.Y, c.YTmp) + if c.Panic { + f := func() { dswap(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy) } + testpanics(f, c.Name, t) + continue + } + dswap(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy) + if !dSliceTolEqual(c.XTmp, c.DswapAns.X) { + t.Errorf("dswap: x mismatch %v: expected %v, found %v", c.Name, c.DswapAns.X, c.XTmp) + } + if !dSliceTolEqual(c.YTmp, c.DswapAns.Y) { + t.Errorf("dswap: y mismatch %v: expected %v, found %v", c.Name, c.DswapAns.Y, c.YTmp) + } + } +} + +type Dcopier interface { + Dcopy(n int, x []float64, incX int, y []float64, incY int) +} + +func DcopyTest(t *testing.T, d Dcopier) { + dcopy := d.Dcopy + for _, c := range DoubleTwoVectorCases { + dCopyTwoTmp(c.X, c.XTmp, c.Y, c.YTmp) + if c.Panic { + f := func() { dcopy(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy) } + testpanics(f, c.Name, t) + continue + } + dcopy(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy) + if !dSliceTolEqual(c.XTmp, c.DcopyAns.X) { + t.Errorf("dswap: x mismatch %v: expected %v, found %v", c.Name, c.DcopyAns.X, c.XTmp) + } + if !dSliceTolEqual(c.YTmp, c.DcopyAns.Y) { + t.Errorf("dswap: y mismatch %v: expected %v, found %v", c.Name, c.DcopyAns.Y, c.YTmp) + } + } +} + +type Daxpyer interface { + Daxpy(n int, alpha float64, x []float64, incX int, y []float64, incY int) +} + +func DaxpyTest(t *testing.T, d Daxpyer) { + daxpy := d.Daxpy + for _, c := range DoubleTwoVectorCases { + for _, kind := range c.DaxpyCases { + dCopyTwoTmp(c.X, c.XTmp, c.Y, c.YTmp) + if c.Panic { + f := func() { daxpy(c.N, kind.Alpha, c.XTmp, c.Incx, c.YTmp, c.Incy) } + testpanics(f, c.Name, t) + continue + } + daxpy(c.N, kind.Alpha, c.XTmp, c.Incx, c.YTmp, c.Incy) + if !dSliceTolEqual(c.YTmp, kind.Ans) { + t.Errorf("daxpy: mismatch %v: expected %v, found %v", c.Name, kind.Ans, c.YTmp) + } + } + } +} + +type DrotgTestStruct struct { + Name string + A, B float64 + C, S, R, Z float64 +} + +var DrotgTests = []DrotgTestStruct{ + { + Name: "ZeroAB", + C: 1, + }, + { + Name: "PosA_ZeroB", + A: 0.5, + C: 1, + R: 0.5, + }, + { + Name: "NegA_ZeroB", + A: -4.6, + C: 1, + R: -4.6, + }, + { + Name: "ZeroA_PosB", + B: 3, + S: 1, + R: 3, + Z: 1, + }, + { + Name: "ZeroA_NegB", + B: -0.3, + S: 1, + R: -0.3, + Z: 1, + }, + { + Name: "PosA_PosB_AGTB", + A: 5, + B: 0.3, + C: 0.99820484546577868593549038000, + S: 0.05989229072794672115612942280, + R: 5.00899191454727744602429072688, + Z: 0.05989229072794672115612942280, + }, + { + Name: "PosA_PosB_ALTB", + A: 3, + B: 4, + C: 3.0 / 5, + S: 4.0 / 5, + R: 5, + Z: 5.0 / 3.0, + }, + + { + Name: "PosA_NegB_AGTB", + A: 2.6, + B: -0.9, + C: 0.94498607344025815971847507095, + S: -0.32711056388316628605639521686, + R: 2.751363298439520872718790879655, + Z: -0.3271105638831662860563952168, + }, + { + Name: "PosA_NegB_ALTB", + A: 2.6, + B: -2.9, + C: -0.6675450157520258540548049558, + S: 0.7445694406464903756765132200, + R: -3.8948684188300893100043812234, + Z: 1 / -0.6675450157520258540548049558, + }, + { + Name: "NegA_PosB_AGTB", + A: -11.4, + B: 10.3, + C: 0.7419981952497362418487847947, + S: -0.6704018781642353764072353847, + R: -15.363918770938617534070671122, + Z: -0.6704018781642353764072353847, + }, + { + Name: "NegA_PosB_ALTB", + A: -1.4, + B: 10.3, + C: -0.1346838895922121112404717523, + S: 0.9908886162855605326977564640, + R: 10.394710193170370442523552032, + Z: 1 / -0.1346838895922121112404717523, + }, + { + Name: "NegA_NegB_AGTB", + A: -11.4, + B: 10.3, + C: 0.7419981952497362418487847947, + S: -0.6704018781642353764072353847, + R: -15.363918770938617534070671122, + Z: -0.6704018781642353764072353847, + }, + { + Name: "NegA_NegB_ALTB", + A: -1.4, + B: -10.3, + C: 0.1346838895922121112404717523, + S: 0.9908886162855605326977564640, + R: -10.394710193170370442523552032, + Z: 1 / 0.1346838895922121112404717523, + }, +} + +type Drotger interface { + Drotg(a, b float64) (c, s, r, z float64) +} + +func DrotgTest(t *testing.T, d Drotger) { + drotg := d.Drotg + for _, test := range DrotgTests { + c, s, r, z := drotg(test.A, test.B) + if !dTolEqual(c, test.C) { + t.Errorf("drotg: c mismatch %v: expected %v, found %v", test.Name, test.C, c) + } + if !dTolEqual(s, test.S) { + t.Errorf("drotg: s mismatch %v: expected %v, found %v", test.Name, test.S, s) + } + if !dTolEqual(r, test.R) { + t.Errorf("drotg: r mismatch %v: expected %v, found %v", test.Name, test.R, r) + } + if !dTolEqual(z, test.Z) { + t.Errorf("drotg: z mismatch %v: expected %v, found %v", test.Name, test.Z, z) + } + } +} + +type DrotmgTestStruct struct { + Name string + D1, D2, X1, Y1 float64 + P *blas.DrotmParams + Rd1, Rd2, Rx1 float64 +} + +var DrotmgTests = []DrotmgTestStruct{ + { + Name: "NegD1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + }, + D1: -4, + D2: 6, + X1: 8, + Y1: -4, + }, + { + Name: "ZeroD2", + P: &blas.DrotmParams{ + Flag: blas.Identity, + }, + D1: 4, + X1: 8, + Y1: -5, + Rd1: 4, + Rx1: 8, + }, + { + Name: "ZeroY1", + P: &blas.DrotmParams{ + Flag: blas.Identity, + }, + D1: 4, + D2: -6, + X1: 8, + Rd1: 4, + Rd2: -6, + Rx1: 8, + }, + { + Name: "NegQ2_and_AQ1_LT_AQ2", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + }, + D1: 8, + D2: -6, + X1: 4, + Y1: 8, + Rd1: 0, + Rd2: 0, + Rx1: 0, + }, + { + Name: "ZeroD1", + P: &blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{0, 0, 0, 2}, + }, + D1: 0, + D2: 2, + X1: 8, + Y1: 4, + Rd1: 2, + Rd2: 0, + Rx1: 4, + }, + { + Name: "AbsQ1_GT_AbsQU__D2_Pos", + P: &blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{0, -0.625, 0.9375, 0}, + }, + D1: 2, + D2: 3, + X1: 8, + Y1: 5, + Rd1: 1.2610837438423645, + Rd2: 1.8916256157635467, + Rx1: 12.6875, + }, + { + Name: "AbsQ1_GT_AbsQU__D2_Neg", + P: &blas.DrotmParams{ + Flag: blas.OffDiagonal, + H: [4]float64{0, -0.625, -0.9375, 0}, + }, + D1: 2, + D2: -3, + X1: 8, + Y1: 5, + Rd1: 4.830188679245283, + Rd2: -7.245283018867925, + Rx1: 3.3125, + }, + { + Name: "AbsQ1_LT_AbsQU__D2_Pos", + P: &blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{5.0 / 12, 0, 0, 0.625}, + }, + D1: 2, + D2: 3, + X1: 5, + Y1: 8, + Rd1: 2.3801652892561984, + Rd2: 1.586776859504132, + Rx1: 121.0 / 12, + }, + { + Name: "D1=D2_X1=X2", + P: &blas.DrotmParams{ + Flag: blas.Diagonal, + H: [4]float64{1, 0, 0, 1}, + }, + D1: 2, + D2: 2, + X1: 8, + Y1: 8, + Rd1: 1, + Rd2: 1, + Rx1: 16, + }, + { + Name: "RD1_Big_RD2_Big_Flag_0", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{4096, -3584, 1792, 4096}, + }, + D1: 1600000000, + D2: 800000000, + X1: 8, + Y1: 7, + Rd1: 68.96627824858757, + Rd2: 34.483139124293785, + Rx1: 45312, + }, + { + Name: "RD1_Big_RD2_Big_Flag_1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{2340.5714285714284, -4096, 4096, 4681.142857142857}, + }, + D1: 800000000, + D2: 1600000000, + X1: 8, + Y1: 7, + Rd1: 57.6914092640818, + Rd2: 28.8457046320409, + Rx1: 47396.57142857142, + }, + { + Name: "RD1_Big_RD2_Med_Flag_0", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{4096, -1, 0.0004096, 1}, + }, + D1: 20000000, + D2: 2, + X1: 8, + Y1: 8, + Rd1: 1.1920927762985347, + Rd2: 1.9999998000000199, + Rx1: 32768.0032768, + }, + { + Name: "RD1_Big_RD2_Med_Flag_1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{4.096e-17, -1, 4096, 1e-10}, + }, + D1: 2, + D2: 20000000000, + X1: 8, + Y1: 80000000000, + Rd1: 1192.0928955078125, + Rd2: 2, + Rx1: 3.2768e+14, + }, + + // TODO: Add D1 big, D2 small, Flag = 0 + { + Name: "D1_Big_D2_Small_Flag_1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{2.8671999999999997e-26, -0.000244140625, 4096, 2.44140625e-16}, + }, + D1: 0.000000014, + D2: 2000000000, + X1: 0.000008, + Y1: 8000000, + Rd1: 119.20928955078125, + Rd2: 0.234881024, + Rx1: 3.2768e+10, + }, + + { + Name: "RD1_Med_RD2_Big_Flag_0", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{1, -0.0004096, 1000, 4096}, + }, + D1: 2, + D2: 20000000000, + X1: 80000000, + Y1: 8, + Rd1: 1.9998000199980002, + Rd2: 1191.9736981379988, + Rx1: 8.0008e+07, + }, + { + Name: "D1_Med_D2_Big_Flag_1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{50, -4096, 1, 4.096e-06}, + }, + D1: 20000000000, + D2: 0.4, + X1: 80000000, + Y1: 80000000000000000, + Rd1: 0.39999998000000103, + Rd2: 1192.092835903171, + Rx1: 8.0000004e+16, + }, + { + Name: "RD1_Med_RD2_Small_Flag_0", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{1, -0.0007233796296296296, 1.1111111111111111e-10, 0.000244140625}, + }, + D1: 1.2, + D2: 0.000000000045, + X1: 2.7, + Y1: 8, + Rd1: 1.1999999996049382, + Rd2: 0.0007549747197514486, + Rx1: 2.700000000888889, + }, + { + Name: "RD1_Med_RD2_Small_Flag_1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.0002197265625, -1, 0.000244140625, 3.375e-11}, + }, + D1: 1.2, + D2: 0.000000000045, + X1: 2.7, + Y1: 80000000000, + Rd1: 0.0007549747199770676, + Rd2: 1.19999999996355, + Rx1: 1.9531250000593264e+07, + }, + // TODO: Add Small, Big, 0 case + { + Name: "D1_Small_D2_Big_Flag_1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{2.3731773997569866e+10, -1.6777216e+07, 0.000244140625, 1.6777216e-07}, + }, + D1: 120000000000000000, + D2: 0.000000000012345, + X1: 0.08, + Y1: 8000000000000, + Rd1: 0.00010502490698765249, + Rd2: 216.1836123957717, + Rx1: 3.8516669198055897e+09, + }, + { + Name: "RD1_Small_RD2_Med_Flag_0", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.000244140625, -1e-08, 0.24414062499999997, 1}, + }, + D1: 0.0000000002, + D2: 20, + X1: 0.8, + Y1: 0.000000008, + Rd1: 0.003355409645903541, + Rd2: 19.99980000199998, + Rx1: 0.000195314453125, + }, + { + Name: "RD1_Small_RD2_Med_Flag_1", + P: &blas.DrotmParams{ + Flag: blas.Rescaling, + H: [4]float64{0.0012207031250000002, -1, 0.000244140625, 1e-09}, + }, + D1: 0.02, + D2: 0.000000000004, + X1: 0.008, + Y1: 8000000, + Rd1: 6.710886366445568e-05, + Rd2: 0.019999999900000003, + Rx1: 1953.125009765625, + }, + // TODO: Add Small, Small, 0 case + // TODO: Add Small, Small, 1 case +} + +type Drotmger interface { + Drotmg(d1, d2, x1, y1 float64) (p blas.DrotmParams, rd1, rd2, rx1 float64) +} + +func DrotmgTest(t *testing.T, d Drotmger) { + for _, test := range DrotmgTests { + + p, rd1, rd2, rx1 := d.Drotmg(test.D1, test.D2, test.X1, test.Y1) + + if p.Flag != test.P.Flag { + t.Errorf("drotmg flag mismatch %v: expected %v, found %v", test.Name, test.P.Flag, p.Flag) + } + for i, val := range p.H { + if !dTolEqual(test.P.H[i], val) { + t.Errorf("drotmg H mismatch %v: expected %v, found %v", test.Name, test.P.H, p.H) + break + } + } + if !dTolEqual(rd1, test.Rd1) { + t.Errorf("drotmg rd1 mismatch %v: expected %v, found %v", test.Name, test.Rd1, rd1) + } + if !dTolEqual(rd2, test.Rd2) { + t.Errorf("drotmg rd2 mismatch %v: expected %v, found %v", test.Name, test.Rd2, rd2) + } + if !dTolEqual(rx1, test.Rx1) { + t.Errorf("drotmg rx1 mismatch %v: expected %v, found %v", test.Name, test.Rx1, rx1) + } + } +} + +type Droter interface { + Drot(n int, x []float64, incX int, y []float64, incY int, c, s float64) +} + +func DrotTest(t *testing.T, d Droter) { + drot := d.Drot + for _, c := range DoubleTwoVectorCases { + for _, kind := range c.DrotCases { + dCopyTwoTmp(c.X, c.XTmp, c.Y, c.YTmp) + if c.Panic { + f := func() { drot(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy, kind.C, kind.S) } + testpanics(f, c.Name, t) + continue + } + drot(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy, kind.C, kind.S) + if !dSliceTolEqual(c.XTmp, kind.XAns) { + t.Errorf("drot: x mismatch %v: expected %v, found %v", c.Name, kind.XAns, c.XTmp) + } + if !dSliceTolEqual(c.YTmp, kind.YAns) { + t.Errorf("drot: y mismatch %v: expected %v, found %v", c.Name, kind.YAns, c.YTmp) + } + } + } +} + +type Drotmer interface { + Drotm(n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams) +} + +func DrotmTest(t *testing.T, d Drotmer) { + drotm := d.Drotm + for _, c := range DoubleTwoVectorCases { + for _, kind := range c.DrotmCases { + dCopyTwoTmp(c.X, c.XTmp, c.Y, c.YTmp) + if c.Panic { + f := func() { drotm(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy, kind.P) } + testpanics(f, c.Name+", "+kind.Name, t) + continue + } + drotm(c.N, c.XTmp, c.Incx, c.YTmp, c.Incy, kind.P) + if !dSliceTolEqual(c.XTmp, kind.XAns) { + t.Errorf("drotm: mismatch %v: expected %v, found %v", c.Name, kind.XAns, c.XTmp) + } + if !dSliceTolEqual(c.YTmp, kind.YAns) { + t.Errorf("drotm: mismatch %v: expected %v, found %v", c.Name, kind.YAns, c.YTmp) + } + } + } +} + +type Dscaler interface { + Dscal(n int, alpha float64, x []float64, incX int) +} + +func DscalTest(t *testing.T, blasser Dscaler) { + dscal := blasser.Dscal + for _, c := range DoubleOneVectorCases { + for _, kind := range c.DscalCases { + xTmp := make([]float64, len(c.X)) + copy(xTmp, c.X) + if c.Panic { + f := func() { dscal(c.N, kind.Alpha, xTmp, c.Incx) } + testpanics(f, c.Name, t) + continue + } + dscal(c.N, kind.Alpha, xTmp, c.Incx) + if !dSliceTolEqual(xTmp, kind.Ans) { + t.Errorf("dscal: mismatch %v, %v: expected %v, found %v", c.Name, kind.Name, kind.Ans, xTmp) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/level2bench.go b/vendor/gonum.org/v1/gonum/blas/testblas/level2bench.go new file mode 100644 index 00000000..387ffcce --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/level2bench.go @@ -0,0 +1,60 @@ +package testblas + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +func DgemvBenchmark(b *testing.B, blasser Dgemver, tA blas.Transpose, m, n, incX, incY int) { + var lenX, lenY int + if tA == blas.NoTrans { + lenX = n + lenY = m + } else { + lenX = m + lenY = n + } + xr := make([]float64, lenX) + for i := range xr { + xr[i] = rand.Float64() + } + x := makeIncremented(xr, incX, 0) + yr := make([]float64, lenY) + for i := range yr { + yr[i] = rand.Float64() + } + y := makeIncremented(yr, incY, 0) + a := make([]float64, m*n) + for i := range a { + a[i] = rand.Float64() + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + blasser.Dgemv(tA, m, n, 2, a, n, x, incX, 3, y, incY) + } +} + +func DgerBenchmark(b *testing.B, blasser Dgerer, m, n, incX, incY int) { + xr := make([]float64, m) + for i := range xr { + xr[i] = rand.Float64() + } + x := makeIncremented(xr, incX, 0) + yr := make([]float64, n) + for i := range yr { + yr[i] = rand.Float64() + } + y := makeIncremented(yr, incY, 0) + a := make([]float64, m*n) + for i := range a { + a[i] = rand.Float64() + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + blasser.Dger(m, n, 2, x, incX, y, incY, a, n) + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zaxpy.go b/vendor/gonum.org/v1/gonum/blas/testblas/zaxpy.go new file mode 100644 index 00000000..9aeace52 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zaxpy.go @@ -0,0 +1,157 @@ +// 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 testblas + +import ( + "fmt" + "testing" +) + +type Zaxpyer interface { + Zaxpy(n int, alpha complex128, x []complex128, incX int, y []complex128, incY int) +} + +func ZaxpyTest(t *testing.T, impl Zaxpyer) { + for tc, test := range []struct { + alpha complex128 + x, y []complex128 + + want []complex128 // Result when both increments have the same sign. + wantRev []complex128 // Result when the increments have opposite sign. + }{ + { + alpha: 0, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i, 63 + 64i}, + want: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i, 63 + 64i}, + wantRev: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i, 63 + 64i}, + }, + { + alpha: 1, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i, 63 + 64i}, + want: []complex128{31 + 33i, 36 + 38i, 41 + 43i, 46 + 48i, 51 + 53i, 56 + 58i, 61 + 63i, 66 + 68i, 71 + 73i, 76 + 78i, 81 + 83i, 86 + 88i}, + wantRev: []complex128{53 + 55i, 54 + 56i, 55 + 57i, 56 + 58i, 57 + 59i, 58 + 60i, 59 + 61i, 60 + 62i, 61 + 63i, 62 + 64i, 63 + 65i, 64 + 66i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i}, + y: []complex128{30 + 31i}, + want: []complex128{19 + 44i}, + wantRev: []complex128{19 + 44i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i}, + y: []complex128{30 + 31i, 33 + 34i}, + want: []complex128{19 + 44i, 14 + 67i}, + wantRev: []complex128{11 + 64i, 22 + 47i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i}, + wantRev: []complex128{3 + 84i, 14 + 67i, 25 + 50i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i}, + wantRev: []complex128{-5 + 104i, 6 + 87i, 17 + 70i, 28 + 53i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i}, + wantRev: []complex128{-13 + 124i, -2 + 107i, 9 + 90i, 20 + 73i, 31 + 56i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i, -6 + 159i}, + wantRev: []complex128{-21 + 144i, -10 + 127i, 1 + 110i, 12 + 93i, 23 + 76i, 34 + 59i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i, -6 + 159i, -11 + 182i}, + wantRev: []complex128{-29 + 164i, -18 + 147i, -7 + 130i, 4 + 113i, 15 + 96i, 26 + 79i, 37 + 62i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i, -6 + 159i, -11 + 182i, -16 + 205i}, + wantRev: []complex128{-37 + 184i, -26 + 167i, -15 + 150i, -4 + 133i, 7 + 116i, 18 + 99i, 29 + 82i, 40 + 65i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i, -6 + 159i, -11 + 182i, -16 + 205i, -21 + 228i}, + wantRev: []complex128{-45 + 204i, -34 + 187i, -23 + 170i, -12 + 153i, -1 + 136i, 10 + 119i, 21 + 102i, 32 + 85i, 43 + 68i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i, -6 + 159i, -11 + 182i, -16 + 205i, -21 + 228i, -26 + 251i}, + wantRev: []complex128{-53 + 224i, -42 + 207i, -31 + 190i, -20 + 173i, -9 + 156i, 2 + 139i, 13 + 122i, 24 + 105i, 35 + 88i, 46 + 71i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i, -6 + 159i, -11 + 182i, -16 + 205i, -21 + 228i, -26 + 251i, -31 + 274i}, + wantRev: []complex128{-61 + 244i, -50 + 227i, -39 + 210i, -28 + 193i, -17 + 176i, -6 + 159i, 5 + 142i, 16 + 125i, 27 + 108i, 38 + 91i, 49 + 74i}, + }, + { + alpha: 3 + 7i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i, 63 + 64i}, + want: []complex128{19 + 44i, 14 + 67i, 9 + 90i, 4 + 113i, -1 + 136i, -6 + 159i, -11 + 182i, -16 + 205i, -21 + 228i, -26 + 251i, -31 + 274i, -36 + 297i}, + wantRev: []complex128{-69 + 264i, -58 + 247i, -47 + 230i, -36 + 213i, -25 + 196i, -14 + 179i, -3 + 162i, 8 + 145i, 19 + 128i, 30 + 111i, 41 + 94i, 52 + 77i}, + }, + } { + n := len(test.x) + if len(test.y) != n || len(test.want) != n || len(test.wantRev) != n { + panic("bad test") + } + for _, inc := range allPairs([]int{-7, -3, 1, 13}, []int{-11, -5, 1, 17}) { + incX := inc[0] + incY := inc[1] + + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + y := makeZVector(test.y, incY) + + var want []complex128 + if incX*incY > 0 { + want = makeZVector(test.want, incY) + } else { + want = makeZVector(test.wantRev, incY) + } + + impl.Zaxpy(n, test.alpha, x, incX, y, incY) + + prefix := fmt.Sprintf("Case %v (incX=%v,incY=%v):", tc, incX, incY) + + if !zsame(x, xCopy) { + t.Errorf("%v: unexpected modification of x", prefix) + } + + if !zsame(y, want) { + t.Errorf("%v: unexpected y:\nwant %v\ngot %v", prefix, want, y) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zcopy.go b/vendor/gonum.org/v1/gonum/blas/testblas/zcopy.go new file mode 100644 index 00000000..9aba717d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zcopy.go @@ -0,0 +1,71 @@ +// 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 testblas + +import ( + "fmt" + "math" + "math/rand" + "testing" +) + +type Zcopyer interface { + Zcopy(n int, x []complex128, incX int, y []complex128, incY int) +} + +func ZcopyTest(t *testing.T, impl Zcopyer) { + rnd := rand.New(rand.NewSource(1)) + for n := 0; n <= 20; n++ { + for _, inc := range allPairs([]int{-7, -3, 1, 13}, []int{-11, -5, 1, 17}) { + incX := inc[0] + incY := inc[1] + aincX := abs(incX) + aincY := abs(incY) + + var x []complex128 + if n > 0 { + x = make([]complex128, (n-1)*aincX+1) + } + for i := range x { + x[i] = complex(math.NaN(), math.NaN()) + } + for i := 0; i < n; i++ { + x[i*aincX] = complex(rnd.NormFloat64(), rnd.NormFloat64()) + } + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + var y []complex128 + if n > 0 { + y = make([]complex128, (n-1)*aincY+1) + } + for i := range y { + y[i] = complex(math.NaN(), math.NaN()) + } + + want := make([]complex128, len(y)) + if incX*incY > 0 { + for i := 0; i < n; i++ { + want[i*aincY] = x[i*aincX] + } + } else { + for i := 0; i < n; i++ { + want[i*aincY] = x[(n-1-i)*aincX] + } + } + + impl.Zcopy(n, x, incX, y, incY) + + prefix := fmt.Sprintf("Case n=%v,incX=%v,incY=%v:", n, incX, incY) + + if !zsame(x, xCopy) { + t.Errorf("%v: unexpected modification of x", prefix) + } + if !zsame(y, want) { + t.Errorf("%v: unexpected y:\nwant %v\ngot %v", prefix, want, y) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zdotc.go b/vendor/gonum.org/v1/gonum/blas/testblas/zdotc.go new file mode 100644 index 00000000..a28b0c1a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zdotc.go @@ -0,0 +1,139 @@ +// 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 testblas + +import ( + "fmt" + "testing" +) + +type Zdotcer interface { + Zdotc(n int, x []complex128, incX int, y []complex128, incY int) complex128 +} + +func ZdotcTest(t *testing.T, impl Zdotcer) { + for tc, test := range []struct { + x, y []complex128 + + want complex128 // Result when both increments have the same sign. + wantRev complex128 // Result when the increments have opposite sign. + }{ + { + x: nil, + y: nil, + want: 0, + wantRev: 0, + }, + { + x: []complex128{1 + 2i}, + y: []complex128{30 + 31i}, + want: 92 - 29i, + wantRev: 92 - 29i, + }, + { + x: []complex128{1 + 2i, 3 + 4i}, + y: []complex128{30 + 31i, 33 + 34i}, + want: 327 - 59i, + wantRev: 315 - 59i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i}, + want: 729 - 90i, + wantRev: 681 - 90i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i}, + want: 1322 - 122i, + wantRev: 1202 - 122i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i}, + want: 2130 - 155i, + wantRev: 1890 - 155i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i}, + want: 3177 - 189i, + wantRev: 2757 - 189i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i}, + want: 4487 - 224i, + wantRev: 3815 - 224i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i}, + want: 6084 - 260i, + wantRev: 5076 - 260i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i}, + want: 7992 - 297i, + wantRev: 6552 - 297i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i}, + want: 10235 - 335i, + wantRev: 8255 - 335i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i}, + want: 12837 - 374i, + wantRev: 10197 - 374i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i, 63 + 64i}, + want: 15822 - 414i, + wantRev: 12390 - 414i, + }, + } { + n := len(test.x) + if len(test.y) != n { + panic("bad test") + } + for _, inc := range allPairs([]int{-7, -3, 1, 13}, []int{-11, -5, 1, 17}) { + incX := inc[0] + incY := inc[1] + + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + y := makeZVector(test.y, incY) + yCopy := make([]complex128, len(y)) + copy(yCopy, y) + + want := test.want + if incX*incY < 0 { + want = test.wantRev + } + + got := impl.Zdotc(n, x, incX, y, incY) + + prefix := fmt.Sprintf("Case %v (incX=%v,incY=%v):", tc, incX, incY) + + if !zsame(x, xCopy) { + t.Errorf("%v: unexpected modification of x", prefix) + } + if !zsame(y, yCopy) { + t.Errorf("%v: unexpected modification of y", prefix) + } + + if got != want { + t.Errorf("%v: unexpected result. want %v, got %v", prefix, want, got) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zdotu.go b/vendor/gonum.org/v1/gonum/blas/testblas/zdotu.go new file mode 100644 index 00000000..7b83b735 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zdotu.go @@ -0,0 +1,139 @@ +// 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 testblas + +import ( + "fmt" + "testing" +) + +type Zdotuer interface { + Zdotu(n int, x []complex128, incX int, y []complex128, incY int) complex128 +} + +func ZdotuTest(t *testing.T, impl Zdotuer) { + for tc, test := range []struct { + x, y []complex128 + + want complex128 // Result when both increments have the same sign. + wantRev complex128 // Result when the increments have opposite sign. + }{ + { + x: nil, + y: nil, + want: 0, + wantRev: 0, + }, + { + x: []complex128{1 + 2i}, + y: []complex128{30 + 31i}, + want: -32 + 91i, + wantRev: -32 + 91i, + }, + { + x: []complex128{1 + 2i, 3 + 4i}, + y: []complex128{30 + 31i, 33 + 34i}, + want: -69 + 325i, + wantRev: -69 + 313i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i}, + want: -111 + 726i, + wantRev: -111 + 678i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i}, + want: -158 + 1318i, + wantRev: -158 + 1198i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i}, + want: -210 + 2125i, + wantRev: -210 + 1885i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i}, + want: -267 + 3171i, + wantRev: -267 + 2751i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i}, + want: -329 + 4480i, + wantRev: -329 + 3808i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i}, + want: -396 + 6076i, + wantRev: -396 + 5068i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i}, + want: -468 + 7983i, + wantRev: -468 + 6543i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i}, + want: -545 + 10225i, + wantRev: -545 + 8245i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i}, + want: -627 + 12826i, + wantRev: -627 + 10186i, + }, + { + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + y: []complex128{30 + 31i, 33 + 34i, 36 + 37i, 39 + 40i, 42 + 43i, 45 + 46i, 48 + 49i, 51 + 52i, 54 + 55i, 57 + 58i, 60 + 61i, 63 + 64i}, + want: -714 + 15810i, + wantRev: -714 + 12378i, + }, + } { + n := len(test.x) + if len(test.y) != n { + panic("bad test") + } + for _, inc := range allPairs([]int{-7, -3, 1, 13}, []int{-11, -5, 1, 17}) { + incX := inc[0] + incY := inc[1] + + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + y := makeZVector(test.y, incY) + yCopy := make([]complex128, len(y)) + copy(yCopy, y) + + want := test.want + if incX*incY < 0 { + want = test.wantRev + } + + got := impl.Zdotu(n, x, incX, y, incY) + + prefix := fmt.Sprintf("Case %v (incX=%v,incY=%v):", tc, incX, incY) + + if !zsame(x, xCopy) { + t.Errorf("%v: unexpected modification of x", prefix) + } + if !zsame(y, yCopy) { + t.Errorf("%v: unexpected modification of y", prefix) + } + + if got != want { + t.Errorf("%v: unexpected result. want %v, got %v", prefix, want, got) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zdscal.go b/vendor/gonum.org/v1/gonum/blas/testblas/zdscal.go new file mode 100644 index 00000000..9037d841 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zdscal.go @@ -0,0 +1,119 @@ +// 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 testblas + +import ( + "fmt" + "testing" +) + +type Zdscaler interface { + Zdscal(n int, alpha float64, x []complex128, incX int) +} + +func ZdscalTest(t *testing.T, impl Zdscaler) { + for tc, test := range []struct { + alpha float64 + x []complex128 + want []complex128 + }{ + { + alpha: 3, + x: nil, + want: nil, + }, + { + alpha: 3, + x: []complex128{1 + 2i}, + want: []complex128{3 + 6i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i}, + want: []complex128{3 + 6i, 9 + 12i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i, 33 + 36i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i, 33 + 36i, 39 + 42i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i, 33 + 36i, 39 + 42i, 45 + 48i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i, 33 + 36i, 39 + 42i, 45 + 48i, 51 + 54i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i, 33 + 36i, 39 + 42i, 45 + 48i, 51 + 54i, 57 + 60i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i, 33 + 36i, 39 + 42i, 45 + 48i, 51 + 54i, 57 + 60i, 63 + 66i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + want: []complex128{3 + 6i, 9 + 12i, 15 + 18i, 21 + 24i, 27 + 30i, 33 + 36i, 39 + 42i, 45 + 48i, 51 + 54i, 57 + 60i, 63 + 66i, 69 + 72i}, + }, + { + alpha: 0, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + want: []complex128{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + } { + n := len(test.x) + if len(test.want) != n { + panic("bad test") + } + for _, incX := range []int{-3, -1, 1, 2, 4, 7, 10} { + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + want := makeZVector(test.want, incX) + + impl.Zdscal(n, test.alpha, x, incX) + + prefix := fmt.Sprintf("Case %v (n=%v,incX=%v):", tc, n, incX) + + if incX < 0 { + if !zsame(x, xCopy) { + t.Errorf("%v: unexpected modification of x\nwant %v\ngot %v", prefix, want, x) + } + continue + } + if !zsame(x, want) { + t.Errorf("%v: unexpected result:\nwant: %v\ngot: %v", prefix, want, x) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zgerc.go b/vendor/gonum.org/v1/gonum/blas/testblas/zgerc.go new file mode 100644 index 00000000..15a83745 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zgerc.go @@ -0,0 +1,183 @@ +// 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 testblas + +import ( + "testing" +) + +type Zgercer interface { + Zgerc(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) +} + +func ZgercTest(t *testing.T, impl Zgercer) { + for tc, test := range []struct { + alpha complex128 + x []complex128 + incX int + y []complex128 + incY int + a []complex128 + + want []complex128 + }{ + { + incX: 1, + incY: 1, + alpha: 1 + 2i, + }, + { + incX: 1, + incY: 1, + alpha: 1 + 2i, + x: []complex128{1 + 13i, 18 + 15i, 10 + 18i}, + y: []complex128{15 + 12i, 4 + 8i, 5 + 16i, 19 + 12i}, + a: []complex128{ + 10 + 9i, 6 + 17i, 3 + 10i, 6 + 7i, + 3 + 4i, 11 + 16i, 5 + 14i, 11 + 18i, + 18 + 6i, 4 + 1i, 13 + 2i, 14 + 3i}, + want: []complex128{ + -185 + 534i, 26 + 277i, 118 + 485i, -289 + 592i, + 435 + 913i, 371 + 316i, 761 + 461i, 395 + 1131i, + 84 + 888i, 204 + 361i, 491 + 608i, -24 + 1037i}, + }, + { + incX: 7, + incY: 13, + alpha: 1 + 2i, + x: []complex128{1 + 13i, 18 + 15i, 10 + 18i}, + y: []complex128{15 + 12i, 4 + 8i, 5 + 16i, 19 + 12i}, + a: []complex128{ + 10 + 9i, 6 + 17i, 3 + 10i, 6 + 7i, + 3 + 4i, 11 + 16i, 5 + 14i, 11 + 18i, + 18 + 6i, 4 + 1i, 13 + 2i, 14 + 3i}, + want: []complex128{ + -185 + 534i, 26 + 277i, 118 + 485i, -289 + 592i, + 435 + 913i, 371 + 316i, 761 + 461i, 395 + 1131i, + 84 + 888i, 204 + 361i, 491 + 608i, -24 + 1037i}, + }, + { + incX: -7, + incY: -13, + alpha: 1 + 2i, + x: []complex128{10 + 18i, 18 + 15i, 1 + 13i}, + y: []complex128{19 + 12i, 5 + 16i, 4 + 8i, 15 + 12i}, + a: []complex128{ + 10 + 9i, 6 + 17i, 3 + 10i, 6 + 7i, + 3 + 4i, 11 + 16i, 5 + 14i, 11 + 18i, + 18 + 6i, 4 + 1i, 13 + 2i, 14 + 3i}, + want: []complex128{ + -185 + 534i, 26 + 277i, 118 + 485i, -289 + 592i, + 435 + 913i, 371 + 316i, 761 + 461i, 395 + 1131i, + 84 + 888i, 204 + 361i, 491 + 608i, -24 + 1037i}, + }, + { + incX: 1, + incY: 1, + alpha: 1 + 2i, + x: []complex128{5 + 16i, 12 + 19i, 9 + 7i, 2 + 4i}, + y: []complex128{18 + 7i, 20 + 15i, 12 + 14i}, + a: []complex128{ + 11 + 4i, 17 + 18i, 7 + 13i, + 14 + 20i, 14 + 10i, 7 + 5i, + 7 + 17i, 10 + 6i, 11 + 13i, + 7 + 6i, 19 + 16i, 8 + 8i, + }, + want: []complex128{ + -293 + 661i, -133 + 943i, 47 + 703i, + -153 + 976i, 139 + 1260i, 297 + 885i, + 92 + 502i, 285 + 581i, 301 + 383i, + -45 + 192i, 19 + 266i, 48 + 188i, + }, + }, + { + incX: 7, + incY: 13, + alpha: 1 + 2i, + x: []complex128{5 + 16i, 12 + 19i, 9 + 7i, 2 + 4i}, + y: []complex128{18 + 7i, 20 + 15i, 12 + 14i}, + a: []complex128{ + 11 + 4i, 17 + 18i, 7 + 13i, + 14 + 20i, 14 + 10i, 7 + 5i, + 7 + 17i, 10 + 6i, 11 + 13i, + 7 + 6i, 19 + 16i, 8 + 8i, + }, + want: []complex128{ + -293 + 661i, -133 + 943i, 47 + 703i, + -153 + 976i, 139 + 1260i, 297 + 885i, + 92 + 502i, 285 + 581i, 301 + 383i, + -45 + 192i, 19 + 266i, 48 + 188i, + }, + }, + { + incX: -7, + incY: -13, + alpha: 1 + 2i, + x: []complex128{2 + 4i, 9 + 7i, 12 + 19i, 5 + 16i}, + y: []complex128{12 + 14i, 20 + 15i, 18 + 7i}, + a: []complex128{ + 11 + 4i, 17 + 18i, 7 + 13i, + 14 + 20i, 14 + 10i, 7 + 5i, + 7 + 17i, 10 + 6i, 11 + 13i, + 7 + 6i, 19 + 16i, 8 + 8i, + }, + want: []complex128{ + -293 + 661i, -133 + 943i, 47 + 703i, + -153 + 976i, 139 + 1260i, 297 + 885i, + 92 + 502i, 285 + 581i, 301 + 383i, + -45 + 192i, 19 + 266i, 48 + 188i, + }, + }, + { + incX: -7, + incY: -13, + alpha: 0, + x: []complex128{2 + 4i, 9 + 7i, 12 + 19i, 5 + 16i}, + y: []complex128{12 + 14i, 20 + 15i, 18 + 7i}, + a: []complex128{ + 11 + 4i, 17 + 18i, 7 + 13i, + 14 + 20i, 14 + 10i, 7 + 5i, + 7 + 17i, 10 + 6i, 11 + 13i, + 7 + 6i, 19 + 16i, 8 + 8i, + }, + want: []complex128{ + 11 + 4i, 17 + 18i, 7 + 13i, + 14 + 20i, 14 + 10i, 7 + 5i, + 7 + 17i, 10 + 6i, 11 + 13i, + 7 + 6i, 19 + 16i, 8 + 8i, + }, + }, + } { + m := len(test.x) + n := len(test.y) + incX := test.incX + incY := test.incY + + for _, lda := range []int{max(1, n), n + 20} { + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + y := makeZVector(test.y, incY) + yCopy := make([]complex128, len(y)) + copy(yCopy, y) + + a := makeZGeneral(test.a, m, n, lda) + want := makeZGeneral(test.want, m, n, lda) + + impl.Zgerc(m, n, test.alpha, x, incX, y, incY, a, lda) + + if !zsame(x, xCopy) { + t.Errorf("Case %v: unexpected modification of x", tc) + } + if !zsame(y, yCopy) { + t.Errorf("Case %v: unexpected modification of y", tc) + } + if !zsame(want, a) { + t.Errorf("Case %v: unexpected result\nwant %v\ngot %v", tc, want, a) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zgeru.go b/vendor/gonum.org/v1/gonum/blas/testblas/zgeru.go new file mode 100644 index 00000000..09c66e71 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zgeru.go @@ -0,0 +1,257 @@ +// 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 testblas + +import ( + "testing" +) + +type Zgeruer interface { + Zgeru(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) +} + +func ZgeruTest(t *testing.T, impl Zgeruer) { + for tc, test := range []struct { + alpha complex128 + x []complex128 + incX int + y []complex128 + incY int + a []complex128 + + want []complex128 + }{ + { + incX: 1, + incY: 1, + alpha: 1 + 2i, + }, + { + incX: 1, + incY: 1, + alpha: 1 + 2i, + x: []complex128{1 + 13i, 18 + 15i, 10 + 18i}, + y: []complex128{15 + 12i, 4 + 8i, 5 + 16i, 19 + 12i}, + a: []complex128{ + 4 + 7i, 4 + 7i, 12 + 3i, 9 + 10i, + 3 + 3i, 1 + 2i, 17 + 17i, 9 + 18i, + 14 + 12i, 9 + 16i, 1 + 1i, 9 + 1i, + }, + want: []complex128{ + -551 - 68i, -216 - 133i, -353 - 322i, -646 - 5i, + -789 + 624i, -455 + 110i, -859 + 80i, -831 + 843i, + -832 + 270i, -399 - 40i, -737 - 225i, -941 + 411i, + }, + }, + { + incX: 7, + incY: 13, + alpha: 1 + 2i, + x: []complex128{1 + 13i, 18 + 15i, 10 + 18i}, + y: []complex128{15 + 12i, 4 + 8i, 5 + 16i, 19 + 12i}, + a: []complex128{ + 4 + 7i, 4 + 7i, 12 + 3i, 9 + 10i, + 3 + 3i, 1 + 2i, 17 + 17i, 9 + 18i, + 14 + 12i, 9 + 16i, 1 + 1i, 9 + 1i, + }, + want: []complex128{ + -551 - 68i, -216 - 133i, -353 - 322i, -646 - 5i, + -789 + 624i, -455 + 110i, -859 + 80i, -831 + 843i, + -832 + 270i, -399 - 40i, -737 - 225i, -941 + 411i, + }, + }, + { + incX: 1, + incY: 13, + alpha: 1 + 2i, + x: []complex128{1 + 13i, 18 + 15i, 10 + 18i}, + y: []complex128{15 + 12i, 4 + 8i, 5 + 16i, 19 + 12i}, + a: []complex128{ + 4 + 7i, 4 + 7i, 12 + 3i, 9 + 10i, + 3 + 3i, 1 + 2i, 17 + 17i, 9 + 18i, + 14 + 12i, 9 + 16i, 1 + 1i, 9 + 1i, + }, + want: []complex128{ + -551 - 68i, -216 - 133i, -353 - 322i, -646 - 5i, + -789 + 624i, -455 + 110i, -859 + 80i, -831 + 843i, + -832 + 270i, -399 - 40i, -737 - 225i, -941 + 411i, + }, + }, + { + incX: 1, + incY: -13, + alpha: 1 + 2i, + x: []complex128{1 + 13i, 18 + 15i, 10 + 18i}, + y: []complex128{19 + 12i, 5 + 16i, 4 + 8i, 15 + 12i}, + a: []complex128{ + 4 + 7i, 4 + 7i, 12 + 3i, 9 + 10i, + 3 + 3i, 1 + 2i, 17 + 17i, 9 + 18i, + 14 + 12i, 9 + 16i, 1 + 1i, 9 + 1i, + }, + want: []complex128{ + -551 - 68i, -216 - 133i, -353 - 322i, -646 - 5i, + -789 + 624i, -455 + 110i, -859 + 80i, -831 + 843i, + -832 + 270i, -399 - 40i, -737 - 225i, -941 + 411i, + }, + }, + { + incX: 7, + incY: 1, + alpha: 1 + 2i, + x: []complex128{1 + 13i, 18 + 15i, 10 + 18i}, + y: []complex128{15 + 12i, 4 + 8i, 5 + 16i, 19 + 12i}, + a: []complex128{ + 4 + 7i, 4 + 7i, 12 + 3i, 9 + 10i, + 3 + 3i, 1 + 2i, 17 + 17i, 9 + 18i, + 14 + 12i, 9 + 16i, 1 + 1i, 9 + 1i, + }, + want: []complex128{ + -551 - 68i, -216 - 133i, -353 - 322i, -646 - 5i, + -789 + 624i, -455 + 110i, -859 + 80i, -831 + 843i, + -832 + 270i, -399 - 40i, -737 - 225i, -941 + 411i, + }, + }, + { + incX: -7, + incY: 1, + alpha: 1 + 2i, + x: []complex128{10 + 18i, 18 + 15i, 1 + 13i}, + y: []complex128{15 + 12i, 4 + 8i, 5 + 16i, 19 + 12i}, + a: []complex128{ + 4 + 7i, 4 + 7i, 12 + 3i, 9 + 10i, + 3 + 3i, 1 + 2i, 17 + 17i, 9 + 18i, + 14 + 12i, 9 + 16i, 1 + 1i, 9 + 1i, + }, + want: []complex128{ + -551 - 68i, -216 - 133i, -353 - 322i, -646 - 5i, + -789 + 624i, -455 + 110i, -859 + 80i, -831 + 843i, + -832 + 270i, -399 - 40i, -737 - 225i, -941 + 411i, + }, + }, + { + incX: -7, + incY: -13, + alpha: 1 + 2i, + x: []complex128{10 + 18i, 18 + 15i, 1 + 13i}, + y: []complex128{19 + 12i, 5 + 16i, 4 + 8i, 15 + 12i}, + a: []complex128{ + 4 + 7i, 4 + 7i, 12 + 3i, 9 + 10i, + 3 + 3i, 1 + 2i, 17 + 17i, 9 + 18i, + 14 + 12i, 9 + 16i, 1 + 1i, 9 + 1i, + }, + want: []complex128{ + -551 - 68i, -216 - 133i, -353 - 322i, -646 - 5i, + -789 + 624i, -455 + 110i, -859 + 80i, -831 + 843i, + -832 + 270i, -399 - 40i, -737 - 225i, -941 + 411i, + }, + }, + { + incX: 1, + incY: 1, + alpha: 1 + 2i, + x: []complex128{5 + 16i, 12 + 19i, 9 + 7i, 2 + 4i}, + y: []complex128{18 + 7i, 20 + 15i, 12 + 14i}, + a: []complex128{ + 8 + 17i, 2 + 2i, 8 + 17i, + 1 + 10i, 10 + 15i, 4 + 18i, + 11 + 3i, 15 + 7i, 12 + 15i, + 20 + 10i, 8 + 13i, 19 + 10i, + }, + want: []complex128{ + -660 + 296i, -928 + 117i, -680 - 49i, + -768 + 602i, -1155 + 485i, -910 + 170i, + -254 + 418i, -460 + 432i, -398 + 245i, + -144 + 112i, -232 + 83i, -165 + 22i, + }, + }, + { + incX: 7, + incY: 13, + alpha: 1 + 2i, + x: []complex128{5 + 16i, 12 + 19i, 9 + 7i, 2 + 4i}, + y: []complex128{18 + 7i, 20 + 15i, 12 + 14i}, + a: []complex128{ + 8 + 17i, 2 + 2i, 8 + 17i, + 1 + 10i, 10 + 15i, 4 + 18i, + 11 + 3i, 15 + 7i, 12 + 15i, + 20 + 10i, 8 + 13i, 19 + 10i, + }, + want: []complex128{ + -660 + 296i, -928 + 117i, -680 - 49i, + -768 + 602i, -1155 + 485i, -910 + 170i, + -254 + 418i, -460 + 432i, -398 + 245i, + -144 + 112i, -232 + 83i, -165 + 22i, + }, + }, + { + incX: -7, + incY: -13, + alpha: 1 + 2i, + x: []complex128{2 + 4i, 9 + 7i, 12 + 19i, 5 + 16i}, + y: []complex128{12 + 14i, 20 + 15i, 18 + 7i}, + a: []complex128{ + 8 + 17i, 2 + 2i, 8 + 17i, + 1 + 10i, 10 + 15i, 4 + 18i, + 11 + 3i, 15 + 7i, 12 + 15i, + 20 + 10i, 8 + 13i, 19 + 10i, + }, + want: []complex128{ + -660 + 296i, -928 + 117i, -680 - 49i, + -768 + 602i, -1155 + 485i, -910 + 170i, + -254 + 418i, -460 + 432i, -398 + 245i, + -144 + 112i, -232 + 83i, -165 + 22i, + }, + }, + { + incX: -7, + incY: -13, + alpha: 0, + x: []complex128{5 + 16i, 12 + 19i, 9 + 7i, 2 + 4i}, + y: []complex128{18 + 7i, 20 + 15i, 12 + 14i}, + a: []complex128{ + 8 + 17i, 2 + 2i, 8 + 17i, + 1 + 10i, 10 + 15i, 4 + 18i, + 11 + 3i, 15 + 7i, 12 + 15i, + 20 + 10i, 8 + 13i, 19 + 10i, + }, + want: []complex128{ + 8 + 17i, 2 + 2i, 8 + 17i, + 1 + 10i, 10 + 15i, 4 + 18i, + 11 + 3i, 15 + 7i, 12 + 15i, + 20 + 10i, 8 + 13i, 19 + 10i, + }, + }, + } { + m := len(test.x) + n := len(test.y) + incX := test.incX + incY := test.incY + + for _, lda := range []int{max(1, n), n + 20} { + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + y := makeZVector(test.y, incY) + yCopy := make([]complex128, len(y)) + copy(yCopy, y) + + a := makeZGeneral(test.a, m, n, lda) + want := makeZGeneral(test.want, m, n, lda) + + impl.Zgeru(m, n, test.alpha, x, incX, y, incY, a, lda) + + if !zsame(x, xCopy) { + t.Errorf("Case %v: unexpected modification of x", tc) + } + if !zsame(y, yCopy) { + t.Errorf("Case %v: unexpected modification of y", tc) + } + if !zsame(want, a) { + t.Errorf("Case %v: unexpected result\nwant %v\ngot %v", tc, want, a) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zher.go b/vendor/gonum.org/v1/gonum/blas/testblas/zher.go new file mode 100644 index 00000000..fbd14b65 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zher.go @@ -0,0 +1,155 @@ +// 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 testblas + +import ( + "math" + "math/cmplx" + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Zherer interface { + Zher(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, a []complex128, lda int) +} + +func ZherTest(t *testing.T, impl Zherer) { + for tc, test := range []struct { + alpha float64 + x []complex128 + a []complex128 + + want []complex128 + wantRev []complex128 // Result when incX is negative. + }{ + { + alpha: 1, + }, + { + alpha: 3, + x: []complex128{ + 0 - 3i, + 6 + 10i, + -2 - 7i, + }, + a: []complex128{ + -2 + 0i, -3 - 11i, 0 + 4i, + -3 + 11i, -6 + 0i, 7 + 2i, + 0 - 4i, 7 - 2i, 18 + 0i, + }, + want: []complex128{ + 25 + 0i, -93 - 65i, 63 + 22i, + -93 + 65i, 402 + 0i, -239 + 68i, + 63 - 22i, -239 - 68i, 177 + 0i}, + wantRev: []complex128{ + 157 + 0i, -249 - 77i, 63 - 14i, + -249 + 77i, 402 + 0i, -83 + 56i, + 63 + 14i, -83 - 56i, 45 + 0i, + }, + }, + { + alpha: 3, + x: []complex128{ + -6 + 2i, + -2 - 4i, + 0 + 0i, + 0 + 7i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 122 + 0i, 3 - 77i, 3 + 11i, 52 + 125i, + 3 + 77i, 76 + 0i, -5 + 2i, -91 + 37i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 52 - 125i, -91 - 37i, 2 + 1i, 165 + 0i, + }, + wantRev: []complex128{ + 149 + 0i, -9 + 7i, -81 - 31i, 52 - 127i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + -81 + 31i, -5 - 2i, 74 + 0i, 14 + 83i, + 52 + 127i, -7 + 5i, 14 - 83i, 138 + 0i, + }, + }, + { + alpha: 0, + x: []complex128{ + -6 + 2i, + -2 - 4i, + 0 + 0i, + 0 + 7i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + wantRev: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + }, + } { + n := len(test.x) + for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} { + for _, incX := range []int{-11, -2, -1, 1, 2, 7} { + for _, lda := range []int{max(1, n), n + 11} { + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + a := makeZGeneral(test.a, n, n, lda) + + var want []complex128 + if incX > 0 { + want = makeZGeneral(test.want, n, n, lda) + } else { + want = makeZGeneral(test.wantRev, n, n, lda) + } + + if uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + a[i*lda+j] = cmplx.NaN() + want[i*lda+j] = cmplx.NaN() + } + a[i*lda+i] = complex(real(a[i*lda+i]), math.NaN()) + } + } else { + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + a[i*lda+j] = cmplx.NaN() + want[i*lda+j] = cmplx.NaN() + } + a[i*lda+i] = complex(real(a[i*lda+i]), math.NaN()) + } + } + + impl.Zher(uplo, n, test.alpha, x, incX, a, lda) + + if !zsame(x, xCopy) { + t.Errorf("Case %v (uplo=%v,incX=%v,lda=%v: unexpected modification of x", tc, uplo, incX, lda) + } + if !zsame(want, a) { + t.Errorf("Case %v (uplo=%v,incX=%v,lda=%v: unexpected result\nwant: %v\ngot: %v", tc, uplo, incX, lda, want, a) + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zher2.go b/vendor/gonum.org/v1/gonum/blas/testblas/zher2.go new file mode 100644 index 00000000..0a4c2435 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zher2.go @@ -0,0 +1,257 @@ +// 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 testblas + +import ( + "math" + "math/cmplx" + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Zher2er interface { + Zher2(uplo blas.Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) +} + +func Zher2Test(t *testing.T, impl Zher2er) { + for tc, test := range []struct { + alpha complex128 + incX, incY int + x []complex128 + y []complex128 + a []complex128 + + want []complex128 + }{ + { + alpha: 1 + 2i, + incX: 1, + incY: 1, + }, + { + alpha: 1 + 2i, + incX: 1, + incY: 1, + x: []complex128{ + -6 + 2i, + -2 - 4i, + 0 + 0i, + 0 + 7i, + }, + y: []complex128{ + 2 - 5i, + 0 + 0i, + -8 - 9i, + 6 + 6i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 62 + 0i, 43 - 7i, 173 + 1i, -173 + 55i, + 43 + 7i, 16 + 0i, 19 + 120i, -19 - 89i, + 173 - 1i, 19 - 120i, 14 + 0i, 51 + 181i, + -173 - 55i, -19 + 89i, 51 - 181i, -66 + 0i, + }, + }, + { + alpha: 1 + 2i, + incX: 3, + incY: 7, + x: []complex128{ + -6 + 2i, + -2 - 4i, + 0 + 0i, + 0 + 7i, + }, + y: []complex128{ + 2 - 5i, + 0 + 0i, + -8 - 9i, + 6 + 6i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 62 + 0i, 43 - 7i, 173 + 1i, -173 + 55i, + 43 + 7i, 16 + 0i, 19 + 120i, -19 - 89i, + 173 - 1i, 19 - 120i, 14 + 0i, 51 + 181i, + -173 - 55i, -19 + 89i, 51 - 181i, -66 + 0i, + }, + }, + { + alpha: 1 + 2i, + incX: -3, + incY: 7, + x: []complex128{ + 0 + 7i, + 0 + 0i, + -2 - 4i, + -6 + 2i, + }, + y: []complex128{ + 2 - 5i, + 0 + 0i, + -8 - 9i, + 6 + 6i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 62 + 0i, 43 - 7i, 173 + 1i, -173 + 55i, + 43 + 7i, 16 + 0i, 19 + 120i, -19 - 89i, + 173 - 1i, 19 - 120i, 14 + 0i, 51 + 181i, + -173 - 55i, -19 + 89i, 51 - 181i, -66 + 0i, + }, + }, + { + alpha: 1 + 2i, + incX: 3, + incY: -7, + x: []complex128{ + -6 + 2i, + -2 - 4i, + 0 + 0i, + 0 + 7i, + }, + y: []complex128{ + 6 + 6i, + -8 - 9i, + 0 + 0i, + 2 - 5i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 62 + 0i, 43 - 7i, 173 + 1i, -173 + 55i, + 43 + 7i, 16 + 0i, 19 + 120i, -19 - 89i, + 173 - 1i, 19 - 120i, 14 + 0i, 51 + 181i, + -173 - 55i, -19 + 89i, 51 - 181i, -66 + 0i, + }, + }, + { + alpha: 1 + 2i, + incX: -3, + incY: -7, + x: []complex128{ + 0 + 7i, + 0 + 0i, + -2 - 4i, + -6 + 2i, + }, + y: []complex128{ + 6 + 6i, + -8 - 9i, + 0 + 0i, + 2 - 5i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 62 + 0i, 43 - 7i, 173 + 1i, -173 + 55i, + 43 + 7i, 16 + 0i, 19 + 120i, -19 - 89i, + 173 - 1i, 19 - 120i, 14 + 0i, 51 + 181i, + -173 - 55i, -19 + 89i, 51 - 181i, -66 + 0i, + }, + }, + { + alpha: 0, + incX: 1, + incY: 1, + x: []complex128{ + -6 + 2i, + -2 - 4i, + 0 + 0i, + 0 + 7i, + }, + y: []complex128{ + 2 - 5i, + 0 + 0i, + -8 - 9i, + 6 + 6i, + }, + a: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + want: []complex128{ + 2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i, + -9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i, + 3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i, + 10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i, + }, + }, + } { + n := len(test.x) + incX := test.incX + incY := test.incY + for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} { + for _, lda := range []int{max(1, n), n + 11} { + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + y := makeZVector(test.y, incY) + yCopy := make([]complex128, len(y)) + copy(yCopy, y) + + a := makeZGeneral(test.a, n, n, lda) + want := makeZGeneral(test.want, n, n, lda) + + if uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + a[i*lda+j] = cmplx.NaN() + want[i*lda+j] = cmplx.NaN() + } + a[i*lda+i] = complex(real(a[i*lda+i]), math.NaN()) + } + } else { + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + a[i*lda+j] = cmplx.NaN() + want[i*lda+j] = cmplx.NaN() + } + a[i*lda+i] = complex(real(a[i*lda+i]), math.NaN()) + } + } + + impl.Zher2(uplo, n, test.alpha, x, incX, y, incY, a, lda) + + if !zsame(x, xCopy) { + t.Errorf("Case %v (uplo=%v,incX=%v,incY=%v,lda=%v: unexpected modification of x", tc, uplo, incX, incY, lda) + } + if !zsame(y, yCopy) { + t.Errorf("Case %v (uplo=%v,incX=%v,incY=%v,lda=%v: unexpected modification of y", tc, uplo, incX, incY, lda) + } + if !zsame(want, a) { + t.Errorf("Case %v (uplo=%v,incX=%v,incY=%v,lda=%v: unexpected result\nwant: %v\ngot: %v", tc, uplo, incX, incY, lda, want, a) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zscal.go b/vendor/gonum.org/v1/gonum/blas/testblas/zscal.go new file mode 100644 index 00000000..67210e1b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zscal.go @@ -0,0 +1,119 @@ +// 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 testblas + +import ( + "fmt" + "testing" +) + +type Zscaler interface { + Zscal(n int, alpha complex128, x []complex128, incX int) +} + +func ZscalTest(t *testing.T, impl Zscaler) { + for tc, test := range []struct { + alpha complex128 + x []complex128 + want []complex128 + }{ + { + alpha: 2 + 5i, + x: nil, + want: nil, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i}, + want: []complex128{-8 + 9i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i}, + want: []complex128{-8 + 9i, -14 + 23i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i, -38 + 79i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i, -38 + 79i, -44 + 93i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i, -38 + 79i, -44 + 93i, -50 + 107i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i, -38 + 79i, -44 + 93i, -50 + 107i, -56 + 121i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i, -38 + 79i, -44 + 93i, -50 + 107i, -56 + 121i, -62 + 135i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i, -38 + 79i, -44 + 93i, -50 + 107i, -56 + 121i, -62 + 135i, -68 + 149i}, + }, + { + alpha: 2 + 5i, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + want: []complex128{-8 + 9i, -14 + 23i, -20 + 37i, -26 + 51i, -32 + 65i, -38 + 79i, -44 + 93i, -50 + 107i, -56 + 121i, -62 + 135i, -68 + 149i, -74 + 163i}, + }, + { + alpha: 0, + x: []complex128{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i, 9 + 10i, 11 + 12i, 13 + 14i, 15 + 16i, 17 + 18i, 19 + 20i, 21 + 22i, 23 + 24i}, + want: []complex128{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + } { + n := len(test.x) + if len(test.want) != n { + panic("bad test") + } + for _, incX := range []int{-3, -1, 1, 2, 4, 7, 10} { + x := makeZVector(test.x, incX) + xCopy := make([]complex128, len(x)) + copy(xCopy, x) + + want := makeZVector(test.want, incX) + + impl.Zscal(n, test.alpha, x, incX) + + prefix := fmt.Sprintf("Case %v (n=%v,incX=%v):", tc, n, incX) + + if incX < 0 { + if !zsame(x, xCopy) { + t.Errorf("%v: unexpected modification of x\nwant %v\ngot %v", prefix, want, x) + } + continue + } + if !zsame(x, want) { + t.Errorf("%v: unexpected result:\nwant: %v\ngot: %v", prefix, want, x) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/blas/testblas/zswap.go b/vendor/gonum.org/v1/gonum/blas/testblas/zswap.go new file mode 100644 index 00000000..1be1037e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/blas/testblas/zswap.go @@ -0,0 +1,68 @@ +// 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 testblas + +import ( + "fmt" + "math/cmplx" + "math/rand" + "testing" +) + +type Zswaper interface { + Zswap(n int, x []complex128, incX int, y []complex128, incY int) +} + +func ZswapTest(t *testing.T, impl Zswaper) { + rnd := rand.New(rand.NewSource(1)) + for n := 0; n < 20; n++ { + for _, inc := range allPairs([]int{-5, -1, 1, 2, 5, 10}, []int{-3, -1, 1, 3, 7, 12}) { + incX := inc[0] + incY := inc[1] + aincX := abs(incX) + aincY := abs(incY) + + var x, y []complex128 + if n > 0 { + x = make([]complex128, (n-1)*aincX+1) + y = make([]complex128, (n-1)*aincY+1) + } + for i := range x { + x[i] = cmplx.NaN() + } + for i := range y { + y[i] = cmplx.NaN() + } + for i := 0; i < n; i++ { + x[i*aincX] = complex(rnd.NormFloat64(), rnd.NormFloat64()) + y[i*aincY] = complex(rnd.NormFloat64(), rnd.NormFloat64()) + } + + xWant := make([]complex128, len(x)) + yWant := make([]complex128, len(y)) + if incX*incY > 0 { + for i := 0; i < n; i++ { + xWant[i*aincX] = y[i*aincY] + yWant[i*aincY] = x[i*aincX] + } + } else { + for i := 0; i < n; i++ { + xWant[(n-i-1)*aincX] = y[i*aincY] + yWant[(n-i-1)*aincY] = x[i*aincX] + } + } + + impl.Zswap(n, x, incX, y, incY) + + prefix := fmt.Sprintf("Case n=%v,incX=%v,incY=%v:", n, incX, incY) + if !zsame(x, xWant) { + t.Errorf("%v: unexpected x:\nwant %v\ngot %v", prefix, xWant, x) + } + if !zsame(y, yWant) { + t.Errorf("%v: unexpected y:\nwant %v\ngot %v", prefix, yWant, y) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/README.md b/vendor/gonum.org/v1/gonum/diff/README.md new file mode 100644 index 00000000..6fbcf725 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/README.md @@ -0,0 +1,3 @@ +# Gonum diff [![GoDoc](https://godoc.org/gonum.org/v1/gonum/diff?status.svg)](https://godoc.org/gonum.org/v1/gonum/diff) + +Package diff is a package for computing derivatives of functions for the Go language. diff --git a/vendor/gonum.org/v1/gonum/diff/fd/crosslaplacian.go b/vendor/gonum.org/v1/gonum/diff/fd/crosslaplacian.go new file mode 100644 index 00000000..9b2f1d1f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/crosslaplacian.go @@ -0,0 +1,186 @@ +// 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 fd + +import ( + "math" + "sync" +) + +// CrossLaplacian computes a Laplacian-like quantity for a function of two vectors +// at the locations x and y. +// It computes +// ∇_y · ∇_x f(x,y) = \sum_i ∂^2 f(x,y)/∂x_i ∂y_i +// The two input vector lengths must be the same. +// +// Finite difference formula and other options are specified by settings. If +// settings is nil, CrossLaplacian will be estimated using the Forward formula and +// a default step size. +// +// CrossLaplacian panics if the two input vectors are not the same length, or if +// the derivative order of the formula is not 1. +func CrossLaplacian(f func(x, y []float64) float64, x, y []float64, settings *Settings) float64 { + n := len(x) + if n == 0 { + panic("crosslaplacian: x has zero length") + } + if len(x) != len(y) { + panic("crosslaplacian: input vector length mismatch") + } + + // Default settings. + formula := Forward + step := math.Sqrt(formula.Step) // Use the sqrt because taking derivatives of derivatives. + var originValue float64 + var originKnown, concurrent bool + + // Use user settings if provided. + if settings != nil { + if !settings.Formula.isZero() { + formula = settings.Formula + step = math.Sqrt(formula.Step) + checkFormula(formula) + if formula.Derivative != 1 { + panic(badDerivOrder) + } + } + if settings.Step != 0 { + if settings.Step < 0 { + panic(negativeStep) + } + step = settings.Step + } + originKnown = settings.OriginKnown + originValue = settings.OriginValue + concurrent = settings.Concurrent + } + + evals := n * len(formula.Stencil) * len(formula.Stencil) + if usesOrigin(formula.Stencil) { + evals -= n + } + + nWorkers := computeWorkers(concurrent, evals) + if nWorkers == 1 { + return crossLaplacianSerial(f, x, y, formula.Stencil, step, originKnown, originValue) + } + return crossLaplacianConcurrent(nWorkers, evals, f, x, y, formula.Stencil, step, originKnown, originValue) +} + +func crossLaplacianSerial(f func(x, y []float64) float64, x, y []float64, stencil []Point, step float64, originKnown bool, originValue float64) float64 { + n := len(x) + xCopy := make([]float64, len(x)) + yCopy := make([]float64, len(y)) + fo := func() float64 { + // Copy x and y in case they are modified during the call. + copy(xCopy, x) + copy(yCopy, y) + return f(x, y) + } + origin := getOrigin(originKnown, originValue, fo, stencil) + + is2 := 1 / (step * step) + var laplacian float64 + for i := 0; i < n; i++ { + for _, pty := range stencil { + for _, ptx := range stencil { + var v float64 + if ptx.Loc == 0 && pty.Loc == 0 { + v = origin + } else { + // Copying the data anew has two benefits. First, it + // avoids floating point issues where adding and then + // subtracting the step don't return to the exact same + // location. Secondly, it protects against the function + // modifying the input data. + copy(yCopy, y) + copy(xCopy, x) + yCopy[i] += pty.Loc * step + xCopy[i] += ptx.Loc * step + v = f(xCopy, yCopy) + } + laplacian += v * ptx.Coeff * pty.Coeff * is2 + } + } + } + return laplacian +} + +func crossLaplacianConcurrent(nWorkers, evals int, f func(x, y []float64) float64, x, y []float64, stencil []Point, step float64, originKnown bool, originValue float64) float64 { + n := len(x) + type run struct { + i int + xIdx, yIdx int + result float64 + } + + send := make(chan run, evals) + ans := make(chan run, evals) + + var originWG sync.WaitGroup + hasOrigin := usesOrigin(stencil) + if hasOrigin { + originWG.Add(1) + // Launch worker to compute the origin. + go func() { + defer originWG.Done() + xCopy := make([]float64, len(x)) + yCopy := make([]float64, len(y)) + copy(xCopy, x) + copy(yCopy, y) + originValue = f(xCopy, yCopy) + }() + } + + var workerWG sync.WaitGroup + // Launch workers. + for i := 0; i < nWorkers; i++ { + workerWG.Add(1) + go func(send <-chan run, ans chan<- run) { + defer workerWG.Done() + xCopy := make([]float64, len(x)) + yCopy := make([]float64, len(y)) + for r := range send { + if stencil[r.xIdx].Loc == 0 && stencil[r.yIdx].Loc == 0 { + originWG.Wait() + r.result = originValue + } else { + // See crossLaplacianSerial for comment on the copy. + copy(xCopy, x) + copy(yCopy, y) + xCopy[r.i] += stencil[r.xIdx].Loc * step + yCopy[r.i] += stencil[r.yIdx].Loc * step + r.result = f(xCopy, yCopy) + } + ans <- r + } + }(send, ans) + } + + // Launch the distributor, which sends all of runs. + go func(send chan<- run) { + for i := 0; i < n; i++ { + for xIdx := range stencil { + for yIdx := range stencil { + send <- run{ + i: i, xIdx: xIdx, yIdx: yIdx, + } + } + } + } + close(send) + // Wait for all the workers to quit, then close the ans channel. + workerWG.Wait() + close(ans) + }(send) + + // Read in the results. + is2 := 1 / (step * step) + var laplacian float64 + for r := range ans { + laplacian += r.result * stencil[r.xIdx].Coeff * stencil[r.yIdx].Coeff * is2 + } + return laplacian +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/crosslaplacian_test.go b/vendor/gonum.org/v1/gonum/diff/fd/crosslaplacian_test.go new file mode 100644 index 00000000..e27a83fa --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/crosslaplacian_test.go @@ -0,0 +1,111 @@ +// 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 fd + +import ( + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +type CrossLaplacianTester interface { + Func(x, y []float64) float64 + CrossLaplacian(x, y []float64) float64 +} + +type WrapperCL struct { + Tester HessianTester +} + +func (WrapperCL) constructZ(x, y []float64) []float64 { + z := make([]float64, len(x)+len(y)) + copy(z, x) + copy(z[len(x):], y) + return z +} + +func (w WrapperCL) Func(x, y []float64) float64 { + z := w.constructZ(x, y) + return w.Tester.Func(z) +} + +func (w WrapperCL) CrossLaplacian(x, y []float64) float64 { + z := w.constructZ(x, y) + hess := mat.NewSymDense(len(z), nil) + w.Tester.Hess(hess, z) + // The CrossLaplacian is the trace of the off-diagonal block of the Hessian. + var l float64 + for i := 0; i < len(x); i++ { + l += hess.At(i, i+len(x)) + } + return l +} + +func TestCrossLaplacian(t *testing.T) { + for cas, test := range []struct { + l CrossLaplacianTester + x, y []float64 + settings *Settings + tol float64 + }{ + { + l: WrapperCL{Watson{}}, + x: []float64{0.2, 0.3}, + y: []float64{0.1, 0.4}, + tol: 1e-3, + }, + { + l: WrapperCL{Watson{}}, + x: []float64{2, 3, 1}, + y: []float64{1, 4, 1}, + tol: 1e-3, + }, + { + l: WrapperCL{ConstFunc(6)}, + x: []float64{2, -3, 1}, + y: []float64{1, 4, -5}, + tol: 1e-6, + }, + { + l: WrapperCL{LinearFunc{w: []float64{10, 6, -1, 5}, c: 5}}, + x: []float64{3, 1}, + y: []float64{8, 6}, + tol: 1e-6, + }, + { + l: WrapperCL{QuadFunc{ + a: mat.NewSymDense(4, []float64{ + 10, 2, 1, 9, + 2, 5, -3, 4, + 1, -3, 6, 2, + 9, 4, 2, -14, + }), + b: mat.NewVecDense(4, []float64{3, -2, -1, 4}), + c: 5, + }}, + x: []float64{-1.6, -3}, + y: []float64{1.8, 3.4}, + tol: 1e-6, + }, + } { + got := CrossLaplacian(test.l.Func, test.x, test.y, test.settings) + want := test.l.CrossLaplacian(test.x, test.y) + if !floats.EqualWithinAbsOrRel(got, want, test.tol, test.tol) { + t.Errorf("Cas %d: CrossLaplacian mismatch serial. got %v, want %v", cas, got, want) + } + + // Test that concurrency works. + settings := test.settings + if settings == nil { + settings = &Settings{} + } + settings.Concurrent = true + got2 := CrossLaplacian(test.l.Func, test.x, test.y, settings) + if !floats.EqualWithinAbsOrRel(got, got2, 1e-6, 1e-6) { + t.Errorf("Cas %d: Laplacian mismatch. got %v, want %v", cas, got2, got) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/derivative.go b/vendor/gonum.org/v1/gonum/diff/fd/derivative.go new file mode 100644 index 00000000..e5aa9af3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/derivative.go @@ -0,0 +1,71 @@ +// 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 fd + +import ( + "math" + "runtime" + "sync" +) + +// Derivative estimates the derivative of the function f at the given location. +// The finite difference formula, the step size, and other options are +// specified by settings. If settings is nil, the first derivative will be +// estimated using the Forward formula and a default step size. +func Derivative(f func(float64) float64, x float64, settings *Settings) float64 { + // Default settings. + formula := Forward + step := formula.Step + var originValue float64 + var originKnown, concurrent bool + + // Use user settings if provided. + if settings != nil { + if !settings.Formula.isZero() { + formula = settings.Formula + step = formula.Step + checkFormula(formula) + } + if settings.Step != 0 { + step = settings.Step + } + originKnown = settings.OriginKnown + originValue = settings.OriginValue + concurrent = settings.Concurrent + } + + var deriv float64 + if !concurrent || runtime.GOMAXPROCS(0) == 1 { + for _, pt := range formula.Stencil { + if originKnown && pt.Loc == 0 { + deriv += pt.Coeff * originValue + continue + } + deriv += pt.Coeff * f(x+step*pt.Loc) + } + return deriv / math.Pow(step, float64(formula.Derivative)) + } + + wg := &sync.WaitGroup{} + mux := &sync.Mutex{} + for _, pt := range formula.Stencil { + if originKnown && pt.Loc == 0 { + mux.Lock() + deriv += pt.Coeff * originValue + mux.Unlock() + continue + } + wg.Add(1) + go func(pt Point) { + defer wg.Done() + fofx := f(x + step*pt.Loc) + mux.Lock() + defer mux.Unlock() + deriv += pt.Coeff * fofx + }(pt) + } + wg.Wait() + return deriv / math.Pow(step, float64(formula.Derivative)) +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/derivative_test.go b/vendor/gonum.org/v1/gonum/diff/fd/derivative_test.go new file mode 100644 index 00000000..35d4f0f3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/derivative_test.go @@ -0,0 +1,145 @@ +// 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 fd + +import ( + "math" + "testing" +) + +var xSquared = func(x float64) float64 { return x * x } + +type testPoint struct { + f func(float64) float64 + loc float64 + fofx float64 + ans float64 +} + +var testsFirst = []testPoint{ + { + f: xSquared, + loc: 0, + fofx: 0, + ans: 0, + }, + { + f: xSquared, + loc: 5, + fofx: 25, + ans: 10, + }, + { + f: xSquared, + loc: 2, + fofx: 4, + ans: 4, + }, + { + f: xSquared, + loc: -5, + fofx: 25, + ans: -10, + }, +} + +var testsSecond = []testPoint{ + { + f: xSquared, + loc: 0, + fofx: 0, + ans: 2, + }, + { + f: xSquared, + loc: 5, + fofx: 25, + ans: 2, + }, + { + f: xSquared, + loc: 2, + fofx: 4, + ans: 2, + }, + { + f: xSquared, + loc: -5, + fofx: 25, + ans: 2, + }, +} + +func testDerivative(t *testing.T, formula Formula, tol float64, tests []testPoint) { + for i, test := range tests { + + ans := Derivative(test.f, test.loc, &Settings{ + Formula: formula, + }) + if math.Abs(test.ans-ans) > tol { + t.Errorf("Case %v: ans mismatch serial: expected %v, found %v", i, test.ans, ans) + } + + ans = Derivative(test.f, test.loc, &Settings{ + Formula: formula, + OriginKnown: true, + OriginValue: test.fofx, + }) + if math.Abs(test.ans-ans) > tol { + t.Errorf("Case %v: ans mismatch serial origin known: expected %v, found %v", i, test.ans, ans) + } + + ans = Derivative(test.f, test.loc, &Settings{ + Formula: formula, + Concurrent: true, + }) + if math.Abs(test.ans-ans) > tol { + t.Errorf("Case %v: ans mismatch concurrent: expected %v, found %v", i, test.ans, ans) + } + + ans = Derivative(test.f, test.loc, &Settings{ + Formula: formula, + OriginKnown: true, + OriginValue: test.fofx, + Concurrent: true, + }) + if math.Abs(test.ans-ans) > tol { + t.Errorf("Case %v: ans mismatch concurrent: expected %v, found %v", i, test.ans, ans) + } + } +} + +func TestForward(t *testing.T) { + testDerivative(t, Forward, 2e-4, testsFirst) +} + +func TestBackward(t *testing.T) { + testDerivative(t, Backward, 2e-4, testsFirst) +} + +func TestCentral(t *testing.T) { + testDerivative(t, Central, 1e-6, testsFirst) +} + +func TestCentralSecond(t *testing.T) { + testDerivative(t, Central2nd, 1e-3, testsSecond) +} + +// TestDerivativeDefault checks that the derivative works when settings is nil +// or zero value. +func TestDerivativeDefault(t *testing.T) { + tol := 1e-6 + for i, test := range testsFirst { + ans := Derivative(test.f, test.loc, nil) + if math.Abs(test.ans-ans) > tol { + t.Errorf("Case %v: ans mismatch default: expected %v, found %v", i, test.ans, ans) + } + + ans = Derivative(test.f, test.loc, &Settings{}) + if math.Abs(test.ans-ans) > tol { + t.Errorf("Case %v: ans mismatch zero value: expected %v, found %v", i, test.ans, ans) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/diff.go b/vendor/gonum.org/v1/gonum/diff/fd/diff.go new file mode 100644 index 00000000..3bde48d9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/diff.go @@ -0,0 +1,148 @@ +// 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 fd + +import ( + "math" + "runtime" +) + +// A Point is a stencil location in a finite difference formula. +type Point struct { + Loc float64 + Coeff float64 +} + +// Formula represents a finite difference formula on a regularly spaced grid +// that approximates the derivative of order k of a function f at x as +// d^k f(x) ≈ (1 / Step^k) * \sum_i Coeff_i * f(x + Step * Loc_i). +// Step must be positive, or the finite difference formula will panic. +type Formula struct { + // Stencil is the set of sampling Points which are used to estimate the + // derivative. The locations will be scaled by Step and are relative to x. + Stencil []Point + Derivative int // The order of the approximated derivative. + Step float64 // Default step size for the formula. +} + +func (f Formula) isZero() bool { + return f.Stencil == nil && f.Derivative == 0 && f.Step == 0 +} + +// Settings is the settings structure for computing finite differences. +type Settings struct { + // Formula is the finite difference formula used + // for approximating the derivative. + // Zero value indicates a default formula. + Formula Formula + // Step is the distance between points of the stencil. + // If equal to 0, formula's default step will be used. + Step float64 + + OriginKnown bool // Flag that the value at the origin x is known. + OriginValue float64 // Value at the origin (only used if OriginKnown is true). + + Concurrent bool // Should the function calls be executed concurrently. +} + +// Forward represents a first-order accurate forward approximation +// to the first derivative. +var Forward = Formula{ + Stencil: []Point{{Loc: 0, Coeff: -1}, {Loc: 1, Coeff: 1}}, + Derivative: 1, + Step: 2e-8, +} + +// Forward2nd represents a first-order accurate forward approximation +// to the second derivative. +var Forward2nd = Formula{ + Stencil: []Point{{Loc: 0, Coeff: 1}, {Loc: 1, Coeff: -2}, {Loc: 2, Coeff: 1}}, + Derivative: 2, + Step: 1e-4, +} + +// Backward represents a first-order accurate backward approximation +// to the first derivative. +var Backward = Formula{ + Stencil: []Point{{Loc: -1, Coeff: -1}, {Loc: 0, Coeff: 1}}, + Derivative: 1, + Step: 2e-8, +} + +// Backward2nd represents a first-order accurate forward approximation +// to the second derivative. +var Backward2nd = Formula{ + Stencil: []Point{{Loc: 0, Coeff: 1}, {Loc: -1, Coeff: -2}, {Loc: -2, Coeff: 1}}, + Derivative: 2, + Step: 1e-4, +} + +// Central represents a second-order accurate centered approximation +// to the first derivative. +var Central = Formula{ + Stencil: []Point{{Loc: -1, Coeff: -0.5}, {Loc: 1, Coeff: 0.5}}, + Derivative: 1, + Step: 6e-6, +} + +// Central2nd represents a secord-order accurate centered approximation +// to the second derivative. +var Central2nd = Formula{ + Stencil: []Point{{Loc: -1, Coeff: 1}, {Loc: 0, Coeff: -2}, {Loc: 1, Coeff: 1}}, + Derivative: 2, + Step: 1e-4, +} + +var negativeStep = "fd: negative step" + +// checkFormula checks if the formula is valid, and panics otherwise. +func checkFormula(formula Formula) { + if formula.Derivative == 0 || formula.Stencil == nil || formula.Step <= 0 { + panic("fd: bad formula") + } +} + +// computeWorkers returns the desired number of workers given the concurrency +// level and number of evaluations. +func computeWorkers(concurrent bool, evals int) int { + if !concurrent { + return 1 + } + nWorkers := runtime.GOMAXPROCS(0) + if nWorkers > evals { + nWorkers = evals + } + return nWorkers +} + +// usesOrigin returns whether the stencil uses the origin, which is true iff +// one of the locations in the stencil equals 0. +func usesOrigin(stencil []Point) bool { + for _, pt := range stencil { + if pt.Loc == 0 { + return true + } + } + return false +} + +// getOrigin returns the value at the origin. It returns originValue if originKnown +// is true. It returns the value returned by f if stencil contains a point with +// zero location, and NaN otherwise. +func getOrigin(originKnown bool, originValue float64, f func() float64, stencil []Point) float64 { + if originKnown { + return originValue + } + for _, pt := range stencil { + if pt.Loc == 0 { + return f() + } + } + return math.NaN() +} + +const ( + badDerivOrder = "fd: invalid derivative order" +) diff --git a/vendor/gonum.org/v1/gonum/diff/fd/doc.go b/vendor/gonum.org/v1/gonum/diff/fd/doc.go new file mode 100644 index 00000000..ec6fbb10 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package fd provides functions to approximate derivatives using finite differences. +package fd // import "gonum.org/v1/gonum/diff/fd" diff --git a/vendor/gonum.org/v1/gonum/diff/fd/example_test.go b/vendor/gonum.org/v1/gonum/diff/fd/example_test.go new file mode 100644 index 00000000..adc9db0f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/example_test.go @@ -0,0 +1,68 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package fd_test + +import ( + "fmt" + "math" + + "gonum.org/v1/gonum/diff/fd" + "gonum.org/v1/gonum/mat" +) + +func ExampleDerivative() { + f := func(x float64) float64 { + return math.Sin(x) + } + // Compute the first derivative of f at 0 using the default settings. + fmt.Println("f'(0) ≈", fd.Derivative(f, 0, nil)) + // Compute the first derivative of f at 0 using the forward approximation + // with a custom step size. + df := fd.Derivative(f, 0, &fd.Settings{ + Formula: fd.Forward, + Step: 1e-3, + }) + fmt.Println("f'(0) ≈", df) + + f = func(x float64) float64 { + return math.Pow(math.Cos(x), 3) + } + // Compute the second derivative of f at 0 using + // the centered approximation, concurrent evaluation, + // and a known function value at x. + df = fd.Derivative(f, 0, &fd.Settings{ + Formula: fd.Central2nd, + Concurrent: true, + OriginKnown: true, + OriginValue: f(0), + }) + fmt.Println("f''(0) ≈", df) + + // Output: + // f'(0) ≈ 1 + // f'(0) ≈ 0.9999998333333416 + // f''(0) ≈ -2.999999981767587 +} + +func ExampleJacobian() { + f := func(dst, x []float64) { + dst[0] = x[0] + 1 + dst[1] = 5 * x[2] + dst[2] = 4*x[1]*x[1] - 2*x[2] + dst[3] = x[2] * math.Sin(x[0]) + } + jac := mat.NewDense(4, 3, nil) + fd.Jacobian(jac, f, []float64{1, 2, 3}, &fd.JacobianSettings{ + Formula: fd.Central, + Concurrent: true, + }) + fmt.Printf("J ≈ %.6v\n", mat.Formatted(jac, mat.Prefix(" "))) + + // Output: + // J ≈ ⎡ 1 0 0⎤ + // ⎢ 0 0 5⎥ + // ⎢ 0 16 -2⎥ + // ⎣ 1.62091 0 0.841471⎦ +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/gradient.go b/vendor/gonum.org/v1/gonum/diff/fd/gradient.go new file mode 100644 index 00000000..79bb3d1a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/gradient.go @@ -0,0 +1,145 @@ +// 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 fd + +import "gonum.org/v1/gonum/floats" + +// Gradient estimates the gradient of the multivariate function f at the +// location x. If dst is not nil, the result will be stored in-place into dst +// and returned, otherwise a new slice will be allocated first. Finite +// difference formula and other options are specified by settings. If settings is +// nil, the gradient will be estimated using the Forward formula and a default +// step size. +// +// Gradient panics if the length of dst and x is not equal, or if the derivative +// order of the formula is not 1. +func Gradient(dst []float64, f func([]float64) float64, x []float64, settings *Settings) []float64 { + if dst == nil { + dst = make([]float64, len(x)) + } + if len(dst) != len(x) { + panic("fd: slice length mismatch") + } + + // Default settings. + formula := Forward + step := formula.Step + var originValue float64 + var originKnown, concurrent bool + + // Use user settings if provided. + if settings != nil { + if !settings.Formula.isZero() { + formula = settings.Formula + step = formula.Step + checkFormula(formula) + if formula.Derivative != 1 { + panic(badDerivOrder) + } + } + if settings.Step != 0 { + step = settings.Step + } + originKnown = settings.OriginKnown + originValue = settings.OriginValue + concurrent = settings.Concurrent + } + + evals := len(formula.Stencil) * len(x) + nWorkers := computeWorkers(concurrent, evals) + + hasOrigin := usesOrigin(formula.Stencil) + // Copy x in case it is modified during the call. + xcopy := make([]float64, len(x)) + if hasOrigin && !originKnown { + copy(xcopy, x) + originValue = f(xcopy) + } + + if nWorkers == 1 { + for i := range xcopy { + var deriv float64 + for _, pt := range formula.Stencil { + if pt.Loc == 0 { + deriv += pt.Coeff * originValue + continue + } + // Copying the data anew has two benefits. First, it + // avoids floating point issues where adding and then + // subtracting the step don't return to the exact same + // location. Secondly, it protects against the function + // modifying the input data. + copy(xcopy, x) + xcopy[i] += pt.Loc * step + deriv += pt.Coeff * f(xcopy) + } + dst[i] = deriv / step + } + return dst + } + + sendChan := make(chan fdrun, evals) + ansChan := make(chan fdrun, evals) + quit := make(chan struct{}) + defer close(quit) + + // Launch workers. Workers receive an index and a step, and compute the answer. + for i := 0; i < nWorkers; i++ { + go func(sendChan <-chan fdrun, ansChan chan<- fdrun, quit <-chan struct{}) { + xcopy := make([]float64, len(x)) + for { + select { + case <-quit: + return + case run := <-sendChan: + // See above comment on the copy. + copy(xcopy, x) + xcopy[run.idx] += run.pt.Loc * step + run.result = f(xcopy) + ansChan <- run + } + } + }(sendChan, ansChan, quit) + } + + // Launch the distributor. Distributor sends the cases to be computed. + go func(sendChan chan<- fdrun, ansChan chan<- fdrun) { + for i := range x { + for _, pt := range formula.Stencil { + if pt.Loc == 0 { + // Answer already known. Send the answer on the answer channel. + ansChan <- fdrun{ + idx: i, + pt: pt, + result: originValue, + } + continue + } + // Answer not known, send the answer to be computed. + sendChan <- fdrun{ + idx: i, + pt: pt, + } + } + } + }(sendChan, ansChan) + + for i := range dst { + dst[i] = 0 + } + // Read in all of the results. + for i := 0; i < evals; i++ { + run := <-ansChan + dst[run.idx] += run.pt.Coeff * run.result + } + floats.Scale(1/step, dst) + return dst +} + +type fdrun struct { + idx int + pt Point + result float64 +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/gradient_test.go b/vendor/gonum.org/v1/gonum/diff/fd/gradient_test.go new file mode 100644 index 00000000..0774ad73 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/gradient_test.go @@ -0,0 +1,187 @@ +// 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 fd + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Rosenbrock struct { + nDim int +} + +func (r Rosenbrock) F(x []float64) (sum float64) { + deriv := make([]float64, len(x)) + return r.FDf(x, deriv) +} + +func (r Rosenbrock) FDf(x []float64, deriv []float64) (sum float64) { + for i := range deriv { + deriv[i] = 0 + } + + for i := 0; i < len(x)-1; i++ { + sum += math.Pow(1-x[i], 2) + 100*math.Pow(x[i+1]-math.Pow(x[i], 2), 2) + } + for i := 0; i < len(x)-1; i++ { + deriv[i] += -1 * 2 * (1 - x[i]) + deriv[i] += 2 * 100 * (x[i+1] - math.Pow(x[i], 2)) * (-2 * x[i]) + } + for i := 1; i < len(x); i++ { + deriv[i] += 2 * 100 * (x[i] - math.Pow(x[i-1], 2)) + } + + return sum +} + +func TestGradient(t *testing.T) { + rand.Seed(1) + for i, test := range []struct { + nDim int + tol float64 + formula Formula + }{ + { + nDim: 2, + tol: 2e-4, + formula: Forward, + }, + { + nDim: 2, + tol: 1e-6, + formula: Central, + }, + { + nDim: 40, + tol: 2e-4, + formula: Forward, + }, + { + nDim: 40, + tol: 1e-6, + formula: Central, + }, + } { + x := make([]float64, test.nDim) + for i := range x { + x[i] = rand.Float64() + } + xcopy := make([]float64, len(x)) + copy(xcopy, x) + + r := Rosenbrock{len(x)} + trueGradient := make([]float64, len(x)) + r.FDf(x, trueGradient) + + // Try with gradient nil. + gradient := Gradient(nil, r.F, x, &Settings{ + Formula: test.formula, + }) + if !floats.EqualApprox(gradient, trueGradient, test.tol) { + t.Errorf("Case %v: gradient mismatch in serial with nil. Want: %v, Got: %v.", i, trueGradient, gradient) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %v: x modified during call to gradient in serial with nil.", i) + } + + // Try with provided gradient. + for i := range gradient { + gradient[i] = rand.Float64() + } + Gradient(gradient, r.F, x, &Settings{ + Formula: test.formula, + }) + if !floats.EqualApprox(gradient, trueGradient, test.tol) { + t.Errorf("Case %v: gradient mismatch in serial. Want: %v, Got: %v.", i, trueGradient, gradient) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %v: x modified during call to gradient in serial with non-nil.", i) + } + + // Try with known value. + for i := range gradient { + gradient[i] = rand.Float64() + } + Gradient(gradient, r.F, x, &Settings{ + Formula: test.formula, + OriginKnown: true, + OriginValue: r.F(x), + }) + if !floats.EqualApprox(gradient, trueGradient, test.tol) { + t.Errorf("Case %v: gradient mismatch with known origin in serial. Want: %v, Got: %v.", i, trueGradient, gradient) + } + + // Try with concurrent evaluation. + for i := range gradient { + gradient[i] = rand.Float64() + } + Gradient(gradient, r.F, x, &Settings{ + Formula: test.formula, + Concurrent: true, + }) + if !floats.EqualApprox(gradient, trueGradient, test.tol) { + t.Errorf("Case %v: gradient mismatch with unknown origin in parallel. Want: %v, Got: %v.", i, trueGradient, gradient) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %v: x modified during call to gradient in parallel", i) + } + + // Try with concurrent evaluation with origin known. + for i := range gradient { + gradient[i] = rand.Float64() + } + Gradient(gradient, r.F, x, &Settings{ + Formula: test.formula, + Concurrent: true, + OriginKnown: true, + OriginValue: r.F(x), + }) + if !floats.EqualApprox(gradient, trueGradient, test.tol) { + t.Errorf("Case %v: gradient mismatch with known origin in parallel. Want: %v, Got: %v.", i, trueGradient, gradient) + } + + // Try with nil settings. + for i := range gradient { + gradient[i] = rand.Float64() + } + Gradient(gradient, r.F, x, nil) + if !floats.EqualApprox(gradient, trueGradient, test.tol) { + t.Errorf("Case %v: gradient mismatch with default settings. Want: %v, Got: %v.", i, trueGradient, gradient) + } + + // Try with zero-valued settings. + for i := range gradient { + gradient[i] = rand.Float64() + } + Gradient(gradient, r.F, x, &Settings{}) + if !floats.EqualApprox(gradient, trueGradient, test.tol) { + t.Errorf("Case %v: gradient mismatch with zero settings. Want: %v, Got: %v.", i, trueGradient, gradient) + } + } +} + +func Panics(fun func()) (b bool) { + defer func() { + err := recover() + if err != nil { + b = true + } + }() + fun() + return +} + +func TestGradientPanics(t *testing.T) { + // Test that it panics + if !Panics(func() { + Gradient([]float64{0.0}, func(x []float64) float64 { return x[0] * x[0] }, []float64{0.0, 0.0}, nil) + }) { + t.Errorf("Gradient did not panic with length mismatch") + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/hessian.go b/vendor/gonum.org/v1/gonum/diff/fd/hessian.go new file mode 100644 index 00000000..871097ce --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/hessian.go @@ -0,0 +1,193 @@ +// 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 fd + +import ( + "math" + "sync" + + "gonum.org/v1/gonum/mat" +) + +// Hessian approximates the Hessian matrix of the multivariate function f +// at the location x. That is +// H_{i,j} = ∂^2 f(x)/∂x_i ∂x_j +// If dst is not nil, the resulting H will be stored in-place into dst +// and returned, otherwise a new matrix will be allocated first. Finite difference +// formula and other options are specified by settings. If settings is nil, +// the Hessian will be estimated using the Forward formula and a default step size. +// +// Hessian panics if the size of dst and x is not equal, or if the derivative +// order of the formula is not 1. +func Hessian(dst *mat.SymDense, f func(x []float64) float64, x []float64, settings *Settings) *mat.SymDense { + n := len(x) + if dst == nil { + dst = mat.NewSymDense(n, nil) + } else { + if n2 := dst.Symmetric(); n2 != n { + panic("hessian: dst size mismatch") + } + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dst.SetSym(i, j, 0) + } + } + } + + // Default settings. + formula := Forward + step := math.Sqrt(formula.Step) // Use the sqrt because taking derivatives of derivatives. + var originValue float64 + var originKnown, concurrent bool + + // Use user settings if provided. + if settings != nil { + if !settings.Formula.isZero() { + formula = settings.Formula + step = math.Sqrt(formula.Step) + checkFormula(formula) + if formula.Derivative != 1 { + panic(badDerivOrder) + } + } + if settings.Step != 0 { + if settings.Step < 0 { + panic(negativeStep) + } + step = settings.Step + } + originKnown = settings.OriginKnown + originValue = settings.OriginValue + concurrent = settings.Concurrent + } + + evals := n * (n + 1) / 2 * len(formula.Stencil) * len(formula.Stencil) + for _, pt := range formula.Stencil { + if pt.Loc == 0 { + evals -= n * (n + 1) / 2 + break + } + } + + nWorkers := computeWorkers(concurrent, evals) + if nWorkers == 1 { + hessianSerial(dst, f, x, formula.Stencil, step, originKnown, originValue) + return dst + } + hessianConcurrent(dst, nWorkers, evals, f, x, formula.Stencil, step, originKnown, originValue) + return dst +} + +func hessianSerial(dst *mat.SymDense, f func(x []float64) float64, x []float64, stencil []Point, step float64, originKnown bool, originValue float64) { + n := len(x) + xCopy := make([]float64, n) + fo := func() float64 { + // Copy x in case it is modified during the call. + copy(xCopy, x) + return f(x) + } + is2 := 1 / (step * step) + origin := getOrigin(originKnown, originValue, fo, stencil) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + var hess float64 + for _, pti := range stencil { + for _, ptj := range stencil { + var v float64 + if pti.Loc == 0 && ptj.Loc == 0 { + v = origin + } else { + // Copying the data anew has two benefits. First, it + // avoids floating point issues where adding and then + // subtracting the step don't return to the exact same + // location. Secondly, it protects against the function + // modifying the input data. + copy(xCopy, x) + xCopy[i] += pti.Loc * step + xCopy[j] += ptj.Loc * step + v = f(xCopy) + } + hess += v * pti.Coeff * ptj.Coeff * is2 + } + } + dst.SetSym(i, j, hess) + } + } +} + +func hessianConcurrent(dst *mat.SymDense, nWorkers, evals int, f func(x []float64) float64, x []float64, stencil []Point, step float64, originKnown bool, originValue float64) { + n := dst.Symmetric() + type run struct { + i, j int + iIdx, jIdx int + result float64 + } + + send := make(chan run, evals) + ans := make(chan run, evals) + + var originWG sync.WaitGroup + hasOrigin := usesOrigin(stencil) + if hasOrigin { + originWG.Add(1) + // Launch worker to compute the origin. + go func() { + defer originWG.Done() + xCopy := make([]float64, len(x)) + copy(xCopy, x) + originValue = f(xCopy) + }() + } + + var workerWG sync.WaitGroup + // Launch workers. + for i := 0; i < nWorkers; i++ { + workerWG.Add(1) + go func(send <-chan run, ans chan<- run) { + defer workerWG.Done() + xCopy := make([]float64, len(x)) + for r := range send { + if stencil[r.iIdx].Loc == 0 && stencil[r.jIdx].Loc == 0 { + originWG.Wait() + r.result = originValue + } else { + // See hessianSerial for comment on the copy. + copy(xCopy, x) + xCopy[r.i] += stencil[r.iIdx].Loc * step + xCopy[r.j] += stencil[r.jIdx].Loc * step + r.result = f(xCopy) + } + ans <- r + } + }(send, ans) + } + + // Launch the distributor, which sends all of runs. + go func(send chan<- run) { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + for iIdx := range stencil { + for jIdx := range stencil { + send <- run{ + i: i, j: j, iIdx: iIdx, jIdx: jIdx, + } + } + } + } + } + close(send) + // Wait for all the workers to quit, then close the ans channel. + workerWG.Wait() + close(ans) + }(send) + + is2 := 1 / (step * step) + // Read in the results. + for r := range ans { + v := r.result * stencil[r.iIdx].Coeff * stencil[r.jIdx].Coeff * is2 + v += dst.At(r.i, r.j) + dst.SetSym(r.i, r.j, v) + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/hessian_test.go b/vendor/gonum.org/v1/gonum/diff/fd/hessian_test.go new file mode 100644 index 00000000..f9ae8736 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/hessian_test.go @@ -0,0 +1,94 @@ +// 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 fd + +import ( + "testing" + + "gonum.org/v1/gonum/mat" +) + +type HessianTester interface { + Func(x []float64) float64 + Grad(grad, x []float64) + Hess(dst mat.MutableSymmetric, x []float64) +} + +var hessianTestCases = []struct { + h HessianTester + x []float64 + settings *Settings + tol float64 +}{ + { + h: Watson{}, + x: []float64{0.2, 0.3, 0.1, 0.4}, + tol: 1e-3, + }, + { + h: Watson{}, + x: []float64{2, 3, 1, 4}, + tol: 1e-3, + settings: &Settings{ + Step: 1e-5, + Formula: Central, + }, + }, + { + h: Watson{}, + x: []float64{2, 3, 1}, + tol: 1e-3, + settings: &Settings{ + OriginKnown: true, + OriginValue: 7606.529501201192, + }, + }, + { + h: ConstFunc(5), + x: []float64{1, 9}, + tol: 1e-16, + }, + { + h: LinearFunc{w: []float64{10, 6, -1}, c: 5}, + x: []float64{3, 1, 8}, + tol: 1e-6, + }, + { + h: QuadFunc{ + a: mat.NewSymDense(3, []float64{ + 10, 2, 1, + 2, 5, -3, + 1, -3, 6, + }), + b: mat.NewVecDense(3, []float64{3, -2, -1}), + c: 5, + }, + x: []float64{-1.6, -3, 2}, + tol: 1e-6, + }, +} + +func TestHessian(t *testing.T) { + for cas, test := range hessianTestCases { + n := len(test.x) + got := Hessian(nil, test.h.Func, test.x, test.settings) + want := mat.NewSymDense(n, nil) + test.h.Hess(want, test.x) + if !mat.EqualApprox(got, want, test.tol) { + t.Errorf("Cas %d: Hessian mismatch\ngot=\n%0.4v\nwant=\n%0.4v\n", cas, mat.Formatted(got), mat.Formatted(want)) + } + + // Test that concurrency works. + settings := test.settings + if settings == nil { + settings = &Settings{} + } + settings.Concurrent = true + got2 := Hessian(nil, test.h.Func, test.x, settings) + if !mat.EqualApprox(got, got2, 1e-5) { + t.Errorf("Cas %d: Hessian mismatch concurrent\ngot=\n%0.6v\nwant=\n%0.6v\n", cas, mat.Formatted(got2), mat.Formatted(got)) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/jacobian.go b/vendor/gonum.org/v1/gonum/diff/fd/jacobian.go new file mode 100644 index 00000000..658d1183 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/jacobian.go @@ -0,0 +1,200 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package fd + +import ( + "sync" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +type JacobianSettings struct { + Formula Formula + OriginValue []float64 + Step float64 + Concurrent bool +} + +// Jacobian approximates the Jacobian matrix of a vector-valued function f at +// the location x and stores the result in-place into dst. +// +// Finite difference formula and other options are specified by settings. If +// settings is nil, the Jacobian will be estimated using the Forward formula and +// a default step size. +// +// The Jacobian matrix J is the matrix of all first-order partial derivatives of f. +// If f maps an n-dimensional vector x to an m-dimensional vector y = f(x), J is +// an m×n matrix whose elements are given as +// J_{i,j} = ∂f_i/∂x_j, +// or expanded out +// [ ∂f_1/∂x_1 ... ∂f_1/∂x_n ] +// [ . . . ] +// J = [ . . . ] +// [ . . . ] +// [ ∂f_m/∂x_1 ... ∂f_m/∂x_n ] +// +// dst must be non-nil, the number of its columns must equal the length of x, and +// the derivative order of the formula must be 1, otherwise Jacobian will panic. +func Jacobian(dst *mat.Dense, f func(y, x []float64), x []float64, settings *JacobianSettings) { + n := len(x) + if n == 0 { + panic("jacobian: x has zero length") + } + m, c := dst.Dims() + if c != n { + panic("jacobian: mismatched matrix size") + } + + // Default settings. + formula := Forward + step := formula.Step + var originValue []float64 + var concurrent bool + + // Use user settings if provided. + if settings != nil { + if !settings.Formula.isZero() { + formula = settings.Formula + step = formula.Step + checkFormula(formula) + if formula.Derivative != 1 { + panic(badDerivOrder) + } + } + if settings.Step != 0 { + step = settings.Step + } + originValue = settings.OriginValue + if originValue != nil && len(originValue) != m { + panic("jacobian: mismatched OriginValue slice length") + } + concurrent = settings.Concurrent + } + + evals := n * len(formula.Stencil) + for _, pt := range formula.Stencil { + if pt.Loc == 0 { + evals -= n - 1 + break + } + } + + nWorkers := computeWorkers(concurrent, evals) + if nWorkers == 1 { + jacobianSerial(dst, f, x, originValue, formula, step) + return + } + jacobianConcurrent(dst, f, x, originValue, formula, step, nWorkers) +} + +func jacobianSerial(dst *mat.Dense, f func([]float64, []float64), x, origin []float64, formula Formula, step float64) { + m, n := dst.Dims() + xcopy := make([]float64, n) + y := make([]float64, m) + col := make([]float64, m) + for j := 0; j < n; j++ { + for i := range col { + col[i] = 0 + } + for _, pt := range formula.Stencil { + if pt.Loc == 0 { + if origin == nil { + origin = make([]float64, m) + copy(xcopy, x) + f(origin, xcopy) + } + floats.AddScaled(col, pt.Coeff, origin) + } else { + copy(xcopy, x) + xcopy[j] += pt.Loc * step + f(y, xcopy) + floats.AddScaled(col, pt.Coeff, y) + } + } + dst.SetCol(j, col) + } + dst.Scale(1/step, dst) +} + +func jacobianConcurrent(dst *mat.Dense, f func([]float64, []float64), x, origin []float64, formula Formula, step float64, nWorkers int) { + m, n := dst.Dims() + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + dst.Set(i, j, 0) + } + } + + var ( + wg sync.WaitGroup + mu = make([]sync.Mutex, n) // Guard access to individual columns. + ) + worker := func(jobs <-chan jacJob) { + defer wg.Done() + xcopy := make([]float64, n) + y := make([]float64, m) + yVec := mat.NewVecDense(m, y) + for job := range jobs { + copy(xcopy, x) + xcopy[job.j] += job.pt.Loc * step + f(y, xcopy) + col := dst.ColView(job.j) + mu[job.j].Lock() + col.AddScaledVec(col, job.pt.Coeff, yVec) + mu[job.j].Unlock() + } + } + jobs := make(chan jacJob, nWorkers) + for i := 0; i < nWorkers; i++ { + wg.Add(1) + go worker(jobs) + } + var hasOrigin bool + for _, pt := range formula.Stencil { + if pt.Loc == 0 { + hasOrigin = true + continue + } + for j := 0; j < n; j++ { + jobs <- jacJob{j, pt} + } + } + close(jobs) + if hasOrigin && origin == nil { + wg.Add(1) + go func() { + defer wg.Done() + origin = make([]float64, m) + xcopy := make([]float64, n) + copy(xcopy, x) + f(origin, xcopy) + }() + } + wg.Wait() + + if hasOrigin { + // The formula evaluated at x, we need to add scaled origin to + // all columns of dst. Iterate again over all Formula points + // because we don't forbid repeated locations. + + originVec := mat.NewVecDense(m, origin) + for _, pt := range formula.Stencil { + if pt.Loc != 0 { + continue + } + for j := 0; j < n; j++ { + col := dst.ColView(j) + col.AddScaledVec(col, pt.Coeff, originVec) + } + } + } + + dst.Scale(1/step, dst) +} + +type jacJob struct { + j int + pt Point +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/jacobian_test.go b/vendor/gonum.org/v1/gonum/diff/fd/jacobian_test.go new file mode 100644 index 00000000..020f2c1b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/jacobian_test.go @@ -0,0 +1,268 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package fd + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +func vecFunc13(y, x []float64) { + y[0] = 5*x[0] + x[2]*math.Sin(x[1]) + 1 +} +func vecFunc13Jac(jac *mat.Dense, x []float64) { + jac.Set(0, 0, 5) + jac.Set(0, 1, x[2]*math.Cos(x[1])) + jac.Set(0, 2, math.Sin(x[1])) +} + +func vecFunc22(y, x []float64) { + y[0] = x[0]*x[0]*x[1] + 1 + y[1] = 5*x[0] + math.Sin(x[1]) + 1 +} +func vecFunc22Jac(jac *mat.Dense, x []float64) { + jac.Set(0, 0, 2*x[0]*x[1]) + jac.Set(0, 1, x[0]*x[0]) + jac.Set(1, 0, 5) + jac.Set(1, 1, math.Cos(x[1])) +} + +func vecFunc43(y, x []float64) { + y[0] = x[0] + 1 + y[1] = 5*x[2] + 1 + y[2] = 4*x[1]*x[1] - 2*x[2] + 1 + y[3] = x[2]*math.Sin(x[0]) + 1 +} +func vecFunc43Jac(jac *mat.Dense, x []float64) { + jac.Set(0, 0, 1) + jac.Set(0, 1, 0) + jac.Set(0, 2, 0) + jac.Set(1, 0, 0) + jac.Set(1, 1, 0) + jac.Set(1, 2, 5) + jac.Set(2, 0, 0) + jac.Set(2, 1, 8*x[1]) + jac.Set(2, 2, -2) + jac.Set(3, 0, x[2]*math.Cos(x[0])) + jac.Set(3, 1, 0) + jac.Set(3, 2, math.Sin(x[0])) +} + +func TestJacobian(t *testing.T) { + rand.Seed(1) + + // Test with default settings. + for tc, test := range []struct { + m, n int + f func([]float64, []float64) + jac func(*mat.Dense, []float64) + }{ + { + m: 1, + n: 3, + f: vecFunc13, + jac: vecFunc13Jac, + }, + { + m: 2, + n: 2, + f: vecFunc22, + jac: vecFunc22Jac, + }, + { + m: 4, + n: 3, + f: vecFunc43, + jac: vecFunc43Jac, + }, + } { + const tol = 1e-6 + + x := randomSlice(test.n, 10) + xcopy := make([]float64, test.n) + copy(xcopy, x) + + want := mat.NewDense(test.m, test.n, nil) + test.jac(want, x) + + got := mat.NewDense(test.m, test.n, nil) + fillNaNDense(got) + Jacobian(got, test.f, x, nil) + if !mat.EqualApprox(want, got, tol) { + t.Errorf("Case %d (default settings): unexpected Jacobian.\nwant: %v\ngot: %v", + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %d (default settings): x modified", tc) + } + } + + // Test with non-default settings. + for tc, test := range []struct { + m, n int + f func([]float64, []float64) + jac func(*mat.Dense, []float64) + tol float64 + formula Formula + }{ + { + m: 1, + n: 3, + f: vecFunc13, + jac: vecFunc13Jac, + tol: 1e-6, + formula: Forward, + }, + { + m: 1, + n: 3, + f: vecFunc13, + jac: vecFunc13Jac, + tol: 1e-6, + formula: Backward, + }, + { + m: 1, + n: 3, + f: vecFunc13, + jac: vecFunc13Jac, + tol: 1e-9, + formula: Central, + }, + { + m: 2, + n: 2, + f: vecFunc22, + jac: vecFunc22Jac, + tol: 1e-6, + formula: Forward, + }, + { + m: 2, + n: 2, + f: vecFunc22, + jac: vecFunc22Jac, + tol: 1e-6, + formula: Backward, + }, + { + m: 2, + n: 2, + f: vecFunc22, + jac: vecFunc22Jac, + tol: 1e-9, + formula: Central, + }, + { + m: 4, + n: 3, + f: vecFunc43, + jac: vecFunc43Jac, + tol: 1e-6, + formula: Forward, + }, + { + m: 4, + n: 3, + f: vecFunc43, + jac: vecFunc43Jac, + tol: 1e-6, + formula: Backward, + }, + { + m: 4, + n: 3, + f: vecFunc43, + jac: vecFunc43Jac, + tol: 1e-9, + formula: Central, + }, + } { + x := randomSlice(test.n, 10) + xcopy := make([]float64, test.n) + copy(xcopy, x) + + want := mat.NewDense(test.m, test.n, nil) + test.jac(want, x) + + got := mat.NewDense(test.m, test.n, nil) + fillNaNDense(got) + Jacobian(got, test.f, x, &JacobianSettings{ + Formula: test.formula, + }) + if !mat.EqualApprox(want, got, test.tol) { + t.Errorf("Case %d: unexpected Jacobian.\nwant: %v\ngot: %v", + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %d: x modified", tc) + } + + fillNaNDense(got) + Jacobian(got, test.f, x, &JacobianSettings{ + Formula: test.formula, + Concurrent: true, + }) + if !mat.EqualApprox(want, got, test.tol) { + t.Errorf("Case %d (concurrent): unexpected Jacobian.\nwant: %v\ngot: %v", + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %d (concurrent): x modified", tc) + } + + fillNaNDense(got) + origin := make([]float64, test.m) + test.f(origin, x) + Jacobian(got, test.f, x, &JacobianSettings{ + Formula: test.formula, + OriginValue: origin, + }) + if !mat.EqualApprox(want, got, test.tol) { + t.Errorf("Case %d (origin): unexpected Jacobian.\nwant: %v\ngot: %v", + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %d (origin): x modified", tc) + } + + fillNaNDense(got) + Jacobian(got, test.f, x, &JacobianSettings{ + Formula: test.formula, + OriginValue: origin, + Concurrent: true, + }) + if !mat.EqualApprox(want, got, test.tol) { + t.Errorf("Case %d (concurrent, origin): unexpected Jacobian.\nwant: %v\ngot: %v", + tc, mat.Formatted(want, mat.Prefix(" ")), mat.Formatted(got, mat.Prefix(" "))) + } + if !floats.Equal(x, xcopy) { + t.Errorf("Case %d (concurrent, origin): x modified", tc) + } + } +} + +// randomSlice returns a slice of n elements from the interval [-bound,bound). +func randomSlice(n int, bound float64) []float64 { + x := make([]float64, n) + for i := range x { + x[i] = 2*bound*rand.Float64() - bound + } + return x +} + +// fillNaNDense fills the matrix m with NaN values. +func fillNaNDense(m *mat.Dense) { + r, c := m.Dims() + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + m.Set(i, j, math.NaN()) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/laplacian.go b/vendor/gonum.org/v1/gonum/diff/fd/laplacian.go new file mode 100644 index 00000000..e5a8ca15 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/laplacian.go @@ -0,0 +1,158 @@ +// 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 fd + +import "sync" + +// Laplacian computes the Laplacian of the multivariate function f at the location +// x. That is, Laplacian returns +// ∆ f(x) = ∇ · ∇ f(x) = \sum_i ∂^2 f(x)/∂x_i^2 +// The finite difference formula and other options are specified by settings. +// The order of the difference formula must be 2 or Laplacian will panic. +func Laplacian(f func(x []float64) float64, x []float64, settings *Settings) float64 { + n := len(x) + if n == 0 { + panic("laplacian: x has zero length") + } + + // Default settings. + formula := Central2nd + step := formula.Step + var originValue float64 + var originKnown, concurrent bool + + // Use user settings if provided. + if settings != nil { + if !settings.Formula.isZero() { + formula = settings.Formula + step = formula.Step + checkFormula(formula) + if formula.Derivative != 2 { + panic(badDerivOrder) + } + } + if settings.Step != 0 { + if settings.Step < 0 { + panic(negativeStep) + } + step = settings.Step + } + originKnown = settings.OriginKnown + originValue = settings.OriginValue + concurrent = settings.Concurrent + } + + evals := n * len(formula.Stencil) + if usesOrigin(formula.Stencil) { + evals -= n + } + + nWorkers := computeWorkers(concurrent, evals) + if nWorkers == 1 { + return laplacianSerial(f, x, formula.Stencil, step, originKnown, originValue) + } + return laplacianConcurrent(nWorkers, evals, f, x, formula.Stencil, step, originKnown, originValue) +} + +func laplacianSerial(f func(x []float64) float64, x []float64, stencil []Point, step float64, originKnown bool, originValue float64) float64 { + n := len(x) + xCopy := make([]float64, n) + fo := func() float64 { + // Copy x in case it is modified during the call. + copy(xCopy, x) + return f(x) + } + is2 := 1 / (step * step) + origin := getOrigin(originKnown, originValue, fo, stencil) + var laplacian float64 + for i := 0; i < n; i++ { + for _, pt := range stencil { + var v float64 + if pt.Loc == 0 { + v = origin + } else { + // Copying the data anew has two benefits. First, it + // avoids floating point issues where adding and then + // subtracting the step don't return to the exact same + // location. Secondly, it protects against the function + // modifying the input data. + copy(xCopy, x) + xCopy[i] += pt.Loc * step + v = f(xCopy) + } + laplacian += v * pt.Coeff * is2 + } + } + return laplacian +} + +func laplacianConcurrent(nWorkers, evals int, f func(x []float64) float64, x []float64, stencil []Point, step float64, originKnown bool, originValue float64) float64 { + type run struct { + i int + idx int + result float64 + } + n := len(x) + send := make(chan run, evals) + ans := make(chan run, evals) + + var originWG sync.WaitGroup + hasOrigin := usesOrigin(stencil) + if hasOrigin { + originWG.Add(1) + // Launch worker to compute the origin. + go func() { + defer originWG.Done() + xCopy := make([]float64, len(x)) + copy(xCopy, x) + originValue = f(xCopy) + }() + } + + var workerWG sync.WaitGroup + // Launch workers. + for i := 0; i < nWorkers; i++ { + workerWG.Add(1) + go func(send <-chan run, ans chan<- run) { + defer workerWG.Done() + xCopy := make([]float64, len(x)) + for r := range send { + if stencil[r.idx].Loc == 0 { + originWG.Wait() + r.result = originValue + } else { + // See laplacianSerial for comment on the copy. + copy(xCopy, x) + xCopy[r.i] += stencil[r.idx].Loc * step + r.result = f(xCopy) + } + ans <- r + } + }(send, ans) + } + + // Launch the distributor, which sends all of runs. + go func(send chan<- run) { + for i := 0; i < n; i++ { + for idx := range stencil { + send <- run{ + i: i, idx: idx, + } + } + } + close(send) + // Wait for all the workers to quit, then close the ans channel. + workerWG.Wait() + close(ans) + }(send) + + // Read in the results. + is2 := 1 / (step * step) + var laplacian float64 + for r := range ans { + laplacian += r.result * stencil[r.idx].Coeff * is2 + } + return laplacian +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/laplacian_test.go b/vendor/gonum.org/v1/gonum/diff/fd/laplacian_test.go new file mode 100644 index 00000000..75949d4a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/laplacian_test.go @@ -0,0 +1,44 @@ +// 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 fd + +import ( + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +func TestLaplacian(t *testing.T) { + for cas, test := range hessianTestCases { + // Modify the test cases where the forumla is set. + settings := test.settings + if settings != nil && !settings.Formula.isZero() { + settings.Formula = Forward2nd + } + + n := len(test.x) + got := Laplacian(test.h.Func, test.x, test.settings) + hess := mat.NewSymDense(n, nil) + test.h.Hess(hess, test.x) + var want float64 + for i := 0; i < n; i++ { + want += hess.At(i, i) + } + if !floats.EqualWithinAbsOrRel(got, want, test.tol, test.tol) { + t.Errorf("Cas %d: Laplacian mismatch. got %v, want %v", cas, got, want) + } + + // Test that concurrency works. + if settings == nil { + settings = &Settings{} + } + settings.Concurrent = true + got2 := Laplacian(test.h.Func, test.x, settings) + if !floats.EqualWithinAbsOrRel(got, got2, 1e-5, 1e-5) { + t.Errorf("Cas %d: Laplacian mismatch. got %v, want %v", cas, got2, got) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/simplefunctions_test.go b/vendor/gonum.org/v1/gonum/diff/fd/simplefunctions_test.go new file mode 100644 index 00000000..1c1dd42e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/simplefunctions_test.go @@ -0,0 +1,87 @@ +// 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 fd + +import ( + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +// ConstFunc is a constant function returning the value held by the type. +type ConstFunc float64 + +func (c ConstFunc) Func(x []float64) float64 { + return float64(c) +} + +func (c ConstFunc) Grad(grad, x []float64) { + for i := range grad { + grad[i] = 0 + } +} + +func (c ConstFunc) Hess(dst mat.MutableSymmetric, x []float64) { + n := len(x) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dst.SetSym(i, j, 0) + } + } +} + +// LinearFunc is a linear function returning w*x+c. +type LinearFunc struct { + w []float64 + c float64 +} + +func (l LinearFunc) Func(x []float64) float64 { + return floats.Dot(l.w, x) + l.c +} + +func (l LinearFunc) Grad(grad, x []float64) { + copy(grad, l.w) +} + +func (l LinearFunc) Hess(dst mat.MutableSymmetric, x []float64) { + n := len(x) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dst.SetSym(i, j, 0) + } + } +} + +// QuadFunc is a quadratic function returning 0.5*x'*a*x + b*x + c. +type QuadFunc struct { + a *mat.SymDense + b *mat.VecDense + c float64 +} + +func (q QuadFunc) Func(x []float64) float64 { + v := mat.NewVecDense(len(x), x) + var tmp mat.VecDense + tmp.MulVec(q.a, v) + return 0.5*mat.Dot(&tmp, v) + mat.Dot(q.b, v) + q.c +} + +func (q QuadFunc) Grad(grad, x []float64) { + var tmp mat.VecDense + v := mat.NewVecDense(len(x), x) + tmp.MulVec(q.a, v) + for i := range grad { + grad[i] = tmp.At(i, 0) + q.b.At(i, 0) + } +} + +func (q QuadFunc) Hess(dst mat.MutableSymmetric, x []float64) { + n := len(x) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dst.SetSym(i, j, q.a.At(i, j)) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/diff/fd/watson_test.go b/vendor/gonum.org/v1/gonum/diff/fd/watson_test.go new file mode 100644 index 00000000..62095e21 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/diff/fd/watson_test.go @@ -0,0 +1,132 @@ +// 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 fd + +import "gonum.org/v1/gonum/mat" + +// Watson implements the Watson's function. +// Dimension of the problem should be 2 <= dim <= 31. For dim == 9, the problem +// of minimizing the function is very ill conditioned. +// +// This is copied from gonum.org/v1/optimize/functions for testing Hessian-like +// derivative methods. +// +// References: +// - Kowalik, J.S., Osborne, M.R.: Methods for Unconstrained Optimization +// Problems. Elsevier North-Holland, New York, 1968 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type Watson struct{} + +func (Watson) Func(x []float64) (sum float64) { + for i := 1; i <= 29; i++ { + d1 := float64(i) / 29 + + d2 := 1.0 + var s1 float64 + for j := 1; j < len(x); j++ { + s1 += float64(j) * d2 * x[j] + d2 *= d1 + } + + d2 = 1.0 + var s2 float64 + for _, v := range x { + s2 += d2 * v + d2 *= d1 + } + + t := s1 - s2*s2 - 1 + sum += t * t + } + t := x[1] - x[0]*x[0] - 1 + sum += x[0]*x[0] + t*t + return sum +} + +func (Watson) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 29; i++ { + d1 := float64(i) / 29 + + d2 := 1.0 + var s1 float64 + for j := 1; j < len(x); j++ { + s1 += float64(j) * d2 * x[j] + d2 *= d1 + } + + d2 = 1.0 + var s2 float64 + for _, v := range x { + s2 += d2 * v + d2 *= d1 + } + + t := s1 - s2*s2 - 1 + s3 := 2 * d1 * s2 + d2 = 2 / d1 + for j := range x { + grad[j] += d2 * (float64(j) - s3) * t + d2 *= d1 + } + } + t := x[1] - x[0]*x[0] - 1 + grad[0] += x[0] * (2 - 4*t) + grad[1] += 2 * t +} + +func (Watson) Hess(hess mat.MutableSymmetric, x []float64) { + dim := len(x) + if dim != hess.Symmetric() { + panic("incorrect size of the Hessian") + } + + for j := 0; j < dim; j++ { + for k := j; k < dim; k++ { + hess.SetSym(j, k, 0) + } + } + for i := 1; i <= 29; i++ { + d1 := float64(i) / 29 + d2 := 1.0 + var s1 float64 + for j := 1; j < dim; j++ { + s1 += float64(j) * d2 * x[j] + d2 *= d1 + } + + d2 = 1.0 + var s2 float64 + for _, v := range x { + s2 += d2 * v + d2 *= d1 + } + + t := s1 - s2*s2 - 1 + s3 := 2 * d1 * s2 + d2 = 2 / d1 + th := 2 * d1 * d1 * t + for j := 0; j < dim; j++ { + v := float64(j) - s3 + d3 := 1 / d1 + for k := 0; k <= j; k++ { + hess.SetSym(k, j, hess.At(k, j)+d2*d3*(v*(float64(k)-s3)-th)) + d3 *= d1 + } + d2 *= d1 + } + } + t1 := x[1] - x[0]*x[0] - 1 + hess.SetSym(0, 0, hess.At(0, 0)+8*x[0]*x[0]+2-4*t1) + hess.SetSym(0, 1, hess.At(0, 1)-4*x[0]) + hess.SetSym(1, 1, hess.At(1, 1)+2) +} diff --git a/vendor/gonum.org/v1/gonum/floats/README.md b/vendor/gonum.org/v1/gonum/floats/README.md new file mode 100644 index 00000000..ee867bb7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/floats/README.md @@ -0,0 +1,4 @@ +# Gonum floats [![GoDoc](https://godoc.org/gonum.org/v1/gonum/floats?status.svg)](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. diff --git a/vendor/gonum.org/v1/gonum/floats/doc.go b/vendor/gonum.org/v1/gonum/floats/doc.go new file mode 100644 index 00000000..a9bd5742 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/floats/doc.go @@ -0,0 +1,11 @@ +// 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" diff --git a/vendor/gonum.org/v1/gonum/floats/examples_test.go b/vendor/gonum.org/v1/gonum/floats/examples_test.go new file mode 100644 index 00000000..3bc59ad1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/floats/examples_test.go @@ -0,0 +1,104 @@ +// 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 ( + "fmt" +) + +// Set of examples for all the functions + +func ExampleAdd_simple() { + // Adding three slices together. Note that + // the result is stored in the first slice + s1 := []float64{1, 2, 3, 4} + s2 := []float64{5, 6, 7, 8} + s3 := []float64{1, 1, 1, 1} + Add(s1, s2) + Add(s1, s3) + + fmt.Println("s1 =", s1) + fmt.Println("s2 =", s2) + fmt.Println("s3 =", s3) + // Output: + // s1 = [7 9 11 13] + // s2 = [5 6 7 8] + // s3 = [1 1 1 1] +} + +func ExampleAdd_newslice() { + // If one wants to store the result in a + // new container, just make a new slice + s1 := []float64{1, 2, 3, 4} + s2 := []float64{5, 6, 7, 8} + s3 := []float64{1, 1, 1, 1} + dst := make([]float64, len(s1)) + + AddTo(dst, s1, s2) + Add(dst, s3) + + fmt.Println("dst =", dst) + fmt.Println("s1 =", s1) + fmt.Println("s2 =", s2) + fmt.Println("s3 =", s3) + // Output: + // dst = [7 9 11 13] + // s1 = [1 2 3 4] + // s2 = [5 6 7 8] + // s3 = [1 1 1 1] +} + +func ExampleAdd_unequallengths() { + // If the lengths of the slices are unknown, + // use Eqlen to check + s1 := []float64{1, 2, 3} + s2 := []float64{5, 6, 7, 8} + + eq := EqualLengths(s1, s2) + if eq { + Add(s1, s2) + } else { + fmt.Println("Unequal lengths") + } + // Output: + // Unequal lengths +} + +func ExampleAddConst() { + s := []float64{1, -2, 3, -4} + c := 5.0 + + AddConst(c, s) + + fmt.Println("s =", s) + // Output: + // s = [6 3 8 1] +} + +func ExampleCumProd() { + s := []float64{1, -2, 3, -4} + dst := make([]float64, len(s)) + + CumProd(dst, s) + + fmt.Println("dst =", dst) + fmt.Println("s =", s) + // Output: + // dst = [1 -2 -6 24] + // s = [1 -2 3 -4] +} + +func ExampleCumSum() { + s := []float64{1, -2, 3, -4} + dst := make([]float64, len(s)) + + CumSum(dst, s) + + fmt.Println("dst =", dst) + fmt.Println("s =", s) + // Output: + // dst = [1 -1 2 -2] + // s = [1 -2 3 -4] +} diff --git a/vendor/gonum.org/v1/gonum/floats/floats.go b/vendor/gonum.org/v1/gonum/floats/floats.go new file mode 100644 index 00000000..6a582b70 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/floats/floats.go @@ -0,0 +1,771 @@ +// 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) { + for i := range dst { + dst[i] += c + } +} + +// 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 s while tracking their original order. +// At the conclusion of Argsort, s will contain the original elements of s +// 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 := s[0] + var ind int + for i, v := range s { + if v > 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 { + min := s[0] + var ind int + for i, v := range s { + if v < 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 +} + +// Nearest returns the index of the element in s +// whose value is nearest to v. If several such +// elements exist, the lowest index is returned. +// Panics if len(s) == 0. +func Nearest(s []float64, v float64) int { + var ind int + dist := math.Abs(v - s[0]) + for i, val := range s { + newDist := math.Abs(v - val) + if newDist < dist { + dist = newDist + ind = i + } + } + return ind +} + +// NearestWithinSpan return the index of a hypothetical vector created +// by Span with length n and bounds l and u whose value is closest +// to v. NearestWithinSpan panics if u < l. If the value is greater than u or +// less than l, the function returns -1. +func NearestWithinSpan(n int, l, u float64, v float64) int { + if u < l { + panic("floats: upper bound greater than lower bound") + } + if v < l || v > u { + return -1 + } + // 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) + } +} + +// 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. +// +// 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") + } + 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 { + var sum float64 + for _, val := range s { + sum += val + } + return sum +} + +// 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 +} diff --git a/vendor/gonum.org/v1/gonum/floats/floats_test.go b/vendor/gonum.org/v1/gonum/floats/floats_test.go new file mode 100644 index 00000000..32e4a392 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/floats/floats_test.go @@ -0,0 +1,1403 @@ +// 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 ( + "math" + "math/rand" + "strconv" + "testing" +) + +const ( + EqTolerance = 1E-14 + Small = 10 + Medium = 1000 + Large = 100000 + Huge = 10000000 +) + +func AreSlicesEqual(t *testing.T, truth, comp []float64, str string) { + if !EqualApprox(comp, truth, EqTolerance) { + t.Errorf(str+". Expected %v, returned %v", truth, comp) + } +} + +func Panics(fun func()) (b bool) { + defer func() { + err := recover() + if err != nil { + b = true + } + }() + fun() + return +} + +func TestAdd(t *testing.T) { + a := []float64{1, 2, 3} + b := []float64{4, 5, 6} + c := []float64{7, 8, 9} + truth := []float64{12, 15, 18} + n := make([]float64, len(a)) + + Add(n, a) + Add(n, b) + Add(n, c) + AreSlicesEqual(t, truth, n, "Wrong addition of slices new receiver") + Add(a, b) + Add(a, c) + AreSlicesEqual(t, truth, n, "Wrong addition of slices for no new receiver") + + // Test that it panics + if !Panics(func() { Add(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Did not panic with length mismatch") + } +} + +func TestAddTo(t *testing.T) { + a := []float64{1, 2, 3} + b := []float64{4, 5, 6} + truth := []float64{5, 7, 9} + n1 := make([]float64, len(a)) + + n2 := AddTo(n1, a, b) + AreSlicesEqual(t, truth, n1, "Bad addition from mutator") + AreSlicesEqual(t, truth, n2, "Bad addition from returned slice") + + // Test that it panics + if !Panics(func() { AddTo(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) { + t.Errorf("Did not panic with length mismatch") + } + if !Panics(func() { AddTo(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Did not panic with length mismatch") + } + +} + +func TestAddConst(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + c := 6.0 + truth := []float64{9, 10, 7, 13, 11} + AddConst(c, s) + AreSlicesEqual(t, truth, s, "Wrong addition of constant") +} + +func TestAddScaled(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + alpha := 6.0 + dst := []float64{1, 2, 3, 4, 5} + ans := []float64{19, 26, 9, 46, 35} + AddScaled(dst, alpha, s) + if !EqualApprox(dst, ans, EqTolerance) { + t.Errorf("Adding scaled did not match") + } + short := []float64{1} + if !Panics(func() { AddScaled(dst, alpha, short) }) { + t.Errorf("Doesn't panic if s is smaller than dst") + } + if !Panics(func() { AddScaled(short, alpha, s) }) { + t.Errorf("Doesn't panic if dst is smaller than s") + } +} + +func TestAddScaledTo(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + alpha := 6.0 + y := []float64{1, 2, 3, 4, 5} + dst1 := make([]float64, 5) + ans := []float64{19, 26, 9, 46, 35} + dst2 := AddScaledTo(dst1, y, alpha, s) + if !EqualApprox(dst1, ans, EqTolerance) { + t.Errorf("AddScaledTo did not match for mutator") + } + if !EqualApprox(dst2, ans, EqTolerance) { + t.Errorf("AddScaledTo did not match for returned slice") + } + AddScaledTo(dst1, y, alpha, s) + if !EqualApprox(dst1, ans, EqTolerance) { + t.Errorf("Reusing dst did not match") + } + short := []float64{1} + if !Panics(func() { AddScaledTo(dst1, y, alpha, short) }) { + t.Errorf("Doesn't panic if s is smaller than dst") + } + if !Panics(func() { AddScaledTo(short, y, alpha, s) }) { + t.Errorf("Doesn't panic if dst is smaller than s") + } + if !Panics(func() { AddScaledTo(dst1, short, alpha, s) }) { + t.Errorf("Doesn't panic if y is smaller than dst") + } +} + +func TestArgsort(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + inds := make([]int, len(s)) + + Argsort(s, inds) + + sortedS := []float64{1, 3, 4, 5, 7} + trueInds := []int{2, 0, 1, 4, 3} + + if !Equal(s, sortedS) { + t.Error("elements not sorted correctly") + } + for i := range trueInds { + if trueInds[i] != inds[i] { + t.Error("inds not correct") + } + } + + inds = []int{1, 2} + if !Panics(func() { Argsort(s, inds) }) { + t.Error("does not panic if lengths do not match") + } +} + +func TestCount(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + f := func(v float64) bool { return v > 3.5 } + truth := 3 + n := Count(f, s) + if n != truth { + t.Errorf("Wrong number of elements counted") + } +} + +func TestCumProd(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + receiver := make([]float64, len(s)) + result := CumProd(receiver, s) + truth := []float64{3, 12, 12, 84, 420} + AreSlicesEqual(t, truth, receiver, "Wrong cumprod mutated with new receiver") + AreSlicesEqual(t, truth, result, "Wrong cumprod result with new receiver") + CumProd(receiver, s) + AreSlicesEqual(t, truth, receiver, "Wrong cumprod returned with reused receiver") + + // Test that it panics + if !Panics(func() { CumProd(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Did not panic with length mismatch") + } + + // Test empty CumProd + emptyReceiver := make([]float64, 0) + truth = []float64{} + CumProd(emptyReceiver, emptyReceiver) + AreSlicesEqual(t, truth, emptyReceiver, "Wrong cumprod returned with empty receiver") + +} + +func TestCumSum(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + receiver := make([]float64, len(s)) + result := CumSum(receiver, s) + truth := []float64{3, 7, 8, 15, 20} + AreSlicesEqual(t, truth, receiver, "Wrong cumsum mutated with new receiver") + AreSlicesEqual(t, truth, result, "Wrong cumsum returned with new receiver") + CumSum(receiver, s) + AreSlicesEqual(t, truth, receiver, "Wrong cumsum returned with reused receiver") + + // Test that it panics + if !Panics(func() { CumSum(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Did not panic with length mismatch") + } + + // Test empty CumSum + emptyReceiver := make([]float64, 0) + truth = []float64{} + CumSum(emptyReceiver, emptyReceiver) + AreSlicesEqual(t, truth, emptyReceiver, "Wrong cumsum returned with empty receiver") + +} + +func TestDistance(t *testing.T) { + norms := []float64{1, 2, 4, math.Inf(1)} + slices := []struct { + s []float64 + t []float64 + }{ + { + nil, + nil, + }, + { + []float64{8, 9, 10, -12}, + []float64{8, 9, 10, -12}, + }, + { + []float64{1, 2, 3, -4, -5, 8}, + []float64{-9.2, -6.8, 9, -3, -2, 1}, + }, + } + + for j, test := range slices { + tmp := make([]float64, len(test.s)) + for i, L := range norms { + dist := Distance(test.s, test.t, L) + copy(tmp, test.s) + Sub(tmp, test.t) + norm := Norm(tmp, L) + if dist != norm { // Use equality because they should be identical + t.Errorf("Distance does not match norm for case %v, %v. Expected %v, Found %v.", i, j, norm, dist) + } + } + } + + if !Panics(func() { Distance([]float64{}, norms, 1) }) { + t.Errorf("Did not panic with unequal lengths") + } + +} + +func TestDiv(t *testing.T) { + s1 := []float64{5, 12, 27} + s2 := []float64{1, 2, 3} + ans := []float64{5, 6, 9} + Div(s1, s2) + if !EqualApprox(s1, ans, EqTolerance) { + t.Errorf("Mul doesn't give correct answer") + } + s1short := []float64{1} + if !Panics(func() { Div(s1short, s2) }) { + t.Errorf("Did not panic with unequal lengths") + } + s2short := []float64{1} + if !Panics(func() { Div(s1, s2short) }) { + t.Errorf("Did not panic with unequal lengths") + } +} + +func TestDivTo(t *testing.T) { + s1 := []float64{5, 12, 27} + s1orig := []float64{5, 12, 27} + s2 := []float64{1, 2, 3} + s2orig := []float64{1, 2, 3} + dst1 := make([]float64, 3) + ans := []float64{5, 6, 9} + dst2 := DivTo(dst1, s1, s2) + if !EqualApprox(dst1, ans, EqTolerance) { + t.Errorf("DivTo doesn't give correct answer in mutated slice") + } + if !EqualApprox(dst2, ans, EqTolerance) { + t.Errorf("DivTo doesn't give correct answer in returned slice") + } + if !EqualApprox(s1, s1orig, EqTolerance) { + t.Errorf("S1 changes during multo") + } + if !EqualApprox(s2, s2orig, EqTolerance) { + t.Errorf("s2 changes during multo") + } + DivTo(dst1, s1, s2) + if !EqualApprox(dst1, ans, EqTolerance) { + t.Errorf("DivTo doesn't give correct answer reusing dst") + } + dstShort := []float64{1} + if !Panics(func() { DivTo(dstShort, s1, s2) }) { + t.Errorf("Did not panic with s1 wrong length") + } + s1short := []float64{1} + if !Panics(func() { DivTo(dst1, s1short, s2) }) { + t.Errorf("Did not panic with s1 wrong length") + } + s2short := []float64{1} + if !Panics(func() { DivTo(dst1, s1, s2short) }) { + t.Errorf("Did not panic with s2 wrong length") + } +} + +func TestDot(t *testing.T) { + s1 := []float64{1, 2, 3, 4} + s2 := []float64{-3, 4, 5, -6} + truth := -4.0 + ans := Dot(s1, s2) + if ans != truth { + t.Errorf("Dot product computed incorrectly") + } + + // Test that it panics + if !Panics(func() { Dot(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Did not panic with length mismatch") + } +} + +func TestEquals(t *testing.T) { + s1 := []float64{1, 2, 3, 4} + s2 := []float64{1, 2, 3, 4} + if !Equal(s1, s2) { + t.Errorf("Equal slices returned as unequal") + } + s2 = []float64{1, 2, 3, 4 + 1e-14} + if Equal(s1, s2) { + t.Errorf("Unequal slices returned as equal") + } + if Equal(s1, []float64{}) { + t.Errorf("Unequal slice lengths returned as equal") + } +} + +func TestEqualApprox(t *testing.T) { + s1 := []float64{1, 2, 3, 4} + s2 := []float64{1, 2, 3, 4 + 1e-10} + if EqualApprox(s1, s2, 1e-13) { + t.Errorf("Unequal slices returned as equal for absolute") + } + if !EqualApprox(s1, s2, 1e-5) { + t.Errorf("Equal slices returned as unequal for absolute") + } + s1 = []float64{1, 2, 3, 1000} + s2 = []float64{1, 2, 3, 1000 * (1 + 1e-7)} + if EqualApprox(s1, s2, 1e-8) { + t.Errorf("Unequal slices returned as equal for relative") + } + if !EqualApprox(s1, s2, 1e-5) { + t.Errorf("Equal slices returned as unequal for relative") + } + if EqualApprox(s1, []float64{}, 1e-5) { + t.Errorf("Unequal slice lengths returned as equal") + } +} + +func TestEqualFunc(t *testing.T) { + s1 := []float64{1, 2, 3, 4} + s2 := []float64{1, 2, 3, 4} + eq := func(x, y float64) bool { return x == y } + if !EqualFunc(s1, s2, eq) { + t.Errorf("Equal slices returned as unequal") + } + s2 = []float64{1, 2, 3, 4 + 1e-14} + if EqualFunc(s1, s2, eq) { + t.Errorf("Unequal slices returned as equal") + } + if EqualFunc(s1, []float64{}, eq) { + t.Errorf("Unequal slice lengths returned as equal") + } +} + +func TestEqualsRelative(t *testing.T) { + var equalityTests = []struct { + a, b float64 + tol float64 + equal bool + }{ + {1000000, 1000001, 0, true}, + {1000001, 1000000, 0, true}, + {10000, 10001, 0, false}, + {10001, 10000, 0, false}, + {-1000000, -1000001, 0, true}, + {-1000001, -1000000, 0, true}, + {-10000, -10001, 0, false}, + {-10001, -10000, 0, false}, + {1.0000001, 1.0000002, 0, true}, + {1.0000002, 1.0000001, 0, true}, + {1.0002, 1.0001, 0, false}, + {1.0001, 1.0002, 0, false}, + {-1.000001, -1.000002, 0, true}, + {-1.000002, -1.000001, 0, true}, + {-1.0001, -1.0002, 0, false}, + {-1.0002, -1.0001, 0, false}, + {0.000000001000001, 0.000000001000002, 0, true}, + {0.000000001000002, 0.000000001000001, 0, true}, + {0.000000000001002, 0.000000000001001, 0, false}, + {0.000000000001001, 0.000000000001002, 0, false}, + {-0.000000001000001, -0.000000001000002, 0, true}, + {-0.000000001000002, -0.000000001000001, 0, true}, + {-0.000000000001002, -0.000000000001001, 0, false}, + {-0.000000000001001, -0.000000000001002, 0, false}, + {0, 0, 0, true}, + {0, -0, 0, true}, + {-0, -0, 0, true}, + {0.00000001, 0, 0, false}, + {0, 0.00000001, 0, false}, + {-0.00000001, 0, 0, false}, + {0, -0.00000001, 0, false}, + {0, 1e-310, 0.01, true}, + {1e-310, 0, 0.01, true}, + {1e-310, 0, 0.000001, false}, + {0, 1e-310, 0.000001, false}, + {0, -1e-310, 0.1, true}, + {-1e-310, 0, 0.1, true}, + {-1e-310, 0, 0.00000001, false}, + {0, -1e-310, 0.00000001, false}, + {math.Inf(1), math.Inf(1), 0, true}, + {math.Inf(-1), math.Inf(-1), 0, true}, + {math.Inf(-1), math.Inf(1), 0, false}, + {math.Inf(1), math.MaxFloat64, 0, false}, + {math.Inf(-1), -math.MaxFloat64, 0, false}, + {math.NaN(), math.NaN(), 0, false}, + {math.NaN(), 0, 0, false}, + {-0, math.NaN(), 0, false}, + {math.NaN(), -0, 0, false}, + {0, math.NaN(), 0, false}, + {math.NaN(), math.Inf(1), 0, false}, + {math.Inf(1), math.NaN(), 0, false}, + {math.NaN(), math.Inf(-1), 0, false}, + {math.Inf(-1), math.NaN(), 0, false}, + {math.NaN(), math.MaxFloat64, 0, false}, + {math.MaxFloat64, math.NaN(), 0, false}, + {math.NaN(), -math.MaxFloat64, 0, false}, + {-math.MaxFloat64, math.NaN(), 0, false}, + {math.NaN(), math.SmallestNonzeroFloat64, 0, false}, + {math.SmallestNonzeroFloat64, math.NaN(), 0, false}, + {math.NaN(), -math.SmallestNonzeroFloat64, 0, false}, + {-math.SmallestNonzeroFloat64, math.NaN(), 0, false}, + {1.000000001, -1.0, 0, false}, + {-1.0, 1.000000001, 0, false}, + {-1.000000001, 1.0, 0, false}, + {1.0, -1.000000001, 0, false}, + {10 * math.SmallestNonzeroFloat64, 10 * -math.SmallestNonzeroFloat64, 0, true}, + {1e11 * math.SmallestNonzeroFloat64, 1e11 * -math.SmallestNonzeroFloat64, 0, false}, + {math.SmallestNonzeroFloat64, -math.SmallestNonzeroFloat64, 0, true}, + {-math.SmallestNonzeroFloat64, math.SmallestNonzeroFloat64, 0, true}, + {math.SmallestNonzeroFloat64, 0, 0, true}, + {0, math.SmallestNonzeroFloat64, 0, true}, + {-math.SmallestNonzeroFloat64, 0, 0, true}, + {0, -math.SmallestNonzeroFloat64, 0, true}, + {0.000000001, -math.SmallestNonzeroFloat64, 0, false}, + {0.000000001, math.SmallestNonzeroFloat64, 0, false}, + {math.SmallestNonzeroFloat64, 0.000000001, 0, false}, + {-math.SmallestNonzeroFloat64, 0.000000001, 0, false}, + } + for _, ts := range equalityTests { + if ts.tol == 0 { + ts.tol = 1e-5 + } + if equal := EqualWithinRel(ts.a, ts.b, ts.tol); equal != ts.equal { + t.Errorf("Relative equality of %g and %g with tolerance %g returned: %v. Expected: %v", + ts.a, ts.b, ts.tol, equal, ts.equal) + } + } +} + +func nextAfterN(x, y float64, n int) float64 { + for i := 0; i < n; i++ { + x = math.Nextafter(x, y) + } + return x +} + +func TestEqualsULP(t *testing.T) { + if f := 67329.242; !EqualWithinULP(f, nextAfterN(f, math.Inf(1), 10), 10) { + t.Errorf("Equal values returned as unequal") + } + if f := 67329.242; EqualWithinULP(f, nextAfterN(f, math.Inf(1), 5), 1) { + t.Errorf("Unequal values returned as equal") + } + if f := 67329.242; EqualWithinULP(nextAfterN(f, math.Inf(1), 5), f, 1) { + t.Errorf("Unequal values returned as equal") + } + if f := nextAfterN(0, math.Inf(1), 2); !EqualWithinULP(f, nextAfterN(f, math.Inf(-1), 5), 10) { + t.Errorf("Equal values returned as unequal") + } + if !EqualWithinULP(67329.242, 67329.242, 10) { + t.Errorf("Equal float64s not returned as equal") + } + if EqualWithinULP(1, math.NaN(), 10) { + t.Errorf("NaN returned as equal") + } + +} + +func TestEqualLengths(t *testing.T) { + s1 := []float64{1, 2, 3, 4} + s2 := []float64{1, 2, 3, 4} + s3 := []float64{1, 2, 3} + if !EqualLengths(s1, s2) { + t.Errorf("Equal lengths returned as unequal") + } + if EqualLengths(s1, s3) { + t.Errorf("Unequal lengths returned as equal") + } + if !EqualLengths(s1) { + t.Errorf("Single slice returned as unequal") + } + if !EqualLengths() { + t.Errorf("No slices returned as unequal") + } +} + +func eqIntSlice(one, two []int) string { + if len(one) != len(two) { + return "Length mismatch" + } + for i, val := range one { + if val != two[i] { + return "Index " + strconv.Itoa(i) + " mismatch" + } + } + return "" +} + +func TestFind(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + f := func(v float64) bool { return v > 3.5 } + allTrueInds := []int{1, 3, 4} + + // Test finding first two elements + inds, err := Find(nil, f, s, 2) + if err != nil { + t.Errorf("Find first two: Improper error return") + } + trueInds := allTrueInds[:2] + str := eqIntSlice(inds, trueInds) + if str != "" { + t.Errorf("Find first two: " + str) + } + + // Test finding no elements with non nil slice + inds = []int{1, 2, 3, 4, 5, 6} + inds, err = Find(inds, f, s, 0) + if err != nil { + t.Errorf("Find no elements: Improper error return") + } + str = eqIntSlice(inds, []int{}) + if str != "" { + t.Errorf("Find no non-nil: " + str) + } + + // Test finding first two elements with non nil slice + inds = []int{1, 2, 3, 4, 5, 6} + inds, err = Find(inds, f, s, 2) + if err != nil { + t.Errorf("Find first two non-nil: Improper error return") + } + str = eqIntSlice(inds, trueInds) + if str != "" { + t.Errorf("Find first two non-nil: " + str) + } + + // Test finding too many elements + inds, err = Find(inds, f, s, 4) + if err == nil { + t.Errorf("Request too many: No error returned") + } + str = eqIntSlice(inds, allTrueInds) + if str != "" { + t.Errorf("Request too many: Does not match all of the inds: " + str) + } + + // Test finding all elements + inds, err = Find(nil, f, s, -1) + if err != nil { + t.Errorf("Find all: Improper error returned") + } + str = eqIntSlice(inds, allTrueInds) + if str != "" { + t.Errorf("Find all: Does not match all of the inds: " + str) + } +} + +func TestHasNaN(t *testing.T) { + for i, test := range []struct { + s []float64 + ans bool + }{ + {}, + { + s: []float64{1, 2, 3, 4}, + }, + { + s: []float64{1, math.NaN(), 3, 4}, + ans: true, + }, + { + s: []float64{1, 2, 3, math.NaN()}, + ans: true, + }, + } { + b := HasNaN(test.s) + if b != test.ans { + t.Errorf("HasNaN mismatch case %d. Expected %v, Found %v", i, test.ans, b) + } + } +} + +func TestLogSpan(t *testing.T) { + receiver1 := make([]float64, 6) + truth := []float64{0.001, 0.01, 0.1, 1, 10, 100} + receiver2 := LogSpan(receiver1, 0.001, 100) + tst := make([]float64, 6) + for i := range truth { + tst[i] = receiver1[i] / truth[i] + } + comp := make([]float64, 6) + for i := range comp { + comp[i] = 1 + } + AreSlicesEqual(t, comp, tst, "Improper logspace from mutator") + + for i := range truth { + tst[i] = receiver2[i] / truth[i] + } + AreSlicesEqual(t, comp, tst, "Improper logspace from returned slice") + + if !Panics(func() { LogSpan(nil, 1, 5) }) { + t.Errorf("Span accepts nil argument") + } + if !Panics(func() { LogSpan(make([]float64, 1), 1, 5) }) { + t.Errorf("Span accepts argument of len = 1") + } +} + +func TestLogSumExp(t *testing.T) { + s := []float64{1, 2, 3, 4, 5} + val := LogSumExp(s) + // http://www.wolframalpha.com/input/?i=log%28exp%281%29+%2B+exp%282%29+%2B+exp%283%29+%2B+exp%284%29+%2B+exp%285%29%29 + truth := 5.4519143959375933331957225109748087179338972737576824 + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Wrong logsumexp for many values") + } + s = []float64{1, 2} + // http://www.wolframalpha.com/input/?i=log%28exp%281%29+%2B+exp%282%29%29 + truth = 2.3132616875182228340489954949678556419152800856703483 + val = LogSumExp(s) + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Wrong logsumexp for two values. %v expected, %v found", truth, val) + } + // This case would normally underflow + s = []float64{-1001, -1002, -1003, -1004, -1005} + // http://www.wolframalpha.com/input/?i=log%28exp%28-1001%29%2Bexp%28-1002%29%2Bexp%28-1003%29%2Bexp%28-1004%29%2Bexp%28-1005%29%29 + truth = -1000.54808560406240666680427748902519128206610272624 + val = LogSumExp(s) + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Doesn't match for underflow case. %v expected, %v found", truth, val) + } + // positive infinite case + s = []float64{1, 2, 3, 4, 5, math.Inf(1)} + val = LogSumExp(s) + truth = math.Inf(1) + if val != truth { + t.Errorf("Doesn't match for pos Infinity case. %v expected, %v found", truth, val) + } + // negative infinite case + s = []float64{1, 2, 3, 4, 5, math.Inf(-1)} + val = LogSumExp(s) + truth = 5.4519143959375933331957225109748087179338972737576824 // same as first case + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Wrong logsumexp for values with negative infinity") + } + +} + +func TestMaxAndIdx(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + ind := MaxIdx(s) + val := Max(s) + if val != 7 { + t.Errorf("Wrong value returned") + } + if ind != 3 { + t.Errorf("Wrong index returned") + } +} + +func TestMinAndIdx(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + ind := MinIdx(s) + val := Min(s) + if val != 1 { + t.Errorf("Wrong value returned") + } + if ind != 2 { + t.Errorf("Wrong index returned") + } +} + +func TestMul(t *testing.T) { + s1 := []float64{1, 2, 3} + s2 := []float64{1, 2, 3} + ans := []float64{1, 4, 9} + Mul(s1, s2) + if !EqualApprox(s1, ans, EqTolerance) { + t.Errorf("Mul doesn't give correct answer") + } + s1short := []float64{1} + if !Panics(func() { Mul(s1short, s2) }) { + t.Errorf("Did not panic with unequal lengths") + } + s2short := []float64{1} + if !Panics(func() { Mul(s1, s2short) }) { + t.Errorf("Did not panic with unequal lengths") + } +} + +func TestMulTo(t *testing.T) { + s1 := []float64{1, 2, 3} + s1orig := []float64{1, 2, 3} + s2 := []float64{1, 2, 3} + s2orig := []float64{1, 2, 3} + dst1 := make([]float64, 3) + ans := []float64{1, 4, 9} + dst2 := MulTo(dst1, s1, s2) + if !EqualApprox(dst1, ans, EqTolerance) { + t.Errorf("MulTo doesn't give correct answer in mutated slice") + } + if !EqualApprox(dst2, ans, EqTolerance) { + t.Errorf("MulTo doesn't give correct answer in returned slice") + } + if !EqualApprox(s1, s1orig, EqTolerance) { + t.Errorf("S1 changes during multo") + } + if !EqualApprox(s2, s2orig, EqTolerance) { + t.Errorf("s2 changes during multo") + } + MulTo(dst1, s1, s2) + if !EqualApprox(dst1, ans, EqTolerance) { + t.Errorf("MulTo doesn't give correct answer reusing dst") + } + dstShort := []float64{1} + if !Panics(func() { MulTo(dstShort, s1, s2) }) { + t.Errorf("Did not panic with s1 wrong length") + } + s1short := []float64{1} + if !Panics(func() { MulTo(dst1, s1short, s2) }) { + t.Errorf("Did not panic with s1 wrong length") + } + s2short := []float64{1} + if !Panics(func() { MulTo(dst1, s1, s2short) }) { + t.Errorf("Did not panic with s2 wrong length") + } +} + +func TestNearest(t *testing.T) { + s := []float64{6.2, 3, 5, 6.2, 8} + ind := Nearest(s, 2.0) + if ind != 1 { + t.Errorf("Wrong index returned when value is less than all of elements") + } + ind = Nearest(s, 9.0) + if ind != 4 { + t.Errorf("Wrong index returned when value is greater than all of elements") + } + ind = Nearest(s, 3.1) + if ind != 1 { + t.Errorf("Wrong index returned when value is greater than closest element") + } + ind = Nearest(s, 3.1) + if ind != 1 { + t.Errorf("Wrong index returned when value is greater than closest element") + } + ind = Nearest(s, 2.9) + if ind != 1 { + t.Errorf("Wrong index returned when value is less than closest element") + } + ind = Nearest(s, 3) + if ind != 1 { + t.Errorf("Wrong index returned when value is equal to element") + } + ind = Nearest(s, 6.2) + if ind != 0 { + t.Errorf("Wrong index returned when value is equal to several elements") + } + ind = Nearest(s, 4) + if ind != 1 { + t.Errorf("Wrong index returned when value is exactly between two closest elements") + } +} + +func TestNearestWithinSpan(t *testing.T) { + if !Panics(func() { NearestWithinSpan(10, 8, 2, 4.5) }) { + t.Errorf("Did not panic when upper bound is lower than greater bound") + } + for i, test := range []struct { + length int + lower float64 + upper float64 + value float64 + idx int + }{ + { + length: 13, + lower: 7, + upper: 8.2, + value: 6, + idx: -1, + }, + { + length: 13, + lower: 7, + upper: 8.2, + value: 10, + idx: -1, + }, + { + length: 13, + lower: 7, + upper: 8.2, + value: 7.19, + idx: 2, + }, + { + length: 13, + lower: 7, + upper: 8.2, + value: 7.21, + idx: 2, + }, + { + length: 13, + lower: 7, + upper: 8.2, + value: 7.2, + idx: 2, + }, + { + length: 13, + lower: 7, + upper: 8.2, + value: 7.151, + idx: 2, + }, + { + length: 13, + lower: 7, + upper: 8.2, + value: 7.249, + idx: 2, + }, + } { + if idx := NearestWithinSpan(test.length, test.lower, test.upper, test.value); test.idx != idx { + t.Errorf("Case %v mismatch: Want: %v, Got: %v", i, test.idx, idx) + } + } +} + +func TestNorm(t *testing.T) { + s := []float64{-1, -3.4, 5, -6} + val := Norm(s, math.Inf(1)) + truth := 6.0 + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) + } + // http://www.wolframalpha.com/input/?i=%28%28-1%29%5E2+%2B++%28-3.4%29%5E2+%2B+5%5E2%2B++6%5E2%29%5E%281%2F2%29 + val = Norm(s, 2) + truth = 8.5767126569566267590651614132751986658027271236078592 + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) + } + // http://www.wolframalpha.com/input/?i=%28%28%7C-1%7C%29%5E3+%2B++%28%7C-3.4%7C%29%5E3+%2B+%7C5%7C%5E3%2B++%7C6%7C%5E3%29%5E%281%2F3%29 + val = Norm(s, 3) + truth = 7.2514321388020228478109121239004816430071237369356233 + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) + } + + //http://www.wolframalpha.com/input/?i=%7C-1%7C+%2B+%7C-3.4%7C+%2B+%7C5%7C%2B++%7C6%7C + val = Norm(s, 1) + truth = 15.4 + if math.Abs(val-truth) > EqTolerance { + t.Errorf("Doesn't match for inf norm. %v expected, %v found", truth, val) + } +} + +func TestProd(t *testing.T) { + s := []float64{} + val := Prod(s) + if val != 1 { + t.Errorf("Val not returned as default when slice length is zero") + } + s = []float64{3, 4, 1, 7, 5} + val = Prod(s) + if val != 420 { + t.Errorf("Wrong prod returned. Expected %v returned %v", 420, val) + } +} + +func TestReverse(t *testing.T) { + for _, s := range [][]float64{ + {0}, + {1, 0}, + {2, 1, 0}, + {3, 2, 1, 0}, + {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + } { + Reverse(s) + for i, v := range s { + if v != float64(i) { + t.Errorf("unexpected values for element %d: got:%v want:%v", i, v, i) + } + } + } +} + +func TestRound(t *testing.T) { + for _, test := range []struct { + x float64 + prec int + want float64 + }{ + {x: 0, prec: 1, want: 0}, + {x: math.Inf(1), prec: 1, want: math.Inf(1)}, + {x: math.NaN(), prec: 1, want: math.NaN()}, + {x: func() float64 { var f float64; return -f }(), prec: 1, want: 0}, + {x: math.MaxFloat64 / 2, prec: 1, want: math.MaxFloat64 / 2}, + {x: 1 << 64, prec: 1, want: 1 << 64}, + {x: 454.4445, prec: 3, want: 454.445}, + {x: 454.44445, prec: 4, want: 454.4445}, + {x: 0.42499, prec: 4, want: 0.425}, + {x: 0.42599, prec: 4, want: 0.426}, + {x: 0.424999999999993, prec: 2, want: 0.42}, + {x: 0.425, prec: 2, want: 0.43}, + {x: 0.425000000000001, prec: 2, want: 0.43}, + {x: 123.4244999999999, prec: 3, want: 123.424}, + {x: 123.4245, prec: 3, want: 123.425}, + {x: 123.4245000000001, prec: 3, want: 123.425}, + + {x: 454.45, prec: 0, want: 454}, + {x: 454.45, prec: 1, want: 454.5}, + {x: 454.45, prec: 2, want: 454.45}, + {x: 454.45, prec: 3, want: 454.45}, + {x: 454.445, prec: 0, want: 454}, + {x: 454.445, prec: 1, want: 454.4}, + {x: 454.445, prec: 2, want: 454.45}, + {x: 454.445, prec: 3, want: 454.445}, + {x: 454.445, prec: 4, want: 454.445}, + {x: 454.55, prec: 0, want: 455}, + {x: 454.55, prec: 1, want: 454.6}, + {x: 454.55, prec: 2, want: 454.55}, + {x: 454.55, prec: 3, want: 454.55}, + {x: 454.455, prec: 0, want: 454}, + {x: 454.455, prec: 1, want: 454.5}, + {x: 454.455, prec: 2, want: 454.46}, + {x: 454.455, prec: 3, want: 454.455}, + {x: 454.455, prec: 4, want: 454.455}, + + // Negative precision. + {x: 454.45, prec: -1, want: 450}, + {x: 454.45, prec: -2, want: 500}, + {x: 500, prec: -3, want: 1000}, + {x: 500, prec: -4, want: 0}, + {x: 1500, prec: -3, want: 2000}, + {x: 1500, prec: -4, want: 0}, + } { + for _, sign := range []float64{1, -1} { + got := Round(sign*test.x, test.prec) + want := sign * test.want + if want == 0 { + want = 0 + } + if (got != want || math.Signbit(got) != math.Signbit(want)) && !(math.IsNaN(got) && math.IsNaN(want)) { + t.Errorf("unexpected result for Round(%g, %d): got: %g, want: %g", sign*test.x, test.prec, got, want) + } + } + } +} + +func TestRoundEven(t *testing.T) { + for _, test := range []struct { + x float64 + prec int + want float64 + }{ + {x: 0, prec: 1, want: 0}, + {x: math.Inf(1), prec: 1, want: math.Inf(1)}, + {x: math.NaN(), prec: 1, want: math.NaN()}, + {x: func() float64 { var f float64; return -f }(), prec: 1, want: 0}, + {x: math.MaxFloat64 / 2, prec: 1, want: math.MaxFloat64 / 2}, + {x: 1 << 64, prec: 1, want: 1 << 64}, + {x: 454.4445, prec: 3, want: 454.444}, + {x: 454.44445, prec: 4, want: 454.4444}, + {x: 0.42499, prec: 4, want: 0.425}, + {x: 0.42599, prec: 4, want: 0.426}, + {x: 0.424999999999993, prec: 2, want: 0.42}, + {x: 0.425, prec: 2, want: 0.42}, + {x: 0.425000000000001, prec: 2, want: 0.43}, + {x: 123.4244999999999, prec: 3, want: 123.424}, + {x: 123.4245, prec: 3, want: 123.424}, + {x: 123.4245000000001, prec: 3, want: 123.425}, + + {x: 454.45, prec: 0, want: 454}, + {x: 454.45, prec: 1, want: 454.4}, + {x: 454.45, prec: 2, want: 454.45}, + {x: 454.45, prec: 3, want: 454.45}, + {x: 454.445, prec: 0, want: 454}, + {x: 454.445, prec: 1, want: 454.4}, + {x: 454.445, prec: 2, want: 454.44}, + {x: 454.445, prec: 3, want: 454.445}, + {x: 454.445, prec: 4, want: 454.445}, + {x: 454.55, prec: 0, want: 455}, + {x: 454.55, prec: 1, want: 454.6}, + {x: 454.55, prec: 2, want: 454.55}, + {x: 454.55, prec: 3, want: 454.55}, + {x: 454.455, prec: 0, want: 454}, + {x: 454.455, prec: 1, want: 454.5}, + {x: 454.455, prec: 2, want: 454.46}, + {x: 454.455, prec: 3, want: 454.455}, + {x: 454.455, prec: 4, want: 454.455}, + + // Negative precision. + {x: 454.45, prec: -1, want: 450}, + {x: 454.45, prec: -2, want: 500}, + {x: 500, prec: -3, want: 0}, + {x: 500, prec: -4, want: 0}, + {x: 1500, prec: -3, want: 2000}, + {x: 1500, prec: -4, want: 0}, + } { + for _, sign := range []float64{1, -1} { + got := RoundEven(sign*test.x, test.prec) + want := sign * test.want + if want == 0 { + want = 0 + } + if (got != want || math.Signbit(got) != math.Signbit(want)) && !(math.IsNaN(got) && math.IsNaN(want)) { + t.Errorf("unexpected result for RoundEven(%g, %d): got: %g, want: %g", sign*test.x, test.prec, got, want) + } + } + } +} + +func TestSame(t *testing.T) { + s1 := []float64{1, 2, 3, 4} + s2 := []float64{1, 2, 3, 4} + if !Same(s1, s2) { + t.Errorf("Equal slices returned as unequal") + } + s2 = []float64{1, 2, 3, 4 + 1e-14} + if Same(s1, s2) { + t.Errorf("Unequal slices returned as equal") + } + if Same(s1, []float64{}) { + t.Errorf("Unequal slice lengths returned as equal") + } + s1 = []float64{1, 2, math.NaN(), 4} + s2 = []float64{1, 2, math.NaN(), 4} + if !Same(s1, s2) { + t.Errorf("Slices with matching NaN values returned as unequal") + } + s1 = []float64{1, 2, math.NaN(), 4} + s2 = []float64{1, math.NaN(), 3, 4} + if !Same(s1, s2) { + t.Errorf("Slices with unmatching NaN values returned as equal") + } +} + +func TestScale(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + c := 5.0 + truth := []float64{15, 20, 5, 35, 25} + Scale(c, s) + AreSlicesEqual(t, truth, s, "Bad scaling") +} + +func TestSpan(t *testing.T) { + receiver1 := make([]float64, 5) + truth := []float64{1, 2, 3, 4, 5} + receiver2 := Span(receiver1, 1, 5) + AreSlicesEqual(t, truth, receiver1, "Improper linspace from mutator") + AreSlicesEqual(t, truth, receiver2, "Improper linspace from returned slice") + receiver1 = make([]float64, 6) + truth = []float64{0, 0.2, 0.4, 0.6, 0.8, 1.0} + Span(receiver1, 0, 1) + AreSlicesEqual(t, truth, receiver1, "Improper linspace") + if !Panics(func() { Span(nil, 1, 5) }) { + t.Errorf("Span accepts nil argument") + } + if !Panics(func() { Span(make([]float64, 1), 1, 5) }) { + t.Errorf("Span accepts argument of len = 1") + } +} + +func TestSub(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + v := []float64{1, 2, 3, 4, 5} + truth := []float64{2, 2, -2, 3, 0} + Sub(s, v) + AreSlicesEqual(t, truth, s, "Bad subtract") + // Test that it panics + if !Panics(func() { Sub(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Did not panic with length mismatch") + } +} + +func TestSubTo(t *testing.T) { + s := []float64{3, 4, 1, 7, 5} + v := []float64{1, 2, 3, 4, 5} + truth := []float64{2, 2, -2, 3, 0} + dst1 := make([]float64, len(s)) + dst2 := SubTo(dst1, s, v) + AreSlicesEqual(t, truth, dst1, "Bad subtract from mutator") + AreSlicesEqual(t, truth, dst2, "Bad subtract from returned slice") + // Test that all mismatch combinations panic + if !Panics(func() { SubTo(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) { + t.Errorf("Did not panic with dst different length") + } + if !Panics(func() { SubTo(make([]float64, 3), make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Did not panic with subtractor different length") + } + if !Panics(func() { SubTo(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Did not panic with subtractee different length") + } +} + +func TestSum(t *testing.T) { + s := []float64{} + val := Sum(s) + if val != 0 { + t.Errorf("Val not returned as default when slice length is zero") + } + s = []float64{3, 4, 1, 7, 5} + val = Sum(s) + if val != 20 { + t.Errorf("Wrong sum returned") + } +} + +func TestWithin(t *testing.T) { + for i, test := range []struct { + s []float64 + v float64 + idx int + panics bool + }{ + { + s: []float64{1, 2, 5, 9}, + v: 1, + idx: 0, + }, + { + s: []float64{1, 2, 5, 9}, + v: 9, + idx: -1, + }, + { + s: []float64{1, 2, 5, 9}, + v: 1.5, + idx: 0, + }, + { + s: []float64{1, 2, 5, 9}, + v: 2, + idx: 1, + }, + { + s: []float64{1, 2, 5, 9}, + v: 2.5, + idx: 1, + }, + { + s: []float64{1, 2, 5, 9}, + v: -3, + idx: -1, + }, + { + s: []float64{1, 2, 5, 9}, + v: 15, + idx: -1, + }, + { + s: []float64{1, 2, 5, 9}, + v: math.NaN(), + idx: -1, + }, + { + s: []float64{5, 2, 6}, + panics: true, + }, + { + panics: true, + }, + { + s: []float64{1}, + panics: true, + }, + } { + var idx int + panics := Panics(func() { idx = Within(test.s, test.v) }) + if panics { + if !test.panics { + t.Errorf("Case %v: bad panic", i) + } + continue + } + if test.panics { + if !panics { + t.Errorf("Case %v: did not panic when it should", i) + } + continue + } + if idx != test.idx { + t.Errorf("Case %v: Idx mismatch. Want: %v, got: %v", i, test.idx, idx) + } + } + +} + +func randomSlice(l int) []float64 { + s := make([]float64, l) + for i := range s { + s[i] = rand.Float64() + } + return s +} + +func benchmarkMin(b *testing.B, size int) { + s := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Min(s) + } +} +func BenchmarkMinSmall(b *testing.B) { benchmarkMin(b, Small) } +func BenchmarkMinMed(b *testing.B) { benchmarkMin(b, Medium) } +func BenchmarkMinLarge(b *testing.B) { benchmarkMin(b, Large) } +func BenchmarkMinHuge(b *testing.B) { benchmarkMin(b, Huge) } + +func benchmarkAdd(b *testing.B, size int) { + s1 := randomSlice(size) + s2 := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Add(s1, s2) + } +} +func BenchmarkAddSmall(b *testing.B) { benchmarkAdd(b, Small) } +func BenchmarkAddMed(b *testing.B) { benchmarkAdd(b, Medium) } +func BenchmarkAddLarge(b *testing.B) { benchmarkAdd(b, Large) } +func BenchmarkAddHuge(b *testing.B) { benchmarkAdd(b, Huge) } + +func benchmarkAddTo(b *testing.B, size int) { + s1 := randomSlice(size) + s2 := randomSlice(size) + dst := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + AddTo(dst, s1, s2) + } +} +func BenchmarkAddToSmall(b *testing.B) { benchmarkAddTo(b, Small) } +func BenchmarkAddToMed(b *testing.B) { benchmarkAddTo(b, Medium) } +func BenchmarkAddToLarge(b *testing.B) { benchmarkAddTo(b, Large) } +func BenchmarkAddToHuge(b *testing.B) { benchmarkAddTo(b, Huge) } + +func benchmarkCumProd(b *testing.B, size int) { + s := randomSlice(size) + dst := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + CumProd(dst, s) + } +} +func BenchmarkCumProdSmall(b *testing.B) { benchmarkCumProd(b, Small) } +func BenchmarkCumProdMed(b *testing.B) { benchmarkCumProd(b, Medium) } +func BenchmarkCumProdLarge(b *testing.B) { benchmarkCumProd(b, Large) } +func BenchmarkCumProdHuge(b *testing.B) { benchmarkCumProd(b, Huge) } + +func benchmarkCumSum(b *testing.B, size int) { + s := randomSlice(size) + dst := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + CumSum(dst, s) + } +} +func BenchmarkCumSumSmall(b *testing.B) { benchmarkCumSum(b, Small) } +func BenchmarkCumSumMed(b *testing.B) { benchmarkCumSum(b, Medium) } +func BenchmarkCumSumLarge(b *testing.B) { benchmarkCumSum(b, Large) } +func BenchmarkCumSumHuge(b *testing.B) { benchmarkCumSum(b, Huge) } + +func benchmarkDiv(b *testing.B, size int) { + s := randomSlice(size) + dst := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Div(dst, s) + } +} +func BenchmarkDivSmall(b *testing.B) { benchmarkDiv(b, Small) } +func BenchmarkDivMed(b *testing.B) { benchmarkDiv(b, Medium) } +func BenchmarkDivLarge(b *testing.B) { benchmarkDiv(b, Large) } +func BenchmarkDivHuge(b *testing.B) { benchmarkDiv(b, Huge) } + +func benchmarkDivTo(b *testing.B, size int) { + s1 := randomSlice(size) + s2 := randomSlice(size) + dst := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + DivTo(dst, s1, s2) + } +} +func BenchmarkDivToSmall(b *testing.B) { benchmarkDivTo(b, Small) } +func BenchmarkDivToMed(b *testing.B) { benchmarkDivTo(b, Medium) } +func BenchmarkDivToLarge(b *testing.B) { benchmarkDivTo(b, Large) } +func BenchmarkDivToHuge(b *testing.B) { benchmarkDivTo(b, Huge) } + +func benchmarkSub(b *testing.B, size int) { + s1 := randomSlice(size) + s2 := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Sub(s1, s2) + } +} +func BenchmarkSubSmall(b *testing.B) { benchmarkSub(b, Small) } +func BenchmarkSubMed(b *testing.B) { benchmarkSub(b, Medium) } +func BenchmarkSubLarge(b *testing.B) { benchmarkSub(b, Large) } +func BenchmarkSubHuge(b *testing.B) { benchmarkSub(b, Huge) } + +func benchmarkSubTo(b *testing.B, size int) { + s1 := randomSlice(size) + s2 := randomSlice(size) + dst := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + SubTo(dst, s1, s2) + } +} +func BenchmarkSubToSmall(b *testing.B) { benchmarkSubTo(b, Small) } +func BenchmarkSubToMed(b *testing.B) { benchmarkSubTo(b, Medium) } +func BenchmarkSubToLarge(b *testing.B) { benchmarkSubTo(b, Large) } +func BenchmarkSubToHuge(b *testing.B) { benchmarkSubTo(b, Huge) } + +func benchmarkLogSumExp(b *testing.B, size int) { + s := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + LogSumExp(s) + } +} +func BenchmarkLogSumExpSmall(b *testing.B) { benchmarkLogSumExp(b, Small) } +func BenchmarkLogSumExpMed(b *testing.B) { benchmarkLogSumExp(b, Medium) } +func BenchmarkLogSumExpLarge(b *testing.B) { benchmarkLogSumExp(b, Large) } +func BenchmarkLogSumExpHuge(b *testing.B) { benchmarkLogSumExp(b, Huge) } + +func benchmarkDot(b *testing.B, size int) { + s1 := randomSlice(size) + s2 := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + Dot(s1, s2) + } +} +func BenchmarkDotSmall(b *testing.B) { benchmarkDot(b, Small) } +func BenchmarkDotMed(b *testing.B) { benchmarkDot(b, Medium) } +func BenchmarkDotLarge(b *testing.B) { benchmarkDot(b, Large) } +func BenchmarkDotHuge(b *testing.B) { benchmarkDot(b, Huge) } + +func benchmarkAddScaledTo(b *testing.B, size int) { + dst := randomSlice(size) + y := randomSlice(size) + s := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i++ { + AddScaledTo(dst, y, 2.3, s) + } +} +func BenchmarkAddScaledToSmall(b *testing.B) { benchmarkAddScaledTo(b, Small) } +func BenchmarkAddScaledToMedium(b *testing.B) { benchmarkAddScaledTo(b, Medium) } +func BenchmarkAddScaledToLarge(b *testing.B) { benchmarkAddScaledTo(b, Large) } +func BenchmarkAddScaledToHuge(b *testing.B) { benchmarkAddScaledTo(b, Huge) } + +func benchmarkScale(b *testing.B, size int) { + dst := randomSlice(size) + b.ResetTimer() + for i := 0; i < b.N; i += 2 { + Scale(2.0, dst) + Scale(0.5, dst) + } +} +func BenchmarkScaleSmall(b *testing.B) { benchmarkScale(b, Small) } +func BenchmarkScaleMedium(b *testing.B) { benchmarkScale(b, Medium) } +func BenchmarkScaleLarge(b *testing.B) { benchmarkScale(b, Large) } +func BenchmarkScaleHuge(b *testing.B) { benchmarkScale(b, Huge) } diff --git a/vendor/gonum.org/v1/gonum/floats/parse_example_test.go b/vendor/gonum.org/v1/gonum/floats/parse_example_test.go new file mode 100644 index 00000000..cb8c4e51 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/floats/parse_example_test.go @@ -0,0 +1,43 @@ +// Copyright ©2017 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_test + +import ( + "bufio" + "fmt" + "log" + "strings" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/stat" +) + +func ExampleParseWithNA() { + // Calculate the mean of a list of numbers + // ignoring missing values. + const data = `6 +missing +4 +` + + var vals, weights []float64 + sc := bufio.NewScanner(strings.NewReader(data)) + for sc.Scan() { + v, w, err := floats.ParseWithNA(sc.Text(), "missing") + if err != nil { + log.Fatal(err) + } + vals = append(vals, v) + weights = append(weights, w) + } + err := sc.Err() + if err != nil { + log.Fatal(err) + } + fmt.Println(stat.Mean(vals, weights)) + + // Output: + // 5 +} diff --git a/vendor/gonum.org/v1/gonum/graph/.gitignore b/vendor/gonum.org/v1/gonum/graph/.gitignore new file mode 100644 index 00000000..86e0d240 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/.gitignore @@ -0,0 +1 @@ +test.out \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/graph/README.md b/vendor/gonum.org/v1/gonum/graph/README.md new file mode 100644 index 00000000..f0a9505e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/README.md @@ -0,0 +1,3 @@ +# Gonum graph [![GoDoc](https://godoc.org/gonum.org/v1/gonum/graph?status.svg)](https://godoc.org/gonum.org/v1/gonum/graph) + +This is a generalized graph package for the Go language. diff --git a/vendor/gonum.org/v1/gonum/graph/community/bisect.go b/vendor/gonum.org/v1/gonum/graph/community/bisect.go new file mode 100644 index 00000000..ddfdb0a9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/bisect.go @@ -0,0 +1,248 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package community + +import ( + "errors" + "fmt" + "math" + "math/rand" + + "gonum.org/v1/gonum/graph" +) + +// Interval is an interval of resolutions with a common score. +type Interval struct { + // Low and High delimit the interval + // such that the interval is [low, high). + Low, High float64 + + // Score is the score of the interval. + Score float64 + + // Reduced is the best scoring + // community membership found for the + // interval. + Reduced +} + +// Reduced is a graph reduction. +type Reduced interface { + // Communities returns the community + // structure of the reduction. + Communities() [][]graph.Node +} + +// Size is a score function that is the reciprocal of the number of communities. +func Size(g ReducedGraph) float64 { return 1 / float64(len(g.Structure())) } + +// Weight is a score function that is the sum of community weights. The concrete +// type of g must be a pointer to a ReducedUndirected or a ReducedDirected, otherwise +// Weight will panic. +func Weight(g ReducedGraph) float64 { + var w float64 + switch g := g.(type) { + case *ReducedUndirected: + for _, n := range g.nodes { + w += n.weight + } + case *ReducedDirected: + for _, n := range g.nodes { + w += n.weight + } + default: + panic(fmt.Sprintf("community: invalid graph type: %T", g)) + } + return w +} + +// ModularScore returns a modularized scoring function for Profile based on the +// graph g and the given score function. The effort parameter determines how +// many attempts will be made to get an improved score for any given resolution. +func ModularScore(g graph.Graph, score func(ReducedGraph) float64, effort int, src *rand.Rand) func(float64) (float64, Reduced) { + return func(resolution float64) (float64, Reduced) { + max := math.Inf(-1) + var best Reduced + for i := 0; i < effort; i++ { + r := Modularize(g, resolution, src) + s := score(r) + if s > max { + max = s + best = r + } + } + return max, best + } +} + +// SizeMultiplex is a score function that is the reciprocal of the number of communities. +func SizeMultiplex(g ReducedMultiplex) float64 { return 1 / float64(len(g.Structure())) } + +// WeightMultiplex is a score function that is the sum of community weights. The concrete +// type of g must be pointer to a ReducedUndirectedMultiplex or a ReducedDirectedMultiplex, +// otherwise WeightMultiplex will panic. +func WeightMultiplex(g ReducedMultiplex) float64 { + var w float64 + switch g := g.(type) { + case *ReducedUndirectedMultiplex: + for _, n := range g.nodes { + for _, lw := range n.weights { + w += lw + } + } + case *ReducedDirectedMultiplex: + for _, n := range g.nodes { + for _, lw := range n.weights { + w += lw + } + } + default: + panic(fmt.Sprintf("community: invalid graph type: %T", g)) + } + return w +} + +// ModularMultiplexScore returns a modularized scoring function for Profile based +// on the graph g and the given score function. The effort parameter determines how +// many attempts will be made to get an improved score for any given resolution. +func ModularMultiplexScore(g Multiplex, weights []float64, all bool, score func(ReducedMultiplex) float64, effort int, src *rand.Rand) func(float64) (float64, Reduced) { + return func(resolution float64) (float64, Reduced) { + max := math.Inf(-1) + var best Reduced + for i := 0; i < effort; i++ { + r := ModularizeMultiplex(g, weights, []float64{resolution}, all, src) + s := score(r) + if s > max { + max = s + best = r + } + } + return max, best + } +} + +// Profile returns an approximate profile of score values in the resolution domain [low,high) +// at the given granularity. The score is calculated by bisecting calls to fn. If log is true, +// log space bisection is used, otherwise bisection is linear. The function fn should be +// monotonically decreasing in at least 1/grain evaluations. Profile will attempt to detect +// non-monotonicity during the bisection. +// +// Since exact modularity optimization is known to be NP-hard and Profile calls modularization +// routines repeatedly, it is unlikely to return the exact resolution profile. +func Profile(fn func(float64) (float64, Reduced), log bool, grain, low, high float64) (profile []Interval, err error) { + if low >= high { + return nil, errors.New("community: zero or negative width domain") + } + + defer func() { + r := recover() + e, ok := r.(nonDecreasing) + if ok { + err = e + return + } + if r != nil { + panic(r) + } + }() + left, comm := fn(low) + right, _ := fn(high) + for i := 1; i < int(1/grain); i++ { + rt, _ := fn(high) + right = math.Max(right, rt) + } + profile = bisect(fn, log, grain, low, left, high, right, comm) + + // We may have missed some non-monotonicity, + // so merge low score discordant domains into + // their lower resolution neighbours. + return fixUp(profile), nil +} + +type nonDecreasing int + +func (n nonDecreasing) Error() string { + return fmt.Sprintf("community: profile does not reliably monotonically decrease: tried %d times", n) +} + +func bisect(fn func(float64) (float64, Reduced), log bool, grain, low, scoreLow, high, scoreHigh float64, comm Reduced) []Interval { + if low >= high { + panic("community: zero or negative width domain") + } + if math.IsNaN(scoreLow) || math.IsNaN(scoreHigh) { + return nil + } + + // Heuristically determine a reasonable number + // of times to try to get a higher value. + maxIter := int(1 / grain) + + lowComm := comm + for n := 0; scoreLow < scoreHigh; n++ { + if n > maxIter { + panic(nonDecreasing(n)) + } + scoreLow, lowComm = fn(low) + } + + if scoreLow == scoreHigh || tooSmall(low, high, grain, log) { + return []Interval{{Low: low, High: high, Score: scoreLow, Reduced: lowComm}} + } + + var mid float64 + if log { + mid = math.Sqrt(low * high) + } else { + mid = (low + high) / 2 + } + + scoreMid := math.Inf(-1) + var midComm Reduced + for n := 0; scoreMid < scoreHigh; n++ { + if n > maxIter { + panic(nonDecreasing(n)) + } + scoreMid, midComm = fn(mid) + } + + lower := bisect(fn, log, grain, low, scoreLow, mid, scoreMid, lowComm) + higher := bisect(fn, log, grain, mid, scoreMid, high, scoreHigh, midComm) + for n := 0; lower[len(lower)-1].Score < higher[0].Score; n++ { + if n > maxIter { + panic(nonDecreasing(n)) + } + lower[len(lower)-1].Score, lower[len(lower)-1].Reduced = fn(low) + } + + if lower[len(lower)-1].Score == higher[0].Score { + higher[0].Low = lower[len(lower)-1].Low + lower = lower[:len(lower)-1] + if len(lower) == 0 { + return higher + } + } + return append(lower, higher...) +} + +// fixUp non-monotonically decreasing interval scores. +func fixUp(profile []Interval) []Interval { + max := profile[len(profile)-1].Score + for i := len(profile) - 2; i >= 0; i-- { + if profile[i].Score > max { + max = profile[i].Score + continue + } + profile[i+1].Low = profile[i].Low + profile = append(profile[:i], profile[i+1:]...) + } + return profile +} + +func tooSmall(low, high, grain float64, log bool) bool { + if log { + return math.Log(high/low) < grain + } + return high-low < grain +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/bisect_test.go b/vendor/gonum.org/v1/gonum/graph/community/bisect_test.go new file mode 100644 index 00000000..5a225d7e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/bisect_test.go @@ -0,0 +1,311 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package community + +import ( + "fmt" + "log" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +func ExampleProfile_simple() { + // Create dumbell graph: + // + // 0 4 + // |\ /| + // | 2 - 3 | + // |/ \| + // 1 5 + // + g := simple.NewUndirectedGraph() + for u, e := range smallDumbell { + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + // Get the profile of internal node weight for resolutions + // between 0.1 and 10 using logarithmic bisection. + p, err := Profile(ModularScore(g, Weight, 10, nil), true, 1e-3, 0.1, 10) + if err != nil { + log.Fatal(err) + } + + // Print out each step with communities ordered. + for _, d := range p { + comm := d.Communities() + for _, c := range comm { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(comm)) + fmt.Printf("Low:%.2v High:%.2v Score:%v Communities:%v Q=%.3v\n", + d.Low, d.High, d.Score, comm, Q(g, comm, d.Low)) + } + + // Output: + // Low:0.1 High:0.29 Score:14 Communities:[[0 1 2 3 4 5]] Q=0.9 + // Low:0.29 High:2.3 Score:12 Communities:[[0 1 2] [3 4 5]] Q=0.714 + // Low:2.3 High:3.5 Score:4 Communities:[[0 1] [2] [3] [4 5]] Q=-0.31 + // Low:3.5 High:10 Score:0 Communities:[[0] [1] [2] [3] [4] [5]] Q=-0.607 +} + +var friends, enemies *simple.WeightedUndirectedGraph + +func init() { + friends = simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range middleEast.friends { + // Ensure unconnected nodes are included. + if !friends.Has(simple.Node(u)) { + friends.AddNode(simple.Node(u)) + } + for v := range e { + friends.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + enemies = simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range middleEast.enemies { + // Ensure unconnected nodes are included. + if !enemies.Has(simple.Node(u)) { + enemies.AddNode(simple.Node(u)) + } + for v := range e { + enemies.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: -1}) + } + } +} + +func ExampleProfile_multiplex() { + // The undirected graphs, friends and enemies, are the political relationships + // in the Middle East as described in the Slate article: + // http://www.slate.com/blogs/the_world_/2014/07/17/the_middle_east_friendship_chart.html + g, err := NewUndirectedLayers(friends, enemies) + if err != nil { + log.Fatal(err) + } + weights := []float64{1, -1} + + // Get the profile of internal node weight for resolutions + // between 0.1 and 10 using logarithmic bisection. + p, err := Profile(ModularMultiplexScore(g, weights, true, WeightMultiplex, 10, nil), true, 1e-3, 0.1, 10) + if err != nil { + log.Fatal(err) + } + + // Print out each step with communities ordered. + for _, d := range p { + comm := d.Communities() + for _, c := range comm { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(comm)) + fmt.Printf("Low:%.2v High:%.2v Score:%v Communities:%v Q=%.3v\n", + d.Low, d.High, d.Score, comm, QMultiplex(g, comm, weights, []float64{d.Low})) + } + + // Output: + // Low:0.1 High:0.72 Score:26 Communities:[[0] [1 7 9 12] [2 8 11] [3 4 5 10] [6]] Q=[24.7 1.97] + // Low:0.72 High:1.1 Score:24 Communities:[[0 6] [1 7 9 12] [2 8 11] [3 4 5 10]] Q=[16.9 14.1] + // Low:1.1 High:1.1 Score:18 Communities:[[0 2 6 11] [1 7 9 12] [3 4 5 8 10]] Q=[9.16 25.1] + // Low:1.1 High:1.6 Score:10 Communities:[[0 3 4 5 6 10] [1 7 9 12] [2 8 11]] Q=[11.5 23.9] + // Low:1.6 High:1.6 Score:8 Communities:[[0 1 6 7 9 12] [2 8 11] [3 4 5 10]] Q=[5.56 39.8] + // Low:1.6 High:1.8 Score:2 Communities:[[0 2 3 4 5 6 10] [1 7 8 9 11 12]] Q=[-1.82 48.6] + // Low:1.8 High:2.3 Score:-6 Communities:[[0 2 3 4 5 6 8 10 11] [1 7 9 12]] Q=[-5 57.5] + // Low:2.3 High:2.4 Score:-10 Communities:[[0 1 2 6 7 8 9 11 12] [3 4 5 10]] Q=[-11.2 79] + // Low:2.4 High:4.3 Score:-52 Communities:[[0 1 2 3 4 5 6 7 8 9 10 11 12]] Q=[-46.1 117] + // Low:4.3 High:10 Score:-54 Communities:[[0 1 2 3 4 6 7 8 9 10 11 12] [5]] Q=[-82 254] +} + +func TestProfileUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testProfileUndirected(t, test, g) + } +} + +func TestProfileWeightedUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testProfileUndirected(t, test, g) + } +} + +func testProfileUndirected(t *testing.T, test communityUndirectedQTest, g graph.Undirected) { + fn := ModularScore(g, Weight, 10, nil) + p, err := Profile(fn, true, 1e-3, 0.1, 10) + if err != nil { + t.Errorf("%s: unexpected error: %v", test.name, err) + } + + const tries = 1000 + for i, d := range p { + var score float64 + for i := 0; i < tries; i++ { + score, _ = fn(d.Low) + if score >= d.Score { + break + } + } + if score < d.Score { + t.Errorf("%s: failed to recover low end score: got: %v want: %v", test.name, score, d.Score) + } + if i != 0 && d.Score >= p[i-1].Score { + t.Errorf("%s: not monotonically decreasing: %v -> %v", test.name, p[i-1], d) + } + } +} + +func TestProfileDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testProfileDirected(t, test, g) + } +} + +func TestProfileWeightedDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewWeightedDirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testProfileDirected(t, test, g) + } +} + +func testProfileDirected(t *testing.T, test communityDirectedQTest, g graph.Directed) { + fn := ModularScore(g, Weight, 10, nil) + p, err := Profile(fn, true, 1e-3, 0.1, 10) + if err != nil { + t.Errorf("%s: unexpected error: %v", test.name, err) + } + + const tries = 1000 + for i, d := range p { + var score float64 + for i := 0; i < tries; i++ { + score, _ = fn(d.Low) + if score >= d.Score { + break + } + } + if score < d.Score { + t.Errorf("%s: failed to recover low end score: got: %v want: %v", test.name, score, d.Score) + } + if i != 0 && d.Score >= p[i-1].Score { + t.Errorf("%s: not monotonically decreasing: %v -> %v", test.name, p[i-1], d) + } + } +} + +func TestProfileUndirectedMultiplex(t *testing.T) { + for _, test := range communityUndirectedMultiplexQTests { + g, weights, err := undirectedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + const all = true + + fn := ModularMultiplexScore(g, weights, all, WeightMultiplex, 10, nil) + p, err := Profile(fn, true, 1e-3, 0.1, 10) + if err != nil { + t.Errorf("%s: unexpected error: %v", test.name, err) + } + + const tries = 1000 + for i, d := range p { + var score float64 + for i := 0; i < tries; i++ { + score, _ = fn(d.Low) + if score >= d.Score { + break + } + } + if score < d.Score { + t.Errorf("%s: failed to recover low end score: got: %v want: %v", test.name, score, d.Score) + } + if i != 0 && d.Score >= p[i-1].Score { + t.Errorf("%s: not monotonically decreasing: %v -> %v", test.name, p[i-1], d) + } + } + } +} + +func TestProfileDirectedMultiplex(t *testing.T) { + for _, test := range communityDirectedMultiplexQTests { + g, weights, err := directedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + const all = true + + fn := ModularMultiplexScore(g, weights, all, WeightMultiplex, 10, nil) + p, err := Profile(fn, true, 1e-3, 0.1, 10) + if err != nil { + t.Errorf("%s: unexpected error: %v", test.name, err) + } + + const tries = 1000 + for i, d := range p { + var score float64 + for i := 0; i < tries; i++ { + score, _ = fn(d.Low) + if score >= d.Score { + break + } + } + if score < d.Score { + t.Errorf("%s: failed to recover low end score: got: %v want: %v", test.name, score, d.Score) + } + if i != 0 && d.Score >= p[i-1].Score { + t.Errorf("%s: not monotonically decreasing: %v -> %v", test.name, p[i-1], d) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/doc.go b/vendor/gonum.org/v1/gonum/graph/community/doc.go new file mode 100644 index 00000000..2509606b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package community provides graph community detection functions. +package community // import "gonum.org/v1/gonum/graph/community" diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain.tex b/vendor/gonum.org/v1/gonum/graph/community/louvain.tex new file mode 100644 index 00000000..046c02ba --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain.tex @@ -0,0 +1,466 @@ +% 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. + +\documentclass{article} + +\usepackage{amsmath,amsfonts} +\usepackage[margin=4cm]{geometry} + +\title{Louvain algorithm for undirected and directed graphs} +\author{The {\tt gonum} Authors} + +\begin{document} + +\maketitle + +The algorithm attempts to find communities (highly connected sub-graphs), +and it does this by minimising the modularity function +\begin{equation} + Q(c) = \frac{1}{2m}\sum_i\sum_j\left[ A_{ij} - \gamma \frac{k_ik_j}{2m} \right] \delta_{ij}(c), +\end{equation} +where $c$ is a partition of nodes into subsets or communities, +$A_{ij}$ is the edge weight between nodes $i$ and $j$, +$\gamma$ is a tuning parameter, +\begin{equation} +m = \frac{1}{2}\sum_i\sum_jA_{ij}, +\end{equation} +\begin{equation} +k_i = \sum_j{A_{ij}}, +\end{equation} +and +\begin{equation} + \delta_{ij}(c) = \left \{ \begin{array}{ll} + 1 & \text{if} \quad c(i) = c(j) \\ + 0 & \text{otherwise} \end{array} \right .. +\end{equation} +Here $c(i)$ denotes the community to which node $i$ belongs +in the partitioning $c$. + +The algorithm finds a hierarchical community structure by iterating +between two phases: +\begin{enumerate} + \item Find a set of communities that minimise $Q$. + \item Construct a new graph, whose nodes are the communities + found in the preceding phase one step. +\end{enumerate} +Each iteration of these two phases is called a `pass'. +In this way, the algorithm obtains a nested community structure, +where at each level $Q$ is minimised for the relevant graph. +We consider this process in more detail, in particular looking +at phase one first in the first pass, when each node is a single +node, and then how this generalises to later passes when each node +is a community. + +\section{Undirected Graphs} + +\subsection{Initial Pass} +\label{sec:initialPass} + +The initial pass is simple as the initial pass uses the original graph, +and in all following passes graphs constructed in the previous pass's +phase two are used. +Here we will consider this initial simple formulation for phase one, and +in Section~\ref{sec:laterPasses} we consider how this generalises for +passes two and onwards. +Phase one works by initially allocating each node to a separate community, +and then iterating through each node $a$ and checking if moving it into +a different community $\beta$ will reduce $Q$. +If there are possible moves that will reduce $Q$, $a$ is moved into the +the community which will generate the largest reduction in $Q$. +This process is continued until there are no moves left to reduce $Q$ +further, meaning a local minimum for $Q$ has been achieved. +Then the algorithm moves to phase two (constructing a new graph where +each node in the new graph is a community in the old graph). + +Note that we assume the original graph to be simple and undirected. +First, we introduce some notation that will be useful: +Let $c(i)$ denote the community to which node $i$ belongs, +and let $\alpha$ be the community that the node $a$ mentioned above +belongs to, i.e., $\alpha = c_a$. +Then we define +\newcommand{\Stot}[1]{\Sigma_{\text{tot}}^{#1}} +\begin{equation} + \Stot{\alpha} = \sum_{i \in \alpha}\sum_{j}A_{ij} = \sum_{i \in \alpha}k_i, +\end{equation} +\newcommand{\kin}[2]{k_{#1}^{#2}} +\begin{equation} + \kin{i}{\alpha} = \sum_{j \in \alpha}A_{ij}, +\end{equation} +and +\newcommand{\Sin}[1]{\Sigma_{\text{in}}^{#1}} +\begin{equation} + \Sin{\alpha} = \sum_{i \in \alpha}\sum_{j \in \alpha}A_{ij} = \sum_{i \in \alpha}\kin{i}{\alpha}. +\end{equation} + +We are interested in how $Q$ will change if we move a node $a$ from its +current community $\alpha$, to a new community $\beta$. +This will have two effects, it will remove the terms from $Q$ +related to $a$ in $\alpha$, which we will call $Q^-$ and it will add terms +related to $a$ in $\beta$, which we will call $Q^+$. +The total change in $Q$ caused by the movement of $a$ from $\alpha$ to $\beta$ is +\begin{equation} + \Delta Q = Q^{+} - Q^{-}, +\end{equation} +where +\begin{align*} +Q^- &= \frac{1}{2m}\left[ \left( A_{aa} - \gamma \frac{k_a^2}{2m} \right) ++ 2\sum_{i \in \alpha, \, i \neq a} \left( A_{ia} - \gamma \frac{k_ik_a}{2m} \right) \right] \\ + &= \frac{1}{2m}\left[ \left( A_{aa} - \gamma \frac{k_a^2}{2m} \right) ++ 2 \left( \kin{a}{\alpha} -A_{aa}\right) - \gamma \frac{2k_a}{2m}\sum_{i \in \alpha, \, i \neq a} k_i \right] \\ + &= \frac{1}{2m}\left[ \left( A_{aa} - \gamma \frac{k_a^2}{2m} \right) ++ 2 \left( \kin{a}{\alpha} -A_{aa}\right) - \gamma \frac{2k_a}{2m}\left( \Stot{\alpha} - k_a \right) \right], \\ +\end{align*} +and +\begin{align*} +Q^+ &= \frac{1}{2m}\left[ \left( A_{aa} - \gamma \frac{k_a^2}{2m} \right) ++ 2\sum_{i \in \beta} \left( A_{ia} - \gamma \frac{k_ik_a}{2m} \right) \right] \\ + &= \frac{1}{2m}\left[ \left( A_{aa} - \gamma \frac{k_a^2}{2m} \right) ++ 2\kin{a}{\beta} - \gamma \frac{2k_a}{2m}\sum_{i \in \beta} k_i \right] \\ + &= \frac{1}{2m}\left[ \left( A_{aa} - \gamma \frac{k_a^2}{2m} \right) ++ 2\kin{a}{\beta} - \gamma \frac{2k_a\Stot{\beta}}{2m} \right]. \\ +\end{align*} +The first term in both these expressions ($Q^-$ and $Q^+$) is the same, and so cancels: +\begin{equation} +\Delta Q = \frac{1}{2m}\left[ \left( 2\kin{a}{\beta} - \gamma \frac{2k_a\Stot{\beta}}{2m} \right) + - \left( 2 \left( \kin{a}{\alpha} -A_{aa}\right) - \gamma \frac{2k_a}{2m}\left( \Stot{\alpha} - k_a \right) \right) \right]. +\end{equation} + +\subsection{Later Passes} +\label{sec:laterPasses} + +In phase two a `meta-graph' is constructed where nodes correspond to +the communities found in the preceding phase one step, and edge weight +between two such communities (nodes, in the meta-graph) +$\alpha$ and $\beta$ are defined to be +\begin{equation} + A_{\alpha \beta}^* = \sum_{i \in \alpha}\sum_{j \in \beta}A_{ij}. + \label{eqn:Aij*} +\end{equation} +Note that $i$ and $j$ refer to nodes in the original graph, not nodes +in the previous graph, and so holds any meta-graph, not just the first. +Also note that this definition of $A^*_{\alpha \beta}$ allows for +$A^*_{\alpha \alpha}$ to be non-zero as +\begin{equation} +A_{\alpha \alpha}^* = \sum_{i \in \alpha}\sum_{j \in \alpha}A_{ij} = \Sin{\alpha}. +\end{equation} + +In this newly constructed graph, $\alpha$ and $\beta$ are nodes, but +also refer to communities (sets of nodes) in the original graph, and I +use these two interpretations interchangeably. +This should be the only ambiguous bit of notation in this document, I hope. + +The results of Section~\ref{sec:initialPass} generalise to these meta-graphs, +and the generalised results mirror those of Section~\ref{sec:initialPass} closely +-- I distinguish the new results from those of Section~\ref{sec:initialPass} by a +superscript $*$. +I use $i$ and $j$ to denote nodes of the original graph as in Section~\ref{sec:initialPass}, +and use $z$ and $w$ to denote nodes of the meta-graph (communities of the original). +I use analogous notation to Section~\ref{sec:initialPass}, $c^*(z)$, to +denote the community to which node $z$ of the meta-graph belongs, +and let $\mathfrak{a}$ be the community that the node $\alpha$ belongs to +($c^*(\alpha) = \mathfrak{a}$), i.e. +\begin{equation} + \mathfrak{a} = \{z | c^*(z) = c^*(\alpha) \}. +\end{equation} + +Given this notation, we can observe that +\begin{equation} +m^* = \frac{1}{2}\sum_{z}\sum_{w}{A_{zw}^*} = \frac{1}{2}\sum_{z}\sum_{w}{\sum_{i \in z}\sum_{j \in w}A_{ij}} = \frac{1}{2}\sum_i\sum_jA_{ij} = m, +\end{equation} +\begin{equation} +k_{z}^* = \sum_{w}{A_{zw}^*} = \sum_{w}{\sum_{i \in z}\sum_{j \in w}A_{ij}} = \sum_{i \in z}\sum_{j}A_{ij} = \Stot{z}, +\end{equation} +\begin{equation} + \Stot{\mathfrak{a} *} = \sum_{z \in \mathfrak{a}}\sum_{w}A_{zw}^* = \sum_{z \in \mathfrak{a}}k_z^* = \sum_{z \in \mathfrak{a}}\Stot{z}, +\end{equation} +\begin{equation} + \kin{z}{\mathfrak{a} *} = \sum_{w \in \mathfrak{a}}{A_{zw}^*} = \sum_{w \in \mathfrak{a}}{\sum_{i \in z}\sum_{j \in w}A_{ij}}, +\end{equation} +and +\begin{equation} +\Sin{\mathfrak{a} *} = \sum_{z \in \mathfrak{a}}\sum_{w \in \mathfrak{a}}A_{zw}^* = \sum_{z \in \mathfrak{a}}\kin{z}{\mathfrak{a} *} = \sum_{z \in \mathfrak{a}}\sum_{w \in \mathfrak{a}}{\sum_{i \in z}\sum_{j \in w}A_{ij}}. + %\label{eqn:Sin} +\end{equation} + +If we let $\mathfrak{b}$ denote the community to which we are considering moving $\alpha$, +then the expression for $\Delta Q$ from Section~\ref{sec:initialPass} trivially generalises to +\begin{equation} +\Delta Q = \frac{1}{2m}\left[ \left( 2 \kin{\alpha}{\mathfrak{b} *} - \gamma \frac{2k_{\alpha}^*\Stot{\mathfrak{b} *}}{2m} \right) + - \left( 2\left( \kin{\alpha}{\mathfrak{a} *} - A_{\alpha \alpha}^* \right) - \gamma \frac{2k_{\alpha}^*}{2m} \left( \Stot{\mathfrak{a} *} - k_{\alpha}^* \right ) \right) \right] \\ +\end{equation} + +\section{Directed Graphs} +\label{sec:directedGraphs} + +It is of interest to consider how this generalises to directed graphs. +If we are to treat incoming and outgoing nodes equally, there are several +thoughts on how to extend the algorithm to directed graphs, of which we +will explore three: +\begin{itemize} + \item Construct an undirected graph first, and then use the undirected case. + \item Generalise the expressions from the undirected case to the directed case, + we will consider two different suggestions for such generalisations. +\end{itemize} +We will show that one of the two `generalisation of expressions' approaches is +equivalent to constructing an undirected graph, and the other is not. + +\subsection{Construction of an undirected graph} +A simple approach to generalising to directed graphs is to construct +an undirected graph with edge weights +\begin{equation} +A_{ij} = B_{ij} + B_{ji}, +\label{eqn:undirectedAB} +\end{equation} +and simply use the undirected algorithm. +Another suggestion is to average the directed edges to make +an undirected graph, i.e. to use a directed graph with edge weights +\begin{equation} +A_{ij} = \frac{B_{ij} + B_{ji}}{2}. +\end{equation} +This raises an important question: does scaling all edge weights across +the entire graph by a constant affect the results of the algorithm? +Hopefully not, but worth checking. +We can follow this through the results for the undirected graph by +substituting $A_{ij}^{(1)} = pA_{ij}$, $p \in \mathbb{R}$, and +distinguishing the new expressions by a superscript ${(1)}$. These +new expressions are: +\begin{equation} +m^{(1)} = \frac{1}{2}\sum_i\sum_jpA_{ij} = p\frac{1}{2}\sum_i\sum_j A_{ij} = pm , +\end{equation} +\begin{equation} +k_i^{(1)} = \sum_j{pA_{ij}} = p\sum_j{A_{ij}} = pk_i, +\end{equation} +and so +\begin{align*} + Q^{(1)}(c) &= \frac{1}{2pm}\sum_i\sum_j\left[ pA_{ij} - \gamma \frac{pk_ipk_j}{2pm} \right] \delta_{ij}(c) \\ + &= \frac{1}{2m}\sum_i\sum_j\left[ A_{ij} - \gamma \frac{k_ik_j}{2m} \right] \delta_{ij}(c) \\ + &= Q(c) +\end{align*} +Note that as we have shown $Q^{(1)} = Q$ there is no need to go into the remainder of the terms +involved in the algorithm, as they all derive from $Q$. + +\subsection{First generalisation of expressions approach} + +One suggested extension to directed graphs is to modify the expressions +involved by adding the `from' case and the `to' case for each term. +If we let $B_{ij}$ be the edge weight between nodes $i$ and $j$ in +the directed graph, and distinguishing these extended expressions by +a superscript $(2)$, the extended expressions become: +\begin{equation} +m^{(2)} = \frac{1}{2}\left ( \sum_i\sum_jB_{ij} + \sum_i\sum_jB_{ji}\right) = \frac{1}{2}\sum_i\sum_j \left( B_{ij} + B_{ji} \right) , +\end{equation} +\begin{equation} +k_i^{(2)} = \sum_jB_{ij} + \sum_jB_{ji} = \sum_j{\left( B_{ij} + B_{ji} \right)}, +\end{equation} +and similarly +\begin{equation} + Q^{(2)}(c) = \frac{1}{2m}\sum_i\sum_j\left[ \left( B_{ij} + B_{ji} \right) - \gamma \frac{k_i^{(2)}k_j^{(2)}}{2m} \right] \delta_{ij}(c). +\end{equation} + +Note how this is equivalent to the construction of an undirected graph as +per Equation~(\ref{eqn:undirectedAB}). Similarly to above, +there is no need to go into the remainder of the terms +involved in the algorithm, as they all derive from $Q$. + + +\subsection{Second generalisation of expressions approach} + +Another approach to generalising the expressions to the +directed case, that still treats incoming and outgoing edges +as equally important, is to propose an alternative modularity +expression: +\newcommand{\dkin}[1]{k_{#1}^{\text{in}}} +\newcommand{\dkout}[1]{k_{#1}^{\text{out}}} +\begin{equation} +Q^{(3)}(c) = \frac{1}{2m}\sum_i\sum_j\left[ 2B_{ij} - 2\gamma \frac{\dkin{i}\dkout{j}}{2m} \right] \delta_{ij}(c), \\ +\end{equation} +where +\begin{equation} +\dkout{i} = \sum_j{B_{ij}} +\quad \quad \text{and} \quad \quad +\dkin{i} = \sum_j{B_{ji}}, +\end{equation} +so $k_i^{(2)} = \dkin{i} + \dkout{i}$. +Note I leave the factor of two in the expression for $Q^{(3)}$ so that it +remains as comparable to that for $Q^{(2)}$ as possible. +There is no need for alternative $m$, as it will still be the same as above. +$Q^{(3)}$ will differ from $Q^{(2)}$ in two ways. +Firstly, as $k_i^{(2)} = \dkin{i} + \dkout{i}$, +\begin{align*} +\sum_i\sum_j k_i^{(2)} k_j^{(2)} \delta_{ij}(c) &= \sum_i\sum_j (\dkin{i} + \dkout{i}) (\dkin{j} + \dkout{j}) \delta_{ij}(c) \\ + &= \sum_i\sum_j \left[ (\dkin{i}\dkin{j} + \dkout{i}\dkout{j}) + (\dkin{i}\dkout{j} + \dkin{j}\dkout{i}) \right] \delta_{ij}(c). \\ + &= \sum_i\sum_j \left[ (\dkin{i}\dkin{j} + \dkout{i}\dkout{j}) + 2\dkin{i}\dkout{j} \right] \delta_{ij}(c), \\ +\end{align*} +and similarly, +\begin{equation} +\sum_i\sum_j \left( B_{ij} + B_{ji} \right) \delta_{ij}(c) = 2\sum_i\sum_j B_{ij} \delta_{ij}(c). +\end{equation} +From these two expressions, we can see that +\begin{equation} +Q^{(3)} - Q^{(2)} = \frac{1}{2m}\sum_i\sum_j \gamma \frac{\dkin{i}\dkin{j} + \dkout{i}\dkout{j}}{2m} \delta_{ij}(c). +\end{equation} + + +\section{Directed Graphs in more detail} +\label{sec:directedGraphsDetail} + +In Section \ref{sec:directedGraphs} we essentially showed three +things: +\begin{itemize} + \item How an undirected graph could be constructed from a directed + graph, thereby allowing the undirected algorithm to be used for + directed graphs. + \item How scaling all edge weights by a non-zero constant would not + affect the modularity function. + \item An alternative approach to extending the algorithm to + directed graphs that is not equivalent to first reducing it + to an undirected graph. +\end{itemize} +It is this third point that we will explore here. +Analogously to Sections \ref{sec:initialPass} and \ref{sec:laterPasses} we will +break this up into the initial pass and the later passes. + +\subsection{Initial pass} +\label{sec:initialPassDirected} + +Continuing with the notation of Section \ref{sec:initialPass}, in which +$c(i)$ denotes the community to which node $i$ belongs, +and $\alpha = c(a)$, we define +\newcommand{\dinStot}[1]{\Sigma_{\text{tot}}^{\text{in}(#1)}} +\newcommand{\doutStot}[1]{\Sigma_{\text{tot}}^{\text{out}(#1)}} +\begin{equation} + \doutStot{\alpha} = \sum_{i \in \alpha}\sum_{j}B_{ij} = \sum_{i \in \alpha}\dkout{i} + \quad \quad \text{and} \quad \quad + \dinStot{\alpha} = \sum_{i \in \alpha}\sum_{j}B_{ji} = \sum_{i \in \alpha}\dkin{i}, +\end{equation} +\newcommand{\dinkin}[2]{k_{#1}^{\text{in}(#2)}} +\newcommand{\doutkin}[2]{k_{#1}^{\text{out}(#2)}} +\begin{equation} + \doutkin{i}{\alpha} = \sum_{j \in \alpha}B_{ij} + \quad \quad \text{and} \quad \quad + \dinkin{i}{\alpha} = \sum_{j \in \alpha}B_{ji}, +\end{equation} +and we will entertain one more ambiguous notation choice: +%\newcommand{\Sin}[1]{\Sigma_{\text{in}}^{#1}} +\begin{equation} + \Sin{\alpha} = \sum_{i \in \alpha}\sum_{j \in \alpha}B_{ij} = \sum_{i \in \alpha}\doutkin{i}{\alpha} = \sum_{i \in \alpha}\dinkin{i}{\alpha}. +\end{equation} + +Analogously to Section \ref{sec:initialPass}, we are interested in how +$Q^{(3)}$ will change if we move a node $a$ from its +current community $\alpha$, to a new community $\beta$, +and analogously this will have two effects -- it will remove the terms +from $Q^{(3)}$ related to $a$ in $\alpha$, which we will call $Q^{-(3)}$ +and it will add terms related to $a$ in $\beta$, which we will call $Q^{+(3)}$. +The total change in $Q^{(3)}$ caused by the movement of $a$ from $\alpha$ to $\beta$ is +\begin{equation} + \Delta Q^{(3)} = Q^{+(3)} - Q^{-(3)}, +\end{equation} +where +\begin{align*} +Q^{-(3)} &= \frac{1}{2m}\left[ \left( 2B_{aa} - 2\gamma \frac{\dkin{a}\dkout{a}}{2m} \right) ++ \sum_{i \in \alpha, \, i \neq a} \left( 2B_{ia} + 2B_{ai} - 2\gamma \frac{\dkin{i}\dkout{a}}{2m} - 2\gamma \frac{\dkin{a}\dkout{i}}{2m} \right) \right] \\ + &= \frac{1}{2m}\left[ \left( 2B_{aa} - 2\gamma \frac{\dkin{a}\dkout{a}}{2m} \right) ++ 2(\dinkin{a}{\alpha} - B_{aa}) + 2(\doutkin{a}{\alpha} - B_{aa}) \hdots \right . \\ + & \quad \quad \quad \quad \quad \quad \left . +- \frac{2\gamma\dkout{a}}{2m} (\dinStot{\alpha} - \dkin{a}) - \frac{2\gamma\dkin{a}}{2m} (\doutStot{\alpha} - \dkout{a}) \right] \\ +\end{align*} +and +\begin{align*} +Q^{+(3)} &= \frac{1}{2m}\left[ \left( 2B_{aa} - 2\gamma \frac{\dkin{a}\dkout{a}}{2m} \right) ++ \sum_{i \in \beta} \left( 2B_{ia} + 2B_{ai} - 2\gamma \frac{\dkin{i}\dkout{a}}{2m} - 2\gamma \frac{\dkin{a}\dkout{i}}{2m} \right) \right] \\ + &= \frac{1}{2m}\left[ \left( 2B_{aa} - 2\gamma \frac{\dkin{a}\dkout{a}}{2m} \right) ++ 2\dinkin{a}{\beta} + 2\doutkin{a}{\beta} - \frac{2\gamma\dkout{a}}{2m} \dinStot{\beta} - \frac{2\gamma\dkin{a}}{2m} \doutStot{\beta} \right] \\ +\end{align*} +Similarly to Section \ref{sec:initialPass}, the first term in both these expressions is the same, and so cancels, leaving: +\begin{align*} +\Delta Q^{(3)} &= \frac{2}{2m}\left[ +\left( \dinkin{a}{\beta} + \doutkin{a}{\beta} - \frac{\gamma\dkout{a}}{2m} \dinStot{\beta} - \frac{\gamma\dkin{a}}{2m} \doutStot{\beta} \right) \right. \\ +& \hspace{-1cm} +- \left. \left( (\dinkin{a}{\alpha} - B_{aa}) + (\doutkin{a}{\alpha} - B_{aa}) - \frac{\gamma\dkout{a}}{2m} (\dinStot{\alpha} - \dkin{a}) - \frac{\gamma\dkin{a}}{2m} (\doutStot{\alpha} - \dkout{a}) \right) \right] \\ + &= \frac{2}{2m}\left[ (\dinkin{a}{\beta}-\dinkin{a}{\alpha}) + (\doutkin{a}{\beta}-\doutkin{a}{\alpha}) + 2B_{aa} \right. \\ +& \hspace{-1cm} \left. +- \frac{\gamma\dkout{a}}{2m} (\dinStot{\beta}-\dinStot{\alpha}) - \frac{\gamma\dkin{a}}{2m} (\doutStot{\beta} - \doutStot{\alpha}) - \frac{2\gamma\dkin{a}\dkout{a}}{2m} \right] +\end{align*} + + + +\subsection{Later passes} +\label{sec:laterPassesDirected} + +In phase two a `meta-graph' is constructed where nodes correspond to +the communities found in the preceding phase one step, and edge weight +between two such communities (nodes, in the meta-graph) +$\alpha$ and $\beta$ are defined to be +\begin{equation} + B_{\alpha \beta}^* = \sum_{i \in \alpha}\sum_{j \in \beta}B_{ij}. + \label{eqn:Bij*} +\end{equation} +Note that $i$ and $j$ refer to nodes in the original graph, not nodes +in the previous graph, and so holds any meta-graph, not just the first. +Also note that this definition of $B^*_{\alpha \beta}$ allows for +$B^*_{\alpha \alpha}$ to be non-zero, in fact +\begin{equation} +B_{\alpha \alpha}^* = \sum_{i \in \alpha}\sum_{j \in \alpha}B_{ij} = \Sin{\alpha}. +\end{equation} + +In this newly constructed graph, $\alpha$ and $\beta$ are nodes, but +also refer to communities (sets of nodes) in the original graph, and I +use these two interpretations interchangeably, completely analogously to +Section \ref{sec:laterPasses}. + +The results of Section~\ref{sec:initialPassDirected} generalise to these meta-graphs, +and the generalised results mirror those of Section~\ref{sec:initialPassDirected} closely +-- I distinguish the new results from those of Section~\ref{sec:initialPassDirected} by a +superscript $*$. +I use $i$ and $j$ to denote nodes of the original graph as in Sections~\ref{sec:initialPass} +and \ref{sec:initialPassDirected}, +and use $z$ and $w$ to denote nodes of the meta-graph (communities of the original). +I use analogous notation to Section~\ref{sec:initialPass}, $c^*(z)$, to +denote the community to which node $z$ of the meta-graph belongs, +and let $\mathfrak{a}$ be the community that the node $\alpha$ belongs to, +i.e., $\mathfrak{a} = c^*(\alpha) $. + +Given this notation, we get all the same results as in \ref{sec:laterPasses}, but +each split into two cases `out' and `in', separating by direction, essentially, so +\newcommand{\dkinStar}[1]{k_{#1}^{\text{in} *}} +\newcommand{\dkoutStar}[1]{k_{#1}^{\text{out} *}} +\begin{equation} +\dkoutStar{z} = \sum_w{B_{zw}^*} = \sum_w\sum_{i \in z}\sum_{j \in w}B_{ij} = \sum_{i \in z}\sum_jB_{ij} = \doutStot{z}, +\end{equation} +\begin{equation} +\dkinStar{z} = \sum_w{B_{wz}^*} = \sum_w\sum_{i \in z}\sum_{j \in w}B_{ji} = \sum_{i \in z}\sum_jB_{ji} = \dinStot{z}, +\end{equation} +\newcommand{\dinStotStar}[1]{\Sigma_{\text{tot}}^{\text{in}(#1) *}} +\newcommand{\doutStotStar}[1]{\Sigma_{\text{tot}}^{\text{out}(#1) *}} +\begin{equation} + \doutStotStar{\mathfrak{a}} = \sum_{z \in \mathfrak{a}}\sum_{w}B_{zw}^* = \sum_{z \in \mathfrak{a}}\dkoutStar{z} = \sum_{z \in \mathfrak{a}}\doutStot{z}, +\end{equation} +\begin{equation} + \dinStotStar{\mathfrak{a}} = \sum_{z \in \mathfrak{a}}\sum_{w}B_{wz}^* = \sum_{z \in \mathfrak{a}}\dkinStar{z} = \sum_{z \in \mathfrak{a}}\dinStot{z}, +\end{equation} +\newcommand{\dinkinStar}[2]{k_{#1}^{\text{in}(#2) *}} +\newcommand{\doutkinStar}[2]{k_{#1}^{\text{out}(#2) *}} +\begin{equation} + \doutkinStar{z}{\mathfrak{a}} = \sum_{w \in \mathfrak{a}}{B_{zw}^*} = \sum_{w \in \mathfrak{a}}{\sum_{i \in z}\sum_{j \in w}B_{ij}}, +\end{equation} +\begin{equation} + \dinkinStar{z}{\mathfrak{a}} = \sum_{w \in \mathfrak{a}}{B_{wz}^*} = \sum_{w \in \mathfrak{a}}{\sum_{i \in z}\sum_{j \in w}B_{ji}}, +\end{equation} +and +\begin{equation} +\Sin{\mathfrak{a} *} = \sum_{z \in \mathfrak{a}}\sum_{w \in \mathfrak{a}}A_{zw}^* = \sum_{z \in \mathfrak{a}}\kin{z}{\mathfrak{a} *} = \sum_{z \in \mathfrak{a}}\sum_{w \in \mathfrak{a}}{\sum_{i \in z}\sum_{j \in w}A_{ij}}. + %\label{eqn:Sin} +\end{equation} + +If we let $\mathfrak{b}$ denote the community to which we are considering moving $\alpha$, +then the expression for $\Delta Q$ from Section~\ref{sec:initialPassDirected} simply generalises as +\begin{align*} +\Delta Q^{(3)} &= \frac{2}{2m}\left[ (\dinkinStar{\alpha}{\mathfrak{b}}-\dinkinStar{\alpha}{\mathfrak{a}}) + (\doutkinStar{\alpha}{\mathfrak{b}}-\doutkinStar{\alpha}{\mathfrak{a}}) + 2B_{\alpha\alpha}^* \right. \\ +& \hspace{-1cm} \left. +- \frac{\gamma\dkoutStar{\alpha}}{2m} (\dinStotStar{\mathfrak{b}}-\dinStotStar{\mathfrak{a}}) - \frac{\gamma\dkinStar{\alpha}}{2m} (\doutStotStar{\mathfrak{b}} - \doutStotStar{\mathfrak{a}}) - \frac{2\gamma\dkinStar{\alpha}\dkoutStar{\alpha}}{2m} \right] +\end{align*} + + +\end{document} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_common.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_common.go new file mode 100644 index 00000000..987776c0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_common.go @@ -0,0 +1,415 @@ +// 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 community + +import ( + "fmt" + "math/rand" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/set" +) + +// Q returns the modularity Q score of the graph g subdivided into the +// given communities at the given resolution. If communities is nil, the +// unclustered modularity score is returned. The resolution parameter +// is γ as defined in Reichardt and Bornholdt doi:10.1103/PhysRevE.74.016110. +// Q will panic if g has any edge with negative edge weight. +// +// If g is undirected, Q is calculated according to +// Q = 1/2m \sum_{ij} [ A_{ij} - (\gamma k_i k_j)/2m ] \delta(c_i,c_j), +// If g is directed, it is calculated according to +// Q = 1/m \sum_{ij} [ A_{ij} - (\gamma k_i^in k_j^out)/m ] \delta(c_i,c_j). +// +// graph.Undirect may be used as a shim to allow calculation of Q for +// directed graphs with the undirected modularity function. +func Q(g graph.Graph, communities [][]graph.Node, resolution float64) float64 { + switch g := g.(type) { + case graph.Undirected: + return qUndirected(g, communities, resolution) + case graph.Directed: + return qDirected(g, communities, resolution) + default: + panic(fmt.Sprintf("community: invalid graph type: %T", g)) + } +} + +// ReducedGraph is a modularised graph. +type ReducedGraph interface { + graph.Graph + + // Communities returns the community memberships + // of the nodes in the graph used to generate + // the reduced graph. + Communities() [][]graph.Node + + // Structure returns the community structure of + // the current level of the module clustering. + // Each slice in the returned value recursively + // describes the membership of a community at + // the current level by indexing via the node + // ID into the structure of the non-nil + // ReducedGraph returned by Expanded, or when the + // ReducedGraph is nil, by containing nodes + // from the original input graph. + // + // The returned value should not be mutated. + Structure() [][]graph.Node + + // Expanded returns the next lower level of the + // module clustering or nil if at the lowest level. + // + // The returned ReducedGraph will be the same + // concrete type as the receiver. + Expanded() ReducedGraph +} + +// Modularize returns the hierarchical modularization of g at the given resolution +// using the Louvain algorithm. If src is nil, rand.Intn is used as the random +// generator. Modularize will panic if g has any edge with negative edge weight. +// +// If g is undirected it is modularised to minimise +// Q = 1/2m \sum_{ij} [ A_{ij} - (\gamma k_i k_j)/2m ] \delta(c_i,c_j), +// If g is directed it is modularised to minimise +// Q = 1/m \sum_{ij} [ A_{ij} - (\gamma k_i^in k_j^out)/m ] \delta(c_i,c_j). +// +// The concrete type of the ReducedGraph will be a pointer to either a +// ReducedUndirected or a ReducedDirected depending on the type of g. +// +// graph.Undirect may be used as a shim to allow modularization of +// directed graphs with the undirected modularity function. +func Modularize(g graph.Graph, resolution float64, src *rand.Rand) ReducedGraph { + switch g := g.(type) { + case graph.Undirected: + return louvainUndirected(g, resolution, src) + case graph.Directed: + return louvainDirected(g, resolution, src) + default: + panic(fmt.Sprintf("community: invalid graph type: %T", g)) + } +} + +// Multiplex is a multiplex graph. +type Multiplex interface { + // Nodes returns the slice of nodes + // for the multiplex graph. + // All layers must refer to the same + // set of nodes. + Nodes() []graph.Node + + // Depth returns the number of layers + // in the multiplex graph. + Depth() int +} + +// QMultiplex returns the modularity Q score of the multiplex graph layers +// subdivided into the given communities at the given resolutions and weights. Q is +// returned as the vector of weighted Q scores for each layer of the multiplex graph. +// If communities is nil, the unclustered modularity score is returned. +// If weights is nil layers are equally weighted, otherwise the length of +// weights must equal the number of layers. If resolutions is nil, a resolution +// of 1.0 is used for all layers, otherwise either a single element slice may be used +// to specify a global resolution, or the length of resolutions must equal the number +// of layers. The resolution parameter is γ as defined in Reichardt and Bornholdt +// doi:10.1103/PhysRevE.74.016110. +// QMultiplex will panic if the graph has any layer weight-scaled edge with +// negative edge weight. +// +// If g is undirected, Q is calculated according to +// Q_{layer} = w_{layer} \sum_{ij} [ A_{layer}*_{ij} - (\gamma_{layer} k_i k_j)/2m_{layer} ] \delta(c_i,c_j), +// If g is directed, it is calculated according to +// Q_{layer} = w_{layer} \sum_{ij} [ A_{layer}*_{ij} - (\gamma_{layer} k_i^in k_j^out)/m_{layer} ] \delta(c_i,c_j). +// +// Note that Q values for multiplex graphs are not scaled by the total layer edge weight. +// +// graph.Undirect may be used as a shim to allow calculation of Q for +// directed graphs. +func QMultiplex(g Multiplex, communities [][]graph.Node, weights, resolutions []float64) []float64 { + if weights != nil && len(weights) != g.Depth() { + panic("community: weights vector length mismatch") + } + if resolutions != nil && len(resolutions) != 1 && len(resolutions) != g.Depth() { + panic("community: resolutions vector length mismatch") + } + + switch g := g.(type) { + case UndirectedMultiplex: + return qUndirectedMultiplex(g, communities, weights, resolutions) + case DirectedMultiplex: + return qDirectedMultiplex(g, communities, weights, resolutions) + default: + panic(fmt.Sprintf("community: invalid graph type: %T", g)) + } +} + +// ReducedMultiplex is a modularised multiplex graph. +type ReducedMultiplex interface { + Multiplex + + // Communities returns the community memberships + // of the nodes in the graph used to generate + // the reduced graph. + Communities() [][]graph.Node + + // Structure returns the community structure of + // the current level of the module clustering. + // Each slice in the returned value recursively + // describes the membership of a community at + // the current level by indexing via the node + // ID into the structure of the non-nil + // ReducedGraph returned by Expanded, or when the + // ReducedGraph is nil, by containing nodes + // from the original input graph. + // + // The returned value should not be mutated. + Structure() [][]graph.Node + + // Expanded returns the next lower level of the + // module clustering or nil if at the lowest level. + // + // The returned ReducedGraph will be the same + // concrete type as the receiver. + Expanded() ReducedMultiplex +} + +// ModularizeMultiplex returns the hierarchical modularization of g at the given resolution +// using the Louvain algorithm. If all is true and g have negatively weighted layers, all +// communities will be searched during the modularization. If src is nil, rand.Intn is +// used as the random generator. ModularizeMultiplex will panic if g has any edge with +// edge weight that does not sign-match the layer weight. +// +// If g is undirected it is modularised to minimise +// Q = \sum w_{layer} \sum_{ij} [ A_{layer}*_{ij} - (\gamma_{layer} k_i k_j)/2m ] \delta(c_i,c_j). +// If g is directed it is modularised to minimise +// Q = \sum w_{layer} \sum_{ij} [ A_{layer}*_{ij} - (\gamma_{layer} k_i^in k_j^out)/m_{layer} ] \delta(c_i,c_j). +// +// The concrete type of the ReducedMultiplex will be a pointer to a +// ReducedUndirectedMultiplex. +// +// graph.Undirect may be used as a shim to allow modularization of +// directed graphs with the undirected modularity function. +func ModularizeMultiplex(g Multiplex, weights, resolutions []float64, all bool, src *rand.Rand) ReducedMultiplex { + if weights != nil && len(weights) != g.Depth() { + panic("community: weights vector length mismatch") + } + if resolutions != nil && len(resolutions) != 1 && len(resolutions) != g.Depth() { + panic("community: resolutions vector length mismatch") + } + + switch g := g.(type) { + case UndirectedMultiplex: + return louvainUndirectedMultiplex(g, weights, resolutions, all, src) + case DirectedMultiplex: + return louvainDirectedMultiplex(g, weights, resolutions, all, src) + default: + panic(fmt.Sprintf("community: invalid graph type: %T", g)) + } +} + +// undirectedEdges is the edge structure of a reduced undirected graph. +type undirectedEdges struct { + // edges and weights is the set + // of edges between nodes. + // weights is keyed such that + // the first element of the key + // is less than the second. + edges [][]int + weights map[[2]int]float64 +} + +// directedEdges is the edge structure of a reduced directed graph. +type directedEdges struct { + // edgesFrom, edgesTo and weights + // is the set of edges between nodes. + edgesFrom [][]int + edgesTo [][]int + weights map[[2]int]float64 +} + +// isValidID returns whether id is a valid ID for a community, +// multiplexCommunity or node. These are all graph.Node types +// stored in []T with a mapping between their index and their ID +// so IDs must be positive and fit within the int type. +func isValidID(id int64) bool { + return id == int64(int(id)) && id >= 0 +} + +// community is a reduced graph node describing its membership. +type community struct { + // community graphs are internal, in-memory + // with dense IDs, so id is always an int. + id int + + nodes []graph.Node + + weight float64 +} + +func (n community) ID() int64 { return int64(n.id) } + +// edge is a reduced graph edge. +type edge struct { + from, to community + weight float64 +} + +func (e edge) From() graph.Node { return e.from } +func (e edge) To() graph.Node { return e.to } +func (e edge) Weight() float64 { return e.weight } + +// multiplexCommunity is a reduced multiplex graph node describing its membership. +type multiplexCommunity struct { + // community graphs are internal, in-memory + // with dense IDs, so id is always an int. + id int + + nodes []graph.Node + + weights []float64 +} + +func (n multiplexCommunity) ID() int64 { return int64(n.id) } + +// multiplexEdge is a reduced graph edge for a multiplex graph. +type multiplexEdge struct { + from, to multiplexCommunity + weight float64 +} + +func (e multiplexEdge) From() graph.Node { return e.from } +func (e multiplexEdge) To() graph.Node { return e.to } +func (e multiplexEdge) Weight() float64 { return e.weight } + +// commIdx is an index of a node in a community held by a localMover. +type commIdx struct { + community int + node int +} + +// node is defined to avoid an import of .../graph/simple. node is +// used in in-memory, dense ID graphs and so is always an int. +type node int + +func (n node) ID() int64 { return int64(n) } + +// minTaker is a set iterator. +type minTaker interface { + TakeMin(p *int) bool +} + +// dense is a dense integer set iterator. +type dense struct { + pos int + n int +} + +// TakeMin mimics intsets.Sparse TakeMin for dense sets. If the dense +// iterator position is less than the iterator size, TakeMin sets *p +// to the the iterator position and increments the position and returns +// true. +// Otherwise, it returns false and *p is undefined. +func (d *dense) TakeMin(p *int) bool { + if d.pos >= d.n { + return false + } + *p = d.pos + d.pos++ + return true +} + +// slice is a sparse integer set iterator. +type slice struct { + pos int + elems []int +} + +// newSlice returns a new slice of elements from s, sorted ascending. +func newSlice(s set.Ints) *slice { + elems := make([]int, 0, len(s)) + for i := range s { + elems = append(elems, i) + } + sort.Ints(elems) + return &slice{elems: elems} +} + +// TakeMin mimics intsets.Sparse TakeMin for a sorted set. If the set +// iterator position is less than the iterator size, TakeMin sets *p +// to the the iterator position's element and increments the position +// and returns true. +// Otherwise, it returns false and *p is undefined. +func (s *slice) TakeMin(p *int) bool { + if s.pos >= len(s.elems) { + return false + } + *p = s.elems[s.pos] + s.pos++ + return true +} + +const ( + negativeWeight = "community: unexpected negative edge weight" + positiveWeight = "community: unexpected positive edge weight" +) + +// positiveWeightFuncFor returns a constructed weight function for the +// positively weighted g. Unweighted graphs have unit weight for existing +// edges. +func positiveWeightFuncFor(g graph.Graph) func(x, y graph.Node) float64 { + if wg, ok := g.(graph.Weighted); ok { + return func(x, y graph.Node) float64 { + w, ok := wg.Weight(x, y) + if !ok { + return 0 + } + if w < 0 { + panic(negativeWeight) + } + return w + } + } + return func(x, y graph.Node) float64 { + e := g.Edge(x, y) + if e == nil { + return 0 + } + return 1 + } +} + +// negativeWeightFuncFor returns a constructed weight function for the +// negatively weighted g. Unweighted graphs have unit weight for existing +// edges. +func negativeWeightFuncFor(g graph.Graph) func(x, y graph.Node) float64 { + if wg, ok := g.(graph.Weighted); ok { + return func(x, y graph.Node) float64 { + w, ok := wg.Weight(x, y) + if !ok { + return 0 + } + if w > 0 { + panic(positiveWeight) + } + return -w + } + } + return func(x, y graph.Node) float64 { + e := g.Edge(x, y) + if e == nil { + return 0 + } + return 1 + } +} + +// depth returns max(1, len(weights)). It is used to ensure +// that multiplex community weights are properly initialised. +func depth(weights []float64) int { + if weights == nil { + return 1 + } + return len(weights) +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_directed.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed.go new file mode 100644 index 00000000..3bd5a319 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed.go @@ -0,0 +1,650 @@ +// 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 community + +import ( + "math" + "math/rand" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/internal/set" +) + +// qDirected returns the modularity Q score of the graph g subdivided into the +// given communities at the given resolution. If communities is nil, the +// unclustered modularity score is returned. The resolution parameter +// is γ as defined in Reichardt and Bornholdt doi:10.1103/PhysRevE.74.016110. +// qDirected will panic if g has any edge with negative edge weight. +// +// Q = 1/m \sum_{ij} [ A_{ij} - (\gamma k_i^in k_j^out)/m ] \delta(c_i,c_j) +// +func qDirected(g graph.Directed, communities [][]graph.Node, resolution float64) float64 { + nodes := g.Nodes() + weight := positiveWeightFuncFor(g) + + // Calculate the total edge weight of the graph + // and the table of penetrating edge weight sums. + var m float64 + k := make(map[int64]directedWeights, len(nodes)) + for _, n := range nodes { + var wOut float64 + u := n + for _, v := range g.From(u) { + wOut += weight(u, v) + } + var wIn float64 + v := n + for _, u := range g.To(v) { + wIn += weight(u, v) + } + w := weight(n, n) + m += w + wOut // We only need to count edges once. + k[n.ID()] = directedWeights{out: w + wOut, in: w + wIn} + } + + if communities == nil { + var q float64 + for _, u := range nodes { + kU := k[u.ID()] + q += weight(u, u) - resolution*kU.out*kU.in/m + } + return q / m + } + + var q float64 + for _, c := range communities { + for _, u := range c { + kU := k[u.ID()] + for _, v := range c { + kV := k[v.ID()] + q += weight(u, v) - resolution*kU.out*kV.in/m + } + } + } + return q / m +} + +// louvainDirected returns the hierarchical modularization of g at the given +// resolution using the Louvain algorithm. If src is nil, rand.Intn is used +// as the random generator. louvainDirected will panic if g has any edge with negative +// edge weight. +func louvainDirected(g graph.Directed, resolution float64, src *rand.Rand) ReducedGraph { + // See louvain.tex for a detailed description + // of the algorithm used here. + + c := reduceDirected(g, nil) + rnd := rand.Intn + if src != nil { + rnd = src.Intn + } + for { + l := newDirectedLocalMover(c, c.communities, resolution) + if l == nil { + return c + } + if done := l.localMovingHeuristic(rnd); done { + return c + } + c = reduceDirected(c, l.communities) + } +} + +// ReducedDirected is a directed graph of communities derived from a +// parent graph by reduction. +type ReducedDirected struct { + // nodes is the set of nodes held + // by the graph. In a ReducedDirected + // the node ID is the index into + // nodes. + nodes []community + directedEdges + + // communities is the community + // structure of the graph. + communities [][]graph.Node + + parent *ReducedDirected +} + +var ( + reducedDirected = (*ReducedDirected)(nil) + + _ graph.WeightedDirected = reducedDirected + _ ReducedGraph = reducedDirected +) + +// Communities returns the community memberships of the nodes in the +// graph used to generate the reduced graph. +func (g *ReducedDirected) Communities() [][]graph.Node { + communities := make([][]graph.Node, len(g.communities)) + if g.parent == nil { + for i, members := range g.communities { + comm := make([]graph.Node, len(members)) + for j, n := range members { + nodes := g.nodes[n.ID()].nodes + if len(nodes) != 1 { + panic("community: unexpected number of nodes in base graph community") + } + comm[j] = nodes[0] + } + communities[i] = comm + } + return communities + } + sub := g.parent.Communities() + for i, members := range g.communities { + var comm []graph.Node + for _, n := range members { + comm = append(comm, sub[n.ID()]...) + } + communities[i] = comm + } + return communities +} + +// Structure returns the community structure of the current level of +// the module clustering. The first index of the returned value +// corresponds to the index of the nodes in the next higher level if +// it exists. The returned value should not be mutated. +func (g *ReducedDirected) Structure() [][]graph.Node { + return g.communities +} + +// Expanded returns the next lower level of the module clustering or nil +// if at the lowest level. +func (g *ReducedDirected) Expanded() ReducedGraph { + return g.parent +} + +// reduceDirected returns a reduced graph constructed from g divided +// into the given communities. The communities value is mutated +// by the call to reduceDirected. If communities is nil and g is a +// ReducedDirected, it is returned unaltered. +func reduceDirected(g graph.Directed, communities [][]graph.Node) *ReducedDirected { + if communities == nil { + if r, ok := g.(*ReducedDirected); ok { + return r + } + + nodes := g.Nodes() + // TODO(kortschak) This sort is necessary really only + // for testing. In practice we would not be using the + // community provided by the user for a Q calculation. + // Probably we should use a function to map the + // communities in the test sets to the remapped order. + sort.Sort(ordered.ByID(nodes)) + communities = make([][]graph.Node, len(nodes)) + for i := range nodes { + communities[i] = []graph.Node{node(i)} + } + + weight := positiveWeightFuncFor(g) + r := ReducedDirected{ + nodes: make([]community, len(nodes)), + directedEdges: directedEdges{ + edgesFrom: make([][]int, len(nodes)), + edgesTo: make([][]int, len(nodes)), + weights: make(map[[2]int]float64), + }, + communities: communities, + } + communityOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + r.nodes[i] = community{id: i, nodes: []graph.Node{n}} + communityOf[n.ID()] = i + } + for _, n := range nodes { + id := communityOf[n.ID()] + + var out []int + u := n + for _, v := range g.From(u) { + vid := communityOf[v.ID()] + if vid != id { + out = append(out, vid) + } + r.weights[[2]int{id, vid}] = weight(u, v) + } + r.edgesFrom[id] = out + + var in []int + v := n + for _, u := range g.To(v) { + uid := communityOf[u.ID()] + if uid != id { + in = append(in, uid) + } + r.weights[[2]int{uid, id}] = weight(u, v) + } + r.edgesTo[id] = in + } + return &r + } + + // Remove zero length communities destructively. + var commNodes int + for i := 0; i < len(communities); { + comm := communities[i] + if len(comm) == 0 { + communities[i] = communities[len(communities)-1] + communities[len(communities)-1] = nil + communities = communities[:len(communities)-1] + } else { + commNodes += len(comm) + i++ + } + } + + r := ReducedDirected{ + nodes: make([]community, len(communities)), + directedEdges: directedEdges{ + edgesFrom: make([][]int, len(communities)), + edgesTo: make([][]int, len(communities)), + weights: make(map[[2]int]float64), + }, + } + r.communities = make([][]graph.Node, len(communities)) + for i := range r.communities { + r.communities[i] = []graph.Node{node(i)} + } + if g, ok := g.(*ReducedDirected); ok { + // Make sure we retain the truncated + // community structure. + g.communities = communities + r.parent = g + } + weight := positiveWeightFuncFor(g) + communityOf := make(map[int64]int, commNodes) + for i, comm := range communities { + r.nodes[i] = community{id: i, nodes: comm} + for _, n := range comm { + communityOf[n.ID()] = i + } + } + for id, comm := range communities { + var out, in []int + for _, n := range comm { + u := n + for _, v := range comm { + r.nodes[id].weight += weight(u, v) + } + + for _, v := range g.From(u) { + vid := communityOf[v.ID()] + found := false + for _, e := range out { + if e == vid { + found = true + break + } + } + if !found && vid != id { + out = append(out, vid) + } + // Add half weights because the other + // ends of edges are also counted. + r.weights[[2]int{id, vid}] += weight(u, v) / 2 + } + + v := n + for _, u := range g.To(v) { + uid := communityOf[u.ID()] + found := false + for _, e := range in { + if e == uid { + found = true + break + } + } + if !found && uid != id { + in = append(in, uid) + } + // Add half weights because the other + // ends of edges are also counted. + r.weights[[2]int{uid, id}] += weight(u, v) / 2 + } + } + r.edgesFrom[id] = out + r.edgesTo[id] = in + } + return &r +} + +// Has returns whether the node exists within the graph. +func (g *ReducedDirected) Has(n graph.Node) bool { + id := n.ID() + return 0 <= id && id < int64(len(g.nodes)) +} + +// Nodes returns all the nodes in the graph. +func (g *ReducedDirected) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.nodes)) + for i := range g.nodes { + nodes[i] = node(i) + } + return nodes +} + +// From returns all nodes in g that can be reached directly from u. +func (g *ReducedDirected) From(u graph.Node) []graph.Node { + out := g.edgesFrom[u.ID()] + nodes := make([]graph.Node, len(out)) + for i, vid := range out { + nodes[i] = g.nodes[vid] + } + return nodes +} + +// To returns all nodes in g that can reach directly to v. +func (g *ReducedDirected) To(v graph.Node) []graph.Node { + in := g.edgesTo[v.ID()] + nodes := make([]graph.Node, len(in)) + for i, uid := range in { + nodes[i] = g.nodes[uid] + } + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g *ReducedDirected) HasEdgeBetween(x, y graph.Node) bool { + xid := x.ID() + yid := y.ID() + if xid == yid || !isValidID(xid) || !isValidID(yid) { + return false + } + _, ok := g.weights[[2]int{int(xid), int(yid)}] + if ok { + return true + } + _, ok = g.weights[[2]int{int(yid), int(xid)}] + return ok +} + +// HasEdgeFromTo returns whether an edge exists from node u to v. +func (g *ReducedDirected) HasEdgeFromTo(u, v graph.Node) bool { + uid := u.ID() + vid := v.ID() + if uid == vid || !isValidID(uid) || !isValidID(vid) { + return false + } + _, ok := g.weights[[2]int{int(uid), int(vid)}] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *ReducedDirected) Edge(u, v graph.Node) graph.Edge { + return g.WeightedEdge(u, v) +} + +// 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 *ReducedDirected) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + uid := u.ID() + vid := v.ID() + if uid == vid || !isValidID(uid) || !isValidID(vid) { + return nil + } + w, ok := g.weights[[2]int{int(uid), int(vid)}] + if !ok { + return nil + } + return edge{from: g.nodes[uid], to: g.nodes[vid], weight: w} +} + +// 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 the internal node weight is returned. If there is no joining +// edge between the two nodes the weight value returned is zero. Weight returns true if an edge +// exists between x and y or if x and y have the same ID, false otherwise. +func (g *ReducedDirected) Weight(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if !isValidID(xid) || !isValidID(yid) { + return 0, false + } + if xid == yid { + return g.nodes[xid].weight, true + } + w, ok = g.weights[[2]int{int(xid), int(yid)}] + return w, ok +} + +// directedLocalMover is a step in graph modularity optimization. +type directedLocalMover struct { + g *ReducedDirected + + // nodes is the set of working nodes. + nodes []graph.Node + // edgeWeightsOf is the weighted degree + // of each node indexed by ID. + edgeWeightsOf []directedWeights + + // m is the total sum of edge + // weights in g. + m float64 + + // weight is the weight function + // provided by g or a function + // that returns the Weight value + // of the non-nil edge between x + // and y. + weight func(x, y graph.Node) float64 + + // communities is the current + // division of g. + communities [][]graph.Node + // memberships is a mapping between + // node ID and community membership. + memberships []int + + // resolution is the Reichardt and + // Bornholdt γ parameter as defined + // in doi:10.1103/PhysRevE.74.016110. + resolution float64 + + // moved indicates that a call to + // move has been made since the last + // call to shuffle. + moved bool + + // changed indicates that a move + // has been made since the creation + // of the local mover. + changed bool +} + +type directedWeights struct { + out, in float64 +} + +// newDirectedLocalMover returns a new directedLocalMover initialized with +// the graph g, a set of communities and a modularity resolution parameter. +// The node IDs of g must be contiguous in [0,n) where n is the number of +// nodes. +// If g has a zero edge weight sum, nil is returned. +func newDirectedLocalMover(g *ReducedDirected, communities [][]graph.Node, resolution float64) *directedLocalMover { + nodes := g.Nodes() + l := directedLocalMover{ + g: g, + nodes: nodes, + edgeWeightsOf: make([]directedWeights, len(nodes)), + communities: communities, + memberships: make([]int, len(nodes)), + resolution: resolution, + weight: positiveWeightFuncFor(g), + } + + // Calculate the total edge weight of the graph + // and degree weights for each node. + for _, n := range l.nodes { + u := n + var wOut float64 + for _, v := range g.From(u) { + wOut += l.weight(u, v) + } + + v := n + var wIn float64 + for _, u := range g.To(v) { + wIn += l.weight(u, v) + } + + w := l.weight(n, n) + l.edgeWeightsOf[n.ID()] = directedWeights{out: w + wOut, in: w + wIn} + l.m += w + wOut + } + + // Assign membership mappings. + for i, c := range communities { + for _, n := range c { + l.memberships[n.ID()] = i + } + } + + return &l +} + +// localMovingHeuristic performs the Louvain local moving heuristic until +// no further moves can be made. It returns a boolean indicating that the +// directedLocalMover has not made any improvement to the community structure and +// so the Louvain algorithm is done. +func (l *directedLocalMover) localMovingHeuristic(rnd func(int) int) (done bool) { + for { + l.shuffle(rnd) + for _, n := range l.nodes { + dQ, dst, src := l.deltaQ(n) + if dQ <= 0 { + continue + } + l.move(dst, src) + } + if !l.moved { + return !l.changed + } + } +} + +// shuffle performs a Fisher-Yates shuffle on the nodes held by the +// directedLocalMover using the random source rnd which should return an +// integer in the range [0,n). +func (l *directedLocalMover) shuffle(rnd func(n int) int) { + l.moved = false + for i := range l.nodes[:len(l.nodes)-1] { + j := i + rnd(len(l.nodes)-i) + l.nodes[i], l.nodes[j] = l.nodes[j], l.nodes[i] + } +} + +// move moves the node at src to the community at dst. +func (l *directedLocalMover) move(dst int, src commIdx) { + l.moved = true + l.changed = true + + srcComm := l.communities[src.community] + n := srcComm[src.node] + + l.memberships[n.ID()] = dst + + l.communities[dst] = append(l.communities[dst], n) + srcComm[src.node], srcComm[len(srcComm)-1] = srcComm[len(srcComm)-1], nil + l.communities[src.community] = srcComm[:len(srcComm)-1] +} + +// deltaQ returns the highest gain in modularity attainable by moving +// n from its current community to another connected community and +// the index of the chosen destination. The index into the directedLocalMover's +// communities field is returned in src if n is in communities. +func (l *directedLocalMover) deltaQ(n graph.Node) (deltaQ float64, dst int, src commIdx) { + id := n.ID() + + a_aa := l.weight(n, n) + k_a := l.edgeWeightsOf[id] + m := l.m + gamma := l.resolution + + // Find communities connected to n. + connected := make(set.Ints) + // The following for loop is equivalent to: + // + // for _, v := range l.g.From(n) { + // connected.Add(l.memberships[v.ID()]) + // } + // for _, v := range l.g.To(n) { + // connected.Add(l.memberships[v.ID()]) + // } + // + // This is done to avoid two allocations. + for _, vid := range l.g.edgesFrom[id] { + connected.Add(l.memberships[vid]) + } + for _, vid := range l.g.edgesTo[id] { + connected.Add(l.memberships[vid]) + } + // Insert the node's own community. + connected.Add(l.memberships[id]) + + candidates := make([]int, 0, len(connected)) + for i := range connected { + candidates = append(candidates, i) + } + sort.Ints(candidates) + + // Calculate the highest modularity gain + // from moving into another community and + // keep the index of that community. + var dQremove float64 + dQadd, dst, src := math.Inf(-1), -1, commIdx{-1, -1} + for _, i := range candidates { + c := l.communities[i] + var k_aC, sigma_totC directedWeights // C is a substitution for ^𝛼 or ^𝛽. + var removal bool + for j, u := range c { + uid := u.ID() + if uid == id { + if src.community != -1 { + panic("community: multiple sources") + } + src = commIdx{i, j} + removal = true + } + + k_aC.in += l.weight(u, n) + k_aC.out += l.weight(n, u) + // sigma_totC could be kept for each community + // and updated for moves, changing the calculation + // of sigma_totC here from O(n_c) to O(1), but + // in practice the time savings do not appear + // to be compelling and do not make up for the + // increase in code complexity and space required. + w := l.edgeWeightsOf[uid] + sigma_totC.in += w.in + sigma_totC.out += w.out + } + + // See louvain.tex for a derivation of these equations. + switch { + case removal: + // The community c was the current community, + // so calculate the change due to removal. + dQremove = (k_aC.in /*^𝛼*/ - a_aa) + (k_aC.out /*^𝛼*/ - a_aa) - + gamma*(k_a.in*(sigma_totC.out /*^𝛼*/ -k_a.out)+k_a.out*(sigma_totC.in /*^𝛼*/ -k_a.in))/m + + default: + // Otherwise calculate the change due to an addition + // to c and retain if it is the current best. + dQ := k_aC.in /*^𝛽*/ + k_aC.out /*^𝛽*/ - + gamma*(k_a.in*sigma_totC.out /*^𝛽*/ +k_a.out*sigma_totC.in /*^𝛽*/)/m + + if dQ > dQadd { + dQadd = dQ + dst = i + } + } + } + + return (dQadd - dQremove) / m, dst, src +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_multiplex.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_multiplex.go new file mode 100644 index 00000000..967ba758 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_multiplex.go @@ -0,0 +1,888 @@ +// 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 community + +import ( + "fmt" + "math" + "math/rand" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/internal/set" +) + +// DirectedMultiplex is a directed multiplex graph. +type DirectedMultiplex interface { + Multiplex + + // Layer returns the lth layer of the + // multiplex graph. + Layer(l int) graph.Directed +} + +// qDirectedMultiplex returns the modularity Q score of the multiplex graph layers +// subdivided into the given communities at the given resolutions and weights. Q is +// returned as the vector of weighted Q scores for each layer of the multiplex graph. +// If communities is nil, the unclustered modularity score is returned. +// If weights is nil layers are equally weighted, otherwise the length of +// weights must equal the number of layers. If resolutions is nil, a resolution +// of 1.0 is used for all layers, otherwise either a single element slice may be used +// to specify a global resolution, or the length of resolutions must equal the number +// of layers. The resolution parameter is γ as defined in Reichardt and Bornholdt +// doi:10.1103/PhysRevE.74.016110. +// qUndirectedMultiplex will panic if the graph has any layer weight-scaled edge with +// negative edge weight. +// +// Q_{layer} = w_{layer} \sum_{ij} [ A_{layer}*_{ij} - (\gamma_{layer} k_i k_j)/2m ] \delta(c_i,c_j) +// +// Note that Q values for multiplex graphs are not scaled by the total layer edge weight. +func qDirectedMultiplex(g DirectedMultiplex, communities [][]graph.Node, weights, resolutions []float64) []float64 { + q := make([]float64, g.Depth()) + nodes := g.Nodes() + layerWeight := 1.0 + layerResolution := 1.0 + if len(resolutions) == 1 { + layerResolution = resolutions[0] + } + for l := 0; l < g.Depth(); l++ { + layer := g.Layer(l) + + if weights != nil { + layerWeight = weights[l] + } + if layerWeight == 0 { + continue + } + + if len(resolutions) > 1 { + layerResolution = resolutions[l] + } + + var weight func(x, y graph.Node) float64 + if layerWeight < 0 { + weight = negativeWeightFuncFor(layer) + } else { + weight = positiveWeightFuncFor(layer) + } + + // Calculate the total edge weight of the layer + // and the table of penetrating edge weight sums. + var m float64 + k := make(map[int64]directedWeights, len(nodes)) + for _, n := range nodes { + var wOut float64 + u := n + for _, v := range layer.From(u) { + wOut += weight(u, v) + } + var wIn float64 + v := n + for _, u := range layer.To(v) { + wIn += weight(u, v) + } + w := weight(n, n) + m += w + wOut // We only need to count edges once. + k[n.ID()] = directedWeights{out: w + wOut, in: w + wIn} + } + + if communities == nil { + var qLayer float64 + for _, u := range nodes { + kU := k[u.ID()] + qLayer += weight(u, u) - layerResolution*kU.out*kU.in/m + } + q[l] = layerWeight * qLayer + continue + } + + var qLayer float64 + for _, c := range communities { + for _, u := range c { + kU := k[u.ID()] + for _, v := range c { + kV := k[v.ID()] + qLayer += weight(u, v) - layerResolution*kU.out*kV.in/m + } + } + } + q[l] = layerWeight * qLayer + } + + return q +} + +// DirectedLayers implements DirectedMultiplex. +type DirectedLayers []graph.Directed + +// NewDirectedLayers returns a DirectedLayers using the provided layers +// ensuring there is a match between IDs for each layer. +func NewDirectedLayers(layers ...graph.Directed) (DirectedLayers, error) { + if len(layers) == 0 { + return nil, nil + } + base := make(set.Int64s) + for _, n := range layers[0].Nodes() { + base.Add(n.ID()) + } + for i, l := range layers[1:] { + next := make(set.Int64s) + for _, n := range l.Nodes() { + next.Add(n.ID()) + } + if !set.Int64sEqual(base, next) { + return nil, fmt.Errorf("community: layer ID mismatch between layers: %d", i+1) + } + } + return layers, nil +} + +// Nodes returns the nodes of the receiver. +func (g DirectedLayers) Nodes() []graph.Node { + if len(g) == 0 { + return nil + } + return g[0].Nodes() +} + +// Depth returns the depth of the multiplex graph. +func (g DirectedLayers) Depth() int { return len(g) } + +// Layer returns the lth layer of the multiplex graph. +func (g DirectedLayers) Layer(l int) graph.Directed { return g[l] } + +// louvainDirectedMultiplex returns the hierarchical modularization of g at the given resolution +// using the Louvain algorithm. If all is true and g has negatively weighted layers, all +// communities will be searched during the modularization. If src is nil, rand.Intn is +// used as the random generator. louvainDirectedMultiplex will panic if g has any edge with +// edge weight that does not sign-match the layer weight. +// +// graph.Undirect may be used as a shim to allow modularization of directed graphs. +func louvainDirectedMultiplex(g DirectedMultiplex, weights, resolutions []float64, all bool, src *rand.Rand) *ReducedDirectedMultiplex { + if weights != nil && len(weights) != g.Depth() { + panic("community: weights vector length mismatch") + } + if resolutions != nil && len(resolutions) != 1 && len(resolutions) != g.Depth() { + panic("community: resolutions vector length mismatch") + } + + // See louvain.tex for a detailed description + // of the algorithm used here. + + c := reduceDirectedMultiplex(g, nil, weights) + rnd := rand.Intn + if src != nil { + rnd = src.Intn + } + for { + l := newDirectedMultiplexLocalMover(c, c.communities, weights, resolutions, all) + if l == nil { + return c + } + if done := l.localMovingHeuristic(rnd); done { + return c + } + c = reduceDirectedMultiplex(c, l.communities, weights) + } +} + +// ReducedDirectedMultiplex is a directed graph of communities derived from a +// parent graph by reduction. +type ReducedDirectedMultiplex struct { + // nodes is the set of nodes held + // by the graph. In a ReducedDirectedMultiplex + // the node ID is the index into + // nodes. + nodes []multiplexCommunity + layers []directedEdges + + // communities is the community + // structure of the graph. + communities [][]graph.Node + + parent *ReducedDirectedMultiplex +} + +var ( + _ DirectedMultiplex = (*ReducedDirectedMultiplex)(nil) + _ graph.WeightedDirected = (*directedLayerHandle)(nil) +) + +// Nodes returns all the nodes in the graph. +func (g *ReducedDirectedMultiplex) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.nodes)) + for i := range g.nodes { + nodes[i] = node(i) + } + return nodes +} + +// Depth returns the number of layers in the multiplex graph. +func (g *ReducedDirectedMultiplex) Depth() int { return len(g.layers) } + +// Layer returns the lth layer of the multiplex graph. +func (g *ReducedDirectedMultiplex) Layer(l int) graph.Directed { + return directedLayerHandle{multiplex: g, layer: l} +} + +// Communities returns the community memberships of the nodes in the +// graph used to generate the reduced graph. +func (g *ReducedDirectedMultiplex) Communities() [][]graph.Node { + communities := make([][]graph.Node, len(g.communities)) + if g.parent == nil { + for i, members := range g.communities { + comm := make([]graph.Node, len(members)) + for j, n := range members { + nodes := g.nodes[n.ID()].nodes + if len(nodes) != 1 { + panic("community: unexpected number of nodes in base graph community") + } + comm[j] = nodes[0] + } + communities[i] = comm + } + return communities + } + sub := g.parent.Communities() + for i, members := range g.communities { + var comm []graph.Node + for _, n := range members { + comm = append(comm, sub[n.ID()]...) + } + communities[i] = comm + } + return communities +} + +// Structure returns the community structure of the current level of +// the module clustering. The first index of the returned value +// corresponds to the index of the nodes in the next higher level if +// it exists. The returned value should not be mutated. +func (g *ReducedDirectedMultiplex) Structure() [][]graph.Node { + return g.communities +} + +// Expanded returns the next lower level of the module clustering or nil +// if at the lowest level. +func (g *ReducedDirectedMultiplex) Expanded() ReducedMultiplex { + return g.parent +} + +// reduceDirectedMultiplex returns a reduced graph constructed from g divided +// into the given communities. The communities value is mutated +// by the call to reduceDirectedMultiplex. If communities is nil and g is a +// ReducedDirectedMultiplex, it is returned unaltered. +func reduceDirectedMultiplex(g DirectedMultiplex, communities [][]graph.Node, weights []float64) *ReducedDirectedMultiplex { + if communities == nil { + if r, ok := g.(*ReducedDirectedMultiplex); ok { + return r + } + + nodes := g.Nodes() + // TODO(kortschak) This sort is necessary really only + // for testing. In practice we would not be using the + // community provided by the user for a Q calculation. + // Probably we should use a function to map the + // communities in the test sets to the remapped order. + sort.Sort(ordered.ByID(nodes)) + communities = make([][]graph.Node, len(nodes)) + for i := range nodes { + communities[i] = []graph.Node{node(i)} + } + + r := ReducedDirectedMultiplex{ + nodes: make([]multiplexCommunity, len(nodes)), + layers: make([]directedEdges, g.Depth()), + communities: communities, + } + communityOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + r.nodes[i] = multiplexCommunity{id: i, nodes: []graph.Node{n}, weights: make([]float64, depth(weights))} + communityOf[n.ID()] = i + } + for i := range r.layers { + r.layers[i] = directedEdges{ + edgesFrom: make([][]int, len(nodes)), + edgesTo: make([][]int, len(nodes)), + weights: make(map[[2]int]float64), + } + } + w := 1.0 + for l := 0; l < g.Depth(); l++ { + layer := g.Layer(l) + if weights != nil { + w = weights[l] + } + if w == 0 { + continue + } + var sign float64 + var weight func(x, y graph.Node) float64 + if w < 0 { + sign, weight = -1, negativeWeightFuncFor(layer) + } else { + sign, weight = 1, positiveWeightFuncFor(layer) + } + for _, n := range nodes { + id := communityOf[n.ID()] + + var out []int + u := n + for _, v := range layer.From(u) { + vid := communityOf[v.ID()] + if vid != id { + out = append(out, vid) + } + r.layers[l].weights[[2]int{id, vid}] = sign * weight(u, v) + } + r.layers[l].edgesFrom[id] = out + + var in []int + v := n + for _, u := range layer.To(v) { + uid := communityOf[u.ID()] + if uid != id { + in = append(in, uid) + } + r.layers[l].weights[[2]int{uid, id}] = sign * weight(u, v) + } + r.layers[l].edgesTo[id] = in + } + } + return &r + } + + // Remove zero length communities destructively. + var commNodes int + for i := 0; i < len(communities); { + comm := communities[i] + if len(comm) == 0 { + communities[i] = communities[len(communities)-1] + communities[len(communities)-1] = nil + communities = communities[:len(communities)-1] + } else { + commNodes += len(comm) + i++ + } + } + + r := ReducedDirectedMultiplex{ + nodes: make([]multiplexCommunity, len(communities)), + layers: make([]directedEdges, g.Depth()), + } + communityOf := make(map[int64]int, commNodes) + for i, comm := range communities { + r.nodes[i] = multiplexCommunity{id: i, nodes: comm, weights: make([]float64, depth(weights))} + for _, n := range comm { + communityOf[n.ID()] = i + } + } + for i := range r.layers { + r.layers[i] = directedEdges{ + edgesFrom: make([][]int, len(communities)), + edgesTo: make([][]int, len(communities)), + weights: make(map[[2]int]float64), + } + } + r.communities = make([][]graph.Node, len(communities)) + for i := range r.communities { + r.communities[i] = []graph.Node{node(i)} + } + if g, ok := g.(*ReducedDirectedMultiplex); ok { + // Make sure we retain the truncated + // community structure. + g.communities = communities + r.parent = g + } + w := 1.0 + for l := 0; l < g.Depth(); l++ { + layer := g.Layer(l) + if weights != nil { + w = weights[l] + } + if w == 0 { + continue + } + var sign float64 + var weight func(x, y graph.Node) float64 + if w < 0 { + sign, weight = -1, negativeWeightFuncFor(layer) + } else { + sign, weight = 1, positiveWeightFuncFor(layer) + } + for id, comm := range communities { + var out, in []int + for _, n := range comm { + u := n + for _, v := range comm { + r.nodes[id].weights[l] += sign * weight(u, v) + } + + for _, v := range layer.From(u) { + vid := communityOf[v.ID()] + found := false + for _, e := range out { + if e == vid { + found = true + break + } + } + if !found && vid != id { + out = append(out, vid) + } + // Add half weights because the other + // ends of edges are also counted. + r.layers[l].weights[[2]int{id, vid}] += sign * weight(u, v) / 2 + } + + v := n + for _, u := range layer.To(v) { + uid := communityOf[u.ID()] + found := false + for _, e := range in { + if e == uid { + found = true + break + } + } + if !found && uid != id { + in = append(in, uid) + } + // Add half weights because the other + // ends of edges are also counted. + r.layers[l].weights[[2]int{uid, id}] += sign * weight(u, v) / 2 + } + + } + r.layers[l].edgesFrom[id] = out + r.layers[l].edgesTo[id] = in + } + } + return &r +} + +// directedLayerHandle is a handle to a multiplex graph layer. +type directedLayerHandle struct { + // multiplex is the complete + // multiplex graph. + multiplex *ReducedDirectedMultiplex + + // layer is an index into the + // multiplex for the current + // layer. + layer int +} + +// Has returns whether the node exists within the graph. +func (g directedLayerHandle) Has(n graph.Node) bool { + id := n.ID() + return 0 <= id && id < int64(len(g.multiplex.nodes)) +} + +// Nodes returns all the nodes in the graph. +func (g directedLayerHandle) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.multiplex.nodes)) + for i := range g.multiplex.nodes { + nodes[i] = node(i) + } + return nodes +} + +// From returns all nodes in g that can be reached directly from u. +func (g directedLayerHandle) From(u graph.Node) []graph.Node { + out := g.multiplex.layers[g.layer].edgesFrom[u.ID()] + nodes := make([]graph.Node, len(out)) + for i, vid := range out { + nodes[i] = g.multiplex.nodes[vid] + } + return nodes +} + +// To returns all nodes in g that can reach directly to v. +func (g directedLayerHandle) To(v graph.Node) []graph.Node { + in := g.multiplex.layers[g.layer].edgesTo[v.ID()] + nodes := make([]graph.Node, len(in)) + for i, uid := range in { + nodes[i] = g.multiplex.nodes[uid] + } + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g directedLayerHandle) HasEdgeBetween(x, y graph.Node) bool { + xid := x.ID() + yid := y.ID() + if xid == yid { + return false + } + if xid == yid || !isValidID(xid) || !isValidID(yid) { + return false + } + _, ok := g.multiplex.layers[g.layer].weights[[2]int{int(xid), int(yid)}] + if ok { + return true + } + _, ok = g.multiplex.layers[g.layer].weights[[2]int{int(yid), int(xid)}] + return ok +} + +// HasEdgeFromTo returns whether an edge exists from node u to v. +func (g directedLayerHandle) HasEdgeFromTo(u, v graph.Node) bool { + uid := u.ID() + vid := v.ID() + if uid == vid || !isValidID(uid) || !isValidID(vid) { + return false + } + _, ok := g.multiplex.layers[g.layer].weights[[2]int{int(uid), int(vid)}] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g directedLayerHandle) Edge(u, v graph.Node) graph.Edge { + return g.WeightedEdge(u, v) +} + +// 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 directedLayerHandle) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + uid := u.ID() + vid := v.ID() + if uid == vid || !isValidID(uid) || !isValidID(vid) { + return nil + } + w, ok := g.multiplex.layers[g.layer].weights[[2]int{int(uid), int(vid)}] + if !ok { + return nil + } + return multiplexEdge{from: g.multiplex.nodes[u.ID()], to: g.multiplex.nodes[v.ID()], weight: w} +} + +// 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 the internal node weight is returned. If there is no joining +// edge between the two nodes the weight value returned is zero. Weight returns true if an edge +// exists between x and y or if x and y have the same ID, false otherwise. +func (g directedLayerHandle) Weight(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if !isValidID(xid) || !isValidID(yid) { + return 0, false + } + if xid == yid { + return g.multiplex.nodes[xid].weights[g.layer], true + } + w, ok = g.multiplex.layers[g.layer].weights[[2]int{int(xid), int(yid)}] + return w, ok +} + +// directedMultiplexLocalMover is a step in graph modularity optimization. +type directedMultiplexLocalMover struct { + g *ReducedDirectedMultiplex + + // nodes is the set of working nodes. + nodes []graph.Node + // edgeWeightsOf is the weighted degree + // of each node indexed by ID. + edgeWeightsOf [][]directedWeights + + // m is the total sum of + // edge weights in g. + m []float64 + + // weight is the weight function + // provided by g or a function + // that returns the Weight value + // of the non-nil edge between x + // and y. + weight []func(x, y graph.Node) float64 + + // communities is the current + // division of g. + communities [][]graph.Node + // memberships is a mapping between + // node ID and community membership. + memberships []int + + // resolution is the Reichardt and + // Bornholdt γ parameter as defined + // in doi:10.1103/PhysRevE.74.016110. + resolutions []float64 + + // weights is the layer weights for + // the modularisation. + weights []float64 + + // searchAll specifies whether the local + // mover should consider non-connected + // communities during the local moving + // heuristic. + searchAll bool + + // moved indicates that a call to + // move has been made since the last + // call to shuffle. + moved bool + + // changed indicates that a move + // has been made since the creation + // of the local mover. + changed bool +} + +// newDirectedMultiplexLocalMover returns a new directedMultiplexLocalMover initialized with +// the graph g, a set of communities and a modularity resolution parameter. The +// node IDs of g must be contiguous in [0,n) where n is the number of nodes. +// If g has a zero edge weight sum, nil is returned. +func newDirectedMultiplexLocalMover(g *ReducedDirectedMultiplex, communities [][]graph.Node, weights, resolutions []float64, all bool) *directedMultiplexLocalMover { + nodes := g.Nodes() + l := directedMultiplexLocalMover{ + g: g, + nodes: nodes, + edgeWeightsOf: make([][]directedWeights, g.Depth()), + m: make([]float64, g.Depth()), + communities: communities, + memberships: make([]int, len(nodes)), + resolutions: resolutions, + weights: weights, + weight: make([]func(x, y graph.Node) float64, g.Depth()), + } + + // Calculate the total edge weight of the graph + // and degree weights for each node. + var zero int + for i := 0; i < g.Depth(); i++ { + l.edgeWeightsOf[i] = make([]directedWeights, len(nodes)) + var weight func(x, y graph.Node) float64 + + if weights != nil { + if weights[i] == 0 { + zero++ + continue + } + if weights[i] < 0 { + weight = negativeWeightFuncFor(g.Layer(i)) + l.searchAll = all + } else { + weight = positiveWeightFuncFor(g.Layer(i)) + } + } else { + weight = positiveWeightFuncFor(g.Layer(i)) + } + + l.weight[i] = weight + layer := g.Layer(i) + for _, n := range l.nodes { + u := n + var wOut float64 + for _, v := range layer.From(u) { + wOut += weight(u, v) + } + + v := n + var wIn float64 + for _, u := range layer.To(v) { + wIn += weight(u, v) + } + + w := weight(n, n) + l.edgeWeightsOf[i][u.ID()] = directedWeights{out: w + wOut, in: w + wIn} + l.m[i] += w + wOut + } + if l.m[i] == 0 { + zero++ + } + } + if zero == g.Depth() { + return nil + } + + // Assign membership mappings. + for i, c := range communities { + for _, n := range c { + l.memberships[n.ID()] = i + } + } + + return &l +} + +// localMovingHeuristic performs the Louvain local moving heuristic until +// no further moves can be made. It returns a boolean indicating that the +// directedMultiplexLocalMover has not made any improvement to the community +// structure and so the Louvain algorithm is done. +func (l *directedMultiplexLocalMover) localMovingHeuristic(rnd func(int) int) (done bool) { + for { + l.shuffle(rnd) + for _, n := range l.nodes { + dQ, dst, src := l.deltaQ(n) + if dQ <= 0 { + continue + } + l.move(dst, src) + } + if !l.moved { + return !l.changed + } + } +} + +// shuffle performs a Fisher-Yates shuffle on the nodes held by the +// directedMultiplexLocalMover using the random source rnd which should return +// an integer in the range [0,n). +func (l *directedMultiplexLocalMover) shuffle(rnd func(n int) int) { + l.moved = false + for i := range l.nodes[:len(l.nodes)-1] { + j := i + rnd(len(l.nodes)-i) + l.nodes[i], l.nodes[j] = l.nodes[j], l.nodes[i] + } +} + +// move moves the node at src to the community at dst. +func (l *directedMultiplexLocalMover) move(dst int, src commIdx) { + l.moved = true + l.changed = true + + srcComm := l.communities[src.community] + n := srcComm[src.node] + + l.memberships[n.ID()] = dst + + l.communities[dst] = append(l.communities[dst], n) + srcComm[src.node], srcComm[len(srcComm)-1] = srcComm[len(srcComm)-1], nil + l.communities[src.community] = srcComm[:len(srcComm)-1] +} + +// deltaQ returns the highest gain in modularity attainable by moving +// n from its current community to another connected community and +// the index of the chosen destination. The index into the +// directedMultiplexLocalMover's communities field is returned in src if n +// is in communities. +func (l *directedMultiplexLocalMover) deltaQ(n graph.Node) (deltaQ float64, dst int, src commIdx) { + id := n.ID() + + var iterator minTaker + if l.searchAll { + iterator = &dense{n: len(l.communities)} + } else { + // Find communities connected to n. + connected := make(set.Ints) + // The following for loop is equivalent to: + // + // for i := 0; i < l.g.Depth(); i++ { + // for _, v := range l.g.Layer(i).From(n) { + // connected.Add(l.memberships[v.ID()]) + // } + // for _, v := range l.g.Layer(i).To(n) { + // connected.Add(l.memberships[v.ID()]) + // } + // } + // + // This is done to avoid an allocation for + // each layer. + for _, layer := range l.g.layers { + for _, vid := range layer.edgesFrom[id] { + connected.Add(l.memberships[vid]) + } + for _, vid := range layer.edgesTo[id] { + connected.Add(l.memberships[vid]) + } + } + // Insert the node's own community. + connected.Add(l.memberships[id]) + iterator = newSlice(connected) + } + + // Calculate the highest modularity gain + // from moving into another community and + // keep the index of that community. + var dQremove float64 + dQadd, dst, src := math.Inf(-1), -1, commIdx{-1, -1} + var i int + for iterator.TakeMin(&i) { + c := l.communities[i] + var removal bool + var _dQadd float64 + for layer := 0; layer < l.g.Depth(); layer++ { + m := l.m[layer] + if m == 0 { + // Do not consider layers with zero sum edge weight. + continue + } + w := 1.0 + if l.weights != nil { + w = l.weights[layer] + } + if w == 0 { + // Do not consider layers with zero weighting. + continue + } + + var k_aC, sigma_totC directedWeights // C is a substitution for ^𝛼 or ^𝛽. + removal = false + for j, u := range c { + uid := u.ID() + if uid == id { + // Only mark and check src community on the first layer. + if layer == 0 { + if src.community != -1 { + panic("community: multiple sources") + } + src = commIdx{i, j} + } + removal = true + } + + k_aC.in += l.weight[layer](n, u) + k_aC.out += l.weight[layer](u, n) + // sigma_totC could be kept for each community + // and updated for moves, changing the calculation + // of sigma_totC here from O(n_c) to O(1), but + // in practice the time savings do not appear + // to be compelling and do not make up for the + // increase in code complexity and space required. + w := l.edgeWeightsOf[layer][uid] + sigma_totC.in += w.in + sigma_totC.out += w.out + } + + a_aa := l.weight[layer](n, n) + k_a := l.edgeWeightsOf[layer][id] + gamma := 1.0 + if l.resolutions != nil { + if len(l.resolutions) == 1 { + gamma = l.resolutions[0] + } else { + gamma = l.resolutions[layer] + } + } + + // See louvain.tex for a derivation of these equations. + // The weighting term, w, is described in V Traag, + // "Algorithms and dynamical models for communities and + // reputation in social networks", chapter 5. + // http://www.traag.net/wp/wp-content/papercite-data/pdf/traag_algorithms_2013.pdf + switch { + case removal: + // The community c was the current community, + // so calculate the change due to removal. + dQremove += w * ((k_aC.in /*^𝛼*/ - a_aa) + (k_aC.out /*^𝛼*/ - a_aa) - + gamma*(k_a.in*(sigma_totC.out /*^𝛼*/ -k_a.out)+k_a.out*(sigma_totC.in /*^𝛼*/ -k_a.in))/m) + + default: + // Otherwise calculate the change due to an addition + // to c. + _dQadd += w * (k_aC.in /*^𝛽*/ + k_aC.out /*^𝛽*/ - + gamma*(k_a.in*sigma_totC.out /*^𝛽*/ +k_a.out*sigma_totC.in /*^𝛽*/)/m) + } + } + if !removal && _dQadd > dQadd { + dQadd = _dQadd + dst = i + } + } + + return dQadd - dQremove, dst, src +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_multiplex_test.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_multiplex_test.go new file mode 100644 index 00000000..896c6122 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_multiplex_test.go @@ -0,0 +1,722 @@ +// 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 community + +import ( + "math" + "math/rand" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +var communityDirectedMultiplexQTests = []struct { + name string + layers []layer + structures []structure + + wantLevels []level +}{ + { + name: "unconnected", + layers: []layer{{g: unconnected, weight: 1}}, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0), + 1: linksTo(1), + 2: linksTo(2), + 3: linksTo(3), + 4: linksTo(4), + 5: linksTo(5), + }, + want: math.NaN(), + }, + }, + wantLevels: []level{ + { + q: math.Inf(-1), // Here math.Inf(-1) is used as a place holder for NaN to allow use of reflect.DeepEqual. + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "simple_directed", + layers: []layer{{g: simpleDirected, weight: 1}}, + // community structure and modularity calculated by C++ implementation: louvain igraph. + // Note that louvain igraph returns Q as an unscaled value. + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1), + 1: linksTo(2, 3, 4), + }, + want: 0.5714285714285716, + tol: 1e-10, + }, + }, + wantLevels: []level{ + { + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1)}, + {simple.Node(2), simple.Node(3), simple.Node(4)}, + }, + q: 0.5714285714285716, + }, + { + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + }, + q: -1.2857142857142856, + }, + }, + }, + { + name: "simple_directed_twice", + layers: []layer{ + {g: simpleDirected, weight: 0.5}, + {g: simpleDirected, weight: 0.5}, + }, + // community structure and modularity calculated by C++ implementation: louvain igraph. + // Note that louvain igraph returns Q as an unscaled value. + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1), + 1: linksTo(2, 3, 4), + }, + want: 0.5714285714285716, + tol: 1e-10, + }, + }, + wantLevels: []level{ + { + q: 0.5714285714285716, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1)}, + {simple.Node(2), simple.Node(3), simple.Node(4)}, + }, + }, + { + q: -1.2857142857142856, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + }, + }, + }, + }, + { + name: "small_dumbell", + layers: []layer{ + {g: smallDumbell, edgeWeight: 1, weight: 1}, + {g: dumbellRepulsion, edgeWeight: -1, weight: -1}, + }, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2), + 1: linksTo(3, 4, 5), + }, + want: 2.5714285714285716, tol: 1e-10, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5), + }, + want: 0, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 2.5714285714285716, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + {simple.Node(3), simple.Node(4), simple.Node(5)}, + }, + }, + { + q: -0.857142857142857, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "repulsion", + layers: []layer{{g: repulsion, edgeWeight: -1, weight: -1}}, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2), + 1: linksTo(3, 4, 5), + }, + want: 9.0, tol: 1e-10, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0), + 1: linksTo(1), + 2: linksTo(2), + 3: linksTo(3), + 4: linksTo(4), + 5: linksTo(5), + }, + want: 3, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 9.0, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + {simple.Node(3), simple.Node(4), simple.Node(5)}, + }, + }, + { + q: 3.0, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "middle_east", + layers: []layer{ + {g: middleEast.friends, edgeWeight: 1, weight: 1}, + {g: middleEast.enemies, edgeWeight: -1, weight: -1}, + }, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 6), + 1: linksTo(1, 7, 9, 12), + 2: linksTo(2, 8, 11), + 3: linksTo(3, 4, 5, 10), + }, + want: 33.818057455540355, tol: 1e-9, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 2, 3, 4, 5, 10), + 1: linksTo(1, 7, 9, 12), + 2: linksTo(6), + 3: linksTo(8, 11), + }, + want: 30.92749658, tol: 1e-7, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), + }, + want: 0, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 33.818057455540355, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(6)}, + {simple.Node(1), simple.Node(7), simple.Node(9), simple.Node(12)}, + {simple.Node(2), simple.Node(8), simple.Node(11)}, + {simple.Node(3), simple.Node(4), simple.Node(5), simple.Node(10)}, + }, + }, + { + q: 3.8071135430916545, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + {simple.Node(6)}, + {simple.Node(7)}, + {simple.Node(8)}, + {simple.Node(9)}, + {simple.Node(10)}, + {simple.Node(11)}, + {simple.Node(12)}, + }, + }, + }, + }, +} + +func TestCommunityQDirectedMultiplex(t *testing.T) { + for _, test := range communityDirectedMultiplexQTests { + g, weights, err := directedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + } + q := QMultiplex(g, communities, weights, []float64{structure.resolution}) + got := floats.Sum(q) + if !floats.EqualWithinAbsOrRel(got, structure.want, structure.tol, structure.tol) && !math.IsNaN(structure.want) { + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + t.Errorf("unexpected Q value for %q %v: got: %v %.3v want: %v", + test.name, communities, got, q, structure.want) + } + } + } +} + +func TestCommunityDeltaQDirectedMultiplex(t *testing.T) { +tests: + for _, test := range communityDirectedMultiplexQTests { + g, weights, err := directedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + rnd := rand.New(rand.NewSource(1)).Intn + for _, structure := range test.structures { + communityOf := make(map[int64]int) + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + communityOf[n] = i + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + resolution := []float64{structure.resolution} + + before := QMultiplex(g, communities, weights, resolution) + + // We test exhaustively. + const all = true + + l := newDirectedMultiplexLocalMover( + reduceDirectedMultiplex(g, nil, weights), + communities, weights, resolution, all) + if l == nil { + if !math.IsNaN(floats.Sum(before)) { + t.Errorf("unexpected nil localMover with non-NaN Q graph: Q=%.4v", before) + } + continue tests + } + + // This is done to avoid run-to-run + // variation due to map iteration order. + sort.Sort(ordered.ByID(l.nodes)) + + l.shuffle(rnd) + + for _, target := range l.nodes { + got, gotDst, gotSrc := l.deltaQ(target) + + want, wantDst := math.Inf(-1), -1 + migrated := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + if n == target.ID() { + continue + } + migrated[i] = append(migrated[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(migrated[i])) + } + + for i, c := range structure.memberships { + if i == communityOf[target.ID()] { + continue + } + if !(all && hasNegative(weights)) { + connected := false + search: + for l := 0; l < g.Depth(); l++ { + if weights[l] < 0 { + connected = true + break search + } + layer := g.Layer(l) + for n := range c { + if layer.HasEdgeBetween(simple.Node(n), target) { + connected = true + break search + } + } + } + if !connected { + continue + } + } + migrated[i] = append(migrated[i], target) + after := QMultiplex(g, migrated, weights, resolution) + migrated[i] = migrated[i][:len(migrated[i])-1] + if delta := floats.Sum(after) - floats.Sum(before); delta > want { + want = delta + wantDst = i + } + } + + if !floats.EqualWithinAbsOrRel(got, want, structure.tol, structure.tol) || gotDst != wantDst { + t.Errorf("unexpected result moving n=%d in c=%d of %s/%.4v: got: %.4v,%d want: %.4v,%d"+ + "\n\t%v\n\t%v", + target.ID(), communityOf[target.ID()], test.name, structure.resolution, got, gotDst, want, wantDst, + communities, migrated) + } + if gotSrc.community != communityOf[target.ID()] { + t.Errorf("unexpected source community index: got: %d want: %d", gotSrc, communityOf[target.ID()]) + } else if communities[gotSrc.community][gotSrc.node].ID() != target.ID() { + wantNodeIdx := -1 + for i, n := range communities[gotSrc.community] { + if n.ID() == target.ID() { + wantNodeIdx = i + break + } + } + t.Errorf("unexpected source node index: got: %d want: %d", gotSrc.node, wantNodeIdx) + } + } + } + } +} + +func TestReduceQConsistencyDirectedMultiplex(t *testing.T) { +tests: + for _, test := range communityDirectedMultiplexQTests { + g, weights, err := directedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + for _, structure := range test.structures { + if math.IsNaN(structure.want) { + continue tests + } + + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + gQ := QMultiplex(g, communities, weights, []float64{structure.resolution}) + gQnull := QMultiplex(g, nil, weights, nil) + + cg0 := reduceDirectedMultiplex(g, nil, weights) + cg0Qnull := QMultiplex(cg0, cg0.Structure(), weights, nil) + if !floats.EqualWithinAbsOrRel(floats.Sum(gQnull), floats.Sum(cg0Qnull), structure.tol, structure.tol) { + t.Errorf("disagreement between null Q from method: %v and function: %v", cg0Qnull, gQnull) + } + cg0Q := QMultiplex(cg0, communities, weights, []float64{structure.resolution}) + if !floats.EqualWithinAbsOrRel(floats.Sum(gQ), floats.Sum(cg0Q), structure.tol, structure.tol) { + t.Errorf("unexpected Q result after initial reduction: got: %v want :%v", cg0Q, gQ) + } + + cg1 := reduceDirectedMultiplex(cg0, communities, weights) + cg1Q := QMultiplex(cg1, cg1.Structure(), weights, []float64{structure.resolution}) + if !floats.EqualWithinAbsOrRel(floats.Sum(gQ), floats.Sum(cg1Q), structure.tol, structure.tol) { + t.Errorf("unexpected Q result after second reduction: got: %v want :%v", cg1Q, gQ) + } + } + } +} + +var localDirectedMultiplexMoveTests = []struct { + name string + layers []layer + structures []moveStructures +}{ + { + name: "blondel", + layers: []layer{{g: blondel, weight: 1}, {g: blondel, weight: 0.5}}, + structures: []moveStructures{ + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(0)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(3)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + // Case to demonstrate when A_aa != k_a^𝛼. + targetNodes: []graph.Node{simple.Node(3), simple.Node(2)}, + resolution: 1, + tol: 1e-14, + }, + }, + }, +} + +func TestMoveLocalDirectedMultiplex(t *testing.T) { + for _, test := range localDirectedMultiplexMoveTests { + g, weights, err := directedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + r := reduceDirectedMultiplex(reduceDirectedMultiplex(g, nil, weights), communities, weights) + + l := newDirectedMultiplexLocalMover(r, r.communities, weights, []float64{structure.resolution}, true) + for _, n := range structure.targetNodes { + dQ, dst, src := l.deltaQ(n) + if dQ > 0 { + before := floats.Sum(QMultiplex(r, l.communities, weights, []float64{structure.resolution})) + l.move(dst, src) + after := floats.Sum(QMultiplex(r, l.communities, weights, []float64{structure.resolution})) + want := after - before + if !floats.EqualWithinAbsOrRel(dQ, want, structure.tol, structure.tol) { + t.Errorf("unexpected deltaQ: got: %v want: %v", dQ, want) + } + } + } + } + } +} + +func TestLouvainDirectedMultiplex(t *testing.T) { + const louvainIterations = 20 + + for _, test := range communityDirectedMultiplexQTests { + g, weights, err := directedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + if test.structures[0].resolution != 1 { + panic("bad test: expect resolution=1") + } + want := make([][]graph.Node, len(test.structures[0].memberships)) + for i, c := range test.structures[0].memberships { + for n := range c { + want[i] = append(want[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(want[i])) + } + sort.Sort(ordered.BySliceIDs(want)) + + var ( + got *ReducedDirectedMultiplex + bestQ = math.Inf(-1) + ) + // Modularize is randomised so we do this to + // ensure the level tests are consistent. + src := rand.New(rand.NewSource(1)) + for i := 0; i < louvainIterations; i++ { + r := ModularizeMultiplex(g, weights, nil, true, src).(*ReducedDirectedMultiplex) + if q := floats.Sum(QMultiplex(r, nil, weights, nil)); q > bestQ || math.IsNaN(q) { + bestQ = q + got = r + + if math.IsNaN(q) { + // Don't try again for non-connected case. + break + } + } + + var qs []float64 + for p := r; p != nil; p = p.Expanded().(*ReducedDirectedMultiplex) { + qs = append(qs, floats.Sum(QMultiplex(p, nil, weights, nil))) + } + + // Recovery of Q values is reversed. + if reverse(qs); !sort.Float64sAreSorted(qs) { + t.Errorf("Q values not monotonically increasing: %.5v", qs) + } + } + + gotCommunities := got.Communities() + for _, c := range gotCommunities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(gotCommunities)) + if !reflect.DeepEqual(gotCommunities, want) { + t.Errorf("unexpected community membership for %s Q=%.4v:\n\tgot: %v\n\twant:%v", + test.name, bestQ, gotCommunities, want) + continue + } + + var levels []level + for p := got; p != nil; p = p.Expanded().(*ReducedDirectedMultiplex) { + var communities [][]graph.Node + if p.parent != nil { + communities = p.parent.Communities() + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(communities)) + } else { + communities = reduceDirectedMultiplex(g, nil, weights).Communities() + } + q := floats.Sum(QMultiplex(p, nil, weights, nil)) + if math.IsNaN(q) { + // Use an equalable flag value in place of NaN. + q = math.Inf(-1) + } + levels = append(levels, level{q: q, communities: communities}) + } + if !reflect.DeepEqual(levels, test.wantLevels) { + t.Errorf("unexpected level structure:\n\tgot: %v\n\twant:%v", levels, test.wantLevels) + } + } +} + +func TestNonContiguousDirectedMultiplex(t *testing.T) { + g := simple.NewDirectedGraph() + for _, e := range []simple.Edge{ + {F: simple.Node(0), T: simple.Node(1)}, + {F: simple.Node(4), T: simple.Node(5)}, + } { + g.SetEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + ModularizeMultiplex(DirectedLayers{g}, nil, nil, true, nil) + }() +} + +func TestNonContiguousWeightedDirectedMultiplex(t *testing.T) { + g := simple.NewWeightedDirectedGraph(0, 0) + for _, e := range []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(4), T: simple.Node(5), W: 1}, + } { + g.SetWeightedEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + ModularizeMultiplex(DirectedLayers{g}, nil, nil, true, nil) + }() +} + +func BenchmarkLouvainDirectedMultiplex(b *testing.B) { + src := rand.New(rand.NewSource(1)) + for i := 0; i < b.N; i++ { + ModularizeMultiplex(DirectedLayers{dupGraphDirected}, nil, nil, true, src) + } +} + +func directedMultiplexFrom(raw []layer) (DirectedLayers, []float64, error) { + var layers []graph.Directed + var weights []float64 + for _, l := range raw { + g := simple.NewWeightedDirectedGraph(0, 0) + for u, e := range l.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + w := 1.0 + if l.edgeWeight != 0 { + w = l.edgeWeight + } + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: w}) + } + } + layers = append(layers, g) + weights = append(weights, l.weight) + } + g, err := NewDirectedLayers(layers...) + if err != nil { + return nil, nil, err + } + return g, weights, nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_test.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_test.go new file mode 100644 index 00000000..5810ffb7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_directed_test.go @@ -0,0 +1,719 @@ +// 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 community + +import ( + "math" + "math/rand" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +type communityDirectedQTest struct { + name string + g []intset + structures []structure + + wantLevels []level +} + +var communityDirectedQTests = []communityDirectedQTest{ + { + name: "simple_directed", + g: simpleDirected, + // community structure and modularity calculated by C++ implementation: louvain igraph. + // Note that louvain igraph returns Q as an unscaled value. + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1), + 1: linksTo(2, 3, 4), + }, + want: 0.5714285714285716 / 7, + tol: 1e-10, + }, + }, + wantLevels: []level{ + { + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1)}, + {simple.Node(2), simple.Node(3), simple.Node(4)}, + }, + q: 0.5714285714285716 / 7, + }, + { + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + }, + q: -1.2857142857142856 / 7, + }, + }, + }, + { + name: "zachary", + g: zachary, + // community structure and modularity calculated by C++ implementation: louvain igraph. + // Note that louvain igraph returns Q as an unscaled value. + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21), + 1: linksTo(4, 5, 6, 10, 16), + 2: linksTo(8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33), + 3: linksTo(23, 24, 25, 27, 28, 31), + }, + want: 34.3417721519 / 79 /* 5->6 and 6->5 because of co-equal rank */, tol: 1e-4, + }, + }, + wantLevels: []level{ + { + q: 0.43470597660631316, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(7), simple.Node(11), simple.Node(12), simple.Node(13), simple.Node(17), simple.Node(19), simple.Node(21)}, + {simple.Node(4), simple.Node(5), simple.Node(6), simple.Node(10), simple.Node(16)}, + {simple.Node(8), simple.Node(9), simple.Node(14), simple.Node(15), simple.Node(18), simple.Node(20), simple.Node(22), simple.Node(26), simple.Node(29), simple.Node(30), simple.Node(32), simple.Node(33)}, + {simple.Node(23), simple.Node(24), simple.Node(25), simple.Node(27), simple.Node(28), simple.Node(31)}, + }, + }, + { + q: 0.3911232174331037, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(7), simple.Node(11), simple.Node(12), simple.Node(13), simple.Node(17), simple.Node(19), simple.Node(21)}, + {simple.Node(4), simple.Node(10)}, + {simple.Node(5), simple.Node(6), simple.Node(16)}, + {simple.Node(8), simple.Node(30)}, + {simple.Node(9), simple.Node(14), simple.Node(15), simple.Node(18), simple.Node(20), simple.Node(22), simple.Node(32), simple.Node(33)}, + {simple.Node(23), simple.Node(24), simple.Node(25), simple.Node(27), simple.Node(28), simple.Node(31)}, + {simple.Node(26), simple.Node(29)}, + }, + }, + { + q: -0.014580996635154624, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + {simple.Node(6)}, + {simple.Node(7)}, + {simple.Node(8)}, + {simple.Node(9)}, + {simple.Node(10)}, + {simple.Node(11)}, + {simple.Node(12)}, + {simple.Node(13)}, + {simple.Node(14)}, + {simple.Node(15)}, + {simple.Node(16)}, + {simple.Node(17)}, + {simple.Node(18)}, + {simple.Node(19)}, + {simple.Node(20)}, + {simple.Node(21)}, + {simple.Node(22)}, + {simple.Node(23)}, + {simple.Node(24)}, + {simple.Node(25)}, + {simple.Node(26)}, + {simple.Node(27)}, + {simple.Node(28)}, + {simple.Node(29)}, + {simple.Node(30)}, + {simple.Node(31)}, + {simple.Node(32)}, + {simple.Node(33)}, + }, + }, + }, + }, + { + name: "blondel", + g: blondel, + // community structure and modularity calculated by C++ implementation: louvain igraph. + // Note that louvain igraph returns Q as an unscaled value. + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5, 6, 7), + 1: linksTo(8, 9, 10, 11, 12, 13, 14, 15), + }, + want: 11.1428571429 / 28, tol: 1e-4, + }, + }, + wantLevels: []level{ + { + q: 0.3979591836734694, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(4), simple.Node(5), simple.Node(6), simple.Node(7)}, + {simple.Node(8), simple.Node(9), simple.Node(10), simple.Node(11), simple.Node(12), simple.Node(13), simple.Node(14), simple.Node(15)}, + }, + }, + { + q: 0.32525510204081637, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(3), simple.Node(5), simple.Node(7)}, + {simple.Node(1), simple.Node(2), simple.Node(4), simple.Node(6)}, + {simple.Node(8), simple.Node(10), simple.Node(11), simple.Node(13), simple.Node(15)}, + {simple.Node(9), simple.Node(12), simple.Node(14)}, + }, + }, + { + q: -0.022959183673469385, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + {simple.Node(6)}, + {simple.Node(7)}, + {simple.Node(8)}, + {simple.Node(9)}, + {simple.Node(10)}, + {simple.Node(11)}, + {simple.Node(12)}, + {simple.Node(13)}, + {simple.Node(14)}, + {simple.Node(15)}, + }, + }, + }, + }, +} + +func TestCommunityQDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testCommunityQDirected(t, test, g) + } +} + +func TestCommunityQWeightedDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewWeightedDirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testCommunityQDirected(t, test, g) + } +} + +func testCommunityQDirected(t *testing.T, test communityDirectedQTest, g graph.Directed) { + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + } + got := Q(g, communities, structure.resolution) + if !floats.EqualWithinAbsOrRel(got, structure.want, structure.tol, structure.tol) && !math.IsNaN(structure.want) { + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + t.Errorf("unexpected Q value for %q %v: got: %v want: %v", + test.name, communities, got, structure.want) + } + } +} + +func TestCommunityDeltaQDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testCommunityDeltaQDirected(t, test, g) + } +} + +func TestCommunityDeltaQWeightedDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewWeightedDirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testCommunityDeltaQDirected(t, test, g) + } +} + +func testCommunityDeltaQDirected(t *testing.T, test communityDirectedQTest, g graph.Directed) { + rnd := rand.New(rand.NewSource(1)).Intn + for _, structure := range test.structures { + communityOf := make(map[int64]int) + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + communityOf[n] = i + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + before := Q(g, communities, structure.resolution) + + l := newDirectedLocalMover(reduceDirected(g, nil), communities, structure.resolution) + if l == nil { + if !math.IsNaN(before) { + t.Errorf("unexpected nil localMover with non-NaN Q graph: Q=%.4v", before) + } + return + } + + // This is done to avoid run-to-run + // variation due to map iteration order. + sort.Sort(ordered.ByID(l.nodes)) + + l.shuffle(rnd) + + for _, target := range l.nodes { + got, gotDst, gotSrc := l.deltaQ(target) + + want, wantDst := math.Inf(-1), -1 + migrated := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + if n == target.ID() { + continue + } + migrated[i] = append(migrated[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(migrated[i])) + } + + for i, c := range structure.memberships { + if i == communityOf[target.ID()] { + continue + } + connected := false + for n := range c { + if g.HasEdgeBetween(simple.Node(n), target) { + connected = true + break + } + } + if !connected { + continue + } + migrated[i] = append(migrated[i], target) + after := Q(g, migrated, structure.resolution) + migrated[i] = migrated[i][:len(migrated[i])-1] + if after-before > want { + want = after - before + wantDst = i + } + } + + if !floats.EqualWithinAbsOrRel(got, want, structure.tol, structure.tol) || gotDst != wantDst { + t.Errorf("unexpected result moving n=%d in c=%d of %s/%.4v: got: %.4v,%d want: %.4v,%d"+ + "\n\t%v\n\t%v", + target.ID(), communityOf[target.ID()], test.name, structure.resolution, got, gotDst, want, wantDst, + communities, migrated) + } + if gotSrc.community != communityOf[target.ID()] { + t.Errorf("unexpected source community index: got: %d want: %d", gotSrc, communityOf[target.ID()]) + } else if communities[gotSrc.community][gotSrc.node].ID() != target.ID() { + wantNodeIdx := -1 + for i, n := range communities[gotSrc.community] { + if n.ID() == target.ID() { + wantNodeIdx = i + break + } + } + t.Errorf("unexpected source node index: got: %d want: %d", gotSrc.node, wantNodeIdx) + } + } + } +} + +func TestReduceQConsistencyDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testReduceQConsistencyDirected(t, test, g) + } +} + +func TestReduceQConsistencyWeightedDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewWeightedDirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testReduceQConsistencyDirected(t, test, g) + } +} + +func testReduceQConsistencyDirected(t *testing.T, test communityDirectedQTest, g graph.Directed) { + for _, structure := range test.structures { + if math.IsNaN(structure.want) { + return + } + + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + gQ := Q(g, communities, structure.resolution) + gQnull := Q(g, nil, 1) + + cg0 := reduceDirected(g, nil) + cg0Qnull := Q(cg0, cg0.Structure(), 1) + if !floats.EqualWithinAbsOrRel(gQnull, cg0Qnull, structure.tol, structure.tol) { + t.Errorf("disagreement between null Q from method: %v and function: %v", cg0Qnull, gQnull) + } + cg0Q := Q(cg0, communities, structure.resolution) + if !floats.EqualWithinAbsOrRel(gQ, cg0Q, structure.tol, structure.tol) { + t.Errorf("unexpected Q result after initial reduction: got: %v want :%v", cg0Q, gQ) + } + + cg1 := reduceDirected(cg0, communities) + cg1Q := Q(cg1, cg1.Structure(), structure.resolution) + if !floats.EqualWithinAbsOrRel(gQ, cg1Q, structure.tol, structure.tol) { + t.Errorf("unexpected Q result after second reduction: got: %v want :%v", cg1Q, gQ) + } + } +} + +type localDirectedMoveTest struct { + name string + g []intset + structures []moveStructures +} + +var localDirectedMoveTests = []localDirectedMoveTest{ + { + name: "blondel", + g: blondel, + structures: []moveStructures{ + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(0)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(3)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + // Case to demonstrate when A_aa != k_a^𝛼. + targetNodes: []graph.Node{simple.Node(3), simple.Node(2)}, + resolution: 1, + tol: 1e-14, + }, + }, + }, +} + +func TestMoveLocalDirected(t *testing.T) { + for _, test := range localDirectedMoveTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testMoveLocalDirected(t, test, g) + } +} + +func TestMoveLocalWeightedDirected(t *testing.T) { + for _, test := range localDirectedMoveTests { + g := simple.NewWeightedDirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testMoveLocalDirected(t, test, g) + } +} + +func testMoveLocalDirected(t *testing.T, test localDirectedMoveTest, g graph.Directed) { + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + r := reduceDirected(reduceDirected(g, nil), communities) + + l := newDirectedLocalMover(r, r.communities, structure.resolution) + for _, n := range structure.targetNodes { + dQ, dst, src := l.deltaQ(n) + if dQ > 0 { + before := Q(r, l.communities, structure.resolution) + l.move(dst, src) + after := Q(r, l.communities, structure.resolution) + want := after - before + if !floats.EqualWithinAbsOrRel(dQ, want, structure.tol, structure.tol) { + t.Errorf("unexpected deltaQ: got: %v want: %v", dQ, want) + } + } + } + } +} + +func TestModularizeDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testModularizeDirected(t, test, g) + } +} + +func TestModularizeWeightedDirected(t *testing.T) { + for _, test := range communityDirectedQTests { + g := simple.NewWeightedDirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testModularizeDirected(t, test, g) + } +} + +func testModularizeDirected(t *testing.T, test communityDirectedQTest, g graph.Directed) { + const louvainIterations = 20 + + if test.structures[0].resolution != 1 { + panic("bad test: expect resolution=1") + } + want := make([][]graph.Node, len(test.structures[0].memberships)) + for i, c := range test.structures[0].memberships { + for n := range c { + want[i] = append(want[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(want[i])) + } + sort.Sort(ordered.BySliceIDs(want)) + + var ( + got *ReducedDirected + bestQ = math.Inf(-1) + ) + // Modularize is randomised so we do this to + // ensure the level tests are consistent. + src := rand.New(rand.NewSource(1)) + for i := 0; i < louvainIterations; i++ { + r := Modularize(g, 1, src).(*ReducedDirected) + if q := Q(r, nil, 1); q > bestQ || math.IsNaN(q) { + bestQ = q + got = r + + if math.IsNaN(q) { + // Don't try again for non-connected case. + break + } + } + + var qs []float64 + for p := r; p != nil; p = p.Expanded().(*ReducedDirected) { + qs = append(qs, Q(p, nil, 1)) + } + + // Recovery of Q values is reversed. + if reverse(qs); !sort.Float64sAreSorted(qs) { + t.Errorf("Q values not monotonically increasing: %.5v", qs) + } + } + + gotCommunities := got.Communities() + for _, c := range gotCommunities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(gotCommunities)) + if !reflect.DeepEqual(gotCommunities, want) { + t.Errorf("unexpected community membership for %s Q=%.4v:\n\tgot: %v\n\twant:%v", + test.name, bestQ, gotCommunities, want) + return + } + + var levels []level + for p := got; p != nil; p = p.Expanded().(*ReducedDirected) { + var communities [][]graph.Node + if p.parent != nil { + communities = p.parent.Communities() + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(communities)) + } else { + communities = reduceDirected(g, nil).Communities() + } + q := Q(p, nil, 1) + if math.IsNaN(q) { + // Use an equalable flag value in place of NaN. + q = math.Inf(-1) + } + levels = append(levels, level{q: q, communities: communities}) + } + if !reflect.DeepEqual(levels, test.wantLevels) { + t.Errorf("unexpected level structure:\n\tgot: %v\n\twant:%v", levels, test.wantLevels) + } +} + +func TestNonContiguousDirected(t *testing.T) { + g := simple.NewDirectedGraph() + for _, e := range []simple.Edge{ + {F: simple.Node(0), T: simple.Node(1)}, + {F: simple.Node(4), T: simple.Node(5)}, + } { + g.SetEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + Modularize(g, 1, nil) + }() +} + +func TestNonContiguousWeightedDirected(t *testing.T) { + g := simple.NewWeightedDirectedGraph(0, 0) + for _, e := range []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(4), T: simple.Node(5), W: 1}, + } { + g.SetWeightedEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + Modularize(g, 1, nil) + }() +} + +func BenchmarkLouvainDirected(b *testing.B) { + src := rand.New(rand.NewSource(1)) + for i := 0; i < b.N; i++ { + Modularize(dupGraphDirected, 1, src) + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_test.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_test.go new file mode 100644 index 00000000..32631404 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_test.go @@ -0,0 +1,277 @@ +// 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 community + +import ( + "fmt" + "math/rand" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/graphs/gen" + "gonum.org/v1/gonum/graph/simple" +) + +// intset is an integer set. +type intset map[int]struct{} + +func linksTo(i ...int) intset { + if len(i) == 0 { + return nil + } + s := make(intset) + for _, v := range i { + s[v] = struct{}{} + } + return s +} + +type layer struct { + g []intset + edgeWeight float64 // Zero edge weight is interpreted as 1.0. + weight float64 +} + +var ( + unconnected = []intset{ /* Nodes 0-4 are implicit .*/ 5: nil} + + smallDumbell = []intset{ + 0: linksTo(1, 2), + 1: linksTo(2), + 2: linksTo(3), + 3: linksTo(4, 5), + 4: linksTo(5), + 5: nil, + } + dumbellRepulsion = []intset{ + 0: linksTo(4), + 1: linksTo(5), + 2: nil, + 3: nil, + 4: nil, + 5: nil, + } + + repulsion = []intset{ + 0: linksTo(3, 4, 5), + 1: linksTo(3, 4, 5), + 2: linksTo(3, 4, 5), + 3: linksTo(0, 1, 2), + 4: linksTo(0, 1, 2), + 5: linksTo(0, 1, 2), + } + + simpleDirected = []intset{ + 0: linksTo(1), + 1: linksTo(0, 4), + 2: linksTo(1), + 3: linksTo(0, 4), + 4: linksTo(2), + } + + // http://www.slate.com/blogs/the_world_/2014/07/17/the_middle_east_friendship_chart.html + middleEast = struct{ friends, complicated, enemies []intset }{ + // green cells + friends: []intset{ + 0: nil, + 1: linksTo(5, 7, 9, 12), + 2: linksTo(11), + 3: linksTo(4, 5, 10), + 4: linksTo(3, 5, 10), + 5: linksTo(1, 3, 4, 8, 10, 12), + 6: nil, + 7: linksTo(1, 12), + 8: linksTo(5, 9, 11), + 9: linksTo(1, 8, 12), + 10: linksTo(3, 4, 5), + 11: linksTo(2, 8), + 12: linksTo(1, 5, 7, 9), + }, + + // yellow cells + complicated: []intset{ + 0: linksTo(2, 4), + 1: linksTo(4, 8), + 2: linksTo(0, 3, 4, 5, 8, 9), + 3: linksTo(2, 8, 11), + 4: linksTo(0, 1, 2, 8), + 5: linksTo(2), + 6: nil, + 7: linksTo(9, 11), + 8: linksTo(1, 2, 3, 4, 10, 12), + 9: linksTo(2, 7, 11), + 10: linksTo(8), + 11: linksTo(3, 7, 9, 12), + 12: linksTo(8, 11), + }, + + // red cells + enemies: []intset{ + 0: linksTo(1, 3, 5, 6, 7, 8, 9, 10, 11, 12), + 1: linksTo(0, 2, 3, 6, 10, 11), + 2: linksTo(1, 6, 7, 10, 12), + 3: linksTo(0, 1, 6, 7, 9, 12), + 4: linksTo(6, 7, 9, 11, 12), + 5: linksTo(0, 6, 7, 9, 11), + 6: linksTo(0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12), + 7: linksTo(0, 2, 3, 4, 5, 6, 8, 10), + 8: linksTo(0, 6, 7), + 9: linksTo(0, 3, 4, 5, 6, 10), + 10: linksTo(0, 1, 2, 6, 7, 9, 11, 12), + 11: linksTo(0, 1, 4, 5, 6, 10), + 12: linksTo(0, 2, 3, 4, 6, 10), + }, + } + + // W. W. Zachary, An information flow model for conflict and fission in small groups, + // Journal of Anthropological Research 33, 452-473 (1977). + // + // The edge list here is constructed such that all link descriptions + // head from a node with lower Page Rank to a node with higher Page + // Rank. This has no impact on undirected tests, but allows a sensible + // view for directed tests. + zachary = []intset{ + 0: nil, // rank=0.097 + 1: linksTo(0, 2), // rank=0.05288 + 2: linksTo(0, 32), // rank=0.05708 + 3: linksTo(0, 1, 2), // rank=0.03586 + 4: linksTo(0, 6, 10), // rank=0.02198 + 5: linksTo(0, 6), // rank=0.02911 + 6: linksTo(0, 5), // rank=0.02911 + 7: linksTo(0, 1, 2, 3), // rank=0.02449 + 8: linksTo(0, 2, 32, 33), // rank=0.02977 + 9: linksTo(2, 33), // rank=0.01431 + 10: linksTo(0, 5), // rank=0.02198 + 11: linksTo(0), // rank=0.009565 + 12: linksTo(0, 3), // rank=0.01464 + 13: linksTo(0, 1, 2, 3, 33), // rank=0.02954 + 14: linksTo(32, 33), // rank=0.01454 + 15: linksTo(32, 33), // rank=0.01454 + 16: linksTo(5, 6), // rank=0.01678 + 17: linksTo(0, 1), // rank=0.01456 + 18: linksTo(32, 33), // rank=0.01454 + 19: linksTo(0, 1, 33), // rank=0.0196 + 20: linksTo(32, 33), // rank=0.01454 + 21: linksTo(0, 1), // rank=0.01456 + 22: linksTo(32, 33), // rank=0.01454 + 23: linksTo(32, 33), // rank=0.03152 + 24: linksTo(27, 31), // rank=0.02108 + 25: linksTo(23, 24, 31), // rank=0.02101 + 26: linksTo(29, 33), // rank=0.01504 + 27: linksTo(2, 23, 33), // rank=0.02564 + 28: linksTo(2, 31, 33), // rank=0.01957 + 29: linksTo(23, 32, 33), // rank=0.02629 + 30: linksTo(1, 8, 32, 33), // rank=0.02459 + 31: linksTo(0, 32, 33), // rank=0.03716 + 32: linksTo(33), // rank=0.07169 + 33: nil, // rank=0.1009 + } + + // doi:10.1088/1742-5468/2008/10/P10008 figure 1 + // + // The edge list here is constructed such that all link descriptions + // head from a node with lower Page Rank to a node with higher Page + // Rank. This has no impact on undirected tests, but allows a sensible + // view for directed tests. + blondel = []intset{ + 0: linksTo(2), // rank=0.06858 + 1: linksTo(2, 4, 7), // rank=0.05264 + 2: nil, // rank=0.08249 + 3: linksTo(0, 7), // rank=0.03884 + 4: linksTo(0, 2, 10), // rank=0.06754 + 5: linksTo(0, 2, 7, 11), // rank=0.06738 + 6: linksTo(2, 7, 11), // rank=0.0528 + 7: nil, // rank=0.07008 + 8: linksTo(10), // rank=0.09226 + 9: linksTo(8), // rank=0.05821 + 10: nil, // rank=0.1035 + 11: linksTo(8, 10), // rank=0.08538 + 12: linksTo(9, 10), // rank=0.04052 + 13: linksTo(10, 11), // rank=0.03855 + 14: linksTo(8, 9, 10), // rank=0.05621 + 15: linksTo(8), // rank=0.02506 + } +) + +type structure struct { + resolution float64 + memberships []intset + want, tol float64 +} + +type level struct { + q float64 + communities [][]graph.Node +} + +type moveStructures struct { + memberships []intset + targetNodes []graph.Node + + resolution float64 + tol float64 +} + +func reverse(f []float64) { + for i, j := 0, len(f)-1; i < j; i, j = i+1, j-1 { + f[i], f[j] = f[j], f[i] + } +} + +func hasNegative(f []float64) bool { + for _, v := range f { + if v < 0 { + return true + } + } + return false +} + +var ( + dupGraph = simple.NewUndirectedGraph() + dupGraphDirected = simple.NewDirectedGraph() +) + +func init() { + err := gen.Duplication(dupGraph, 1000, 0.8, 0.1, 0.5, rand.New(rand.NewSource(1))) + if err != nil { + panic(err) + } + + // Construct a directed graph from dupGraph + // such that every edge dupGraph is replaced + // with an edge that flows from the low node + // ID to the high node ID. + for _, e := range dupGraph.Edges() { + if e.To().ID() < e.From().ID() { + se := e.(simple.Edge) + se.F, se.T = se.T, se.F + e = se + } + dupGraphDirected.SetEdge(e) + } +} + +// This init function checks the Middle East relationship data. +func init() { + world := make([]intset, len(middleEast.friends)) + for i := range world { + world[i] = make(intset) + } + for _, relationships := range [][]intset{middleEast.friends, middleEast.complicated, middleEast.enemies} { + for i, rel := range relationships { + for inter := range rel { + if _, ok := world[i][inter]; ok { + panic(fmt.Sprintf("unexpected relationship: %v--%v", i, inter)) + } + world[i][inter] = struct{}{} + } + } + } + for i := range world { + if len(world[i]) != len(middleEast.friends)-1 { + panic(fmt.Sprintf("missing relationship in %v: %v", i, world[i])) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected.go new file mode 100644 index 00000000..450a438c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected.go @@ -0,0 +1,590 @@ +// 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 community + +import ( + "math" + "math/rand" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/internal/set" +) + +// qUndirected returns the modularity Q score of the graph g subdivided into the +// given communities at the given resolution. If communities is nil, the +// unclustered modularity score is returned. The resolution parameter +// is γ as defined in Reichardt and Bornholdt doi:10.1103/PhysRevE.74.016110. +// qUndirected will panic if g has any edge with negative edge weight. +// +// Q = 1/2m \sum_{ij} [ A_{ij} - (\gamma k_i k_j)/2m ] \delta(c_i,c_j) +// +// graph.Undirect may be used as a shim to allow calculation of Q for +// directed graphs. +func qUndirected(g graph.Undirected, communities [][]graph.Node, resolution float64) float64 { + nodes := g.Nodes() + weight := positiveWeightFuncFor(g) + + // Calculate the total edge weight of the graph + // and the table of penetrating edge weight sums. + var m2 float64 + k := make(map[int64]float64, len(nodes)) + for _, u := range nodes { + w := weight(u, u) + for _, v := range g.From(u) { + w += weight(u, v) + } + m2 += w + k[u.ID()] = w + } + + if communities == nil { + var q float64 + for _, u := range nodes { + kU := k[u.ID()] + q += weight(u, u) - resolution*kU*kU/m2 + } + return q / m2 + } + + // Iterate over the communities, calculating + // the non-self edge weights for the upper + // triangle and adjust the diagonal. + var q float64 + for _, c := range communities { + for i, u := range c { + kU := k[u.ID()] + q += weight(u, u) - resolution*kU*kU/m2 + for _, v := range c[i+1:] { + q += 2 * (weight(u, v) - resolution*kU*k[v.ID()]/m2) + } + } + } + return q / m2 +} + +// louvainUndirected returns the hierarchical modularization of g at the given +// resolution using the Louvain algorithm. If src is nil, rand.Intn is used as +// the random generator. louvainUndirected will panic if g has any edge with negative edge +// weight. +// +// graph.Undirect may be used as a shim to allow modularization of directed graphs. +func louvainUndirected(g graph.Undirected, resolution float64, src *rand.Rand) *ReducedUndirected { + // See louvain.tex for a detailed description + // of the algorithm used here. + + c := reduceUndirected(g, nil) + rnd := rand.Intn + if src != nil { + rnd = src.Intn + } + for { + l := newUndirectedLocalMover(c, c.communities, resolution) + if l == nil { + return c + } + if done := l.localMovingHeuristic(rnd); done { + return c + } + c = reduceUndirected(c, l.communities) + } +} + +// ReducedUndirected is an undirected graph of communities derived from a +// parent graph by reduction. +type ReducedUndirected struct { + // nodes is the set of nodes held + // by the graph. In a ReducedUndirected + // the node ID is the index into + // nodes. + nodes []community + undirectedEdges + + // communities is the community + // structure of the graph. + communities [][]graph.Node + + parent *ReducedUndirected +} + +var ( + reducedUndirected = (*ReducedUndirected)(nil) + + _ graph.WeightedUndirected = reducedUndirected + _ ReducedGraph = reducedUndirected +) + +// Communities returns the community memberships of the nodes in the +// graph used to generate the reduced graph. +func (g *ReducedUndirected) Communities() [][]graph.Node { + communities := make([][]graph.Node, len(g.communities)) + if g.parent == nil { + for i, members := range g.communities { + comm := make([]graph.Node, len(members)) + for j, n := range members { + nodes := g.nodes[n.ID()].nodes + if len(nodes) != 1 { + panic("community: unexpected number of nodes in base graph community") + } + comm[j] = nodes[0] + } + communities[i] = comm + } + return communities + } + sub := g.parent.Communities() + for i, members := range g.communities { + var comm []graph.Node + for _, n := range members { + comm = append(comm, sub[n.ID()]...) + } + communities[i] = comm + } + return communities +} + +// Structure returns the community structure of the current level of +// the module clustering. The first index of the returned value +// corresponds to the index of the nodes in the next higher level if +// it exists. The returned value should not be mutated. +func (g *ReducedUndirected) Structure() [][]graph.Node { + return g.communities +} + +// Expanded returns the next lower level of the module clustering or nil +// if at the lowest level. +func (g *ReducedUndirected) Expanded() ReducedGraph { + return g.parent +} + +// reduceUndirected returns a reduced graph constructed from g divided +// into the given communities. The communities value is mutated +// by the call to reduceUndirected. If communities is nil and g is a +// ReducedUndirected, it is returned unaltered. +func reduceUndirected(g graph.Undirected, communities [][]graph.Node) *ReducedUndirected { + if communities == nil { + if r, ok := g.(*ReducedUndirected); ok { + return r + } + + nodes := g.Nodes() + // TODO(kortschak) This sort is necessary really only + // for testing. In practice we would not be using the + // community provided by the user for a Q calculation. + // Probably we should use a function to map the + // communities in the test sets to the remapped order. + sort.Sort(ordered.ByID(nodes)) + communities = make([][]graph.Node, len(nodes)) + for i := range nodes { + communities[i] = []graph.Node{node(i)} + } + + weight := positiveWeightFuncFor(g) + r := ReducedUndirected{ + nodes: make([]community, len(nodes)), + undirectedEdges: undirectedEdges{ + edges: make([][]int, len(nodes)), + weights: make(map[[2]int]float64), + }, + communities: communities, + } + communityOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + r.nodes[i] = community{id: i, nodes: []graph.Node{n}} + communityOf[n.ID()] = i + } + for _, u := range nodes { + var out []int + uid := communityOf[u.ID()] + for _, v := range g.From(u) { + vid := communityOf[v.ID()] + if vid != uid { + out = append(out, vid) + } + if uid < vid { + // Only store the weight once. + r.weights[[2]int{uid, vid}] = weight(u, v) + } + } + r.edges[uid] = out + } + return &r + } + + // Remove zero length communities destructively. + var commNodes int + for i := 0; i < len(communities); { + comm := communities[i] + if len(comm) == 0 { + communities[i] = communities[len(communities)-1] + communities[len(communities)-1] = nil + communities = communities[:len(communities)-1] + } else { + commNodes += len(comm) + i++ + } + } + + r := ReducedUndirected{ + nodes: make([]community, len(communities)), + undirectedEdges: undirectedEdges{ + edges: make([][]int, len(communities)), + weights: make(map[[2]int]float64), + }, + } + r.communities = make([][]graph.Node, len(communities)) + for i := range r.communities { + r.communities[i] = []graph.Node{node(i)} + } + if g, ok := g.(*ReducedUndirected); ok { + // Make sure we retain the truncated + // community structure. + g.communities = communities + r.parent = g + } + weight := positiveWeightFuncFor(g) + communityOf := make(map[int64]int, commNodes) + for i, comm := range communities { + r.nodes[i] = community{id: i, nodes: comm} + for _, n := range comm { + communityOf[n.ID()] = i + } + } + for uid, comm := range communities { + var out []int + for i, u := range comm { + r.nodes[uid].weight += weight(u, u) + for _, v := range comm[i+1:] { + r.nodes[uid].weight += 2 * weight(u, v) + } + for _, v := range g.From(u) { + vid := communityOf[v.ID()] + found := false + for _, e := range out { + if e == vid { + found = true + break + } + } + if !found && vid != uid { + out = append(out, vid) + } + if uid < vid { + // Only store the weight once. + r.weights[[2]int{uid, vid}] += weight(u, v) + } + } + } + r.edges[uid] = out + } + return &r +} + +// Has returns whether the node exists within the graph. +func (g *ReducedUndirected) Has(n graph.Node) bool { + id := n.ID() + return 0 <= id || id < int64(len(g.nodes)) +} + +// Nodes returns all the nodes in the graph. +func (g *ReducedUndirected) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.nodes)) + for i := range g.nodes { + nodes[i] = node(i) + } + return nodes +} + +// From returns all nodes in g that can be reached directly from u. +func (g *ReducedUndirected) From(u graph.Node) []graph.Node { + out := g.edges[u.ID()] + nodes := make([]graph.Node, len(out)) + for i, vid := range out { + nodes[i] = g.nodes[vid] + } + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g *ReducedUndirected) HasEdgeBetween(x, y graph.Node) bool { + xid := x.ID() + yid := y.ID() + if xid == yid || !isValidID(xid) || !isValidID(yid) { + return false + } + if xid > yid { + xid, yid = yid, xid + } + _, ok := g.weights[[2]int{int(xid), int(yid)}] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *ReducedUndirected) Edge(u, v graph.Node) graph.Edge { + return g.WeightedEdgeBetween(u, v) +} + +// 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 *ReducedUndirected) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + return g.WeightedEdgeBetween(u, v) +} + +// EdgeBetween returns the edge between nodes x and y. +func (g *ReducedUndirected) EdgeBetween(x, y graph.Node) graph.Edge { + return g.WeightedEdgeBetween(x, y) +} + +// WeightedEdgeBetween returns the weighted edge between nodes x and y. +func (g *ReducedUndirected) WeightedEdgeBetween(x, y graph.Node) graph.WeightedEdge { + xid := x.ID() + yid := y.ID() + if xid == yid || !isValidID(xid) || !isValidID(yid) { + return nil + } + if yid < xid { + xid, yid = yid, xid + } + w, ok := g.weights[[2]int{int(xid), int(yid)}] + if !ok { + return nil + } + return edge{from: g.nodes[x.ID()], to: g.nodes[y.ID()], weight: w} +} + +// 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 the internal node weight is returned. If there is no joining +// edge between the two nodes the weight value returned is zero. Weight returns true if an edge +// exists between x and y or if x and y have the same ID, false otherwise. +func (g *ReducedUndirected) Weight(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if !isValidID(xid) || !isValidID(yid) { + return 0, false + } + if xid == yid { + return g.nodes[xid].weight, true + } + if xid > yid { + xid, yid = yid, xid + } + w, ok = g.weights[[2]int{int(xid), int(yid)}] + return w, ok +} + +// undirectedLocalMover is a step in graph modularity optimization. +type undirectedLocalMover struct { + g *ReducedUndirected + + // nodes is the set of working nodes. + nodes []graph.Node + // edgeWeightOf is the weighted degree + // of each node indexed by ID. + edgeWeightOf []float64 + + // m2 is the total sum of + // edge weights in g. + m2 float64 + + // weight is the weight function + // provided by g or a function + // that returns the Weight value + // of the non-nil edge between x + // and y. + weight func(x, y graph.Node) float64 + + // communities is the current + // division of g. + communities [][]graph.Node + // memberships is a mapping between + // node ID and community membership. + memberships []int + + // resolution is the Reichardt and + // Bornholdt γ parameter as defined + // in doi:10.1103/PhysRevE.74.016110. + resolution float64 + + // moved indicates that a call to + // move has been made since the last + // call to shuffle. + moved bool + + // changed indicates that a move + // has been made since the creation + // of the local mover. + changed bool +} + +// newUndirectedLocalMover returns a new undirectedLocalMover initialized with +// the graph g, a set of communities and a modularity resolution parameter. The +// node IDs of g must be contiguous in [0,n) where n is the number of nodes. +// If g has a zero edge weight sum, nil is returned. +func newUndirectedLocalMover(g *ReducedUndirected, communities [][]graph.Node, resolution float64) *undirectedLocalMover { + nodes := g.Nodes() + l := undirectedLocalMover{ + g: g, + nodes: nodes, + edgeWeightOf: make([]float64, len(nodes)), + communities: communities, + memberships: make([]int, len(nodes)), + resolution: resolution, + weight: positiveWeightFuncFor(g), + } + + // Calculate the total edge weight of the graph + // and degree weights for each node. + for _, u := range l.nodes { + w := l.weight(u, u) + for _, v := range g.From(u) { + w += l.weight(u, v) + } + l.edgeWeightOf[u.ID()] = w + l.m2 += w + } + if l.m2 == 0 { + return nil + } + + // Assign membership mappings. + for i, c := range communities { + for _, u := range c { + l.memberships[u.ID()] = i + } + } + + return &l +} + +// localMovingHeuristic performs the Louvain local moving heuristic until +// no further moves can be made. It returns a boolean indicating that the +// undirectedLocalMover has not made any improvement to the community +// structure and so the Louvain algorithm is done. +func (l *undirectedLocalMover) localMovingHeuristic(rnd func(int) int) (done bool) { + for { + l.shuffle(rnd) + for _, n := range l.nodes { + dQ, dst, src := l.deltaQ(n) + if dQ <= 0 { + continue + } + l.move(dst, src) + } + if !l.moved { + return !l.changed + } + } +} + +// shuffle performs a Fisher-Yates shuffle on the nodes held by the +// undirectedLocalMover using the random source rnd which should return +// an integer in the range [0,n). +func (l *undirectedLocalMover) shuffle(rnd func(n int) int) { + l.moved = false + for i := range l.nodes[:len(l.nodes)-1] { + j := i + rnd(len(l.nodes)-i) + l.nodes[i], l.nodes[j] = l.nodes[j], l.nodes[i] + } +} + +// move moves the node at src to the community at dst. +func (l *undirectedLocalMover) move(dst int, src commIdx) { + l.moved = true + l.changed = true + + srcComm := l.communities[src.community] + n := srcComm[src.node] + + l.memberships[n.ID()] = dst + + l.communities[dst] = append(l.communities[dst], n) + srcComm[src.node], srcComm[len(srcComm)-1] = srcComm[len(srcComm)-1], nil + l.communities[src.community] = srcComm[:len(srcComm)-1] +} + +// deltaQ returns the highest gain in modularity attainable by moving +// n from its current community to another connected community and +// the index of the chosen destination. The index into the +// undirectedLocalMover's communities field is returned in src if n +// is in communities. +func (l *undirectedLocalMover) deltaQ(n graph.Node) (deltaQ float64, dst int, src commIdx) { + id := n.ID() + a_aa := l.weight(n, n) + k_a := l.edgeWeightOf[id] + m2 := l.m2 + gamma := l.resolution + + // Find communities connected to n. + connected := make(set.Ints) + // The following for loop is equivalent to: + // + // for _, v := range l.g.From(n) { + // connected.Add(l.memberships[v.ID()]) + // } + // + // This is done to avoid an allocation. + for _, vid := range l.g.edges[id] { + connected.Add(l.memberships[vid]) + } + // Insert the node's own community. + connected.Add(l.memberships[id]) + + candidates := make([]int, 0, len(connected)) + for i := range connected { + candidates = append(candidates, i) + } + sort.Ints(candidates) + + // Calculate the highest modularity gain + // from moving into another community and + // keep the index of that community. + var dQremove float64 + dQadd, dst, src := math.Inf(-1), -1, commIdx{-1, -1} + for _, i := range candidates { + c := l.communities[i] + var k_aC, sigma_totC float64 // C is a substitution for ^𝛼 or ^𝛽. + var removal bool + for j, u := range c { + uid := u.ID() + if uid == id { + if src.community != -1 { + panic("community: multiple sources") + } + src = commIdx{i, j} + removal = true + } + + k_aC += l.weight(n, u) + // sigma_totC could be kept for each community + // and updated for moves, changing the calculation + // of sigma_totC here from O(n_c) to O(1), but + // in practice the time savings do not appear + // to be compelling and do not make up for the + // increase in code complexity and space required. + sigma_totC += l.edgeWeightOf[uid] + } + + // See louvain.tex for a derivation of these equations. + switch { + case removal: + // The community c was the current community, + // so calculate the change due to removal. + dQremove = k_aC /*^𝛼*/ - a_aa - gamma*k_a*(sigma_totC /*^𝛼*/ -k_a)/m2 + + default: + // Otherwise calculate the change due to an addition + // to c and retain if it is the current best. + dQ := k_aC /*^𝛽*/ - gamma*k_a*sigma_totC /*^𝛽*/ /m2 + if dQ > dQadd { + dQadd = dQ + dst = i + } + } + } + + return 2 * (dQadd - dQremove) / m2, dst, src +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_multiplex.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_multiplex.go new file mode 100644 index 00000000..23799522 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_multiplex.go @@ -0,0 +1,826 @@ +// 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 community + +import ( + "fmt" + "math" + "math/rand" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/internal/set" +) + +// UndirectedMultiplex is an undirected multiplex graph. +type UndirectedMultiplex interface { + Multiplex + + // Layer returns the lth layer of the + // multiplex graph. + Layer(l int) graph.Undirected +} + +// qUndirectedMultiplex returns the modularity Q score of the multiplex graph layers +// subdivided into the given communities at the given resolutions and weights. Q is +// returned as the vector of weighted Q scores for each layer of the multiplex graph. +// If communities is nil, the unclustered modularity score is returned. +// If weights is nil layers are equally weighted, otherwise the length of +// weights must equal the number of layers. If resolutions is nil, a resolution +// of 1.0 is used for all layers, otherwise either a single element slice may be used +// to specify a global resolution, or the length of resolutions must equal the number +// of layers. The resolution parameter is γ as defined in Reichardt and Bornholdt +// doi:10.1103/PhysRevE.74.016110. +// qUndirectedMultiplex will panic if the graph has any layer weight-scaled edge with +// negative edge weight. +// +// Q_{layer} = w_{layer} \sum_{ij} [ A_{layer}*_{ij} - (\gamma_{layer} k_i k_j)/2m ] \delta(c_i,c_j) +// +// Note that Q values for multiplex graphs are not scaled by the total layer edge weight. +// +// graph.Undirect may be used as a shim to allow calculation of Q for +// directed graphs. +func qUndirectedMultiplex(g UndirectedMultiplex, communities [][]graph.Node, weights, resolutions []float64) []float64 { + q := make([]float64, g.Depth()) + nodes := g.Nodes() + layerWeight := 1.0 + layerResolution := 1.0 + if len(resolutions) == 1 { + layerResolution = resolutions[0] + } + for l := 0; l < g.Depth(); l++ { + layer := g.Layer(l) + + if weights != nil { + layerWeight = weights[l] + } + if layerWeight == 0 { + continue + } + + if len(resolutions) > 1 { + layerResolution = resolutions[l] + } + + var weight func(x, y graph.Node) float64 + if layerWeight < 0 { + weight = negativeWeightFuncFor(layer) + } else { + weight = positiveWeightFuncFor(layer) + } + + // Calculate the total edge weight of the layer + // and the table of penetrating edge weight sums. + var m2 float64 + k := make(map[int64]float64, len(nodes)) + for _, u := range nodes { + w := weight(u, u) + for _, v := range layer.From(u) { + w += weight(u, v) + } + m2 += w + k[u.ID()] = w + } + + if communities == nil { + var qLayer float64 + for _, u := range nodes { + kU := k[u.ID()] + qLayer += weight(u, u) - layerResolution*kU*kU/m2 + } + q[l] = layerWeight * qLayer + continue + } + + // Iterate over the communities, calculating + // the non-self edge weights for the upper + // triangle and adjust the diagonal. + var qLayer float64 + for _, c := range communities { + for i, u := range c { + kU := k[u.ID()] + qLayer += weight(u, u) - layerResolution*kU*kU/m2 + for _, v := range c[i+1:] { + qLayer += 2 * (weight(u, v) - layerResolution*kU*k[v.ID()]/m2) + } + } + } + q[l] = layerWeight * qLayer + } + + return q +} + +// UndirectedLayers implements UndirectedMultiplex. +type UndirectedLayers []graph.Undirected + +// NewUndirectedLayers returns an UndirectedLayers using the provided layers +// ensuring there is a match between IDs for each layer. +func NewUndirectedLayers(layers ...graph.Undirected) (UndirectedLayers, error) { + if len(layers) == 0 { + return nil, nil + } + base := make(set.Int64s) + for _, n := range layers[0].Nodes() { + base.Add(n.ID()) + } + for i, l := range layers[1:] { + next := make(set.Int64s) + for _, n := range l.Nodes() { + next.Add(n.ID()) + } + if !set.Int64sEqual(next, base) { + return nil, fmt.Errorf("community: layer ID mismatch between layers: %d", i+1) + } + } + return layers, nil +} + +// Nodes returns the nodes of the receiver. +func (g UndirectedLayers) Nodes() []graph.Node { + if len(g) == 0 { + return nil + } + return g[0].Nodes() +} + +// Depth returns the depth of the multiplex graph. +func (g UndirectedLayers) Depth() int { return len(g) } + +// Layer returns the lth layer of the multiplex graph. +func (g UndirectedLayers) Layer(l int) graph.Undirected { return g[l] } + +// louvainUndirectedMultiplex returns the hierarchical modularization of g at the given resolution +// using the Louvain algorithm. If all is true and g has negatively weighted layers, all +// communities will be searched during the modularization. If src is nil, rand.Intn is +// used as the random generator. louvainUndirectedMultiplex will panic if g has any edge with +// edge weight that does not sign-match the layer weight. +// +// graph.Undirect may be used as a shim to allow modularization of directed graphs. +func louvainUndirectedMultiplex(g UndirectedMultiplex, weights, resolutions []float64, all bool, src *rand.Rand) *ReducedUndirectedMultiplex { + if weights != nil && len(weights) != g.Depth() { + panic("community: weights vector length mismatch") + } + if resolutions != nil && len(resolutions) != 1 && len(resolutions) != g.Depth() { + panic("community: resolutions vector length mismatch") + } + + // See louvain.tex for a detailed description + // of the algorithm used here. + + c := reduceUndirectedMultiplex(g, nil, weights) + rnd := rand.Intn + if src != nil { + rnd = src.Intn + } + for { + l := newUndirectedMultiplexLocalMover(c, c.communities, weights, resolutions, all) + if l == nil { + return c + } + if done := l.localMovingHeuristic(rnd); done { + return c + } + c = reduceUndirectedMultiplex(c, l.communities, weights) + } +} + +// ReducedUndirectedMultiplex is an undirected graph of communities derived from a +// parent graph by reduction. +type ReducedUndirectedMultiplex struct { + // nodes is the set of nodes held + // by the graph. In a ReducedUndirectedMultiplex + // the node ID is the index into + // nodes. + nodes []multiplexCommunity + layers []undirectedEdges + + // communities is the community + // structure of the graph. + communities [][]graph.Node + + parent *ReducedUndirectedMultiplex +} + +var ( + _ UndirectedMultiplex = (*ReducedUndirectedMultiplex)(nil) + _ graph.WeightedUndirected = (*undirectedLayerHandle)(nil) +) + +// Nodes returns all the nodes in the graph. +func (g *ReducedUndirectedMultiplex) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.nodes)) + for i := range g.nodes { + nodes[i] = node(i) + } + return nodes +} + +// Depth returns the number of layers in the multiplex graph. +func (g *ReducedUndirectedMultiplex) Depth() int { return len(g.layers) } + +// Layer returns the lth layer of the multiplex graph. +func (g *ReducedUndirectedMultiplex) Layer(l int) graph.Undirected { + return undirectedLayerHandle{multiplex: g, layer: l} +} + +// Communities returns the community memberships of the nodes in the +// graph used to generate the reduced graph. +func (g *ReducedUndirectedMultiplex) Communities() [][]graph.Node { + communities := make([][]graph.Node, len(g.communities)) + if g.parent == nil { + for i, members := range g.communities { + comm := make([]graph.Node, len(members)) + for j, n := range members { + nodes := g.nodes[n.ID()].nodes + if len(nodes) != 1 { + panic("community: unexpected number of nodes in base graph community") + } + comm[j] = nodes[0] + } + communities[i] = comm + } + return communities + } + sub := g.parent.Communities() + for i, members := range g.communities { + var comm []graph.Node + for _, n := range members { + comm = append(comm, sub[n.ID()]...) + } + communities[i] = comm + } + return communities +} + +// Structure returns the community structure of the current level of +// the module clustering. The first index of the returned value +// corresponds to the index of the nodes in the next higher level if +// it exists. The returned value should not be mutated. +func (g *ReducedUndirectedMultiplex) Structure() [][]graph.Node { + return g.communities +} + +// Expanded returns the next lower level of the module clustering or nil +// if at the lowest level. +func (g *ReducedUndirectedMultiplex) Expanded() ReducedMultiplex { + return g.parent +} + +// reduceUndirectedMultiplex returns a reduced graph constructed from g divided +// into the given communities. The communities value is mutated +// by the call to reduceUndirectedMultiplex. If communities is nil and g is a +// ReducedUndirectedMultiplex, it is returned unaltered. +func reduceUndirectedMultiplex(g UndirectedMultiplex, communities [][]graph.Node, weights []float64) *ReducedUndirectedMultiplex { + if communities == nil { + if r, ok := g.(*ReducedUndirectedMultiplex); ok { + return r + } + + nodes := g.Nodes() + // TODO(kortschak) This sort is necessary really only + // for testing. In practice we would not be using the + // community provided by the user for a Q calculation. + // Probably we should use a function to map the + // communities in the test sets to the remapped order. + sort.Sort(ordered.ByID(nodes)) + communities = make([][]graph.Node, len(nodes)) + for i := range nodes { + communities[i] = []graph.Node{node(i)} + } + + r := ReducedUndirectedMultiplex{ + nodes: make([]multiplexCommunity, len(nodes)), + layers: make([]undirectedEdges, g.Depth()), + communities: communities, + } + communityOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + r.nodes[i] = multiplexCommunity{id: i, nodes: []graph.Node{n}, weights: make([]float64, depth(weights))} + communityOf[n.ID()] = i + } + for i := range r.layers { + r.layers[i] = undirectedEdges{ + edges: make([][]int, len(nodes)), + weights: make(map[[2]int]float64), + } + } + w := 1.0 + for l := 0; l < g.Depth(); l++ { + layer := g.Layer(l) + if weights != nil { + w = weights[l] + } + if w == 0 { + continue + } + var sign float64 + var weight func(x, y graph.Node) float64 + if w < 0 { + sign, weight = -1, negativeWeightFuncFor(layer) + } else { + sign, weight = 1, positiveWeightFuncFor(layer) + } + for _, u := range nodes { + var out []int + uid := communityOf[u.ID()] + for _, v := range layer.From(u) { + vid := communityOf[v.ID()] + if vid != uid { + out = append(out, vid) + } + if uid < vid { + // Only store the weight once. + r.layers[l].weights[[2]int{uid, vid}] = sign * weight(u, v) + } + } + r.layers[l].edges[uid] = out + } + } + return &r + } + + // Remove zero length communities destructively. + var commNodes int + for i := 0; i < len(communities); { + comm := communities[i] + if len(comm) == 0 { + communities[i] = communities[len(communities)-1] + communities[len(communities)-1] = nil + communities = communities[:len(communities)-1] + } else { + commNodes += len(comm) + i++ + } + } + + r := ReducedUndirectedMultiplex{ + nodes: make([]multiplexCommunity, len(communities)), + layers: make([]undirectedEdges, g.Depth()), + } + communityOf := make(map[int64]int, commNodes) + for i, comm := range communities { + r.nodes[i] = multiplexCommunity{id: i, nodes: comm, weights: make([]float64, depth(weights))} + for _, n := range comm { + communityOf[n.ID()] = i + } + } + for i := range r.layers { + r.layers[i] = undirectedEdges{ + edges: make([][]int, len(communities)), + weights: make(map[[2]int]float64), + } + } + r.communities = make([][]graph.Node, len(communities)) + for i := range r.communities { + r.communities[i] = []graph.Node{node(i)} + } + if g, ok := g.(*ReducedUndirectedMultiplex); ok { + // Make sure we retain the truncated + // community structure. + g.communities = communities + r.parent = g + } + w := 1.0 + for l := 0; l < g.Depth(); l++ { + layer := g.Layer(l) + if weights != nil { + w = weights[l] + } + if w == 0 { + continue + } + var sign float64 + var weight func(x, y graph.Node) float64 + if w < 0 { + sign, weight = -1, negativeWeightFuncFor(layer) + } else { + sign, weight = 1, positiveWeightFuncFor(layer) + } + for uid, comm := range communities { + var out []int + for i, u := range comm { + r.nodes[uid].weights[l] += sign * weight(u, u) + for _, v := range comm[i+1:] { + r.nodes[uid].weights[l] += 2 * sign * weight(u, v) + } + for _, v := range layer.From(u) { + vid := communityOf[v.ID()] + found := false + for _, e := range out { + if e == vid { + found = true + break + } + } + if !found && vid != uid { + out = append(out, vid) + } + if uid < vid { + // Only store the weight once. + r.layers[l].weights[[2]int{uid, vid}] += sign * weight(u, v) + } + } + } + r.layers[l].edges[uid] = out + } + } + return &r +} + +// undirectedLayerHandle is a handle to a multiplex graph layer. +type undirectedLayerHandle struct { + // multiplex is the complete + // multiplex graph. + multiplex *ReducedUndirectedMultiplex + + // layer is an index into the + // multiplex for the current + // layer. + layer int +} + +// Has returns whether the node exists within the graph. +func (g undirectedLayerHandle) Has(n graph.Node) bool { + id := n.ID() + return 0 <= id && id < int64(len(g.multiplex.nodes)) +} + +// Nodes returns all the nodes in the graph. +func (g undirectedLayerHandle) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.multiplex.nodes)) + for i := range g.multiplex.nodes { + nodes[i] = node(i) + } + return nodes +} + +// From returns all nodes in g that can be reached directly from u. +func (g undirectedLayerHandle) From(u graph.Node) []graph.Node { + out := g.multiplex.layers[g.layer].edges[u.ID()] + nodes := make([]graph.Node, len(out)) + for i, vid := range out { + nodes[i] = g.multiplex.nodes[vid] + } + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g undirectedLayerHandle) HasEdgeBetween(x, y graph.Node) bool { + xid := x.ID() + yid := y.ID() + if xid == yid || !isValidID(xid) || !isValidID(yid) { + return false + } + if xid > yid { + xid, yid = yid, xid + } + _, ok := g.multiplex.layers[g.layer].weights[[2]int{int(xid), int(yid)}] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g undirectedLayerHandle) Edge(u, v graph.Node) graph.Edge { + return g.WeightedEdgeBetween(u, v) +} + +// 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 undirectedLayerHandle) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + return g.WeightedEdgeBetween(u, v) +} + +// EdgeBetween returns the edge between nodes x and y. +func (g undirectedLayerHandle) EdgeBetween(x, y graph.Node) graph.Edge { + return g.WeightedEdgeBetween(x, y) +} + +// WeightedEdgeBetween returns the weighted edge between nodes x and y. +func (g undirectedLayerHandle) WeightedEdgeBetween(x, y graph.Node) graph.WeightedEdge { + xid := x.ID() + yid := y.ID() + if xid == yid || !isValidID(xid) || !isValidID(yid) { + return nil + } + if yid < xid { + xid, yid = yid, xid + } + w, ok := g.multiplex.layers[g.layer].weights[[2]int{int(xid), int(yid)}] + if !ok { + return nil + } + return multiplexEdge{from: g.multiplex.nodes[x.ID()], to: g.multiplex.nodes[y.ID()], weight: w} +} + +// 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 the internal node weight is returned. If there is no joining +// edge between the two nodes the weight value returned is zero. Weight returns true if an edge +// exists between x and y or if x and y have the same ID, false otherwise. +func (g undirectedLayerHandle) Weight(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if !isValidID(xid) || !isValidID(yid) { + return 0, false + } + if xid == yid { + return g.multiplex.nodes[xid].weights[g.layer], true + } + if xid > yid { + xid, yid = yid, xid + } + w, ok = g.multiplex.layers[g.layer].weights[[2]int{int(xid), int(yid)}] + return w, ok +} + +// undirectedMultiplexLocalMover is a step in graph modularity optimization. +type undirectedMultiplexLocalMover struct { + g *ReducedUndirectedMultiplex + + // nodes is the set of working nodes. + nodes []graph.Node + // edgeWeightOf is the weighted degree + // of each node indexed by ID. + edgeWeightOf [][]float64 + + // m2 is the total sum of + // edge weights in g. + m2 []float64 + + // weight is the weight function + // provided by g or a function + // that returns the Weight value + // of the non-nil edge between x + // and y. + weight []func(x, y graph.Node) float64 + + // communities is the current + // division of g. + communities [][]graph.Node + // memberships is a mapping between + // node ID and community membership. + memberships []int + + // resolution is the Reichardt and + // Bornholdt γ parameter as defined + // in doi:10.1103/PhysRevE.74.016110. + resolutions []float64 + + // weights is the layer weights for + // the modularisation. + weights []float64 + + // searchAll specifies whether the local + // mover should consider non-connected + // communities during the local moving + // heuristic. + searchAll bool + + // moved indicates that a call to + // move has been made since the last + // call to shuffle. + moved bool + + // changed indicates that a move + // has been made since the creation + // of the local mover. + changed bool +} + +// newUndirectedMultiplexLocalMover returns a new undirectedMultiplexLocalMover initialized with +// the graph g, a set of communities and a modularity resolution parameter. The +// node IDs of g must be contiguous in [0,n) where n is the number of nodes. +// If g has a zero edge weight sum, nil is returned. +func newUndirectedMultiplexLocalMover(g *ReducedUndirectedMultiplex, communities [][]graph.Node, weights, resolutions []float64, all bool) *undirectedMultiplexLocalMover { + nodes := g.Nodes() + l := undirectedMultiplexLocalMover{ + g: g, + nodes: nodes, + edgeWeightOf: make([][]float64, g.Depth()), + m2: make([]float64, g.Depth()), + communities: communities, + memberships: make([]int, len(nodes)), + resolutions: resolutions, + weights: weights, + weight: make([]func(x, y graph.Node) float64, g.Depth()), + } + + // Calculate the total edge weight of the graph + // and degree weights for each node. + var zero int + for i := 0; i < g.Depth(); i++ { + l.edgeWeightOf[i] = make([]float64, len(nodes)) + var weight func(x, y graph.Node) float64 + + if weights != nil { + if weights[i] == 0 { + zero++ + continue + } + if weights[i] < 0 { + weight = negativeWeightFuncFor(g.Layer(i)) + l.searchAll = all + } else { + weight = positiveWeightFuncFor(g.Layer(i)) + } + } else { + weight = positiveWeightFuncFor(g.Layer(i)) + } + + l.weight[i] = weight + layer := g.Layer(i) + for _, u := range l.nodes { + w := weight(u, u) + for _, v := range layer.From(u) { + w += weight(u, v) + } + l.edgeWeightOf[i][u.ID()] = w + l.m2[i] += w + } + if l.m2[i] == 0 { + zero++ + } + } + if zero == g.Depth() { + return nil + } + + // Assign membership mappings. + for i, c := range communities { + for _, u := range c { + l.memberships[u.ID()] = i + } + } + + return &l +} + +// localMovingHeuristic performs the Louvain local moving heuristic until +// no further moves can be made. It returns a boolean indicating that the +// undirectedMultiplexLocalMover has not made any improvement to the community +// structure and so the Louvain algorithm is done. +func (l *undirectedMultiplexLocalMover) localMovingHeuristic(rnd func(int) int) (done bool) { + for { + l.shuffle(rnd) + for _, n := range l.nodes { + dQ, dst, src := l.deltaQ(n) + if dQ <= 0 { + continue + } + l.move(dst, src) + } + if !l.moved { + return !l.changed + } + } +} + +// shuffle performs a Fisher-Yates shuffle on the nodes held by the +// undirectedMultiplexLocalMover using the random source rnd which should return +// an integer in the range [0,n). +func (l *undirectedMultiplexLocalMover) shuffle(rnd func(n int) int) { + l.moved = false + for i := range l.nodes[:len(l.nodes)-1] { + j := i + rnd(len(l.nodes)-i) + l.nodes[i], l.nodes[j] = l.nodes[j], l.nodes[i] + } +} + +// move moves the node at src to the community at dst. +func (l *undirectedMultiplexLocalMover) move(dst int, src commIdx) { + l.moved = true + l.changed = true + + srcComm := l.communities[src.community] + n := srcComm[src.node] + + l.memberships[n.ID()] = dst + + l.communities[dst] = append(l.communities[dst], n) + srcComm[src.node], srcComm[len(srcComm)-1] = srcComm[len(srcComm)-1], nil + l.communities[src.community] = srcComm[:len(srcComm)-1] +} + +// deltaQ returns the highest gain in modularity attainable by moving +// n from its current community to another connected community and +// the index of the chosen destination. The index into the +// undirectedMultiplexLocalMover's communities field is returned in src if n +// is in communities. +func (l *undirectedMultiplexLocalMover) deltaQ(n graph.Node) (deltaQ float64, dst int, src commIdx) { + id := n.ID() + + var iterator minTaker + if l.searchAll { + iterator = &dense{n: len(l.communities)} + } else { + // Find communities connected to n. + connected := make(set.Ints) + // The following for loop is equivalent to: + // + // for i := 0; i < l.g.Depth(); i++ { + // for _, v := range l.g.Layer(i).From(n) { + // connected.Add(l.memberships[v.ID()]) + // } + // } + // + // This is done to avoid an allocation for + // each layer. + for _, layer := range l.g.layers { + for _, vid := range layer.edges[id] { + connected.Add(l.memberships[vid]) + } + } + // Insert the node's own community. + connected.Add(l.memberships[id]) + iterator = newSlice(connected) + } + + // Calculate the highest modularity gain + // from moving into another community and + // keep the index of that community. + var dQremove float64 + dQadd, dst, src := math.Inf(-1), -1, commIdx{-1, -1} + var i int + for iterator.TakeMin(&i) { + c := l.communities[i] + var removal bool + var _dQadd float64 + for layer := 0; layer < l.g.Depth(); layer++ { + m2 := l.m2[layer] + if m2 == 0 { + // Do not consider layers with zero sum edge weight. + continue + } + w := 1.0 + if l.weights != nil { + w = l.weights[layer] + } + if w == 0 { + // Do not consider layers with zero weighting. + continue + } + + var k_aC, sigma_totC float64 // C is a substitution for ^𝛼 or ^𝛽. + removal = false + for j, u := range c { + uid := u.ID() + if uid == id { + // Only mark and check src community on the first layer. + if layer == 0 { + if src.community != -1 { + panic("community: multiple sources") + } + src = commIdx{i, j} + } + removal = true + } + + k_aC += l.weight[layer](n, u) + // sigma_totC could be kept for each community + // and updated for moves, changing the calculation + // of sigma_totC here from O(n_c) to O(1), but + // in practice the time savings do not appear + // to be compelling and do not make up for the + // increase in code complexity and space required. + sigma_totC += l.edgeWeightOf[layer][uid] + } + + a_aa := l.weight[layer](n, n) + k_a := l.edgeWeightOf[layer][id] + gamma := 1.0 + if l.resolutions != nil { + if len(l.resolutions) == 1 { + gamma = l.resolutions[0] + } else { + gamma = l.resolutions[layer] + } + } + + // See louvain.tex for a derivation of these equations. + // The weighting term, w, is described in V Traag, + // "Algorithms and dynamical models for communities and + // reputation in social networks", chapter 5. + // http://www.traag.net/wp/wp-content/papercite-data/pdf/traag_algorithms_2013.pdf + switch { + case removal: + // The community c was the current community, + // so calculate the change due to removal. + dQremove += w * (k_aC /*^𝛼*/ - a_aa - gamma*k_a*(sigma_totC /*^𝛼*/ -k_a)/m2) + + default: + // Otherwise calculate the change due to an addition + // to c. + _dQadd += w * (k_aC /*^𝛽*/ - gamma*k_a*sigma_totC /*^𝛽*/ /m2) + } + } + if !removal && _dQadd > dQadd { + dQadd = _dQadd + dst = i + } + } + + return 2 * (dQadd - dQremove), dst, src +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_multiplex_test.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_multiplex_test.go new file mode 100644 index 00000000..6f593777 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_multiplex_test.go @@ -0,0 +1,691 @@ +// 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 community + +import ( + "math" + "math/rand" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +var communityUndirectedMultiplexQTests = []struct { + name string + layers []layer + structures []structure + + wantLevels []level +}{ + { + name: "unconnected", + layers: []layer{{g: unconnected, weight: 1}}, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0), + 1: linksTo(1), + 2: linksTo(2), + 3: linksTo(3), + 4: linksTo(4), + 5: linksTo(5), + }, + want: math.NaN(), + }, + }, + wantLevels: []level{ + { + q: math.Inf(-1), // Here math.Inf(-1) is used as a place holder for NaN to allow use of reflect.DeepEqual. + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "small_dumbell", + layers: []layer{ + {g: smallDumbell, edgeWeight: 1, weight: 1}, + {g: dumbellRepulsion, edgeWeight: -1, weight: -1}, + }, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2), + 1: linksTo(3, 4, 5), + }, + want: 7.0, tol: 1e-10, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5), + }, + want: 0, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 7.0, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + {simple.Node(3), simple.Node(4), simple.Node(5)}, + }, + }, + { + q: -1.4285714285714284, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "small_dumbell_twice", + layers: []layer{ + {g: smallDumbell, weight: 0.5}, + {g: smallDumbell, weight: 0.5}, + }, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2), + 1: linksTo(3, 4, 5), + }, + want: 5, tol: 1e-10, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5), + }, + want: 0, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 0.35714285714285715 * 14, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + {simple.Node(3), simple.Node(4), simple.Node(5)}, + }, + }, + { + q: -0.17346938775510204 * 14, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "repulsion", + layers: []layer{{g: repulsion, edgeWeight: -1, weight: -1}}, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2), + 1: linksTo(3, 4, 5), + }, + want: 9.0, tol: 1e-10, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0), + 1: linksTo(1), + 2: linksTo(2), + 3: linksTo(3), + 4: linksTo(4), + 5: linksTo(5), + }, + want: 3, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 9.0, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + {simple.Node(3), simple.Node(4), simple.Node(5)}, + }, + }, + { + q: 3.0, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "middle_east", + layers: []layer{ + {g: middleEast.friends, edgeWeight: 1, weight: 1}, + {g: middleEast.enemies, edgeWeight: -1, weight: -1}, + }, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 6), + 1: linksTo(1, 7, 9, 12), + 2: linksTo(2, 8, 11), + 3: linksTo(3, 4, 5, 10), + }, + want: 33.8180574555, tol: 1e-9, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 2, 3, 4, 5, 10), + 1: linksTo(1, 7, 9, 12), + 2: linksTo(6), + 3: linksTo(8, 11), + }, + want: 30.92749658, tol: 1e-7, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), + }, + want: 0, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 33.818057455540355, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(6)}, + {simple.Node(1), simple.Node(7), simple.Node(9), simple.Node(12)}, + {simple.Node(2), simple.Node(8), simple.Node(11)}, + {simple.Node(3), simple.Node(4), simple.Node(5), simple.Node(10)}, + }, + }, + { + q: 3.8071135430916545, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + {simple.Node(6)}, + {simple.Node(7)}, + {simple.Node(8)}, + {simple.Node(9)}, + {simple.Node(10)}, + {simple.Node(11)}, + {simple.Node(12)}, + }, + }, + }, + }, +} + +func TestCommunityQUndirectedMultiplex(t *testing.T) { + for _, test := range communityUndirectedMultiplexQTests { + g, weights, err := undirectedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + } + q := QMultiplex(g, communities, weights, []float64{structure.resolution}) + got := floats.Sum(q) + if !floats.EqualWithinAbsOrRel(got, structure.want, structure.tol, structure.tol) && !math.IsNaN(structure.want) { + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + t.Errorf("unexpected Q value for %q %v: got: %v %.3v want: %v", + test.name, communities, got, q, structure.want) + } + } + } +} + +func TestCommunityDeltaQUndirectedMultiplex(t *testing.T) { +tests: + for _, test := range communityUndirectedMultiplexQTests { + g, weights, err := undirectedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + rnd := rand.New(rand.NewSource(1)).Intn + for _, structure := range test.structures { + communityOf := make(map[int64]int) + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + communityOf[n] = i + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + resolution := []float64{structure.resolution} + + before := QMultiplex(g, communities, weights, resolution) + + // We test exhaustively. + const all = true + + l := newUndirectedMultiplexLocalMover( + reduceUndirectedMultiplex(g, nil, weights), + communities, weights, resolution, all) + if l == nil { + if !math.IsNaN(floats.Sum(before)) { + t.Errorf("unexpected nil localMover with non-NaN Q graph: Q=%.4v", before) + } + continue tests + } + + // This is done to avoid run-to-run + // variation due to map iteration order. + sort.Sort(ordered.ByID(l.nodes)) + + l.shuffle(rnd) + + for _, target := range l.nodes { + got, gotDst, gotSrc := l.deltaQ(target) + + want, wantDst := math.Inf(-1), -1 + migrated := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + if n == target.ID() { + continue + } + migrated[i] = append(migrated[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(migrated[i])) + } + + for i, c := range structure.memberships { + if i == communityOf[target.ID()] { + continue + } + if !(all && hasNegative(weights)) { + connected := false + search: + for l := 0; l < g.Depth(); l++ { + if weights[l] < 0 { + connected = true + break search + } + layer := g.Layer(l) + for n := range c { + if layer.HasEdgeBetween(simple.Node(n), target) { + connected = true + break search + } + } + } + if !connected { + continue + } + } + migrated[i] = append(migrated[i], target) + after := QMultiplex(g, migrated, weights, resolution) + migrated[i] = migrated[i][:len(migrated[i])-1] + if delta := floats.Sum(after) - floats.Sum(before); delta > want { + want = delta + wantDst = i + } + } + + if !floats.EqualWithinAbsOrRel(got, want, structure.tol, structure.tol) || gotDst != wantDst { + t.Errorf("unexpected result moving n=%d in c=%d of %s/%.4v: got: %.4v,%d want: %.4v,%d"+ + "\n\t%v\n\t%v", + target.ID(), communityOf[target.ID()], test.name, structure.resolution, got, gotDst, want, wantDst, + communities, migrated) + } + if gotSrc.community != communityOf[target.ID()] { + t.Errorf("unexpected source community index: got: %d want: %d", gotSrc, communityOf[target.ID()]) + } else if communities[gotSrc.community][gotSrc.node].ID() != target.ID() { + wantNodeIdx := -1 + for i, n := range communities[gotSrc.community] { + if n.ID() == target.ID() { + wantNodeIdx = i + break + } + } + t.Errorf("unexpected source node index: got: %d want: %d", gotSrc.node, wantNodeIdx) + } + } + } + } +} + +func TestReduceQConsistencyUndirectedMultiplex(t *testing.T) { +tests: + for _, test := range communityUndirectedMultiplexQTests { + g, weights, err := undirectedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + for _, structure := range test.structures { + if math.IsNaN(structure.want) { + continue tests + } + + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + gQ := QMultiplex(g, communities, weights, []float64{structure.resolution}) + gQnull := QMultiplex(g, nil, weights, nil) + + cg0 := reduceUndirectedMultiplex(g, nil, weights) + cg0Qnull := QMultiplex(cg0, cg0.Structure(), weights, nil) + if !floats.EqualWithinAbsOrRel(floats.Sum(gQnull), floats.Sum(cg0Qnull), structure.tol, structure.tol) { + t.Errorf("disagreement between null Q from method: %v and function: %v", cg0Qnull, gQnull) + } + cg0Q := QMultiplex(cg0, communities, weights, []float64{structure.resolution}) + if !floats.EqualWithinAbsOrRel(floats.Sum(gQ), floats.Sum(cg0Q), structure.tol, structure.tol) { + t.Errorf("unexpected Q result after initial reduction: got: %v want :%v", cg0Q, gQ) + } + + cg1 := reduceUndirectedMultiplex(cg0, communities, weights) + cg1Q := QMultiplex(cg1, cg1.Structure(), weights, []float64{structure.resolution}) + if !floats.EqualWithinAbsOrRel(floats.Sum(gQ), floats.Sum(cg1Q), structure.tol, structure.tol) { + t.Errorf("unexpected Q result after second reduction: got: %v want :%v", cg1Q, gQ) + } + } + } +} + +var localUndirectedMultiplexMoveTests = []struct { + name string + layers []layer + structures []moveStructures +}{ + { + name: "blondel", + layers: []layer{{g: blondel, weight: 1}, {g: blondel, weight: 0.5}}, + structures: []moveStructures{ + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(0)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(3)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + // Case to demonstrate when A_aa != k_a^𝛼. + targetNodes: []graph.Node{simple.Node(3), simple.Node(2)}, + resolution: 1, + tol: 1e-14, + }, + }, + }, +} + +func TestMoveLocalUndirectedMultiplex(t *testing.T) { + for _, test := range localUndirectedMultiplexMoveTests { + g, weights, err := undirectedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + r := reduceUndirectedMultiplex(reduceUndirectedMultiplex(g, nil, weights), communities, weights) + + l := newUndirectedMultiplexLocalMover(r, r.communities, weights, []float64{structure.resolution}, true) + for _, n := range structure.targetNodes { + dQ, dst, src := l.deltaQ(n) + if dQ > 0 { + before := floats.Sum(QMultiplex(r, l.communities, weights, []float64{structure.resolution})) + l.move(dst, src) + after := floats.Sum(QMultiplex(r, l.communities, weights, []float64{structure.resolution})) + want := after - before + if !floats.EqualWithinAbsOrRel(dQ, want, structure.tol, structure.tol) { + t.Errorf("unexpected deltaQ: got: %v want: %v", dQ, want) + } + } + } + } + } +} + +func TestLouvainMultiplex(t *testing.T) { + const louvainIterations = 20 + + for _, test := range communityUndirectedMultiplexQTests { + g, weights, err := undirectedMultiplexFrom(test.layers) + if err != nil { + t.Errorf("unexpected error creating multiplex: %v", err) + continue + } + + if test.structures[0].resolution != 1 { + panic("bad test: expect resolution=1") + } + want := make([][]graph.Node, len(test.structures[0].memberships)) + for i, c := range test.structures[0].memberships { + for n := range c { + want[i] = append(want[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(want[i])) + } + sort.Sort(ordered.BySliceIDs(want)) + + var ( + got *ReducedUndirectedMultiplex + bestQ = math.Inf(-1) + ) + // Modularize is randomised so we do this to + // ensure the level tests are consistent. + src := rand.New(rand.NewSource(1)) + for i := 0; i < louvainIterations; i++ { + r := ModularizeMultiplex(g, weights, nil, true, src).(*ReducedUndirectedMultiplex) + if q := floats.Sum(QMultiplex(r, nil, weights, nil)); q > bestQ || math.IsNaN(q) { + bestQ = q + got = r + + if math.IsNaN(q) { + // Don't try again for non-connected case. + break + } + } + + var qs []float64 + for p := r; p != nil; p = p.Expanded().(*ReducedUndirectedMultiplex) { + qs = append(qs, floats.Sum(QMultiplex(p, nil, weights, nil))) + } + + // Recovery of Q values is reversed. + if reverse(qs); !sort.Float64sAreSorted(qs) { + t.Errorf("Q values not monotonically increasing: %.5v", qs) + } + } + + gotCommunities := got.Communities() + for _, c := range gotCommunities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(gotCommunities)) + if !reflect.DeepEqual(gotCommunities, want) { + t.Errorf("unexpected community membership for %s Q=%.4v:\n\tgot: %v\n\twant:%v", + test.name, bestQ, gotCommunities, want) + continue + } + + var levels []level + for p := got; p != nil; p = p.Expanded().(*ReducedUndirectedMultiplex) { + var communities [][]graph.Node + if p.parent != nil { + communities = p.parent.Communities() + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(communities)) + } else { + communities = reduceUndirectedMultiplex(g, nil, weights).Communities() + } + q := floats.Sum(QMultiplex(p, nil, weights, nil)) + if math.IsNaN(q) { + // Use an equalable flag value in place of NaN. + q = math.Inf(-1) + } + levels = append(levels, level{q: q, communities: communities}) + } + if !reflect.DeepEqual(levels, test.wantLevels) { + t.Errorf("unexpected level structure:\n\tgot: %v\n\twant:%v", levels, test.wantLevels) + } + } +} + +func TestNonContiguousUndirectedMultiplex(t *testing.T) { + g := simple.NewUndirectedGraph() + for _, e := range []simple.Edge{ + {F: simple.Node(0), T: simple.Node(1)}, + {F: simple.Node(4), T: simple.Node(5)}, + } { + g.SetEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + ModularizeMultiplex(UndirectedLayers{g}, nil, nil, true, nil) + }() +} + +func TestNonContiguousWeightedUndirectedMultiplex(t *testing.T) { + g := simple.NewWeightedUndirectedGraph(0, 0) + for _, e := range []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(4), T: simple.Node(5), W: 1}, + } { + g.SetWeightedEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + ModularizeMultiplex(UndirectedLayers{g}, nil, nil, true, nil) + }() +} + +func BenchmarkLouvainMultiplex(b *testing.B) { + src := rand.New(rand.NewSource(1)) + for i := 0; i < b.N; i++ { + ModularizeMultiplex(UndirectedLayers{dupGraph}, nil, nil, true, src) + } +} + +func undirectedMultiplexFrom(raw []layer) (UndirectedLayers, []float64, error) { + var layers []graph.Undirected + var weights []float64 + for _, l := range raw { + g := simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range l.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + w := 1.0 + if l.edgeWeight != 0 { + w = l.edgeWeight + } + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: w}) + } + } + layers = append(layers, g) + weights = append(weights, l.weight) + } + g, err := NewUndirectedLayers(layers...) + if err != nil { + return nil, nil, err + } + return g, weights, nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_test.go b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_test.go new file mode 100644 index 00000000..b9a87722 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/louvain_undirected_test.go @@ -0,0 +1,778 @@ +// 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 community + +import ( + "math" + "math/rand" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +type communityUndirectedQTest struct { + name string + g []intset + structures []structure + + wantLevels []level +} + +var communityUndirectedQTests = []communityUndirectedQTest{ + // The java reference implementation is available from http://www.ludowaltman.nl/slm/. + { + name: "unconnected", + g: unconnected, + structures: []structure{ + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0), + 1: linksTo(1), + 2: linksTo(2), + 3: linksTo(3), + 4: linksTo(4), + 5: linksTo(5), + }, + want: math.NaN(), + }, + }, + wantLevels: []level{ + { + q: math.Inf(-1), // Here math.Inf(-1) is used as a place holder for NaN to allow use of reflect.DeepEqual. + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "small_dumbell", + g: smallDumbell, + structures: []structure{ + { + resolution: 1, + // community structure and modularity calculated by java reference implementation. + memberships: []intset{ + 0: linksTo(0, 1, 2), + 1: linksTo(3, 4, 5), + }, + want: 0.357, tol: 1e-3, + }, + { + resolution: 1, + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5), + }, + // theoretical expectation. + want: 0, tol: 1e-14, + }, + }, + wantLevels: []level{ + { + q: 0.35714285714285715, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + {simple.Node(3), simple.Node(4), simple.Node(5)}, + }, + }, + { + q: -0.17346938775510204, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + }, + }, + }, + }, + { + name: "zachary", + g: zachary, + structures: []structure{ + { + resolution: 1, + // community structure and modularity from doi: 10.1140/epjb/e2013-40829-0 + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 7, 11, 12, 13, 17, 19, 21), + 1: linksTo(4, 5, 6, 10, 16), + 2: linksTo(8, 9, 14, 15, 18, 20, 22, 26, 29, 30, 32, 33), + 3: linksTo(23, 24, 25, 27, 28, 31), + }, + // Noted to be the optimal modularisation in the paper above. + want: 0.4198, tol: 1e-4, + }, + { + resolution: 0.5, + // community structure and modularity calculated by java reference implementation. + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 16, 17, 19, 21), + 1: linksTo(8, 14, 15, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33), + }, + want: 0.6218, tol: 1e-3, + }, + { + resolution: 2, + // community structure and modularity calculated by java reference implementation. + memberships: []intset{ + 0: linksTo(14, 18, 20, 22, 32, 33, 15), + 1: linksTo(0, 1, 11, 17, 19, 21), + 2: linksTo(2, 3, 7, 9, 12, 13), + 3: linksTo(4, 5, 6, 10, 16), + 4: linksTo(24, 25, 28, 31), + 5: linksTo(23, 26, 27, 29), + 6: linksTo(8, 30), + }, + want: 0.1645, tol: 1e-3, + }, + }, + wantLevels: []level{ + { + q: 0.4197896120973044, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(7), simple.Node(11), simple.Node(12), simple.Node(13), simple.Node(17), simple.Node(19), simple.Node(21)}, + {simple.Node(4), simple.Node(5), simple.Node(6), simple.Node(10), simple.Node(16)}, + {simple.Node(8), simple.Node(9), simple.Node(14), simple.Node(15), simple.Node(18), simple.Node(20), simple.Node(22), simple.Node(26), simple.Node(29), simple.Node(30), simple.Node(32), simple.Node(33)}, + {simple.Node(23), simple.Node(24), simple.Node(25), simple.Node(27), simple.Node(28), simple.Node(31)}, + }, + }, + { + q: 0.39907955292570674, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(7), simple.Node(11), simple.Node(12), simple.Node(13), simple.Node(17), simple.Node(19), simple.Node(21)}, + {simple.Node(4), simple.Node(10)}, + {simple.Node(5), simple.Node(6), simple.Node(16)}, + {simple.Node(8), simple.Node(9), simple.Node(14), simple.Node(15), simple.Node(18), simple.Node(20), simple.Node(22), simple.Node(26), simple.Node(29), simple.Node(30), simple.Node(32), simple.Node(33)}, + {simple.Node(23), simple.Node(24), simple.Node(25), simple.Node(27), simple.Node(28), simple.Node(31)}, + }, + }, + { + q: -0.04980276134122286, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + {simple.Node(6)}, + {simple.Node(7)}, + {simple.Node(8)}, + {simple.Node(9)}, + {simple.Node(10)}, + {simple.Node(11)}, + {simple.Node(12)}, + {simple.Node(13)}, + {simple.Node(14)}, + {simple.Node(15)}, + {simple.Node(16)}, + {simple.Node(17)}, + {simple.Node(18)}, + {simple.Node(19)}, + {simple.Node(20)}, + {simple.Node(21)}, + {simple.Node(22)}, + {simple.Node(23)}, + {simple.Node(24)}, + {simple.Node(25)}, + {simple.Node(26)}, + {simple.Node(27)}, + {simple.Node(28)}, + {simple.Node(29)}, + {simple.Node(30)}, + {simple.Node(31)}, + {simple.Node(32)}, + {simple.Node(33)}, + }, + }, + }, + }, + { + name: "blondel", + g: blondel, + structures: []structure{ + { + resolution: 1, + // community structure and modularity calculated by java reference implementation. + memberships: []intset{ + 0: linksTo(0, 1, 2, 3, 4, 5, 6, 7), + 1: linksTo(8, 9, 10, 11, 12, 13, 14, 15), + }, + want: 0.3922, tol: 1e-4, + }, + }, + wantLevels: []level{ + { + q: 0.39221938775510207, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(4), simple.Node(5), simple.Node(6), simple.Node(7)}, + {simple.Node(8), simple.Node(9), simple.Node(10), simple.Node(11), simple.Node(12), simple.Node(13), simple.Node(14), simple.Node(15)}, + }, + }, + { + q: 0.34630102040816324, + communities: [][]graph.Node{ + {simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(4), simple.Node(5)}, + {simple.Node(3), simple.Node(6), simple.Node(7)}, + {simple.Node(8), simple.Node(9), simple.Node(10), simple.Node(12), simple.Node(14), simple.Node(15)}, + {simple.Node(11), simple.Node(13)}, + }, + }, + { + q: -0.07142857142857144, + communities: [][]graph.Node{ + {simple.Node(0)}, + {simple.Node(1)}, + {simple.Node(2)}, + {simple.Node(3)}, + {simple.Node(4)}, + {simple.Node(5)}, + {simple.Node(6)}, + {simple.Node(7)}, + {simple.Node(8)}, + {simple.Node(9)}, + {simple.Node(10)}, + {simple.Node(11)}, + {simple.Node(12)}, + {simple.Node(13)}, + {simple.Node(14)}, + {simple.Node(15)}, + }, + }, + }, + }, +} + +func TestCommunityQUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testCommunityQUndirected(t, test, g) + } +} + +func TestCommunityQWeightedUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testCommunityQUndirected(t, test, g) + } +} + +func testCommunityQUndirected(t *testing.T, test communityUndirectedQTest, g graph.Undirected) { + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + } + got := Q(g, communities, structure.resolution) + if !floats.EqualWithinAbsOrRel(got, structure.want, structure.tol, structure.tol) && !math.IsNaN(structure.want) { + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + t.Errorf("unexpected Q value for %q %v: got: %v want: %v", + test.name, communities, got, structure.want) + } + } +} + +func TestCommunityDeltaQUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testCommunityDeltaQUndirected(t, test, g) + } +} + +func TestCommunityDeltaQWeightedUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testCommunityDeltaQUndirected(t, test, g) + } +} + +func testCommunityDeltaQUndirected(t *testing.T, test communityUndirectedQTest, g graph.Undirected) { + rnd := rand.New(rand.NewSource(1)).Intn + for _, structure := range test.structures { + communityOf := make(map[int64]int) + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + communityOf[n] = i + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + before := Q(g, communities, structure.resolution) + + l := newUndirectedLocalMover(reduceUndirected(g, nil), communities, structure.resolution) + if l == nil { + if !math.IsNaN(before) { + t.Errorf("unexpected nil localMover with non-NaN Q graph: Q=%.4v", before) + } + return + } + + // This is done to avoid run-to-run + // variation due to map iteration order. + sort.Sort(ordered.ByID(l.nodes)) + + l.shuffle(rnd) + + for _, target := range l.nodes { + got, gotDst, gotSrc := l.deltaQ(target) + + want, wantDst := math.Inf(-1), -1 + migrated := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + n := int64(n) + if n == target.ID() { + continue + } + migrated[i] = append(migrated[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(migrated[i])) + } + + for i, c := range structure.memberships { + if i == communityOf[target.ID()] { + continue + } + connected := false + for n := range c { + if g.HasEdgeBetween(simple.Node(n), target) { + connected = true + break + } + } + if !connected { + continue + } + migrated[i] = append(migrated[i], target) + after := Q(g, migrated, structure.resolution) + migrated[i] = migrated[i][:len(migrated[i])-1] + if after-before > want { + want = after - before + wantDst = i + } + } + + if !floats.EqualWithinAbsOrRel(got, want, structure.tol, structure.tol) || gotDst != wantDst { + t.Errorf("unexpected result moving n=%d in c=%d of %s/%.4v: got: %.4v,%d want: %.4v,%d"+ + "\n\t%v\n\t%v", + target.ID(), communityOf[target.ID()], test.name, structure.resolution, got, gotDst, want, wantDst, + communities, migrated) + } + if gotSrc.community != communityOf[target.ID()] { + t.Errorf("unexpected source community index: got: %d want: %d", gotSrc, communityOf[target.ID()]) + } else if communities[gotSrc.community][gotSrc.node].ID() != target.ID() { + wantNodeIdx := -1 + for i, n := range communities[gotSrc.community] { + if n.ID() == target.ID() { + wantNodeIdx = i + break + } + } + t.Errorf("unexpected source node index: got: %d want: %d", gotSrc.node, wantNodeIdx) + } + } + } +} + +func TestReduceQConsistencyUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testReduceQConsistencyUndirected(t, test, g) + } +} + +func TestReduceQConsistencyWeightedUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testReduceQConsistencyUndirected(t, test, g) + } +} + +func testReduceQConsistencyUndirected(t *testing.T, test communityUndirectedQTest, g graph.Undirected) { + for _, structure := range test.structures { + if math.IsNaN(structure.want) { + return + } + + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + gQ := Q(g, communities, structure.resolution) + gQnull := Q(g, nil, 1) + + cg0 := reduceUndirected(g, nil) + cg0Qnull := Q(cg0, cg0.Structure(), 1) + if !floats.EqualWithinAbsOrRel(gQnull, cg0Qnull, structure.tol, structure.tol) { + t.Errorf("disagreement between null Q from method: %v and function: %v", cg0Qnull, gQnull) + } + cg0Q := Q(cg0, communities, structure.resolution) + if !floats.EqualWithinAbsOrRel(gQ, cg0Q, structure.tol, structure.tol) { + t.Errorf("unexpected Q result after initial reduction: got: %v want :%v", cg0Q, gQ) + } + + cg1 := reduceUndirected(cg0, communities) + cg1Q := Q(cg1, cg1.Structure(), structure.resolution) + if !floats.EqualWithinAbsOrRel(gQ, cg1Q, structure.tol, structure.tol) { + t.Errorf("unexpected Q result after second reduction: got: %v want :%v", cg1Q, gQ) + } + } +} + +type localUndirectedMoveTest struct { + name string + g []intset + structures []moveStructures +} + +var localUndirectedMoveTests = []localUndirectedMoveTest{ + { + name: "blondel", + g: blondel, + structures: []moveStructures{ + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(0)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + targetNodes: []graph.Node{simple.Node(3)}, + resolution: 1, + tol: 1e-14, + }, + { + memberships: []intset{ + 0: linksTo(0, 1, 2, 4, 5), + 1: linksTo(3, 6, 7), + 2: linksTo(8, 9, 10, 12, 14, 15), + 3: linksTo(11, 13), + }, + // Case to demonstrate when A_aa != k_a^𝛼. + targetNodes: []graph.Node{simple.Node(3), simple.Node(2)}, + resolution: 1, + tol: 1e-14, + }, + }, + }, +} + +func TestMoveLocalUndirected(t *testing.T) { + for _, test := range localUndirectedMoveTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testMoveLocalUndirected(t, test, g) + } +} + +func TestMoveLocalWeightedUndirected(t *testing.T) { + for _, test := range localUndirectedMoveTests { + g := simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testMoveLocalUndirected(t, test, g) + } +} + +func testMoveLocalUndirected(t *testing.T, test localUndirectedMoveTest, g graph.Undirected) { + for _, structure := range test.structures { + communities := make([][]graph.Node, len(structure.memberships)) + for i, c := range structure.memberships { + for n := range c { + communities[i] = append(communities[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(communities[i])) + } + + r := reduceUndirected(reduceUndirected(g, nil), communities) + + l := newUndirectedLocalMover(r, r.communities, structure.resolution) + for _, n := range structure.targetNodes { + dQ, dst, src := l.deltaQ(n) + if dQ > 0 { + before := Q(r, l.communities, structure.resolution) + l.move(dst, src) + after := Q(r, l.communities, structure.resolution) + want := after - before + if !floats.EqualWithinAbsOrRel(dQ, want, structure.tol, structure.tol) { + t.Errorf("unexpected deltaQ: got: %v want: %v", dQ, want) + } + } + } + } +} + +func TestModularizeUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + testModularizeUndirected(t, test, g) + } +} + +func TestModularizeWeightedUndirected(t *testing.T) { + for _, test := range communityUndirectedQTests { + g := simple.NewWeightedUndirectedGraph(0, 0) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + testModularizeUndirected(t, test, g) + } +} + +func testModularizeUndirected(t *testing.T, test communityUndirectedQTest, g graph.Undirected) { + const louvainIterations = 20 + + if test.structures[0].resolution != 1 { + panic("bad test: expect resolution=1") + } + want := make([][]graph.Node, len(test.structures[0].memberships)) + for i, c := range test.structures[0].memberships { + for n := range c { + want[i] = append(want[i], simple.Node(n)) + } + sort.Sort(ordered.ByID(want[i])) + } + sort.Sort(ordered.BySliceIDs(want)) + + var ( + got *ReducedUndirected + bestQ = math.Inf(-1) + ) + // Modularize is randomised so we do this to + // ensure the level tests are consistent. + src := rand.New(rand.NewSource(1)) + for i := 0; i < louvainIterations; i++ { + r := Modularize(g, 1, src).(*ReducedUndirected) + if q := Q(r, nil, 1); q > bestQ || math.IsNaN(q) { + bestQ = q + got = r + + if math.IsNaN(q) { + // Don't try again for non-connected case. + break + } + } + + var qs []float64 + for p := r; p != nil; p = p.Expanded().(*ReducedUndirected) { + qs = append(qs, Q(p, nil, 1)) + } + + // Recovery of Q values is reversed. + if reverse(qs); !sort.Float64sAreSorted(qs) { + t.Errorf("Q values not monotonically increasing: %.5v", qs) + } + } + + gotCommunities := got.Communities() + for _, c := range gotCommunities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(gotCommunities)) + if !reflect.DeepEqual(gotCommunities, want) { + t.Errorf("unexpected community membership for %s Q=%.4v:\n\tgot: %v\n\twant:%v", + test.name, bestQ, gotCommunities, want) + return + } + + var levels []level + for p := got; p != nil; p = p.Expanded().(*ReducedUndirected) { + var communities [][]graph.Node + if p.parent != nil { + communities = p.parent.Communities() + for _, c := range communities { + sort.Sort(ordered.ByID(c)) + } + sort.Sort(ordered.BySliceIDs(communities)) + } else { + communities = reduceUndirected(g, nil).Communities() + } + q := Q(p, nil, 1) + if math.IsNaN(q) { + // Use an equalable flag value in place of NaN. + q = math.Inf(-1) + } + levels = append(levels, level{q: q, communities: communities}) + } + if !reflect.DeepEqual(levels, test.wantLevels) { + t.Errorf("unexpected level structure:\n\tgot: %v\n\twant:%v", levels, test.wantLevels) + } +} + +func TestNonContiguousUndirected(t *testing.T) { + g := simple.NewUndirectedGraph() + for _, e := range []simple.Edge{ + {F: simple.Node(0), T: simple.Node(1)}, + {F: simple.Node(4), T: simple.Node(5)}, + } { + g.SetEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + Modularize(g, 1, nil) + }() +} + +func TestNonContiguousWeightedUndirected(t *testing.T) { + g := simple.NewWeightedUndirectedGraph(0, 0) + for _, e := range []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(4), T: simple.Node(5), W: 1}, + } { + g.SetWeightedEdge(e) + } + + func() { + defer func() { + r := recover() + if r != nil { + t.Error("unexpected panic with non-contiguous ID range") + } + }() + Modularize(g, 1, nil) + }() +} + +func BenchmarkLouvain(b *testing.B) { + src := rand.New(rand.NewSource(1)) + for i := 0; i < b.N; i++ { + Modularize(dupGraph, 1, src) + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/community/printgraphs.go b/vendor/gonum.org/v1/gonum/graph/community/printgraphs.go new file mode 100644 index 00000000..9d8eb1b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/community/printgraphs.go @@ -0,0 +1,142 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ignore + +// printgraphs allows us to generate a consistent directed view of +// a set of edges that follows a reasonably real-world-meaningful +// graph. The interpretation of the links in the resulting directed +// graphs are either "suggests" in the context of a Page Ranking or +// possibly "looks up to" in the Zachary graph. +package main + +import ( + "fmt" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/network" + "gonum.org/v1/gonum/graph/simple" +) + +// set is an integer set. +type set map[int]struct{} + +func linksTo(i ...int) set { + if len(i) == 0 { + return nil + } + s := make(set) + for _, v := range i { + s[v] = struct{}{} + } + return s +} + +var ( + zachary = []set{ + 0: linksTo(1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 17, 19, 21, 31), + 1: linksTo(2, 3, 7, 13, 17, 19, 21, 30), + 2: linksTo(3, 7, 8, 9, 13, 27, 28, 32), + 3: linksTo(7, 12, 13), + 4: linksTo(6, 10), + 5: linksTo(6, 10, 16), + 6: linksTo(16), + 8: linksTo(30, 32, 33), + 9: linksTo(33), + 13: linksTo(33), + 14: linksTo(32, 33), + 15: linksTo(32, 33), + 18: linksTo(32, 33), + 19: linksTo(33), + 20: linksTo(32, 33), + 22: linksTo(32, 33), + 23: linksTo(25, 27, 29, 32, 33), + 24: linksTo(25, 27, 31), + 25: linksTo(31), + 26: linksTo(29, 33), + 27: linksTo(33), + 28: linksTo(31, 33), + 29: linksTo(32, 33), + 30: linksTo(32, 33), + 31: linksTo(32, 33), + 32: linksTo(33), + 33: nil, + } + + blondel = []set{ + 0: linksTo(2, 3, 4, 5), + 1: linksTo(2, 4, 7), + 2: linksTo(4, 5, 6), + 3: linksTo(7), + 4: linksTo(10), + 5: linksTo(7, 11), + 6: linksTo(7, 11), + 8: linksTo(9, 10, 11, 14, 15), + 9: linksTo(12, 14), + 10: linksTo(11, 12, 13, 14), + 11: linksTo(13), + 15: nil, + } +) + +func main() { + for _, raw := range []struct { + name string + set []set + }{ + {"zachary", zachary}, + {"blondel", blondel}, + } { + g := simple.NewUndirectedGraph(0, 0) + for u, e := range raw.set { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + nodes := g.Nodes() + sort.Sort(ordered.ByID(nodes)) + + fmt.Printf("%s = []set{\n", raw.name) + rank := network.PageRank(asDirected{g}, 0.85, 1e-8) + for _, u := range nodes { + to := g.From(nodes[u.ID()]) + sort.Sort(ordered.ByID(to)) + var links []int + for _, v := range to { + if rank[u.ID()] <= rank[v.ID()] { + links = append(links, v.ID()) + } + } + + if links == nil { + fmt.Printf("\t%d: nil, // rank=%.4v\n", u.ID(), rank[u.ID()]) + continue + } + + fmt.Printf("\t%d: linksTo(", u.ID()) + for i, v := range links { + if i != 0 { + fmt.Print(", ") + } + fmt.Print(v) + } + fmt.Printf("), // rank=%.4v\n", rank[u.ID()]) + } + fmt.Println("}") + } +} + +type asDirected struct{ *simple.UndirectedGraph } + +func (g asDirected) HasEdgeFromTo(u, v graph.Node) bool { + return g.UndirectedGraph.HasEdgeBetween(u, v) +} +func (g asDirected) To(v graph.Node) []graph.Node { return g.From(v) } diff --git a/vendor/gonum.org/v1/gonum/graph/doc.go b/vendor/gonum.org/v1/gonum/graph/doc.go new file mode 100644 index 00000000..74477274 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/doc.go @@ -0,0 +1,38 @@ +// 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 implements functions and interfaces to deal with formal discrete graphs. It aims to +be first and foremost flexible, with speed as a strong second priority. + +In this package, graphs are taken to be directed, and undirected graphs are considered to be a +special case of directed graphs that happen to have reciprocal edges. Graphs are, by default, +unweighted, but functions that require weighted edges have several methods of dealing with this. +In order of precedence: + +1. These functions have an argument called Cost (and in some cases, HeuristicCost). If this is +present, it will always be used to determine the cost between two nodes. + +2. These functions will check if your graph implements the Coster (and/or HeuristicCoster) +interface. If this is present, and the Cost (or HeuristicCost) argument is nil, these functions +will be used. + +3. Finally, if no user data is supplied, it will use the functions UniformCost (always returns 1) +and/or NulLHeuristic (always returns 0). + +For information on the specification for Cost functions, please see the Coster interface. + +Finally, although the functions take in a Graph -- they will always use the correct behavior. +If your graph implements DirectedGraph, it will use Successors and To where applicable, +if undirected, it will use From instead. If it implements neither, it will scan the edge list +for successors and predecessors where applicable. (This is slow, you should always implement either +Directed or Undirected) + +This package will never modify a graph that is not Mutable (and the interface does not allow it to +do so). However, return values are free to be modified, so never pass a reference to your own edge +list or node list. It also guarantees that any nodes passed back to the user will be the same +nodes returned to it -- that is, it will never take a Node's ID and then wrap the ID in a new +struct and return that. You'll always get back your original data. +*/ +package graph // import "gonum.org/v1/gonum/graph" diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/doc.go b/vendor/gonum.org/v1/gonum/graph/encoding/doc.go new file mode 100644 index 00000000..1f51390f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package encoding provides a common graph encoding API. +package encoding // import "gonum.org/v1/gonum/graph/encoding" diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/dot/decode.go b/vendor/gonum.org/v1/gonum/graph/encoding/dot/decode.go new file mode 100644 index 00000000..ccc2868d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/dot/decode.go @@ -0,0 +1,278 @@ +// 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" + + "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) +} + +// Unmarshal parses the Graphviz DOT-encoded data and stores the result in dst. +func Unmarshal(data []byte, dst encoding.Builder) error { + file, err := dot.ParseBytes(data) + if err != nil { + return err + } + if len(file.Graphs) != 1 { + return fmt.Errorf("invalid number of graphs; expected 1, got %d", len(file.Graphs)) + } + return copyGraph(dst, file.Graphs[0]) +} + +// 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 := &generator{ + directed: src.Directed, + ids: make(map[string]graph.Node), + } + 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 encoding.Builder, id string) graph.Node { + if n, ok := gen.ids[id]; ok { + return n + } + n := dst.NewNode() + dst.AddNode(n) + if n, ok := n.(DOTIDSetter); ok { + n.SetDOTID(id) + } + 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 +} + +// addStmt adds the given statement to the graph. +func (gen *generator) 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: attr.Key, + Value: attr.Val, + } + if err := n.SetAttribute(a); err != nil { + panic(fmt.Errorf("unable to unmarshal node DOT attribute (%s=%s)", a.Key, a.Value)) + } + } + 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: attr.Key, + Value: attr.Val, + } + if err := n.SetAttribute(a); err != nil { + panic(fmt.Errorf("unable to unmarshal global %s DOT attribute (%s=%s)", dst, a.Key, a.Value)) + } + } + 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 graph. +func (gen *generator) addEdgeStmt(dst encoding.Builder, stmt *ast.EdgeStmt) { + fs := gen.addVertex(dst, stmt.From) + ts := gen.addEdge(dst, stmt.To) + for _, f := range fs { + for _, t := range ts { + edge := dst.NewEdge(f, t) + dst.SetEdge(edge) + e, ok := edge.(encoding.AttributeSetter) + if !ok { + continue + } + for _, attr := range stmt.Attrs { + a := encoding.Attribute{ + Key: attr.Key, + Value: attr.Val, + } + if err := e.SetAttribute(a); err != nil { + panic(fmt.Errorf("unable to unmarshal edge DOT attribute (%s=%s)", a.Key, a.Value)) + } + } + } + } +} + +// addVertex adds the given vertex to the graph, and returns its set of nodes. +func (gen *generator) addVertex(dst encoding.Builder, v ast.Vertex) []graph.Node { + 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 *generator) addEdge(dst encoding.Builder, to *ast.Edge) []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) + for _, f := range fs { + for _, t := range ts { + edge := dst.NewEdge(f, t) + dst.SetEdge(edge) + } + } + } + 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) +} diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/dot/decode_test.go b/vendor/gonum.org/v1/gonum/graph/encoding/dot/decode_test.go new file mode 100644 index 00000000..d05b0507 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/dot/decode_test.go @@ -0,0 +1,247 @@ +// 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" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/encoding" + "gonum.org/v1/gonum/graph/simple" +) + +func TestRoundTrip(t *testing.T) { + golden := []struct { + want string + directed bool + }{ + { + want: directed, + directed: true, + }, + { + want: undirected, + directed: false, + }, + } + for i, g := range golden { + var dst encoding.Builder + if g.directed { + dst = newDotDirectedGraph() + } else { + dst = newDotUndirectedGraph() + } + data := []byte(g.want) + if err := Unmarshal(data, dst); err != nil { + t.Errorf("i=%d: unable to unmarshal DOT graph; %v", i, err) + continue + } + buf, err := Marshal(dst, "", "", "\t", false) + if err != nil { + t.Errorf("i=%d: unable to marshal graph; %v", i, dst) + continue + } + got := string(buf) + if got != g.want { + t.Errorf("i=%d: graph content mismatch; want:\n%s\n\ngot:\n%s", i, g.want, got) + continue + } + } +} + +const directed = `digraph { + graph [ + outputorder=edgesfirst + ]; + node [ + shape=circle + style=filled + ]; + edge [ + penwidth=5 + color=gray + ]; + + // Node definitions. + A [label="foo 2"]; + B [label="bar 2"]; + + // Edge definitions. + A -> B [label="baz 2"]; +}` + +const undirected = `graph { + graph [ + outputorder=edgesfirst + ]; + node [ + shape=circle + style=filled + ]; + edge [ + penwidth=5 + color=gray + ]; + + // Node definitions. + A [label="foo 2"]; + B [label="bar 2"]; + + // Edge definitions. + A -- B [label="baz 2"]; +}` + +// Below follows a minimal implementation of a graph capable of validating the +// round-trip encoding and decoding of DOT graphs with nodes and edges +// containing DOT attributes. + +// dotDirectedGraph extends simple.DirectedGraph to add NewNode and NewEdge +// methods for creating user-defined nodes and edges. +// +// dotDirectedGraph implements the dot.Builder interface. +type dotDirectedGraph struct { + *simple.DirectedGraph + graph, node, edge attributes +} + +// newDotDirectedGraph returns a new directed capable of creating user-defined +// nodes and edges. +func newDotDirectedGraph() *dotDirectedGraph { + return &dotDirectedGraph{DirectedGraph: simple.NewDirectedGraph()} +} + +// NewNode returns a new node with a unique node ID for the graph. +func (g *dotDirectedGraph) NewNode() graph.Node { + return &dotNode{Node: g.DirectedGraph.NewNode()} +} + +// NewEdge returns a new Edge from the source to the destination node. +func (g *dotDirectedGraph) NewEdge(from, to graph.Node) graph.Edge { + return &dotEdge{Edge: g.DirectedGraph.NewEdge(from, to)} +} + +// DOTAttributers implements the dot.Attributers interface. +func (g *dotDirectedGraph) DOTAttributers() (graph, node, edge encoding.Attributer) { + return g.graph, g.node, g.edge +} + +// DOTAttributeSetters implements the dot.AttributeSetters interface. +func (g *dotDirectedGraph) DOTAttributeSetters() (graph, node, edge encoding.AttributeSetter) { + return &g.graph, &g.node, &g.edge +} + +// dotUndirectedGraph extends simple.UndirectedGraph to add NewNode and NewEdge +// methods for creating user-defined nodes and edges. +// +// dotUndirectedGraph implements the dot.Builder interface. +type dotUndirectedGraph struct { + *simple.UndirectedGraph + graph, node, edge attributes +} + +// newDotUndirectedGraph returns a new undirected capable of creating user- +// defined nodes and edges. +func newDotUndirectedGraph() *dotUndirectedGraph { + return &dotUndirectedGraph{UndirectedGraph: simple.NewUndirectedGraph()} +} + +// NewNode adds a new node with a unique node ID to the graph. +func (g *dotUndirectedGraph) NewNode() graph.Node { + return &dotNode{Node: g.UndirectedGraph.NewNode()} +} + +// NewEdge returns a new Edge from the source to the destination node. +func (g *dotUndirectedGraph) NewEdge(from, to graph.Node) graph.Edge { + return &dotEdge{Edge: g.UndirectedGraph.NewEdge(from, to)} +} + +// DOTAttributers implements the dot.Attributers interface. +func (g *dotUndirectedGraph) DOTAttributers() (graph, node, edge encoding.Attributer) { + return g.graph, g.node, g.edge +} + +// DOTUnmarshalerAttrs implements the dot.UnmarshalerAttrs interface. +func (g *dotUndirectedGraph) DOTAttributeSetters() (graph, node, edge encoding.AttributeSetter) { + return &g.graph, &g.node, &g.edge +} + +// dotNode extends simple.Node with a label field to test round-trip encoding +// and decoding of node DOT label attributes. +type dotNode struct { + graph.Node + dotID string + // Node label. + Label string +} + +// DOTID returns the node's DOT ID. +func (n *dotNode) DOTID() string { + return n.dotID +} + +// SetDOTID sets a DOT ID. +func (n *dotNode) SetDOTID(id string) { + n.dotID = id +} + +// SetAttribute sets a DOT attribute. +func (n *dotNode) SetAttribute(attr encoding.Attribute) error { + if attr.Key != "label" { + return fmt.Errorf("unable to unmarshal node DOT attribute with key %q", attr.Key) + } + n.Label = attr.Value + return nil +} + +// Attributes returns the DOT attributes of the node. +func (n *dotNode) Attributes() []encoding.Attribute { + if len(n.Label) == 0 { + return nil + } + return []encoding.Attribute{{ + Key: "label", + Value: n.Label, + }} +} + +// dotEdge extends simple.Edge with a label field to test round-trip encoding and +// decoding of edge DOT label attributes. +type dotEdge struct { + graph.Edge + // Edge label. + Label string +} + +// SetAttribute sets a DOT attribute. +func (e *dotEdge) SetAttribute(attr encoding.Attribute) error { + if attr.Key != "label" { + return fmt.Errorf("unable to unmarshal node DOT attribute with key %q", attr.Key) + } + e.Label = attr.Value + return nil +} + +// Attributes returns the DOT attributes of the edge. +func (e *dotEdge) Attributes() []encoding.Attribute { + if len(e.Label) == 0 { + return nil + } + return []encoding.Attribute{{ + Key: "label", + Value: e.Label, + }} +} + +// attributes is a helper for global attributes. +type attributes []encoding.Attribute + +func (a attributes) Attributes() []encoding.Attribute { + return []encoding.Attribute(a) +} +func (a *attributes) SetAttribute(attr encoding.Attribute) error { + *a = append(*a, attr) + return nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/dot/doc.go b/vendor/gonum.org/v1/gonum/graph/encoding/dot/doc.go new file mode 100644 index 00000000..6a4a6675 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/dot/doc.go @@ -0,0 +1,14 @@ +// 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: http://www.graphviz.org/Documentation/dotguide.pdf +// +// DOT grammar: http://www.graphviz.org/doc/info/lang.html +// +package dot // import "gonum.org/v1/gonum/graph/encoding/dot" diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/dot/dot.go b/vendor/gonum.org/v1/gonum/graph/encoding/dot/dot.go new file mode 100644 index 00000000..2272d7ae --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/dot/dot.go @@ -0,0 +1,5 @@ +// 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 diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/dot/encode.go b/vendor/gonum.org/v1/gonum/graph/encoding/dot/encode.go new file mode 100644 index 00000000..a7a15493 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/dot/encode.go @@ -0,0 +1,359 @@ +// 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" + "sort" + "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 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() (port, compass string) + ToPort() (port, compass string) +} + +// Structurer represents a graph.Graph that can define subgraphs. +type Structurer interface { + Structure() []Graph +} + +// Graph wraps named graph.Graph values. +type Graph interface { + graph.Graph + DOTID() string +} + +// Subgrapher wraps graph.Node values that represent subgraphs. +type Subgrapher interface { + Subgraph() graph.Graph +} + +// Marshal returns the DOT encoding for the graph g, applying the prefix +// and indent to the encoding. Name is used to specify the graph name. If +// name is empty and g implements Graph, the returned string from DOTID +// will be used. If strict is true the output bytes will be prefixed with +// the DOT "strict" keyword. +// +// Graph serialization will work for a graph.Graph without modification, +// however, advanced GraphViz DOT features provided by Marshal depend on +// implementation of the Node, Attributer, Porter, Attributers, Structurer, +// Subgrapher and Graph interfaces. +func Marshal(g graph.Graph, name, prefix, indent string, strict bool) ([]byte, error) { + var p printer + p.indent = indent + p.prefix = prefix + p.visited = make(map[edge]bool) + if strict { + p.buf.WriteString("strict ") + } + err := p.print(g, name, false, false) + if err != nil { + return nil, err + } + return p.buf.Bytes(), nil +} + +type printer struct { + buf bytes.Buffer + + prefix string + indent string + depth int + + visited map[edge]bool + + err error +} + +type edge struct { + inGraph string + from, to int64 +} + +func (p *printer) print(g graph.Graph, name string, needsIndent, isSubgraph bool) error { + nodes := g.Nodes() + sort.Sort(ordered.ByID(nodes)) + + p.buf.WriteString(p.prefix) + if needsIndent { + for i := 0; i < p.depth; i++ { + p.buf.WriteString(p.indent) + } + } + _, isDirected := g.(graph.Directed) + if isSubgraph { + p.buf.WriteString("sub") + } else if isDirected { + p.buf.WriteString("di") + } + p.buf.WriteString("graph") + + if name == "" { + if g, ok := g.(Graph); ok { + name = g.DOTID() + } + } + if name != "" { + p.buf.WriteByte(' ') + p.buf.WriteString(name) + } + + p.openBlock(" {") + 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) + } + } + + havePrintedNodeHeader := false + for _, n := range nodes { + if s, ok := n.(Subgrapher); ok { + // If the node is not linked to any other node + // the graph needs to be written now. + if len(g.From(n)) == 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 { + to := g.From(n) + sort.Sort(ordered.ByID(to)) + for _, t := range to { + if isDirected { + if p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] { + continue + } + p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] = true + } else { + if p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] { + continue + } + p.visited[edge{inGraph: name, from: n.ID(), to: t.ID()}] = true + p.visited[edge{inGraph: name, from: t.ID(), 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, edgeIsPorter := g.Edge(n, t).(Porter) + if edgeIsPorter { + p.writePorts(e.FromPort()) + } + + 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 { + p.writePorts(e.ToPort()) + } + + if a, ok := g.Edge(n, t).(encoding.Attributer); ok { + p.writeAttributeList(a) + } + + p.buf.WriteByte(';') + } + } + p.closeBlock("}") + + return nil +} + +func (p *printer) writeNode(n graph.Node) { + p.buf.WriteString(nodeID(n)) +} + +func (p *printer) writePorts(port, cp string) { + if port != "" { + p.buf.WriteByte(':') + p.buf.WriteString(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 graph.Graph, 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(attributes[0].Key) + p.buf.WriteByte('=') + p.buf.WriteString(attributes[0].Value) + p.buf.WriteString("]") + default: + p.openBlock(" [") + for _, att := range attributes { + p.newline() + p.buf.WriteString(att.Key) + p.buf.WriteByte('=') + p.buf.WriteString(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(att.Key) + p.buf.WriteByte('=') + p.buf.WriteString(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) +} diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/dot/encode_test.go b/vendor/gonum.org/v1/gonum/graph/encoding/dot/encode_test.go new file mode 100644 index 00000000..d4dba18c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/dot/encode_test.go @@ -0,0 +1,1436 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/encoding" + "gonum.org/v1/gonum/graph/simple" +) + +// intset is an integer set. +type intset map[int64]struct{} + +func linksTo(i ...int64) intset { + if len(i) == 0 { + return nil + } + s := make(intset) + for _, v := range i { + s[v] = struct{}{} + } + return s +} + +var ( + // Example graph from http://en.wikipedia.org/wiki/File:PageRanks-Example.svg 16:17, 8 July 2009 + // Node identities are rewritten here to use integers from 0 to match with the DOT output. + pageRankGraph = []intset{ + 0: nil, + 1: linksTo(2), + 2: linksTo(1), + 3: linksTo(0, 1), + 4: linksTo(3, 1, 5), + 5: linksTo(1, 4), + 6: linksTo(1, 4), + 7: linksTo(1, 4), + 8: linksTo(1, 4), + 9: linksTo(4), + 10: linksTo(4), + } + + // Example graph from http://en.wikipedia.org/w/index.php?title=PageRank&oldid=659286279#Power_Method + powerMethodGraph = []intset{ + 0: linksTo(1, 2), + 1: linksTo(3), + 2: linksTo(3, 4), + 3: linksTo(4), + 4: linksTo(0), + } +) + +func directedGraphFrom(g []intset) graph.Directed { + dg := simple.NewDirectedGraph() + for u, e := range g { + for v := range e { + dg.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + return dg +} + +func undirectedGraphFrom(g []intset) graph.Graph { + dg := simple.NewUndirectedGraph() + for u, e := range g { + for v := range e { + dg.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + return dg +} + +const alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +type namedNode struct { + id int64 + name string +} + +func (n namedNode) ID() int64 { return n.id } +func (n namedNode) DOTID() string { return n.name } + +func directedNamedIDGraphFrom(g []intset) graph.Directed { + dg := simple.NewDirectedGraph() + for u, e := range g { + u := int64(u) + nu := namedNode{id: u, name: alpha[u : u+1]} + for v := range e { + nv := namedNode{id: v, name: alpha[v : v+1]} + dg.SetEdge(simple.Edge{F: nu, T: nv}) + } + } + return dg +} + +func undirectedNamedIDGraphFrom(g []intset) graph.Graph { + dg := simple.NewUndirectedGraph() + for u, e := range g { + u := int64(u) + nu := namedNode{id: u, name: alpha[u : u+1]} + for v := range e { + nv := namedNode{id: v, name: alpha[v : v+1]} + dg.SetEdge(simple.Edge{F: nu, T: nv}) + } + } + return dg +} + +type attrNode struct { + id int64 + name string + attr []encoding.Attribute +} + +func (n attrNode) ID() int64 { return n.id } +func (n attrNode) Attributes() []encoding.Attribute { return n.attr } + +func directedNodeAttrGraphFrom(g []intset, attr [][]encoding.Attribute) graph.Directed { + dg := simple.NewDirectedGraph() + for u, e := range g { + u := int64(u) + var at []encoding.Attribute + if u < int64(len(attr)) { + at = attr[u] + } + nu := attrNode{id: u, attr: at} + for v := range e { + if v < int64(len(attr)) { + at = attr[v] + } + nv := attrNode{id: v, attr: at} + dg.SetEdge(simple.Edge{F: nu, T: nv}) + } + } + return dg +} + +func undirectedNodeAttrGraphFrom(g []intset, attr [][]encoding.Attribute) graph.Graph { + dg := simple.NewUndirectedGraph() + for u, e := range g { + u := int64(u) + var at []encoding.Attribute + if u < int64(len(attr)) { + at = attr[u] + } + nu := attrNode{id: u, attr: at} + for v := range e { + if v < int64(len(attr)) { + at = attr[v] + } + nv := attrNode{id: v, attr: at} + dg.SetEdge(simple.Edge{F: nu, T: nv}) + } + } + return dg +} + +type namedAttrNode struct { + id int64 + name string + attr []encoding.Attribute +} + +func (n namedAttrNode) ID() int64 { return n.id } +func (n namedAttrNode) DOTID() string { return n.name } +func (n namedAttrNode) Attributes() []encoding.Attribute { return n.attr } + +func directedNamedIDNodeAttrGraphFrom(g []intset, attr [][]encoding.Attribute) graph.Directed { + dg := simple.NewDirectedGraph() + for u, e := range g { + u := int64(u) + var at []encoding.Attribute + if u < int64(len(attr)) { + at = attr[u] + } + nu := namedAttrNode{id: u, name: alpha[u : u+1], attr: at} + for v := range e { + if v < int64(len(attr)) { + at = attr[v] + } + nv := namedAttrNode{id: v, name: alpha[v : v+1], attr: at} + dg.SetEdge(simple.Edge{F: nu, T: nv}) + } + } + return dg +} + +func undirectedNamedIDNodeAttrGraphFrom(g []intset, attr [][]encoding.Attribute) graph.Graph { + dg := simple.NewUndirectedGraph() + for u, e := range g { + u := int64(u) + var at []encoding.Attribute + if u < int64(len(attr)) { + at = attr[u] + } + nu := namedAttrNode{id: u, name: alpha[u : u+1], attr: at} + for v := range e { + if v < int64(len(attr)) { + at = attr[v] + } + nv := namedAttrNode{id: v, name: alpha[v : v+1], attr: at} + dg.SetEdge(simple.Edge{F: nu, T: nv}) + } + } + return dg +} + +type attrEdge struct { + from, to graph.Node + + attr []encoding.Attribute +} + +func (e attrEdge) From() graph.Node { return e.from } +func (e attrEdge) To() graph.Node { return e.to } +func (e attrEdge) Weight() float64 { return 0 } +func (e attrEdge) Attributes() []encoding.Attribute { return e.attr } + +func directedEdgeAttrGraphFrom(g []intset, attr map[edge][]encoding.Attribute) graph.Directed { + dg := simple.NewDirectedGraph() + for u, e := range g { + u := int64(u) + for v := range e { + dg.SetEdge(attrEdge{from: simple.Node(u), to: simple.Node(v), attr: attr[edge{from: u, to: v}]}) + } + } + return dg +} + +func undirectedEdgeAttrGraphFrom(g []intset, attr map[edge][]encoding.Attribute) graph.Graph { + dg := simple.NewUndirectedGraph() + for u, e := range g { + u := int64(u) + for v := range e { + dg.SetEdge(attrEdge{from: simple.Node(u), to: simple.Node(v), attr: attr[edge{from: u, to: v}]}) + } + } + return dg +} + +type portedEdge struct { + from, to graph.Node + + directed bool + + fromPort string + fromCompass string + toPort string + toCompass string +} + +func (e portedEdge) From() graph.Node { return e.from } +func (e portedEdge) To() graph.Node { return e.to } +func (e portedEdge) Weight() float64 { return 0 } + +// TODO(kortschak): Figure out a better way to handle the fact that +// headedness is an undefined concept in undirected graphs. We sort +// nodes by ID, so lower ID nodes are always from nodes in undirected +// graphs. We can probably do this in the printer, but I am leaving +// this here as a WARNING. +// Maybe the approach should be to document that for undirected graphs +// the low ID node should be returned by the FromPort and the high ID +// by the ToPort calls. +func (e portedEdge) FromPort() (port, compass string) { + return e.fromPort, e.fromCompass +} +func (e portedEdge) ToPort() (port, compass string) { + return e.toPort, e.toCompass +} + +func directedPortedAttrGraphFrom(g []intset, attr [][]encoding.Attribute, ports map[edge]portedEdge) graph.Directed { + dg := simple.NewDirectedGraph() + for u, e := range g { + u := int64(u) + var at []encoding.Attribute + if u < int64(len(attr)) { + at = attr[u] + } + nu := attrNode{id: u, attr: at} + for v := range e { + if v < int64(len(attr)) { + at = attr[v] + } + pe := ports[edge{from: u, to: v}] + pe.from = nu + pe.to = attrNode{id: v, attr: at} + dg.SetEdge(pe) + } + } + return dg +} + +func undirectedPortedAttrGraphFrom(g []intset, attr [][]encoding.Attribute, ports map[edge]portedEdge) graph.Graph { + dg := simple.NewUndirectedGraph() + for u, e := range g { + u := int64(u) + var at []encoding.Attribute + if u < int64(len(attr)) { + at = attr[u] + } + nu := attrNode{id: u, attr: at} + for v := range e { + if v < int64(len(attr)) { + at = attr[v] + } + pe := ports[edge{from: u, to: v}] + pe.from = nu + pe.to = attrNode{id: v, attr: at} + dg.SetEdge(pe) + } + } + return dg +} + +type graphAttributer struct { + graph.Graph + graph attributer + node attributer + edge attributer +} + +type attributer []encoding.Attribute + +func (a attributer) Attributes() []encoding.Attribute { return a } + +func (g graphAttributer) DOTAttributers() (graph, node, edge encoding.Attributer) { + return g.graph, g.node, g.edge +} + +type structuredGraph struct { + *simple.UndirectedGraph + sub []Graph +} + +func undirectedStructuredGraphFrom(c []edge, g ...[]intset) graph.Graph { + s := &structuredGraph{UndirectedGraph: simple.NewUndirectedGraph()} + var base int64 + for i, sg := range g { + sub := simple.NewUndirectedGraph() + for u, e := range sg { + u := int64(u) + for v := range e { + ce := simple.Edge{F: simple.Node(u + base), T: simple.Node(v + base)} + sub.SetEdge(ce) + } + } + s.sub = append(s.sub, namedGraph{id: int64(i), Graph: sub}) + base += int64(len(sg)) + } + for _, e := range c { + s.SetEdge(simple.Edge{F: simple.Node(e.from), T: simple.Node(e.to)}) + } + return s +} + +func (g structuredGraph) Structure() []Graph { + return g.sub +} + +type namedGraph struct { + id int64 + graph.Graph +} + +func (g namedGraph) DOTID() string { return alpha[g.id : g.id+1] } + +type subGraph struct { + id int64 + graph.Graph +} + +func (g subGraph) ID() int64 { return g.id } +func (g subGraph) Subgraph() graph.Graph { + return namedGraph(g) +} + +func undirectedSubGraphFrom(g []intset, s map[int64][]intset) graph.Graph { + var base int64 + subs := make(map[int64]subGraph) + for i, sg := range s { + sub := simple.NewUndirectedGraph() + for u, e := range sg { + u := int64(u) + for v := range e { + ce := simple.Edge{F: simple.Node(u + base), T: simple.Node(v + base)} + sub.SetEdge(ce) + } + } + subs[i] = subGraph{id: int64(i), Graph: sub} + base += int64(len(sg)) + } + + dg := simple.NewUndirectedGraph() + for u, e := range g { + u := int64(u) + var nu graph.Node + if sg, ok := subs[u]; ok { + sg.id += base + nu = sg + } else { + nu = simple.Node(u + base) + } + for v := range e { + var nv graph.Node + if sg, ok := subs[v]; ok { + sg.id += base + nv = sg + } else { + nv = simple.Node(v + base) + } + dg.SetEdge(simple.Edge{F: nu, T: nv}) + } + } + return dg +} + +var encodeTests = []struct { + name string + g graph.Graph + strict bool + + prefix string + + want string +}{ + // Basic graph.Graph handling. + { + name: "PageRank", + g: directedGraphFrom(pageRankGraph), + + want: `digraph PageRank { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + 5; + 6; + 7; + 8; + 9; + 10; + + // Edge definitions. + 1 -> 2; + 2 -> 1; + 3 -> 0; + 3 -> 1; + 4 -> 1; + 4 -> 3; + 4 -> 5; + 5 -> 1; + 5 -> 4; + 6 -> 1; + 6 -> 4; + 7 -> 1; + 7 -> 4; + 8 -> 1; + 8 -> 4; + 9 -> 4; + 10 -> 4; +}`, + }, + { + g: undirectedGraphFrom(pageRankGraph), + + want: `graph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + 5; + 6; + 7; + 8; + 9; + 10; + + // Edge definitions. + 0 -- 3; + 1 -- 2; + 1 -- 3; + 1 -- 4; + 1 -- 5; + 1 -- 6; + 1 -- 7; + 1 -- 8; + 3 -- 4; + 4 -- 5; + 4 -- 6; + 4 -- 7; + 4 -- 8; + 4 -- 9; + 4 -- 10; +}`, + }, + { + g: directedGraphFrom(powerMethodGraph), + + want: `digraph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -> 1; + 0 -> 2; + 1 -> 3; + 2 -> 3; + 2 -> 4; + 3 -> 4; + 4 -> 0; +}`, + }, + { + g: undirectedGraphFrom(powerMethodGraph), + + want: `graph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; +}`, + }, + { + g: undirectedGraphFrom(powerMethodGraph), + prefix: "# ", + + want: `# graph { +# // Node definitions. +# 0; +# 1; +# 2; +# 3; +# 4; +# +# // Edge definitions. +# 0 -- 1; +# 0 -- 2; +# 0 -- 4; +# 1 -- 3; +# 2 -- 3; +# 2 -- 4; +# 3 -- 4; +# }`, + }, + + // Names named nodes. + { + name: "PageRank", + g: directedNamedIDGraphFrom(pageRankGraph), + + want: `digraph PageRank { + // Node definitions. + A; + B; + C; + D; + E; + F; + G; + H; + I; + J; + K; + + // Edge definitions. + B -> C; + C -> B; + D -> A; + D -> B; + E -> B; + E -> D; + E -> F; + F -> B; + F -> E; + G -> B; + G -> E; + H -> B; + H -> E; + I -> B; + I -> E; + J -> E; + K -> E; +}`, + }, + { + g: undirectedNamedIDGraphFrom(pageRankGraph), + + want: `graph { + // Node definitions. + A; + B; + C; + D; + E; + F; + G; + H; + I; + J; + K; + + // Edge definitions. + A -- D; + B -- C; + B -- D; + B -- E; + B -- F; + B -- G; + B -- H; + B -- I; + D -- E; + E -- F; + E -- G; + E -- H; + E -- I; + E -- J; + E -- K; +}`, + }, + { + g: directedNamedIDGraphFrom(powerMethodGraph), + + want: `digraph { + // Node definitions. + A; + B; + C; + D; + E; + + // Edge definitions. + A -> B; + A -> C; + B -> D; + C -> D; + C -> E; + D -> E; + E -> A; +}`, + }, + { + g: undirectedNamedIDGraphFrom(powerMethodGraph), + + want: `graph { + // Node definitions. + A; + B; + C; + D; + E; + + // Edge definitions. + A -- B; + A -- C; + A -- E; + B -- D; + C -- D; + C -- E; + D -- E; +}`, + }, + { + g: undirectedNamedIDGraphFrom(powerMethodGraph), + prefix: "# ", + + want: `# graph { +# // Node definitions. +# A; +# B; +# C; +# D; +# E; +# +# // Edge definitions. +# A -- B; +# A -- C; +# A -- E; +# B -- D; +# C -- D; +# C -- E; +# D -- E; +# }`, + }, + + // Handling nodes with attributes. + { + g: directedNodeAttrGraphFrom(powerMethodGraph, nil), + + want: `digraph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -> 1; + 0 -> 2; + 1 -> 3; + 2 -> 3; + 2 -> 4; + 3 -> 4; + 4 -> 0; +}`, + }, + { + g: undirectedNodeAttrGraphFrom(powerMethodGraph, nil), + + want: `graph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; +}`, + }, + { + g: directedNodeAttrGraphFrom(powerMethodGraph, [][]encoding.Attribute{ + 2: {{"fontsize", "16"}, {"shape", "ellipse"}}, + 4: {}, + }), + + want: `digraph { + // Node definitions. + 0; + 1; + 2 [ + fontsize=16 + shape=ellipse + ]; + 3; + 4; + + // Edge definitions. + 0 -> 1; + 0 -> 2; + 1 -> 3; + 2 -> 3; + 2 -> 4; + 3 -> 4; + 4 -> 0; +}`, + }, + { + g: undirectedNodeAttrGraphFrom(powerMethodGraph, [][]encoding.Attribute{ + 2: {{"fontsize", "16"}, {"shape", "ellipse"}}, + 4: {}, + }), + + want: `graph { + // Node definitions. + 0; + 1; + 2 [ + fontsize=16 + shape=ellipse + ]; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; +}`, + }, + { + g: directedNamedIDNodeAttrGraphFrom(powerMethodGraph, [][]encoding.Attribute{ + 2: {{"fontsize", "16"}, {"shape", "ellipse"}}, + 4: {}, + }), + + want: `digraph { + // Node definitions. + A; + B; + C [ + fontsize=16 + shape=ellipse + ]; + D; + E; + + // Edge definitions. + A -> B; + A -> C; + B -> D; + C -> D; + C -> E; + D -> E; + E -> A; +}`, + }, + { + g: undirectedNamedIDNodeAttrGraphFrom(powerMethodGraph, [][]encoding.Attribute{ + 0: nil, + 1: nil, + 2: {{"fontsize", "16"}, {"shape", "ellipse"}}, + 3: nil, + 4: {}, + }), + + want: `graph { + // Node definitions. + A; + B; + C [ + fontsize=16 + shape=ellipse + ]; + D; + E; + + // Edge definitions. + A -- B; + A -- C; + A -- E; + B -- D; + C -- D; + C -- E; + D -- E; +}`, + }, + + // Handling edge with attributes. + { + g: directedEdgeAttrGraphFrom(powerMethodGraph, nil), + + want: `digraph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -> 1; + 0 -> 2; + 1 -> 3; + 2 -> 3; + 2 -> 4; + 3 -> 4; + 4 -> 0; +}`, + }, + { + g: undirectedEdgeAttrGraphFrom(powerMethodGraph, nil), + + want: `graph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; +}`, + }, + { + g: directedEdgeAttrGraphFrom(powerMethodGraph, map[edge][]encoding.Attribute{ + {from: 0, to: 2}: {{"label", `"???"`}, {"style", "dashed"}}, + {from: 2, to: 4}: {}, + {from: 3, to: 4}: {{"color", "red"}}, + }), + + want: `digraph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -> 1; + 0 -> 2 [ + label="???" + style=dashed + ]; + 1 -> 3; + 2 -> 3; + 2 -> 4; + 3 -> 4 [color=red]; + 4 -> 0; +}`, + }, + { + g: undirectedEdgeAttrGraphFrom(powerMethodGraph, map[edge][]encoding.Attribute{ + {from: 0, to: 2}: {{"label", `"???"`}, {"style", "dashed"}}, + {from: 2, to: 4}: {}, + {from: 3, to: 4}: {{"color", "red"}}, + }), + + want: `graph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2 [ + label="???" + style=dashed + ]; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4 [color=red]; +}`, + }, + + // Handling nodes with ports. + { + g: directedPortedAttrGraphFrom(powerMethodGraph, nil, nil), + + want: `digraph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -> 1; + 0 -> 2; + 1 -> 3; + 2 -> 3; + 2 -> 4; + 3 -> 4; + 4 -> 0; +}`, + }, + { + g: undirectedPortedAttrGraphFrom(powerMethodGraph, nil, nil), + + want: `graph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; +}`, + }, + { + g: directedPortedAttrGraphFrom(powerMethodGraph, + [][]encoding.Attribute{ + 2: {{"shape", "record"}, {"label", `"English|German"`}}, + 4: {{"shape", "record"}, {"label", `"English|German"`}}, + }, + map[edge]portedEdge{ + {from: 0, to: 1}: {fromCompass: "s"}, + {from: 0, to: 2}: {fromCompass: "s", toPort: "Zwei", toCompass: "e"}, + {from: 2, to: 3}: {fromPort: "Zwei", fromCompass: "e"}, + {from: 2, to: 4}: {fromPort: "Two", fromCompass: "w", toPort: "Four", toCompass: "w"}, + {from: 3, to: 4}: {toPort: "Four", toCompass: "w"}, + {from: 4, to: 0}: {fromPort: "Four", fromCompass: "_", toCompass: "s"}, + }, + ), + + want: `digraph { + // Node definitions. + 0; + 1; + 2 [ + shape=record + label="English|German" + ]; + 3; + 4 [ + shape=record + label="English|German" + ]; + + // Edge definitions. + 0:s -> 1; + 0:s -> 2:Zwei:e; + 1 -> 3; + 2:Zwei:e -> 3; + 2:Two:w -> 4:Four:w; + 3 -> 4:Four:w; + 4:Four:_ -> 0:s; +}`, + }, + { + g: undirectedPortedAttrGraphFrom(powerMethodGraph, + [][]encoding.Attribute{ + 2: {{"shape", "record"}, {"label", `"English|German"`}}, + 4: {{"shape", "record"}, {"label", `"English|German"`}}, + }, + map[edge]portedEdge{ + {from: 0, to: 1}: {fromCompass: "s"}, + {from: 0, to: 2}: {fromCompass: "s", toPort: "Zwei", toCompass: "e"}, + {from: 2, to: 3}: {fromPort: "Zwei", fromCompass: "e"}, + {from: 2, to: 4}: {fromPort: "Two", fromCompass: "w", toPort: "Four", toCompass: "w"}, + {from: 3, to: 4}: {toPort: "Four", toCompass: "w"}, + + // This definition is reversed (see comment above at portedEdge + // definition) so that 4 gets the from port. This is a result + // of the fact that we sort nodes by ID, so the lower node + // will be always be printed first when the graph is undirected, + // thus becoming the from port, but we define the edges here + // from a directed adjacency list. + {from: 4, to: 0}: {fromCompass: "s", toPort: "Four", toCompass: "_"}, + }, + ), + + want: `graph { + // Node definitions. + 0; + 1; + 2 [ + shape=record + label="English|German" + ]; + 3; + 4 [ + shape=record + label="English|German" + ]; + + // Edge definitions. + 0:s -- 1; + 0:s -- 2:Zwei:e; + 0:s -- 4:Four:_; + 1 -- 3; + 2:Zwei:e -- 3; + 2:Two:w -- 4:Four:w; + 3 -- 4:Four:w; +}`, + }, + + // Handling graph attributes. + { + g: graphAttributer{Graph: undirectedEdgeAttrGraphFrom(powerMethodGraph, map[edge][]encoding.Attribute{ + {from: 0, to: 2}: {{"label", `"???"`}, {"style", "dashed"}}, + {from: 2, to: 4}: {}, + {from: 3, to: 4}: {{"color", "red"}}, + })}, + + want: `graph { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2 [ + label="???" + style=dashed + ]; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4 [color=red]; +}`, + }, + { + g: graphAttributer{Graph: undirectedEdgeAttrGraphFrom(powerMethodGraph, map[edge][]encoding.Attribute{ + {from: 0, to: 2}: {{"label", `"???"`}, {"style", "dashed"}}, + {from: 2, to: 4}: {}, + {from: 3, to: 4}: {{"color", "red"}}, + }), + graph: []encoding.Attribute{{"rankdir", `"LR"`}}, + node: []encoding.Attribute{{"fontsize", "16"}, {"shape", "ellipse"}}, + }, + + want: `graph { + graph [ + rankdir="LR" + ]; + node [ + fontsize=16 + shape=ellipse + ]; + + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2 [ + label="???" + style=dashed + ]; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4 [color=red]; +}`, + }, + + // Handling structured graphs. + { + g: undirectedStructuredGraphFrom(nil, powerMethodGraph, pageRankGraph), + + want: `graph { + subgraph A { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; + } + subgraph B { + // Node definitions. + 5; + 6; + 7; + 8; + 9; + 10; + 11; + 12; + 13; + 14; + 15; + + // Edge definitions. + 5 -- 8; + 6 -- 7; + 6 -- 8; + 6 -- 9; + 6 -- 10; + 6 -- 11; + 6 -- 12; + 6 -- 13; + 8 -- 9; + 9 -- 10; + 9 -- 11; + 9 -- 12; + 9 -- 13; + 9 -- 14; + 9 -- 15; + } +}`, + }, + { + g: undirectedStructuredGraphFrom([]edge{{from: 0, to: 9}}, powerMethodGraph, pageRankGraph), + + want: `graph { + subgraph A { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; + } + subgraph B { + // Node definitions. + 5; + 6; + 7; + 8; + 9; + 10; + 11; + 12; + 13; + 14; + 15; + + // Edge definitions. + 5 -- 8; + 6 -- 7; + 6 -- 8; + 6 -- 9; + 6 -- 10; + 6 -- 11; + 6 -- 12; + 6 -- 13; + 8 -- 9; + 9 -- 10; + 9 -- 11; + 9 -- 12; + 9 -- 13; + 9 -- 14; + 9 -- 15; + } + // Node definitions. + 0; + 9; + + // Edge definitions. + 0 -- 9; +}`, + }, + + // Handling subgraphs. + { + g: undirectedSubGraphFrom(pageRankGraph, map[int64][]intset{2: powerMethodGraph}), + + want: `graph { + // Node definitions. + 5; + 6; + 8; + 9; + 10; + 11; + 12; + 13; + 14; + 15; + + // Edge definitions. + 5 -- 8; + 6 -- subgraph H { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; + }; + 6 -- 8; + 6 -- 9; + 6 -- 10; + 6 -- 11; + 6 -- 12; + 6 -- 13; + 8 -- 9; + 9 -- 10; + 9 -- 11; + 9 -- 12; + 9 -- 13; + 9 -- 14; + 9 -- 15; +}`, + }, + { + name: "H", + g: undirectedSubGraphFrom(pageRankGraph, map[int64][]intset{1: powerMethodGraph}), + strict: true, + + want: `strict graph H { + // Node definitions. + 5; + 7; + 8; + 9; + 10; + 11; + 12; + 13; + 14; + 15; + + // Edge definitions. + 5 -- 8; + subgraph G { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + + // Edge definitions. + 0 -- 1; + 0 -- 2; + 0 -- 4; + 1 -- 3; + 2 -- 3; + 2 -- 4; + 3 -- 4; + } -- 7; + subgraph G { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + } -- 8; + subgraph G { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + } -- 9; + subgraph G { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + } -- 10; + subgraph G { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + } -- 11; + subgraph G { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + } -- 12; + subgraph G { + // Node definitions. + 0; + 1; + 2; + 3; + 4; + } -- 13; + 8 -- 9; + 9 -- 10; + 9 -- 11; + 9 -- 12; + 9 -- 13; + 9 -- 14; + 9 -- 15; +}`, + }, +} + +func TestEncode(t *testing.T) { + for i, test := range encodeTests { + got, err := Marshal(test.g, test.name, test.prefix, "\t", test.strict) + if err != nil { + t.Errorf("unexpected error: %v", err) + continue + } + if string(got) != test.want { + t.Errorf("unexpected DOT result for test %d:\ngot: %s\nwant:%s", i, got, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/encoding.go b/vendor/gonum.org/v1/gonum/graph/encoding/encoding.go new file mode 100644 index 00000000..0f99ac73 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/encoding.go @@ -0,0 +1,30 @@ +// 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 +} + +// 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 +} diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/graphql/decode.go b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/decode.go new file mode 100644 index 00000000..8ad758c1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/decode.go @@ -0,0 +1,157 @@ +// 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 graphql + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/encoding" +) + +// Unmarshal parses the the JSON-encoded data and stores the result in dst. +// Node IDs are obtained from the JSON fields identified by the uid parameter. +// UIDs obtained from the JSON encoding must map to unique node ID values +// consistently across the JSON-encoded spanning tree. +func Unmarshal(data []byte, uid string, dst encoding.Builder) error { + if uid == "" { + return errors.New("graphql: invalid UID field name") + } + var src json.RawMessage + err := json.Unmarshal(data, &src) + if err != nil { + return err + } + gen := generator{dst: dst, uidName: uid, nodes: make(map[string]graph.Node)} + return gen.walk(src, nil, "") +} + +// StringIDSetter is a graph node that can set its ID based on the given uid string. +type StringIDSetter interface { + SetIDFromString(uid string) error +} + +// LabelSetter is a graph edge that can set its label. +type LabelSetter interface { + SetLabel(string) +} + +type generator struct { + dst encoding.Builder + + // uidName is the name of the UID field in the source JSON. + uidName string + // nodes maps from GraphQL UID string to graph.Node. + nodes map[string]graph.Node +} + +func (g *generator) walk(src json.RawMessage, node graph.Node, attr string) error { + switch src[0] { + case '{': + var val map[string]json.RawMessage + err := json.Unmarshal(src, &val) + if err != nil { + return err + } + if next, ok := val[g.uidName]; !ok { + if node != nil { + var buf bytes.Buffer + err := json.Compact(&buf, src) + if err != nil { + panic(err) + } + return fmt.Errorf("graphql: no UID for node: `%s`", &buf) + } + } else { + var v interface{} + err = json.Unmarshal(next, &v) + if err != nil { + return err + } + value := fmt.Sprint(v) + child, ok := g.nodes[value] + if !ok { + child = g.dst.NewNode() + s, ok := child.(StringIDSetter) + if !ok { + return errors.New("graphql: cannot set UID") + } + err = s.SetIDFromString(value) + if err != nil { + return err + } + g.nodes[value] = child + g.dst.AddNode(child) + } + if node != nil { + e := g.dst.NewEdge(node, child) + if s, ok := e.(LabelSetter); ok { + s.SetLabel(attr) + } + g.dst.SetEdge(e) + } + node = child + } + for attr, src := range val { + if attr == g.uidName { + continue + } + err = g.walk(src, node, attr) + if err != nil { + return err + } + } + + case '[': + var val []json.RawMessage + err := json.Unmarshal(src, &val) + if err != nil { + return err + } + for _, src := range val { + err = g.walk(src, node, attr) + if err != nil { + return err + } + } + + default: + var v interface{} + err := json.Unmarshal(src, &v) + if err != nil { + return err + } + if attr == g.uidName { + value := fmt.Sprint(v) + if s, ok := node.(StringIDSetter); ok { + if _, ok := g.nodes[value]; !ok { + err = s.SetIDFromString(value) + if err != nil { + return err + } + g.nodes[value] = node + } + } else { + return errors.New("graphql: cannot set ID") + } + } else if s, ok := node.(encoding.AttributeSetter); ok { + var value string + if _, ok := v.(float64); ok { + value = string(src) + } else { + value = fmt.Sprint(v) + } + err = s.SetAttribute(encoding.Attribute{Key: attr, Value: value}) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/graphql/decode_test.go b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/decode_test.go new file mode 100644 index 00000000..4bcc7925 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/decode_test.go @@ -0,0 +1,221 @@ +// 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 graphql + +import ( + "errors" + "fmt" + "sort" + "strconv" + "strings" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/encoding" + "gonum.org/v1/gonum/graph/encoding/dot" + "gonum.org/v1/gonum/graph/simple" +) + +var decodeTests = []struct { + name string + json string + roots map[uint64]bool + wantDOT string + wantErr error +}{ + { + name: "starwars", + json: starwars, + roots: map[uint64]bool{ + 0xa3cff1a4c3ef3bb6: true, + 0xb39aa14d66aedad5: true, + }, + wantDOT: `digraph { + // Node definitions. + 0x8a10d5a2611fd03f [name="Richard Marquand"]; + 0xa3cff1a4c3ef3bb6 [ + name="Star Wars: Episode V - The Empire Strikes Back" + release_date=1980-05-21T00:00:00Z + revenue=534000000 + running_time=124 + ]; + 0xb39aa14d66aedad5 [ + name="Star Wars: Episode VI - Return of the Jedi" + release_date=1983-05-25T00:00:00Z + revenue=572000000 + running_time=131 + ]; + 0x0312de17a7ee89f9 [name="Luke Skywalker"]; + 0x3da8d1dcab1bb381 [name="Han Solo"]; + 0x4a7d0b5fe91e78a4 [name="Irvin Kernshner"]; + 0x718337b9dcbaa7d9 [name="Princess Leia"]; + + // Edge definitions. + 0xa3cff1a4c3ef3bb6 -> 0x0312de17a7ee89f9 [label=starring]; + 0xa3cff1a4c3ef3bb6 -> 0x3da8d1dcab1bb381 [label=starring]; + 0xa3cff1a4c3ef3bb6 -> 0x4a7d0b5fe91e78a4 [label=director]; + 0xa3cff1a4c3ef3bb6 -> 0x718337b9dcbaa7d9 [label=starring]; + 0xb39aa14d66aedad5 -> 0x8a10d5a2611fd03f [label=director]; + 0xb39aa14d66aedad5 -> 0x0312de17a7ee89f9 [label=starring]; + 0xb39aa14d66aedad5 -> 0x3da8d1dcab1bb381 [label=starring]; + 0xb39aa14d66aedad5 -> 0x718337b9dcbaa7d9 [label=starring]; +}`, + }, + { + name: "tutorial", + json: dgraphTutorial, + roots: map[uint64]bool{ + 0xfd90205a458151f: true, + 0x52a80955d40ec819: true, + }, + wantDOT: `digraph { + // Node definitions. + 0x892a6da7ee1fbdec [ + age=55 + name=Sarah + ]; + 0x99b74c1b5ab100ec [ + age=35 + name=Artyom + ]; + 0xb9e12a67e34d6acc [ + age=19 + name=Catalina + ]; + 0xbf104824c777525d [name=Perro]; + 0xf590a923ea1fccaa [name=Goldie]; + 0xf92d7dbe272d680b [name="Hyung Sin"]; + 0x0fd90205a458151f [ + age=39 + name=Michael + ]; + 0x37734fcf0a6fcc69 [name="Rammy the sheep"]; + 0x52a80955d40ec819 [ + age=35 + name=Amit + ]; + 0x5e9ad1cd9466228c [ + age=24 + name="Sang Hyun" + ]; + + // Edge definitions. + 0xb9e12a67e34d6acc -> 0xbf104824c777525d [label=owns_pet]; + 0xb9e12a67e34d6acc -> 0x5e9ad1cd9466228c [label=friend]; + 0xf92d7dbe272d680b -> 0x5e9ad1cd9466228c [label=friend]; + 0x0fd90205a458151f -> 0x892a6da7ee1fbdec [label=friend]; + 0x0fd90205a458151f -> 0x99b74c1b5ab100ec [label=friend]; + 0x0fd90205a458151f -> 0xb9e12a67e34d6acc [label=friend]; + 0x0fd90205a458151f -> 0x37734fcf0a6fcc69 [label=owns_pet]; + 0x0fd90205a458151f -> 0x52a80955d40ec819 [label=friend]; + 0x0fd90205a458151f -> 0x5e9ad1cd9466228c [label=friend]; + 0x52a80955d40ec819 -> 0x99b74c1b5ab100ec [label=friend]; + 0x52a80955d40ec819 -> 0x0fd90205a458151f [label=friend]; + 0x52a80955d40ec819 -> 0x5e9ad1cd9466228c [label=friend]; + 0x5e9ad1cd9466228c -> 0xb9e12a67e34d6acc [label=friend]; + 0x5e9ad1cd9466228c -> 0xf590a923ea1fccaa [label=owns_pet]; + 0x5e9ad1cd9466228c -> 0xf92d7dbe272d680b [label=friend]; + 0x5e9ad1cd9466228c -> 0x52a80955d40ec819 [label=friend]; +}`, + }, + { + name: "tutorial missing IDs", + json: dgraphTutorialMissingIDs, + wantErr: errors.New("graphql: no UID for node"), // Incomplete error string. + }, +} + +func TestDecode(t *testing.T) { + for _, test := range decodeTests { + dst := newDirectedGraph() + err := Unmarshal([]byte(test.json), "_uid_", dst) + if test.wantErr == nil && err != nil { + t.Errorf("failed to unmarshal GraphQL JSON graph for %q: %v", test.name, err) + } else if test.wantErr != nil { + if err == nil { + t.Errorf("expected error for %q: got:%v want:%v", test.name, err, test.wantErr) + } + continue + } + b, err := dot.Marshal(dst, "", "", " ", false) + if err != nil { + t.Fatalf("failed to DOT marshal graph %q: %v", test.name, err) + } + gotDOT := string(b) + if gotDOT != test.wantDOT { + t.Errorf("unexpected DOT encoding for %q:\ngot:\n%s\nwant:\n%s", test.name, gotDOT, test.wantDOT) + } + } +} + +type directedGraph struct { + *simple.DirectedGraph +} + +func newDirectedGraph() *directedGraph { + return &directedGraph{DirectedGraph: simple.NewDirectedGraph()} +} + +func (g *directedGraph) NewNode() graph.Node { + return &node{attributes: make(attributes)} +} + +func (g *directedGraph) NewEdge(from, to graph.Node) graph.Edge { + return &edge{Edge: g.DirectedGraph.NewEdge(from, to)} +} + +type node struct { + id uint64 + attributes +} + +func (n *node) ID() int64 { return int64(n.id) } +func (n *node) DOTID() string { return fmt.Sprintf("0x%016x", uint64(n.id)) } + +func (n *node) SetIDFromString(uid string) error { + if !strings.HasPrefix(uid, "0x") { + return fmt.Errorf("uid is not hex value: %q", uid) + } + var err error + n.id, err = strconv.ParseUint(uid[2:], 16, 64) + return err +} + +type edge struct { + graph.Edge + label string +} + +func (e *edge) SetLabel(l string) { + e.label = l +} + +func (e *edge) Attributes() []encoding.Attribute { + return []encoding.Attribute{{"label", e.label}} +} + +type attributes map[string]encoding.Attribute + +func (a attributes) SetAttribute(attr encoding.Attribute) error { + a[attr.Key] = attr + return nil +} + +func (a attributes) Attributes() []encoding.Attribute { + keys := make([]string, 0, len(a)) + for k := range a { + keys = append(keys, k) + } + sort.Strings(keys) + attr := make([]encoding.Attribute, 0, len(keys)) + for _, k := range keys { + v := a[k] + if strings.Contains(v.Value, " ") { + v.Value = `"` + v.Value + `"` + } + attr = append(attr, v) + } + return attr +} diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/graphql/doc.go b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/doc.go new file mode 100644 index 00000000..dd405034 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/doc.go @@ -0,0 +1,7 @@ +// 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 graphql implements JSON marshaling and unmarshaling of graph as +// used by GraphQL +package graphql // import "gonum.org/v1/gonum/graph/encoding/graphql" diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/graphql/graphql.go b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/graphql.go new file mode 100644 index 00000000..7598cb1a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/graphql.go @@ -0,0 +1,5 @@ +// 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 graphql diff --git a/vendor/gonum.org/v1/gonum/graph/encoding/graphql/graphs_test.go b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/graphs_test.go new file mode 100644 index 00000000..0e90348f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/encoding/graphql/graphs_test.go @@ -0,0 +1,1013 @@ +// 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 graphql + +const ( + starwars = `{ + "movie": [ + { + "_uid_": "0xa3cff1a4c3ef3bb6", + "director": [ + { + "_uid_": "0x4a7d0b5fe91e78a4", + "name": "Irvin Kernshner" + } + ], + "name": "Star Wars: Episode V - The Empire Strikes Back", + "release_date": "1980-05-21T00:00:00Z", + "revenue": 534000000, + "running_time": 124, + "starring": [ + { + "_uid_": "0x312de17a7ee89f9", + "name": "Luke Skywalker" + }, + { + "_uid_": "0x3da8d1dcab1bb381", + "name": "Han Solo" + }, + { + "_uid_": "0x718337b9dcbaa7d9", + "name": "Princess Leia" + } + ] + }, + { + "_uid_": "0xb39aa14d66aedad5", + "director": [ + { + "_uid_": "0x8a10d5a2611fd03f", + "name": "Richard Marquand" + } + ], + "name": "Star Wars: Episode VI - Return of the Jedi", + "release_date": "1983-05-25T00:00:00Z", + "revenue": 572000000, + "running_time": 131, + "starring": [ + { + "_uid_": "0x312de17a7ee89f9", + "name": "Luke Skywalker" + }, + { + "_uid_": "0x3da8d1dcab1bb381", + "name": "Han Solo" + }, + { + "_uid_": "0x718337b9dcbaa7d9", + "name": "Princess Leia" + } + ] + } + ] +} +` + + dgraphTutorialMissingIDs = `{ + "everyone": [ + { + "_uid_": "0xfd90205a458151f", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "friend": [ + { + "_uid_": "0xfd90205a458151f", + "age": 39, + "friend": [ + { + "age": 35, + "name": "Amit" + }, + { + "age": 24, + "name": "Sang Hyun" + }, + { + "age": 55, + "name": "Sarah" + }, + { + "age": 35, + "name": "Artyom" + }, + { + "age": 19, + "name": "Catalina" + } + ], + "name": "Michael", + "owns_pet": [ + { + "name": "Rammy the sheep" + } + ] + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "age": 35, + "name": "Amit" + }, + { + "age": 19, + "name": "Catalina" + }, + { + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "name": "Goldie" + } + ] + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "age": 39, + "name": "Michael" + }, + { + "age": 24, + "name": "Sang Hyun" + }, + { + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "age": 24, + "name": "Sang Hyun" + } + ], + "name": "Catalina", + "owns_pet": [ + { + "name": "Perro" + } + ] + }, + { + "_uid_": "0xf92d7dbe272d680b", + "friend": [ + { + "age": 24, + "name": "Sang Hyun" + } + ], + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun" + }, + { + "_uid_": "0x892a6da7ee1fbdec", + "name": "Sarah" + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "name": "Artyom" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "age": 35, + "name": "Amit" + }, + { + "age": 19, + "name": "Catalina" + }, + { + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "name": "Goldie" + } + ] + } + ], + "name": "Catalina" + } + ], + "name": "Michael" + }, + { + "_uid_": "0x52a80955d40ec819", + "friend": [ + { + "_uid_": "0xfd90205a458151f", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "age": 39, + "name": "Michael" + }, + { + "age": 24, + "name": "Sang Hyun" + }, + { + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "age": 35, + "name": "Amit" + }, + { + "age": 19, + "name": "Catalina" + }, + { + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "name": "Goldie" + } + ] + }, + { + "_uid_": "0x892a6da7ee1fbdec", + "age": 55, + "name": "Sarah" + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "age": 24, + "name": "Sang Hyun" + } + ], + "name": "Catalina", + "owns_pet": [ + { + "name": "Perro" + } + ] + } + ], + "name": "Michael" + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "age": 39, + "name": "Michael" + }, + { + "age": 24, + "name": "Sang Hyun" + }, + { + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "age": 24, + "name": "Sang Hyun" + } + ], + "name": "Catalina", + "owns_pet": [ + { + "name": "Perro" + } + ] + }, + { + "_uid_": "0xf92d7dbe272d680b", + "friend": [ + { + "age": 24, + "name": "Sang Hyun" + } + ], + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun" + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "name": "Artyom" + } + ], + "name": "Amit" + } + ] +} +` + + dgraphTutorial = `{ + "everyone": [ + { + "_uid_": "0xfd90205a458151f", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "friend": [ + { + "_uid_": "0xfd90205a458151f", + "age": 39, + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "_uid_": "0xfd90205a458151f" + }, + { + "_uid_": "0x5e9ad1cd9466228c" + }, + { + "_uid_": "0x99b74c1b5ab100ec" + } + ], + "name": "Amit" + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + }, + { + "_uid_": "0x892a6da7ee1fbdec", + "age": 55, + "name": "Sarah" + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c" + } + ], + "name": "Catalina", + "owns_pet": [ + { + "_uid_": "0xbf104824c777525d" + } + ] + } + ], + "name": "Michael", + "owns_pet": [ + { + "_uid_": "0x37734fcf0a6fcc69", + "name": "Rammy the sheep" + } + ] + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "_uid_": "0xfd90205a458151f" + }, + { + "_uid_": "0x5e9ad1cd9466228c" + }, + { + "_uid_": "0x99b74c1b5ab100ec" + } + ], + "name": "Amit" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c" + } + ], + "name": "Catalina", + "owns_pet": [ + { + "_uid_": "0xbf104824c777525d" + } + ] + }, + { + "_uid_": "0xf92d7dbe272d680b", + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c" + } + ], + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa", + "name": "Goldie" + } + ] + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "_uid_": "0xfd90205a458151f", + "age": 39, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0x5e9ad1cd9466228c" + }, + { + "_uid_": "0x892a6da7ee1fbdec" + }, + { + "_uid_": "0x99b74c1b5ab100ec" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + } + ], + "name": "Michael", + "owns_pet": [ + { + "_uid_": "0x37734fcf0a6fcc69" + } + ] + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + } + ], + "name": "Catalina", + "owns_pet": [ + { + "_uid_": "0xbf104824c777525d", + "name": "Perro" + } + ] + }, + { + "_uid_": "0xf92d7dbe272d680b", + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + } + ], + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun" + }, + { + "_uid_": "0x892a6da7ee1fbdec", + "name": "Sarah" + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "name": "Artyom" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "_uid_": "0xfd90205a458151f" + }, + { + "_uid_": "0x5e9ad1cd9466228c" + }, + { + "_uid_": "0x99b74c1b5ab100ec" + } + ], + "name": "Amit" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c" + } + ], + "name": "Catalina", + "owns_pet": [ + { + "_uid_": "0xbf104824c777525d" + } + ] + }, + { + "_uid_": "0xf92d7dbe272d680b", + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c" + } + ], + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa", + "name": "Goldie" + } + ] + } + ], + "name": "Catalina" + } + ], + "name": "Michael" + }, + { + "_uid_": "0x52a80955d40ec819", + "friend": [ + { + "_uid_": "0xfd90205a458151f", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "_uid_": "0xfd90205a458151f", + "age": 39, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0x5e9ad1cd9466228c" + }, + { + "_uid_": "0x892a6da7ee1fbdec" + }, + { + "_uid_": "0x99b74c1b5ab100ec" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + } + ], + "name": "Michael", + "owns_pet": [ + { + "_uid_": "0x37734fcf0a6fcc69" + } + ] + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "_uid_": "0xfd90205a458151f" + }, + { + "_uid_": "0x5e9ad1cd9466228c" + }, + { + "_uid_": "0x99b74c1b5ab100ec" + } + ], + "name": "Amit" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c" + } + ], + "name": "Catalina", + "owns_pet": [ + { + "_uid_": "0xbf104824c777525d" + } + ] + }, + { + "_uid_": "0xf92d7dbe272d680b", + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c" + } + ], + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa", + "name": "Goldie" + } + ] + }, + { + "_uid_": "0x892a6da7ee1fbdec", + "age": 55, + "name": "Sarah" + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + } + ], + "name": "Catalina", + "owns_pet": [ + { + "_uid_": "0xbf104824c777525d", + "name": "Perro" + } + ] + } + ], + "name": "Michael" + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "friend": [ + { + "_uid_": "0x52a80955d40ec819", + "age": 35, + "friend": [ + { + "_uid_": "0xfd90205a458151f", + "age": 39, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0x5e9ad1cd9466228c" + }, + { + "_uid_": "0x892a6da7ee1fbdec" + }, + { + "_uid_": "0x99b74c1b5ab100ec" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + } + ], + "name": "Michael", + "owns_pet": [ + { + "_uid_": "0x37734fcf0a6fcc69" + } + ] + }, + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "age": 35, + "name": "Artyom" + } + ], + "name": "Amit" + }, + { + "_uid_": "0xb9e12a67e34d6acc", + "age": 19, + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + } + ], + "name": "Catalina", + "owns_pet": [ + { + "_uid_": "0xbf104824c777525d", + "name": "Perro" + } + ] + }, + { + "_uid_": "0xf92d7dbe272d680b", + "friend": [ + { + "_uid_": "0x5e9ad1cd9466228c", + "age": 24, + "friend": [ + { + "_uid_": "0x52a80955d40ec819" + }, + { + "_uid_": "0xb9e12a67e34d6acc" + }, + { + "_uid_": "0xf92d7dbe272d680b" + } + ], + "name": "Sang Hyun", + "owns_pet": [ + { + "_uid_": "0xf590a923ea1fccaa" + } + ] + } + ], + "name": "Hyung Sin" + } + ], + "name": "Sang Hyun" + }, + { + "_uid_": "0x99b74c1b5ab100ec", + "name": "Artyom" + } + ], + "name": "Amit" + } + ] +} +` +) diff --git a/vendor/gonum.org/v1/gonum/graph/ex/fdpclust/gn.go b/vendor/gonum.org/v1/gonum/graph/ex/fdpclust/gn.go new file mode 100644 index 00000000..bcb1aad1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/ex/fdpclust/gn.go @@ -0,0 +1,278 @@ +package main + +import ( + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +type GraphNode struct { + id int64 + neighbors []graph.Node + roots []*GraphNode +} + +func (g *GraphNode) Has(n graph.Node) bool { + if n.ID() == g.id { + return true + } + + visited := map[int64]struct{}{g.id: {}} + for _, root := range g.roots { + if root.ID() == n.ID() { + return true + } + + if root.has(n, visited) { + return true + } + } + + for _, neigh := range g.neighbors { + if neigh.ID() == n.ID() { + return true + } + + if gn, ok := neigh.(*GraphNode); ok { + if gn.has(n, visited) { + return true + } + } + } + + return false +} + +func (g *GraphNode) has(n graph.Node, visited map[int64]struct{}) bool { + for _, root := range g.roots { + if _, ok := visited[root.ID()]; ok { + continue + } + + visited[root.ID()] = struct{}{} + if root.ID() == n.ID() { + return true + } + + if root.has(n, visited) { + return true + } + + } + + for _, neigh := range g.neighbors { + if _, ok := visited[neigh.ID()]; ok { + continue + } + + visited[neigh.ID()] = struct{}{} + if neigh.ID() == n.ID() { + return true + } + + if gn, ok := neigh.(*GraphNode); ok { + if gn.has(n, visited) { + return true + } + } + + } + + return false +} + +func (g *GraphNode) Nodes() []graph.Node { + toReturn := []graph.Node{g} + visited := map[int64]struct{}{g.id: {}} + + for _, root := range g.roots { + toReturn = append(toReturn, root) + visited[root.ID()] = struct{}{} + + toReturn = root.nodes(toReturn, visited) + } + + for _, neigh := range g.neighbors { + toReturn = append(toReturn, neigh) + visited[neigh.ID()] = struct{}{} + + if gn, ok := neigh.(*GraphNode); ok { + toReturn = gn.nodes(toReturn, visited) + } + } + + return toReturn +} + +func (g *GraphNode) nodes(list []graph.Node, visited map[int64]struct{}) []graph.Node { + for _, root := range g.roots { + if _, ok := visited[root.ID()]; ok { + continue + } + visited[root.ID()] = struct{}{} + list = append(list, graph.Node(root)) + + list = root.nodes(list, visited) + } + + for _, neigh := range g.neighbors { + if _, ok := visited[neigh.ID()]; ok { + continue + } + + list = append(list, neigh) + if gn, ok := neigh.(*GraphNode); ok { + list = gn.nodes(list, visited) + } + } + + return list +} + +func (g *GraphNode) From(n graph.Node) []graph.Node { + if n.ID() == g.ID() { + return g.neighbors + } + + visited := map[int64]struct{}{g.id: {}} + for _, root := range g.roots { + visited[root.ID()] = struct{}{} + + if result := root.findNeighbors(n, visited); result != nil { + return result + } + } + + for _, neigh := range g.neighbors { + visited[neigh.ID()] = struct{}{} + + if gn, ok := neigh.(*GraphNode); ok { + if result := gn.findNeighbors(n, visited); result != nil { + return result + } + } + } + + return nil +} + +func (g *GraphNode) findNeighbors(n graph.Node, visited map[int64]struct{}) []graph.Node { + if n.ID() == g.ID() { + return g.neighbors + } + + for _, root := range g.roots { + if _, ok := visited[root.ID()]; ok { + continue + } + visited[root.ID()] = struct{}{} + + if result := root.findNeighbors(n, visited); result != nil { + return result + } + } + + for _, neigh := range g.neighbors { + if _, ok := visited[neigh.ID()]; ok { + continue + } + visited[neigh.ID()] = struct{}{} + + if gn, ok := neigh.(*GraphNode); ok { + if result := gn.findNeighbors(n, visited); result != nil { + return result + } + } + } + + return nil +} + +func (g *GraphNode) HasEdgeBetween(u, v graph.Node) bool { + return g.EdgeBetween(u, v) != nil +} + +func (g *GraphNode) Edge(u, v graph.Node) graph.Edge { + return g.EdgeBetween(u, v) +} + +func (g *GraphNode) EdgeBetween(u, v graph.Node) graph.Edge { + if u.ID() == g.id || v.ID() == g.id { + for _, neigh := range g.neighbors { + if neigh.ID() == u.ID() || neigh.ID() == v.ID() { + return simple.Edge{F: g, T: neigh} + } + } + return nil + } + + visited := map[int64]struct{}{g.id: {}} + for _, root := range g.roots { + visited[root.ID()] = struct{}{} + if result := root.edgeBetween(u, v, visited); result != nil { + return result + } + } + + for _, neigh := range g.neighbors { + visited[neigh.ID()] = struct{}{} + if gn, ok := neigh.(*GraphNode); ok { + if result := gn.edgeBetween(u, v, visited); result != nil { + return result + } + } + } + + return nil +} + +func (g *GraphNode) edgeBetween(u, v graph.Node, visited map[int64]struct{}) graph.Edge { + if u.ID() == g.id || v.ID() == g.id { + for _, neigh := range g.neighbors { + if neigh.ID() == u.ID() || neigh.ID() == v.ID() { + return simple.Edge{F: g, T: neigh} + } + } + return nil + } + + for _, root := range g.roots { + if _, ok := visited[root.ID()]; ok { + continue + } + visited[root.ID()] = struct{}{} + if result := root.edgeBetween(u, v, visited); result != nil { + return result + } + } + + for _, neigh := range g.neighbors { + if _, ok := visited[neigh.ID()]; ok { + continue + } + + visited[neigh.ID()] = struct{}{} + if gn, ok := neigh.(*GraphNode); ok { + if result := gn.edgeBetween(u, v, visited); result != nil { + return result + } + } + } + + return nil +} + +func (g *GraphNode) ID() int64 { + return g.id +} + +func (g *GraphNode) AddNeighbor(n *GraphNode) { + g.neighbors = append(g.neighbors, graph.Node(n)) +} + +func (g *GraphNode) AddRoot(n *GraphNode) { + g.roots = append(g.roots, n) +} + +func NewGraphNode(id int64) *GraphNode { + return &GraphNode{id: id} +} diff --git a/vendor/gonum.org/v1/gonum/graph/ex/fdpclust/main.go b/vendor/gonum.org/v1/gonum/graph/ex/fdpclust/main.go new file mode 100644 index 00000000..eb14226a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/ex/fdpclust/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "fmt" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/topo" +) + +func main() { + // graph G { + G := NewGraphNode(0) + // e + e := NewGraphNode(1) + + // subgraph clusterA { + clusterA := NewGraphNode(2) + + // a -- b + a := NewGraphNode(3) + b := NewGraphNode(4) + a.AddNeighbor(b) + b.AddNeighbor(a) + clusterA.AddRoot(a) + clusterA.AddRoot(b) + + // subgraph clusterC { + clusterC := NewGraphNode(5) + // C -- D + C := NewGraphNode(6) + D := NewGraphNode(7) + C.AddNeighbor(D) + D.AddNeighbor(C) + + clusterC.AddRoot(C) + clusterC.AddRoot(D) + // } + clusterA.AddRoot(clusterC) + // } + + // subgraph clusterB { + clusterB := NewGraphNode(8) + + // d -- f + d := NewGraphNode(9) + f := NewGraphNode(10) + d.AddNeighbor(f) + f.AddNeighbor(d) + clusterB.AddRoot(d) + clusterB.AddRoot(f) + // } + + // d -- D + d.AddNeighbor(D) + D.AddNeighbor(d) + + // e -- clusterB + e.AddNeighbor(clusterB) + clusterB.AddNeighbor(e) + + // clusterC -- clusterB + clusterC.AddNeighbor(clusterB) + clusterB.AddNeighbor(clusterC) + + G.AddRoot(e) + G.AddRoot(clusterA) + G.AddRoot(clusterB) + // } + + if !topo.IsPathIn(G, []graph.Node{C, D, d, f}) { + fmt.Println("Not working!") + } else { + fmt.Println("Working!") + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/README.md b/vendor/gonum.org/v1/gonum/graph/formats/dot/README.md new file mode 100644 index 00000000..a26ca902 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/README.md @@ -0,0 +1,9 @@ +# 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. diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast.go new file mode 100644 index 00000000..8bb961ce --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast.go @@ -0,0 +1,406 @@ +// 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 != CompassPointDefault { + fmt.Fprintf(buf, ":%s", p.CompassPoint) + } + return buf.String() +} + +// CompassPoint specifies the set of compass points. +type CompassPoint uint + +// Compass points. +const ( + CompassPointDefault CompassPoint = iota // _ + CompassPointNorth // n + CompassPointNorthEast // ne + CompassPointEast // e + CompassPointSouthEast // se + CompassPointSouth // s + CompassPointSouthWest // sw + CompassPointWest // w + CompassPointNorthWest // nw + CompassPointCenter // c +) + +// String returns the string representation of the compass point. +func (c CompassPoint) String() string { + switch c { + case CompassPointDefault: + 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" + } + 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() {} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast_test.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast_test.go new file mode 100644 index 00000000..2417dce5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast_test.go @@ -0,0 +1,101 @@ +// 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_test + +import ( + "bytes" + "io/ioutil" + "testing" + + "gonum.org/v1/gonum/graph/formats/dot" + "gonum.org/v1/gonum/graph/formats/dot/ast" +) + +func TestParseFile(t *testing.T) { + golden := []struct { + in string + out string + }{ + {in: "../internal/testdata/empty.dot"}, + {in: "../internal/testdata/graph.dot"}, + {in: "../internal/testdata/digraph.dot"}, + {in: "../internal/testdata/strict.dot"}, + {in: "../internal/testdata/multi.dot"}, + {in: "../internal/testdata/named_graph.dot"}, + {in: "../internal/testdata/node_stmt.dot"}, + {in: "../internal/testdata/edge_stmt.dot"}, + {in: "../internal/testdata/attr_stmt.dot"}, + {in: "../internal/testdata/attr.dot"}, + { + in: "../internal/testdata/subgraph.dot", + out: "../internal/testdata/subgraph.golden", + }, + { + in: "../internal/testdata/semi.dot", + out: "../internal/testdata/semi.golden", + }, + { + in: "../internal/testdata/empty_attr.dot", + out: "../internal/testdata/empty_attr.golden", + }, + { + in: "../internal/testdata/attr_lists.dot", + out: "../internal/testdata/attr_lists.golden", + }, + { + in: "../internal/testdata/attr_sep.dot", + out: "../internal/testdata/attr_sep.golden", + }, + {in: "../internal/testdata/subgraph_vertex.dot"}, + { + in: "../internal/testdata/port.dot", + out: "../internal/testdata/port.golden", + }, + } + for _, g := range golden { + file, err := dot.ParseFile(g.in) + if err != nil { + t.Errorf("%q: unable to parse file; %v", g.in, err) + continue + } + // If no output path is specified, the input is already golden. + out := g.in + if len(g.out) > 0 { + out = g.out + } + buf, err := ioutil.ReadFile(out) + if err != nil { + t.Errorf("%q: unable to read file; %v", g.in, err) + continue + } + got := file.String() + // Remove trailing newline. + want := string(bytes.TrimSpace(buf)) + if got != want { + t.Errorf("%q: graph mismatch; expected %q, got %q", g.in, want, got) + } + } +} + +// Verify that all statements implement the Stmt interface. +var ( + _ ast.Stmt = (*ast.NodeStmt)(nil) + _ ast.Stmt = (*ast.EdgeStmt)(nil) + _ ast.Stmt = (*ast.AttrStmt)(nil) + _ ast.Stmt = (*ast.Attr)(nil) + _ ast.Stmt = (*ast.Subgraph)(nil) +) + +// Verify that all vertices implement the Vertex interface. +var ( + _ ast.Vertex = (*ast.Node)(nil) + _ ast.Vertex = (*ast.Subgraph)(nil) +) diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/doc.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/doc.go new file mode 100644 index 00000000..2d96617c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/ast/doc.go @@ -0,0 +1,7 @@ +// 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" diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/doc.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/doc.go new file mode 100644 index 00000000..4337ff08 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package dot implements a parser for Graphviz DOT files. +package dot // import "gonum.org/v1/gonum/graph/formats/dot" diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/dot.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/dot.go new file mode 100644 index 00000000..edc44f68 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/dot.go @@ -0,0 +1,64 @@ +// 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)) +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/Makefile b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/Makefile new file mode 100644 index 00000000..ba04504a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/Makefile @@ -0,0 +1,33 @@ +gen: dot.bnf + gocc $< + ./paste_copyright.bash + +debug_lexer: dot.bnf + gocc -debug_lexer -v -a $< + ./paste_copyright.bash + +debug_parser: dot.bnf + gocc -debug_parser -v -a $< + ./paste_copyright.bash + +clean: + rm -f errors/errors.go + rm -f lexer/acttab.go + rm -f lexer/lexer.go + rm -f lexer/transitiontable.go + rm -f parser/action.go + rm -f parser/actiontable.go + rm -f parser/gototable.go + rm -f parser/parser.go + rm -f parser/productionstable.go + rm -f token/token.go + rm -f util/litconv.go + rm -f util/rune.go + -rmdir --ignore-fail-on-non-empty errors + -rmdir --ignore-fail-on-non-empty lexer + -rmdir --ignore-fail-on-non-empty parser + -rmdir --ignore-fail-on-non-empty token + -rmdir --ignore-fail-on-non-empty util + rm -f terminals.txt LR1_conflicts.txt LR1_sets.txt first.txt lexer_sets.txt + +.PHONY: gen debug_lexer debug_parser clean diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx.go new file mode 100644 index 00000000..1b3bff55 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx.go @@ -0,0 +1,326 @@ +// 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.CompassPointDefault, 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 +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx_test.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx_test.go new file mode 100644 index 00000000..4ec55000 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx_test.go @@ -0,0 +1,90 @@ +// 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_test + +import ( + "bytes" + "io/ioutil" + "testing" + + "gonum.org/v1/gonum/graph/formats/dot" +) + +func TestParseFile(t *testing.T) { + golden := []struct { + in string + out string + }{ + {in: "../testdata/empty.dot"}, + {in: "../testdata/graph.dot"}, + {in: "../testdata/digraph.dot"}, + {in: "../testdata/strict.dot"}, + {in: "../testdata/multi.dot"}, + {in: "../testdata/named_graph.dot"}, + {in: "../testdata/node_stmt.dot"}, + {in: "../testdata/edge_stmt.dot"}, + {in: "../testdata/attr_stmt.dot"}, + {in: "../testdata/attr.dot"}, + { + in: "../testdata/subgraph.dot", + out: "../testdata/subgraph.golden", + }, + { + in: "../testdata/semi.dot", + out: "../testdata/semi.golden", + }, + { + in: "../testdata/empty_attr.dot", + out: "../testdata/empty_attr.golden", + }, + { + in: "../testdata/attr_lists.dot", + out: "../testdata/attr_lists.golden", + }, + { + in: "../testdata/attr_sep.dot", + out: "../testdata/attr_sep.golden", + }, + {in: "../testdata/subgraph_vertex.dot"}, + { + in: "../testdata/port.dot", + out: "../testdata/port.golden", + }, + {in: "../testdata/quoted_id.dot"}, + { + in: "../testdata/backslash_newline_id.dot", + out: "../testdata/backslash_newline_id.golden", + }, + } + for _, g := range golden { + file, err := dot.ParseFile(g.in) + if err != nil { + t.Errorf("%q: unable to parse file; %v", g.in, err) + continue + } + // If no output path is specified, the input is already golden. + out := g.in + if len(g.out) > 0 { + out = g.out + } + buf, err := ioutil.ReadFile(out) + if err != nil { + t.Errorf("%q: unable to read file; %v", g.in, err) + continue + } + got := file.String() + // Remove trailing newline. + want := string(bytes.TrimSpace(buf)) + if got != want { + t.Errorf("%q: graph mismatch; expected `%s`, got `%s`", g.in, want, got) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/doc.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/doc.go new file mode 100644 index 00000000..65fd9011 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/doc.go @@ -0,0 +1,7 @@ +// 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" diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/dot.bnf b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/dot.bnf new file mode 100644 index 00000000..b2eafb3a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/dot.bnf @@ -0,0 +1,358 @@ +// The DOT Language +// +// http://www.graphviz.org/doc/info/lang.html + +// ### [ Tokens ] ############################################################## + +// The keywords node, edge, graph, digraph, subgraph, and strict are case- +// independent. + +node + : 'n' 'o' 'd' 'e' + | 'N' 'o' 'd' 'e' + | 'N' 'O' 'D' 'E' +; + +edge + : 'e' 'd' 'g' 'e' + | 'E' 'd' 'g' 'e' + | 'E' 'D' 'G' 'E' +; + +// TODO: Rename graphx to graph once gocc#20 is fixed [1]. +// +// [1]: https://github.com/goccmack/gocc/issues/20 + +graphx + : 'g' 'r' 'a' 'p' 'h' + | 'G' 'r' 'a' 'p' 'h' + | 'G' 'R' 'A' 'P' 'H' +; + +digraph + : 'd' 'i' 'g' 'r' 'a' 'p' 'h' + | 'D' 'i' 'g' 'r' 'a' 'p' 'h' + | 'd' 'i' 'G' 'r' 'a' 'p' 'h' + | 'D' 'i' 'G' 'r' 'a' 'p' 'h' + | 'D' 'I' 'G' 'R' 'A' 'P' 'H' +; + +subgraph + : 's' 'u' 'b' 'g' 'r' 'a' 'p' 'h' + | 'S' 'u' 'b' 'g' 'r' 'a' 'p' 'h' + | 's' 'u' 'b' 'G' 'r' 'a' 'p' 'h' + | 'S' 'u' 'b' 'G' 'r' 'a' 'p' 'h' + | 'S' 'U' 'B' 'G' 'R' 'A' 'P' 'H' +; + +strict + : 's' 't' 'r' 'i' 'c' 't' + | 'S' 't' 'r' 'i' 'c' 't' + | 'S' 'T' 'R' 'I' 'C' 'T' +; + +// An arbitrary ASCII character except null (0x00), double quote (0x22) and +// backslash (0x5C). +_ascii_char + // skip null (0x00) + : '\x01' - '\x21' + // skip double quote (0x22) + | '\x23' - '\x5B' + // skip backslash (0x5C) + | '\x5D' - '\x7F' +; + +_ascii_letter + : 'a' - 'z' + | 'A' - 'Z' +; + +_ascii_digit : '0' - '9' ; + +_unicode_char + : _ascii_char + | _unicode_byte +; + +_unicode_byte + : '\u0080' - '\uFFFC' + // skip invalid code point (\uFFFD) + | '\uFFFE' - '\U0010FFFF' +; + +_letter : _ascii_letter | _unicode_byte | '_' ; +_decimal_digit : _ascii_digit ; +_decimals : _decimal_digit { _decimal_digit } ; + +// 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 (<...>). + +id + : _letter { _letter | _decimal_digit } + | _int_lit + | _string_lit + | _html_lit +; + +_int_lit + : [ '-' ] '.' _decimals + | [ '-' ] _decimals [ '.' { _decimal_digit } ] +; + +// In quoted strings in DOT, the only escaped character is double-quote ("). +// That is, in quoted strings, the dyad \" is converted to "; all other +// characters are left unchanged. In particular, \\ remains \\. + +// 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. + +// In addition, double-quoted strings can be concatenated using a '+' operator. + +_escaped_char : '\\' ( _unicode_char | '"' | '\\' ) ; +_char : _unicode_char | _escaped_char ; +_string_lit : '"' { _char } '"' ; + +// An arbitrary HTML character except null (0x00), left angle bracket (0x3C) and +// right angle bracket (0x3E). +_html_char + // skip null (0x00) + : '\x01' - '\x3B' + // skip left angle bracket (0x3C) + | '\x3D' + // skip right angle bracket (0x3E) + | '\x3F' - '\xFF' +; + +_html_chars : { _html_char } ; +_html_tag : '<' _html_chars '>' ; +_html_lit : '<' { _html_chars | _html_tag } '>' ; + +// The language supports C++-style comments: /* */ and //. In addition, a line +// beginning with a '#' character is considered a line output from a C +// preprocessor (e.g., # 34 to indicate line 34 ) and discarded. + +_line_comment + : '/' '/' { . } '\n' + | '#' { . } '\n' +; + +_block_comment : '/' '*' { . | '*' } '*' '/' ; +!comment : _line_comment | _block_comment ; + +!whitespace : ' ' | '\t' | '\r' | '\n' ; + +// ### [ Syntax ] ############################################################## + +<< import ( + "gonum.org/v1/gonum/graph/formats/dot/ast" + "gonum.org/v1/gonum/graph/formats/dot/internal/astx" +) >> + +// === [ Files ] =============================================================== + +File + : Graph << astx.NewFile($0) >> + | File Graph << astx.AppendGraph($0, $1) >> +; + +// === [ Graphs ] ============================================================== + +// Graph : [ "strict" ] ( "graph" | "digraph" ) [ ID ] "{" [ StmtList ] "}" + +Graph + : OptStrict DirectedGraph OptID + "{" OptStmtList "}" << astx.NewGraph($0, $1, $2, $4) >> +; + +OptStrict + : empty << false, nil >> + | strict << true, nil >> +; + +DirectedGraph + : graphx << false, nil >> + | digraph << true, nil >> +; + +// === [ Statements ] ========================================================== + +// StmtList +// : Stmt [ ";" ] +// | StmtList Stmt [ ";" ] + +StmtList + : Stmt OptSemi << astx.NewStmtList($0) >> + | StmtList Stmt OptSemi << astx.AppendStmt($0, $1) >> +; + +OptStmtList + : empty + | StmtList +; + +Stmt + : NodeStmt + | EdgeStmt + | AttrStmt + | Attr + | Subgraph +; + +OptSemi + : empty + | ";" +; + +// --- [ Node statement ] ------------------------------------------------------ + +// NodeStmt : Node [ AttrList ] + +NodeStmt + : Node OptAttrList << astx.NewNodeStmt($0, $1) >> +; + +// --- [ Edge statement ] ------------------------------------------------------ + +// EdgeStmt : ( Node | Subgraph ) Edge [ AttrList ] + +EdgeStmt + : Vertex Edge OptAttrList << astx.NewEdgeStmt($0, $1, $2) >> +; + +// Edge : ( "--" | "-->" ) ( Node | Subgraph ) [ Edge ] + +Edge + : DirectedEdge Vertex OptEdge << astx.NewEdge($0, $1, $2) >> +; + +DirectedEdge + : "--" << false, nil >> + | "->" << true, nil >> +; + +OptEdge + : empty + | Edge +; + +// --- [ Attribute statement ] ------------------------------------------------- + +// AttrStmt : ( "graph" | "node" | "edge" ) AttrList + +AttrStmt + : Component AttrList << astx.NewAttrStmt($0, $1) >> +; + +Component + : graphx << ast.GraphKind, nil >> + | node << ast.NodeKind, nil >> + | edge << ast.EdgeKind, nil >> +; + +// AttrList : "[" [ AList ] "]" [ AttrList ] + +AttrList + : "[" OptAList "]" << $1, nil >> + | AttrList "[" OptAList "]" << astx.AppendAttrList($0, $2) >> +; + +OptAttrList + : empty + | AttrList +; + +// AList +// : Attr [ ( ";" | "," ) ] +// | AList Attr [ ( ";" | "," ) ] + +AList + : Attr OptSep << astx.NewAttrList($0) >> + | AList Attr OptSep << astx.AppendAttr($0, $1) >> +; + +OptAList + : empty + | AList +; + +OptSep + : empty + | ";" + | "," +; + +// --- [ Attribute ] ----------------------------------------------------------- + +Attr + : ID "=" ID << astx.NewAttr($0, $2) >> +; + +// --- [ Subgraph ] ------------------------------------------------------------ + +// Subgraph : [ "subgraph" [ ID ] ] "{" [ StmtList ] "}" + +Subgraph + : OptSubgraphID "{" OptStmtList "}" << astx.NewSubgraph($0, $2) >> +; + +OptSubgraphID + : empty + | subgraph OptID << $1, nil >> +; + +// === [ Vertices ] ============================================================ + +Vertex + : Node + | Subgraph +; + +// --- [ Node identifier ] ----------------------------------------------------- + +// Node : ID [ Port ] + +Node + : ID OptPort << astx.NewNode($0, $1) >> +; + +// Port +// : ":" ID [ ":" CompassPoint ] +// | ":" CompassPoint +// +// CompassPoint +// : "n" | "ne" | "e" | "se" | "s" | "sw" | "w" | "nw" | "c" | "_" + +// Note also that the allowed compass point values are not keywords, so these +// strings can be used elsewhere as ordinary identifiers and, conversely, the +// parser will actually accept any identifier. + +Port + : ":" ID << astx.NewPort($1, nil) >> + | ":" ID ":" ID << astx.NewPort($1, $3) >> +; + +OptPort + : empty + | Port +; + +// === [ Identifiers ] ========================================================= + +ID + : id << astx.NewID($0) >> +; + +OptID + : empty << "", nil >> + | ID +; diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/errors.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/errors.go new file mode 100644 index 00000000..44f8825e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/errors.go @@ -0,0 +1,66 @@ +// 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 ( + "bytes" + "fmt" + + "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(bytes.Buffer) + 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(bytes.Buffer) + 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, e.Err.Error()) + } else { + fmt.Fprintf(w, ", expected one of: ") + for _, expected := range e.ExpectedTokens { + fmt.Fprintf(w, "%s ", expected) + } + } + return w.String() +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/acttab.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/acttab.go new file mode 100644 index 00000000..34c9d4dd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/acttab.go @@ -0,0 +1,597 @@ +// 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: 19, + 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: 0, + Ignore: "", + }, + ActionRow{ // S64 + Accept: 0, + Ignore: "", + }, + ActionRow{ // S65 + Accept: 0, + Ignore: "", + }, + ActionRow{ // S66 + Accept: 0, + Ignore: "", + }, + ActionRow{ // S67 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S68 + Accept: 0, + Ignore: "", + }, + ActionRow{ // S69 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S70 + Accept: 19, + 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: -1, + Ignore: "!comment", + }, + ActionRow{ // S90 + Accept: 0, + Ignore: "", + }, + ActionRow{ // S91 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S92 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S93 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S94 + Accept: 12, + Ignore: "", + }, + ActionRow{ // S95 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S96 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S97 + Accept: 11, + Ignore: "", + }, + ActionRow{ // S98 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S99 + Accept: 19, + 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: 6, + Ignore: "", + }, + ActionRow{ // S113 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S114 + Accept: 19, + 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: 5, + Ignore: "", + }, + ActionRow{ // S127 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S128 + Accept: 19, + 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: 7, + Ignore: "", + }, + ActionRow{ // S135 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S136 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S137 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S138 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S139 + Accept: 19, + Ignore: "", + }, + ActionRow{ // S140 + Accept: 17, + Ignore: "", + }, +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer.go new file mode 100644 index 00000000..caa9c461 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer.go @@ -0,0 +1,310 @@ +// 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 = 141 + 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: . +*/ diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer_test.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer_test.go new file mode 100644 index 00000000..f90964fc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer_test.go @@ -0,0 +1,54 @@ +// 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_test + +import ( + "bytes" + "io/ioutil" + "testing" + + "gonum.org/v1/gonum/graph/formats/dot" +) + +func TestParseFile(t *testing.T) { + golden := []struct { + in string + out string + }{ + { + in: "testdata/tokens.dot", + out: "testdata/tokens.golden", + }, + } + for _, g := range golden { + file, err := dot.ParseFile(g.in) + if err != nil { + t.Errorf("%q: unable to parse file; %v", g.in, err) + continue + } + // If no output path is specified, the input is already golden. + out := g.in + if len(g.out) > 0 { + out = g.out + } + buf, err := ioutil.ReadFile(out) + if err != nil { + t.Errorf("%q: unable to read file; %v", g.in, err) + continue + } + got := file.String() + // Remove trailing newline. + want := string(bytes.TrimSpace(buf)) + if got != want { + t.Errorf("%q: graph mismatch; expected %q, got %q", g.in, want, got) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/testdata/tokens.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/testdata/tokens.dot new file mode 100644 index 00000000..3a161951 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/testdata/tokens.dot @@ -0,0 +1,39 @@ +# C preprocessing directives act as comments. +/* block comment */ +// keywords are case-insensitive. +graph { + node [] + Node [] + NODE [] + edge [] + Edge [] + EDGE [] + subgraph {} + subGraph {} + Subgraph {} + SubGraph {} + SUBGRAPH S {} + A; B [style=filled, fillcolor=red] + C:nw -- D:se + "foo" + .10 + -20 + 3.14 + F [label=<
foo
>] + _foo + a10 +} +Graph { +} +GRAPH { +} +digraph { +} +Digraph { +} +diGraph { +} +DiGraph { +} +DIGRAPH { +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/testdata/tokens.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/testdata/tokens.golden new file mode 100644 index 00000000..f64bdefc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/testdata/tokens.golden @@ -0,0 +1,37 @@ +graph { + node [] + node [] + node [] + edge [] + edge [] + edge [] + {} + {} + {} + {} + subgraph S {} + A + B [style=filled fillcolor=red] + C:nw -- D:se + "foo" + .10 + -20 + 3.14 + F [label=<
foo
>] + _foo + a10 +} +graph { +} +graph { +} +digraph { +} +digraph { +} +digraph { +} +digraph { +} +digraph { +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/transitiontable.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/transitiontable.go new file mode 100644 index 00000000..8f8f8393 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/transitiontable.go @@ -0,0 +1,2741 @@ +// 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 + +/* +Let s be the current state +Let r be the current input rune +transitionTable[s](r) returns the next state. +*/ +type TransitionTable [NumStates]func(rune) int + +var TransTab = TransitionTable{ + // S0 + func(r rune) int { + switch { + case r == 9: // ['\t','\t'] + return 1 + case r == 10: // ['\n','\n'] + return 1 + case r == 13: // ['\r','\r'] + return 1 + case r == 32: // [' ',' '] + return 1 + case r == 34: // ['"','"'] + return 2 + case r == 35: // ['#','#'] + return 3 + case r == 44: // [',',','] + return 4 + case r == 45: // ['-','-'] + return 5 + case r == 46: // ['.','.'] + return 6 + case r == 47: // ['/','/'] + return 7 + case 48 <= r && r <= 57: // ['0','9'] + return 8 + case r == 58: // [':',':'] + return 9 + case r == 59: // [';',';'] + return 10 + case r == 60: // ['<','<'] + return 11 + case r == 61: // ['=','='] + return 12 + case 65 <= r && r <= 67: // ['A','C'] + return 13 + case r == 68: // ['D','D'] + return 14 + case r == 69: // ['E','E'] + return 15 + case r == 70: // ['F','F'] + return 13 + case r == 71: // ['G','G'] + return 16 + case 72 <= r && r <= 77: // ['H','M'] + return 13 + case r == 78: // ['N','N'] + return 17 + case 79 <= r && r <= 82: // ['O','R'] + return 13 + case r == 83: // ['S','S'] + return 18 + case 84 <= r && r <= 90: // ['T','Z'] + return 13 + case r == 91: // ['[','['] + return 19 + case r == 93: // [']',']'] + return 20 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 99: // ['a','c'] + return 13 + case r == 100: // ['d','d'] + return 22 + case r == 101: // ['e','e'] + return 23 + case r == 102: // ['f','f'] + return 13 + case r == 103: // ['g','g'] + return 24 + case 104 <= r && r <= 109: // ['h','m'] + return 13 + case r == 110: // ['n','n'] + return 25 + case 111 <= r && r <= 114: // ['o','r'] + return 13 + case r == 115: // ['s','s'] + return 26 + case 116 <= r && r <= 122: // ['t','z'] + return 13 + case r == 123: // ['{','{'] + return 27 + case r == 125: // ['}','}'] + return 28 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S1 + func(r rune) int { + switch { + } + return NoState + }, + // S2 + func(r rune) int { + switch { + case 1 <= r && r <= 33: // [\u0001,'!'] + return 30 + case r == 34: // ['"','"'] + return 31 + case 35 <= r && r <= 91: // ['#','['] + return 30 + case r == 92: // ['\','\'] + return 32 + case 93 <= r && r <= 127: // [']',\u007f] + return 30 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 33 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 33 + } + return NoState + }, + // S3 + func(r rune) int { + switch { + case r == 10: // ['\n','\n'] + return 34 + default: + return 3 + } + }, + // S4 + func(r rune) int { + switch { + } + return NoState + }, + // S5 + func(r rune) int { + switch { + case r == 45: // ['-','-'] + return 35 + case r == 46: // ['.','.'] + return 6 + case 48 <= r && r <= 57: // ['0','9'] + return 8 + case r == 62: // ['>','>'] + return 36 + } + return NoState + }, + // S6 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 37 + } + return NoState + }, + // S7 + func(r rune) int { + switch { + case r == 42: // ['*','*'] + return 38 + case r == 47: // ['/','/'] + return 39 + } + return NoState + }, + // S8 + func(r rune) int { + switch { + case r == 46: // ['.','.'] + return 40 + case 48 <= r && r <= 57: // ['0','9'] + return 8 + } + return NoState + }, + // S9 + func(r rune) int { + switch { + } + return NoState + }, + // S10 + func(r rune) int { + switch { + } + return NoState + }, + // S11 + func(r rune) int { + switch { + case 1 <= r && r <= 59: // [\u0001,';'] + return 41 + case r == 60: // ['<','<'] + return 42 + case r == 61: // ['=','='] + return 41 + case r == 62: // ['>','>'] + return 43 + case 63 <= r && r <= 255: // ['?',\u00ff] + return 41 + } + return NoState + }, + // S12 + func(r rune) int { + switch { + } + return NoState + }, + // S13 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S14 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 72: // ['A','H'] + return 13 + case r == 73: // ['I','I'] + return 45 + case 74 <= r && r <= 90: // ['J','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 104: // ['a','h'] + return 13 + case r == 105: // ['i','i'] + return 46 + case 106 <= r && r <= 122: // ['j','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S15 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 67: // ['A','C'] + return 13 + case r == 68: // ['D','D'] + return 47 + case 69 <= r && r <= 90: // ['E','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 99: // ['a','c'] + return 13 + case r == 100: // ['d','d'] + return 48 + case 101 <= r && r <= 122: // ['e','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S16 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 81: // ['A','Q'] + return 13 + case r == 82: // ['R','R'] + return 49 + case 83 <= r && r <= 90: // ['S','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 50 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S17 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 78: // ['A','N'] + return 13 + case r == 79: // ['O','O'] + return 51 + case 80 <= r && r <= 90: // ['P','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 110: // ['a','n'] + return 13 + case r == 111: // ['o','o'] + return 52 + case 112 <= r && r <= 122: // ['p','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S18 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 83: // ['A','S'] + return 13 + case r == 84: // ['T','T'] + return 53 + case r == 85: // ['U','U'] + return 54 + case 86 <= r && r <= 90: // ['V','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 115: // ['a','s'] + return 13 + case r == 116: // ['t','t'] + return 55 + case r == 117: // ['u','u'] + return 56 + case 118 <= r && r <= 122: // ['v','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S19 + func(r rune) int { + switch { + } + return NoState + }, + // S20 + func(r rune) int { + switch { + } + return NoState + }, + // S21 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S22 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 104: // ['a','h'] + return 13 + case r == 105: // ['i','i'] + return 57 + case 106 <= r && r <= 122: // ['j','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S23 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 99: // ['a','c'] + return 13 + case r == 100: // ['d','d'] + return 58 + case 101 <= r && r <= 122: // ['e','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S24 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 59 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S25 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 110: // ['a','n'] + return 13 + case r == 111: // ['o','o'] + return 60 + case 112 <= r && r <= 122: // ['p','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S26 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 115: // ['a','s'] + return 13 + case r == 116: // ['t','t'] + return 61 + case r == 117: // ['u','u'] + return 62 + case 118 <= r && r <= 122: // ['v','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S27 + func(r rune) int { + switch { + } + return NoState + }, + // S28 + func(r rune) int { + switch { + } + return NoState + }, + // S29 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S30 + func(r rune) int { + switch { + case 1 <= r && r <= 33: // [\u0001,'!'] + return 30 + case r == 34: // ['"','"'] + return 31 + case 35 <= r && r <= 91: // ['#','['] + return 30 + case r == 92: // ['\','\'] + return 32 + case 93 <= r && r <= 127: // [']',\u007f] + return 30 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 33 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 33 + } + return NoState + }, + // S31 + func(r rune) int { + switch { + } + return NoState + }, + // S32 + func(r rune) int { + switch { + case 1 <= r && r <= 33: // [\u0001,'!'] + return 63 + case r == 34: // ['"','"'] + return 64 + case 35 <= r && r <= 91: // ['#','['] + return 63 + case r == 92: // ['\','\'] + return 64 + case 93 <= r && r <= 127: // [']',\u007f] + return 63 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 65 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 65 + } + return NoState + }, + // S33 + func(r rune) int { + switch { + case 1 <= r && r <= 33: // [\u0001,'!'] + return 30 + case r == 34: // ['"','"'] + return 31 + case 35 <= r && r <= 91: // ['#','['] + return 30 + case r == 92: // ['\','\'] + return 32 + case 93 <= r && r <= 127: // [']',\u007f] + return 30 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 33 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 33 + } + return NoState + }, + // S34 + func(r rune) int { + switch { + } + return NoState + }, + // S35 + func(r rune) int { + switch { + } + return NoState + }, + // S36 + func(r rune) int { + switch { + } + return NoState + }, + // S37 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 37 + } + return NoState + }, + // S38 + func(r rune) int { + switch { + case r == 42: // ['*','*'] + return 66 + default: + return 38 + } + }, + // S39 + func(r rune) int { + switch { + case r == 10: // ['\n','\n'] + return 34 + default: + return 39 + } + }, + // S40 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 67 + } + return NoState + }, + // S41 + func(r rune) int { + switch { + case 1 <= r && r <= 59: // [\u0001,';'] + return 41 + case r == 60: // ['<','<'] + return 42 + case r == 61: // ['=','='] + return 41 + case r == 62: // ['>','>'] + return 43 + case 63 <= r && r <= 255: // ['?',\u00ff] + return 41 + } + return NoState + }, + // S42 + func(r rune) int { + switch { + case 1 <= r && r <= 59: // [\u0001,';'] + return 68 + case r == 61: // ['=','='] + return 68 + case 63 <= r && r <= 255: // ['?',\u00ff] + return 68 + } + return NoState + }, + // S43 + func(r rune) int { + switch { + } + return NoState + }, + // S44 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S45 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 70: // ['A','F'] + return 13 + case r == 71: // ['G','G'] + return 69 + case 72 <= r && r <= 90: // ['H','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S46 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 70: // ['A','F'] + return 13 + case r == 71: // ['G','G'] + return 70 + case 72 <= r && r <= 90: // ['H','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 102: // ['a','f'] + return 13 + case r == 103: // ['g','g'] + return 71 + case 104 <= r && r <= 122: // ['h','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S47 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 70: // ['A','F'] + return 13 + case r == 71: // ['G','G'] + return 72 + case 72 <= r && r <= 90: // ['H','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S48 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 102: // ['a','f'] + return 13 + case r == 103: // ['g','g'] + return 73 + case 104 <= r && r <= 122: // ['h','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S49 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case r == 65: // ['A','A'] + return 74 + case 66 <= r && r <= 90: // ['B','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S50 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 75 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S51 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 67: // ['A','C'] + return 13 + case r == 68: // ['D','D'] + return 76 + case 69 <= r && r <= 90: // ['E','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S52 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 99: // ['a','c'] + return 13 + case r == 100: // ['d','d'] + return 77 + case 101 <= r && r <= 122: // ['e','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S53 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 81: // ['A','Q'] + return 13 + case r == 82: // ['R','R'] + return 78 + case 83 <= r && r <= 90: // ['S','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S54 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case r == 65: // ['A','A'] + return 13 + case r == 66: // ['B','B'] + return 79 + case 67 <= r && r <= 90: // ['C','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S55 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 80 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S56 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 13 + case r == 98: // ['b','b'] + return 81 + case 99 <= r && r <= 122: // ['c','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S57 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 70: // ['A','F'] + return 13 + case r == 71: // ['G','G'] + return 82 + case 72 <= r && r <= 90: // ['H','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 102: // ['a','f'] + return 13 + case r == 103: // ['g','g'] + return 83 + case 104 <= r && r <= 122: // ['h','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S58 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 102: // ['a','f'] + return 13 + case r == 103: // ['g','g'] + return 84 + case 104 <= r && r <= 122: // ['h','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S59 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 85 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S60 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 99: // ['a','c'] + return 13 + case r == 100: // ['d','d'] + return 86 + case 101 <= r && r <= 122: // ['e','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S61 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 87 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S62 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 13 + case r == 98: // ['b','b'] + return 88 + case 99 <= r && r <= 122: // ['c','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S63 + func(r rune) int { + switch { + case 1 <= r && r <= 33: // [\u0001,'!'] + return 30 + case r == 34: // ['"','"'] + return 31 + case 35 <= r && r <= 91: // ['#','['] + return 30 + case r == 92: // ['\','\'] + return 32 + case 93 <= r && r <= 127: // [']',\u007f] + return 30 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 33 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 33 + } + return NoState + }, + // S64 + func(r rune) int { + switch { + case 1 <= r && r <= 33: // [\u0001,'!'] + return 30 + case r == 34: // ['"','"'] + return 31 + case 35 <= r && r <= 91: // ['#','['] + return 30 + case r == 92: // ['\','\'] + return 32 + case 93 <= r && r <= 127: // [']',\u007f] + return 30 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 33 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 33 + } + return NoState + }, + // S65 + func(r rune) int { + switch { + case 1 <= r && r <= 33: // [\u0001,'!'] + return 30 + case r == 34: // ['"','"'] + return 31 + case 35 <= r && r <= 91: // ['#','['] + return 30 + case r == 92: // ['\','\'] + return 32 + case 93 <= r && r <= 127: // [']',\u007f] + return 30 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 33 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 33 + } + return NoState + }, + // S66 + func(r rune) int { + switch { + case r == 42: // ['*','*'] + return 66 + case r == 47: // ['/','/'] + return 89 + default: + return 38 + } + }, + // S67 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 67 + } + return NoState + }, + // S68 + func(r rune) int { + switch { + case 1 <= r && r <= 59: // [\u0001,';'] + return 68 + case r == 61: // ['=','='] + return 68 + case r == 62: // ['>','>'] + return 90 + case 63 <= r && r <= 255: // ['?',\u00ff] + return 68 + } + return NoState + }, + // S69 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 81: // ['A','Q'] + return 13 + case r == 82: // ['R','R'] + return 91 + case 83 <= r && r <= 90: // ['S','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S70 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 92 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S71 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 93 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S72 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 68: // ['A','D'] + return 13 + case r == 69: // ['E','E'] + return 94 + case 70 <= r && r <= 90: // ['F','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S73 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 100: // ['a','d'] + return 13 + case r == 101: // ['e','e'] + return 94 + case 102 <= r && r <= 122: // ['f','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S74 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 79: // ['A','O'] + return 13 + case r == 80: // ['P','P'] + return 95 + case 81 <= r && r <= 90: // ['Q','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S75 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 96 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S76 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 68: // ['A','D'] + return 13 + case r == 69: // ['E','E'] + return 97 + case 70 <= r && r <= 90: // ['F','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S77 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 100: // ['a','d'] + return 13 + case r == 101: // ['e','e'] + return 97 + case 102 <= r && r <= 122: // ['f','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S78 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 72: // ['A','H'] + return 13 + case r == 73: // ['I','I'] + return 98 + case 74 <= r && r <= 90: // ['J','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S79 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 70: // ['A','F'] + return 13 + case r == 71: // ['G','G'] + return 99 + case 72 <= r && r <= 90: // ['H','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S80 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 104: // ['a','h'] + return 13 + case r == 105: // ['i','i'] + return 100 + case 106 <= r && r <= 122: // ['j','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S81 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 70: // ['A','F'] + return 13 + case r == 71: // ['G','G'] + return 101 + case 72 <= r && r <= 90: // ['H','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 102: // ['a','f'] + return 13 + case r == 103: // ['g','g'] + return 102 + case 104 <= r && r <= 122: // ['h','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S82 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 103 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S83 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 104 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S84 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 100: // ['a','d'] + return 13 + case r == 101: // ['e','e'] + return 94 + case 102 <= r && r <= 122: // ['f','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S85 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 105 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S86 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 100: // ['a','d'] + return 13 + case r == 101: // ['e','e'] + return 97 + case 102 <= r && r <= 122: // ['f','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S87 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 104: // ['a','h'] + return 13 + case r == 105: // ['i','i'] + return 106 + case 106 <= r && r <= 122: // ['j','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S88 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 70: // ['A','F'] + return 13 + case r == 71: // ['G','G'] + return 107 + case 72 <= r && r <= 90: // ['H','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 102: // ['a','f'] + return 13 + case r == 103: // ['g','g'] + return 108 + case 104 <= r && r <= 122: // ['h','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S89 + func(r rune) int { + switch { + } + return NoState + }, + // S90 + func(r rune) int { + switch { + case 1 <= r && r <= 59: // [\u0001,';'] + return 41 + case r == 60: // ['<','<'] + return 42 + case r == 61: // ['=','='] + return 41 + case r == 62: // ['>','>'] + return 43 + case 63 <= r && r <= 255: // ['?',\u00ff] + return 41 + } + return NoState + }, + // S91 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case r == 65: // ['A','A'] + return 109 + case 66 <= r && r <= 90: // ['B','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S92 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 110 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S93 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 111 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S94 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S95 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 71: // ['A','G'] + return 13 + case r == 72: // ['H','H'] + return 112 + case 73 <= r && r <= 90: // ['I','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S96 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 112 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S97 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S98 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 66: // ['A','B'] + return 13 + case r == 67: // ['C','C'] + return 113 + case 68 <= r && r <= 90: // ['D','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S99 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 81: // ['A','Q'] + return 13 + case r == 82: // ['R','R'] + return 114 + case 83 <= r && r <= 90: // ['S','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S100 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 98: // ['a','b'] + return 13 + case r == 99: // ['c','c'] + return 115 + case 100 <= r && r <= 122: // ['d','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S101 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 116 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S102 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 117 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S103 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 118 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S104 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 119 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S105 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 112 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S106 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 98: // ['a','b'] + return 13 + case r == 99: // ['c','c'] + return 120 + case 100 <= r && r <= 122: // ['d','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S107 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 121 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S108 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 113: // ['a','q'] + return 13 + case r == 114: // ['r','r'] + return 122 + case 115 <= r && r <= 122: // ['s','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S109 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 79: // ['A','O'] + return 13 + case r == 80: // ['P','P'] + return 123 + case 81 <= r && r <= 90: // ['Q','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S110 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 124 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S111 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 125 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S112 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S113 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 83: // ['A','S'] + return 13 + case r == 84: // ['T','T'] + return 126 + case 85 <= r && r <= 90: // ['U','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S114 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case r == 65: // ['A','A'] + return 127 + case 66 <= r && r <= 90: // ['B','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S115 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 115: // ['a','s'] + return 13 + case r == 116: // ['t','t'] + return 126 + case 117 <= r && r <= 122: // ['u','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S116 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 128 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S117 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 129 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S118 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 130 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S119 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 131 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S120 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 115: // ['a','s'] + return 13 + case r == 116: // ['t','t'] + return 126 + case 117 <= r && r <= 122: // ['u','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S121 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 132 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S122 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case r == 97: // ['a','a'] + return 133 + case 98 <= r && r <= 122: // ['b','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S123 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 71: // ['A','G'] + return 13 + case r == 72: // ['H','H'] + return 134 + case 73 <= r && r <= 90: // ['I','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S124 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 134 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S125 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 134 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S126 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S127 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 79: // ['A','O'] + return 13 + case r == 80: // ['P','P'] + return 135 + case 81 <= r && r <= 90: // ['Q','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S128 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 136 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S129 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 137 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S130 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 134 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S131 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 134 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S132 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 138 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S133 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 111: // ['a','o'] + return 13 + case r == 112: // ['p','p'] + return 139 + case 113 <= r && r <= 122: // ['q','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S134 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S135 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 71: // ['A','G'] + return 13 + case r == 72: // ['H','H'] + return 140 + case 73 <= r && r <= 90: // ['I','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S136 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 140 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S137 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 140 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S138 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 140 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S139 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 103: // ['a','g'] + return 13 + case r == 104: // ['h','h'] + return 140 + case 105 <= r && r <= 122: // ['i','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, + // S140 + func(r rune) int { + switch { + case 48 <= r && r <= 57: // ['0','9'] + return 44 + case 65 <= r && r <= 90: // ['A','Z'] + return 13 + case r == 95: // ['_','_'] + return 21 + case 97 <= r && r <= 122: // ['a','z'] + return 13 + case 128 <= r && r <= 65532: // [\u0080,\ufffc] + return 29 + case 65534 <= r && r <= 1114111: // [\ufffe,\U0010ffff] + return 29 + } + return NoState + }, +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/action.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/action.go new file mode 100644 index 00000000..10d7eccb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/action.go @@ -0,0 +1,61 @@ +// 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) +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/actiontable.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/actiontable.go new file mode 100644 index 00000000..9596d120 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/actiontable.go @@ -0,0 +1,2199 @@ +// 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 + +type ( + actionTable [numStates]actionRow + actionRow struct { + canRecover bool + actions [numSymbols]action + } +) + +var actionTab = actionTable{ + actionRow{ // S0 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + shift(4), /* strict */ + reduce(4), /* graphx, reduce: OptStrict */ + reduce(4), /* digraph, reduce: OptStrict */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S1 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + accept(true), /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + shift(4), /* strict */ + reduce(4), /* graphx, reduce: OptStrict */ + reduce(4), /* digraph, reduce: OptStrict */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S2 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + reduce(1), /* $, reduce: File */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + reduce(1), /* strict, reduce: File */ + reduce(1), /* graphx, reduce: File */ + reduce(1), /* digraph, reduce: File */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S3 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + shift(7), /* graphx */ + shift(8), /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S4 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + reduce(5), /* graphx, reduce: OptStrict */ + reduce(5), /* digraph, reduce: OptStrict */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S5 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + reduce(2), /* $, reduce: File */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + reduce(2), /* strict, reduce: File */ + reduce(2), /* graphx, reduce: File */ + reduce(2), /* digraph, reduce: File */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S6 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(53), /* {, reduce: OptID */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(11), /* id */ + }, + }, + actionRow{ // S7 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(6), /* {, reduce: DirectedGraph */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(6), /* id, reduce: DirectedGraph */ + }, + }, + actionRow{ // S8 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(7), /* {, reduce: DirectedGraph */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(7), /* id, reduce: DirectedGraph */ + }, + }, + actionRow{ // S9 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + shift(12), /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S10 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(54), /* {, reduce: OptID */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S11 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(52), /* {, reduce: ID */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S12 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(43), /* {, reduce: OptSubgraphID */ + reduce(10), /* }, reduce: OptStmtList */ + nil, /* empty */ + nil, /* strict */ + shift(14), /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + shift(25), /* node */ + shift(26), /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + shift(29), /* subgraph */ + nil, /* : */ + shift(30), /* id */ + }, + }, + actionRow{ // S13 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + shift(31), /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S14 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + reduce(27), /* [, reduce: Component */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S15 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(43), /* {, reduce: OptSubgraphID */ + reduce(11), /* }, reduce: OptStmtList */ + nil, /* empty */ + nil, /* strict */ + shift(14), /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + shift(25), /* node */ + shift(26), /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + shift(29), /* subgraph */ + nil, /* : */ + shift(30), /* id */ + }, + }, + actionRow{ // S16 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(17), /* {, reduce: OptSemi */ + reduce(17), /* }, reduce: OptSemi */ + nil, /* empty */ + nil, /* strict */ + reduce(17), /* graphx, reduce: OptSemi */ + nil, /* digraph */ + shift(34), /* ; */ + nil, /* -- */ + nil, /* -> */ + reduce(17), /* node, reduce: OptSemi */ + reduce(17), /* edge, reduce: OptSemi */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(17), /* subgraph, reduce: OptSemi */ + nil, /* : */ + reduce(17), /* id, reduce: OptSemi */ + }, + }, + actionRow{ // S17 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(12), /* {, reduce: Stmt */ + reduce(12), /* }, reduce: Stmt */ + nil, /* empty */ + nil, /* strict */ + reduce(12), /* graphx, reduce: Stmt */ + nil, /* digraph */ + reduce(12), /* ;, reduce: Stmt */ + nil, /* -- */ + nil, /* -> */ + reduce(12), /* node, reduce: Stmt */ + reduce(12), /* edge, reduce: Stmt */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(12), /* subgraph, reduce: Stmt */ + nil, /* : */ + reduce(12), /* id, reduce: Stmt */ + }, + }, + actionRow{ // S18 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(13), /* {, reduce: Stmt */ + reduce(13), /* }, reduce: Stmt */ + nil, /* empty */ + nil, /* strict */ + reduce(13), /* graphx, reduce: Stmt */ + nil, /* digraph */ + reduce(13), /* ;, reduce: Stmt */ + nil, /* -- */ + nil, /* -> */ + reduce(13), /* node, reduce: Stmt */ + reduce(13), /* edge, reduce: Stmt */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(13), /* subgraph, reduce: Stmt */ + nil, /* : */ + reduce(13), /* id, reduce: Stmt */ + }, + }, + actionRow{ // S19 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(14), /* {, reduce: Stmt */ + reduce(14), /* }, reduce: Stmt */ + nil, /* empty */ + nil, /* strict */ + reduce(14), /* graphx, reduce: Stmt */ + nil, /* digraph */ + reduce(14), /* ;, reduce: Stmt */ + nil, /* -- */ + nil, /* -> */ + reduce(14), /* node, reduce: Stmt */ + reduce(14), /* edge, reduce: Stmt */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(14), /* subgraph, reduce: Stmt */ + nil, /* : */ + reduce(14), /* id, reduce: Stmt */ + }, + }, + actionRow{ // S20 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(15), /* {, reduce: Stmt */ + reduce(15), /* }, reduce: Stmt */ + nil, /* empty */ + nil, /* strict */ + reduce(15), /* graphx, reduce: Stmt */ + nil, /* digraph */ + reduce(15), /* ;, reduce: Stmt */ + nil, /* -- */ + nil, /* -> */ + reduce(15), /* node, reduce: Stmt */ + reduce(15), /* edge, reduce: Stmt */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(15), /* subgraph, reduce: Stmt */ + nil, /* : */ + reduce(15), /* id, reduce: Stmt */ + }, + }, + actionRow{ // S21 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(16), /* {, reduce: Stmt */ + reduce(16), /* }, reduce: Stmt */ + nil, /* empty */ + nil, /* strict */ + reduce(16), /* graphx, reduce: Stmt */ + nil, /* digraph */ + reduce(16), /* ;, reduce: Stmt */ + reduce(46), /* --, reduce: Vertex */ + reduce(46), /* ->, reduce: Vertex */ + reduce(16), /* node, reduce: Stmt */ + reduce(16), /* edge, reduce: Stmt */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(16), /* subgraph, reduce: Stmt */ + nil, /* : */ + reduce(16), /* id, reduce: Stmt */ + }, + }, + actionRow{ // S22 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(32), /* {, reduce: OptAttrList */ + reduce(32), /* }, reduce: OptAttrList */ + nil, /* empty */ + nil, /* strict */ + reduce(32), /* graphx, reduce: OptAttrList */ + nil, /* digraph */ + reduce(32), /* ;, reduce: OptAttrList */ + reduce(45), /* --, reduce: Vertex */ + reduce(45), /* ->, reduce: Vertex */ + reduce(32), /* node, reduce: OptAttrList */ + reduce(32), /* edge, reduce: OptAttrList */ + shift(37), /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(32), /* subgraph, reduce: OptAttrList */ + nil, /* : */ + reduce(32), /* id, reduce: OptAttrList */ + }, + }, + actionRow{ // S23 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + shift(40), /* -- */ + shift(41), /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S24 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + shift(37), /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S25 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + reduce(28), /* [, reduce: Component */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S26 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + reduce(29), /* [, reduce: Component */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S27 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(50), /* {, reduce: OptPort */ + reduce(50), /* }, reduce: OptPort */ + nil, /* empty */ + nil, /* strict */ + reduce(50), /* graphx, reduce: OptPort */ + nil, /* digraph */ + reduce(50), /* ;, reduce: OptPort */ + reduce(50), /* --, reduce: OptPort */ + reduce(50), /* ->, reduce: OptPort */ + reduce(50), /* node, reduce: OptPort */ + reduce(50), /* edge, reduce: OptPort */ + reduce(50), /* [, reduce: OptPort */ + nil, /* ] */ + nil, /* , */ + shift(43), /* = */ + reduce(50), /* subgraph, reduce: OptPort */ + shift(46), /* : */ + reduce(50), /* id, reduce: OptPort */ + }, + }, + actionRow{ // S28 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + shift(47), /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S29 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(53), /* {, reduce: OptID */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(11), /* id */ + }, + }, + actionRow{ // S30 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(52), /* {, reduce: ID */ + reduce(52), /* }, reduce: ID */ + nil, /* empty */ + nil, /* strict */ + reduce(52), /* graphx, reduce: ID */ + nil, /* digraph */ + reduce(52), /* ;, reduce: ID */ + reduce(52), /* --, reduce: ID */ + reduce(52), /* ->, reduce: ID */ + reduce(52), /* node, reduce: ID */ + reduce(52), /* edge, reduce: ID */ + reduce(52), /* [, reduce: ID */ + nil, /* ] */ + nil, /* , */ + reduce(52), /* =, reduce: ID */ + reduce(52), /* subgraph, reduce: ID */ + reduce(52), /* :, reduce: ID */ + reduce(52), /* id, reduce: ID */ + }, + }, + actionRow{ // S31 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + reduce(3), /* $, reduce: Graph */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + reduce(3), /* strict, reduce: Graph */ + reduce(3), /* graphx, reduce: Graph */ + reduce(3), /* digraph, reduce: Graph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S32 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(17), /* {, reduce: OptSemi */ + reduce(17), /* }, reduce: OptSemi */ + nil, /* empty */ + nil, /* strict */ + reduce(17), /* graphx, reduce: OptSemi */ + nil, /* digraph */ + shift(34), /* ; */ + nil, /* -- */ + nil, /* -> */ + reduce(17), /* node, reduce: OptSemi */ + reduce(17), /* edge, reduce: OptSemi */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(17), /* subgraph, reduce: OptSemi */ + nil, /* : */ + reduce(17), /* id, reduce: OptSemi */ + }, + }, + actionRow{ // S33 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(8), /* {, reduce: StmtList */ + reduce(8), /* }, reduce: StmtList */ + nil, /* empty */ + nil, /* strict */ + reduce(8), /* graphx, reduce: StmtList */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + reduce(8), /* node, reduce: StmtList */ + reduce(8), /* edge, reduce: StmtList */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(8), /* subgraph, reduce: StmtList */ + nil, /* : */ + reduce(8), /* id, reduce: StmtList */ + }, + }, + actionRow{ // S34 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(18), /* {, reduce: OptSemi */ + reduce(18), /* }, reduce: OptSemi */ + nil, /* empty */ + nil, /* strict */ + reduce(18), /* graphx, reduce: OptSemi */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + reduce(18), /* node, reduce: OptSemi */ + reduce(18), /* edge, reduce: OptSemi */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(18), /* subgraph, reduce: OptSemi */ + nil, /* : */ + reduce(18), /* id, reduce: OptSemi */ + }, + }, + actionRow{ // S35 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(19), /* {, reduce: NodeStmt */ + reduce(19), /* }, reduce: NodeStmt */ + nil, /* empty */ + nil, /* strict */ + reduce(19), /* graphx, reduce: NodeStmt */ + nil, /* digraph */ + reduce(19), /* ;, reduce: NodeStmt */ + nil, /* -- */ + nil, /* -> */ + reduce(19), /* node, reduce: NodeStmt */ + reduce(19), /* edge, reduce: NodeStmt */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(19), /* subgraph, reduce: NodeStmt */ + nil, /* : */ + reduce(19), /* id, reduce: NodeStmt */ + }, + }, + actionRow{ // S36 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(33), /* {, reduce: OptAttrList */ + reduce(33), /* }, reduce: OptAttrList */ + nil, /* empty */ + nil, /* strict */ + reduce(33), /* graphx, reduce: OptAttrList */ + nil, /* digraph */ + reduce(33), /* ;, reduce: OptAttrList */ + nil, /* -- */ + nil, /* -> */ + reduce(33), /* node, reduce: OptAttrList */ + reduce(33), /* edge, reduce: OptAttrList */ + shift(50), /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(33), /* subgraph, reduce: OptAttrList */ + nil, /* : */ + reduce(33), /* id, reduce: OptAttrList */ + }, + }, + actionRow{ // S37 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(36), /* ], reduce: OptAList */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(55), /* id */ + }, + }, + actionRow{ // S38 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(32), /* {, reduce: OptAttrList */ + reduce(32), /* }, reduce: OptAttrList */ + nil, /* empty */ + nil, /* strict */ + reduce(32), /* graphx, reduce: OptAttrList */ + nil, /* digraph */ + reduce(32), /* ;, reduce: OptAttrList */ + nil, /* -- */ + nil, /* -> */ + reduce(32), /* node, reduce: OptAttrList */ + reduce(32), /* edge, reduce: OptAttrList */ + shift(37), /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(32), /* subgraph, reduce: OptAttrList */ + nil, /* : */ + reduce(32), /* id, reduce: OptAttrList */ + }, + }, + actionRow{ // S39 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(43), /* {, reduce: OptSubgraphID */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + shift(29), /* subgraph */ + nil, /* : */ + shift(62), /* id */ + }, + }, + actionRow{ // S40 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(22), /* {, reduce: DirectedEdge */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(22), /* subgraph, reduce: DirectedEdge */ + nil, /* : */ + reduce(22), /* id, reduce: DirectedEdge */ + }, + }, + actionRow{ // S41 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(23), /* {, reduce: DirectedEdge */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(23), /* subgraph, reduce: DirectedEdge */ + nil, /* : */ + reduce(23), /* id, reduce: DirectedEdge */ + }, + }, + actionRow{ // S42 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(26), /* {, reduce: AttrStmt */ + reduce(26), /* }, reduce: AttrStmt */ + nil, /* empty */ + nil, /* strict */ + reduce(26), /* graphx, reduce: AttrStmt */ + nil, /* digraph */ + reduce(26), /* ;, reduce: AttrStmt */ + nil, /* -- */ + nil, /* -> */ + reduce(26), /* node, reduce: AttrStmt */ + reduce(26), /* edge, reduce: AttrStmt */ + shift(50), /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(26), /* subgraph, reduce: AttrStmt */ + nil, /* : */ + reduce(26), /* id, reduce: AttrStmt */ + }, + }, + actionRow{ // S43 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(64), /* id */ + }, + }, + actionRow{ // S44 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(47), /* {, reduce: Node */ + reduce(47), /* }, reduce: Node */ + nil, /* empty */ + nil, /* strict */ + reduce(47), /* graphx, reduce: Node */ + nil, /* digraph */ + reduce(47), /* ;, reduce: Node */ + reduce(47), /* --, reduce: Node */ + reduce(47), /* ->, reduce: Node */ + reduce(47), /* node, reduce: Node */ + reduce(47), /* edge, reduce: Node */ + reduce(47), /* [, reduce: Node */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(47), /* subgraph, reduce: Node */ + nil, /* : */ + reduce(47), /* id, reduce: Node */ + }, + }, + actionRow{ // S45 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(51), /* {, reduce: OptPort */ + reduce(51), /* }, reduce: OptPort */ + nil, /* empty */ + nil, /* strict */ + reduce(51), /* graphx, reduce: OptPort */ + nil, /* digraph */ + reduce(51), /* ;, reduce: OptPort */ + reduce(51), /* --, reduce: OptPort */ + reduce(51), /* ->, reduce: OptPort */ + reduce(51), /* node, reduce: OptPort */ + reduce(51), /* edge, reduce: OptPort */ + reduce(51), /* [, reduce: OptPort */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(51), /* subgraph, reduce: OptPort */ + nil, /* : */ + reduce(51), /* id, reduce: OptPort */ + }, + }, + actionRow{ // S46 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(62), /* id */ + }, + }, + actionRow{ // S47 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(43), /* {, reduce: OptSubgraphID */ + reduce(10), /* }, reduce: OptStmtList */ + nil, /* empty */ + nil, /* strict */ + shift(14), /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + shift(25), /* node */ + shift(26), /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + shift(29), /* subgraph */ + nil, /* : */ + shift(30), /* id */ + }, + }, + actionRow{ // S48 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(44), /* {, reduce: OptSubgraphID */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S49 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(9), /* {, reduce: StmtList */ + reduce(9), /* }, reduce: StmtList */ + nil, /* empty */ + nil, /* strict */ + reduce(9), /* graphx, reduce: StmtList */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + reduce(9), /* node, reduce: StmtList */ + reduce(9), /* edge, reduce: StmtList */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(9), /* subgraph, reduce: StmtList */ + nil, /* : */ + reduce(9), /* id, reduce: StmtList */ + }, + }, + actionRow{ // S50 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(36), /* ], reduce: OptAList */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(55), /* id */ + }, + }, + actionRow{ // S51 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + shift(68), /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(38), /* ], reduce: OptSep */ + shift(70), /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(38), /* id, reduce: OptSep */ + }, + }, + actionRow{ // S52 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + shift(71), /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S53 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(37), /* ], reduce: OptAList */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(55), /* id */ + }, + }, + actionRow{ // S54 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + shift(73), /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S55 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + reduce(52), /* =, reduce: ID */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S56 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(20), /* {, reduce: EdgeStmt */ + reduce(20), /* }, reduce: EdgeStmt */ + nil, /* empty */ + nil, /* strict */ + reduce(20), /* graphx, reduce: EdgeStmt */ + nil, /* digraph */ + reduce(20), /* ;, reduce: EdgeStmt */ + nil, /* -- */ + nil, /* -> */ + reduce(20), /* node, reduce: EdgeStmt */ + reduce(20), /* edge, reduce: EdgeStmt */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(20), /* subgraph, reduce: EdgeStmt */ + nil, /* : */ + reduce(20), /* id, reduce: EdgeStmt */ + }, + }, + actionRow{ // S57 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(46), /* {, reduce: Vertex */ + reduce(46), /* }, reduce: Vertex */ + nil, /* empty */ + nil, /* strict */ + reduce(46), /* graphx, reduce: Vertex */ + nil, /* digraph */ + reduce(46), /* ;, reduce: Vertex */ + reduce(46), /* --, reduce: Vertex */ + reduce(46), /* ->, reduce: Vertex */ + reduce(46), /* node, reduce: Vertex */ + reduce(46), /* edge, reduce: Vertex */ + reduce(46), /* [, reduce: Vertex */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(46), /* subgraph, reduce: Vertex */ + nil, /* : */ + reduce(46), /* id, reduce: Vertex */ + }, + }, + actionRow{ // S58 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(45), /* {, reduce: Vertex */ + reduce(45), /* }, reduce: Vertex */ + nil, /* empty */ + nil, /* strict */ + reduce(45), /* graphx, reduce: Vertex */ + nil, /* digraph */ + reduce(45), /* ;, reduce: Vertex */ + reduce(45), /* --, reduce: Vertex */ + reduce(45), /* ->, reduce: Vertex */ + reduce(45), /* node, reduce: Vertex */ + reduce(45), /* edge, reduce: Vertex */ + reduce(45), /* [, reduce: Vertex */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(45), /* subgraph, reduce: Vertex */ + nil, /* : */ + reduce(45), /* id, reduce: Vertex */ + }, + }, + actionRow{ // S59 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(24), /* {, reduce: OptEdge */ + reduce(24), /* }, reduce: OptEdge */ + nil, /* empty */ + nil, /* strict */ + reduce(24), /* graphx, reduce: OptEdge */ + nil, /* digraph */ + reduce(24), /* ;, reduce: OptEdge */ + shift(40), /* -- */ + shift(41), /* -> */ + reduce(24), /* node, reduce: OptEdge */ + reduce(24), /* edge, reduce: OptEdge */ + reduce(24), /* [, reduce: OptEdge */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(24), /* subgraph, reduce: OptEdge */ + nil, /* : */ + reduce(24), /* id, reduce: OptEdge */ + }, + }, + actionRow{ // S60 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(50), /* {, reduce: OptPort */ + reduce(50), /* }, reduce: OptPort */ + nil, /* empty */ + nil, /* strict */ + reduce(50), /* graphx, reduce: OptPort */ + nil, /* digraph */ + reduce(50), /* ;, reduce: OptPort */ + reduce(50), /* --, reduce: OptPort */ + reduce(50), /* ->, reduce: OptPort */ + reduce(50), /* node, reduce: OptPort */ + reduce(50), /* edge, reduce: OptPort */ + reduce(50), /* [, reduce: OptPort */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(50), /* subgraph, reduce: OptPort */ + shift(46), /* : */ + reduce(50), /* id, reduce: OptPort */ + }, + }, + actionRow{ // S61 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + shift(76), /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S62 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(52), /* {, reduce: ID */ + reduce(52), /* }, reduce: ID */ + nil, /* empty */ + nil, /* strict */ + reduce(52), /* graphx, reduce: ID */ + nil, /* digraph */ + reduce(52), /* ;, reduce: ID */ + reduce(52), /* --, reduce: ID */ + reduce(52), /* ->, reduce: ID */ + reduce(52), /* node, reduce: ID */ + reduce(52), /* edge, reduce: ID */ + reduce(52), /* [, reduce: ID */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(52), /* subgraph, reduce: ID */ + reduce(52), /* :, reduce: ID */ + reduce(52), /* id, reduce: ID */ + }, + }, + actionRow{ // S63 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(41), /* {, reduce: Attr */ + reduce(41), /* }, reduce: Attr */ + nil, /* empty */ + nil, /* strict */ + reduce(41), /* graphx, reduce: Attr */ + nil, /* digraph */ + reduce(41), /* ;, reduce: Attr */ + nil, /* -- */ + nil, /* -> */ + reduce(41), /* node, reduce: Attr */ + reduce(41), /* edge, reduce: Attr */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(41), /* subgraph, reduce: Attr */ + nil, /* : */ + reduce(41), /* id, reduce: Attr */ + }, + }, + actionRow{ // S64 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(52), /* {, reduce: ID */ + reduce(52), /* }, reduce: ID */ + nil, /* empty */ + nil, /* strict */ + reduce(52), /* graphx, reduce: ID */ + nil, /* digraph */ + reduce(52), /* ;, reduce: ID */ + nil, /* -- */ + nil, /* -> */ + reduce(52), /* node, reduce: ID */ + reduce(52), /* edge, reduce: ID */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(52), /* subgraph, reduce: ID */ + nil, /* : */ + reduce(52), /* id, reduce: ID */ + }, + }, + actionRow{ // S65 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(48), /* {, reduce: Port */ + reduce(48), /* }, reduce: Port */ + nil, /* empty */ + nil, /* strict */ + reduce(48), /* graphx, reduce: Port */ + nil, /* digraph */ + reduce(48), /* ;, reduce: Port */ + reduce(48), /* --, reduce: Port */ + reduce(48), /* ->, reduce: Port */ + reduce(48), /* node, reduce: Port */ + reduce(48), /* edge, reduce: Port */ + reduce(48), /* [, reduce: Port */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(48), /* subgraph, reduce: Port */ + shift(77), /* : */ + reduce(48), /* id, reduce: Port */ + }, + }, + actionRow{ // S66 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + shift(78), /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S67 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + shift(79), /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S68 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(39), /* ], reduce: OptSep */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(39), /* id, reduce: OptSep */ + }, + }, + actionRow{ // S69 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(34), /* ], reduce: AList */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(34), /* id, reduce: AList */ + }, + }, + actionRow{ // S70 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(40), /* ], reduce: OptSep */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(40), /* id, reduce: OptSep */ + }, + }, + actionRow{ // S71 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(30), /* {, reduce: AttrList */ + reduce(30), /* }, reduce: AttrList */ + nil, /* empty */ + nil, /* strict */ + reduce(30), /* graphx, reduce: AttrList */ + nil, /* digraph */ + reduce(30), /* ;, reduce: AttrList */ + nil, /* -- */ + nil, /* -> */ + reduce(30), /* node, reduce: AttrList */ + reduce(30), /* edge, reduce: AttrList */ + reduce(30), /* [, reduce: AttrList */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(30), /* subgraph, reduce: AttrList */ + nil, /* : */ + reduce(30), /* id, reduce: AttrList */ + }, + }, + actionRow{ // S72 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + shift(68), /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(38), /* ], reduce: OptSep */ + shift(70), /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(38), /* id, reduce: OptSep */ + }, + }, + actionRow{ // S73 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(82), /* id */ + }, + }, + actionRow{ // S74 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(25), /* {, reduce: OptEdge */ + reduce(25), /* }, reduce: OptEdge */ + nil, /* empty */ + nil, /* strict */ + reduce(25), /* graphx, reduce: OptEdge */ + nil, /* digraph */ + reduce(25), /* ;, reduce: OptEdge */ + nil, /* -- */ + nil, /* -> */ + reduce(25), /* node, reduce: OptEdge */ + reduce(25), /* edge, reduce: OptEdge */ + reduce(25), /* [, reduce: OptEdge */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(25), /* subgraph, reduce: OptEdge */ + nil, /* : */ + reduce(25), /* id, reduce: OptEdge */ + }, + }, + actionRow{ // S75 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(21), /* {, reduce: Edge */ + reduce(21), /* }, reduce: Edge */ + nil, /* empty */ + nil, /* strict */ + reduce(21), /* graphx, reduce: Edge */ + nil, /* digraph */ + reduce(21), /* ;, reduce: Edge */ + nil, /* -- */ + nil, /* -> */ + reduce(21), /* node, reduce: Edge */ + reduce(21), /* edge, reduce: Edge */ + reduce(21), /* [, reduce: Edge */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(21), /* subgraph, reduce: Edge */ + nil, /* : */ + reduce(21), /* id, reduce: Edge */ + }, + }, + actionRow{ // S76 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(43), /* {, reduce: OptSubgraphID */ + reduce(10), /* }, reduce: OptStmtList */ + nil, /* empty */ + nil, /* strict */ + shift(14), /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + shift(25), /* node */ + shift(26), /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + shift(29), /* subgraph */ + nil, /* : */ + shift(30), /* id */ + }, + }, + actionRow{ // S77 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + shift(85), /* id */ + }, + }, + actionRow{ // S78 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(42), /* {, reduce: Subgraph */ + reduce(42), /* }, reduce: Subgraph */ + nil, /* empty */ + nil, /* strict */ + reduce(42), /* graphx, reduce: Subgraph */ + nil, /* digraph */ + reduce(42), /* ;, reduce: Subgraph */ + reduce(42), /* --, reduce: Subgraph */ + reduce(42), /* ->, reduce: Subgraph */ + reduce(42), /* node, reduce: Subgraph */ + reduce(42), /* edge, reduce: Subgraph */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(42), /* subgraph, reduce: Subgraph */ + nil, /* : */ + reduce(42), /* id, reduce: Subgraph */ + }, + }, + actionRow{ // S79 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(31), /* {, reduce: AttrList */ + reduce(31), /* }, reduce: AttrList */ + nil, /* empty */ + nil, /* strict */ + reduce(31), /* graphx, reduce: AttrList */ + nil, /* digraph */ + reduce(31), /* ;, reduce: AttrList */ + nil, /* -- */ + nil, /* -> */ + reduce(31), /* node, reduce: AttrList */ + reduce(31), /* edge, reduce: AttrList */ + reduce(31), /* [, reduce: AttrList */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(31), /* subgraph, reduce: AttrList */ + nil, /* : */ + reduce(31), /* id, reduce: AttrList */ + }, + }, + actionRow{ // S80 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(35), /* ], reduce: AList */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(35), /* id, reduce: AList */ + }, + }, + actionRow{ // S81 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + reduce(41), /* ;, reduce: Attr */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(41), /* ], reduce: Attr */ + reduce(41), /* ,, reduce: Attr */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(41), /* id, reduce: Attr */ + }, + }, + actionRow{ // S82 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + nil, /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + reduce(52), /* ;, reduce: ID */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + reduce(52), /* ], reduce: ID */ + reduce(52), /* ,, reduce: ID */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + reduce(52), /* id, reduce: ID */ + }, + }, + actionRow{ // S83 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + nil, /* { */ + shift(86), /* } */ + nil, /* empty */ + nil, /* strict */ + nil, /* graphx */ + nil, /* digraph */ + nil, /* ; */ + nil, /* -- */ + nil, /* -> */ + nil, /* node */ + nil, /* edge */ + nil, /* [ */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + nil, /* subgraph */ + nil, /* : */ + nil, /* id */ + }, + }, + actionRow{ // S84 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(49), /* {, reduce: Port */ + reduce(49), /* }, reduce: Port */ + nil, /* empty */ + nil, /* strict */ + reduce(49), /* graphx, reduce: Port */ + nil, /* digraph */ + reduce(49), /* ;, reduce: Port */ + reduce(49), /* --, reduce: Port */ + reduce(49), /* ->, reduce: Port */ + reduce(49), /* node, reduce: Port */ + reduce(49), /* edge, reduce: Port */ + reduce(49), /* [, reduce: Port */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(49), /* subgraph, reduce: Port */ + nil, /* : */ + reduce(49), /* id, reduce: Port */ + }, + }, + actionRow{ // S85 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(52), /* {, reduce: ID */ + reduce(52), /* }, reduce: ID */ + nil, /* empty */ + nil, /* strict */ + reduce(52), /* graphx, reduce: ID */ + nil, /* digraph */ + reduce(52), /* ;, reduce: ID */ + reduce(52), /* --, reduce: ID */ + reduce(52), /* ->, reduce: ID */ + reduce(52), /* node, reduce: ID */ + reduce(52), /* edge, reduce: ID */ + reduce(52), /* [, reduce: ID */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(52), /* subgraph, reduce: ID */ + nil, /* : */ + reduce(52), /* id, reduce: ID */ + }, + }, + actionRow{ // S86 + canRecover: false, + actions: [numSymbols]action{ + nil, /* INVALID */ + nil, /* $ */ + reduce(42), /* {, reduce: Subgraph */ + reduce(42), /* }, reduce: Subgraph */ + nil, /* empty */ + nil, /* strict */ + reduce(42), /* graphx, reduce: Subgraph */ + nil, /* digraph */ + reduce(42), /* ;, reduce: Subgraph */ + reduce(42), /* --, reduce: Subgraph */ + reduce(42), /* ->, reduce: Subgraph */ + reduce(42), /* node, reduce: Subgraph */ + reduce(42), /* edge, reduce: Subgraph */ + reduce(42), /* [, reduce: Subgraph */ + nil, /* ] */ + nil, /* , */ + nil, /* = */ + reduce(42), /* subgraph, reduce: Subgraph */ + nil, /* : */ + reduce(42), /* id, reduce: Subgraph */ + }, + }, +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/gototable.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/gototable.go new file mode 100644 index 00000000..9c55e43d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/gototable.go @@ -0,0 +1,2807 @@ +// 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 + +const numNTSymbols = 30 + +type ( + gotoTable [numStates]gotoRow + gotoRow [numNTSymbols]int +) + +var gotoTab = gotoTable{ + gotoRow{ // S0 + -1, // S' + 1, // File + 2, // Graph + 3, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S1 + -1, // S' + -1, // File + 5, // Graph + 3, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S2 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S3 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + 6, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S4 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S5 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S6 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 10, // ID + 9, // OptID + }, + gotoRow{ // S7 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S8 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S9 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S10 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S11 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S12 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + 15, // StmtList + 13, // OptStmtList + 16, // Stmt + -1, // OptSemi + 17, // NodeStmt + 18, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + 19, // AttrStmt + 24, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + 20, // Attr + 21, // Subgraph + 28, // OptSubgraphID + 23, // Vertex + 22, // Node + -1, // Port + -1, // OptPort + 27, // ID + -1, // OptID + }, + gotoRow{ // S13 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S14 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S15 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + 32, // Stmt + -1, // OptSemi + 17, // NodeStmt + 18, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + 19, // AttrStmt + 24, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + 20, // Attr + 21, // Subgraph + 28, // OptSubgraphID + 23, // Vertex + 22, // Node + -1, // Port + -1, // OptPort + 27, // ID + -1, // OptID + }, + gotoRow{ // S16 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + 33, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S17 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S18 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S19 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S20 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S21 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S22 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + 36, // AttrList + 35, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S23 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + 38, // Edge + 39, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S24 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + 42, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S25 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S26 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S27 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + 45, // Port + 44, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S28 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S29 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 10, // ID + 48, // OptID + }, + gotoRow{ // S30 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S31 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S32 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + 49, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S33 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S34 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S35 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S36 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S37 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + 53, // AList + 52, // OptAList + -1, // OptSep + 51, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 54, // ID + -1, // OptID + }, + gotoRow{ // S38 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + 36, // AttrList + 56, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S39 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + 57, // Subgraph + 61, // OptSubgraphID + 59, // Vertex + 58, // Node + -1, // Port + -1, // OptPort + 60, // ID + -1, // OptID + }, + gotoRow{ // S40 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S41 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S42 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S43 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 63, // ID + -1, // OptID + }, + gotoRow{ // S44 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S45 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S46 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 65, // ID + -1, // OptID + }, + gotoRow{ // S47 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + 15, // StmtList + 66, // OptStmtList + 16, // Stmt + -1, // OptSemi + 17, // NodeStmt + 18, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + 19, // AttrStmt + 24, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + 20, // Attr + 21, // Subgraph + 28, // OptSubgraphID + 23, // Vertex + 22, // Node + -1, // Port + -1, // OptPort + 27, // ID + -1, // OptID + }, + gotoRow{ // S48 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S49 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S50 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + 53, // AList + 67, // OptAList + -1, // OptSep + 51, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 54, // ID + -1, // OptID + }, + gotoRow{ // S51 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + 69, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S52 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S53 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + 72, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 54, // ID + -1, // OptID + }, + gotoRow{ // S54 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S55 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S56 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S57 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S58 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S59 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + 74, // Edge + 39, // DirectedEdge + 75, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S60 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + 45, // Port + 44, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S61 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S62 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S63 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S64 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S65 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S66 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S67 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S68 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S69 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S70 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S71 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S72 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + 80, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S73 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 81, // ID + -1, // OptID + }, + gotoRow{ // S74 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S75 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S76 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + 15, // StmtList + 83, // OptStmtList + 16, // Stmt + -1, // OptSemi + 17, // NodeStmt + 18, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + 19, // AttrStmt + 24, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + 20, // Attr + 21, // Subgraph + 28, // OptSubgraphID + 23, // Vertex + 22, // Node + -1, // Port + -1, // OptPort + 27, // ID + -1, // OptID + }, + gotoRow{ // S77 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + 84, // ID + -1, // OptID + }, + gotoRow{ // S78 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S79 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S80 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S81 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S82 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S83 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S84 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S85 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, + gotoRow{ // S86 + -1, // S' + -1, // File + -1, // Graph + -1, // OptStrict + -1, // DirectedGraph + -1, // StmtList + -1, // OptStmtList + -1, // Stmt + -1, // OptSemi + -1, // NodeStmt + -1, // EdgeStmt + -1, // Edge + -1, // DirectedEdge + -1, // OptEdge + -1, // AttrStmt + -1, // Component + -1, // AttrList + -1, // OptAttrList + -1, // AList + -1, // OptAList + -1, // OptSep + -1, // Attr + -1, // Subgraph + -1, // OptSubgraphID + -1, // Vertex + -1, // Node + -1, // Port + -1, // OptPort + -1, // ID + -1, // OptID + }, +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser.go new file mode 100644 index 00000000..18e146e0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser.go @@ -0,0 +1,221 @@ +// 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 ( + "bytes" + "fmt" + + 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(bytes.Buffer) + 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 { + fmt.Fprintf(w, "%v", s.attrib[i]) + } + 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(int(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 +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser_test.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser_test.go new file mode 100644 index 00000000..c48cd6f6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser_test.go @@ -0,0 +1,114 @@ +// 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_test + +import ( + "bytes" + "io/ioutil" + "testing" + + "gonum.org/v1/gonum/graph/formats/dot" +) + +func TestParseFile(t *testing.T) { + golden := []struct { + in string + out string + }{ + {in: "../testdata/empty.dot"}, + {in: "../testdata/graph.dot"}, + {in: "../testdata/digraph.dot"}, + {in: "../testdata/strict.dot"}, + {in: "../testdata/multi.dot"}, + {in: "../testdata/named_graph.dot"}, + {in: "../testdata/node_stmt.dot"}, + {in: "../testdata/edge_stmt.dot"}, + {in: "../testdata/attr_stmt.dot"}, + {in: "../testdata/attr.dot"}, + { + in: "../testdata/subgraph.dot", + out: "../testdata/subgraph.golden", + }, + { + in: "../testdata/semi.dot", + out: "../testdata/semi.golden", + }, + { + in: "../testdata/empty_attr.dot", + out: "../testdata/empty_attr.golden", + }, + { + in: "../testdata/attr_lists.dot", + out: "../testdata/attr_lists.golden", + }, + { + in: "../testdata/attr_sep.dot", + out: "../testdata/attr_sep.golden", + }, + {in: "../testdata/subgraph_vertex.dot"}, + { + in: "../testdata/port.dot", + out: "../testdata/port.golden", + }, + {in: "../testdata/quoted_id.dot"}, + { + in: "../testdata/backslash_newline_id.dot", + out: "../testdata/backslash_newline_id.golden", + }, + } + for _, g := range golden { + file, err := dot.ParseFile(g.in) + if err != nil { + t.Errorf("%q: unable to parse file; %v", g.in, err) + continue + } + // If no output path is specified, the input is already golden. + out := g.in + if len(g.out) > 0 { + out = g.out + } + buf, err := ioutil.ReadFile(out) + if err != nil { + t.Errorf("%q: unable to read file; %v", g.in, err) + continue + } + got := file.String() + // Remove trailing newline. + want := string(bytes.TrimSpace(buf)) + if got != want { + t.Errorf("%q: graph mismatch; expected `%s`, got `%s`", g.in, want, got) + } + } +} + +func TestParseError(t *testing.T) { + golden := []struct { + path string + want string + }{ + { + path: "../testdata/error.dot", + want: `Error in S30: INVALID(0,~), Pos(offset=13, line=2, column=7), expected one of: { } graphx ; -- -> node edge [ = subgraph : id `, + }, + } + for _, g := range golden { + _, err := dot.ParseFile(g.path) + if err == nil { + t.Errorf("%q: expected error, got nil", g.path) + continue + } + got := err.Error() + if got != g.want { + t.Errorf("%q: error mismatch; expected `%v`, got `%v`", g.path, g.want, got) + continue + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/productionstable.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/productionstable.go new file mode 100644 index 00000000..96c56350 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/productionstable.go @@ -0,0 +1,586 @@ +// 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 + }, + }, +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/paste_copyright.bash b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/paste_copyright.bash new file mode 100755 index 00000000..569bd925 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/paste_copyright.bash @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +find . -type f -name '*.go' \ +| xargs sed -i -e "s|// Code generated by gocc; DO NOT EDIT.|\ +// Code generated by gocc; DO NOT EDIT.\n\ +\n\ +// This file is dual licensed under CC0 and The gonum license.\n\ +//\n\ +// Copyright ©2017 The gonum Authors. All rights reserved.\n\ +// Use of this source code is governed by a BSD-style\n\ +// license that can be found in the LICENSE file.\n\ +//\n\ +// Copyright ©2017 Robin Eklind.\n\ +// This file is made available under a Creative Commons CC0 1.0\n\ +// Universal Public Domain Dedication.\ +|" + diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr.dot new file mode 100644 index 00000000..dabe9734 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr.dot @@ -0,0 +1,4 @@ +digraph { + bgcolor=transparent + A +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_lists.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_lists.dot new file mode 100644 index 00000000..b71411cd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_lists.dot @@ -0,0 +1,3 @@ +digraph { + A [style=filled] [fillcolor=red] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_lists.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_lists.golden new file mode 100644 index 00000000..14316d93 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_lists.golden @@ -0,0 +1,3 @@ +digraph { + A [style=filled fillcolor=red] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_sep.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_sep.dot new file mode 100644 index 00000000..ef47a120 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_sep.dot @@ -0,0 +1,3 @@ +digraph { + A [style=filled, fillcolor=red; color=blue] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_sep.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_sep.golden new file mode 100644 index 00000000..95bfd972 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_sep.golden @@ -0,0 +1,3 @@ +digraph { + A [style=filled fillcolor=red color=blue] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_stmt.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_stmt.dot new file mode 100644 index 00000000..e87d70a4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/attr_stmt.dot @@ -0,0 +1,6 @@ +digraph { + graph [bgcolor=transparent] + node [style=filled fillcolor=white] + edge [minlen=2] + A -> B +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/backslash_newline_id.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/backslash_newline_id.dot new file mode 100644 index 00000000..81051384 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/backslash_newline_id.dot @@ -0,0 +1,4 @@ +digraph { + A [name="hello \ +world"] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/backslash_newline_id.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/backslash_newline_id.golden new file mode 100644 index 00000000..449c3a3e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/backslash_newline_id.golden @@ -0,0 +1,3 @@ +digraph { + A [name="hello world"] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/digraph.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/digraph.dot new file mode 100644 index 00000000..1063ebfa --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/digraph.dot @@ -0,0 +1,3 @@ +digraph { + A -> B +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/edge_stmt.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/edge_stmt.dot new file mode 100644 index 00000000..019d23d7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/edge_stmt.dot @@ -0,0 +1,4 @@ +digraph { + A -> B -> C + D -> E [color=red minlen=2] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty.dot new file mode 100644 index 00000000..418b7bca --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty.dot @@ -0,0 +1,2 @@ +graph { +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty_attr.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty_attr.dot new file mode 100644 index 00000000..b92d60e5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty_attr.dot @@ -0,0 +1,3 @@ +digraph { + A [] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty_attr.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty_attr.golden new file mode 100644 index 00000000..369e4495 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/empty_attr.golden @@ -0,0 +1,3 @@ +digraph { + A +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/error.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/error.dot new file mode 100644 index 00000000..ad77f61f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/error.dot @@ -0,0 +1,3 @@ +digraph { + A ~ B +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/graph.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/graph.dot new file mode 100644 index 00000000..0524c144 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/graph.dot @@ -0,0 +1,3 @@ +graph { + A -- B +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/multi.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/multi.dot new file mode 100644 index 00000000..21945188 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/multi.dot @@ -0,0 +1,6 @@ +digraph { + A -> B +} +digraph { + C -> D +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/named_graph.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/named_graph.dot new file mode 100644 index 00000000..3fc680da --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/named_graph.dot @@ -0,0 +1,3 @@ +graph G { + A +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/node_stmt.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/node_stmt.dot new file mode 100644 index 00000000..369e4495 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/node_stmt.dot @@ -0,0 +1,3 @@ +digraph { + A +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/port.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/port.dot new file mode 100644 index 00000000..1d4bf415 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/port.dot @@ -0,0 +1,11 @@ +digraph { + A:ne -> B:sw + C:foo -> D:bar:se + E:_ -> F + G:n + H:e + I:s + J:w + K:nw + L:c +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/port.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/port.golden new file mode 100644 index 00000000..18ca1f30 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/port.golden @@ -0,0 +1,11 @@ +digraph { + A:ne -> B:sw + C:foo -> D:bar:se + E -> F + G:n + H:e + I:s + J:w + K:nw + L:c +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/quoted_id.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/quoted_id.dot new file mode 100644 index 00000000..0c3b5652 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/quoted_id.dot @@ -0,0 +1,3 @@ +digraph { + "A" -> "B" ["color"="red"] +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/semi.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/semi.dot new file mode 100644 index 00000000..c8bcbf34 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/semi.dot @@ -0,0 +1,3 @@ +digraph { + A -> B; C +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/semi.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/semi.golden new file mode 100644 index 00000000..61bca268 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/semi.golden @@ -0,0 +1,4 @@ +digraph { + A -> B + C +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/strict.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/strict.dot new file mode 100644 index 00000000..bf222ad9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/strict.dot @@ -0,0 +1,4 @@ +strict digraph { + A -> B + A -> B +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph.dot new file mode 100644 index 00000000..a03667dd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph.dot @@ -0,0 +1,5 @@ +digraph { + {A} + subgraph {B} + subgraph S {C} +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph.golden b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph.golden new file mode 100644 index 00000000..0cd6fe72 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph.golden @@ -0,0 +1,5 @@ +digraph { + {A} + {B} + subgraph S {C} +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph_vertex.dot b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph_vertex.dot new file mode 100644 index 00000000..b414ad84 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/testdata/subgraph_vertex.dot @@ -0,0 +1,3 @@ +digraph { + {A B} -> C +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/token/token.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/token/token.go new file mode 100644 index 00000000..1492df0d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/token/token.go @@ -0,0 +1,116 @@ +// 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, + }, +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/util/litconv.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/util/litconv.go new file mode 100644 index 00000000..ed6e348b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/util/litconv.go @@ -0,0 +1,118 @@ +// 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 util + +import ( + "fmt" + "strconv" + "unicode" + "unicode/utf8" +) + +/* Interface */ + +/* +Convert the literal value of a scanned token to rune +*/ +func RuneValue(lit []byte) rune { + if lit[1] == '\\' { + return escapeCharVal(lit) + } + r, size := utf8.DecodeRune(lit[1:]) + if size != len(lit)-2 { + panic(fmt.Sprintf("Error decoding rune. Lit: %s, rune: %d, size%d\n", lit, r, size)) + } + return r +} + +/* +Convert the literal value of a scanned token to int64 +*/ +func IntValue(lit []byte) (int64, error) { + return strconv.ParseInt(string(lit), 10, 64) +} + +/* +Convert the literal value of a scanned token to uint64 +*/ +func UintValue(lit []byte) (uint64, error) { + return strconv.ParseUint(string(lit), 10, 64) +} + +/* Util */ + +func escapeCharVal(lit []byte) rune { + var i, base, max uint32 + offset := 2 + switch lit[offset] { + case 'a': + return '\a' + case 'b': + return '\b' + case 'f': + return '\f' + case 'n': + return '\n' + case 'r': + return '\r' + case 't': + return '\t' + case 'v': + return '\v' + case '\\': + return '\\' + case '\'': + return '\'' + case '0', '1', '2', '3', '4', '5', '6', '7': + i, base, max = 3, 8, 255 + case 'x': + i, base, max = 2, 16, 255 + offset++ + case 'u': + i, base, max = 4, 16, unicode.MaxRune + offset++ + case 'U': + i, base, max = 8, 16, unicode.MaxRune + offset++ + default: + panic(fmt.Sprintf("Error decoding character literal: %s\n", lit)) + } + + var x uint32 + for ; i > 0 && offset < len(lit)-1; i-- { + ch, size := utf8.DecodeRune(lit[offset:]) + offset += size + d := uint32(digitVal(ch)) + if d >= base { + panic(fmt.Sprintf("charVal(%s): illegal character (%c) in escape sequence. size=%d, offset=%d", lit, ch, size, offset)) + } + x = x*base + d + } + if x > max || 0xD800 <= x && x < 0xE000 { + panic(fmt.Sprintf("Error decoding escape char value. Lit:%s, offset:%d, escape sequence is invalid Unicode code point\n", lit, offset)) + } + + return rune(x) +} + +func digitVal(ch rune) int { + switch { + case '0' <= ch && ch <= '9': + return int(ch) - '0' + case 'a' <= ch && ch <= 'f': + return int(ch) - 'a' + 10 + case 'A' <= ch && ch <= 'F': + return int(ch) - 'A' + 10 + } + return 16 // larger than any legal digit val +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/util/rune.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/util/rune.go new file mode 100644 index 00000000..583b1e06 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/internal/util/rune.go @@ -0,0 +1,49 @@ +// 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 util + +import ( + "fmt" +) + +func RuneToString(r rune) string { + if r >= 0x20 && r < 0x7f { + return fmt.Sprintf("'%c'", r) + } + switch r { + case 0x07: + return "'\\a'" + case 0x08: + return "'\\b'" + case 0x0C: + return "'\\f'" + case 0x0A: + return "'\\n'" + case 0x0D: + return "'\\r'" + case 0x09: + return "'\\t'" + case 0x0b: + return "'\\v'" + case 0x5c: + return "'\\\\\\'" + case 0x27: + return "'\\''" + case 0x22: + return "'\\\"'" + } + if r < 0x10000 { + return fmt.Sprintf("\\u%04x", r) + } + return fmt.Sprintf("\\U%08x", r) +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/makeinternal.bash b/vendor/gonum.org/v1/gonum/graph/formats/dot/makeinternal.bash new file mode 100755 index 00000000..df377163 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/makeinternal.bash @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +cd internal +make clean && make diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/sem.go b/vendor/gonum.org/v1/gonum/graph/formats/dot/sem.go new file mode 100644 index 00000000..eb55b031 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/sem.go @@ -0,0 +1,160 @@ +// 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 +} diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/testdata/.gitignore b/vendor/gonum.org/v1/gonum/graph/formats/dot/testdata/.gitignore new file mode 100644 index 00000000..90453be2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/testdata/.gitignore @@ -0,0 +1,5 @@ +*.dot +*.png +graphviz +input +output diff --git a/vendor/gonum.org/v1/gonum/graph/formats/dot/testdata/Makefile b/vendor/gonum.org/v1/gonum/graph/formats/dot/testdata/Makefile new file mode 100644 index 00000000..c3bfcb9b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/formats/dot/testdata/Makefile @@ -0,0 +1,106 @@ +# Dependencies: +# +# * imgcmp +# go get github.com/mewkiz/cmd/imgcmp +# * dotfmt +# go get github.com/graphism/dot/cmd/dotfmt +# * dot +# sudo pacman -S graphviz +# * recode +# sudo pacman -S recode + +DOT=$(wildcard *.dot) + +# Skip DOT files for which the generated PNG images mismatch. +# +# ref: https://github.com/graphism/dot/issues/2 +# +# pixel colors differ at x=550, y=1885 +DOT:=$(filter-out b51.dot, $(DOT)) +# pixel colors differ at x=5395, y=1920 +DOT:=$(filter-out b106.dot, $(DOT)) + +# Skip segfaulting files. +# +# Segmentation fault (core dumped) +DOT:=$(filter-out b15.dot, $(DOT)) +# Segmentation fault (core dumped) +DOT:=$(filter-out b81.dot, $(DOT)) +# *** stack smashing detected ***: dot terminated +DOT:=$(filter-out sides.dot, $(DOT)) +# *** stack smashing detected ***: dot terminated +DOT:=$(filter-out tee.dot, $(DOT)) + +# Skip DOT files above 100 kB. +DOT:=$(filter-out 4elt.dot, $(DOT)) +DOT:=$(filter-out b29.dot, $(DOT)) +DOT:=$(filter-out b81.dot, $(DOT)) +DOT:=$(filter-out b100.dot, $(DOT)) +DOT:=$(filter-out b102.dot, $(DOT)) +DOT:=$(filter-out b103.dot, $(DOT)) +DOT:=$(filter-out b104.dot, $(DOT)) +DOT:=$(filter-out root.dot, $(DOT)) +DOT:=$(filter-out root_circo.dot, $(DOT)) +DOT:=$(filter-out root_twopi.dot, $(DOT)) + +# Skip invalid DOT file. +# +# Error: No or improper image file="eqn.png" +# in label of node struct1 +DOT:=$(filter-out html4.dot, $(DOT)) + +# Skip multi-graph DOT file which outputs to standard output. +DOT:=$(filter-out multi.dot, $(DOT)) + +# *.dot -> *.png +PNG=$(DOT:.dot=.png) + +INPUT_PNG=$(addprefix input/,$(PNG)) +OUTPUT_PNG=$(addprefix output/,$(PNG)) + +all: + +test: input $(INPUT_PNG) output $(OUTPUT_PNG) + @echo "PASS" + +input: + mkdir -p $@ + dot -V + +input/%.png: %.dot + dot -Tpng -o $@ $< + +output: + mkdir -p $@ + +output/%.png: %.dot + dotfmt -o "output/$<" $< + dot -Tpng -o $@ "output/$<" + imgcmp "input/$(notdir $@)" $@ + +fetch: graphviz + # Copy *.gv and *.dot files. + find graphviz -type f -name '*.gv' -not -wholename "graphviz/rtest/share/b545.gv" -not -name "base.gv" | xargs -I '{}' cp "{}" . + find graphviz -type f -name '*.dot' | xargs -I '{}' cp "{}" . + + # Rename *.gv to *.dot. + #rename .gv .dot *.gv + ls *.gv | xargs -I '{}' basename "{}" .gv | xargs -I '{}' mv "{}.gv" "{}.dot" + + # Remove execute permissions. + chmod 0644 *.dot + + # Convert Latin1 encoded files to UTF-8. + grep -l "charset=latin1" *.dot | xargs -I '{}' recode ISO-8859-1..UTF8 "{}" + recode ISO-8859-1..UTF8 Latin1.dot + + # Clean up. + rm -rf graphviz + +graphviz: + git clone https://github.com/ellson/graphviz.git + +clean: + rm -rf *.dot input output + +.PHONY: all test fetch clean diff --git a/vendor/gonum.org/v1/gonum/graph/graph.go b/vendor/gonum.org/v1/gonum/graph/graph.go new file mode 100644 index 00000000..0ca587d8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graph.go @@ -0,0 +1,247 @@ +// 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() Node + To() Node +} + +// 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 { + // Has returns whether the node exists within the graph. + Has(Node) bool + + // Nodes returns all the nodes in the graph. + Nodes() []Node + + // From returns all nodes that can be reached directly + // from the given node. + From(Node) []Node + + // HasEdgeBetween returns whether an edge exists between + // nodes x and y without considering direction. + HasEdgeBetween(x, y Node) bool + + // 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. + Edge(u, v Node) Edge +} + +// Weighted is a weighted graph. +type Weighted interface { + Graph + + // 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. + WeightedEdge(u, v Node) WeightedEdge + + // 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 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(x, y Node) (w float64, ok bool) +} + +// Undirected is an undirected graph. +type Undirected interface { + Graph + + // EdgeBetween returns the edge between nodes x and y. + EdgeBetween(x, y Node) Edge +} + +// WeightedUndirected is a weighted undirected graph. +type WeightedUndirected interface { + Weighted + + // WeightedEdgeBetween returns the edge between nodes + // x and y. + WeightedEdgeBetween(x, y Node) WeightedEdge +} + +// Directed is a directed graph. +type Directed interface { + Graph + + // HasEdgeFromTo returns whether an edge exists + // in the graph from u to v. + HasEdgeFromTo(u, v Node) bool + + // To returns all nodes that can reach directly + // to the given node. + To(Node) []Node +} + +// WeightedDirected is a weighted directed graph. +type WeightedDirected interface { + Weighted + + // HasEdgeFromTo returns whether an edge exists + // in the graph from u to v. + HasEdgeFromTo(u, v Node) bool + + // To returns all nodes that can reach directly + // to the given node. + To(Node) []Node +} + +// 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 + + // 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 a node 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(Node) +} + +// 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. + 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. + SetWeightedEdge(e WeightedEdge) +} + +// EdgeRemover is an interface for removing nodes from a graph. +type EdgeRemover interface { + // RemoveEdge removes the given edge, leaving the + // terminal nodes. If the edge does not exist it + // is a no-op. + RemoveEdge(Edge) +} + +// 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 _, n := range nodes { + dst.AddNode(n) + } + for _, u := range nodes { + for _, v := range src.From(u) { + dst.SetEdge(src.Edge(u, v)) + } + } +} + +// 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 _, n := range nodes { + dst.AddNode(n) + } + for _, u := range nodes { + for _, v := range src.From(u) { + dst.SetWeightedEdge(src.WeightedEdge(u, v)) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/batagelj_brandes.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/batagelj_brandes.go new file mode 100644 index 00000000..4c578927 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/batagelj_brandes.go @@ -0,0 +1,357 @@ +// 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. + +// The functions in this file are random graph generators from the paper +// by Batagelj and Brandes http://algo.uni-konstanz.de/publications/bb-eglrn-05.pdf + +package gen + +import ( + "fmt" + "math" + "math/rand" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +// Gnp constructs a Gilbert’s model graph in the destination, dst, of order n. Edges +// between nodes are formed with the probability, p. If src is not nil it is used +// as the random source, otherwise rand.Float64 is used. The graph is constructed +// in O(n+m) time where m is the number of edges added. +func Gnp(dst GraphBuilder, n int, p float64, src *rand.Rand) error { + if p == 0 { + return nil + } + if p < 0 || p > 1 { + return fmt.Errorf("gen: bad probability: p=%v", p) + } + var r func() float64 + if src == nil { + r = rand.Float64 + } else { + r = src.Float64 + } + + for i := 0; i < n; i++ { + if !dst.Has(simple.Node(i)) { + dst.AddNode(simple.Node(i)) + } + } + + lp := math.Log(1 - p) + + // Add forward edges for all graphs. + for v, w := 1, -1; v < n; { + w += 1 + int(math.Log(1-r())/lp) + for w >= v && v < n { + w -= v + v++ + } + if v < n { + dst.SetEdge(simple.Edge{F: simple.Node(w), T: simple.Node(v)}) + } + } + + // Add backward edges for directed graphs. + if _, ok := dst.(graph.Directed); !ok { + return nil + } + for v, w := 1, -1; v < n; { + w += 1 + int(math.Log(1-r())/lp) + for w >= v && v < n { + w -= v + v++ + } + if v < n { + dst.SetEdge(simple.Edge{F: simple.Node(v), T: simple.Node(w)}) + } + } + + return nil +} + +// edgeNodesFor returns the pair of nodes for the ith edge in a simple +// undirected graph. The pair is returned such that w.ID < v.ID. +func edgeNodesFor(i int) (v, w simple.Node) { + // This is an algebraic simplification of the expressions described + // on p3 of http://algo.uni-konstanz.de/publications/bb-eglrn-05.pdf + v = simple.Node(0.5 + math.Sqrt(float64(1+8*i))/2) + w = simple.Node(i) - v*(v-1)/2 + return v, w +} + +// Gnm constructs a Erdős-Rényi model graph in the destination, dst, of +// order n and size m. If src is not nil it is used as the random source, +// otherwise rand.Intn is used. The graph is constructed in O(m) expected +// time for m ≤ (n choose 2)/2. +func Gnm(dst GraphBuilder, n, m int, src *rand.Rand) error { + if m == 0 { + return nil + } + + hasEdge := dst.HasEdgeBetween + d, isDirected := dst.(graph.Directed) + if isDirected { + m /= 2 + hasEdge = d.HasEdgeFromTo + } + + nChoose2 := (n - 1) * n / 2 + if m < 0 || m > nChoose2 { + return fmt.Errorf("gen: bad size: m=%d", m) + } + + var rnd func(int) int + if src == nil { + rnd = rand.Intn + } else { + rnd = src.Intn + } + + for i := 0; i < n; i++ { + if !dst.Has(simple.Node(i)) { + dst.AddNode(simple.Node(i)) + } + } + + // Add forward edges for all graphs. + for i := 0; i < m; i++ { + for { + v, w := edgeNodesFor(rnd(nChoose2)) + e := simple.Edge{F: w, T: v} + if !hasEdge(e.F, e.T) { + dst.SetEdge(e) + break + } + } + } + + // Add backward edges for directed graphs. + if !isDirected { + return nil + } + for i := 0; i < m; i++ { + for { + v, w := edgeNodesFor(rnd(nChoose2)) + e := simple.Edge{F: v, T: w} + if !hasEdge(e.F, e.T) { + dst.SetEdge(e) + break + } + } + } + + return nil +} + +// SmallWorldsBB constructs a small worlds graph of order n in the destination, dst. +// Node degree is specified by d and edge replacement by the probability, p. +// If src is not nil it is used as the random source, otherwise rand.Float64 is used. +// The graph is constructed in O(nd) time. +// +// The algorithm used is described in http://algo.uni-konstanz.de/publications/bb-eglrn-05.pdf +func SmallWorldsBB(dst GraphBuilder, n, d int, p float64, src *rand.Rand) error { + if d < 1 || d > (n-1)/2 { + return fmt.Errorf("gen: bad degree: d=%d", d) + } + if p == 0 { + return nil + } + if p < 0 || p >= 1 { + return fmt.Errorf("gen: bad replacement: p=%v", p) + } + var ( + rnd func() float64 + rndN func(int) int + ) + if src == nil { + rnd = rand.Float64 + rndN = rand.Intn + } else { + rnd = src.Float64 + rndN = src.Intn + } + + hasEdge := dst.HasEdgeBetween + dg, isDirected := dst.(graph.Directed) + if isDirected { + hasEdge = dg.HasEdgeFromTo + } + + for i := 0; i < n; i++ { + if !dst.Has(simple.Node(i)) { + dst.AddNode(simple.Node(i)) + } + } + + nChoose2 := (n - 1) * n / 2 + + lp := math.Log(1 - p) + + // Add forward edges for all graphs. + k := int(math.Log(1-rnd()) / lp) + m := 0 + replace := make(map[int]int) + for v := 0; v < n; v++ { + for i := 1; i <= d; i++ { + if k > 0 { + j := v*(v-1)/2 + (v+i)%n + var ej simple.Edge + ej.T, ej.F = edgeNodesFor(j) + if !hasEdge(ej.From(), ej.To()) { + dst.SetEdge(ej) + } + k-- + m++ + var em simple.Edge + em.T, em.F = edgeNodesFor(m) + if !hasEdge(em.From(), em.To()) { + replace[j] = m + } else { + replace[j] = replace[m] + } + } else { + k = int(math.Log(1-rnd()) / lp) + } + } + } + for i := m + 1; i <= n*d && i < nChoose2; i++ { + r := rndN(nChoose2-i) + i + var er simple.Edge + er.T, er.F = edgeNodesFor(r) + if !hasEdge(er.From(), er.To()) { + dst.SetEdge(er) + } else { + er.T, er.F = edgeNodesFor(replace[r]) + if !hasEdge(er.From(), er.To()) { + dst.SetEdge(er) + } + } + var ei simple.Edge + ei.T, ei.F = edgeNodesFor(i) + if !hasEdge(ei.From(), ei.To()) { + replace[r] = i + } else { + replace[r] = replace[i] + } + } + + // Add backward edges for directed graphs. + if !isDirected { + return nil + } + k = int(math.Log(1-rnd()) / lp) + m = 0 + replace = make(map[int]int) + for v := 0; v < n; v++ { + for i := 1; i <= d; i++ { + if k > 0 { + j := v*(v-1)/2 + (v+i)%n + var ej simple.Edge + ej.F, ej.T = edgeNodesFor(j) + if !hasEdge(ej.From(), ej.To()) { + dst.SetEdge(ej) + } + k-- + m++ + if !hasEdge(edgeNodesFor(m)) { + replace[j] = m + } else { + replace[j] = replace[m] + } + } else { + k = int(math.Log(1-rnd()) / lp) + } + } + } + for i := m + 1; i <= n*d && i < nChoose2; i++ { + r := rndN(nChoose2-i) + i + var er simple.Edge + er.F, er.T = edgeNodesFor(r) + if !hasEdge(er.From(), er.To()) { + dst.SetEdge(er) + } else { + er.F, er.T = edgeNodesFor(replace[r]) + if !hasEdge(er.From(), er.To()) { + dst.SetEdge(er) + } + } + if !hasEdge(edgeNodesFor(i)) { + replace[r] = i + } else { + replace[r] = replace[i] + } + } + + return nil +} + +/* +// Multigraph generators. + +type EdgeAdder interface { + AddEdge(graph.Edge) +} + +func PreferentialAttachment(dst EdgeAdder, n, d int, src *rand.Rand) { + if d < 1 { + panic("gen: bad d") + } + var rnd func(int) int + if src == nil { + rnd = rand.Intn + } else { + rnd = src.Intn + } + + m := make([]simple.Node, 2*n*d) + for v := 0; v < n; v++ { + for i := 0; i < d; i++ { + m[2*(v*d+i)] = simple.Node(v) + m[2*(v*d+i)+1] = simple.Node(m[rnd(2*v*d+i+1)]) + } + } + for i := 0; i < n*d; i++ { + dst.AddEdge(simple.Edge{F: m[2*i], T: m[2*i+1], W: 1}) + } +} + +func BipartitePreferentialAttachment(dst EdgeAdder, n, d int, src *rand.Rand) { + if d < 1 { + panic("gen: bad d") + } + var rnd func(int) int + if src == nil { + rnd = rand.Intn + } else { + rnd = src.Intn + } + + m1 := make([]simple.Node, 2*n*d) + m2 := make([]simple.Node, 2*n*d) + for v := 0; v < n; v++ { + for i := 0; i < d; i++ { + m1[2*(v*d+i)] = simple.Node(v) + m2[2*(v*d+i)] = simple.Node(n + v) + + if r := rnd(2*v*d + i + 1); r&0x1 == 0 { + m1[2*(v*d+i)+1] = m2[r] + } else { + m1[2*(v*d+i)+1] = m1[r] + } + + if r := rnd(2*v*d + i + 1); r&0x1 == 0 { + m2[2*(v*d+i)+1] = m1[r] + } else { + m2[2*(v*d+i)+1] = m2[r] + } + } + } + for i := 0; i < n*d; i++ { + dst.AddEdge(simple.Edge{F: m1[2*i], T: m1[2*i+1], W: 1}) + dst.AddEdge(simple.Edge{F: m2[2*i], T: m2[2*i+1], W: 1}) + } +} +*/ diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/batagelj_brandes_test.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/batagelj_brandes_test.go new file mode 100644 index 00000000..544e2e96 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/batagelj_brandes_test.go @@ -0,0 +1,174 @@ +// 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 gen + +import ( + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +type gnUndirected struct { + graph.UndirectedBuilder + addBackwards bool + addSelfLoop bool + addMultipleEdge bool +} + +func (g *gnUndirected) SetEdge(e graph.Edge) { + switch { + case e.From().ID() == e.To().ID(): + g.addSelfLoop = true + return + case e.From().ID() > e.To().ID(): + g.addBackwards = true + case g.UndirectedBuilder.HasEdgeBetween(e.From(), e.To()): + g.addMultipleEdge = true + } + + g.UndirectedBuilder.SetEdge(e) +} + +type gnDirected struct { + graph.DirectedBuilder + addSelfLoop bool + addMultipleEdge bool +} + +func (g *gnDirected) SetEdge(e graph.Edge) { + switch { + case e.From().ID() == e.To().ID(): + g.addSelfLoop = true + return + case g.DirectedBuilder.HasEdgeFromTo(e.From(), e.To()): + g.addMultipleEdge = true + } + + g.DirectedBuilder.SetEdge(e) +} + +func TestGnpUndirected(t *testing.T) { + for n := 2; n <= 20; n++ { + for p := 0.; p <= 1; p += 0.1 { + g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph()} + err := Gnp(g, n, p, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, p=%v: %v", n, p, err) + } + if g.addBackwards { + t.Errorf("edge added with From.ID > To.ID: n=%d, p=%v", n, p) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, p=%v", n, p) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, p=%v", n, p) + } + } + } +} + +func TestGnpDirected(t *testing.T) { + for n := 2; n <= 20; n++ { + for p := 0.; p <= 1; p += 0.1 { + g := &gnDirected{DirectedBuilder: simple.NewDirectedGraph()} + err := Gnp(g, n, p, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, p=%v: %v", n, p, err) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, p=%v", n, p) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, p=%v", n, p) + } + } + } +} + +func TestGnmUndirected(t *testing.T) { + for n := 2; n <= 20; n++ { + nChoose2 := (n - 1) * n / 2 + for m := 0; m <= nChoose2; m++ { + g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph()} + err := Gnm(g, n, m, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, m=%d: %v", n, m, err) + } + if g.addBackwards { + t.Errorf("edge added with From.ID > To.ID: n=%d, m=%d", n, m) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, m=%d", n, m) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, m=%d", n, m) + } + } + } +} + +func TestGnmDirected(t *testing.T) { + for n := 2; n <= 20; n++ { + nChoose2 := (n - 1) * n / 2 + for m := 0; m <= nChoose2*2; m++ { + g := &gnDirected{DirectedBuilder: simple.NewDirectedGraph()} + err := Gnm(g, n, m, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, m=%d: %v", n, m, err) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, m=%d", n, m) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, m=%d", n, m) + } + } + } +} + +func TestSmallWorldsBBUndirected(t *testing.T) { + for n := 2; n <= 20; n++ { + for d := 1; d <= (n-1)/2; d++ { + for p := 0.; p < 1; p += 0.1 { + g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph()} + err := SmallWorldsBB(g, n, d, p, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, d=%d, p=%v: %v", n, d, p, err) + } + if g.addBackwards { + t.Errorf("edge added with From.ID > To.ID: n=%d, d=%d, p=%v", n, d, p) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, d=%d, p=%v", n, d, p) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, d=%d, p=%v", n, d, p) + } + } + } + } +} + +func TestSmallWorldsBBDirected(t *testing.T) { + for n := 2; n <= 20; n++ { + for d := 1; d <= (n-1)/2; d++ { + for p := 0.; p < 1; p += 0.1 { + g := &gnDirected{DirectedBuilder: simple.NewDirectedGraph()} + err := SmallWorldsBB(g, n, d, p, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, d=%d, p=%v: %v", n, d, p, err) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, d=%d, p=%v", n, d, p) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, d=%d, p=%v", n, d, p) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/doc.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/doc.go new file mode 100644 index 00000000..f5ebfcb5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gen provides random graph generation functions. +package gen // import "gonum.org/v1/gonum/graph/graphs/gen" diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/duplication.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/duplication.go new file mode 100644 index 00000000..8ffa578d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/duplication.go @@ -0,0 +1,125 @@ +// 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 gen + +import ( + "fmt" + "math" + "math/rand" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" +) + +// UndirectedMutator is an undirected graph builder that can remove edges. +type UndirectedMutator interface { + graph.UndirectedBuilder + graph.EdgeRemover +} + +// Duplication constructs a graph in the destination, dst, of order n. New nodes +// are created by duplicating an existing node and all its edges. Each new edge is +// deleted with probability delta. Additional edges are added between the new node +// and existing nodes with probability alpha/|V|. An exception to this addition +// rule is made for the parent node when sigma is not NaN; in this case an edge is +// created with probability sigma. With the exception of the sigma parameter, this +// corresponds to the completely correlated case in doi:10.1016/S0022-5193(03)00028-6. +// If src is not nil it is used as the random source, otherwise rand.Float64 is used. +func Duplication(dst UndirectedMutator, n int, delta, alpha, sigma float64, src *rand.Rand) error { + // As described in doi:10.1016/S0022-5193(03)00028-6 but + // also clarified in doi:10.1186/gb-2007-8-4-r51. + + if delta < 0 || delta > 1 { + return fmt.Errorf("gen: bad delta: delta=%v", delta) + } + if alpha <= 0 || alpha > 1 { + return fmt.Errorf("gen: bad alpha: alpha=%v", alpha) + } + if sigma < 0 || sigma > 1 { + return fmt.Errorf("gen: bad sigma: sigma=%v", sigma) + } + + var ( + rnd func() float64 + rndN func(int) int + ) + if src == nil { + rnd = rand.Float64 + rndN = rand.Intn + } else { + rnd = src.Float64 + rndN = src.Intn + } + + nodes := dst.Nodes() + sort.Sort(ordered.ByID(nodes)) + if len(nodes) == 0 { + n-- + u := dst.NewNode() + dst.AddNode(u) + nodes = append(nodes, u) + } + for i := 0; i < n; i++ { + u := nodes[rndN(len(nodes))] + d := dst.NewNode() + + // Add the duplicate node. + dst.AddNode(d) + + // Loop until we have connectivity + // into the rest of the graph. + for { + // Add edges to parent's neighbours. + to := dst.From(u) + sort.Sort(ordered.ByID(to)) + for _, v := range to { + if rnd() < delta || dst.HasEdgeBetween(v, d) { + continue + } + if v.ID() < d.ID() { + dst.SetEdge(dst.NewEdge(v, d)) + } else { + dst.SetEdge(dst.NewEdge(d, v)) + } + } + + // Add edges to old nodes. + scaledAlpha := alpha / float64(len(nodes)) + for _, v := range nodes { + switch v.ID() { + case u.ID(): + if !math.IsNaN(sigma) { + if i == 0 || rnd() < sigma { + if v.ID() < d.ID() { + dst.SetEdge(dst.NewEdge(v, d)) + } else { + dst.SetEdge(dst.NewEdge(d, v)) + } + } + continue + } + fallthrough + default: + if rnd() < scaledAlpha && !dst.HasEdgeBetween(v, d) { + if v.ID() < d.ID() { + dst.SetEdge(dst.NewEdge(v, d)) + } else { + dst.SetEdge(dst.NewEdge(d, v)) + } + } + } + } + + if len(dst.From(d)) != 0 { + break + } + } + + nodes = append(nodes, d) + } + + return nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/duplication_test.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/duplication_test.go new file mode 100644 index 00000000..b58eb899 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/duplication_test.go @@ -0,0 +1,58 @@ +// 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 gen + +import ( + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +type duplication struct { + UndirectedMutator + addBackwards bool + addSelfLoop bool + addMultipleEdge bool +} + +func (g *duplication) SetEdge(e graph.Edge) { + switch { + case e.From().ID() == e.To().ID(): + g.addSelfLoop = true + return + case e.From().ID() > e.To().ID(): + g.addBackwards = true + case g.UndirectedMutator.HasEdgeBetween(e.From(), e.To()): + g.addMultipleEdge = true + } + + g.UndirectedMutator.SetEdge(e) +} + +func TestDuplication(t *testing.T) { + for n := 2; n <= 50; n++ { + for alpha := 0.1; alpha <= 1; alpha += 0.1 { + for delta := 0.; delta <= 1; delta += 0.2 { + for sigma := 0.; sigma <= 1; sigma += 0.2 { + g := &duplication{UndirectedMutator: simple.NewUndirectedGraph()} + err := Duplication(g, n, delta, alpha, sigma, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, alpha=%v, delta=%v sigma=%v: %v", n, alpha, delta, sigma, err) + } + if g.addBackwards { + t.Errorf("edge added with From.ID > To.ID: n=%d, alpha=%v, delta=%v sigma=%v", n, alpha, delta, sigma) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, alpha=%v, delta=%v sigma=%v", n, alpha, delta, sigma) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, alpha=%v, delta=%v sigma=%v", n, alpha, delta, sigma) + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/gen.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/gen.go new file mode 100644 index 00000000..85c484e6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/gen.go @@ -0,0 +1,21 @@ +// 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 gen + +import "gonum.org/v1/gonum/graph" + +// GraphBuilder is a graph that can have nodes and edges added. +type GraphBuilder interface { + Has(graph.Node) bool + HasEdgeBetween(x, y graph.Node) bool + graph.Builder +} + +func abs(a int) int { + if a < 0 { + return -a + } + return a +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/holme_kim.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/holme_kim.go new file mode 100644 index 00000000..457fb1be --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/holme_kim.go @@ -0,0 +1,160 @@ +// 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 gen + +import ( + "errors" + "fmt" + "math/rand" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" + "gonum.org/v1/gonum/stat/sampleuv" +) + +// TunableClusteringScaleFree constructs a graph in the destination, dst, of order n. +// The graph is constructed successively starting from an m order graph with one node +// having degree m-1. At each iteration of graph addition, one node is added with m +// additional edges joining existing nodes with probability proportional to the nodes' +// degrees. The edges are formed as a triad with probability, p. +// If src is not nil it is used as the random source, otherwise rand.Float64 and +// rand.Intn are used. +// +// The algorithm is essentially as described in http://arxiv.org/abs/cond-mat/0110452. +func TunableClusteringScaleFree(dst graph.UndirectedBuilder, n, m int, p float64, src *rand.Rand) error { + if p < 0 || p > 1 { + return fmt.Errorf("gen: bad probability: p=%v", p) + } + if n <= m { + return fmt.Errorf("gen: n <= m: n=%v m=%d", n, m) + } + + var ( + rnd func() float64 + rndN func(int) int + ) + if src == nil { + rnd = rand.Float64 + rndN = rand.Intn + } else { + rnd = src.Float64 + rndN = src.Intn + } + + // Initial condition. + wt := make([]float64, n) + for u := 0; u < m; u++ { + if !dst.Has(simple.Node(u)) { + dst.AddNode(simple.Node(u)) + } + // We need to give equal probability for + // adding the first generation of edges. + wt[u] = 1 + } + ws := sampleuv.NewWeighted(wt, src) + for i := range wt { + // These weights will organically grow + // after the first growth iteration. + wt[i] = 0 + } + + // Growth. + for v := m; v < n; v++ { + var u int + pa: + for i := 0; i < m; i++ { + // Triad formation. + if i != 0 && rnd() < p { + for _, w := range permute(dst.From(simple.Node(u)), rndN) { + wid := w.ID() + if wid == int64(v) || dst.HasEdgeBetween(w, simple.Node(v)) { + continue + } + dst.SetEdge(simple.Edge{F: w, T: simple.Node(v)}) + wt[wid]++ + wt[v]++ + continue pa + } + } + + // Preferential attachment. + for { + var ok bool + u, ok = ws.Take() + if !ok { + return errors.New("gen: depleted distribution") + } + if u == v || dst.HasEdgeBetween(simple.Node(u), simple.Node(v)) { + continue + } + dst.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + wt[u]++ + wt[v]++ + break + } + } + + ws.ReweightAll(wt) + } + + return nil +} + +func permute(n []graph.Node, rnd func(int) int) []graph.Node { + for i := range n[:len(n)-1] { + j := rnd(len(n)-i) + i + n[i], n[j] = n[j], n[i] + } + return n +} + +// PreferentialAttachment constructs a graph in the destination, dst, of order n. +// The graph is constructed successively starting from an m order graph with one +// node having degree m-1. At each iteration of graph addition, one node is added +// with m additional edges joining existing nodes with probability proportional +// to the nodes' degrees. If src is not nil it is used as the random source, +// otherwise rand.Float64 is used. +// +// The algorithm is essentially as described in http://arxiv.org/abs/cond-mat/0110452 +// after 10.1126/science.286.5439.509. +func PreferentialAttachment(dst graph.UndirectedBuilder, n, m int, src *rand.Rand) error { + if n <= m { + return fmt.Errorf("gen: n <= m: n=%v m=%d", n, m) + } + + // Initial condition. + wt := make([]float64, n) + for u := 0; u < m; u++ { + if !dst.Has(simple.Node(u)) { + dst.AddNode(simple.Node(u)) + } + // We need to give equal probability for + // adding the first generation of edges. + wt[u] = 1 + } + ws := sampleuv.NewWeighted(wt, src) + for i := range wt { + // These weights will organically grow + // after the first growth iteration. + wt[i] = 0 + } + + // Growth. + for v := m; v < n; v++ { + for i := 0; i < m; i++ { + // Preferential attachment. + u, ok := ws.Take() + if !ok { + return errors.New("gen: depleted distribution") + } + dst.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + wt[u]++ + wt[v]++ + } + ws.ReweightAll(wt) + } + + return nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/holme_kim_test.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/holme_kim_test.go new file mode 100644 index 00000000..82eb62a8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/holme_kim_test.go @@ -0,0 +1,55 @@ +// 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 gen + +import ( + "testing" + + "gonum.org/v1/gonum/graph/simple" +) + +func TestTunableClusteringScaleFree(t *testing.T) { + for n := 2; n <= 20; n++ { + for m := 0; m < n; m++ { + for p := 0.; p <= 1; p += 0.1 { + g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph()} + err := TunableClusteringScaleFree(g, n, m, p, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, m=%d, p=%v: %v", n, m, p, err) + } + if g.addBackwards { + t.Errorf("edge added with From.ID > To.ID: n=%d, m=%d, p=%v", n, m, p) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, m=%d, p=%v", n, m, p) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, m=%d, p=%v", n, m, p) + } + } + } + } +} + +func TestPreferentialAttachment(t *testing.T) { + for n := 2; n <= 20; n++ { + for m := 0; m < n; m++ { + g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph()} + err := PreferentialAttachment(g, n, m, nil) + if err != nil { + t.Fatalf("unexpected error: n=%d, m=%d: %v", n, m, err) + } + if g.addBackwards { + t.Errorf("edge added with From.ID > To.ID: n=%d, m=%d", n, m) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: n=%d, m=%d", n, m) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: n=%d, m=%d", n, m) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/small_world.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/small_world.go new file mode 100644 index 00000000..3ff40e87 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/small_world.go @@ -0,0 +1,204 @@ +// 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 gen + +import ( + "errors" + "fmt" + "math" + "math/rand" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" + "gonum.org/v1/gonum/stat/sampleuv" +) + +// NavigableSmallWorld constructs an N-dimensional grid with guaranteed local connectivity +// and random long-range connectivity in the destination, dst. The dims parameters specifies +// the length of each of the N dimensions, p defines the Manhattan distance between local +// nodes, and q defines the number of out-going long-range connections from each node. Long- +// range connections are made with a probability proportional to |d(u,v)|^-r where d is the +// Manhattan distance between non-local nodes. +// +// The algorithm is essentially as described on p4 of http://www.cs.cornell.edu/home/kleinber/swn.pdf. +func NavigableSmallWorld(dst GraphBuilder, dims []int, p, q int, r float64, src *rand.Rand) (err error) { + if p < 1 { + return fmt.Errorf("gen: bad local distance: p=%v", p) + } + if q < 0 { + return fmt.Errorf("gen: bad distant link count: q=%v", q) + } + if r < 0 { + return fmt.Errorf("gen: bad decay constant: r=%v", r) + } + + n := 1 + for _, d := range dims { + n *= d + } + for i := 0; i < n; i++ { + if !dst.Has(simple.Node(i)) { + dst.AddNode(simple.Node(i)) + } + } + + hasEdge := dst.HasEdgeBetween + d, isDirected := dst.(graph.Directed) + if isDirected { + hasEdge = d.HasEdgeFromTo + } + + locality := make([]int, len(dims)) + for i := range locality { + locality[i] = p*2 + 1 + } + iterateOver(dims, func(u []int) { + uid := idFrom(u, dims) + iterateOver(locality, func(delta []int) { + d := manhattanDelta(u, delta, dims, -p) + if d == 0 || d > p { + return + } + vid := idFromDelta(u, delta, dims, -p) + e := simple.Edge{F: simple.Node(uid), T: simple.Node(vid)} + if uid > vid { + e.F, e.T = e.T, e.F + } + if !hasEdge(e.From(), e.To()) { + dst.SetEdge(e) + } + if !isDirected { + return + } + e.F, e.T = e.T, e.F + if !hasEdge(e.From(), e.To()) { + dst.SetEdge(e) + } + }) + }) + + defer func() { + r := recover() + if r != nil { + if r != "depleted distribution" { + panic(r) + } + err = errors.New("depleted distribution") + } + }() + w := make([]float64, n) + ws := sampleuv.NewWeighted(w, src) + iterateOver(dims, func(u []int) { + uid := idFrom(u, dims) + iterateOver(dims, func(v []int) { + d := manhattanBetween(u, v) + if d <= p { + return + } + w[idFrom(v, dims)] = math.Pow(float64(d), -r) + }) + ws.ReweightAll(w) + for i := 0; i < q; i++ { + vid, ok := ws.Take() + if !ok { + panic("depleted distribution") + } + e := simple.Edge{F: simple.Node(uid), T: simple.Node(vid)} + if !isDirected && uid > vid { + e.F, e.T = e.T, e.F + } + if !hasEdge(e.From(), e.To()) { + dst.SetEdge(e) + } + } + for i := range w { + w[i] = 0 + } + }) + + return nil +} + +// iterateOver performs an iteration over all dimensions of dims, calling fn +// for each state. The elements of state must not be mutated by fn. +func iterateOver(dims []int, fn func(state []int)) { + iterator(0, dims, make([]int, len(dims)), fn) +} + +func iterator(d int, dims, state []int, fn func(state []int)) { + if d >= len(dims) { + fn(state) + return + } + for i := 0; i < dims[d]; i++ { + state[d] = i + iterator(d+1, dims, state, fn) + } +} + +// manhattanBetween returns the Manhattan distance between a and b. +func manhattanBetween(a, b []int) int { + if len(a) != len(b) { + panic("gen: unexpected dimension") + } + var d int + for i, v := range a { + d += abs(v - b[i]) + } + return d +} + +// manhattanDelta returns the Manhattan norm of delta+translate. If a +// translated by delta+translate is out of the range given by dims, +// zero is returned. +func manhattanDelta(a, delta, dims []int, translate int) int { + if len(a) != len(dims) { + panic("gen: unexpected dimension") + } + if len(delta) != len(dims) { + panic("gen: unexpected dimension") + } + var d int + for i, v := range delta { + v += translate + t := a[i] + v + if t < 0 || t >= dims[i] { + return 0 + } + d += abs(v) + } + return d +} + +// idFrom returns a node id for the slice n over the given dimensions. +func idFrom(n, dims []int) int { + s := 1 + var id int + for d, m := range dims { + p := n[d] + if p < 0 || p >= m { + panic("gen: element out of range") + } + id += p * s + s *= m + } + return id +} + +// idFromDelta returns a node id for the slice base plus the delta over the given +// dimensions and applying the translation. +func idFromDelta(base, delta, dims []int, translate int) int { + s := 1 + var id int + for d, m := range dims { + n := base[d] + delta[d] + translate + if n < 0 || n >= m { + panic("gen: element out of range") + } + id += n * s + s *= m + } + return id +} diff --git a/vendor/gonum.org/v1/gonum/graph/graphs/gen/small_world_test.go b/vendor/gonum.org/v1/gonum/graph/graphs/gen/small_world_test.go new file mode 100644 index 00000000..ef667146 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/graphs/gen/small_world_test.go @@ -0,0 +1,72 @@ +// 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 gen + +import ( + "testing" + + "gonum.org/v1/gonum/graph/simple" +) + +var smallWorldDimensionParameters = [][]int{ + {50}, + {10, 10}, + {6, 5, 4}, +} + +func TestNavigableSmallWorldUndirected(t *testing.T) { + for p := 1; p < 5; p++ { + for q := 0; q < 10; q++ { + for r := 0.5; r < 10; r++ { + for _, dims := range smallWorldDimensionParameters { + g := &gnUndirected{UndirectedBuilder: simple.NewUndirectedGraph()} + err := NavigableSmallWorld(g, dims, p, q, r, nil) + n := 1 + for _, d := range dims { + n *= d + } + if err != nil { + t.Fatalf("unexpected error: dims=%v n=%d, p=%d, q=%d, r=%v: %v", dims, n, p, q, r, err) + } + if g.addBackwards { + t.Errorf("edge added with From.ID > To.ID: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) + } + } + } + } + } +} + +func TestNavigableSmallWorldDirected(t *testing.T) { + for p := 1; p < 5; p++ { + for q := 0; q < 10; q++ { + for r := 0.5; r < 10; r++ { + for _, dims := range smallWorldDimensionParameters { + g := &gnDirected{DirectedBuilder: simple.NewDirectedGraph()} + err := NavigableSmallWorld(g, dims, p, q, r, nil) + n := 1 + for _, d := range dims { + n *= d + } + if err != nil { + t.Fatalf("unexpected error: dims=%v n=%d, p=%d, q=%d, r=%v: %v", dims, n, p, q, r, err) + } + if g.addSelfLoop { + t.Errorf("unexpected self edge: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) + } + if g.addMultipleEdge { + t.Errorf("unexpected multiple edge: dims=%v n=%d, p=%d, q=%d, r=%v", dims, n, p, q, r) + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/internal/linear/doc.go b/vendor/gonum.org/v1/gonum/graph/internal/linear/doc.go new file mode 100644 index 00000000..8828a561 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/linear/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package linear provides common linear data structures. +package linear // import "gonum.org/v1/gonum/graph/internal/linear" diff --git a/vendor/gonum.org/v1/gonum/graph/internal/linear/linear.go b/vendor/gonum.org/v1/gonum/graph/internal/linear/linear.go new file mode 100644 index 00000000..610b45eb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/linear/linear.go @@ -0,0 +1,73 @@ +// 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 linear + +import ( + "gonum.org/v1/gonum/graph" +) + +// NodeStack implements a LIFO stack of graph.Node. +type NodeStack []graph.Node + +// Len returns the number of graph.Nodes on the stack. +func (s *NodeStack) Len() int { return len(*s) } + +// Pop returns the last graph.Node on the stack and removes it +// from the stack. +func (s *NodeStack) Pop() graph.Node { + v := *s + v, n := v[:len(v)-1], v[len(v)-1] + *s = v + return n +} + +// Push adds the node n to the stack at the last position. +func (s *NodeStack) Push(n graph.Node) { *s = append(*s, n) } + +// NodeQueue implements a FIFO queue. +type NodeQueue struct { + head int + data []graph.Node +} + +// Len returns the number of graph.Nodes in the queue. +func (q *NodeQueue) Len() int { return len(q.data) - q.head } + +// Enqueue adds the node n to the back of the queue. +func (q *NodeQueue) Enqueue(n graph.Node) { + if len(q.data) == cap(q.data) && q.head > 0 { + l := q.Len() + copy(q.data, q.data[q.head:]) + q.head = 0 + q.data = append(q.data[:l], n) + } else { + q.data = append(q.data, n) + } +} + +// Dequeue returns the graph.Node at the front of the queue and +// removes it from the queue. +func (q *NodeQueue) Dequeue() graph.Node { + if q.Len() == 0 { + panic("queue: empty queue") + } + + var n graph.Node + n, q.data[q.head] = q.data[q.head], nil + q.head++ + + if q.Len() == 0 { + q.head = 0 + q.data = q.data[:0] + } + + return n +} + +// Reset clears the queue for reuse. +func (q *NodeQueue) Reset() { + q.head = 0 + q.data = q.data[:0] +} diff --git a/vendor/gonum.org/v1/gonum/graph/internal/ordered/doc.go b/vendor/gonum.org/v1/gonum/graph/internal/ordered/doc.go new file mode 100644 index 00000000..8220c8fd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/ordered/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ordered provides common sort ordering types. +package ordered // import "gonum.org/v1/gonum/graph/internal/ordered" diff --git a/vendor/gonum.org/v1/gonum/graph/internal/ordered/sort.go b/vendor/gonum.org/v1/gonum/graph/internal/ordered/sort.go new file mode 100644 index 00000000..4342daf1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/ordered/sort.go @@ -0,0 +1,69 @@ +// 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] } diff --git a/vendor/gonum.org/v1/gonum/graph/internal/set/doc.go b/vendor/gonum.org/v1/gonum/graph/internal/set/doc.go new file mode 100644 index 00000000..383615ef --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/set/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package set provides integer and graph.Node sets. +package set // import "gonum.org/v1/gonum/graph/internal/set" diff --git a/vendor/gonum.org/v1/gonum/graph/internal/set/same.go b/vendor/gonum.org/v1/gonum/graph/internal/set/same.go new file mode 100644 index 00000000..c776dc32 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/set/same.go @@ -0,0 +1,36 @@ +// 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 + +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)) +} diff --git a/vendor/gonum.org/v1/gonum/graph/internal/set/same_appengine.go b/vendor/gonum.org/v1/gonum/graph/internal/set/same_appengine.go new file mode 100644 index 00000000..082ed265 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/set/same_appengine.go @@ -0,0 +1,36 @@ +// 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 + +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() +} diff --git a/vendor/gonum.org/v1/gonum/graph/internal/set/set.go b/vendor/gonum.org/v1/gonum/graph/internal/set/set.go new file mode 100644 index 00000000..339e9f63 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/set/set.go @@ -0,0 +1,256 @@ +// 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 + +// 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()) +} + +// Has reports the existence of the element in the set. +func (s Nodes) Has(n graph.Node) bool { + _, ok := s[n.ID()] + return ok +} + +// clear clears the set, possibly using the same backing store. +func (s *Nodes) clear() { + if len(*s) != 0 { + *s = make(Nodes) + } +} + +// Copy performs a perfect copy from src to dst (meaning the sets will +// be equal). +func (dst Nodes) Copy(src Nodes) Nodes { + if same(src, dst) { + return dst + } + + if len(dst) > 0 { + dst = make(Nodes, len(src)) + } + + 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 +} + +// Union takes the union of a and b, and stores it in dst. +// +// 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 (dst Nodes) Union(a, b Nodes) Nodes { + if same(a, b) { + return dst.Copy(a) + } + + if !same(a, dst) && !same(b, dst) { + dst.clear() + } + + if !same(dst, a) { + for e, n := range a { + dst[e] = n + } + } + + if !same(dst, b) { + for e, n := range b { + dst[e] = n + } + } + + return dst +} + +// Intersect takes the intersection of a and b, and stores it in dst. +// +// 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 (dst Nodes) Intersect(a, b Nodes) Nodes { + var swap Nodes + + if same(a, b) { + return dst.Copy(a) + } + if same(a, dst) { + swap = b + } else if same(b, dst) { + swap = a + } else { + dst.clear() + + if len(a) > len(b) { + a, b = b, a + } + + for e, n := range a { + if _, ok := b[e]; ok { + dst[e] = n + } + } + + return dst + } + + for e := range dst { + if _, ok := swap[e]; !ok { + delete(dst, e) + } + } + + return dst +} diff --git a/vendor/gonum.org/v1/gonum/graph/internal/set/set_test.go b/vendor/gonum.org/v1/gonum/graph/internal/set/set_test.go new file mode 100644 index 00000000..f665b398 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/internal/set/set_test.go @@ -0,0 +1,413 @@ +// 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 "testing" + +type node int64 + +func (n node) ID() int64 { return int64(n) } + +// count reports the number of elements stored in the node set. +func (s Nodes) count() int { + return len(s) +} + +// TestSame tests the assumption that pointer equality via unsafe conversion +// of a map[int]struct{} to uintptr is a valid test for perfect identity between +// set values. If any of the tests in TestSame fail, the package is broken and same +// must be reimplemented to conform to the runtime map implementation. The relevant +// code to look at (at least for gc) is in runtime/hashmap.{h,goc}. +func TestSame(t *testing.T) { + var ( + a = make(Nodes) + b = make(Nodes) + c = a + ) + + if same(a, b) { + t.Error("Independently created sets test as same") + } + if !same(a, c) { + t.Error("Set copy and original test as not same.") + } + a.Add(node(1)) + if !same(a, c) { + t.Error("Set copy and original test as not same after addition.") + } + if !same(nil, nil) { + t.Error("nil sets test as not same.") + } + if same(b, nil) { + t.Error("nil and empty sets test as same.") + } +} + +func TestAdd(t *testing.T) { + s := make(Nodes) + if s == nil { + t.Fatal("Set cannot be created successfully") + } + + if s.count() != 0 { + t.Error("Set somehow contains new elements upon creation") + } + + s.Add(node(1)) + s.Add(node(3)) + s.Add(node(5)) + + if s.count() != 3 { + t.Error("Incorrect number of set elements after adding") + } + + if !s.Has(node(1)) || !s.Has(node(3)) || !s.Has(node(5)) { + t.Error("Set doesn't contain element that was added") + } + + s.Add(node(1)) + + if s.count() > 3 { + t.Error("Set double-adds element (element not unique)") + } else if s.count() < 3 { + t.Error("Set double-add lowered len") + } + + if !s.Has(node(1)) { + t.Error("Set doesn't contain double-added element") + } + + if !s.Has(node(3)) || !s.Has(node(5)) { + t.Error("Set removes element on double-add") + } + + for e, n := range s { + if e != n.ID() { + t.Errorf("Element ID did not match key: %d != %d", e, n.ID()) + } + } +} + +func TestRemove(t *testing.T) { + s := make(Nodes) + + s.Add(node(1)) + s.Add(node(3)) + s.Add(node(5)) + + s.Remove(node(1)) + + if s.count() != 2 { + t.Error("Incorrect number of set elements after removing an element") + } + + if s.Has(node(1)) { + t.Error("Element present after removal") + } + + if !s.Has(node(3)) || !s.Has(node(5)) { + t.Error("Set remove removed wrong element") + } + + s.Remove(node(1)) + + if s.count() != 2 || s.Has(node(1)) { + t.Error("Double set remove does something strange") + } + + s.Add(node(1)) + + if s.count() != 3 || !s.Has(node(1)) { + t.Error("Cannot add element after removal") + } +} + +func TestClear(t *testing.T) { + s := make(Nodes) + + s.Add(node(8)) + s.Add(node(9)) + s.Add(node(10)) + + s.clear() + + if s.count() != 0 { + t.Error("clear did not properly reset set to size 0") + } +} + +func TestSelfEqual(t *testing.T) { + s := make(Nodes) + + if !Equal(s, s) { + t.Error("Set is not equal to itself") + } + + s.Add(node(1)) + + if !Equal(s, s) { + t.Error("Set ceases self equality after adding element") + } +} + +func TestEqual(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + + if !Equal(a, b) { + t.Error("Two different empty sets not equal") + } + + a.Add(node(1)) + if Equal(a, b) { + t.Error("Two different sets with different elements not equal") + } + + b.Add(node(1)) + if !Equal(a, b) { + t.Error("Two sets with same element not equal") + } +} + +func TestCopy(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + + a.Add(node(1)) + a.Add(node(2)) + a.Add(node(3)) + + b.Copy(a) + + if !Equal(a, b) { + t.Fatalf("Two sets not equal after copy") + } + + b.Remove(node(1)) + + if Equal(a, b) { + t.Errorf("Mutating one set mutated another after copy") + } +} + +func TestSelfCopy(t *testing.T) { + a := make(Nodes) + + a.Add(node(1)) + a.Add(node(2)) + + a.Copy(a) + + if a.count() != 2 { + t.Error("Something strange happened when copying into self") + } +} + +func TestUnionSame(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + c := make(Nodes) + + a.Add(node(1)) + a.Add(node(2)) + + b.Add(node(1)) + b.Add(node(2)) + + c.Union(a, b) + + if c.count() != 2 { + t.Error("Union of same sets yields set with wrong len") + } + + if !c.Has(node(1)) || !c.Has(node(2)) { + t.Error("Union of same sets yields wrong elements") + } + + for i, s := range []Nodes{a, b, c} { + for e, n := range s { + if e != n.ID() { + t.Errorf("Element ID did not match key in s%d: %d != %d", i+1, e, n.ID()) + } + } + } +} + +func TestUnionDiff(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + c := make(Nodes) + + a.Add(node(1)) + a.Add(node(2)) + + b.Add(node(3)) + + c.Union(a, b) + + if c.count() != 3 { + t.Error("Union of different sets yields set with wrong len") + } + + if !c.Has(node(1)) || !c.Has(node(2)) || !c.Has(node(3)) { + t.Error("Union of different sets yields set with wrong elements") + } + + if a.Has(node(3)) || !a.Has(node(2)) || !a.Has(node(1)) || a.count() != 2 { + t.Error("Union of sets mutates non-destination set (argument 1)") + } + + if !b.Has(node(3)) || b.Has(node(1)) || b.Has(node(2)) || b.count() != 1 { + t.Error("Union of sets mutates non-destination set (argument 2)") + } + + for i, s := range []Nodes{a, b, c} { + for e, n := range s { + if e != n.ID() { + t.Errorf("Element ID did not match key in s%d: %d != %d", i+1, e, n.ID()) + } + } + } +} + +func TestUnionOverlapping(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + c := make(Nodes) + + a.Add(node(1)) + a.Add(node(2)) + + b.Add(node(2)) + b.Add(node(3)) + + c.Union(a, b) + + if c.count() != 3 { + t.Error("Union of overlapping sets yields set with wrong len") + } + + if !c.Has(node(1)) || !c.Has(node(2)) || !c.Has(node(3)) { + t.Error("Union of overlapping sets yields set with wrong elements") + } + + if a.Has(node(3)) || !a.Has(node(2)) || !a.Has(node(1)) || a.count() != 2 { + t.Error("Union of sets mutates non-destination set (argument 1)") + } + + if !b.Has(node(3)) || b.Has(node(1)) || !b.Has(node(2)) || b.count() != 2 { + t.Error("Union of sets mutates non-destination set (argument 2)") + } + + for i, s := range []Nodes{a, b, c} { + for e, n := range s { + if e != n.ID() { + t.Errorf("Element ID did not match key in s%d: %d != %d", i+1, e, n.ID()) + } + } + } +} + +func TestIntersectSame(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + c := make(Nodes) + + a.Add(node(2)) + a.Add(node(3)) + + b.Add(node(2)) + b.Add(node(3)) + + c.Intersect(a, b) + + if card := c.count(); card != 2 { + t.Errorf("Intersection of identical sets yields set of wrong len %d", card) + } + + if !c.Has(node(2)) || !c.Has(node(3)) { + t.Error("Intersection of identical sets yields set of wrong elements") + } + + for i, s := range []Nodes{a, b, c} { + for e, n := range s { + if e != n.ID() { + t.Errorf("Element ID did not match key in s%d: %d != %d", i+1, e, n.ID()) + } + } + } +} + +func TestIntersectDiff(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + c := make(Nodes) + + a.Add(node(2)) + a.Add(node(3)) + + b.Add(node(1)) + b.Add(node(4)) + + c.Intersect(a, b) + + if card := c.count(); card != 0 { + t.Errorf("Intersection of different yields non-empty set %d", card) + } + + if !a.Has(node(2)) || !a.Has(node(3)) || a.Has(node(1)) || a.Has(node(4)) || a.count() != 2 { + t.Error("Intersection of sets mutates non-destination set (argument 1)") + } + + if b.Has(node(2)) || b.Has(node(3)) || !b.Has(node(1)) || !b.Has(node(4)) || b.count() != 2 { + t.Error("Intersection of sets mutates non-destination set (argument 1)") + } + + for i, s := range []Nodes{a, b, c} { + for e, n := range s { + if e != n.ID() { + t.Errorf("Element ID did not match key in s%d: %d != %d", i+1, e, n.ID()) + } + } + } +} + +func TestIntersectOverlapping(t *testing.T) { + a := make(Nodes) + b := make(Nodes) + c := make(Nodes) + + a.Add(node(2)) + a.Add(node(3)) + + b.Add(node(3)) + b.Add(node(4)) + + c.Intersect(a, b) + + if card := c.count(); card != 1 { + t.Errorf("Intersection of overlapping sets yields set of incorrect len %d", card) + } + + if !c.Has(node(3)) { + t.Errorf("Intersection of overlapping sets yields set with wrong element") + } + + if !a.Has(node(2)) || !a.Has(node(3)) || a.Has(node(4)) || a.count() != 2 { + t.Error("Intersection of sets mutates non-destination set (argument 1)") + } + + if b.Has(node(2)) || !b.Has(node(3)) || !b.Has(node(4)) || b.count() != 2 { + t.Error("Intersection of sets mutates non-destination set (argument 1)") + } + + for i, s := range []Nodes{a, b, c} { + for e, n := range s { + if e != n.ID() { + t.Errorf("Element ID did not match key in s%d: %d != %d", i+1, e, n.ID()) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/network/betweenness.go b/vendor/gonum.org/v1/gonum/graph/network/betweenness.go new file mode 100644 index 00000000..547f44f7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/betweenness.go @@ -0,0 +1,250 @@ +// 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 network + +import ( + "math" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/linear" + "gonum.org/v1/gonum/graph/path" +) + +// Betweenness returns the non-zero betweenness centrality for nodes in the unweighted graph g. +// +// C_B(v) = \sum_{s ≠ v ≠ t ∈ V} (\sigma_{st}(v) / \sigma_{st}) +// +// where \sigma_{st} and \sigma_{st}(v) are the number of shortest paths from s to t, +// and the subset of those paths containing v respectively. +func Betweenness(g graph.Graph) map[int64]float64 { + // Brandes' algorithm for finding betweenness centrality for nodes in + // and unweighted graph: + // + // http://www.inf.uni-konstanz.de/algo/publications/b-fabc-01.pdf + + // TODO(kortschak): Consider using the parallel algorithm when + // GOMAXPROCS != 1. + // + // http://htor.inf.ethz.ch/publications/img/edmonds-hoefler-lumsdaine-bc.pdf + + // Also note special case for sparse networks: + // http://wwwold.iit.cnr.it/staff/marco.pellegrini/papiri/asonam-final.pdf + + cb := make(map[int64]float64) + brandes(g, func(s graph.Node, stack linear.NodeStack, p map[int64][]graph.Node, delta, sigma map[int64]float64) { + for stack.Len() != 0 { + w := stack.Pop() + for _, v := range p[w.ID()] { + delta[v.ID()] += sigma[v.ID()] / sigma[w.ID()] * (1 + delta[w.ID()]) + } + if w.ID() != s.ID() { + if d := delta[w.ID()]; d != 0 { + cb[w.ID()] += d + } + } + } + }) + return cb +} + +// EdgeBetweenness returns the non-zero betweenness centrality for edges in the +// unweighted graph g. For an edge e the centrality C_B is computed as +// +// C_B(e) = \sum_{s ≠ t ∈ V} (\sigma_{st}(e) / \sigma_{st}), +// +// where \sigma_{st} and \sigma_{st}(e) are the number of shortest paths from s +// to t, and the subset of those paths containing e, respectively. +// +// If g is undirected, edges are retained such that u.ID < v.ID where u and v are +// the nodes of e. +func EdgeBetweenness(g graph.Graph) map[[2]int64]float64 { + // Modified from Brandes' original algorithm as described in Algorithm 7 + // with the exception that node betweenness is not calculated: + // + // http://algo.uni-konstanz.de/publications/b-vspbc-08.pdf + + _, isUndirected := g.(graph.Undirected) + cb := make(map[[2]int64]float64) + brandes(g, func(s graph.Node, stack linear.NodeStack, p map[int64][]graph.Node, delta, sigma map[int64]float64) { + for stack.Len() != 0 { + w := stack.Pop() + for _, v := range p[w.ID()] { + c := sigma[v.ID()] / sigma[w.ID()] * (1 + delta[w.ID()]) + vid := v.ID() + wid := w.ID() + if isUndirected && wid < vid { + vid, wid = wid, vid + } + cb[[2]int64{vid, wid}] += c + delta[v.ID()] += c + } + } + }) + return cb +} + +// brandes is the common code for Betweenness and EdgeBetweenness. It corresponds +// to algorithm 1 in http://algo.uni-konstanz.de/publications/b-vspbc-08.pdf with +// the accumulation loop provided by the accumulate closure. +func brandes(g graph.Graph, accumulate func(s graph.Node, stack linear.NodeStack, p map[int64][]graph.Node, delta, sigma map[int64]float64)) { + var ( + nodes = g.Nodes() + stack linear.NodeStack + p = make(map[int64][]graph.Node, len(nodes)) + sigma = make(map[int64]float64, len(nodes)) + d = make(map[int64]int, len(nodes)) + delta = make(map[int64]float64, len(nodes)) + queue linear.NodeQueue + ) + for _, s := range nodes { + stack = stack[:0] + + for _, w := range nodes { + p[w.ID()] = p[w.ID()][:0] + } + + for _, t := range nodes { + sigma[t.ID()] = 0 + d[t.ID()] = -1 + } + sigma[s.ID()] = 1 + d[s.ID()] = 0 + + queue.Enqueue(s) + for queue.Len() != 0 { + v := queue.Dequeue() + stack.Push(v) + for _, w := range g.From(v) { + // w found for the first time? + if d[w.ID()] < 0 { + queue.Enqueue(w) + d[w.ID()] = d[v.ID()] + 1 + } + // shortest path to w via v? + if d[w.ID()] == d[v.ID()]+1 { + sigma[w.ID()] += sigma[v.ID()] + p[w.ID()] = append(p[w.ID()], v) + } + } + } + + for _, v := range nodes { + delta[v.ID()] = 0 + } + + // S returns vertices in order of non-increasing distance from s + accumulate(s, stack, p, delta, sigma) + } +} + +// BetweennessWeighted returns the non-zero betweenness centrality for nodes in the weighted +// graph g used to construct the given shortest paths. +// +// C_B(v) = \sum_{s ≠ v ≠ t ∈ V} (\sigma_{st}(v) / \sigma_{st}) +// +// where \sigma_{st} and \sigma_{st}(v) are the number of shortest paths from s to t, +// and the subset of those paths containing v respectively. +func BetweennessWeighted(g graph.Weighted, p path.AllShortest) map[int64]float64 { + cb := make(map[int64]float64) + + nodes := g.Nodes() + for i, s := range nodes { + for j, t := range nodes { + if i == j { + continue + } + d := p.Weight(s, t) + if math.IsInf(d, 0) { + continue + } + + // If we have a unique path, don't do the + // extra work needed to get all paths. + path, _, unique := p.Between(s, t) + if unique { + for _, v := range path[1 : len(path)-1] { + // For undirected graphs we double count + // passage though nodes. This is consistent + // with Brandes' algorithm's behaviour. + cb[v.ID()]++ + } + continue + } + + // Otherwise iterate over all paths. + paths, _ := p.AllBetween(s, t) + stFrac := 1 / float64(len(paths)) + for _, path := range paths { + for _, v := range path[1 : len(path)-1] { + cb[v.ID()] += stFrac + } + } + } + } + + return cb +} + +// EdgeBetweennessWeighted returns the non-zero betweenness centrality for edges in +// the weighted graph g. For an edge e the centrality C_B is computed as +// +// C_B(e) = \sum_{s ≠ t ∈ V} (\sigma_{st}(e) / \sigma_{st}), +// +// where \sigma_{st} and \sigma_{st}(e) are the number of shortest paths from s +// to t, and the subset of those paths containing e, respectively. +// +// If g is undirected, edges are retained such that u.ID < v.ID where u and v are +// the nodes of e. +func EdgeBetweennessWeighted(g graph.Weighted, p path.AllShortest) map[[2]int64]float64 { + cb := make(map[[2]int64]float64) + + _, isUndirected := g.(graph.Undirected) + nodes := g.Nodes() + for i, s := range nodes { + for j, t := range nodes { + if i == j { + continue + } + d := p.Weight(s, t) + if math.IsInf(d, 0) { + continue + } + + // If we have a unique path, don't do the + // extra work needed to get all paths. + path, _, unique := p.Between(s, t) + if unique { + for k, v := range path[1:] { + // For undirected graphs we double count + // passage though edges. This is consistent + // with Brandes' algorithm's behaviour. + uid := path[k].ID() + vid := v.ID() + if isUndirected && vid < uid { + uid, vid = vid, uid + } + cb[[2]int64{uid, vid}]++ + } + continue + } + + // Otherwise iterate over all paths. + paths, _ := p.AllBetween(s, t) + stFrac := 1 / float64(len(paths)) + for _, path := range paths { + for k, v := range path[1:] { + uid := path[k].ID() + vid := v.ID() + if isUndirected && vid < uid { + uid, vid = vid, uid + } + cb[[2]int64{uid, vid}] += stFrac + } + } + } + } + + return cb +} diff --git a/vendor/gonum.org/v1/gonum/graph/network/betweenness_test.go b/vendor/gonum.org/v1/gonum/graph/network/betweenness_test.go new file mode 100644 index 00000000..04fcd056 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/betweenness_test.go @@ -0,0 +1,338 @@ +// 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 network + +import ( + "fmt" + "math" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph/path" + "gonum.org/v1/gonum/graph/simple" +) + +var betweennessTests = []struct { + g []set + + wantTol float64 + want map[int64]float64 + wantEdges map[[2]int64]float64 +}{ + { + // Example graph from http://en.wikipedia.org/wiki/File:PageRanks-Example.svg 16:17, 8 July 2009 + g: []set{ + A: nil, + B: linksTo(C), + C: linksTo(B), + D: linksTo(A, B), + E: linksTo(D, B, F), + F: linksTo(B, E), + G: linksTo(B, E), + H: linksTo(B, E), + I: linksTo(B, E), + J: linksTo(E), + K: linksTo(E), + }, + + wantTol: 1e-1, + want: map[int64]float64{ + B: 32, + D: 18, + E: 48, + }, + wantEdges: map[[2]int64]float64{ + {A, D}: 20, + {B, C}: 20, + {B, D}: 16, + {B, E}: 12, + {B, F}: 9, + {B, G}: 9, + {B, H}: 9, + {B, I}: 9, + {D, E}: 20, + {E, F}: 11, + {E, G}: 11, + {E, H}: 11, + {E, I}: 11, + {E, J}: 20, + {E, K}: 20, + }, + }, + { + // Example graph from http://en.wikipedia.org/w/index.php?title=PageRank&oldid=659286279#Power_Method + g: []set{ + A: linksTo(B, C), + B: linksTo(D), + C: linksTo(D, E), + D: linksTo(E), + E: linksTo(A), + }, + + wantTol: 1e-3, + want: map[int64]float64{ + A: 2, + B: 0.6667, + C: 0.6667, + D: 2, + E: 0.6667, + }, + wantEdges: map[[2]int64]float64{ + {A, B}: 2 + 2/3. + 4/2., + {A, C}: 2 + 2/3. + 2/2., + {A, E}: 2 + 2/3. + 2/2., + {B, D}: 2 + 2/3. + 4/2., + {C, D}: 2 + 2/3. + 2/2., + {C, E}: 2, + {D, E}: 2 + 2/3. + 2/2., + }, + }, + { + g: []set{ + A: linksTo(B), + B: linksTo(C), + C: nil, + }, + + wantTol: 1e-3, + want: map[int64]float64{ + B: 2, + }, + wantEdges: map[[2]int64]float64{ + {A, B}: 4, + {B, C}: 4, + }, + }, + { + g: []set{ + A: linksTo(B), + B: linksTo(C), + C: linksTo(D), + D: linksTo(E), + E: nil, + }, + + wantTol: 1e-3, + want: map[int64]float64{ + B: 6, + C: 8, + D: 6, + }, + wantEdges: map[[2]int64]float64{ + {A, B}: 8, + {B, C}: 12, + {C, D}: 12, + {D, E}: 8, + }, + }, + { + g: []set{ + A: linksTo(C), + B: linksTo(C), + C: nil, + D: linksTo(C), + E: linksTo(C), + }, + + wantTol: 1e-3, + want: map[int64]float64{ + C: 12, + }, + wantEdges: map[[2]int64]float64{ + {A, C}: 8, + {B, C}: 8, + {C, D}: 8, + {C, E}: 8, + }, + }, + { + g: []set{ + A: linksTo(B, C, D, E), + B: linksTo(C, D, E), + C: linksTo(D, E), + D: linksTo(E), + E: nil, + }, + + wantTol: 1e-3, + want: map[int64]float64{}, + wantEdges: map[[2]int64]float64{ + {A, B}: 2, + {A, C}: 2, + {A, D}: 2, + {A, E}: 2, + {B, C}: 2, + {B, D}: 2, + {B, E}: 2, + {C, D}: 2, + {C, E}: 2, + {D, E}: 2, + }, + }, +} + +func TestBetweenness(t *testing.T) { + for i, test := range betweennessTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + got := Betweenness(g) + prec := 1 - int(math.Log10(test.wantTol)) + for n := range test.g { + wantN, gotOK := got[int64(n)] + gotN, wantOK := test.want[int64(n)] + if gotOK != wantOK { + t.Errorf("unexpected betweenness result for test %d, node %c", i, n+'A') + } + if !floats.EqualWithinAbsOrRel(gotN, wantN, test.wantTol, test.wantTol) { + t.Errorf("unexpected betweenness result for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.want, prec)) + break + } + } + } +} + +func TestEdgeBetweenness(t *testing.T) { + for i, test := range betweennessTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + got := EdgeBetweenness(g) + prec := 1 - int(math.Log10(test.wantTol)) + outer: + for u := range test.g { + for v := range test.g { + wantQ, gotOK := got[[2]int64{int64(u), int64(v)}] + gotQ, wantOK := test.wantEdges[[2]int64{int64(u), int64(v)}] + if gotOK != wantOK { + t.Errorf("unexpected betweenness result for test %d, edge (%c,%c)", i, u+'A', v+'A') + } + if !floats.EqualWithinAbsOrRel(gotQ, wantQ, test.wantTol, test.wantTol) { + t.Errorf("unexpected betweenness result for test %d:\ngot: %v\nwant:%v", + i, orderedPairFloats(got, prec), orderedPairFloats(test.wantEdges, prec)) + break outer + } + } + } + } +} + +func TestBetweennessWeighted(t *testing.T) { + for i, test := range betweennessTests { + g := simple.NewWeightedUndirectedGraph(0, math.Inf(1)) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + p, ok := path.FloydWarshall(g) + if !ok { + t.Errorf("unexpected negative cycle in test %d", i) + continue + } + + got := BetweennessWeighted(g, p) + prec := 1 - int(math.Log10(test.wantTol)) + for n := range test.g { + gotN, gotOK := got[int64(n)] + wantN, wantOK := test.want[int64(n)] + if gotOK != wantOK { + t.Errorf("unexpected betweenness existence for test %d, node %c", i, n+'A') + } + if !floats.EqualWithinAbsOrRel(gotN, wantN, test.wantTol, test.wantTol) { + t.Errorf("unexpected betweenness result for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.want, prec)) + break + } + } + } +} + +func TestEdgeBetweennessWeighted(t *testing.T) { + for i, test := range betweennessTests { + g := simple.NewWeightedUndirectedGraph(0, math.Inf(1)) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + + p, ok := path.FloydWarshall(g) + if !ok { + t.Errorf("unexpected negative cycle in test %d", i) + continue + } + + got := EdgeBetweennessWeighted(g, p) + prec := 1 - int(math.Log10(test.wantTol)) + outer: + for u := range test.g { + for v := range test.g { + wantQ, gotOK := got[[2]int64{int64(u), int64(v)}] + gotQ, wantOK := test.wantEdges[[2]int64{int64(u), int64(v)}] + if gotOK != wantOK { + t.Errorf("unexpected betweenness result for test %d, edge (%c,%c)", i, u+'A', v+'A') + } + if !floats.EqualWithinAbsOrRel(gotQ, wantQ, test.wantTol, test.wantTol) { + t.Errorf("unexpected betweenness result for test %d:\ngot: %v\nwant:%v", + i, orderedPairFloats(got, prec), orderedPairFloats(test.wantEdges, prec)) + break outer + } + } + } + } +} + +func orderedPairFloats(w map[[2]int64]float64, prec int) []pairKeyFloatVal { + o := make(orderedPairFloatsMap, 0, len(w)) + for k, v := range w { + o = append(o, pairKeyFloatVal{prec: prec, key: k, val: v}) + } + sort.Sort(o) + return o +} + +type pairKeyFloatVal struct { + prec int + key [2]int64 + val float64 +} + +func (kv pairKeyFloatVal) String() string { + return fmt.Sprintf("(%c,%c):%.*f", kv.key[0]+'A', kv.key[1]+'A', kv.prec, kv.val) +} + +type orderedPairFloatsMap []pairKeyFloatVal + +func (o orderedPairFloatsMap) Len() int { return len(o) } +func (o orderedPairFloatsMap) Less(i, j int) bool { + return o[i].key[0] < o[j].key[0] || (o[i].key[0] == o[j].key[0] && o[i].key[1] < o[j].key[1]) +} +func (o orderedPairFloatsMap) Swap(i, j int) { o[i], o[j] = o[j], o[i] } diff --git a/vendor/gonum.org/v1/gonum/graph/network/distance.go b/vendor/gonum.org/v1/gonum/graph/network/distance.go new file mode 100644 index 00000000..7e5ef6a3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/distance.go @@ -0,0 +1,124 @@ +// 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 network + +import ( + "math" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/path" +) + +// Closeness returns the closeness centrality for nodes in the graph g used to +// construct the given shortest paths. +// +// C(v) = 1 / \sum_u d(u,v) +// +// For directed graphs the incoming paths are used. Infinite distances are +// not considered. +func Closeness(g graph.Graph, p path.AllShortest) map[int64]float64 { + nodes := g.Nodes() + c := make(map[int64]float64, len(nodes)) + for _, u := range nodes { + var sum float64 + for _, v := range nodes { + // The ordering here is not relevant for + // undirected graphs, but we make sure we + // are counting incoming paths. + d := p.Weight(v, u) + if math.IsInf(d, 0) { + continue + } + sum += d + } + c[u.ID()] = 1 / sum + } + return c +} + +// Farness returns the farness for nodes in the graph g used to construct +// the given shortest paths. +// +// F(v) = \sum_u d(u,v) +// +// For directed graphs the incoming paths are used. Infinite distances are +// not considered. +func Farness(g graph.Graph, p path.AllShortest) map[int64]float64 { + nodes := g.Nodes() + f := make(map[int64]float64, len(nodes)) + for _, u := range nodes { + var sum float64 + for _, v := range nodes { + // The ordering here is not relevant for + // undirected graphs, but we make sure we + // are counting incoming paths. + d := p.Weight(v, u) + if math.IsInf(d, 0) { + continue + } + sum += d + } + f[u.ID()] = sum + } + return f +} + +// Harmonic returns the harmonic centrality for nodes in the graph g used to +// construct the given shortest paths. +// +// H(v)= \sum_{u ≠ v} 1 / d(u,v) +// +// For directed graphs the incoming paths are used. Infinite distances are +// not considered. +func Harmonic(g graph.Graph, p path.AllShortest) map[int64]float64 { + nodes := g.Nodes() + h := make(map[int64]float64, len(nodes)) + for i, u := range nodes { + var sum float64 + for j, v := range nodes { + // The ordering here is not relevant for + // undirected graphs, but we make sure we + // are counting incoming paths. + d := p.Weight(v, u) + if math.IsInf(d, 0) { + continue + } + if i != j { + sum += 1 / d + } + } + h[u.ID()] = sum + } + return h +} + +// Residual returns the Dangalchev's residual closeness for nodes in the graph +// g used to construct the given shortest paths. +// +// C(v)= \sum_{u ≠ v} 1 / 2^d(u,v) +// +// For directed graphs the incoming paths are used. Infinite distances are +// not considered. +func Residual(g graph.Graph, p path.AllShortest) map[int64]float64 { + nodes := g.Nodes() + r := make(map[int64]float64, len(nodes)) + for i, u := range nodes { + var sum float64 + for j, v := range nodes { + // The ordering here is not relevant for + // undirected graphs, but we make sure we + // are counting incoming paths. + d := p.Weight(v, u) + if math.IsInf(d, 0) { + continue + } + if i != j { + sum += math.Exp2(-d) + } + } + r[u.ID()] = sum + } + return r +} diff --git a/vendor/gonum.org/v1/gonum/graph/network/distance_test.go b/vendor/gonum.org/v1/gonum/graph/network/distance_test.go new file mode 100644 index 00000000..4015883b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/distance_test.go @@ -0,0 +1,394 @@ +// 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 network + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph/path" + "gonum.org/v1/gonum/graph/simple" +) + +var undirectedCentralityTests = []struct { + g []set + + farness map[int64]float64 + harmonic map[int64]float64 + residual map[int64]float64 +}{ + { + g: []set{ + A: linksTo(B), + B: linksTo(C), + C: nil, + }, + + farness: map[int64]float64{ + A: 1 + 2, + B: 1 + 1, + C: 2 + 1, + }, + harmonic: map[int64]float64{ + A: 1 + 1.0/2.0, + B: 1 + 1, + C: 1.0/2.0 + 1, + }, + residual: map[int64]float64{ + A: 1/math.Exp2(1) + 1/math.Exp2(2), + B: 1/math.Exp2(1) + 1/math.Exp2(1), + C: 1/math.Exp2(2) + 1/math.Exp2(1), + }, + }, + { + g: []set{ + A: linksTo(B), + B: linksTo(C), + C: linksTo(D), + D: linksTo(E), + E: nil, + }, + + farness: map[int64]float64{ + A: 1 + 2 + 3 + 4, + B: 1 + 1 + 2 + 3, + C: 2 + 1 + 1 + 2, + D: 3 + 2 + 1 + 1, + E: 4 + 3 + 2 + 1, + }, + harmonic: map[int64]float64{ + A: 1 + 1.0/2.0 + 1.0/3.0 + 1.0/4.0, + B: 1 + 1 + 1.0/2.0 + 1.0/3.0, + C: 1.0/2.0 + 1 + 1 + 1.0/2.0, + D: 1.0/3.0 + 1.0/2.0 + 1 + 1, + E: 1.0/4.0 + 1.0/3.0 + 1.0/2.0 + 1, + }, + residual: map[int64]float64{ + A: 1/math.Exp2(1) + 1/math.Exp2(2) + 1/math.Exp2(3) + 1/math.Exp2(4), + B: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(2) + 1/math.Exp2(3), + C: 1/math.Exp2(2) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(2), + D: 1/math.Exp2(3) + 1/math.Exp2(2) + 1/math.Exp2(1) + 1/math.Exp2(1), + E: 1/math.Exp2(4) + 1/math.Exp2(3) + 1/math.Exp2(2) + 1/math.Exp2(1), + }, + }, + { + g: []set{ + A: linksTo(C), + B: linksTo(C), + C: nil, + D: linksTo(C), + E: linksTo(C), + }, + + farness: map[int64]float64{ + A: 2 + 2 + 1 + 2, + B: 2 + 1 + 2 + 2, + C: 1 + 1 + 1 + 1, + D: 2 + 1 + 2 + 2, + E: 2 + 2 + 1 + 2, + }, + harmonic: map[int64]float64{ + A: 1.0/2.0 + 1.0/2.0 + 1 + 1.0/2.0, + B: 1.0/2.0 + 1 + 1.0/2.0 + 1.0/2.0, + C: 1 + 1 + 1 + 1, + D: 1.0/2.0 + 1 + 1.0/2.0 + 1.0/2.0, + E: 1.0/2.0 + 1.0/2.0 + 1 + 1.0/2.0, + }, + residual: map[int64]float64{ + A: 1/math.Exp2(2) + 1/math.Exp2(2) + 1/math.Exp2(1) + 1/math.Exp2(2), + B: 1/math.Exp2(2) + 1/math.Exp2(1) + 1/math.Exp2(2) + 1/math.Exp2(2), + C: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + D: 1/math.Exp2(2) + 1/math.Exp2(1) + 1/math.Exp2(2) + 1/math.Exp2(2), + E: 1/math.Exp2(2) + 1/math.Exp2(2) + 1/math.Exp2(1) + 1/math.Exp2(2), + }, + }, + { + g: []set{ + A: linksTo(B, C, D, E), + B: linksTo(C, D, E), + C: linksTo(D, E), + D: linksTo(E), + E: nil, + }, + + farness: map[int64]float64{ + A: 1 + 1 + 1 + 1, + B: 1 + 1 + 1 + 1, + C: 1 + 1 + 1 + 1, + D: 1 + 1 + 1 + 1, + E: 1 + 1 + 1 + 1, + }, + harmonic: map[int64]float64{ + A: 1 + 1 + 1 + 1, + B: 1 + 1 + 1 + 1, + C: 1 + 1 + 1 + 1, + D: 1 + 1 + 1 + 1, + E: 1 + 1 + 1 + 1, + }, + residual: map[int64]float64{ + A: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + B: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + C: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + D: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + E: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + }, + }, +} + +func TestDistanceCentralityUndirected(t *testing.T) { + const tol = 1e-12 + prec := 1 - int(math.Log10(tol)) + + for i, test := range undirectedCentralityTests { + g := simple.NewWeightedUndirectedGraph(0, math.Inf(1)) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + p, ok := path.FloydWarshall(g) + if !ok { + t.Errorf("unexpected negative cycle in test %d", i) + continue + } + + var got map[int64]float64 + + got = Closeness(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], 1/test.farness[int64(n)], tol, tol) { + want := make(map[int64]float64) + for n, v := range test.farness { + want[n] = 1 / v + } + t.Errorf("unexpected closeness centrality for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(want, prec)) + break + } + } + + got = Farness(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.farness[int64(n)], tol, tol) { + t.Errorf("unexpected farness for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.farness, prec)) + break + } + } + + got = Harmonic(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.harmonic[int64(n)], tol, tol) { + t.Errorf("unexpected harmonic centrality for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.harmonic, prec)) + break + } + } + + got = Residual(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.residual[int64(n)], tol, tol) { + t.Errorf("unexpected residual closeness for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.residual, prec)) + break + } + } + } +} + +var directedCentralityTests = []struct { + g []set + + farness map[int64]float64 + harmonic map[int64]float64 + residual map[int64]float64 +}{ + { + g: []set{ + A: linksTo(B), + B: linksTo(C), + C: nil, + }, + + farness: map[int64]float64{ + A: 0, + B: 1, + C: 2 + 1, + }, + harmonic: map[int64]float64{ + A: 0, + B: 1, + C: 1.0/2.0 + 1, + }, + residual: map[int64]float64{ + A: 0, + B: 1 / math.Exp2(1), + C: 1/math.Exp2(2) + 1/math.Exp2(1), + }, + }, + { + g: []set{ + A: linksTo(B), + B: linksTo(C), + C: linksTo(D), + D: linksTo(E), + E: nil, + }, + + farness: map[int64]float64{ + A: 0, + B: 1, + C: 2 + 1, + D: 3 + 2 + 1, + E: 4 + 3 + 2 + 1, + }, + harmonic: map[int64]float64{ + A: 0, + B: 1, + C: 1.0/2.0 + 1, + D: 1.0/3.0 + 1.0/2.0 + 1, + E: 1.0/4.0 + 1.0/3.0 + 1.0/2.0 + 1, + }, + residual: map[int64]float64{ + A: 0, + B: 1 / math.Exp2(1), + C: 1/math.Exp2(2) + 1/math.Exp2(1), + D: 1/math.Exp2(3) + 1/math.Exp2(2) + 1/math.Exp2(1), + E: 1/math.Exp2(4) + 1/math.Exp2(3) + 1/math.Exp2(2) + 1/math.Exp2(1), + }, + }, + { + g: []set{ + A: linksTo(C), + B: linksTo(C), + C: nil, + D: linksTo(C), + E: linksTo(C), + }, + + farness: map[int64]float64{ + A: 0, + B: 0, + C: 1 + 1 + 1 + 1, + D: 0, + E: 0, + }, + harmonic: map[int64]float64{ + A: 0, + B: 0, + C: 1 + 1 + 1 + 1, + D: 0, + E: 0, + }, + residual: map[int64]float64{ + A: 0, + B: 0, + C: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + D: 0, + E: 0, + }, + }, + { + g: []set{ + A: linksTo(B, C, D, E), + B: linksTo(C, D, E), + C: linksTo(D, E), + D: linksTo(E), + E: nil, + }, + + farness: map[int64]float64{ + A: 0, + B: 1, + C: 1 + 1, + D: 1 + 1 + 1, + E: 1 + 1 + 1 + 1, + }, + harmonic: map[int64]float64{ + A: 0, + B: 1, + C: 1 + 1, + D: 1 + 1 + 1, + E: 1 + 1 + 1 + 1, + }, + residual: map[int64]float64{ + A: 0, + B: 1 / math.Exp2(1), + C: 1/math.Exp2(1) + 1/math.Exp2(1), + D: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + E: 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1) + 1/math.Exp2(1), + }, + }, +} + +func TestDistanceCentralityDirected(t *testing.T) { + const tol = 1e-12 + prec := 1 - int(math.Log10(tol)) + + for i, test := range directedCentralityTests { + g := simple.NewWeightedDirectedGraph(0, math.Inf(1)) + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetWeightedEdge(simple.WeightedEdge{F: simple.Node(u), T: simple.Node(v), W: 1}) + } + } + p, ok := path.FloydWarshall(g) + if !ok { + t.Errorf("unexpected negative cycle in test %d", i) + continue + } + + var got map[int64]float64 + + got = Closeness(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], 1/test.farness[int64(n)], tol, tol) { + want := make(map[int64]float64) + for n, v := range test.farness { + want[int64(n)] = 1 / v + } + t.Errorf("unexpected closeness centrality for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(want, prec)) + break + } + } + + got = Farness(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.farness[int64(n)], tol, tol) { + t.Errorf("unexpected farness for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.farness, prec)) + break + } + } + + got = Harmonic(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.harmonic[int64(n)], tol, tol) { + t.Errorf("unexpected harmonic centrality for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.harmonic, prec)) + break + } + } + + got = Residual(g, p) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.residual[int64(n)], tol, tol) { + t.Errorf("unexpected residual closeness for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.residual, prec)) + break + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/network/doc.go b/vendor/gonum.org/v1/gonum/graph/network/doc.go new file mode 100644 index 00000000..c456f2da --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package network provides network analysis functions. +package network // import "gonum.org/v1/gonum/graph/network" diff --git a/vendor/gonum.org/v1/gonum/graph/network/hits.go b/vendor/gonum.org/v1/gonum/graph/network/hits.go new file mode 100644 index 00000000..53ef944c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/hits.go @@ -0,0 +1,101 @@ +// 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 network + +import ( + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph" +) + +// HubAuthority is a Hyperlink-Induced Topic Search hub-authority score pair. +type HubAuthority struct { + Hub float64 + Authority float64 +} + +// HITS returns the Hyperlink-Induced Topic Search hub-authority scores for +// nodes of the directed graph g. HITS terminates when the 2-norm of the +// vector difference between iterations is below tol. The returned map is +// keyed on the graph node IDs. +func HITS(g graph.Directed, tol float64) map[int64]HubAuthority { + nodes := g.Nodes() + + // Make a topological copy of g with dense node IDs. + indexOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + indexOf[n.ID()] = i + } + nodesLinkingTo := make([][]int, len(nodes)) + nodesLinkedFrom := make([][]int, len(nodes)) + for i, n := range nodes { + for _, u := range g.To(n) { + nodesLinkingTo[i] = append(nodesLinkingTo[i], indexOf[u.ID()]) + } + for _, v := range g.From(n) { + nodesLinkedFrom[i] = append(nodesLinkedFrom[i], indexOf[v.ID()]) + } + } + indexOf = nil + + w := make([]float64, 4*len(nodes)) + auth := w[:len(nodes)] + hub := w[len(nodes) : 2*len(nodes)] + for i := range nodes { + auth[i] = 1 + hub[i] = 1 + } + deltaAuth := w[2*len(nodes) : 3*len(nodes)] + deltaHub := w[3*len(nodes):] + + var norm float64 + for { + norm = 0 + for v := range nodes { + var a float64 + for _, u := range nodesLinkingTo[v] { + a += hub[u] + } + deltaAuth[v] = auth[v] + auth[v] = a + norm += a * a + } + norm = math.Sqrt(norm) + + for i := range auth { + auth[i] /= norm + deltaAuth[i] -= auth[i] + } + + norm = 0 + for u := range nodes { + var h float64 + for _, v := range nodesLinkedFrom[u] { + h += auth[v] + } + deltaHub[u] = hub[u] + hub[u] = h + norm += h * h + } + norm = math.Sqrt(norm) + + for i := range hub { + hub[i] /= norm + deltaHub[i] -= hub[i] + } + + if floats.Norm(deltaAuth, 2) < tol && floats.Norm(deltaHub, 2) < tol { + break + } + } + + hubAuth := make(map[int64]HubAuthority, len(nodes)) + for i, n := range nodes { + hubAuth[n.ID()] = HubAuthority{Hub: hub[i], Authority: auth[i]} + } + + return hubAuth +} diff --git a/vendor/gonum.org/v1/gonum/graph/network/hits_test.go b/vendor/gonum.org/v1/gonum/graph/network/hits_test.go new file mode 100644 index 00000000..b711f36e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/hits_test.go @@ -0,0 +1,98 @@ +// 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 network + +import ( + "fmt" + "math" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph/simple" +) + +var hitsTests = []struct { + g []set + tol float64 + + wantTol float64 + want map[int64]HubAuthority +}{ + { + // Example graph from http://www.cis.hut.fi/Opinnot/T-61.6020/2008/pagerank_hits.pdf page 8. + g: []set{ + A: linksTo(B, C, D), + B: linksTo(C, D), + C: linksTo(B), + D: nil, + }, + tol: 1e-4, + + wantTol: 1e-4, + want: map[int64]HubAuthority{ + A: {Hub: 0.7887, Authority: 0}, + B: {Hub: 0.5774, Authority: 0.4597}, + C: {Hub: 0.2113, Authority: 0.6280}, + D: {Hub: 0, Authority: 0.6280}, + }, + }, +} + +func TestHITS(t *testing.T) { + for i, test := range hitsTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + got := HITS(g, test.tol) + prec := 1 - int(math.Log10(test.wantTol)) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)].Hub, test.want[int64(n)].Hub, test.wantTol, test.wantTol) { + t.Errorf("unexpected HITS result for test %d:\ngot: %v\nwant:%v", + i, orderedHubAuth(got, prec), orderedHubAuth(test.want, prec)) + break + } + if !floats.EqualWithinAbsOrRel(got[int64(n)].Authority, test.want[int64(n)].Authority, test.wantTol, test.wantTol) { + t.Errorf("unexpected HITS result for test %d:\ngot: %v\nwant:%v", + i, orderedHubAuth(got, prec), orderedHubAuth(test.want, prec)) + break + } + } + } +} + +func orderedHubAuth(w map[int64]HubAuthority, prec int) []keyHubAuthVal { + o := make(orderedHubAuthMap, 0, len(w)) + for k, v := range w { + o = append(o, keyHubAuthVal{prec: prec, key: k, val: v}) + } + sort.Sort(o) + return o +} + +type keyHubAuthVal struct { + prec int + key int64 + val HubAuthority +} + +func (kv keyHubAuthVal) String() string { + return fmt.Sprintf("%d:{H:%.*f, A:%.*f}", + kv.key, kv.prec, kv.val.Hub, kv.prec, kv.val.Authority, + ) +} + +type orderedHubAuthMap []keyHubAuthVal + +func (o orderedHubAuthMap) Len() int { return len(o) } +func (o orderedHubAuthMap) Less(i, j int) bool { return o[i].key < o[j].key } +func (o orderedHubAuthMap) Swap(i, j int) { o[i], o[j] = o[j], o[i] } diff --git a/vendor/gonum.org/v1/gonum/graph/network/network.go b/vendor/gonum.org/v1/gonum/graph/network/network.go new file mode 100644 index 00000000..2faabdea --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/network.go @@ -0,0 +1,13 @@ +// 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. + +// TODO(kortschak): Implement: +// * edge-weighted PageRank and HITS +// * PersonalizedPageRank: +// http://infolab.stanford.edu/~backrub/google.html 2.1.2 Intuitive Justification +// http://ilpubs.stanford.edu:8090/596/1/2003-35.pdf +// http://www.vldb.org/pvldb/vol7/p1023-maehara.pdf +// * other centrality measures + +package network diff --git a/vendor/gonum.org/v1/gonum/graph/network/network_test.go b/vendor/gonum.org/v1/gonum/graph/network/network_test.go new file mode 100644 index 00000000..b999c218 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/network_test.go @@ -0,0 +1,33 @@ +// 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 network + +const ( + A = iota + B + C + D + E + F + G + H + I + J + K +) + +// set is an integer set. +type set map[int64]struct{} + +func linksTo(i ...int64) set { + if len(i) == 0 { + return nil + } + s := make(set) + for _, v := range i { + s[v] = struct{}{} + } + return s +} diff --git a/vendor/gonum.org/v1/gonum/graph/network/page.go b/vendor/gonum.org/v1/gonum/graph/network/page.go new file mode 100644 index 00000000..fb2c58e3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/page.go @@ -0,0 +1,228 @@ +// 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 network + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/mat" +) + +// PageRank returns the PageRank weights for nodes of the directed graph g +// using the given damping factor and terminating when the 2-norm of the +// vector difference between iterations is below tol. The returned map is +// keyed on the graph node IDs. +func PageRank(g graph.Directed, damp, tol float64) map[int64]float64 { + // PageRank is implemented according to "How Google Finds Your Needle + // in the Web's Haystack". + // + // G.I^k = alpha.S.I^k + (1-alpha).1/n.1.I^k + // + // http://www.ams.org/samplings/feature-column/fcarc-pagerank + + nodes := g.Nodes() + indexOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + indexOf[n.ID()] = i + } + + m := mat.NewDense(len(nodes), len(nodes), nil) + dangling := damp / float64(len(nodes)) + for j, u := range nodes { + to := g.From(u) + f := damp / float64(len(to)) + for _, v := range to { + m.Set(indexOf[v.ID()], j, f) + } + if len(to) == 0 { + for i := range nodes { + m.Set(i, j, dangling) + } + } + } + matrix := m.RawMatrix().Data + dt := (1 - damp) / float64(len(nodes)) + for i := range matrix { + matrix[i] += dt + } + + last := make([]float64, len(nodes)) + for i := range last { + last[i] = 1 + } + lastV := mat.NewVecDense(len(nodes), last) + + vec := make([]float64, len(nodes)) + var sum float64 + for i := range vec { + r := rand.NormFloat64() + sum += r + vec[i] = r + } + f := 1 / sum + for i := range vec { + vec[i] *= f + } + v := mat.NewVecDense(len(nodes), vec) + + for { + lastV, v = v, lastV + v.MulVec(m, lastV) + if normDiff(vec, last) < tol { + break + } + } + + ranks := make(map[int64]float64, len(nodes)) + for i, r := range v.RawVector().Data { + ranks[nodes[i].ID()] = r + } + + return ranks +} + +// PageRankSparse returns the PageRank weights for nodes of the sparse directed +// graph g using the given damping factor and terminating when the 2-norm of the +// vector difference between iterations is below tol. The returned map is +// keyed on the graph node IDs. +func PageRankSparse(g graph.Directed, damp, tol float64) map[int64]float64 { + // PageRankSparse is implemented according to "How Google Finds Your Needle + // in the Web's Haystack". + // + // G.I^k = alpha.H.I^k + alpha.A.I^k + (1-alpha).1/n.1.I^k + // + // http://www.ams.org/samplings/feature-column/fcarc-pagerank + + nodes := g.Nodes() + indexOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + indexOf[n.ID()] = i + } + + m := make(rowCompressedMatrix, len(nodes)) + var dangling compressedRow + df := damp / float64(len(nodes)) + for j, u := range nodes { + to := g.From(u) + f := damp / float64(len(to)) + for _, v := range to { + m.addTo(indexOf[v.ID()], j, f) + } + if len(to) == 0 { + dangling.addTo(j, df) + } + } + + last := make([]float64, len(nodes)) + for i := range last { + last[i] = 1 + } + lastV := mat.NewVecDense(len(nodes), last) + + vec := make([]float64, len(nodes)) + var sum float64 + for i := range vec { + r := rand.NormFloat64() + sum += r + vec[i] = r + } + f := 1 / sum + for i := range vec { + vec[i] *= f + } + v := mat.NewVecDense(len(nodes), vec) + + dt := (1 - damp) / float64(len(nodes)) + for { + lastV, v = v, lastV + + m.mulVecUnitary(v, lastV) // First term of the G matrix equation; + with := dangling.dotUnitary(lastV) // Second term; + away := onesDotUnitary(dt, lastV) // Last term. + + floats.AddConst(with+away, v.RawVector().Data) + if normDiff(vec, last) < tol { + break + } + } + + ranks := make(map[int64]float64, len(nodes)) + for i, r := range v.RawVector().Data { + ranks[nodes[i].ID()] = r + } + + return ranks +} + +// rowCompressedMatrix implements row-compressed +// matrix/vector multiplication. +type rowCompressedMatrix []compressedRow + +// addTo adds the value v to the matrix element at (i,j). Repeated +// calls to addTo with the same column index will result in +// non-unique element representation. +func (m rowCompressedMatrix) addTo(i, j int, v float64) { m[i].addTo(j, v) } + +// mulVecUnitary multiplies the receiver by the src vector, storing +// the result in dst. It assumes src and dst are the same length as m +// and that both have unitary vector increments. +func (m rowCompressedMatrix) mulVecUnitary(dst, src *mat.VecDense) { + dMat := dst.RawVector().Data + for i, r := range m { + dMat[i] = r.dotUnitary(src) + } +} + +// compressedRow implements a simplified scatter-based Ddot. +type compressedRow []sparseElement + +// addTo adds the value v to the vector element at j. Repeated +// calls to addTo with the same vector index will result in +// non-unique element representation. +func (r *compressedRow) addTo(j int, v float64) { + *r = append(*r, sparseElement{index: j, value: v}) +} + +// dotUnitary performs a simplified scatter-based Ddot operations on +// v and the receiver. v must have have a unitary vector increment. +func (r compressedRow) dotUnitary(v *mat.VecDense) float64 { + var sum float64 + vec := v.RawVector().Data + for _, e := range r { + sum += vec[e.index] * e.value + } + return sum +} + +// sparseElement is a sparse vector or matrix element. +type sparseElement struct { + index int + value float64 +} + +// onesDotUnitary performs the equivalent of a Ddot of v with +// a ones vector of equal length. v must have have a unitary +// vector increment. +func onesDotUnitary(alpha float64, v *mat.VecDense) float64 { + var sum float64 + for _, f := range v.RawVector().Data { + sum += alpha * f + } + return sum +} + +// normDiff returns the 2-norm of the difference between x and y. +// This is a cut down version of gonum/floats.Distance. +func normDiff(x, y []float64) float64 { + var sum float64 + for i, v := range x { + d := v - y[i] + sum += d * d + } + return math.Sqrt(sum) +} diff --git a/vendor/gonum.org/v1/gonum/graph/network/page_test.go b/vendor/gonum.org/v1/gonum/graph/network/page_test.go new file mode 100644 index 00000000..0a85dcf2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/network/page_test.go @@ -0,0 +1,151 @@ +// 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 network + +import ( + "fmt" + "math" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/graph/simple" +) + +var pageRankTests = []struct { + g []set + damp float64 + tol float64 + + wantTol float64 + want map[int64]float64 +}{ + { + // Example graph from http://en.wikipedia.org/wiki/File:PageRanks-Example.svg 16:17, 8 July 2009 + g: []set{ + A: nil, + B: linksTo(C), + C: linksTo(B), + D: linksTo(A, B), + E: linksTo(D, B, F), + F: linksTo(B, E), + G: linksTo(B, E), + H: linksTo(B, E), + I: linksTo(B, E), + J: linksTo(E), + K: linksTo(E), + }, + damp: 0.85, + tol: 1e-8, + + wantTol: 1e-8, + want: map[int64]float64{ + A: 0.03278149, + B: 0.38440095, + C: 0.34291029, + D: 0.03908709, + E: 0.08088569, + F: 0.03908709, + G: 0.01616948, + H: 0.01616948, + I: 0.01616948, + J: 0.01616948, + K: 0.01616948, + }, + }, + { + // Example graph from http://en.wikipedia.org/w/index.php?title=PageRank&oldid=659286279#Power_Method + // Expected result calculated with the given MATLAB code. + g: []set{ + A: linksTo(B, C), + B: linksTo(D), + C: linksTo(D, E), + D: linksTo(E), + E: linksTo(A), + }, + damp: 0.80, + tol: 1e-3, + + wantTol: 1e-3, + want: map[int64]float64{ + A: 0.250, + B: 0.140, + C: 0.140, + D: 0.208, + E: 0.262, + }, + }, +} + +func TestPageRank(t *testing.T) { + for i, test := range pageRankTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + got := PageRank(g, test.damp, test.tol) + prec := 1 - int(math.Log10(test.wantTol)) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.want[int64(n)], test.wantTol, test.wantTol) { + t.Errorf("unexpected PageRank result for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.want, prec)) + break + } + } + } +} + +func TestPageRankSparse(t *testing.T) { + for i, test := range pageRankTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + got := PageRankSparse(g, test.damp, test.tol) + prec := 1 - int(math.Log10(test.wantTol)) + for n := range test.g { + if !floats.EqualWithinAbsOrRel(got[int64(n)], test.want[int64(n)], test.wantTol, test.wantTol) { + t.Errorf("unexpected PageRank result for test %d:\ngot: %v\nwant:%v", + i, orderedFloats(got, prec), orderedFloats(test.want, prec)) + break + } + } + } +} + +func orderedFloats(w map[int64]float64, prec int) []keyFloatVal { + o := make(orderedFloatsMap, 0, len(w)) + for k, v := range w { + o = append(o, keyFloatVal{prec: prec, key: k, val: v}) + } + sort.Sort(o) + return o +} + +type keyFloatVal struct { + prec int + key int64 + val float64 +} + +func (kv keyFloatVal) String() string { return fmt.Sprintf("%c:%.*f", kv.key+'A', kv.prec, kv.val) } + +type orderedFloatsMap []keyFloatVal + +func (o orderedFloatsMap) Len() int { return len(o) } +func (o orderedFloatsMap) Less(i, j int) bool { return o[i].key < o[j].key } +func (o orderedFloatsMap) Swap(i, j int) { o[i], o[j] = o[j], o[i] } diff --git a/vendor/gonum.org/v1/gonum/graph/path/a_star.go b/vendor/gonum.org/v1/gonum/graph/path/a_star.go new file mode 100644 index 00000000..0d24c084 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/a_star.go @@ -0,0 +1,151 @@ +// 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 path + +import ( + "container/heap" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/set" +) + +// AStar finds the A*-shortest path from s to t in g using the heuristic h. The path and +// its cost are returned in a Shortest along with paths and costs to all nodes explored +// during the search. The number of expanded nodes is also returned. This value may help +// with heuristic tuning. +// +// The path will be the shortest path if the heuristic is admissible. A heuristic is +// admissible if for any node, n, in the graph, the heuristic estimate of the cost of +// the path from n to t is less than or equal to the true cost of that path. +// +// If h is nil, AStar will use the g.HeuristicCost method if g implements HeuristicCoster, +// falling back to NullHeuristic otherwise. If the graph does not implement graph.Weighter, +// UniformCost is used. AStar will panic if g has an A*-reachable negative edge weight. +func AStar(s, t graph.Node, g graph.Graph, h Heuristic) (path Shortest, expanded int) { + if !g.Has(s) || !g.Has(t) { + return Shortest{from: s}, 0 + } + var weight Weighting + if wg, ok := g.(graph.Weighted); ok { + weight = wg.Weight + } else { + weight = UniformCost(g) + } + if h == nil { + if g, ok := g.(HeuristicCoster); ok { + h = g.HeuristicCost + } else { + h = NullHeuristic + } + } + + path = newShortestFrom(s, g.Nodes()) + tid := t.ID() + + visited := make(set.Int64s) + open := &aStarQueue{indexOf: make(map[int64]int)} + heap.Push(open, aStarNode{node: s, gscore: 0, fscore: h(s, t)}) + + for open.Len() != 0 { + u := heap.Pop(open).(aStarNode) + uid := u.node.ID() + i := path.indexOf[uid] + expanded++ + + if uid == tid { + break + } + + visited.Add(uid) + for _, v := range g.From(u.node) { + vid := v.ID() + if visited.Has(vid) { + continue + } + j := path.indexOf[vid] + + w, ok := weight(u.node, v) + if !ok { + panic("A*: unexpected invalid weight") + } + if w < 0 { + panic("A*: negative edge weight") + } + g := u.gscore + w + if n, ok := open.node(vid); !ok { + path.set(j, g, i) + heap.Push(open, aStarNode{node: v, gscore: g, fscore: g + h(v, t)}) + } else if g < n.gscore { + path.set(j, g, i) + open.update(vid, g, g+h(v, t)) + } + } + } + + return path, expanded +} + +// NullHeuristic is an admissible, consistent heuristic that will not speed up computation. +func NullHeuristic(_, _ graph.Node) float64 { + return 0 +} + +// aStarNode adds A* accounting to a graph.Node. +type aStarNode struct { + node graph.Node + gscore float64 + fscore float64 +} + +// aStarQueue is an A* priority queue. +type aStarQueue struct { + indexOf map[int64]int + nodes []aStarNode +} + +func (q *aStarQueue) Less(i, j int) bool { + return q.nodes[i].fscore < q.nodes[j].fscore +} + +func (q *aStarQueue) Swap(i, j int) { + q.indexOf[q.nodes[i].node.ID()] = j + q.indexOf[q.nodes[j].node.ID()] = i + q.nodes[i], q.nodes[j] = q.nodes[j], q.nodes[i] +} + +func (q *aStarQueue) Len() int { + return len(q.nodes) +} + +func (q *aStarQueue) Push(x interface{}) { + n := x.(aStarNode) + q.indexOf[n.node.ID()] = len(q.nodes) + q.nodes = append(q.nodes, n) +} + +func (q *aStarQueue) Pop() interface{} { + n := q.nodes[len(q.nodes)-1] + q.nodes = q.nodes[:len(q.nodes)-1] + delete(q.indexOf, n.node.ID()) + return n +} + +func (q *aStarQueue) update(id int64, g, f float64) { + i, ok := q.indexOf[id] + if !ok { + return + } + q.nodes[i].gscore = g + q.nodes[i].fscore = f + heap.Fix(q, i) +} + +func (q *aStarQueue) node(id int64) (aStarNode, bool) { + loc, ok := q.indexOf[id] + if ok { + return q.nodes[loc], true + } + return aStarNode{}, false +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/a_star_test.go b/vendor/gonum.org/v1/gonum/graph/path/a_star_test.go new file mode 100644 index 00000000..dd63d4b9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/a_star_test.go @@ -0,0 +1,310 @@ +// 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 path + +import ( + "math" + "reflect" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/path/internal" + "gonum.org/v1/gonum/graph/path/internal/testgraphs" + "gonum.org/v1/gonum/graph/simple" + "gonum.org/v1/gonum/graph/topo" +) + +var aStarTests = []struct { + name string + g graph.Graph + + s, t int64 + heuristic Heuristic + wantPath []int64 +}{ + { + name: "simple path", + g: func() graph.Graph { + return internal.NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ) + }(), + + s: 1, t: 14, + wantPath: []int64{1, 2, 6, 10, 14}, + }, + { + name: "small open graph", + g: internal.NewGrid(3, 3, true), + + s: 0, t: 8, + }, + { + name: "large open graph", + g: internal.NewGrid(1000, 1000, true), + + s: 0, t: 999*1000 + 999, + }, + { + name: "no path", + g: func() graph.Graph { + tg := internal.NewGrid(5, 5, true) + + // Create a complete "wall" across the middle row. + tg.Set(2, 0, false) + tg.Set(2, 1, false) + tg.Set(2, 2, false) + tg.Set(2, 3, false) + tg.Set(2, 4, false) + + return tg + }(), + + s: 2, t: 22, + }, + { + name: "partially obstructed", + g: func() graph.Graph { + tg := internal.NewGrid(10, 10, true) + + // Create a partial "wall" across the middle + // row with a gap at the left-hand end. + tg.Set(4, 1, false) + tg.Set(4, 2, false) + tg.Set(4, 3, false) + tg.Set(4, 4, false) + tg.Set(4, 5, false) + tg.Set(4, 6, false) + tg.Set(4, 7, false) + tg.Set(4, 8, false) + tg.Set(4, 9, false) + + return tg + }(), + + s: 5, t: 9*10 + 9, + }, + { + name: "partially obstructed with heuristic", + g: func() graph.Graph { + tg := internal.NewGrid(10, 10, true) + + // Create a partial "wall" across the middle + // row with a gap at the left-hand end. + tg.Set(4, 1, false) + tg.Set(4, 2, false) + tg.Set(4, 3, false) + tg.Set(4, 4, false) + tg.Set(4, 5, false) + tg.Set(4, 6, false) + tg.Set(4, 7, false) + tg.Set(4, 8, false) + tg.Set(4, 9, false) + + return tg + }(), + + s: 5, t: 9*10 + 9, + // Manhattan Heuristic + heuristic: func(u, v graph.Node) float64 { + uid := u.ID() + cu := (uid % 10) + ru := (uid - cu) / 10 + + vid := v.ID() + cv := (vid % 10) + rv := (vid - cv) / 10 + + return math.Abs(float64(ru-rv)) + math.Abs(float64(cu-cv)) + }, + }, +} + +func TestAStar(t *testing.T) { + for _, test := range aStarTests { + pt, _ := AStar(simple.Node(test.s), simple.Node(test.t), test.g, test.heuristic) + + p, cost := pt.To(simple.Node(test.t)) + + if !topo.IsPathIn(test.g, p) { + t.Errorf("got path that is not path in input graph for %q", test.name) + } + + bfp, ok := BellmanFordFrom(simple.Node(test.s), test.g) + if !ok { + t.Fatalf("unexpected negative cycle in %q", test.name) + } + if want := bfp.WeightTo(simple.Node(test.t)); cost != want { + t.Errorf("unexpected cost for %q: got:%v want:%v", test.name, cost, want) + } + + var got = make([]int64, 0, len(p)) + for _, n := range p { + got = append(got, n.ID()) + } + if test.wantPath != nil && !reflect.DeepEqual(got, test.wantPath) { + t.Errorf("unexpected result for %q:\ngot: %v\nwant:%v", test.name, got, test.wantPath) + } + } +} + +func TestExhaustiveAStar(t *testing.T) { + g := simple.NewWeightedUndirectedGraph(0, math.Inf(1)) + nodes := []locatedNode{ + {id: 1, x: 0, y: 6}, + {id: 2, x: 1, y: 0}, + {id: 3, x: 8, y: 7}, + {id: 4, x: 16, y: 0}, + {id: 5, x: 17, y: 6}, + {id: 6, x: 9, y: 8}, + } + for _, n := range nodes { + g.AddNode(n) + } + + edges := []weightedEdge{ + {from: g.Node(1), to: g.Node(2), cost: 7}, + {from: g.Node(1), to: g.Node(3), cost: 9}, + {from: g.Node(1), to: g.Node(6), cost: 14}, + {from: g.Node(2), to: g.Node(3), cost: 10}, + {from: g.Node(2), to: g.Node(4), cost: 15}, + {from: g.Node(3), to: g.Node(4), cost: 11}, + {from: g.Node(3), to: g.Node(6), cost: 2}, + {from: g.Node(4), to: g.Node(5), cost: 7}, + {from: g.Node(5), to: g.Node(6), cost: 9}, + } + for _, e := range edges { + g.SetWeightedEdge(e) + } + + heuristic := func(u, v graph.Node) float64 { + lu := u.(locatedNode) + lv := v.(locatedNode) + return math.Hypot(lu.x-lv.x, lu.y-lv.y) + } + + if ok, edge, goal := isMonotonic(g, heuristic); !ok { + t.Fatalf("non-monotonic heuristic at edge:%v for goal:%v", edge, goal) + } + + ps := DijkstraAllPaths(g) + for _, start := range g.Nodes() { + for _, goal := range g.Nodes() { + pt, _ := AStar(start, goal, g, heuristic) + gotPath, gotWeight := pt.To(goal) + wantPath, wantWeight, _ := ps.Between(start, goal) + if gotWeight != wantWeight { + t.Errorf("unexpected path weight from %v to %v result: got:%f want:%f", + start, goal, gotWeight, wantWeight) + } + if !reflect.DeepEqual(gotPath, wantPath) { + t.Errorf("unexpected path from %v to %v result:\ngot: %v\nwant:%v", + start, goal, gotPath, wantPath) + } + } + } +} + +type locatedNode struct { + id int64 + x, y float64 +} + +func (n locatedNode) ID() int64 { return n.id } + +type weightedEdge struct { + from, to graph.Node + cost float64 +} + +func (e weightedEdge) From() graph.Node { return e.from } +func (e weightedEdge) To() graph.Node { return e.to } +func (e weightedEdge) Weight() float64 { return e.cost } + +func isMonotonic(g UndirectedWeightLister, h Heuristic) (ok bool, at graph.Edge, goal graph.Node) { + for _, goal := range g.Nodes() { + for _, edge := range g.WeightedEdges() { + from := edge.From() + to := edge.To() + w, ok := g.Weight(from, to) + if !ok { + panic("A*: unexpected invalid weight") + } + if h(from, goal) > w+h(to, goal) { + return false, edge, goal + } + } + } + return true, nil, nil +} + +func TestAStarNullHeuristic(t *testing.T) { + for _, test := range testgraphs.ShortestPathTests { + g := test.Graph() + for _, e := range test.Edges { + g.SetWeightedEdge(e) + } + + var ( + pt Shortest + + panicked bool + ) + func() { + defer func() { + panicked = recover() != nil + }() + pt, _ = AStar(test.Query.From(), test.Query.To(), g.(graph.Graph), nil) + }() + if panicked || test.HasNegativeWeight { + if !test.HasNegativeWeight { + t.Errorf("%q: unexpected panic", test.Name) + } + if !panicked { + t.Errorf("%q: expected panic for negative edge weight", test.Name) + } + continue + } + + if pt.From().ID() != test.Query.From().ID() { + t.Fatalf("%q: unexpected from node ID: got:%d want:%d", test.Name, pt.From().ID(), test.Query.From().ID()) + } + + p, weight := pt.To(test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + if weight := pt.WeightTo(test.Query.To()); weight != test.Weight { + t.Errorf("%q: unexpected weight from Weight: got:%f want:%f", + test.Name, weight, test.Weight) + } + + var got []int64 + for _, n := range p { + got = append(got, n.ID()) + } + ok := len(got) == 0 && len(test.WantPaths) == 0 + for _, sp := range test.WantPaths { + if reflect.DeepEqual(got, sp) { + ok = true + break + } + } + if !ok { + t.Errorf("%q: unexpected shortest path:\ngot: %v\nwant from:%v", + test.Name, p, test.WantPaths) + } + + np, weight := pt.To(test.NoPathFor.To()) + if pt.From().ID() == test.NoPathFor.From().ID() && (np != nil || !math.IsInf(weight, 1)) { + t.Errorf("%q: unexpected path:\ngot: path=%v weight=%f\nwant:path= weight=+Inf", + test.Name, np, weight) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/bellman_ford_moore.go b/vendor/gonum.org/v1/gonum/graph/path/bellman_ford_moore.go new file mode 100644 index 00000000..e7370b7c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/bellman_ford_moore.go @@ -0,0 +1,67 @@ +// 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 path + +import "gonum.org/v1/gonum/graph" + +// BellmanFordFrom returns a shortest-path tree for a shortest path from u to all nodes in +// the graph g, or false indicating that a negative cycle exists in the graph. If the graph +// does not implement graph.Weighter, UniformCost is used. +// +// The time complexity of BellmanFordFrom is O(|V|.|E|). +func BellmanFordFrom(u graph.Node, g graph.Graph) (path Shortest, ok bool) { + if !g.Has(u) { + return Shortest{from: u}, true + } + var weight Weighting + if wg, ok := g.(graph.Weighted); ok { + weight = wg.Weight + } else { + weight = UniformCost(g) + } + + nodes := g.Nodes() + + path = newShortestFrom(u, nodes) + path.dist[path.indexOf[u.ID()]] = 0 + + // TODO(kortschak): Consider adding further optimisations + // from http://arxiv.org/abs/1111.5414. + for i := 1; i < len(nodes); i++ { + changed := false + for j, u := range nodes { + for _, v := range g.From(u) { + k := path.indexOf[v.ID()] + w, ok := weight(u, v) + if !ok { + panic("bellman-ford: unexpected invalid weight") + } + joint := path.dist[j] + w + if joint < path.dist[k] { + path.set(k, joint, j) + changed = true + } + } + } + if !changed { + break + } + } + + for j, u := range nodes { + for _, v := range g.From(u) { + k := path.indexOf[v.ID()] + w, ok := weight(u, v) + if !ok { + panic("bellman-ford: unexpected invalid weight") + } + if path.dist[j]+w < path.dist[k] { + return path, false + } + } + } + + return path, true +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/bellman_ford_moore_test.go b/vendor/gonum.org/v1/gonum/graph/path/bellman_ford_moore_test.go new file mode 100644 index 00000000..b753368f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/bellman_ford_moore_test.go @@ -0,0 +1,70 @@ +// 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 path + +import ( + "math" + "reflect" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/path/internal/testgraphs" +) + +func TestBellmanFordFrom(t *testing.T) { + for _, test := range testgraphs.ShortestPathTests { + g := test.Graph() + for _, e := range test.Edges { + g.SetWeightedEdge(e) + } + + pt, ok := BellmanFordFrom(test.Query.From(), g.(graph.Graph)) + if test.HasNegativeCycle { + if ok { + t.Errorf("%q: expected negative cycle", test.Name) + } + continue + } + if !ok { + t.Fatalf("%q: unexpected negative cycle", test.Name) + } + + if pt.From().ID() != test.Query.From().ID() { + t.Fatalf("%q: unexpected from node ID: got:%d want:%d", test.Name, pt.From().ID(), test.Query.From().ID()) + } + + p, weight := pt.To(test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + if weight := pt.WeightTo(test.Query.To()); weight != test.Weight { + t.Errorf("%q: unexpected weight from Weight: got:%f want:%f", + test.Name, weight, test.Weight) + } + + var got []int64 + for _, n := range p { + got = append(got, n.ID()) + } + ok = len(got) == 0 && len(test.WantPaths) == 0 + for _, sp := range test.WantPaths { + if reflect.DeepEqual(got, sp) { + ok = true + break + } + } + if !ok { + t.Errorf("%q: unexpected shortest path:\ngot: %v\nwant from:%v", + test.Name, p, test.WantPaths) + } + + np, weight := pt.To(test.NoPathFor.To()) + if pt.From().ID() == test.NoPathFor.From().ID() && (np != nil || !math.IsInf(weight, 1)) { + t.Errorf("%q: unexpected path:\ngot: path=%v weight=%f\nwant:path= weight=+Inf", + test.Name, np, weight) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/bench_test.go b/vendor/gonum.org/v1/gonum/graph/path/bench_test.go new file mode 100644 index 00000000..e08525f0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/bench_test.go @@ -0,0 +1,141 @@ +// 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 path + +import ( + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/graphs/gen" + "gonum.org/v1/gonum/graph/simple" +) + +var ( + gnpUndirected_10_tenth = gnpUndirected(10, 0.1) + gnpUndirected_100_tenth = gnpUndirected(100, 0.1) + gnpUndirected_1000_tenth = gnpUndirected(1000, 0.1) + gnpUndirected_10_half = gnpUndirected(10, 0.5) + gnpUndirected_100_half = gnpUndirected(100, 0.5) + gnpUndirected_1000_half = gnpUndirected(1000, 0.5) +) + +func gnpUndirected(n int, p float64) graph.Undirected { + g := simple.NewUndirectedGraph() + gen.Gnp(g, n, p, nil) + return g +} + +func benchmarkAStarNilHeuristic(b *testing.B, g graph.Undirected) { + var expanded int + for i := 0; i < b.N; i++ { + _, expanded = AStar(simple.Node(0), simple.Node(1), g, nil) + } + if expanded == 0 { + b.Fatal("unexpected number of expanded nodes") + } +} + +func BenchmarkAStarGnp_10_tenth(b *testing.B) { + benchmarkAStarNilHeuristic(b, gnpUndirected_10_tenth) +} +func BenchmarkAStarGnp_100_tenth(b *testing.B) { + benchmarkAStarNilHeuristic(b, gnpUndirected_100_tenth) +} +func BenchmarkAStarGnp_1000_tenth(b *testing.B) { + benchmarkAStarNilHeuristic(b, gnpUndirected_1000_tenth) +} +func BenchmarkAStarGnp_10_half(b *testing.B) { + benchmarkAStarNilHeuristic(b, gnpUndirected_10_half) +} +func BenchmarkAStarGnp_100_half(b *testing.B) { + benchmarkAStarNilHeuristic(b, gnpUndirected_100_half) +} +func BenchmarkAStarGnp_1000_half(b *testing.B) { + benchmarkAStarNilHeuristic(b, gnpUndirected_1000_half) +} + +var ( + nswUndirected_10_2_2_2 = navigableSmallWorldUndirected(10, 2, 2, 2) + nswUndirected_10_2_5_2 = navigableSmallWorldUndirected(10, 2, 5, 2) + nswUndirected_100_5_10_2 = navigableSmallWorldUndirected(100, 5, 10, 2) + nswUndirected_100_5_20_2 = navigableSmallWorldUndirected(100, 5, 20, 2) +) + +func navigableSmallWorldUndirected(n, p, q int, r float64) graph.Undirected { + g := simple.NewUndirectedGraph() + gen.NavigableSmallWorld(g, []int{n, n}, p, q, r, nil) + return g +} + +func coordinatesForID(n graph.Node, c, r int) [2]int { + id := n.ID() + if id >= int64(c*r) { + panic("out of range") + } + return [2]int{int(id) / r, int(id) % r} +} + +// manhattanBetween returns the Manhattan distance between a and b. +func manhattanBetween(a, b [2]int) float64 { + var d int + for i, v := range a { + d += abs(v - b[i]) + } + return float64(d) +} + +func abs(a int) int { + if a < 0 { + return -a + } + return a +} + +func benchmarkAStarHeuristic(b *testing.B, g graph.Undirected, h Heuristic) { + var expanded int + for i := 0; i < b.N; i++ { + _, expanded = AStar(simple.Node(0), simple.Node(1), g, h) + } + if expanded == 0 { + b.Fatal("unexpected number of expanded nodes") + } +} + +func BenchmarkAStarUndirectedmallWorld_10_2_2_2(b *testing.B) { + benchmarkAStarHeuristic(b, nswUndirected_10_2_2_2, nil) +} +func BenchmarkAStarUndirectedmallWorld_10_2_2_2_Heur(b *testing.B) { + h := func(x, y graph.Node) float64 { + return manhattanBetween(coordinatesForID(x, 10, 10), coordinatesForID(y, 10, 10)) + } + benchmarkAStarHeuristic(b, nswUndirected_10_2_2_2, h) +} +func BenchmarkAStarUndirectedmallWorld_10_2_5_2(b *testing.B) { + benchmarkAStarHeuristic(b, nswUndirected_10_2_5_2, nil) +} +func BenchmarkAStarUndirectedmallWorld_10_2_5_2_Heur(b *testing.B) { + h := func(x, y graph.Node) float64 { + return manhattanBetween(coordinatesForID(x, 10, 10), coordinatesForID(y, 10, 10)) + } + benchmarkAStarHeuristic(b, nswUndirected_10_2_5_2, h) +} +func BenchmarkAStarUndirectedmallWorld_100_5_10_2(b *testing.B) { + benchmarkAStarHeuristic(b, nswUndirected_100_5_10_2, nil) +} +func BenchmarkAStarUndirectedmallWorld_100_5_10_2_Heur(b *testing.B) { + h := func(x, y graph.Node) float64 { + return manhattanBetween(coordinatesForID(x, 100, 100), coordinatesForID(y, 100, 100)) + } + benchmarkAStarHeuristic(b, nswUndirected_100_5_10_2, h) +} +func BenchmarkAStarUndirectedmallWorld_100_5_20_2(b *testing.B) { + benchmarkAStarHeuristic(b, nswUndirected_100_5_20_2, nil) +} +func BenchmarkAStarUndirectedmallWorld_100_5_20_2_Heur(b *testing.B) { + h := func(x, y graph.Node) float64 { + return manhattanBetween(coordinatesForID(x, 100, 100), coordinatesForID(y, 100, 100)) + } + benchmarkAStarHeuristic(b, nswUndirected_100_5_20_2, h) +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/control_flow.go b/vendor/gonum.org/v1/gonum/graph/path/control_flow.go new file mode 100644 index 00000000..5633e391 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/control_flow.go @@ -0,0 +1,118 @@ +// 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 path + +import ( + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/set" +) + +// Dominators returns all dominators for all nodes in g. It does not +// prune for strict post-dominators, immediate dominators etc. +// +// A dominates B if and only if the only path through B travels through A. +func Dominators(start graph.Node, g graph.Graph) map[int64]set.Nodes { + allNodes := make(set.Nodes) + nlist := g.Nodes() + dominators := make(map[int64]set.Nodes, len(nlist)) + for _, node := range nlist { + allNodes.Add(node) + } + + var to func(graph.Node) []graph.Node + switch g := g.(type) { + case graph.Directed: + to = g.To + default: + to = g.From + } + + for _, node := range nlist { + dominators[node.ID()] = make(set.Nodes) + if node.ID() == start.ID() { + dominators[node.ID()].Add(start) + } else { + dominators[node.ID()].Copy(allNodes) + } + } + + for somethingChanged := true; somethingChanged; { + somethingChanged = false + for _, node := range nlist { + if node.ID() == start.ID() { + continue + } + preds := to(node) + if len(preds) == 0 { + continue + } + tmp := make(set.Nodes).Copy(dominators[preds[0].ID()]) + for _, pred := range preds[1:] { + tmp.Intersect(tmp, dominators[pred.ID()]) + } + + dom := make(set.Nodes) + dom.Add(node) + + dom.Union(dom, tmp) + if !set.Equal(dom, dominators[node.ID()]) { + dominators[node.ID()] = dom + somethingChanged = true + } + } + } + + return dominators +} + +// PostDominators returns all post-dominators for all nodes in g. It does not +// prune for strict post-dominators, immediate post-dominators etc. +// +// A post-dominates B if and only if all paths from B travel through A. +func PostDominators(end graph.Node, g graph.Graph) map[int64]set.Nodes { + allNodes := make(set.Nodes) + nlist := g.Nodes() + dominators := make(map[int64]set.Nodes, len(nlist)) + for _, node := range nlist { + allNodes.Add(node) + } + + for _, node := range nlist { + dominators[node.ID()] = make(set.Nodes) + if node.ID() == end.ID() { + dominators[node.ID()].Add(end) + } else { + dominators[node.ID()].Copy(allNodes) + } + } + + for somethingChanged := true; somethingChanged; { + somethingChanged = false + for _, node := range nlist { + if node.ID() == end.ID() { + continue + } + succs := g.From(node) + if len(succs) == 0 { + continue + } + tmp := make(set.Nodes).Copy(dominators[succs[0].ID()]) + for _, succ := range succs[1:] { + tmp.Intersect(tmp, dominators[succ.ID()]) + } + + dom := make(set.Nodes) + dom.Add(node) + + dom.Union(dom, tmp) + if !set.Equal(dom, dominators[node.ID()]) { + dominators[node.ID()] = dom + somethingChanged = true + } + } + } + + return dominators +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/dijkstra.go b/vendor/gonum.org/v1/gonum/graph/path/dijkstra.go new file mode 100644 index 00000000..4c14d2b4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/dijkstra.go @@ -0,0 +1,147 @@ +// 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 path + +import ( + "container/heap" + + "gonum.org/v1/gonum/graph" +) + +// DijkstraFrom returns a shortest-path tree for a shortest path from u to all nodes in +// the graph g. If the graph does not implement graph.Weighter, UniformCost is used. +// DijkstraFrom will panic if g has a u-reachable negative edge weight. +// +// The time complexity of DijkstrFrom is O(|E|.log|V|). +func DijkstraFrom(u graph.Node, g graph.Graph) Shortest { + if !g.Has(u) { + return Shortest{from: u} + } + var weight Weighting + if wg, ok := g.(graph.Weighted); ok { + weight = wg.Weight + } else { + weight = UniformCost(g) + } + + nodes := g.Nodes() + path := newShortestFrom(u, nodes) + + // Dijkstra's algorithm here is implemented essentially as + // described in Function B.2 in figure 6 of UTCS Technical + // Report TR-07-54. + // + // This implementation deviates from the report as follows: + // - the value of path.dist for the start vertex u is initialized to 0; + // - outdated elements from the priority queue (i.e. with respect to the dist value) + // are skipped. + // + // http://www.cs.utexas.edu/ftp/techreports/tr07-54.pdf + Q := priorityQueue{{node: u, dist: 0}} + for Q.Len() != 0 { + mid := heap.Pop(&Q).(distanceNode) + k := path.indexOf[mid.node.ID()] + if mid.dist > path.dist[k] { + continue + } + for _, v := range g.From(mid.node) { + j := path.indexOf[v.ID()] + w, ok := weight(mid.node, v) + if !ok { + panic("dijkstra: unexpected invalid weight") + } + if w < 0 { + panic("dijkstra: negative edge weight") + } + joint := path.dist[k] + w + if joint < path.dist[j] { + heap.Push(&Q, distanceNode{node: v, dist: joint}) + path.set(j, joint, k) + } + } + } + + return path +} + +// DijkstraAllPaths returns a shortest-path tree for shortest paths in the graph g. +// If the graph does not implement graph.Weighter, UniformCost is used. +// DijkstraAllPaths will panic if g has a negative edge weight. +// +// The time complexity of DijkstrAllPaths is O(|V|.|E|+|V|^2.log|V|). +func DijkstraAllPaths(g graph.Graph) (paths AllShortest) { + paths = newAllShortest(g.Nodes(), false) + dijkstraAllPaths(g, paths) + return paths +} + +// dijkstraAllPaths is the all-paths implementation of Dijkstra. It is shared +// between DijkstraAllPaths and JohnsonAllPaths to avoid repeated allocation +// of the nodes slice and the indexOf map. It returns nothing, but stores the +// result of the work in the paths parameter which is a reference type. +func dijkstraAllPaths(g graph.Graph, paths AllShortest) { + var weight Weighting + if wg, ok := g.(graph.Weighted); ok { + weight = wg.Weight + } else { + weight = UniformCost(g) + } + + var Q priorityQueue + for i, u := range paths.nodes { + // Dijkstra's algorithm here is implemented essentially as + // described in Function B.2 in figure 6 of UTCS Technical + // Report TR-07-54 with the addition of handling multiple + // co-equal paths. + // + // http://www.cs.utexas.edu/ftp/techreports/tr07-54.pdf + + // Q must be empty at this point. + heap.Push(&Q, distanceNode{node: u, dist: 0}) + for Q.Len() != 0 { + mid := heap.Pop(&Q).(distanceNode) + k := paths.indexOf[mid.node.ID()] + if mid.dist < paths.dist.At(i, k) { + paths.dist.Set(i, k, mid.dist) + } + for _, v := range g.From(mid.node) { + j := paths.indexOf[v.ID()] + w, ok := weight(mid.node, v) + if !ok { + panic("dijkstra: unexpected invalid weight") + } + if w < 0 { + panic("dijkstra: negative edge weight") + } + joint := paths.dist.At(i, k) + w + if joint < paths.dist.At(i, j) { + heap.Push(&Q, distanceNode{node: v, dist: joint}) + paths.set(i, j, joint, k) + } else if joint == paths.dist.At(i, j) { + paths.add(i, j, k) + } + } + } + } +} + +type distanceNode struct { + node graph.Node + dist float64 +} + +// priorityQueue implements a no-dec priority queue. +type priorityQueue []distanceNode + +func (q priorityQueue) Len() int { return len(q) } +func (q priorityQueue) Less(i, j int) bool { return q[i].dist < q[j].dist } +func (q priorityQueue) Swap(i, j int) { q[i], q[j] = q[j], q[i] } +func (q *priorityQueue) Push(n interface{}) { *q = append(*q, n.(distanceNode)) } +func (q *priorityQueue) Pop() interface{} { + t := *q + var n interface{} + n, *q = t[len(t)-1], t[:len(t)-1] + return n +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/dijkstra_test.go b/vendor/gonum.org/v1/gonum/graph/path/dijkstra_test.go new file mode 100644 index 00000000..ccb74644 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/dijkstra_test.go @@ -0,0 +1,178 @@ +// 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 path + +import ( + "math" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/path/internal/testgraphs" +) + +func TestDijkstraFrom(t *testing.T) { + for _, test := range testgraphs.ShortestPathTests { + g := test.Graph() + for _, e := range test.Edges { + g.SetWeightedEdge(e) + } + + var ( + pt Shortest + + panicked bool + ) + func() { + defer func() { + panicked = recover() != nil + }() + pt = DijkstraFrom(test.Query.From(), g.(graph.Graph)) + }() + if panicked || test.HasNegativeWeight { + if !test.HasNegativeWeight { + t.Errorf("%q: unexpected panic", test.Name) + } + if !panicked { + t.Errorf("%q: expected panic for negative edge weight", test.Name) + } + continue + } + + if pt.From().ID() != test.Query.From().ID() { + t.Fatalf("%q: unexpected from node ID: got:%d want:%d", test.Name, pt.From().ID(), test.Query.From().ID()) + } + + p, weight := pt.To(test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + if weight := pt.WeightTo(test.Query.To()); weight != test.Weight { + t.Errorf("%q: unexpected weight from Weight: got:%f want:%f", + test.Name, weight, test.Weight) + } + + var got []int64 + for _, n := range p { + got = append(got, n.ID()) + } + ok := len(got) == 0 && len(test.WantPaths) == 0 + for _, sp := range test.WantPaths { + if reflect.DeepEqual(got, sp) { + ok = true + break + } + } + if !ok { + t.Errorf("%q: unexpected shortest path:\ngot: %v\nwant from:%v", + test.Name, p, test.WantPaths) + } + + np, weight := pt.To(test.NoPathFor.To()) + if pt.From().ID() == test.NoPathFor.From().ID() && (np != nil || !math.IsInf(weight, 1)) { + t.Errorf("%q: unexpected path:\ngot: path=%v weight=%f\nwant:path= weight=+Inf", + test.Name, np, weight) + } + } +} + +func TestDijkstraAllPaths(t *testing.T) { + for _, test := range testgraphs.ShortestPathTests { + g := test.Graph() + for _, e := range test.Edges { + g.SetWeightedEdge(e) + } + + var ( + pt AllShortest + + panicked bool + ) + func() { + defer func() { + panicked = recover() != nil + }() + pt = DijkstraAllPaths(g.(graph.Graph)) + }() + if panicked || test.HasNegativeWeight { + if !test.HasNegativeWeight { + t.Errorf("%q: unexpected panic", test.Name) + } + if !panicked { + t.Errorf("%q: expected panic for negative edge weight", test.Name) + } + continue + } + + // Check all random paths returned are OK. + for i := 0; i < 10; i++ { + p, weight, unique := pt.Between(test.Query.From(), test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + if weight := pt.Weight(test.Query.From(), test.Query.To()); weight != test.Weight { + t.Errorf("%q: unexpected weight from Weight: got:%f want:%f", + test.Name, weight, test.Weight) + } + if unique != test.HasUniquePath { + t.Errorf("%q: unexpected number of paths: got: unique=%t want: unique=%t", + test.Name, unique, test.HasUniquePath) + } + + var got []int64 + for _, n := range p { + got = append(got, n.ID()) + } + ok := len(got) == 0 && len(test.WantPaths) == 0 + for _, sp := range test.WantPaths { + if reflect.DeepEqual(got, sp) { + ok = true + break + } + } + if !ok { + t.Errorf("%q: unexpected shortest path:\ngot: %v\nwant from:%v", + test.Name, p, test.WantPaths) + } + } + + np, weight, unique := pt.Between(test.NoPathFor.From(), test.NoPathFor.To()) + if np != nil || !math.IsInf(weight, 1) || unique { + t.Errorf("%q: unexpected path:\ngot: path=%v weight=%f unique=%t\nwant:path= weight=+Inf unique=false", + test.Name, np, weight, unique) + } + + paths, weight := pt.AllBetween(test.Query.From(), test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + + var got [][]int64 + if len(paths) != 0 { + got = make([][]int64, len(paths)) + } + for i, p := range paths { + for _, v := range p { + got[i] = append(got[i], v.ID()) + } + } + sort.Sort(ordered.BySliceValues(got)) + if !reflect.DeepEqual(got, test.WantPaths) { + t.Errorf("testing %q: unexpected shortest paths:\ngot: %v\nwant:%v", + test.Name, got, test.WantPaths) + } + + nps, weight := pt.AllBetween(test.NoPathFor.From(), test.NoPathFor.To()) + if nps != nil || !math.IsInf(weight, 1) { + t.Errorf("%q: unexpected path:\ngot: paths=%v weight=%f\nwant:path= weight=+Inf", + test.Name, nps, weight) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/disjoint.go b/vendor/gonum.org/v1/gonum/graph/path/disjoint.go new file mode 100644 index 00000000..4f530f69 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/disjoint.go @@ -0,0 +1,87 @@ +// 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 path + +// A disjoint set is a collection of non-overlapping sets. That is, for any two sets in the +// disjoint set, their intersection is the empty set. +// +// A disjoint set has three principle operations: Make Set, Find, and Union. +// +// Make set creates a new set for an element (presuming it does not already exist in any set in +// the disjoint set), Find finds the set containing that element (if any), and Union merges two +// sets in the disjoint set. In general, algorithms operating on disjoint sets are "union-find" +// algorithms, where two sets are found with Find, and then joined with Union. +// +// A concrete example of a union-find algorithm can be found as discrete.Kruskal -- which unions +// two sets when an edge is created between two vertices, and refuses to make an edge between two +// vertices if they're part of the same set. +type disjointSet struct { + master map[int64]*disjointSetNode +} + +type disjointSetNode struct { + parent *disjointSetNode + rank int +} + +func newDisjointSet() *disjointSet { + return &disjointSet{master: make(map[int64]*disjointSetNode)} +} + +// If the element isn't already somewhere in there, adds it to the master set and its own tiny set. +func (ds *disjointSet) makeSet(e int64) { + if _, ok := ds.master[e]; ok { + return + } + dsNode := &disjointSetNode{rank: 0} + dsNode.parent = dsNode + ds.master[e] = dsNode +} + +// Returns the set the element belongs to, or nil if none. +func (ds *disjointSet) find(e int64) *disjointSetNode { + dsNode, ok := ds.master[e] + if !ok { + return nil + } + + return find(dsNode) +} + +func find(dsNode *disjointSetNode) *disjointSetNode { + if dsNode.parent != dsNode { + dsNode.parent = find(dsNode.parent) + } + + return dsNode.parent +} + +// Unions two subsets within the disjointSet. +// +// If x or y are not in this disjoint set, the behavior is undefined. If either pointer is nil, +// this function will panic. +func (ds *disjointSet) union(x, y *disjointSetNode) { + if x == nil || y == nil { + panic("Disjoint Set union on nil sets") + } + xRoot := find(x) + yRoot := find(y) + if xRoot == nil || yRoot == nil { + return + } + + if xRoot == yRoot { + return + } + + if xRoot.rank < yRoot.rank { + xRoot.parent = yRoot + } else if yRoot.rank < xRoot.rank { + yRoot.parent = xRoot + } else { + yRoot.parent = xRoot + xRoot.rank++ + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/disjoint_test.go b/vendor/gonum.org/v1/gonum/graph/path/disjoint_test.go new file mode 100644 index 00000000..2639592a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/disjoint_test.go @@ -0,0 +1,63 @@ +// 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 path + +import ( + "testing" +) + +func TestDisjointSetMakeSet(t *testing.T) { + ds := newDisjointSet() + if ds.master == nil { + t.Fatal("Internal disjoint set map erroneously nil") + } else if len(ds.master) != 0 { + t.Error("Disjoint set master map of wrong size") + } + + ds.makeSet(3) + if len(ds.master) != 1 { + t.Error("Disjoint set master map of wrong size") + } + + if node, ok := ds.master[3]; !ok { + t.Error("Make set did not successfully add element") + } else { + if node == nil { + t.Fatal("Disjoint set node from makeSet is nil") + } + + if node.rank != 0 { + t.Error("Node rank set incorrectly") + } + + if node.parent != node { + t.Error("Node parent set incorrectly") + } + } +} + +func TestDisjointSetFind(t *testing.T) { + ds := newDisjointSet() + + ds.makeSet(3) + ds.makeSet(5) + + if ds.find(3) == ds.find(5) { + t.Error("Disjoint sets incorrectly found to be the same") + } +} + +func TestUnion(t *testing.T) { + ds := newDisjointSet() + + ds.makeSet(3) + ds.makeSet(5) + + ds.union(ds.find(3), ds.find(5)) + + if ds.find(3) != ds.find(5) { + t.Error("Sets found to be disjoint after union") + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/doc.go b/vendor/gonum.org/v1/gonum/graph/path/doc.go new file mode 100644 index 00000000..f9e7b1dd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package path provides graph path finding functions. +package path // import "gonum.org/v1/gonum/graph/path" diff --git a/vendor/gonum.org/v1/gonum/graph/path/dynamic/doc.go b/vendor/gonum.org/v1/gonum/graph/path/dynamic/doc.go new file mode 100644 index 00000000..a0e9458f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/dynamic/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package dynamic provides incremental heuristic graph path finding functions. +package dynamic // import "gonum.org/v1/gonum/graph/path/dynamic" diff --git a/vendor/gonum.org/v1/gonum/graph/path/dynamic/dstarlite.go b/vendor/gonum.org/v1/gonum/graph/path/dynamic/dstarlite.go new file mode 100644 index 00000000..e8794dc8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/dynamic/dstarlite.go @@ -0,0 +1,491 @@ +// 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 dynamic + +import ( + "container/heap" + "fmt" + "math" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/path" + "gonum.org/v1/gonum/graph/simple" +) + +// DStarLite implements the D* Lite dynamic re-planning path search algorithm. +// +// doi:10.1109/tro.2004.838026 and ISBN:0-262-51129-0 pp476-483 +// +type DStarLite struct { + s, t *dStarLiteNode + last *dStarLiteNode + + model WorldModel + queue dStarLiteQueue + keyModifier float64 + + weight path.Weighting + heuristic path.Heuristic +} + +// WorldModel is a mutable weighted directed graph that returns nodes identified +// by id number. +type WorldModel interface { + graph.WeightedBuilder + graph.WeightedDirected + Node(id int64) graph.Node +} + +// NewDStarLite returns a new DStarLite planner for the path from s to t in g using the +// heuristic h. The world model, m, is used to store shortest path information during path +// planning. The world model must be an empty graph when NewDStarLite is called. +// +// If h is nil, the DStarLite will use the g.HeuristicCost method if g implements +// path.HeuristicCoster, falling back to path.NullHeuristic otherwise. If the graph does not +// implement graph.Weighter, path.UniformCost is used. NewDStarLite will panic if g has +// a negative edge weight. +func NewDStarLite(s, t graph.Node, g graph.Graph, h path.Heuristic, m WorldModel) *DStarLite { + /* + procedure Initialize() + {02”} U = ∅; + {03”} k_m = 0; + {04”} for all s ∈ S rhs(s) = g(s) = ∞; + {05”} rhs(s_goal) = 0; + {06”} U.Insert(s_goal, [h(s_start, s_goal); 0]); + */ + + d := &DStarLite{ + s: newDStarLiteNode(s), + t: newDStarLiteNode(t), // badKey is overwritten below. + + model: m, + + heuristic: h, + } + d.t.rhs = 0 + + /* + procedure Main() + {29”} s_last = s_start; + {30”} Initialize(); + */ + d.last = d.s + + if wg, ok := g.(graph.Weighted); ok { + d.weight = wg.Weight + } else { + d.weight = path.UniformCost(g) + } + if d.heuristic == nil { + if g, ok := g.(path.HeuristicCoster); ok { + d.heuristic = g.HeuristicCost + } else { + d.heuristic = path.NullHeuristic + } + } + + d.queue.insert(d.t, key{d.heuristic(s, t), 0}) + + for _, n := range g.Nodes() { + switch n.ID() { + case d.s.ID(): + d.model.AddNode(d.s) + case d.t.ID(): + d.model.AddNode(d.t) + default: + d.model.AddNode(newDStarLiteNode(n)) + } + } + for _, u := range d.model.Nodes() { + for _, v := range g.From(u) { + w := edgeWeight(d.weight, u, v) + if w < 0 { + panic("D* Lite: negative edge weight") + } + d.model.SetWeightedEdge(simple.WeightedEdge{F: u, T: d.model.Node(v.ID()), W: w}) + } + } + + /* + procedure Main() + {31”} ComputeShortestPath(); + */ + d.findShortestPath() + + return d +} + +// edgeWeight is a helper function that returns the weight of the edge between +// two connected nodes, u and v, using the provided weight function. It panics +// if there is no edge between u and v. +func edgeWeight(weight path.Weighting, u, v graph.Node) float64 { + w, ok := weight(u, v) + if !ok { + panic("D* Lite: unexpected invalid weight") + } + return w +} + +// keyFor is the CalculateKey procedure in the D* Lite papers. +func (d *DStarLite) keyFor(s *dStarLiteNode) key { + /* + procedure CalculateKey(s) + {01”} return [min(g(s), rhs(s)) + h(s_start, s) + k_m; min(g(s), rhs(s))]; + */ + k := key{1: math.Min(s.g, s.rhs)} + k[0] = k[1] + d.heuristic(d.s.Node, s.Node) + d.keyModifier + return k +} + +// update is the UpdateVertex procedure in the D* Lite papers. +func (d *DStarLite) update(u *dStarLiteNode) { + /* + procedure UpdateVertex(u) + {07”} if (g(u) != rhs(u) AND u ∈ U) U.Update(u,CalculateKey(u)); + {08”} else if (g(u) != rhs(u) AND u /∈ U) U.Insert(u,CalculateKey(u)); + {09”} else if (g(u) = rhs(u) AND u ∈ U) U.Remove(u); + */ + inQueue := u.inQueue() + switch { + case inQueue && u.g != u.rhs: + d.queue.update(u, d.keyFor(u)) + case !inQueue && u.g != u.rhs: + d.queue.insert(u, d.keyFor(u)) + case inQueue && u.g == u.rhs: + d.queue.remove(u) + } +} + +// findShortestPath is the ComputeShortestPath procedure in the D* Lite papers. +func (d *DStarLite) findShortestPath() { + /* + procedure ComputeShortestPath() + {10”} while (U.TopKey() < CalculateKey(s_start) OR rhs(s_start) > g(s_start)) + {11”} u = U.Top(); + {12”} k_old = U.TopKey(); + {13”} k_new = CalculateKey(u); + {14”} if(k_old < k_new) + {15”} U.Update(u, k_new); + {16”} else if (g(u) > rhs(u)) + {17”} g(u) = rhs(u); + {18”} U.Remove(u); + {19”} for all s ∈ Pred(u) + {20”} if (s != s_goal) rhs(s) = min(rhs(s), c(s, u) + g(u)); + {21”} UpdateVertex(s); + {22”} else + {23”} g_old = g(u); + {24”} g(u) = ∞; + {25”} for all s ∈ Pred(u) ∪ {u} + {26”} if (rhs(s) = c(s, u) + g_old) + {27”} if (s != s_goal) rhs(s) = min s'∈Succ(s)(c(s, s') + g(s')); + {28”} UpdateVertex(s); + */ + for d.queue.Len() != 0 { // We use d.queue.Len since d.queue does not return an infinite key when empty. + u := d.queue.top() + if !u.key.less(d.keyFor(d.s)) && d.s.rhs <= d.s.g { + break + } + switch kNew := d.keyFor(u); { + case u.key.less(kNew): + d.queue.update(u, kNew) + case u.g > u.rhs: + u.g = u.rhs + d.queue.remove(u) + for _, _s := range d.model.To(u) { + s := _s.(*dStarLiteNode) + if s.ID() != d.t.ID() { + s.rhs = math.Min(s.rhs, edgeWeight(d.model.Weight, s, u)+u.g) + } + d.update(s) + } + default: + gOld := u.g + u.g = math.Inf(1) + for _, _s := range append(d.model.To(u), u) { + s := _s.(*dStarLiteNode) + if s.rhs == edgeWeight(d.model.Weight, s, u)+gOld { + if s.ID() != d.t.ID() { + s.rhs = math.Inf(1) + for _, t := range d.model.From(s) { + s.rhs = math.Min(s.rhs, edgeWeight(d.model.Weight, s, t)+t.(*dStarLiteNode).g) + } + } + } + d.update(s) + } + } + } +} + +// Step performs one movement step along the best path towards the goal. +// It returns false if no further progression toward the goal can be +// achieved, either because the goal has been reached or because there +// is no path. +func (d *DStarLite) Step() bool { + /* + procedure Main() + {32”} while (s_start != s_goal) + {33”} // if (rhs(s_start) = ∞) then there is no known path + {34”} s_start = argmin s'∈Succ(s_start)(c(s_start, s') + g(s')); + */ + if d.s.ID() == d.t.ID() { + return false + } + if math.IsInf(d.s.rhs, 1) { + return false + } + + // We use rhs comparison to break ties + // between coequally weighted nodes. + rhs := math.Inf(1) + min := math.Inf(1) + + var next *dStarLiteNode + for _, _s := range d.model.From(d.s) { + s := _s.(*dStarLiteNode) + w := edgeWeight(d.model.Weight, d.s, s) + s.g + if w < min || (w == min && s.rhs < rhs) { + next = s + min = w + rhs = s.rhs + } + } + d.s = next + + /* + procedure Main() + {35”} Move to s_start; + */ + return true +} + +// MoveTo moves to n in the world graph. +func (d *DStarLite) MoveTo(n graph.Node) { + d.last = d.s + d.s = d.model.Node(n.ID()).(*dStarLiteNode) + d.keyModifier += d.heuristic(d.last, d.s) +} + +// UpdateWorld updates or adds edges in the world graph. UpdateWorld will +// panic if changes include a negative edge weight. +func (d *DStarLite) UpdateWorld(changes []graph.Edge) { + /* + procedure Main() + {36”} Scan graph for changed edge costs; + {37”} if any edge costs changed + {38”} k_m = k_m + h(s_last, s_start); + {39”} s_last = s_start; + {40”} for all directed edges (u, v) with changed edge costs + {41”} c_old = c(u, v); + {42”} Update the edge cost c(u, v); + {43”} if (c_old > c(u, v)) + {44”} if (u != s_goal) rhs(u) = min(rhs(u), c(u, v) + g(v)); + {45”} else if (rhs(u) = c_old + g(v)) + {46”} if (u != s_goal) rhs(u) = min s'∈Succ(u)(c(u, s') + g(s')); + {47”} UpdateVertex(u); + {48”} ComputeShortestPath() + */ + if len(changes) == 0 { + return + } + d.keyModifier += d.heuristic(d.last, d.s) + d.last = d.s + for _, e := range changes { + from := e.From() + to := e.To() + c, _ := d.weight(from, to) + if c < 0 { + panic("D* Lite: negative edge weight") + } + cOld, _ := d.model.Weight(from, to) + u := d.worldNodeFor(from) + v := d.worldNodeFor(to) + d.model.SetWeightedEdge(simple.WeightedEdge{F: u, T: v, W: c}) + if cOld > c { + if u.ID() != d.t.ID() { + u.rhs = math.Min(u.rhs, c+v.g) + } + } else if u.rhs == cOld+v.g { + if u.ID() != d.t.ID() { + u.rhs = math.Inf(1) + for _, t := range d.model.From(u) { + u.rhs = math.Min(u.rhs, edgeWeight(d.model.Weight, u, t)+t.(*dStarLiteNode).g) + } + } + } + d.update(u) + } + d.findShortestPath() +} + +func (d *DStarLite) worldNodeFor(n graph.Node) *dStarLiteNode { + switch w := d.model.Node(n.ID()).(type) { + case *dStarLiteNode: + return w + case graph.Node: + panic(fmt.Sprintf("D* Lite: illegal world model node type: %T", w)) + default: + return newDStarLiteNode(n) + } +} + +// Here returns the current location. +func (d *DStarLite) Here() graph.Node { + return d.s.Node +} + +// Path returns the path from the current location to the goal and the +// weight of the path. +func (d *DStarLite) Path() (p []graph.Node, weight float64) { + u := d.s + p = []graph.Node{u.Node} + for u.ID() != d.t.ID() { + if math.IsInf(u.rhs, 1) { + return nil, math.Inf(1) + } + + // We use stored rhs comparison to break + // ties between calculated rhs-coequal nodes. + rhsMin := math.Inf(1) + min := math.Inf(1) + var ( + next *dStarLiteNode + cost float64 + ) + for _, _v := range d.model.From(u) { + v := _v.(*dStarLiteNode) + w := edgeWeight(d.model.Weight, u, v) + if rhs := w + v.g; rhs < min || (rhs == min && v.rhs < rhsMin) { + next = v + min = rhs + rhsMin = v.rhs + cost = w + } + } + if next == nil { + return nil, math.NaN() + } + u = next + weight += cost + p = append(p, u.Node) + } + return p, weight +} + +/* +The pseudocode uses the following functions to manage the priority +queue: + + * U.Top() returns a vertex with the smallest priority of all + vertices in priority queue U. + * U.TopKey() returns the smallest priority of all vertices in + priority queue U. (If is empty, then U.TopKey() returns [∞;∞].) + * U.Pop() deletes the vertex with the smallest priority in + priority queue U and returns the vertex. + * U.Insert(s, k) inserts vertex s into priority queue with + priority k. + * U.Update(s, k) changes the priority of vertex s in priority + queue U to k. (It does nothing if the current priority of vertex + s already equals k.) + * Finally, U.Remove(s) removes vertex s from priority queue U. +*/ + +// key is a D* Lite priority queue key. +type key [2]float64 + +var badKey = key{math.NaN(), math.NaN()} + +// less returns whether k is less than other. From ISBN:0-262-51129-0 pp476-483: +// +// k ≤ k' iff k₁ < k'₁ OR (k₁ == k'₁ AND k₂ ≤ k'₂) +// +func (k key) less(other key) bool { + if k != k || other != other { + panic("D* Lite: poisoned key") + } + return k[0] < other[0] || (k[0] == other[0] && k[1] < other[1]) +} + +// dStarLiteNode adds D* Lite accounting to a graph.Node. +type dStarLiteNode struct { + graph.Node + key key + idx int + rhs float64 + g float64 +} + +// newDStarLiteNode returns a dStarLite node that is in a legal state +// for existence outside the DStarLite priority queue. +func newDStarLiteNode(n graph.Node) *dStarLiteNode { + return &dStarLiteNode{ + Node: n, + rhs: math.Inf(1), + g: math.Inf(1), + key: badKey, + idx: -1, + } +} + +// inQueue returns whether the node is in the queue. +func (q *dStarLiteNode) inQueue() bool { + return q.idx >= 0 +} + +// dStarLiteQueue is a D* Lite priority queue. +type dStarLiteQueue []*dStarLiteNode + +func (q dStarLiteQueue) Less(i, j int) bool { + return q[i].key.less(q[j].key) +} + +func (q dStarLiteQueue) Swap(i, j int) { + q[i], q[j] = q[j], q[i] + q[i].idx = i + q[j].idx = j +} + +func (q dStarLiteQueue) Len() int { + return len(q) +} + +func (q *dStarLiteQueue) Push(x interface{}) { + n := x.(*dStarLiteNode) + n.idx = len(*q) + *q = append(*q, n) +} + +func (q *dStarLiteQueue) Pop() interface{} { + n := (*q)[len(*q)-1] + n.idx = -1 + *q = (*q)[:len(*q)-1] + return n +} + +// top returns the top node in the queue. Note that instead of +// returning a key [∞;∞] when q is empty, the caller checks for +// an empty queue by calling q.Len. +func (q dStarLiteQueue) top() *dStarLiteNode { + return q[0] +} + +// insert puts the node u into the queue with the key k. +func (q *dStarLiteQueue) insert(u *dStarLiteNode, k key) { + u.key = k + heap.Push(q, u) +} + +// update updates the node in the queue identified by id with the key k. +func (q *dStarLiteQueue) update(n *dStarLiteNode, k key) { + n.key = k + heap.Fix(q, n.idx) +} + +// remove removes the node identified by id from the queue. +func (q *dStarLiteQueue) remove(n *dStarLiteNode) { + heap.Remove(q, n.idx) + n.key = badKey + n.idx = -1 +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/dynamic/dstarlite_test.go b/vendor/gonum.org/v1/gonum/graph/path/dynamic/dstarlite_test.go new file mode 100644 index 00000000..9c53a5da --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/dynamic/dstarlite_test.go @@ -0,0 +1,680 @@ +// 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 dynamic + +import ( + "bytes" + "flag" + "fmt" + "math" + "reflect" + "strings" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/path" + "gonum.org/v1/gonum/graph/path/internal" + "gonum.org/v1/gonum/graph/path/internal/testgraphs" + "gonum.org/v1/gonum/graph/simple" +) + +var ( + debug = flag.Bool("debug", false, "write path progress for failing dynamic case tests") + vdebug = flag.Bool("vdebug", false, "write path progress for all dynamic case tests (requires test.v)") + maxWide = flag.Int("maxwidth", 5, "maximum width grid to dump for debugging") +) + +func TestDStarLiteNullHeuristic(t *testing.T) { + for _, test := range testgraphs.ShortestPathTests { + // Skip zero-weight cycles. + if strings.HasPrefix(test.Name, "zero-weight") { + continue + } + + g := test.Graph() + for _, e := range test.Edges { + g.SetWeightedEdge(e) + } + + var ( + d *DStarLite + + panicked bool + ) + func() { + defer func() { + panicked = recover() != nil + }() + d = NewDStarLite(test.Query.From(), test.Query.To(), g.(graph.Graph), path.NullHeuristic, simple.NewWeightedDirectedGraph(0, math.Inf(1))) + }() + if panicked || test.HasNegativeWeight { + if !test.HasNegativeWeight { + t.Errorf("%q: unexpected panic", test.Name) + } + if !panicked { + t.Errorf("%q: expected panic for negative edge weight", test.Name) + } + continue + } + + p, weight := d.Path() + + if !math.IsInf(weight, 1) && p[0].ID() != test.Query.From().ID() { + t.Fatalf("%q: unexpected from node ID: got:%d want:%d", test.Name, p[0].ID(), test.Query.From().ID()) + } + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + + var got []int64 + for _, n := range p { + got = append(got, n.ID()) + } + ok := len(got) == 0 && len(test.WantPaths) == 0 + for _, sp := range test.WantPaths { + if reflect.DeepEqual(got, sp) { + ok = true + break + } + } + if !ok { + t.Errorf("%q: unexpected shortest path:\ngot: %v\nwant from:%v", + test.Name, p, test.WantPaths) + } + } +} + +var dynamicDStarLiteTests = []struct { + g *internal.Grid + radius float64 + all bool + diag, unit bool + remember []bool + modify func(*internal.LimitedVisionGrid) + + heuristic func(dx, dy float64) float64 + + s, t graph.Node + + want []graph.Node + weight float64 + wantedPaths map[int64][]graph.Node +}{ + { + // This is the example shown in figures 6 and 7 of doi:10.1109/tro.2004.838026. + g: internal.NewGridFrom( + "...", + ".*.", + ".*.", + ".*.", + "...", + ), + radius: 1.5, + all: true, + diag: true, + unit: true, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Max(math.Abs(dx), math.Abs(dy)) + }, + + s: simple.Node(3), + t: simple.Node(14), + + want: []graph.Node{ + simple.Node(3), + simple.Node(6), + simple.Node(9), + simple.Node(13), + simple.Node(14), + }, + weight: 4, + }, + { + // This is a small example that has the property that the first corner + // may be taken incorrectly at 90° or correctly at 45° because the + // calculated rhs values of 12 and 17 are tied when moving from node + // 16, and the grid is small enough to examine by a dump. + g: internal.NewGridFrom( + ".....", + "...*.", + "**.*.", + "...*.", + ), + radius: 1.5, + all: true, + diag: true, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Max(math.Abs(dx), math.Abs(dy)) + }, + + s: simple.Node(15), + t: simple.Node(14), + + want: []graph.Node{ + simple.Node(15), + simple.Node(16), + simple.Node(12), + simple.Node(7), + simple.Node(3), + simple.Node(9), + simple.Node(14), + }, + weight: 7.242640687119285, + wantedPaths: map[int64][]graph.Node{ + 12: {simple.Node(12), simple.Node(7), simple.Node(3), simple.Node(9), simple.Node(14)}, + }, + }, + { + // This is the example shown in figure 2 of doi:10.1109/tro.2004.838026 + // with the exception that diagonal edge weights are calculated with the hypot + // function instead of a step count and only allowing information to be known + // from exploration. + g: internal.NewGridFrom( + "..................", + "..................", + "..................", + "..................", + "..................", + "..................", + "....*.*...........", + "*****.***.........", + "......*...........", + "......***.........", + "......*...........", + "......*...........", + "......*...........", + "*****.*...........", + "......*...........", + ), + radius: 1.5, + all: true, + diag: true, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Max(math.Abs(dx), math.Abs(dy)) + }, + + s: simple.Node(253), + t: simple.Node(122), + + want: []graph.Node{ + simple.Node(253), + simple.Node(254), + simple.Node(255), + simple.Node(256), + simple.Node(239), + simple.Node(221), + simple.Node(203), + simple.Node(185), + simple.Node(167), + simple.Node(149), + simple.Node(131), + simple.Node(113), + simple.Node(96), + + // The following section depends + // on map iteration order. + nil, + nil, + nil, + nil, + nil, + nil, + nil, + + simple.Node(122), + }, + weight: 21.242640687119287, + }, + { + // This is the example shown in figure 2 of doi:10.1109/tro.2004.838026 + // with the exception that diagonal edge weights are calculated with the hypot + // function instead of a step count, not closing the exit and only allowing + // information to be known from exploration. + g: internal.NewGridFrom( + "..................", + "..................", + "..................", + "..................", + "..................", + "..................", + "....*.*...........", + "*****.***.........", + "..................", // Keep open. + "......***.........", + "......*...........", + "......*...........", + "......*...........", + "*****.*...........", + "......*...........", + ), + radius: 1.5, + all: true, + diag: true, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Max(math.Abs(dx), math.Abs(dy)) + }, + + s: simple.Node(253), + t: simple.Node(122), + + want: []graph.Node{ + simple.Node(253), + simple.Node(254), + simple.Node(255), + simple.Node(256), + simple.Node(239), + simple.Node(221), + simple.Node(203), + simple.Node(185), + simple.Node(167), + simple.Node(150), + simple.Node(151), + simple.Node(152), + + // The following section depends + // on map iteration order. + nil, + nil, + nil, + nil, + nil, + + simple.Node(122), + }, + weight: 18.656854249492383, + }, + { + // This is the example shown in figure 2 of doi:10.1109/tro.2004.838026 + // with the exception that diagonal edge weights are calculated with the hypot + // function instead of a step count, the exit is closed at a distance and + // information is allowed to be known from exploration. + g: internal.NewGridFrom( + "..................", + "..................", + "..................", + "..................", + "..................", + "..................", + "....*.*...........", + "*****.***.........", + "........*.........", + "......***.........", + "......*...........", + "......*...........", + "......*...........", + "*****.*...........", + "......*...........", + ), + radius: 1.5, + all: true, + diag: true, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Max(math.Abs(dx), math.Abs(dy)) + }, + + s: simple.Node(253), + t: simple.Node(122), + + want: []graph.Node{ + simple.Node(253), + simple.Node(254), + simple.Node(255), + simple.Node(256), + simple.Node(239), + simple.Node(221), + simple.Node(203), + simple.Node(185), + simple.Node(167), + simple.Node(150), + simple.Node(151), + simple.Node(150), + simple.Node(131), + simple.Node(113), + simple.Node(96), + + // The following section depends + // on map iteration order. + nil, + nil, + nil, + nil, + nil, + nil, + nil, + + simple.Node(122), + }, + weight: 24.07106781186548, + }, + { + // This is the example shown in figure 2 of doi:10.1109/tro.2004.838026 + // with the exception that diagonal edge weights are calculated with the hypot + // function instead of a step count. + g: internal.NewGridFrom( + "..................", + "..................", + "..................", + "..................", + "..................", + "..................", + "....*.*...........", + "*****.***.........", + "......*...........", // Forget this wall. + "......***.........", + "......*...........", + "......*...........", + "......*...........", + "*****.*...........", + "......*...........", + ), + radius: 1.5, + all: true, + diag: true, + remember: []bool{true}, + + modify: func(l *internal.LimitedVisionGrid) { + all := l.Grid.AllVisible + l.Grid.AllVisible = false + for _, n := range l.Nodes() { + l.Known[n.ID()] = !l.Grid.Has(n) + } + l.Grid.AllVisible = all + + const ( + wallRow = 8 + wallCol = 6 + ) + l.Known[l.NodeAt(wallRow, wallCol).ID()] = false + + // Check we have a correctly modified representation. + for _, u := range l.Nodes() { + for _, v := range l.Nodes() { + if l.HasEdgeBetween(u, v) != l.Grid.HasEdgeBetween(u, v) { + ur, uc := l.RowCol(u.ID()) + vr, vc := l.RowCol(v.ID()) + if (ur == wallRow && uc == wallCol) || (vr == wallRow && vc == wallCol) { + if !l.HasEdgeBetween(u, v) { + panic(fmt.Sprintf("expected to believe edge between %v (%d,%d) and %v (%d,%d) is passable", + u, v, ur, uc, vr, vc)) + } + continue + } + panic(fmt.Sprintf("disagreement about edge between %v (%d,%d) and %v (%d,%d): got:%t want:%t", + u, v, ur, uc, vr, vc, l.HasEdgeBetween(u, v), l.Grid.HasEdgeBetween(u, v))) + } + } + } + }, + + heuristic: func(dx, dy float64) float64 { + return math.Max(math.Abs(dx), math.Abs(dy)) + }, + + s: simple.Node(253), + t: simple.Node(122), + + want: []graph.Node{ + simple.Node(253), + simple.Node(254), + simple.Node(255), + simple.Node(256), + simple.Node(239), + simple.Node(221), + simple.Node(203), + simple.Node(185), + simple.Node(167), + simple.Node(149), + simple.Node(131), + simple.Node(113), + simple.Node(96), + + // The following section depends + // on map iteration order. + nil, + nil, + nil, + nil, + nil, + nil, + nil, + + simple.Node(122), + }, + weight: 21.242640687119287, + }, + { + g: internal.NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1, + all: true, + diag: false, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Hypot(dx, dy) + }, + + s: simple.Node(1), + t: simple.Node(14), + + want: []graph.Node{ + simple.Node(1), + simple.Node(2), + simple.Node(6), + simple.Node(10), + simple.Node(14), + }, + weight: 4, + }, + { + g: internal.NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1.5, + all: true, + diag: true, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Hypot(dx, dy) + }, + + s: simple.Node(1), + t: simple.Node(14), + + want: []graph.Node{ + simple.Node(1), + simple.Node(6), + simple.Node(10), + simple.Node(14), + }, + weight: math.Sqrt2 + 2, + }, + { + g: internal.NewGridFrom( + "...", + ".*.", + ".*.", + ".*.", + ".*.", + ), + radius: 1, + all: true, + diag: false, + remember: []bool{false, true}, + + heuristic: func(dx, dy float64) float64 { + return math.Hypot(dx, dy) + }, + + s: simple.Node(6), + t: simple.Node(14), + + want: []graph.Node{ + simple.Node(6), + simple.Node(9), + simple.Node(12), + simple.Node(9), + simple.Node(6), + simple.Node(3), + simple.Node(0), + simple.Node(1), + simple.Node(2), + simple.Node(5), + simple.Node(8), + simple.Node(11), + simple.Node(14), + }, + weight: 12, + }, +} + +func TestDStarLiteDynamic(t *testing.T) { + for i, test := range dynamicDStarLiteTests { + for _, remember := range test.remember { + l := &internal.LimitedVisionGrid{ + Grid: test.g, + VisionRadius: test.radius, + Location: test.s, + } + if remember { + l.Known = make(map[int64]bool) + } + + l.Grid.AllVisible = test.all + + l.Grid.AllowDiagonal = test.diag + l.Grid.UnitEdgeWeight = test.unit + + if test.modify != nil { + test.modify(l) + } + + got := []graph.Node{test.s} + l.MoveTo(test.s) + + heuristic := func(a, b graph.Node) float64 { + ax, ay := l.XY(a) + bx, by := l.XY(b) + return test.heuristic(ax-bx, ay-by) + } + + world := simple.NewWeightedDirectedGraph(0, math.Inf(1)) + d := NewDStarLite(test.s, test.t, l, heuristic, world) + var ( + dp *dumper + buf bytes.Buffer + ) + _, c := l.Grid.Dims() + if c <= *maxWide && (*debug || *vdebug) { + dp = &dumper{ + w: &buf, + + dStarLite: d, + grid: l, + } + } + + dp.dump(true) + dp.printEdges("Initial world knowledge: %s\n\n", simpleWeightedEdgesOf(l, world.Edges())) + for d.Step() { + changes, _ := l.MoveTo(d.Here()) + got = append(got, l.Location) + d.UpdateWorld(changes) + dp.dump(true) + if wantedPath, ok := test.wantedPaths[l.Location.ID()]; ok { + gotPath, _ := d.Path() + if !samePath(gotPath, wantedPath) { + t.Errorf("unexpected intermediate path estimation for test %d %s memory:\ngot: %v\nwant:%v", + i, memory(remember), gotPath, wantedPath) + } + } + dp.printEdges("Edges changing after last step:\n%s\n\n", simpleWeightedEdgesOf(l, changes)) + } + + if weight := weightOf(got, l.Grid); !samePath(got, test.want) || weight != test.weight { + t.Errorf("unexpected path for test %d %s memory got weight:%v want weight:%v:\ngot: %v\nwant:%v", + i, memory(remember), weight, test.weight, got, test.want) + b, err := l.Render(got) + t.Errorf("path taken (err:%v):\n%s", err, b) + if c <= *maxWide && (*debug || *vdebug) { + t.Error(buf.String()) + } + } else if c <= *maxWide && *vdebug { + t.Logf("Test %d:\n%s", i, buf.String()) + } + } + } +} + +type memory bool + +func (m memory) String() string { + if m { + return "with" + } + return "without" +} + +// samePath compares two paths for equality ignoring nodes that are nil. +func samePath(a, b []graph.Node) bool { + if len(a) != len(b) { + return false + } + for i, e := range a { + if e == nil || b[i] == nil { + continue + } + if e.ID() != b[i].ID() { + return false + } + } + return true +} + +// weightOf return the weight of the path in g. +func weightOf(path []graph.Node, g graph.Weighted) float64 { + var w float64 + if len(path) > 1 { + for p, n := range path[1:] { + ew, ok := g.Weight(path[p], n) + if !ok { + return math.Inf(1) + } + w += ew + } + } + return w +} + +// simpleWeightedEdgesOf returns the weighted edges in g corresponding to the given edges. +func simpleWeightedEdgesOf(g graph.Weighted, edges []graph.Edge) []simple.WeightedEdge { + w := make([]simple.WeightedEdge, len(edges)) + for i, e := range edges { + w[i].F = e.From() + w[i].T = e.To() + ew, _ := g.Weight(e.From(), e.To()) + w[i].W = ew + } + return w +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/dynamic/dumper_test.go b/vendor/gonum.org/v1/gonum/graph/path/dynamic/dumper_test.go new file mode 100644 index 00000000..f76a3649 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/dynamic/dumper_test.go @@ -0,0 +1,153 @@ +// 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 dynamic + +import ( + "bytes" + "fmt" + "io" + "sort" + "text/tabwriter" + + "gonum.org/v1/gonum/graph/path/internal" + "gonum.org/v1/gonum/graph/simple" +) + +// dumper implements a grid D* Lite statistics dump. +type dumper struct { + step int + + dStarLite *DStarLite + grid *internal.LimitedVisionGrid + + w io.Writer +} + +// dump writes a single step of a D* Lite path search to the dumper's io.Writer. +func (d *dumper) dump(withpath bool) { + if d == nil { + return + } + var pathStep map[int64]int + if withpath { + pathStep = make(map[int64]int) + path, _ := d.dStarLite.Path() + for i, n := range path { + pathStep[n.ID()] = i + } + } + fmt.Fprintf(d.w, "Step:%d kₘ=%v\n", d.step, d.dStarLite.keyModifier) + d.step++ + w := tabwriter.NewWriter(d.w, 0, 0, 0, ' ', tabwriter.Debug) + rows, cols := d.grid.Grid.Dims() + for r := 0; r < rows; r++ { + if r == 0 { + for c := 0; c < cols; c++ { + if c != 0 { + fmt.Fprint(w, "\t") + } + fmt.Fprint(w, "-------------------") + } + fmt.Fprintln(w) + } + for ln := 0; ln < 6; ln++ { + for c := 0; c < cols; c++ { + if c != 0 { + fmt.Fprint(w, "\t") + } + n := d.dStarLite.model.Node(d.grid.NodeAt(r, c).ID()).(*dStarLiteNode) + switch ln { + case 0: + if n.ID() == d.grid.Location.ID() { + if d.grid.Grid.HasOpen(n) { + fmt.Fprintf(w, "id:%2d >@<", n.ID()) + } else { + // Mark location as illegal. + fmt.Fprintf(w, "id:%2d >!<", n.ID()) + } + } else if n.ID() == d.dStarLite.t.ID() { + fmt.Fprintf(w, "id:%2d G", n.ID()) + // Mark goal cell as illegal. + if !d.grid.Grid.HasOpen(n) { + fmt.Fprint(w, "!") + } + } else if pathStep[n.ID()] > 0 { + fmt.Fprintf(w, "id:%2d %2d", n.ID(), pathStep[n.ID()]) + // Mark path cells with an obstruction. + if !d.grid.Grid.HasOpen(n) { + fmt.Fprint(w, "!") + } + } else { + fmt.Fprintf(w, "id:%2d", n.ID()) + // Mark cells with an obstruction. + if !d.grid.Grid.HasOpen(n) { + fmt.Fprint(w, " *") + } + } + case 1: + fmt.Fprintf(w, "h: %.4v", d.dStarLite.heuristic(n, d.dStarLite.Here())) + case 2: + fmt.Fprintf(w, "g: %.4v", n.g) + case 3: + fmt.Fprintf(w, "rhs:%.4v", n.rhs) + case 4: + if n.g != n.rhs { + fmt.Fprintf(w, "key:%.3f", n.key) + } + if n.key == n.key { + // Mark keys for nodes in the priority queue. + // We use NaN inequality for this check since all + // keys not in the queue must have their key set + // to badKey. + // + // This should always mark cells where key is + // printed. + fmt.Fprint(w, "*") + } + if n.g > n.rhs { + fmt.Fprint(w, "^") + } + if n.g < n.rhs { + fmt.Fprint(w, "v") + } + default: + fmt.Fprint(w, "-------------------") + } + } + fmt.Fprintln(w) + } + } + w.Flush() + fmt.Fprintln(d.w) +} + +// printEdges pretty prints the given edges to the dumper's io.Writer using the provided +// format string. The edges are first formated to a string, so the format string must use +// the %s verb to indicate where the edges are to be printed. +func (d *dumper) printEdges(format string, edges []simple.WeightedEdge) { + if d == nil { + return + } + var buf bytes.Buffer + sort.Sort(lexically(edges)) + for i, e := range edges { + if i != 0 { + fmt.Fprint(&buf, ", ") + } + fmt.Fprintf(&buf, "%d->%d:%.4v", e.From().ID(), e.To().ID(), e.Weight()) + } + if len(edges) == 0 { + fmt.Fprint(&buf, "none") + } + fmt.Fprintf(d.w, format, buf.Bytes()) +} + +type lexically []simple.WeightedEdge + +func (l lexically) Len() int { return len(l) } +func (l lexically) Less(i, j int) bool { + return l[i].From().ID() < l[j].From().ID() || (l[i].From().ID() == l[j].From().ID() && l[i].To().ID() < l[j].To().ID()) +} +func (l lexically) Swap(i, j int) { l[i], l[j] = l[j], l[i] } diff --git a/vendor/gonum.org/v1/gonum/graph/path/floydwarshall.go b/vendor/gonum.org/v1/gonum/graph/path/floydwarshall.go new file mode 100644 index 00000000..310fec6d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/floydwarshall.go @@ -0,0 +1,59 @@ +// 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 path + +import "gonum.org/v1/gonum/graph" + +// FloydWarshall returns a shortest-path tree for the graph g or false indicating +// that a negative cycle exists in the graph. If the graph does not implement +// graph.Weighter, UniformCost is used. +// +// The time complexity of FloydWarshall is O(|V|^3). +func FloydWarshall(g graph.Graph) (paths AllShortest, ok bool) { + var weight Weighting + if wg, ok := g.(graph.Weighted); ok { + weight = wg.Weight + } else { + weight = UniformCost(g) + } + + nodes := g.Nodes() + paths = newAllShortest(nodes, true) + for i, u := range nodes { + paths.dist.Set(i, i, 0) + for _, v := range g.From(u) { + j := paths.indexOf[v.ID()] + w, ok := weight(u, v) + if !ok { + panic("floyd-warshall: unexpected invalid weight") + } + paths.set(i, j, w, j) + } + } + + for k := range nodes { + for i := range nodes { + for j := range nodes { + ij := paths.dist.At(i, j) + joint := paths.dist.At(i, k) + paths.dist.At(k, j) + if ij > joint { + paths.set(i, j, joint, paths.at(i, k)...) + } else if ij-joint == 0 { + paths.add(i, j, paths.at(i, k)...) + } + } + } + } + + ok = true + for i := range nodes { + if paths.dist.At(i, i) < 0 { + ok = false + break + } + } + + return paths, ok +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/floydwarshall_test.go b/vendor/gonum.org/v1/gonum/graph/path/floydwarshall_test.go new file mode 100644 index 00000000..d23c0341 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/floydwarshall_test.go @@ -0,0 +1,102 @@ +// 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 path + +import ( + "math" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/path/internal/testgraphs" +) + +func TestFloydWarshall(t *testing.T) { + for _, test := range testgraphs.ShortestPathTests { + g := test.Graph() + for _, e := range test.Edges { + g.SetWeightedEdge(e) + } + + pt, ok := FloydWarshall(g.(graph.Graph)) + if test.HasNegativeCycle { + if ok { + t.Errorf("%q: expected negative cycle", test.Name) + } + continue + } + if !ok { + t.Fatalf("%q: unexpected negative cycle", test.Name) + } + + // Check all random paths returned are OK. + for i := 0; i < 10; i++ { + p, weight, unique := pt.Between(test.Query.From(), test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + if weight := pt.Weight(test.Query.From(), test.Query.To()); weight != test.Weight { + t.Errorf("%q: unexpected weight from Weight: got:%f want:%f", + test.Name, weight, test.Weight) + } + if unique != test.HasUniquePath { + t.Errorf("%q: unexpected number of paths: got: unique=%t want: unique=%t", + test.Name, unique, test.HasUniquePath) + } + + var got []int64 + for _, n := range p { + got = append(got, n.ID()) + } + ok := len(got) == 0 && len(test.WantPaths) == 0 + for _, sp := range test.WantPaths { + if reflect.DeepEqual(got, sp) { + ok = true + break + } + } + if !ok { + t.Errorf("%q: unexpected shortest path:\ngot: %v\nwant from:%v", + test.Name, p, test.WantPaths) + } + } + + np, weight, unique := pt.Between(test.NoPathFor.From(), test.NoPathFor.To()) + if np != nil || !math.IsInf(weight, 1) || unique { + t.Errorf("%q: unexpected path:\ngot: path=%v weight=%f unique=%t\nwant:path= weight=+Inf unique=false", + test.Name, np, weight, unique) + } + + paths, weight := pt.AllBetween(test.Query.From(), test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + + var got [][]int64 + if len(paths) != 0 { + got = make([][]int64, len(paths)) + } + for i, p := range paths { + for _, v := range p { + got[i] = append(got[i], v.ID()) + } + } + sort.Sort(ordered.BySliceValues(got)) + if !reflect.DeepEqual(got, test.WantPaths) { + t.Errorf("testing %q: unexpected shortest paths:\ngot: %v\nwant:%v", + test.Name, got, test.WantPaths) + } + + nps, weight := pt.AllBetween(test.NoPathFor.From(), test.NoPathFor.To()) + if nps != nil || !math.IsInf(weight, 1) { + t.Errorf("%q: unexpected path:\ngot: paths=%v weight=%f\nwant:path= weight=+Inf", + test.Name, nps, weight) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/internal/grid.go b/vendor/gonum.org/v1/gonum/graph/path/internal/grid.go new file mode 100644 index 00000000..4afe8fb6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/internal/grid.go @@ -0,0 +1,296 @@ +// 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 internal + +import ( + "errors" + "fmt" + "math" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +const ( + Closed = '*' // Closed is the closed grid node representation. + Open = '.' // Open is the open grid node repesentation. + Unknown = '?' // Unknown is the unknown grid node repesentation. +) + +// Grid is a 2D grid planar undirected graph. +type Grid struct { + // AllowDiagonal specifies whether + // diagonally adjacent nodes can + // be connected by an edge. + AllowDiagonal bool + // UnitEdgeWeight specifies whether + // finite edge weights are returned as + // the unit length. Otherwise edge + // weights are the Euclidean distance + // between connected nodes. + UnitEdgeWeight bool + + // AllVisible specifies whether + // non-open nodes are visible + // in calls to Nodes and HasNode. + AllVisible bool + + open []bool + r, c int +} + +// NewGrid returns an r by c grid with all positions +// set to the specified open state. +func NewGrid(r, c int, open bool) *Grid { + states := make([]bool, r*c) + if open { + for i := range states { + states[i] = true + } + } + return &Grid{ + open: states, + r: r, + c: c, + } +} + +// NewGridFrom returns a grid specified by the rows strings. All rows must +// be the same length and must only contain the Open or Closed characters, +// NewGridFrom will panic otherwise. +func NewGridFrom(rows ...string) *Grid { + if len(rows) == 0 { + return nil + } + for i, r := range rows[:len(rows)-1] { + if len(r) != len(rows[i+1]) { + panic("grid: unequal row lengths") + } + } + states := make([]bool, 0, len(rows)*len(rows[0])) + for _, r := range rows { + for _, b := range r { + switch b { + case Closed: + states = append(states, false) + case Open: + states = append(states, true) + default: + panic(fmt.Sprintf("grid: invalid state: %q", r)) + } + } + } + return &Grid{ + open: states, + r: len(rows), + c: len(rows[0]), + } +} + +// Nodes returns all the open nodes in the grid if AllVisible is +// false, otherwise all nodes are returned. +func (g *Grid) Nodes() []graph.Node { + var nodes []graph.Node + for id, ok := range g.open { + if ok || g.AllVisible { + nodes = append(nodes, simple.Node(id)) + } + } + return nodes +} + +// Has returns whether n is a node in the grid. The state of +// the AllVisible field determines whether a non-open node is +// present. +func (g *Grid) Has(n graph.Node) bool { + return g.has(n.ID()) +} + +func (g *Grid) has(id int64) bool { + return 0 <= id && id < int64(len(g.open)) && (g.AllVisible || g.open[id]) +} + +// HasOpen returns whether n is an open node in the grid. +func (g *Grid) HasOpen(n graph.Node) bool { + id := n.ID() + return 0 <= id && id < int64(len(g.open)) && g.open[id] +} + +// Set sets the node at position (r, c) to the specified open state. +func (g *Grid) Set(r, c int, open bool) { + if r < 0 || r >= g.r { + panic("grid: illegal row index") + } + if c < 0 || c >= g.c { + panic("grid: illegal column index") + } + g.open[r*g.c+c] = open +} + +// Dims returns the dimensions of the grid. +func (g *Grid) Dims() (r, c int) { + return g.r, g.c +} + +// RowCol returns the row and column of the id. RowCol will panic if the +// node id is outside the range of the grid. +func (g *Grid) RowCol(id int64) (r, c int) { + if id < 0 || int64(len(g.open)) <= id { + panic("grid: illegal node id") + } + return int(id) / g.c, int(id) % g.c +} + +// XY returns the cartesian coordinates of n. If n is not a node +// in the grid, (NaN, NaN) is returned. +func (g *Grid) XY(n graph.Node) (x, y float64) { + if !g.Has(n) { + return math.NaN(), math.NaN() + } + r, c := g.RowCol(n.ID()) + return float64(c), float64(r) +} + +// NodeAt returns the node at (r, c). The returned node may be open or closed. +func (g *Grid) NodeAt(r, c int) graph.Node { + if r < 0 || r >= g.r || c < 0 || c >= g.c { + return nil + } + return simple.Node(r*g.c + c) +} + +// From returns all the nodes reachable from u. Reachabilty requires that both +// ends of an edge must be open. +func (g *Grid) From(u graph.Node) []graph.Node { + if !g.HasOpen(u) { + return nil + } + nr, nc := g.RowCol(u.ID()) + var to []graph.Node + for r := nr - 1; r <= nr+1; r++ { + for c := nc - 1; c <= nc+1; c++ { + if v := g.NodeAt(r, c); v != nil && g.HasEdgeBetween(u, v) { + to = append(to, v) + } + } + } + return to +} + +// HasEdgeBetween returns whether there is an edge between u and v. +func (g *Grid) HasEdgeBetween(u, v graph.Node) bool { + if !g.HasOpen(u) || !g.HasOpen(v) || u.ID() == v.ID() { + return false + } + ur, uc := g.RowCol(u.ID()) + vr, vc := g.RowCol(v.ID()) + if abs(ur-vr) > 1 || abs(uc-vc) > 1 { + return false + } + return g.AllowDiagonal || ur == vr || uc == vc +} + +func abs(i int) int { + if i < 0 { + return -i + } + return i +} + +// Edge returns the edge between u and v. +func (g *Grid) Edge(u, v graph.Node) graph.Edge { + return g.WeightedEdgeBetween(u, v) +} + +// WeightedEdge returns the weighted edge between u and v. +func (g *Grid) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + return g.WeightedEdgeBetween(u, v) +} + +// EdgeBetween returns the edge between u and v. +func (g *Grid) EdgeBetween(u, v graph.Node) graph.Edge { + return g.WeightedEdgeBetween(u, v) +} + +// WeightedEdgeBetween returns the weighted edge between u and v. +func (g *Grid) WeightedEdgeBetween(u, v graph.Node) graph.WeightedEdge { + if g.HasEdgeBetween(u, v) { + if !g.AllowDiagonal || g.UnitEdgeWeight { + return simple.WeightedEdge{F: u, T: v, W: 1} + } + ux, uy := g.XY(u) + vx, vy := g.XY(v) + return simple.WeightedEdge{F: u, T: v, W: math.Hypot(ux-vx, uy-vy)} + } + return nil +} + +// Weight returns the weight of the given edge. +func (g *Grid) Weight(x, y graph.Node) (w float64, ok bool) { + if x.ID() == y.ID() { + return 0, true + } + if !g.HasEdgeBetween(x, y) { + return math.Inf(1), false + } + if e := g.EdgeBetween(x, y); e != nil { + if !g.AllowDiagonal || g.UnitEdgeWeight { + return 1, true + } + ux, uy := g.XY(e.From()) + vx, vy := g.XY(e.To()) + return math.Hypot(ux-vx, uy-vy), true + } + return math.Inf(1), true +} + +// String returns a string representation of the grid. +func (g *Grid) String() string { + b, _ := g.Render(nil) + return string(b) +} + +// Render returns a text representation of the graph +// with the given path included. If the path is not a path +// in the grid Render returns a non-nil error and the +// path up to that point. +func (g *Grid) Render(path []graph.Node) ([]byte, error) { + b := make([]byte, g.r*(g.c+1)-1) + for r := 0; r < g.r; r++ { + for c := 0; c < g.c; c++ { + if g.open[r*g.c+c] { + b[r*(g.c+1)+c] = Open + } else { + b[r*(g.c+1)+c] = Closed + } + } + if r < g.r-1 { + b[r*(g.c+1)+g.c] = '\n' + } + } + + // We don't use topo.IsPathIn at the outset because we + // want to draw as much as possible before failing. + for i, n := range path { + if !g.Has(n) || (i != 0 && !g.HasEdgeBetween(path[i-1], n)) { + id := n.ID() + if 0 <= id && id < int64(len(g.open)) { + r, c := g.RowCol(n.ID()) + b[r*(g.c+1)+c] = '!' + } + return b, errors.New("grid: not a path in graph") + } + r, c := g.RowCol(n.ID()) + switch i { + case len(path) - 1: + b[r*(g.c+1)+c] = 'G' + case 0: + b[r*(g.c+1)+c] = 'S' + default: + b[r*(g.c+1)+c] = 'o' + } + } + return b, nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/internal/grid_test.go b/vendor/gonum.org/v1/gonum/graph/path/internal/grid_test.go new file mode 100644 index 00000000..66ff4d8f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/internal/grid_test.go @@ -0,0 +1,258 @@ +// 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 internal + +import ( + "bytes" + "errors" + "reflect" + "strings" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +var _ graph.Graph = (*Grid)(nil) + +func join(g ...string) string { return strings.Join(g, "\n") } + +type node int64 + +func (n node) ID() int64 { return int64(n) } + +func TestGrid(t *testing.T) { + g := NewGrid(4, 4, false) + + got := g.String() + want := join( + "****", + "****", + "****", + "****", + ) + if got != want { + t.Fatalf("unexpected grid rendering:\ngot: %q\nwant:%q", got, want) + } + + var ops = []struct { + r, c int + state bool + want string + }{ + { + r: 0, c: 1, + state: true, + want: join( + "*.**", + "****", + "****", + "****", + ), + }, + { + r: 0, c: 1, + state: false, + want: join( + "****", + "****", + "****", + "****", + ), + }, + { + r: 0, c: 1, + state: true, + want: join( + "*.**", + "****", + "****", + "****", + ), + }, + { + r: 0, c: 2, + state: true, + want: join( + "*..*", + "****", + "****", + "****", + ), + }, + { + r: 1, c: 2, + state: true, + want: join( + "*..*", + "**.*", + "****", + "****", + ), + }, + { + r: 2, c: 2, + state: true, + want: join( + "*..*", + "**.*", + "**.*", + "****", + ), + }, + { + r: 3, c: 2, + state: true, + want: join( + "*..*", + "**.*", + "**.*", + "**.*", + ), + }, + } + for _, test := range ops { + g.Set(test.r, test.c, test.state) + got := g.String() + if got != test.want { + t.Fatalf("unexpected grid rendering after set (%d, %d) open state to %t:\ngot: %q\nwant:%q", + test.r, test.c, test.state, got, test.want) + } + } + + // Match the last state from the loop against the + // explicit description of the grid. + got = NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ).String() + want = g.String() + if got != want { + t.Fatalf("unexpected grid rendering from NewGridFrom:\ngot: %q\nwant:%q", got, want) + } + + var paths = []struct { + path []graph.Node + diagonal bool + want string + }{ + { + path: nil, + diagonal: false, + want: join( + "*..*", + "**.*", + "**.*", + "**.*", + ), + }, + { + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + diagonal: false, + want: join( + "*So*", + "**o*", + "**o*", + "**G*", + ), + }, + { + path: []graph.Node{node(1), node(6), node(10), node(14)}, + diagonal: false, + want: join( + "*S.*", + "**!*", + "**.*", + "**.*", + ), + }, + { + path: []graph.Node{node(1), node(6), node(10), node(14)}, + diagonal: true, + want: join( + "*S.*", + "**o*", + "**o*", + "**G*", + ), + }, + { + path: []graph.Node{node(1), node(5), node(9)}, + diagonal: false, + want: join( + "*S.*", + "*!.*", + "**.*", + "**.*", + ), + }, + } + for _, test := range paths { + g.AllowDiagonal = test.diagonal + got, err := g.Render(test.path) + errored := err != nil + if bytes.Contains(got, []byte{'!'}) != errored { + t.Fatalf("unexpected error return: got:%v want:%v", err, errors.New("grid: not a path in graph")) + } + if string(got) != test.want { + t.Fatalf("unexpected grid path rendering for %v:\ngot: %q\nwant:%q", test.path, got, want) + } + } + + var coords = []struct { + r, c int + id int64 + }{ + {r: 0, c: 0, id: 0}, + {r: 0, c: 3, id: 3}, + {r: 3, c: 0, id: 12}, + {r: 3, c: 3, id: 15}, + } + for _, test := range coords { + if id := g.NodeAt(test.r, test.c).ID(); id != test.id { + t.Fatalf("unexpected ID for node at (%d, %d):\ngot: %d\nwant:%d", test.r, test.c, id, test.id) + } + if r, c := g.RowCol(test.id); r != test.r || c != test.c { + t.Fatalf("unexpected row/col for node %d:\ngot: (%d, %d)\nwant:(%d, %d)", test.id, r, c, test.r, test.c) + } + } + + var reach = []struct { + from graph.Node + diagonal bool + to []graph.Node + }{ + { + from: node(0), + diagonal: false, + to: nil, + }, + { + from: node(2), + diagonal: false, + to: []graph.Node{simple.Node(1), simple.Node(6)}, + }, + { + from: node(1), + diagonal: false, + to: []graph.Node{simple.Node(2)}, + }, + { + from: node(1), + diagonal: true, + to: []graph.Node{simple.Node(2), simple.Node(6)}, + }, + } + for _, test := range reach { + g.AllowDiagonal = test.diagonal + got := g.From(test.from) + if !reflect.DeepEqual(got, test.to) { + t.Fatalf("unexpected nodes from %d with allow diagonal=%t:\ngot: %v\nwant:%v", + test.from, test.diagonal, got, test.to) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/internal/limited.go b/vendor/gonum.org/v1/gonum/graph/path/internal/limited.go new file mode 100644 index 00000000..3a2d768d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/internal/limited.go @@ -0,0 +1,316 @@ +// 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 internal + +import ( + "errors" + "math" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +// LimitedVisionGrid is a 2D grid planar undirected graph where the capacity +// to determine the presence of edges is dependent on the current and past +// positions on the grid. In the absence of information, the grid is +// optimistic. +type LimitedVisionGrid struct { + Grid *Grid + + // Location is the current + // location on the grid. + Location graph.Node + + // VisionRadius specifies how far + // away edges can be detected. + VisionRadius float64 + + // Known holds a store of known + // nodes, if not nil. + Known map[int64]bool +} + +// MoveTo moves to the node n on the grid and returns a slice of newly seen and +// already known edges. MoveTo panics if n is nil. +func (l *LimitedVisionGrid) MoveTo(n graph.Node) (new, old []graph.Edge) { + l.Location = n + row, column := l.RowCol(n.ID()) + x := float64(column) + y := float64(row) + seen := make(map[[2]int64]bool) + bound := int(l.VisionRadius + 0.5) + for r := row - bound; r <= row+bound; r++ { + for c := column - bound; c <= column+bound; c++ { + u := l.NodeAt(r, c) + if u == nil { + continue + } + ux, uy := l.XY(u) + if math.Hypot(x-ux, y-uy) > l.VisionRadius { + continue + } + for _, v := range l.allPossibleFrom(u) { + if seen[[2]int64{u.ID(), v.ID()}] { + continue + } + seen[[2]int64{u.ID(), v.ID()}] = true + + vx, vy := l.XY(v) + if !l.Known[v.ID()] && math.Hypot(x-vx, y-vy) > l.VisionRadius { + continue + } + + e := simple.Edge{F: u, T: v} + if !l.Known[u.ID()] || !l.Known[v.ID()] { + new = append(new, e) + } else { + old = append(old, e) + } + } + } + } + + if l.Known != nil { + for r := row - bound; r <= row+bound; r++ { + for c := column - bound; c <= column+bound; c++ { + u := l.NodeAt(r, c) + if u == nil { + continue + } + ux, uy := l.XY(u) + if math.Hypot(x-ux, y-uy) > l.VisionRadius { + continue + } + for _, v := range l.allPossibleFrom(u) { + vx, vy := l.XY(v) + if math.Hypot(x-vx, y-vy) > l.VisionRadius { + continue + } + l.Known[v.ID()] = true + } + l.Known[u.ID()] = true + } + } + + } + + return new, old +} + +// allPossibleFrom returns all the nodes possibly reachable from u. +func (l *LimitedVisionGrid) allPossibleFrom(u graph.Node) []graph.Node { + if !l.Has(u) { + return nil + } + nr, nc := l.RowCol(u.ID()) + var to []graph.Node + for r := nr - 1; r <= nr+1; r++ { + for c := nc - 1; c <= nc+1; c++ { + v := l.NodeAt(r, c) + if v == nil || u.ID() == v.ID() { + continue + } + ur, uc := l.RowCol(u.ID()) + vr, vc := l.RowCol(v.ID()) + if abs(ur-vr) > 1 || abs(uc-vc) > 1 { + continue + } + if !l.Grid.AllowDiagonal && ur != vr && uc != vc { + continue + } + to = append(to, v) + } + } + return to +} + +// RowCol returns the row and column of the id. RowCol will panic if the +// node id is outside the range of the grid. +func (l *LimitedVisionGrid) RowCol(id int64) (r, c int) { + return l.Grid.RowCol(id) +} + +// XY returns the cartesian coordinates of n. If n is not a node +// in the grid, (NaN, NaN) is returned. +func (l *LimitedVisionGrid) XY(n graph.Node) (x, y float64) { + if !l.Has(n) { + return math.NaN(), math.NaN() + } + r, c := l.RowCol(n.ID()) + return float64(c), float64(r) +} + +// Nodes returns all the nodes in the grid. +func (l *LimitedVisionGrid) Nodes() []graph.Node { + nodes := make([]graph.Node, 0, len(l.Grid.open)) + for id := range l.Grid.open { + nodes = append(nodes, simple.Node(id)) + } + return nodes +} + +// NodeAt returns the node at (r, c). The returned node may be open or closed. +func (l *LimitedVisionGrid) NodeAt(r, c int) graph.Node { + return l.Grid.NodeAt(r, c) +} + +// Has returns whether n is a node in the grid. +func (l *LimitedVisionGrid) Has(n graph.Node) bool { + return l.has(n.ID()) +} + +func (l *LimitedVisionGrid) has(id int64) bool { + return 0 <= id && id < int64(len(l.Grid.open)) +} + +// From returns nodes that are optimistically reachable from u. +func (l *LimitedVisionGrid) From(u graph.Node) []graph.Node { + if !l.Has(u) { + return nil + } + + nr, nc := l.RowCol(u.ID()) + var to []graph.Node + for r := nr - 1; r <= nr+1; r++ { + for c := nc - 1; c <= nc+1; c++ { + if v := l.NodeAt(r, c); v != nil && l.HasEdgeBetween(u, v) { + to = append(to, v) + } + } + } + return to +} + +// HasEdgeBetween optimistically returns whether an edge is exists between u and v. +func (l *LimitedVisionGrid) HasEdgeBetween(u, v graph.Node) bool { + if u.ID() == v.ID() { + return false + } + ur, uc := l.RowCol(u.ID()) + vr, vc := l.RowCol(v.ID()) + if abs(ur-vr) > 1 || abs(uc-vc) > 1 { + return false + } + if !l.Grid.AllowDiagonal && ur != vr && uc != vc { + return false + } + + x, y := l.XY(l.Location) + ux, uy := l.XY(u) + vx, vy := l.XY(v) + uKnown := l.Known[u.ID()] || math.Hypot(x-ux, y-uy) <= l.VisionRadius + vKnown := l.Known[v.ID()] || math.Hypot(x-vx, y-vy) <= l.VisionRadius + + switch { + case uKnown && vKnown: + return l.Grid.HasEdgeBetween(u, v) + case uKnown: + return l.Grid.HasOpen(u) + case vKnown: + return l.Grid.HasOpen(v) + default: + return true + } +} + +// Edge optimistically returns the edge from u to v. +func (l *LimitedVisionGrid) Edge(u, v graph.Node) graph.Edge { + return l.WeightedEdgeBetween(u, v) +} + +// Edge optimistically returns the weighted edge from u to v. +func (l *LimitedVisionGrid) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + return l.WeightedEdgeBetween(u, v) +} + +// WeightedEdgeBetween optimistically returns the edge between u and v. +func (l *LimitedVisionGrid) EdgeBetween(u, v graph.Node) graph.Edge { + return l.WeightedEdgeBetween(u, v) +} + +// WeightedEdgeBetween optimistically returns the weighted edge between u and v. +func (l *LimitedVisionGrid) WeightedEdgeBetween(u, v graph.Node) graph.WeightedEdge { + if l.HasEdgeBetween(u, v) { + if !l.Grid.AllowDiagonal || l.Grid.UnitEdgeWeight { + return simple.WeightedEdge{F: u, T: v, W: 1} + } + ux, uy := l.XY(u) + vx, vy := l.XY(v) + return simple.WeightedEdge{F: u, T: v, W: math.Hypot(ux-vx, uy-vy)} + } + return nil +} + +// Weight returns the weight of the given edge. +func (l *LimitedVisionGrid) Weight(x, y graph.Node) (w float64, ok bool) { + if x.ID() == y.ID() { + return 0, true + } + if !l.HasEdgeBetween(x, y) { + return math.Inf(1), false + } + if e := l.EdgeBetween(x, y); e != nil { + if !l.Grid.AllowDiagonal || l.Grid.UnitEdgeWeight { + return 1, true + } + ux, uy := l.XY(e.From()) + vx, vy := l.XY(e.To()) + return math.Hypot(ux-vx, uy-vy), true + + } + return math.Inf(1), true +} + +// String returns a string representation of the grid. +func (l *LimitedVisionGrid) String() string { + b, _ := l.Render(nil) + return string(b) +} + +// Render returns a text representation of the graph +// with the given path included. If the path is not a path +// in the grid Render returns a non-nil error and the +// path up to that point. +func (l *LimitedVisionGrid) Render(path []graph.Node) ([]byte, error) { + rows, cols := l.Grid.Dims() + b := make([]byte, rows*(cols+1)-1) + for r := 0; r < rows; r++ { + for c := 0; c < cols; c++ { + if !l.Known[int64(r*cols+c)] { + b[r*(cols+1)+c] = Unknown + } else if l.Grid.open[r*cols+c] { + b[r*(cols+1)+c] = Open + } else { + b[r*(cols+1)+c] = Closed + } + } + if r < rows-1 { + b[r*(cols+1)+cols] = '\n' + } + } + + // We don't use topo.IsPathIn at the outset because we + // want to draw as much as possible before failing. + for i, n := range path { + if !l.Has(n) || (i != 0 && !l.HasEdgeBetween(path[i-1], n)) { + id := n.ID() + if 0 <= id && id < int64(len(l.Grid.open)) { + r, c := l.RowCol(n.ID()) + b[r*(cols+1)+c] = '!' + } + return b, errors.New("grid: not a path in graph") + } + r, c := l.RowCol(n.ID()) + switch i { + case len(path) - 1: + b[r*(cols+1)+c] = 'G' + case 0: + b[r*(cols+1)+c] = 'S' + default: + b[r*(cols+1)+c] = 'o' + } + } + return b, nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/internal/limited_test.go b/vendor/gonum.org/v1/gonum/graph/path/internal/limited_test.go new file mode 100644 index 00000000..018dd778 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/internal/limited_test.go @@ -0,0 +1,1242 @@ +// 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 internal + +import ( + "math" + "reflect" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +type changes struct { + n graph.Node + + new, old []simple.WeightedEdge +} + +var limitedVisionTests = []struct { + g *Grid + radius float64 + diag bool + remember bool + + path []graph.Node + + want []changes +}{ + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1, + diag: false, + remember: false, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + }, + old: nil, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + }, + old: nil, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + }, + old: nil, + }, + { + n: node(14), + new: []simple.WeightedEdge{ + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: nil, + }, + }, + }, + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1.5, + diag: false, + remember: false, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(14), + new: []simple.WeightedEdge{ + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: nil, + }, + }, + }, + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1, + diag: false, + remember: true, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + }, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + }, + }, + { + n: node(14), + new: []simple.WeightedEdge{ + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + }, + }, + }, + }, + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1.5, + diag: false, + remember: true, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + }, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + }, + }, + { + n: node(14), + new: nil, + old: []simple.WeightedEdge{ + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + }, + }, + }, + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1, + diag: true, + remember: false, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(14), + new: []simple.WeightedEdge{ + {F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: nil, + }, + }, + }, + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1.5, + diag: true, + remember: false, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(4), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(14), + new: []simple.WeightedEdge{ + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: nil, + }, + }, + }, + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1, + diag: true, + remember: true, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + }, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + }, + }, + { + n: node(14), + new: []simple.WeightedEdge{ + {F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)}, + }, + }, + }, + }, + { + g: NewGridFrom( + "*..*", + "**.*", + "**.*", + "**.*", + ), + radius: 1.5, + diag: true, + remember: true, + path: []graph.Node{node(1), node(2), node(6), node(10), node(14)}, + + want: []changes{ + { + n: node(1), + new: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(0), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(4), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(4), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(4), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + old: nil, + }, + { + n: node(2), + new: []simple.WeightedEdge{ + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + }, + }, + { + n: node(6), + new: []simple.WeightedEdge{ + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(1), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(1), T: simple.Node(6), W: math.Sqrt2}, + {F: simple.Node(2), T: simple.Node(1), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(2), T: simple.Node(6), W: 1}, + {F: simple.Node(2), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(3), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + }, + }, + { + n: node(10), + new: []simple.WeightedEdge{ + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + old: []simple.WeightedEdge{ + {F: simple.Node(5), T: simple.Node(0), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(1), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(5), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(1), W: math.Sqrt2}, + {F: simple.Node(6), T: simple.Node(2), W: 1}, + {F: simple.Node(6), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(6), T: simple.Node(10), W: 1}, + {F: simple.Node(6), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(2), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(3), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(7), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + }, + }, + { + n: node(14), + new: nil, + old: []simple.WeightedEdge{ + {F: simple.Node(9), T: simple.Node(4), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(9), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(5), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(6), W: 1}, + {F: simple.Node(10), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(10), T: simple.Node(14), W: 1}, + {F: simple.Node(10), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(6), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(7), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(11), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(13), T: simple.Node(14), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(9), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(10), W: 1}, + {F: simple.Node(14), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(13), W: math.Inf(1)}, + {F: simple.Node(14), T: simple.Node(15), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(10), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(11), W: math.Inf(1)}, + {F: simple.Node(15), T: simple.Node(14), W: math.Inf(1)}, + }, + }, + }, + }, +} + +func TestLimitedVisionGrid(t *testing.T) { + for i, test := range limitedVisionTests { + l := &LimitedVisionGrid{ + Grid: test.g, + VisionRadius: test.radius, + Location: test.path[0], + } + if test.remember { + l.Known = make(map[int64]bool) + } + l.Grid.AllowDiagonal = test.diag + + x, y := l.XY(test.path[0]) + for _, u := range l.Nodes() { + ux, uy := l.XY(u) + uNear := math.Hypot(x-ux, y-uy) <= test.radius + for _, v := range l.Nodes() { + vx, vy := l.XY(v) + vNear := math.Hypot(x-vx, y-vy) <= test.radius + if u.ID() == v.ID() && l.HasEdgeBetween(u, v) { + t.Errorf("unexpected self edge: %v -- %v", u, v) + } + if !uNear && !vNear && !l.HasEdgeBetween(u, v) && couldConnectIn(l, u, v) { + t.Errorf("unexpected pessimism: no hope in distant edge between %v and %v for test %d", + u, v, i) + } + if (uNear && vNear) && l.HasEdgeBetween(u, v) != l.Grid.HasEdgeBetween(u, v) { + t.Errorf("unrealistic optimism: disagreement about edge between %v and %v for test %d: got:%t want:%t", + u, v, i, l.HasEdgeBetween(u, v), l.Grid.HasEdgeBetween(u, v)) + } + } + } + + var got []changes + for _, n := range test.path { + new, old := l.MoveTo(n) + got = append(got, changes{n: n, new: asConcreteEdges(new, l), old: asConcreteEdges(old, l)}) + } + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexpected walk for test %d:\ngot: %+v\nwant:%+v", i, got, test.want) + } + } +} + +func asConcreteEdges(changes []graph.Edge, in graph.Weighted) []simple.WeightedEdge { + if changes == nil { + return nil + } + we := make([]simple.WeightedEdge, len(changes)) + for i, e := range changes { + we[i].F = e.From() + we[i].T = e.To() + w, ok := in.Weight(e.From(), e.To()) + if !ok && !math.IsInf(w, 1) { + panic("unexpected invalid finite weight") + } + we[i].W = w + } + return we +} + +func couldConnectIn(l *LimitedVisionGrid, u, v graph.Node) bool { + if u.ID() == v.ID() { + return false + } + + ur, uc := l.RowCol(u.ID()) + vr, vc := l.RowCol(v.ID()) + if abs(ur-vr) > 1 || abs(uc-vc) > 1 { + return false + } + if (ur != vr || uc != vc) && !l.Grid.AllowDiagonal { + return false + } + + if !l.Known[u.ID()] && !l.Known[v.ID()] { + return true + } + if l.Known[u.ID()] && !l.Grid.HasOpen(u) { + return false + } + if l.Known[v.ID()] && !l.Grid.HasOpen(v) { + return false + } + + return true +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/internal/testgraphs/shortest.go b/vendor/gonum.org/v1/gonum/graph/path/internal/testgraphs/shortest.go new file mode 100644 index 00000000..3a9c6bc8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/internal/testgraphs/shortest.go @@ -0,0 +1,654 @@ +// 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 testgraphs + +import ( + "fmt" + "math" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +func init() { + for _, test := range ShortestPathTests { + if len(test.WantPaths) != 1 && test.HasUniquePath { + panic(fmt.Sprintf("%q: bad shortest path test: non-unique paths marked unique", test.Name)) + } + } +} + +// ShortestPathTests are graphs used to test the static shortest path routines in path: BellmanFord, +// DijkstraAllPaths, DijkstraFrom, FloydWarshall and Johnson, and the static degenerate case for the +// dynamic shortest path routine in path/dynamic: DStarLite. +var ShortestPathTests = []struct { + Name string + Graph func() graph.WeightedEdgeAdder + Edges []simple.WeightedEdge + HasNegativeWeight bool + HasNegativeCycle bool + + Query simple.Edge + Weight float64 + WantPaths [][]int64 + HasUniquePath bool + + NoPathFor simple.Edge +}{ + // Positive weighted graphs. + { + Name: "empty directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + Weight: math.Inf(1), + + NoPathFor: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + }, + { + Name: "empty undirected", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + Weight: math.Inf(1), + + NoPathFor: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + }, + { + Name: "one edge directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 1}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + Weight: 1, + WantPaths: [][]int64{ + {0, 1}, + }, + HasUniquePath: true, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(3)}, + }, + { + Name: "one edge self directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 1}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(0)}, + Weight: 0, + WantPaths: [][]int64{ + {0}, + }, + HasUniquePath: true, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(3)}, + }, + { + Name: "one edge undirected", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 1}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + Weight: 1, + WantPaths: [][]int64{ + {0, 1}, + }, + HasUniquePath: true, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(3)}, + }, + { + Name: "two paths directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(2), W: 2}, + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(2)}, + Weight: 2, + WantPaths: [][]int64{ + {0, 1, 2}, + {0, 2}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(1)}, + }, + { + Name: "two paths undirected", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(2), W: 2}, + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(2)}, + Weight: 2, + WantPaths: [][]int64{ + {0, 1, 2}, + {0, 2}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(4)}, + }, + { + Name: "confounding paths directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->5 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(5), W: 1}, + + // Add direct edge to goal of weight 4 + {F: simple.Node(0), T: simple.Node(5), W: 4}, + + // Add edge to a node that's still optimal + {F: simple.Node(0), T: simple.Node(2), W: 2}, + + // Add edge to 3 that's overpriced + {F: simple.Node(0), T: simple.Node(3), W: 4}, + + // Add very cheap edge to 4 which is a dead end + {F: simple.Node(0), T: simple.Node(4), W: 0.25}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(5)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 5}, + {0, 2, 3, 5}, + {0, 5}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "confounding paths undirected", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->5 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(5), W: 1}, + + // Add direct edge to goal of weight 4 + {F: simple.Node(0), T: simple.Node(5), W: 4}, + + // Add edge to a node that's still optimal + {F: simple.Node(0), T: simple.Node(2), W: 2}, + + // Add edge to 3 that's overpriced + {F: simple.Node(0), T: simple.Node(3), W: 4}, + + // Add very cheap edge to 4 which is a dead end + {F: simple.Node(0), T: simple.Node(4), W: 0.25}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(5)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 5}, + {0, 2, 3, 5}, + {0, 5}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(5), T: simple.Node(6)}, + }, + { + Name: "confounding paths directed 2-step", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->5 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(5), W: 1}, + + // Add two step path to goal of weight 4 + {F: simple.Node(0), T: simple.Node(6), W: 2}, + {F: simple.Node(6), T: simple.Node(5), W: 2}, + + // Add edge to a node that's still optimal + {F: simple.Node(0), T: simple.Node(2), W: 2}, + + // Add edge to 3 that's overpriced + {F: simple.Node(0), T: simple.Node(3), W: 4}, + + // Add very cheap edge to 4 which is a dead end + {F: simple.Node(0), T: simple.Node(4), W: 0.25}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(5)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 5}, + {0, 2, 3, 5}, + {0, 6, 5}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "confounding paths undirected 2-step", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->5 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(5), W: 1}, + + // Add two step path to goal of weight 4 + {F: simple.Node(0), T: simple.Node(6), W: 2}, + {F: simple.Node(6), T: simple.Node(5), W: 2}, + + // Add edge to a node that's still optimal + {F: simple.Node(0), T: simple.Node(2), W: 2}, + + // Add edge to 3 that's overpriced + {F: simple.Node(0), T: simple.Node(3), W: 4}, + + // Add very cheap edge to 4 which is a dead end + {F: simple.Node(0), T: simple.Node(4), W: 0.25}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(5)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 5}, + {0, 2, 3, 5}, + {0, 6, 5}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(5), T: simple.Node(7)}, + }, + { + Name: "zero-weight cycle directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + + // Add a zero-weight cycle. + {F: simple.Node(1), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(1), W: 0}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight cycle^2 directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + + // Add a zero-weight cycle. + {F: simple.Node(1), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(1), W: 0}, + // With its own zero-weight cycle. + {F: simple.Node(5), T: simple.Node(6), W: 0}, + {F: simple.Node(6), T: simple.Node(5), W: 0}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight cycle^2 confounding directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + + // Add a zero-weight cycle. + {F: simple.Node(1), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(1), W: 0}, + // With its own zero-weight cycle. + {F: simple.Node(5), T: simple.Node(6), W: 0}, + {F: simple.Node(6), T: simple.Node(5), W: 0}, + // But leading to the target. + {F: simple.Node(5), T: simple.Node(4), W: 3}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + {0, 1, 5, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight cycle^3 directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + + // Add a zero-weight cycle. + {F: simple.Node(1), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(1), W: 0}, + // With its own zero-weight cycle. + {F: simple.Node(5), T: simple.Node(6), W: 0}, + {F: simple.Node(6), T: simple.Node(5), W: 0}, + // With its own zero-weight cycle. + {F: simple.Node(6), T: simple.Node(7), W: 0}, + {F: simple.Node(7), T: simple.Node(6), W: 0}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight 3·cycle^2 confounding directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + + // Add a zero-weight cycle. + {F: simple.Node(1), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(1), W: 0}, + // With 3 of its own zero-weight cycles. + {F: simple.Node(5), T: simple.Node(6), W: 0}, + {F: simple.Node(6), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(7), W: 0}, + {F: simple.Node(7), T: simple.Node(5), W: 0}, + // Each leading to the target. + {F: simple.Node(5), T: simple.Node(4), W: 3}, + {F: simple.Node(6), T: simple.Node(4), W: 3}, + {F: simple.Node(7), T: simple.Node(4), W: 3}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + {0, 1, 5, 4}, + {0, 1, 5, 6, 4}, + {0, 1, 5, 7, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight reversed 3·cycle^2 confounding directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + + // Add a zero-weight cycle. + {F: simple.Node(3), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(3), W: 0}, + // With 3 of its own zero-weight cycles. + {F: simple.Node(5), T: simple.Node(6), W: 0}, + {F: simple.Node(6), T: simple.Node(5), W: 0}, + {F: simple.Node(5), T: simple.Node(7), W: 0}, + {F: simple.Node(7), T: simple.Node(5), W: 0}, + // Each leading from the source. + {F: simple.Node(0), T: simple.Node(5), W: 3}, + {F: simple.Node(0), T: simple.Node(6), W: 3}, + {F: simple.Node(0), T: simple.Node(7), W: 3}, + }, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + {0, 5, 3, 4}, + {0, 6, 5, 3, 4}, + {0, 7, 5, 3, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight |V|·cycle^(n/|V|) directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: func() []simple.WeightedEdge { + e := []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + } + next := len(e) + 1 + + // Add n zero-weight cycles. + const n = 100 + for i := 0; i < n; i++ { + e = append(e, + simple.WeightedEdge{F: simple.Node(next + i), T: simple.Node(i), W: 0}, + simple.WeightedEdge{F: simple.Node(i), T: simple.Node(next + i), W: 0}, + ) + } + return e + }(), + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight n·cycle directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: func() []simple.WeightedEdge { + e := []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + } + next := len(e) + 1 + + // Add n zero-weight cycles. + const n = 100 + for i := 0; i < n; i++ { + e = append(e, + simple.WeightedEdge{F: simple.Node(next + i), T: simple.Node(1), W: 0}, + simple.WeightedEdge{F: simple.Node(1), T: simple.Node(next + i), W: 0}, + ) + } + return e + }(), + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + { + Name: "zero-weight bi-directional tree with single exit directed", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: func() []simple.WeightedEdge { + e := []simple.WeightedEdge{ + // Add a path from 0->4 of weight 4 + {F: simple.Node(0), T: simple.Node(1), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + {F: simple.Node(2), T: simple.Node(3), W: 1}, + {F: simple.Node(3), T: simple.Node(4), W: 1}, + } + + // Make a bi-directional tree rooted at node 2 with + // a single exit to node 4 and co-equal cost from + // 2 to 4. + const ( + depth = 4 + branching = 4 + ) + + next := len(e) + 1 + src := 2 + var i, last int + for l := 0; l < depth; l++ { + for i = 0; i < branching; i++ { + last = next + i + e = append(e, simple.WeightedEdge{F: simple.Node(src), T: simple.Node(last), W: 0}) + e = append(e, simple.WeightedEdge{F: simple.Node(last), T: simple.Node(src), W: 0}) + } + src = next + 1 + next += branching + } + e = append(e, simple.WeightedEdge{F: simple.Node(last), T: simple.Node(4), W: 2}) + return e + }(), + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(4)}, + Weight: 4, + WantPaths: [][]int64{ + {0, 1, 2, 3, 4}, + {0, 1, 2, 6, 10, 14, 20, 4}, + }, + HasUniquePath: false, + + NoPathFor: simple.Edge{F: simple.Node(4), T: simple.Node(5)}, + }, + + // Negative weighted graphs. + { + Name: "one edge directed negative", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: -1}, + }, + HasNegativeWeight: true, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + Weight: -1, + WantPaths: [][]int64{ + {0, 1}, + }, + HasUniquePath: true, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(3)}, + }, + { + Name: "one edge undirected negative", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: -1}, + }, + HasNegativeWeight: true, + HasNegativeCycle: true, + + Query: simple.Edge{F: simple.Node(0), T: simple.Node(1)}, + }, + { + Name: "wp graph negative", // http://en.wikipedia.org/w/index.php?title=Johnson%27s_algorithm&oldid=564595231 + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node('w'), T: simple.Node('z'), W: 2}, + {F: simple.Node('x'), T: simple.Node('w'), W: 6}, + {F: simple.Node('x'), T: simple.Node('y'), W: 3}, + {F: simple.Node('y'), T: simple.Node('w'), W: 4}, + {F: simple.Node('y'), T: simple.Node('z'), W: 5}, + {F: simple.Node('z'), T: simple.Node('x'), W: -7}, + {F: simple.Node('z'), T: simple.Node('y'), W: -3}, + }, + HasNegativeWeight: true, + + Query: simple.Edge{F: simple.Node('z'), T: simple.Node('y')}, + Weight: -4, + WantPaths: [][]int64{ + {'z', 'x', 'y'}, + }, + HasUniquePath: true, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(3)}, + }, + { + Name: "roughgarden negative", + Graph: func() graph.WeightedEdgeAdder { return simple.NewWeightedDirectedGraph(0, math.Inf(1)) }, + Edges: []simple.WeightedEdge{ + {F: simple.Node('a'), T: simple.Node('b'), W: -2}, + {F: simple.Node('b'), T: simple.Node('c'), W: -1}, + {F: simple.Node('c'), T: simple.Node('a'), W: 4}, + {F: simple.Node('c'), T: simple.Node('x'), W: 2}, + {F: simple.Node('c'), T: simple.Node('y'), W: -3}, + {F: simple.Node('z'), T: simple.Node('x'), W: 1}, + {F: simple.Node('z'), T: simple.Node('y'), W: -4}, + }, + HasNegativeWeight: true, + + Query: simple.Edge{F: simple.Node('a'), T: simple.Node('y')}, + Weight: -6, + WantPaths: [][]int64{ + {'a', 'b', 'c', 'y'}, + }, + HasUniquePath: true, + + NoPathFor: simple.Edge{F: simple.Node(2), T: simple.Node(3)}, + }, +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/johnson_apsp.go b/vendor/gonum.org/v1/gonum/graph/path/johnson_apsp.go new file mode 100644 index 00000000..444564f1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/johnson_apsp.go @@ -0,0 +1,142 @@ +// 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 path + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +// JohnsonAllPaths returns a shortest-path tree for shortest paths in the graph g. +// If the graph does not implement graph.Weighter, UniformCost is used. +// +// The time complexity of JohnsonAllPaths is O(|V|.|E|+|V|^2.log|V|). +func JohnsonAllPaths(g graph.Graph) (paths AllShortest, ok bool) { + jg := johnsonWeightAdjuster{ + g: g, + from: g.From, + edgeTo: g.Edge, + } + if wg, ok := g.(graph.Weighted); ok { + jg.weight = wg.Weight + } else { + jg.weight = UniformCost(g) + } + + paths = newAllShortest(g.Nodes(), false) + + sign := int64(-1) + for { + // Choose a random node ID until we find + // one that is not in g. + jg.q = sign * rand.Int63() + if _, exists := paths.indexOf[jg.q]; !exists { + break + } + sign *= -1 + } + + jg.bellmanFord = true + jg.adjustBy, ok = BellmanFordFrom(johnsonGraphNode(jg.q), jg) + if !ok { + return paths, false + } + + jg.bellmanFord = false + dijkstraAllPaths(jg, paths) + + for i, u := range paths.nodes { + hu := jg.adjustBy.WeightTo(u) + for j, v := range paths.nodes { + if i == j { + continue + } + hv := jg.adjustBy.WeightTo(v) + paths.dist.Set(i, j, paths.dist.At(i, j)-hu+hv) + } + } + + return paths, ok +} + +type johnsonWeightAdjuster struct { + q int64 + g graph.Graph + + from func(graph.Node) []graph.Node + edgeTo func(graph.Node, graph.Node) graph.Edge + weight Weighting + + bellmanFord bool + adjustBy Shortest +} + +var ( + // johnsonWeightAdjuster has the behaviour + // of a directed graph, but we don't need + // to be explicit with the type since it + // is not exported. + _ graph.Graph = johnsonWeightAdjuster{} + _ graph.Weighted = johnsonWeightAdjuster{} +) + +func (g johnsonWeightAdjuster) Has(n graph.Node) bool { + if g.bellmanFord && n.ID() == g.q { + return true + } + return g.g.Has(n) + +} + +func (g johnsonWeightAdjuster) Nodes() []graph.Node { + if g.bellmanFord { + return append(g.g.Nodes(), johnsonGraphNode(g.q)) + } + return g.g.Nodes() +} + +func (g johnsonWeightAdjuster) From(n graph.Node) []graph.Node { + if g.bellmanFord && n.ID() == g.q { + return g.g.Nodes() + } + return g.from(n) +} + +func (g johnsonWeightAdjuster) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + panic("path: unintended use of johnsonWeightAdjuster") +} + +func (g johnsonWeightAdjuster) Edge(u, v graph.Node) graph.Edge { + if g.bellmanFord && u.ID() == g.q && g.g.Has(v) { + return simple.Edge{F: johnsonGraphNode(g.q), T: v} + } + return g.edgeTo(u, v) +} + +func (g johnsonWeightAdjuster) Weight(x, y graph.Node) (w float64, ok bool) { + if g.bellmanFord { + switch g.q { + case x.ID(): + return 0, true + case y.ID(): + return math.Inf(1), false + default: + return g.weight(x, y) + } + } + w, ok = g.weight(x, y) + return w + g.adjustBy.WeightTo(x) - g.adjustBy.WeightTo(y), ok +} + +func (johnsonWeightAdjuster) HasEdgeBetween(_, _ graph.Node) bool { + panic("path: unintended use of johnsonWeightAdjuster") +} + +type johnsonGraphNode int64 + +func (n johnsonGraphNode) ID() int64 { return int64(n) } diff --git a/vendor/gonum.org/v1/gonum/graph/path/johnson_apsp_test.go b/vendor/gonum.org/v1/gonum/graph/path/johnson_apsp_test.go new file mode 100644 index 00000000..1635ce92 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/johnson_apsp_test.go @@ -0,0 +1,102 @@ +// 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 path + +import ( + "math" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/path/internal/testgraphs" +) + +func TestJohnsonAllPaths(t *testing.T) { + for _, test := range testgraphs.ShortestPathTests { + g := test.Graph() + for _, e := range test.Edges { + g.SetWeightedEdge(e) + } + + pt, ok := JohnsonAllPaths(g.(graph.Graph)) + if test.HasNegativeCycle { + if ok { + t.Errorf("%q: expected negative cycle", test.Name) + } + continue + } + if !ok { + t.Fatalf("%q: unexpected negative cycle", test.Name) + } + + // Check all random paths returned are OK. + for i := 0; i < 10; i++ { + p, weight, unique := pt.Between(test.Query.From(), test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + if weight := pt.Weight(test.Query.From(), test.Query.To()); weight != test.Weight { + t.Errorf("%q: unexpected weight from Weight: got:%f want:%f", + test.Name, weight, test.Weight) + } + if unique != test.HasUniquePath { + t.Errorf("%q: unexpected number of paths: got: unique=%t want: unique=%t", + test.Name, unique, test.HasUniquePath) + } + + var got []int64 + for _, n := range p { + got = append(got, n.ID()) + } + ok := len(got) == 0 && len(test.WantPaths) == 0 + for _, sp := range test.WantPaths { + if reflect.DeepEqual(got, sp) { + ok = true + break + } + } + if !ok { + t.Errorf("%q: unexpected shortest path:\ngot: %v\nwant from:%v", + test.Name, p, test.WantPaths) + } + } + + np, weight, unique := pt.Between(test.NoPathFor.From(), test.NoPathFor.To()) + if np != nil || !math.IsInf(weight, 1) || unique { + t.Errorf("%q: unexpected path:\ngot: path=%v weight=%f unique=%t\nwant:path= weight=+Inf unique=false", + test.Name, np, weight, unique) + } + + paths, weight := pt.AllBetween(test.Query.From(), test.Query.To()) + if weight != test.Weight { + t.Errorf("%q: unexpected weight from Between: got:%f want:%f", + test.Name, weight, test.Weight) + } + + var got [][]int64 + if len(paths) != 0 { + got = make([][]int64, len(paths)) + } + for i, p := range paths { + for _, v := range p { + got[i] = append(got[i], v.ID()) + } + } + sort.Sort(ordered.BySliceValues(got)) + if !reflect.DeepEqual(got, test.WantPaths) { + t.Errorf("testing %q: unexpected shortest paths:\ngot: %v\nwant:%v", + test.Name, got, test.WantPaths) + } + + nps, weight := pt.AllBetween(test.NoPathFor.From(), test.NoPathFor.To()) + if nps != nil || !math.IsInf(weight, 1) { + t.Errorf("%q: unexpected path:\ngot: paths=%v weight=%f\nwant:path= weight=+Inf", + test.Name, nps, weight) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/shortest.go b/vendor/gonum.org/v1/gonum/graph/path/shortest.go new file mode 100644 index 00000000..a21a7d4f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/shortest.go @@ -0,0 +1,319 @@ +// 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 path + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/mat" +) + +// Shortest is a shortest-path tree created by the BellmanFordFrom or DijkstraFrom +// single-source shortest path functions. +type Shortest struct { + // from holds the source node given to + // DijkstraFrom. + from graph.Node + + // nodes hold the nodes of the analysed + // graph. + nodes []graph.Node + // indexOf contains a mapping between + // the id-dense representation of the + // graph and the potentially id-sparse + // nodes held in nodes. + indexOf map[int64]int + + // dist and next represent the shortest + // paths between nodes. + // + // Indices into dist and next are + // mapped through indexOf. + // + // dist contains the distances + // from the from node for each + // node in the graph. + dist []float64 + // next contains the shortest-path + // tree of the graph. The index is a + // linear mapping of to-dense-id. + next []int +} + +func newShortestFrom(u graph.Node, nodes []graph.Node) Shortest { + indexOf := make(map[int64]int, len(nodes)) + uid := u.ID() + for i, n := range nodes { + indexOf[n.ID()] = i + if n.ID() == uid { + u = n + } + } + + p := Shortest{ + from: u, + + nodes: nodes, + indexOf: indexOf, + + dist: make([]float64, len(nodes)), + next: make([]int, len(nodes)), + } + for i := range nodes { + p.dist[i] = math.Inf(1) + p.next[i] = -1 + } + p.dist[indexOf[uid]] = 0 + + return p +} + +func (p Shortest) set(to int, weight float64, mid int) { + p.dist[to] = weight + p.next[to] = mid +} + +// From returns the starting node of the paths held by the Shortest. +func (p Shortest) From() graph.Node { return p.from } + +// WeightTo returns the weight of the minimum path to v. +func (p Shortest) WeightTo(v graph.Node) float64 { + to, toOK := p.indexOf[v.ID()] + if !toOK { + return math.Inf(1) + } + return p.dist[to] +} + +// To returns a shortest path to v and the weight of the path. +func (p Shortest) To(v graph.Node) (path []graph.Node, weight float64) { + to, toOK := p.indexOf[v.ID()] + if !toOK || math.IsInf(p.dist[to], 1) { + return nil, math.Inf(1) + } + from := p.indexOf[p.from.ID()] + path = []graph.Node{p.nodes[to]} + for to != from { + path = append(path, p.nodes[p.next[to]]) + to = p.next[to] + } + reverse(path) + return path, p.dist[p.indexOf[v.ID()]] +} + +// AllShortest is a shortest-path tree created by the DijkstraAllPaths, FloydWarshall +// or JohnsonAllPaths all-pairs shortest paths functions. +type AllShortest struct { + // nodes hold the nodes of the analysed + // graph. + nodes []graph.Node + // indexOf contains a mapping between + // the id-dense representation of the + // graph and the potentially id-sparse + // nodes held in nodes. + indexOf map[int64]int + + // dist, next and forward represent + // the shortest paths between nodes. + // + // Indices into dist and next are + // mapped through indexOf. + // + // dist contains the pairwise + // distances between nodes. + dist *mat.Dense + // next contains the shortest-path + // tree of the graph. The first index + // is a linear mapping of from-dense-id + // and to-dense-id, to-major with a + // stride equal to len(nodes); the + // slice indexed to is the list of + // intermediates leading from the 'from' + // node to the 'to' node represented + // by dense id. + // The interpretation of next is + // dependent on the state of forward. + next [][]int + // forward indicates the direction of + // path reconstruction. Forward + // reconstruction is used for Floyd- + // Warshall and reverse is used for + // Dijkstra. + forward bool +} + +func newAllShortest(nodes []graph.Node, forward bool) AllShortest { + indexOf := make(map[int64]int, len(nodes)) + for i, n := range nodes { + indexOf[n.ID()] = i + } + dist := make([]float64, len(nodes)*len(nodes)) + for i := range dist { + dist[i] = math.Inf(1) + } + return AllShortest{ + nodes: nodes, + indexOf: indexOf, + + dist: mat.NewDense(len(nodes), len(nodes), dist), + next: make([][]int, len(nodes)*len(nodes)), + forward: forward, + } +} + +func (p AllShortest) at(from, to int) (mid []int) { + return p.next[from+to*len(p.nodes)] +} + +func (p AllShortest) set(from, to int, weight float64, mid ...int) { + p.dist.Set(from, to, weight) + p.next[from+to*len(p.nodes)] = append(p.next[from+to*len(p.nodes)][:0], mid...) +} + +func (p AllShortest) add(from, to int, mid ...int) { +loop: // These are likely to be rare, so just loop over collisions. + for _, k := range mid { + for _, v := range p.next[from+to*len(p.nodes)] { + if k == v { + continue loop + } + } + p.next[from+to*len(p.nodes)] = append(p.next[from+to*len(p.nodes)], k) + } +} + +// Weight returns the weight of the minimum path between u and v. +func (p AllShortest) Weight(u, v graph.Node) float64 { + from, fromOK := p.indexOf[u.ID()] + to, toOK := p.indexOf[v.ID()] + if !fromOK || !toOK { + return math.Inf(1) + } + return p.dist.At(from, to) +} + +// Between returns a shortest path from u to v and the weight of the path. If more than +// one shortest path exists between u and v, a randomly chosen path will be returned and +// unique is returned false. If a cycle with zero weight exists in the path, it will not +// be included, but unique will be returned false. +func (p AllShortest) Between(u, v graph.Node) (path []graph.Node, weight float64, unique bool) { + from, fromOK := p.indexOf[u.ID()] + to, toOK := p.indexOf[v.ID()] + if !fromOK || !toOK || len(p.at(from, to)) == 0 { + if u.ID() == v.ID() { + return []graph.Node{p.nodes[from]}, 0, true + } + return nil, math.Inf(1), false + } + + seen := make([]int, len(p.nodes)) + for i := range seen { + seen[i] = -1 + } + var n graph.Node + if p.forward { + n = p.nodes[from] + seen[from] = 0 + } else { + n = p.nodes[to] + seen[to] = 0 + } + + path = []graph.Node{n} + weight = p.dist.At(from, to) + unique = true + + var next int + for from != to { + c := p.at(from, to) + if len(c) != 1 { + unique = false + next = c[rand.Intn(len(c))] + } else { + next = c[0] + } + if seen[next] >= 0 { + path = path[:seen[next]] + } + seen[next] = len(path) + path = append(path, p.nodes[next]) + if p.forward { + from = next + } else { + to = next + } + } + if !p.forward { + reverse(path) + } + + return path, weight, unique +} + +// AllBetween returns all shortest paths from u to v and the weight of the paths. Paths +// containing zero-weight cycles are not returned. +func (p AllShortest) AllBetween(u, v graph.Node) (paths [][]graph.Node, weight float64) { + from, fromOK := p.indexOf[u.ID()] + to, toOK := p.indexOf[v.ID()] + if !fromOK || !toOK || len(p.at(from, to)) == 0 { + if u.ID() == v.ID() { + return [][]graph.Node{{p.nodes[from]}}, 0 + } + return nil, math.Inf(1) + } + + var n graph.Node + if p.forward { + n = u + } else { + n = v + } + seen := make([]bool, len(p.nodes)) + paths = p.allBetween(from, to, seen, []graph.Node{n}, nil) + + return paths, p.dist.At(from, to) +} + +func (p AllShortest) allBetween(from, to int, seen []bool, path []graph.Node, paths [][]graph.Node) [][]graph.Node { + if p.forward { + seen[from] = true + } else { + seen[to] = true + } + if from == to { + if path == nil { + return paths + } + if !p.forward { + reverse(path) + } + return append(paths, path) + } + first := true + for _, n := range p.at(from, to) { + if seen[n] { + continue + } + if first { + path = append([]graph.Node(nil), path...) + first = false + } + if p.forward { + from = n + } else { + to = n + } + paths = p.allBetween(from, to, append([]bool(nil), seen...), append(path, p.nodes[n]), paths) + } + return paths +} + +func reverse(p []graph.Node) { + for i, j := 0, len(p)-1; i < j; i, j = i+1, j-1 { + p[i], p[j] = p[j], p[i] + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/spanning_tree.go b/vendor/gonum.org/v1/gonum/graph/path/spanning_tree.go new file mode 100644 index 00000000..a21a3e83 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/spanning_tree.go @@ -0,0 +1,187 @@ +// 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 path + +import ( + "container/heap" + "math" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +// WeightedBuilder is a type that can add nodes and weighted edges. +type WeightedBuilder interface { + AddNode(graph.Node) + SetWeightedEdge(graph.WeightedEdge) +} + +// Prim generates a minimum spanning tree of g by greedy tree extension, placing +// the result in the destination, dst. If the edge weights of g are distinct +// it will be the unique minimum spanning tree of g. The destination is not cleared +// first. The weight of the minimum spanning tree is returned. If g is not connected, +// a minimum spanning forest will be constructed in dst and the sum of minimum +// spanning tree weights will be returned. +// +// Nodes and Edges from g are used to construct dst, so if the Node and Edge +// types used in g are pointer or reference-like, then the values will be shared +// between the graphs. +// +// If dst has nodes that exist in g, Prim will panic. +func Prim(dst WeightedBuilder, g graph.WeightedUndirected) float64 { + nodes := g.Nodes() + if len(nodes) == 0 { + return 0 + } + + q := &primQueue{ + indexOf: make(map[int64]int, len(nodes)-1), + nodes: make([]simple.WeightedEdge, 0, len(nodes)-1), + } + dst.AddNode(nodes[0]) + for _, u := range nodes[1:] { + dst.AddNode(u) + heap.Push(q, simple.WeightedEdge{F: u, W: math.Inf(1)}) + } + + u := nodes[0] + for _, v := range g.From(u) { + w, ok := g.Weight(u, v) + if !ok { + panic("prim: unexpected invalid weight") + } + q.update(v, u, w) + } + + var w float64 + for q.Len() > 0 { + e := heap.Pop(q).(simple.WeightedEdge) + if e.To() != nil && g.HasEdgeBetween(e.From(), e.To()) { + dst.SetWeightedEdge(g.WeightedEdge(e.From(), e.To())) + w += e.Weight() + } + + u = e.From() + for _, n := range g.From(u) { + if key, ok := q.key(n); ok { + w, ok := g.Weight(u, n) + if !ok { + panic("prim: unexpected invalid weight") + } + if w < key { + q.update(n, u, w) + } + } + } + } + return w +} + +// primQueue is a Prim's priority queue. The priority queue is a +// queue of edge From nodes keyed on the minimum edge weight to +// a node in the set of nodes already connected to the minimum +// spanning forest. +type primQueue struct { + indexOf map[int64]int + nodes []simple.WeightedEdge +} + +func (q *primQueue) Less(i, j int) bool { + return q.nodes[i].Weight() < q.nodes[j].Weight() +} + +func (q *primQueue) Swap(i, j int) { + q.indexOf[q.nodes[i].From().ID()] = j + q.indexOf[q.nodes[j].From().ID()] = i + q.nodes[i], q.nodes[j] = q.nodes[j], q.nodes[i] +} + +func (q *primQueue) Len() int { + return len(q.nodes) +} + +func (q *primQueue) Push(x interface{}) { + n := x.(simple.WeightedEdge) + q.indexOf[n.From().ID()] = len(q.nodes) + q.nodes = append(q.nodes, n) +} + +func (q *primQueue) Pop() interface{} { + n := q.nodes[len(q.nodes)-1] + q.nodes = q.nodes[:len(q.nodes)-1] + delete(q.indexOf, n.From().ID()) + return n +} + +// key returns the key for the node u and whether the node is +// in the queue. If the node is not in the queue, key is returned +// as +Inf. +func (q *primQueue) key(u graph.Node) (key float64, ok bool) { + i, ok := q.indexOf[u.ID()] + if !ok { + return math.Inf(1), false + } + return q.nodes[i].Weight(), ok +} + +// update updates u's position in the queue with the new closest +// MST-connected neighbour, v, and the key weight between u and v. +func (q *primQueue) update(u, v graph.Node, key float64) { + id := u.ID() + i, ok := q.indexOf[id] + if !ok { + return + } + q.nodes[i].T = v + q.nodes[i].W = key + heap.Fix(q, i) +} + +// UndirectedWeightLister is an undirected graph that returns edge weights and +// the set of edges in the graph. +type UndirectedWeightLister interface { + graph.WeightedUndirected + WeightedEdges() []graph.WeightedEdge +} + +// Kruskal generates a minimum spanning tree of g by greedy tree coalescence, placing +// the result in the destination, dst. If the edge weights of g are distinct +// it will be the unique minimum spanning tree of g. The destination is not cleared +// first. The weight of the minimum spanning tree is returned. If g is not connected, +// a minimum spanning forest will be constructed in dst and the sum of minimum +// spanning tree weights will be returned. +// +// Nodes and Edges from g are used to construct dst, so if the Node and Edge +// types used in g are pointer or reference-like, then the values will be shared +// between the graphs. +// +// If dst has nodes that exist in g, Kruskal will panic. +func Kruskal(dst WeightedBuilder, g UndirectedWeightLister) float64 { + edges := g.WeightedEdges() + sort.Sort(byWeight(edges)) + + ds := newDisjointSet() + for _, node := range g.Nodes() { + dst.AddNode(node) + ds.makeSet(node.ID()) + } + + var w float64 + for _, e := range edges { + if s1, s2 := ds.find(e.From().ID()), ds.find(e.To().ID()); s1 != s2 { + ds.union(s1, s2) + dst.SetWeightedEdge(g.WeightedEdge(e.From(), e.To())) + w += e.Weight() + } + } + return w +} + +type byWeight []graph.WeightedEdge + +func (e byWeight) Len() int { return len(e) } +func (e byWeight) Less(i, j int) bool { return e[i].Weight() < e[j].Weight() } +func (e byWeight) Swap(i, j int) { e[i], e[j] = e[j], e[i] } diff --git a/vendor/gonum.org/v1/gonum/graph/path/spanning_tree_test.go b/vendor/gonum.org/v1/gonum/graph/path/spanning_tree_test.go new file mode 100644 index 00000000..e6515335 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/spanning_tree_test.go @@ -0,0 +1,294 @@ +// 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 path + +import ( + "fmt" + "math" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" +) + +func init() { + for _, test := range spanningTreeTests { + var w float64 + for _, e := range test.treeEdges { + w += e.W + } + if w != test.want { + panic(fmt.Sprintf("bad test: %s weight mismatch: %v != %v", test.name, w, test.want)) + } + } +} + +type spanningGraph interface { + graph.WeightedBuilder + graph.WeightedUndirected + WeightedEdges() []graph.WeightedEdge +} + +var spanningTreeTests = []struct { + name string + graph func() spanningGraph + edges []simple.WeightedEdge + want float64 + treeEdges []simple.WeightedEdge +}{ + { + name: "Empty", + graph: func() spanningGraph { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + want: 0, + }, + { + // https://upload.wikimedia.org/wikipedia/commons/f/f7/Prim%27s_algorithm.svg + // Modified to make edge weights unique; A--B is increased to 2.5 otherwise + // to prevent the alternative solution being found. + name: "Prim WP figure 1", + graph: func() spanningGraph { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + edges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('B'), W: 2.5}, + {F: simple.Node('A'), T: simple.Node('D'), W: 1}, + {F: simple.Node('B'), T: simple.Node('D'), W: 2}, + {F: simple.Node('C'), T: simple.Node('D'), W: 3}, + }, + + want: 6, + treeEdges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('D'), W: 1}, + {F: simple.Node('B'), T: simple.Node('D'), W: 2}, + {F: simple.Node('C'), T: simple.Node('D'), W: 3}, + }, + }, + { + // https://upload.wikimedia.org/wikipedia/commons/5/5c/MST_kruskal_en.gif + name: "Kruskal WP figure 1", + graph: func() spanningGraph { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + edges: []simple.WeightedEdge{ + {F: simple.Node('a'), T: simple.Node('b'), W: 3}, + {F: simple.Node('a'), T: simple.Node('e'), W: 1}, + {F: simple.Node('b'), T: simple.Node('c'), W: 5}, + {F: simple.Node('b'), T: simple.Node('e'), W: 4}, + {F: simple.Node('c'), T: simple.Node('d'), W: 2}, + {F: simple.Node('c'), T: simple.Node('e'), W: 6}, + {F: simple.Node('d'), T: simple.Node('e'), W: 7}, + }, + + want: 11, + treeEdges: []simple.WeightedEdge{ + {F: simple.Node('a'), T: simple.Node('b'), W: 3}, + {F: simple.Node('a'), T: simple.Node('e'), W: 1}, + {F: simple.Node('b'), T: simple.Node('c'), W: 5}, + {F: simple.Node('c'), T: simple.Node('d'), W: 2}, + }, + }, + { + // https://upload.wikimedia.org/wikipedia/commons/8/87/Kruskal_Algorithm_6.svg + name: "Kruskal WP example", + graph: func() spanningGraph { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + edges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('B'), W: 7}, + {F: simple.Node('A'), T: simple.Node('D'), W: 5}, + {F: simple.Node('B'), T: simple.Node('C'), W: 8}, + {F: simple.Node('B'), T: simple.Node('D'), W: 9}, + {F: simple.Node('B'), T: simple.Node('E'), W: 7}, + {F: simple.Node('C'), T: simple.Node('E'), W: 5}, + {F: simple.Node('D'), T: simple.Node('E'), W: 15}, + {F: simple.Node('D'), T: simple.Node('F'), W: 6}, + {F: simple.Node('E'), T: simple.Node('F'), W: 8}, + {F: simple.Node('E'), T: simple.Node('G'), W: 9}, + {F: simple.Node('F'), T: simple.Node('G'), W: 11}, + }, + + want: 39, + treeEdges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('B'), W: 7}, + {F: simple.Node('A'), T: simple.Node('D'), W: 5}, + {F: simple.Node('B'), T: simple.Node('E'), W: 7}, + {F: simple.Node('C'), T: simple.Node('E'), W: 5}, + {F: simple.Node('D'), T: simple.Node('F'), W: 6}, + {F: simple.Node('E'), T: simple.Node('G'), W: 9}, + }, + }, + { + // https://upload.wikimedia.org/wikipedia/commons/2/2e/Boruvka%27s_algorithm_%28Sollin%27s_algorithm%29_Anim.gif + name: "Borůvka WP example", + graph: func() spanningGraph { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + edges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('B'), W: 13}, + {F: simple.Node('A'), T: simple.Node('C'), W: 6}, + {F: simple.Node('B'), T: simple.Node('C'), W: 7}, + {F: simple.Node('B'), T: simple.Node('D'), W: 1}, + {F: simple.Node('C'), T: simple.Node('D'), W: 14}, + {F: simple.Node('C'), T: simple.Node('E'), W: 8}, + {F: simple.Node('C'), T: simple.Node('H'), W: 20}, + {F: simple.Node('D'), T: simple.Node('E'), W: 9}, + {F: simple.Node('D'), T: simple.Node('F'), W: 3}, + {F: simple.Node('E'), T: simple.Node('F'), W: 2}, + {F: simple.Node('E'), T: simple.Node('J'), W: 18}, + {F: simple.Node('G'), T: simple.Node('H'), W: 15}, + {F: simple.Node('G'), T: simple.Node('I'), W: 5}, + {F: simple.Node('G'), T: simple.Node('J'), W: 19}, + {F: simple.Node('G'), T: simple.Node('K'), W: 10}, + {F: simple.Node('H'), T: simple.Node('J'), W: 17}, + {F: simple.Node('I'), T: simple.Node('K'), W: 11}, + {F: simple.Node('J'), T: simple.Node('K'), W: 16}, + {F: simple.Node('J'), T: simple.Node('L'), W: 4}, + {F: simple.Node('K'), T: simple.Node('L'), W: 12}, + }, + + want: 83, + treeEdges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('C'), W: 6}, + {F: simple.Node('B'), T: simple.Node('C'), W: 7}, + {F: simple.Node('B'), T: simple.Node('D'), W: 1}, + {F: simple.Node('D'), T: simple.Node('F'), W: 3}, + {F: simple.Node('E'), T: simple.Node('F'), W: 2}, + {F: simple.Node('E'), T: simple.Node('J'), W: 18}, + {F: simple.Node('G'), T: simple.Node('H'), W: 15}, + {F: simple.Node('G'), T: simple.Node('I'), W: 5}, + {F: simple.Node('G'), T: simple.Node('K'), W: 10}, + {F: simple.Node('J'), T: simple.Node('L'), W: 4}, + {F: simple.Node('K'), T: simple.Node('L'), W: 12}, + }, + }, + { + // https://upload.wikimedia.org/wikipedia/commons/d/d2/Minimum_spanning_tree.svg + // Nodes labelled row major. + name: "Minimum Spanning Tree WP figure 1", + graph: func() spanningGraph { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + edges: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 4}, + {F: simple.Node(1), T: simple.Node(3), W: 1}, + {F: simple.Node(1), T: simple.Node(4), W: 4}, + {F: simple.Node(2), T: simple.Node(3), W: 5}, + {F: simple.Node(2), T: simple.Node(5), W: 9}, + {F: simple.Node(2), T: simple.Node(6), W: 9}, + {F: simple.Node(2), T: simple.Node(8), W: 7}, + {F: simple.Node(3), T: simple.Node(4), W: 3}, + {F: simple.Node(3), T: simple.Node(8), W: 9}, + {F: simple.Node(4), T: simple.Node(8), W: 10}, + {F: simple.Node(4), T: simple.Node(10), W: 18}, + {F: simple.Node(5), T: simple.Node(6), W: 2}, + {F: simple.Node(5), T: simple.Node(7), W: 4}, + {F: simple.Node(5), T: simple.Node(9), W: 6}, + {F: simple.Node(6), T: simple.Node(7), W: 2}, + {F: simple.Node(6), T: simple.Node(8), W: 8}, + {F: simple.Node(7), T: simple.Node(8), W: 9}, + {F: simple.Node(7), T: simple.Node(9), W: 3}, + {F: simple.Node(7), T: simple.Node(10), W: 9}, + {F: simple.Node(8), T: simple.Node(10), W: 8}, + {F: simple.Node(9), T: simple.Node(10), W: 9}, + }, + + want: 38, + treeEdges: []simple.WeightedEdge{ + {F: simple.Node(1), T: simple.Node(2), W: 4}, + {F: simple.Node(1), T: simple.Node(3), W: 1}, + {F: simple.Node(2), T: simple.Node(8), W: 7}, + {F: simple.Node(3), T: simple.Node(4), W: 3}, + {F: simple.Node(5), T: simple.Node(6), W: 2}, + {F: simple.Node(6), T: simple.Node(7), W: 2}, + {F: simple.Node(6), T: simple.Node(8), W: 8}, + {F: simple.Node(7), T: simple.Node(9), W: 3}, + {F: simple.Node(8), T: simple.Node(10), W: 8}, + }, + }, + + { + // https://upload.wikimedia.org/wikipedia/commons/2/2e/Boruvka%27s_algorithm_%28Sollin%27s_algorithm%29_Anim.gif + // but with C--H and E--J cut. + name: "Borůvka WP example cut", + graph: func() spanningGraph { return simple.NewWeightedUndirectedGraph(0, math.Inf(1)) }, + edges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('B'), W: 13}, + {F: simple.Node('A'), T: simple.Node('C'), W: 6}, + {F: simple.Node('B'), T: simple.Node('C'), W: 7}, + {F: simple.Node('B'), T: simple.Node('D'), W: 1}, + {F: simple.Node('C'), T: simple.Node('D'), W: 14}, + {F: simple.Node('C'), T: simple.Node('E'), W: 8}, + {F: simple.Node('D'), T: simple.Node('E'), W: 9}, + {F: simple.Node('D'), T: simple.Node('F'), W: 3}, + {F: simple.Node('E'), T: simple.Node('F'), W: 2}, + {F: simple.Node('G'), T: simple.Node('H'), W: 15}, + {F: simple.Node('G'), T: simple.Node('I'), W: 5}, + {F: simple.Node('G'), T: simple.Node('J'), W: 19}, + {F: simple.Node('G'), T: simple.Node('K'), W: 10}, + {F: simple.Node('H'), T: simple.Node('J'), W: 17}, + {F: simple.Node('I'), T: simple.Node('K'), W: 11}, + {F: simple.Node('J'), T: simple.Node('K'), W: 16}, + {F: simple.Node('J'), T: simple.Node('L'), W: 4}, + {F: simple.Node('K'), T: simple.Node('L'), W: 12}, + }, + + want: 65, + treeEdges: []simple.WeightedEdge{ + {F: simple.Node('A'), T: simple.Node('C'), W: 6}, + {F: simple.Node('B'), T: simple.Node('C'), W: 7}, + {F: simple.Node('B'), T: simple.Node('D'), W: 1}, + {F: simple.Node('D'), T: simple.Node('F'), W: 3}, + {F: simple.Node('E'), T: simple.Node('F'), W: 2}, + {F: simple.Node('G'), T: simple.Node('H'), W: 15}, + {F: simple.Node('G'), T: simple.Node('I'), W: 5}, + {F: simple.Node('G'), T: simple.Node('K'), W: 10}, + {F: simple.Node('J'), T: simple.Node('L'), W: 4}, + {F: simple.Node('K'), T: simple.Node('L'), W: 12}, + }, + }, +} + +func testMinumumSpanning(mst func(dst WeightedBuilder, g spanningGraph) float64, t *testing.T) { + for _, test := range spanningTreeTests { + g := test.graph() + for _, e := range test.edges { + g.SetWeightedEdge(e) + } + + dst := simple.NewWeightedUndirectedGraph(0, math.Inf(1)) + w := mst(dst, g) + if w != test.want { + t.Errorf("unexpected minimum spanning tree weight for %q: got: %f want: %f", + test.name, w, test.want) + } + var got float64 + for _, e := range dst.WeightedEdges() { + got += e.Weight() + } + if got != test.want { + t.Errorf("unexpected minimum spanning tree edge weight sum for %q: got: %f want: %f", + test.name, got, test.want) + } + + gotEdges := dst.Edges() + if len(gotEdges) != len(test.treeEdges) { + t.Errorf("unexpected number of spanning tree edges for %q: got: %d want: %d", + test.name, len(gotEdges), len(test.treeEdges)) + } + for _, e := range test.treeEdges { + w, ok := dst.Weight(e.From(), e.To()) + if !ok { + t.Errorf("spanning tree edge not found in graph for %q: %+v", + test.name, e) + } + if w != e.Weight() { + t.Errorf("unexpected spanning tree edge weight for %q: got: %f want: %f", + test.name, w, e.Weight()) + } + } + } +} + +func TestKruskal(t *testing.T) { + testMinumumSpanning(func(dst WeightedBuilder, g spanningGraph) float64 { + return Kruskal(dst, g) + }, t) +} + +func TestPrim(t *testing.T) { + testMinumumSpanning(func(dst WeightedBuilder, g spanningGraph) float64 { + return Prim(dst, g) + }, t) +} diff --git a/vendor/gonum.org/v1/gonum/graph/path/weight.go b/vendor/gonum.org/v1/gonum/graph/path/weight.go new file mode 100644 index 00000000..91b9d321 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/path/weight.go @@ -0,0 +1,40 @@ +// 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 path + +import ( + "math" + + "gonum.org/v1/gonum/graph" +) + +// Weighting is a mapping between a pair of nodes and a weight. It follows the +// semantics of the Weighter interface. +type Weighting func(x, y graph.Node) (w float64, ok bool) + +// UniformCost returns a Weighting that returns an edge cost of 1 for existing +// edges, zero for node identity and Inf for otherwise absent edges. +func UniformCost(g graph.Graph) Weighting { + return func(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if xid == yid { + return 0, true + } + if e := g.Edge(x, y); e != nil { + return 1, true + } + return math.Inf(1), false + } +} + +// Heuristic returns an estimate of the cost of travelling between two nodes. +type Heuristic func(x, y graph.Node) float64 + +// HeuristicCoster wraps the HeuristicCost method. A graph implementing the +// interface provides a heuristic between any two given nodes. +type HeuristicCoster interface { + HeuristicCost(x, y graph.Node) float64 +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go b/vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go new file mode 100644 index 00000000..b6db362d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go @@ -0,0 +1,300 @@ +// 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/mat" +) + +// 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 +} + +// Node returns the node in the graph with the given ID. +func (g *DirectedMatrix) Node(id int64) graph.Node { + if !g.has(id) { + return nil + } + if g.nodes == nil { + return Node(id) + } + return g.nodes[id] +} + +// Has returns whether the node exists within the graph. +func (g *DirectedMatrix) Has(n graph.Node) bool { + return g.has(n.ID()) +} + +func (g *DirectedMatrix) has(id int64) bool { + r, _ := g.mat.Dims() + return 0 <= id && id < int64(r) +} + +// Nodes returns all the nodes in the graph. +func (g *DirectedMatrix) Nodes() []graph.Node { + if g.nodes != nil { + nodes := make([]graph.Node, len(g.nodes)) + copy(nodes, g.nodes) + return nodes + } + r, _ := g.mat.Dims() + nodes := make([]graph.Node, r) + for i := 0; i < r; i++ { + nodes[i] = Node(i) + } + return nodes +} + +// Edges returns all the edges in the graph. +func (g *DirectedMatrix) Edges() []graph.Edge { + 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}) + } + } + } + return edges +} + +// From returns all nodes in g that can be reached directly from n. +func (g *DirectedMatrix) From(n graph.Node) []graph.Node { + id := n.ID() + if !g.has(id) { + return nil + } + var neighbors []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) { + neighbors = append(neighbors, g.Node(int64(j))) + } + } + return neighbors +} + +// To returns all nodes in g that can reach directly to n. +func (g *DirectedMatrix) To(n graph.Node) []graph.Node { + id := n.ID() + if !g.has(id) { + return nil + } + var neighbors []graph.Node + r, _ := g.mat.Dims() + for i := 0; i < r; i++ { + if int64(i) == id { + continue + } + // id is not greater than maximum int by this point. + if !isSame(g.mat.At(i, int(id)), g.absent) { + neighbors = append(neighbors, g.Node(int64(i))) + } + } + return neighbors +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y without +// considering direction. +func (g *DirectedMatrix) HasEdgeBetween(x, y graph.Node) bool { + xid := x.ID() + if !g.has(xid) { + return false + } + yid := y.ID() + 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)) +} + +// 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(u, v graph.Node) graph.Edge { + return g.WeightedEdge(u, v) +} + +// 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(u, v graph.Node) graph.WeightedEdge { + if g.HasEdgeFromTo(u, v) { + // x.ID() and y.ID() are not greater than maximum int by this point. + return WeightedEdge{F: g.Node(u.ID()), T: g.Node(v.ID()), W: g.mat.At(int(u.ID()), int(v.ID()))} + } + return nil +} + +// HasEdgeFromTo returns whether an edge exists in the graph from u to v. +func (g *DirectedMatrix) HasEdgeFromTo(u, v graph.Node) bool { + uid := u.ID() + if !g.has(uid) { + return false + } + vid := v.ID() + 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) +} + +// 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(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if xid == yid { + return g.self, true + } + if g.has(xid) && g.has(yid) { + // xid and yid are not greater than maximum int by this point. + return g.mat.At(int(xid), int(yid)), true + } + return g.absent, false +} + +// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge +// are not in g or the edge is a self loop, SetEdge panics. +func (g *DirectedMatrix) SetEdge(e graph.Edge) { + g.setWeightedEdge(e, 1) +} + +// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g +// or the edge is a self loop, SetWeightedEdge panics. +func (g *DirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) { + g.setWeightedEdge(e, e.Weight()) +} + +func (g *DirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) { + fid := e.From().ID() + tid := e.To().ID() + if fid == tid { + panic("simple: set illegal edge") + } + if int64(int(fid)) != fid { + panic("simple: unavailable from node ID for dense graph") + } + if int64(int(tid)) != tid { + panic("simple: unavailable to node ID for dense graph") + } + // fid and tid are not greater than maximum int by this point. + g.mat.Set(int(fid), int(tid), weight) +} + +// RemoveEdge removes e from the graph, leaving the terminal nodes. If the edge does not exist +// it is a no-op. +func (g *DirectedMatrix) RemoveEdge(e graph.Edge) { + fid := e.From().ID() + if !g.has(fid) { + return + } + tid := e.To().ID() + 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) +} + +// Degree returns the in+out degree of n in g. +func (g *DirectedMatrix) Degree(n graph.Node) int { + id := n.ID() + if !g.has(id) { + return 0 + } + var deg int + r, c := g.mat.Dims() + for i := 0; i < r; i++ { + if int64(i) == id { + continue + } + // id is not greater than maximum int by this point. + if !isSame(g.mat.At(int(id), i), g.absent) { + deg++ + } + } + for i := 0; i < c; i++ { + if int64(i) == id { + continue + } + // id is not greater than maximum int by this point. + if !isSame(g.mat.At(i, int(id)), g.absent) { + deg++ + } + } + return deg +} + +// 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 +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go b/vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go new file mode 100644 index 00000000..da4cb4f3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go @@ -0,0 +1,261 @@ +// 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/mat" +) + +// 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 +} + +// Node returns the node in the graph with the given ID. +func (g *UndirectedMatrix) Node(id int64) graph.Node { + if !g.has(id) { + return nil + } + if g.nodes == nil { + return Node(id) + } + return g.nodes[id] +} + +// Has returns whether the node exists within the graph. +func (g *UndirectedMatrix) Has(n graph.Node) bool { + return g.has(n.ID()) +} + +func (g *UndirectedMatrix) has(id int64) bool { + r := g.mat.Symmetric() + return 0 <= id && id < int64(r) +} + +// Nodes returns all the nodes in the graph. +func (g *UndirectedMatrix) Nodes() []graph.Node { + if g.nodes != nil { + nodes := make([]graph.Node, len(g.nodes)) + copy(nodes, g.nodes) + return nodes + } + r := g.mat.Symmetric() + nodes := make([]graph.Node, r) + for i := 0; i < r; i++ { + nodes[i] = Node(i) + } + return nodes +} + +// Edges returns all the edges in the graph. +func (g *UndirectedMatrix) Edges() []graph.Edge { + 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}) + } + } + } + return edges +} + +// From returns all nodes in g that can be reached directly from n. +func (g *UndirectedMatrix) From(n graph.Node) []graph.Node { + id := n.ID() + if !g.has(id) { + return nil + } + var neighbors []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) { + neighbors = append(neighbors, g.Node(int64(i))) + } + } + return neighbors +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g *UndirectedMatrix) HasEdgeBetween(u, v graph.Node) bool { + uid := u.ID() + if !g.has(uid) { + return false + } + vid := v.ID() + 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) +} + +// 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(u, v graph.Node) graph.Edge { + return g.WeightedEdgeBetween(u, v) +} + +// 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(u, v graph.Node) graph.WeightedEdge { + return g.WeightedEdgeBetween(u, v) +} + +// EdgeBetween returns the edge between nodes x and y. +func (g *UndirectedMatrix) EdgeBetween(u, v graph.Node) graph.Edge { + return g.WeightedEdgeBetween(u, v) +} + +// WeightedEdgeBetween returns the weighted edge between nodes x and y. +func (g *UndirectedMatrix) WeightedEdgeBetween(u, v graph.Node) graph.WeightedEdge { + if g.HasEdgeBetween(u, v) { + // u.ID() and v.ID() are not greater than maximum int by this point. + return WeightedEdge{F: g.Node(u.ID()), T: g.Node(v.ID()), W: g.mat.At(int(u.ID()), int(v.ID()))} + } + return nil +} + +// 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(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if xid == yid { + return g.self, true + } + if g.has(xid) && g.has(yid) { + // xid and yid are not greater than maximum int by this point. + return g.mat.At(int(xid), int(yid)), true + } + return g.absent, false +} + +// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge are +// not in g or the edge is a self loop, SetEdge panics. +func (g *UndirectedMatrix) SetEdge(e graph.Edge) { + g.setWeightedEdge(e, 1) +} + +// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g +// or the edge is a self loop, SetWeightedEdge panics. +func (g *UndirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) { + g.setWeightedEdge(e, e.Weight()) +} + +func (g *UndirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) { + fid := e.From().ID() + tid := e.To().ID() + if fid == tid { + panic("simple: set illegal edge") + } + if int64(int(fid)) != fid { + panic("simple: unavailable from node ID for dense graph") + } + if int64(int(tid)) != tid { + panic("simple: unavailable to node ID for dense graph") + } + // fid and tid are not greater than maximum int by this point. + g.mat.SetSym(int(fid), int(tid), weight) +} + +// RemoveEdge removes e from the graph, leaving the terminal nodes. If the edge does not exist +// it is a no-op. +func (g *UndirectedMatrix) RemoveEdge(e graph.Edge) { + fid := e.From().ID() + if !g.has(fid) { + return + } + tid := e.To().ID() + 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) +} + +// Degree returns the degree of n in g. +func (g *UndirectedMatrix) Degree(n graph.Node) int { + id := n.ID() + if !g.has(id) { + return 0 + } + var deg int + r := g.mat.Symmetric() + for i := 0; i < r; i++ { + if int64(i) == id { + continue + } + // id is not greater than maximum int by this point. + if !isSame(g.mat.At(int(id), i), g.absent) { + deg++ + } + } + return deg +} + +// 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 +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/densegraph_test.go b/vendor/gonum.org/v1/gonum/graph/simple/densegraph_test.go new file mode 100644 index 00000000..5a68c219 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/densegraph_test.go @@ -0,0 +1,149 @@ +// 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" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" +) + +var ( + directedMatrix = (*DirectedMatrix)(nil) + + _ graph.Graph = directedMatrix + _ graph.Directed = directedMatrix + _ graph.WeightedDirected = directedMatrix + + undirectedMatrix = (*UndirectedMatrix)(nil) + + _ graph.Graph = undirectedMatrix + _ graph.Undirected = undirectedMatrix + _ graph.WeightedUndirected = undirectedMatrix +) + +func TestBasicDenseImpassable(t *testing.T) { + dg := NewUndirectedMatrix(5, math.Inf(1), 0, math.Inf(1)) + if dg == nil { + t.Fatal("Directed graph could not be made") + } + + for i := 0; i < 5; i++ { + if !dg.Has(Node(i)) { + t.Errorf("Node that should exist doesn't: %d", i) + } + + if degree := dg.Degree(Node(i)); degree != 0 { + t.Errorf("Node in impassable graph has a neighbor. Node: %d Degree: %d", i, degree) + } + } + + for i := 5; i < 10; i++ { + if dg.Has(Node(i)) { + t.Errorf("Node exists that shouldn't: %d", i) + } + } +} + +func TestBasicDensePassable(t *testing.T) { + dg := NewUndirectedMatrix(5, 1, 0, math.Inf(1)) + if dg == nil { + t.Fatal("Directed graph could not be made") + } + + for i := 0; i < 5; i++ { + if !dg.Has(Node(i)) { + t.Errorf("Node that should exist doesn't: %d", i) + } + + if degree := dg.Degree(Node(i)); degree != 4 { + t.Errorf("Node in passable graph missing neighbors. Node: %d Degree: %d", i, degree) + } + } + + for i := 5; i < 10; i++ { + if dg.Has(Node(i)) { + t.Errorf("Node exists that shouldn't: %d", i) + } + } +} + +func TestDirectedDenseAddRemove(t *testing.T) { + dg := NewDirectedMatrix(10, math.Inf(1), 0, math.Inf(1)) + dg.SetWeightedEdge(WeightedEdge{F: Node(0), T: Node(2), W: 1}) + + if neighbors := dg.From(Node(0)); len(neighbors) != 1 || neighbors[0].ID() != 2 || + dg.Edge(Node(0), Node(2)) == nil { + t.Errorf("Adding edge didn't create successor") + } + + dg.RemoveEdge(Edge{F: Node(0), T: Node(2)}) + + if neighbors := dg.From(Node(0)); len(neighbors) != 0 || dg.Edge(Node(0), Node(2)) != nil { + t.Errorf("Removing edge didn't properly remove successor") + } + + if neighbors := dg.To(Node(2)); len(neighbors) != 0 || dg.Edge(Node(0), Node(2)) != nil { + t.Errorf("Removing directed edge wrongly kept predecessor") + } + + dg.SetWeightedEdge(WeightedEdge{F: Node(0), T: Node(2), W: 2}) + // I figure we've torture tested From/To at this point + // so we'll just use the bool functions now + if dg.Edge(Node(0), Node(2)) == nil { + t.Fatal("Adding directed edge didn't change successor back") + } + c1, _ := dg.Weight(Node(2), Node(0)) + c2, _ := dg.Weight(Node(0), Node(2)) + if c1 == c2 { + t.Error("Adding directed edge affected cost in undirected manner") + } +} + +func TestUndirectedDenseAddRemove(t *testing.T) { + dg := NewUndirectedMatrix(10, math.Inf(1), 0, math.Inf(1)) + dg.SetEdge(Edge{F: Node(0), T: Node(2)}) + + if neighbors := dg.From(Node(0)); len(neighbors) != 1 || neighbors[0].ID() != 2 || + dg.EdgeBetween(Node(0), Node(2)) == nil { + t.Errorf("Couldn't add neighbor") + } + + if neighbors := dg.From(Node(2)); len(neighbors) != 1 || neighbors[0].ID() != 0 || + dg.EdgeBetween(Node(2), Node(0)) == nil { + t.Errorf("Adding an undirected neighbor didn't add it reciprocally") + } +} + +func TestDenseLists(t *testing.T) { + dg := NewDirectedMatrix(15, 1, 0, math.Inf(1)) + nodes := dg.Nodes() + + if len(nodes) != 15 { + t.Fatalf("Wrong number of nodes") + } + + sort.Sort(ordered.ByID(nodes)) + + for i, node := range dg.Nodes() { + if int64(i) != node.ID() { + t.Errorf("Node list doesn't return properly id'd nodes") + } + } + + edges := dg.Edges() + if len(edges) != 15*14 { + t.Errorf("Improper number of edges for passable dense graph") + } + + dg.RemoveEdge(Edge{F: Node(12), T: Node(11)}) + edges = dg.Edges() + if len(edges) != (15*14)-1 { + t.Errorf("Removing edge didn't affect edge listing properly") + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/directed.go b/vendor/gonum.org/v1/gonum/graph/simple/directed.go new file mode 100644 index 00000000..0796cb13 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/directed.go @@ -0,0 +1,245 @@ +// 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" +) + +// 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 idSet +} + +// NewDirectedGraph returns a DirectedGraph with the specified self and absent +// edge weight values. +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: newIDSet(), + } +} + +// 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)) == maxInt { + panic("simple: cannot allocate node: no slot") + } + return Node(g.nodeIDs.newID()) +} + +// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID. +func (g *DirectedGraph) AddNode(n graph.Node) { + if _, exists := g.nodes[n.ID()]; exists { + panic(fmt.Sprintf("simple: node ID collision: %d", n.ID())) + } + g.nodes[n.ID()] = n + g.from[n.ID()] = make(map[int64]graph.Edge) + g.to[n.ID()] = make(map[int64]graph.Edge) + g.nodeIDs.use(n.ID()) +} + +// RemoveNode removes n 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(n graph.Node) { + if _, ok := g.nodes[n.ID()]; !ok { + return + } + delete(g.nodes, n.ID()) + + for from := range g.from[n.ID()] { + delete(g.to[from], n.ID()) + } + delete(g.from, n.ID()) + + for to := range g.to[n.ID()] { + delete(g.from[to], n.ID()) + } + delete(g.to, n.ID()) + + g.nodeIDs.release(n.ID()) +} + +// NewEdge returns a new Edge from the source to the destination node. +func (g *DirectedGraph) NewEdge(from, to graph.Node) graph.Edge { + return &Edge{F: from, T: to} +} + +// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added. +// 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 !g.Has(from) { + g.AddNode(from) + } + if !g.Has(to) { + g.AddNode(to) + } + + g.from[fid][tid] = e + g.to[tid][fid] = e +} + +// RemoveEdge removes e from the graph, leaving the terminal nodes. If the edge does not exist +// it is a no-op. +func (g *DirectedGraph) RemoveEdge(e graph.Edge) { + from, to := e.From(), e.To() + if _, ok := g.nodes[from.ID()]; !ok { + return + } + if _, ok := g.nodes[to.ID()]; !ok { + return + } + + delete(g.from[from.ID()], to.ID()) + delete(g.to[to.ID()], from.ID()) +} + +// Node returns the node in the graph with the given ID. +func (g *DirectedGraph) Node(id int64) graph.Node { + return g.nodes[id] +} + +// Has returns whether the node exists within the graph. +func (g *DirectedGraph) Has(n graph.Node) bool { + _, ok := g.nodes[n.ID()] + + return ok +} + +// Nodes returns all the nodes in the graph. +func (g *DirectedGraph) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.from)) + i := 0 + for _, n := range g.nodes { + nodes[i] = n + i++ + } + + return nodes +} + +// Edges returns all the edges in the graph. +func (g *DirectedGraph) Edges() []graph.Edge { + var edges []graph.Edge + for _, u := range g.nodes { + for _, e := range g.from[u.ID()] { + edges = append(edges, e) + } + } + return edges +} + +// From returns all nodes in g that can be reached directly from n. +func (g *DirectedGraph) From(n graph.Node) []graph.Node { + if _, ok := g.from[n.ID()]; !ok { + return nil + } + + from := make([]graph.Node, len(g.from[n.ID()])) + i := 0 + for id := range g.from[n.ID()] { + from[i] = g.nodes[id] + i++ + } + + return from +} + +// To returns all nodes in g that can reach directly to n. +func (g *DirectedGraph) To(n graph.Node) []graph.Node { + if _, ok := g.from[n.ID()]; !ok { + return nil + } + + to := make([]graph.Node, len(g.to[n.ID()])) + i := 0 + for id := range g.to[n.ID()] { + to[i] = g.nodes[id] + i++ + } + + return to +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y without +// considering direction. +func (g *DirectedGraph) HasEdgeBetween(x, y graph.Node) bool { + xid := x.ID() + yid := y.ID() + if _, ok := g.nodes[xid]; !ok { + return false + } + if _, ok := g.nodes[yid]; !ok { + return false + } + if _, ok := g.from[xid][yid]; ok { + return true + } + _, ok := g.from[yid][xid] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *DirectedGraph) Edge(u, v graph.Node) graph.Edge { + if _, ok := g.nodes[u.ID()]; !ok { + return nil + } + if _, ok := g.nodes[v.ID()]; !ok { + return nil + } + edge, ok := g.from[u.ID()][v.ID()] + if !ok { + return nil + } + return edge +} + +// HasEdgeFromTo returns whether an edge exists in the graph from u to v. +func (g *DirectedGraph) HasEdgeFromTo(u, v graph.Node) bool { + if _, ok := g.nodes[u.ID()]; !ok { + return false + } + if _, ok := g.nodes[v.ID()]; !ok { + return false + } + if _, ok := g.from[u.ID()][v.ID()]; !ok { + return false + } + return true +} + +// Degree returns the in+out degree of n in g. +func (g *DirectedGraph) Degree(n graph.Node) int { + if _, ok := g.nodes[n.ID()]; !ok { + return 0 + } + + return len(g.from[n.ID()]) + len(g.to[n.ID()]) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/directed_test.go b/vendor/gonum.org/v1/gonum/graph/simple/directed_test.go new file mode 100644 index 00000000..b66845bd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/directed_test.go @@ -0,0 +1,65 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/graph" +) + +var ( + directedGraph = (*DirectedGraph)(nil) + + _ graph.Graph = directedGraph + _ graph.Directed = directedGraph +) + +// Tests Issue #27 +func TestEdgeOvercounting(t *testing.T) { + g := generateDummyGraph() + + if neigh := g.From(Node(Node(2))); len(neigh) != 2 { + t.Errorf("Node 2 has incorrect number of neighbors got neighbors %v (count %d), expected 2 neighbors {0,1}", neigh, len(neigh)) + } +} + +func generateDummyGraph() *DirectedGraph { + nodes := [4]struct{ srcID, targetID int }{ + {2, 1}, + {1, 0}, + {2, 0}, + {0, 2}, + } + + g := NewDirectedGraph() + + for _, n := range nodes { + g.SetEdge(Edge{F: Node(n.srcID), T: Node(n.targetID)}) + } + + return g +} + +// Test for issue #123 https://github.com/gonum/graph/issues/123 +func TestIssue123DirectedGraph(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Errorf("unexpected panic: %v", r) + } + }() + g := NewDirectedGraph() + + n0 := g.NewNode() + g.AddNode(n0) + + n1 := g.NewNode() + g.AddNode(n1) + + g.RemoveNode(n0) + + n2 := g.NewNode() + g.AddNode(n2) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/doc.go b/vendor/gonum.org/v1/gonum/graph/simple/doc.go new file mode 100644 index 00000000..1b688a95 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/doc.go @@ -0,0 +1,7 @@ +// 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. +package simple // import "gonum.org/v1/gonum/graph/simple" diff --git a/vendor/gonum.org/v1/gonum/graph/simple/simple.go b/vendor/gonum.org/v1/gonum/graph/simple/simple.go new file mode 100644 index 00000000..13c1618a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/simple.go @@ -0,0 +1,99 @@ +// 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" + "gonum.org/v1/gonum/graph/internal/set" +) + +// 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) +} + +// 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 } + +// 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 } + +// 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)) +} + +// maxInt is the maximum value of int64. +const maxInt = int64(^uint64(0) >> 1) + +// idSet implements available ID storage. +type idSet struct { + maxID int64 + used, free set.Int64s +} + +// newIDSet returns a new idSet. The returned value should not be passed +// except by pointer. +func newIDSet() idSet { + return idSet{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 *idSet) newID() int64 { + for id := range s.free { + return id + } + if s.maxID != maxInt { + 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 idSet. +func (s *idSet) use(id int64) { + s.used.Add(id) + s.free.Remove(id) + if id > s.maxID { + s.maxID = id + } +} + +// free frees the id for reuse. +func (s *idSet) release(id int64) { + s.free.Add(id) + s.used.Remove(id) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/undirected.go b/vendor/gonum.org/v1/gonum/graph/simple/undirected.go new file mode 100644 index 00000000..7254e4a0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/undirected.go @@ -0,0 +1,205 @@ +// 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" +) + +// UndirectedGraph implements a generalized undirected graph. +type UndirectedGraph struct { + nodes map[int64]graph.Node + edges map[int64]map[int64]graph.Edge + + nodeIDs idSet +} + +// NewUndirectedGraph returns an UndirectedGraph with the specified self and absent +// edge weight values. +func NewUndirectedGraph() *UndirectedGraph { + return &UndirectedGraph{ + nodes: make(map[int64]graph.Node), + edges: make(map[int64]map[int64]graph.Edge), + + nodeIDs: newIDSet(), + } +} + +// NewNode returns a new unique Node to be added to g. The Node's ID does +// not become valid in g until the Node is added to g. +func (g *UndirectedGraph) NewNode() graph.Node { + if len(g.nodes) == 0 { + return Node(0) + } + if int64(len(g.nodes)) == maxInt { + panic("simple: cannot allocate node: no slot") + } + return Node(g.nodeIDs.newID()) +} + +// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID. +func (g *UndirectedGraph) AddNode(n graph.Node) { + if _, exists := g.nodes[n.ID()]; exists { + panic(fmt.Sprintf("simple: node ID collision: %d", n.ID())) + } + g.nodes[n.ID()] = n + g.edges[n.ID()] = make(map[int64]graph.Edge) + g.nodeIDs.use(n.ID()) +} + +// RemoveNode removes n 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 *UndirectedGraph) RemoveNode(n graph.Node) { + if _, ok := g.nodes[n.ID()]; !ok { + return + } + delete(g.nodes, n.ID()) + + for from := range g.edges[n.ID()] { + delete(g.edges[from], n.ID()) + } + delete(g.edges, n.ID()) + + g.nodeIDs.release(n.ID()) +} + +// NewEdge returns a new Edge from the source to the destination node. +func (g *UndirectedGraph) NewEdge(from, to graph.Node) graph.Edge { + return &Edge{F: from, T: to} +} + +// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added. +// It will panic if the IDs of the e.From and e.To are equal. +func (g *UndirectedGraph) 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 !g.Has(from) { + g.AddNode(from) + } + if !g.Has(to) { + g.AddNode(to) + } + + g.edges[fid][tid] = e + g.edges[tid][fid] = e +} + +// RemoveEdge removes e from the graph, leaving the terminal nodes. If the edge does not exist +// it is a no-op. +func (g *UndirectedGraph) RemoveEdge(e graph.Edge) { + from, to := e.From(), e.To() + if _, ok := g.nodes[from.ID()]; !ok { + return + } + if _, ok := g.nodes[to.ID()]; !ok { + return + } + + delete(g.edges[from.ID()], to.ID()) + delete(g.edges[to.ID()], from.ID()) +} + +// Node returns the node in the graph with the given ID. +func (g *UndirectedGraph) Node(id int64) graph.Node { + return g.nodes[id] +} + +// Has returns whether the node exists within the graph. +func (g *UndirectedGraph) Has(n graph.Node) bool { + _, ok := g.nodes[n.ID()] + return ok +} + +// Nodes returns all the nodes in the graph. +func (g *UndirectedGraph) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.nodes)) + i := 0 + for _, n := range g.nodes { + nodes[i] = n + i++ + } + + return nodes +} + +// Edges returns all the edges in the graph. +func (g *UndirectedGraph) Edges() []graph.Edge { + var edges []graph.Edge + + seen := make(map[[2]int64]struct{}) + for _, u := range g.edges { + for _, e := range u { + uid := e.From().ID() + vid := e.To().ID() + if _, ok := seen[[2]int64{uid, vid}]; ok { + continue + } + seen[[2]int64{uid, vid}] = struct{}{} + seen[[2]int64{vid, uid}] = struct{}{} + edges = append(edges, e) + } + } + + return edges +} + +// From returns all nodes in g that can be reached directly from n. +func (g *UndirectedGraph) From(n graph.Node) []graph.Node { + if !g.Has(n) { + return nil + } + + nodes := make([]graph.Node, len(g.edges[n.ID()])) + i := 0 + for from := range g.edges[n.ID()] { + nodes[i] = g.nodes[from] + i++ + } + + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g *UndirectedGraph) HasEdgeBetween(x, y graph.Node) bool { + _, ok := g.edges[x.ID()][y.ID()] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *UndirectedGraph) Edge(u, v graph.Node) graph.Edge { + return g.EdgeBetween(u, v) +} + +// EdgeBetween returns the edge between nodes x and y. +func (g *UndirectedGraph) EdgeBetween(x, y graph.Node) graph.Edge { + // We don't need to check if neigh exists because + // it's implicit in the edges access. + if !g.Has(x) { + return nil + } + + return g.edges[x.ID()][y.ID()] +} + +// Degree returns the degree of n in g. +func (g *UndirectedGraph) Degree(n graph.Node) int { + if _, ok := g.nodes[n.ID()]; !ok { + return 0 + } + + return len(g.edges[n.ID()]) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/undirected_test.go b/vendor/gonum.org/v1/gonum/graph/simple/undirected_test.go new file mode 100644 index 00000000..f5c0dafc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/undirected_test.go @@ -0,0 +1,67 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/graph" +) + +var ( + undirectedGraph = (*UndirectedGraph)(nil) + + _ graph.Graph = undirectedGraph + _ graph.Undirected = undirectedGraph +) + +func TestAssertMutableNotDirected(t *testing.T) { + var g graph.UndirectedBuilder = NewUndirectedGraph() + if _, ok := g.(graph.Directed); ok { + t.Fatal("Graph is directed, but a MutableGraph cannot safely be directed!") + } +} + +func TestMaxID(t *testing.T) { + g := NewUndirectedGraph() + nodes := make(map[graph.Node]struct{}) + for i := Node(0); i < 3; i++ { + g.AddNode(i) + nodes[i] = struct{}{} + } + g.RemoveNode(Node(0)) + delete(nodes, Node(0)) + g.RemoveNode(Node(2)) + delete(nodes, Node(2)) + n := g.NewNode() + g.AddNode(n) + if !g.Has(n) { + t.Error("added node does not exist in graph") + } + if _, exists := nodes[n]; exists { + t.Errorf("Created already existing node id: %v", n.ID()) + } +} + +// Test for issue #123 https://github.com/gonum/graph/issues/123 +func TestIssue123UndirectedGraph(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Errorf("unexpected panic: %v", r) + } + }() + g := NewUndirectedGraph() + + n0 := g.NewNode() + g.AddNode(n0) + + n1 := g.NewNode() + g.AddNode(n1) + + g.RemoveNode(n0) + + n2 := g.NewNode() + g.AddNode(n2) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/weighted_directed.go b/vendor/gonum.org/v1/gonum/graph/simple/weighted_directed.go new file mode 100644 index 00000000..fbe3ae80 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/weighted_directed.go @@ -0,0 +1,285 @@ +// 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" +) + +// WeightedDirectedGraph implements a generalized weighted directed graph. +type WeightedDirectedGraph struct { + nodes map[int64]graph.Node + from map[int64]map[int64]graph.WeightedEdge + to map[int64]map[int64]graph.WeightedEdge + + self, absent float64 + + nodeIDs idSet +} + +// NewWeightedDirectedGraph returns a WeightedDirectedGraph with the specified self and absent +// edge weight values. +func NewWeightedDirectedGraph(self, absent float64) *WeightedDirectedGraph { + return &WeightedDirectedGraph{ + nodes: make(map[int64]graph.Node), + from: make(map[int64]map[int64]graph.WeightedEdge), + to: make(map[int64]map[int64]graph.WeightedEdge), + + self: self, + absent: absent, + + nodeIDs: newIDSet(), + } +} + +// NewNode returns a new unique Node to be added to g. The Node's ID does +// not become valid in g until the Node is added to g. +func (g *WeightedDirectedGraph) NewNode() graph.Node { + if len(g.nodes) == 0 { + return Node(0) + } + if int64(len(g.nodes)) == maxInt { + panic("simple: cannot allocate node: no slot") + } + return Node(g.nodeIDs.newID()) +} + +// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID. +func (g *WeightedDirectedGraph) AddNode(n graph.Node) { + if _, exists := g.nodes[n.ID()]; exists { + panic(fmt.Sprintf("simple: node ID collision: %d", n.ID())) + } + g.nodes[n.ID()] = n + g.from[n.ID()] = make(map[int64]graph.WeightedEdge) + g.to[n.ID()] = make(map[int64]graph.WeightedEdge) + g.nodeIDs.use(n.ID()) +} + +// RemoveNode removes n 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 *WeightedDirectedGraph) RemoveNode(n graph.Node) { + if _, ok := g.nodes[n.ID()]; !ok { + return + } + delete(g.nodes, n.ID()) + + for from := range g.from[n.ID()] { + delete(g.to[from], n.ID()) + } + delete(g.from, n.ID()) + + for to := range g.to[n.ID()] { + delete(g.from[to], n.ID()) + } + delete(g.to, n.ID()) + + g.nodeIDs.release(n.ID()) +} + +// NewWeightedEdge returns a new weighted edge from the source to the destination node. +func (g *WeightedDirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge { + return &WeightedEdge{F: from, T: to, W: weight} +} + +// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added. +// It will panic if the IDs of the e.From and e.To are equal. +func (g *WeightedDirectedGraph) SetWeightedEdge(e graph.WeightedEdge) { + var ( + from = e.From() + fid = from.ID() + to = e.To() + tid = to.ID() + ) + + if fid == tid { + panic("simple: adding self edge") + } + + if !g.Has(from) { + g.AddNode(from) + } + if !g.Has(to) { + g.AddNode(to) + } + + g.from[fid][tid] = e + g.to[tid][fid] = e +} + +// RemoveEdge removes e from the graph, leaving the terminal nodes. If the edge does not exist +// it is a no-op. +func (g *WeightedDirectedGraph) RemoveEdge(e graph.Edge) { + from, to := e.From(), e.To() + if _, ok := g.nodes[from.ID()]; !ok { + return + } + if _, ok := g.nodes[to.ID()]; !ok { + return + } + + delete(g.from[from.ID()], to.ID()) + delete(g.to[to.ID()], from.ID()) +} + +// Node returns the node in the graph with the given ID. +func (g *WeightedDirectedGraph) Node(id int64) graph.Node { + return g.nodes[id] +} + +// Has returns whether the node exists within the graph. +func (g *WeightedDirectedGraph) Has(n graph.Node) bool { + _, ok := g.nodes[n.ID()] + + return ok +} + +// Nodes returns all the nodes in the graph. +func (g *WeightedDirectedGraph) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.from)) + i := 0 + for _, n := range g.nodes { + nodes[i] = n + i++ + } + + return nodes +} + +// Edges returns all the edges in the graph. +func (g *WeightedDirectedGraph) Edges() []graph.Edge { + var edges []graph.Edge + for _, u := range g.nodes { + for _, e := range g.from[u.ID()] { + edges = append(edges, e) + } + } + return edges +} + +// WeightedEdges returns all the weighted edges in the graph. +func (g *WeightedDirectedGraph) WeightedEdges() []graph.WeightedEdge { + var edges []graph.WeightedEdge + for _, u := range g.nodes { + for _, e := range g.from[u.ID()] { + edges = append(edges, e) + } + } + return edges +} + +// From returns all nodes in g that can be reached directly from n. +func (g *WeightedDirectedGraph) From(n graph.Node) []graph.Node { + if _, ok := g.from[n.ID()]; !ok { + return nil + } + + from := make([]graph.Node, len(g.from[n.ID()])) + i := 0 + for id := range g.from[n.ID()] { + from[i] = g.nodes[id] + i++ + } + + return from +} + +// To returns all nodes in g that can reach directly to n. +func (g *WeightedDirectedGraph) To(n graph.Node) []graph.Node { + if _, ok := g.from[n.ID()]; !ok { + return nil + } + + to := make([]graph.Node, len(g.to[n.ID()])) + i := 0 + for id := range g.to[n.ID()] { + to[i] = g.nodes[id] + i++ + } + + return to +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y without +// considering direction. +func (g *WeightedDirectedGraph) HasEdgeBetween(x, y graph.Node) bool { + xid := x.ID() + yid := y.ID() + if _, ok := g.nodes[xid]; !ok { + return false + } + if _, ok := g.nodes[yid]; !ok { + return false + } + if _, ok := g.from[xid][yid]; ok { + return true + } + _, ok := g.from[yid][xid] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *WeightedDirectedGraph) Edge(u, v graph.Node) graph.Edge { + return g.WeightedEdge(u, v) +} + +// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *WeightedDirectedGraph) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + if _, ok := g.nodes[u.ID()]; !ok { + return nil + } + if _, ok := g.nodes[v.ID()]; !ok { + return nil + } + edge, ok := g.from[u.ID()][v.ID()] + if !ok { + return nil + } + return edge +} + +// HasEdgeFromTo returns whether an edge exists in the graph from u to v. +func (g *WeightedDirectedGraph) HasEdgeFromTo(u, v graph.Node) bool { + if _, ok := g.nodes[u.ID()]; !ok { + return false + } + if _, ok := g.nodes[v.ID()]; !ok { + return false + } + if _, ok := g.from[u.ID()][v.ID()]; !ok { + return false + } + return true +} + +// 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 *WeightedDirectedGraph) Weight(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if xid == yid { + return g.self, true + } + if to, ok := g.from[xid]; ok { + if e, ok := to[yid]; ok { + return e.Weight(), true + } + } + return g.absent, false +} + +// Degree returns the in+out degree of n in g. +func (g *WeightedDirectedGraph) Degree(n graph.Node) int { + if _, ok := g.nodes[n.ID()]; !ok { + return 0 + } + + return len(g.from[n.ID()]) + len(g.to[n.ID()]) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/weighted_directed_test.go b/vendor/gonum.org/v1/gonum/graph/simple/weighted_directed_test.go new file mode 100644 index 00000000..714b067d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/weighted_directed_test.go @@ -0,0 +1,67 @@ +// 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" + "testing" + + "gonum.org/v1/gonum/graph" +) + +var ( + weightedDirectedGraph = (*WeightedDirectedGraph)(nil) + + _ graph.Graph = weightedDirectedGraph + _ graph.Directed = weightedDirectedGraph + _ graph.WeightedDirected = weightedDirectedGraph +) + +// Tests Issue #27 +func TestWeightedEdgeOvercounting(t *testing.T) { + g := generateDummyGraph() + + if neigh := g.From(Node(Node(2))); len(neigh) != 2 { + t.Errorf("Node 2 has incorrect number of neighbors got neighbors %v (count %d), expected 2 neighbors {0,1}", neigh, len(neigh)) + } +} + +func generateDummyWeightedGraph() *WeightedDirectedGraph { + nodes := [4]struct{ srcID, targetID int }{ + {2, 1}, + {1, 0}, + {2, 0}, + {0, 2}, + } + + g := NewWeightedDirectedGraph(0, math.Inf(1)) + + for _, n := range nodes { + g.SetWeightedEdge(WeightedEdge{F: Node(n.srcID), T: Node(n.targetID), W: 1}) + } + + return g +} + +// Test for issue #123 https://github.com/gonum/graph/issues/123 +func TestIssue123WeightedDirectedGraph(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Errorf("unexpected panic: %v", r) + } + }() + g := NewWeightedDirectedGraph(0, math.Inf(1)) + + n0 := g.NewNode() + g.AddNode(n0) + + n1 := g.NewNode() + g.AddNode(n1) + + g.RemoveNode(n0) + + n2 := g.NewNode() + g.AddNode(n2) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected.go b/vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected.go new file mode 100644 index 00000000..9ec4cd61 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected.go @@ -0,0 +1,260 @@ +// 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" +) + +// WeightedUndirectedGraph implements a generalized weighted undirected graph. +type WeightedUndirectedGraph struct { + nodes map[int64]graph.Node + edges map[int64]map[int64]graph.WeightedEdge + + self, absent float64 + + nodeIDs idSet +} + +// NewWeightedUndirectedGraph returns an WeightedUndirectedGraph with the specified self and absent +// edge weight values. +func NewWeightedUndirectedGraph(self, absent float64) *WeightedUndirectedGraph { + return &WeightedUndirectedGraph{ + nodes: make(map[int64]graph.Node), + edges: make(map[int64]map[int64]graph.WeightedEdge), + + self: self, + absent: absent, + + nodeIDs: newIDSet(), + } +} + +// NewNode returns a new unique Node to be added to g. The Node's ID does +// not become valid in g until the Node is added to g. +func (g *WeightedUndirectedGraph) NewNode() graph.Node { + if len(g.nodes) == 0 { + return Node(0) + } + if int64(len(g.nodes)) == maxInt { + panic("simple: cannot allocate node: no slot") + } + return Node(g.nodeIDs.newID()) +} + +// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID. +func (g *WeightedUndirectedGraph) AddNode(n graph.Node) { + if _, exists := g.nodes[n.ID()]; exists { + panic(fmt.Sprintf("simple: node ID collision: %d", n.ID())) + } + g.nodes[n.ID()] = n + g.edges[n.ID()] = make(map[int64]graph.WeightedEdge) + g.nodeIDs.use(n.ID()) +} + +// RemoveNode removes n 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 *WeightedUndirectedGraph) RemoveNode(n graph.Node) { + if _, ok := g.nodes[n.ID()]; !ok { + return + } + delete(g.nodes, n.ID()) + + for from := range g.edges[n.ID()] { + delete(g.edges[from], n.ID()) + } + delete(g.edges, n.ID()) + + g.nodeIDs.release(n.ID()) +} + +// NewWeightedEdge returns a new weighted edge from the source to the destination node. +func (g *WeightedUndirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge { + return &WeightedEdge{F: from, T: to, W: weight} +} + +// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added. +// It will panic if the IDs of the e.From and e.To are equal. +func (g *WeightedUndirectedGraph) SetWeightedEdge(e graph.WeightedEdge) { + var ( + from = e.From() + fid = from.ID() + to = e.To() + tid = to.ID() + ) + + if fid == tid { + panic("simple: adding self edge") + } + + if !g.Has(from) { + g.AddNode(from) + } + if !g.Has(to) { + g.AddNode(to) + } + + g.edges[fid][tid] = e + g.edges[tid][fid] = e +} + +// RemoveEdge removes e from the graph, leaving the terminal nodes. If the edge does not exist +// it is a no-op. +func (g *WeightedUndirectedGraph) RemoveEdge(e graph.Edge) { + from, to := e.From(), e.To() + if _, ok := g.nodes[from.ID()]; !ok { + return + } + if _, ok := g.nodes[to.ID()]; !ok { + return + } + + delete(g.edges[from.ID()], to.ID()) + delete(g.edges[to.ID()], from.ID()) +} + +// Node returns the node in the graph with the given ID. +func (g *WeightedUndirectedGraph) Node(id int64) graph.Node { + return g.nodes[id] +} + +// Has returns whether the node exists within the graph. +func (g *WeightedUndirectedGraph) Has(n graph.Node) bool { + _, ok := g.nodes[n.ID()] + return ok +} + +// Nodes returns all the nodes in the graph. +func (g *WeightedUndirectedGraph) Nodes() []graph.Node { + nodes := make([]graph.Node, len(g.nodes)) + i := 0 + for _, n := range g.nodes { + nodes[i] = n + i++ + } + + return nodes +} + +// Edges returns all the edges in the graph. +func (g *WeightedUndirectedGraph) Edges() []graph.Edge { + var edges []graph.Edge + + seen := make(map[[2]int64]struct{}) + for _, u := range g.edges { + for _, e := range u { + uid := e.From().ID() + vid := e.To().ID() + if _, ok := seen[[2]int64{uid, vid}]; ok { + continue + } + seen[[2]int64{uid, vid}] = struct{}{} + seen[[2]int64{vid, uid}] = struct{}{} + edges = append(edges, e) + } + } + + return edges +} + +// WeightedEdges returns all the weighted edges in the graph. +func (g *WeightedUndirectedGraph) WeightedEdges() []graph.WeightedEdge { + var edges []graph.WeightedEdge + + seen := make(map[[2]int64]struct{}) + for _, u := range g.edges { + for _, e := range u { + uid := e.From().ID() + vid := e.To().ID() + if _, ok := seen[[2]int64{uid, vid}]; ok { + continue + } + seen[[2]int64{uid, vid}] = struct{}{} + seen[[2]int64{vid, uid}] = struct{}{} + edges = append(edges, e) + } + } + + return edges +} + +// From returns all nodes in g that can be reached directly from n. +func (g *WeightedUndirectedGraph) From(n graph.Node) []graph.Node { + if !g.Has(n) { + return nil + } + + nodes := make([]graph.Node, len(g.edges[n.ID()])) + i := 0 + for from := range g.edges[n.ID()] { + nodes[i] = g.nodes[from] + i++ + } + + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g *WeightedUndirectedGraph) HasEdgeBetween(x, y graph.Node) bool { + _, ok := g.edges[x.ID()][y.ID()] + return ok +} + +// Edge returns the edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *WeightedUndirectedGraph) Edge(u, v graph.Node) graph.Edge { + return g.WeightedEdgeBetween(u, v) +} + +// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise. +// The node v must be directly reachable from u as defined by the From method. +func (g *WeightedUndirectedGraph) WeightedEdge(u, v graph.Node) graph.WeightedEdge { + return g.WeightedEdgeBetween(u, v) +} + +// EdgeBetween returns the edge between nodes x and y. +func (g *WeightedUndirectedGraph) EdgeBetween(x, y graph.Node) graph.Edge { + return g.WeightedEdgeBetween(x, y) +} + +// WeightedEdgeBetween returns the weighted edge between nodes x and y. +func (g *WeightedUndirectedGraph) WeightedEdgeBetween(x, y graph.Node) graph.WeightedEdge { + // We don't need to check if neigh exists because + // it's implicit in the edges access. + if !g.Has(x) { + return nil + } + + return g.edges[x.ID()][y.ID()] +} + +// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge. +// If x and y are the same node or there is no joining edge between the two nodes the weight +// value returned is either the graph's absent or self value. Weight returns true if an edge +// exists between x and y or if x and y have the same ID, false otherwise. +func (g *WeightedUndirectedGraph) Weight(x, y graph.Node) (w float64, ok bool) { + xid := x.ID() + yid := y.ID() + if xid == yid { + return g.self, true + } + if n, ok := g.edges[xid]; ok { + if e, ok := n[yid]; ok { + return e.Weight(), true + } + } + return g.absent, false +} + +// Degree returns the degree of n in g. +func (g *WeightedUndirectedGraph) Degree(n graph.Node) int { + if _, ok := g.nodes[n.ID()]; !ok { + return 0 + } + + return len(g.edges[n.ID()]) +} diff --git a/vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected_test.go b/vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected_test.go new file mode 100644 index 00000000..a3796ee3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected_test.go @@ -0,0 +1,69 @@ +// 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" + "testing" + + "gonum.org/v1/gonum/graph" +) + +var ( + weightedUndirectedGraph = (*WeightedUndirectedGraph)(nil) + + _ graph.Graph = weightedUndirectedGraph + _ graph.Undirected = weightedUndirectedGraph + _ graph.WeightedUndirected = weightedUndirectedGraph +) + +func TestAssertWeightedMutableNotDirected(t *testing.T) { + var g graph.UndirectedWeightedBuilder = NewWeightedUndirectedGraph(0, math.Inf(1)) + if _, ok := g.(graph.Directed); ok { + t.Fatal("Graph is directed, but a MutableGraph cannot safely be directed!") + } +} + +func TestWeightedMaxID(t *testing.T) { + g := NewWeightedUndirectedGraph(0, math.Inf(1)) + nodes := make(map[graph.Node]struct{}) + for i := Node(0); i < 3; i++ { + g.AddNode(i) + nodes[i] = struct{}{} + } + g.RemoveNode(Node(0)) + delete(nodes, Node(0)) + g.RemoveNode(Node(2)) + delete(nodes, Node(2)) + n := g.NewNode() + g.AddNode(n) + if !g.Has(n) { + t.Error("added node does not exist in graph") + } + if _, exists := nodes[n]; exists { + t.Errorf("Created already existing node id: %v", n.ID()) + } +} + +// Test for issue #123 https://github.com/gonum/graph/issues/123 +func TestIssue123WeightedUndirectedGraph(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Errorf("unexpected panic: %v", r) + } + }() + g := NewWeightedUndirectedGraph(0, math.Inf(1)) + + n0 := g.NewNode() + g.AddNode(n0) + + n1 := g.NewNode() + g.AddNode(n1) + + g.RemoveNode(n0) + + n2 := g.NewNode() + g.AddNode(n2) +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/bench_test.go b/vendor/gonum.org/v1/gonum/graph/topo/bench_test.go new file mode 100644 index 00000000..7b2bdc3e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/bench_test.go @@ -0,0 +1,57 @@ +// 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 topo + +import ( + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/graphs/gen" + "gonum.org/v1/gonum/graph/simple" +) + +var ( + gnpDirected_10_tenth = gnpDirected(10, 0.1) + gnpDirected_100_tenth = gnpDirected(100, 0.1) + gnpDirected_1000_tenth = gnpDirected(1000, 0.1) + gnpDirected_10_half = gnpDirected(10, 0.5) + gnpDirected_100_half = gnpDirected(100, 0.5) + gnpDirected_1000_half = gnpDirected(1000, 0.5) +) + +func gnpDirected(n int, p float64) graph.Directed { + g := simple.NewDirectedGraph() + gen.Gnp(g, n, p, nil) + return g +} + +func benchmarkTarjanSCC(b *testing.B, g graph.Directed) { + var sccs [][]graph.Node + for i := 0; i < b.N; i++ { + sccs = TarjanSCC(g) + } + if len(sccs) == 0 { + b.Fatal("unexpected number zero-sized SCC set") + } +} + +func BenchmarkTarjanSCCGnp_10_tenth(b *testing.B) { + benchmarkTarjanSCC(b, gnpDirected_10_tenth) +} +func BenchmarkTarjanSCCGnp_100_tenth(b *testing.B) { + benchmarkTarjanSCC(b, gnpDirected_100_tenth) +} +func BenchmarkTarjanSCCGnp_1000_tenth(b *testing.B) { + benchmarkTarjanSCC(b, gnpDirected_1000_tenth) +} +func BenchmarkTarjanSCCGnp_10_half(b *testing.B) { + benchmarkTarjanSCC(b, gnpDirected_10_half) +} +func BenchmarkTarjanSCCGnp_100_half(b *testing.B) { + benchmarkTarjanSCC(b, gnpDirected_100_half) +} +func BenchmarkTarjanSCCGnp_1000_half(b *testing.B) { + benchmarkTarjanSCC(b, gnpDirected_1000_half) +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch.go b/vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch.go new file mode 100644 index 00000000..9c478056 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch.go @@ -0,0 +1,225 @@ +// 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 topo + +import ( + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/set" +) + +// VertexOrdering returns the vertex ordering and the k-cores of +// the undirected graph g. +func VertexOrdering(g graph.Undirected) (order []graph.Node, cores [][]graph.Node) { + nodes := g.Nodes() + + // The algorithm used here is essentially as described at + // http://en.wikipedia.org/w/index.php?title=Degeneracy_%28graph_theory%29&oldid=640308710 + + // Initialize an output list L. + var l []graph.Node + + // Compute a number d_v for each vertex v in G, + // the number of neighbors of v that are not already in L. + // Initially, these numbers are just the degrees of the vertices. + dv := make(map[int64]int, len(nodes)) + var ( + maxDegree int + neighbours = make(map[int64][]graph.Node) + ) + for _, n := range nodes { + adj := g.From(n) + neighbours[n.ID()] = adj + dv[n.ID()] = len(adj) + if len(adj) > maxDegree { + maxDegree = len(adj) + } + } + + // Initialize an array D such that D[i] contains a list of the + // vertices v that are not already in L for which d_v = i. + d := make([][]graph.Node, maxDegree+1) + for _, n := range nodes { + deg := dv[n.ID()] + d[deg] = append(d[deg], n) + } + + // Initialize k to 0. + k := 0 + // Repeat n times: + s := []int{0} + for range nodes { + // Scan the array cells D[0], D[1], ... until + // finding an i for which D[i] is nonempty. + var ( + i int + di []graph.Node + ) + for i, di = range d { + if len(di) != 0 { + break + } + } + + // Set k to max(k,i). + if i > k { + k = i + s = append(s, make([]int, k-len(s)+1)...) + } + + // Select a vertex v from D[i]. Add v to the + // beginning of L and remove it from D[i]. + var v graph.Node + v, d[i] = di[len(di)-1], di[:len(di)-1] + l = append(l, v) + s[k]++ + delete(dv, v.ID()) + + // For each neighbor w of v not already in L, + // subtract one from d_w and move w to the + // cell of D corresponding to the new value of d_w. + for _, w := range neighbours[v.ID()] { + dw, ok := dv[w.ID()] + if !ok { + continue + } + for i, n := range d[dw] { + if n.ID() == w.ID() { + d[dw][i], d[dw] = d[dw][len(d[dw])-1], d[dw][:len(d[dw])-1] + dw-- + d[dw] = append(d[dw], w) + break + } + } + dv[w.ID()] = dw + } + } + + for i, j := 0, len(l)-1; i < j; i, j = i+1, j-1 { + l[i], l[j] = l[j], l[i] + } + cores = make([][]graph.Node, len(s)) + offset := len(l) + for i, n := range s { + cores[i] = l[offset-n : offset] + offset -= n + } + return l, cores +} + +// BronKerbosch returns the set of maximal cliques of the undirected graph g. +func BronKerbosch(g graph.Undirected) [][]graph.Node { + nodes := g.Nodes() + + // The algorithm used here is essentially BronKerbosch3 as described at + // http://en.wikipedia.org/w/index.php?title=Bron%E2%80%93Kerbosch_algorithm&oldid=656805858 + + p := make(set.Nodes, len(nodes)) + for _, n := range nodes { + p.Add(n) + } + x := make(set.Nodes) + var bk bronKerbosch + order, _ := VertexOrdering(g) + for _, v := range order { + neighbours := g.From(v) + nv := make(set.Nodes, len(neighbours)) + for _, n := range neighbours { + nv.Add(n) + } + bk.maximalCliquePivot(g, []graph.Node{v}, make(set.Nodes).Intersect(p, nv), make(set.Nodes).Intersect(x, nv)) + p.Remove(v) + x.Add(v) + } + return bk +} + +type bronKerbosch [][]graph.Node + +func (bk *bronKerbosch) maximalCliquePivot(g graph.Undirected, r []graph.Node, p, x set.Nodes) { + if len(p) == 0 && len(x) == 0 { + *bk = append(*bk, r) + return + } + + neighbours := bk.choosePivotFrom(g, p, x) + nu := make(set.Nodes, len(neighbours)) + for _, n := range neighbours { + nu.Add(n) + } + for _, v := range p { + if nu.Has(v) { + continue + } + neighbours := g.From(v) + nv := make(set.Nodes, len(neighbours)) + for _, n := range neighbours { + nv.Add(n) + } + + var found bool + for _, n := range r { + if n.ID() == v.ID() { + found = true + break + } + } + var sr []graph.Node + if !found { + sr = append(r[:len(r):len(r)], v) + } + + bk.maximalCliquePivot(g, sr, make(set.Nodes).Intersect(p, nv), make(set.Nodes).Intersect(x, nv)) + p.Remove(v) + x.Add(v) + } +} + +func (*bronKerbosch) choosePivotFrom(g graph.Undirected, p, x set.Nodes) (neighbors []graph.Node) { + // TODO(kortschak): Investigate the impact of pivot choice that maximises + // |p ⋂ neighbours(u)| as a function of input size. Until then, leave as + // compile time option. + if !tomitaTanakaTakahashi { + for _, n := range p { + return g.From(n) + } + for _, n := range x { + return g.From(n) + } + panic("bronKerbosch: empty set") + } + + var ( + max = -1 + pivot graph.Node + ) + maxNeighbors := func(s set.Nodes) { + outer: + for _, u := range s { + nb := g.From(u) + c := len(nb) + if c <= max { + continue + } + for n := range nb { + if _, ok := p[int64(n)]; ok { + continue + } + c-- + if c <= max { + continue outer + } + } + max = c + pivot = u + neighbors = nb + } + } + maxNeighbors(p) + maxNeighbors(x) + if pivot == nil { + panic("bronKerbosch: empty set") + } + return neighbors +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch_test.go b/vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch_test.go new file mode 100644 index 00000000..8fdb67c0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch_test.go @@ -0,0 +1,163 @@ +// 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 topo + +import ( + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +var vOrderTests = []struct { + g []intset + wantCore [][]int64 + wantK int +}{ + { + g: []intset{ + 0: linksTo(1, 2, 4, 6), + 1: linksTo(2, 4, 6), + 2: linksTo(3, 6), + 3: linksTo(4, 5), + 4: linksTo(6), + 5: nil, + 6: nil, + }, + wantCore: [][]int64{ + {}, + {5}, + {3}, + {0, 1, 2, 4, 6}, + }, + wantK: 3, + }, + { + g: batageljZaversnikGraph, + wantCore: [][]int64{ + {0}, + {5, 9, 10, 16}, + {1, 2, 3, 4, 11, 12, 13, 15}, + {6, 7, 8, 14, 17, 18, 19, 20}, + }, + wantK: 3, + }, +} + +func TestVertexOrdering(t *testing.T) { + for i, test := range vOrderTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + order, core := VertexOrdering(g) + if len(core)-1 != test.wantK { + t.Errorf("unexpected value of k for test %d: got: %d want: %d", i, len(core)-1, test.wantK) + } + var offset int + for k, want := range test.wantCore { + sort.Sort(ordered.Int64s(want)) + got := make([]int64, len(want)) + for j, n := range order[len(order)-len(want)-offset : len(order)-offset] { + got[j] = n.ID() + } + sort.Sort(ordered.Int64s(got)) + if !reflect.DeepEqual(got, want) { + t.Errorf("unexpected %d-core for test %d:\ngot: %v\nwant:%v", k, i, got, test.wantCore) + } + + for j, n := range core[k] { + got[j] = n.ID() + } + sort.Sort(ordered.Int64s(got)) + if !reflect.DeepEqual(got, want) { + t.Errorf("unexpected %d-core for test %d:\ngot: %v\nwant:%v", k, i, got, test.wantCore) + } + offset += len(want) + } + } +} + +var bronKerboschTests = []struct { + g []intset + want [][]int64 +}{ + { + // This is the example given in the Bron-Kerbosch article on wikipedia (renumbered). + // http://en.wikipedia.org/w/index.php?title=Bron%E2%80%93Kerbosch_algorithm&oldid=656805858 + g: []intset{ + 0: linksTo(1, 4), + 1: linksTo(2, 4), + 2: linksTo(3), + 3: linksTo(4, 5), + 4: nil, + 5: nil, + }, + want: [][]int64{ + {0, 1, 4}, + {1, 2}, + {2, 3}, + {3, 4}, + {3, 5}, + }, + }, + { + g: batageljZaversnikGraph, + want: [][]int64{ + {0}, + {1, 2}, + {1, 3}, + {2, 4}, + {3, 4}, + {4, 5}, + {6, 7, 8, 14}, + {7, 11, 12}, + {9, 11}, + {10, 11}, + {12, 18}, + {13, 14, 15}, + {14, 15, 17}, + {15, 16}, + {17, 18, 19, 20}, + }, + }, +} + +func TestBronKerbosch(t *testing.T) { + for i, test := range bronKerboschTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + cliques := BronKerbosch(g) + got := make([][]int64, len(cliques)) + for j, c := range cliques { + ids := make([]int64, len(c)) + for k, n := range c { + ids[k] = n.ID() + } + sort.Sort(ordered.Int64s(ids)) + got[j] = ids + } + sort.Sort(ordered.BySliceValues(got)) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexpected cliques for test %d:\ngot: %v\nwant:%v", i, got, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/common_test.go b/vendor/gonum.org/v1/gonum/graph/topo/common_test.go new file mode 100644 index 00000000..6b09e78b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/common_test.go @@ -0,0 +1,47 @@ +// 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 topo + +// batageljZaversnikGraph is the example graph from +// figure 1 of http://arxiv.org/abs/cs/0310049v1 +var batageljZaversnikGraph = []intset{ + 0: nil, + + 1: linksTo(2, 3), + 2: linksTo(4), + 3: linksTo(4), + 4: linksTo(5), + 5: nil, + + 6: linksTo(7, 8, 14), + 7: linksTo(8, 11, 12, 14), + 8: linksTo(14), + 9: linksTo(11), + 10: linksTo(11), + 11: linksTo(12), + 12: linksTo(18), + 13: linksTo(14, 15), + 14: linksTo(15, 17), + 15: linksTo(16, 17), + 16: nil, + 17: linksTo(18, 19, 20), + 18: linksTo(19, 20), + 19: linksTo(20), + 20: nil, +} + +// intset is an integer set. +type intset map[int64]struct{} + +func linksTo(i ...int64) intset { + if len(i) == 0 { + return nil + } + s := make(intset) + for _, v := range i { + s[v] = struct{}{} + } + return s +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/doc.go b/vendor/gonum.org/v1/gonum/graph/topo/doc.go new file mode 100644 index 00000000..ba1bf552 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package topo provides graph topology analysis functions. +package topo // import "gonum.org/v1/gonum/graph/topo" diff --git a/vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles.go b/vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles.go new file mode 100644 index 00000000..de84cf9c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles.go @@ -0,0 +1,280 @@ +// 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 topo + +import ( + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/internal/set" +) + +// johnson implements Johnson's "Finding all the elementary +// circuits of a directed graph" algorithm. SIAM J. Comput. 4(1):1975. +// +// Comments in the johnson methods are kept in sync with the comments +// and labels from the paper. +type johnson struct { + adjacent johnsonGraph // SCC adjacency list. + b []set.Ints // Johnson's "B-list". + blocked []bool + s int + + stack []graph.Node + + result [][]graph.Node +} + +// DirectedCyclesIn returns the set of elementary cycles in the graph g. +func DirectedCyclesIn(g graph.Directed) [][]graph.Node { + jg := johnsonGraphFrom(g) + j := johnson{ + adjacent: jg, + b: make([]set.Ints, len(jg.orig)), + blocked: make([]bool, len(jg.orig)), + } + + // len(j.nodes) is the order of g. + for j.s < len(j.adjacent.orig)-1 { + // We use the previous SCC adjacency to reduce the work needed. + sccs := TarjanSCC(j.adjacent.subgraph(j.s)) + // A_k = adjacency structure of strong component K with least + // vertex in subgraph of G induced by {s, s+1, ... ,n}. + j.adjacent = j.adjacent.sccSubGraph(sccs, 2) // Only allow SCCs with >= 2 vertices. + if j.adjacent.order() == 0 { + break + } + + // s = least vertex in V_k + if s := j.adjacent.leastVertexIndex(); s < j.s { + j.s = s + } + for i, v := range j.adjacent.orig { + if !j.adjacent.nodes.Has(v.ID()) { + continue + } + if len(j.adjacent.succ[v.ID()]) > 0 { + j.blocked[i] = false + j.b[i] = make(set.Ints) + } + } + //L3: + _ = j.circuit(j.s) + j.s++ + } + + return j.result +} + +// circuit is the CIRCUIT sub-procedure in the paper. +func (j *johnson) circuit(v int) bool { + f := false + n := j.adjacent.orig[v] + j.stack = append(j.stack, n) + j.blocked[v] = true + + //L1: + for w := range j.adjacent.succ[n.ID()] { + w := j.adjacent.indexOf(w) + if w == j.s { + // Output circuit composed of stack followed by s. + r := make([]graph.Node, len(j.stack)+1) + copy(r, j.stack) + r[len(r)-1] = j.adjacent.orig[j.s] + j.result = append(j.result, r) + f = true + } else if !j.blocked[w] { + if j.circuit(w) { + f = true + } + } + } + + //L2: + if f { + j.unblock(v) + } else { + for w := range j.adjacent.succ[n.ID()] { + j.b[j.adjacent.indexOf(w)].Add(v) + } + } + j.stack = j.stack[:len(j.stack)-1] + + return f +} + +// unblock is the UNBLOCK sub-procedure in the paper. +func (j *johnson) unblock(u int) { + j.blocked[u] = false + for w := range j.b[u] { + j.b[u].Remove(w) + if j.blocked[w] { + j.unblock(w) + } + } +} + +// johnsonGraph is an edge list representation of a graph with helpers +// necessary for Johnson's algorithm +type johnsonGraph struct { + // Keep the original graph nodes and a + // look-up to into the non-sparse + // collection of potentially sparse IDs. + orig []graph.Node + index map[int64]int + + nodes set.Int64s + succ map[int64]set.Int64s +} + +// johnsonGraphFrom returns a deep copy of the graph g. +func johnsonGraphFrom(g graph.Directed) johnsonGraph { + nodes := g.Nodes() + sort.Sort(ordered.ByID(nodes)) + c := johnsonGraph{ + orig: nodes, + index: make(map[int64]int, len(nodes)), + + nodes: make(set.Int64s, len(nodes)), + succ: make(map[int64]set.Int64s), + } + for i, u := range nodes { + c.index[u.ID()] = i + for _, v := range g.From(u) { + if c.succ[u.ID()] == nil { + c.succ[u.ID()] = make(set.Int64s) + c.nodes.Add(u.ID()) + } + c.nodes.Add(v.ID()) + c.succ[u.ID()].Add(v.ID()) + } + } + return c +} + +// order returns the order of the graph. +func (g johnsonGraph) order() int { return g.nodes.Count() } + +// indexOf returns the index of the retained node for the given node ID. +func (g johnsonGraph) indexOf(id int64) int { + return g.index[id] +} + +// leastVertexIndex returns the index into orig of the least vertex. +func (g johnsonGraph) leastVertexIndex() int { + for _, v := range g.orig { + if g.nodes.Has(v.ID()) { + return g.indexOf(v.ID()) + } + } + panic("johnsonCycles: empty set") +} + +// subgraph returns a subgraph of g induced by {s, s+1, ... , n}. The +// subgraph is destructively generated in g. +func (g johnsonGraph) subgraph(s int) johnsonGraph { + sn := g.orig[s].ID() + for u, e := range g.succ { + if u < sn { + g.nodes.Remove(u) + delete(g.succ, u) + continue + } + for v := range e { + if v < sn { + g.succ[u].Remove(v) + } + } + } + return g +} + +// sccSubGraph returns the graph of the tarjan's strongly connected +// components with each SCC containing at least min vertices. +// sccSubGraph returns nil if there is no SCC with at least min +// members. +func (g johnsonGraph) sccSubGraph(sccs [][]graph.Node, min int) johnsonGraph { + if len(g.nodes) == 0 { + g.nodes = nil + g.succ = nil + return g + } + sub := johnsonGraph{ + orig: g.orig, + index: g.index, + nodes: make(set.Int64s), + succ: make(map[int64]set.Int64s), + } + + var n int + for _, scc := range sccs { + if len(scc) < min { + continue + } + n++ + for _, u := range scc { + for _, v := range scc { + if _, ok := g.succ[u.ID()][v.ID()]; ok { + if sub.succ[u.ID()] == nil { + sub.succ[u.ID()] = make(set.Int64s) + sub.nodes.Add(u.ID()) + } + sub.nodes.Add(v.ID()) + sub.succ[u.ID()].Add(v.ID()) + } + } + } + } + if n == 0 { + g.nodes = nil + g.succ = nil + return g + } + + return sub +} + +// Nodes is required to satisfy Tarjan. +func (g johnsonGraph) Nodes() []graph.Node { + n := make([]graph.Node, 0, len(g.nodes)) + for id := range g.nodes { + n = append(n, johnsonGraphNode(id)) + } + return n +} + +// Successors is required to satisfy Tarjan. +func (g johnsonGraph) From(n graph.Node) []graph.Node { + adj := g.succ[n.ID()] + if len(adj) == 0 { + return nil + } + succ := make([]graph.Node, 0, len(adj)) + for n := range adj { + succ = append(succ, johnsonGraphNode(n)) + } + return succ +} + +func (johnsonGraph) Has(graph.Node) bool { + panic("topo: unintended use of johnsonGraph") +} +func (johnsonGraph) HasEdgeBetween(_, _ graph.Node) bool { + panic("topo: unintended use of johnsonGraph") +} +func (johnsonGraph) Edge(_, _ graph.Node) graph.Edge { + panic("topo: unintended use of johnsonGraph") +} +func (johnsonGraph) HasEdgeFromTo(_, _ graph.Node) bool { + panic("topo: unintended use of johnsonGraph") +} +func (johnsonGraph) To(graph.Node) []graph.Node { + panic("topo: unintended use of johnsonGraph") +} + +type johnsonGraphNode int64 + +func (n johnsonGraphNode) ID() int64 { return int64(n) } diff --git a/vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles_test.go b/vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles_test.go new file mode 100644 index 00000000..bf53120d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles_test.go @@ -0,0 +1,117 @@ +// 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 topo + +import ( + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +var cyclesInTests = []struct { + g []intset + want [][]int64 +}{ + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 7), + 2: linksTo(3, 6), + 3: linksTo(4), + 4: linksTo(2, 5), + 6: linksTo(3, 5), + 7: linksTo(0, 6), + }, + want: [][]int64{ + {0, 1, 7, 0}, + {2, 3, 4, 2}, + {2, 6, 3, 4, 2}, + }, + }, + { + g: []intset{ + 0: linksTo(1, 2, 3), + 1: linksTo(2), + 2: linksTo(3), + 3: linksTo(1), + }, + want: [][]int64{ + {1, 2, 3, 1}, + }, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(0, 2), + 2: linksTo(1), + }, + want: [][]int64{ + {0, 1, 0}, + {1, 2, 1}, + }, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 3), + 2: linksTo(4, 5), + 3: linksTo(4, 5), + 4: linksTo(6), + 5: nil, + 6: nil, + }, + want: nil, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 3, 4), + 2: linksTo(0, 3), + 3: linksTo(4), + 4: linksTo(3), + }, + want: [][]int64{ + {0, 1, 2, 0}, + {3, 4, 3}, + }, + }, +} + +func TestDirectedCyclesIn(t *testing.T) { + for i, test := range cyclesInTests { + g := simple.NewDirectedGraph() + g.AddNode(simple.Node(-10)) // Make sure we test graphs with sparse IDs. + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + cycles := DirectedCyclesIn(g) + var got [][]int64 + if cycles != nil { + got = make([][]int64, len(cycles)) + } + // johnson.circuit does range iteration over maps, + // so sort to ensure consistent ordering. + for j, c := range cycles { + ids := make([]int64, len(c)) + for k, n := range c { + ids[k] = n.ID() + } + got[j] = ids + } + sort.Sort(ordered.BySliceValues(got)) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexpected johnson result for %d:\n\tgot:%#v\n\twant:%#v", i, got, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/non_tomita_choice.go b/vendor/gonum.org/v1/gonum/graph/topo/non_tomita_choice.go new file mode 100644 index 00000000..de09ebd8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/non_tomita_choice.go @@ -0,0 +1,9 @@ +// 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. + +//+build !tomita + +package topo + +const tomitaTanakaTakahashi = false diff --git a/vendor/gonum.org/v1/gonum/graph/topo/paton_cycles.go b/vendor/gonum.org/v1/gonum/graph/topo/paton_cycles.go new file mode 100644 index 00000000..d012ecaa --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/paton_cycles.go @@ -0,0 +1,81 @@ +// 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 topo + +import ( + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/linear" + "gonum.org/v1/gonum/graph/internal/set" +) + +// UndirectedCyclesIn returns a set of cycles that forms a cycle basis in the graph g. +// Any cycle in g can be constructed as a symmetric difference of its elements. +func UndirectedCyclesIn(g graph.Undirected) [][]graph.Node { + // From "An algorithm for finding a fundamental set of cycles of a graph" + // https://doi.org/10.1145/363219.363232 + + var cycles [][]graph.Node + done := make(set.Int64s) + var tree linear.NodeStack + for _, n := range g.Nodes() { + id := n.ID() + if done.Has(id) { + continue + } + done.Add(id) + + tree = tree[:0] + tree.Push(n) + from := sets{id: set.Int64s{}} + to := map[int64]graph.Node{id: n} + + for tree.Len() != 0 { + u := tree.Pop() + uid := u.ID() + adj := from[uid] + for _, v := range g.From(u) { + vid := v.ID() + switch { + case uid == vid: + cycles = append(cycles, []graph.Node{u}) + case !from.has(vid): + done.Add(vid) + to[vid] = u + tree.Push(v) + from.add(uid, vid) + case !adj.Has(vid): + c := []graph.Node{v, u} + adj := from[vid] + p := to[uid] + for !adj.Has(p.ID()) { + c = append(c, p) + p = to[p.ID()] + } + c = append(c, p, c[0]) + cycles = append(cycles, c) + adj.Add(uid) + } + } + } + } + + return cycles +} + +type sets map[int64]set.Int64s + +func (s sets) add(uid, vid int64) { + e, ok := s[vid] + if !ok { + e = make(set.Int64s) + s[vid] = e + } + e.Add(uid) +} + +func (s sets) has(uid int64) bool { + _, ok := s[uid] + return ok +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/paton_cycles_test.go b/vendor/gonum.org/v1/gonum/graph/topo/paton_cycles_test.go new file mode 100644 index 00000000..c36590be --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/paton_cycles_test.go @@ -0,0 +1,143 @@ +// 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 topo + +import ( + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +var undirectedCyclesInTests = []struct { + g []intset + want [][][]int64 +}{ + { + g: []intset{ + 0: linksTo(1, 2), + 1: linksTo(2, 4, 5, 9), + 2: linksTo(4, 7, 9), + 3: linksTo(5), + 4: linksTo(8), + 5: linksTo(7, 8), + 6: nil, + 7: nil, + 8: nil, + 9: nil, + 10: linksTo(11, 12), + 11: linksTo(12), + 12: nil, + }, + want: [][][]int64{ + { + {0, 1, 2, 0}, + {1, 2, 7, 5, 1}, + {1, 2, 9, 1}, + {1, 4, 8, 5, 1}, + {2, 4, 8, 5, 7, 2}, + {10, 11, 12, 10}, + }, + { + {0, 1, 2, 0}, + {1, 2, 4, 1}, + {1, 2, 7, 5, 1}, + {1, 2, 9, 1}, + {1, 4, 8, 5, 1}, + {10, 11, 12, 10}, + }, + { + {0, 1, 2, 0}, + {1, 2, 4, 1}, + {1, 2, 9, 1}, + {1, 4, 8, 5, 1}, + {2, 4, 8, 5, 7, 2}, + {10, 11, 12, 10}, + }, + { + {0, 1, 2, 0}, + {1, 2, 4, 1}, + {1, 2, 7, 5, 1}, + {1, 2, 9, 1}, + {2, 4, 8, 5, 7, 2}, + {10, 11, 12, 10}, + }, + }, + }, +} + +func TestUndirectedCyclesIn(t *testing.T) { + for i, test := range undirectedCyclesInTests { + g := simple.NewUndirectedGraph() + g.AddNode(simple.Node(-10)) // Make sure we test graphs with sparse IDs. + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + cycles := UndirectedCyclesIn(g) + var got [][]int64 + if cycles != nil { + got = make([][]int64, len(cycles)) + } + // Canonicalise the cycles. + for j, c := range cycles { + ids := make([]int64, len(c)) + for k, n := range canonicalise(c[:len(c)-1]) { + ids[k] = n.ID() + } + ids[len(ids)-1] = ids[0] + got[j] = ids + } + sort.Sort(ordered.BySliceValues(got)) + var matched bool + for _, want := range test.want { + if reflect.DeepEqual(got, want) { + matched = true + break + } + } + if !matched { + t.Errorf("unexpected paton result for %d:\n\tgot:%#v\n\twant from:%#v", i, got, test.want) + } + } +} + +// canonicalise returns the cycle path c cyclicly permuted such that +// the first element has the lowest ID and then conditionally +// reversed so that the second element has the lowest possible +// neighbouring ID. +// c lists each node only onces - the final node must not be a +// reiteration of the first node. +func canonicalise(c []graph.Node) []graph.Node { + if len(c) < 2 { + return c + } + idx := 0 + min := c[0].ID() + for i, n := range c[1:] { + if id := n.ID(); id < min { + idx = i + 1 + min = id + } + } + if idx != 0 { + c = append(c[idx:], c[:idx]...) + } + if c[len(c)-1].ID() < c[1].ID() { + s := c[1:] + for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + } + return c +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/tarjan.go b/vendor/gonum.org/v1/gonum/graph/topo/tarjan.go new file mode 100644 index 00000000..cd5d6a86 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/tarjan.go @@ -0,0 +1,203 @@ +// 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 topo + +import ( + "fmt" + "sort" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/internal/set" +) + +// Unorderable is an error containing sets of unorderable graph.Nodes. +type Unorderable [][]graph.Node + +// Error satisfies the error interface. +func (e Unorderable) Error() string { + const maxNodes = 10 + var n int + for _, c := range e { + n += len(c) + } + if n > maxNodes { + // Don't return errors that are too long. + return fmt.Sprintf("topo: no topological ordering: %d nodes in %d cyclic components", n, len(e)) + } + return fmt.Sprintf("topo: no topological ordering: cyclic components: %v", [][]graph.Node(e)) +} + +func lexical(nodes []graph.Node) { sort.Sort(ordered.ByID(nodes)) } + +// Sort performs a topological sort of the directed graph g returning the 'from' to 'to' +// sort order. If a topological ordering is not possible, an Unorderable error is returned +// listing cyclic components in g with each cyclic component's members sorted by ID. When +// an Unorderable error is returned, each cyclic component's topological position within +// the sorted nodes is marked with a nil graph.Node. +func Sort(g graph.Directed) (sorted []graph.Node, err error) { + sccs := TarjanSCC(g) + return sortedFrom(sccs, lexical) +} + +// SortStabilized performs a topological sort of the directed graph g returning the 'from' +// to 'to' sort order, or the order defined by the in place order sort function where there +// is no unambiguous topological ordering. If a topological ordering is not possible, an +// Unorderable error is returned listing cyclic components in g with each cyclic component's +// members sorted by the provided order function. If order is nil, nodes are ordered lexically +// by node ID. When an Unorderable error is returned, each cyclic component's topological +// position within the sorted nodes is marked with a nil graph.Node. +func SortStabilized(g graph.Directed, order func([]graph.Node)) (sorted []graph.Node, err error) { + if order == nil { + order = lexical + } + sccs := tarjanSCCstabilized(g, order) + return sortedFrom(sccs, order) +} + +func sortedFrom(sccs [][]graph.Node, order func([]graph.Node)) ([]graph.Node, error) { + sorted := make([]graph.Node, 0, len(sccs)) + var sc Unorderable + for _, s := range sccs { + if len(s) != 1 { + order(s) + sc = append(sc, s) + sorted = append(sorted, nil) + continue + } + sorted = append(sorted, s[0]) + } + var err error + if sc != nil { + for i, j := 0, len(sc)-1; i < j; i, j = i+1, j-1 { + sc[i], sc[j] = sc[j], sc[i] + } + err = sc + } + reverse(sorted) + return sorted, err +} + +func reverse(p []graph.Node) { + for i, j := 0, len(p)-1; i < j; i, j = i+1, j-1 { + p[i], p[j] = p[j], p[i] + } +} + +// TarjanSCC returns the strongly connected components of the graph g using Tarjan's algorithm. +// +// A strongly connected component of a graph is a set of vertices where it's possible to reach any +// vertex in the set from any other (meaning there's a cycle between them.) +// +// Generally speaking, a directed graph where the number of strongly connected components is equal +// to the number of nodes is acyclic, unless you count reflexive edges as a cycle (which requires +// only a little extra testing.) +// +func TarjanSCC(g graph.Directed) [][]graph.Node { + return tarjanSCCstabilized(g, nil) +} + +func tarjanSCCstabilized(g graph.Directed, order func([]graph.Node)) [][]graph.Node { + nodes := g.Nodes() + var succ func(graph.Node) []graph.Node + if order == nil { + succ = g.From + } else { + order(nodes) + reverse(nodes) + + succ = func(n graph.Node) []graph.Node { + to := g.From(n) + order(to) + reverse(to) + return to + } + } + + t := tarjan{ + succ: succ, + + indexTable: make(map[int64]int, len(nodes)), + lowLink: make(map[int64]int, len(nodes)), + onStack: make(set.Int64s), + } + for _, v := range nodes { + if t.indexTable[v.ID()] == 0 { + t.strongconnect(v) + } + } + return t.sccs +} + +// tarjan implements Tarjan's strongly connected component finding +// algorithm. The implementation is from the pseudocode at +// +// http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm?oldid=642744644 +// +type tarjan struct { + succ func(graph.Node) []graph.Node + + index int + indexTable map[int64]int + lowLink map[int64]int + onStack set.Int64s + + stack []graph.Node + + sccs [][]graph.Node +} + +// strongconnect is the strongconnect function described in the +// wikipedia article. +func (t *tarjan) strongconnect(v graph.Node) { + vID := v.ID() + + // Set the depth index for v to the smallest unused index. + t.index++ + t.indexTable[vID] = t.index + t.lowLink[vID] = t.index + t.stack = append(t.stack, v) + t.onStack.Add(vID) + + // Consider successors of v. + for _, w := range t.succ(v) { + wID := w.ID() + if t.indexTable[wID] == 0 { + // Successor w has not yet been visited; recur on it. + t.strongconnect(w) + t.lowLink[vID] = min(t.lowLink[vID], t.lowLink[wID]) + } else if t.onStack.Has(wID) { + // Successor w is in stack s and hence in the current SCC. + t.lowLink[vID] = min(t.lowLink[vID], t.indexTable[wID]) + } + } + + // If v is a root node, pop the stack and generate an SCC. + if t.lowLink[vID] == t.indexTable[vID] { + // Start a new strongly connected component. + var ( + scc []graph.Node + w graph.Node + ) + for { + w, t.stack = t.stack[len(t.stack)-1], t.stack[:len(t.stack)-1] + t.onStack.Remove(w.ID()) + // Add w to current strongly connected component. + scc = append(scc, w) + if w.ID() == vID { + break + } + } + // Output the current strongly connected component. + t.sccs = append(t.sccs, scc) + } +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/tarjan_test.go b/vendor/gonum.org/v1/gonum/graph/topo/tarjan_test.go new file mode 100644 index 00000000..8751c507 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/tarjan_test.go @@ -0,0 +1,308 @@ +// 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 topo + +import ( + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +type interval struct{ start, end int } + +var tarjanTests = []struct { + g []intset + + ambiguousOrder []interval + want [][]int64 + + sortedLength int + unorderableLength int + sortable bool +}{ + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 7), + 2: linksTo(3, 6), + 3: linksTo(4), + 4: linksTo(2, 5), + 6: linksTo(3, 5), + 7: linksTo(0, 6), + }, + + want: [][]int64{ + {5}, + {2, 3, 4, 6}, + {0, 1, 7}, + }, + + sortedLength: 1, + unorderableLength: 2, + sortable: false, + }, + { + g: []intset{ + 0: linksTo(1, 2, 3), + 1: linksTo(2), + 2: linksTo(3), + 3: linksTo(1), + }, + + want: [][]int64{ + {1, 2, 3}, + {0}, + }, + + sortedLength: 1, + unorderableLength: 1, + sortable: false, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(0, 2), + 2: linksTo(1), + }, + + want: [][]int64{ + {0, 1, 2}, + }, + + sortedLength: 0, + unorderableLength: 1, + sortable: false, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 3), + 2: linksTo(4, 5), + 3: linksTo(4, 5), + 4: linksTo(6), + 5: nil, + 6: nil, + }, + + // Node pairs (2, 3) and (4, 5) are not + // relatively orderable within each pair. + ambiguousOrder: []interval{ + {0, 3}, // This includes node 6 since it only needs to be before 4 in topo sort. + {3, 5}, + }, + want: [][]int64{ + {6}, {5}, {4}, {3}, {2}, {1}, {0}, + }, + + sortedLength: 7, + sortable: true, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 3, 4), + 2: linksTo(0, 3), + 3: linksTo(4), + 4: linksTo(3), + }, + + // SCCs are not relatively ordable. + ambiguousOrder: []interval{ + {0, 2}, + }, + want: [][]int64{ + {0, 1, 2}, + {3, 4}, + }, + + sortedLength: 0, + unorderableLength: 2, + sortable: false, + }, +} + +func TestSort(t *testing.T) { + for i, test := range tarjanTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + sorted, err := Sort(g) + var gotSortedLen int + for _, n := range sorted { + if n != nil { + gotSortedLen++ + } + } + if gotSortedLen != test.sortedLength { + t.Errorf("unexpected number of sortable nodes for test %d: got:%d want:%d", i, gotSortedLen, test.sortedLength) + } + if err == nil != test.sortable { + t.Errorf("unexpected sortability for test %d: got error: %v want: nil-error=%t", i, err, test.sortable) + } + if err != nil && len(err.(Unorderable)) != test.unorderableLength { + t.Errorf("unexpected number of unorderable nodes for test %d: got:%d want:%d", i, len(err.(Unorderable)), test.unorderableLength) + } + } +} + +func TestTarjanSCC(t *testing.T) { + for i, test := range tarjanTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + gotSCCs := TarjanSCC(g) + // tarjan.strongconnect does range iteration over maps, + // so sort SCC members to ensure consistent ordering. + gotIDs := make([][]int64, len(gotSCCs)) + for i, scc := range gotSCCs { + gotIDs[i] = make([]int64, len(scc)) + for j, id := range scc { + gotIDs[i][j] = id.ID() + } + sort.Sort(ordered.Int64s(gotIDs[i])) + } + for _, iv := range test.ambiguousOrder { + sort.Sort(ordered.BySliceValues(test.want[iv.start:iv.end])) + sort.Sort(ordered.BySliceValues(gotIDs[iv.start:iv.end])) + } + if !reflect.DeepEqual(gotIDs, test.want) { + t.Errorf("unexpected Tarjan scc result for %d:\n\tgot:%v\n\twant:%v", i, gotIDs, test.want) + } + } +} + +var stabilizedSortTests = []struct { + g []intset + + want []graph.Node + err error +}{ + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 7), + 2: linksTo(3, 6), + 3: linksTo(4), + 4: linksTo(2, 5), + 6: linksTo(3, 5), + 7: linksTo(0, 6), + }, + + want: []graph.Node{nil, nil, simple.Node(5)}, + err: Unorderable{ + {simple.Node(0), simple.Node(1), simple.Node(7)}, + {simple.Node(2), simple.Node(3), simple.Node(4), simple.Node(6)}, + }, + }, + { + g: []intset{ + 0: linksTo(1, 2, 3), + 1: linksTo(2), + 2: linksTo(3), + 3: linksTo(1), + }, + + want: []graph.Node{simple.Node(0), nil}, + err: Unorderable{ + {simple.Node(1), simple.Node(2), simple.Node(3)}, + }, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(0, 2), + 2: linksTo(1), + }, + + want: []graph.Node{nil}, + err: Unorderable{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + }, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 3), + 2: linksTo(4, 5), + 3: linksTo(4, 5), + 4: linksTo(6), + 5: nil, + 6: nil, + }, + + want: []graph.Node{simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(4), simple.Node(5), simple.Node(6)}, + err: nil, + }, + { + g: []intset{ + 0: linksTo(1), + 1: linksTo(2, 3, 4), + 2: linksTo(0, 3), + 3: linksTo(4), + 4: linksTo(3), + }, + + want: []graph.Node{nil, nil}, + err: Unorderable{ + {simple.Node(0), simple.Node(1), simple.Node(2)}, + {simple.Node(3), simple.Node(4)}, + }, + }, + { + g: []intset{ + 0: linksTo(1, 2, 3, 4, 5, 6), + 1: linksTo(7), + 2: linksTo(7), + 3: linksTo(7), + 4: linksTo(7), + 5: linksTo(7), + 6: linksTo(7), + 7: nil, + }, + + want: []graph.Node{simple.Node(0), simple.Node(1), simple.Node(2), simple.Node(3), simple.Node(4), simple.Node(5), simple.Node(6), simple.Node(7)}, + err: nil, + }, +} + +func TestSortStabilized(t *testing.T) { + for i, test := range stabilizedSortTests { + g := simple.NewDirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + got, err := SortStabilized(g, nil) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexpected sort result for test %d: got:%d want:%d", i, got, test.want) + } + if !reflect.DeepEqual(err, test.err) { + t.Errorf("unexpected sort error for test %d: got:%v want:%v", i, err, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/tomita_choice.go b/vendor/gonum.org/v1/gonum/graph/topo/tomita_choice.go new file mode 100644 index 00000000..d4eca625 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/tomita_choice.go @@ -0,0 +1,9 @@ +// 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. + +//+build tomita + +package topo + +const tomitaTanakaTakahashi = true diff --git a/vendor/gonum.org/v1/gonum/graph/topo/topo.go b/vendor/gonum.org/v1/gonum/graph/topo/topo.go new file mode 100644 index 00000000..fe55f428 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/topo.go @@ -0,0 +1,68 @@ +// 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 topo + +import ( + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/traverse" +) + +// IsPathIn returns whether path is a path in g. +// +// As special cases, IsPathIn returns true for a zero length path or for +// a path of length 1 when the node in path exists in the graph. +func IsPathIn(g graph.Graph, path []graph.Node) bool { + switch len(path) { + case 0: + return true + case 1: + return g.Has(path[0]) + default: + var canReach func(u, v graph.Node) bool + switch g := g.(type) { + case graph.Directed: + canReach = g.HasEdgeFromTo + default: + canReach = g.HasEdgeBetween + } + + for i, u := range path[:len(path)-1] { + if !canReach(u, path[i+1]) { + return false + } + } + return true + } +} + +// PathExistsIn returns whether there is a path in g starting at from extending +// to to. +// +// PathExistsIn exists as a helper function. If many tests for path existence +// are being performed, other approaches will be more efficient. +func PathExistsIn(g graph.Graph, from, to graph.Node) bool { + var t traverse.BreadthFirst + return t.Walk(g, from, func(n graph.Node, _ int) bool { return n.ID() == to.ID() }) != nil +} + +// ConnectedComponents returns the connected components of the undirected graph g. +func ConnectedComponents(g graph.Undirected) [][]graph.Node { + var ( + w traverse.DepthFirst + c []graph.Node + cc [][]graph.Node + ) + during := func(n graph.Node) { + c = append(c, n) + } + after := func() { + cc = append(cc, []graph.Node(nil)) + cc[len(cc)-1] = append(cc[len(cc)-1], c...) + c = c[:0] + } + w.WalkAll(g, nil, after, during) + + return cc +} diff --git a/vendor/gonum.org/v1/gonum/graph/topo/topo_test.go b/vendor/gonum.org/v1/gonum/graph/topo/topo_test.go new file mode 100644 index 00000000..bb75796d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/topo/topo_test.go @@ -0,0 +1,175 @@ +// 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 topo + +import ( + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +func TestIsPath(t *testing.T) { + dg := simple.NewDirectedGraph() + if !IsPathIn(dg, nil) { + t.Error("IsPath returns false on nil path") + } + p := []graph.Node{simple.Node(0)} + if IsPathIn(dg, p) { + t.Error("IsPath returns true on nonexistant node") + } + dg.AddNode(p[0]) + if !IsPathIn(dg, p) { + t.Error("IsPath returns false on single-length path with existing node") + } + p = append(p, simple.Node(1)) + dg.AddNode(p[1]) + if IsPathIn(dg, p) { + t.Error("IsPath returns true on bad path of length 2") + } + dg.SetEdge(simple.Edge{F: p[0], T: p[1]}) + if !IsPathIn(dg, p) { + t.Error("IsPath returns false on correct path of length 2") + } + p[0], p[1] = p[1], p[0] + if IsPathIn(dg, p) { + t.Error("IsPath erroneously returns true for a reverse path") + } + p = []graph.Node{p[1], p[0], simple.Node(2)} + dg.SetEdge(simple.Edge{F: p[1], T: p[2]}) + if !IsPathIn(dg, p) { + t.Error("IsPath does not find a correct path for path > 2 nodes") + } + ug := simple.NewUndirectedGraph() + ug.SetEdge(simple.Edge{F: p[1], T: p[0]}) + ug.SetEdge(simple.Edge{F: p[1], T: p[2]}) + if !IsPathIn(dg, p) { + t.Error("IsPath does not correctly account for undirected behavior") + } +} + +var pathExistsInUndirectedTests = []struct { + g []intset + from, to int + want bool +}{ + {g: batageljZaversnikGraph, from: 0, to: 0, want: true}, + {g: batageljZaversnikGraph, from: 0, to: 1, want: false}, + {g: batageljZaversnikGraph, from: 1, to: 2, want: true}, + {g: batageljZaversnikGraph, from: 2, to: 1, want: true}, + {g: batageljZaversnikGraph, from: 2, to: 12, want: false}, + {g: batageljZaversnikGraph, from: 20, to: 6, want: true}, +} + +func TestPathExistsInUndirected(t *testing.T) { + for i, test := range pathExistsInUndirectedTests { + g := simple.NewUndirectedGraph() + + for u, e := range test.g { + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + if !g.Has(simple.Node(v)) { + g.AddNode(simple.Node(v)) + } + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + got := PathExistsIn(g, simple.Node(test.from), simple.Node(test.to)) + if got != test.want { + t.Errorf("unexpected result for path existence in test %d: got:%t want %t", i, got, test.want) + } + } +} + +var pathExistsInDirectedTests = []struct { + g []intset + from, to int + want bool +}{ + // The graph definition is such that from node IDs are + // less than to node IDs. + {g: batageljZaversnikGraph, from: 0, to: 0, want: true}, + {g: batageljZaversnikGraph, from: 0, to: 1, want: false}, + {g: batageljZaversnikGraph, from: 1, to: 2, want: true}, + {g: batageljZaversnikGraph, from: 2, to: 1, want: false}, + {g: batageljZaversnikGraph, from: 2, to: 12, want: false}, + {g: batageljZaversnikGraph, from: 20, to: 6, want: false}, + {g: batageljZaversnikGraph, from: 6, to: 20, want: true}, +} + +func TestPathExistsInDirected(t *testing.T) { + for i, test := range pathExistsInDirectedTests { + g := simple.NewDirectedGraph() + + for u, e := range test.g { + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + if !g.Has(simple.Node(v)) { + g.AddNode(simple.Node(v)) + } + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + + got := PathExistsIn(g, simple.Node(test.from), simple.Node(test.to)) + if got != test.want { + t.Errorf("unexpected result for path existence in test %d: got:%t want %t", i, got, test.want) + } + } +} + +var connectedComponentTests = []struct { + g []intset + want [][]int64 +}{ + { + g: batageljZaversnikGraph, + want: [][]int64{ + {0}, + {1, 2, 3, 4, 5}, + {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, + }, + }, +} + +func TestConnectedComponents(t *testing.T) { + for i, test := range connectedComponentTests { + g := simple.NewUndirectedGraph() + + for u, e := range test.g { + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + if !g.Has(simple.Node(v)) { + g.AddNode(simple.Node(v)) + } + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + cc := ConnectedComponents(g) + got := make([][]int64, len(cc)) + for j, c := range cc { + ids := make([]int64, len(c)) + for k, n := range c { + ids[k] = n.ID() + } + sort.Sort(ordered.Int64s(ids)) + got[j] = ids + } + sort.Sort(ordered.BySliceValues(got)) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexpected connected components for test %d %T:\ngot: %v\nwant:%v", i, g, got, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/graph/traverse/doc.go b/vendor/gonum.org/v1/gonum/graph/traverse/doc.go new file mode 100644 index 00000000..7bb3ca11 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/traverse/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package traverse provides basic graph traversal primitives. +package traverse // import "gonum.org/v1/gonum/graph/traverse" diff --git a/vendor/gonum.org/v1/gonum/graph/traverse/traverse.go b/vendor/gonum.org/v1/gonum/graph/traverse/traverse.go new file mode 100644 index 00000000..329649e2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/traverse/traverse.go @@ -0,0 +1,180 @@ +// 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 traverse + +import ( + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/internal/linear" + "gonum.org/v1/gonum/graph/internal/set" +) + +// BreadthFirst implements stateful breadth-first graph traversal. +type BreadthFirst struct { + EdgeFilter func(graph.Edge) bool + Visit func(u, v graph.Node) + queue linear.NodeQueue + visited set.Int64s +} + +// Walk performs a breadth-first traversal of the graph g starting from the given node, +// depending on the the EdgeFilter field and the until parameter if they are non-nil. The +// traversal follows edges for which EdgeFilter(edge) is true and returns the first node +// for which until(node, depth) is true. During the traversal, if the Visit field is +// non-nil, it is called with the nodes joined by each followed edge. +func (b *BreadthFirst) Walk(g graph.Graph, from graph.Node, until func(n graph.Node, d int) bool) graph.Node { + if b.visited == nil { + b.visited = make(set.Int64s) + } + b.queue.Enqueue(from) + b.visited.Add(from.ID()) + + var ( + depth int + children int + untilNext = 1 + ) + for b.queue.Len() > 0 { + t := b.queue.Dequeue() + if until != nil && until(t, depth) { + return t + } + for _, n := range g.From(t) { + if b.EdgeFilter != nil && !b.EdgeFilter(g.Edge(t, n)) { + continue + } + if b.visited.Has(n.ID()) { + continue + } + if b.Visit != nil { + b.Visit(t, n) + } + b.visited.Add(n.ID()) + children++ + b.queue.Enqueue(n) + } + if untilNext--; untilNext == 0 { + depth++ + untilNext = children + children = 0 + } + } + + return nil +} + +// WalkAll calls Walk for each unvisited node of the graph g using edges independent +// of their direction. The functions before and after are called prior to commencing +// and after completing each walk if they are non-nil respectively. The function +// during is called on each node as it is traversed. +func (b *BreadthFirst) WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) { + b.Reset() + for _, from := range g.Nodes() { + if b.Visited(from) { + continue + } + if before != nil { + before() + } + b.Walk(g, from, func(n graph.Node, _ int) bool { + if during != nil { + during(n) + } + return false + }) + if after != nil { + after() + } + } +} + +// Visited returned whether the node n was visited during a traverse. +func (b *BreadthFirst) Visited(n graph.Node) bool { + return b.visited.Has(n.ID()) +} + +// Reset resets the state of the traverser for reuse. +func (b *BreadthFirst) Reset() { + b.queue.Reset() + b.visited = nil +} + +// DepthFirst implements stateful depth-first graph traversal. +type DepthFirst struct { + EdgeFilter func(graph.Edge) bool + Visit func(u, v graph.Node) + stack linear.NodeStack + visited set.Int64s +} + +// Walk performs a depth-first traversal of the graph g starting from the given node, +// depending on the the EdgeFilter field and the until parameter if they are non-nil. The +// traversal follows edges for which EdgeFilter(edge) is true and returns the first node +// for which until(node) is true. During the traversal, if the Visit field is non-nil, it +// is called with the nodes joined by each followed edge. +func (d *DepthFirst) Walk(g graph.Graph, from graph.Node, until func(graph.Node) bool) graph.Node { + if d.visited == nil { + d.visited = make(set.Int64s) + } + d.stack.Push(from) + d.visited.Add(from.ID()) + + for d.stack.Len() > 0 { + t := d.stack.Pop() + if until != nil && until(t) { + return t + } + for _, n := range g.From(t) { + if d.EdgeFilter != nil && !d.EdgeFilter(g.Edge(t, n)) { + continue + } + if d.visited.Has(n.ID()) { + continue + } + if d.Visit != nil { + d.Visit(t, n) + } + d.visited.Add(n.ID()) + d.stack.Push(n) + } + } + + return nil +} + +// WalkAll calls Walk for each unvisited node of the graph g using edges independent +// of their direction. The functions before and after are called prior to commencing +// and after completing each walk if they are non-nil respectively. The function +// during is called on each node as it is traversed. +func (d *DepthFirst) WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) { + d.Reset() + for _, from := range g.Nodes() { + if d.Visited(from) { + continue + } + if before != nil { + before() + } + d.Walk(g, from, func(n graph.Node) bool { + if during != nil { + during(n) + } + return false + }) + if after != nil { + after() + } + } +} + +// Visited returned whether the node n was visited during a traverse. +func (d *DepthFirst) Visited(n graph.Node) bool { + return d.visited.Has(n.ID()) +} + +// Reset resets the state of the traverser for reuse. +func (d *DepthFirst) Reset() { + d.stack = d.stack[:0] + d.visited = nil +} diff --git a/vendor/gonum.org/v1/gonum/graph/traverse/traverse_test.go b/vendor/gonum.org/v1/gonum/graph/traverse/traverse_test.go new file mode 100644 index 00000000..ad817352 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/traverse/traverse_test.go @@ -0,0 +1,433 @@ +// 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 traverse + +import ( + "fmt" + "reflect" + "sort" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/graphs/gen" + "gonum.org/v1/gonum/graph/internal/ordered" + "gonum.org/v1/gonum/graph/simple" +) + +var ( + // batageljZaversnikGraph is the example graph from + // figure 1 of http://arxiv.org/abs/cs/0310049v1 + batageljZaversnikGraph = []intset{ + 0: nil, + + 1: linksTo(2, 3), + 2: linksTo(4), + 3: linksTo(4), + 4: linksTo(5), + 5: nil, + + 6: linksTo(7, 8, 14), + 7: linksTo(8, 11, 12, 14), + 8: linksTo(14), + 9: linksTo(11), + 10: linksTo(11), + 11: linksTo(12), + 12: linksTo(18), + 13: linksTo(14, 15), + 14: linksTo(15, 17), + 15: linksTo(16, 17), + 16: nil, + 17: linksTo(18, 19, 20), + 18: linksTo(19, 20), + 19: linksTo(20), + 20: nil, + } + + // wpBronKerboschGraph is the example given in the Bron-Kerbosch article on wikipedia (renumbered). + // http://en.wikipedia.org/w/index.php?title=Bron%E2%80%93Kerbosch_algorithm&oldid=656805858 + wpBronKerboschGraph = []intset{ + 0: linksTo(1, 4), + 1: linksTo(2, 4), + 2: linksTo(3), + 3: linksTo(4, 5), + 4: nil, + 5: nil, + } +) + +var breadthFirstTests = []struct { + g []intset + from graph.Node + edge func(graph.Edge) bool + until func(graph.Node, int) bool + final map[graph.Node]bool + want [][]int64 +}{ + { + g: wpBronKerboschGraph, + from: simple.Node(1), + final: map[graph.Node]bool{nil: true}, + want: [][]int64{ + {1}, + {0, 2, 4}, + {3}, + {5}, + }, + }, + { + g: wpBronKerboschGraph, + edge: func(e graph.Edge) bool { + // Do not traverse an edge between 3 and 5. + return (e.From().ID() != 3 || e.To().ID() != 5) && (e.From().ID() != 5 || e.To().ID() != 3) + }, + from: simple.Node(1), + final: map[graph.Node]bool{nil: true}, + want: [][]int64{ + {1}, + {0, 2, 4}, + {3}, + }, + }, + { + g: wpBronKerboschGraph, + from: simple.Node(1), + until: func(n graph.Node, _ int) bool { return n == simple.Node(3) }, + final: map[graph.Node]bool{simple.Node(3): true}, + want: [][]int64{ + {1}, + {0, 2, 4}, + }, + }, + { + g: batageljZaversnikGraph, + from: simple.Node(13), + final: map[graph.Node]bool{nil: true}, + want: [][]int64{ + {13}, + {14, 15}, + {6, 7, 8, 16, 17}, + {11, 12, 18, 19, 20}, + {9, 10}, + }, + }, + { + g: batageljZaversnikGraph, + from: simple.Node(13), + until: func(_ graph.Node, d int) bool { return d > 2 }, + final: map[graph.Node]bool{ + simple.Node(11): true, + simple.Node(12): true, + simple.Node(18): true, + simple.Node(19): true, + simple.Node(20): true, + }, + want: [][]int64{ + {13}, + {14, 15}, + {6, 7, 8, 16, 17}, + }, + }, +} + +func TestBreadthFirst(t *testing.T) { + for i, test := range breadthFirstTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + w := BreadthFirst{ + EdgeFilter: test.edge, + } + var got [][]int64 + final := w.Walk(g, test.from, func(n graph.Node, d int) bool { + if test.until != nil && test.until(n, d) { + return true + } + if d >= len(got) { + got = append(got, []int64(nil)) + } + got[d] = append(got[d], n.ID()) + return false + }) + if !test.final[final] { + t.Errorf("unexepected final node for test %d:\ngot: %v\nwant: %v", i, final, test.final) + } + for _, l := range got { + sort.Sort(ordered.Int64s(l)) + } + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexepected BFS level structure for test %d:\ngot: %v\nwant: %v", i, got, test.want) + } + } +} + +var depthFirstTests = []struct { + g []intset + from graph.Node + edge func(graph.Edge) bool + until func(graph.Node) bool + final map[graph.Node]bool + want []int64 +}{ + { + g: wpBronKerboschGraph, + from: simple.Node(1), + final: map[graph.Node]bool{nil: true}, + want: []int64{0, 1, 2, 3, 4, 5}, + }, + { + g: wpBronKerboschGraph, + edge: func(e graph.Edge) bool { + // Do not traverse an edge between 3 and 5. + return (e.From().ID() != 3 || e.To().ID() != 5) && (e.From().ID() != 5 || e.To().ID() != 3) + }, + from: simple.Node(1), + final: map[graph.Node]bool{nil: true}, + want: []int64{0, 1, 2, 3, 4}, + }, + { + g: wpBronKerboschGraph, + from: simple.Node(1), + until: func(n graph.Node) bool { return n == simple.Node(3) }, + final: map[graph.Node]bool{simple.Node(3): true}, + }, + { + g: batageljZaversnikGraph, + from: simple.Node(0), + final: map[graph.Node]bool{nil: true}, + want: []int64{0}, + }, + { + g: batageljZaversnikGraph, + from: simple.Node(3), + final: map[graph.Node]bool{nil: true}, + want: []int64{1, 2, 3, 4, 5}, + }, + { + g: batageljZaversnikGraph, + from: simple.Node(13), + final: map[graph.Node]bool{nil: true}, + want: []int64{6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, + }, +} + +func TestDepthFirst(t *testing.T) { + for i, test := range depthFirstTests { + g := simple.NewUndirectedGraph() + for u, e := range test.g { + // Add nodes that are not defined by an edge. + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + w := DepthFirst{ + EdgeFilter: test.edge, + } + var got []int64 + final := w.Walk(g, test.from, func(n graph.Node) bool { + if test.until != nil && test.until(n) { + return true + } + got = append(got, n.ID()) + return false + }) + if !test.final[final] { + t.Errorf("unexepected final node for test %d:\ngot: %v\nwant: %v", i, final, test.final) + } + sort.Sort(ordered.Int64s(got)) + if test.want != nil && !reflect.DeepEqual(got, test.want) { + t.Errorf("unexepected DFS traversed nodes for test %d:\ngot: %v\nwant: %v", i, got, test.want) + } + } +} + +var walkAllTests = []struct { + g []intset + edge func(graph.Edge) bool + want [][]int64 +}{ + { + g: batageljZaversnikGraph, + want: [][]int64{ + {0}, + {1, 2, 3, 4, 5}, + {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, + }, + }, + { + g: batageljZaversnikGraph, + edge: func(e graph.Edge) bool { + // Do not traverse an edge between 3 and 5. + return (e.From().ID() != 4 || e.To().ID() != 5) && (e.From().ID() != 5 || e.To().ID() != 4) + }, + want: [][]int64{ + {0}, + {1, 2, 3, 4}, + {5}, + {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, + }, + }, +} + +func TestWalkAll(t *testing.T) { + for i, test := range walkAllTests { + g := simple.NewUndirectedGraph() + + for u, e := range test.g { + if !g.Has(simple.Node(u)) { + g.AddNode(simple.Node(u)) + } + for v := range e { + if !g.Has(simple.Node(v)) { + g.AddNode(simple.Node(v)) + } + g.SetEdge(simple.Edge{F: simple.Node(u), T: simple.Node(v)}) + } + } + type walker interface { + WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) + } + for _, w := range []walker{ + &BreadthFirst{}, + &DepthFirst{}, + } { + var ( + c []graph.Node + cc [][]graph.Node + ) + switch w := w.(type) { + case *BreadthFirst: + w.EdgeFilter = test.edge + case *DepthFirst: + w.EdgeFilter = test.edge + default: + panic(fmt.Sprintf("bad walker type: %T", w)) + } + during := func(n graph.Node) { + c = append(c, n) + } + after := func() { + cc = append(cc, []graph.Node(nil)) + cc[len(cc)-1] = append(cc[len(cc)-1], c...) + c = c[:0] + } + w.WalkAll(g, nil, after, during) + + got := make([][]int64, len(cc)) + for j, c := range cc { + ids := make([]int64, len(c)) + for k, n := range c { + ids[k] = n.ID() + } + sort.Sort(ordered.Int64s(ids)) + got[j] = ids + } + sort.Sort(ordered.BySliceValues(got)) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("unexpected connected components for test %d using %T:\ngot: %v\nwant:%v", i, w, got, test.want) + } + } + } +} + +// intset is an integer set. +type intset map[int]struct{} + +func linksTo(i ...int) intset { + if len(i) == 0 { + return nil + } + s := make(intset) + for _, v := range i { + s[v] = struct{}{} + } + return s +} + +var ( + gnpUndirected_10_tenth = gnpUndirected(10, 0.1) + gnpUndirected_100_tenth = gnpUndirected(100, 0.1) + gnpUndirected_1000_tenth = gnpUndirected(1000, 0.1) + gnpUndirected_10_half = gnpUndirected(10, 0.5) + gnpUndirected_100_half = gnpUndirected(100, 0.5) + gnpUndirected_1000_half = gnpUndirected(1000, 0.5) +) + +func gnpUndirected(n int, p float64) graph.Undirected { + g := simple.NewUndirectedGraph() + gen.Gnp(g, n, p, nil) + return g +} + +func benchmarkWalkAllBreadthFirst(b *testing.B, g graph.Undirected) { + n := len(g.Nodes()) + b.ResetTimer() + var bft BreadthFirst + for i := 0; i < b.N; i++ { + bft.WalkAll(g, nil, nil, nil) + } + if len(bft.visited) != n { + b.Fatalf("unexpected number of nodes visited: want: %d got %d", n, len(bft.visited)) + } +} + +func BenchmarkWalkAllBreadthFirstGnp_10_tenth(b *testing.B) { + benchmarkWalkAllBreadthFirst(b, gnpUndirected_10_tenth) +} +func BenchmarkWalkAllBreadthFirstGnp_100_tenth(b *testing.B) { + benchmarkWalkAllBreadthFirst(b, gnpUndirected_100_tenth) +} +func BenchmarkWalkAllBreadthFirstGnp_1000_tenth(b *testing.B) { + benchmarkWalkAllBreadthFirst(b, gnpUndirected_1000_tenth) +} +func BenchmarkWalkAllBreadthFirstGnp_10_half(b *testing.B) { + benchmarkWalkAllBreadthFirst(b, gnpUndirected_10_half) +} +func BenchmarkWalkAllBreadthFirstGnp_100_half(b *testing.B) { + benchmarkWalkAllBreadthFirst(b, gnpUndirected_100_half) +} +func BenchmarkWalkAllBreadthFirstGnp_1000_half(b *testing.B) { + benchmarkWalkAllBreadthFirst(b, gnpUndirected_1000_half) +} + +func benchmarkWalkAllDepthFirst(b *testing.B, g graph.Undirected) { + n := len(g.Nodes()) + b.ResetTimer() + var dft DepthFirst + for i := 0; i < b.N; i++ { + dft.WalkAll(g, nil, nil, nil) + } + if len(dft.visited) != n { + b.Fatalf("unexpected number of nodes visited: want: %d got %d", n, len(dft.visited)) + } +} + +func BenchmarkWalkAllDepthFirstGnp_10_tenth(b *testing.B) { + benchmarkWalkAllDepthFirst(b, gnpUndirected_10_tenth) +} +func BenchmarkWalkAllDepthFirstGnp_100_tenth(b *testing.B) { + benchmarkWalkAllDepthFirst(b, gnpUndirected_100_tenth) +} +func BenchmarkWalkAllDepthFirstGnp_1000_tenth(b *testing.B) { + benchmarkWalkAllDepthFirst(b, gnpUndirected_1000_tenth) +} +func BenchmarkWalkAllDepthFirstGnp_10_half(b *testing.B) { + benchmarkWalkAllDepthFirst(b, gnpUndirected_10_half) +} +func BenchmarkWalkAllDepthFirstGnp_100_half(b *testing.B) { + benchmarkWalkAllDepthFirst(b, gnpUndirected_100_half) +} +func BenchmarkWalkAllDepthFirstGnp_1000_half(b *testing.B) { + benchmarkWalkAllDepthFirst(b, gnpUndirected_1000_half) +} diff --git a/vendor/gonum.org/v1/gonum/graph/undirect.go b/vendor/gonum.org/v1/gonum/graph/undirect.go new file mode 100644 index 00000000..e045dad4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/undirect.go @@ -0,0 +1,224 @@ +// 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 graph + +// Undirect converts a directed graph to an undirected graph. +type Undirect struct { + G Directed +} + +var _ Undirected = Undirect{} + +// Has returns whether the node exists within the graph. +func (g Undirect) Has(n Node) bool { return g.G.Has(n) } + +// Nodes returns all the nodes in the graph. +func (g Undirect) Nodes() []Node { return g.G.Nodes() } + +// From returns all nodes in g that can be reached directly from u. +func (g Undirect) From(u Node) []Node { + var nodes []Node + seen := make(map[int64]struct{}) + for _, n := range g.G.From(u) { + seen[n.ID()] = struct{}{} + nodes = append(nodes, n) + } + for _, n := range g.G.To(u) { + id := n.ID() + if _, ok := seen[id]; ok { + continue + } + seen[n.ID()] = struct{}{} + nodes = append(nodes, n) + } + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g Undirect) HasEdgeBetween(x, y Node) bool { return g.G.HasEdgeBetween(x, y) } + +// 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. +// If an edge exists, the Edge returned is an EdgePair. The weight of +// the edge is determined by applying the Merge func to the weights of the +// edges between u and v. +func (g Undirect) Edge(u, v Node) Edge { return g.EdgeBetween(u, v) } + +// EdgeBetween returns the edge between nodes x and y. If an edge exists, the +// Edge returned is an EdgePair. The weight of the edge is determined by +// applying the Merge func to the weights of edges between x and y. +func (g Undirect) EdgeBetween(x, y Node) Edge { + fe := g.G.Edge(x, y) + re := g.G.Edge(y, x) + if fe == nil && re == nil { + return nil + } + + return EdgePair{fe, re} +} + +// UndirectWeighted converts a directed weighted graph to an undirected weighted graph, +// resolving edge weight conflicts. +type UndirectWeighted struct { + G WeightedDirected + + // Absent is the value used to + // represent absent edge weights + // passed to Merge if the reverse + // edge is present. + Absent float64 + + // Merge defines how discordant edge + // weights in G are resolved. A merge + // is performed if at least one edge + // exists between the nodes being + // considered. The edges corresponding + // to the two weights are also passed, + // in the same order. + // The order of weight parameters + // passed to Merge is not defined, so + // the function should be commutative. + // If Merge is nil, the arithmetic + // mean is used to merge weights. + Merge func(x, y float64, xe, ye Edge) float64 +} + +var ( + _ Undirected = UndirectWeighted{} + _ WeightedUndirected = UndirectWeighted{} +) + +// Has returns whether the node exists within the graph. +func (g UndirectWeighted) Has(n Node) bool { return g.G.Has(n) } + +// Nodes returns all the nodes in the graph. +func (g UndirectWeighted) Nodes() []Node { return g.G.Nodes() } + +// From returns all nodes in g that can be reached directly from u. +func (g UndirectWeighted) From(u Node) []Node { + var nodes []Node + seen := make(map[int64]struct{}) + for _, n := range g.G.From(u) { + seen[n.ID()] = struct{}{} + nodes = append(nodes, n) + } + for _, n := range g.G.To(u) { + id := n.ID() + if _, ok := seen[id]; ok { + continue + } + seen[n.ID()] = struct{}{} + nodes = append(nodes, n) + } + return nodes +} + +// HasEdgeBetween returns whether an edge exists between nodes x and y. +func (g UndirectWeighted) HasEdgeBetween(x, y Node) bool { return g.G.HasEdgeBetween(x, y) } + +// 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. +// If an edge exists, the Edge returned is an EdgePair. The weight of +// the edge is determined by applying the Merge func to the weights of the +// edges between u and v. +func (g UndirectWeighted) Edge(u, v Node) Edge { return g.WeightedEdgeBetween(u, v) } + +// 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. +// If an edge exists, the Edge returned is an EdgePair. The weight of +// the edge is determined by applying the Merge func to the weights of the +// edges between u and v. +func (g UndirectWeighted) WeightedEdge(u, v Node) WeightedEdge { return g.WeightedEdgeBetween(u, v) } + +// EdgeBetween returns the edge between nodes x and y. If an edge exists, the +// Edge returned is an EdgePair. The weight of the edge is determined by +// applying the Merge func to the weights of edges between x and y. +func (g UndirectWeighted) EdgeBetween(x, y Node) Edge { + return g.WeightedEdgeBetween(x, y) +} + +// WeightedEdgeBetween returns the weighted edge between nodes x and y. If an edge exists, the +// Edge returned is an EdgePair. The weight of the edge is determined by +// applying the Merge func to the weights of edges between x and y. +func (g UndirectWeighted) WeightedEdgeBetween(x, y Node) WeightedEdge { + fe := g.G.Edge(x, y) + re := g.G.Edge(y, x) + if fe == nil && re == nil { + return nil + } + + f, ok := g.G.Weight(x, y) + if !ok { + f = g.Absent + } + r, ok := g.G.Weight(y, x) + if !ok { + r = g.Absent + } + + var w float64 + if g.Merge == nil { + w = (f + r) / 2 + } else { + w = g.Merge(f, r, fe, re) + } + return WeightedEdgePair{EdgePair: [2]Edge{fe, re}, W: w} +} + +// 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 the internal node weight is returned. If there is no joining +// edge between the two nodes the weight value returned is zero. Weight returns true if an edge +// exists between x and y or if x and y have the same ID, false otherwise. +func (g UndirectWeighted) Weight(x, y Node) (w float64, ok bool) { + fe := g.G.Edge(x, y) + re := g.G.Edge(y, x) + + f, fOk := g.G.Weight(x, y) + if !fOk { + f = g.Absent + } + r, rOK := g.G.Weight(y, x) + if !rOK { + r = g.Absent + } + ok = fOk || rOK + + if g.Merge == nil { + return (f + r) / 2, ok + } + return g.Merge(f, r, fe, re), ok +} + +// EdgePair is an opposed pair of directed edges. +type EdgePair [2]Edge + +// From returns the from node of the first non-nil edge, or nil. +func (e EdgePair) From() Node { + if e[0] != nil { + return e[0].From() + } else if e[1] != nil { + return e[1].From() + } + return nil +} + +// To returns the to node of the first non-nil edge, or nil. +func (e EdgePair) To() Node { + if e[0] != nil { + return e[0].To() + } else if e[1] != nil { + return e[1].To() + } + return nil +} + +// WeightedEdgePair is an opposed pair of directed edges. +type WeightedEdgePair struct { + EdgePair + W float64 +} + +// Weight returns the merged edge weights of the two edges. +func (e WeightedEdgePair) Weight() float64 { return e.W } diff --git a/vendor/gonum.org/v1/gonum/graph/undirect_test.go b/vendor/gonum.org/v1/gonum/graph/undirect_test.go new file mode 100644 index 00000000..8b9b9883 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/graph/undirect_test.go @@ -0,0 +1,175 @@ +// 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 graph_test + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/graph" + "gonum.org/v1/gonum/graph/simple" + "gonum.org/v1/gonum/mat" +) + +type weightedDirectedBuilder interface { + graph.WeightedBuilder + graph.WeightedDirected +} + +var weightedDirectedGraphs = []struct { + skipUnweighted bool + + g func() weightedDirectedBuilder + edges []simple.WeightedEdge + absent float64 + merge func(x, y float64, xe, ye graph.Edge) float64 + + want mat.Matrix +}{ + { + g: func() weightedDirectedBuilder { return simple.NewWeightedDirectedGraph(0, 0) }, + edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 2}, + {F: simple.Node(1), T: simple.Node(0), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + }, + want: mat.NewSymDense(3, []float64{ + 0, (1. + 2.) / 2., 0, + (1. + 2.) / 2., 0, 1. / 2., + 0, 1. / 2., 0, + }), + }, + { + g: func() weightedDirectedBuilder { return simple.NewWeightedDirectedGraph(0, 0) }, + edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 2}, + {F: simple.Node(1), T: simple.Node(0), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + }, + absent: 1, + merge: func(x, y float64, _, _ graph.Edge) float64 { return math.Sqrt(x * y) }, + want: mat.NewSymDense(3, []float64{ + 0, math.Sqrt(1 * 2), 0, + math.Sqrt(1 * 2), 0, math.Sqrt(1 * 1), + 0, math.Sqrt(1 * 1), 0, + }), + }, + { + skipUnweighted: true, // The min merge function cannot be used in the unweighted case. + + g: func() weightedDirectedBuilder { return simple.NewWeightedDirectedGraph(0, 0) }, + edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 2}, + {F: simple.Node(1), T: simple.Node(0), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + }, + merge: func(x, y float64, _, _ graph.Edge) float64 { return math.Min(x, y) }, + want: mat.NewSymDense(3, []float64{ + 0, math.Min(1, 2), 0, + math.Min(1, 2), 0, math.Min(1, 0), + 0, math.Min(1, 0), 0, + }), + }, + { + g: func() weightedDirectedBuilder { return simple.NewWeightedDirectedGraph(0, 0) }, + edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 2}, + {F: simple.Node(1), T: simple.Node(0), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + }, + merge: func(x, y float64, xe, ye graph.Edge) float64 { + if xe == nil { + return y + } + if ye == nil { + return x + } + return math.Min(x, y) + }, + want: mat.NewSymDense(3, []float64{ + 0, math.Min(1, 2), 0, + math.Min(1, 2), 0, 1, + 0, 1, 0, + }), + }, + { + g: func() weightedDirectedBuilder { return simple.NewWeightedDirectedGraph(0, 0) }, + edges: []simple.WeightedEdge{ + {F: simple.Node(0), T: simple.Node(1), W: 2}, + {F: simple.Node(1), T: simple.Node(0), W: 1}, + {F: simple.Node(1), T: simple.Node(2), W: 1}, + }, + merge: func(x, y float64, _, _ graph.Edge) float64 { return math.Max(x, y) }, + want: mat.NewSymDense(3, []float64{ + 0, math.Max(1, 2), 0, + math.Max(1, 2), 0, math.Max(1, 0), + 0, math.Max(1, 0), 0, + }), + }, +} + +func TestUndirect(t *testing.T) { + for i, test := range weightedDirectedGraphs { + if test.skipUnweighted { + continue + } + g := test.g() + for _, e := range test.edges { + g.SetWeightedEdge(e) + } + + src := graph.Undirect{G: g} + dst := simple.NewUndirectedMatrixFrom(src.Nodes(), 0, 0, 0) + for _, u := range src.Nodes() { + for _, v := range src.From(u) { + dst.SetEdge(src.Edge(u, v)) + } + } + + want := unit{test.want} + if !mat.Equal(dst.Matrix(), want) { + t.Errorf("unexpected result for case %d:\ngot:\n%.4v\nwant:\n%.4v", i, + mat.Formatted(dst.Matrix()), + mat.Formatted(want), + ) + } + } +} + +func TestUndirectWeighted(t *testing.T) { + for i, test := range weightedDirectedGraphs { + g := test.g() + for _, e := range test.edges { + g.SetWeightedEdge(e) + } + + src := graph.UndirectWeighted{G: g, Absent: test.absent, Merge: test.merge} + dst := simple.NewUndirectedMatrixFrom(src.Nodes(), 0, 0, 0) + for _, u := range src.Nodes() { + for _, v := range src.From(u) { + dst.SetWeightedEdge(src.WeightedEdge(u, v)) + } + } + + if !mat.Equal(dst.Matrix(), test.want) { + t.Errorf("unexpected result for case %d:\ngot:\n%.4v\nwant:\n%.4v", i, + mat.Formatted(dst.Matrix()), + mat.Formatted(test.want), + ) + } + } +} + +type unit struct { + mat.Matrix +} + +func (m unit) At(i, j int) float64 { + v := m.Matrix.At(i, j) + if v == 0 { + return 0 + } + return 1 +} diff --git a/vendor/gonum.org/v1/gonum/integrate/README.md b/vendor/gonum.org/v1/gonum/integrate/README.md new file mode 100644 index 00000000..1c929a8d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/README.md @@ -0,0 +1,3 @@ +# Gonum integrate [![GoDoc](https://godoc.org/gonum.org/v1/gonum/integrate?status.svg)](https://godoc.org/gonum.org/v1/gonum/integrate) + +Package integrate provides numerical evaluation of definite integrals of single-variable functions for the Go programming language. diff --git a/vendor/gonum.org/v1/gonum/integrate/doc.go b/vendor/gonum.org/v1/gonum/integrate/doc.go new file mode 100644 index 00000000..81bddb3b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/doc.go @@ -0,0 +1,7 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package integrate provides functions to compute an integral given a +// specific list of evaluations. +package integrate // import "gonum.org/v1/gonum/integrate" diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/doc.go b/vendor/gonum.org/v1/gonum/integrate/quad/doc.go new file mode 100644 index 00000000..480edcc0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/doc.go @@ -0,0 +1,7 @@ +// 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 quad provides numerical evaluation of definite integrals of single-variable functions. +// +package quad // import "gonum.org/v1/gonum/integrate/quad" diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/example_test.go b/vendor/gonum.org/v1/gonum/integrate/quad/example_test.go new file mode 100644 index 00000000..32a4886a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/example_test.go @@ -0,0 +1,47 @@ +// 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 quad_test + +import ( + "fmt" + "math" + "runtime" + + "gonum.org/v1/gonum/integrate/quad" + "gonum.org/v1/gonum/stat/distuv" +) + +func Example() { + fmt.Println("Evaluate the expected value of x^2 + 3 under a Weibull distribution") + f := func(x float64) float64 { + d := distuv.Weibull{Lambda: 1, K: 1.5} + return (x*x + 3) * d.Prob(x) + } + ev := quad.Fixed(f, 0, math.Inf(1), 10, nil, 0) + fmt.Printf("EV with 10 points = %0.6v\n", ev) + + ev = quad.Fixed(f, 0, math.Inf(1), 30, nil, 0) + fmt.Printf("EV with 30 points = %0.6v\n", ev) + + ev = quad.Fixed(f, 0, math.Inf(1), 100, nil, 0) + fmt.Printf("EV with 100 points = %0.6v\n", ev) + + ev = quad.Fixed(f, 0, math.Inf(1), 10000, nil, 0) + fmt.Printf("EV with 10000 points = %0.6v\n\n", ev) + + fmt.Println("Estimate using parallel evaluations of f.") + concurrent := runtime.GOMAXPROCS(0) + ev = quad.Fixed(f, 0, math.Inf(1), 100, nil, concurrent) + fmt.Printf("EV = %0.6v\n", ev) + // Output: + // Evaluate the expected value of x^2 + 3 under a Weibull distribution + // EV with 10 points = 4.20175 + // EV with 30 points = 4.19066 + // EV with 100 points = 4.19064 + // EV with 10000 points = 4.19064 + // + // Estimate using parallel evaluations of f. + // EV = 4.19064 +} diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/hermite.go b/vendor/gonum.org/v1/gonum/integrate/quad/hermite.go new file mode 100644 index 00000000..d2755f0e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/hermite.go @@ -0,0 +1,314 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package quad + +import ( + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mathext" +) + +// Hermite generates sample locations and weights for performing quadrature with +// with a squared-exponential weight +// int_-inf^inf e^(-x^2) f(x) dx . +type Hermite struct{} + +func (h Hermite) FixedLocations(x, weight []float64, min, max float64) { + // TODO(btracey): Implement the case where x > 20, x < 200 so that we don't + // need to store all of that data. + + // Algorithm adapted from Chebfun http://www.chebfun.org/. + // + // References: + // Algorithm: + // G. H. Golub and J. A. Welsch, "Calculation of Gauss quadrature rules", + // Math. Comp. 23:221-230, 1969. + // A. Glaser, X. Liu and V. Rokhlin, "A fast algorithm for the + // calculation of the roots of special functions", SIAM Journal + // on Scientific Computing", 29(4):1420-1438:, 2007. + // A. Townsend, T. Trogdon, and S.Olver, Fast computation of Gauss quadrature + // nodes and weights on the whole real line, IMA J. Numer. Anal., 36: 337–358, + // 2016. http://arxiv.org/abs/1410.5286 + + if len(x) != len(weight) { + panic("hermite: slice length mismatch") + } + if min >= max { + panic("hermite: min >= max") + } + if !math.IsInf(min, -1) || !math.IsInf(max, 1) { + panic("hermite: non-infinite bound") + } + h.locations(x, weight) +} + +func (h Hermite) locations(x, weights []float64) { + n := len(x) + switch { + case 0 < n && n <= 200: + copy(x, xCacheHermite[n-1]) + copy(weights, wCacheHermite[n-1]) + case n > 200: + h.locationsAsy(x, weights) + } +} + +// Algorithm adapted from Chebfun http://www.chebfun.org/. Specific code +// https://github.com/chebfun/chebfun/blob/development/hermpts.m. + +// Original Copyright Notice: + +/* +Copyright (c) 2015, The Chancellor, Masters and Scholars of the University +of Oxford, and the Chebfun Developers. 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 University of Oxford nor the names of its + 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. +*/ + +// locationAsy returns the node locations and weights of a Hermite quadrature rule +// with len(x) points. +func (h Hermite) locationsAsy(x, w []float64) { + // A. Townsend, T. Trogdon, and S.Olver, Fast computation of Gauss quadrature + // nodes and weights the whole real line, IMA J. Numer. Anal., + // 36: 337–358, 2016. http://arxiv.org/abs/1410.5286 + + // Find the positive locations and weights. + n := len(x) + l := n / 2 + xa := x[l:] + wa := w[l:] + for i := range xa { + xa[i], wa[i] = h.locationsAsy0(i, n) + } + // Flip around zero -- copy the negative x locations with the corresponding + // weights. + if n%2 == 0 { + l-- + } + for i, v := range xa { + x[l-i] = -v + } + for i, v := range wa { + w[l-i] = v + } + sumW := floats.Sum(w) + c := math.SqrtPi / sumW + floats.Scale(c, w) +} + +// locationsAsy0 returns the location and weight for location i in an n-point +// quadrature rule. The rule is symmetric, so i should be <= n/2 + n%2. +func (h Hermite) locationsAsy0(i, n int) (x, w float64) { + const convTol = 1e-16 + const convIter = 20 + theta0 := h.hermiteInitialGuess(i, n) + t0 := theta0 / math.Sqrt(2*float64(n)+1) + theta0 = math.Acos(t0) + sqrt2np1 := math.Sqrt(2*float64(n) + 1) + var vali, dvali float64 + for k := 0; k < convIter; k++ { + vali, dvali = h.hermpolyAsyAiry(i, n, theta0) + dt := -vali / (math.Sqrt2 * sqrt2np1 * dvali * math.Sin(theta0)) + theta0 -= dt + if math.Abs(theta0) < convTol { + break + } + } + x = sqrt2np1 * math.Cos(theta0) + ders := x*vali + math.Sqrt2*dvali + w = math.Exp(-x*x) / (ders * ders) + return x, w +} + +// hermpolyAsyAiry evaluates the Hermite polynomials using the Airy asymptotic +// formula in theta-space. +func (h Hermite) hermpolyAsyAiry(i, n int, t float64) (valVec, dvalVec float64) { + musq := 2*float64(n) + 1 + cosT := math.Cos(t) + sinT := math.Sin(t) + sin2T := 2 * cosT * sinT + eta := 0.5*t - 0.25*sin2T + chi := -math.Pow(3*eta/2, 2.0/3) + phi := math.Pow(-chi/(sinT*sinT), 1.0/4) + cnst := 2 * math.SqrtPi * math.Pow(musq, 1.0/6) * phi + airy0 := real(mathext.AiryAi(complex(math.Pow(musq, 2.0/3)*chi, 0))) + airy1 := real(mathext.AiryAiDeriv(complex(math.Pow(musq, 2.0/3)*chi, 0))) + + // Terms in 12.10.43: + const ( + a1 = 15.0 / 144 + b1 = -7.0 / 5 * a1 + a2 = 5.0 * 7 * 9 * 11.0 / 2.0 / 144.0 / 144.0 + b2 = -13.0 / 11 * a2 + a3 = 7.0 * 9 * 11 * 13 * 15 * 17 / 6.0 / 144.0 / 144.0 / 144.0 + b3 = -19.0 / 17 * a3 + ) + + // Pre-compute terms. + cos2T := cosT * cosT + cos3T := cos2T * cosT + cos4T := cos3T * cosT + cos5T := cos4T * cosT + cos7T := cos5T * cos2T + cos9T := cos7T * cos2T + + chi2 := chi * chi + chi3 := chi2 * chi + chi4 := chi3 * chi + chi5 := chi4 * chi + + phi6 := math.Pow(phi, 6) + phi12 := phi6 * phi6 + phi18 := phi12 * phi6 + + // u polynomials in 12.10.9. + u1 := (cos3T - 6*cosT) / 24.0 + u2 := (-9*cos4T + 249*cos2T + 145) / 1152.0 + u3 := (-4042*cos9T + 18189*cos7T - 28287*cos5T - 151995*cos3T - 259290*cosT) / 414720.0 + + val := airy0 + B0 := -(phi6*u1 + a1) / chi2 + val += B0 * airy1 / math.Pow(musq, 4.0/3) + A1 := (phi12*u2 + b1*phi6*u1 + b2) / chi3 + val += A1 * airy0 / (musq * musq) + B1 := -(phi18*u3 + a1*phi12*u2 + a2*phi6*u1 + a3) / chi5 + val += B1 * airy1 / math.Pow(musq, 4.0/3+2) + val *= cnst + + // Derivative. + eta = 0.5*t - 0.25*sin2T + chi = -math.Pow(3*eta/2, 2.0/3) + phi = math.Pow(-chi/(sinT*sinT), 1.0/4) + cnst = math.Sqrt2 * math.SqrtPi * math.Pow(musq, 1.0/3) / phi + + // v polynomials in 12.10.10. + v1 := (cos3T + 6*cosT) / 24 + v2 := (15*cos4T - 327*cos2T - 143) / 1152 + v3 := (259290*cosT + 238425*cos3T - 36387*cos5T + 18189*cos7T - 4042*cos9T) / 414720 + + C0 := -(phi6*v1 + b1) / chi + dval := C0 * airy0 / math.Pow(musq, 2.0/3) + dval += airy1 + C1 := -(phi18*v3 + b1*phi12*v2 + b2*phi6*v1 + b3) / chi4 + dval += C1 * airy0 / math.Pow(musq, 2.0/3+2) + D1 := (phi12*v2 + a1*phi6*v1 + a2) / chi3 + dval += D1 * airy1 / (musq * musq) + dval *= cnst + return val, dval +} + +// hermiteInitialGuess returns the initial guess for node i in an n-point Hermite +// quadrature rule. The rule is symmetric, so i should be <= n/2 + n%2. +func (h Hermite) hermiteInitialGuess(i, n int) float64 { + // There are two different formulas for the initial guesses of the hermite + // quadrature locations. The first uses the Gatteschi formula and is good + // near x = sqrt(n+0.5) + // [1] L. Gatteschi, Asymptotics and bounds for the zeros of Laguerre + // polynomials: a survey, J. Comput. Appl. Math., 144 (2002), pp. 7-27. + // The second is the Tricomi initial guesses, good near x = 0. This is + // equation 2.1 in [1] and is originally from + // [2] F. G. Tricomi, Sugli zeri delle funzioni di cui si conosce una + // rappresentazione asintotica, Ann. Mat. Pura Appl. 26 (1947), pp. 283-300. + + // If the number of points is odd, there is a quadrature point at 1, which + // has an initial guess of 0. + if n%2 == 1 { + if i == 0 { + return 0 + } + i-- + } + + m := n / 2 + a := -0.5 + if n%2 == 1 { + a = 0.5 + } + nu := 4*float64(m) + 2*a + 2 + + // Find the split between Gatteschi guesses and Tricomi guesses. + p := 0.4985 + math.SmallestNonzeroFloat64 + pidx := int(math.Floor(p * float64(n))) + + // Use the Tricomi initial guesses in the first half where x is nearer to zero. + // Note: zeros of besselj(+/-.5,x) are integer and half-integer multiples of pi. + if i < pidx { + rhs := math.Pi * (4*float64(m) - 4*(float64(i)+1) + 3) / nu + tnk := math.Pi / 2 + for k := 0; k < 7; k++ { + val := tnk - math.Sin(tnk) - rhs + dval := 1 - math.Cos(tnk) + dTnk := val / dval + tnk -= dTnk + if math.Abs(dTnk) < 1e-14 { + break + } + } + vc := math.Cos(tnk / 2) + t := vc * vc + return math.Sqrt(nu*t - (5.0/(4.0*(1-t)*(1-t))-1.0/(1-t)-1+3*a*a)/3/nu) + } + + // Use Gatteschi guesses in the second half where x is nearer to sqrt(n+0.5) + i = i + 1 - m + var ar float64 + if i < len(airyRtsExact) { + ar = airyRtsExact[i] + } else { + t := 3.0 / 8 * math.Pi * (4*(float64(i)+1) - 1) + ar = math.Pow(t, 2.0/3) * (1 + + 5.0/48*math.Pow(t, -2) - + 5.0/36*math.Pow(t, -4) + + 77125.0/82944*math.Pow(t, -6) - + 108056875.0/6967296*math.Pow(t, -8) + + 162375596875.0/334430208*math.Pow(t, -10)) + } + r := nu + math.Pow(2, 2.0/3)*ar*math.Pow(nu, 1.0/3) + + 0.2*math.Pow(2, 4.0/3)*ar*ar*math.Pow(nu, -1.0/3) + + (11.0/35-a*a-12.0/175*ar*ar*ar)/nu + + (16.0/1575*ar+92.0/7875*math.Pow(ar, 4))*math.Pow(2, 2.0/3)*math.Pow(nu, -5.0/3) - + (15152.0/3031875*math.Pow(ar, 5)+1088.0/121275*ar*ar)*math.Pow(2, 1.0/3)*math.Pow(nu, -7.0/3) + if r < 0 { + ar = 0 + } else { + ar = math.Sqrt(r) + } + return ar +} + +// airyRtsExact are the first airy roots. +var airyRtsExact = []float64{ + -2.338107410459762, + -4.087949444130970, + -5.520559828095555, + -6.786708090071765, + -7.944133587120863, + -9.022650853340979, + -10.040174341558084, + -11.008524303733260, + -11.936015563236262, + -12.828776752865757, +} diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/hermite_data.go b/vendor/gonum.org/v1/gonum/integrate/quad/hermite_data.go new file mode 100644 index 00000000..c50c8dbb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/hermite_data.go @@ -0,0 +1,413 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package quad + +// xCache computed from Chebfun. +var xCacheHermite = [][]float64{ + {0.0000000000000000e+00}, + {-7.0710678118654757e-01, 7.0710678118654757e-01}, + {-1.2247448713915887e+00, 0.0000000000000000e+00, 1.2247448713915887e+00}, + {-1.6506801238857842e+00, -5.2464762327529035e-01, 5.2464762327529035e-01, 1.6506801238857842e+00}, + {-2.0201828704560856e+00, -9.5857246461381873e-01, 0.0000000000000000e+00, 9.5857246461381873e-01, 2.0201828704560856e+00}, + {-2.3506049736744914e+00, -1.3358490740136970e+00, -4.3607741192761657e-01, 4.3607741192761657e-01, 1.3358490740136970e+00, 2.3506049736744914e+00}, + {-2.6519613568352316e+00, -1.6735516287674714e+00, -8.1628788285896481e-01, 0.0000000000000000e+00, 8.1628788285896481e-01, 1.6735516287674714e+00, 2.6519613568352316e+00}, + {-2.9306374202572436e+00, -1.9816567566958443e+00, -1.1571937124467804e+00, -3.8118699020732216e-01, 3.8118699020732216e-01, 1.1571937124467804e+00, 1.9816567566958443e+00, 2.9306374202572436e+00}, + {-3.1909932017815295e+00, -2.2665805845318427e+00, -1.4685532892166682e+00, -7.2355101875283767e-01, 0.0000000000000000e+00, 7.2355101875283767e-01, 1.4685532892166682e+00, 2.2665805845318427e+00, 3.1909932017815295e+00}, + {-3.4361591188377378e+00, -2.5327316742327901e+00, -1.7566836492998816e+00, -1.0366108297895138e+00, -3.4290132722370481e-01, 3.4290132722370481e-01, 1.0366108297895138e+00, 1.7566836492998816e+00, 2.5327316742327901e+00, 3.4361591188377378e+00}, + {-3.6684708465595812e+00, -2.7832900997816514e+00, -2.0259480158257550e+00, -1.3265570844949326e+00, -6.5680956688209979e-01, 0.0000000000000000e+00, 6.5680956688209979e-01, 1.3265570844949326e+00, 2.0259480158257550e+00, 2.7832900997816514e+00, 3.6684708465595812e+00}, + {-3.8897248978697814e+00, -3.0206370251208896e+00, -2.2795070805010593e+00, -1.5976826351526043e+00, -9.4778839124016367e-01, -3.1424037625435908e-01, 3.1424037625435908e-01, 9.4778839124016367e-01, 1.5976826351526043e+00, 2.2795070805010593e+00, 3.0206370251208896e+00, 3.8897248978697814e+00}, + {-4.1013375961786389e+00, -3.2466089783724090e+00, -2.5197356856782389e+00, -1.8531076516015121e+00, -1.2200550365907483e+00, -6.0576387917106034e-01, 0.0000000000000000e+00, 6.0576387917106034e-01, 1.2200550365907483e+00, 1.8531076516015121e+00, 2.5197356856782389e+00, 3.2466089783724090e+00, 4.1013375961786389e+00}, + {-4.3044485704736335e+00, -3.4626569336022701e+00, -2.7484707249854017e+00, -2.0951832585077166e+00, -1.4766827311411406e+00, -8.7871378732939931e-01, -2.9174551067256199e-01, 2.9174551067256199e-01, 8.7871378732939931e-01, 1.4766827311411406e+00, 2.0951832585077166e+00, 2.7484707249854017e+00, 3.4626569336022701e+00, 4.3044485704736335e+00}, + {-4.4999907073093910e+00, -3.6699503734044541e+00, -2.9671669279056028e+00, -2.3257324861738580e+00, -1.7199925751864888e+00, -1.1361155852109204e+00, -5.6506958325557588e-01, 0.0000000000000000e+00, 5.6506958325557588e-01, 1.1361155852109204e+00, 1.7199925751864888e+00, 2.3257324861738580e+00, 2.9671669279056028e+00, 3.6699503734044541e+00, 4.4999907073093910e+00}, + {-4.6887389393058223e+00, -3.8694479048601238e+00, -3.1769991619799529e+00, -2.5462021578474796e+00, -1.9517879909162528e+00, -1.3802585391988815e+00, -8.2295144914465546e-01, -2.7348104613815244e-01, 2.7348104613815244e-01, 8.2295144914465546e-01, 1.3802585391988815e+00, 1.9517879909162528e+00, 2.5462021578474796e+00, 3.1769991619799529e+00, 3.8694479048601238e+00, 4.6887389393058223e+00}, + {-4.8713451936744061e+00, -4.0619466758754772e+00, -3.3789320911414946e+00, -2.7577629157038897e+00, -2.1735028266666214e+00, -1.6129243142212311e+00, -1.0676487257434508e+00, -5.3163300134265479e-01, 0.0000000000000000e+00, 5.3163300134265479e-01, 1.0676487257434508e+00, 1.6129243142212311e+00, 2.1735028266666214e+00, 2.7577629157038897e+00, 3.3789320911414946e+00, 4.0619466758754772e+00, 4.8713451936744061e+00}, + {-5.0483640088744668e+00, -4.2481178735681260e+00, -3.5737690684862655e+00, -2.9613775055316052e+00, -2.3862990891666858e+00, -1.8355316042616294e+00, -1.3009208583896172e+00, -7.7668291926741173e-01, -2.5826775051909689e-01, 2.5826775051909689e-01, 7.7668291926741173e-01, 1.3009208583896172e+00, 1.8355316042616294e+00, 2.3862990891666858e+00, 2.9613775055316052e+00, 3.5737690684862655e+00, 4.2481178735681260e+00, 5.0483640088744668e+00}, + {-5.2202716905374844e+00, -4.4285328066037799e+00, -3.7621873519640201e+00, -3.1578488183476034e+00, -2.5911337897945423e+00, -2.0492317098506181e+00, -1.5241706193935327e+00, -1.0103683871343114e+00, -5.0352016342388828e-01, 0.0000000000000000e+00, 5.0352016342388828e-01, 1.0103683871343114e+00, 1.5241706193935327e+00, 2.0492317098506181e+00, 2.5911337897945423e+00, 3.1578488183476034e+00, 3.7621873519640201e+00, 4.4285328066037799e+00, 5.2202716905374844e+00}, + {-5.3874808900112319e+00, -4.6036824495507451e+00, -3.9447640401156265e+00, -3.3478545673832172e+00, -2.7888060584281313e+00, -2.2549740020892761e+00, -1.7385377121165857e+00, -1.2340762153953231e+00, -7.3747372854539406e-01, -2.4534070830090132e-01, 2.4534070830090132e-01, 7.3747372854539406e-01, 1.2340762153953231e+00, 1.7385377121165857e+00, 2.2549740020892761e+00, 2.7888060584281313e+00, 3.3478545673832172e+00, 3.9447640401156265e+00, 4.6036824495507451e+00, 5.3874808900112319e+00}, + {-5.5503518732646775e+00, -4.7739923434112193e+00, -4.1219955474918395e+00, -3.5319728771376777e+00, -2.9799912077045980e+00, -2.4535521245128376e+00, -1.9449629491862539e+00, -1.4489342506507319e+00, -9.6149963441836894e-01, -4.7945070707910747e-01, -0.0000000000000000e+00, 4.7945070707910747e-01, 9.6149963441836894e-01, 1.4489342506507319e+00, 1.9449629491862539e+00, 2.4535521245128376e+00, 2.9799912077045980e+00, 3.5319728771376777e+00, 4.1219955474918395e+00, 4.7739923434112193e+00, 5.5503518732646775e+00}, + {-5.7092013532052626e+00, -4.9398341310601763e+00, -4.2943124805931614e+00, -3.7107015328778048e+00, -3.1652659092021374e+00, -2.6456374410581724e+00, -2.1442335927985341e+00, -1.6558743732864223e+00, -1.1767139584812445e+00, -7.0368609717000696e-01, -2.3417913993099065e-01, 2.3417913993099065e-01, 7.0368609717000696e-01, 1.1767139584812445e+00, 1.6558743732864223e+00, 2.1442335927985341e+00, 2.6456374410581724e+00, 3.1652659092021374e+00, 3.7107015328778048e+00, 4.2943124805931614e+00, 4.9398341310601763e+00, 5.7092013532052626e+00}, + {-5.8643094989845714e+00, -5.1015346104766763e+00, -4.4620911737400064e+00, -3.8844727081061015e+00, -3.3451271599412244e+00, -2.8318037871261570e+00, -2.3370162114744559e+00, -1.8556770376713707e+00, -1.3840395856824952e+00, -9.1915146544256365e-01, -4.5853835006810478e-01, -0.0000000000000000e+00, 4.5853835006810478e-01, 9.1915146544256365e-01, 1.3840395856824952e+00, 1.8556770376713707e+00, 2.3370162114744559e+00, 2.8318037871261570e+00, 3.3451271599412244e+00, 3.8844727081061015e+00, 4.4620911737400064e+00, 5.1015346104766763e+00, 5.8643094989845714e+00}, + {-6.0159255614257390e+00, -5.2593829276680442e+00, -4.6256627564237878e+00, -4.0536644024481490e+00, -3.5200068130345241e+00, -3.0125461375655647e+00, -2.5238810170114268e+00, -2.0490035736616985e+00, -1.5842500109616942e+00, -1.1267608176112451e+00, -6.7417110703721217e-01, -2.2441454747251557e-01, 2.2441454747251557e-01, 6.7417110703721217e-01, 1.1267608176112451e+00, 1.5842500109616942e+00, 2.0490035736616985e+00, 2.5238810170114268e+00, 3.0125461375655647e+00, 3.5200068130345241e+00, 4.0536644024481490e+00, 4.6256627564237878e+00, 5.2593829276680442e+00, 6.0159255614257390e+00}, + {-6.1642724340524513e+00, -5.4136363552800333e+00, -4.7853203673522238e+00, -4.2186094443865612e+00, -3.6902828769983551e+00, -3.1882949244251044e+00, -2.7053202371730256e+00, -2.2364201302672808e+00, -1.7780011243371474e+00, -1.3272807020730839e+00, -8.8198275621382138e-01, -4.4014729864530827e-01, -0.0000000000000000e+00, 4.4014729864530827e-01, 8.8198275621382138e-01, 1.3272807020730839e+00, 1.7780011243371474e+00, 2.2364201302672808e+00, 2.7053202371730256e+00, 3.1882949244251044e+00, 3.6902828769983551e+00, 4.2186094443865612e+00, 4.7853203673522238e+00, 5.4136363552800333e+00, 6.1642724340524513e+00}, + {-6.3095503856256920e+00, -5.5645249819501030e+00, -4.9413249572413793e+00, -4.3796026629833040e+00, -3.8562884199091489e+00, -3.3594271823508297e+00, -2.8817622195430865e+00, -2.4184157647737790e+00, -1.9658547856411364e+00, -1.5213615166519212e+00, -1.0827330110778832e+00, -6.4809521399344827e-01, -2.1577785624346338e-01, 2.1577785624346338e-01, 6.4809521399344827e-01, 1.0827330110778832e+00, 1.5213615166519212e+00, 1.9658547856411364e+00, 2.4184157647737790e+00, 2.8817622195430865e+00, 3.3594271823508297e+00, 3.8562884199091489e+00, 4.3796026629833040e+00, 4.9413249572413793e+00, 5.5645249819501030e+00, 6.3095503856256920e+00}, + {-6.4519401407534707e+00, -5.7122555528165355e+00, -5.0939100031131836e+00, -4.5369066633724415e+00, -4.0183186704087381e+00, -3.5262753401343527e+00, -3.0535824198222552e+00, -2.5954163389108178e+00, -2.1482966453616275e+00, -1.7095607392603374e+00, -1.2770668173398578e+00, -8.4901134206010298e-01, -4.2380790054385303e-01, -0.0000000000000000e+00, 4.2380790054385303e-01, 8.4901134206010298e-01, 1.2770668173398578e+00, 1.7095607392603374e+00, 2.1482966453616275e+00, 2.5954163389108178e+00, 3.0535824198222552e+00, 3.5262753401343527e+00, 4.0183186704087381e+00, 4.5369066633724415e+00, 5.0939100031131836e+00, 5.7122555528165355e+00, 6.4519401407534707e+00}, + {-6.5916054423677419e+00, -5.8570146413828503e+00, -5.2432853732029354e+00, -4.6907565239431177e+00, -4.1766367421292676e+00, -3.6891342384616794e+00, -3.2211120765614556e+00, -2.7677953529135935e+00, -2.3257498426564407e+00, -1.8923604968376853e+00, -1.4655372634574091e+00, -1.0435352737542081e+00, -6.2483671950520925e-01, -2.0806738269073688e-01, 2.0806738269073688e-01, 6.2483671950520925e-01, 1.0435352737542081e+00, 1.4655372634574091e+00, 1.8923604968376853e+00, 2.3257498426564407e+00, 2.7677953529135935e+00, 3.2211120765614556e+00, 3.6891342384616794e+00, 4.1766367421292676e+00, 4.6907565239431177e+00, 5.2432853732029354e+00, 5.8570146413828503e+00, 6.5916054423677419e+00}, + {-6.7286951986088495e+00, -5.9989712894638192e+00, -5.3896405219667507e+00, -4.8413636510591642e+00, -4.3314782938191501e+00, -3.8482667922136202e+00, -3.3846451410922138e+00, -2.9358825042901264e+00, -2.4985856910194042e+00, -2.0701810760534278e+00, -1.6486229138923163e+00, -1.2322157550847530e+00, -8.1949868127091163e-01, -4.0916463639492873e-01, -0.0000000000000000e+00, 4.0916463639492873e-01, 8.1949868127091163e-01, 1.2322157550847530e+00, 1.6486229138923163e+00, 2.0701810760534278e+00, 2.4985856910194042e+00, 2.9358825042901264e+00, 3.3846451410922138e+00, 3.8482667922136202e+00, 4.3314782938191501e+00, 4.8413636510591642e+00, 5.3896405219667507e+00, 5.9989712894638192e+00, 6.7286951986088495e+00}, + {-6.8633452935298900e+00, -6.1382792201239331e+00, -5.5331471515674950e+00, -4.9889189685899442e+00, -4.4830553570925176e+00, -4.0039086038612286e+00, -3.5444438731553496e+00, -3.0999705295864417e+00, -2.6671321245356170e+00, -2.2433914677615041e+00, -1.8267411436036880e+00, -1.4155278001981884e+00, -1.0083382710467235e+00, -6.0392105862555223e-01, -2.0112857654887151e-01, 2.0112857654887151e-01, 6.0392105862555223e-01, 1.0083382710467235e+00, 1.4155278001981884e+00, 1.8267411436036880e+00, 2.2433914677615041e+00, 2.6671321245356170e+00, 3.0999705295864417e+00, 3.5444438731553496e+00, 4.0039086038612286e+00, 4.4830553570925176e+00, 4.9889189685899442e+00, 5.5331471515674950e+00, 6.1382792201239331e+00, 6.8633452935298900e+00}, + {-6.9956801237185395e+00, -6.2750787049428602e+00, -5.6739614446185875e+00, -5.1335955771123798e+00, -4.6315595063128594e+00, -4.1562717558181452e+00, -3.7007434032314697e+00, -3.2603207323135406e+00, -2.8316804533902054e+00, -2.4123177054804201e+00, -2.0002585489356388e+00, -1.5938858604721398e+00, -1.1918269983500462e+00, -7.9287697691530890e-01, -3.9594273647142297e-01, -0.0000000000000000e+00, 3.9594273647142297e-01, 7.9287697691530890e-01, 1.1918269983500462e+00, 1.5938858604721398e+00, 2.0002585489356388e+00, 2.4123177054804201e+00, 2.8316804533902054e+00, 3.2603207323135406e+00, 3.7007434032314697e+00, 4.1562717558181452e+00, 4.6315595063128594e+00, 5.1335955771123798e+00, 5.6739614446185875e+00, 6.2750787049428602e+00, 6.9956801237185395e+00}, + {-7.1258139098307272e+00, -6.4094981492696599e+00, -5.8122259495159128e+00, -5.2755509865158796e+00, -4.7771645035025960e+00, -4.3055479533511987e+00, -3.8537554854714444e+00, -3.4171674928185705e+00, -2.9924908250023741e+00, -2.5772495377323170e+00, -2.1694991836061122e+00, -1.7676541094632017e+00, -1.3703764109528718e+00, -9.7650046358968279e-01, -5.8497876543593241e-01, -1.9484074156939934e-01, 1.9484074156939934e-01, 5.8497876543593241e-01, 9.7650046358968279e-01, 1.3703764109528718e+00, 1.7676541094632017e+00, 2.1694991836061122e+00, 2.5772495377323170e+00, 2.9924908250023741e+00, 3.4171674928185705e+00, 3.8537554854714444e+00, 4.3055479533511987e+00, 4.7771645035025960e+00, 5.2755509865158796e+00, 5.8122259495159128e+00, 6.4094981492696599e+00, 7.1258139098307272e+00}, + {-7.2538518220151991e+00, -6.5416554457380762e+00, -5.9480711820871450e+00, -5.4149290026141923e+00, -4.9200285205950083e+00, -4.4519111488328269e+00, -4.0036716099569309e+00, -3.5707219802327179e+00, -3.1497966817038248e+00, -2.7384458243513548e+00, -2.3347511515295150e+00, -1.9371545818222065e+00, -1.5443482612431219e+00, -1.1552002041267895e+00, -7.6870137975886854e-01, -3.8392601450840907e-01, -0.0000000000000000e+00, 3.8392601450840907e-01, 7.6870137975886854e-01, 1.1552002041267895e+00, 1.5443482612431219e+00, 1.9371545818222065e+00, 2.3347511515295150e+00, 2.7384458243513548e+00, 3.1497966817038248e+00, 3.5707219802327179e+00, 4.0036716099569309e+00, 4.4519111488328269e+00, 4.9200285205950083e+00, 5.4149290026141923e+00, 5.9480711820871450e+00, 6.5416554457380762e+00, 7.2538518220151991e+00}, + {-7.3798909504812453e+00, -6.6716591360701694e+00, -6.0816169939363158e+00, -5.5518613309887774e+00, -5.0602960186057615e+00, -4.5955197481081704e+00, -4.1506656029707809e+00, -3.7211752324761531e+00, -3.3038084315644154e+00, -2.8961389431744311e+00, -2.4962719408165470e+00, -2.1026736904673324e+00, -1.7140625533873379e+00, -1.3293355518847858e+00, -9.4751645803344731e-01, -5.6771726855487448e-01, -1.8910806052714246e-01, 1.8910806052714246e-01, 5.6771726855487448e-01, 9.4751645803344731e-01, 1.3293355518847858e+00, 1.7140625533873379e+00, 2.1026736904673324e+00, 2.4962719408165470e+00, 2.8961389431744311e+00, 3.3038084315644154e+00, 3.7211752324761531e+00, 4.1506656029707809e+00, 4.5955197481081704e+00, 5.0602960186057615e+00, 5.5518613309887774e+00, 6.0816169939363158e+00, 6.6716591360701694e+00, 7.3798909504812453e+00}, + {-7.5040211464489355e+00, -6.7996094132841307e+00, -6.2129737476337166e+00, -5.6864689480904413e+00, -5.1980993461977523e+00, -4.7365184774132105e+00, -4.2948958144927625e+00, -3.8687007309691541e+00, -3.4547164957519905e+00, -3.0505384204304464e+00, -2.6542927811971722e+00, -2.2644675010425686e+00, -1.8798039887309170e+00, -1.4992244886117301e+00, -1.1217809907203027e+00, -7.4661763987986696e-01, -3.7294171704961682e-01, -0.0000000000000000e+00, 3.7294171704961682e-01, 7.4661763987986696e-01, 1.1217809907203027e+00, 1.4992244886117301e+00, 1.8798039887309170e+00, 2.2644675010425686e+00, 2.6542927811971722e+00, 3.0505384204304464e+00, 3.4547164957519905e+00, 3.8687007309691541e+00, 4.2948958144927625e+00, 4.7365184774132105e+00, 5.1980993461977523e+00, 5.6864689480904413e+00, 6.2129737476337166e+00, 6.7996094132841307e+00, 7.5040211464489355e+00}, + {-7.6263257540038927e+00, -6.9255989902599406e+00, -6.3422433309944113e+00, -5.8188632795055772e+00, -5.3335601071130636e+00, -4.8750399724670830e+00, -4.4365069701928563e+00, -4.0134565677494702e+00, -3.6026938571484757e+00, -3.2018339457881582e+00, -2.8090222351311036e+00, -2.4227660420535617e+00, -2.0418271835544202e+00, -1.6651500018434142e+00, -1.2918109588209239e+00, -9.2098180157075304e-01, -5.5190143329042274e-01, -1.8385336710581282e-01, 1.8385336710581282e-01, 5.5190143329042274e-01, 9.2098180157075304e-01, 1.2918109588209239e+00, 1.6651500018434142e+00, 2.0418271835544202e+00, 2.4227660420535617e+00, 2.8090222351311036e+00, 3.2018339457881582e+00, 3.6026938571484757e+00, 4.0134565677494702e+00, 4.4365069701928563e+00, 4.8750399724670830e+00, 5.3335601071130636e+00, 5.8188632795055772e+00, 6.3422433309944113e+00, 6.9255989902599406e+00, 7.6263257540038927e+00}, + {-7.7468822496494552e+00, -7.0497138557782293e+00, -6.4695200365240302e+00, -5.9491472174619711e+00, -5.4667903359685601e+00, -5.0112061385730726e+00, -4.5756317486673579e+00, -4.1555872811264782e+00, -3.7478982064754800e+00, -3.3501978949725357e+00, -2.9606491813032889e+00, -2.5777768581132716e+00, -2.2003609340092520e+00, -1.8273652487636047e+00, -1.4578876468742090e+00, -1.0911237649759331e+00, -7.2633961660512014e-01, -3.6284990505065795e-01, -0.0000000000000000e+00, 3.6284990505065795e-01, 7.2633961660512014e-01, 1.0911237649759331e+00, 1.4578876468742090e+00, 1.8273652487636047e+00, 2.2003609340092520e+00, 2.5777768581132716e+00, 2.9606491813032889e+00, 3.3501978949725357e+00, 3.7478982064754800e+00, 4.1555872811264782e+00, 4.5756317486673579e+00, 5.0112061385730726e+00, 5.4667903359685601e+00, 5.9491472174619711e+00, 6.4695200365240302e+00, 7.0497138557782293e+00, 7.7468822496494552e+00}, + {-7.8657628033800400e+00, -7.1720339353200302e+00, -6.5948913272654934e+00, -6.0774160035375608e+00, -5.5978935141846780e+00, -5.1451293207408231e+00, -4.7123921320848874e+00, -4.2952254197496051e+00, -3.8904737609633409e+00, -3.4957874548356260e+00, -3.1093453117179419e+00, -2.7296879628883253e+00, -2.3556117330355080e+00, -1.9860977780390656e+00, -1.6202627556330140e+00, -1.2573231317007134e+00, -8.9656834619313597e-01, -5.3733981087098337e-01, -1.7901372329587750e-01, 1.7901372329587750e-01, 5.3733981087098337e-01, 8.9656834619313597e-01, 1.2573231317007134e+00, 1.6202627556330140e+00, 1.9860977780390656e+00, 2.3556117330355080e+00, 2.7296879628883253e+00, 3.1093453117179419e+00, 3.4957874548356260e+00, 3.8904737609633409e+00, 4.2952254197496051e+00, 4.7123921320848874e+00, 5.1451293207408231e+00, 5.5978935141846780e+00, 6.0774160035375608e+00, 6.5948913272654934e+00, 7.1720339353200302e+00, 7.8657628033800400e+00}, + {-7.9830347727197806e+00, -7.2926336708657198e+00, -6.7184385064440910e+00, -6.2037579977281085e+00, -5.7269654517821049e+00, -5.2769133152304262e+00, -4.8469005687435258e+00, -4.4324928825930368e+00, -4.0305528146024674e+00, -3.6387464248745358e+00, -3.2552672359922297e+00, -2.8786703113749548e+00, -2.5077666938913192e+00, -2.1415530119868800e+00, -1.7791625828543136e+00, -1.4198301576857355e+00, -1.0628655672811786e+00, -7.0763327334857218e-01, -3.5353584699632934e-01, -0.0000000000000000e+00, 3.5353584699632934e-01, 7.0763327334857218e-01, 1.0628655672811786e+00, 1.4198301576857355e+00, 1.7791625828543136e+00, 2.1415530119868800e+00, 2.5077666938913192e+00, 2.8786703113749548e+00, 3.2552672359922297e+00, 3.6387464248745358e+00, 4.0305528146024674e+00, 4.4324928825930368e+00, 4.8469005687435258e+00, 5.2769133152304262e+00, 5.7269654517821049e+00, 6.2037579977281085e+00, 6.7184385064440910e+00, 7.2926336708657198e+00, 7.9830347727197806e+00}, + {-8.0987611392508505e+00, -7.4115825314854691e+00, -6.8402373052493548e+00, -6.3282553512200810e+00, -5.8540950560303990e+00, -5.4066542479701267e+00, -4.9792609785452555e+00, -4.5675020728443938e+00, -4.1682570668324992e+00, -3.7792067534352229e+00, -3.3985582658596281e+00, -3.0248798839012840e+00, -2.6569959984428957e+00, -2.2939171418750832e+00, -1.9347914722822956e+00, -1.5788698949316138e+00, -1.2254801090462888e+00, -8.7400661235708799e-01, -5.2387471383227713e-01, -1.7453721459758240e-01, 1.7453721459758240e-01, 5.2387471383227713e-01, 8.7400661235708799e-01, 1.2254801090462888e+00, 1.5788698949316138e+00, 1.9347914722822956e+00, 2.2939171418750832e+00, 2.6569959984428957e+00, 3.0248798839012840e+00, 3.3985582658596281e+00, 3.7792067534352229e+00, 4.1682570668324992e+00, 4.5675020728443938e+00, 4.9792609785452555e+00, 5.4066542479701267e+00, 5.8540950560303990e+00, 6.3282553512200810e+00, 6.8402373052493548e+00, 7.4115825314854691e+00, 8.0987611392508505e+00}, + {-8.2130008955982792e+00, -7.5289454645396203e+00, -6.9603584006367480e+00, -6.4509845971747524e+00, -5.9793650041651327e+00, -5.5344413406134461e+00, -5.1095696265331334e+00, -4.7003568963041156e+00, -4.3036987671546498e+00, -3.9172898548377817e+00, -3.5393499373637116e+00, -3.1684594539419857e+00, -2.8034549614843187e+00, -2.4433595531234111e+00, -2.0873346819187244e+00, -1.7346456088220295e+00, -1.3846357891600325e+00, -1.0367072529242058e+00, -6.9030505233020811e-01, -3.4490446301543276e-01, -0.0000000000000000e+00, 3.4490446301543276e-01, 6.9030505233020811e-01, 1.0367072529242058e+00, 1.3846357891600325e+00, 1.7346456088220295e+00, 2.0873346819187244e+00, 2.4433595531234111e+00, 2.8034549614843187e+00, 3.1684594539419857e+00, 3.5393499373637116e+00, 3.9172898548377817e+00, 4.3036987671546498e+00, 4.7003568963041156e+00, 5.1095696265331334e+00, 5.5344413406134461e+00, 5.9793650041651327e+00, 6.4509845971747524e+00, 6.9603584006367480e+00, 7.5289454645396203e+00, 8.2130008955982792e+00}, + {-8.3258093895669294e+00, -7.6447832957047419e+00, -7.0788678730491084e+00, -6.5720171713874747e+00, -6.1028523343815264e+00, -5.6603575812830567e+00, -5.2379158850176495e+00, -4.8311536291282762e+00, -4.4369817058810304e+00, -4.0531077444247670e+00, -3.6777633163885568e+00, -3.3095400965109221e+00, -2.9472857823054786e+00, -2.5900348706171261e+00, -2.2369607870543176e+00, -1.8873416205434848e+00, -1.5405348009155460e+00, -1.1959577943778097e+00, -8.5307290916055367e-01, -5.1137491831546933e-01, -1.7038058556181696e-01, 1.7038058556181696e-01, 5.1137491831546933e-01, 8.5307290916055367e-01, 1.1959577943778097e+00, 1.5405348009155460e+00, 1.8873416205434848e+00, 2.2369607870543176e+00, 2.5900348706171261e+00, 2.9472857823054786e+00, 3.3095400965109221e+00, 3.6777633163885568e+00, 4.0531077444247670e+00, 4.4369817058810304e+00, 4.8311536291282762e+00, 5.2379158850176495e+00, 5.6603575812830567e+00, 6.1028523343815264e+00, 6.5720171713874747e+00, 7.0788678730491084e+00, 7.6447832957047419e+00, 8.3258093895669294e+00}, + {-8.4372386310833765e+00, -7.7591530847325343e+00, -7.1958276123464335e+00, -6.6914198727121068e+00, -6.2246289668942199e+00, -5.7844803140775571e+00, -5.3643829011515560e+00, -4.9599816751949550e+00, -4.5682020755441552e+00, -4.1867640213660025e+00, -3.8139101240654272e+00, -3.4482424822200026e+00, -3.0886190396004185e+00, -2.7340846945379047e+00, -2.3838237072843595e+00, -2.0371256888641933e+00, -1.6933605309399098e+00, -1.3519593686708704e+00, -1.0123996845633196e+00, -6.7419327674231389e-01, -3.3687619662553298e-01, -0.0000000000000000e+00, 3.3687619662553298e-01, 6.7419327674231389e-01, 1.0123996845633196e+00, 1.3519593686708704e+00, 1.6933605309399098e+00, 2.0371256888641933e+00, 2.3838237072843595e+00, 2.7340846945379047e+00, 3.0886190396004185e+00, 3.4482424822200026e+00, 3.8139101240654272e+00, 4.1867640213660025e+00, 4.5682020755441552e+00, 4.9599816751949550e+00, 5.3643829011515560e+00, 5.7844803140775571e+00, 6.2246289668942199e+00, 6.6914198727121068e+00, 7.1958276123464335e+00, 7.7591530847325343e+00, 8.4372386310833765e+00}, + {-8.5473375667355391e+00, -7.8721084427748513e+00, -7.3112956789163306e+00, -6.8092552715358323e+00, -6.3447621648968919e+00, -5.9068817590275451e+00, -5.4890481838807421e+00, -5.0869242297582531e+00, -4.6974492230014393e+00, -4.3183547234421118e+00, -3.9478937115246548e+00, -3.5846779931052279e+00, -3.2275749742774260e+00, -2.8756390821704421e+00, -2.5280644271476649e+00, -2.1841510195665261e+00, -1.8432799206176103e+00, -1.5048944344828714e+00, -1.1684854631902055e+00, -8.3357976100207332e-01, -4.9973020830067427e-01, -1.6650746707363237e-01, 1.6650746707363237e-01, 4.9973020830067427e-01, 8.3357976100207332e-01, 1.1684854631902055e+00, 1.5048944344828714e+00, 1.8432799206176103e+00, 2.1841510195665261e+00, 2.5280644271476649e+00, 2.8756390821704421e+00, 3.2275749742774260e+00, 3.5846779931052279e+00, 3.9478937115246548e+00, 4.3183547234421118e+00, 4.6974492230014393e+00, 5.0869242297582531e+00, 5.4890481838807421e+00, 5.9068817590275451e+00, 6.3447621648968919e+00, 6.8092552715358323e+00, 7.3112956789163306e+00, 7.8721084427748513e+00, 8.5473375667355391e+00}, + {-8.6561523259903268e+00, -7.9836998162220016e+00, -7.4253266258561936e+00, -6.9255820732775950e+00, -6.4633149436642530e+00, -6.0276294722536941e+00, -5.6119841218396642e+00, -5.2120588631620075e+00, -4.8248063087032573e+00, -4.4479690736019313e+00, -4.0798099079253927e+00, -3.7189496893415628e+00, -3.3642645958565400e+00, -3.0148178197492252e+00, -2.6698124652513462e+00, -2.3285579714531894e+00, -1.9904454586466382e+00, -1.6549291191547923e+00, -1.3215117856392311e+00, -9.8973342486571125e-01, -6.5916168887413507e-01, -3.2938389969666915e-01, -0.0000000000000000e+00, 3.2938389969666915e-01, 6.5916168887413507e-01, 9.8973342486571125e-01, 1.3215117856392311e+00, 1.6549291191547923e+00, 1.9904454586466382e+00, 2.3285579714531894e+00, 2.6698124652513462e+00, 3.0148178197492252e+00, 3.3642645958565400e+00, 3.7189496893415628e+00, 4.0798099079253927e+00, 4.4479690736019313e+00, 4.8248063087032573e+00, 5.2120588631620075e+00, 5.6119841218396642e+00, 6.0276294722536941e+00, 6.4633149436642530e+00, 6.9255820732775950e+00, 7.4253266258561936e+00, 7.9836998162220016e+00, 8.6561523259903268e+00}, + {-8.7637264425763934e+00, -8.0939747412671181e+00, -7.5379717872258256e+00, -7.0404554428052171e+00, -6.5803464347374083e+00, -6.1467867545054018e+00, -5.7332584418499435e+00, -5.3354580360572301e+00, -4.9503508867398853e+00, -4.5756901345704328e+00, -4.2097477613269749e+00, -3.8511531505025514e+00, -3.4987906412463645e+00, -3.1517315196384712e+00, -2.8091871354772668e+00, -2.4704755132281426e+00, -2.1349968729707256e+00, -1.8022151950574945e+00, -1.4716439717320722e+00, -1.1428349031264304e+00, -8.1536867934468149e-01, -4.8884723585117468e-01, -1.6288702795526222e-01, 1.6288702795526222e-01, 4.8884723585117468e-01, 8.1536867934468149e-01, 1.1428349031264304e+00, 1.4716439717320722e+00, 1.8022151950574945e+00, 2.1349968729707256e+00, 2.4704755132281426e+00, 2.8091871354772668e+00, 3.1517315196384712e+00, 3.4987906412463645e+00, 3.8511531505025514e+00, 4.2097477613269749e+00, 4.5756901345704328e+00, 4.9503508867398853e+00, 5.3354580360572301e+00, 5.7332584418499435e+00, 6.1467867545054018e+00, 6.5803464347374083e+00, 7.0404554428052171e+00, 7.5379717872258256e+00, 8.0939747412671181e+00, 8.7637264425763934e+00}, + {-8.8701010540232534e+00, -8.2029780727977943e+00, -7.6492795366289874e+00, -7.1539272947757162e+00, -6.6959122110632512e+00, -6.2644130149704740e+00, -5.8529346161254212e+00, -5.4571895556816514e+00, -5.0741554169850653e+00, -4.7015953849679351e+00, -4.3377901884924199e+00, -3.9813772107064693e+00, -3.6312484092926161e+00, -3.2864825713246675e+00, -2.9462986351921705e+00, -2.6100224744061520e+00, -2.2770625758595000e+00, -1.9468917579991860e+00, -1.6190330813590508e+00, -1.2930487170109526e+00, -9.6853092273781483e-01, -6.4509452302768844e-01, -3.2237044915615060e-01, -0.0000000000000000e+00, 3.2237044915615060e-01, 6.4509452302768844e-01, 9.6853092273781483e-01, 1.2930487170109526e+00, 1.6190330813590508e+00, 1.9468917579991860e+00, 2.2770625758595000e+00, 2.6100224744061520e+00, 2.9462986351921705e+00, 3.2864825713246675e+00, 3.6312484092926161e+00, 3.9813772107064693e+00, 4.3377901884924199e+00, 4.7015953849679351e+00, 5.0741554169850653e+00, 5.4571895556816514e+00, 5.8529346161254212e+00, 6.2644130149704740e+00, 6.6959122110632512e+00, 7.1539272947757162e+00, 7.6492795366289874e+00, 8.2029780727977943e+00, 8.8701010540232534e+00}, + {-8.9753150819316865e+00, -8.3107521907047843e+00, -7.7592955197657743e+00, -7.2660465541643502e+00, -6.8100645780741411e+00, -6.3805640961864096e+00, -5.9710722250135460e+00, -5.5773169812237278e+00, -5.1962877187923642e+00, -4.8257572281332095e+00, -4.4640145469344583e+00, -4.1097046035605898e+00, -3.7617264902283578e+00, -3.4191659693638847e+00, -3.0812489886451053e+00, -2.7473086248223830e+00, -2.4167609048732164e+00, -2.0890866609442762e+00, -1.7638175798953000e+00, -1.4405252201375651e+00, -1.1188121524021566e+00, -7.9830462777856215e-01, -4.7864633759449599e-01, -1.5949293584886245e-01, 1.5949293584886245e-01, 4.7864633759449599e-01, 7.9830462777856215e-01, 1.1188121524021566e+00, 1.4405252201375651e+00, 1.7638175798953000e+00, 2.0890866609442762e+00, 2.4167609048732164e+00, 2.7473086248223830e+00, 3.0812489886451053e+00, 3.4191659693638847e+00, 3.7617264902283578e+00, 4.1097046035605898e+00, 4.4640145469344583e+00, 4.8257572281332095e+00, 5.1962877187923642e+00, 5.5773169812237278e+00, 5.9710722250135460e+00, 6.3805640961864096e+00, 6.8100645780741411e+00, 7.2660465541643502e+00, 7.7592955197657743e+00, 8.3107521907047843e+00, 8.9753150819316865e+00}, + {-9.0794053951994336e+00, -8.4173371862679787e+00, -7.8680628640816641e+00, -7.3768593906319282e+00, -6.9228528349597616e+00, -6.4952925650076585e+00, -6.0877272810547556e+00, -5.6958999850352088e+00, -5.3168113741835157e+00, -4.9482434430048912e+00, -4.5884931402744824e+00, -4.2362125300687872e+00, -3.8903074057661615e+00, -3.5498700372120946e+00, -3.2141328684568560e+00, -2.8824356106455995e+00, -2.5542011939519624e+00, -2.2289177453859468e+00, -1.9061247609883607e+00, -1.5854022514550468e+00, -1.2663620236873581e+00, -9.4864050761025742e-01, -6.3189269951096161e-01, -3.1578690052375491e-01, -0.0000000000000000e+00, 3.1578690052375491e-01, 6.3189269951096161e-01, 9.4864050761025742e-01, 1.2663620236873581e+00, 1.5854022514550468e+00, 1.9061247609883607e+00, 2.2289177453859468e+00, 2.5542011939519624e+00, 2.8824356106455995e+00, 3.2141328684568560e+00, 3.5498700372120946e+00, 3.8903074057661615e+00, 4.2362125300687872e+00, 4.5884931402744824e+00, 4.9482434430048912e+00, 5.3168113741835157e+00, 5.6958999850352088e+00, 6.0877272810547556e+00, 6.4952925650076585e+00, 6.9228528349597616e+00, 7.3768593906319282e+00, 7.8680628640816641e+00, 8.4173371862679787e+00, 9.0794053951994336e+00}, + {-9.1824069581293166e+00, -8.5227710309178022e+00, -7.9756223682056362e+00, -7.4864094298641941e+00, -7.0343235097706103e+00, -6.6086479738553576e+00, -6.2029525192746719e+00, -5.8129946754204047e+00, -5.4357860872249475e+00, -5.0691175849172350e+00, -4.7112936661690421e+00, -4.3609731604545781e+00, -4.0170681728581341e+00, -3.6786770625152689e+00, -3.3450383139378910e+00, -3.0154977695745222e+00, -2.6894847022677451e+00, -2.3664939042986637e+00, -2.0460719686864088e+00, -1.7278065475158983e+00, -1.4113177548982998e+00, -1.0962511289576817e+00, -7.8227172955460689e-01, -4.6905905667823600e-01, -1.5630254688946871e-01, 1.5630254688946871e-01, 4.6905905667823600e-01, 7.8227172955460689e-01, 1.0962511289576817e+00, 1.4113177548982998e+00, 1.7278065475158983e+00, 2.0460719686864088e+00, 2.3664939042986637e+00, 2.6894847022677451e+00, 3.0154977695745222e+00, 3.3450383139378910e+00, 3.6786770625152689e+00, 4.0170681728581341e+00, 4.3609731604545781e+00, 4.7112936661690421e+00, 5.0691175849172350e+00, 5.4357860872249475e+00, 5.8129946754204047e+00, 6.2029525192746719e+00, 6.6086479738553576e+00, 7.0343235097706103e+00, 7.4864094298641941e+00, 7.9756223682056362e+00, 8.5227710309178022e+00, 9.1824069581293166e+00}, + {-9.2843529650947954e+00, -8.6270897293636839e+00, -8.0820126735040123e+00, -7.5947379445835947e+00, -7.1445205714796174e+00, -6.7206770958687514e+00, -6.3167976579034049e+00, -5.9286538858731372e+00, -5.5532680052649175e+00, -5.1884393429381372e+00, -4.8324796145780748e+00, -4.4840540790573504e+00, -4.1420808019620621e+00, -3.8056638567519334e+00, -3.4740473616558587e+00, -3.1465828437716956e+00, -2.8227054233054294e+00, -2.5019160040577368e+00, -2.1837676525361926e+00, -1.8678549556995603e+00, -1.5538055294554218e+00, -1.2412730966236114e+00, -9.2993171560017596e-01, -6.1947084974715272e-01, -3.0959104093724038e-01, -0.0000000000000000e+00, 3.0959104093724038e-01, 6.1947084974715272e-01, 9.2993171560017596e-01, 1.2412730966236114e+00, 1.5538055294554218e+00, 1.8678549556995603e+00, 2.1837676525361926e+00, 2.5019160040577368e+00, 2.8227054233054294e+00, 3.1465828437716956e+00, 3.4740473616558587e+00, 3.8056638567519334e+00, 4.1420808019620621e+00, 4.4840540790573504e+00, 4.8324796145780748e+00, 5.1884393429381372e+00, 5.5532680052649175e+00, 5.9286538858731372e+00, 6.3167976579034049e+00, 6.7206770958687514e+00, 7.1445205714796174e+00, 7.5947379445835947e+00, 8.0820126735040123e+00, 8.6270897293636839e+00, 9.2843529650947954e+00}, + {-9.3852749632231376e+00, -8.7303274588209110e+00, -8.1872704197671577e+00, -7.7018840275679166e+00, -7.2534856216969716e+00, -6.8314241370686029e+00, -6.4293096331149808e+00, -6.0429274349196920e+00, -5.6693100068563673e+00, -5.3062648593656414e+00, -4.9521106229353720e+00, -4.6055186799962122e+00, -4.2654127388779193e+00, -3.9309022499573141e+00, -3.6012366010181420e+00, -3.2757726058076915e+00, -2.9539507925538842e+00, -2.6352776875892849e+00, -2.3193122827994568e+00, -2.0056554817328660e+00, -1.6939417005414366e+00, -1.3838320462108629e+00, -1.0750086571198576e+00, -7.6716990012409136e-01, -4.6002619243746073e-01, -1.5329626692045756e-01, 1.5329626692045756e-01, 4.6002619243746073e-01, 7.6716990012409136e-01, 1.0750086571198576e+00, 1.3838320462108629e+00, 1.6939417005414366e+00, 2.0056554817328660e+00, 2.3193122827994568e+00, 2.6352776875892849e+00, 2.9539507925538842e+00, 3.2757726058076915e+00, 3.6012366010181420e+00, 3.9309022499573141e+00, 4.2654127388779193e+00, 4.6055186799962122e+00, 4.9521106229353720e+00, 5.3062648593656414e+00, 5.6693100068563673e+00, 6.0429274349196920e+00, 6.4293096331149808e+00, 6.8314241370686029e+00, 7.2534856216969716e+00, 7.7018840275679166e+00, 8.1872704197671577e+00, 8.7303274588209110e+00, 9.3852749632231376e+00}, + {-9.4852029643727302e+00, -8.8325166958454133e+00, -8.2914303867830093e+00, -7.8078847487003955e+00, -7.3612580683690458e+00, -6.9409309282147520e+00, -6.5405328108757619e+00, -6.1558623601311924e+00, -5.7839619604859447e+00, -5.4226470161614522e+00, -5.0702427937817154e+00, -4.7254265200961152e+00, -4.3871272577720717e+00, -4.0544595295034727e+00, -3.7266776654942122e+00, -3.4031434102599176e+00, -3.0833023089391358e+00, -2.7666660769675384e+00, -2.4527991478588032e+00, -2.1413081984302371e+00, -1.8318338313140423e+00, -1.5240438405087577e+00, -1.2176276482547366e+00, -9.1229161088998856e-01, -6.0775496588729694e-01, -3.0374624334991529e-01, -0.0000000000000000e+00, 3.0374624334991529e-01, 6.0775496588729694e-01, 9.1229161088998856e-01, 1.2176276482547366e+00, 1.5240438405087577e+00, 1.8318338313140423e+00, 2.1413081984302371e+00, 2.4527991478588032e+00, 2.7666660769675384e+00, 3.0833023089391358e+00, 3.4031434102599176e+00, 3.7266776654942122e+00, 4.0544595295034727e+00, 4.3871272577720717e+00, 4.7254265200961152e+00, 5.0702427937817154e+00, 5.4226470161614522e+00, 5.7839619604859447e+00, 6.1558623601311924e+00, 6.5405328108757619e+00, 6.9409309282147520e+00, 7.3612580683690458e+00, 7.8078847487003955e+00, 8.2914303867830093e+00, 8.8325166958454133e+00, 9.4852029643727302e+00}, + {-9.5841655475234688e+00, -8.9336883320961924e+00, -8.3945256233272012e+00, -7.9127752978124946e+00, -7.4678752834836200e+00, -7.0492370986783772e+00, -6.6505091785664918e+00, -6.2675031293697510e+00, -5.8972709576411209e+00, -5.5376356924033008e+00, -5.1869289795928895e+00, -4.8438336345819870e+00, -4.5072838118199003e+00, -4.1763988304784849e+00, -3.8504376683661063e+00, -3.5287666814910854e+00, -3.2108360825282936e+00, -2.8961623904571474e+00, -2.5843150518736273e+00, -2.2749060375416974e+00, -1.9675815973920669e+00, -1.6620156026589967e+00, -1.3579040662442226e+00, -1.0549605418738988e+00, -7.5291217747488703e-01, -4.5149624980624264e-01, -1.5045704292086298e-01, 1.5045704292086298e-01, 4.5149624980624264e-01, 7.5291217747488703e-01, 1.0549605418738988e+00, 1.3579040662442226e+00, 1.6620156026589967e+00, 1.9675815973920669e+00, 2.2749060375416974e+00, 2.5843150518736273e+00, 2.8961623904571474e+00, 3.2108360825282936e+00, 3.5287666814910854e+00, 3.8504376683661063e+00, 4.1763988304784849e+00, 4.5072838118199003e+00, 4.8438336345819870e+00, 5.1869289795928895e+00, 5.5376356924033008e+00, 5.8972709576411209e+00, 6.2675031293697510e+00, 6.6505091785664918e+00, 7.0492370986783772e+00, 7.4678752834836200e+00, 7.9127752978124946e+00, 8.3945256233272012e+00, 8.9336883320961924e+00, 9.5841655475234688e+00}, + {-9.6821899525637249e+00, -9.0338717801824053e+00, -8.4965875649075624e+00, -8.0165891148558295e+00, -7.5733727465411995e+00, -7.1563802343429099e+00, -6.7592785186840851e+00, -6.3778918319127680e+00, -6.0092815232536667e+00, -5.6512779962558639e+00, -5.3022190388457897e+00, -4.9607928202275557e+00, -4.6259383469194120e+00, -4.2967794840336984e+00, -3.9725795904787460e+00, -3.6527093464132974e+00, -3.3366233189341656e+00, -3.0238424864191802e+00, -2.7139409275560999e+00, -2.4065354826206522e+00, -2.1012775733291407e+00, -1.7978466126036980e+00, -1.4959445977962444e+00, -1.1952915904152335e+00, -8.9562186046229086e-01, -5.9668052547571682e-01, -2.9822055049276669e-01, -0.0000000000000000e+00, 2.9822055049276669e-01, 5.9668052547571682e-01, 8.9562186046229086e-01, 1.1952915904152335e+00, 1.4959445977962444e+00, 1.7978466126036980e+00, 2.1012775733291407e+00, 2.4065354826206522e+00, 2.7139409275560999e+00, 3.0238424864191802e+00, 3.3366233189341656e+00, 3.6527093464132974e+00, 3.9725795904787460e+00, 4.2967794840336984e+00, 4.6259383469194120e+00, 4.9607928202275557e+00, 5.3022190388457897e+00, 5.6512779962558639e+00, 6.0092815232536667e+00, 6.3778918319127680e+00, 6.7592785186840851e+00, 7.1563802343429099e+00, 7.5733727465411995e+00, 8.0165891148558295e+00, 8.4965875649075624e+00, 9.0338717801824053e+00, 9.6821899525637249e+00}, + {-9.7793021663403099e+00, -9.1330950706121001e+00, -8.5976461414362131e+00, -8.1193580087474686e+00, -7.6777841753281493e+00, -7.2623960212867891e+00, -6.8668785666252870e+00, -6.4870683517446244e+00, -6.1200358061419919e+00, -5.7636184744715768e+00, -5.4161600667900469e+00, -5.0763538899639924e+00, -4.7431435831181288e+00, -4.4156573291002159e+00, -4.0931626262997982e+00, -3.7750342196411242e+00, -3.4607307491477983e+00, -3.1497773444199684e+00, -2.8417523763809922e+00, -2.5362771776597737e+00, -2.2330079208452407e+00, -1.9316290883640068e+00, -1.6318481297059444e+00, -1.3333910111792098e+00, -1.0359984385570031e+00, -7.3942258523430104e-01, -4.4342419505035346e-01, -1.4776995439420115e-01, 1.4776995439420115e-01, 4.4342419505035346e-01, 7.3942258523430104e-01, 1.0359984385570031e+00, 1.3333910111792098e+00, 1.6318481297059444e+00, 1.9316290883640068e+00, 2.2330079208452407e+00, 2.5362771776597737e+00, 2.8417523763809922e+00, 3.1497773444199684e+00, 3.4607307491477983e+00, 3.7750342196411242e+00, 4.0931626262997982e+00, 4.4156573291002159e+00, 4.7431435831181288e+00, 5.0763538899639924e+00, 5.4161600667900469e+00, 5.7636184744715768e+00, 6.1200358061419919e+00, 6.4870683517446244e+00, 6.8668785666252870e+00, 7.2623960212867891e+00, 7.6777841753281493e+00, 8.1193580087474686e+00, 8.5976461414362131e+00, 9.1330950706121001e+00, 9.7793021663403099e+00}, + {-9.8755270017367671e+00, -9.2313849407386552e+00, -8.6977298758606238e+00, -8.2211122660677169e+00, -7.7811416453357003e+00, -7.3673183767785728e+00, -6.9733451542956244e+00, -6.5950705250038864e+00, -6.2295737517233460e+00, -5.8746993020212539e+00, -5.5287966039093659e+00, -5.1905639023838361e+00, -4.8589492677211483e+00, -4.5330849920738157e+00, -4.2122424936406224e+00, -3.8958003472863840e+00, -3.5832210121368786e+00, -3.2740334921948340e+00, -2.9678201464818930e+00, -2.6642064637087906e+00, -2.3628529934485321e+00, -2.0634488697846303e+00, -1.7657065251132762e+00, -1.4693573011471874e+00, -1.1741477394031905e+00, -8.7983638589173074e-01, -5.8619098157190686e-01, -2.9298593604778866e-01, -0.0000000000000000e+00, 2.9298593604778866e-01, 5.8619098157190686e-01, 8.7983638589173074e-01, 1.1741477394031905e+00, 1.4693573011471874e+00, 1.7657065251132762e+00, 2.0634488697846303e+00, 2.3628529934485321e+00, 2.6642064637087906e+00, 2.9678201464818930e+00, 3.2740334921948340e+00, 3.5832210121368786e+00, 3.8958003472863840e+00, 4.2122424936406224e+00, 4.5330849920738157e+00, 4.8589492677211483e+00, 5.1905639023838361e+00, 5.5287966039093659e+00, 5.8746993020212539e+00, 6.2295737517233460e+00, 6.5950705250038864e+00, 6.9733451542956244e+00, 7.3673183767785728e+00, 7.7811416453357003e+00, 8.2211122660677169e+00, 8.6977298758606238e+00, 9.2313849407386552e+00, 9.8755270017367671e+00}, + {-9.9708881704574601e+00, -9.3287669164964395e+00, -8.7968659746627651e+00, -8.3218807506473613e+00, -7.8834756990041477e+00, -7.4711795689242475e+00, -7.0787123410660744e+00, -6.7019342833176401e+00, -6.3379332589686221e+00, -5.9845604541065045e+00, -5.6401708246496867e+00, -5.3034673690975112e+00, -4.9734024034844930e+00, -4.6491121384000209e+00, -4.3298717115959429e+00, -4.0150633146984989e+00, -3.7041529964080997e+00, -3.3966733857420293e+00, -3.0922105568140124e+00, -2.7903938536440540e+00, -2.4908878695658663e+00, -2.1933860192661303e+00, -1.8976053029060733e+00, -1.6032819710214761e+00, -1.3101678741366003e+00, -1.0180273335786967e+00, -7.2663440704649163e-01, -4.3577044873391346e-01, -1.4522188229810670e-01, 1.4522188229810670e-01, 4.3577044873391346e-01, 7.2663440704649163e-01, 1.0180273335786967e+00, 1.3101678741366003e+00, 1.6032819710214761e+00, 1.8976053029060733e+00, 2.1933860192661303e+00, 2.4908878695658663e+00, 2.7903938536440540e+00, 3.0922105568140124e+00, 3.3966733857420293e+00, 3.7041529964080997e+00, 4.0150633146984989e+00, 4.3298717115959429e+00, 4.6491121384000209e+00, 4.9734024034844930e+00, 5.3034673690975112e+00, 5.6401708246496867e+00, 5.9845604541065045e+00, 6.3379332589686221e+00, 6.7019342833176401e+00, 7.0787123410660744e+00, 7.4711795689242475e+00, 7.8834756990041477e+00, 8.3218807506473613e+00, 8.7968659746627651e+00, 9.3287669164964395e+00, 9.9708881704574601e+00}, + {-1.0065408350118513e+01, -9.4252653876263999e+00, -8.8950804110294346e+00, -8.4216909949586132e+00, -7.9848154458297120e+00, -7.5740103261427940e+00, -7.1830125334106762e+00, -6.8076937845356600e+00, -6.4451503233185363e+00, -6.0932398625106678e+00, -5.7503227086468636e+00, -5.4151064424967945e+00, -5.0865474548246592e+00, -4.7637856994329741e+00, -4.4460998505989417e+00, -4.1328755226679874e+00, -3.8235821457915500e+00, -3.5177557486926583e+00, -3.2149858747990203e+00, -2.9149054536014392e+00, -2.6171828242728932e+00, -2.3215153515122373e+00, -2.0276242346848043e+00, -1.7352502204281328e+00, -1.4441500040985724e+00, -1.1540931580511036e+00, -8.6485946196705754e-01, -5.7623653694114951e-01, -2.8801770388153508e-01, -0.0000000000000000e+00, 2.8801770388153508e-01, 5.7623653694114951e-01, 8.6485946196705754e-01, 1.1540931580511036e+00, 1.4441500040985724e+00, 1.7352502204281328e+00, 2.0276242346848043e+00, 2.3215153515122373e+00, 2.6171828242728932e+00, 2.9149054536014392e+00, 3.2149858747990203e+00, 3.5177557486926583e+00, 3.8235821457915500e+00, 4.1328755226679874e+00, 4.4460998505989417e+00, 4.7637856994329741e+00, 5.0865474548246592e+00, 5.4151064424967945e+00, 5.7503227086468636e+00, 6.0932398625106678e+00, 6.4451503233185363e+00, 6.8076937845356600e+00, 7.1830125334106762e+00, 7.5740103261427940e+00, 7.9848154458297120e+00, 8.4216909949586132e+00, 8.8950804110294346e+00, 9.4252653876263999e+00, 1.0065408350118513e+01}, + {-1.0159109246180085e+01, -9.5209036770133171e+00, -8.9923980014049434e+00, -8.5205692841176308e+00, -8.0851886542490199e+00, -7.6758399375048869e+00, -7.2862765943955985e+00, -6.9123815321893174e+00, -6.5512591670629208e+00, -6.2007735579934371e+00, -5.8592901963942339e+00, -5.5255210861386832e+00, -5.1984265345762939e+00, -4.8771500774731509e+00, -4.5609737579358356e+00, -4.2492864359560061e+00, -3.9415607339261842e+00, -3.6373358761707317e+00, -3.3362046535475867e+00, -3.0378033382307490e+00, -2.7418037480696915e+00, -2.4479069023076856e+00, -2.1558378712292110e+00, -1.8653415312330315e+00, -1.5761790119750203e+00, -1.2881246748688935e+00, -1.0009634995607180e+00, -7.1448878167257845e-01, -4.2850006422062747e-01, -1.4280123870343886e-01, 1.4280123870343886e-01, 4.2850006422062747e-01, 7.1448878167257845e-01, 1.0009634995607180e+00, 1.2881246748688935e+00, 1.5761790119750203e+00, 1.8653415312330315e+00, 2.1558378712292110e+00, 2.4479069023076856e+00, 2.7418037480696915e+00, 3.0378033382307490e+00, 3.3362046535475867e+00, 3.6373358761707317e+00, 3.9415607339261842e+00, 4.2492864359560061e+00, 4.5609737579358356e+00, 4.8771500774731509e+00, 5.1984265345762939e+00, 5.5255210861386832e+00, 5.8592901963942339e+00, 6.2007735579934371e+00, 6.5512591670629208e+00, 6.9123815321893174e+00, 7.2862765943955985e+00, 7.6758399375048869e+00, 8.0851886542490199e+00, 8.5205692841176308e+00, 8.9923980014049434e+00, 9.5209036770133171e+00, 1.0159109246180085e+01}, + {-1.0252011649196143e+01, -9.6157041046875609e+00, -9.0888424760573390e+00, -8.6185407332142496e+00, -8.1846218361099510e+00, -7.7766963448476236e+00, -7.3885339440499829e+00, -7.0160284848388690e+00, -6.6562923584988729e+00, -6.3071958002194259e+00, -5.9671093310413950e+00, -5.6347492296736759e+00, -5.3090795734924505e+00, -4.9892473314939929e+00, -4.6745377615999182e+00, -4.3643428074654231e+00, -4.0581381112767332e+00, -3.7554659075853780e+00, -3.4559220338316390e+00, -3.1591458858192856e+00, -2.8648125198053043e+00, -2.5726263447097191e+00, -2.2823160084101848e+00, -1.9936301908281084e+00, -1.7063340915790624e+00, -1.4202064526026656e+00, -1.1350369935815596e+00, -8.5062416477081448e-01, -5.6677314117022048e-01, -2.8329399584293824e-01, -0.0000000000000000e+00, 2.8329399584293824e-01, 5.6677314117022048e-01, 8.5062416477081448e-01, 1.1350369935815596e+00, 1.4202064526026656e+00, 1.7063340915790624e+00, 1.9936301908281084e+00, 2.2823160084101848e+00, 2.5726263447097191e+00, 2.8648125198053043e+00, 3.1591458858192856e+00, 3.4559220338316390e+00, 3.7554659075853780e+00, 4.0581381112767332e+00, 4.3643428074654231e+00, 4.6745377615999182e+00, 4.9892473314939929e+00, 5.3090795734924505e+00, 5.6347492296736759e+00, 5.9671093310413950e+00, 6.3071958002194259e+00, 6.6562923584988729e+00, 7.0160284848388690e+00, 7.3885339440499829e+00, 7.7766963448476236e+00, 8.1846218361099510e+00, 8.6185407332142496e+00, 9.0888424760573390e+00, 9.6157041046875609e+00, 1.0252011649196143e+01}, + {-1.0344135487806895e+01, -9.7096880469839437e+00, -9.1844365442194498e+00, -8.7156293586041365e+00, -8.2831403244454158e+00, -7.8766062274725090e+00, -7.4898126515277026e+00, -7.1186641563335851e+00, -6.7602809210235622e+00, -6.4125391965266108e+00, -6.0738143878025932e+00, -5.7428269099958227e+00, -5.4185444743952305e+00, -5.1001173457332412e+00, -4.7868338549738239e+00, -4.4780888809091079e+00, -4.1733609279699495e+00, -3.8721950721542884e+00, -3.5741900152128512e+00, -3.2789880784162539e+00, -2.9862673397528621e+00, -2.6957353597041749e+00, -2.4071241008699498e+00, -2.1201857552620891e+00, -1.8346892680544815e+00, -1.5504173991942523e+00, -1.2671642017112603e+00, -9.8473282246759541e-01, -7.0293355055041085e-01, -4.2158205259642756e-01, -1.4049774444160384e-01, 1.4049774444160384e-01, 4.2158205259642756e-01, 7.0293355055041085e-01, 9.8473282246759541e-01, 1.2671642017112603e+00, 1.5504173991942523e+00, 1.8346892680544815e+00, 2.1201857552620891e+00, 2.4071241008699498e+00, 2.6957353597041749e+00, 2.9862673397528621e+00, 3.2789880784162539e+00, 3.5741900152128512e+00, 3.8721950721542884e+00, 4.1733609279699495e+00, 4.4780888809091079e+00, 4.7868338549738239e+00, 5.1001173457332412e+00, 5.4185444743952305e+00, 5.7428269099958227e+00, 6.0738143878025932e+00, 6.4125391965266108e+00, 6.7602809210235622e+00, 7.1186641563335851e+00, 7.4898126515277026e+00, 7.8766062274725090e+00, 8.2831403244454158e+00, 8.7156293586041365e+00, 9.1844365442194498e+00, 9.7096880469839437e+00, 1.0344135487806895e+01}, + {-1.0435499877854168e+01, -9.8028759912974959e+00, -9.2792019543050390e+00, -8.8118581437284540e+00, -8.3807683451863202e+00, -7.9755950801420372e+00, -7.5901395198641071e+00, -7.2203167078889665e+00, -6.8632544331795353e+00, -6.5168348106821155e+00, -6.1794379922705955e+00, -5.8497884000810672e+00, -5.5268572526403030e+00, -5.2097979830408345e+00, -4.8979018644975740e+00, -4.5905665744435185e+00, -4.2872733352824408e+00, -3.9875699104197153e+00, -3.6910577000963465e+00, -3.3973817713303909e+00, -3.1062230279282566e+00, -2.8172919672837975e+00, -2.5303236304712007e+00, -2.2450734604812066e+00, -1.9613138583081484e+00, -1.6788312791720135e+00, -1.3974237486049623e+00, -1.1168987050996462e+00, -8.3707109558947612e-01, -5.5776166427908214e-01, -2.7879538567115225e-01, -0.0000000000000000e+00, 2.7879538567115225e-01, 5.5776166427908214e-01, 8.3707109558947612e-01, 1.1168987050996462e+00, 1.3974237486049623e+00, 1.6788312791720135e+00, 1.9613138583081484e+00, 2.2450734604812066e+00, 2.5303236304712007e+00, 2.8172919672837975e+00, 3.1062230279282566e+00, 3.3973817713303909e+00, 3.6910577000963465e+00, 3.9875699104197153e+00, 4.2872733352824408e+00, 4.5905665744435185e+00, 4.8979018644975740e+00, 5.2097979830408345e+00, 5.5268572526403030e+00, 5.8497884000810672e+00, 6.1794379922705955e+00, 6.5168348106821155e+00, 6.8632544331795353e+00, 7.2203167078889665e+00, 7.5901395198641071e+00, 7.9755950801420372e+00, 8.3807683451863202e+00, 8.8118581437284540e+00, 9.2792019543050390e+00, 9.8028759912974959e+00, 1.0435499877854168e+01}, + {-1.0526123167960545e+01, -9.8952875868295376e+00, -9.3731595496467204e+00, -8.9072490999647691e+00, -8.4775290833798636e+00, -8.0736872850102248e+00, -7.6895401640404968e+00, -7.3210130327809484e+00, -6.9652411205511076e+00, -6.6201122626360274e+00, -6.2840112287748280e+00, -5.9556663267994852e+00, -5.6340521643499724e+00, -5.3183252246332708e+00, -5.0077796021987675e+00, -4.7018156474074990e+00, -4.3999171682281375e+00, -4.1016344745666560e+00, -3.8065715139453600e+00, -3.5143759357409059e+00, -3.2247312919920357e+00, -2.9373508230046212e+00, -2.6519724354306349e+00, -2.3683545886324011e+00, -2.0862728798817618e+00, -1.8055171714655447e+00, -1.5258891402098638e+00, -1.2472001569431179e+00, -9.6926942307117792e-01, -6.9192230581004455e-01, -4.1498882412107863e-01, -1.3830224498700971e-01, 1.3830224498700971e-01, 4.1498882412107863e-01, 6.9192230581004455e-01, 9.6926942307117792e-01, 1.2472001569431179e+00, 1.5258891402098638e+00, 1.8055171714655447e+00, 2.0862728798817618e+00, 2.3683545886324011e+00, 2.6519724354306349e+00, 2.9373508230046212e+00, 3.2247312919920357e+00, 3.5143759357409059e+00, 3.8065715139453600e+00, 4.1016344745666560e+00, 4.3999171682281375e+00, 4.7018156474074990e+00, 5.0077796021987675e+00, 5.3183252246332708e+00, 5.6340521643499724e+00, 5.9556663267994852e+00, 6.2840112287748280e+00, 6.6201122626360274e+00, 6.9652411205511076e+00, 7.3210130327809484e+00, 7.6895401640404968e+00, 8.0736872850102248e+00, 8.4775290833798636e+00, 8.9072490999647691e+00, 9.3731595496467204e+00, 9.8952875868295376e+00, 1.0526123167960545e+01}, + {-1.0616022981878281e+01, -9.9869416916766838e+00, -9.4663293201553849e+00, -9.0018233229591331e+00, -8.5734447444179089e+00, -8.1709061780525847e+00, -7.7880390829895703e+00, -7.4207788343663230e+00, -7.0662679403068926e+00, -6.7223998201657338e+00, -6.3875637397870904e+00, -6.0604917788315049e+00, -5.7401618236902250e+00, -5.4257332976973487e+00, -5.1165030047214124e+00, -4.8118738520274640e+00, -4.5113321113682128e+00, -4.2144305099719546e+00, -3.9207754044447234e+00, -3.6300168776328952e+00, -3.3418409684468302e+00, -3.0559634843286707e+00, -2.7721250051570916e+00, -2.4900867953039354e+00, -2.2096274151691842e+00, -1.9305398759772254e+00, -1.6526292190403253e+00, -1.3757104277236682e+00, -1.0996066000569449e+00, -8.2414732440241278e-01, -5.4916721122159917e-01, -2.7450454175394473e-01, -0.0000000000000000e+00, 2.7450454175394473e-01, 5.4916721122159917e-01, 8.2414732440241278e-01, 1.0996066000569449e+00, 1.3757104277236682e+00, 1.6526292190403253e+00, 1.9305398759772254e+00, 2.2096274151691842e+00, 2.4900867953039354e+00, 2.7721250051570916e+00, 3.0559634843286707e+00, 3.3418409684468302e+00, 3.6300168776328952e+00, 3.9207754044447234e+00, 4.2144305099719546e+00, 4.5113321113682128e+00, 4.8118738520274640e+00, 5.1165030047214124e+00, 5.4257332976973487e+00, 5.7401618236902250e+00, 6.0604917788315049e+00, 6.3875637397870904e+00, 6.7223998201657338e+00, 7.0662679403068926e+00, 7.4207788343663230e+00, 7.7880390829895703e+00, 8.1709061780525847e+00, 8.5734447444179089e+00, 9.0018233229591331e+00, 9.4663293201553849e+00, 9.9869416916766838e+00, 1.0616022981878281e+01}, + {-1.0705216257883158e+01, -1.0077856416579301e+01, -9.5587304502592971e+00, -9.0956010448419295e+00, -8.6685366107264805e+00, -8.2672741104998497e+00, -7.8856597261055059e+00, -7.5196386980596541e+00, -7.1663606590936650e+00, -6.8237244832006141e+00, -6.4901238172609474e+00, -6.1642944056838216e+00, -5.8452173103130356e+00, -5.5320547921086867e+00, -5.2241062602848638e+00, -4.9207770717124939e+00, -4.6215558496899147e+00, -4.3259976200905568e+00, -4.0337110220232306e+00, -3.7443484358240933e+00, -3.4575982403178411e+00, -3.1731786504386261e+00, -2.8908327450724003e+00, -2.6103244026894505e+00, -2.3314349368154352e+00, -2.0539602757725310e+00, -1.7777085685161123e+00, -1.5024981254275005e+00, -1.2281556226723449e+00, -9.5451451326831394e-01, -6.8141359873982055e-01, -4.0869572314721075e-01, -1.3620655703952730e-01, 1.3620655703952730e-01, 4.0869572314721075e-01, 6.8141359873982055e-01, 9.5451451326831394e-01, 1.2281556226723449e+00, 1.5024981254275005e+00, 1.7777085685161123e+00, 2.0539602757725310e+00, 2.3314349368154352e+00, 2.6103244026894505e+00, 2.8908327450724003e+00, 3.1731786504386261e+00, 3.4575982403178411e+00, 3.7443484358240933e+00, 4.0337110220232306e+00, 4.3259976200905568e+00, 4.6215558496899147e+00, 4.9207770717124939e+00, 5.2241062602848638e+00, 5.5320547921086867e+00, 5.8452173103130356e+00, 6.1642944056838216e+00, 6.4901238172609474e+00, 6.8237244832006141e+00, 7.1663606590936650e+00, 7.5196386980596541e+00, 7.8856597261055059e+00, 8.2672741104998497e+00, 8.6685366107264805e+00, 9.0956010448419295e+00, 9.5587304502592971e+00, 1.0077856416579301e+01, 1.0705216257883158e+01}, + {-1.0793719285461286e+01, -1.0168049165614175e+01, -9.6503813634446356e+00, -9.1886016826884820e+00, -8.7628250943199557e+00, -8.3628125057261151e+00, -7.9824245547615575e+00, -7.6176161578278192e+00, -7.2655439249081999e+00, -6.9241120615277021e+00, -6.5917184866891132e+00, -6.2671025086846086e+00, -5.9492482679521004e+00, -5.6373207673775578e+00, -5.3306219248283462e+00, -5.0285594473595783e+00, -4.7306242061652037e+00, -4.4363734165111914e+00, -4.1454178838251625e+00, -3.8574121614750752e+00, -3.5720468340630473e+00, -3.2890423786892447e+00, -3.0081442150749433e+00, -2.7291186629245998e+00, -2.4517495992505411e+00, -2.1758356606878357e+00, -1.9011878731830645e+00, -1.6276276184711236e+00, -1.3549848665269235e+00, -1.0830966177633830e+00, -8.1180550955890352e-01, -5.4095854971511481e-01, -2.7040594535031914e-01, -0.0000000000000000e+00, 2.7040594535031914e-01, 5.4095854971511481e-01, 8.1180550955890352e-01, 1.0830966177633830e+00, 1.3549848665269235e+00, 1.6276276184711236e+00, 1.9011878731830645e+00, 2.1758356606878357e+00, 2.4517495992505411e+00, 2.7291186629245998e+00, 3.0081442150749433e+00, 3.2890423786892447e+00, 3.5720468340630473e+00, 3.8574121614750752e+00, 4.1454178838251625e+00, 4.4363734165111914e+00, 4.7306242061652037e+00, 5.0285594473595783e+00, 5.3306219248283462e+00, 5.6373207673775578e+00, 5.9492482679521004e+00, 6.2671025086846086e+00, 6.5917184866891132e+00, 6.9241120615277021e+00, 7.2655439249081999e+00, 7.6176161578278192e+00, 7.9824245547615575e+00, 8.3628125057261151e+00, 8.7628250943199557e+00, 9.1886016826884820e+00, 9.6503813634446356e+00, 1.0168049165614175e+01, 1.0793719285461286e+01}, + {-1.0881547739512506e+01, -1.0257536674087854e+01, -9.7412997636867704e+00, -9.2808438835486236e+00, -8.8563297855819929e+00, -8.4575419119948716e+00, -8.0783550992846092e+00, -7.7147337577029216e+00, -7.3638413335052801e+00, -7.0235872465011688e+00, -6.6923735845747432e+00, -6.3689431247367301e+00, -6.0522829950450374e+00, -5.7415608508027303e+00, -5.4360810284450567e+00, -5.1352534929147948e+00, -4.8385712673985131e+00, -4.5455936557800598e+00, -4.2559335229494488e+00, -3.9692474811577245e+00, -3.6852281980879265e+00, -3.4035982804227491e+00, -3.1241053447888532e+00, -2.8465179952316144e+00, -2.5706225005795180e+00, -2.2962200172773377e+00, -2.0231242405790431e+00, -1.7511593940081669e+00, -1.4801584867781896e+00, -1.2099617834856000e+00, -9.4041544125892573e-01, -6.7137027764848267e-01, -4.0268063855845554e-01, -1.3420333993493833e-01, 1.3420333993493833e-01, 4.0268063855845554e-01, 6.7137027764848267e-01, 9.4041544125892573e-01, 1.2099617834856000e+00, 1.4801584867781896e+00, 1.7511593940081669e+00, 2.0231242405790431e+00, 2.2962200172773377e+00, 2.5706225005795180e+00, 2.8465179952316144e+00, 3.1241053447888532e+00, 3.4035982804227491e+00, 3.6852281980879265e+00, 3.9692474811577245e+00, 4.2559335229494488e+00, 4.5455936557800598e+00, 4.8385712673985131e+00, 5.1352534929147948e+00, 5.4360810284450567e+00, 5.7415608508027303e+00, 6.0522829950450374e+00, 6.3689431247367301e+00, 6.6923735845747432e+00, 7.0235872465011688e+00, 7.3638413335052801e+00, 7.7147337577029216e+00, 8.0783550992846092e+00, 8.4575419119948716e+00, 8.8563297855819929e+00, 9.2808438835486236e+00, 9.7412997636867704e+00, 1.0257536674087854e+01, 1.0881547739512506e+01}, + {-1.0968716712272720e+01, -1.0346335043862190e+01, -9.8315026740330858e+00, -9.3723455663368824e+00, -8.9490694985983303e+00, -8.5514820514248040e+00, -8.1734720117891584e+00, -7.8110131087611858e+00, -7.4612754898399762e+00, -7.1221736773103954e+00, -6.7921138299353210e+00, -6.4698421035199560e+00, -6.1543485281550758e+00, -5.8448033276997977e+00, -5.5405131730790877e+00, -5.2408902012860343e+00, -4.9454294985999852e+00, -4.6536923643912962e+00, -4.3652936245432166e+00, -4.0798918452871904e+00, -3.7971816649246475e+00, -3.5168876985063164e+00, -3.2387596283073630e+00, -2.9625681999937008e+00, -2.6881019184401618e+00, -2.4151642892936240e+00, -2.1435714896364328e+00, -1.8731503781015579e+00, -1.6037367745786486e+00, -1.3351739542940309e+00, -1.0673113119622561e+00, -8.0000315987311321e-01, -5.3310762988307847e-01, -2.6648565380755118e-01, -0.0000000000000000e+00, 2.6648565380755118e-01, 5.3310762988307847e-01, 8.0000315987311321e-01, 1.0673113119622561e+00, 1.3351739542940309e+00, 1.6037367745786486e+00, 1.8731503781015579e+00, 2.1435714896364328e+00, 2.4151642892936240e+00, 2.6881019184401618e+00, 2.9625681999937008e+00, 3.2387596283073630e+00, 3.5168876985063164e+00, 3.7971816649246475e+00, 4.0798918452871904e+00, 4.3652936245432166e+00, 4.6536923643912962e+00, 4.9454294985999852e+00, 5.2408902012860343e+00, 5.5405131730790877e+00, 5.8448033276997977e+00, 6.1543485281550758e+00, 6.4698421035199560e+00, 6.7921138299353210e+00, 7.1221736773103954e+00, 7.4612754898399762e+00, 7.8110131087611858e+00, 8.1734720117891584e+00, 8.5514820514248040e+00, 8.9490694985983303e+00, 9.3723455663368824e+00, 9.8315026740330858e+00, 1.0346335043862190e+01, 1.0968716712272720e+01}, + {-1.1055240743138121e+01, -1.0434459776321237e+01, -9.9210064725726337e+00, -9.4631239608462057e+00, -9.0410623133341144e+00, -8.6446518655005491e+00, -8.2677951152318059e+00, -7.9064749419687779e+00, -7.5578680649896128e+00, -7.2198940023018814e+00, -6.8909628903904032e+00, -6.5698241787566660e+00, -6.2554707188783159e+00, -5.9470752244713703e+00, -5.6439466223452381e+00, -5.3454991415732502e+00, -5.0512298489716008e+00, -4.7607019531713526e+00, -4.4735321501381859e+00, -4.1893808634925733e+00, -3.9079445988680890e+00, -3.6289498686372541e+00, -3.3521483007723556e+00, -3.0773126524497552e+00, -2.8042335229302870e+00, -2.5327166122907285e+00, -2.2625804097899467e+00, -1.9936542226231451e+00, -1.7257764756009522e+00, -1.4587932269483976e+00, -1.1925568563654070e+00, -9.2692488970661657e-01, -6.6175893081256654e-01, -3.9692367564298847e-01, -1.3228598727031571e-01, 1.3228598727031571e-01, 3.9692367564298847e-01, 6.6175893081256654e-01, 9.2692488970661657e-01, 1.1925568563654070e+00, 1.4587932269483976e+00, 1.7257764756009522e+00, 1.9936542226231451e+00, 2.2625804097899467e+00, 2.5327166122907285e+00, 2.8042335229302870e+00, 3.0773126524497552e+00, 3.3521483007723556e+00, 3.6289498686372541e+00, 3.9079445988680890e+00, 4.1893808634925733e+00, 4.4735321501381859e+00, 4.7607019531713526e+00, 5.0512298489716008e+00, 5.3454991415732502e+00, 5.6439466223452381e+00, 5.9470752244713703e+00, 6.2554707188783159e+00, 6.5698241787566660e+00, 6.8909628903904032e+00, 7.2198940023018814e+00, 7.5578680649896128e+00, 7.9064749419687779e+00, 8.2677951152318059e+00, 8.6446518655005491e+00, 9.0410623133341144e+00, 9.4631239608462057e+00, 9.9210064725726337e+00, 1.0434459776321237e+01, 1.1055240743138121e+01}, + {-1.1141133846557336e+01, -1.0521925803168939e+01, -1.0009826926005323e+01, -9.5531956441224679e+00, -9.1323256149194787e+00, -8.7370695574210657e+00, -8.3613434490107519e+00, -8.0011391572542987e+00, -7.6536398489544064e+00, -7.3167699357978755e+00, -6.9889434433253230e+00, -6.6689130340885914e+00, -6.3556743048467315e+00, -6.0484023852002728e+00, -5.7464083842334572e+00, -5.4491085484699262e+00, -5.1560018484650616e+00, -4.8666533221367576e+00, -4.5806814514481742e+00, -4.2977484283048772e+00, -4.0175525306328757e+00, -3.7398220661958628e+00, -3.4643104988218911e+00, -3.1907924783359922e+00, -2.9190605692775651e+00, -2.6489225254318436e+00, -2.3801989943566357e+00, -2.1127215630246923e+00, -1.8463310754751214e+00, -1.5808761680325296e+00, -1.3162119786216788e+00, -1.0521989949595671e+00, -7.8870201263520334e-01, -5.2558917877833533e-01, -2.6273110051935877e-01, -0.0000000000000000e+00, 2.6273110051935877e-01, 5.2558917877833533e-01, 7.8870201263520334e-01, 1.0521989949595671e+00, 1.3162119786216788e+00, 1.5808761680325296e+00, 1.8463310754751214e+00, 2.1127215630246923e+00, 2.3801989943566357e+00, 2.6489225254318436e+00, 2.9190605692775651e+00, 3.1907924783359922e+00, 3.4643104988218911e+00, 3.7398220661958628e+00, 4.0175525306328757e+00, 4.2977484283048772e+00, 4.5806814514481742e+00, 4.8666533221367576e+00, 5.1560018484650616e+00, 5.4491085484699262e+00, 5.7464083842334572e+00, 6.0484023852002728e+00, 6.3556743048467315e+00, 6.6689130340885914e+00, 6.9889434433253230e+00, 7.3167699357978755e+00, 7.6536398489544064e+00, 8.0011391572542987e+00, 8.3613434490107519e+00, 8.7370695574210657e+00, 9.1323256149194787e+00, 9.5531956441224679e+00, 1.0009826926005323e+01, 1.0521925803168939e+01, 1.1141133846557336e+01}, + {-1.1226409538142136e+01, -1.0608747515229252e+01, -1.0097979221003259e+01, -9.6425765744143064e+00, -9.2228761302815698e+00, -8.8287526315494791e+00, -8.4541353114024211e+00, -8.0950248691313433e+00, -7.7486107996948919e+00, -7.4128223108085409e+00, -7.0860772325710890e+00, -6.7671313640535109e+00, -6.4549829753707284e+00, -6.1488095423716089e+00, -5.8479242873741697e+00, -5.5517454045920136e+00, -5.2597736967589261e+00, -4.9715759567771789e+00, -4.6867723746994256e+00, -4.4050268283718435e+00, -4.1260392804003079e+00, -3.8495397401994360e+00, -3.5752834066737424e+00, -3.3030467134928974e+00, -3.0326240725636300e+00, -2.7638251631581228e+00, -2.4964726512514903e+00, -2.2304002505260021e+00, -1.9654510562578547e+00, -1.7014760979685193e+00, -1.4383330677067736e+00, -1.1758851891099782e+00, -9.1400019866369742e-01, -6.5254941532698807e-01, -3.9140687826621273e-01, -1.3044853509282020e-01, 1.3044853509282020e-01, 3.9140687826621273e-01, 6.5254941532698807e-01, 9.1400019866369742e-01, 1.1758851891099782e+00, 1.4383330677067736e+00, 1.7014760979685193e+00, 1.9654510562578547e+00, 2.2304002505260021e+00, 2.4964726512514903e+00, 2.7638251631581228e+00, 3.0326240725636300e+00, 3.3030467134928974e+00, 3.5752834066737424e+00, 3.8495397401994360e+00, 4.1260392804003079e+00, 4.4050268283718435e+00, 4.6867723746994256e+00, 4.9715759567771789e+00, 5.2597736967589261e+00, 5.5517454045920136e+00, 5.8479242873741697e+00, 6.1488095423716089e+00, 6.4549829753707284e+00, 6.7671313640535109e+00, 7.0860772325710890e+00, 7.4128223108085409e+00, 7.7486107996948919e+00, 8.0950248691313433e+00, 8.4541353114024211e+00, 8.8287526315494791e+00, 9.2228761302815698e+00, 9.6425765744143064e+00, 1.0097979221003259e+01, 1.0608747515229252e+01, 1.1226409538142136e+01}, + {-1.1311080859133723e+01, -1.0694938789404631e+01, -1.0185477993538820e+01, -9.7312821228925461e+00, -9.3127299623383131e+00, -8.9197179302027116e+00, -8.5461882990986897e+00, -8.1881504491623041e+00, -7.8428000887281044e+00, -7.5080711279939001e+00, -7.1823851209949314e+00, -6.8645009305993021e+00, -6.5534194322069030e+00, -6.2483203822637563e+00, -5.9485190514660768e+00, -5.6534355164057573e+00, -5.3625723452058249e+00, -5.0754980166052253e+00, -4.7918343564389145e+00, -4.5112468522638922e+00, -4.2334370704564908e+00, -3.9581366357170062e+00, -3.6851023893880592e+00, -3.4141124491940373e+00, -3.1449629665080243e+00, -2.8774654290158654e+00, -2.6114443936789562e+00, -2.3467355617654575e+00, -2.0831841274592904e+00, -1.8206433462185645e+00, -1.5589732800480507e+00, -1.2980396851534748e+00, -1.0377130137484731e+00, -7.7786750657853077e-01, -5.1838035636125168e-01, -2.5913092507112634e-01, -0.0000000000000000e+00, 2.5913092507112634e-01, 5.1838035636125168e-01, 7.7786750657853077e-01, 1.0377130137484731e+00, 1.2980396851534748e+00, 1.5589732800480507e+00, 1.8206433462185645e+00, 2.0831841274592904e+00, 2.3467355617654575e+00, 2.6114443936789562e+00, 2.8774654290158654e+00, 3.1449629665080243e+00, 3.4141124491940373e+00, 3.6851023893880592e+00, 3.9581366357170062e+00, 4.2334370704564908e+00, 4.5112468522638922e+00, 4.7918343564389145e+00, 5.0754980166052253e+00, 5.3625723452058249e+00, 5.6534355164057573e+00, 5.9485190514660768e+00, 6.2483203822637563e+00, 6.5534194322069030e+00, 6.8645009305993021e+00, 7.1823851209949314e+00, 7.5080711279939001e+00, 7.8428000887281044e+00, 8.1881504491623041e+00, 8.5461882990986897e+00, 8.9197179302027116e+00, 9.3127299623383131e+00, 9.7312821228925461e+00, 1.0185477993538820e+01, 1.0694938789404631e+01, 1.1311080859133723e+01}, + {-1.1395160399349303e+01, -1.0780513013934538e+01, -1.0272337356338001e+01, -9.8193271033153593e+00, -9.4019026219489774e+00, -9.0099816679963673e+00, -8.6375193440825591e+00, -8.2805335655260475e+00, -7.9362261435724362e+00, -7.6025356011958438e+00, -7.2778871393556734e+00, -6.9610426155273659e+00, -6.6510054458855254e+00, -6.3469576054906103e+00, -6.0482163524027337e+00, -5.7542035843517603e+00, -5.4644235724164387e+00, -5.1784464167185336e+00, -4.8958955116562031e+00, -4.6164378838097413e+00, -4.3397766284785542e+00, -4.0656449059380266e+00, -3.7938011146597774e+00, -3.5240249647298416e+00, -3.2561142480573673e+00, -2.9898821536352491e+00, -2.7251550130837989e+00, -2.4617703885377660e+00, -2.1995754346550642e+00, -1.9384254811801831e+00, -1.6781827934921525e+00, -1.4187154768845949e+00, -1.1598964966533338e+00, -9.0160279089609208e-01, -6.4371445661134197e-01, -3.8611399247334727e-01, -1.2868558374092035e-01, 1.2868558374092035e-01, 3.8611399247334727e-01, 6.4371445661134197e-01, 9.0160279089609208e-01, 1.1598964966533338e+00, 1.4187154768845949e+00, 1.6781827934921525e+00, 1.9384254811801831e+00, 2.1995754346550642e+00, 2.4617703885377660e+00, 2.7251550130837989e+00, 2.9898821536352491e+00, 3.2561142480573673e+00, 3.5240249647298416e+00, 3.7938011146597774e+00, 4.0656449059380266e+00, 4.3397766284785542e+00, 4.6164378838097413e+00, 4.8958955116562031e+00, 5.1784464167185336e+00, 5.4644235724164387e+00, 5.7542035843517603e+00, 6.0482163524027337e+00, 6.3469576054906103e+00, 6.6510054458855254e+00, 6.9610426155273659e+00, 7.2778871393556734e+00, 7.6025356011958438e+00, 7.9362261435724362e+00, 8.2805335655260475e+00, 8.6375193440825591e+00, 9.0099816679963673e+00, 9.4019026219489774e+00, 9.8193271033153593e+00, 1.0272337356338001e+01, 1.0780513013934538e+01, 1.1395160399349303e+01}, + {-1.1478660318722643e+01, -1.0865483112083050e+01, -1.0358570924603207e+01, -9.9067257997991209e+00, -9.4904090577984004e+00, -9.0995594639401105e+00, -8.7281447480576215e+00, -8.3721912199266999e+00, -8.0289066873027544e+00, -7.6962341998287283e+00, -7.3726025317424613e+00, -7.0567764692174766e+00, -6.7477619079872566e+00, -6.4447429831267424e+00, -6.1470388825769424e+00, -5.8540732676978866e+00, -5.5653520540734327e+00, -5.2804469030361734e+00, -4.9989827149592099e+00, -4.7206279897915646e+00, -4.4450872824012313e+00, -4.1720952149448500e+00, -3.9014116643261456e+00, -3.6328178485882909e+00, -3.3661131093032384e+00, -3.1011122385952579e+00, -2.8376432363425028e+00, -2.5755454098889712e+00, -2.3146677482934548e+00, -2.0548675177858016e+00, -1.7960090360977110e+00, -1.5379625916624640e+00, -1.2806034800245349e+00, -1.0238111346569745e+00, -7.6746833310481610e-01, -5.1146046221189689e-01, -2.5567482833134803e-01, -0.0000000000000000e+00, 2.5567482833134803e-01, 5.1146046221189689e-01, 7.6746833310481610e-01, 1.0238111346569745e+00, 1.2806034800245349e+00, 1.5379625916624640e+00, 1.7960090360977110e+00, 2.0548675177858016e+00, 2.3146677482934548e+00, 2.5755454098889712e+00, 2.8376432363425028e+00, 3.1011122385952579e+00, 3.3661131093032384e+00, 3.6328178485882909e+00, 3.9014116643261456e+00, 4.1720952149448500e+00, 4.4450872824012313e+00, 4.7206279897915646e+00, 4.9989827149592099e+00, 5.2804469030361734e+00, 5.5653520540734327e+00, 5.8540732676978866e+00, 6.1470388825769424e+00, 6.4447429831267424e+00, 6.7477619079872566e+00, 7.0567764692174766e+00, 7.3726025317424613e+00, 7.6962341998287283e+00, 8.0289066873027544e+00, 8.3721912199266999e+00, 8.7281447480576215e+00, 9.0995594639401105e+00, 9.4904090577984004e+00, 9.9067257997991209e+00, 1.0358570924603207e+01, 1.0865483112083050e+01, 1.1478660318722643e+01}, + {-1.1561592367542413e+01, -1.0949861564373141e+01, -1.0444191840136728e+01, -9.9934919928404522e+00, -9.5782636843755515e+00, -9.1884663714605921e+00, -8.8180802146261925e+00, -8.4631397820581817e+00, -8.1208587754520742e+00, -7.7891846883888824e+00, -7.4665497978837827e+00, -7.1517217559506374e+00, -6.8437088797189292e+00, -6.5416974088024276e+00, -6.2450084067917304e+00, -5.9530672445968058e+00, -5.6653814275042969e+00, -5.3815241217984982e+00, -5.1011216754614015e+00, -4.8238440007350292e+00, -4.5493970476880525e+00, -4.2775168321151087e+00, -4.0079646366324129e+00, -3.7405231094103377e+00, -3.4749930580623096e+00, -3.2111907876889831e+00, -2.9489458689195023e+00, -2.6880992485383528e+00, -2.4285016349547641e+00, -2.1700121054020434e+00, -1.9124968927478689e+00, -1.6558283181292228e+00, -1.3998838419857680e+00, -1.1445452109440197e+00, -8.8969768175512143e-01, -6.3522930636766928e-01, -3.8103026441027604e-01, -1.2699223100184112e-01, 1.2699223100184112e-01, 3.8103026441027604e-01, 6.3522930636766928e-01, 8.8969768175512143e-01, 1.1445452109440197e+00, 1.3998838419857680e+00, 1.6558283181292228e+00, 1.9124968927478689e+00, 2.1700121054020434e+00, 2.4285016349547641e+00, 2.6880992485383528e+00, 2.9489458689195023e+00, 3.2111907876889831e+00, 3.4749930580623096e+00, 3.7405231094103377e+00, 4.0079646366324129e+00, 4.2775168321151087e+00, 4.5493970476880525e+00, 4.8238440007350292e+00, 5.1011216754614015e+00, 5.3815241217984982e+00, 5.6653814275042969e+00, 5.9530672445968058e+00, 6.2450084067917304e+00, 6.5416974088024276e+00, 6.8437088797189292e+00, 7.1517217559506374e+00, 7.4665497978837827e+00, 7.7891846883888824e+00, 8.1208587754520742e+00, 8.4631397820581817e+00, 8.8180802146261925e+00, 9.1884663714605921e+00, 9.5782636843755515e+00, 9.9934919928404522e+00, 1.0444191840136728e+01, 1.0949861564373141e+01, 1.1561592367542413e+01}, + {-1.1643967905483196e+01, -1.1033660429475029e+01, -1.0529212793984577e+01, -1.0079638983721908e+01, -9.6654804081925363e+00, -9.2767169065128172e+00, -8.9073408793931357e+00, -8.5533950218190302e+00, -8.2120988304736517e+00, -7.8814041633182299e+00, -7.5597467325857197e+00, -7.2458969961152926e+00, -6.9388656371030670e+00, -6.6378409471161133e+00, -6.3421458141623201e+00, -6.0512072677740329e+00, -5.7645343514856853e+00, -5.4817016838558219e+00, -5.2023370059655702e+00, -4.9261115854472983e+00, -4.6527327077376199e+00, -4.3819377189728366e+00, -4.1134892401757890e+00, -3.8471712777564733e+00, -3.5827860282892376e+00, -3.3201512269147213e+00, -3.0590979254933970e+00, -2.7994686133415088e+00, -2.5411156130214039e+00, -2.2838996982733861e+00, -2.0276888921639609e+00, -1.7723574118602183e+00, -1.5177847328096994e+00, -1.2638547500001409e+00, -1.0104550177477929e+00, -7.5747605237336058e-01, -5.0481068435860232e-01, -2.5235344827118406e-01, -0.0000000000000000e+00, 2.5235344827118406e-01, 5.0481068435860232e-01, 7.5747605237336058e-01, 1.0104550177477929e+00, 1.2638547500001409e+00, 1.5177847328096994e+00, 1.7723574118602183e+00, 2.0276888921639609e+00, 2.2838996982733861e+00, 2.5411156130214039e+00, 2.7994686133415088e+00, 3.0590979254933970e+00, 3.3201512269147213e+00, 3.5827860282892376e+00, 3.8471712777564733e+00, 4.1134892401757890e+00, 4.3819377189728366e+00, 4.6527327077376199e+00, 4.9261115854472983e+00, 5.2023370059655702e+00, 5.4817016838558219e+00, 5.7645343514856853e+00, 6.0512072677740329e+00, 6.3421458141623201e+00, 6.6378409471161133e+00, 6.9388656371030670e+00, 7.2458969961152926e+00, 7.5597467325857197e+00, 7.8814041633182299e+00, 8.2120988304736517e+00, 8.5533950218190302e+00, 8.9073408793931357e+00, 9.2767169065128172e+00, 9.6654804081925363e+00, 1.0079638983721908e+01, 1.0529212793984577e+01, 1.1033660429475029e+01, 1.1643967905483196e+01}, + {-1.1725797919515925e+01, -1.1116891363846698e+01, -1.0613646047709890e+01, -1.0165179617422121e+01, -9.7520726523771355e+00, -9.3643250739262687e+00, -8.9959413381560331e+00, -8.6429721394539492e+00, -8.3026426739573083e+00, -7.9729090874349415e+00, -7.6522104625334553e+00, -7.3393200055543293e+00, -7.0332507130647253e+00, -6.7331928786770474e+00, -6.4384711663544172e+00, -6.1485142162283823e+00, -5.8628325617022545e+00, -5.5810022242153172e+00, -5.3026522869660511e+00, -5.0274553198842957e+00, -4.7551198880737857e+00, -4.4853846092140870e+00, -4.2180133803413131e+00, -3.9527914995987943e+00, -3.6895224813523542e+00, -3.4280254143563189e+00, -3.1681327493707792e+00, -2.9096884292910694e+00, -2.6525462944632925e+00, -2.3965687104578790e+00, -2.1416253765529731e+00, -1.8875922815137989e+00, -1.6343507796298868e+00, -1.3817867648795250e+00, -1.1297899248837724e+00, -8.7825305924819486e-01, -6.2707144915742807e-01, -3.7614226682388563e-01, -1.2536401469850444e-01, 1.2536401469850444e-01, 3.7614226682388563e-01, 6.2707144915742807e-01, 8.7825305924819486e-01, 1.1297899248837724e+00, 1.3817867648795250e+00, 1.6343507796298868e+00, 1.8875922815137989e+00, 2.1416253765529731e+00, 2.3965687104578790e+00, 2.6525462944632925e+00, 2.9096884292910694e+00, 3.1681327493707792e+00, 3.4280254143563189e+00, 3.6895224813523542e+00, 3.9527914995987943e+00, 4.2180133803413131e+00, 4.4853846092140870e+00, 4.7551198880737857e+00, 5.0274553198842957e+00, 5.3026522869660511e+00, 5.5810022242153172e+00, 5.8628325617022545e+00, 6.1485142162283823e+00, 6.4384711663544172e+00, 6.7331928786770474e+00, 7.0332507130647253e+00, 7.3393200055543293e+00, 7.6522104625334553e+00, 7.9729090874349415e+00, 8.3026426739573083e+00, 8.6429721394539492e+00, 8.9959413381560331e+00, 9.3643250739262687e+00, 9.7520726523771355e+00, 1.0165179617422121e+01, 1.0613646047709890e+01, 1.1116891363846698e+01, 1.1725797919515925e+01}, + {-1.1807093040777294e+01, -1.1199565640216381e+01, -1.0697503453395814e+01, -1.0250126304140645e+01, -9.8380533797602858e+00, -9.4513043921191180e+00, -9.0838956733280174e+00, -8.7318857937825296e+00, -8.3925055567758680e+00, -8.0637153221240894e+00, -7.7439574806678753e+00, -7.4320079322856305e+00, -7.1268819366716176e+00, -6.8277717420599027e+00, -6.5340037424695643e+00, -6.2450081432878877e+00, -5.9602969222394462e+00, -5.6794474572664067e+00, -5.4020901259356995e+00, -5.1278987508656595e+00, -4.8565831248972122e+00, -4.5878830825516648e+00, -4.3215637389507622e+00, -4.0574116223471224e+00, -3.7952314990808915e+00, -3.5348437409765978e+00, -3.2760821218442313e+00, -3.0187919563650998e+00, -2.7628285142266278e+00, -2.5080556569501704e+00, -2.2543446558260460e+00, -2.0015731577016731e+00, -1.7496242717478425e+00, -1.4983857552446240e+00, -1.2477492802359769e+00, -9.9760976585826833e-01, -7.4786476344152575e-01, -4.9841388325234109e-01, -2.4915825309625725e-01, -0.0000000000000000e+00, 2.4915825309625725e-01, 4.9841388325234109e-01, 7.4786476344152575e-01, 9.9760976585826833e-01, 1.2477492802359769e+00, 1.4983857552446240e+00, 1.7496242717478425e+00, 2.0015731577016731e+00, 2.2543446558260460e+00, 2.5080556569501704e+00, 2.7628285142266278e+00, 3.0187919563650998e+00, 3.2760821218442313e+00, 3.5348437409765978e+00, 3.7952314990808915e+00, 4.0574116223471224e+00, 4.3215637389507622e+00, 4.5878830825516648e+00, 4.8565831248972122e+00, 5.1278987508656595e+00, 5.4020901259356995e+00, 5.6794474572664067e+00, 5.9602969222394462e+00, 6.2450081432878877e+00, 6.5340037424695643e+00, 6.8277717420599027e+00, 7.1268819366716176e+00, 7.4320079322856305e+00, 7.7439574806678753e+00, 8.0637153221240894e+00, 8.3925055567758680e+00, 8.7318857937825296e+00, 9.0838956733280174e+00, 9.4513043921191180e+00, 9.8380533797602858e+00, 1.0250126304140645e+01, 1.0697503453395814e+01, 1.1199565640216381e+01, 1.1807093040777294e+01}, + {-1.1887863560471148e+01, -1.1281694164989270e+01, -1.0780796472469154e+01, -1.0334491039538371e+01, -9.9234351145692425e+00, -9.5376679163020608e+00, -9.1712174787264829e+00, -8.8201501286610533e+00, -8.4817021873215737e+00, -8.1538381574634560e+00, -7.8350036783292891e+00, -7.5239772908068669e+00, -7.2197764697589237e+00, -6.9215953729258182e+00, -6.6287620808575998e+00, -6.3407083213299842e+00, -6.0569474734510278e+00, -5.7770582280615690e+00, -5.5006722123151564e+00, -5.2274644551006757e+00, -4.9571459285134285e+00, -4.6894576329528137e+00, -4.4241658477651837e+00, -4.1610582741258364e+00, -3.8999408693873892e+00, -3.6406352232272088e+00, -3.3829763625124016e+00, -3.1268108983731295e+00, -2.8719954485287333e+00, -2.6183952824717842e+00, -2.3658831480742251e+00, -2.1143382465070100e+00, -1.8636453287449284e+00, -1.6136938918510606e+00, -1.3643774570540068e+00, -1.1155929146033490e+00, -8.6723992270397532e-01, -6.1922034962756711e-01, -3.7143774948304431e-01, -1.2379686317313206e-01, 1.2379686317313206e-01, 3.7143774948304431e-01, 6.1922034962756711e-01, 8.6723992270397532e-01, 1.1155929146033490e+00, 1.3643774570540068e+00, 1.6136938918510606e+00, 1.8636453287449284e+00, 2.1143382465070100e+00, 2.3658831480742251e+00, 2.6183952824717842e+00, 2.8719954485287333e+00, 3.1268108983731295e+00, 3.3829763625124016e+00, 3.6406352232272088e+00, 3.8999408693873892e+00, 4.1610582741258364e+00, 4.4241658477651837e+00, 4.6894576329528137e+00, 4.9571459285134285e+00, 5.2274644551006757e+00, 5.5006722123151564e+00, 5.7770582280615690e+00, 6.0569474734510278e+00, 6.3407083213299842e+00, 6.6287620808575998e+00, 6.9215953729258182e+00, 7.2197764697589237e+00, 7.5239772908068669e+00, 7.8350036783292891e+00, 8.1538381574634560e+00, 8.4817021873215737e+00, 8.8201501286610533e+00, 9.1712174787264829e+00, 9.5376679163020608e+00, 9.9234351145692425e+00, 1.0334491039538371e+01, 1.0780796472469154e+01, 1.1281694164989270e+01, 1.1887863560471148e+01}, + {-1.1968119444868723e+01, -1.1363287494653905e+01, -1.0863536193428574e+01, -1.0418285423785731e+01, -1.0008229962827862e+01, -9.6234282602828909e+00, -9.2579198828492224e+00, -8.9077787978104048e+00, -8.5702467579780226e+00, -8.2432923404437446e+00, -7.9253643753426406e+00, -7.6152439941755770e+00, -7.3119508411483105e+00, -7.0146809405398773e+00, -6.7227640181091326e+00, -6.4356332834442265e+00, -6.1528034765082218e+00, -5.8738545599912273e+00, -5.5984193685789059e+00, -5.3261740939400637e+00, -5.0568308420977290e+00, -4.7901317317816865e+00, -4.5258441564113081e+00, -4.2637569369381021e+00, -4.0036771651776295e+00, -3.7454275882737633e+00, -3.4888444214602070e+00, -3.2337755028119282e+00, -2.9800787232025514e+00, -2.7276206792242430e+00, -2.4762755077735275e+00, -2.2259238693277426e+00, -1.9764520533164986e+00, -1.7277511839192137e+00, -1.4797165084468731e+00, -1.2322467534512360e+00, -9.8524353603723147e-01, -7.3861081967444187e-01, -4.9225440521533759e-01, -2.4608144890838049e-01, -0.0000000000000000e+00, 2.4608144890838049e-01, 4.9225440521533759e-01, 7.3861081967444187e-01, 9.8524353603723147e-01, 1.2322467534512360e+00, 1.4797165084468731e+00, 1.7277511839192137e+00, 1.9764520533164986e+00, 2.2259238693277426e+00, 2.4762755077735275e+00, 2.7276206792242430e+00, 2.9800787232025514e+00, 3.2337755028119282e+00, 3.4888444214602070e+00, 3.7454275882737633e+00, 4.0036771651776295e+00, 4.2637569369381021e+00, 4.5258441564113081e+00, 4.7901317317816865e+00, 5.0568308420977290e+00, 5.3261740939400637e+00, 5.5984193685789059e+00, 5.8738545599912273e+00, 6.1528034765082218e+00, 6.4356332834442265e+00, 6.7227640181091326e+00, 7.0146809405398773e+00, 7.3119508411483105e+00, 7.6152439941755770e+00, 7.9253643753426406e+00, 8.2432923404437446e+00, 8.5702467579780226e+00, 8.9077787978104048e+00, 9.2579198828492224e+00, 9.6234282602828909e+00, 1.0008229962827862e+01, 1.0418285423785731e+01, 1.0863536193428574e+01, 1.1363287494653905e+01, 1.1968119444868723e+01}, + {-1.2047870349469452e+01, -1.1444355851257512e+01, -1.0945733348554121e+01, -1.0501520679503271e+01, -1.0092449631556644e+01, -9.7085976169732788e+00, -9.3440155707490522e+00, -8.9947849881314195e+00, -8.6581529699601738e+00, -8.3320921014281222e+00, -8.0150543482026926e+00, -7.7058233840379780e+00, -7.4034209786511349e+00, -7.1070449818933454e+00, -6.8160267254566378e+00, -6.5298008622888712e+00, -6.2478834549069706e+00, -5.9698556991575886e+00, -5.6953515977146445e+00, -5.4240484642257165e+00, -5.1556594962091573e+00, -4.8899278863041147e+00, -4.6266220952405250e+00, -4.3655320142842475e+00, -4.1064658171809416e+00, -3.8492473525444271e+00, -3.5937139640934332e+00, -3.3397146526239907e+00, -3.0871085130972600e+00, -2.8357633947424321e+00, -2.5855547430080739e+00, -2.3363645905095152e+00, -2.0880806704972801e+00, -1.8405956313004481e+00, -1.5938063340319311e+00, -1.3476132188376881e+00, -1.1019197273183625e+00, -8.5663177059026308e-01, -6.1165723388752291e-01, -3.6690550971654429e-01, -1.2228705241518351e-01, 1.2228705241518351e-01, 3.6690550971654429e-01, 6.1165723388752291e-01, 8.5663177059026308e-01, 1.1019197273183625e+00, 1.3476132188376881e+00, 1.5938063340319311e+00, 1.8405956313004481e+00, 2.0880806704972801e+00, 2.3363645905095152e+00, 2.5855547430080739e+00, 2.8357633947424321e+00, 3.0871085130972600e+00, 3.3397146526239907e+00, 3.5937139640934332e+00, 3.8492473525444271e+00, 4.1064658171809416e+00, 4.3655320142842475e+00, 4.6266220952405250e+00, 4.8899278863041147e+00, 5.1556594962091573e+00, 5.4240484642257165e+00, 5.6953515977146445e+00, 5.9698556991575886e+00, 6.2478834549069706e+00, 6.5298008622888712e+00, 6.8160267254566378e+00, 7.1070449818933454e+00, 7.4034209786511349e+00, 7.7058233840379780e+00, 8.0150543482026926e+00, 8.3320921014281222e+00, 8.6581529699601738e+00, 8.9947849881314195e+00, 9.3440155707490522e+00, 9.7085976169732788e+00, 1.0092449631556644e+01, 1.0501520679503271e+01, 1.0945733348554121e+01, 1.1444355851257512e+01, 1.2047870349469452e+01}, + {-1.2127125632378913e+01, -1.1524909137013976e+01, -1.1027398329668573e+01, -1.0584207668672128e+01, -1.0176105446857637e+01, -9.7931877776907488e+00, -9.4295168046084115e+00, -9.0811814416185097e+00, -8.7454340566434574e+00, -8.4202511789832108e+00, -8.1040878565034831e+00, -7.7957302587642490e+00, -7.4942022390283798e+00, -7.1987034336195581e+00, -6.9085667427912707e+00, -6.6232282263685835e+00, -6.3422052331830958e+00, -6.0650801557222689e+00, -5.7914881274189227e+00, -5.5211075455728480e+00, -5.2536526594233770e+00, -4.9888676939643233e+00, -4.7265221335751297e+00, -4.4664068937399284e+00, -4.2083311812642945e+00, -3.9521198942311013e+00, -3.6976114493318364e+00, -3.4446559506485350e+00, -3.1931136334230796e+00, -2.9428535308492294e+00, -2.6937523228426583e+00, -2.4456933340503899e+00, -2.1985656547350549e+00, -1.9522633630987765e+00, -1.7066848314488341e+00, -1.4617321016098621e+00, -1.2173103173449662e+00, -9.7332720340140344e-01, -7.2969258225037825e-01, -4.8631792072343311e-01, -2.4311589961848629e-01, -0.0000000000000000e+00, 2.4311589961848629e-01, 4.8631792072343311e-01, 7.2969258225037825e-01, 9.7332720340140344e-01, 1.2173103173449662e+00, 1.4617321016098621e+00, 1.7066848314488341e+00, 1.9522633630987765e+00, 2.1985656547350549e+00, 2.4456933340503899e+00, 2.6937523228426583e+00, 2.9428535308492294e+00, 3.1931136334230796e+00, 3.4446559506485350e+00, 3.6976114493318364e+00, 3.9521198942311013e+00, 4.2083311812642945e+00, 4.4664068937399284e+00, 4.7265221335751297e+00, 4.9888676939643233e+00, 5.2536526594233770e+00, 5.5211075455728480e+00, 5.7914881274189227e+00, 6.0650801557222689e+00, 6.3422052331830958e+00, 6.6232282263685835e+00, 6.9085667427912707e+00, 7.1987034336195581e+00, 7.4942022390283798e+00, 7.7957302587642490e+00, 8.1040878565034831e+00, 8.4202511789832108e+00, 8.7454340566434574e+00, 9.0811814416185097e+00, 9.4295168046084115e+00, 9.7931877776907488e+00, 1.0176105446857637e+01, 1.0584207668672128e+01, 1.1027398329668573e+01, 1.1524909137013976e+01, 1.2127125632378913e+01}, + {-1.2205894366956139e+01, -1.1604956948103077e+01, -1.1108541203015454e+01, -1.0666356908585685e+01, -1.0259208370962089e+01, -9.8772101503410621e+00, -9.5144354431069669e+00, -9.1669804759729860e+00, -8.8321028054925428e+00, -8.5077828432020937e+00, -8.1924786677436181e+00, -7.8849788998338592e+00, -7.5843094360641796e+00, -7.2896716618750510e+00, -7.0004000104832143e+00, -6.7159319139391096e+00, -6.4357859730612450e+00, -6.1595457424759266e+00, -5.8868474512821898e+00, -5.6173705443855964e+00, -5.3508302854168104e+00, -5.0869718928011789e+00, -4.8255658337490095e+00, -4.5664040049460510e+00, -4.3092966007328037e+00, -4.0540695203033383e+00, -3.8005622017862843e+00, -3.5486257974651720e+00, -3.2981216238257258e+00, -3.0489198345947157e+00, -2.8008982758405363e+00, -2.5539414905028606e+00, -2.3079398460883205e+00, -2.0627887641978626e+00, -1.8183880343913310e+00, -1.5746411979031998e+00, -1.3314549890897636e+00, -1.0887388243534069e+00, -8.4640432975900237e-01, -6.0436489970992124e-01, -3.6253527994578344e-01, -1.2083116880501313e-01, 1.2083116880501313e-01, 3.6253527994578344e-01, 6.0436489970992124e-01, 8.4640432975900237e-01, 1.0887388243534069e+00, 1.3314549890897636e+00, 1.5746411979031998e+00, 1.8183880343913310e+00, 2.0627887641978626e+00, 2.3079398460883205e+00, 2.5539414905028606e+00, 2.8008982758405363e+00, 3.0489198345947157e+00, 3.2981216238257258e+00, 3.5486257974651720e+00, 3.8005622017862843e+00, 4.0540695203033383e+00, 4.3092966007328037e+00, 4.5664040049460510e+00, 4.8255658337490095e+00, 5.0869718928011789e+00, 5.3508302854168104e+00, 5.6173705443855964e+00, 5.8868474512821898e+00, 6.1595457424759266e+00, 6.4357859730612450e+00, 6.7159319139391096e+00, 7.0004000104832143e+00, 7.2896716618750510e+00, 7.5843094360641796e+00, 7.8849788998338592e+00, 8.1924786677436181e+00, 8.5077828432020937e+00, 8.8321028054925428e+00, 9.1669804759729860e+00, 9.5144354431069669e+00, 9.8772101503410621e+00, 1.0259208370962089e+01, 1.0666356908585685e+01, 1.1108541203015454e+01, 1.1604956948103077e+01, 1.2205894366956139e+01}, + {-1.2284185353778504e+01, -1.1684508587714936e+01, -1.1189171723313381e+01, -1.0747978586907845e+01, -1.0341769018312585e+01, -9.9606757765591638e+00, -9.5987829596674032e+00, -9.2521940040089010e+00, -8.9181715786909077e+00, -8.5946999176295051e+00, -8.2802400806274559e+00, -7.9735830966018995e+00, -7.6737568668958440e+00, -7.3799644903419361e+00, -7.0915418991761436e+00, -6.8079278647256025e+00, -6.5286422072422212e+00, -6.2532696108544226e+00, -5.9814473672099631e+00, -5.7128559348775809e+00, -5.4472115568012640e+00, -5.1842604083343016e+00, -4.9237739013081612e+00, -4.6655448734152234e+00, -4.4093844640660000e+00, -4.1551195285347458e+00, -3.9025904784769208e+00, -3.6516494632523195e+00, -3.4021588258868611e+00, -3.1539897819612150e+00, -2.9070212806051177e+00, -2.6611390150638674e+00, -2.4162345566678476e+00, -2.1722045909628105e+00, -1.9289502385999013e+00, -1.6863764465968691e+00, -1.4443914379551996e+00, -1.2029062094928866e+00, -9.6183406923470449e-01, -7.2109020587034223e-01, -4.8059128370529336e-01, -2.4025505723472676e-01, -0.0000000000000000e+00, 2.4025505723472676e-01, 4.8059128370529336e-01, 7.2109020587034223e-01, 9.6183406923470449e-01, 1.2029062094928866e+00, 1.4443914379551996e+00, 1.6863764465968691e+00, 1.9289502385999013e+00, 2.1722045909628105e+00, 2.4162345566678476e+00, 2.6611390150638674e+00, 2.9070212806051177e+00, 3.1539897819612150e+00, 3.4021588258868611e+00, 3.6516494632523195e+00, 3.9025904784769208e+00, 4.1551195285347458e+00, 4.4093844640660000e+00, 4.6655448734152234e+00, 4.9237739013081612e+00, 5.1842604083343016e+00, 5.4472115568012640e+00, 5.7128559348775809e+00, 5.9814473672099631e+00, 6.2532696108544226e+00, 6.5286422072422212e+00, 6.8079278647256025e+00, 7.0915418991761436e+00, 7.3799644903419361e+00, 7.6737568668958440e+00, 7.9735830966018995e+00, 8.2802400806274559e+00, 8.5946999176295051e+00, 8.9181715786909077e+00, 9.2521940040089010e+00, 9.5987829596674032e+00, 9.9606757765591638e+00, 1.0341769018312585e+01, 1.0747978586907845e+01, 1.1189171723313381e+01, 1.1684508587714936e+01, 1.2284185353778504e+01}, + {-1.2362007131968511e+01, -1.1763573078389516e+01, -1.1269299347041693e+01, -1.0829082575898250e+01, -1.0423797670745445e+01, -1.0043595347880535e+01, -9.6825704596576454e+00, -9.3368335519365662e+00, -9.0036523325638047e+00, -8.6810147998900291e+00, -8.3673849469719066e+00, -8.0615561695659022e+00, -7.7625583367306144e+00, -7.4695962264936551e+00, -7.1820072377109705e+00, -6.8992314496242599e+00, -6.6207898710143054e+00, -6.3462682846048741e+00, -6.0753050133032716e+00, -5.8075814973426141e+00, -5.5428149259789015e+00, -5.2807523972174923e+00, -5.0211662316993868e+00, -4.7638501705179523e+00, -4.5086162584922675e+00, -4.2552922649886131e+00, -4.0037195305892794e+00, -3.7537511542142386e+00, -3.5052504546692158e+00, -3.2580896550268070e+00, -3.0121487491227401e+00, -2.7673145177270055e+00, -2.5234796683078762e+00, -2.2805420772311842e+00, -2.0384041170786049e+00, -1.7969720547840342e+00, -1.5561555086656726e+00, -1.3158669543141910e+00, -1.0760212707898533e+00, -8.3653531976321294e-01, -5.9732755116498426e-01, -3.5831762963623587e-01, -1.1942607662410318e-01, 1.1942607662410318e-01, 3.5831762963623587e-01, 5.9732755116498426e-01, 8.3653531976321294e-01, 1.0760212707898533e+00, 1.3158669543141910e+00, 1.5561555086656726e+00, 1.7969720547840342e+00, 2.0384041170786049e+00, 2.2805420772311842e+00, 2.5234796683078762e+00, 2.7673145177270055e+00, 3.0121487491227401e+00, 3.2580896550268070e+00, 3.5052504546692158e+00, 3.7537511542142386e+00, 4.0037195305892794e+00, 4.2552922649886131e+00, 4.5086162584922675e+00, 4.7638501705179523e+00, 5.0211662316993868e+00, 5.2807523972174923e+00, 5.5428149259789015e+00, 5.8075814973426141e+00, 6.0753050133032716e+00, 6.3462682846048741e+00, 6.6207898710143054e+00, 6.8992314496242599e+00, 7.1820072377109705e+00, 7.4695962264936551e+00, 7.7625583367306144e+00, 8.0615561695659022e+00, 8.3673849469719066e+00, 8.6810147998900291e+00, 9.0036523325638047e+00, 9.3368335519365662e+00, 9.6825704596576454e+00, 1.0043595347880535e+01, 1.0423797670745445e+01, 1.0829082575898250e+01, 1.1269299347041693e+01, 1.1763573078389516e+01, 1.2362007131968511e+01}, + {-1.2439367989923680e+01, -1.1842159173697059e+01, -1.1348933245008068e+01, -1.0909678445859965e+01, -1.0505304291834085e+01, -1.0125979221008995e+01, -9.7658086966213720e+00, -9.4209102766018642e+00, -9.0885566358796162e+00, -8.7667394811116139e+00, -8.4539256923192720e+00, -8.1489109922424241e+00, -7.8507271820680931e+00, -7.5585806862536904e+00, -7.2718103393202060e+00, -6.9898574985414994e+00, -6.7122443318572111e+00, -6.4385576912861495e+00, -6.1684369014005451e+00, -5.9015643538974087e+00, -5.6376581532613121e+00, -5.3764662879277241e+00, -5.1177619537428889e+00, -4.8613397599750519e+00, -4.6070126197625800e+00, -4.3546091773629314e+00, -4.1039716607125998e+00, -3.8549540740709145e+00, -3.6074206648573135e+00, -3.3612446132027243e+00, -3.1163069035955786e+00, -2.8724953462701670e+00, -2.6297037223368069e+00, -2.3878310315742213e+00, -2.1467808256453083e+00, -1.9064606125144659e+00, -1.6667813202271460e+00, -1.4276568101012006e+00, -1.1890034308805355e+00, -9.5073960659419110e-01, -7.1278545180861597e-01, -4.7506240870319627e-01, -2.3749290097360490e-01, -0.0000000000000000e+00, 2.3749290097360490e-01, 4.7506240870319627e-01, 7.1278545180861597e-01, 9.5073960659419110e-01, 1.1890034308805355e+00, 1.4276568101012006e+00, 1.6667813202271460e+00, 1.9064606125144659e+00, 2.1467808256453083e+00, 2.3878310315742213e+00, 2.6297037223368069e+00, 2.8724953462701670e+00, 3.1163069035955786e+00, 3.3612446132027243e+00, 3.6074206648573135e+00, 3.8549540740709145e+00, 4.1039716607125998e+00, 4.3546091773629314e+00, 4.6070126197625800e+00, 4.8613397599750519e+00, 5.1177619537428889e+00, 5.3764662879277241e+00, 5.6376581532613121e+00, 5.9015643538974087e+00, 6.1684369014005451e+00, 6.4385576912861495e+00, 6.7122443318572111e+00, 6.9898574985414994e+00, 7.2718103393202060e+00, 7.5585806862536904e+00, 7.8507271820680931e+00, 8.1489109922424241e+00, 8.4539256923192720e+00, 8.7667394811116139e+00, 9.0885566358796162e+00, 9.4209102766018642e+00, 9.7658086966213720e+00, 1.0125979221008995e+01, 1.0505304291834085e+01, 1.0909678445859965e+01, 1.1348933245008068e+01, 1.1842159173697059e+01, 1.2439367989923680e+01}, + {-1.2516275975487387e+01, -1.1920275369301974e+01, -1.1428082314244874e+01, -1.0989775477860821e+01, -1.0586298540449153e+01, -1.0207837432241758e+01, -9.8485080876029141e+00, -9.5044349817531568e+00, -9.1728956871075304e+00, -8.8518855642291054e+00, -8.5398743353481130e+00, -8.2356600117533336e+00, -7.9382762925370942e+00, -7.6469312171655428e+00, -7.3609650262218116e+00, -7.0798203265112649e+00, -6.8030204171920579e+00, -6.5301531917714213e+00, -6.2608589484644162e+00, -5.9948210018972574e+00, -5.7317583424731948e+00, -5.4714198187320084e+00, -5.2135794701554339e+00, -4.9580327411502472e+00, -4.7045933784481448e+00, -4.4530908645538636e+00, -4.2033682759582804e+00, -3.9552804810525908e+00, -3.7086926119853119e+00, -3.4634787590926437e+00, -3.2195208473769141e+00, -2.9767076627641722e+00, -2.7349340022167890e+00, -2.4940999266938628e+00, -2.2541100997915855e+00, -2.0148731979134999e+00, -1.7763013802059482e+00, -1.5383098083876734e+00, -1.3008162081103343e+00, -1.0637404646882309e+00, -8.2700424699148045e-01, -5.9053065405312266e-01, -3.5424387953214642e-01, -1.1806888962751633e-01, 1.1806888962751633e-01, 3.5424387953214642e-01, 5.9053065405312266e-01, 8.2700424699148045e-01, 1.0637404646882309e+00, 1.3008162081103343e+00, 1.5383098083876734e+00, 1.7763013802059482e+00, 2.0148731979134999e+00, 2.2541100997915855e+00, 2.4940999266938628e+00, 2.7349340022167890e+00, 2.9767076627641722e+00, 3.2195208473769141e+00, 3.4634787590926437e+00, 3.7086926119853119e+00, 3.9552804810525908e+00, 4.2033682759582804e+00, 4.4530908645538636e+00, 4.7045933784481448e+00, 4.9580327411502472e+00, 5.2135794701554339e+00, 5.4714198187320084e+00, 5.7317583424731948e+00, 5.9948210018972574e+00, 6.2608589484644162e+00, 6.5301531917714213e+00, 6.8030204171920579e+00, 7.0798203265112649e+00, 7.3609650262218116e+00, 7.6469312171655428e+00, 7.9382762925370942e+00, 8.2356600117533336e+00, 8.5398743353481130e+00, 8.8518855642291054e+00, 9.1728956871075304e+00, 9.5044349817531568e+00, 9.8485080876029141e+00, 1.0207837432241758e+01, 1.0586298540449153e+01, 1.0989775477860821e+01, 1.1428082314244874e+01, 1.1920275369301974e+01, 1.2516275975487387e+01}, + {-1.2592738905595901e+01, -1.1997929913449418e+01, -1.1506755189277548e+01, -1.1069382675775751e+01, -1.0666789783587026e+01, -1.0289179711107796e+01, -9.9306787276273880e+00, -9.5874181334018580e+00, -9.2566803307032135e+00, -8.9364642812455379e+00, -8.6252425061665043e+00, -8.3218152682134434e+00, -8.0252181314463780e+00, -7.7346607201821760e+00, -7.4494846527302592e+00, -7.1691337582185994e+00, -6.8931324404171299e+00, -6.6210696079053228e+00, -6.3525865059800601e+00, -6.0873673452070678e+00, -5.8251319742404801e+00, -5.5656300731513921e+00, -5.3086364953650067e+00, -5.0539474894081309e+00, -4.8013776030542550e+00, -4.5507571227604720e+00, -4.3019299373155544e+00, -4.0547517407947415e+00, -3.8090885091914664e+00, -3.5648151994628399e+00, -3.3218146305539729e+00, -3.0799765142115443e+00, -2.8391966097343762e+00, -2.5993759817212956e+00, -2.3604203437138307e+00, -2.1222394736491395e+00, -1.8847466894257894e+00, -1.6478583747824140e+00, -1.4114935472024899e+00, -1.1755734607673940e+00, -9.4002123784514680e-01, -7.0476152427011995e-01, -4.6972016327466942e-01, -2.3482388390393241e-01, -0.0000000000000000e+00, 2.3482388390393241e-01, 4.6972016327466942e-01, 7.0476152427011995e-01, 9.4002123784514680e-01, 1.1755734607673940e+00, 1.4114935472024899e+00, 1.6478583747824140e+00, 1.8847466894257894e+00, 2.1222394736491395e+00, 2.3604203437138307e+00, 2.5993759817212956e+00, 2.8391966097343762e+00, 3.0799765142115443e+00, 3.3218146305539729e+00, 3.5648151994628399e+00, 3.8090885091914664e+00, 4.0547517407947415e+00, 4.3019299373155544e+00, 4.5507571227604720e+00, 4.8013776030542550e+00, 5.0539474894081309e+00, 5.3086364953650067e+00, 5.5656300731513921e+00, 5.8251319742404801e+00, 6.0873673452070678e+00, 6.3525865059800601e+00, 6.6210696079053228e+00, 6.8931324404171299e+00, 7.1691337582185994e+00, 7.4494846527302592e+00, 7.7346607201821760e+00, 8.0252181314463780e+00, 8.3218152682134434e+00, 8.6252425061665043e+00, 8.9364642812455379e+00, 9.2566803307032135e+00, 9.5874181334018580e+00, 9.9306787276273880e+00, 1.0289179711107796e+01, 1.0666789783587026e+01, 1.1069382675775751e+01, 1.1506755189277548e+01, 1.1997929913449418e+01, 1.2592738905595901e+01}, + {-1.2668764375434174e+01, -1.2075130816910921e+01, -1.1584960252804917e+01, -1.1148508777693781e+01, -1.0746787108514194e+01, -1.0370015493271170e+01, -1.0012330403392184e+01, -9.6698698743374543e+00, -9.3399210724883908e+00, -9.0204865095226339e+00, -8.7100414635651475e+00, -8.4073884130034546e+00, -8.1115647551404777e+00, -7.8217816701739293e+00, -7.5373821269924042e+00, -7.2578111510465870e+00, -6.9825942253568725e+00, -6.7113212484546603e+00, -6.4436343875167896e+00, -6.1792187234934586e+00, -5.9177949371442047e+00, -5.6591135131207473e+00, -5.4029500908349490e+00, -5.1491016937770269e+00, -4.8973836402140369e+00, -4.6476269884213890e+00, -4.3996764055654278e+00, -4.1533883754886318e+00, -3.9086296798928606e+00, -3.6652761017603779e+00, -3.4232113106647768e+00, -3.1823258978578806e+00, -2.9425165353484215e+00, -2.7036852380958849e+00, -2.4657387122776617e+00, -2.2285877756048471e+00, -1.9921468380503871e+00, -1.7563334332534348e+00, -1.5210677923813427e+00, -1.2862724534455954e+00, -1.0518719000409926e+00, -8.1779222425489551e-01, -5.8396080911088377e-01, -3.5030602639582364e-01, -1.1675694609164179e-01, 1.1675694609164179e-01, 3.5030602639582364e-01, 5.8396080911088377e-01, 8.1779222425489551e-01, 1.0518719000409926e+00, 1.2862724534455954e+00, 1.5210677923813427e+00, 1.7563334332534348e+00, 1.9921468380503871e+00, 2.2285877756048471e+00, 2.4657387122776617e+00, 2.7036852380958849e+00, 2.9425165353484215e+00, 3.1823258978578806e+00, 3.4232113106647768e+00, 3.6652761017603779e+00, 3.9086296798928606e+00, 4.1533883754886318e+00, 4.3996764055654278e+00, 4.6476269884213890e+00, 4.8973836402140369e+00, 5.1491016937770269e+00, 5.4029500908349490e+00, 5.6591135131207473e+00, 5.9177949371442047e+00, 6.1792187234934586e+00, 6.4436343875167896e+00, 6.7113212484546603e+00, 6.9825942253568725e+00, 7.2578111510465870e+00, 7.5373821269924042e+00, 7.8217816701739293e+00, 8.1115647551404777e+00, 8.4073884130034546e+00, 8.7100414635651475e+00, 9.0204865095226339e+00, 9.3399210724883908e+00, 9.6698698743374543e+00, 1.0012330403392184e+01, 1.0370015493271170e+01, 1.0746787108514194e+01, 1.1148508777693781e+01, 1.1584960252804917e+01, 1.2075130816910921e+01, 1.2668764375434174e+01}, + {-1.2744359767130547e+01, -1.2151885862422731e+01, -1.1662705645828531e+01, -1.1227162266730099e+01, -1.0826299334271541e+01, -1.0450353932747101e+01, -1.0093472606221523e+01, -9.7518000378530658e+00, -9.4226280941850682e+00, -9.1039627871662461e+00, -8.7942821113015697e+00, -8.4923907260054339e+00, -8.1973278312442819e+00, -7.9083061352456419e+00, -7.6246699314466770e+00, -7.3458654167536865e+00, -7.0714191292405717e+00, -6.8009219334794446e+00, -6.5340168945910211e+00, -6.2703899396887248e+00, -6.0097625569049269e+00, -5.7518860100246414e+00, -5.4965366980951300e+00, -5.2435123921335229e+00, -4.9926291522002995e+00, -4.7437187782456505e+00, -4.4966266840419751e+00, -4.2512101096067996e+00, -4.0073366067337117e+00, -3.7648827465709873e+00, -3.5237330089839838e+00, -3.2837788216598618e+00, -3.0449177232349895e+00, -2.8070526296277643e+00, -2.5700911865913141e+00, -2.3339451945166196e+00, -2.0985300939053997e+00, -1.8637645018342535e+00, -1.6295697912525116e+00, -1.3958697061759588e+00, -1.1625900068179993e+00, -9.2965813948535503e-01, -6.9700292669283159e-01, -4.6455427344836053e-01, -2.3224288604634152e-01, -0.0000000000000000e+00, 2.3224288604634152e-01, 4.6455427344836053e-01, 6.9700292669283159e-01, 9.2965813948535503e-01, 1.1625900068179993e+00, 1.3958697061759588e+00, 1.6295697912525116e+00, 1.8637645018342535e+00, 2.0985300939053997e+00, 2.3339451945166196e+00, 2.5700911865913141e+00, 2.8070526296277643e+00, 3.0449177232349895e+00, 3.2837788216598618e+00, 3.5237330089839838e+00, 3.7648827465709873e+00, 4.0073366067337117e+00, 4.2512101096067996e+00, 4.4966266840419751e+00, 4.7437187782456505e+00, 4.9926291522002995e+00, 5.2435123921335229e+00, 5.4965366980951300e+00, 5.7518860100246414e+00, 6.0097625569049269e+00, 6.2703899396887248e+00, 6.5340168945910211e+00, 6.8009219334794446e+00, 7.0714191292405717e+00, 7.3458654167536865e+00, 7.6246699314466770e+00, 7.9083061352456419e+00, 8.1973278312442819e+00, 8.4923907260054339e+00, 8.7942821113015697e+00, 9.1039627871662461e+00, 9.4226280941850682e+00, 9.7518000378530658e+00, 1.0093472606221523e+01, 1.0450353932747101e+01, 1.0826299334271541e+01, 1.1227162266730099e+01, 1.1662705645828531e+01, 1.2151885862422731e+01, 1.2744359767130547e+01}, + {-1.2819532258018480e+01, -1.2228202613648115e+01, -1.1739999277265277e+01, -1.1305351381280618e+01, -1.0905335022579179e+01, -1.0530203913474873e+01, -1.0174114544331893e+01, -9.8332181607332707e+00, -9.5048112671603402e+00, -9.1869033275673413e+00, -8.8779750134809063e+00, -8.5768331318717053e+00, -8.2825186558731350e+00, -7.9942457949462566e+00, -7.7113601420959172e+00, -7.4333090418794825e+00, -7.1596200643171857e+00, -6.8898850172400419e+00, -6.6237478409567272e+00, -6.3608952857640544e+00, -6.1010496237476017e+00, -5.8439628737731484e+00, -5.5894121696594157e+00, -5.3371960041051256e+00, -5.0871311519710600e+00, -4.8390501265746098e+00, -4.5927990585018197e+00, -4.3482359124910070e+00, -4.1052289771248800e+00, -3.8636555763680760e+00, -3.6234009627673571e+00, -3.3843573603426855e+00, -3.1464231315109763e+00, -2.9095020472812747e+00, -2.6735026437884462e+00, -2.4383376512469250e+00, -2.2039234837948438e+00, -1.9701797806022634e+00, -1.7370289901408089e+00, -1.5043959907356530e+00, -1.2722077415053921e+00, -1.0403929585875988e+00, -8.0888181218354049e-01, -5.7760564046232032e-01, -3.4649667676368101e-01, -1.1548778684603313e-01, 1.1548778684603313e-01, 3.4649667676368101e-01, 5.7760564046232032e-01, 8.0888181218354049e-01, 1.0403929585875988e+00, 1.2722077415053921e+00, 1.5043959907356530e+00, 1.7370289901408089e+00, 1.9701797806022634e+00, 2.2039234837948438e+00, 2.4383376512469250e+00, 2.6735026437884462e+00, 2.9095020472812747e+00, 3.1464231315109763e+00, 3.3843573603426855e+00, 3.6234009627673571e+00, 3.8636555763680760e+00, 4.1052289771248800e+00, 4.3482359124910070e+00, 4.5927990585018197e+00, 4.8390501265746098e+00, 5.0871311519710600e+00, 5.3371960041051256e+00, 5.5894121696594157e+00, 5.8439628737731484e+00, 6.1010496237476017e+00, 6.3608952857640544e+00, 6.6237478409567272e+00, 6.8898850172400419e+00, 7.1596200643171857e+00, 7.4333090418794825e+00, 7.7113601420959172e+00, 7.9942457949462566e+00, 8.2825186558731350e+00, 8.5768331318717053e+00, 8.8779750134809063e+00, 9.1869033275673413e+00, 9.5048112671603402e+00, 9.8332181607332707e+00, 1.0174114544331893e+01, 1.0530203913474873e+01, 1.0905335022579179e+01, 1.1305351381280618e+01, 1.1739999277265277e+01, 1.2228202613648115e+01, 1.2819532258018480e+01}, + {-1.2894288828491323e+01, -1.2304088423692580e+01, -1.1816848833075053e+01, -1.1383084124753704e+01, -1.0983902488179488e+01, -1.0609574060288383e+01, -1.0254265154452550e+01, -9.9141334955519440e+00, -9.5864801654334606e+00, -9.2693180331543115e+00, -8.9611304090936645e+00, -8.6607262153924776e+00, -8.3671481698791865e+00, -8.0796119574473497e+00, -7.7974644466766474e+00, -7.5201541069686444e+00, -7.2472095182038041e+00, -6.9782234097463292e+00, -6.7128405754384817e+00, -6.4507485669373850e+00, -6.1916704180836000e+00, -5.9353588800666905e+00, -5.6815917979923949e+00, -5.4301683618693133e+00, -5.1809060359441155e+00, -4.9336380202893313e+00, -4.6882111343374202e+00, -4.4444840380621056e+00, -4.2023257256606739e+00, -3.9616142408689083e+00, -3.7222355738045620e+00, -3.4840827074346534e+00, -3.2470547880671274e+00, -3.0110563991586603e+00, -2.7759969215550591e+00, -2.5417899662931847e+00, -2.3083528684815695e+00, -2.0756062326810416e+00, -1.8434735217321803e+00, -1.6118806822031735e+00, -1.3807558006205385e+00, -1.1500287854429532e+00, -9.1963107038107428e-01, -6.8949533518145145e-01, -4.5955524040186729e-01, -2.2974517302503578e-01, -0.0000000000000000e+00, 2.2974517302503578e-01, 4.5955524040186729e-01, 6.8949533518145145e-01, 9.1963107038107428e-01, 1.1500287854429532e+00, 1.3807558006205385e+00, 1.6118806822031735e+00, 1.8434735217321803e+00, 2.0756062326810416e+00, 2.3083528684815695e+00, 2.5417899662931847e+00, 2.7759969215550591e+00, 3.0110563991586603e+00, 3.2470547880671274e+00, 3.4840827074346534e+00, 3.7222355738045620e+00, 3.9616142408689083e+00, 4.2023257256606739e+00, 4.4444840380621056e+00, 4.6882111343374202e+00, 4.9336380202893313e+00, 5.1809060359441155e+00, 5.4301683618693133e+00, 5.6815917979923949e+00, 5.9353588800666905e+00, 6.1916704180836000e+00, 6.4507485669373850e+00, 6.7128405754384817e+00, 6.9782234097463292e+00, 7.2472095182038041e+00, 7.5201541069686444e+00, 7.7974644466766474e+00, 8.0796119574473497e+00, 8.3671481698791865e+00, 8.6607262153924776e+00, 8.9611304090936645e+00, 9.2693180331543115e+00, 9.5864801654334606e+00, 9.9141334955519440e+00, 1.0254265154452550e+01, 1.0609574060288383e+01, 1.0983902488179488e+01, 1.1383084124753704e+01, 1.1816848833075053e+01, 1.2304088423692580e+01, 1.2894288828491323e+01}, + {-1.2968636269474320e+01, -1.2379550443198964e+01, -1.1893261784933093e+01, -1.1460368274811241e+01, -1.1062009808653285e+01, -1.0688472749322155e+01, -1.0333933112841928e+01, -9.9945550223243256e+00, -9.6676440779928683e+00, -9.3512165084081822e+00, -9.0437582257661120e+00, -8.7440802360223131e+00, -8.4512269741988870e+00, -8.1644155757609358e+00, -7.8829941618009407e+00, -7.6064123046955778e+00, -7.3341995730571172e+00, -7.0659495970458304e+00, -6.8013080034124762e+00, -6.5399631244304128e+00, -6.2816387346344911e+00, -6.0260882959858302e+00, -5.7730903426736297e+00, -5.5224447390110498e+00, -5.2739696146779718e+00, -5.0274988314577831e+00, -4.7828798713474461e+00, -4.5399720618862149e+00, -4.2986450736710040e+00, -4.0587776392825550e+00, -3.8202564535947250e+00, -3.5829752236268817e+00, -3.3468338423962911e+00, -3.1117376661126466e+00, -2.8775968778776946e+00, -2.6443259240630739e+00, -2.4118430119268002e+00, -2.1800696589332400e+00, -1.9489302857683151e+00, -1.7183518462708216e+00, -1.4882634884931585e+00, -1.2585962419071162e+00, -1.0292827264188049e+00, -8.0025687937913981e-01, -5.7145369719413508e-01, -3.4280898846921665e-01, -1.1425913587653955e-01, 1.1425913587653955e-01, 3.4280898846921665e-01, 5.7145369719413508e-01, 8.0025687937913981e-01, 1.0292827264188049e+00, 1.2585962419071162e+00, 1.4882634884931585e+00, 1.7183518462708216e+00, 1.9489302857683151e+00, 2.1800696589332400e+00, 2.4118430119268002e+00, 2.6443259240630739e+00, 2.8775968778776946e+00, 3.1117376661126466e+00, 3.3468338423962911e+00, 3.5829752236268817e+00, 3.8202564535947250e+00, 4.0587776392825550e+00, 4.2986450736710040e+00, 4.5399720618862149e+00, 4.7828798713474461e+00, 5.0274988314577831e+00, 5.2739696146779718e+00, 5.5224447390110498e+00, 5.7730903426736297e+00, 6.0260882959858302e+00, 6.2816387346344911e+00, 6.5399631244304128e+00, 6.8013080034124762e+00, 7.0659495970458304e+00, 7.3341995730571172e+00, 7.6064123046955778e+00, 7.8829941618009407e+00, 8.1644155757609358e+00, 8.4512269741988870e+00, 8.7440802360223131e+00, 9.0437582257661120e+00, 9.3512165084081822e+00, 9.6676440779928683e+00, 9.9945550223243256e+00, 1.0333933112841928e+01, 1.0688472749322155e+01, 1.1062009808653285e+01, 1.1460368274811241e+01, 1.1893261784933093e+01, 1.2379550443198964e+01, 1.2968636269474320e+01}, + {-1.3042581189536424e+01, -1.2454595628047418e+01, -1.1969245398474266e+01, -1.1537211392148828e+01, -1.1139664833741461e+01, -1.0766908117887827e+01, -1.0413126845737839e+01, -1.0074491459554146e+01, -9.7483120204672815e+00, -9.4326080721882803e+00, -9.1258680927746667e+00, -8.8269051416209461e+00, -8.5347653443616345e+00, -8.2486672630612325e+00, -7.9679602491408312e+00, -7.6920949569654464e+00, -7.4206019236498832e+00, -7.1530756603397334e+00, -6.8891626070319019e+00, -6.6285518568795139e+00, -6.3709679051115460e+00, -6.1161649040299730e+00, -5.8639220558946130e+00, -5.6140398775862348e+00, -5.3663371416203249e+00, -5.1206483478982010e+00, -4.8768216162575175e+00, -4.6347169158093715e+00, -4.3942045661421210e+00, -4.1551639597063925e+00, -3.9174824654279452e+00, -3.6810544817710307e+00, -3.4457806137632216e+00, -3.2115669533719382e+00, -2.9783244464395575e+00, -2.7459683323916124e+00, -2.5144176453186349e+00, -2.2835947669364720e+00, -2.0534250234577174e+00, -1.8238363196378788e+00, -1.5947588042551295e+00, -1.3661245620886429e+00, -1.1378673281137517e+00, -9.0992222016050861e-01, -6.8222548670729899e-01, -4.5471426681985894e-01, -2.2732635951125563e-01, -0.0000000000000000e+00, 2.2732635951125563e-01, 4.5471426681985894e-01, 6.8222548670729899e-01, 9.0992222016050861e-01, 1.1378673281137517e+00, 1.3661245620886429e+00, 1.5947588042551295e+00, 1.8238363196378788e+00, 2.0534250234577174e+00, 2.2835947669364720e+00, 2.5144176453186349e+00, 2.7459683323916124e+00, 2.9783244464395575e+00, 3.2115669533719382e+00, 3.4457806137632216e+00, 3.6810544817710307e+00, 3.9174824654279452e+00, 4.1551639597063925e+00, 4.3942045661421210e+00, 4.6347169158093715e+00, 4.8768216162575175e+00, 5.1206483478982010e+00, 5.3663371416203249e+00, 5.6140398775862348e+00, 5.8639220558946130e+00, 6.1161649040299730e+00, 6.3709679051115460e+00, 6.6285518568795139e+00, 6.8891626070319019e+00, 7.1530756603397334e+00, 7.4206019236498832e+00, 7.6920949569654464e+00, 7.9679602491408312e+00, 8.2486672630612325e+00, 8.5347653443616345e+00, 8.8269051416209461e+00, 9.1258680927746667e+00, 9.4326080721882803e+00, 9.7483120204672815e+00, 1.0074491459554146e+01, 1.0413126845737839e+01, 1.0766908117887827e+01, 1.1139664833741461e+01, 1.1537211392148828e+01, 1.1969245398474266e+01, 1.2454595628047418e+01, 1.3042581189536424e+01}, + {-1.3116130021662876e+01, -1.2529230746683540e+01, -1.2044806741134924e+01, -1.1613620828842913e+01, -1.1216875194202160e+01, -1.0844888073853586e+01, -1.0491854539276538e+01, -1.0153951274713688e+01, -9.8284927461917118e+00, -9.5135017694124251e+00, -9.2074693533717600e+00, -8.9092105814595968e+00, -8.6177732442147459e+00, -8.3323773071700593e+00, -8.0523733307197105e+00, -7.7772130310612386e+00, -7.5064278944277563e+00, -7.2396132940083531e+00, -6.9764164642851814e+00, -6.7165272404965179e+00, -6.4596708195551207e+00, -6.2056020247183090e+00, -5.9541007064117260e+00, -5.7049680135255354e+00, -5.4580233400707856e+00, -5.2131018018189597e+00, -4.9700521331667717e+00, -4.7287349203529301e+00, -4.4890211062169945e+00, -4.2507907159031859e+00, -4.0139317636282685e+00, -3.7783393087968626e+00, -3.5439146360273117e+00, -3.3105645385243054e+00, -3.0782006880468189e+00, -2.8467390777247825e+00, -2.6160995263623885e+00, -2.3862052347697795e+00, -2.1569823861931283e+00, -1.9283597841455022e+00, -1.7002685219383502e+00, -1.4726416790227095e+00, -1.2454140399065079e+00, -1.0185218319476799e+00, -7.9190247875401665e-01, -5.6549436626674887e-01, -3.3923661887888523e-01, -1.1306888315145193e-01, 1.1306888315145193e-01, 3.3923661887888523e-01, 5.6549436626674887e-01, 7.9190247875401665e-01, 1.0185218319476799e+00, 1.2454140399065079e+00, 1.4726416790227095e+00, 1.7002685219383502e+00, 1.9283597841455022e+00, 2.1569823861931283e+00, 2.3862052347697795e+00, 2.6160995263623885e+00, 2.8467390777247825e+00, 3.0782006880468189e+00, 3.3105645385243054e+00, 3.5439146360273117e+00, 3.7783393087968626e+00, 4.0139317636282685e+00, 4.2507907159031859e+00, 4.4890211062169945e+00, 4.7287349203529301e+00, 4.9700521331667717e+00, 5.2131018018189597e+00, 5.4580233400707856e+00, 5.7049680135255354e+00, 5.9541007064117260e+00, 6.2056020247183090e+00, 6.4596708195551207e+00, 6.7165272404965179e+00, 6.9764164642851814e+00, 7.2396132940083531e+00, 7.5064278944277563e+00, 7.7772130310612386e+00, 8.0523733307197105e+00, 8.3323773071700593e+00, 8.6177732442147459e+00, 8.9092105814595968e+00, 9.2074693533717600e+00, 9.5135017694124251e+00, 9.8284927461917118e+00, 1.0153951274713688e+01, 1.0491854539276538e+01, 1.0844888073853586e+01, 1.1216875194202160e+01, 1.1613620828842913e+01, 1.2044806741134924e+01, 1.2529230746683540e+01, 1.3116130021662876e+01}, + {-1.3189289029708117e+01, -1.2603462387096409e+01, -1.2119952689615966e+01, -1.1689603736290559e+01, -1.1293648310231410e+01, -1.0922420304556775e+01, -1.0570124148913189e+01, -1.0232942694191875e+01, -9.9081947567061555e+00, -9.5939063821323529e+00, -9.2885710764670684e+00, -8.9910059185401376e+00, -8.7002603389157791e+00, -8.4155556842608696e+00, -8.1362437033700719e+00, -7.8617771549009925e+00, -7.5916884556157704e+00, -7.3255738226210259e+00, -7.0630812669681537e+00, -6.8039013480672903e+00, -6.5477599464293741e+00, -6.2944125378566032e+00, -6.0436396020679171e+00, -5.7952429005012469e+00, -5.5490424284915560e+00, -5.3048738966808706e+00, -5.0625866320797561e+00, -4.8220418150442850e+00, -4.5831109874666334e+00, -4.3456747816687633e+00, -4.1096218301890062e+00, -3.8748478248038931e+00, -3.6412546993987251e+00, -3.4087499161671784e+00, -3.1772458384281856e+00, -2.9466591763501873e+00, -2.7169104942556110e+00, -2.4879237700815029e+00, -2.2596259991006340e+00, -2.0319468352407690e+00, -1.8048182643389761e+00, -1.5781743044796297e+00, -1.3519507292254074e+00, -1.1260848100881036e+00, -9.0051507502248329e-01, -6.7518108007869271e-01, -4.5002319163025301e-01, -2.2498237681566594e-01, -0.0000000000000000e+00, 2.2498237681566594e-01, 4.5002319163025301e-01, 6.7518108007869271e-01, 9.0051507502248329e-01, 1.1260848100881036e+00, 1.3519507292254074e+00, 1.5781743044796297e+00, 1.8048182643389761e+00, 2.0319468352407690e+00, 2.2596259991006340e+00, 2.4879237700815029e+00, 2.7169104942556110e+00, 2.9466591763501873e+00, 3.1772458384281856e+00, 3.4087499161671784e+00, 3.6412546993987251e+00, 3.8748478248038931e+00, 4.1096218301890062e+00, 4.3456747816687633e+00, 4.5831109874666334e+00, 4.8220418150442850e+00, 5.0625866320797561e+00, 5.3048738966808706e+00, 5.5490424284915560e+00, 5.7952429005012469e+00, 6.0436396020679171e+00, 6.2944125378566032e+00, 6.5477599464293741e+00, 6.8039013480672903e+00, 7.0630812669681537e+00, 7.3255738226210259e+00, 7.5916884556157704e+00, 7.8617771549009925e+00, 8.1362437033700719e+00, 8.4155556842608696e+00, 8.7002603389157791e+00, 8.9910059185401376e+00, 9.2885710764670684e+00, 9.5939063821323529e+00, 9.9081947567061555e+00, 1.0232942694191875e+01, 1.0570124148913189e+01, 1.0922420304556775e+01, 1.1293648310231410e+01, 1.1689603736290559e+01, 1.2119952689615966e+01, 1.2603462387096409e+01, 1.3189289029708117e+01}, + {-1.3262064314547260e+01, -1.2677296963466635e+01, -1.2194689936989255e+01, -1.1765167072765909e+01, -1.1369991399473138e+01, -1.0999512285277628e+01, -1.0647943408373985e+01, -1.0311473712742933e+01, -9.9874263117220838e+00, -9.6738304400421331e+00, -9.3691820677047506e+00, -9.0723002412708205e+00, -8.7822360072393444e+00, -8.4982120718321887e+00, -8.2195813524123764e+00, -7.9457976314642735e+00, -7.6763942384382915e+00, -7.4109682169993913e+00, -7.1491683376448565e+00, -6.8906858668688686e+00, -6.6352473515597925e+00, -6.3826089025647779e+00, -6.1325516109861775e+00, -5.8848778323693072e+00, -5.6394081442881152e+00, -5.3959788324149320e+00, -5.1544397956688064e+00, -4.9146527868415708e+00, -4.6764899241060425e+00, -4.4398324229806452e+00, -4.2045695090093798e+00, -3.9705974795569130e+00, -3.7378188893809927e+00, -3.5061418395049322e+00, -3.2754793527162449e+00, -3.0457488220163000e+00, -2.8168715207266257e+00, -2.5887721648595683e+00, -2.3613785198892869e+00, -2.1346210452930161e+00, -1.9084325712330619e+00, -1.6827480025638228e+00, -1.4575040460115227e+00, -1.2326389569154106e+00, -1.0080923023599291e+00, -7.8380473788493388e-01, -5.5971779524889242e-01, -3.3577367894853466e-01, -1.1191506937570589e-01, 1.1191506937570589e-01, 3.3577367894853466e-01, 5.5971779524889242e-01, 7.8380473788493388e-01, 1.0080923023599291e+00, 1.2326389569154106e+00, 1.4575040460115227e+00, 1.6827480025638228e+00, 1.9084325712330619e+00, 2.1346210452930161e+00, 2.3613785198892869e+00, 2.5887721648595683e+00, 2.8168715207266257e+00, 3.0457488220163000e+00, 3.2754793527162449e+00, 3.5061418395049322e+00, 3.7378188893809927e+00, 3.9705974795569130e+00, 4.2045695090093798e+00, 4.4398324229806452e+00, 4.6764899241060425e+00, 4.9146527868415708e+00, 5.1544397956688064e+00, 5.3959788324149320e+00, 5.6394081442881152e+00, 5.8848778323693072e+00, 6.1325516109861775e+00, 6.3826089025647779e+00, 6.6352473515597925e+00, 6.8906858668688686e+00, 7.1491683376448565e+00, 7.4109682169993913e+00, 7.6763942384382915e+00, 7.9457976314642735e+00, 8.2195813524123764e+00, 8.4982120718321887e+00, 8.7822360072393444e+00, 9.0723002412708205e+00, 9.3691820677047506e+00, 9.6738304400421331e+00, 9.9874263117220838e+00, 1.0311473712742933e+01, 1.0647943408373985e+01, 1.0999512285277628e+01, 1.1369991399473138e+01, 1.1765167072765909e+01, 1.2194689936989255e+01, 1.2677296963466635e+01, 1.3262064314547260e+01}, + {-1.3334461819943153e+01, -1.2750740722503373e+01, -1.2269024999467902e+01, -1.1840317610615624e+01, -1.1445911484642805e+01, -1.1076171287300262e+01, -1.0725319838167971e+01, -1.0389552102465858e+01, -1.0066195438589224e+01, -9.7532822304545537e+00, -9.4493108799743251e+00, -9.1531023745391185e+00, -8.8637093532419815e+00, -8.5803558609974342e+00, -8.3023959646056102e+00, -8.0292844524423987e+00, -7.7605555495112331e+00, -7.4958071093975249e+00, -7.2346886456654547e+00, -6.9768921155793651e+00, -6.7221447159938794e+00, -6.4702031761523404e+00, -6.2208491815292408e+00, -5.9738856642890008e+00, -5.7291337661713966e+00, -5.4864303291169465e+00, -5.2456258043992712e+00, -5.0065824967968044e+00, -4.7691730793126910e+00, -4.5332793281004458e+00, -4.2987910379219327e+00, -4.0656050865933535e+00, -3.8336246231287601e+00, -3.6027583591447181e+00, -3.3729199468884627e+00, -3.1440274302474247e+00, -2.9160027574766345e+00, -2.6887713462813925e+00, -2.4622616934204693e+00, -2.2364050222293588e+00, -2.0111349624646375e+00, -1.7863872576859270e+00, -1.5620994960576213e+00, -1.3382108609965631e+00, -1.1146618985362737e+00, -8.9139429864040043e-01, -6.6835068799126329e-01, -4.4547443201433412e-01, -2.2270944408436802e-01, -0.0000000000000000e+00, 2.2270944408436802e-01, 4.4547443201433412e-01, 6.6835068799126329e-01, 8.9139429864040043e-01, 1.1146618985362737e+00, 1.3382108609965631e+00, 1.5620994960576213e+00, 1.7863872576859270e+00, 2.0111349624646375e+00, 2.2364050222293588e+00, 2.4622616934204693e+00, 2.6887713462813925e+00, 2.9160027574766345e+00, 3.1440274302474247e+00, 3.3729199468884627e+00, 3.6027583591447181e+00, 3.8336246231287601e+00, 4.0656050865933535e+00, 4.2987910379219327e+00, 4.5332793281004458e+00, 4.7691730793126910e+00, 5.0065824967968044e+00, 5.2456258043992712e+00, 5.4864303291169465e+00, 5.7291337661713966e+00, 5.9738856642890008e+00, 6.2208491815292408e+00, 6.4702031761523404e+00, 6.7221447159938794e+00, 6.9768921155793651e+00, 7.2346886456654547e+00, 7.4958071093975249e+00, 7.7605555495112331e+00, 8.0292844524423987e+00, 8.3023959646056102e+00, 8.5803558609974342e+00, 8.8637093532419815e+00, 9.1531023745391185e+00, 9.4493108799743251e+00, 9.7532822304545537e+00, 1.0066195438589224e+01, 1.0389552102465858e+01, 1.0725319838167971e+01, 1.1076171287300262e+01, 1.1445911484642805e+01, 1.1840317610615624e+01, 1.2269024999467902e+01, 1.2750740722503373e+01, 1.3334461819943153e+01}, + {-1.3406487338144908e+01, -1.2823799749487808e+01, -1.2342964222859672e+01, -1.1915061943114164e+01, -1.1521415400787030e+01, -1.1152404385585125e+01, -1.0802260753684713e+01, -1.0467185421342810e+01, -1.0144509941292846e+01, -9.8322698077779673e+00, -9.5289658233901147e+00, -9.2334208902191612e+00, -8.9446892173254735e+00, -8.6619961681345181e+00, -8.3846969404162657e+00, -8.1122473111627915e+00, -7.8441823844608196e+00, -7.5801008078574874e+00, -7.3196528223045343e+00, -7.0625310602488653e+00, -6.8084633528587952e+00, -6.5572070319215392e+00, -6.3085443611121343e+00, -6.0622788326143020e+00, -5.8182321352035169e+00, -5.5762416493299236e+00, -5.3361583601383602e+00, -5.0978451050891360e+00, -4.8611750917912095e+00, -4.6260306357871555e+00, -4.3923020786826834e+00, -4.1598868551310302e+00, -3.9286886834276706e+00, -3.6986168593184914e+00, -3.4695856364185889e+00, -3.2415136796310131e+00, -3.0143235803311552e+00, -2.7879414239819891e+00, -2.5622964023726080e+00, -2.3373204639068783e+00, -2.1129479963711879e+00, -1.8891155374270083e+00, -1.6657615087415094e+00, -1.4428259702159327e+00, -1.2202503912189531e+00, -9.9797743609810530e-01, -7.7595076154014564e-01, -5.5411482359161690e-01, -3.3241469234223181e-01, -1.1079587242243949e-01, 1.1079587242243949e-01, 3.3241469234223181e-01, 5.5411482359161690e-01, 7.7595076154014564e-01, 9.9797743609810530e-01, 1.2202503912189531e+00, 1.4428259702159327e+00, 1.6657615087415094e+00, 1.8891155374270083e+00, 2.1129479963711879e+00, 2.3373204639068783e+00, 2.5622964023726080e+00, 2.7879414239819891e+00, 3.0143235803311552e+00, 3.2415136796310131e+00, 3.4695856364185889e+00, 3.6986168593184914e+00, 3.9286886834276706e+00, 4.1598868551310302e+00, 4.3923020786826834e+00, 4.6260306357871555e+00, 4.8611750917912095e+00, 5.0978451050891360e+00, 5.3361583601383602e+00, 5.5762416493299236e+00, 5.8182321352035169e+00, 6.0622788326143020e+00, 6.3085443611121343e+00, 6.5572070319215392e+00, 6.8084633528587952e+00, 7.0625310602488653e+00, 7.3196528223045343e+00, 7.5801008078574874e+00, 7.8441823844608196e+00, 8.1122473111627915e+00, 8.3846969404162657e+00, 8.6619961681345181e+00, 8.9446892173254735e+00, 9.2334208902191612e+00, 9.5289658233901147e+00, 9.8322698077779673e+00, 1.0144509941292846e+01, 1.0467185421342810e+01, 1.0802260753684713e+01, 1.1152404385585125e+01, 1.1521415400787030e+01, 1.1915061943114164e+01, 1.2342964222859672e+01, 1.2823799749487808e+01, 1.3406487338144908e+01}, + {-1.3478146515232797e+01, -1.2896479974039561e+01, -1.2416513788721415e+01, -1.1989406490998284e+01, -1.1596509802200323e+01, -1.1228218466075560e+01, -1.0878773272902121e+01, -1.0544381021362536e+01, -1.0222377409009630e+01, -9.9108010025237636e+00, -9.6081549747716188e+00, -9.3132641171485986e+00, -9.0251841867360021e+00, -8.7431418459354120e+00, -8.4664934056489916e+00, -8.1946956148339627e+00, -7.9272844408189824e+00, -7.6638593097942502e+00, -7.4040711750779735e+00, -7.1476133293942068e+00, -6.8942142232839023e+00, -6.6436317759717189e+00, -6.3956488139470400e+00, -6.1500693736430252e+00, -5.9067156746204947e+00, -5.6654256190158065e+00, -5.4260507083580034e+00, -5.1884542945483902e+00, -4.9525101007153634e+00, -4.7181009617643239e+00, -4.4851177450803661e+00, -4.2534584199474237e+00, -4.0230272504840583e+00, -3.7937340917372753e+00, -3.5654937723650511e+00, -3.3382255503269591e+00, -3.1118526303762444e+00, -2.8863017340447339e+00, -2.6615027143383925e+00, -2.4373882085955381e+00, -2.2138933239623526e+00, -1.9909553507579980e+00, -1.7685134996706828e+00, -1.5465086592745161e+00, -1.3248831708071216e+00, -1.1035806175170297e+00, -8.8254562619156474e-01, -6.6172367872096116e-01, -4.4106093175132588e-01, -2.2050404263430215e-01, -0.0000000000000000e+00, 2.2050404263430215e-01, 4.4106093175132588e-01, 6.6172367872096116e-01, 8.8254562619156474e-01, 1.1035806175170297e+00, 1.3248831708071216e+00, 1.5465086592745161e+00, 1.7685134996706828e+00, 1.9909553507579980e+00, 2.2138933239623526e+00, 2.4373882085955381e+00, 2.6615027143383925e+00, 2.8863017340447339e+00, 3.1118526303762444e+00, 3.3382255503269591e+00, 3.5654937723650511e+00, 3.7937340917372753e+00, 4.0230272504840583e+00, 4.2534584199474237e+00, 4.4851177450803661e+00, 4.7181009617643239e+00, 4.9525101007153634e+00, 5.1884542945483902e+00, 5.4260507083580034e+00, 5.6654256190158065e+00, 5.9067156746204947e+00, 6.1500693736430252e+00, 6.3956488139470400e+00, 6.6436317759717189e+00, 6.8942142232839023e+00, 7.1476133293942068e+00, 7.4040711750779735e+00, 7.6638593097942502e+00, 7.9272844408189824e+00, 8.1946956148339627e+00, 8.4664934056489916e+00, 8.7431418459354120e+00, 9.0251841867360021e+00, 9.3132641171485986e+00, 9.6081549747716188e+00, 9.9108010025237636e+00, 1.0222377409009630e+01, 1.0544381021362536e+01, 1.0878773272902121e+01, 1.1228218466075560e+01, 1.1596509802200323e+01, 1.1989406490998284e+01, 1.2416513788721415e+01, 1.2896479974039561e+01, 1.3478146515232797e+01}, + {-1.3549444856223355e+01, -1.2968787175621387e+01, -1.2489679720231214e+01, -1.2063357508698903e+01, -1.1671201169018351e+01, -1.1303620232659483e+01, -1.0954864323727046e+01, -1.0621146056253156e+01, -1.0299805224248269e+01, -9.9888834298724642e+00, -9.6868861866549612e+00, -9.3926401506071997e+00, -9.1052026055338082e+00, -8.8238014938930043e+00, -8.5477942224789647e+00, -8.2766384961541863e+00, -8.0098711302417200e+00, -7.7470923148599020e+00, -7.4879537012921364e+00, -7.2321492282755919e+00, -6.9794079514507139e+00, -6.7294883630724422e+00, -6.4821738377935736e+00, -6.2372689413028590e+00, -5.9945964085177108e+00, -5.7539946473095069e+00, -5.5153156590327264e+00, -5.2784232927787453e+00, -5.0431917691668700e+00, -4.8095044235715418e+00, -4.5772526293071110e+00, -4.3463348693861139e+00, -4.1166559316947993e+00, -3.8881262072644476e+00, -3.6606610751014688e+00, -3.4341803600244734e+00, -3.2086078523280142e+00, -2.9838708799890519e+00, -2.7598999256576846e+00, -2.5366282819075883e+00, -2.3139917392243752e+00, -2.0919283020285095e+00, -1.8703779286996216e+00, -1.6492822921192409e+00, -1.4285845577012724e+00, -1.2082291762513240e+00, -9.8816168930097070e-01, -7.6832854481204382e-01, -5.4867692134760149e-01, -3.2915455896704260e-01, -1.0970959522807897e-01, 1.0970959522807897e-01, 3.2915455896704260e-01, 5.4867692134760149e-01, 7.6832854481204382e-01, 9.8816168930097070e-01, 1.2082291762513240e+00, 1.4285845577012724e+00, 1.6492822921192409e+00, 1.8703779286996216e+00, 2.0919283020285095e+00, 2.3139917392243752e+00, 2.5366282819075883e+00, 2.7598999256576846e+00, 2.9838708799890519e+00, 3.2086078523280142e+00, 3.4341803600244734e+00, 3.6606610751014688e+00, 3.8881262072644476e+00, 4.1166559316947993e+00, 4.3463348693861139e+00, 4.5772526293071110e+00, 4.8095044235715418e+00, 5.0431917691668700e+00, 5.2784232927787453e+00, 5.5153156590327264e+00, 5.7539946473095069e+00, 5.9945964085177108e+00, 6.2372689413028590e+00, 6.4821738377935736e+00, 6.7294883630724422e+00, 6.9794079514507139e+00, 7.2321492282755919e+00, 7.4879537012921364e+00, 7.7470923148599020e+00, 8.0098711302417200e+00, 8.2766384961541863e+00, 8.5477942224789647e+00, 8.8238014938930043e+00, 9.1052026055338082e+00, 9.3926401506071997e+00, 9.6868861866549612e+00, 9.9888834298724642e+00, 1.0299805224248269e+01, 1.0621146056253156e+01, 1.0954864323727046e+01, 1.1303620232659483e+01, 1.1671201169018351e+01, 1.2063357508698903e+01, 1.2489679720231214e+01, 1.2968787175621387e+01, 1.3549444856223355e+01}, + {-1.3620387729947742e+01, -1.3040726988796493e+01, -1.2562467887793943e+01, -1.2136921090287251e+01, -1.1745495813506075e+01, -1.1378616213805854e+01, -1.1030540650989794e+01, -1.0697487488847003e+01, -1.0376800570599057e+01, -1.0066524497824579e+01, -9.7651670958633421e+00, -9.4715568613271639e+00, -9.1847525840655759e+00, -8.9039834682597192e+00, -8.6286079999230569e+00, -8.3580848243237309e+00, -8.0919515900932844e+00, -7.8298092371332197e+00, -7.5713101008750368e+00, -7.3161487524084921e+00, -7.0640548388279587e+00, -6.8147874116676039e+00, -6.5681303797817083e+00, -6.3238888238470219e+00, -6.0818859794767741e+00, -5.8419607451405371e+00, -5.6039656063250805e+00, -5.3677648929830539e+00, -5.1332333061803963e+00, -4.9002546639192408e+00, -4.6687208267203344e+00, -4.4385307716320357e+00, -4.2095897895522105e+00, -3.9818087855776474e+00, -3.7551036658752275e+00, -3.5293947975507334e+00, -3.3046065303600929e+00, -3.0806667710024973e+00, -2.8575066022592246e+00, -2.6350599404753994e+00, -2.4132632258847226e+00, -2.1920551410961067e+00, -1.9713763537322730e+00, -1.7511692797619354e+00, -1.5313778645213059e+00, -1.3119473787947484e+00, -1.0928242276321787e+00, -8.7395576983320977e-01, -6.5529014623361903e-01, -4.3677611509527065e-01, -2.1836289303147782e-01, -0.0000000000000000e+00, 2.1836289303147782e-01, 4.3677611509527065e-01, 6.5529014623361903e-01, 8.7395576983320977e-01, 1.0928242276321787e+00, 1.3119473787947484e+00, 1.5313778645213059e+00, 1.7511692797619354e+00, 1.9713763537322730e+00, 2.1920551410961067e+00, 2.4132632258847226e+00, 2.6350599404753994e+00, 2.8575066022592246e+00, 3.0806667710024973e+00, 3.3046065303600929e+00, 3.5293947975507334e+00, 3.7551036658752275e+00, 3.9818087855776474e+00, 4.2095897895522105e+00, 4.4385307716320357e+00, 4.6687208267203344e+00, 4.9002546639192408e+00, 5.1332333061803963e+00, 5.3677648929830539e+00, 5.6039656063250805e+00, 5.8419607451405371e+00, 6.0818859794767741e+00, 6.3238888238470219e+00, 6.5681303797817083e+00, 6.8147874116676039e+00, 7.0640548388279587e+00, 7.3161487524084921e+00, 7.5713101008750368e+00, 7.8298092371332197e+00, 8.0919515900932844e+00, 8.3580848243237309e+00, 8.6286079999230569e+00, 8.9039834682597192e+00, 9.1847525840655759e+00, 9.4715568613271639e+00, 9.7651670958633421e+00, 1.0066524497824579e+01, 1.0376800570599057e+01, 1.0697487488847003e+01, 1.1030540650989794e+01, 1.1378616213805854e+01, 1.1745495813506075e+01, 1.2136921090287251e+01, 1.2562467887793943e+01, 1.3040726988796493e+01, 1.3620387729947742e+01}, + {-1.3690980373715535e+01, -1.3112304908251922e+01, -1.2634884014394832e+01, -1.2210103175151124e+01, -1.1819399886057777e+01, -1.1453212768894272e+01, -1.1105808823112232e+01, -1.0773412098098593e+01, -1.0453370440115185e+01, -1.0143731414960465e+01, -9.8430051316625278e+00, -9.5500219040630885e+00, -9.2638420079694495e+00, -8.9836958915100507e+00, -8.7089431037842626e+00, -8.4390432154976232e+00, -8.1735346944358760e+00, -7.9120192166772831e+00, -7.6541497885353431e+00, -7.3996216003602537e+00, -7.1481648776449447e+00, -6.8995392180679298e+00, -6.6535290513692580e+00, -6.4099399596264091e+00, -6.1685956652061904e+00, -5.9293355428005707e+00, -5.6920125471434968e+00, -5.4564914735798906e+00, -5.2226474874947222e+00, -4.9903648726555803e+00, -4.7595359591142765e+00, -4.5300601993847316e+00, -4.3018433678250396e+00, -4.0747968629734785e+00, -3.8488370963629586e+00, -3.6238849543164635e+00, -3.3998653215923187e+00, -3.1767066576408891e+00, -2.9543406177575795e+00, -2.7327017126497148e+00, -2.5117270009375883e+00, -2.2913558099291085e+00, -2.0715294806793496e+00, -1.8521911338989445e+00, -1.6332854537309136e+00, -1.4147584867915231e+00, -1.1965574541809449e+00, -9.7863057442477308e-01, -7.6092689551645798e-01, -5.4339613440036172e-01, -3.2598852237076159e-01, -1.0865465496797615e-01, 1.0865465496797615e-01, 3.2598852237076159e-01, 5.4339613440036172e-01, 7.6092689551645798e-01, 9.7863057442477308e-01, 1.1965574541809449e+00, 1.4147584867915231e+00, 1.6332854537309136e+00, 1.8521911338989445e+00, 2.0715294806793496e+00, 2.2913558099291085e+00, 2.5117270009375883e+00, 2.7327017126497148e+00, 2.9543406177575795e+00, 3.1767066576408891e+00, 3.3998653215923187e+00, 3.6238849543164635e+00, 3.8488370963629586e+00, 4.0747968629734785e+00, 4.3018433678250396e+00, 4.5300601993847316e+00, 4.7595359591142765e+00, 4.9903648726555803e+00, 5.2226474874947222e+00, 5.4564914735798906e+00, 5.6920125471434968e+00, 5.9293355428005707e+00, 6.1685956652061904e+00, 6.4099399596264091e+00, 6.6535290513692580e+00, 6.8995392180679298e+00, 7.1481648776449447e+00, 7.3996216003602537e+00, 7.6541497885353431e+00, 7.9120192166772831e+00, 8.1735346944358760e+00, 8.4390432154976232e+00, 8.7089431037842626e+00, 8.9836958915100507e+00, 9.2638420079694495e+00, 9.5500219040630885e+00, 9.8430051316625278e+00, 1.0143731414960465e+01, 1.0453370440115185e+01, 1.0773412098098593e+01, 1.1105808823112232e+01, 1.1453212768894272e+01, 1.1819399886057777e+01, 1.2210103175151124e+01, 1.2634884014394832e+01, 1.3112304908251922e+01, 1.3690980373715535e+01}, + {-1.3761227897775342e+01, -1.3183526293600599e+01, -1.2706933680714704e+01, -1.2282909553416038e+01, -1.1892919380924928e+01, -1.1527416094254811e+01, -1.1180675238467860e+01, -1.0848926485775479e+01, -1.0529521640346799e+01, -1.0220511197831829e+01, -9.9204075235256379e+00, -9.6280427257475036e+00, -9.3424785467404909e+00, -9.0629466613367704e+00, -8.7888076661013130e+00, -8.5195220427131719e+00, -8.2546290644616640e+00, -7.9937311305046359e+00, -7.7364819052916909e+00, -7.4825771858770791e+00, -7.2317477636524030e+00, -6.9837537698848138e+00, -6.7383801424910441e+00, -6.4954329519998799e+00, -6.2547363942623555e+00, -6.0161303065289111e+00, -5.7794680986505123e+00, -5.5446150166977928e+00, -5.3114466751017559e+00, -5.0798478074449882e+00, -4.8497111966094790e+00, -4.6209367530474879e+00, -4.3934307161440911e+00, -4.1671049584554103e+00, -3.9418763763764075e+00, -3.7176663537665213e+00, -3.4944002874250444e+00, -3.2720071651989722e+00, -3.0504191890280565e+00, -2.8295714364637563e+00, -2.6094015552011851e+00, -2.3898494859824693e+00, -2.1708572099022447e+00, -1.9523685166996116e+00, -1.7343287910777165e+00, -1.5166848144697649e+00, -1.2993845799825059e+00, -1.0823771185059250e+00, -8.6561233418988326e-01, -6.4904084766152925e-01, -4.3261384549707677e-01, -2.1628293457217421e-01, -0.0000000000000000e+00, 2.1628293457217421e-01, 4.3261384549707677e-01, 6.4904084766152925e-01, 8.6561233418988326e-01, 1.0823771185059250e+00, 1.2993845799825059e+00, 1.5166848144697649e+00, 1.7343287910777165e+00, 1.9523685166996116e+00, 2.1708572099022447e+00, 2.3898494859824693e+00, 2.6094015552011851e+00, 2.8295714364637563e+00, 3.0504191890280565e+00, 3.2720071651989722e+00, 3.4944002874250444e+00, 3.7176663537665213e+00, 3.9418763763764075e+00, 4.1671049584554103e+00, 4.3934307161440911e+00, 4.6209367530474879e+00, 4.8497111966094790e+00, 5.0798478074449882e+00, 5.3114466751017559e+00, 5.5446150166977928e+00, 5.7794680986505123e+00, 6.0161303065289111e+00, 6.2547363942623555e+00, 6.4954329519998799e+00, 6.7383801424910441e+00, 6.9837537698848138e+00, 7.2317477636524030e+00, 7.4825771858770791e+00, 7.7364819052916909e+00, 7.9937311305046359e+00, 8.2546290644616640e+00, 8.5195220427131719e+00, 8.7888076661013130e+00, 9.0629466613367704e+00, 9.3424785467404909e+00, 9.6280427257475036e+00, 9.9204075235256379e+00, 1.0220511197831829e+01, 1.0529521640346799e+01, 1.0848926485775479e+01, 1.1180675238467860e+01, 1.1527416094254811e+01, 1.1892919380924928e+01, 1.2282909553416038e+01, 1.2706933680714704e+01, 1.3183526293600599e+01, 1.3761227897775342e+01}, + {-1.3831135289582965e+01, -1.3254396373973801e+01, -1.2778622330019754e+01, -1.2355345871125120e+01, -1.1966060141686793e+01, -1.1601232228934139e+01, -1.1255146131451047e+01, -1.0924037082840369e+01, -1.0605260801047601e+01, -1.0296870678005966e+01, -9.9973813085297891e+00, -9.7056265732561915e+00, -9.4206696618824566e+00, -9.1417434592085591e+00, -8.8682095941331820e+00, -8.5995294453241531e+00, -8.3352430784012270e+00, -8.0749536029866285e+00, -7.8183153294116643e+00, -7.5650246493836404e+00, -7.3148129082162541e+00, -7.0674407587544215e+00, -6.8226936349524259e+00, -6.5803780834395011e+00, -6.3403187609122504e+00, -6.1023559541821202e+00, -5.8663435147929848e+00, -5.6321471256242530e+00, -5.3996428356774224e+00, -5.1687158132495581e+00, -4.9392592782592839e+00, -4.7111735825401517e+00, -4.4843654131098756e+00, -4.2587470982328570e+00, -4.0342359998584794e+00, -3.8107539789883282e+00, -3.5882269228863879e+00, -3.3665843249351557e+00, -3.1457589094612213e+00, -2.9256862950849976e+00, -2.7063046911512725e+00, -2.4875546226165683e+00, -2.2693786794419482e+00, -2.0517212870941761e+00, -1.8345284952160181e+00, -1.6177477819054702e+00, -1.4013278713576325e+00, -1.1852185628827800e+00, -9.6937056952866862e-01, -7.5373536471122926e-01, -5.3826503540107018e-01, -3.2291214052800010e-01, -1.0762957335551564e-01, 1.0762957335551564e-01, 3.2291214052800010e-01, 5.3826503540107018e-01, 7.5373536471122926e-01, 9.6937056952866862e-01, 1.1852185628827800e+00, 1.4013278713576325e+00, 1.6177477819054702e+00, 1.8345284952160181e+00, 2.0517212870941761e+00, 2.2693786794419482e+00, 2.4875546226165683e+00, 2.7063046911512725e+00, 2.9256862950849976e+00, 3.1457589094612213e+00, 3.3665843249351557e+00, 3.5882269228863879e+00, 3.8107539789883282e+00, 4.0342359998584794e+00, 4.2587470982328570e+00, 4.4843654131098756e+00, 4.7111735825401517e+00, 4.9392592782592839e+00, 5.1687158132495581e+00, 5.3996428356774224e+00, 5.6321471256242530e+00, 5.8663435147929848e+00, 6.1023559541821202e+00, 6.3403187609122504e+00, 6.5803780834395011e+00, 6.8226936349524259e+00, 7.0674407587544215e+00, 7.3148129082162541e+00, 7.5650246493836404e+00, 7.8183153294116643e+00, 8.0749536029866285e+00, 8.3352430784012270e+00, 8.5995294453241531e+00, 8.8682095941331820e+00, 9.1417434592085591e+00, 9.4206696618824566e+00, 9.7056265732561915e+00, 9.9973813085297891e+00, 1.0296870678005966e+01, 1.0605260801047601e+01, 1.0924037082840369e+01, 1.1255146131451047e+01, 1.1601232228934139e+01, 1.1966060141686793e+01, 1.2355345871125120e+01, 1.2778622330019754e+01, 1.3254396373973801e+01, 1.3831135289582965e+01}, + {-1.3900707417887173e+01, -1.3324920252415142e+01, -1.2849955272837832e+01, -1.2427417635190753e+01, -1.2038827866477725e+01, -1.1674667060202870e+01, -1.1329227578271460e+01, -1.0998750155541702e+01, -1.0680594380572309e+01, -1.0372816508782414e+01, -1.0073933338405658e+01, -9.7827805008057851e+00, -9.4984226146699928e+00, -9.2200937585148388e+00, -8.9471565789061032e+00, -8.6790733379711611e+00, -8.4153848809401453e+00, -8.1556950157409371e+00, -7.8996586867968652e+00, -7.6469728688944967e+00, -7.3973694497863685e+00, -7.1506095923972852e+00, -6.9064792151159047e+00, -6.6647853288831929e+00, -6.4253530391943388e+00, -6.1880230700488541e+00, -5.9526497019202820e+00, -5.7190990412807672e+00, -5.4872475579716511e+00, -5.2569808406969596e+00, -5.0281925314641187e+00, -4.8007834078342349e+00, -4.5746605880295625e+00, -4.3497368387482860e+00, -4.1259299692968714e+00, -3.9031622986173096e+00, -3.6813601841446331e+00, -3.4604536033170050e+00, -3.2403757800798094e+00, -3.0210628499554302e+00, -2.8024535582518539e+00, -2.5844889868023952e+00, -2.3671123053017529e+00, -2.1502685438583309e+00, -1.9339043838414955e+00, -1.7179679644825636e+00, -1.5024087030036999e+00, -1.2871771263105225e+00, -1.0722247125008730e+00, -8.5750374062088575e-01, -6.4296714724579429e-01, -4.2856838858126434e-01, -2.1426130687493608e-01, -0.0000000000000000e+00, 2.1426130687493608e-01, 4.2856838858126434e-01, 6.4296714724579429e-01, 8.5750374062088575e-01, 1.0722247125008730e+00, 1.2871771263105225e+00, 1.5024087030036999e+00, 1.7179679644825636e+00, 1.9339043838414955e+00, 2.1502685438583309e+00, 2.3671123053017529e+00, 2.5844889868023952e+00, 2.8024535582518539e+00, 3.0210628499554302e+00, 3.2403757800798094e+00, 3.4604536033170050e+00, 3.6813601841446331e+00, 3.9031622986173096e+00, 4.1259299692968714e+00, 4.3497368387482860e+00, 4.5746605880295625e+00, 4.8007834078342349e+00, 5.0281925314641187e+00, 5.2569808406969596e+00, 5.4872475579716511e+00, 5.7190990412807672e+00, 5.9526497019202820e+00, 6.1880230700488541e+00, 6.4253530391943388e+00, 6.6647853288831929e+00, 6.9064792151159047e+00, 7.1506095923972852e+00, 7.3973694497863685e+00, 7.6469728688944967e+00, 7.8996586867968652e+00, 8.1556950157409371e+00, 8.4153848809401453e+00, 8.6790733379711611e+00, 8.9471565789061032e+00, 9.2200937585148388e+00, 9.4984226146699928e+00, 9.7827805008057851e+00, 1.0073933338405658e+01, 1.0372816508782414e+01, 1.0680594380572309e+01, 1.0998750155541702e+01, 1.1329227578271460e+01, 1.1674667060202870e+01, 1.2038827866477725e+01, 1.2427417635190753e+01, 1.2849955272837832e+01, 1.3324920252415142e+01, 1.3900707417887173e+01}, + {-1.3969949036642459e+01, -1.3395102910086411e+01, -1.2920937691432538e+01, -1.2499130218130038e+01, -1.2111228112984248e+01, -1.1747726328818176e+01, -1.1402925502488745e+01, -1.1073071811228770e+01, -1.0755528671982248e+01, -1.0448355171600436e+01, -1.0150070286259611e+01, -9.8595113770046634e+00, -9.5757444735437325e+00, -9.2980048323218245e+00, -9.0256561033487941e+00, -8.7581614191156962e+00, -8.4950623921731907e+00, -8.2359635170287859e+00, -7.9805203608479554e+00, -7.7284304703735840e+00, -7.4794262647792982e+00, -7.2332694060552951e+00, -6.9897462859257979e+00, -6.7486643683832410e+00, -6.5098491962299123e+00, -6.2731419188661652e+00, -6.0383972335511160e+00, -5.8054816577895725e+00, -5.5742720692284102e+00, -5.3446544634117208e+00, -5.1165228902768884e+00, -4.8897785383006882e+00, -4.6643289413814166e+00, -4.4400872883391642e+00, -4.2169718186716345e+00, -3.9949052911662122e+00, -3.7738145143243407e+00, -3.5536299294390266e+00, -3.3342852386840143e+00, -3.1157170718023619e+00, -2.8978646859830590e+00, -2.6806696943332091e+00, -2.4640758190263061e+00, -2.2480286657622290e+00, -2.0324755166339639e+00, -1.8173651388771286e+00, -1.6026476072949805e+00, -1.3882741384147259e+00, -1.1741969346494687e+00, -9.6036903692102105e-01, -7.4674418434770939e-01, -5.3327667972273107e-01, -3.1992125960608508e-01, -1.0663296792943616e-01, 1.0663296792943616e-01, 3.1992125960608508e-01, 5.3327667972273107e-01, 7.4674418434770939e-01, 9.6036903692102105e-01, 1.1741969346494687e+00, 1.3882741384147259e+00, 1.6026476072949805e+00, 1.8173651388771286e+00, 2.0324755166339639e+00, 2.2480286657622290e+00, 2.4640758190263061e+00, 2.6806696943332091e+00, 2.8978646859830590e+00, 3.1157170718023619e+00, 3.3342852386840143e+00, 3.5536299294390266e+00, 3.7738145143243407e+00, 3.9949052911662122e+00, 4.2169718186716345e+00, 4.4400872883391642e+00, 4.6643289413814166e+00, 4.8897785383006882e+00, 5.1165228902768884e+00, 5.3446544634117208e+00, 5.5742720692284102e+00, 5.8054816577895725e+00, 6.0383972335511160e+00, 6.2731419188661652e+00, 6.5098491962299123e+00, 6.7486643683832410e+00, 6.9897462859257979e+00, 7.2332694060552951e+00, 7.4794262647792982e+00, 7.7284304703735840e+00, 7.9805203608479554e+00, 8.2359635170287859e+00, 8.4950623921731907e+00, 8.7581614191156962e+00, 9.0256561033487941e+00, 9.2980048323218245e+00, 9.5757444735437325e+00, 9.8595113770046634e+00, 1.0150070286259611e+01, 1.0448355171600436e+01, 1.0755528671982248e+01, 1.1073071811228770e+01, 1.1402925502488745e+01, 1.1747726328818176e+01, 1.2111228112984248e+01, 1.2499130218130038e+01, 1.2920937691432538e+01, 1.3395102910086411e+01, 1.3969949036642459e+01}, + {-1.4038864788757728e+01, -1.3464949210295044e+01, -1.2991574644085651e+01, -1.2570488862595592e+01, -1.2183266303224141e+01, -1.1820415634054809e+01, -1.1476245680301457e+01, -1.1147008003906418e+01, -1.0830069808875091e+01, -1.0523492982154455e+01, -1.0225798652986768e+01, -9.9358258915767603e+00, -9.6526421211592019e+00, -9.3754837607621955e+00, -9.1037154500398181e+00, -8.8368011791635279e+00, -8.5742833161234948e+00, -8.3157670306912532e+00, -8.0609085018410500e+00, -7.8094058375754942e+00, -7.5609919779111072e+00, -7.3154290733448306e+00, -7.0725039783127066e+00, -6.8320245990954787e+00, -6.5938169048330693e+00, -6.3577224590892367e+00, -6.1235963643451115e+00, -5.8913055371925065e+00, -5.6607272507011190e+00, -5.4317478943805018e+00, -5.2042619126759186e+00, -4.9781708909532618e+00, -4.7533827640966910e+00, -4.5298111276324908e+00, -4.3073746350430024e+00, -4.0859964678941409e+00, -3.8656038677524993e+00, -3.6461277207507310e+00, -3.4275021871760831e+00, -3.2096643696850733e+00, -2.9925540147475451e+00, -2.7761132427418982e+00, -2.5602863027962388e+00, -2.3450193490255717e+00, -2.1302602352750175e+00, -1.9159583258608970e+00, -1.7020643201191179e+00, -1.4885300888347839e+00, -1.2753085208470012e+00, -1.0623533783056693e+00, -8.4961915920820152e-01, -6.3706096596817285e-01, -4.2463437886846966e-01, -2.1229533333143397e-01, -0.0000000000000000e+00, 2.1229533333143397e-01, 4.2463437886846966e-01, 6.3706096596817285e-01, 8.4961915920820152e-01, 1.0623533783056693e+00, 1.2753085208470012e+00, 1.4885300888347839e+00, 1.7020643201191179e+00, 1.9159583258608970e+00, 2.1302602352750175e+00, 2.3450193490255717e+00, 2.5602863027962388e+00, 2.7761132427418982e+00, 2.9925540147475451e+00, 3.2096643696850733e+00, 3.4275021871760831e+00, 3.6461277207507310e+00, 3.8656038677524993e+00, 4.0859964678941409e+00, 4.3073746350430024e+00, 4.5298111276324908e+00, 4.7533827640966910e+00, 4.9781708909532618e+00, 5.2042619126759186e+00, 5.4317478943805018e+00, 5.6607272507011190e+00, 5.8913055371925065e+00, 6.1235963643451115e+00, 6.3577224590892367e+00, 6.5938169048330693e+00, 6.8320245990954787e+00, 7.0725039783127066e+00, 7.3154290733448306e+00, 7.5609919779111072e+00, 7.8094058375754942e+00, 8.0609085018410500e+00, 8.3157670306912532e+00, 8.5742833161234948e+00, 8.8368011791635279e+00, 9.1037154500398181e+00, 9.3754837607621955e+00, 9.6526421211592019e+00, 9.9358258915767603e+00, 1.0225798652986768e+01, 1.0523492982154455e+01, 1.0830069808875091e+01, 1.1147008003906418e+01, 1.1476245680301457e+01, 1.1820415634054809e+01, 1.2183266303224141e+01, 1.2570488862595592e+01, 1.2991574644085651e+01, 1.3464949210295044e+01, 1.4038864788757728e+01}, + {-1.4107459209689143e+01, -1.3534463902352346e+01, -1.3061871069197858e+01, -1.2641498685712268e+01, -1.2254947728119026e+01, -1.1892740438516830e+01, -1.1549193745603484e+01, -1.1220564539543394e+01, -1.0904223770953831e+01, -1.0598236096233554e+01, -1.0301124773392132e+01, -1.0011730561776583e+01, -9.7291222611091452e+00, -9.4525374380792577e+00, -9.1813417085894020e+00, -8.9149999082012474e+00, -8.6530551488522143e+00, -8.3951132646519024e+00, -8.1408310358446965e+00, -7.8899071213998058e+00, -7.6420749720138357e+00, -7.3970972165620390e+00, -7.1547611620163289e+00, -6.9148751466506351e+00, -6.6772655554639746e+00, -6.4417743554625506e+00, -6.2082570433307618e+00, -5.9765809233777674e+00, -5.7466236523236125e+00, -5.5182720014163928e+00, -5.2914207968757996e+00, -5.0659720076635653e+00, -4.8418339557415173e+00, -4.6189206287614857e+00, -4.3971510788768189e+00, -4.1764488943211937e+00, -3.9567417327500811e+00, -3.7379609072207938e+00, -3.5200410172016268e+00, -3.3029196182276346e+00, -3.0865369248200669e+00, -2.8708355421046665e+00, -2.6557602222368328e+00, -2.4412576422971846e+00, -2.2272762007812905e+00, -2.0137658301898180e+00, -1.8006778235437944e+00, -1.5879646729152568e+00, -1.3755799182849759e+00, -1.1634780052233955e+00, -9.5161415004400396e-01, -7.3994421120471532e-01, -5.2842456583606134e-01, -3.1701199035803573e-01, -1.0566354421255454e-01, 1.0566354421255454e-01, 3.1701199035803573e-01, 5.2842456583606134e-01, 7.3994421120471532e-01, 9.5161415004400396e-01, 1.1634780052233955e+00, 1.3755799182849759e+00, 1.5879646729152568e+00, 1.8006778235437944e+00, 2.0137658301898180e+00, 2.2272762007812905e+00, 2.4412576422971846e+00, 2.6557602222368328e+00, 2.8708355421046665e+00, 3.0865369248200669e+00, 3.3029196182276346e+00, 3.5200410172016268e+00, 3.7379609072207938e+00, 3.9567417327500811e+00, 4.1764488943211937e+00, 4.3971510788768189e+00, 4.6189206287614857e+00, 4.8418339557415173e+00, 5.0659720076635653e+00, 5.2914207968757996e+00, 5.5182720014163928e+00, 5.7466236523236125e+00, 5.9765809233777674e+00, 6.2082570433307618e+00, 6.4417743554625506e+00, 6.6772655554639746e+00, 6.9148751466506351e+00, 7.1547611620163289e+00, 7.3970972165620390e+00, 7.6420749720138357e+00, 7.8899071213998058e+00, 8.1408310358446965e+00, 8.3951132646519024e+00, 8.6530551488522143e+00, 8.9149999082012474e+00, 9.1813417085894020e+00, 9.4525374380792577e+00, 9.7291222611091452e+00, 1.0011730561776583e+01, 1.0301124773392132e+01, 1.0598236096233554e+01, 1.0904223770953831e+01, 1.1220564539543394e+01, 1.1549193745603484e+01, 1.1892740438516830e+01, 1.2254947728119026e+01, 1.2641498685712268e+01, 1.3061871069197858e+01, 1.3534463902352346e+01, 1.4107459209689143e+01}, + {-1.4175736730885069e+01, -1.3603651625271072e+01, -1.3131831789217085e+01, -1.2712164683229908e+01, -1.2326277551871243e+01, -1.1964706072741592e+01, -1.1621775194820279e+01, -1.1293747081147552e+01, -1.0977996389349029e+01, -1.0672590515300062e+01, -1.0376054822035842e+01, -1.0087231738512564e+01, -9.8051914243374672e+00, -9.5291725793451221e+00, -9.2585417826765291e+00, -8.9927647033681737e+00, -8.7313851861824325e+00, -8.4740097190111463e+00, -8.2202956732045873e+00, -7.9699422487875475e+00, -7.7226833973667368e+00, -7.4782822164736231e+00, -7.2365264558624682e+00, -6.9972248759462685e+00, -6.7602042675666434e+00, -6.5253069909368815e+00, -6.2923889264375843e+00, -6.0613177552660416e+00, -5.8319715065921489e+00, -5.6042373217821275e+00, -5.3780103967408355e+00, -5.1531930714178591e+00, -4.9296940416745816e+00, -4.7074276734866194e+00, -4.4863134031967471e+00, -4.2662752104856114e+00, -4.0472411530744239e+00, -3.8291429540521795e+00, -3.6119156342329615e+00, -3.3954971831747680e+00, -3.1798282634899460e+00, -2.9648519438950705e+00, -2.7505134571206762e+00, -2.5367599793568107e+00, -2.3235404283709329e+00, -2.1108052778175836e+00, -1.8985063855784825e+00, -1.6865968342381339e+00, -1.4750307820226600e+00, -1.2637633227153910e+00, -1.0527503532175146e+00, -8.4194844755040910e-01, -6.3131473620181966e-01, -4.2080678980376768e-01, -2.1038250619832910e-01, -0.0000000000000000e+00, 2.1038250619832910e-01, 4.2080678980376768e-01, 6.3131473620181966e-01, 8.4194844755040910e-01, 1.0527503532175146e+00, 1.2637633227153910e+00, 1.4750307820226600e+00, 1.6865968342381339e+00, 1.8985063855784825e+00, 2.1108052778175836e+00, 2.3235404283709329e+00, 2.5367599793568107e+00, 2.7505134571206762e+00, 2.9648519438950705e+00, 3.1798282634899460e+00, 3.3954971831747680e+00, 3.6119156342329615e+00, 3.8291429540521795e+00, 4.0472411530744239e+00, 4.2662752104856114e+00, 4.4863134031967471e+00, 4.7074276734866194e+00, 4.9296940416745816e+00, 5.1531930714178591e+00, 5.3780103967408355e+00, 5.6042373217821275e+00, 5.8319715065921489e+00, 6.0613177552660416e+00, 6.2923889264375843e+00, 6.5253069909368815e+00, 6.7602042675666434e+00, 6.9972248759462685e+00, 7.2365264558624682e+00, 7.4782822164736231e+00, 7.7226833973667368e+00, 7.9699422487875475e+00, 8.2202956732045873e+00, 8.4740097190111463e+00, 8.7313851861824325e+00, 8.9927647033681737e+00, 9.2585417826765291e+00, 9.5291725793451221e+00, 9.8051914243374672e+00, 1.0087231738512564e+01, 1.0376054822035842e+01, 1.0672590515300062e+01, 1.0977996389349029e+01, 1.1293747081147552e+01, 1.1621775194820279e+01, 1.1964706072741592e+01, 1.2326277551871243e+01, 1.2712164683229908e+01, 1.3131831789217085e+01, 1.3603651625271072e+01, 1.4175736730885069e+01}, + {-1.4243701683090396e+01, -1.3672516911310485e+01, -1.3201461514403192e+01, -1.2782491733501539e+01, -1.2397260816155137e+01, -1.2036317739606817e+01, -1.1693995391536458e+01, -1.1366561153620273e+01, -1.1051393351707578e+01, -1.0746562091821255e+01, -1.0450594818817532e+01, -1.0162335612194752e+01, -9.8808559752619285e+00, -9.6053957268710537e+00, -9.3353223967607271e+00, -9.0701024758844149e+00, -8.8092805310594660e+00, -8.5524636937560086e+00, -8.2993099166213113e+00, -8.0495189311868405e+00, -7.8028251805712348e+00, -7.5589922216241447e+00, -7.3178082375274442e+00, -7.0790824013949303e+00, -6.8426419003295491e+00, -6.6083294779732258e+00, -6.3760013883766673e+00, -6.1455256793035486e+00, -5.9167807417097054e+00, -5.6896540760274723e+00, -5.4640412363607487e+00, -5.2398449216799987e+00, -5.0169741892502993e+00, -4.7953437702964461e+00, -4.5748734716450743e+00, -4.3554876500322477e+00, -4.1371147481089601e+00, -3.9196868830532363e+00, -3.7031394802088755e+00, -3.4874109453955420e+00, -3.2724423705327612e+00, -3.0581772680375412e+00, -2.8445613301276866e+00, -2.6315422097183796e+00, -2.4190693200603040e+00, -2.2070936506509247e+00, -1.9955675972702900e+00, -1.7844448042599628e+00, -1.5736800173872914e+00, -1.3632289458242499e+00, -1.1530481319262951e+00, -9.4309482762671593e-01, -7.3332687636947402e-01, -5.2370259959160714e-01, -3.1418068683720984e-01, -1.0472008864073033e-01, 1.0472008864073033e-01, 3.1418068683720984e-01, 5.2370259959160714e-01, 7.3332687636947402e-01, 9.4309482762671593e-01, 1.1530481319262951e+00, 1.3632289458242499e+00, 1.5736800173872914e+00, 1.7844448042599628e+00, 1.9955675972702900e+00, 2.2070936506509247e+00, 2.4190693200603040e+00, 2.6315422097183796e+00, 2.8445613301276866e+00, 3.0581772680375412e+00, 3.2724423705327612e+00, 3.4874109453955420e+00, 3.7031394802088755e+00, 3.9196868830532363e+00, 4.1371147481089601e+00, 4.3554876500322477e+00, 4.5748734716450743e+00, 4.7953437702964461e+00, 5.0169741892502993e+00, 5.2398449216799987e+00, 5.4640412363607487e+00, 5.6896540760274723e+00, 5.9167807417097054e+00, 6.1455256793035486e+00, 6.3760013883766673e+00, 6.6083294779732258e+00, 6.8426419003295491e+00, 7.0790824013949303e+00, 7.3178082375274442e+00, 7.5589922216241447e+00, 7.8028251805712348e+00, 8.0495189311868405e+00, 8.2993099166213113e+00, 8.5524636937560086e+00, 8.8092805310594660e+00, 9.0701024758844149e+00, 9.3353223967607271e+00, 9.6053957268710537e+00, 9.8808559752619285e+00, 1.0162335612194752e+01, 1.0450594818817532e+01, 1.0746562091821255e+01, 1.1051393351707578e+01, 1.1366561153620273e+01, 1.1693995391536458e+01, 1.2036317739606817e+01, 1.2397260816155137e+01, 1.2782491733501539e+01, 1.3201461514403192e+01, 1.3672516911310485e+01, 1.4243701683090396e+01}, + {-1.4311358299517268e+01, -1.3741064189376445e+01, -1.3270764846437274e+01, -1.2852484601295865e+01, -1.2467902444132251e+01, -1.2107580518550922e+01, -1.1765859570925668e+01, -1.1439012148401694e+01, -1.1124420207060311e+01, -1.0820156534367447e+01, -1.0524750634313888e+01, -1.0237048218321810e+01, -9.9561221176215060e+00, -9.6812132563270588e+00, -9.4116901024866948e+00, -9.1470199577543809e+00, -8.8867481005681856e+00, -8.6304822961073278e+00, -8.3778810688446761e+00, -8.1286446726129125e+00, -7.8825080329965438e+00, -7.6392351571886659e+00, -7.3986146528207790e+00, -7.1604560966616368e+00, -6.9245870629045054e+00, -6.6908506692717395e+00, -6.4591035339104934e+00, -6.2292140613060107e+00, -6.0010609940399187e+00, -5.7745321810917920e+00, -5.5495235238436296e+00, -5.3259380689199052e+00, -5.1036852231316345e+00, -4.8826800705576368e+00, -4.6628427755272810e+00, -4.4440980582138394e+00, -4.2263747318887201e+00, -4.0096052927608685e+00, -3.7937255548353970e+00, -3.5786743234488534e+00, -3.3643931021355877e+00, -3.1508258282961985e+00, -2.9379186338110879e+00, -2.7256196272975335e+00, -2.5138786951694905e+00, -2.3026473190429599e+00, -2.0918784073499572e+00, -1.8815261392920377e+00, -1.6715458194887483e+00, -1.4618937418644296e+00, -1.2525270614742765e+00, -1.0434036731020315e+00, -8.3448209557097697e-01, -6.2572136079995633e-01, -4.1708090670945613e-01, -2.0852047314122538e-01, -0.0000000000000000e+00, 2.0852047314122538e-01, 4.1708090670945613e-01, 6.2572136079995633e-01, 8.3448209557097697e-01, 1.0434036731020315e+00, 1.2525270614742765e+00, 1.4618937418644296e+00, 1.6715458194887483e+00, 1.8815261392920377e+00, 2.0918784073499572e+00, 2.3026473190429599e+00, 2.5138786951694905e+00, 2.7256196272975335e+00, 2.9379186338110879e+00, 3.1508258282961985e+00, 3.3643931021355877e+00, 3.5786743234488534e+00, 3.7937255548353970e+00, 4.0096052927608685e+00, 4.2263747318887201e+00, 4.4440980582138394e+00, 4.6628427755272810e+00, 4.8826800705576368e+00, 5.1036852231316345e+00, 5.3259380689199052e+00, 5.5495235238436296e+00, 5.7745321810917920e+00, 6.0010609940399187e+00, 6.2292140613060107e+00, 6.4591035339104934e+00, 6.6908506692717395e+00, 6.9245870629045054e+00, 7.1604560966616368e+00, 7.3986146528207790e+00, 7.6392351571886659e+00, 7.8825080329965438e+00, 8.1286446726129125e+00, 8.3778810688446761e+00, 8.6304822961073278e+00, 8.8867481005681856e+00, 9.1470199577543809e+00, 9.4116901024866948e+00, 9.6812132563270588e+00, 9.9561221176215060e+00, 1.0237048218321810e+01, 1.0524750634313888e+01, 1.0820156534367447e+01, 1.1124420207060311e+01, 1.1439012148401694e+01, 1.1765859570925668e+01, 1.2107580518550922e+01, 1.2467902444132251e+01, 1.2852484601295865e+01, 1.3270764846437274e+01, 1.3741064189376445e+01, 1.4311358299517268e+01}, + {-1.4378710718888687e+01, -1.3809297788283777e+01, -1.3339746281883333e+01, -1.2922147941452449e+01, -1.2538207244299381e+01, -1.2178499369616199e+01, -1.1837372843992933e+01, -1.1511105327917651e+01, -1.1197082370480098e+01, -1.0893379412488740e+01, -1.0598527994882549e+01, -1.0311375442821380e+01, -1.0030995900063404e+01, -9.7566313825866331e+00, -9.4876512847987584e+00, -9.2235237081638886e+00, -8.9637946326267190e+00, -8.7080724475249998e+00, -8.4560162400066048e+00, -8.2073267773259264e+00, -7.9617394588210120e+00, -7.7190187333975366e+00, -7.4789536245148378e+00, -7.2413541039213873e+00, -7.0060481241167620e+00, -6.7728791679610003e+00, -6.5417042085499943e+00, -6.3123919976942711e+00, -6.0848216199144423e+00, -5.8588812627189206e+00, -5.6344671643769209e+00, -5.4114827083623283e+00, -5.1898376397716799e+00, -4.9694473837781068e+00, -4.7502324499094550e+00, -4.5321179088799042e+00, -4.3150329310427544e+00, -4.0989103774038682e+00, -3.8836864356433058e+00, -3.6693002948148599e+00, -3.4556938533892665e+00, -3.2428114561228023e+00, -3.0305996559046307e+00, -2.8190069972914444e+00, -2.6079838188988345e+00, -2.3974820722025694e+00, -2.1874551546235876e+00, -1.9778577550389427e+00, -1.7686457100860522e+00, -1.5597758698165716e+00, -1.3512059714147289e+00, -1.1428945198277283e+00, -9.3480067426661317e-01, -7.2688413962779108e-01, -5.1910506196077233e-01, -3.1142392716846806e-01, -1.0380146217422165e-01, 1.0380146217422165e-01, 3.1142392716846806e-01, 5.1910506196077233e-01, 7.2688413962779108e-01, 9.3480067426661317e-01, 1.1428945198277283e+00, 1.3512059714147289e+00, 1.5597758698165716e+00, 1.7686457100860522e+00, 1.9778577550389427e+00, 2.1874551546235876e+00, 2.3974820722025694e+00, 2.6079838188988345e+00, 2.8190069972914444e+00, 3.0305996559046307e+00, 3.2428114561228023e+00, 3.4556938533892665e+00, 3.6693002948148599e+00, 3.8836864356433058e+00, 4.0989103774038682e+00, 4.3150329310427544e+00, 4.5321179088799042e+00, 4.7502324499094550e+00, 4.9694473837781068e+00, 5.1898376397716799e+00, 5.4114827083623283e+00, 5.6344671643769209e+00, 5.8588812627189206e+00, 6.0848216199144423e+00, 6.3123919976942711e+00, 6.5417042085499943e+00, 6.7728791679610003e+00, 7.0060481241167620e+00, 7.2413541039213873e+00, 7.4789536245148378e+00, 7.7190187333975366e+00, 7.9617394588210120e+00, 8.2073267773259264e+00, 8.4560162400066048e+00, 8.7080724475249998e+00, 8.9637946326267190e+00, 9.2235237081638886e+00, 9.4876512847987584e+00, 9.7566313825866331e+00, 1.0030995900063404e+01, 1.0311375442821380e+01, 1.0598527994882549e+01, 1.0893379412488740e+01, 1.1197082370480098e+01, 1.1511105327917651e+01, 1.1837372843992933e+01, 1.2178499369616199e+01, 1.2538207244299381e+01, 1.2922147941452449e+01, 1.3339746281883333e+01, 1.3809297788283777e+01, 1.4378710718888687e+01}, + {-1.4445762988361196e+01, -1.3877221939887596e+01, -1.3408410215509624e+01, -1.2991486302387372e+01, -1.2608179914177892e+01, -1.2249079137323781e+01, -1.1908540201639026e+01, -1.1582845829838529e+01, -1.1269385127541279e+01, -1.0966236161382101e+01, -1.0671932487544689e+01, -1.0385323027156920e+01, -1.0105483221483672e+01, -9.8316561653115180e+00, -9.5632121677809998e+00, -9.2996201195877468e+00, -9.0404266923744707e+00, -8.7852408903904529e+00, -8.5337223546130900e+00, -8.2855723571485260e+00, -8.0405267626925543e+00, -7.7983504535582933e+00, -7.5588328607481419e+00, -7.3217843426652625e+00, -7.0870332216969052e+00, -6.8544233372804051e+00, -6.6238120087139674e+00, -6.3950683261592980e+00, -6.1680717068342963e+00, -5.9427106672279626e+00, -5.7188817726033569e+00, -5.4964887330064514e+00, -5.2754416211185129e+00, -5.0556561920420737e+00, -4.8370532888321796e+00, -4.6195583205220858e+00, -4.4031008017280051e+00, -4.1876139447872083e+00, -3.9730342968900869e+00, -3.7593014158877045e+00, -3.5463575794514748e+00, -3.3341475230768891e+00, -3.1226182030944165e+00, -2.9117185814056987e+00, -2.7013994291239474e+00, -2.4916131466813880e+00, -2.2823135982874576e+00, -2.0734559588903583e+00, -1.8649965720202712e+00, -1.6568928170822563e+00, -1.4491029848262951e+00, -1.2415861598558324e+00, -1.0343021091482230e+00, -8.2721117565385283e-01, -6.2027417611781133e-01, -4.1345230233083557e-01, -2.0670702506645103e-01, -0.0000000000000000e+00, 2.0670702506645103e-01, 4.1345230233083557e-01, 6.2027417611781133e-01, 8.2721117565385283e-01, 1.0343021091482230e+00, 1.2415861598558324e+00, 1.4491029848262951e+00, 1.6568928170822563e+00, 1.8649965720202712e+00, 2.0734559588903583e+00, 2.2823135982874576e+00, 2.4916131466813880e+00, 2.7013994291239474e+00, 2.9117185814056987e+00, 3.1226182030944165e+00, 3.3341475230768891e+00, 3.5463575794514748e+00, 3.7593014158877045e+00, 3.9730342968900869e+00, 4.1876139447872083e+00, 4.4031008017280051e+00, 4.6195583205220858e+00, 4.8370532888321796e+00, 5.0556561920420737e+00, 5.2754416211185129e+00, 5.4964887330064514e+00, 5.7188817726033569e+00, 5.9427106672279626e+00, 6.1680717068342963e+00, 6.3950683261592980e+00, 6.6238120087139674e+00, 6.8544233372804051e+00, 7.0870332216969052e+00, 7.3217843426652625e+00, 7.5588328607481419e+00, 7.7983504535582933e+00, 8.0405267626925543e+00, 8.2855723571485260e+00, 8.5337223546130900e+00, 8.7852408903904529e+00, 9.0404266923744707e+00, 9.2996201195877468e+00, 9.5632121677809998e+00, 9.8316561653115180e+00, 1.0105483221483672e+01, 1.0385323027156920e+01, 1.0671932487544689e+01, 1.0966236161382101e+01, 1.1269385127541279e+01, 1.1582845829838529e+01, 1.1908540201639026e+01, 1.2249079137323781e+01, 1.2608179914177892e+01, 1.2991486302387372e+01, 1.3408410215509624e+01, 1.3877221939887596e+01, 1.4445762988361196e+01}, + {-1.4512519066332473e+01, -1.3944840782089997e+01, -1.3476760943476538e+01, -1.3060504129456817e+01, -1.2677825043852227e+01, -1.2319324554388889e+01, -1.1979366518555956e+01, -1.1654238671159664e+01, -1.1341333638590701e+01, -1.1038732086359635e+01, -1.0744969564657922e+01, -1.0458896573213373e+01, -1.0179589836134598e+01, -9.9062935142905033e+00, -9.6383788202379357e+00, -9.3753154236236274e+00, -9.1166506782713626e+00, -8.8619941943843266e+00, -8.6110061582143160e+00, -8.3633883384434800e+00, -8.1188770570299589e+00, -7.8772376216979518e+00, -7.6382598630271916e+00, -7.4017545180817317e+00, -7.1675502710629999e+00, -6.9354913097861042e+00, -6.7054352913834911e+00, -6.4772516357915970e+00, -6.2508200841027559e+00, -6.0260294726803698e+00, -5.8027766843552886e+00, -5.5809657459630806e+00, -5.3605070475936927e+00, -5.1413166636713479e+00, -4.9233157596994808e+00, -4.7064300714392884e+00, -4.4905894456231428e+00, -4.2757274331715260e+00, -4.0617809273868284e+00, -3.8486898408169177e+00, -3.6363968154755777e+00, -3.4248469619214639e+00, -3.2139876233679749e+00, -3.0037681615511667e+00, -2.7941397615435219e+00, -2.5850552530853812e+00, -2.3764689463269284e+00, -2.1683364801428588e+00, -1.9606146814080672e+00, -1.7532614338130410e+00, -1.5462355549578937e+00, -1.3394966805987920e+00, -1.1330051550337377e+00, -9.2672192670934395e-01, -7.2060844820888659e-01, -5.1462657984655003e-01, -3.0873849614504811e-01, -1.0290659451494534e-01, 1.0290659451494534e-01, 3.0873849614504811e-01, 5.1462657984655003e-01, 7.2060844820888659e-01, 9.2672192670934395e-01, 1.1330051550337377e+00, 1.3394966805987920e+00, 1.5462355549578937e+00, 1.7532614338130410e+00, 1.9606146814080672e+00, 2.1683364801428588e+00, 2.3764689463269284e+00, 2.5850552530853812e+00, 2.7941397615435219e+00, 3.0037681615511667e+00, 3.2139876233679749e+00, 3.4248469619214639e+00, 3.6363968154755777e+00, 3.8486898408169177e+00, 4.0617809273868284e+00, 4.2757274331715260e+00, 4.4905894456231428e+00, 4.7064300714392884e+00, 4.9233157596994808e+00, 5.1413166636713479e+00, 5.3605070475936927e+00, 5.5809657459630806e+00, 5.8027766843552886e+00, 6.0260294726803698e+00, 6.2508200841027559e+00, 6.4772516357915970e+00, 6.7054352913834911e+00, 6.9354913097861042e+00, 7.1675502710629999e+00, 7.4017545180817317e+00, 7.6382598630271916e+00, 7.8772376216979518e+00, 8.1188770570299589e+00, 8.3633883384434800e+00, 8.6110061582143160e+00, 8.8619941943843266e+00, 9.1166506782713626e+00, 9.3753154236236274e+00, 9.6383788202379357e+00, 9.9062935142905033e+00, 1.0179589836134598e+01, 1.0458896573213373e+01, 1.0744969564657922e+01, 1.1038732086359635e+01, 1.1341333638590701e+01, 1.1654238671159664e+01, 1.1979366518555956e+01, 1.2319324554388889e+01, 1.2677825043852227e+01, 1.3060504129456817e+01, 1.3476760943476538e+01, 1.3944840782089997e+01, 1.4512519066332473e+01}, + {-1.4578982825139288e+01, -1.4012158361728110e+01, -1.3544802666397535e+01, -1.3129205768185479e+01, -1.2747147119365039e+01, -1.2389240245284292e+01, -1.2049856556961975e+01, -1.1725288752112307e+01, -1.1412932942839976e+01, -1.1110872367128264e+01, -1.0817644548390337e+01, -1.0532101547973223e+01, -1.0253321358511124e+01, -9.9805491945452847e+00, -9.7131571610296650e+00, -9.4506156965670485e+00, -9.1924728279240568e+00, -8.9383387625761230e+00, -8.6878742237708870e+00, -8.4407814687705134e+00, -8.1967972689854154e+00, -7.9556873498473575e+00, -7.7172419338499774e+00, -7.4812721290378645e+00, -7.2476069736794351e+00, -7.0160909961088489e+00, -6.7865821832816833e+00, -6.5589502767074928e+00, -6.3330753329246656e+00, -6.1088464994807214e+00, -5.8861609677875624e+00, -5.6649230721526251e+00, -5.4450435103908958e+00, -5.2264386661630065e+00, -5.0090300168969302e+00, -4.7927436140809663e+00, -4.5775096250454670e+00, -4.3632619272160529e+00, -4.1499377473239889e+00, -3.9374773392776570e+00, -3.7258236953922830e+00, -3.5149222864888690e+00, -3.3047208270435604e+00, -3.0951690621230776e+00, -2.8862185733023908e+00, -2.6778226011448112e+00, -2.4699358821459070e+00, -2.2625144983121754e+00, -2.0555157377720055e+00, -1.8488979650073754e+00, -1.6426204994556326e+00, -1.4366435013663816e+00, -1.2309278639126584e+00, -1.0254351106514223e+00, -8.2012729750837221e-01, -6.1496691852828633e-01, -4.0991681468614050e-01, -2.0494008509748737e-01, -0.0000000000000000e+00, 2.0494008509748737e-01, 4.0991681468614050e-01, 6.1496691852828633e-01, 8.2012729750837221e-01, 1.0254351106514223e+00, 1.2309278639126584e+00, 1.4366435013663816e+00, 1.6426204994556326e+00, 1.8488979650073754e+00, 2.0555157377720055e+00, 2.2625144983121754e+00, 2.4699358821459070e+00, 2.6778226011448112e+00, 2.8862185733023908e+00, 3.0951690621230776e+00, 3.3047208270435604e+00, 3.5149222864888690e+00, 3.7258236953922830e+00, 3.9374773392776570e+00, 4.1499377473239889e+00, 4.3632619272160529e+00, 4.5775096250454670e+00, 4.7927436140809663e+00, 5.0090300168969302e+00, 5.2264386661630065e+00, 5.4450435103908958e+00, 5.6649230721526251e+00, 5.8861609677875624e+00, 6.1088464994807214e+00, 6.3330753329246656e+00, 6.5589502767074928e+00, 6.7865821832816833e+00, 7.0160909961088489e+00, 7.2476069736794351e+00, 7.4812721290378645e+00, 7.7172419338499774e+00, 7.9556873498473575e+00, 8.1967972689854154e+00, 8.4407814687705134e+00, 8.6878742237708870e+00, 8.9383387625761230e+00, 9.1924728279240568e+00, 9.4506156965670485e+00, 9.7131571610296650e+00, 9.9805491945452847e+00, 1.0253321358511124e+01, 1.0532101547973223e+01, 1.0817644548390337e+01, 1.1110872367128264e+01, 1.1412932942839976e+01, 1.1725288752112307e+01, 1.2049856556961975e+01, 1.2389240245284292e+01, 1.2747147119365039e+01, 1.3129205768185479e+01, 1.3544802666397535e+01, 1.4012158361728110e+01, 1.4578982825139288e+01}, + {-1.4645158053651027e+01, -1.4079178637349177e+01, -1.3612539492279215e+01, -1.3197595467366467e+01, -1.2816150525975972e+01, -1.2458830729659516e+01, -1.2120014970184142e+01, -1.1796000859913661e+01, -1.1484187962287965e+01, -1.1182662061890452e+01, -1.0889962635005938e+01, -1.0604943287993811e+01, -1.0326683268027864e+01, -1.0054428831215711e+01, -9.7875529641744929e+00, -9.5255268647413445e+00, -9.2678992236538775e+00, -9.0142808372415573e+00, -8.7643329577328277e+00, -8.5177583232401322e+00, -8.2742941470872093e+00, -8.0337065649878543e+00, -7.7957861839727647e+00, -7.5603444756835589e+00, -7.3272108250171302e+00, -7.0962300932900497e+00, -6.8672605896069676e+00, -6.6401723692025154e+00, -6.4148457960045002e+00, -6.1911703204459041e+00, -5.9690434339462293e+00, -5.7483697694039071e+00, -5.5290603231377613e+00, -5.3110317784497383e+00, -5.0942059146888043e+00, -4.8785090886224198e+00, -4.6638717772489988e+00, -4.4502281730478108e+00, -4.2375158241640083e+00, -4.0256753132434273e+00, -3.8146499696239737e+00, -3.6043856104035212e+00, -3.3948303065739314e+00, -3.1859341709648956e+00, -2.9776491652016608e+00, -2.7699289232646307e+00, -2.5627285895601974e+00, -2.3560046696818464e+00, -2.1497148922675668e+00, -1.9438180805509269e+00, -1.7382740323646890e+00, -1.5330434074921915e+00, -1.3280876213767709e+00, -1.1233687442963156e+00, -9.1884940519120828e-01, -7.1449269940145821e-01, -5.1026209962444491e-01, -3.0612136944972701e-01, -1.0203447886287802e-01, 1.0203447886287802e-01, 3.0612136944972701e-01, 5.1026209962444491e-01, 7.1449269940145821e-01, 9.1884940519120828e-01, 1.1233687442963156e+00, 1.3280876213767709e+00, 1.5330434074921915e+00, 1.7382740323646890e+00, 1.9438180805509269e+00, 2.1497148922675668e+00, 2.3560046696818464e+00, 2.5627285895601974e+00, 2.7699289232646307e+00, 2.9776491652016608e+00, 3.1859341709648956e+00, 3.3948303065739314e+00, 3.6043856104035212e+00, 3.8146499696239737e+00, 4.0256753132434273e+00, 4.2375158241640083e+00, 4.4502281730478108e+00, 4.6638717772489988e+00, 4.8785090886224198e+00, 5.0942059146888043e+00, 5.3110317784497383e+00, 5.5290603231377613e+00, 5.7483697694039071e+00, 5.9690434339462293e+00, 6.1911703204459041e+00, 6.4148457960045002e+00, 6.6401723692025154e+00, 6.8672605896069676e+00, 7.0962300932900497e+00, 7.3272108250171302e+00, 7.5603444756835589e+00, 7.7957861839727647e+00, 8.0337065649878543e+00, 8.2742941470872093e+00, 8.5177583232401322e+00, 8.7643329577328277e+00, 9.0142808372415573e+00, 9.2678992236538775e+00, 9.5255268647413445e+00, 9.7875529641744929e+00, 1.0054428831215711e+01, 1.0326683268027864e+01, 1.0604943287993811e+01, 1.0889962635005938e+01, 1.1182662061890452e+01, 1.1484187962287965e+01, 1.1796000859913661e+01, 1.2120014970184142e+01, 1.2458830729659516e+01, 1.2816150525975972e+01, 1.3197595467366467e+01, 1.3612539492279215e+01, 1.4079178637349177e+01, 1.4645158053651027e+01}, + {-1.4711048459763671e+01, -1.4145905481877998e+01, -1.3679975439346320e+01, -1.3265677382038762e+01, -1.2884839551290751e+01, -1.2528100425622796e+01, -1.2189846306095971e+01, -1.1866379672363987e+01, -1.1555103505482034e+01, -1.1254106111274996e+01, -1.0961928898971054e+01, -1.0677427003696076e+01, -1.0399680913497548e+01, -1.0127937914235881e+01, -9.8615718637313439e+00, -9.6000547095956161e+00, -9.3429357978203189e+00, -9.0898265054222858e+00, -8.8403886058470427e+00, -8.5943253105810840e+00, -8.3513742675803542e+00, -8.1113020156791773e+00, -7.8738995393403330e+00, -7.6389786667002593e+00, -7.4063691221380390e+00, -7.1759160927206223e+00, -6.9474782023460993e+00, -6.7209258124599129e+00, -6.4961395866732436e+00, -6.2730092703749003e+00, -6.0514326468076227e+00, -5.8313146389908859e+00, -5.6125665329607717e+00, -5.3951053025257689e+00, -5.1788530194404441e+00, -4.9637363358218023e+00, -4.7496860279573854e+00, -4.5366365925149861e+00, -4.3245258876633645e+00, -4.1132948128290048e+00, -3.9028870218050722e+00, -3.6932486647410911e+00, -3.4843281552109961e+00, -3.2760759591109072e+00, -3.0684444025981263e+00, -2.8613874966667088e+00, -2.6548607762763461e+00, -2.4488211522211656e+00, -2.2432267741522884e+00, -2.0380369033597177e+00, -1.8332117940811192e+00, -1.6287125822420414e+00, -1.4245011806478818e+00, -1.2205401797456257e+00, -1.0167927531555376e+00, -8.1322256724173581e-01, -6.0979369404756556e-01, -4.0647052696828645e-01, -2.0321769857092067e-01, -0.0000000000000000e+00, 2.0321769857092067e-01, 4.0647052696828645e-01, 6.0979369404756556e-01, 8.1322256724173581e-01, 1.0167927531555376e+00, 1.2205401797456257e+00, 1.4245011806478818e+00, 1.6287125822420414e+00, 1.8332117940811192e+00, 2.0380369033597177e+00, 2.2432267741522884e+00, 2.4488211522211656e+00, 2.6548607762763461e+00, 2.8613874966667088e+00, 3.0684444025981263e+00, 3.2760759591109072e+00, 3.4843281552109961e+00, 3.6932486647410911e+00, 3.9028870218050722e+00, 4.1132948128290048e+00, 4.3245258876633645e+00, 4.5366365925149861e+00, 4.7496860279573854e+00, 4.9637363358218023e+00, 5.1788530194404441e+00, 5.3951053025257689e+00, 5.6125665329607717e+00, 5.8313146389908859e+00, 6.0514326468076227e+00, 6.2730092703749003e+00, 6.4961395866732436e+00, 6.7209258124599129e+00, 6.9474782023460993e+00, 7.1759160927206223e+00, 7.4063691221380390e+00, 7.6389786667002593e+00, 7.8738995393403330e+00, 8.1113020156791773e+00, 8.3513742675803542e+00, 8.5943253105810840e+00, 8.8403886058470427e+00, 9.0898265054222858e+00, 9.3429357978203189e+00, 9.6000547095956161e+00, 9.8615718637313439e+00, 1.0127937914235881e+01, 1.0399680913497548e+01, 1.0677427003696076e+01, 1.0961928898971054e+01, 1.1254106111274996e+01, 1.1555103505482034e+01, 1.1866379672363987e+01, 1.2189846306095971e+01, 1.2528100425622796e+01, 1.2884839551290751e+01, 1.3265677382038762e+01, 1.3679975439346320e+01, 1.4145905481877998e+01, 1.4711048459763671e+01}, + {-1.4776657672798869e+01, -1.4212342685181815e+01, -1.3747114438757134e+01, -1.3333455576348189e+01, -1.2953218388266750e+01, -1.2597053652892484e+01, -1.2259355010417195e+01, -1.1936429761298314e+01, -1.1625684271126064e+01, -1.1325209342106415e+01, -1.1033548296890791e+01, -1.0749557783474378e+01, -1.0472319517421079e+01, -1.0201081802811933e+01, -9.9352193584733488e+00, -9.6742048725828571e+00, -9.4175883379130294e+00, -9.1649817042418142e+00, -8.9160472587078665e+00, -8.6704886789370494e+00, -8.4280440404817565e+00, -8.1884802783862387e+00, -7.9515887476984757e+00, -7.7171816262142663e+00, -7.4850889709254078e+00, -7.2551562877054536e+00, -7.0272425081913878e+00, -6.8012182928404501e+00, -6.5769645975720454e+00, -6.3543714551491233e+00, -6.1333369328198826e+00, -5.9137662356417078e+00, -5.6955709309901366e+00, -5.4786682744780215e+00, -5.2629806212085075e+00, -5.0484349092048060e+00, -4.8349622041811422e+00, -4.6224972966778903e+00, -4.4109783440817232e+00, -4.2003465512658975e+00, -3.9905458845758908e+00, -3.7815228146971922e+00, -3.5732260846105883e+00, -3.3656064993935964e+00, -3.1586167350865688e+00, -2.9522111642257620e+00, -2.7463456959669994e+00, -2.5409776289935784e+00, -2.3360655156294796e+00, -2.1315690357710211e+00, -1.9274488794124773e+00, -1.7236666366787170e+00, -1.5201846943942978e+00, -1.3169661383169375e+00, -1.1139746602463279e+00, -9.1117446928904511e-01, -7.0853020661847821e-01, -5.0600686311669596e-01, -3.0356969932406813e-01, -1.0118416715318335e-01, 1.0118416715318335e-01, 3.0356969932406813e-01, 5.0600686311669596e-01, 7.0853020661847821e-01, 9.1117446928904511e-01, 1.1139746602463279e+00, 1.3169661383169375e+00, 1.5201846943942978e+00, 1.7236666366787170e+00, 1.9274488794124773e+00, 2.1315690357710211e+00, 2.3360655156294796e+00, 2.5409776289935784e+00, 2.7463456959669994e+00, 2.9522111642257620e+00, 3.1586167350865688e+00, 3.3656064993935964e+00, 3.5732260846105883e+00, 3.7815228146971922e+00, 3.9905458845758908e+00, 4.2003465512658975e+00, 4.4109783440817232e+00, 4.6224972966778903e+00, 4.8349622041811422e+00, 5.0484349092048060e+00, 5.2629806212085075e+00, 5.4786682744780215e+00, 5.6955709309901366e+00, 5.9137662356417078e+00, 6.1333369328198826e+00, 6.3543714551491233e+00, 6.5769645975720454e+00, 6.8012182928404501e+00, 7.0272425081913878e+00, 7.2551562877054536e+00, 7.4850889709254078e+00, 7.7171816262142663e+00, 7.9515887476984757e+00, 8.1884802783862387e+00, 8.4280440404817565e+00, 8.6704886789370494e+00, 8.9160472587078665e+00, 9.1649817042418142e+00, 9.4175883379130294e+00, 9.6742048725828571e+00, 9.9352193584733488e+00, 1.0201081802811933e+01, 1.0472319517421079e+01, 1.0749557783474378e+01, 1.1033548296890791e+01, 1.1325209342106415e+01, 1.1625684271126064e+01, 1.1936429761298314e+01, 1.2259355010417195e+01, 1.2597053652892484e+01, 1.2953218388266750e+01, 1.3333455576348189e+01, 1.3747114438757134e+01, 1.4212342685181815e+01, 1.4776657672798869e+01}, + {-1.4841989245812462e+01, -1.4278493956537387e+01, -1.3813960337214354e+01, -1.3400934026297357e+01, -1.3021291138101008e+01, -1.2665694635824183e+01, -1.2328545429882384e+01, -1.2006155595899877e+01, -1.1695934851542777e+01, -1.1395976471020912e+01, -1.1104825671283981e+01, -1.0821340597636343e+01, -1.0544604180098764e+01, -1.0273865729711682e+01, -1.0008500816363464e+01, -9.7479828598297100e+00, -9.4918624914245004e+00, -9.2397522259904878e+00, -8.9913148570644346e+00, -8.7462545214071792e+00, -8.5043097153654035e+00, -8.2652477635213177e+00, -8.0288603849063733e+00, -7.7949601003933706e+00, -7.5633772929797445e+00, -7.3339577806748517e+00, -7.1065607960848611e+00, -6.8810572917778128e+00, -6.6573285089186554e+00, -6.4352647603911377e+00, -6.2147643899767431e+00, -5.9957328770520153e+00, -5.7780820623389184e+00, -5.5617294749593142e+00, -5.3465977447386317e+00, -5.1326140866195260e+00, -4.9197098463649933e+00, -4.7078200985868248e+00, -4.4968832896314073e+00, -4.2868409190677941e+00, -4.0776372545120747e+00, -3.8692190753327944e+00, -3.6615354414501788e+00, -3.4545374839947667e+00, -3.2481782150506633e+00, -3.0424123540922232e+00, -2.8371961690442937e+00, -2.6324873301662031e+00, -2.4282447751872818e+00, -2.2244285843140195e+00, -2.0209998638917077e+00, -1.8179206376413908e+00, -1.6151537445099000e+00, -1.4126627422698670e+00, -1.2104118160904516e+00, -1.0083656913702024e+00, -8.0648955018269064e-01, -6.0474895073475177e-01, -4.0310974927746679e-01, -2.0153802394231832e-01, -0.0000000000000000e+00, 2.0153802394231832e-01, 4.0310974927746679e-01, 6.0474895073475177e-01, 8.0648955018269064e-01, 1.0083656913702024e+00, 1.2104118160904516e+00, 1.4126627422698670e+00, 1.6151537445099000e+00, 1.8179206376413908e+00, 2.0209998638917077e+00, 2.2244285843140195e+00, 2.4282447751872818e+00, 2.6324873301662031e+00, 2.8371961690442937e+00, 3.0424123540922232e+00, 3.2481782150506633e+00, 3.4545374839947667e+00, 3.6615354414501788e+00, 3.8692190753327944e+00, 4.0776372545120747e+00, 4.2868409190677941e+00, 4.4968832896314073e+00, 4.7078200985868248e+00, 4.9197098463649933e+00, 5.1326140866195260e+00, 5.3465977447386317e+00, 5.5617294749593142e+00, 5.7780820623389184e+00, 5.9957328770520153e+00, 6.2147643899767431e+00, 6.4352647603911377e+00, 6.6573285089186554e+00, 6.8810572917778128e+00, 7.1065607960848611e+00, 7.3339577806748517e+00, 7.5633772929797445e+00, 7.7949601003933706e+00, 8.0288603849063733e+00, 8.2652477635213177e+00, 8.5043097153654035e+00, 8.7462545214071792e+00, 8.9913148570644346e+00, 9.2397522259904878e+00, 9.4918624914245004e+00, 9.7479828598297100e+00, 1.0008500816363464e+01, 1.0273865729711682e+01, 1.0544604180098764e+01, 1.0821340597636343e+01, 1.1104825671283981e+01, 1.1395976471020912e+01, 1.1695934851542777e+01, 1.2006155595899877e+01, 1.2328545429882384e+01, 1.2665694635824183e+01, 1.3021291138101008e+01, 1.3400934026297357e+01, 1.3813960337214354e+01, 1.4278493956537387e+01, 1.4841989245812462e+01}, + {-1.4907046657816622e+01, -1.4344362927004781e+01, -1.3880516899476401e+01, -1.3468116622389784e+01, -1.3089061813006204e+01, -1.2734027506319505e+01, -1.2397421815284703e+01, -1.2075561545881943e+01, -1.1765859735997486e+01, -1.1466412107936478e+01, -1.1175765754204676e+01, -1.0892780302181299e+01, -1.0616539883571752e+01, -1.0346294805375646e+01, -1.0081421478842227e+01, -9.8213940466086171e+00, -9.5657637705148062e+00, -9.3141437229916662e+00, -9.0661971968977273e+00, -8.8216287813440992e+00, -8.5801773868921547e+00, -8.3416107212171422e+00, -8.1057208609652847e+00, -7.8723206637443432e+00, -7.6412408321991903e+00, -7.4123274900628546e+00, -7.1854401644106494e+00, -6.9604500933022759e+00, -6.7372387963808658e+00, -6.5156968597076492e+00, -6.2957228964512764e+00, -6.0772226529322166e+00, -5.8601082355882221e+00, -5.6442974391377119e+00, -5.4297131599071493e+00, -5.2162828812008781e+00, -5.0039382199076590e+00, -4.7926145253924428e+00, -4.5822505232162971e+00, -4.3727879974390058e+00, -4.1641715062468725e+00, -3.9563481264582303e+00, -3.7492672231264832e+00, -3.5428802410129703e+00, -3.3371405151612126e+00, -3.1320030981875178e+00, -2.9274246022241841e+00, -2.7233630537216094e+00, -2.5197777595433375e+00, -2.3166291829805914e+00, -2.1138788284758951e+00, -1.9114891339837408e+00, -1.7094233700136701e+00, -1.5076455445008548e+00, -1.3061203127337706e+00, -1.1048128916400251e+00, -9.0368897779154544e-01, -7.0271466854059361e-01, -5.0185638573956481e-01, -3.0108080153124556e-01, -1.0035476572283220e-01, 1.0035476572283220e-01, 3.0108080153124556e-01, 5.0185638573956481e-01, 7.0271466854059361e-01, 9.0368897779154544e-01, 1.1048128916400251e+00, 1.3061203127337706e+00, 1.5076455445008548e+00, 1.7094233700136701e+00, 1.9114891339837408e+00, 2.1138788284758951e+00, 2.3166291829805914e+00, 2.5197777595433375e+00, 2.7233630537216094e+00, 2.9274246022241841e+00, 3.1320030981875178e+00, 3.3371405151612126e+00, 3.5428802410129703e+00, 3.7492672231264832e+00, 3.9563481264582303e+00, 4.1641715062468725e+00, 4.3727879974390058e+00, 4.5822505232162971e+00, 4.7926145253924428e+00, 5.0039382199076590e+00, 5.2162828812008781e+00, 5.4297131599071493e+00, 5.6442974391377119e+00, 5.8601082355882221e+00, 6.0772226529322166e+00, 6.2957228964512764e+00, 6.5156968597076492e+00, 6.7372387963808658e+00, 6.9604500933022759e+00, 7.1854401644106494e+00, 7.4123274900628546e+00, 7.6412408321991903e+00, 7.8723206637443432e+00, 8.1057208609652847e+00, 8.3416107212171422e+00, 8.5801773868921547e+00, 8.8216287813440992e+00, 9.0661971968977273e+00, 9.3141437229916662e+00, 9.5657637705148062e+00, 9.8213940466086171e+00, 1.0081421478842227e+01, 1.0346294805375646e+01, 1.0616539883571752e+01, 1.0892780302181299e+01, 1.1175765754204676e+01, 1.1466412107936478e+01, 1.1765859735997486e+01, 1.2075561545881943e+01, 1.2397421815284703e+01, 1.2734027506319505e+01, 1.3089061813006204e+01, 1.3468116622389784e+01, 1.3880516899476401e+01, 1.4344362927004781e+01, 1.4907046657816622e+01}, + {-1.4971833315919479e+01, -1.4409953151712163e+01, -1.3946787810773682e+01, -1.3535007172173161e+01, -1.3156534338879860e+01, -1.2802056306622088e+01, -1.2465988324400744e+01, -1.2144651884544359e+01, -1.1835463313889939e+01, -1.1536520759384242e+01, -1.1246373170717687e+01, -1.0963881642425228e+01, -1.0688131495402112e+01, -1.0418374021858449e+01, -1.0153986464937166e+01, -9.8944436816224322e+00, -9.6392975564791730e+00, -9.3881617122605014e+00, -9.1406999342794091e+00, -8.8966172574222746e+00, -8.6556530000977201e+00, -8.4175752468453187e+00, -8.1821764257789713e+00, -7.9492697251276718e+00, -7.7186861610617425e+00, -7.4902721568710229e+00, -7.2638875278553732e+00, -7.0394037912138101e+00, -6.8167027385795480e+00, -6.5956752225409012e+00, -6.3762201188154259e+00, -6.1582434336162883e+00, -5.9416575318080138e+00, -5.7263804661537199e+00, -5.5123353916408391e+00, -5.2994500517810534e+00, -5.0876563260932981e+00, -4.8768898298307777e+00, -4.6670895585055892e+00, -4.4581975709748294e+00, -4.2501587058390200e+00, -4.0429203267128022e+00, -3.8364320925946052e+00, -3.6306457501139446e+00, -3.4255149448939752e+00, -3.2209950496501372e+00, -3.0170430069668734e+00, -2.8136171849644747e+00, -2.6106772442959039e+00, -2.4081840151061349e+00, -2.2060993827498390e+00, -2.0043861812019168e+00, -1.8030080932132322e+00, -1.6019295563640745e+00, -1.4011156742530042e+00, -1.2005321321308888e+00, -1.0001451163508825e+00, -7.9992123705629015e-01, -5.9982745357081801e-01, -3.9983100199064880e-01, -1.9989932450580150e-01, -0.0000000000000000e+00, 1.9989932450580150e-01, 3.9983100199064880e-01, 5.9982745357081801e-01, 7.9992123705629015e-01, 1.0001451163508825e+00, 1.2005321321308888e+00, 1.4011156742530042e+00, 1.6019295563640745e+00, 1.8030080932132322e+00, 2.0043861812019168e+00, 2.2060993827498390e+00, 2.4081840151061349e+00, 2.6106772442959039e+00, 2.8136171849644747e+00, 3.0170430069668734e+00, 3.2209950496501372e+00, 3.4255149448939752e+00, 3.6306457501139446e+00, 3.8364320925946052e+00, 4.0429203267128022e+00, 4.2501587058390200e+00, 4.4581975709748294e+00, 4.6670895585055892e+00, 4.8768898298307777e+00, 5.0876563260932981e+00, 5.2994500517810534e+00, 5.5123353916408391e+00, 5.7263804661537199e+00, 5.9416575318080138e+00, 6.1582434336162883e+00, 6.3762201188154259e+00, 6.5956752225409012e+00, 6.8167027385795480e+00, 7.0394037912138101e+00, 7.2638875278553732e+00, 7.4902721568710229e+00, 7.7186861610617425e+00, 7.9492697251276718e+00, 8.1821764257789713e+00, 8.4175752468453187e+00, 8.6556530000977201e+00, 8.8966172574222746e+00, 9.1406999342794091e+00, 9.3881617122605014e+00, 9.6392975564791730e+00, 9.8944436816224322e+00, 1.0153986464937166e+01, 1.0418374021858449e+01, 1.0688131495402112e+01, 1.0963881642425228e+01, 1.1246373170717687e+01, 1.1536520759384242e+01, 1.1835463313889939e+01, 1.2144651884544359e+01, 1.2465988324400744e+01, 1.2802056306622088e+01, 1.3156534338879860e+01, 1.3535007172173161e+01, 1.3946787810773682e+01, 1.4409953151712163e+01, 1.4971833315919479e+01}, + {-1.5036352557386012e+01, -1.4475268112055591e+01, -1.4012776679134205e+01, -1.3601609402686369e+01, -1.3223712557871778e+01, -1.2869784992006130e+01, -1.2534249024802044e+01, -1.2213430791710801e+01, -1.1904749877820654e+01, -1.1606306831707778e+01, -1.1316652442235313e+01, -1.1034649256479808e+01, -1.0759383772299557e+01, -1.0490108256609062e+01, -1.0226200775202839e+01, -9.9671368911110161e+00, -9.7124691040283810e+00, -9.4618115799659321e+00, -9.2148285900237301e+00, -8.9712256084886892e+00, -8.7307423554516284e+00, -8.4931472862936879e+00, -8.2582331746602566e+00, -8.0258135335048770e+00, -7.7957196866256542e+00, -7.5677983509350675e+00, -7.3419096239550905e+00, -7.1179252959243602e+00, -6.8957274242423345e+00, -6.6752071216509830e+00, -6.4562635198693066e+00, -6.2388028782578386e+00, -6.0227378131410365e+00, -5.8079866281147483e+00, -5.5944727293462684e+00, -5.3821241127798674e+00, -5.1708729124709514e+00, -4.9606550011220074e+00, -4.7514096353844053e+00, -4.5430791396990857e+00, -4.3356086234350091e+00, -4.1289457268926073e+00, -3.9230403924055310e+00, -3.7178446573254824e+00, -3.5133124661335695e+00, -3.3093994993045657e+00, -3.1060630168714907e+00, -2.9032617149079720e+00, -2.7009555933736791e+00, -2.4991058339609178e+00, -2.2976746867440045e+00, -2.0966253645719419e+00, -1.8959219442631448e+00, -1.6955292737615766e+00, -1.4954128844992702e+00, -1.2955389082829973e+00, -1.0958739980844798e+00, -8.9638525216554721e-01, -6.9704014101314027e-01, -4.9780643659506446e-01, -2.9865214347665664e-01, -9.9545431361682174e-02, 9.9545431361682174e-02, 2.9865214347665664e-01, 4.9780643659506446e-01, 6.9704014101314027e-01, 8.9638525216554721e-01, 1.0958739980844798e+00, 1.2955389082829973e+00, 1.4954128844992702e+00, 1.6955292737615766e+00, 1.8959219442631448e+00, 2.0966253645719419e+00, 2.2976746867440045e+00, 2.4991058339609178e+00, 2.7009555933736791e+00, 2.9032617149079720e+00, 3.1060630168714907e+00, 3.3093994993045657e+00, 3.5133124661335695e+00, 3.7178446573254824e+00, 3.9230403924055310e+00, 4.1289457268926073e+00, 4.3356086234350091e+00, 4.5430791396990857e+00, 4.7514096353844053e+00, 4.9606550011220074e+00, 5.1708729124709514e+00, 5.3821241127798674e+00, 5.5944727293462684e+00, 5.8079866281147483e+00, 6.0227378131410365e+00, 6.2388028782578386e+00, 6.4562635198693066e+00, 6.6752071216509830e+00, 6.8957274242423345e+00, 7.1179252959243602e+00, 7.3419096239550905e+00, 7.5677983509350675e+00, 7.7957196866256542e+00, 8.0258135335048770e+00, 8.2582331746602566e+00, 8.4931472862936879e+00, 8.7307423554516284e+00, 8.9712256084886892e+00, 9.2148285900237301e+00, 9.4618115799659321e+00, 9.7124691040283810e+00, 9.9671368911110161e+00, 1.0226200775202839e+01, 1.0490108256609062e+01, 1.0759383772299557e+01, 1.1034649256479808e+01, 1.1316652442235313e+01, 1.1606306831707778e+01, 1.1904749877820654e+01, 1.2213430791710801e+01, 1.2534249024802044e+01, 1.2869784992006130e+01, 1.3223712557871778e+01, 1.3601609402686369e+01, 1.4012776679134205e+01, 1.4475268112055591e+01, 1.5036352557386012e+01}, + {-1.5100607651623633e+01, -1.4540311217817694e+01, -1.4078487037622645e+01, -1.3667926962814708e+01, -1.3290600230854309e+01, -1.2937217433362431e+01, -1.2602207896558657e+01, -1.2281902356552338e+01, -1.1973723626537621e+01, -1.1675774634136665e+01, -1.1386607989721913e+01, -1.1105087678592627e+01, -1.0830301363602338e+01, -1.0561502276097833e+01, -1.0298069295499928e+01, -1.0039478682788769e+01, -9.7852835453915379e+00, -9.5350985857059971e+00, -9.2885885541431801e+00, -9.0454593582072000e+00, -8.8054511136991565e+00, -8.5683326410153491e+00, -8.3338970535972763e+00, -8.1019581834327870e+00, -7.8723476562632699e+00, -7.6449124769105978e+00, -7.4195130193460823e+00, -7.1960213409877323e+00, -6.9743197590276207e+00, -6.7542996402499806e+00, -6.5358603661027201e+00, -6.3189084426373174e+00, -6.1033567309754471e+00, -5.8891237786542385e+00, -5.6761332358780425e+00, -5.4643133436064266e+00, -5.2535964827157065e+00, -5.0439187753191463e+00, -4.8352197308201870e+00, -4.6274419304806678e+00, -4.4205307452707974e+00, -4.2144340825751483e+00, -4.0091021579943744e+00, -3.8044872890333408e+00, -3.6005437079246576e+00, -3.3972273912192827e+00, -3.1944959040967831e+00, -2.9923082576177755e+00, -2.7906247773689459e+00, -2.5894069821439305e+00, -2.3886174714670143e+00, -2.1882198209057537e+00, -1.9881784842371524e+00, -1.7884587016329878e+00, -1.5890264131159799e+00, -1.3898481766117783e+00, -1.1908910899840175e+00, -9.9212271649240336e-01, -7.9351101315811157e-01, -5.9502426155773702e-01, -3.9663100059735329e-01, -1.9829996084264417e-01, -0.0000000000000000e+00, 1.9829996084264417e-01, 3.9663100059735329e-01, 5.9502426155773702e-01, 7.9351101315811157e-01, 9.9212271649240336e-01, 1.1908910899840175e+00, 1.3898481766117783e+00, 1.5890264131159799e+00, 1.7884587016329878e+00, 1.9881784842371524e+00, 2.1882198209057537e+00, 2.3886174714670143e+00, 2.5894069821439305e+00, 2.7906247773689459e+00, 2.9923082576177755e+00, 3.1944959040967831e+00, 3.3972273912192827e+00, 3.6005437079246576e+00, 3.8044872890333408e+00, 4.0091021579943744e+00, 4.2144340825751483e+00, 4.4205307452707974e+00, 4.6274419304806678e+00, 4.8352197308201870e+00, 5.0439187753191463e+00, 5.2535964827157065e+00, 5.4643133436064266e+00, 5.6761332358780425e+00, 5.8891237786542385e+00, 6.1033567309754471e+00, 6.3189084426373174e+00, 6.5358603661027201e+00, 6.7542996402499806e+00, 6.9743197590276207e+00, 7.1960213409877323e+00, 7.4195130193460823e+00, 7.6449124769105978e+00, 7.8723476562632699e+00, 8.1019581834327870e+00, 8.3338970535972763e+00, 8.5683326410153491e+00, 8.8054511136991565e+00, 9.0454593582072000e+00, 9.2885885541431801e+00, 9.5350985857059971e+00, 9.7852835453915379e+00, 1.0039478682788769e+01, 1.0298069295499928e+01, 1.0561502276097833e+01, 1.0830301363602338e+01, 1.1105087678592627e+01, 1.1386607989721913e+01, 1.1675774634136665e+01, 1.1973723626537621e+01, 1.2281902356552338e+01, 1.2602207896558657e+01, 1.2937217433362431e+01, 1.3290600230854309e+01, 1.3667926962814708e+01, 1.4078487037622645e+01, 1.4540311217817694e+01, 1.5100607651623633e+01}, + {-1.5164601802095889e+01, -1.4605085809208793e+01, -1.4143922346496764e+01, -1.3733963425557441e+01, -1.3357201039800040e+01, -1.3004357419686706e+01, -1.2669868834839699e+01, -1.2350070580302615e+01, -1.2042388667769094e+01, -1.1744928381740326e+01, -1.1456244136772701e+01, -1.1175201342355262e+01, -1.0900888814619361e+01, -1.0632560739297817e+01, -1.0369596800621338e+01, -1.0111473949621464e+01, -9.8577458942500833e+00, -9.6080278666058625e+00, -9.3619850901178872e+00, -9.1193238995071209e+00, -8.8797848004974700e+00, -8.6431369728612566e+00, -8.4091738642920379e+00, -8.1777096203182182e+00, -7.9485761631426497e+00, -7.7216207799931862e+00, -7.4967041157356897e+00, -7.2736984893343362e+00, -7.0524864720372555e+00, -6.8329596788076081e+00, -6.6150177348097277e+00, -6.3985673866027142e+00, -6.1835217337299566e+00, -5.9697995610809267e+00, -5.7573247560732410e+00, -5.5460257976013150e+00, -5.3358353060028794e+00, -5.1266896451402619e+00, -4.9185285691809160e+00, -4.7112949078678819e+00, -4.5049342850546665e+00, -4.2993948660856276e+00, -4.0946271302677770e+00, -3.8905836652304053e+00, -3.6872189804268034e+00, -3.4844893374148405e+00, -3.2823525948738599e+00, -3.0807680665852137e+00, -2.8796963908316315e+00, -2.6790994098635554e+00, -2.4789400582443553e+00, -2.2791822590257231e+00, -2.0797908268232597e+00, -1.8807313769636194e+00, -1.6819702399610155e+00, -1.4834743806546613e+00, -1.2852113214015310e+00, -1.0871490687721614e+00, -8.8925604324227414e-01, -6.9150101141075326e-01, -4.9385302030582290e-01, -2.9628133336672019e-01, -9.8755367708345074e-02, 9.8755367708345074e-02, 2.9628133336672019e-01, 4.9385302030582290e-01, 6.9150101141075326e-01, 8.8925604324227414e-01, 1.0871490687721614e+00, 1.2852113214015310e+00, 1.4834743806546613e+00, 1.6819702399610155e+00, 1.8807313769636194e+00, 2.0797908268232597e+00, 2.2791822590257231e+00, 2.4789400582443553e+00, 2.6790994098635554e+00, 2.8796963908316315e+00, 3.0807680665852137e+00, 3.2823525948738599e+00, 3.4844893374148405e+00, 3.6872189804268034e+00, 3.8905836652304053e+00, 4.0946271302677770e+00, 4.2993948660856276e+00, 4.5049342850546665e+00, 4.7112949078678819e+00, 4.9185285691809160e+00, 5.1266896451402619e+00, 5.3358353060028794e+00, 5.5460257976013150e+00, 5.7573247560732410e+00, 5.9697995610809267e+00, 6.1835217337299566e+00, 6.3985673866027142e+00, 6.6150177348097277e+00, 6.8329596788076081e+00, 7.0524864720372555e+00, 7.2736984893343362e+00, 7.4967041157356897e+00, 7.7216207799931862e+00, 7.9485761631426497e+00, 8.1777096203182182e+00, 8.4091738642920379e+00, 8.6431369728612566e+00, 8.8797848004974700e+00, 9.1193238995071209e+00, 9.3619850901178872e+00, 9.6080278666058625e+00, 9.8577458942500833e+00, 1.0111473949621464e+01, 1.0369596800621338e+01, 1.0632560739297817e+01, 1.0900888814619361e+01, 1.1175201342355262e+01, 1.1456244136772701e+01, 1.1744928381740326e+01, 1.2042388667769094e+01, 1.2350070580302615e+01, 1.2669868834839699e+01, 1.3004357419686706e+01, 1.3357201039800040e+01, 1.3733963425557441e+01, 1.4143922346496764e+01, 1.4605085809208793e+01, 1.5164601802095889e+01}, + {-1.5228338148167351e+01, -1.4669595158833971e+01, -1.4209085995284871e+01, -1.3799722290211674e+01, -1.3423518590070948e+01, -1.3071208660474600e+01, -1.2737235652415684e+01, -1.2417939378869717e+01, -1.2110749020947747e+01, -1.1813772198267726e+01, -1.1525565112572695e+01, -1.1244994583785543e+01, -1.0971150569840248e+01, -1.0703288201027481e+01, -1.0440787957772772e+01, -1.0183127473450343e+01, -9.9298610495114250e+00, -9.6806044412474730e+00, -9.4350233389881648e+00, -9.1928244988460293e+00, -8.9537488108565402e+00, -8.7175658087076293e+00, -8.4840692689832480e+00, -8.2530736454457152e+00, -8.0244111514703373e+00, -7.7979293513870109e+00, -7.5734891556083452e+00, -7.3509631392269048e+00, -7.1302341220350698e+00, -6.9111939615465703e+00, -6.6937425208758290e+00, -6.4777867811645358e+00, -6.2632400742737344e+00, -6.0500214161419841e+00, -5.8380549248774187e+00, -5.6272693105464811e+00, -5.4175974259243240e+00, -5.2089758693153980e+00, -5.0013446320386352e+00, -4.7946467843764919e+00, -4.5888281947698371e+00, -4.3838372778464736e+00, -4.1796247675352030e+00, -3.9761435120673356e+00, -3.7733482881250526e+00, -3.5711956317782176e+00, -3.3696436841717392e+00, -3.1686520501953628e+00, -2.9681816685955908e+00, -2.7681946921824054e+00, -2.5686543769473498e+00, -2.3695249790490402e+00, -2.1707716587411507e+00, -1.9723603904195017e+00, -1.7742578780516791e+00, -1.5764314753267801e+00, -1.3788491099261777e+00, -1.1814792113700685e+00, -9.8429064194027271e-01, -7.8725263021825032e-01, -5.9033470680942102e-01, -3.9350664185130130e-01, -1.9673838392423251e-01, -0.0000000000000000e+00, 1.9673838392423251e-01, 3.9350664185130130e-01, 5.9033470680942102e-01, 7.8725263021825032e-01, 9.8429064194027271e-01, 1.1814792113700685e+00, 1.3788491099261777e+00, 1.5764314753267801e+00, 1.7742578780516791e+00, 1.9723603904195017e+00, 2.1707716587411507e+00, 2.3695249790490402e+00, 2.5686543769473498e+00, 2.7681946921824054e+00, 2.9681816685955908e+00, 3.1686520501953628e+00, 3.3696436841717392e+00, 3.5711956317782176e+00, 3.7733482881250526e+00, 3.9761435120673356e+00, 4.1796247675352030e+00, 4.3838372778464736e+00, 4.5888281947698371e+00, 4.7946467843764919e+00, 5.0013446320386352e+00, 5.2089758693153980e+00, 5.4175974259243240e+00, 5.6272693105464811e+00, 5.8380549248774187e+00, 6.0500214161419841e+00, 6.2632400742737344e+00, 6.4777867811645358e+00, 6.6937425208758290e+00, 6.9111939615465703e+00, 7.1302341220350698e+00, 7.3509631392269048e+00, 7.5734891556083452e+00, 7.7979293513870109e+00, 8.0244111514703373e+00, 8.2530736454457152e+00, 8.4840692689832480e+00, 8.7175658087076293e+00, 8.9537488108565402e+00, 9.1928244988460293e+00, 9.4350233389881648e+00, 9.6806044412474730e+00, 9.9298610495114250e+00, 1.0183127473450343e+01, 1.0440787957772772e+01, 1.0703288201027481e+01, 1.0971150569840248e+01, 1.1244994583785543e+01, 1.1525565112572695e+01, 1.1813772198267726e+01, 1.2110749020947747e+01, 1.2417939378869717e+01, 1.2737235652415684e+01, 1.3071208660474600e+01, 1.3423518590070948e+01, 1.3799722290211674e+01, 1.4209085995284871e+01, 1.4669595158833971e+01, 1.5228338148167351e+01}, + {-1.5291819766882741e+01, -1.4733842473589300e+01, -1.4273981304787835e+01, -1.3865206984476242e+01, -1.3489556412623140e+01, -1.3137774788027649e+01, -1.2804312082067129e+01, -1.2485512585349447e+01, -1.2178808619831244e+01, -1.1882310118878310e+01, -1.1594575054741449e+01, -1.1314471644289977e+01, -1.1041090976019634e+01, -1.0773689115161440e+01, -1.0511647329914869e+01, -1.0254443928470931e+01, -1.0001633798930122e+01, -9.7528332134391675e+00, -9.5077083232790560e+00, -9.2659663002961761e+00, -9.0273484133947868e+00, -8.7916245448886858e+00, -8.5585887950645070e+00, -8.3280559207901454e+00, -8.0998584215078964e+00, -7.8738441335354343e+00, -7.6498742276810061e+00, -7.4278215299523005e+00, -7.2075691033873337e+00, -6.9890090426447742e+00, -6.7720414432559277e+00, -6.5565735152644828e+00, -6.3425188170017792e+00, -6.1297965894221624e+00, -5.9183311750858119e+00, -5.7080515087680856e+00, -5.4988906689739094e+00, -5.2907854814771786e+00, -5.0836761674893394e+00, -4.8775060302648141e+00, -4.6722211749326386e+00, -4.4677702571485822e+00, -4.2641042568255187e+00, -4.0611762737492727e+00, -3.8589413423442820e+00, -3.6573562632353078e+00, -3.4563794495717373e+00, -3.2559707863506588e+00, -3.0560915012026797e+00, -2.8567040452974051e+00, -2.6577719831894839e+00, -2.4592598905657392e+00, -2.2611332589730622e+00, -2.0633584067085660e+00, -1.8659023951405984e+00, -1.6687329498037236e+00, -1.4718183856744860e+00, -1.2751275360891583e+00, -1.0786296848109087e+00, -8.8229450079298133e-01, -6.8609197521733478e-01, -4.8999236041545891e-01, -2.9396611030029574e-01, -9.7983821955818992e-02, 9.7983821955818992e-02, 2.9396611030029574e-01, 4.8999236041545891e-01, 6.8609197521733478e-01, 8.8229450079298133e-01, 1.0786296848109087e+00, 1.2751275360891583e+00, 1.4718183856744860e+00, 1.6687329498037236e+00, 1.8659023951405984e+00, 2.0633584067085660e+00, 2.2611332589730622e+00, 2.4592598905657392e+00, 2.6577719831894839e+00, 2.8567040452974051e+00, 3.0560915012026797e+00, 3.2559707863506588e+00, 3.4563794495717373e+00, 3.6573562632353078e+00, 3.8589413423442820e+00, 4.0611762737492727e+00, 4.2641042568255187e+00, 4.4677702571485822e+00, 4.6722211749326386e+00, 4.8775060302648141e+00, 5.0836761674893394e+00, 5.2907854814771786e+00, 5.4988906689739094e+00, 5.7080515087680856e+00, 5.9183311750858119e+00, 6.1297965894221624e+00, 6.3425188170017792e+00, 6.5565735152644828e+00, 6.7720414432559277e+00, 6.9890090426447742e+00, 7.2075691033873337e+00, 7.4278215299523005e+00, 7.6498742276810061e+00, 7.8738441335354343e+00, 8.0998584215078964e+00, 8.3280559207901454e+00, 8.5585887950645070e+00, 8.7916245448886858e+00, 9.0273484133947868e+00, 9.2659663002961761e+00, 9.5077083232790560e+00, 9.7528332134391675e+00, 1.0001633798930122e+01, 1.0254443928470931e+01, 1.0511647329914869e+01, 1.0773689115161440e+01, 1.1041090976019634e+01, 1.1314471644289977e+01, 1.1594575054741449e+01, 1.1882310118878310e+01, 1.2178808619831244e+01, 1.2485512585349447e+01, 1.2804312082067129e+01, 1.3137774788027649e+01, 1.3489556412623140e+01, 1.3865206984476242e+01, 1.4273981304787835e+01, 1.4733842473589300e+01, 1.5291819766882741e+01}, + {-1.5355049674683126e+01, -1.4797830896490307e+01, -1.4338611529008967e+01, -1.3930420866479178e+01, -1.3555317966130856e+01, -1.3204059359674192e+01, -1.2871101778903627e+01, -1.2552793952444540e+01, -1.2246571315023999e+01, -1.1950546092769182e+01, -1.1663278012068952e+01, -1.1383636673511937e+01, -1.1110714285141645e+01, -1.0843767837715543e+01, -1.0582179378973514e+01, -1.0325427884573593e+01, -1.0073068822584037e+01, -9.8247189758331519e+00, -9.5800449507652310e+00, -9.3387543294632973e+00, -9.1005887544187765e+00, -8.8653184514446028e+00, -8.6327378395084349e+00, -8.4026619736253494e+00, -8.1749236343739895e+00, -7.9493709251260496e+00, -7.7258652721212853e+00, -7.5042797472635216e+00, -7.2844976517401534e+00, -7.0664113121603904e+00, -6.8499210511601492e+00, -6.6349343022359886e+00, -6.4213648445851028e+00, -6.2091321383995863e+00, -5.9981607447217984e+00, -5.7883798168558824e+00, -5.5797226526273649e+00, -5.3721262986220681e+00, -5.1655311990180879e+00, -4.9598808828268046e+00, -4.7551216843394561e+00, -4.5512024923799270e+00, -4.3480745246271999e+00, -4.1456911238198586e+00, -3.9440075731117403e+00, -3.7429809282294269e+00, -3.5425698644023571e+00, -3.3427345363058465e+00, -3.1434364494849998e+00, -2.9446383419204585e+00, -2.7463040745609382e+00, -2.5483985297872240e+00, -2.3508875168916132e+00, -2.1537376837587945e+00, -1.9569164340215148e+00, -1.7603918490392145e+00, -1.5641326141118630e+00, -1.3681079483960505e+00, -1.1722875380371232e+00, -9.7664147207086760e-01, -7.8114018068176028e-01, -5.8575437543280562e-01, -3.9045499110504589e-01, -1.9521312880340755e-01, -0.0000000000000000e+00, 1.9521312880340755e-01, 3.9045499110504589e-01, 5.8575437543280562e-01, 7.8114018068176028e-01, 9.7664147207086760e-01, 1.1722875380371232e+00, 1.3681079483960505e+00, 1.5641326141118630e+00, 1.7603918490392145e+00, 1.9569164340215148e+00, 2.1537376837587945e+00, 2.3508875168916132e+00, 2.5483985297872240e+00, 2.7463040745609382e+00, 2.9446383419204585e+00, 3.1434364494849998e+00, 3.3427345363058465e+00, 3.5425698644023571e+00, 3.7429809282294269e+00, 3.9440075731117403e+00, 4.1456911238198586e+00, 4.3480745246271999e+00, 4.5512024923799270e+00, 4.7551216843394561e+00, 4.9598808828268046e+00, 5.1655311990180879e+00, 5.3721262986220681e+00, 5.5797226526273649e+00, 5.7883798168558824e+00, 5.9981607447217984e+00, 6.2091321383995863e+00, 6.4213648445851028e+00, 6.6349343022359886e+00, 6.8499210511601492e+00, 7.0664113121603904e+00, 7.2844976517401534e+00, 7.5042797472635216e+00, 7.7258652721212853e+00, 7.9493709251260496e+00, 8.1749236343739895e+00, 8.4026619736253494e+00, 8.6327378395084349e+00, 8.8653184514446028e+00, 9.1005887544187765e+00, 9.3387543294632973e+00, 9.5800449507652310e+00, 9.8247189758331519e+00, 1.0073068822584037e+01, 1.0325427884573593e+01, 1.0582179378973514e+01, 1.0843767837715543e+01, 1.1110714285141645e+01, 1.1383636673511937e+01, 1.1663278012068952e+01, 1.1950546092769182e+01, 1.2246571315023999e+01, 1.2552793952444540e+01, 1.2871101778903627e+01, 1.3204059359674192e+01, 1.3555317966130856e+01, 1.3930420866479178e+01, 1.4338611529008967e+01, 1.4797830896490307e+01, 1.5355049674683126e+01}, + {-1.5418030829061875e+01, -1.4861563508435680e+01, -1.4402979857014893e+01, -1.3995367226732167e+01, -1.3620806639033354e+01, -1.3270065859909028e+01, -1.2937608322597471e+01, -1.2619787154794016e+01, -1.2314040876404606e+01, -1.2018483985703304e+01, -1.1731677947147649e+01, -1.1452493732070961e+01, -1.1180024657270208e+01, -1.0913528629812234e+01, -1.0652388468924656e+01, -1.0396083810552501e+01, -1.0144170696212489e+01, -9.8962664133982265e+00, -9.6520380180840490e+00, -9.4111934972461668e+00, -9.1734748618357518e+00, -8.9386526761940264e+00, -8.7065216731065060e+00, -8.4768972009392183e+00, -8.2496123166430966e+00, -8.0245153858819371e+00, -7.8014680855407574e+00, -7.5803437285851887e+00, -7.3610258494479153e+00, -7.1434070016947420e+00, -6.9273877299634155e+00, -6.7128756859735788e+00, -6.4997848644138259e+00, -6.2880349391774812e+00, -6.0775506840731746e+00, -5.8682614650210780e+00, -5.6601007930399492e+00, -5.4530059291673494e+00, -5.2469175339362204e+00, -5.0417793552319132e+00, -4.8375379493332744e+00, -4.6341424307446326e+00, -4.4315442470876985e+00, -4.2296969758707617e+00, -4.0285561404088908e+00, -3.8280790425501139e+00, -3.6282246101824178e+00, -3.4289532577657682e+00, -3.2302267583609394e+00, -3.0320081258198956e+00, -2.8342615059664689e+00, -2.6369520757359015e+00, -2.4400459493612159e+00, -2.2435100907965948e+00, -2.0473122316554950e+00, -1.8514207940163270e+00, -1.6558048175129170e+00, -1.4604338901821434e+00, -1.2652780825883267e+00, -1.0703078847841583e+00, -8.7549414570205153e-01, -6.8080801459844631e-01, -4.8622088419741660e-01, -2.9170433519935240e-01, -9.7230081835906187e-02, 9.7230081835906187e-02, 2.9170433519935240e-01, 4.8622088419741660e-01, 6.8080801459844631e-01, 8.7549414570205153e-01, 1.0703078847841583e+00, 1.2652780825883267e+00, 1.4604338901821434e+00, 1.6558048175129170e+00, 1.8514207940163270e+00, 2.0473122316554950e+00, 2.2435100907965948e+00, 2.4400459493612159e+00, 2.6369520757359015e+00, 2.8342615059664689e+00, 3.0320081258198956e+00, 3.2302267583609394e+00, 3.4289532577657682e+00, 3.6282246101824178e+00, 3.8280790425501139e+00, 4.0285561404088908e+00, 4.2296969758707617e+00, 4.4315442470876985e+00, 4.6341424307446326e+00, 4.8375379493332744e+00, 5.0417793552319132e+00, 5.2469175339362204e+00, 5.4530059291673494e+00, 5.6601007930399492e+00, 5.8682614650210780e+00, 6.0775506840731746e+00, 6.2880349391774812e+00, 6.4997848644138259e+00, 6.7128756859735788e+00, 6.9273877299634155e+00, 7.1434070016947420e+00, 7.3610258494479153e+00, 7.5803437285851887e+00, 7.8014680855407574e+00, 8.0245153858819371e+00, 8.2496123166430966e+00, 8.4768972009392183e+00, 8.7065216731065060e+00, 8.9386526761940264e+00, 9.1734748618357518e+00, 9.4111934972461668e+00, 9.6520380180840490e+00, 9.8962664133982265e+00, 1.0144170696212489e+01, 1.0396083810552501e+01, 1.0652388468924656e+01, 1.0913528629812234e+01, 1.1180024657270208e+01, 1.1452493732070961e+01, 1.1731677947147649e+01, 1.2018483985703304e+01, 1.2314040876404606e+01, 1.2619787154794016e+01, 1.2937608322597471e+01, 1.3270065859909028e+01, 1.3620806639033354e+01, 1.3995367226732167e+01, 1.4402979857014893e+01, 1.4861563508435680e+01, 1.5418030829061875e+01}, + {-1.5480766130162912e+01, -1.4925043329908892e+01, -1.4467089414730456e+01, -1.4060049290015051e+01, -1.3686025751508065e+01, -1.3335797702455430e+01, -1.3003835219535608e+01, -1.2686495791216792e+01, -1.2381220995463224e+01, -1.2086127582443233e+01, -1.1799778738905447e+01, -1.1521046794198202e+01, -1.1249026163290472e+01, -1.0982975660531801e+01, -1.0722278868759513e+01, -1.0466416077189237e+01, -1.0214943894423017e+01, -9.9674801067548007e+00, -9.7236922142042346e+00, -9.4832886034446808e+00, -9.2460116489073236e+00, -9.0116322486398488e+00, -8.7799454445339524e+00, -8.5507668736650881e+00, -8.3239298647512676e+00, -8.0992830411501870e+00, -7.8766883257751701e+00, -7.6560192679949264e+00, -7.4371596307659544e+00, -7.2200021898070377e+00, -7.0044477068537327e+00, -6.7904040468269269e+00, -6.5777854147500525e+00, -6.3665116929098069e+00, -6.1565078624054426e+00, -5.9477034961131627e+00, -5.7400323123838195e+00, -5.5334317806272333e+00, -5.3278427714156580e+00, -5.1232092449384545e+00, -4.9194779726184912e+00, -4.7165982875032402e+00, -4.5145218597049430e+00, -4.3132024937121241e+00, -4.1125959448506144e+00, -3.9126597525531843e+00, -3.7133530884165373e+00, -3.5146366172935721e+00, -3.3164723698963634e+00, -3.1188236255781381e+00, -2.9216548041266144e+00, -2.7249313655408702e+00, -2.5286197168834539e+00, -2.3326871254017765e+00, -2.1371016372005704e+00, -1.9418320008225314e+00, -1.7468475951589244e+00, -1.5521183611674445e+00, -1.3576147369221905e+00, -1.1633075955612597e+00, -9.6916818573207730e-01, -7.7516807416380029e-01, -5.8127909002062172e-01, -3.8747327070995596e-01, -1.9372280883577261e-01, -0.0000000000000000e+00, 1.9372280883577261e-01, 3.8747327070995596e-01, 5.8127909002062172e-01, 7.7516807416380029e-01, 9.6916818573207730e-01, 1.1633075955612597e+00, 1.3576147369221905e+00, 1.5521183611674445e+00, 1.7468475951589244e+00, 1.9418320008225314e+00, 2.1371016372005704e+00, 2.3326871254017765e+00, 2.5286197168834539e+00, 2.7249313655408702e+00, 2.9216548041266144e+00, 3.1188236255781381e+00, 3.3164723698963634e+00, 3.5146366172935721e+00, 3.7133530884165373e+00, 3.9126597525531843e+00, 4.1125959448506144e+00, 4.3132024937121241e+00, 4.5145218597049430e+00, 4.7165982875032402e+00, 4.9194779726184912e+00, 5.1232092449384545e+00, 5.3278427714156580e+00, 5.5334317806272333e+00, 5.7400323123838195e+00, 5.9477034961131627e+00, 6.1565078624054426e+00, 6.3665116929098069e+00, 6.5777854147500525e+00, 6.7904040468269269e+00, 7.0044477068537327e+00, 7.2200021898070377e+00, 7.4371596307659544e+00, 7.6560192679949264e+00, 7.8766883257751701e+00, 8.0992830411501870e+00, 8.3239298647512676e+00, 8.5507668736650881e+00, 8.7799454445339524e+00, 9.0116322486398488e+00, 9.2460116489073236e+00, 9.4832886034446808e+00, 9.7236922142042346e+00, 9.9674801067548007e+00, 1.0214943894423017e+01, 1.0466416077189237e+01, 1.0722278868759513e+01, 1.0982975660531801e+01, 1.1249026163290472e+01, 1.1521046794198202e+01, 1.1799778738905447e+01, 1.2086127582443233e+01, 1.2381220995463224e+01, 1.2686495791216792e+01, 1.3003835219535608e+01, 1.3335797702455430e+01, 1.3686025751508065e+01, 1.4060049290015051e+01, 1.4467089414730456e+01, 1.4925043329908892e+01, 1.5480766130162912e+01}, + {-1.5543258422323774e+01, -1.4988273322620483e+01, -1.4530943266670407e+01, -1.4124470217193569e+01, -1.3750978557373212e+01, -1.3401258232252896e+01, -1.3069785904893536e+01, -1.2752923386873304e+01, -1.2448115287552957e+01, -1.2153480589094658e+01, -1.1867584185044096e+01, -1.1589299750272769e+01, -1.1317722787546410e+01, -1.1052113009654860e+01, -1.0791854755335825e+01, -1.0536428960217005e+01, -1.0285392793773033e+01, -1.0038364535378761e+01, -9.7950121237570809e+00, -9.5550443402238834e+00, -9.3182039178520490e+00, -9.0842620837165757e+00, -8.8530141842483925e+00, -8.6242761407386386e+00, -8.3978815492187184e+00, -8.1736792862980483e+00, -7.9515315164625289e+00, -7.7313120209923101e+00, -7.5129047868198517e+00, -7.2962028071941081e+00, -7.0811070562331242e+00, -6.8675256072344579e+00, -6.6553728706063735e+00, -6.4445689319376820e+00, -6.2350389743700507e+00, -6.0267127723148342e+00, -5.8195242458455034e+00, -5.6134110669298432e+00, -5.4083143101435791e+00, -5.2041781417053947e+00, -5.0009495416506535e+00, -4.7985780547627241e+00, -4.5970155665415948e+00, -4.3962161010367922e+00, -4.1961356378270693e+00, -3.9967319458099735e+00, -3.7979644317837824e+00, -3.5997940020732910e+00, -3.4021829356783408e+00, -3.2050947676167678e+00, -3.0084941812975128e+00, -2.8123469088994537e+00, -2.6166196388511782e+00, -2.4212799296093106e+00, -2.2262961290209549e+00, -2.0316372986313107e+00, -1.8372731423624578e+00, -1.6431739390450815e+00, -1.4493104783328268e+00, -1.2556539995700138e+00, -1.0621761332184900e+00, -8.6884884447915023e-01, -6.7564437876870465e-01, -4.8253520873311562e-01, -2.8949398249614278e-01, -9.6493472854955881e-02, 9.6493472854955881e-02, 2.8949398249614278e-01, 4.8253520873311562e-01, 6.7564437876870465e-01, 8.6884884447915023e-01, 1.0621761332184900e+00, 1.2556539995700138e+00, 1.4493104783328268e+00, 1.6431739390450815e+00, 1.8372731423624578e+00, 2.0316372986313107e+00, 2.2262961290209549e+00, 2.4212799296093106e+00, 2.6166196388511782e+00, 2.8123469088994537e+00, 3.0084941812975128e+00, 3.2050947676167678e+00, 3.4021829356783408e+00, 3.5997940020732910e+00, 3.7979644317837824e+00, 3.9967319458099735e+00, 4.1961356378270693e+00, 4.3962161010367922e+00, 4.5970155665415948e+00, 4.7985780547627241e+00, 5.0009495416506535e+00, 5.2041781417053947e+00, 5.4083143101435791e+00, 5.6134110669298432e+00, 5.8195242458455034e+00, 6.0267127723148342e+00, 6.2350389743700507e+00, 6.4445689319376820e+00, 6.6553728706063735e+00, 6.8675256072344579e+00, 7.0811070562331242e+00, 7.2962028071941081e+00, 7.5129047868198517e+00, 7.7313120209923101e+00, 7.9515315164625289e+00, 8.1736792862980483e+00, 8.3978815492187184e+00, 8.6242761407386386e+00, 8.8530141842483925e+00, 9.0842620837165757e+00, 9.3182039178520490e+00, 9.5550443402238834e+00, 9.7950121237570809e+00, 1.0038364535378761e+01, 1.0285392793773033e+01, 1.0536428960217005e+01, 1.0791854755335825e+01, 1.1052113009654860e+01, 1.1317722787546410e+01, 1.1589299750272769e+01, 1.1867584185044096e+01, 1.2153480589094658e+01, 1.2448115287552957e+01, 1.2752923386873304e+01, 1.3069785904893536e+01, 1.3401258232252896e+01, 1.3750978557373212e+01, 1.4124470217193569e+01, 1.4530943266670407e+01, 1.4988273322620483e+01, 1.5543258422323774e+01}, + {-1.5605510495565703e+01, -1.5051256391093448e+01, -1.4594544417610667e+01, -1.4188633106973045e+01, -1.3815668245922964e+01, -1.3466450727373902e+01, -1.3135463744634585e+01, -1.2819073395348772e+01, -1.2514727294059055e+01, -1.2220546635363748e+01, -1.1935098004387349e+01, -1.1657256409263454e+01, -1.1386118430379335e+01, -1.1120944670301025e+01, -1.0861120216120376e+01, -1.0606126643170979e+01, -1.0355521675732227e+01, -1.0108924080680463e+01, -9.8660022302368411e+00, -9.6264652954408270e+00, -9.3900563633043106e+00, -9.1565469853869601e+00, -8.9257328082304568e+00, -8.6974300329890397e+00, -8.4714725186984587e+00, -8.2477093909264614e+00, -8.0260030514294165e+00, -7.8062275090663409e+00, -7.5882669703629624e+00, -7.3720146416474837e+00, -7.1573717048843459e+00, -6.9442464371104355e+00, -6.7325534493647661e+00, -6.5222130256523068e+00, -6.3131505461243611e+00, -6.1052959815328816e+00, -5.8985834483025466e+00, -5.6929508153954593e+00, -5.4883393556191784e+00, -5.2846934352257779e+00, -5.0819602366259380e+00, -4.8800895098428096e+00, -4.6790333489905045e+00, -4.4787459906088296e+00, -4.2791836311409464e+00, -4.0803042612209337e+00, -3.8820675147573152e+00, -3.6844345310674940e+00, -3.4873678285452550e+00, -3.2908311885362425e+00, -3.0947895482603323e+00, -2.8992089017596818e+00, -2.7040562079709125e+00, -2.5092993051224148e+00, -2.3149068307458065e+00, -2.1208481466662792e+00, -1.9270932684016822e+00, -1.7336127984562590e+00, -1.5403778630431328e+00, -1.3473600518110582e+00, -1.1545313601863669e+00, -9.6186413397127435e-01, -7.6933101586525243e-01, -5.7690489359762542e-01, -3.8455884937721463e-01, -1.9226611037913860e-01, -0.0000000000000000e+00, 1.9226611037913860e-01, 3.8455884937721463e-01, 5.7690489359762542e-01, 7.6933101586525243e-01, 9.6186413397127435e-01, 1.1545313601863669e+00, 1.3473600518110582e+00, 1.5403778630431328e+00, 1.7336127984562590e+00, 1.9270932684016822e+00, 2.1208481466662792e+00, 2.3149068307458065e+00, 2.5092993051224148e+00, 2.7040562079709125e+00, 2.8992089017596818e+00, 3.0947895482603323e+00, 3.2908311885362425e+00, 3.4873678285452550e+00, 3.6844345310674940e+00, 3.8820675147573152e+00, 4.0803042612209337e+00, 4.2791836311409464e+00, 4.4787459906088296e+00, 4.6790333489905045e+00, 4.8800895098428096e+00, 5.0819602366259380e+00, 5.2846934352257779e+00, 5.4883393556191784e+00, 5.6929508153954593e+00, 5.8985834483025466e+00, 6.1052959815328816e+00, 6.3131505461243611e+00, 6.5222130256523068e+00, 6.7325534493647661e+00, 6.9442464371104355e+00, 7.1573717048843459e+00, 7.3720146416474837e+00, 7.5882669703629624e+00, 7.8062275090663409e+00, 8.0260030514294165e+00, 8.2477093909264614e+00, 8.4714725186984587e+00, 8.6974300329890397e+00, 8.9257328082304568e+00, 9.1565469853869601e+00, 9.3900563633043106e+00, 9.6264652954408270e+00, 9.8660022302368411e+00, 1.0108924080680463e+01, 1.0355521675732227e+01, 1.0606126643170979e+01, 1.0861120216120376e+01, 1.1120944670301025e+01, 1.1386118430379335e+01, 1.1657256409263454e+01, 1.1935098004387349e+01, 1.2220546635363748e+01, 1.2514727294059055e+01, 1.2819073395348772e+01, 1.3135463744634585e+01, 1.3466450727373902e+01, 1.3815668245922964e+01, 1.4188633106973045e+01, 1.4594544417610667e+01, 1.5051256391093448e+01, 1.5605510495565703e+01}, + {-1.5667525087033042e+01, -1.5113995384194148e+01, -1.4657895814201638e+01, -1.4252540997590891e+01, -1.3880097943698006e+01, -1.3531378400872688e+01, -1.3200872037437804e+01, -1.2884949200661589e+01, -1.2581060484489544e+01, -1.2287329276732219e+01, -1.2002323839142806e+01, -1.1724920501080165e+01, -1.1454216910571811e+01, -1.1189474551468571e+01, -1.0930079251827893e+01, -1.0675513220130126e+01, -1.0425334729531320e+01, -1.0179163028964693e+01, -9.9366669190764370e+00, -9.6975559558409401e+00, -9.4615735756363968e+00, -9.2284916500953180e+00, -8.9981061215741249e+00, -8.7702334668725097e+00, -8.5447078038596302e+00, -8.3213785029101519e+00, -8.1001081988952368e+00, -7.8807711240717229e+00, -7.6632517003331104e+00, -7.4474433427993905e+00, -7.2332474369156490e+00, -7.0205724589985739e+00, -6.8093332161497848e+00, -6.5994501860991619e+00, -6.3908489411790317e+00, -6.1834596435017497e+00, -5.9772166006971021e+00, -5.7720578733949548e+00, -5.5679249271127809e+00, -5.3647623224033971e+00, -5.1625174380934791e+00, -4.9611402232433406e+00, -4.7605829741178525e+00, -4.5608001330046735e+00, -4.3617481061705252e+00, -4.1633850986262280e+00, -3.9656709636900676e+00, -3.7685670656076877e+00, -3.5720361537138379e+00, -3.3760422468139430e+00, -3.1805505266274205e+00, -2.9855272392745684e+00, -2.7909396039085173e+00, -2.5967557276963822e+00, -2.4029445264418832e+00, -2.2094756502175628e+00, -2.0163194134400269e+00, -1.8234467288779213e+00, -1.6308290451307998e+00, -1.4384382871587706e+00, -1.2462467994785644e+00, -1.0542272916723083e+00, -8.6235278588129705e-01, -6.7059656597901129e-01, -4.7893212813590247e-01, -2.8733313250340886e-01, -9.5773355756546857e-02, 9.5773355756546857e-02, 2.8733313250340886e-01, 4.7893212813590247e-01, 6.7059656597901129e-01, 8.6235278588129705e-01, 1.0542272916723083e+00, 1.2462467994785644e+00, 1.4384382871587706e+00, 1.6308290451307998e+00, 1.8234467288779213e+00, 2.0163194134400269e+00, 2.2094756502175628e+00, 2.4029445264418832e+00, 2.5967557276963822e+00, 2.7909396039085173e+00, 2.9855272392745684e+00, 3.1805505266274205e+00, 3.3760422468139430e+00, 3.5720361537138379e+00, 3.7685670656076877e+00, 3.9656709636900676e+00, 4.1633850986262280e+00, 4.3617481061705252e+00, 4.5608001330046735e+00, 4.7605829741178525e+00, 4.9611402232433406e+00, 5.1625174380934791e+00, 5.3647623224033971e+00, 5.5679249271127809e+00, 5.7720578733949548e+00, 5.9772166006971021e+00, 6.1834596435017497e+00, 6.3908489411790317e+00, 6.5994501860991619e+00, 6.8093332161497848e+00, 7.0205724589985739e+00, 7.2332474369156490e+00, 7.4474433427993905e+00, 7.6632517003331104e+00, 7.8807711240717229e+00, 8.1001081988952368e+00, 8.3213785029101519e+00, 8.5447078038596302e+00, 8.7702334668725097e+00, 8.9981061215741249e+00, 9.2284916500953180e+00, 9.4615735756363968e+00, 9.6975559558409401e+00, 9.9366669190764370e+00, 1.0179163028964693e+01, 1.0425334729531320e+01, 1.0675513220130126e+01, 1.0930079251827893e+01, 1.1189474551468571e+01, 1.1454216910571811e+01, 1.1724920501080165e+01, 1.2002323839142806e+01, 1.2287329276732219e+01, 1.2581060484489544e+01, 1.2884949200661589e+01, 1.3200872037437804e+01, 1.3531378400872688e+01, 1.3880097943698006e+01, 1.4252540997590891e+01, 1.4657895814201638e+01, 1.5113995384194148e+01, 1.5667525087033042e+01}, + {-1.5729304882383959e+01, -1.5176493096610994e+01, -1.4721000346526051e+01, -1.4316196868450396e+01, -1.3944270716194302e+01, -1.3596044402569063e+01, -1.3266014016557564e+01, -1.2950554119200040e+01, -1.2647118258490758e+01, -1.2353831996553668e+01, -1.2069265257081389e+01, -1.1792295678839055e+01, -1.1522021967701262e+01, -1.1257706480479557e+01, -1.0998735778960949e+01, -1.0744592698355470e+01, -1.0494836054902457e+01, -1.0249085574277188e+01, -1.0007010480604432e+01, -9.7683207101299594e+00, -9.5327600441503151e+00, -9.3001006700843707e+00, -9.0701388219340853e+00, -8.8426912480559938e+00, -8.6175923211137029e+00, -8.3946916522729023e+00, -8.1738521055035420e+00, -7.9549481324236444e+00, -7.7378643662186803e+00, -7.5224944266685263e+00, -7.3087398984951246e+00, -7.0965094530044173e+00, -6.8857180889690319e+00, -6.6762864733372753e+00, -6.4681403659874999e+00, -6.2612101156154036e+00, -6.0554302161231597e+00, -5.8507389147062092e+00, -5.6470778643062038e+00, -5.4443918142929100e+00, -5.2426283342121209e+00, -5.0417375662357022e+00, -4.8416720026085907e+00, -4.6423862849333188e+00, -4.4438370225867869e+00, -4.2459826279436079e+00, -4.0487831663989748e+00, -3.8522002194524045e+00, -3.6561967593406961e+00, -3.4607370339009882e+00, -3.2657864605087177e+00, -3.0713115280751384e+00, -2.8772797062087854e+00, -2.6836593607479262e+00, -2.4904196749593304e+00, -2.2975305757745934e+00, -2.1049626645007851e+00, -1.9126871514986146e+00, -1.7206757943700177e+00, -1.5289008392390442e+00, -1.3373349647460135e+00, -1.1459512284058875e+00, -9.5472301500823675e-01, -7.6362398675858623e-01, -5.7262803487972669e-01, -3.8170923240711668e-01, -1.9084178792504236e-01, -0.0000000000000000e+00, 1.9084178792504236e-01, 3.8170923240711668e-01, 5.7262803487972669e-01, 7.6362398675858623e-01, 9.5472301500823675e-01, 1.1459512284058875e+00, 1.3373349647460135e+00, 1.5289008392390442e+00, 1.7206757943700177e+00, 1.9126871514986146e+00, 2.1049626645007851e+00, 2.2975305757745934e+00, 2.4904196749593304e+00, 2.6836593607479262e+00, 2.8772797062087854e+00, 3.0713115280751384e+00, 3.2657864605087177e+00, 3.4607370339009882e+00, 3.6561967593406961e+00, 3.8522002194524045e+00, 4.0487831663989748e+00, 4.2459826279436079e+00, 4.4438370225867869e+00, 4.6423862849333188e+00, 4.8416720026085907e+00, 5.0417375662357022e+00, 5.2426283342121209e+00, 5.4443918142929100e+00, 5.6470778643062038e+00, 5.8507389147062092e+00, 6.0554302161231597e+00, 6.2612101156154036e+00, 6.4681403659874999e+00, 6.6762864733372753e+00, 6.8857180889690319e+00, 7.0965094530044173e+00, 7.3087398984951246e+00, 7.5224944266685263e+00, 7.7378643662186803e+00, 7.9549481324236444e+00, 8.1738521055035420e+00, 8.3946916522729023e+00, 8.6175923211137029e+00, 8.8426912480559938e+00, 9.0701388219340853e+00, 9.3001006700843707e+00, 9.5327600441503151e+00, 9.7683207101299594e+00, 1.0007010480604432e+01, 1.0249085574277188e+01, 1.0494836054902457e+01, 1.0744592698355470e+01, 1.0998735778960949e+01, 1.1257706480479557e+01, 1.1522021967701262e+01, 1.1792295678839055e+01, 1.2069265257081389e+01, 1.2353831996553668e+01, 1.2647118258490758e+01, 1.2950554119200040e+01, 1.3266014016557564e+01, 1.3596044402569063e+01, 1.3944270716194302e+01, 1.4316196868450396e+01, 1.4721000346526051e+01, 1.5176493096610994e+01, 1.5729304882383959e+01}, + {-1.5790852517134587e+01, -1.5238752270283085e+01, -1.4783860849603613e+01, -1.4379603641698345e+01, -1.4008189569512616e+01, -1.3660451820769911e+01, -1.3330892851617801e+01, -1.3015891401590464e+01, -1.2712903947791023e+01, -1.2420058208074661e+01, -1.2135925753638015e+01, -1.1859385521045176e+01, -1.1589537264407285e+01, -1.1325644205334678e+01, -1.1067093632255466e+01, -1.0813369000829548e+01, -1.0564029664716180e+01, -1.0318695821142974e+01, -1.0077037112888743e+01, -9.8387638519273803e+00, -9.6036201601455531e+00, -9.3713785365821725e+00, -9.1418355028369902e+00, -8.9148080748582679e+00, -8.6901308761912386e+00, -8.4676537549061486e+00, -8.2472398001890390e+00, -8.0287636791201553e+00, -7.8121102322437741e+00, -7.5971732800158449e+00, -7.3838546023854859e+00, -7.1720630615179752e+00, -6.9617138436331016e+00, -6.7527278005665341e+00, -6.5450308752913493e+00, -6.3385535985021413e+00, -6.1332306456429340e+00, -5.9290004455850367e+00, -5.7258048336320568e+00, -5.5235887427222501e+00, -5.3222999276716845e+00, -5.1218887180998118e+00, -4.9223077963371686e+00, -4.7235119971600676e+00, -4.5254581266508760e+00, -4.3281047978617426e+00, -4.1314122812779592e+00, -3.9353423683453870e+00, -3.7398582465531405e+00, -3.5449243847552383e+00, -3.3505064275787246e+00, -3.1565710979056170e+00, -2.9630861065357892e+00, -2.7700200682405702e+00, -2.5773424235052076e+00, -2.3850233653343853e+00, -2.1930337705606084e+00, -2.0013451351519014e+00, -1.8099295130641593e+00, -1.6187594582257014e+00, -1.4278079692779639e+00, -1.2370484367275345e+00, -1.0464545921915449e+00, -8.5600045944125114e-01, -6.6566030696788747e-01, -4.7540860181095812e-01, -2.8521996440226244e-01, -9.5069124189415724e-02, 9.5069124189415724e-02, 2.8521996440226244e-01, 4.7540860181095812e-01, 6.6566030696788747e-01, 8.5600045944125114e-01, 1.0464545921915449e+00, 1.2370484367275345e+00, 1.4278079692779639e+00, 1.6187594582257014e+00, 1.8099295130641593e+00, 2.0013451351519014e+00, 2.1930337705606084e+00, 2.3850233653343853e+00, 2.5773424235052076e+00, 2.7700200682405702e+00, 2.9630861065357892e+00, 3.1565710979056170e+00, 3.3505064275787246e+00, 3.5449243847552383e+00, 3.7398582465531405e+00, 3.9353423683453870e+00, 4.1314122812779592e+00, 4.3281047978617426e+00, 4.5254581266508760e+00, 4.7235119971600676e+00, 4.9223077963371686e+00, 5.1218887180998118e+00, 5.3222999276716845e+00, 5.5235887427222501e+00, 5.7258048336320568e+00, 5.9290004455850367e+00, 6.1332306456429340e+00, 6.3385535985021413e+00, 6.5450308752913493e+00, 6.7527278005665341e+00, 6.9617138436331016e+00, 7.1720630615179752e+00, 7.3838546023854859e+00, 7.5971732800158449e+00, 7.8121102322437741e+00, 8.0287636791201553e+00, 8.2472398001890390e+00, 8.4676537549061486e+00, 8.6901308761912386e+00, 8.9148080748582679e+00, 9.1418355028369902e+00, 9.3713785365821725e+00, 9.6036201601455531e+00, 9.8387638519273803e+00, 1.0077037112888743e+01, 1.0318695821142974e+01, 1.0564029664716180e+01, 1.0813369000829548e+01, 1.1067093632255466e+01, 1.1325644205334678e+01, 1.1589537264407285e+01, 1.1859385521045176e+01, 1.2135925753638015e+01, 1.2420058208074661e+01, 1.2712903947791023e+01, 1.3015891401590464e+01, 1.3330892851617801e+01, 1.3660451820769911e+01, 1.4008189569512616e+01, 1.4379603641698345e+01, 1.4783860849603613e+01, 1.5238752270283085e+01, 1.5790852517134587e+01}, + {-1.5852170577958367e+01, -1.5300775595780827e+01, -1.4846480104844703e+01, -1.4442764183748782e+01, -1.4071857451951351e+01, -1.3724603683931077e+01, -1.3395511650343654e+01, -1.3080964234499790e+01, -1.2778420818075578e+01, -1.2486011256383852e+01, -1.2202308753936913e+01, -1.1926193533696322e+01, -1.1656766388576511e+01, -1.1393291396981837e+01, -1.1135156567035956e+01, -1.0881845968701494e+01, -1.0632919487519736e+01, -1.0387997787201458e+01, -1.0146750924472403e+01, -9.9088895826069283e+00, -9.6741582198685645e+00, -9.4423296428652392e+00, -9.2132006568631315e+00, -8.9865885415552977e+00, -8.7623281675764328e+00, -8.5402696161385645e+00, -8.3202761978883633e+00, -8.1022227916007061e+00, -7.8859944413814738e+00, -7.6714851645199493e+00, -7.4585969322894226e+00, -7.2472387937374041e+00, -7.0373261184664502e+00, -6.8287799390351633e+00, -6.6215263772344395e+00, -6.4154961413560549e+00, -6.2106240838470441e+00, -6.0068488105662023e+00, -5.8041123343284946e+00, -5.6023597666149243e+00, -5.4015390422975438e+00, -5.2016006730266913e+00, -5.0024975255849276e+00, -4.8041846220567344e+00, -4.6066189591163766e+00, -4.4097593441152032e+00, -4.2135662459677485e+00, -4.0180016591039696e+00, -3.8230289789816339e+00, -3.6286128878452084e+00, -3.4347192495813528e+00, -3.2413150126609418e+00, -3.0483681202772592e+00, -2.8558474268927547e+00, -2.6637226204951387e+00, -2.4719641499397405e+00, -2.2805431568207979e+00, -2.0894314113711125e+00, -1.8986012519385917e+00, -1.7080255276306118e+00, -1.5176775437537562e+00, -1.3275310097080575e+00, -1.1375599890219745e+00, -9.4773885123753698e-01, -7.5804222537475319e-01, -5.6844495472091694e-01, -3.7892205270411800e-01, -1.8944865962132065e-01, -0.0000000000000000e+00, 1.8944865962132065e-01, 3.7892205270411800e-01, 5.6844495472091694e-01, 7.5804222537475319e-01, 9.4773885123753698e-01, 1.1375599890219745e+00, 1.3275310097080575e+00, 1.5176775437537562e+00, 1.7080255276306118e+00, 1.8986012519385917e+00, 2.0894314113711125e+00, 2.2805431568207979e+00, 2.4719641499397405e+00, 2.6637226204951387e+00, 2.8558474268927547e+00, 3.0483681202772592e+00, 3.2413150126609418e+00, 3.4347192495813528e+00, 3.6286128878452084e+00, 3.8230289789816339e+00, 4.0180016591039696e+00, 4.2135662459677485e+00, 4.4097593441152032e+00, 4.6066189591163766e+00, 4.8041846220567344e+00, 5.0024975255849276e+00, 5.2016006730266913e+00, 5.4015390422975438e+00, 5.6023597666149243e+00, 5.8041123343284946e+00, 6.0068488105662023e+00, 6.2106240838470441e+00, 6.4154961413560549e+00, 6.6215263772344395e+00, 6.8287799390351633e+00, 7.0373261184664502e+00, 7.2472387937374041e+00, 7.4585969322894226e+00, 7.6714851645199493e+00, 7.8859944413814738e+00, 8.1022227916007061e+00, 8.3202761978883633e+00, 8.5402696161385645e+00, 8.7623281675764328e+00, 8.9865885415552977e+00, 9.2132006568631315e+00, 9.4423296428652392e+00, 9.6741582198685645e+00, 9.9088895826069283e+00, 1.0146750924472403e+01, 1.0387997787201458e+01, 1.0632919487519736e+01, 1.0881845968701494e+01, 1.1135156567035956e+01, 1.1393291396981837e+01, 1.1656766388576511e+01, 1.1926193533696322e+01, 1.2202308753936913e+01, 1.2486011256383852e+01, 1.2778420818075578e+01, 1.3080964234499790e+01, 1.3395511650343654e+01, 1.3724603683931077e+01, 1.4071857451951351e+01, 1.4442764183748782e+01, 1.4846480104844703e+01, 1.5300775595780827e+01, 1.5852170577958367e+01}, + {-1.5913261603942480e+01, -1.5362565713640512e+01, -1.4908860841455180e+01, -1.4505681306755122e+01, -1.4135277255544954e+01, -1.3788502962262141e+01, -1.3459873460233181e+01, -1.3145775742375259e+01, -1.2843672070795714e+01, -1.2551694420292197e+01, -1.2268417614744900e+01, -1.1992723152311497e+01, -1.1723712855448614e+01, -1.1460651651502332e+01, -1.1202928261484638e+01, -1.0950027363642045e+01, -1.0701509369981165e+01, -1.0456995405743042e+01, -1.0216155937006269e+01, -9.9787020140292348e+00, -9.7443784273495506e+00, -9.5129582872037410e+00, -9.2842386787046287e+00, -9.0580371415563476e+00, -8.8341887898063280e+00, -8.6125439341638330e+00, -8.3929661031022729e+00, -8.1753303834489426e+00, -7.9595220192037859e+00, -7.7454352207811352e+00, -7.5329721470151476e+00, -7.3220420300038924e+00, -7.1125604188199452e+00, -6.9044485227388090e+00, -6.6976326382579296e+00, -6.4920436470380141e+00, -6.2876165741721222e+00, -6.0842901980089970e+00, -5.8820067042248958e+00, -5.6807113780286782e+00, -5.4803523293560428e+00, -5.2808802467053466e+00, -5.0822481759241382e+00, -4.8844113207996323e+00, -4.6873268627591953e+00, -4.4909537973654823e+00, -4.2952527856086178e+00, -4.1001860182656378e+00, -3.9057170918238593e+00, -3.7118108946570874e+00, -3.5184335023072513e+00, -3.3255520808638139e+00, -3.1331347975530193e+00, -2.9411507377518000e+00, -2.7495698277296028e+00, -2.5583627624976102e+00, -2.3675009382106698e+00, -2.1769563886241587e+00, -1.9867017251572272e+00, -1.7967100801564784e+00, -1.6069550529909824e+00, -1.4174106586413215e+00, -1.2280512784727862e+00, -1.0388516129063341e+00, -8.4978663572097946e-01, -6.6083154973822611e-01, -4.7196174365329491e-01, -2.8315274978949312e-01, -9.4380202561292328e-02, 9.4380202561292328e-02, 2.8315274978949312e-01, 4.7196174365329491e-01, 6.6083154973822611e-01, 8.4978663572097946e-01, 1.0388516129063341e+00, 1.2280512784727862e+00, 1.4174106586413215e+00, 1.6069550529909824e+00, 1.7967100801564784e+00, 1.9867017251572272e+00, 2.1769563886241587e+00, 2.3675009382106698e+00, 2.5583627624976102e+00, 2.7495698277296028e+00, 2.9411507377518000e+00, 3.1331347975530193e+00, 3.3255520808638139e+00, 3.5184335023072513e+00, 3.7118108946570874e+00, 3.9057170918238593e+00, 4.1001860182656378e+00, 4.2952527856086178e+00, 4.4909537973654823e+00, 4.6873268627591953e+00, 4.8844113207996323e+00, 5.0822481759241382e+00, 5.2808802467053466e+00, 5.4803523293560428e+00, 5.6807113780286782e+00, 5.8820067042248958e+00, 6.0842901980089970e+00, 6.2876165741721222e+00, 6.4920436470380141e+00, 6.6976326382579296e+00, 6.9044485227388090e+00, 7.1125604188199452e+00, 7.3220420300038924e+00, 7.5329721470151476e+00, 7.7454352207811352e+00, 7.9595220192037859e+00, 8.1753303834489426e+00, 8.3929661031022729e+00, 8.6125439341638330e+00, 8.8341887898063280e+00, 9.0580371415563476e+00, 9.2842386787046287e+00, 9.5129582872037410e+00, 9.7443784273495506e+00, 9.9787020140292348e+00, 1.0216155937006269e+01, 1.0456995405743042e+01, 1.0701509369981165e+01, 1.0950027363642045e+01, 1.1202928261484638e+01, 1.1460651651502332e+01, 1.1723712855448614e+01, 1.1992723152311497e+01, 1.2268417614744900e+01, 1.2551694420292197e+01, 1.2843672070795714e+01, 1.3145775742375259e+01, 1.3459873460233181e+01, 1.3788502962262141e+01, 1.4135277255544954e+01, 1.4505681306755122e+01, 1.4908860841455180e+01, 1.5362565713640512e+01, 1.5913261603942480e+01}, + {-1.5974128087803059e+01, -1.5424125215654696e+01, -1.4971005737794270e+01, -1.4568357770032772e+01, -1.4198451817550286e+01, -1.3852152569276431e+01, -1.3523981270171619e+01, -1.3210328989123949e+01, -1.2908660844914866e+01, -1.2617110914147242e+01, -1.2334255626355663e+01, -1.2058977743887230e+01, -1.1790380109646946e+01, -1.1527728492218195e+01, -1.1270412318828130e+01, -1.1017916870112439e+01, -1.0769803079243415e+01, -1.0525692528151630e+01, -1.0285256087783404e+01, -1.0048205171171734e+01, -9.8142848971316887e+00, -9.5832686756941996e+00, -9.3549538681059694e+00, -9.1291582704569425e+00, -8.9057172366410864e+00, -8.6844813033334454e+00, -8.4653142133164536e+00, -8.2480912579473227e+00, -8.0326978775762718e+00, -7.8190284721625867e+00, -7.6069853844711011e+00, -7.3964780259572480e+00, -7.1874221213951852e+00, -6.9797390529218948e+00, -6.7733552877875338e+00, -6.5682018769582182e+00, -6.3642140139886543e+00, -6.1613306454010424e+00, -5.9594941252729363e+00, -5.7586499079259337e+00, -5.5587462735771860e+00, -5.3597340826114390e+00, -5.1615665547873322e+00, -4.9641990702352388e+00, -4.7675889895563337e+00, -4.5716954907107725e+00, -4.3764794207003801e+00, -4.1819031603187895e+00, -3.9879305004682921e+00, -3.7945265287347798e+00, -3.6016575250757095e+00, -3.4092908656157688e+00, -3.2173949336645937e+00, -3.0259390371736554e+00, -2.8348933319378968e+00, -2.6442287499240060e+00, -2.4539169321730845e+00, -2.2639301657825421e+00, -2.0742413245213673e+00, -1.8848238126757204e+00, -1.6956515117588089e+00, -1.5066987297510446e+00, -1.3179401525641421e+00, -1.1293507974466097e+00, -9.4090596806846227e-01, -7.5258121104029896e-01, -5.6435227363645946e-01, -3.7619506250401802e-01, -1.8808560314914807e-01, -0.0000000000000000e+00, 1.8808560314914807e-01, 3.7619506250401802e-01, 5.6435227363645946e-01, 7.5258121104029896e-01, 9.4090596806846227e-01, 1.1293507974466097e+00, 1.3179401525641421e+00, 1.5066987297510446e+00, 1.6956515117588089e+00, 1.8848238126757204e+00, 2.0742413245213673e+00, 2.2639301657825421e+00, 2.4539169321730845e+00, 2.6442287499240060e+00, 2.8348933319378968e+00, 3.0259390371736554e+00, 3.2173949336645937e+00, 3.4092908656157688e+00, 3.6016575250757095e+00, 3.7945265287347798e+00, 3.9879305004682921e+00, 4.1819031603187895e+00, 4.3764794207003801e+00, 4.5716954907107725e+00, 4.7675889895563337e+00, 4.9641990702352388e+00, 5.1615665547873322e+00, 5.3597340826114390e+00, 5.5587462735771860e+00, 5.7586499079259337e+00, 5.9594941252729363e+00, 6.1613306454010424e+00, 6.3642140139886543e+00, 6.5682018769582182e+00, 6.7733552877875338e+00, 6.9797390529218948e+00, 7.1874221213951852e+00, 7.3964780259572480e+00, 7.6069853844711011e+00, 7.8190284721625867e+00, 8.0326978775762718e+00, 8.2480912579473227e+00, 8.4653142133164536e+00, 8.6844813033334454e+00, 8.9057172366410864e+00, 9.1291582704569425e+00, 9.3549538681059694e+00, 9.5832686756941996e+00, 9.8142848971316887e+00, 1.0048205171171734e+01, 1.0285256087783404e+01, 1.0525692528151630e+01, 1.0769803079243415e+01, 1.1017916870112439e+01, 1.1270412318828130e+01, 1.1527728492218195e+01, 1.1790380109646946e+01, 1.2058977743887230e+01, 1.2334255626355663e+01, 1.2617110914147242e+01, 1.2908660844914866e+01, 1.3210328989123949e+01, 1.3523981270171619e+01, 1.3852152569276431e+01, 1.4198451817550286e+01, 1.4568357770032772e+01, 1.4971005737794270e+01, 1.5424125215654696e+01, 1.5974128087803059e+01}, + {-1.6034772477060816e+01, -1.5485456646120181e+01, -1.5032917422687504e+01, -1.4630796281434252e+01, -1.4261383921882931e+01, -1.3915555363288536e+01, -1.3587838011990620e+01, -1.3274626979734647e+01, -1.2973390218594389e+01, -1.2682263889584272e+01, -1.2399826014408026e+01, -1.2124960608784908e+01, -1.1856771527137033e+01, -1.1594525371724179e+01, -1.1337612269445431e+01, -1.1085518097551031e+01, -1.0837804305192460e+01, -1.0594092926257336e+01, -1.0354055232179574e+01, -1.0117402994660386e+01, -9.8838816568977812e+00, -9.6532649249849332e+00, -9.4253504326923299e+00, -9.1999562289744645e+00, -8.9769179041114668e+00, -8.7560862173209468e+00, -8.5373251222877080e+00, -8.3205101114907762e+00, -8.1055268182049698e+00, -7.8922698284767430e+00, -7.6806416654983130e+00, -7.4705519165212015e+00, -7.2619164783901100e+00, -7.0546569023913719e+00, -6.8486998227236997e+00, -6.6439764557516492e+00, -6.4404221594710993e+00, -6.2379760444330401e+00, -6.0365806288366217e+00, -5.8361815316904240e+00, -5.6367271989099255e+00, -5.4381686580140975e+00, -5.2404592977393536e+00, -5.0435546694321367e+00, -4.8474123075333448e+00, -4.6519915668456937e+00, -4.4572534745922692e+00, -4.2631605955419172e+00, -4.0696769087032161e+00, -3.8767676942807565e+00, -3.6843994297509557e+00, -3.4925396940542712e+00, -3.3011570790203533e+00, -3.1102211072454056e+00, -2.9197021557295608e+00, -2.7295713846583514e+00, -2.5398006707783964e+00, -2.3503625448744949e+00, -2.1612301329048256e+00, -1.9723771003938499e+00, -1.7837775997197194e+00, -1.5954062199652144e+00, -1.4072379390291252e+00, -1.2192480777190431e+00, -1.0314122555671925e+00, -8.4370634812858625e-01, -6.5610644553571928e-01, -4.6858881209649367e-01, -2.8112984673230629e-01, -9.3706044061378571e-02, 9.3706044061378571e-02, 2.8112984673230629e-01, 4.6858881209649367e-01, 6.5610644553571928e-01, 8.4370634812858625e-01, 1.0314122555671925e+00, 1.2192480777190431e+00, 1.4072379390291252e+00, 1.5954062199652144e+00, 1.7837775997197194e+00, 1.9723771003938499e+00, 2.1612301329048256e+00, 2.3503625448744949e+00, 2.5398006707783964e+00, 2.7295713846583514e+00, 2.9197021557295608e+00, 3.1102211072454056e+00, 3.3011570790203533e+00, 3.4925396940542712e+00, 3.6843994297509557e+00, 3.8767676942807565e+00, 4.0696769087032161e+00, 4.2631605955419172e+00, 4.4572534745922692e+00, 4.6519915668456937e+00, 4.8474123075333448e+00, 5.0435546694321367e+00, 5.2404592977393536e+00, 5.4381686580140975e+00, 5.6367271989099255e+00, 5.8361815316904240e+00, 6.0365806288366217e+00, 6.2379760444330401e+00, 6.4404221594710993e+00, 6.6439764557516492e+00, 6.8486998227236997e+00, 7.0546569023913719e+00, 7.2619164783901100e+00, 7.4705519165212015e+00, 7.6806416654983130e+00, 7.8922698284767430e+00, 8.1055268182049698e+00, 8.3205101114907762e+00, 8.5373251222877080e+00, 8.7560862173209468e+00, 8.9769179041114668e+00, 9.1999562289744645e+00, 9.4253504326923299e+00, 9.6532649249849332e+00, 9.8838816568977812e+00, 1.0117402994660386e+01, 1.0354055232179574e+01, 1.0594092926257336e+01, 1.0837804305192460e+01, 1.1085518097551031e+01, 1.1337612269445431e+01, 1.1594525371724179e+01, 1.1856771527137033e+01, 1.2124960608784908e+01, 1.2399826014408026e+01, 1.2682263889584272e+01, 1.2973390218594389e+01, 1.3274626979734647e+01, 1.3587838011990620e+01, 1.3915555363288536e+01, 1.4261383921882931e+01, 1.4630796281434252e+01, 1.5032917422687504e+01, 1.5485456646120181e+01, 1.6034772477060816e+01}, + {-1.6095197175178654e+01, -1.5546562503045239e+01, -1.5094598476696428e+01, -1.4692999498678725e+01, -1.4324076300505626e+01, -1.3978714148861499e+01, -1.3651446561974707e+01, -1.3338672661844436e+01, -1.3037863210821454e+01, -1.2747156437216972e+01, -1.2465131941640982e+01, -1.2190674982552025e+01, -1.1922890417116040e+01, -1.1661045673847648e+01, -1.1404531572900545e+01, -1.1152834582481235e+01, -1.0905516662643253e+01, -1.0662200294603309e+01, -1.0422557146004042e+01, -1.0186299343207718e+01, -9.9531726499989794e+00, -9.7229510648991155e+00, -9.4954324906908987e+00, -9.2704352257718199e+00, -9.0477950934492313e+00, -8.8273630721636813e+00, -8.6090033232019607e+00, -8.3925915368661208e+00, -8.1780135360427444e+00, -7.9651640895243876e+00, -7.7539458975483946e+00, -7.5442687197268468e+00, -7.3360486214748111e+00, -7.1292073196522763e+00, -6.9236716117447346e+00, -6.7193728757570428e+00, -6.5162466302615387e+00, -6.3142321458564812e+00, -6.1132721007540169e+00, -5.9133122744035465e+00, -5.7143012740244483e+00, -5.5161902897161745e+00, -5.3189328744684259e+00, -5.1224847459365774e+00, -4.9268036072990391e+00, -4.7318489848907346e+00, -4.5375820806238156e+00, -4.3439656374738016e+00, -4.1509638165353397e+00, -3.9585420843435810e+00, -3.7666671093205584e+00, -3.5753066663455639e+00, -3.3844295485681095e+00, -3.1940054856848250e+00, -3.0040050679901400e+00, -2.8143996755869578e+00, -2.6251614122095890e+00, -2.4362630431683869e+00, -2.2476779369751214e+00, -2.0593800102511661e+00, -1.8713436755579074e+00, -1.6835437918212028e+00, -1.4959556170497912e+00, -1.3085547630718375e+00, -1.1213171520347327e+00, -9.3421897443120272e-01, -7.4723664843005233e-01, -5.6034678030272367e-01, -3.7352612574750421e-01, -1.8675155192184525e-01, -0.0000000000000000e+00, 1.8675155192184525e-01, 3.7352612574750421e-01, 5.6034678030272367e-01, 7.4723664843005233e-01, 9.3421897443120272e-01, 1.1213171520347327e+00, 1.3085547630718375e+00, 1.4959556170497912e+00, 1.6835437918212028e+00, 1.8713436755579074e+00, 2.0593800102511661e+00, 2.2476779369751214e+00, 2.4362630431683869e+00, 2.6251614122095890e+00, 2.8143996755869578e+00, 3.0040050679901400e+00, 3.1940054856848250e+00, 3.3844295485681095e+00, 3.5753066663455639e+00, 3.7666671093205584e+00, 3.9585420843435810e+00, 4.1509638165353397e+00, 4.3439656374738016e+00, 4.5375820806238156e+00, 4.7318489848907346e+00, 4.9268036072990391e+00, 5.1224847459365774e+00, 5.3189328744684259e+00, 5.5161902897161745e+00, 5.7143012740244483e+00, 5.9133122744035465e+00, 6.1132721007540169e+00, 6.3142321458564812e+00, 6.5162466302615387e+00, 6.7193728757570428e+00, 6.9236716117447346e+00, 7.1292073196522763e+00, 7.3360486214748111e+00, 7.5442687197268468e+00, 7.7539458975483946e+00, 7.9651640895243876e+00, 8.1780135360427444e+00, 8.3925915368661208e+00, 8.6090033232019607e+00, 8.8273630721636813e+00, 9.0477950934492313e+00, 9.2704352257718199e+00, 9.4954324906908987e+00, 9.7229510648991155e+00, 9.9531726499989794e+00, 1.0186299343207718e+01, 1.0422557146004042e+01, 1.0662200294603309e+01, 1.0905516662643253e+01, 1.1152834582481235e+01, 1.1404531572900545e+01, 1.1661045673847648e+01, 1.1922890417116040e+01, 1.2190674982552025e+01, 1.2465131941640982e+01, 1.2747156437216972e+01, 1.3037863210821454e+01, 1.3338672661844436e+01, 1.3651446561974707e+01, 1.3978714148861499e+01, 1.4324076300505626e+01, 1.4692999498678725e+01, 1.5094598476696428e+01, 1.5546562503045239e+01, 1.6095197175178654e+01}, + {-1.6155404542662776e+01, -1.5607445239317764e+01, -1.5156051433346871e+01, -1.4754970030637802e+01, -1.4386531634770627e+01, -1.4041631678205716e+01, -1.3714809742317117e+01, -1.3402468927252324e+01, -1.3102082782981558e+01, -1.2811791588270133e+01, -1.2530176509588186e+01, -1.2256124037680147e+01, -1.1988740023836153e+01, -1.1727292715539413e+01, -1.1471173619903071e+01, -1.1219869790544209e+01, -1.0972943693447091e+01, -1.0730018252630529e+01, -1.0490765527764685e+01, -1.0254897995961329e+01, -1.0022161737889968e+01, -9.7923310409601427e+00, -9.5652040735500723e+00, -9.3405993801743854e+00, -9.1183530139059350e+00, -8.8983161691878188e+00, -8.6803532117101110e+00, -8.4643400264036650e+00, -8.2501626225617972e+00, -8.0377159484935703e+00, -7.8269028782146863e+00, -7.6176333403821728e+00, -7.4098235656060059e+00, -7.2033954328740331e+00, -6.9982758994323033e+00, -6.7943965013094090e+00, -6.5916929139374751e+00, -6.3901045641355303e+00, -6.1895742861825749e+00, -5.9900480158931027e+00, -5.7914745175749145e+00, -5.5938051395422690e+00, -5.3969935945114758e+00, -5.2009957617479348e+00, -5.0057695082847111e+00, -4.8112745269098740e+00, -4.6174721889364516e+00, -4.4243254100357463e+00, -4.2317985276405068e+00, -4.0398571886161809e+00, -3.8484682460617101e+00, -3.6575996642408795e+00, -3.4672204307647947e+00, -3.2773004752487735e+00, -3.0878105937554641e+00, -2.8987223784123866e+00, -2.7100081516581653e+00, -2.5216409046290269e+00, -2.3335942392467470e+00, -2.1458423136124405e+00, -1.9583597903480086e+00, -1.7711217875596625e+00, -1.5841038321261636e+00, -1.3972818150389417e+00, -1.2106319485423875e+00, -1.0241307248408380e+00, -8.3775487615432709e-01, -6.5148133591837221e-01, -4.6528720093408932e-01, -2.7914969428399067e-01, -9.3046128836030015e-02, 9.3046128836030015e-02, 2.7914969428399067e-01, 4.6528720093408932e-01, 6.5148133591837221e-01, 8.3775487615432709e-01, 1.0241307248408380e+00, 1.2106319485423875e+00, 1.3972818150389417e+00, 1.5841038321261636e+00, 1.7711217875596625e+00, 1.9583597903480086e+00, 2.1458423136124405e+00, 2.3335942392467470e+00, 2.5216409046290269e+00, 2.7100081516581653e+00, 2.8987223784123866e+00, 3.0878105937554641e+00, 3.2773004752487735e+00, 3.4672204307647947e+00, 3.6575996642408795e+00, 3.8484682460617101e+00, 4.0398571886161809e+00, 4.2317985276405068e+00, 4.4243254100357463e+00, 4.6174721889364516e+00, 4.8112745269098740e+00, 5.0057695082847111e+00, 5.2009957617479348e+00, 5.3969935945114758e+00, 5.5938051395422690e+00, 5.7914745175749145e+00, 5.9900480158931027e+00, 6.1895742861825749e+00, 6.3901045641355303e+00, 6.5916929139374751e+00, 6.7943965013094090e+00, 6.9982758994323033e+00, 7.2033954328740331e+00, 7.4098235656060059e+00, 7.6176333403821728e+00, 7.8269028782146863e+00, 8.0377159484935703e+00, 8.2501626225617972e+00, 8.4643400264036650e+00, 8.6803532117101110e+00, 8.8983161691878188e+00, 9.1183530139059350e+00, 9.3405993801743854e+00, 9.5652040735500723e+00, 9.7923310409601427e+00, 1.0022161737889968e+01, 1.0254897995961329e+01, 1.0490765527764685e+01, 1.0730018252630529e+01, 1.0972943693447091e+01, 1.1219869790544209e+01, 1.1471173619903071e+01, 1.1727292715539413e+01, 1.1988740023836153e+01, 1.2256124037680147e+01, 1.2530176509588186e+01, 1.2811791588270133e+01, 1.3102082782981558e+01, 1.3402468927252324e+01, 1.3714809742317117e+01, 1.4041631678205716e+01, 1.4386531634770627e+01, 1.4754970030637802e+01, 1.5156051433346871e+01, 1.5607445239317764e+01, 1.6155404542662776e+01}, + {-1.6215396898128663e+01, -1.5668107263835802e+01, -1.5217278780317361e+01, -1.4816710438579342e+01, -1.4448752556717958e+01, -1.4104310652531494e+01, -1.3777930322527094e+01, -1.3466018613382040e+01, -1.3166051840377859e+01, -1.2876172316156813e+01, -1.2594962760214381e+01, -1.2321310885302282e+01, -1.2054323528364668e+01, -1.1793269748698537e+01, -1.1537541734199792e+01, -1.1286627118459547e+01, -1.1040088868523824e+01, -1.0797550346784112e+01, -1.0558684000851162e+01, -1.0323202654766870e+01, -1.0090852702474850e+01, -9.8614087168236804e+00, -9.6346691284611641e+00, -9.4104527247850562e+00, -9.1885957854652229e+00, -8.9689497178220225e+00, -8.7513790888474610e+00, -8.5357599750069966e+00, -8.3219785688987216e+00, -8.1099299952250909e+00, -7.8995172986236630e+00, -7.6906505735952022e+00, -7.4832462126880364e+00, -7.2772262536958907e+00, -7.0725178102281943e+00, -6.8690525728554430e+00, -6.6667663702937121e+00, -6.4655987819036467e+00, -6.2654927942392939e+00, -6.0663944955663265e+00, -5.8682528032352996e+00, -5.6710192195879507e+00, -5.4746476127280044e+00, -5.2790940190292117e+00, -5.0843164647041039e+00, -4.8902748041336244e+00, -4.6969305729742112e+00, -4.5042468543255083e+00, -4.3121881564674842e+00, -4.1207203008672968e+00, -3.9298103193193850e+00, -3.7394263592217327e+00, -3.5495375961107607e+00, -3.3601141526799938e+00, -3.1711270235961577e+00, -2.9825480055027773e+00, -2.7943496316674543e+00, -2.6065051107863355e+00, -2.4189882695090272e+00, -2.2317734982904458e+00, -2.0448357002136932e+00, -1.8581502424607397e+00, -1.6716929101361060e+00, -1.4854398621734262e+00, -1.2993675890761167e+00, -1.1134528722618340e+00, -9.2767274479622841e-01, -7.4200445331498865e-01, -5.5642542094454162e-01, -3.7091321104119962e-01, -1.8544549157619233e-01, -0.0000000000000000e+00, 1.8544549157619233e-01, 3.7091321104119962e-01, 5.5642542094454162e-01, 7.4200445331498865e-01, 9.2767274479622841e-01, 1.1134528722618340e+00, 1.2993675890761167e+00, 1.4854398621734262e+00, 1.6716929101361060e+00, 1.8581502424607397e+00, 2.0448357002136932e+00, 2.2317734982904458e+00, 2.4189882695090272e+00, 2.6065051107863355e+00, 2.7943496316674543e+00, 2.9825480055027773e+00, 3.1711270235961577e+00, 3.3601141526799938e+00, 3.5495375961107607e+00, 3.7394263592217327e+00, 3.9298103193193850e+00, 4.1207203008672968e+00, 4.3121881564674842e+00, 4.5042468543255083e+00, 4.6969305729742112e+00, 4.8902748041336244e+00, 5.0843164647041039e+00, 5.2790940190292117e+00, 5.4746476127280044e+00, 5.6710192195879507e+00, 5.8682528032352996e+00, 6.0663944955663265e+00, 6.2654927942392939e+00, 6.4655987819036467e+00, 6.6667663702937121e+00, 6.8690525728554430e+00, 7.0725178102281943e+00, 7.2772262536958907e+00, 7.4832462126880364e+00, 7.6906505735952022e+00, 7.8995172986236630e+00, 8.1099299952250909e+00, 8.3219785688987216e+00, 8.5357599750069966e+00, 8.7513790888474610e+00, 8.9689497178220225e+00, 9.1885957854652229e+00, 9.4104527247850562e+00, 9.6346691284611641e+00, 9.8614087168236804e+00, 1.0090852702474850e+01, 1.0323202654766870e+01, 1.0558684000851162e+01, 1.0797550346784112e+01, 1.1040088868523824e+01, 1.1286627118459547e+01, 1.1537541734199792e+01, 1.1793269748698537e+01, 1.2054323528364668e+01, 1.2321310885302282e+01, 1.2594962760214381e+01, 1.2876172316156813e+01, 1.3166051840377859e+01, 1.3466018613382040e+01, 1.3777930322527094e+01, 1.4104310652531494e+01, 1.4448752556717958e+01, 1.4816710438579342e+01, 1.5217278780317361e+01, 1.5668107263835802e+01, 1.6215396898128663e+01}, + {-1.6275176519333314e+01, -1.5728550942602004e+01, -1.5278282960589307e+01, -1.4878223237370916e+01, -1.4510741650331246e+01, -1.4166753723357122e+01, -1.3840811020790602e+01, -1.3529324504696065e+01, -1.3229773233699543e+01, -1.2940301538002238e+01, -1.2659493677496206e+01, -1.2386238576832154e+01, -1.2119644050283457e+01, -1.1858979961933818e+01, -1.1603639174400232e+01, -1.1353109895917042e+01, -1.1106955589822139e+01, -1.0864800052544570e+01, -1.0626316115639773e+01, -1.0391216946349248e+01, -1.0159249248367633e+01, -9.9301878766205718e+00, -9.7038315207870216e+00, -9.4799992080020576e+00, -9.2585274414535341e+00, -9.0392678383049354e+00, -8.8220851638421109e+00, -8.6068556830666605e+00, -8.3934657688780785e+00, -8.1818107193508762e+00, -7.9717937466932813e+00, -7.7633251081577797e+00, -7.5563213550879356e+00, -7.3507046808793666e+00, -7.1464023522306821e+00, -6.9433462109007360e+00, -6.7414722354477217e+00, -6.5407201542348838e+00, -6.3410331024462083e+00, -6.1423573170383490e+00, -5.9446418645201566e+00, -5.7478383972427567e+00, -5.5519009345358734e+00, -5.3567856655668686e+00, -5.1624507712492340e+00, -4.9688562629036443e+00, -4.7759638356907441e+00, -4.5837367351012581e+00, -4.3921396350144111e+00, -4.2011385260270222e+00, -4.0107006129187415e+00, -3.8207942202581950e+00, -3.6313887052743148e+00, -3.4424543772197556e+00, -3.2539624225418282e+00, -3.0658848352527657e+00, -2.8781943519573039e+00, -2.6908643910529264e+00, -2.5038689956679221e+00, -2.3171827799457509e+00, -2.1307808783218642e+00, -1.9446388974719979e+00, -1.7587328706394580e+00, -1.5730392140737939e+00, -1.3875346853347825e+00, -1.2021963432343084e+00, -1.0170015092047828e+00, -8.3192772989651476e-01, -6.4695274081809961e-01, -4.6205443084366904e-01, -2.7721080741886533e-01, -9.2399962303806829e-02, 9.2399962303806829e-02, 2.7721080741886533e-01, 4.6205443084366904e-01, 6.4695274081809961e-01, 8.3192772989651476e-01, 1.0170015092047828e+00, 1.2021963432343084e+00, 1.3875346853347825e+00, 1.5730392140737939e+00, 1.7587328706394580e+00, 1.9446388974719979e+00, 2.1307808783218642e+00, 2.3171827799457509e+00, 2.5038689956679221e+00, 2.6908643910529264e+00, 2.8781943519573039e+00, 3.0658848352527657e+00, 3.2539624225418282e+00, 3.4424543772197556e+00, 3.6313887052743148e+00, 3.8207942202581950e+00, 4.0107006129187415e+00, 4.2011385260270222e+00, 4.3921396350144111e+00, 4.5837367351012581e+00, 4.7759638356907441e+00, 4.9688562629036443e+00, 5.1624507712492340e+00, 5.3567856655668686e+00, 5.5519009345358734e+00, 5.7478383972427567e+00, 5.9446418645201566e+00, 6.1423573170383490e+00, 6.3410331024462083e+00, 6.5407201542348838e+00, 6.7414722354477217e+00, 6.9433462109007360e+00, 7.1464023522306821e+00, 7.3507046808793666e+00, 7.5563213550879356e+00, 7.7633251081577797e+00, 7.9717937466932813e+00, 8.1818107193508762e+00, 8.3934657688780785e+00, 8.6068556830666605e+00, 8.8220851638421109e+00, 9.0392678383049354e+00, 9.2585274414535341e+00, 9.4799992080020576e+00, 9.7038315207870216e+00, 9.9301878766205718e+00, 1.0159249248367633e+01, 1.0391216946349248e+01, 1.0626316115639773e+01, 1.0864800052544570e+01, 1.1106955589822139e+01, 1.1353109895917042e+01, 1.1603639174400232e+01, 1.1858979961933818e+01, 1.2119644050283457e+01, 1.2386238576832154e+01, 1.2659493677496206e+01, 1.2940301538002238e+01, 1.3229773233699543e+01, 1.3529324504696065e+01, 1.3840811020790602e+01, 1.4166753723357122e+01, 1.4510741650331246e+01, 1.4878223237370916e+01, 1.5278282960589307e+01, 1.5728550942602004e+01, 1.6275176519333314e+01}, + {-1.6334745644175054e+01, -1.5788778599783345e+01, -1.5339066373560392e+01, -1.4939510896644496e+01, -1.4572501452752805e+01, -1.4228963493774261e+01, -1.3903454505286284e+01, -1.3592389334062910e+01, -1.3293249760441302e+01, -1.3004182116116599e+01, -1.2723772188949674e+01, -1.2450910105547806e+01, -1.2184704649330305e+01, -1.1924426482264677e+01, -1.1669469135738963e+01, -1.1419321387402469e+01, -1.1173547192211004e+01, -1.0931770776387262e+01, -1.0693665351523348e+01, -1.0458944424415622e+01, -1.0227355005071125e+01, -9.9986722272145627e+00, -9.7726950364017036e+00, -9.5492426964438799e+00, -9.3281519310537870e+00, -9.1092745642913098e+00, -8.8924755568174323e+00, -8.6776313592631116e+00, -8.4646285219201989e+00, -8.2533625133112452e+00, -8.0437367102645929e+00, -7.8356615297967140e+00, -7.6290536790115411e+00, -7.4238355038151660e+00, -7.2199344208383769e+00, -7.0172824197970574e+00, -6.8158156257772653e+00, -6.6154739127391755e+00, -6.4162005609911104e+00, -6.2179419525665987e+00, -6.0206472994014675e+00, -5.8242683999987914e+00, -5.6287594209215639e+00, -5.4340766999932706e+00, -5.2401785685362707e+00, -5.0470251903539998e+00, -4.8545784154787137e+00, -4.6628016469727172e+00, -4.4716597192961824e+00, -4.2811187869459504e+00, -4.0911462222326103e+00, -3.9017105212024688e+00, -3.7127812168303533e+00, -3.5243287987118928e+00, -3.3363246385723251e+00, -3.1487409209853521e+00, -2.9615505787617051e+00, -2.7747272325244832e+00, -2.5882451340382215e+00, -2.4020791129020052e+00, -2.2162045262547485e+00, -2.0305972111736730e+00, -1.8452334394757037e+00, -1.6600898746564745e+00, -1.4751435307233549e+00, -1.2903717326977489e+00, -1.1057520785781945e+00, -9.2126240256979075e-01, -7.3688073939740739e-01, -5.5258528953022001e-01, -3.6835438515345242e-01, -1.8416645673001250e-01, -0.0000000000000000e+00, 1.8416645673001250e-01, 3.6835438515345242e-01, 5.5258528953022001e-01, 7.3688073939740739e-01, 9.2126240256979075e-01, 1.1057520785781945e+00, 1.2903717326977489e+00, 1.4751435307233549e+00, 1.6600898746564745e+00, 1.8452334394757037e+00, 2.0305972111736730e+00, 2.2162045262547485e+00, 2.4020791129020052e+00, 2.5882451340382215e+00, 2.7747272325244832e+00, 2.9615505787617051e+00, 3.1487409209853521e+00, 3.3363246385723251e+00, 3.5243287987118928e+00, 3.7127812168303533e+00, 3.9017105212024688e+00, 4.0911462222326103e+00, 4.2811187869459504e+00, 4.4716597192961824e+00, 4.6628016469727172e+00, 4.8545784154787137e+00, 5.0470251903539998e+00, 5.2401785685362707e+00, 5.4340766999932706e+00, 5.6287594209215639e+00, 5.8242683999987914e+00, 6.0206472994014675e+00, 6.2179419525665987e+00, 6.4162005609911104e+00, 6.6154739127391755e+00, 6.8158156257772653e+00, 7.0172824197970574e+00, 7.2199344208383769e+00, 7.4238355038151660e+00, 7.6290536790115411e+00, 7.8356615297967140e+00, 8.0437367102645929e+00, 8.2533625133112452e+00, 8.4646285219201989e+00, 8.6776313592631116e+00, 8.8924755568174323e+00, 9.1092745642913098e+00, 9.3281519310537870e+00, 9.5492426964438799e+00, 9.7726950364017036e+00, 9.9986722272145627e+00, 1.0227355005071125e+01, 1.0458944424415622e+01, 1.0693665351523348e+01, 1.0931770776387262e+01, 1.1173547192211004e+01, 1.1419321387402469e+01, 1.1669469135738963e+01, 1.1924426482264677e+01, 1.2184704649330305e+01, 1.2450910105547806e+01, 1.2723772188949674e+01, 1.3004182116116599e+01, 1.3293249760441302e+01, 1.3592389334062910e+01, 1.3903454505286284e+01, 1.4228963493774261e+01, 1.4572501452752805e+01, 1.4939510896644496e+01, 1.5339066373560392e+01, 1.5788778599783345e+01, 1.6334745644175054e+01}, + {-1.6394106471662131e+01, -1.5848792518737463e+01, -1.5399631376122628e+01, -1.5000575841923927e+01, -1.4634034455459645e+01, -1.4290942519672281e+01, -1.3965863395458523e+01, -1.3655215784079445e+01, -1.3356484166275854e+01, -1.3067816859418864e+01, -1.2787801167106462e+01, -1.2515328408121787e+01, -1.2249508326984577e+01, -1.1989612376763933e+01, -1.1735034751777302e+01, -1.1485264793960161e+01, -1.1239866945305195e+01, -1.0998465857673063e+01, -1.0760735118869476e+01, -1.0526388571683613e+01, -1.0295173529077774e+01, -1.0066865400378582e+01, -9.8412633839451633e+00, -9.6181869772854895e+00, -9.3974731217264083e+00, -9.1789738453613765e+00, -8.9625543013934692e+00, -8.7480911232640413e+00, -8.5354710358385653e+00, -8.3245896752567052e+00, -8.1153505801125796e+00, -7.9076643242985316e+00, -7.7014477677473518e+00, -7.4966234058915848e+00, -7.2931188022489746e+00, -7.0908660913775821e+00, -6.8898015416986063e+00, -6.6898651694904157e+00, -6.4910003968128018e+00, -6.2931537473009849e+00, -6.0962745747319902e+00, -5.9003148200559909e+00, -5.7052287932366612e+00, -5.5109729767842897e+00, -5.3175058483147666e+00, -5.1247877198432272e+00, -4.9327805918366323e+00, -4.7414480203154818e+00, -4.5507549955198634e+00, -4.3606678308461584e+00, -4.1711540609235342e+00, -3.9821823478385219e+00, -3.7937223946353149e+00, -3.6057448653220203e+00, -3.4182213107015205e+00, -3.2311240994220300e+00, -3.0444263537086158e+00, -2.8581018892943821e+00, -2.6721251591199171e+00, -2.4864712004130762e+00, -2.3011155847990197e+00, -2.1160343711234311e+00, -1.9312040607006651e+00, -1.7466015547236411e+00, -1.5622041135941906e+00, -1.3779893179515634e+00, -1.1939350311932622e+00, -1.0100193632965979e+00, -8.2622063576151961e-01, -6.4251734750563116e-01, -4.5888814155095509e-01, -2.7531177234913912e-01, -9.1767073597484664e-02, 9.1767073597484664e-02, 2.7531177234913912e-01, 4.5888814155095509e-01, 6.4251734750563116e-01, 8.2622063576151961e-01, 1.0100193632965979e+00, 1.1939350311932622e+00, 1.3779893179515634e+00, 1.5622041135941906e+00, 1.7466015547236411e+00, 1.9312040607006651e+00, 2.1160343711234311e+00, 2.3011155847990197e+00, 2.4864712004130762e+00, 2.6721251591199171e+00, 2.8581018892943821e+00, 3.0444263537086158e+00, 3.2311240994220300e+00, 3.4182213107015205e+00, 3.6057448653220203e+00, 3.7937223946353149e+00, 3.9821823478385219e+00, 4.1711540609235342e+00, 4.3606678308461584e+00, 4.5507549955198634e+00, 4.7414480203154818e+00, 4.9327805918366323e+00, 5.1247877198432272e+00, 5.3175058483147666e+00, 5.5109729767842897e+00, 5.7052287932366612e+00, 5.9003148200559909e+00, 6.0962745747319902e+00, 6.2931537473009849e+00, 6.4910003968128018e+00, 6.6898651694904157e+00, 6.8898015416986063e+00, 7.0908660913775821e+00, 7.2931188022489746e+00, 7.4966234058915848e+00, 7.7014477677473518e+00, 7.9076643242985316e+00, 8.1153505801125796e+00, 8.3245896752567052e+00, 8.5354710358385653e+00, 8.7480911232640413e+00, 8.9625543013934692e+00, 9.1789738453613765e+00, 9.3974731217264083e+00, 9.6181869772854895e+00, 9.8412633839451633e+00, 1.0066865400378582e+01, 1.0295173529077774e+01, 1.0526388571683613e+01, 1.0760735118869476e+01, 1.0998465857673063e+01, 1.1239866945305195e+01, 1.1485264793960161e+01, 1.1735034751777302e+01, 1.1989612376763933e+01, 1.2249508326984577e+01, 1.2515328408121787e+01, 1.2787801167106462e+01, 1.3067816859418864e+01, 1.3356484166275854e+01, 1.3655215784079445e+01, 1.3965863395458523e+01, 1.4290942519672281e+01, 1.4634034455459645e+01, 1.5000575841923927e+01, 1.5399631376122628e+01, 1.5848792518737463e+01, 1.6394106471662131e+01}, + {-1.6453261162851238e+01, -1.5908594943006905e+01, -1.5459980283706434e+01, -1.5061420455716602e+01, -1.4695343105401838e+01, -1.4352693310923225e+01, -1.4028040263249208e+01, -1.3717806488350135e+01, -1.3419479146381439e+01, -1.3131208524813520e+01, -1.2851583430941135e+01, -1.2579496366100177e+01, -1.2314058027999442e+01, -1.2054540654144855e+01, -1.1800339096046955e+01, -1.1550943254895040e+01, -1.1305918055227691e+01, -1.1064888570473238e+01, -1.0827528760910019e+01, -1.0593552801837916e+01, -1.0362708305895856e+01, -1.0134770954893138e+01, -9.9095401969966606e+00, -9.6868357605097319e+00, -9.4664948015418702e+00, -9.2483695494377951e+00, -9.0323253471918115e+00, -8.8182390083208837e+00, -8.6059974295318415e+00, -8.3954964118396482e+00, -8.1866396528418637e+00, -7.9793378805138149e+00, -7.7735081047843622e+00, -7.5690729677310218e+00, -7.3659601768199030e+00, -7.1641020084474496e+00, -6.9634348712930993e+00, -6.7638989207955804e+00, -6.5654377175196297e+00, -6.3679979233591490e+00, -6.1715290304849564e+00, -5.9759831187344989e+00, -5.7813146377916294e+00, -5.5874802110437694e+00, -5.3944384584526848e+00, -5.2021498361504346e+00, -5.0105764907872219e+00, -4.8196821269235706e+00, -4.6294318859840997e+00, -4.4397922354810584e+00, -4.2507308673785191e+00, -4.0622166046072063e+00, -3.8742193148591682e+00, -3.6867098308940789e+00, -3.4996598766773372e+00, -3.3130419987465562e+00, -3.1268295022692216e+00, -2.9409963913117498e+00, -2.7555173128901118e+00, -2.5703675044157226e+00, -2.3855227441881959e+00, -2.2009593046196674e+00, -2.0166539079042916e+00, -1.8325836838717240e+00, -1.6487261297853975e+00, -1.4650590718655645e+00, -1.2815606283337120e+00, -1.0982091737893589e+00, -9.1498330474263811e-01, -7.3186180613665275e-01, -5.4882361870252716e-01, -3.6584780699750397e-01, -1.8291352798246857e-01, -0.0000000000000000e+00, 1.8291352798246857e-01, 3.6584780699750397e-01, 5.4882361870252716e-01, 7.3186180613665275e-01, 9.1498330474263811e-01, 1.0982091737893589e+00, 1.2815606283337120e+00, 1.4650590718655645e+00, 1.6487261297853975e+00, 1.8325836838717240e+00, 2.0166539079042916e+00, 2.2009593046196674e+00, 2.3855227441881959e+00, 2.5703675044157226e+00, 2.7555173128901118e+00, 2.9409963913117498e+00, 3.1268295022692216e+00, 3.3130419987465562e+00, 3.4996598766773372e+00, 3.6867098308940789e+00, 3.8742193148591682e+00, 4.0622166046072063e+00, 4.2507308673785191e+00, 4.4397922354810584e+00, 4.6294318859840997e+00, 4.8196821269235706e+00, 5.0105764907872219e+00, 5.2021498361504346e+00, 5.3944384584526848e+00, 5.5874802110437694e+00, 5.7813146377916294e+00, 5.9759831187344989e+00, 6.1715290304849564e+00, 6.3679979233591490e+00, 6.5654377175196297e+00, 6.7638989207955804e+00, 6.9634348712930993e+00, 7.1641020084474496e+00, 7.3659601768199030e+00, 7.5690729677310218e+00, 7.7735081047843622e+00, 7.9793378805138149e+00, 8.1866396528418637e+00, 8.3954964118396482e+00, 8.6059974295318415e+00, 8.8182390083208837e+00, 9.0323253471918115e+00, 9.2483695494377951e+00, 9.4664948015418702e+00, 9.6868357605097319e+00, 9.9095401969966606e+00, 1.0134770954893138e+01, 1.0362708305895856e+01, 1.0593552801837916e+01, 1.0827528760910019e+01, 1.1064888570473238e+01, 1.1305918055227691e+01, 1.1550943254895040e+01, 1.1800339096046955e+01, 1.2054540654144855e+01, 1.2314058027999442e+01, 1.2579496366100177e+01, 1.2851583430941135e+01, 1.3131208524813520e+01, 1.3419479146381439e+01, 1.3717806488350135e+01, 1.4028040263249208e+01, 1.4352693310923225e+01, 1.4695343105401838e+01, 1.5061420455716602e+01, 1.5459980283706434e+01, 1.5908594943006905e+01, 1.6453261162851238e+01}, + {-1.6512211841757207e+01, -1.5968188077282482e+01, -1.5520115371292015e+01, -1.5122047078570679e+01, -1.4756429806104775e+01, -1.4414218332528858e+01, -1.4089987634289908e+01, -1.3780164032724846e+01, -1.3482237346726031e+01, -1.3194359818522189e+01, -1.2915121747251227e+01, -1.2643416807332409e+01, -1.2378356641882881e+01, -1.2119214266294843e+01, -1.1865385183637930e+01, -1.1616359849416588e+01, -1.1371703666311570e+01, -1.1131042125331231e+01, -1.0894049555564962e+01, -1.0660440461418377e+01, -1.0429962752004187e+01, -1.0202392378570206e+01, -9.9775290361704698e+00, -9.7551926810776539e+00, -9.5352206814286085e+00, -9.3174654651143189e+00, -9.1017925622483045e+00, -8.8880789637690558e+00, -8.6762117355753663e+00, -8.4660868409009815e+00, -8.2576081336726084e+00, -8.0506864932467330e+00, -7.8452390768098423e+00, -7.6411886703008571e+00, -7.4384631222974562e+00, -7.2369948481366277e+00, -7.0367203937895502e+00, -6.8375800508126918e+00, -6.6395175151495431e+00, -6.4424795837354694e+00, -6.2464158838193349e+00, -6.0512786307039113e+00, -5.8570224102572590e+00, -5.6636039830858733e+00, -5.4709821077089327e+00, -5.2791173804478735e+00, -5.0879720900604992e+00, -4.8975100854141935e+00, -4.7076966547174930e+00, -4.5184984150200371e+00, -4.3298832108534802e+00, -4.1418200210249481e+00, -3.9542788726937901e+00, -3.7672307619648824e+00, -3.5806475803201039e+00, -3.3945020462860152e+00, -3.2087676418019360e+00, -3.0234185528101056e+00, -2.8384296136395832e+00, -2.6537762547990797e+00, -2.4694344538319206e+00, -2.2853806889194859e+00, -2.1015918949484664e+00, -1.9180454217825835e+00, -1.7347189945015418e+00, -1.5515906753892701e+00, -1.3686388274702970e+00, -1.1858420794076876e+00, -1.0031792915885485e+00, -8.2062952323391314e-01, -6.3817200037899757e-01, -4.5578608457752007e-01, -2.7345124219010619e-01, -9.1147014121871414e-02, 9.1147014121871414e-02, 2.7345124219010619e-01, 4.5578608457752007e-01, 6.3817200037899757e-01, 8.2062952323391314e-01, 1.0031792915885485e+00, 1.1858420794076876e+00, 1.3686388274702970e+00, 1.5515906753892701e+00, 1.7347189945015418e+00, 1.9180454217825835e+00, 2.1015918949484664e+00, 2.2853806889194859e+00, 2.4694344538319206e+00, 2.6537762547990797e+00, 2.8384296136395832e+00, 3.0234185528101056e+00, 3.2087676418019360e+00, 3.3945020462860152e+00, 3.5806475803201039e+00, 3.7672307619648824e+00, 3.9542788726937901e+00, 4.1418200210249481e+00, 4.3298832108534802e+00, 4.5184984150200371e+00, 4.7076966547174930e+00, 4.8975100854141935e+00, 5.0879720900604992e+00, 5.2791173804478735e+00, 5.4709821077089327e+00, 5.6636039830858733e+00, 5.8570224102572590e+00, 6.0512786307039113e+00, 6.2464158838193349e+00, 6.4424795837354694e+00, 6.6395175151495431e+00, 6.8375800508126918e+00, 7.0367203937895502e+00, 7.2369948481366277e+00, 7.4384631222974562e+00, 7.6411886703008571e+00, 7.8452390768098423e+00, 8.0506864932467330e+00, 8.2576081336726084e+00, 8.4660868409009815e+00, 8.6762117355753663e+00, 8.8880789637690558e+00, 9.1017925622483045e+00, 9.3174654651143189e+00, 9.5352206814286085e+00, 9.7551926810776539e+00, 9.9775290361704698e+00, 1.0202392378570206e+01, 1.0429962752004187e+01, 1.0660440461418377e+01, 1.0894049555564962e+01, 1.1131042125331231e+01, 1.1371703666311570e+01, 1.1616359849416588e+01, 1.1865385183637930e+01, 1.2119214266294843e+01, 1.2378356641882881e+01, 1.2643416807332409e+01, 1.2915121747251227e+01, 1.3194359818522189e+01, 1.3482237346726031e+01, 1.3780164032724846e+01, 1.4089987634289908e+01, 1.4414218332528858e+01, 1.4756429806104775e+01, 1.5122047078570679e+01, 1.5520115371292015e+01, 1.5968188077282482e+01, 1.6512211841757207e+01}, + {-1.6570960596234816e+01, -1.6027574088336884e+01, -1.5580038874389315e+01, -1.5182458010099252e+01, -1.4817296918736639e+01, -1.4475520005731354e+01, -1.4151707989055947e+01, -1.3842290956496822e+01, -1.3544761365310002e+01, -1.3257273397371849e+01, -1.2978418831992128e+01, -1.2707092507353986e+01, -1.2442407004329516e+01, -1.2183636109757821e+01, -1.1930175972733117e+01, -1.1681517598227204e+01, -1.1437226862743914e+01, -1.1196929670964046e+01, -1.0960300717203255e+01, -1.0727054831642461e+01, -1.0496940216738453e+01, -1.0269733090205794e+01, -1.0045233391137220e+01, -9.8232613010212955e+00, -9.6036543973400637e+00, -9.3862653039000534e+00, -9.1709597353376804e+00, -8.9576148574362815e+00, -8.7461179027166409e+00, -8.5363649940564841e+00, -8.3282601391216602e+00, -8.1217143660350786e+00, -7.9166449765926146e+00, -7.7129748979045933e+00, -7.5106321169206671e+00, -7.3095491851216430e+00, -7.1096627829092727e+00, -6.9109133350249667e+00, -6.7132446697794288e+00, -6.5166037160520816e+00, -6.3209402329793747e+00, -6.1262065680386195e+00, -5.9323574398835213e+00, -5.7393497428256754e+00, -5.5471423703043676e+00, -5.3556960550616148e+00, -5.1649732240539885e+00, -4.9749378663979575e+00, -4.7855554128699298e+00, -4.5967926256728040e+00, -4.4086174973432648e+00, -4.2209991578129564e+00, -4.0339077887557737e+00, -3.8473145444559340e+00, -3.6611914785198536e+00, -3.4755114758312047e+00, -3.2902481892147279e+00, -3.1053759803318370e+00, -2.9208698643810656e+00, -2.7367054582199937e+00, -2.5528589315633066e+00, -2.3693069609448871e+00, -2.1860266861608908e+00, -2.0029956689361597e+00, -1.8201918535785517e+00, -1.6375935294051731e+00, -1.4551792947414237e+00, -1.2729280223085093e+00, -1.0908188258278129e+00, -9.0883102768153856e-01, -7.2694412747841530e-01, -5.4513777138121788e-01, -3.6339172205944553e-01, -1.8168582913588810e-01, -0.0000000000000000e+00, 1.8168582913588810e-01, 3.6339172205944553e-01, 5.4513777138121788e-01, 7.2694412747841530e-01, 9.0883102768153856e-01, 1.0908188258278129e+00, 1.2729280223085093e+00, 1.4551792947414237e+00, 1.6375935294051731e+00, 1.8201918535785517e+00, 2.0029956689361597e+00, 2.1860266861608908e+00, 2.3693069609448871e+00, 2.5528589315633066e+00, 2.7367054582199937e+00, 2.9208698643810656e+00, 3.1053759803318370e+00, 3.2902481892147279e+00, 3.4755114758312047e+00, 3.6611914785198536e+00, 3.8473145444559340e+00, 4.0339077887557737e+00, 4.2209991578129564e+00, 4.4086174973432648e+00, 4.5967926256728040e+00, 4.7855554128699298e+00, 4.9749378663979575e+00, 5.1649732240539885e+00, 5.3556960550616148e+00, 5.5471423703043676e+00, 5.7393497428256754e+00, 5.9323574398835213e+00, 6.1262065680386195e+00, 6.3209402329793747e+00, 6.5166037160520816e+00, 6.7132446697794288e+00, 6.9109133350249667e+00, 7.1096627829092727e+00, 7.3095491851216430e+00, 7.5106321169206671e+00, 7.7129748979045933e+00, 7.9166449765926146e+00, 8.1217143660350786e+00, 8.3282601391216602e+00, 8.5363649940564841e+00, 8.7461179027166409e+00, 8.9576148574362815e+00, 9.1709597353376804e+00, 9.3862653039000534e+00, 9.6036543973400637e+00, 9.8232613010212955e+00, 1.0045233391137220e+01, 1.0269733090205794e+01, 1.0496940216738453e+01, 1.0727054831642461e+01, 1.0960300717203255e+01, 1.1196929670964046e+01, 1.1437226862743914e+01, 1.1681517598227204e+01, 1.1930175972733117e+01, 1.2183636109757821e+01, 1.2442407004329516e+01, 1.2707092507353986e+01, 1.2978418831992128e+01, 1.3257273397371849e+01, 1.3544761365310002e+01, 1.3842290956496822e+01, 1.4151707989055947e+01, 1.4475520005731354e+01, 1.4817296918736639e+01, 1.5182458010099252e+01, 1.5580038874389315e+01, 1.6027574088336884e+01, 1.6570960596234816e+01}, + {-1.6629509478833860e+01, -1.6086755105929722e+01, -1.5639752989987683e+01, -1.5242655509972604e+01, -1.4877946763142496e+01, -1.4536600709088953e+01, -1.4213203763983850e+01, -1.3904189753562465e+01, -1.3607053753368865e+01, -1.3319951870041416e+01, -1.3041477351568494e+01, -1.2770526190723876e+01, -1.2506211898605262e+01, -1.2247809027167504e+01, -1.1994714366091593e+01, -1.1746419465057167e+01, -1.1502490670154140e+01, -1.1262554295905716e+01, -1.1026285398343321e+01, -1.0793399130164836e+01, -1.0563643984112028e+01, -1.0336796441464246e+01, -1.0112656682574075e+01, -9.8910451114622759e+00, -9.6717995123443519e+00, -9.4547727023830390e+00, -9.2398305782140078e+00, -9.0268504779630501e+00, -8.8157197982791242e+00, -8.6063348191874436e+00, -8.3985996995836860e+00, -8.1924256138258222e+00, -7.9877300057571530e+00, -7.7844359410588435e+00, -7.5824715424057798e+00, -7.3817694947224117e+00, -7.1822666100804051e+00, -6.9839034435780709e+00, -6.7866239529910715e+00, -6.5903751961596155e+00, -6.3951070610365948e+00, -6.2007720241079047e+00, -6.0073249335450427e+00, -5.8147228139876921e+00, -5.6229246903015975e+00, -5.4318914280313058e+00, -5.2415855885816516e+00, -5.0519712974268067e+00, -4.8630141238699967e+00, -4.6746809710674029e+00, -4.4869399751921195e+00, -4.2997604127527840e+00, -4.1131126152005661e+00, -3.9269678900605394e+00, -3.7412984479117779e+00, -3.5560773346168779e+00, -3.3712783682677476e+00, -3.1868760803720186e+00, -3.0028456608544345e+00, -2.8191629064911972e+00, -2.6358041724333074e+00, -2.4527463265082488e+00, -2.2699667060184630e+00, -2.0874430767805627e+00, -1.9051535941715365e+00, -1.7230767659677173e+00, -1.5411914167793415e+00, -1.3594766538983880e+00, -1.1779118343903046e+00, -9.9647653327140173e-01, -8.1515051262328730e-01, -6.3391369150388599e-01, -4.5274611652143021e-01, -2.7162793294346238e-01, -9.0539356217393022e-02, 9.0539356217393022e-02, 2.7162793294346238e-01, 4.5274611652143021e-01, 6.3391369150388599e-01, 8.1515051262328730e-01, 9.9647653327140173e-01, 1.1779118343903046e+00, 1.3594766538983880e+00, 1.5411914167793415e+00, 1.7230767659677173e+00, 1.9051535941715365e+00, 2.0874430767805627e+00, 2.2699667060184630e+00, 2.4527463265082488e+00, 2.6358041724333074e+00, 2.8191629064911972e+00, 3.0028456608544345e+00, 3.1868760803720186e+00, 3.3712783682677476e+00, 3.5560773346168779e+00, 3.7412984479117779e+00, 3.9269678900605394e+00, 4.1131126152005661e+00, 4.2997604127527840e+00, 4.4869399751921195e+00, 4.6746809710674029e+00, 4.8630141238699967e+00, 5.0519712974268067e+00, 5.2415855885816516e+00, 5.4318914280313058e+00, 5.6229246903015975e+00, 5.8147228139876921e+00, 6.0073249335450427e+00, 6.2007720241079047e+00, 6.3951070610365948e+00, 6.5903751961596155e+00, 6.7866239529910715e+00, 6.9839034435780709e+00, 7.1822666100804051e+00, 7.3817694947224117e+00, 7.5824715424057798e+00, 7.7844359410588435e+00, 7.9877300057571530e+00, 8.1924256138258222e+00, 8.3985996995836860e+00, 8.6063348191874436e+00, 8.8157197982791242e+00, 9.0268504779630501e+00, 9.2398305782140078e+00, 9.4547727023830390e+00, 9.6717995123443519e+00, 9.8910451114622759e+00, 1.0112656682574075e+01, 1.0336796441464246e+01, 1.0563643984112028e+01, 1.0793399130164836e+01, 1.1026285398343321e+01, 1.1262554295905716e+01, 1.1502490670154140e+01, 1.1746419465057167e+01, 1.1994714366091593e+01, 1.2247809027167504e+01, 1.2506211898605262e+01, 1.2770526190723876e+01, 1.3041477351568494e+01, 1.3319951870041416e+01, 1.3607053753368865e+01, 1.3904189753562465e+01, 1.4213203763983850e+01, 1.4536600709088953e+01, 1.4877946763142496e+01, 1.5242655509972604e+01, 1.5639752989987683e+01, 1.6086755105929722e+01, 1.6629509478833860e+01}, + {-1.6687860507628386e+01, -1.6145733223684985e+01, -1.5699259877476434e+01, -1.5302641798879872e+01, -1.4938381618846188e+01, -1.4597462779517947e+01, -1.4274477352553639e+01, -1.3965862873544308e+01, -1.3669117016537621e+01, -1.3382397798268309e+01, -1.3104299924083964e+01, -1.2833720532318454e+01, -1.2569774056886668e+01, -1.2311735808633442e+01, -1.2059003212482786e+01, -1.1811068358148432e+01, -1.1567498057148995e+01, -1.1327919030095220e+01, -1.1092006691295751e+01, -1.0859476512776732e+01, -1.0630077274574017e+01, -1.0403585718697158e+01, -1.0179802264046788e+01, -9.9585475345593846e+00, -9.7396595186399217e+00, -9.5229912243166375e+00, -9.3084087277706491e+00, -9.0957895370391153e+00, -8.8850212104784116e+00, -8.6760001828398110e+00, -8.4686307618168346e+00, -8.2628242655509627e+00, -8.0584982774535074e+00, -7.8555759992614407e+00, -7.6539856868168998e+00, -7.4536601558800220e+00, -7.2545363475276838e+00, -7.0565549444870097e+00, -6.8596600312005922e+00, -6.6637987915949521e+00, -6.4689212394819462e+00, -6.2749799773089512e+00, -6.0819299796217976e+00, -5.8897283981415303e+00, -5.6983343858032613e+00, -5.5077089374792596e+00, -5.3178147454224645e+00, -5.1286160677313077e+00, -4.9400786083607757e+00, -4.7521694073949581e+00, -4.5648567404584961e+00, -4.3781100262830321e+00, -4.1918997415637014e+00, -4.0061973423430199e+00, -3.8209751912478049e+00, -3.6362064899810247e+00, -3.4518652165367119e+00, -3.2679260666634748e+00, -3.0843643991522391e+00, -2.9011561845674412e+00, -2.7182779570790365e+00, -2.5357067690860005e+00, -2.3534201483511836e+00, -2.1713960573929474e+00, -1.9896128549013927e+00, -1.8080492589666075e+00, -1.6266843119235277e+00, -1.4454973466329897e+00, -1.2644679540316108e+00, -1.0835759517944645e+00, -9.0280135396429395e-01, -7.2212434140935688e-01, -5.4152523297908439e-01, -3.6098445723261258e-01, -1.8048252462003789e-01, -0.0000000000000000e+00, 1.8048252462003789e-01, 3.6098445723261258e-01, 5.4152523297908439e-01, 7.2212434140935688e-01, 9.0280135396429395e-01, 1.0835759517944645e+00, 1.2644679540316108e+00, 1.4454973466329897e+00, 1.6266843119235277e+00, 1.8080492589666075e+00, 1.9896128549013927e+00, 2.1713960573929474e+00, 2.3534201483511836e+00, 2.5357067690860005e+00, 2.7182779570790365e+00, 2.9011561845674412e+00, 3.0843643991522391e+00, 3.2679260666634748e+00, 3.4518652165367119e+00, 3.6362064899810247e+00, 3.8209751912478049e+00, 4.0061973423430199e+00, 4.1918997415637014e+00, 4.3781100262830321e+00, 4.5648567404584961e+00, 4.7521694073949581e+00, 4.9400786083607757e+00, 5.1286160677313077e+00, 5.3178147454224645e+00, 5.5077089374792596e+00, 5.6983343858032613e+00, 5.8897283981415303e+00, 6.0819299796217976e+00, 6.2749799773089512e+00, 6.4689212394819462e+00, 6.6637987915949521e+00, 6.8596600312005922e+00, 7.0565549444870097e+00, 7.2545363475276838e+00, 7.4536601558800220e+00, 7.6539856868168998e+00, 7.8555759992614407e+00, 8.0584982774535074e+00, 8.2628242655509627e+00, 8.4686307618168346e+00, 8.6760001828398110e+00, 8.8850212104784116e+00, 9.0957895370391153e+00, 9.3084087277706491e+00, 9.5229912243166375e+00, 9.7396595186399217e+00, 9.9585475345593846e+00, 1.0179802264046788e+01, 1.0403585718697158e+01, 1.0630077274574017e+01, 1.0859476512776732e+01, 1.1092006691295751e+01, 1.1327919030095220e+01, 1.1567498057148995e+01, 1.1811068358148432e+01, 1.2059003212482786e+01, 1.2311735808633442e+01, 1.2569774056886668e+01, 1.2833720532318454e+01, 1.3104299924083964e+01, 1.3382397798268309e+01, 1.3669117016537621e+01, 1.3965862873544308e+01, 1.4274477352553639e+01, 1.4597462779517947e+01, 1.4938381618846188e+01, 1.5302641798879872e+01, 1.5699259877476434e+01, 1.6145733223684985e+01, 1.6687860507628386e+01}, + {-1.6746015667021069e+01, -1.6204510499941978e+01, -1.5758561659537367e+01, -1.5362419059461168e+01, -1.4998603726021303e+01, -1.4658108513302281e+01, -1.4335531106337195e+01, -1.4027312722878635e+01, -1.3730953615978237e+01, -1.3444613698016527e+01, -1.3166889120550762e+01, -1.2896678158583638e+01, -1.2633096161556749e+01, -1.2375419193081754e+01, -1.2123045308073459e+01, -1.1875467131689264e+01, -1.1632251936796413e+01, -1.1393026846411182e+01, -1.1157467629750515e+01, -1.0925290075047540e+01, -1.0696243246707187e+01, -1.0470104144699656e+01, -1.0246673423826493e+01, -1.0025771925388167e+01, -9.8072378395003508e+00, -9.5909243626320890e+00, -9.3766977481232310e+00, -9.1644356715597066e+00, -8.9540258506546646e+00, -8.7453648725360029e+00, -8.5383571913371981e+00, -8.3329142666081459e+00, -8.1289538189277764e+00, -7.9263991836556649e+00, -7.7251787473280729e+00, -7.5252254540210100e+00, -7.3264763712435084e+00, -7.1288723067188302e+00, -6.9323574688579237e+00, -6.7368791649028887e+00, -6.5423875316754021e+00, -6.3488352946504518e+00, -6.1561775517231760e+00, -5.9643715785732399e+00, -5.7733766529779098e+00, -5.5831538957985396e+00, -5.3936661266788803e+00, -5.2048777327581446e+00, -5.0167545489255820e+00, -4.8292637483334380e+00, -4.6423737420472682e+00, -4.4560540868511129e+00, -4.2702754003439098e+00, -4.0850092825657862e+00, -3.9002282434810596e+00, -3.7159056357210827e+00, -3.5320155920561942e+00, -3.3485329671235227e+00, -3.1654332829874168e+00, -2.9826926781529521e+00, -2.8002878596910716e+00, -2.6181960581673263e+00, -2.4363949850953830e+00, -2.2548627926621019e+00, -2.0735780354934534e+00, -1.8925196342502328e+00, -1.7116668408598084e+00, -1.5309992052052144e+00, -1.3504965431061176e+00, -1.1701389054376192e+00, -9.8990654824282009e-01, -8.0977990370358899e-01, -6.2973955184126684e-01, -4.4976619282513375e-01, -2.6984061977151302e-01, -8.9943691920400901e-02, 8.9943691920400901e-02, 2.6984061977151302e-01, 4.4976619282513375e-01, 6.2973955184126684e-01, 8.0977990370358899e-01, 9.8990654824282009e-01, 1.1701389054376192e+00, 1.3504965431061176e+00, 1.5309992052052144e+00, 1.7116668408598084e+00, 1.8925196342502328e+00, 2.0735780354934534e+00, 2.2548627926621019e+00, 2.4363949850953830e+00, 2.6181960581673263e+00, 2.8002878596910716e+00, 2.9826926781529521e+00, 3.1654332829874168e+00, 3.3485329671235227e+00, 3.5320155920561942e+00, 3.7159056357210827e+00, 3.9002282434810596e+00, 4.0850092825657862e+00, 4.2702754003439098e+00, 4.4560540868511129e+00, 4.6423737420472682e+00, 4.8292637483334380e+00, 5.0167545489255820e+00, 5.2048777327581446e+00, 5.3936661266788803e+00, 5.5831538957985396e+00, 5.7733766529779098e+00, 5.9643715785732399e+00, 6.1561775517231760e+00, 6.3488352946504518e+00, 6.5423875316754021e+00, 6.7368791649028887e+00, 6.9323574688579237e+00, 7.1288723067188302e+00, 7.3264763712435084e+00, 7.5252254540210100e+00, 7.7251787473280729e+00, 7.9263991836556649e+00, 8.1289538189277764e+00, 8.3329142666081459e+00, 8.5383571913371981e+00, 8.7453648725360029e+00, 8.9540258506546646e+00, 9.1644356715597066e+00, 9.3766977481232310e+00, 9.5909243626320890e+00, 9.8072378395003508e+00, 1.0025771925388167e+01, 1.0246673423826493e+01, 1.0470104144699656e+01, 1.0696243246707187e+01, 1.0925290075047540e+01, 1.1157467629750515e+01, 1.1393026846411182e+01, 1.1632251936796413e+01, 1.1875467131689264e+01, 1.2123045308073459e+01, 1.2375419193081754e+01, 1.2633096161556749e+01, 1.2896678158583638e+01, 1.3166889120550762e+01, 1.3444613698016527e+01, 1.3730953615978237e+01, 1.4027312722878635e+01, 1.4335531106337195e+01, 1.4658108513302281e+01, 1.4998603726021303e+01, 1.5362419059461168e+01, 1.5758561659537367e+01, 1.6204510499941978e+01, 1.6746015667021069e+01}, + {-1.6803976908523694e+01, -1.6263088958580713e+01, -1.5817660423010251e+01, -1.5421989437211316e+01, -1.5058615286432362e+01, -1.4718540167071973e+01, -1.4396367336014109e+01, -1.4088541665869107e+01, -1.3792565969471646e+01, -1.3506602040607744e+01, -1.3229247466060766e+01, -1.2959401648746917e+01, -1.2696180846459008e+01, -1.2438861869552357e+01, -1.2186843397769389e+01, -1.1939618587201746e+01, -1.1696755168060276e+01, -1.1457880662155430e+01, -1.1222671190311015e+01, -1.0990842853911044e+01, -1.0762144998868230e+01, -1.0536354880406639e+01, -1.0313273386643994e+01, -1.0092721573755421e+01, -9.8745378311513203e+00, -9.6585755413803565e+00, -9.4447011326189330e+00, -9.2327924457049324e+00, -9.0227373554249493e+00, -8.8144325990031405e+00, -8.6077827747261111e+00, -8.4026994812503251e+00, -8.1991005739976206e+00, -7.9969095195952864e+00, -7.7960548328817607e+00, -7.5964695838133709e+00, -7.3980909638458217e+00, -7.2008599031569602e+00, -7.0047207315224398e+00, -6.8096208768281805e+00, -6.6155105961598455e+00, -6.4223427351940696e+00, -6.2300725122630887e+00, -6.0386573240004857e+00, -5.8480565699220763e+00, -5.6582314936691613e+00, -5.4691450389548066e+00, -5.2807617185180318e+00, -5.0930474946144608e+00, -4.9059696697619373e+00, -4.7194967866215638e+00, -4.5335985360330326e+00, -4.3482456723419469e+00, -4.1634099352589846e+00, -3.9790639775789276e+00, -3.7951812981638180e+00, -3.6117361796606513e+00, -3.4287036304814422e+00, -3.2460593306235781e+00, -3.0637795809520179e+00, -2.8818412556030690e+00, -2.7002217572028795e+00, -2.5188989746230557e+00, -2.3378512430214919e+00, -2.1570573059390363e+00, -1.9764962792423748e+00, -1.7961476167208907e+00, -1.6159910771604287e+00, -1.4360066927302104e+00, -1.2561747385307371e+00, -1.0764757031605943e+00, -8.9689026016876394e-01, -7.1739924026651414e-01, -5.3798360417923241e-01, -3.5862441602383283e-01, -1.7930281710163956e-01, -0.0000000000000000e+00, 1.7930281710163956e-01, 3.5862441602383283e-01, 5.3798360417923241e-01, 7.1739924026651414e-01, 8.9689026016876394e-01, 1.0764757031605943e+00, 1.2561747385307371e+00, 1.4360066927302104e+00, 1.6159910771604287e+00, 1.7961476167208907e+00, 1.9764962792423748e+00, 2.1570573059390363e+00, 2.3378512430214919e+00, 2.5188989746230557e+00, 2.7002217572028795e+00, 2.8818412556030690e+00, 3.0637795809520179e+00, 3.2460593306235781e+00, 3.4287036304814422e+00, 3.6117361796606513e+00, 3.7951812981638180e+00, 3.9790639775789276e+00, 4.1634099352589846e+00, 4.3482456723419469e+00, 4.5335985360330326e+00, 4.7194967866215638e+00, 4.9059696697619373e+00, 5.0930474946144608e+00, 5.2807617185180318e+00, 5.4691450389548066e+00, 5.6582314936691613e+00, 5.8480565699220763e+00, 6.0386573240004857e+00, 6.2300725122630887e+00, 6.4223427351940696e+00, 6.6155105961598455e+00, 6.8096208768281805e+00, 7.0047207315224398e+00, 7.2008599031569602e+00, 7.3980909638458217e+00, 7.5964695838133709e+00, 7.7960548328817607e+00, 7.9969095195952864e+00, 8.1991005739976206e+00, 8.4026994812503251e+00, 8.6077827747261111e+00, 8.8144325990031405e+00, 9.0227373554249493e+00, 9.2327924457049324e+00, 9.4447011326189330e+00, 9.6585755413803565e+00, 9.8745378311513203e+00, 1.0092721573755421e+01, 1.0313273386643994e+01, 1.0536354880406639e+01, 1.0762144998868230e+01, 1.0990842853911044e+01, 1.1222671190311015e+01, 1.1457880662155430e+01, 1.1696755168060276e+01, 1.1939618587201746e+01, 1.2186843397769389e+01, 1.2438861869552357e+01, 1.2696180846459008e+01, 1.2959401648746917e+01, 1.3229247466060766e+01, 1.3506602040607744e+01, 1.3792565969471646e+01, 1.4088541665869107e+01, 1.4396367336014109e+01, 1.4718540167071973e+01, 1.5058615286432362e+01, 1.5421989437211316e+01, 1.5817660423010251e+01, 1.6263088958580713e+01, 1.6803976908523694e+01}, + {-1.6861746151514453e+01, -1.6321470589822656e+01, -1.5876558219732326e+01, -1.5481355041356229e+01, -1.5118418464347313e+01, -1.4778759958751550e+01, -1.4456988312356128e+01, -1.4149552025707647e+01, -1.3853956452475600e+01, -1.3568365253816872e+01, -1.3291377440919536e+01, -1.3021893535990777e+01, -1.2759030698111300e+01, -1.2502066478454370e+01, -1.2250400176513523e+01, -1.2003525474883981e+01, -1.1761010557188053e+01, -1.1522483340487554e+01, -1.1287620293977072e+01, -1.1056137829198551e+01, -1.0827785570772761e+01, -1.0602341026531503e+01, -1.0379605315384135e+01, -1.0159399705951289e+01, -9.9415627845826098e+00, -9.7259481176063289e+00, -9.5124223057752690e+00, -9.3008633529456954e+00, -9.0911592887589681e+00, -8.8832069983214303e+00, -8.6769112218541409e+00, -8.4721836948885070e+00, -8.2689424054370715e+00, -8.0671109491149302e+00, -7.8666179667484384e+00, -7.6673966518192671e+00, -7.4693843173280303e+00, -7.2725220134526776e+00, -7.0767541888205505e+00, -6.8820283893841117e+00, -6.6882949898457129e+00, -6.4955069533605654e+00, -6.3036196158933109e+00, -6.1125904921391818e+00, -5.9223791003665953e+00, -5.7329468039109130e+00, -5.5442566673621716e+00, -5.3562733257536657e+00, -5.1689628652816504e+00, -4.9822927142762881e+00, -4.7962315433057050e+00, -4.6107491734334216e+00, -4.4258164917680798e+00, -4.2414053735465238e+00, -4.0574886100793801e+00, -3.8740398419645214e+00, -3.6910334970398750e+00, -3.5084447326044930e+00, -3.3262493814868481e+00, -3.1444239015829951e+00, -2.9629453285254086e+00, -2.7817912311767614e+00, -2.6009396696722078e+00, -2.4203691557594618e+00, -2.2400586152085502e+00, -2.0599873520829730e+00, -1.8801350146814075e+00, -1.7004815629744074e+00, -1.5210072373739318e+00, -1.3416925286852595e+00, -1.1625181491010375e+00, -9.8346500410607329e-01, -8.0451416516907071e-01, -6.2564684310401653e-01, -4.4684436198936728e-01, -2.6808813353769451e-01, -8.9359631812036308e-02, 8.9359631812036308e-02, 2.6808813353769451e-01, 4.4684436198936728e-01, 6.2564684310401653e-01, 8.0451416516907071e-01, 9.8346500410607329e-01, 1.1625181491010375e+00, 1.3416925286852595e+00, 1.5210072373739318e+00, 1.7004815629744074e+00, 1.8801350146814075e+00, 2.0599873520829730e+00, 2.2400586152085502e+00, 2.4203691557594618e+00, 2.6009396696722078e+00, 2.7817912311767614e+00, 2.9629453285254086e+00, 3.1444239015829951e+00, 3.3262493814868481e+00, 3.5084447326044930e+00, 3.6910334970398750e+00, 3.8740398419645214e+00, 4.0574886100793801e+00, 4.2414053735465238e+00, 4.4258164917680798e+00, 4.6107491734334216e+00, 4.7962315433057050e+00, 4.9822927142762881e+00, 5.1689628652816504e+00, 5.3562733257536657e+00, 5.5442566673621716e+00, 5.7329468039109130e+00, 5.9223791003665953e+00, 6.1125904921391818e+00, 6.3036196158933109e+00, 6.4955069533605654e+00, 6.6882949898457129e+00, 6.8820283893841117e+00, 7.0767541888205505e+00, 7.2725220134526776e+00, 7.4693843173280303e+00, 7.6673966518192671e+00, 7.8666179667484384e+00, 8.0671109491149302e+00, 8.2689424054370715e+00, 8.4721836948885070e+00, 8.6769112218541409e+00, 8.8832069983214303e+00, 9.0911592887589681e+00, 9.3008633529456954e+00, 9.5124223057752690e+00, 9.7259481176063289e+00, 9.9415627845826098e+00, 1.0159399705951289e+01, 1.0379605315384135e+01, 1.0602341026531503e+01, 1.0827785570772761e+01, 1.1056137829198551e+01, 1.1287620293977072e+01, 1.1522483340487554e+01, 1.1761010557188053e+01, 1.2003525474883981e+01, 1.2250400176513523e+01, 1.2502066478454370e+01, 1.2759030698111300e+01, 1.3021893535990777e+01, 1.3291377440919536e+01, 1.3568365253816872e+01, 1.3853956452475600e+01, 1.4149552025707647e+01, 1.4456988312356128e+01, 1.4778759958751550e+01, 1.5118418464347313e+01, 1.5481355041356229e+01, 1.5876558219732326e+01, 1.6321470589822656e+01, 1.6861746151514453e+01}, + {-1.6919325283973091e+01, -1.6379657351007765e+01, -1.5935257067352701e+01, -1.5540517945702927e+01, -1.5178015387422422e+01, -1.4838770068479555e+01, -1.4517396267181470e+01, -1.4210346085463854e+01, -1.3915127399149720e+01, -1.3629905722933353e+01, -1.3353281481744700e+01, -1.3084156308589026e+01, -1.2821648256881092e+01, -1.2565035612781342e+01, -1.2313718290542331e+01, -1.2067190494908804e+01, -1.1825020859053186e+01, -1.1586837691812352e+01, -1.1352317807578974e+01, -1.1121177925121051e+01, -1.0893167945027271e+01, -1.0668065625149652e+01, -1.0445672312722746e+01, -1.0225809486441577e+01, -1.0008315927297842e+01, -9.7930453831581623e+00, -9.5798646251513500e+00, -9.3686518179792717e+00, -9.1592951439814989e+00, -8.9516916339961323e+00, -8.7457461680254056e+00, -8.5413706163114078e+00, -8.3384830972746489e+00, -8.1370073333099651e+00, -7.9368720889917341e+00, -7.7380106790491130e+00, -7.5403605357059194e+00, -7.3438628267689321e+00, -7.1484621172907721e+00, -6.9541060688033616e+00, -6.7607451710725037e+00, -6.5683325021070607e+00, -6.3768235128018915e+00, -6.1861758331287540e+00, -5.9963490972348117e+00, -5.8073047851809010e+00, -5.6190060793645857e+00, -5.4314177339367200e+00, -5.2445059557435734e+00, -5.0582382955161487e+00, -4.8725835481900202e+00, -4.6875116613772301e+00, -4.5029936511304234e+00, -4.3190015242413970e+00, -4.1355082064043351e+00, -3.9524874756501580e+00, -3.7699139005244779e+00, -3.5877627825391012e+00, -3.4060101024770435e+00, -3.2246324701747149e+00, -3.0436070774431303e+00, -2.8629116538234336e+00, -2.6825244249014188e+00, -2.5024240729314422e+00, -2.3225896995428044e+00, -2.1430007903215516e+00, -1.9636371810781683e+00, -1.7844790256269836e+00, -1.6055067649166126e+00, -1.4267010973625776e+00, -1.2480429502435568e+00, -1.0695134520316971e+00, -8.9109390553517087e-01, -7.1276576173782080e-01, -5.3451059422635872e-01, -3.5631007410029453e-01, -1.7814594526358507e-01, -0.0000000000000000e+00, 1.7814594526358507e-01, 3.5631007410029453e-01, 5.3451059422635872e-01, 7.1276576173782080e-01, 8.9109390553517087e-01, 1.0695134520316971e+00, 1.2480429502435568e+00, 1.4267010973625776e+00, 1.6055067649166126e+00, 1.7844790256269836e+00, 1.9636371810781683e+00, 2.1430007903215516e+00, 2.3225896995428044e+00, 2.5024240729314422e+00, 2.6825244249014188e+00, 2.8629116538234336e+00, 3.0436070774431303e+00, 3.2246324701747149e+00, 3.4060101024770435e+00, 3.5877627825391012e+00, 3.7699139005244779e+00, 3.9524874756501580e+00, 4.1355082064043351e+00, 4.3190015242413970e+00, 4.5029936511304234e+00, 4.6875116613772301e+00, 4.8725835481900202e+00, 5.0582382955161487e+00, 5.2445059557435734e+00, 5.4314177339367200e+00, 5.6190060793645857e+00, 5.8073047851809010e+00, 5.9963490972348117e+00, 6.1861758331287540e+00, 6.3768235128018915e+00, 6.5683325021070607e+00, 6.7607451710725037e+00, 6.9541060688033616e+00, 7.1484621172907721e+00, 7.3438628267689321e+00, 7.5403605357059194e+00, 7.7380106790491130e+00, 7.9368720889917341e+00, 8.1370073333099651e+00, 8.3384830972746489e+00, 8.5413706163114078e+00, 8.7457461680254056e+00, 8.9516916339961323e+00, 9.1592951439814989e+00, 9.3686518179792717e+00, 9.5798646251513500e+00, 9.7930453831581623e+00, 1.0008315927297842e+01, 1.0225809486441577e+01, 1.0445672312722746e+01, 1.0668065625149652e+01, 1.0893167945027271e+01, 1.1121177925121051e+01, 1.1352317807578974e+01, 1.1586837691812352e+01, 1.1825020859053186e+01, 1.2067190494908804e+01, 1.2313718290542331e+01, 1.2565035612781342e+01, 1.2821648256881092e+01, 1.3084156308589026e+01, 1.3353281481744700e+01, 1.3629905722933353e+01, 1.3915127399149720e+01, 1.4210346085463854e+01, 1.4517396267181470e+01, 1.4838770068479555e+01, 1.5178015387422422e+01, 1.5540517945702927e+01, 1.5935257067352701e+01, 1.6379657351007765e+01, 1.6919325283973091e+01}, + {-1.6976716163194499e+01, -1.6437651167348605e+01, -1.5993758950122626e+01, -1.5599480189464179e+01, -1.5237408147560531e+01, -1.4898572639500255e+01, -1.4577593394280033e+01, -1.4270926089044083e+01, -1.3976081103348914e+01, -1.3691225791789593e+01, -1.3414961982530070e+01, -1.3146192411007465e+01, -1.2884036018123565e+01, -1.2627771819287853e+01, -1.2376800338602001e+01, -1.2130616298680719e+01, -1.1888788778454018e+01, -1.1650946475122105e+01, -1.1416766545164455e+01, -1.1185966011702471e+01, -1.0958295048610227e+01, -1.0733531661229089e+01, -1.0511477422708499e+01, -1.0291954019502739e+01, -1.0074800425004574e+01, -9.8598705664345285e+00, -9.6470313831544541e+00, -9.4361611985975138e+00, -9.2271483457046273e+00, -9.0198899989563817e+00, -8.8142911760456872e+00, -8.6102638798256326e+00, -8.4077263570086043e+00, -8.2066024546299392e+00, -8.0068210588433661e+00, -7.8083156034214856e+00, -7.6110236375661993e+00, -7.4148864444214286e+00, -7.2198487031214214e+00, -7.0258581883766524e+00, -6.8328655025529308e+00, -6.6408238359815064e+00, -6.4496887518830528e+00, -6.2594179928228799e+00, -6.0699713060598244e+00, -5.8813102855233703e+00, -5.6933982284661457e+00, -5.5062000051024196e+00, -5.3196819397663528e+00, -5.1338117023131167e+00, -4.9485582086476523e+00, -4.7638915294038444e+00, -4.5797828059155004e+00, -4.3962041727224284e+00, -4.2131286859429329e+00, -4.0305302569201968e+00, -3.8483835906160127e+00, -3.6666641282827874e+00, -3.4853479939947509e+00, -3.3044119446629794e+00, -3.1238333231970716e+00, -2.9435900145097715e+00, -2.7636604040902180e+00, -2.5840233388973028e+00, -2.4046580903472949e+00, -2.2255443191898578e+00, -2.0466620420841379e+00, -1.8679915997020398e+00, -1.6895136261993984e+00, -1.5112090199076367e+00, -1.3330589151089478e+00, -1.1550446547671134e+00, -9.7714776409397042e-01, -7.9934992483832146e-01, -6.2163295018989517e-01, -4.4397876019583243e-01, -2.6636935759120106e-01, -8.8786803948269877e-02, 8.8786803948269877e-02, 2.6636935759120106e-01, 4.4397876019583243e-01, 6.2163295018989517e-01, 7.9934992483832146e-01, 9.7714776409397042e-01, 1.1550446547671134e+00, 1.3330589151089478e+00, 1.5112090199076367e+00, 1.6895136261993984e+00, 1.8679915997020398e+00, 2.0466620420841379e+00, 2.2255443191898578e+00, 2.4046580903472949e+00, 2.5840233388973028e+00, 2.7636604040902180e+00, 2.9435900145097715e+00, 3.1238333231970716e+00, 3.3044119446629794e+00, 3.4853479939947509e+00, 3.6666641282827874e+00, 3.8483835906160127e+00, 4.0305302569201968e+00, 4.2131286859429329e+00, 4.3962041727224284e+00, 4.5797828059155004e+00, 4.7638915294038444e+00, 4.9485582086476523e+00, 5.1338117023131167e+00, 5.3196819397663528e+00, 5.5062000051024196e+00, 5.6933982284661457e+00, 5.8813102855233703e+00, 6.0699713060598244e+00, 6.2594179928228799e+00, 6.4496887518830528e+00, 6.6408238359815064e+00, 6.8328655025529308e+00, 7.0258581883766524e+00, 7.2198487031214214e+00, 7.4148864444214286e+00, 7.6110236375661993e+00, 7.8083156034214856e+00, 8.0068210588433661e+00, 8.2066024546299392e+00, 8.4077263570086043e+00, 8.6102638798256326e+00, 8.8142911760456872e+00, 9.0198899989563817e+00, 9.2271483457046273e+00, 9.4361611985975138e+00, 9.6470313831544541e+00, 9.8598705664345285e+00, 1.0074800425004574e+01, 1.0291954019502739e+01, 1.0511477422708499e+01, 1.0733531661229089e+01, 1.0958295048610227e+01, 1.1185966011702471e+01, 1.1416766545164455e+01, 1.1650946475122105e+01, 1.1888788778454018e+01, 1.2130616298680719e+01, 1.2376800338602001e+01, 1.2627771819287853e+01, 1.2884036018123565e+01, 1.3146192411007465e+01, 1.3414961982530070e+01, 1.3691225791789593e+01, 1.3976081103348914e+01, 1.4270926089044083e+01, 1.4577593394280033e+01, 1.4898572639500255e+01, 1.5237408147560531e+01, 1.5599480189464179e+01, 1.5993758950122626e+01, 1.6437651167348605e+01, 1.6976716163194499e+01}, + {-1.7033920616481659e+01, -1.6495453932662432e+01, -1.6052065819662449e+01, -1.5658243778058655e+01, -1.5296598801743723e+01, -1.4958169779028550e+01, -1.4637581850310665e+01, -1.4331294242121345e+01, -1.4036819819586414e+01, -1.3752327763757672e+01, -1.3476421295676769e+01, -1.3208004244970210e+01, -1.2946196433284063e+01, -1.2690277599628986e+01, -1.2439648873125966e+01, -1.2193805490052643e+01, -1.1952316971370964e+01, -1.1714812399295406e+01, -1.1480969269340585e+01, -1.1250504906165974e+01, -1.1023169754304320e+01, -1.0798742064110225e+01, -1.0577023632291938e+01, -1.0357836350801911e+01, -1.0141019383247183e+01, -9.9264268340723447e+00, -9.7139258087846567e+00, -9.5033947874905458e+00, -9.2947222516928303e+00, -9.0878055174840568e+00, -8.8825497382175893e+00, -8.6788670473198550e+00, -8.4766758177429260e+00, -8.2759000190893772e+00, -8.0764686569918620e+00, -7.8783152821330633e+00, -7.6813775585211594e+00, -7.4855968824216461e+00, -7.2909180447858821e+00, -7.0972889311843357e+00, -6.9046602542051492e+00, -6.7129853140601305e+00, -6.5222197837846556e+00, -6.3323215159520476e+00, -6.1432503682675650e+00, -5.9549680457789771e+00, -5.7674379577529349e+00, -5.5806250875296657e+00, -5.3944958738913487e+00, -5.2090181026688498e+00, -5.0241608074728896e+00, -4.8398941785737106e+00, -4.6561894790717648e+00, -4.4730189676038190e+00, -4.2903558269168203e+00, -4.1081740977179662e+00, -3.9264486172753981e+00, -3.7451549623013909e+00, -3.5642693956998519e+00, -3.3837688168037010e+00, -3.2036307147658607e+00, -3.0238331248011101e+00, -2.8443545870054412e+00, -2.6651741075053921e+00, -2.4862711217125546e+00, -2.3076254594784578e+00, -2.1292173119626474e+00, -1.9510272000422848e+00, -1.7730359441052344e+00, -1.5952246350806079e+00, -1.4175746065712449e+00, -1.2400674079618077e+00, -1.0626847783841744e+00, -8.8540862142874210e-01, -7.0822098049619520e-01, -5.3110401468933777e-01, -3.5403997514879265e-01, -1.7701118173979521e-01, -0.0000000000000000e+00, 1.7701118173979521e-01, 3.5403997514879265e-01, 5.3110401468933777e-01, 7.0822098049619520e-01, 8.8540862142874210e-01, 1.0626847783841744e+00, 1.2400674079618077e+00, 1.4175746065712449e+00, 1.5952246350806079e+00, 1.7730359441052344e+00, 1.9510272000422848e+00, 2.1292173119626474e+00, 2.3076254594784578e+00, 2.4862711217125546e+00, 2.6651741075053921e+00, 2.8443545870054412e+00, 3.0238331248011101e+00, 3.2036307147658607e+00, 3.3837688168037010e+00, 3.5642693956998519e+00, 3.7451549623013909e+00, 3.9264486172753981e+00, 4.1081740977179662e+00, 4.2903558269168203e+00, 4.4730189676038190e+00, 4.6561894790717648e+00, 4.8398941785737106e+00, 5.0241608074728896e+00, 5.2090181026688498e+00, 5.3944958738913487e+00, 5.5806250875296657e+00, 5.7674379577529349e+00, 5.9549680457789771e+00, 6.1432503682675650e+00, 6.3323215159520476e+00, 6.5222197837846556e+00, 6.7129853140601305e+00, 6.9046602542051492e+00, 7.0972889311843357e+00, 7.2909180447858821e+00, 7.4855968824216461e+00, 7.6813775585211594e+00, 7.8783152821330633e+00, 8.0764686569918620e+00, 8.2759000190893772e+00, 8.4766758177429260e+00, 8.6788670473198550e+00, 8.8825497382175893e+00, 9.0878055174840568e+00, 9.2947222516928303e+00, 9.5033947874905458e+00, 9.7139258087846567e+00, 9.9264268340723447e+00, 1.0141019383247183e+01, 1.0357836350801911e+01, 1.0577023632291938e+01, 1.0798742064110225e+01, 1.1023169754304320e+01, 1.1250504906165974e+01, 1.1480969269340585e+01, 1.1714812399295406e+01, 1.1952316971370964e+01, 1.2193805490052643e+01, 1.2439648873125966e+01, 1.2690277599628986e+01, 1.2946196433284063e+01, 1.3208004244970210e+01, 1.3476421295676769e+01, 1.3752327763757672e+01, 1.4036819819586414e+01, 1.4331294242121345e+01, 1.4637581850310665e+01, 1.4958169779028550e+01, 1.5296598801743723e+01, 1.5658243778058655e+01, 1.6052065819662449e+01, 1.6495453932662432e+01, 1.7033920616481659e+01}, + {-1.7090940441818589e+01, -1.6553067510081998e+01, -1.6110179595706111e+01, -1.5716810683887498e+01, -1.5355589372841228e+01, -1.5017563559089020e+01, -1.4697363755671436e+01, -1.4391452713037102e+01, -1.4097345763967498e+01, -1.3813213902715583e+01, -1.3537661732992635e+01, -1.3269594170493015e+01, -1.3008131910966144e+01, -1.2752555411464087e+01, -1.2502266401375357e+01, -1.2256760626504082e+01, -1.2015608046183521e+01, -1.1778438124354272e+01, -1.1544928692572215e+01, -1.1314797374275166e+01, -1.1087794882081830e+01, -1.0863699708936927e+01, -1.0642313872803815e+01, -1.0423459468924202e+01, -1.0206975848984905e+01, -9.9927172925773995e+00, -9.7805510693200404e+00, -9.5703558139886304e+00, -9.3620201546636572e+00, -9.1554415470755703e+00, -8.9505252782658893e+00, -8.7471836102562435e+00, -8.5453350402475099e+00, -8.3449036583995202e+00, -8.1458185877888383e+00, -7.9480134939425788e+00, -7.7514261535735791e+00, -7.5559980739261903e+00, -7.3616741555800598e+00, -7.1684023927258176e+00, -6.9761336058782426e+00, -6.7848212027732666e+00, -6.5944209638389415e+00, -6.4048908491640280e+00, -6.2161908243320640e+00, -6.0282827028602410e+00, -5.8411300032943645e+00, -5.6546978192742712e+00, -5.4689527011066783e+00, -5.2838625475716334e+00, -5.0993965068499545e+00, -4.9155248855969580e+00, -4.7322190653061282e+00, -4.5494514252081650e+00, -4.3671952710387769e+00, -4.1854247690845812e+00, -4.0041148849824761e+00, -3.8232413268052290e+00, -3.6427804920159894e+00, -3.4627094179181652e+00, -3.2830057352652728e+00, -3.1036476247289064e+00, -2.9246137759523689e+00, -2.7458833489433849e+00, -2.5674359375820566e+00, -2.3892515350402799e+00, -2.2113105009265008e+00, -2.0335935299852599e+00, -1.8560816221946776e+00, -1.6787560541171089e+00, -1.5015983513687976e+00, -1.3245902620836472e+00, -1.1477137312543411e+00, -9.7095087584109574e-01, -7.9428396054439432e-01, -6.1769537414325426e-01, -4.4116760630493546e-01, -2.6468322477561551e-01, -8.8224852864438347e-02, 8.8224852864438347e-02, 2.6468322477561551e-01, 4.4116760630493546e-01, 6.1769537414325426e-01, 7.9428396054439432e-01, 9.7095087584109574e-01, 1.1477137312543411e+00, 1.3245902620836472e+00, 1.5015983513687976e+00, 1.6787560541171089e+00, 1.8560816221946776e+00, 2.0335935299852599e+00, 2.2113105009265008e+00, 2.3892515350402799e+00, 2.5674359375820566e+00, 2.7458833489433849e+00, 2.9246137759523689e+00, 3.1036476247289064e+00, 3.2830057352652728e+00, 3.4627094179181652e+00, 3.6427804920159894e+00, 3.8232413268052290e+00, 4.0041148849824761e+00, 4.1854247690845812e+00, 4.3671952710387769e+00, 4.5494514252081650e+00, 4.7322190653061282e+00, 4.9155248855969580e+00, 5.0993965068499545e+00, 5.2838625475716334e+00, 5.4689527011066783e+00, 5.6546978192742712e+00, 5.8411300032943645e+00, 6.0282827028602410e+00, 6.2161908243320640e+00, 6.4048908491640280e+00, 6.5944209638389415e+00, 6.7848212027732666e+00, 6.9761336058782426e+00, 7.1684023927258176e+00, 7.3616741555800598e+00, 7.5559980739261903e+00, 7.7514261535735791e+00, 7.9480134939425788e+00, 8.1458185877888383e+00, 8.3449036583995202e+00, 8.5453350402475099e+00, 8.7471836102562435e+00, 8.9505252782658893e+00, 9.1554415470755703e+00, 9.3620201546636572e+00, 9.5703558139886304e+00, 9.7805510693200404e+00, 9.9927172925773995e+00, 1.0206975848984905e+01, 1.0423459468924202e+01, 1.0642313872803815e+01, 1.0863699708936927e+01, 1.1087794882081830e+01, 1.1314797374275166e+01, 1.1544928692572215e+01, 1.1778438124354272e+01, 1.2015608046183521e+01, 1.2256760626504082e+01, 1.2502266401375357e+01, 1.2752555411464087e+01, 1.3008131910966144e+01, 1.3269594170493015e+01, 1.3537661732992635e+01, 1.3813213902715583e+01, 1.4097345763967498e+01, 1.4391452713037102e+01, 1.4697363755671436e+01, 1.5017563559089020e+01, 1.5355589372841228e+01, 1.5716810683887498e+01, 1.6110179595706111e+01, 1.6553067510081998e+01, 1.7090940441818589e+01}, + {-1.7147777408524032e+01, -1.6610493732745791e+01, -1.6168102166823996e+01, -1.5775182847088153e+01, -1.5414381850393539e+01, -1.5076756017330117e+01, -1.4756941195343936e+01, -1.4451403633675961e+01, -1.4157661115094985e+01, -1.3873886433984071e+01, -1.3598685566661047e+01, -1.3330964506884797e+01, -1.3069844817966612e+01, -1.2814607669526135e+01, -1.2564655386543684e+01, -1.2319484220282153e+01, -1.2078664564848737e+01, -1.1841826262681151e+01, -1.1608647478438799e+01, -1.1378846131631990e+01, -1.1152173200444981e+01, -1.0928407418040756e+01, -1.0707351021384738e+01, -1.0488826306849386e+01, -1.0272672812117237e+01, -1.0058744989900266e+01, -9.8469102719449655e+00, -9.6370474457447699e+00, -9.4290452840267438e+00, -9.2228013802394901e+00, -9.0182211531960341e+00, -8.8152169915922389e+00, -8.6137075149457782e+00, -8.4136169320244640e+00, -8.2148744813764658e+00, -8.0174139413725705e+00, -7.8211731993958935e+00, -7.6260938715966651e+00, -7.4321209660664360e+00, -7.2392025834514619e+00, -7.0472896499758120e+00, -6.8563356786247329e+00, -6.6662965548819884e+00, -6.4771303439479562e+00, -6.2887971168089667e+00, -6.1012587928995696e+00, -5.9144789974110621e+00, -5.7284229315624149e+00, -5.5430572543722416e+00, -5.3583499746593573e+00, -5.1742703521606801e+00, -4.9907888067929420e+00, -4.8078768352029666e+00, -4.6255069338529911e+00, -4.4436525279753418e+00, -4.2622879058067751e+00, -4.0813881575787159e+00, -3.9009291187969852e+00, -3.7208873173946002e+00, -3.5412399243848873e+00, -3.3619647076803778e+00, -3.1830399887764611e+00, -3.0044446020282125e+00, -2.8261578562746821e+00, -2.6481594985877317e+00, -2.4704296799425793e+00, -2.2929489226249280e+00, -2.1156980892051682e+00, -1.9386583529239170e+00, -1.7618111693452876e+00, -1.5851382491449768e+00, -1.4086215319096145e+00, -1.2322431608320461e+00, -1.0559854581943640e+00, -8.7983090153669952e-01, -7.0376210041511855e-01, -5.2776177365646371e-01, -3.5181272702177707e-01, -1.7589783119299077e-01, -0.0000000000000000e+00, 1.7589783119299077e-01, 3.5181272702177707e-01, 5.2776177365646371e-01, 7.0376210041511855e-01, 8.7983090153669952e-01, 1.0559854581943640e+00, 1.2322431608320461e+00, 1.4086215319096145e+00, 1.5851382491449768e+00, 1.7618111693452876e+00, 1.9386583529239170e+00, 2.1156980892051682e+00, 2.2929489226249280e+00, 2.4704296799425793e+00, 2.6481594985877317e+00, 2.8261578562746821e+00, 3.0044446020282125e+00, 3.1830399887764611e+00, 3.3619647076803778e+00, 3.5412399243848873e+00, 3.7208873173946002e+00, 3.9009291187969852e+00, 4.0813881575787159e+00, 4.2622879058067751e+00, 4.4436525279753418e+00, 4.6255069338529911e+00, 4.8078768352029666e+00, 4.9907888067929420e+00, 5.1742703521606801e+00, 5.3583499746593573e+00, 5.5430572543722416e+00, 5.7284229315624149e+00, 5.9144789974110621e+00, 6.1012587928995696e+00, 6.2887971168089667e+00, 6.4771303439479562e+00, 6.6662965548819884e+00, 6.8563356786247329e+00, 7.0472896499758120e+00, 7.2392025834514619e+00, 7.4321209660664360e+00, 7.6260938715966651e+00, 7.8211731993958935e+00, 8.0174139413725705e+00, 8.2148744813764658e+00, 8.4136169320244640e+00, 8.6137075149457782e+00, 8.8152169915922389e+00, 9.0182211531960341e+00, 9.2228013802394901e+00, 9.4290452840267438e+00, 9.6370474457447699e+00, 9.8469102719449655e+00, 1.0058744989900266e+01, 1.0272672812117237e+01, 1.0488826306849386e+01, 1.0707351021384738e+01, 1.0928407418040756e+01, 1.1152173200444981e+01, 1.1378846131631990e+01, 1.1608647478438799e+01, 1.1841826262681151e+01, 1.2078664564848737e+01, 1.2319484220282153e+01, 1.2564655386543684e+01, 1.2814607669526135e+01, 1.3069844817966612e+01, 1.3330964506884797e+01, 1.3598685566661047e+01, 1.3873886433984071e+01, 1.4157661115094985e+01, 1.4451403633675961e+01, 1.4756941195343936e+01, 1.5076756017330117e+01, 1.5414381850393539e+01, 1.5775182847088153e+01, 1.6168102166823996e+01, 1.6610493732745791e+01, 1.7147777408524032e+01}, + {-1.7204433257886514e+01, -1.6667734404468501e+01, -1.6225835391124875e+01, -1.5833362176266244e+01, -1.5472978191373558e+01, -1.5135749157814335e+01, -1.4816316219712570e+01, -1.4511149100314286e+01, -1.4217768014947598e+01, -1.3934347545235219e+01, -1.3659495030180320e+01, -1.3392117533718560e+01, -1.3131337480278725e+01, -1.2876436746658081e+01, -1.2626818248827179e+01, -1.2381978739506893e+01, -1.2141489044042531e+01, -1.1904979380197393e+01, -1.1672128242851137e+01, -1.1442653844932979e+01, -1.1216307427723020e+01, -1.0992867962280265e+01, -1.0772137902368133e+01, -1.0553939743380022e+01, -1.0338113206958853e+01, -1.0124512916959700e+01, -9.9130064653237309e+00, -9.7034727903605109e+00, -9.4958008075637199e+00, -9.2898882462326107e+00, -9.0856406550885644e+00, -8.8829705476356562e+00, -8.6817966638328432e+00, -8.4820433291649113e+00, -8.2836398957394959e+00, -8.0865202528325053e+00, -7.8906223965273750e+00, -7.6958880498740347e+00, -7.5022623264288848e+00, -7.3096934312013273e+00, -7.1181323939823153e+00, -6.9275328308096045e+00, -6.7378507299670023e+00, -6.5490442594474336e+00, -6.3610735932529767e+00, -6.1739007542758424e+00, -5.9874894718156684e+00, -5.8018050520510185e+00, -5.6168142600053486e+00, -5.4324852117363971e+00, -5.2487872756390139e+00, -5.0656909818891060e+00, -4.8831679391745020e+00, -4.7011907579602283e+00, -4.5197329796234431e+00, -4.3387690108692292e+00, -4.1582740629043391e+00, -3.9782240949032923e+00, -3.7985957613512462e+00, -3.6193663628916424e+00, -3.4405138003449269e+00, -3.2620165315981051e+00, -3.0838535310943649e+00, -2.9060042516778903e+00, -2.7284485885718048e+00, -2.5511668452873062e+00, -2.3741397012797925e+00, -2.1973481811834414e+00, -2.0207736254695439e+00, -1.8443976623860776e+00, -1.6682021810467551e+00, -1.4921693055472409e+00, -1.3162813699945290e+00, -1.1405208943427161e+00, -9.6487056093471757e-01, -7.8931319165491054e-01, -6.1383172560234123e-01, -4.3840919719805421e-01, -2.6302871464332994e-01, -8.7673438648223800e-02, 8.7673438648223800e-02, 2.6302871464332994e-01, 4.3840919719805421e-01, 6.1383172560234123e-01, 7.8931319165491054e-01, 9.6487056093471757e-01, 1.1405208943427161e+00, 1.3162813699945290e+00, 1.4921693055472409e+00, 1.6682021810467551e+00, 1.8443976623860776e+00, 2.0207736254695439e+00, 2.1973481811834414e+00, 2.3741397012797925e+00, 2.5511668452873062e+00, 2.7284485885718048e+00, 2.9060042516778903e+00, 3.0838535310943649e+00, 3.2620165315981051e+00, 3.4405138003449269e+00, 3.6193663628916424e+00, 3.7985957613512462e+00, 3.9782240949032923e+00, 4.1582740629043391e+00, 4.3387690108692292e+00, 4.5197329796234431e+00, 4.7011907579602283e+00, 4.8831679391745020e+00, 5.0656909818891060e+00, 5.2487872756390139e+00, 5.4324852117363971e+00, 5.6168142600053486e+00, 5.8018050520510185e+00, 5.9874894718156684e+00, 6.1739007542758424e+00, 6.3610735932529767e+00, 6.5490442594474336e+00, 6.7378507299670023e+00, 6.9275328308096045e+00, 7.1181323939823153e+00, 7.3096934312013273e+00, 7.5022623264288848e+00, 7.6958880498740347e+00, 7.8906223965273750e+00, 8.0865202528325053e+00, 8.2836398957394959e+00, 8.4820433291649113e+00, 8.6817966638328432e+00, 8.8829705476356562e+00, 9.0856406550885644e+00, 9.2898882462326107e+00, 9.4958008075637199e+00, 9.7034727903605109e+00, 9.9130064653237309e+00, 1.0124512916959700e+01, 1.0338113206958853e+01, 1.0553939743380022e+01, 1.0772137902368133e+01, 1.0992867962280265e+01, 1.1216307427723020e+01, 1.1442653844932979e+01, 1.1672128242851137e+01, 1.1904979380197393e+01, 1.2141489044042531e+01, 1.2381978739506893e+01, 1.2626818248827179e+01, 1.2876436746658081e+01, 1.3131337480278725e+01, 1.3392117533718560e+01, 1.3659495030180320e+01, 1.3934347545235219e+01, 1.4217768014947598e+01, 1.4511149100314286e+01, 1.4816316219712570e+01, 1.5135749157814335e+01, 1.5472978191373558e+01, 1.5833362176266244e+01, 1.6225835391124875e+01, 1.6667734404468501e+01, 1.7204433257886514e+01}, + {-1.7260909703781458e+01, -1.6724791300392337e+01, -1.6283381096937688e+01, -1.5891350549206285e+01, -1.5531380320925585e+01, -1.5194544951785256e+01, -1.4875490845359661e+01, -1.4570691174443654e+01, -1.4277668569732091e+01, -1.3994599387373768e+01, -1.3720092319274791e+01, -1.3453055491772846e+01, -1.3192612184064762e+01, -1.2938044974817329e+01, -1.2688757366462070e+01, -1.2444246609242258e+01, -1.2204083956265350e+01, -1.1967899997504619e+01, -1.1735373555229600e+01, -1.1506223133185523e+01, -1.1280200233327742e+01, -1.1057084062337088e+01, -1.0836677288618299e+01, -1.0618802604522946e+01, -1.0403299913666036e+01, -1.0190024009115621e+01, -9.9788426411218261e+00, -9.7696348969572284e+00, -9.5622898330514161e+00, -9.3567053127370503e+00, -9.1527870128321815e+00, -8.9504475698358625e+00, -8.7496058423271297e+00, -8.5501862706726577e+00, -8.3521183186851253e+00, -8.1553359846666886e+00, -7.9597773714928959e+00, -7.7653843071712023e+00, -7.5721020087422000e+00, -7.3798787835549238e+00, -7.1886657628964983e+00, -6.9984166637349920e+00, -6.8090875749762771e+00, -6.6206367651677347e+00, -6.4330245090246105e+00, -6.2462129305252470e+00, -6.0601658606325453e+00, -5.8748487079613687e+00, -5.6902283409336283e+00, -5.5062729801514685e+00, -5.3229520998798137e+00, -5.1402363376670781e+00, -4.9580974112509208e+00, -4.7765080419975057e+00, -4.5954418842104330e+00, -4.4148734597213917e+00, -4.2347780972404623e+00, -4.0551318760012771e+00, -3.8759115732862068e+00, -3.6970946154603719e+00, -3.5186590321815130e+00, -3.3405834134862555e+00, -3.1628468694827729e+00, -2.9854289924057533e+00, -2.8083098208124282e+00, -2.6314698057185479e+00, -2.4548897784909895e+00, -2.2785509203293697e+00, -2.1024347331829158e+00, -1.9265230119611116e+00, -1.7507978179074160e+00, -1.5752414530149108e+00, -1.3998364353710842e+00, -1.2245654753263127e+00, -1.0494114523869875e+00, -8.7435739273980528e-01, -6.9938644731849353e-01, -5.2448187032830795e-01, -3.4962699814701426e-01, -1.7480522852383426e-01, -0.0000000000000000e+00, 1.7480522852383426e-01, 3.4962699814701426e-01, 5.2448187032830795e-01, 6.9938644731849353e-01, 8.7435739273980528e-01, 1.0494114523869875e+00, 1.2245654753263127e+00, 1.3998364353710842e+00, 1.5752414530149108e+00, 1.7507978179074160e+00, 1.9265230119611116e+00, 2.1024347331829158e+00, 2.2785509203293697e+00, 2.4548897784909895e+00, 2.6314698057185479e+00, 2.8083098208124282e+00, 2.9854289924057533e+00, 3.1628468694827729e+00, 3.3405834134862555e+00, 3.5186590321815130e+00, 3.6970946154603719e+00, 3.8759115732862068e+00, 4.0551318760012771e+00, 4.2347780972404623e+00, 4.4148734597213917e+00, 4.5954418842104330e+00, 4.7765080419975057e+00, 4.9580974112509208e+00, 5.1402363376670781e+00, 5.3229520998798137e+00, 5.5062729801514685e+00, 5.6902283409336283e+00, 5.8748487079613687e+00, 6.0601658606325453e+00, 6.2462129305252470e+00, 6.4330245090246105e+00, 6.6206367651677347e+00, 6.8090875749762771e+00, 6.9984166637349920e+00, 7.1886657628964983e+00, 7.3798787835549238e+00, 7.5721020087422000e+00, 7.7653843071712023e+00, 7.9597773714928959e+00, 8.1553359846666886e+00, 8.3521183186851253e+00, 8.5501862706726577e+00, 8.7496058423271297e+00, 8.9504475698358625e+00, 9.1527870128321815e+00, 9.3567053127370503e+00, 9.5622898330514161e+00, 9.7696348969572284e+00, 9.9788426411218261e+00, 1.0190024009115621e+01, 1.0403299913666036e+01, 1.0618802604522946e+01, 1.0836677288618299e+01, 1.1057084062337088e+01, 1.1280200233327742e+01, 1.1506223133185523e+01, 1.1735373555229600e+01, 1.1967899997504619e+01, 1.2204083956265350e+01, 1.2444246609242258e+01, 1.2688757366462070e+01, 1.2938044974817329e+01, 1.3192612184064762e+01, 1.3453055491772846e+01, 1.3720092319274791e+01, 1.3994599387373768e+01, 1.4277668569732091e+01, 1.4570691174443654e+01, 1.4875490845359661e+01, 1.5194544951785256e+01, 1.5531380320925585e+01, 1.5891350549206285e+01, 1.6283381096937688e+01, 1.6724791300392337e+01, 1.7260909703781458e+01}, + {-1.7317208433270949e+01, -1.6781666167619914e+01, -1.6340741083473855e+01, -1.5949149813561979e+01, -1.5589590133082927e+01, -1.5253145338412237e+01, -1.4934467055837311e+01, -1.4630031883570041e+01, -1.4337364850710150e+01, -1.4054644075392147e+01, -1.3780479592778537e+01, -1.3513780583944808e+01, -1.3253671176599115e+01, -1.2999434646049597e+01, -1.2750475076730016e+01, -1.2506290212533999e+01, -1.2266451730913499e+01, -1.2030590590990464e+01, -1.1798385939645330e+01, -1.1569556568885659e+01, -1.1343854238969067e+01, -1.1121058389970566e+01, -1.0900971902825360e+01, -1.0683417664825948e+01, -1.0468235759616565e+01, -1.0255281147593752e+01, -1.0044421735476904e+01, -9.8355367576951434e+00, -9.6285154098307064e+00, -9.4232556874808058e+00, -9.2196633937979797e+00, -9.0176512865137788e+00, -8.8171383410582820e+00, -8.6180491108986974e+00, -8.4203131697537437e+00, -8.2238646231301775e+00, -8.0286416788466841e+00, -7.8345862679873983e+00, -7.6416437091600784e+00, -7.4497624100959028e+00, -7.2588936015760819e+00, -7.0689910994481711e+00, -6.8800110911364190e+00, -6.6919119435819789e+00, -6.5046540299913760e+00, -6.3181995731417278e+00, -6.1325125033020340e+00, -5.9475583290919758e+00, -5.7633040198215193e+00, -5.5797178980431177e+00, -5.3967695412089913e+00, -5.2144296914634500e+00, -5.0326701727181335e+00, -4.8514638142596134e+00, -4.6707843802263858e+00, -4.4906065043681664e+00, -4.3109056295662098e+00, -4.1316579516506131e+00, -3.9528403671005403e+00, -3.7744304242568925e+00, -3.5964062777151744e+00, -3.4187466455998319e+00, -3.2414307694507918e+00, -3.0644383764788512e+00, -2.8877496439694483e+00, -2.7113451656344782e+00, -2.5352059197296661e+00, -2.3593132387707172e+00, -2.1836487806954117e+00, -2.0081945013310838e+00, -1.8329326280378133e+00, -1.6578456344072345e+00, -1.4829162159053173e+00, -1.3081272663548922e+00, -1.1334618551601847e+00, -9.5890320518127026e-01, -7.8443467117124477e-01, -6.1003971869307638e-01, -4.3570190343662574e-01, -2.6140485085923082e-01, -8.7132236075583736e-02, 8.7132236075583736e-02, 2.6140485085923082e-01, 4.3570190343662574e-01, 6.1003971869307638e-01, 7.8443467117124477e-01, 9.5890320518127026e-01, 1.1334618551601847e+00, 1.3081272663548922e+00, 1.4829162159053173e+00, 1.6578456344072345e+00, 1.8329326280378133e+00, 2.0081945013310838e+00, 2.1836487806954117e+00, 2.3593132387707172e+00, 2.5352059197296661e+00, 2.7113451656344782e+00, 2.8877496439694483e+00, 3.0644383764788512e+00, 3.2414307694507918e+00, 3.4187466455998319e+00, 3.5964062777151744e+00, 3.7744304242568925e+00, 3.9528403671005403e+00, 4.1316579516506131e+00, 4.3109056295662098e+00, 4.4906065043681664e+00, 4.6707843802263858e+00, 4.8514638142596134e+00, 5.0326701727181335e+00, 5.2144296914634500e+00, 5.3967695412089913e+00, 5.5797178980431177e+00, 5.7633040198215193e+00, 5.9475583290919758e+00, 6.1325125033020340e+00, 6.3181995731417278e+00, 6.5046540299913760e+00, 6.6919119435819789e+00, 6.8800110911364190e+00, 7.0689910994481711e+00, 7.2588936015760819e+00, 7.4497624100959028e+00, 7.6416437091600784e+00, 7.8345862679873983e+00, 8.0286416788466841e+00, 8.2238646231301775e+00, 8.4203131697537437e+00, 8.6180491108986974e+00, 8.8171383410582820e+00, 9.0176512865137788e+00, 9.2196633937979797e+00, 9.4232556874808058e+00, 9.6285154098307064e+00, 9.8355367576951434e+00, 1.0044421735476904e+01, 1.0255281147593752e+01, 1.0468235759616565e+01, 1.0683417664825948e+01, 1.0900971902825360e+01, 1.1121058389970566e+01, 1.1343854238969067e+01, 1.1569556568885659e+01, 1.1798385939645330e+01, 1.2030590590990464e+01, 1.2266451730913499e+01, 1.2506290212533999e+01, 1.2750475076730016e+01, 1.2999434646049597e+01, 1.3253671176599115e+01, 1.3513780583944808e+01, 1.3780479592778537e+01, 1.4054644075392147e+01, 1.4337364850710150e+01, 1.4630031883570041e+01, 1.4934467055837311e+01, 1.5253145338412237e+01, 1.5589590133082927e+01, 1.5949149813561979e+01, 1.6340741083473855e+01, 1.6781666167619914e+01, 1.7317208433270949e+01}, + {-1.7373331107186754e+01, -1.6838360725829279e+01, -1.6397917121470808e+01, -1.6006761787526802e+01, -1.5647609491464893e+01, -1.5311552225513632e+01, -1.4993246802416799e+01, -1.4689173221989655e+01, -1.4396858895000966e+01, -1.4114483689200235e+01, -1.3840658973492838e+01, -1.3574294976135944e+01, -1.3314516667182943e+01, -1.3060608013433232e+01, -1.2811973676932878e+01, -1.2568111891415747e+01, -1.2328594755317379e+01, -1.2093053593899976e+01, -1.1861167875925814e+01, -1.1632656679158853e+01, -1.1407272019832192e+01, -1.1184793569232429e+01, -1.0965024418758787e+01, -1.0747787648671435e+01, -1.0532923520744902e+01, -1.0320287160863774e+01, -1.0109746630421466e+01, -9.9011813092421690e+00, -9.6944805303231938e+00, -9.4895424198040619e+00, -9.2862729054572402e+00, -9.0845848645331397e+00, -8.8843973875939959e+00, -8.6856351394777924e+00, -8.4882278020634931e+00, -8.2921095862957674e+00, -8.0972188031442496e+00, -7.9034974849477484e+00, -7.7108910500251024e+00, -7.5193480045954200e+00, -7.3288196769976075e+00, -7.1392599799761927e+00, -6.9506251974411839e+00, -6.7628737926408222e+00, -6.5759662351281483e+00, -6.3898648442721324e+00, -6.2045336473746264e+00, -6.0199382507162937e+00, -5.8360457220763333e+00, -5.6528244834591428e+00, -5.4702442129216378e+00, -5.2882757545322603e+00, -5.1068910356106052e+00, -4.9260629904980000e+00, -4.7457654901969706e+00, -4.5659732772932937e+00, -4.3866619056401390e+00, -4.2078076843410157e+00, -4.0293876256181580e+00, -3.8513793961965916e+00, -3.6737612718723360e+00, -3.4965120949666812e+00, -3.3196112343979944e+00, -3.1430385481283984e+00, -2.9667743477655746e+00, -2.7907993651201082e+00, -2.6150947205366424e+00, -2.4396418928328796e+00, -2.2644226906944231e+00, -2.0894192253858019e+00, -1.9146138846489213e+00, -1.7399893076698572e+00, -1.5655283610033905e+00, -1.3912141153521926e+00, -1.2170298231041317e+00, -1.0429588965369114e+00, -8.6898488660423323e-01, -6.9509146222196017e-01, -5.2126238997639096e-01, -3.4748151417981160e-01, -1.7373273720096005e-01, -0.0000000000000000e+00, 1.7373273720096005e-01, 3.4748151417981160e-01, 5.2126238997639096e-01, 6.9509146222196017e-01, 8.6898488660423323e-01, 1.0429588965369114e+00, 1.2170298231041317e+00, 1.3912141153521926e+00, 1.5655283610033905e+00, 1.7399893076698572e+00, 1.9146138846489213e+00, 2.0894192253858019e+00, 2.2644226906944231e+00, 2.4396418928328796e+00, 2.6150947205366424e+00, 2.7907993651201082e+00, 2.9667743477655746e+00, 3.1430385481283984e+00, 3.3196112343979944e+00, 3.4965120949666812e+00, 3.6737612718723360e+00, 3.8513793961965916e+00, 4.0293876256181580e+00, 4.2078076843410157e+00, 4.3866619056401390e+00, 4.5659732772932937e+00, 4.7457654901969706e+00, 4.9260629904980000e+00, 5.1068910356106052e+00, 5.2882757545322603e+00, 5.4702442129216378e+00, 5.6528244834591428e+00, 5.8360457220763333e+00, 6.0199382507162937e+00, 6.2045336473746264e+00, 6.3898648442721324e+00, 6.5759662351281483e+00, 6.7628737926408222e+00, 6.9506251974411839e+00, 7.1392599799761927e+00, 7.3288196769976075e+00, 7.5193480045954200e+00, 7.7108910500251024e+00, 7.9034974849477484e+00, 8.0972188031442496e+00, 8.2921095862957674e+00, 8.4882278020634931e+00, 8.6856351394777924e+00, 8.8843973875939959e+00, 9.0845848645331397e+00, 9.2862729054572402e+00, 9.4895424198040619e+00, 9.6944805303231938e+00, 9.9011813092421690e+00, 1.0109746630421466e+01, 1.0320287160863774e+01, 1.0532923520744902e+01, 1.0747787648671435e+01, 1.0965024418758787e+01, 1.1184793569232429e+01, 1.1407272019832192e+01, 1.1632656679158853e+01, 1.1861167875925814e+01, 1.2093053593899976e+01, 1.2328594755317379e+01, 1.2568111891415747e+01, 1.2811973676932878e+01, 1.3060608013433232e+01, 1.3314516667182943e+01, 1.3574294976135944e+01, 1.3840658973492838e+01, 1.4114483689200235e+01, 1.4396858895000966e+01, 1.4689173221989655e+01, 1.4993246802416799e+01, 1.5311552225513632e+01, 1.5647609491464893e+01, 1.6006761787526802e+01, 1.6397917121470808e+01, 1.6838360725829279e+01, 1.7373331107186754e+01}, + {-1.7429279360697116e+01, -1.6894876667871738e+01, -1.6454910953817389e+01, -1.6064188260485547e+01, -1.5705440229953897e+01, -1.5369767490259161e+01, -1.5051832004816319e+01, -1.4748117151542182e+01, -1.4456152706360307e+01, -1.4174120274430678e+01, -1.3900632549018214e+01, -1.3634600798111430e+01, -1.3375150828031479e+01, -1.3121567291995134e+01, -1.2873255425338009e+01, -1.2629713947884454e+01, -1.2390515375747968e+01, -1.2155291397374004e+01, -1.1923721800726158e+01, -1.1695525946865237e+01, -1.1470456105717808e+01, -1.1248292177643179e+01, -1.1028837462481100e+01, -1.0811915231528733e+01, -1.0597365922834403e+01, -1.0385044825972880e+01, -1.0174820155259216e+01, -9.9665714341945719e+00, -9.7601881314978272e+00, -9.5555685021734451e+00, -9.3526185969451436e+00, -9.1512514109155187e+00, -8.9513861481082948e+00, -8.7529475830520980e+00, -8.5558655040914431e+00, -8.3600742258949641e+00, -8.1655121608455978e+00, -7.9721214407712111e+00, -7.7798475819041020e+00, -7.5886391871177059e+00, -7.3984476804351802e+00, -7.2092270695808969e+00, -7.0209337329860251e+00, -6.8335262281900011e+00, -6.6469651190213561e+00, -6.4612128193108518e+00, -6.2762334512001194e+00, -6.0919927163706555e+00, -5.9084577787394661e+00, -5.7255971573558835e+00, -5.5433806283944191e+00, -5.3617791352758264e+00, -5.1807647060662454e+00, -5.0003103774057065e+00, -4.8203901243047591e+00, -4.6409787952237167e+00, -4.4620520519147870e+00, -4.2835863135645020e+00, -4.1055587048237943e+00, -3.9279470073566172e+00, -3.7507296145762479e+00, -3.5738854892718694e+00, -3.3973941238575383e+00, -3.2212355030015671e+00, -3.0453900684172543e+00, -2.8698386856160685e+00, -2.6945626124422972e+00, -2.5195434692239367e+00, -2.3447632103886216e+00, -2.1702040974057377e+00, -1.9958486729268685e+00, -1.8216797360063830e+00, -1.6476803182925728e+00, -1.4738336610872771e+00, -1.3001231931786021e+00, -1.1265325093571319e+00, -9.5304534953113307e-01, -7.7964557836059989e-01, -6.0631716533377134e-01, -4.3304416521289407e-01, -2.5981069877863450e-01, -8.6600933804640304e-02, 8.6600933804640304e-02, 2.5981069877863450e-01, 4.3304416521289407e-01, 6.0631716533377134e-01, 7.7964557836059989e-01, 9.5304534953113307e-01, 1.1265325093571319e+00, 1.3001231931786021e+00, 1.4738336610872771e+00, 1.6476803182925728e+00, 1.8216797360063830e+00, 1.9958486729268685e+00, 2.1702040974057377e+00, 2.3447632103886216e+00, 2.5195434692239367e+00, 2.6945626124422972e+00, 2.8698386856160685e+00, 3.0453900684172543e+00, 3.2212355030015671e+00, 3.3973941238575383e+00, 3.5738854892718694e+00, 3.7507296145762479e+00, 3.9279470073566172e+00, 4.1055587048237943e+00, 4.2835863135645020e+00, 4.4620520519147870e+00, 4.6409787952237167e+00, 4.8203901243047591e+00, 5.0003103774057065e+00, 5.1807647060662454e+00, 5.3617791352758264e+00, 5.5433806283944191e+00, 5.7255971573558835e+00, 5.9084577787394661e+00, 6.0919927163706555e+00, 6.2762334512001194e+00, 6.4612128193108518e+00, 6.6469651190213561e+00, 6.8335262281900011e+00, 7.0209337329860251e+00, 7.2092270695808969e+00, 7.3984476804351802e+00, 7.5886391871177059e+00, 7.7798475819041020e+00, 7.9721214407712111e+00, 8.1655121608455978e+00, 8.3600742258949641e+00, 8.5558655040914431e+00, 8.7529475830520980e+00, 8.9513861481082948e+00, 9.1512514109155187e+00, 9.3526185969451436e+00, 9.5555685021734451e+00, 9.7601881314978272e+00, 9.9665714341945719e+00, 1.0174820155259216e+01, 1.0385044825972880e+01, 1.0597365922834403e+01, 1.0811915231528733e+01, 1.1028837462481100e+01, 1.1248292177643179e+01, 1.1470456105717808e+01, 1.1695525946865237e+01, 1.1923721800726158e+01, 1.2155291397374004e+01, 1.2390515375747968e+01, 1.2629713947884454e+01, 1.2873255425338009e+01, 1.3121567291995134e+01, 1.3375150828031479e+01, 1.3634600798111430e+01, 1.3900632549018214e+01, 1.4174120274430678e+01, 1.4456152706360307e+01, 1.4748117151542182e+01, 1.5051832004816319e+01, 1.5369767490259161e+01, 1.5705440229953897e+01, 1.6064188260485547e+01, 1.6454910953817389e+01, 1.6894876667871738e+01, 1.7429279360697116e+01}, + {-1.7485054803857970e+01, -1.6951215660353082e+01, -1.6511724296161706e+01, -1.6121430993647511e+01, -1.5763084153353320e+01, -1.5427792979852288e+01, -1.5110224551907818e+01, -1.4806865602342286e+01, -1.4515248255936989e+01, -1.4233555843220696e+01, -1.3960402372562056e+01, -1.3694700144334103e+01, -1.3435575795134914e+01, -1.3182314659599264e+01, -1.2934322542095073e+01, -1.2691098644846306e+01, -1.2452215898392630e+01, -1.2217306351455802e+01, -1.1986050108567399e+01, -1.1758166811670554e+01, -1.1533408982146776e+01, -1.1311556747331544e+01, -1.1092413613523263e+01, -1.0875803041166620e+01, -1.0661565642768281e+01, -1.0449556869836458e+01, -1.0239645087896863e+01, -1.0031709962451384e+01, -9.8256410962894503e+00, -9.6213368716463528e+00, -9.4187034605725390e+00, -9.2176539744013386e+00, -9.0181077289936873e+00, -8.8199896069364012e+00, -8.6232295013939773e+00, -8.4277618290957275e+00, -8.2335251021525675e+00, -8.0404615501699581e+00, -7.8485167855520830e+00, -7.6576395060512166e+00, -7.4677812295616199e+00, -7.2788960569330223e+00, -7.0909404592182668e+00, -6.9038730862998348e+00, -6.7176545942812487e+00, -6.5322474893984905e+00, -6.3476159865165220e+00, -6.1637258805374548e+00, -5.9805444292681393e+00, -5.7980402464829925e+00, -5.6161832040781530e+00, -5.4349443423501533e+00, -5.2542957875499878e+00, -5.0742106759647410e+00, -4.8946630838663463e+00, -4.7156279627427748e+00, -4.5370810792926148e+00, -4.3589989597211884e+00, -4.1813588379261919e+00, -4.0041386072044292e+00, -3.8273167751493955e+00, -3.6508724214429682e+00, -3.4747851582739164e+00, -3.2990350931419172e+00, -3.1236027938286419e+00, -2.9484692553376957e+00, -2.7736158686231027e+00, -2.5990243909418167e+00, -2.4246769176797933e+00, -2.2505558555135576e+00, -2.0766438967802112e+00, -1.9029239949385686e+00, -1.7293793410127316e+00, -1.5559933409170248e+00, -1.3827495935679281e+00, -1.2096318696945301e+00, -1.0366240912641824e+00, -8.6371031144450516e-01, -6.9087469502674481e-01, -5.1810149923876170e-01, -3.4537505487866837e-01, -1.7267974770236652e-01, -0.0000000000000000e+00, 1.7267974770236652e-01, 3.4537505487866837e-01, 5.1810149923876170e-01, 6.9087469502674481e-01, 8.6371031144450516e-01, 1.0366240912641824e+00, 1.2096318696945301e+00, 1.3827495935679281e+00, 1.5559933409170248e+00, 1.7293793410127316e+00, 1.9029239949385686e+00, 2.0766438967802112e+00, 2.2505558555135576e+00, 2.4246769176797933e+00, 2.5990243909418167e+00, 2.7736158686231027e+00, 2.9484692553376957e+00, 3.1236027938286419e+00, 3.2990350931419172e+00, 3.4747851582739164e+00, 3.6508724214429682e+00, 3.8273167751493955e+00, 4.0041386072044292e+00, 4.1813588379261919e+00, 4.3589989597211884e+00, 4.5370810792926148e+00, 4.7156279627427748e+00, 4.8946630838663463e+00, 5.0742106759647410e+00, 5.2542957875499878e+00, 5.4349443423501533e+00, 5.6161832040781530e+00, 5.7980402464829925e+00, 5.9805444292681393e+00, 6.1637258805374548e+00, 6.3476159865165220e+00, 6.5322474893984905e+00, 6.7176545942812487e+00, 6.9038730862998348e+00, 7.0909404592182668e+00, 7.2788960569330223e+00, 7.4677812295616199e+00, 7.6576395060512166e+00, 7.8485167855520830e+00, 8.0404615501699581e+00, 8.2335251021525675e+00, 8.4277618290957275e+00, 8.6232295013939773e+00, 8.8199896069364012e+00, 9.0181077289936873e+00, 9.2176539744013386e+00, 9.4187034605725390e+00, 9.6213368716463528e+00, 9.8256410962894503e+00, 1.0031709962451384e+01, 1.0239645087896863e+01, 1.0449556869836458e+01, 1.0661565642768281e+01, 1.0875803041166620e+01, 1.1092413613523263e+01, 1.1311556747331544e+01, 1.1533408982146776e+01, 1.1758166811670554e+01, 1.1986050108567399e+01, 1.2217306351455802e+01, 1.2452215898392630e+01, 1.2691098644846306e+01, 1.2934322542095073e+01, 1.3182314659599264e+01, 1.3435575795134914e+01, 1.3694700144334103e+01, 1.3960402372562056e+01, 1.4233555843220696e+01, 1.4515248255936989e+01, 1.4806865602342286e+01, 1.5110224551907818e+01, 1.5427792979852288e+01, 1.5763084153353320e+01, 1.6121430993647511e+01, 1.6511724296161706e+01, 1.6951215660353082e+01, 1.7485054803857970e+01}, + {-1.7540659022148994e+01, -1.7007379344198675e+01, -1.6568358837502078e+01, -1.6178491720661924e+01, -1.5820543038026845e+01, -1.5485630512193200e+01, -1.5168426302403656e+01, -1.4865420473490115e+01, -1.4574147483007465e+01, -1.4292792374971157e+01, -1.4019970463722631e+01, -1.3754595074773901e+01, -1.3495793669093878e+01, -1.3242852257808744e+01, -1.2995177210125478e+01, -1.2752268207034200e+01, -1.2513698590301434e+01, -1.2279100766067012e+01, -1.2048155152843032e+01, -1.1820581671084192e+01, -1.1596133091430600e+01, -1.1374589766138451e+01, -1.1155755406023257e+01, -1.0939453658827642e+01, -1.0725525309740862e+01, -1.0513825970487574e+01, -1.0304224156133158e+01, -1.0096599672544393e+01, -9.8908422549712061e+00, -9.6868504112873062e+00, -9.4845304332878886e+00, -9.2837955469590963e+00, -9.0845651784194441e+00, -8.8867643167273460e+00, -8.6903229582689274e+00, -8.4951756202195732e+00, -8.3012609127831123e+00, -8.1085211616830808e+00, -7.9169020738077709e+00, -7.7263524400685295e+00, -7.5368238704753843e+00, -7.3482705572089442e+00, -7.1606490621065957e+00, -6.9739181255105622e+00, -6.7880384938663552e+00, -6.6029727638288866e+00, -6.4186852409432520e+00, -6.2351418112283552e+00, -6.0523098242126343e+00, -5.8701579861589899e+00, -5.6886562623761669e+00, -5.5077757876508500e+00, -5.3274887839522851e+00, -5.1477684846624596e+00, -4.9685890646722539e+00, -4.7899255757595700e+00, -4.6117538867311527e+00, -4.4340506278668892e+00, -4.2567931392552376e+00, -4.0799594226519913e+00, -3.9035280965327215e+00, -3.7274783540427840e+00, -3.5517899235782049e+00, -3.3764430317567267e+00, -3.2014183685612045e+00, -3.0266970544577654e+00, -2.8522606093090528e+00, -2.6780909229187282e+00, -2.5041702270574335e+00, -2.3304810688329010e+00, -2.1570062852778933e+00, -1.9837289790394881e+00, -1.8106324950618549e+00, -1.6377003981623639e+00, -1.4649164514076216e+00, -1.2922645952019900e+00, -1.1197289270063837e+00, -9.4729368160967065e-01, -7.7494321187896786e-01, -6.0266196991848653e-01, -4.3043448856942984e-01, -2.5824536318581770e-01, -8.6079233622990678e-02, 8.6079233622990678e-02, 2.5824536318581770e-01, 4.3043448856942984e-01, 6.0266196991848653e-01, 7.7494321187896786e-01, 9.4729368160967065e-01, 1.1197289270063837e+00, 1.2922645952019900e+00, 1.4649164514076216e+00, 1.6377003981623639e+00, 1.8106324950618549e+00, 1.9837289790394881e+00, 2.1570062852778933e+00, 2.3304810688329010e+00, 2.5041702270574335e+00, 2.6780909229187282e+00, 2.8522606093090528e+00, 3.0266970544577654e+00, 3.2014183685612045e+00, 3.3764430317567267e+00, 3.5517899235782049e+00, 3.7274783540427840e+00, 3.9035280965327215e+00, 4.0799594226519913e+00, 4.2567931392552376e+00, 4.4340506278668892e+00, 4.6117538867311527e+00, 4.7899255757595700e+00, 4.9685890646722539e+00, 5.1477684846624596e+00, 5.3274887839522851e+00, 5.5077757876508500e+00, 5.6886562623761669e+00, 5.8701579861589899e+00, 6.0523098242126343e+00, 6.2351418112283552e+00, 6.4186852409432520e+00, 6.6029727638288866e+00, 6.7880384938663552e+00, 6.9739181255105622e+00, 7.1606490621065957e+00, 7.3482705572089442e+00, 7.5368238704753843e+00, 7.7263524400685295e+00, 7.9169020738077709e+00, 8.1085211616830808e+00, 8.3012609127831123e+00, 8.4951756202195732e+00, 8.6903229582689274e+00, 8.8867643167273460e+00, 9.0845651784194441e+00, 9.2837955469590963e+00, 9.4845304332878886e+00, 9.6868504112873062e+00, 9.8908422549712061e+00, 1.0096599672544393e+01, 1.0304224156133158e+01, 1.0513825970487574e+01, 1.0725525309740862e+01, 1.0939453658827642e+01, 1.1155755406023257e+01, 1.1374589766138451e+01, 1.1596133091430600e+01, 1.1820581671084192e+01, 1.2048155152843032e+01, 1.2279100766067012e+01, 1.2513698590301434e+01, 1.2752268207034200e+01, 1.2995177210125478e+01, 1.3242852257808744e+01, 1.3495793669093878e+01, 1.3754595074773901e+01, 1.4019970463722631e+01, 1.4292792374971157e+01, 1.4574147483007465e+01, 1.4865420473490115e+01, 1.5168426302403656e+01, 1.5485630512193200e+01, 1.5820543038026845e+01, 1.6178491720661924e+01, 1.6568358837502078e+01, 1.7007379344198675e+01, 1.7540659022148994e+01}, + {-1.7596093576995067e+01, -1.7063369335203092e+01, -1.6624816240761632e+01, -1.6235372148216229e+01, -1.5877818632519856e+01, -1.5543281876523103e+01, -1.5226439085523806e+01, -1.4923783633761518e+01, -1.4632852295689380e+01, -1.4351831817083784e+01, -1.4079338809250348e+01, -1.3814287615693701e+01, -1.3555806515930390e+01, -1.3303182192722531e+01, -1.3055821575985398e+01, -1.2813224821897842e+01, -1.2574965680305057e+01, -1.2340676911954159e+01, -1.2110039246794949e+01, -1.1882772881465453e+01, -1.1658630833708994e+01, -1.1437393678686862e+01, -1.1218865329829219e+01, -1.1002869620365653e+01, -1.0789247506430682e+01, -1.0577854758286833e+01, -1.0368560038906804e+01, -1.0161243292925425e+01, -9.9557943864826086e+00, -9.7521119515382608e+00, -9.5501023980913669e+00, -9.3496790652448780e+00, -9.1507614878382224e+00, -8.9532747598589513e+00, -8.7571489793618653e+00, -8.5623187624005972e+00, -8.3687228156851035e+00, -8.1763035594473781e+00, -7.9850067934236462e+00, -7.7947814000180404e+00, -7.6055790796564340e+00, -7.4173541141133637e+00, -7.2300631542333695e+00, -7.0436650289972214e+00, -6.8581205733240118e+00, -6.6733924723685520e+00, -6.4894451203829293e+00, -6.3062444924720467e+00, -6.1237580277938539e+00, -5.9419545229426243e+00, -5.7608040344137255e+00, -5.5802777891851223e+00, -5.4003481025684028e+00, -5.2209883025831942e+00, -5.0421726601961838e+00, -4.8638763248414749e+00, -4.6860752647046970e+00, -4.5087462113102941e+00, -4.3318666080012935e+00, -4.1554145619443341e+00, -3.9793687993309228e+00, -3.8037086234793556e+00, -3.6284138755712148e+00, -3.4534648977822986e+00, -3.2788424985907505e+00, -3.1045279200654083e+00, -2.9305028069552952e+00, -2.7567491774170563e+00, -2.5832493952312059e+00, -2.4099861433705372e+00, -2.2369423987951111e+00, -2.0641014083580762e+00, -1.8914466657152740e+00, -1.7189618891393004e+00, -1.5466310001455315e+00, -1.3744381028436181e+00, -1.2023674639332740e+00, -1.0304034932677821e+00, -8.5853072491269411e-01, -6.8673379863064854e-01, -5.1499744172618944e-01, -3.4330645118694048e-01, -1.7164567605949776e-01, -0.0000000000000000e+00, 1.7164567605949776e-01, 3.4330645118694048e-01, 5.1499744172618944e-01, 6.8673379863064854e-01, 8.5853072491269411e-01, 1.0304034932677821e+00, 1.2023674639332740e+00, 1.3744381028436181e+00, 1.5466310001455315e+00, 1.7189618891393004e+00, 1.8914466657152740e+00, 2.0641014083580762e+00, 2.2369423987951111e+00, 2.4099861433705372e+00, 2.5832493952312059e+00, 2.7567491774170563e+00, 2.9305028069552952e+00, 3.1045279200654083e+00, 3.2788424985907505e+00, 3.4534648977822986e+00, 3.6284138755712148e+00, 3.8037086234793556e+00, 3.9793687993309228e+00, 4.1554145619443341e+00, 4.3318666080012935e+00, 4.5087462113102941e+00, 4.6860752647046970e+00, 4.8638763248414749e+00, 5.0421726601961838e+00, 5.2209883025831942e+00, 5.4003481025684028e+00, 5.5802777891851223e+00, 5.7608040344137255e+00, 5.9419545229426243e+00, 6.1237580277938539e+00, 6.3062444924720467e+00, 6.4894451203829293e+00, 6.6733924723685520e+00, 6.8581205733240118e+00, 7.0436650289972214e+00, 7.2300631542333695e+00, 7.4173541141133637e+00, 7.6055790796564340e+00, 7.7947814000180404e+00, 7.9850067934236462e+00, 8.1763035594473781e+00, 8.3687228156851035e+00, 8.5623187624005972e+00, 8.7571489793618653e+00, 8.9532747598589513e+00, 9.1507614878382224e+00, 9.3496790652448780e+00, 9.5501023980913669e+00, 9.7521119515382608e+00, 9.9557943864826086e+00, 1.0161243292925425e+01, 1.0368560038906804e+01, 1.0577854758286833e+01, 1.0789247506430682e+01, 1.1002869620365653e+01, 1.1218865329829219e+01, 1.1437393678686862e+01, 1.1658630833708994e+01, 1.1882772881465453e+01, 1.2110039246794949e+01, 1.2340676911954159e+01, 1.2574965680305057e+01, 1.2813224821897842e+01, 1.3055821575985398e+01, 1.3303182192722531e+01, 1.3555806515930390e+01, 1.3814287615693701e+01, 1.4079338809250348e+01, 1.4351831817083784e+01, 1.4632852295689380e+01, 1.4923783633761518e+01, 1.5226439085523806e+01, 1.5543281876523103e+01, 1.5877818632519856e+01, 1.6235372148216229e+01, 1.6624816240761632e+01, 1.7063369335203092e+01, 1.7596093576995067e+01}, + {-1.7651360006273592e+01, -1.7119187224564673e+01, -1.6681098143347068e+01, -1.6292073956617820e+01, -1.5934912658163535e+01, -1.5600748834050473e+01, -1.5284264701644213e+01, -1.4981956922278711e+01, -1.4691364571634727e+01, -1.4410676085677181e+01, -1.4138509363787067e+01, -1.3873779760412367e+01, -1.3615616367875141e+01, -1.3363306535787522e+01, -1.3116257750703349e+01, -1.2873970640467419e+01, -1.2636019359905287e+01, -1.2402037021606754e+01, -1.2171704664459938e+01, -1.1944742758999288e+01, -1.1720904567955738e+01, -1.1499970887418726e+01, -1.1281745831568482e+01, -1.1066053417347991e+01, -1.0852734770136896e+01, -1.0641645817094179e+01, -1.0432655367504838e+01, -1.0225643503212597e+01, -1.0020500219714993e+01, -9.8171242715446922e+00, -9.6154221854030180e+00, -9.4153074120141333e+00, -9.2166995934430851e+00, -9.0195239271065724e+00, -8.8237106112187824e+00, -8.6291943591887517e+00, -8.4359139726921839e+00, -8.2438119649078239e+00, -8.0528342268332285e+00, -7.8629297307503139e+00, -7.6740502658540599e+00, -7.4861502018311290e+00, -7.2991862768130868e+00, -7.1131174066575413e+00, -6.9279045129506267e+00, -6.7435103674923891e+00, -6.5598994513357987e+00, -6.3770378267108159e+00, -6.1948930203856341e+00, -6.0134339172047717e+00, -5.8326306627035311e+00, -5.6524545738351115e+00, -5.4728780569640936e+00, -5.2938745323809906e+00, -5.1154183646798366e+00, -4.9374847984163193e+00, -4.7600498985294708e+00, -4.5830904950670517e+00, -4.4065841318044781e+00, -4.2305090183906966e+00, -4.0548439856925214e+00, -3.8795684440424409e+00, -3.7046623441243547e+00, -3.5301061402576419e+00, -3.3558807558629016e+00, -3.1819675509129310e+00, -3.0083482911904582e+00, -2.8350051191900167e+00, -2.6619205265154431e+00, -2.4890773276369966e+00, -2.3164586348831824e+00, -2.1440478345522327e+00, -1.9718285640369488e+00, -1.7997846898643619e+00, -1.6279002865585475e+00, -1.4561596162410049e+00, -1.2845471088883613e+00, -1.1130473431718593e+00, -9.4164502780718806e-01, -7.7032498334676469e-01, -5.9907212434961710e-01, -4.2787144186658727e-01, -2.5670798618070745e-01, -8.5566849744303619e-02, 8.5566849744303619e-02, 2.5670798618070745e-01, 4.2787144186658727e-01, 5.9907212434961710e-01, 7.7032498334676469e-01, 9.4164502780718806e-01, 1.1130473431718593e+00, 1.2845471088883613e+00, 1.4561596162410049e+00, 1.6279002865585475e+00, 1.7997846898643619e+00, 1.9718285640369488e+00, 2.1440478345522327e+00, 2.3164586348831824e+00, 2.4890773276369966e+00, 2.6619205265154431e+00, 2.8350051191900167e+00, 3.0083482911904582e+00, 3.1819675509129310e+00, 3.3558807558629016e+00, 3.5301061402576419e+00, 3.7046623441243547e+00, 3.8795684440424409e+00, 4.0548439856925214e+00, 4.2305090183906966e+00, 4.4065841318044781e+00, 4.5830904950670517e+00, 4.7600498985294708e+00, 4.9374847984163193e+00, 5.1154183646798366e+00, 5.2938745323809906e+00, 5.4728780569640936e+00, 5.6524545738351115e+00, 5.8326306627035311e+00, 6.0134339172047717e+00, 6.1948930203856341e+00, 6.3770378267108159e+00, 6.5598994513357987e+00, 6.7435103674923891e+00, 6.9279045129506267e+00, 7.1131174066575413e+00, 7.2991862768130868e+00, 7.4861502018311290e+00, 7.6740502658540599e+00, 7.8629297307503139e+00, 8.0528342268332285e+00, 8.2438119649078239e+00, 8.4359139726921839e+00, 8.6291943591887517e+00, 8.8237106112187824e+00, 9.0195239271065724e+00, 9.2166995934430851e+00, 9.4153074120141333e+00, 9.6154221854030180e+00, 9.8171242715446922e+00, 1.0020500219714993e+01, 1.0225643503212597e+01, 1.0432655367504838e+01, 1.0641645817094179e+01, 1.0852734770136896e+01, 1.1066053417347991e+01, 1.1281745831568482e+01, 1.1499970887418726e+01, 1.1720904567955738e+01, 1.1944742758999288e+01, 1.2171704664459938e+01, 1.2402037021606754e+01, 1.2636019359905287e+01, 1.2873970640467419e+01, 1.3116257750703349e+01, 1.3363306535787522e+01, 1.3615616367875141e+01, 1.3873779760412367e+01, 1.4138509363787067e+01, 1.4410676085677181e+01, 1.4691364571634727e+01, 1.4981956922278711e+01, 1.5284264701644213e+01, 1.5600748834050473e+01, 1.5934912658163535e+01, 1.6292073956617820e+01, 1.6681098143347068e+01, 1.7119187224564673e+01, 1.7651360006273592e+01}, + {-1.7706459824808160e+01, -1.7174834579405605e+01, -1.6737206157692185e+01, -1.6348598800359760e+01, -1.5991826809662236e+01, -1.5658033118559841e+01, -1.5341904922927041e+01, -1.5039942149162044e+01, -1.4749686158703426e+01, -1.4469327066282485e+01, -1.4197484050584235e+01, -1.3933073470045795e+01, -1.3675225224131985e+01, -1.3423227324587016e+01, -1.3176487810593191e+01, -1.2934507778191829e+01, -1.2696861784139129e+01, -1.2463183290148008e+01, -1.2233153641587771e+01, -1.2006493580642585e+01, -1.1782956612954054e+01, -1.1562323753600294e+01, -1.1344399315683788e+01, -1.1129007498123606e+01, -1.0915989593880358e+01, -1.0705201685404040e+01, -1.0496512726733012e+01, -1.0289802935397134e+01, -1.0084962434756044e+01, -9.8818901004391417e+00, -9.6804925743867667e+00, -9.4806834174876062e+00, -9.2823823775768961e+00, -9.0855147540413785e+00, -8.8900108437873531e+00, -8.6958054560996842e+00, -8.5028374861240277e+00, -8.3110495384702450e+00, -8.1203875938581902e+00, -7.9308007128818385e+00, -7.7422407719095485e+00, -7.5546622269112049e+00, -7.3680219016401658e+00, -7.1822787971261874e+00, -6.9973939198751642e+00, -6.8133301265393582e+00, -6.6300519831306728e+00, -6.4475256371099929e+00, -6.2657187009061461e+00, -6.0846001456053820e+00, -5.9041402037120223e+00, -5.7243102800175727e+00, -5.5450828697328980e+00, -5.3664314831390003e+00, -5.1883305760991361e+00, -5.0107554858504457e+00, -4.8336823715588126e+00, -4.6570881591776718e+00, -4.4809504902012192e+00, -4.3052476739459955e+00, -4.1299586430328983e+00, -3.9550629117751774e+00, -3.7805405372073957e+00, -3.6063720825162893e+00, -3.4325385826573980e+00, -3.2590215119615689e+00, -3.0858027535533901e+00, -2.9128645704195151e+00, -2.7401895779789363e+00, -2.5677607180197990e+00, -2.3955612338784800e+00, -2.2235746467465418e+00, -2.0517847329999523e+00, -1.8801755024527722e+00, -1.7087311774444227e+00, -1.5374361726757684e+00, -1.3662750757146653e+00, -1.1952326280963763e+00, -1.0242937069484293e+00, -8.5344330707311145e-01, -6.8266652342392853e-01, -5.1194853391500583e-01, -3.4127458250465148e-01, -1.7062996249611376e-01, -0.0000000000000000e+00, 1.7062996249611376e-01, 3.4127458250465148e-01, 5.1194853391500583e-01, 6.8266652342392853e-01, 8.5344330707311145e-01, 1.0242937069484293e+00, 1.1952326280963763e+00, 1.3662750757146653e+00, 1.5374361726757684e+00, 1.7087311774444227e+00, 1.8801755024527722e+00, 2.0517847329999523e+00, 2.2235746467465418e+00, 2.3955612338784800e+00, 2.5677607180197990e+00, 2.7401895779789363e+00, 2.9128645704195151e+00, 3.0858027535533901e+00, 3.2590215119615689e+00, 3.4325385826573980e+00, 3.6063720825162893e+00, 3.7805405372073957e+00, 3.9550629117751774e+00, 4.1299586430328983e+00, 4.3052476739459955e+00, 4.4809504902012192e+00, 4.6570881591776718e+00, 4.8336823715588126e+00, 5.0107554858504457e+00, 5.1883305760991361e+00, 5.3664314831390003e+00, 5.5450828697328980e+00, 5.7243102800175727e+00, 5.9041402037120223e+00, 6.0846001456053820e+00, 6.2657187009061461e+00, 6.4475256371099929e+00, 6.6300519831306728e+00, 6.8133301265393582e+00, 6.9973939198751642e+00, 7.1822787971261874e+00, 7.3680219016401658e+00, 7.5546622269112049e+00, 7.7422407719095485e+00, 7.9308007128818385e+00, 8.1203875938581902e+00, 8.3110495384702450e+00, 8.5028374861240277e+00, 8.6958054560996842e+00, 8.8900108437873531e+00, 9.0855147540413785e+00, 9.2823823775768961e+00, 9.4806834174876062e+00, 9.6804925743867667e+00, 9.8818901004391417e+00, 1.0084962434756044e+01, 1.0289802935397134e+01, 1.0496512726733012e+01, 1.0705201685404040e+01, 1.0915989593880358e+01, 1.1129007498123606e+01, 1.1344399315683788e+01, 1.1562323753600294e+01, 1.1782956612954054e+01, 1.2006493580642585e+01, 1.2233153641587771e+01, 1.2463183290148008e+01, 1.2696861784139129e+01, 1.2934507778191829e+01, 1.3176487810593191e+01, 1.3423227324587016e+01, 1.3675225224131985e+01, 1.3933073470045795e+01, 1.4197484050584235e+01, 1.4469327066282485e+01, 1.4749686158703426e+01, 1.5039942149162044e+01, 1.5341904922927041e+01, 1.5658033118559841e+01, 1.5991826809662236e+01, 1.6348598800359760e+01, 1.6737206157692185e+01, 1.7174834579405605e+01, 1.7706459824808160e+01}, + {-1.7761394524848996e+01, -1.7230312943277969e+01, -1.6793141871786613e+01, -1.6404948308671031e+01, -1.6048562755664683e+01, -1.5715136437003761e+01, -1.5399361493933315e+01, -1.5097741096163510e+01, -1.4807818875617881e+01, -1.4527786614519313e+01, -1.4256264762200541e+01, -1.3992170674226745e+01, -1.3734635051620387e+01, -1.3482946563606328e+01, -1.3236513798043475e+01, -1.2994838315752334e+01, -1.2757495072417459e+01, -1.2524117876199165e+01, -1.2294388376531968e+01, -1.2068027585042133e+01, -1.1844789248242524e+01, -1.1624454598296943e+01, -1.1406828145437910e+01, -1.1191734268858408e+01, -1.0979014427470727e+01, -1.0768524857445218e+01, -1.0560134656049588e+01, -1.0353724175012228e+01, -1.0149183664094940e+01, -9.9464121185839414e+00, -9.7453162942320208e+00, -9.5458098606732449e+00, -9.3478126700959958e+00, -9.1512501224373288e+00, -8.9560526118688415e+00, -8.7621550421132515e+00, -8.5694964003332892e+00, -8.3780193810985182e+00, -8.1876700533578219e+00, -7.9983975644987861e+00, -7.8101538765164022e+00, -7.6228935300856273e+00, -7.4365734329690358e+00, -7.2511526697184987e+00, -7.0665923300691791e+00, -6.8828553537915784e+00, -6.6999063900760145e+00, -6.5177116697841271e+00, -6.3362388891223835e+00, -6.1554571034797059e+00, -5.9753366303309603e+00, -5.7958489602446139e+00, -5.6169666751500360e+00, -5.4386633731207876e+00, -5.2609135990173996e+00, -5.0836927804084810e+00, -4.9069771682545298e+00, -4.7307437818957530e+00, -4.5549703579349439e+00, -4.3796353026499011e+00, -4.2047176476080219e+00, -4.0301970081890968e+00, -3.8560535447518163e+00, -3.6822679262054381e+00, -3.5088212957709741e+00, -3.3356952387365157e+00, -3.1628717520292895e+00, -2.9903332154429094e+00, -2.8180623643724516e+00, -2.6460422639225052e+00, -2.4742562842645146e+00, -2.3026880771296399e+00, -2.1313215533321839e+00, -1.9601408612264668e+00, -1.7891303660069930e+00, -1.6182746297679145e+00, -1.4475583922432660e+00, -1.2769665521542517e+00, -1.1064841490940971e+00, -9.3609634588467550e-01, -7.6578841134230902e-01, -5.9554570339290602e-01, -4.2535365247890039e-01, -2.5519774520239308e-01, -8.5063508150433453e-02, 8.5063508150433453e-02, 2.5519774520239308e-01, 4.2535365247890039e-01, 5.9554570339290602e-01, 7.6578841134230902e-01, 9.3609634588467550e-01, 1.1064841490940971e+00, 1.2769665521542517e+00, 1.4475583922432660e+00, 1.6182746297679145e+00, 1.7891303660069930e+00, 1.9601408612264668e+00, 2.1313215533321839e+00, 2.3026880771296399e+00, 2.4742562842645146e+00, 2.6460422639225052e+00, 2.8180623643724516e+00, 2.9903332154429094e+00, 3.1628717520292895e+00, 3.3356952387365157e+00, 3.5088212957709741e+00, 3.6822679262054381e+00, 3.8560535447518163e+00, 4.0301970081890968e+00, 4.2047176476080219e+00, 4.3796353026499011e+00, 4.5549703579349439e+00, 4.7307437818957530e+00, 4.9069771682545298e+00, 5.0836927804084810e+00, 5.2609135990173996e+00, 5.4386633731207876e+00, 5.6169666751500360e+00, 5.7958489602446139e+00, 5.9753366303309603e+00, 6.1554571034797059e+00, 6.3362388891223835e+00, 6.5177116697841271e+00, 6.6999063900760145e+00, 6.8828553537915784e+00, 7.0665923300691791e+00, 7.2511526697184987e+00, 7.4365734329690358e+00, 7.6228935300856273e+00, 7.8101538765164022e+00, 7.9983975644987861e+00, 8.1876700533578219e+00, 8.3780193810985182e+00, 8.5694964003332892e+00, 8.7621550421132515e+00, 8.9560526118688415e+00, 9.1512501224373288e+00, 9.3478126700959958e+00, 9.5458098606732449e+00, 9.7453162942320208e+00, 9.9464121185839414e+00, 1.0149183664094940e+01, 1.0353724175012228e+01, 1.0560134656049588e+01, 1.0768524857445218e+01, 1.0979014427470727e+01, 1.1191734268858408e+01, 1.1406828145437910e+01, 1.1624454598296943e+01, 1.1844789248242524e+01, 1.2068027585042133e+01, 1.2294388376531968e+01, 1.2524117876199165e+01, 1.2757495072417459e+01, 1.2994838315752334e+01, 1.3236513798043475e+01, 1.3482946563606328e+01, 1.3734635051620387e+01, 1.3992170674226745e+01, 1.4256264762200541e+01, 1.4527786614519313e+01, 1.4807818875617881e+01, 1.5097741096163510e+01, 1.5399361493933315e+01, 1.5715136437003761e+01, 1.6048562755664683e+01, 1.6404948308671031e+01, 1.6793141871786613e+01, 1.7230312943277969e+01, 1.7761394524848996e+01}, + {-1.7816165576540595e+01, -1.7285623836656182e+01, -1.6848906849690259e+01, -1.6461124086051807e+01, -1.6105122139319558e+01, -1.5772060470078458e+01, -1.5456636132218662e+01, -1.5155355517282629e+01, -1.4865764512599243e+01, -1.4586056556752672e+01, -1.4314853361179868e+01, -1.4051073271804183e+01, -1.3793847785696649e+01, -1.3542466224976369e+01, -1.3296337722283933e+01, -1.3054964299852571e+01, -1.2817921309339152e+01, -1.2584842902718409e+01, -1.2355411031114167e+01, -1.2129346973425209e+01, -1.1906404715032753e+01, -1.1686365703318645e+01, -1.1469034643887829e+01, -1.1254236094539081e+01, -1.1041811678540856e+01, -1.0831617784246889e+01, -1.0623523650663971e+01, -1.0417409762265434e+01, -1.0213166493789654e+01, -1.0010692958774635e+01, -9.8098960253945080e+00, -9.6106894706457702e+00, -9.4129932496899222e+00, -9.2167328616325275e+00, -9.0218387965226103e+00, -8.8282460511228340e+00, -8.6358937032013543e+00, -8.4447245358586134e+00, -8.2546847048231751e+00, -8.0657234428032414e+00, -7.8777927959207110e+00, -7.6908473880261887e+00, -7.5048442093293950e+00, -7.3197424263067070e+00, -7.1355032102865055e+00, -6.9520895824801361e+00, -6.7694662735346460e+00, -6.5875995959434990e+00, -6.4064573278715784e+00, -6.2260086071378540e+00, -6.0462238342585293e+00, -5.8670745835899512e+00, -5.6885335217276216e+00, -5.5105743324184848e+00, -5.3331716473306852e+00, -5.1563009821003343e+00, -4.9799386771402681e+00, -4.8040618427527138e+00, -4.6286483081374303e+00, -4.4536765739303981e+00, -4.2791257679461268e+00, -4.1049756038301792e+00, -3.9312063423578660e+00, -3.7577987551410561e+00, -3.5847340905279546e+00, -3.4119940415009409e+00, -3.2395607153955579e+00, -3.0674166052796257e+00, -2.8955445628456173e+00, -2.7239277726819950e+00, -2.5525497278003657e+00, -2.3813942063052753e+00, -2.2104452491022966e+00, -2.0396871385479329e+00, -1.8691043779518630e+00, -1.6986816718482496e+00, -1.5284039069583553e+00, -1.3582561337715613e+00, -1.1882235486761765e+00, -1.0182914765751778e+00, -8.4844535392529652e-01, -6.7867071214067709e-01, -5.0895316130475177e-01, -3.3927837413597878e-01, -1.6963207015474091e-01, -0.0000000000000000e+00, 1.6963207015474091e-01, 3.3927837413597878e-01, 5.0895316130475177e-01, 6.7867071214067709e-01, 8.4844535392529652e-01, 1.0182914765751778e+00, 1.1882235486761765e+00, 1.3582561337715613e+00, 1.5284039069583553e+00, 1.6986816718482496e+00, 1.8691043779518630e+00, 2.0396871385479329e+00, 2.2104452491022966e+00, 2.3813942063052753e+00, 2.5525497278003657e+00, 2.7239277726819950e+00, 2.8955445628456173e+00, 3.0674166052796257e+00, 3.2395607153955579e+00, 3.4119940415009409e+00, 3.5847340905279546e+00, 3.7577987551410561e+00, 3.9312063423578660e+00, 4.1049756038301792e+00, 4.2791257679461268e+00, 4.4536765739303981e+00, 4.6286483081374303e+00, 4.8040618427527138e+00, 4.9799386771402681e+00, 5.1563009821003343e+00, 5.3331716473306852e+00, 5.5105743324184848e+00, 5.6885335217276216e+00, 5.8670745835899512e+00, 6.0462238342585293e+00, 6.2260086071378540e+00, 6.4064573278715784e+00, 6.5875995959434990e+00, 6.7694662735346460e+00, 6.9520895824801361e+00, 7.1355032102865055e+00, 7.3197424263067070e+00, 7.5048442093293950e+00, 7.6908473880261887e+00, 7.8777927959207110e+00, 8.0657234428032414e+00, 8.2546847048231751e+00, 8.4447245358586134e+00, 8.6358937032013543e+00, 8.8282460511228340e+00, 9.0218387965226103e+00, 9.2167328616325275e+00, 9.4129932496899222e+00, 9.6106894706457702e+00, 9.8098960253945080e+00, 1.0010692958774635e+01, 1.0213166493789654e+01, 1.0417409762265434e+01, 1.0623523650663971e+01, 1.0831617784246889e+01, 1.1041811678540856e+01, 1.1254236094539081e+01, 1.1469034643887829e+01, 1.1686365703318645e+01, 1.1906404715032753e+01, 1.2129346973425209e+01, 1.2355411031114167e+01, 1.2584842902718409e+01, 1.2817921309339152e+01, 1.3054964299852571e+01, 1.3296337722283933e+01, 1.3542466224976369e+01, 1.3793847785696649e+01, 1.4051073271804183e+01, 1.4314853361179868e+01, 1.4586056556752672e+01, 1.4865764512599243e+01, 1.5155355517282629e+01, 1.5456636132218662e+01, 1.5772060470078458e+01, 1.6105122139319558e+01, 1.6461124086051807e+01, 1.6848906849690259e+01, 1.7285623836656182e+01, 1.7816165576540595e+01}, + {-1.7870774428377043e+01, -1.7340768757416335e+01, -1.6904502632033939e+01, -1.6517127712794291e+01, -1.6161506578815988e+01, -1.5828806872783744e+01, -1.5513730528912630e+01, -1.5212787139365300e+01, -1.4923524831985965e+01, -1.4644138690731507e+01, -1.4373251680710139e+01, -1.4109783131522859e+01, -1.3852865330854605e+01, -1.3601788249195971e+01, -1.3355961560129954e+01, -1.3114887743985697e+01, -1.2878142545481497e+01, -1.2645360457815213e+01, -1.2416223731463095e+01, -1.2190453910463864e+01, -1.1967805217099682e+01, -1.1748059312137153e+01, -1.1531021094829603e+01, -1.1316515299946504e+01, -1.1104383713549687e+01, -1.0894482874671912e+01, -1.0686682162601475e+01, -1.0480862193135913e+01, -1.0276913464597831e+01, -1.0074735207405618e+01, -9.8742344007979135e+00, -9.6753249277855886e+00, -9.4779268451589243e+00, -9.2819657498467407e+00, -9.0873722264251189e+00, -8.8940813633373228e+00, -8.7020323275849982e+00, -8.5111679894115486e+00, -8.3214345899181446e+00, -8.1327814457042589e+00, -7.9451606855641499e+00, -7.7585270150414196e+00, -7.5728375052793471e+00, -7.3880514031314979e+00, -7.2041299599356252e+00, -7.0210362767207544e+00, -6.8387351639253717e+00, -6.6571930139644744e+00, -6.4763776852031878e+00, -6.2962583960814955e+00, -6.1168056282939949e+00, -5.9379910380649177e+00, -5.7597873746756241e+00, -5.5821684055025109e+00, -5.4051088469102604e+00, -5.2285843004206338e+00, -5.0525711936423852e+00, -4.8770467255047967e+00, -4.7019888153869536e+00, -4.5273760557783174e+00, -4.3531876681442050e+00, -4.1794034617032088e+00, -4.0060037948530276e+00, -3.8329695390070744e+00, -3.6602820446272100e+00, -3.4879231092581433e+00, -3.3158749473870577e+00, -3.1441201619679244e+00, -2.9726417174641275e+00, -2.8014229142755962e+00, -2.6304473644278392e+00, -2.4596989684102435e+00, -2.2891618930598643e+00, -2.1188205503948270e+00, -1.9486595773085056e+00, -1.7786638160418760e+00, -1.6088182953569903e+00, -1.4391082123394401e+00, -1.2695189147619996e+00, -1.1000358839454638e+00, -9.3064471805601867e-01, -7.6133111578138291e-01, -5.9208086033042751e-01, -4.2287980370308703e-01, -2.5371385117911249e-01, -8.4568945975610571e-02, 8.4568945975610571e-02, 2.5371385117911249e-01, 4.2287980370308703e-01, 5.9208086033042751e-01, 7.6133111578138291e-01, 9.3064471805601867e-01, 1.1000358839454638e+00, 1.2695189147619996e+00, 1.4391082123394401e+00, 1.6088182953569903e+00, 1.7786638160418760e+00, 1.9486595773085056e+00, 2.1188205503948270e+00, 2.2891618930598643e+00, 2.4596989684102435e+00, 2.6304473644278392e+00, 2.8014229142755962e+00, 2.9726417174641275e+00, 3.1441201619679244e+00, 3.3158749473870577e+00, 3.4879231092581433e+00, 3.6602820446272100e+00, 3.8329695390070744e+00, 4.0060037948530276e+00, 4.1794034617032088e+00, 4.3531876681442050e+00, 4.5273760557783174e+00, 4.7019888153869536e+00, 4.8770467255047967e+00, 5.0525711936423852e+00, 5.2285843004206338e+00, 5.4051088469102604e+00, 5.5821684055025109e+00, 5.7597873746756241e+00, 5.9379910380649177e+00, 6.1168056282939949e+00, 6.2962583960814955e+00, 6.4763776852031878e+00, 6.6571930139644744e+00, 6.8387351639253717e+00, 7.0210362767207544e+00, 7.2041299599356252e+00, 7.3880514031314979e+00, 7.5728375052793471e+00, 7.7585270150414196e+00, 7.9451606855641499e+00, 8.1327814457042589e+00, 8.3214345899181446e+00, 8.5111679894115486e+00, 8.7020323275849982e+00, 8.8940813633373228e+00, 9.0873722264251189e+00, 9.2819657498467407e+00, 9.4779268451589243e+00, 9.6753249277855886e+00, 9.8742344007979135e+00, 1.0074735207405618e+01, 1.0276913464597831e+01, 1.0480862193135913e+01, 1.0686682162601475e+01, 1.0894482874671912e+01, 1.1104383713549687e+01, 1.1316515299946504e+01, 1.1531021094829603e+01, 1.1748059312137153e+01, 1.1967805217099682e+01, 1.2190453910463864e+01, 1.2416223731463095e+01, 1.2645360457815213e+01, 1.2878142545481497e+01, 1.3114887743985697e+01, 1.3355961560129954e+01, 1.3601788249195971e+01, 1.3852865330854605e+01, 1.4109783131522859e+01, 1.4373251680710139e+01, 1.4644138690731507e+01, 1.4923524831985965e+01, 1.5212787139365300e+01, 1.5513730528912630e+01, 1.5828806872783744e+01, 1.6161506578815988e+01, 1.6517127712794291e+01, 1.6904502632033939e+01, 1.7340768757416335e+01, 1.7870774428377043e+01}, + {-1.7925222507645273e+01, -1.7395749181302794e+01, -1.6959930736506667e+01, -1.6572960745489535e+01, -1.6217717667909398e+01, -1.5885377274967727e+01, -1.5570646349282180e+01, -1.5270037662686175e+01, -1.4981101568835271e+01, -1.4702034786209495e+01, -1.4431461525263758e+01, -1.4168302092683751e+01, -1.3911689561406538e+01, -1.3660914545833675e+01, -1.3415387256705733e+01, -1.3174610629179487e+01, -1.2938160798167818e+01, -1.2705672595541055e+01, -1.2476828568829013e+01, -1.2251350525113802e+01, -1.2028992921645616e+01, -1.1809537630775932e+01, -1.1592789743714977e+01, -1.1378574170599888e+01, -1.1166732858754798e+01, -1.0957122496418719e+01, -1.0749612601735487e+01, -1.0544083920437931e+01, -1.0340427073072608e+01, -1.0138541405599460e+01, -9.9383340069978168e+00, -9.7397188649785829e+00, -9.5426161366508815e+00, -9.3469515154567748e+00, -9.1526556791851785e+00, -8.9596638066377352e+00, -8.7679151527158581e+00, -8.5773526734573888e+00, -8.3879226939696405e+00, -8.1995746133560008e+00, -8.0122606416719417e+00, -7.8259355647163380e+00, -7.6405565330989909e+00, -7.4560828725515957e+00, -7.2724759128875176e+00, -7.0896988333823048e+00, -6.9077165226546269e+00, -6.7264954513869304e+00, -6.5460035564448802e+00, -6.3662101351413103e+00, -6.1870857485496860e+00, -6.0086021329082362e+00, -5.8307321182728238e+00, -5.6534495536772900e+00, -5.4767292381468682e+00, -5.3005468569855445e+00, -5.1248789228235241e+00, -4.9497027209678768e+00, -4.7749962586489980e+00, -4.6007382177989511e+00, -4.4269079110357756e+00, -4.2534852405612638e+00, -4.0804506597091201e+00, -3.9077851369063397e+00, -3.7354701218335649e+00, -3.5634875135904314e+00, -3.3918196306899016e+00, -3.2204491827214987e+00, -3.0493592435375283e+00, -2.8785332258289715e+00, -2.7079548569689353e+00, -2.5376081560115265e+00, -2.3674774117429300e+00, -2.1975471616893691e+00, -2.0278021719937014e+00, -1.8582274180786869e+00, -1.6888080660205369e+00, -1.5195294545613143e+00, -1.3503770776931412e+00, -1.1813365677510279e+00, -1.0123936789545276e+00, -8.4353427134138192e-01, -6.7474429503886002e-01, -5.0600977482067722e-01, -3.3731679489919819e-01, -1.6865148390411927e-01, -0.0000000000000000e+00, 1.6865148390411927e-01, 3.3731679489919819e-01, 5.0600977482067722e-01, 6.7474429503886002e-01, 8.4353427134138192e-01, 1.0123936789545276e+00, 1.1813365677510279e+00, 1.3503770776931412e+00, 1.5195294545613143e+00, 1.6888080660205369e+00, 1.8582274180786869e+00, 2.0278021719937014e+00, 2.1975471616893691e+00, 2.3674774117429300e+00, 2.5376081560115265e+00, 2.7079548569689353e+00, 2.8785332258289715e+00, 3.0493592435375283e+00, 3.2204491827214987e+00, 3.3918196306899016e+00, 3.5634875135904314e+00, 3.7354701218335649e+00, 3.9077851369063397e+00, 4.0804506597091201e+00, 4.2534852405612638e+00, 4.4269079110357756e+00, 4.6007382177989511e+00, 4.7749962586489980e+00, 4.9497027209678768e+00, 5.1248789228235241e+00, 5.3005468569855445e+00, 5.4767292381468682e+00, 5.6534495536772900e+00, 5.8307321182728238e+00, 6.0086021329082362e+00, 6.1870857485496860e+00, 6.3662101351413103e+00, 6.5460035564448802e+00, 6.7264954513869304e+00, 6.9077165226546269e+00, 7.0896988333823048e+00, 7.2724759128875176e+00, 7.4560828725515957e+00, 7.6405565330989909e+00, 7.8259355647163380e+00, 8.0122606416719417e+00, 8.1995746133560008e+00, 8.3879226939696405e+00, 8.5773526734573888e+00, 8.7679151527158581e+00, 8.9596638066377352e+00, 9.1526556791851785e+00, 9.3469515154567748e+00, 9.5426161366508815e+00, 9.7397188649785829e+00, 9.9383340069978168e+00, 1.0138541405599460e+01, 1.0340427073072608e+01, 1.0544083920437931e+01, 1.0749612601735487e+01, 1.0957122496418719e+01, 1.1166732858754798e+01, 1.1378574170599888e+01, 1.1592789743714977e+01, 1.1809537630775932e+01, 1.2028992921645616e+01, 1.2251350525113802e+01, 1.2476828568829013e+01, 1.2705672595541055e+01, 1.2938160798167818e+01, 1.3174610629179487e+01, 1.3415387256705733e+01, 1.3660914545833675e+01, 1.3911689561406538e+01, 1.4168302092683751e+01, 1.4431461525263758e+01, 1.4702034786209495e+01, 1.4981101568835271e+01, 1.5270037662686175e+01, 1.5570646349282180e+01, 1.5885377274967727e+01, 1.6217717667909398e+01, 1.6572960745489535e+01, 1.6959930736506667e+01, 1.7395749181302794e+01, 1.7925222507645273e+01}, + {-1.7979511220856821e+01, -1.7450566562382527e+01, -1.7015192658329994e+01, -1.6628624717520726e+01, -1.6273756976433262e+01, -1.5941773281856777e+01, -1.5627385233279865e+01, -1.5327108761515133e+01, -1.5038496431508072e+01, -1.4759746585548676e+01, -1.4489484671220278e+01, -1.4226631965786098e+01, -1.3970322322144929e+01, -1.3719846994209712e+01, -1.3474616726146943e+01, -1.3234134904720168e+01, -1.2997978052213019e+01, -1.2765781336657277e+01, -1.2537227600374516e+01, -1.2312038911428751e+01, -1.2089969960138866e+01, -1.1870802828673778e+01, -1.1654342798540783e+01, -1.1440414953672729e+01, -1.1228861401155735e+01, -1.1019538976992907e+01, -1.0812317336788272e+01, -1.0607077354851786e+01, -1.0403709772624749e+01, -1.0202114050301228e+01, -1.0002197385309380e+01, -9.8038738687782931e+00, -9.6070637568592137e+00, -9.4116928382313976e+00, -9.2176918826171956e+00, -9.0249961578901878e+00, -8.8335450055546225e+00, -8.6432814661321498e+00, -8.4541519474088638e+00, -8.2661059296450645e+00, -8.0790957027880133e+00, -7.8930761314972990e+00, -7.7080044444269156e+00, -7.5238400447339577e+00, -7.3405443392217018e+00, -7.1580805838909543e+00, -6.9764137439811300e+00, -6.7955103668419072e+00, -6.6153384661958059e+00, -6.4358674165386551e+00, -6.2570678565839728e+00, -6.0789116007933410e+00, -5.9013715581517205e+00, -5.7244216574471602e+00, -5.5480367784012250e+00, -5.3721926880716282e+00, -5.1968659820138337e+00, -5.0220340297452291e+00, -4.8476749241050427e+00, -4.6737674341465381e+00, -4.5002909612360460e+00, -4.3272254980667917e+00, -4.1545515903248518e+00, -3.9822503007705263e+00, -3.8103031755212977e+00, -3.6386922123428187e+00, -3.4673998307723486e+00, -3.2964088439149859e+00, -3.1257024317672348e+00, -2.9552641159350221e+00, -2.7850777356245309e+00, -2.6151274247942147e+00, -2.4453975903652418e+00, -2.2758728913956188e+00, -2.1065382191302762e+00, -1.9373786778457494e+00, -1.7683795664136901e+00, -1.5995263605124337e+00, -1.4308046954202789e+00, -1.2622003493280531e+00, -1.0936992271119663e+00, -9.2528734451076988e-01, -7.5695081265386188e-01, -5.8867582288920217e-01, -4.2044863186181980e-01, -2.5225554679525719e-01, -8.4082910929564950e-02, 8.4082910929564950e-02, 2.5225554679525719e-01, 4.2044863186181980e-01, 5.8867582288920217e-01, 7.5695081265386188e-01, 9.2528734451076988e-01, 1.0936992271119663e+00, 1.2622003493280531e+00, 1.4308046954202789e+00, 1.5995263605124337e+00, 1.7683795664136901e+00, 1.9373786778457494e+00, 2.1065382191302762e+00, 2.2758728913956188e+00, 2.4453975903652418e+00, 2.6151274247942147e+00, 2.7850777356245309e+00, 2.9552641159350221e+00, 3.1257024317672348e+00, 3.2964088439149859e+00, 3.4673998307723486e+00, 3.6386922123428187e+00, 3.8103031755212977e+00, 3.9822503007705263e+00, 4.1545515903248518e+00, 4.3272254980667917e+00, 4.5002909612360460e+00, 4.6737674341465381e+00, 4.8476749241050427e+00, 5.0220340297452291e+00, 5.1968659820138337e+00, 5.3721926880716282e+00, 5.5480367784012250e+00, 5.7244216574471602e+00, 5.9013715581517205e+00, 6.0789116007933410e+00, 6.2570678565839728e+00, 6.4358674165386551e+00, 6.6153384661958059e+00, 6.7955103668419072e+00, 6.9764137439811300e+00, 7.1580805838909543e+00, 7.3405443392217018e+00, 7.5238400447339577e+00, 7.7080044444269156e+00, 7.8930761314972990e+00, 8.0790957027880133e+00, 8.2661059296450645e+00, 8.4541519474088638e+00, 8.6432814661321498e+00, 8.8335450055546225e+00, 9.0249961578901878e+00, 9.2176918826171956e+00, 9.4116928382313976e+00, 9.6070637568592137e+00, 9.8038738687782931e+00, 1.0002197385309380e+01, 1.0202114050301228e+01, 1.0403709772624749e+01, 1.0607077354851786e+01, 1.0812317336788272e+01, 1.1019538976992907e+01, 1.1228861401155735e+01, 1.1440414953672729e+01, 1.1654342798540783e+01, 1.1870802828673778e+01, 1.2089969960138866e+01, 1.2312038911428751e+01, 1.2537227600374516e+01, 1.2765781336657277e+01, 1.2997978052213019e+01, 1.3234134904720168e+01, 1.3474616726146943e+01, 1.3719846994209712e+01, 1.3970322322144929e+01, 1.4226631965786098e+01, 1.4489484671220278e+01, 1.4759746585548676e+01, 1.5038496431508072e+01, 1.5327108761515133e+01, 1.5627385233279865e+01, 1.5941773281856777e+01, 1.6273756976433262e+01, 1.6628624717520726e+01, 1.7015192658329994e+01, 1.7450566562382527e+01, 1.7979511220856821e+01}, + {-1.8033641954168267e+01, -1.7505222333487513e+01, -1.7070289870719815e+01, -1.6684121139543407e+01, -1.6329626050797177e+01, -1.5997996474571265e+01, -1.5683948796077209e+01, -1.5384002084668344e+01, -1.5095711102237930e+01, -1.4817275804306519e+01, -1.4547322867471838e+01, -1.4284774533151579e+01, -1.4028765428985777e+01, -1.3778587444058825e+01, -1.3533651852283532e+01, -1.3293462488855706e+01, -1.3057596260647884e+01, -1.2825688669380938e+01, -1.2597422849942523e+01, -1.2372521129351217e+01, -1.2150738429127935e+01, -1.1931857039523125e+01, -1.1715682430712077e+01, -1.1502039858881551e+01, -1.1290771589409180e+01, -1.1081734604649661e+01, -1.0874798696301507e+01, -1.0669844865923427e+01, -1.0466763974552268e+01, -1.0265455595339178e+01, -1.0065827032900119e+01, -9.8677924805319144e+00, -9.6712722921832484e+00, -9.4761923505272865e+00, -9.2824835159740040e+00, -9.0900811442169349e+00, -8.8989246621016740e+00, -8.7089571933595398e+00, -8.5201252271656553e+00, -8.3323783236290581e+00, -8.1456688512594901e+00, -7.9599517522241854e+00, -7.7751843318419356e+00, -7.5913260692870139e+00, -7.4083384469130396e+00, -7.2261847959726726e+00, -7.0448301568163600e+00, -6.8642411519124229e+00, -6.6843858702502548e+00, -6.5052337618746865e+00, -6.3267555414586063e+00, -6.1489230999568738e+00, -5.9717094235012285e+00, -5.7950885187964847e+00, -5.6190353443649403e+00, -5.4435257470611598e+00, -5.2685364033444513e+00, -5.0940447648531757e+00, -4.9200290078745663e+00, -4.7464679863470698e+00, -4.5733411880702048e+00, -4.4006286938303605e+00, -4.2283111391802617e+00, -4.0563696786358214e+00, -3.8847859520769483e+00, -3.7135420531591667e+00, -3.5426204995608663e+00, -3.3720042049069567e+00, -3.2016764522238601e+00, -3.0316208687934161e+00, -2.8618214022844848e+00, -2.6922622980510740e+00, -2.5229280774947309e+00, -2.3538035173969201e+00, -2.1848736301342204e+00, -2.0161236446955049e+00, -1.8475389884259239e+00, -1.6791052694275435e+00, -1.5108082595509420e+00, -1.3426338779160372e+00, -1.1745681749038943e+00, -1.0065973165643360e+00, -8.3870756938683533e-01, -6.7088528538449332e-01, -5.0311688744285843e-01, -3.3538885488700437e-01, -1.6768770922162865e-01, -0.0000000000000000e+00, 1.6768770922162865e-01, 3.3538885488700437e-01, 5.0311688744285843e-01, 6.7088528538449332e-01, 8.3870756938683533e-01, 1.0065973165643360e+00, 1.1745681749038943e+00, 1.3426338779160372e+00, 1.5108082595509420e+00, 1.6791052694275435e+00, 1.8475389884259239e+00, 2.0161236446955049e+00, 2.1848736301342204e+00, 2.3538035173969201e+00, 2.5229280774947309e+00, 2.6922622980510740e+00, 2.8618214022844848e+00, 3.0316208687934161e+00, 3.2016764522238601e+00, 3.3720042049069567e+00, 3.5426204995608663e+00, 3.7135420531591667e+00, 3.8847859520769483e+00, 4.0563696786358214e+00, 4.2283111391802617e+00, 4.4006286938303605e+00, 4.5733411880702048e+00, 4.7464679863470698e+00, 4.9200290078745663e+00, 5.0940447648531757e+00, 5.2685364033444513e+00, 5.4435257470611598e+00, 5.6190353443649403e+00, 5.7950885187964847e+00, 5.9717094235012285e+00, 6.1489230999568738e+00, 6.3267555414586063e+00, 6.5052337618746865e+00, 6.6843858702502548e+00, 6.8642411519124229e+00, 7.0448301568163600e+00, 7.2261847959726726e+00, 7.4083384469130396e+00, 7.5913260692870139e+00, 7.7751843318419356e+00, 7.9599517522241854e+00, 8.1456688512594901e+00, 8.3323783236290581e+00, 8.5201252271656553e+00, 8.7089571933595398e+00, 8.8989246621016740e+00, 9.0900811442169349e+00, 9.2824835159740040e+00, 9.4761923505272865e+00, 9.6712722921832484e+00, 9.8677924805319144e+00, 1.0065827032900119e+01, 1.0265455595339178e+01, 1.0466763974552268e+01, 1.0669844865923427e+01, 1.0874798696301507e+01, 1.1081734604649661e+01, 1.1290771589409180e+01, 1.1502039858881551e+01, 1.1715682430712077e+01, 1.1931857039523125e+01, 1.2150738429127935e+01, 1.2372521129351217e+01, 1.2597422849942523e+01, 1.2825688669380938e+01, 1.3057596260647884e+01, 1.3293462488855706e+01, 1.3533651852283532e+01, 1.3778587444058825e+01, 1.4028765428985777e+01, 1.4284774533151579e+01, 1.4547322867471838e+01, 1.4817275804306519e+01, 1.5095711102237930e+01, 1.5384002084668344e+01, 1.5683948796077209e+01, 1.5997996474571265e+01, 1.6329626050797177e+01, 1.6684121139543407e+01, 1.7070289870719815e+01, 1.7505222333487513e+01, 1.8033641954168267e+01}, + {-1.8087616073790890e+01, -1.7559717906645613e+01, -1.7125223825336107e+01, -1.6739451499952981e+01, -1.6385326414471709e+01, -1.6054048410627541e+01, -1.5740338628583727e+01, -1.5440719256044483e+01, -1.5152747237684542e+01, -1.4874624131806939e+01, -1.4604977836012001e+01, -1.4342731549531273e+01, -1.4087020669594040e+01, -1.3837137716174603e+01, -1.3592494489303405e+01, -1.3352595269479263e+01, -1.3117017345422802e+01, -1.2885396550109379e+01, -1.2657416308802228e+01, -1.2432799205480446e+01, -1.2211300391032086e+01, -1.1992702362083911e+01, -1.1776810775879971e+01, -1.1563451059348457e+01, -1.1352465634716971e+01, -1.1143711629308052e+01, -1.0937058969577729e+01, -1.0732388783033896e+01, -1.0529592049038808e+01, -1.0328568452453034e+01, -1.0129225403849107e+01, -9.9314771974714695e+00, -9.7352442838524844e+00, -9.5404526384475599e+00, -9.3470332111408592e+00, -9.1549214442271172e+00, -8.9640568486659262e+00, -8.7743826301592698e+00, -8.5858453580177638e+00, -8.3983946709283614e+00, -8.2119830146725530e+00, -8.0265654076120381e+00, -7.8420992303922956e+00, -7.6585440368392881e+00, -7.4758613834617105e+00, -7.2940146753366397e+00, -7.1129690264635128e+00, -6.9326911329302607e+00, -6.7531491574546436e+00, -6.5743126240500311e+00, -6.3961523217237177e+00, -6.2186402162517354e+00, -6.0417493691907094e+00, -5.8654538633877182e+00, -5.6897287343358398e+00, -5.5145499067980914e+00, -5.3398941361876862e+00, -5.1657389542492513e+00, -4.9920626186351811e+00, -4.8188440660145870e+00, -4.6460628683903158e+00, -4.4736991923328295e+00, -4.3017337608691273e+00, -4.1301478177908013e+00, -3.9589230941681977e+00, -3.7880417768779360e+00, -3.6174864789689782e+00, -3.4472402117084235e+00, -3.2772863581623723e+00, -3.1076086481798137e+00, -2.9381911346587741e+00, -2.7690181709839532e+00, -2.6000743895340599e+00, -2.4313446811650303e+00, -2.2628141755824469e+00, -2.0944682225228455e+00, -1.9262923736692732e+00, -1.7582723652315242e+00, -1.5903941011259675e+00, -1.4226436366938928e+00, -1.2550071629008195e+00, -1.0874709909623226e+00, -9.2002153734466763e-01, -7.5264530909089167e-01, -5.8532888942501560e-01, -4.1805892358878166e-01, -2.5082210486674750e-01, -8.3605160756706529e-02, 8.3605160756706529e-02, 2.5082210486674750e-01, 4.1805892358878166e-01, 5.8532888942501560e-01, 7.5264530909089167e-01, 9.2002153734466763e-01, 1.0874709909623226e+00, 1.2550071629008195e+00, 1.4226436366938928e+00, 1.5903941011259675e+00, 1.7582723652315242e+00, 1.9262923736692732e+00, 2.0944682225228455e+00, 2.2628141755824469e+00, 2.4313446811650303e+00, 2.6000743895340599e+00, 2.7690181709839532e+00, 2.9381911346587741e+00, 3.1076086481798137e+00, 3.2772863581623723e+00, 3.4472402117084235e+00, 3.6174864789689782e+00, 3.7880417768779360e+00, 3.9589230941681977e+00, 4.1301478177908013e+00, 4.3017337608691273e+00, 4.4736991923328295e+00, 4.6460628683903158e+00, 4.8188440660145870e+00, 4.9920626186351811e+00, 5.1657389542492513e+00, 5.3398941361876862e+00, 5.5145499067980914e+00, 5.6897287343358398e+00, 5.8654538633877182e+00, 6.0417493691907094e+00, 6.2186402162517354e+00, 6.3961523217237177e+00, 6.5743126240500311e+00, 6.7531491574546436e+00, 6.9326911329302607e+00, 7.1129690264635128e+00, 7.2940146753366397e+00, 7.4758613834617105e+00, 7.6585440368392881e+00, 7.8420992303922956e+00, 8.0265654076120381e+00, 8.2119830146725530e+00, 8.3983946709283614e+00, 8.5858453580177638e+00, 8.7743826301592698e+00, 8.9640568486659262e+00, 9.1549214442271172e+00, 9.3470332111408592e+00, 9.5404526384475599e+00, 9.7352442838524844e+00, 9.9314771974714695e+00, 1.0129225403849107e+01, 1.0328568452453034e+01, 1.0529592049038808e+01, 1.0732388783033896e+01, 1.0937058969577729e+01, 1.1143711629308052e+01, 1.1352465634716971e+01, 1.1563451059348457e+01, 1.1776810775879971e+01, 1.1992702362083911e+01, 1.2211300391032086e+01, 1.2432799205480446e+01, 1.2657416308802228e+01, 1.2885396550109379e+01, 1.3117017345422802e+01, 1.3352595269479263e+01, 1.3592494489303405e+01, 1.3837137716174603e+01, 1.4087020669594040e+01, 1.4342731549531273e+01, 1.4604977836012001e+01, 1.4874624131806939e+01, 1.5152747237684542e+01, 1.5440719256044483e+01, 1.5740338628583727e+01, 1.6054048410627541e+01, 1.6385326414471709e+01, 1.6739451499952981e+01, 1.7125223825336107e+01, 1.7559717906645613e+01, 1.8087616073790890e+01}, + {-1.8141434926389717e+01, -1.7614054673500309e+01, -1.7179995952720883e+01, -1.6794617265339959e+01, -1.6440859568460443e+01, -1.6109930624426557e+01, -1.5796556297952138e+01, -1.5497261875146510e+01, -1.5209606469472327e+01, -1.4931793231695860e+01, -1.4662451272508532e+01, -1.4400504742695974e+01, -1.4145089803991842e+01, -1.3895499603035967e+01, -1.3651146462397561e+01, -1.3411535104793492e+01, -1.3176243198091708e+01, -1.2944906904124267e+01, -1.2717209936373832e+01, -1.2492875133818373e+01, -1.2271657874909140e+01, -1.2053340860973840e+01, -1.1837729934755059e+01, -1.1624650692438404e+01, -1.1413945711687965e+01, -1.1205472263438262e+01, -1.0999100407593694e+01, -1.0794711396339702e+01, -1.0592196326121911e+01, -1.0391454992291058e+01, -1.0192394910173833e+01, -9.9949304737714737e+00, -9.7989822290161133e+00, -9.6044762429642674e+00, -9.4113435537920687e+00, -9.2195196892087417e+00, -9.0289442430934326e+00, -8.8395605019136383e+00, -8.6513151138967856e+00, -8.4641577950728877e+00, -8.2780410672415687e+00, -8.0929200236841812e+00, -7.9087521190744416e+00, -7.7254969805656009e+00, -7.5431162374687224e+00, -7.3615733673019719e+00, -7.1808335562975261e+00, -7.0008635727114159e+00, -6.8216316515006419e+00, -6.6431073891179739e+00, -6.4652616473335298e+00, -6.2880664651279838e+00, -6.1114949778187784e+00, -5.9355213426810298e+00, -5.7601206704114505e+00, -5.5852689618586204e+00, -5.4109430495080577e+00, -5.2371205432672880e+00, -5.0637797801455120e+00, -4.8908997774658411e+00, -4.7184601892859508e+00, -4.5464412657363820e+00, -4.3748238150150680e+00, -4.2035891678025479e+00, -4.0327191438852346e+00, -3.8621960207943373e+00, -3.6920025042860427e+00, -3.5221217005044698e+00, -3.3525370896831359e+00, -3.1832325012532876e+00, -3.0141920902387014e+00, -2.8454003148266174e+00, -2.6768419150134308e+00, -2.5085018922317608e+00, -2.3403654898726809e+00, -2.1724181746232882e+00, -2.0046456185454748e+00, -1.8370336818268698e+00, -1.6695683961394456e+00, -1.5022359485453094e+00, -1.3350226658927800e+00, -1.1679149996489939e+00, -1.0008995111180643e+00, -8.3396285699622974e-01, -6.6709177521751994e-01, -5.0027307104524965e-01, -3.3349360336615247e-01, -1.6674027114518436e-01, -0.0000000000000000e+00, 1.6674027114518436e-01, 3.3349360336615247e-01, 5.0027307104524965e-01, 6.6709177521751994e-01, 8.3396285699622974e-01, 1.0008995111180643e+00, 1.1679149996489939e+00, 1.3350226658927800e+00, 1.5022359485453094e+00, 1.6695683961394456e+00, 1.8370336818268698e+00, 2.0046456185454748e+00, 2.1724181746232882e+00, 2.3403654898726809e+00, 2.5085018922317608e+00, 2.6768419150134308e+00, 2.8454003148266174e+00, 3.0141920902387014e+00, 3.1832325012532876e+00, 3.3525370896831359e+00, 3.5221217005044698e+00, 3.6920025042860427e+00, 3.8621960207943373e+00, 4.0327191438852346e+00, 4.2035891678025479e+00, 4.3748238150150680e+00, 4.5464412657363820e+00, 4.7184601892859508e+00, 4.8908997774658411e+00, 5.0637797801455120e+00, 5.2371205432672880e+00, 5.4109430495080577e+00, 5.5852689618586204e+00, 5.7601206704114505e+00, 5.9355213426810298e+00, 6.1114949778187784e+00, 6.2880664651279838e+00, 6.4652616473335298e+00, 6.6431073891179739e+00, 6.8216316515006419e+00, 7.0008635727114159e+00, 7.1808335562975261e+00, 7.3615733673019719e+00, 7.5431162374687224e+00, 7.7254969805656009e+00, 7.9087521190744416e+00, 8.0929200236841812e+00, 8.2780410672415687e+00, 8.4641577950728877e+00, 8.6513151138967856e+00, 8.8395605019136383e+00, 9.0289442430934326e+00, 9.2195196892087417e+00, 9.4113435537920687e+00, 9.6044762429642674e+00, 9.7989822290161133e+00, 9.9949304737714737e+00, 1.0192394910173833e+01, 1.0391454992291058e+01, 1.0592196326121911e+01, 1.0794711396339702e+01, 1.0999100407593694e+01, 1.1205472263438262e+01, 1.1413945711687965e+01, 1.1624650692438404e+01, 1.1837729934755059e+01, 1.2053340860973840e+01, 1.2271657874909140e+01, 1.2492875133818373e+01, 1.2717209936373832e+01, 1.2944906904124267e+01, 1.3176243198091708e+01, 1.3411535104793492e+01, 1.3651146462397561e+01, 1.3895499603035967e+01, 1.4145089803991842e+01, 1.4400504742695974e+01, 1.4662451272508532e+01, 1.4931793231695860e+01, 1.5209606469472327e+01, 1.5497261875146510e+01, 1.5796556297952138e+01, 1.6109930624426557e+01, 1.6440859568460443e+01, 1.6794617265339959e+01, 1.7179995952720883e+01, 1.7614054673500309e+01, 1.8141434926389717e+01}, + {-1.8195099839472430e+01, -1.7668234005719587e+01, -1.7234607662724841e+01, -1.6849619880933339e+01, -1.6496226991759631e+01, -1.6165644627729627e+01, -1.5852603348070128e+01, -1.5553631517589562e+01, -1.5266290404714507e+01, -1.4988784742481727e+01, -1.4719744846860621e+01, -1.4458095814010402e+01, -1.4202974565149994e+01, -1.3953674869416368e+01, -1.3709609568387386e+01, -1.3470283823956324e+01, -1.3235275680476827e+01, -1.3004221626275813e+01, -1.2776805660932723e+01, -1.2552750876494338e+01, -1.2331812877201305e+01, -1.2113774567435913e+01, -1.1898441973897304e+01, -1.1685640860572095e+01, -1.1475213959174649e+01, -1.1267018682922650e+01, -1.1060925223886697e+01, -1.0856814957685176e+01, -1.0654579096632252e+01, -1.0454117545377073e+01, -1.0255337922825921e+01, -1.0058154721574315e+01, -9.8624885817991093e+00, -9.6682656610062114e+00, -9.4754170845116796e+00, -9.2838784642833954e+00, -9.0935894759573372e+00, -8.9044934855939797e+00, -8.7165372191524781e+00, -8.5296704688056462e+00, -8.3438458311533719e+00, -8.1590184731587261e+00, -7.9751459222633976e+00, -7.7921878776629914e+00, -7.6101060401591205e+00, -7.4288639583701048e+00, -7.2484268893885622e+00, -7.0687616722327293e+00, -6.8898366126570973e+00, -6.7116213780739269e+00, -6.5340869014957565e+00, -6.3572052935446060e+00, -6.1809497616900950e+00, -6.0052945359788579e+00, -5.8302148006042280e+00, -5.6556866307401252e+00, -5.4816869341281516e+00, -5.3081933969635617e+00, -5.1351844336752253e+00, -4.9626391402379442e+00, -4.7905372506934265e+00, -4.6188590965895351e+00, -4.4475855690767556e+00, -4.2766980834267416e+00, -4.1061785457606526e+00, -3.9360093217952534e+00, -3.7661732074327352e+00, -3.5966534010361229e+00, -3.4274334772463870e+00, -3.2584973622099573e+00, -3.0898293100966461e+00, -2.9214138807980121e+00, -2.7532359187051947e+00, -2.5852805324732593e+00, -2.4175330756862730e+00, -2.2499791283437252e+00, -2.0826044790946652e+00, -1.9153951081510019e+00, -1.7483371708160103e+00, -1.5814169815681258e+00, -1.4146209986437335e+00, -1.2479358090658317e+00, -1.0813481140682928e+00, -9.1484471486787966e-01, -7.4841249873834059e-01, -5.8203842534274008e-01, -4.1570951328174155e-01, -2.4941282681685847e-01, -8.3135462728728945e-02, 8.3135462728728945e-02, 2.4941282681685847e-01, 4.1570951328174155e-01, 5.8203842534274008e-01, 7.4841249873834059e-01, 9.1484471486787966e-01, 1.0813481140682928e+00, 1.2479358090658317e+00, 1.4146209986437335e+00, 1.5814169815681258e+00, 1.7483371708160103e+00, 1.9153951081510019e+00, 2.0826044790946652e+00, 2.2499791283437252e+00, 2.4175330756862730e+00, 2.5852805324732593e+00, 2.7532359187051947e+00, 2.9214138807980121e+00, 3.0898293100966461e+00, 3.2584973622099573e+00, 3.4274334772463870e+00, 3.5966534010361229e+00, 3.7661732074327352e+00, 3.9360093217952534e+00, 4.1061785457606526e+00, 4.2766980834267416e+00, 4.4475855690767556e+00, 4.6188590965895351e+00, 4.7905372506934265e+00, 4.9626391402379442e+00, 5.1351844336752253e+00, 5.3081933969635617e+00, 5.4816869341281516e+00, 5.6556866307401252e+00, 5.8302148006042280e+00, 6.0052945359788579e+00, 6.1809497616900950e+00, 6.3572052935446060e+00, 6.5340869014957565e+00, 6.7116213780739269e+00, 6.8898366126570973e+00, 7.0687616722327293e+00, 7.2484268893885622e+00, 7.4288639583701048e+00, 7.6101060401591205e+00, 7.7921878776629914e+00, 7.9751459222633976e+00, 8.1590184731587261e+00, 8.3438458311533719e+00, 8.5296704688056462e+00, 8.7165372191524781e+00, 8.9044934855939797e+00, 9.0935894759573372e+00, 9.2838784642833954e+00, 9.4754170845116796e+00, 9.6682656610062114e+00, 9.8624885817991093e+00, 1.0058154721574315e+01, 1.0255337922825921e+01, 1.0454117545377073e+01, 1.0654579096632252e+01, 1.0856814957685176e+01, 1.1060925223886697e+01, 1.1267018682922650e+01, 1.1475213959174649e+01, 1.1685640860572095e+01, 1.1898441973897304e+01, 1.2113774567435913e+01, 1.2331812877201305e+01, 1.2552750876494338e+01, 1.2776805660932723e+01, 1.3004221626275813e+01, 1.3235275680476827e+01, 1.3470283823956324e+01, 1.3709609568387386e+01, 1.3953674869416368e+01, 1.4202974565149994e+01, 1.4458095814010402e+01, 1.4719744846860621e+01, 1.4988784742481727e+01, 1.5266290404714507e+01, 1.5553631517589562e+01, 1.5852603348070128e+01, 1.6165644627729627e+01, 1.6496226991759631e+01, 1.6849619880933339e+01, 1.7234607662724841e+01, 1.7668234005719587e+01, 1.8195099839472430e+01}, + {-1.8248612121768343e+01, -1.7722257255394386e+01, -1.7289060344922966e+01, -1.6904460771032490e+01, -1.6551430141805881e+01, -1.6221191910121661e+01, -1.5908481300039147e+01, -1.5609829735595335e+01, -1.5322800626523263e+01, -1.5045600278061576e+01, -1.4776860203741105e+01, -1.4515506438991860e+01, -1.4260676659563400e+01, -1.4011665252976300e+01, -1.3767885576334674e+01, -1.3528843227708883e+01, -1.3294116625314924e+01, -1.3063342581647838e+01, -1.2836205380293851e+01, -1.2612428364469304e+01, -1.2391767362459763e+01, -1.2174005480084015e+01, -1.1958948926483190e+01, -1.1746423632015365e+01, -1.1536272481085435e+01, -1.1328353027891652e+01, -1.1122535595414808e+01, -1.0918701681487823e+01, -1.0716742613104932e+01, -1.0516558403048526e+01, -1.0318056772656865e+01, -1.0121152311984588e+01, -9.9257657543260880e+00, -9.7318233465134139e+00, -9.5392562998795718e+00, -9.3480003095250854e+00, -9.1579951317106332e+00, -8.9691842109485744e+00, -8.7815143497770496e+00, -8.5949354153447821e+00, -8.4094000778684173e+00, -8.2248635767903480e+00, -8.0412835110966494e+00, -7.8586196507783281e+00, -7.6768337668550366e+00, -7.4958894777450231e+00, -7.3157521100712737e+00, -7.1363885722521356e+00, -6.9577672394433048e+00, -6.7798578485838581e+00, -6.6026314024574280e+00, -6.4260600818151339e+00, -6.2501171647232399e+00, -6.0747769523986586e+00, -5.9000147008819077e+00, -5.7258065579720290e+00, -5.5521295049130304e+00, -5.3789613023779728e+00, -5.2062804403463288e+00, -5.0340660915133606e+00, -4.8622980679082559e+00, -4.6909567804310086e+00, -4.5200232010473753e+00, -4.3494788274071139e+00, -4.1793056496735739e+00, -4.0094861193729656e+00, -3.8400031200895830e+00, -3.6708399398492308e+00, -3.5019802450472732e+00, -3.3334080557903905e+00, -3.1651077225323845e+00, -2.9970639038944427e+00, -2.8292615455692673e+00, -2.6616858602164983e+00, -2.4943223082640649e+00, -2.3271565795365086e+00, -2.1601745756370865e+00, -1.9933623930155944e+00, -1.8267063066584319e+00, -1.6601927543415429e+00, -1.4938083213904756e+00, -1.3275397258950710e+00, -1.1613738043291120e+00, -9.9529749752779750e-01, -8.2929783697808435e-01, -6.6336193137884258e-01, -4.9747695342938458e-01, -3.3163012680628950e-01, -1.6580871328955671e-01, -0.0000000000000000e+00, 1.6580871328955671e-01, 3.3163012680628950e-01, 4.9747695342938458e-01, 6.6336193137884258e-01, 8.2929783697808435e-01, 9.9529749752779750e-01, 1.1613738043291120e+00, 1.3275397258950710e+00, 1.4938083213904756e+00, 1.6601927543415429e+00, 1.8267063066584319e+00, 1.9933623930155944e+00, 2.1601745756370865e+00, 2.3271565795365086e+00, 2.4943223082640649e+00, 2.6616858602164983e+00, 2.8292615455692673e+00, 2.9970639038944427e+00, 3.1651077225323845e+00, 3.3334080557903905e+00, 3.5019802450472732e+00, 3.6708399398492308e+00, 3.8400031200895830e+00, 4.0094861193729656e+00, 4.1793056496735739e+00, 4.3494788274071139e+00, 4.5200232010473753e+00, 4.6909567804310086e+00, 4.8622980679082559e+00, 5.0340660915133606e+00, 5.2062804403463288e+00, 5.3789613023779728e+00, 5.5521295049130304e+00, 5.7258065579720290e+00, 5.9000147008819077e+00, 6.0747769523986586e+00, 6.2501171647232399e+00, 6.4260600818151339e+00, 6.6026314024574280e+00, 6.7798578485838581e+00, 6.9577672394433048e+00, 7.1363885722521356e+00, 7.3157521100712737e+00, 7.4958894777450231e+00, 7.6768337668550366e+00, 7.8586196507783281e+00, 8.0412835110966494e+00, 8.2248635767903480e+00, 8.4094000778684173e+00, 8.5949354153447821e+00, 8.7815143497770496e+00, 8.9691842109485744e+00, 9.1579951317106332e+00, 9.3480003095250854e+00, 9.5392562998795718e+00, 9.7318233465134139e+00, 9.9257657543260880e+00, 1.0121152311984588e+01, 1.0318056772656865e+01, 1.0516558403048526e+01, 1.0716742613104932e+01, 1.0918701681487823e+01, 1.1122535595414808e+01, 1.1328353027891652e+01, 1.1536272481085435e+01, 1.1746423632015365e+01, 1.1958948926483190e+01, 1.2174005480084015e+01, 1.2391767362459763e+01, 1.2612428364469304e+01, 1.2836205380293851e+01, 1.3063342581647838e+01, 1.3294116625314924e+01, 1.3528843227708883e+01, 1.3767885576334674e+01, 1.4011665252976300e+01, 1.4260676659563400e+01, 1.4515506438991860e+01, 1.4776860203741105e+01, 1.5045600278061576e+01, 1.5322800626523263e+01, 1.5609829735595335e+01, 1.5908481300039147e+01, 1.6221191910121661e+01, 1.6551430141805881e+01, 1.6904460771032490e+01, 1.7289060344922966e+01, 1.7722257255394386e+01, 1.8248612121768343e+01}, + {-1.8301973063597831e+01, -1.7776125755426882e+01, -1.7343355369019513e+01, -1.6959141339427859e+01, -1.6606470454912181e+01, -1.6276573939462359e+01, -1.5964191652640661e+01, -1.5665858058473457e+01, -1.5379138694506308e+01, -1.5102241428233055e+01, -1.4833798963124122e+01, -1.4572738267853815e+01, -1.4318197767810874e+01, -1.4069472464839684e+01, -1.3825976228134913e+01, -1.3587215088986124e+01, -1.3352767836885693e+01, -1.3122271606204340e+01, -1.2895410962476978e+01, -1.2671909498220252e+01, -1.2451523264048797e+01, -1.2234035565627281e+01, -1.2019252793050947e+01, -1.1807001041645883e+01, -1.1597123347173454e+01, -1.1389477403535365e+01, -1.1183933663391947e+01, -1.0980373745597644e+01, -1.0778689090663802e+01, -1.0578779818366641e+01, -1.0380553751354837e+01, -1.0183925576033463e+01, -9.9888161177141903e+00, -9.7951517114594342e+00, -9.6028636535242580e+00, -9.4118877210445753e+00, -9.2221637498031388e+00, -9.0336352616534104e+00, -8.8462491345909715e+00, -8.6599553096056603e+00, -8.4747065293805139e+00, -8.2904581046690247e+00, -8.1071677048133868e+00, -7.9247951693895704e+00, -7.7433023384005537e+00, -7.5626528988034316e+00, -7.3828122454620404e+00, -7.2037473548748121e+00, -7.0254266702460146e+00, -6.8478199966541871e+00, -6.6708984052298304e+00, -6.4946341453898597e+00, -6.3190005642925637e+00, -6.1439720327768708e+00, -5.9695238771362042e+00, -5.7956323161519689e+00, -5.6222744028767648e+00, -5.4494279707139679e+00, -5.2770715833897031e+00, -5.1051844884564179e+00, -4.9337465740051734e+00, -4.7627383282970204e+00, -4.5921408020531498e+00, -4.4219355731693852e+00, -4.2521047136434067e+00, -4.0826307585233783e+00, -3.9134966767045909e+00, -3.7446858434166801e+00, -3.5761820142581890e+00, -3.4079693006478804e+00, -3.2400321465734825e+00, -3.0723553065286380e+00, -2.9049238245378035e+00, -2.7377230141769160e+00, -2.5707384395048281e+00, -2.4039558968269845e+00, -2.2373613972185420e+00, -2.0709411497393346e+00, -1.9046815452776742e+00, -1.7385691409641026e+00, -1.5725906450998823e+00, -1.4067329025482804e+00, -1.2409828805395797e+00, -1.0753276548433179e+00, -9.0975439626347543e-01, -7.4425035741428780e-01, -5.7880285973602430e-01, -4.1339928071149723e-01, -2.4802704124523722e-01, -8.2673593168222662e-02, 8.2673593168222662e-02, 2.4802704124523722e-01, 4.1339928071149723e-01, 5.7880285973602430e-01, 7.4425035741428780e-01, 9.0975439626347543e-01, 1.0753276548433179e+00, 1.2409828805395797e+00, 1.4067329025482804e+00, 1.5725906450998823e+00, 1.7385691409641026e+00, 1.9046815452776742e+00, 2.0709411497393346e+00, 2.2373613972185420e+00, 2.4039558968269845e+00, 2.5707384395048281e+00, 2.7377230141769160e+00, 2.9049238245378035e+00, 3.0723553065286380e+00, 3.2400321465734825e+00, 3.4079693006478804e+00, 3.5761820142581890e+00, 3.7446858434166801e+00, 3.9134966767045909e+00, 4.0826307585233783e+00, 4.2521047136434067e+00, 4.4219355731693852e+00, 4.5921408020531498e+00, 4.7627383282970204e+00, 4.9337465740051734e+00, 5.1051844884564179e+00, 5.2770715833897031e+00, 5.4494279707139679e+00, 5.6222744028767648e+00, 5.7956323161519689e+00, 5.9695238771362042e+00, 6.1439720327768708e+00, 6.3190005642925637e+00, 6.4946341453898597e+00, 6.6708984052298304e+00, 6.8478199966541871e+00, 7.0254266702460146e+00, 7.2037473548748121e+00, 7.3828122454620404e+00, 7.5626528988034316e+00, 7.7433023384005537e+00, 7.9247951693895704e+00, 8.1071677048133868e+00, 8.2904581046690247e+00, 8.4747065293805139e+00, 8.6599553096056603e+00, 8.8462491345909715e+00, 9.0336352616534104e+00, 9.2221637498031388e+00, 9.4118877210445753e+00, 9.6028636535242580e+00, 9.7951517114594342e+00, 9.9888161177141903e+00, 1.0183925576033463e+01, 1.0380553751354837e+01, 1.0578779818366641e+01, 1.0778689090663802e+01, 1.0980373745597644e+01, 1.1183933663391947e+01, 1.1389477403535365e+01, 1.1597123347173454e+01, 1.1807001041645883e+01, 1.2019252793050947e+01, 1.2234035565627281e+01, 1.2451523264048797e+01, 1.2671909498220252e+01, 1.2895410962476978e+01, 1.3122271606204340e+01, 1.3352767836885693e+01, 1.3587215088986124e+01, 1.3825976228134913e+01, 1.4069472464839684e+01, 1.4318197767810874e+01, 1.4572738267853815e+01, 1.4833798963124122e+01, 1.5102241428233055e+01, 1.5379138694506308e+01, 1.5665858058473457e+01, 1.5964191652640661e+01, 1.6276573939462359e+01, 1.6606470454912181e+01, 1.6959141339427859e+01, 1.7343355369019513e+01, 1.7776125755426882e+01, 1.8301973063597831e+01}, + {-1.8355183937232482e+01, -1.7829840819908938e+01, -1.7397494085242659e+01, -1.7013662969810934e+01, -1.6661349346692710e+01, -1.6331792162325648e+01, -1.6019735882790211e+01, -1.5721717993090206e+01, -1.5435306145250426e+01, -1.5158709759192869e+01, -1.4890562720798751e+01, -1.4629792926034948e+01, -1.4375539545099908e+01, -1.4127098190154650e+01, -1.3883883239094454e+01, -1.3645401153510734e+01, -1.3411231091622829e+01, -1.3181010507418183e+01, -1.2954424246353401e+01, -1.2731196148405482e+01, -1.2511082484830109e+01, -1.2293866759574003e+01, -1.2079355542224606e+01, -1.1867375091697919e+01, -1.1657768593802700e+01, -1.1450393880891689e+01, -1.1245121534098722e+01, -1.1041833292131351e+01, -1.0840420707879813e+01, -1.0640784006999668e+01, -1.0442831112353673e+01, -1.0246476805614231e+01, -1.0051642003036079e+01, -9.8582531268427509e+00, -9.6662415571436178e+00, -9.4755431520404851e+00, -9.2860978257640348e+00, -9.0978491764272782e+00, -8.9107441563917540e+00, -8.7247327793845830e+00, -8.5397678594367203e+00, -8.3558047774774487e+00, -8.1728012720508225e+00, -7.9907172511424713e+00, -7.8095146225403225e+00, -7.6291571405168730e+00, -7.4496102669262783e+00, -7.2708410450674368e+00, -7.0928179848824850e+00, -6.9155109582455818e+00, -6.7388911032550611e+00, -6.5629307365772949e+00, -6.3876032730067926e+00, -6.2128831515070333e+00, -6.0387457670829185e+00, -5.8651674079104827e+00, -5.6921251972144509e+00, -5.5195970394407690e+00, -5.3475615703205710e+00, -5.1759981104652155e+00, -5.0048866221698640e+00, -4.8342076691363776e+00, -4.6639423788555394e+00, -4.4940724074145217e+00, -4.3245799065183155e+00, -4.1554474925341225e+00, -3.9866582173856151e+00, -3.8181955411399695e+00, -3.6500433061447404e+00, -3.4821857125843008e+00, -3.3146072953368710e+00, -3.1472929020232101e+00, -2.9802276721470844e+00, -2.8133970172356633e+00, -2.6467866018952186e+00, -2.4803823257039688e+00, -2.3141703058696805e+00, -2.1481368605848363e+00, -1.9822684930168015e+00, -1.8165518758745727e+00, -1.6509738364973834e+00, -1.4855213424137426e+00, -1.3201814873224036e+00, -1.1549414774493456e+00, -9.8978861823713149e-01, -8.2471030132498657e-01, -6.5969399177967603e-01, -4.9472721553871407e-01, -3.2979754702868869e-01, -1.6489259692248556e-01, -0.0000000000000000e+00, 1.6489259692248556e-01, 3.2979754702868869e-01, 4.9472721553871407e-01, 6.5969399177967603e-01, 8.2471030132498657e-01, 9.8978861823713149e-01, 1.1549414774493456e+00, 1.3201814873224036e+00, 1.4855213424137426e+00, 1.6509738364973834e+00, 1.8165518758745727e+00, 1.9822684930168015e+00, 2.1481368605848363e+00, 2.3141703058696805e+00, 2.4803823257039688e+00, 2.6467866018952186e+00, 2.8133970172356633e+00, 2.9802276721470844e+00, 3.1472929020232101e+00, 3.3146072953368710e+00, 3.4821857125843008e+00, 3.6500433061447404e+00, 3.8181955411399695e+00, 3.9866582173856151e+00, 4.1554474925341225e+00, 4.3245799065183155e+00, 4.4940724074145217e+00, 4.6639423788555394e+00, 4.8342076691363776e+00, 5.0048866221698640e+00, 5.1759981104652155e+00, 5.3475615703205710e+00, 5.5195970394407690e+00, 5.6921251972144509e+00, 5.8651674079104827e+00, 6.0387457670829185e+00, 6.2128831515070333e+00, 6.3876032730067926e+00, 6.5629307365772949e+00, 6.7388911032550611e+00, 6.9155109582455818e+00, 7.0928179848824850e+00, 7.2708410450674368e+00, 7.4496102669262783e+00, 7.6291571405168730e+00, 7.8095146225403225e+00, 7.9907172511424713e+00, 8.1728012720508225e+00, 8.3558047774774487e+00, 8.5397678594367203e+00, 8.7247327793845830e+00, 8.9107441563917540e+00, 9.0978491764272782e+00, 9.2860978257640348e+00, 9.4755431520404851e+00, 9.6662415571436178e+00, 9.8582531268427509e+00, 1.0051642003036079e+01, 1.0246476805614231e+01, 1.0442831112353673e+01, 1.0640784006999668e+01, 1.0840420707879813e+01, 1.1041833292131351e+01, 1.1245121534098722e+01, 1.1450393880891689e+01, 1.1657768593802700e+01, 1.1867375091697919e+01, 1.2079355542224606e+01, 1.2293866759574003e+01, 1.2511082484830109e+01, 1.2731196148405482e+01, 1.2954424246353401e+01, 1.3181010507418183e+01, 1.3411231091622829e+01, 1.3645401153510734e+01, 1.3883883239094454e+01, 1.4127098190154650e+01, 1.4375539545099908e+01, 1.4629792926034948e+01, 1.4890562720798751e+01, 1.5158709759192869e+01, 1.5435306145250426e+01, 1.5721717993090206e+01, 1.6019735882790211e+01, 1.6331792162325648e+01, 1.6661349346692710e+01, 1.7013662969810934e+01, 1.7397494085242659e+01, 1.7829840819908938e+01, 1.8355183937232482e+01}, + {-1.8408245997246180e+01, -1.7883403744491030e+01, -1.7451477824729114e+01, -1.7068027026173699e+01, -1.6716068212476749e+01, -1.6386848004427836e+01, -1.6075115445979726e+01, -1.5777411024325023e+01, -1.5491304492792262e+01, -1.5215006814022102e+01, -1.4947153048869007e+01, -1.4686672014714095e+01, -1.4432703621796808e+01, -1.4184544088639219e+01, -1.3941608298492062e+01, -1.3703403140370927e+01, -1.3469508138708429e+01, -1.3239561064882505e+01, -1.3013247042274847e+01, -1.2790290156511402e+01, -1.2570446897828043e+01, -1.2353500966915787e+01, -1.2139259111417608e+01, -1.1927547752486015e+01, -1.1718210224692305e+01, -1.1511104497611852e+01, -1.1306101279669830e+01, -1.1103082428282363e+01, -1.0901939607604296e+01, -1.0702573148080202e+01, -1.0504891071714988e+01, -1.0308808254390055e+01, -1.0114245702254145e+01, -9.9211299236483459e+00, -9.7293923814947600e+00, -9.5389690138184235e+00, -9.3497998122512573e+00, -9.1618284501124911e+00, -8.9750019530671192e+00, -8.7892704065055494e+00, -8.6045866947189253e+00, -8.4209062677087161e+00, -8.2381869320992998e+00, -8.0563886631444781e+00, -7.8754734352537348e+00, -7.6954050688277018e+00, -7.5161490914978035e+00, -7.3376726121226348e+00, -7.1599442061117617e+00, -6.9829338108329129e+00, -6.8066126300166054e+00, -6.6309530462073942e+00, -6.4559285404270428e+00, -6.2815136183148121e+00, -6.1076837420963281e+00, -5.9344152678072613e+00, -5.7616853872629088e+00, -5.5894720743212600e+00, -5.4177540350364595e+00, -5.2465106613426817e+00, -5.0757219879463076e+00, -4.9053686521374775e+00, -4.7354318562614344e+00, -4.5658933326158548e+00, -4.3967353105632334e+00, -4.2279404856676086e+00, -4.0594919906828633e+00, -3.8913733682357932e+00, -3.7235685450613194e+00, -3.5560618076598769e+00, -3.3888377792582984e+00, -3.2218813979656056e+00, -3.0551778960241212e+00, -2.8887127800643957e+00, -2.7224718122796761e+00, -2.5564409924420968e+00, -2.3906065406885992e+00, -2.2249548810097695e+00, -2.0594726253794451e+00, -1.8941465584671033e+00, -1.7289636228787715e+00, -1.5639109048755229e+00, -1.3989756205215691e+00, -1.2341451022165917e+00, -1.0694067855692595e+00, -9.0474819657091143e-01, -7.4015693903015356e-01, -5.7562068223063112e-01, -4.1112714877553319e-01, -2.4666410258345153e-01, -8.2219337001082138e-02, 8.2219337001082138e-02, 2.4666410258345153e-01, 4.1112714877553319e-01, 5.7562068223063112e-01, 7.4015693903015356e-01, 9.0474819657091143e-01, 1.0694067855692595e+00, 1.2341451022165917e+00, 1.3989756205215691e+00, 1.5639109048755229e+00, 1.7289636228787715e+00, 1.8941465584671033e+00, 2.0594726253794451e+00, 2.2249548810097695e+00, 2.3906065406885992e+00, 2.5564409924420968e+00, 2.7224718122796761e+00, 2.8887127800643957e+00, 3.0551778960241212e+00, 3.2218813979656056e+00, 3.3888377792582984e+00, 3.5560618076598769e+00, 3.7235685450613194e+00, 3.8913733682357932e+00, 4.0594919906828633e+00, 4.2279404856676086e+00, 4.3967353105632334e+00, 4.5658933326158548e+00, 4.7354318562614344e+00, 4.9053686521374775e+00, 5.0757219879463076e+00, 5.2465106613426817e+00, 5.4177540350364595e+00, 5.5894720743212600e+00, 5.7616853872629088e+00, 5.9344152678072613e+00, 6.1076837420963281e+00, 6.2815136183148121e+00, 6.4559285404270428e+00, 6.6309530462073942e+00, 6.8066126300166054e+00, 6.9829338108329129e+00, 7.1599442061117617e+00, 7.3376726121226348e+00, 7.5161490914978035e+00, 7.6954050688277018e+00, 7.8754734352537348e+00, 8.0563886631444781e+00, 8.2381869320992998e+00, 8.4209062677087161e+00, 8.6045866947189253e+00, 8.7892704065055494e+00, 8.9750019530671192e+00, 9.1618284501124911e+00, 9.3497998122512573e+00, 9.5389690138184235e+00, 9.7293923814947600e+00, 9.9211299236483459e+00, 1.0114245702254145e+01, 1.0308808254390055e+01, 1.0504891071714988e+01, 1.0702573148080202e+01, 1.0901939607604296e+01, 1.1103082428282363e+01, 1.1306101279669830e+01, 1.1511104497611852e+01, 1.1718210224692305e+01, 1.1927547752486015e+01, 1.2139259111417608e+01, 1.2353500966915787e+01, 1.2570446897828043e+01, 1.2790290156511402e+01, 1.3013247042274847e+01, 1.3239561064882505e+01, 1.3469508138708429e+01, 1.3703403140370927e+01, 1.3941608298492062e+01, 1.4184544088639219e+01, 1.4432703621796808e+01, 1.4686672014714095e+01, 1.4947153048869007e+01, 1.5215006814022102e+01, 1.5491304492792262e+01, 1.5777411024325023e+01, 1.6075115445979726e+01, 1.6386848004427836e+01, 1.6716068212476749e+01, 1.7068027026173699e+01, 1.7451477824729114e+01, 1.7883403744491030e+01, 1.8408245997246180e+01}, + {-1.8461160480857558e+01, -1.7936815806741905e+01, -1.7505307899899091e+01, -1.7122234853198016e+01, -1.6770628427712005e+01, -1.6441742871044735e+01, -1.6130331776708392e+01, -1.5832938615515195e+01, -1.5547135229076916e+01, -1.5271134113158810e+01, -1.5003571496240674e+01, -1.4743377111311560e+01, -1.4489691603942756e+01, -1.4241811795112390e+01, -1.3999153070125370e+01, -1.3761222742582584e+01, -1.3527600700651213e+01, -1.3297925030905425e+01, -1.3071881132685062e+01, -1.2849193335481473e+01, -1.2629618346876333e+01, -1.2412940062792593e+01, -1.2198965407516690e+01, -1.1987520963108198e+01, -1.1778450211639703e+01, -1.1571611258704099e+01, -1.1366874938858906e+01, -1.1164123227107424e+01, -1.0963247897778071e+01, -1.0764149385037474e+01, -1.0566735808984420e+01, -1.0370922138674908e+01, -1.0176629469126997e+01, -9.9837843937805424e+00, -9.7923184573541491e+00, -9.6021676767792830e+00, -9.4132721200689708e+00, -9.2255755347225286e+00, -9.0390250186738808e+00, -8.8535707279314924e+00, -8.6691656159885877e+00, -8.4857652008457727e+00, -8.3033273561177268e+00, -8.1218121232175022e+00, -7.9411815420463903e+00, -7.7613994979807179e+00, -7.5824315832521663e+00, -7.4042449710755918e+00, -7.2268083010962609e+00, -7.0500915749135666e+00, -6.8740660605962152e+00, -6.6987042052389292e+00, -6.5239795547267194e+00, -6.3498666799725676e+00, -6.1763411089806590e+00, -6.0033792641618602e+00, -5.8309584043931153e+00, -5.6590565713687386e+00, -5.4876525398409859e+00, -5.3167257713902920e+00, -5.1462563714034442e+00, -4.9762250489711075e+00, -4.8066130794454613e+00, -4.6374022694244390e+00, -4.4685749239519819e+00, -4.3001138157438552e+00, -4.1320021562665863e+00, -3.9642235685129914e+00, -3.7967620613319606e+00, -3.6296020051828295e+00, -3.4627281091959579e+00, -3.2961253994312023e+00, -3.1297791982350316e+00, -2.9636751046050795e+00, -2.7977989754781833e+00, -2.6321369078644477e+00, -2.4666752217556631e+00, -2.3014004437416671e+00, -2.1362992912728620e+00, -1.9713586575113293e+00, -1.8065655967166996e+00, -1.6419073101163049e+00, -1.4773711322121057e+00, -1.3129445174795540e+00, -1.1486150274158851e+00, -9.8437031789740859e-01, -8.2019812680717263e-01, -6.5608626189593511e-01, -4.9202258884072003e-01, -3.2799501946636006e-01, -1.6399150009634114e-01, -0.0000000000000000e+00, 1.6399150009634114e-01, 3.2799501946636006e-01, 4.9202258884072003e-01, 6.5608626189593511e-01, 8.2019812680717263e-01, 9.8437031789740859e-01, 1.1486150274158851e+00, 1.3129445174795540e+00, 1.4773711322121057e+00, 1.6419073101163049e+00, 1.8065655967166996e+00, 1.9713586575113293e+00, 2.1362992912728620e+00, 2.3014004437416671e+00, 2.4666752217556631e+00, 2.6321369078644477e+00, 2.7977989754781833e+00, 2.9636751046050795e+00, 3.1297791982350316e+00, 3.2961253994312023e+00, 3.4627281091959579e+00, 3.6296020051828295e+00, 3.7967620613319606e+00, 3.9642235685129914e+00, 4.1320021562665863e+00, 4.3001138157438552e+00, 4.4685749239519819e+00, 4.6374022694244390e+00, 4.8066130794454613e+00, 4.9762250489711075e+00, 5.1462563714034442e+00, 5.3167257713902920e+00, 5.4876525398409859e+00, 5.6590565713687386e+00, 5.8309584043931153e+00, 6.0033792641618602e+00, 6.1763411089806590e+00, 6.3498666799725676e+00, 6.5239795547267194e+00, 6.6987042052389292e+00, 6.8740660605962152e+00, 7.0500915749135666e+00, 7.2268083010962609e+00, 7.4042449710755918e+00, 7.5824315832521663e+00, 7.7613994979807179e+00, 7.9411815420463903e+00, 8.1218121232175022e+00, 8.3033273561177268e+00, 8.4857652008457727e+00, 8.6691656159885877e+00, 8.8535707279314924e+00, 9.0390250186738808e+00, 9.2255755347225286e+00, 9.4132721200689708e+00, 9.6021676767792830e+00, 9.7923184573541491e+00, 9.9837843937805424e+00, 1.0176629469126997e+01, 1.0370922138674908e+01, 1.0566735808984420e+01, 1.0764149385037474e+01, 1.0963247897778071e+01, 1.1164123227107424e+01, 1.1366874938858906e+01, 1.1571611258704099e+01, 1.1778450211639703e+01, 1.1987520963108198e+01, 1.2198965407516690e+01, 1.2412940062792593e+01, 1.2629618346876333e+01, 1.2849193335481473e+01, 1.3071881132685062e+01, 1.3297925030905425e+01, 1.3527600700651213e+01, 1.3761222742582584e+01, 1.3999153070125370e+01, 1.4241811795112390e+01, 1.4489691603942756e+01, 1.4743377111311560e+01, 1.5003571496240674e+01, 1.5271134113158810e+01, 1.5547135229076916e+01, 1.5832938615515195e+01, 1.6130331776708392e+01, 1.6441742871044735e+01, 1.6770628427712005e+01, 1.7122234853198016e+01, 1.7505307899899091e+01, 1.7936815806741905e+01, 1.8461160480857558e+01}, + {-1.8513928608263910e+01, -1.7990078266499342e+01, -1.7558985604821832e+01, -1.7176287776635139e+01, -1.6825031348357740e+01, -1.6496478147418177e+01, -1.6185386288902521e+01, -1.5888302208889046e+01, -1.5602799824404595e+01, -1.5327093154858311e+01, -1.5059819589095412e+01, -1.4799909769977225e+01, -1.4546505073756210e+01, -1.4298902920011114e+01, -1.4056519192842705e+01, -1.3818861627636300e+01, -1.3585510473849133e+01, -1.3356104131088610e+01, -1.3130328272714728e+01, -1.2907907470327904e+01, -1.2688598647247023e+01, -1.2472185893139361e+01, -1.2258476307546671e+01, -1.2047296632129509e+01, -1.1838490495223393e+01, -1.1631916137256281e+01, -1.1427444517781534e+01, -1.1224957728290695e+01, -1.1024347652217228e+01, -1.0825514826405534e+01, -1.0628367468022887e+01, -1.0432820638288694e+01, -1.0238795520089184e+01, -1.0046218790968188e+01, -9.8550220764490426e+00, -9.6651414713778827e+00, -9.4765171191542965e+00, -9.2890928404578474e+00, -9.1028158044838392e+00, -8.9176362368413074e+00, -8.7335071591960247e+00, -8.5503841565041103e+00, -8.3682251683108984e+00, -8.1869903011111198e+00, -8.0066416592005272e+00, -7.8271431918122021e+00, -7.6484605546357463e+00, -7.4705609840747460e+00, -7.2934131828156445e+00, -7.1169872154661693e+00, -6.9412544131792480e+00, -6.7661872863133015e+00, -6.5917594442957039e+00, -6.4179455219559527e+00, -6.2447211116812200e+00, -6.0720627008216166e+00, -5.8999476138372433e+00, -5.7283539587355410e+00, -5.5572605773966774e+00, -5.3866469994277919e+00, -5.2164933992246887e+00, -5.0467805559527736e+00, -4.8774898161882945e+00, -4.7086030589866992e+00, -4.5401026631678034e+00, -4.3719714766276327e+00, -4.2041927875047698e+00, -4.0367502970449332e+00, -3.8696280940217886e+00, -3.7028106305845436e+00, -3.5362826994142633e+00, -3.3700294120808700e+00, -3.2040361785018661e+00, -3.0382886874118746e+00, -2.8727728877593544e+00, -2.7074749709533479e+00, -2.5423813538889330e+00, -2.3774786626852964e+00, -2.2127537170750284e+00, -2.0481935153874455e+00, -1.8837852200725123e+00, -1.7195161437153161e+00, -1.5553737354940405e+00, -1.3913455680370777e+00, -1.2274193246372884e+00, -1.0635827867835286e+00, -8.9982382197139399e-01, -7.3613037175675000e-01, -5.7249044001699179e-01, -4.0889208138615224e-01, -2.4532338983095259e-01, -8.1772487335672980e-02, 8.1772487335672980e-02, 2.4532338983095259e-01, 4.0889208138615224e-01, 5.7249044001699179e-01, 7.3613037175675000e-01, 8.9982382197139399e-01, 1.0635827867835286e+00, 1.2274193246372884e+00, 1.3913455680370777e+00, 1.5553737354940405e+00, 1.7195161437153161e+00, 1.8837852200725123e+00, 2.0481935153874455e+00, 2.2127537170750284e+00, 2.3774786626852964e+00, 2.5423813538889330e+00, 2.7074749709533479e+00, 2.8727728877593544e+00, 3.0382886874118746e+00, 3.2040361785018661e+00, 3.3700294120808700e+00, 3.5362826994142633e+00, 3.7028106305845436e+00, 3.8696280940217886e+00, 4.0367502970449332e+00, 4.2041927875047698e+00, 4.3719714766276327e+00, 4.5401026631678034e+00, 4.7086030589866992e+00, 4.8774898161882945e+00, 5.0467805559527736e+00, 5.2164933992246887e+00, 5.3866469994277919e+00, 5.5572605773966774e+00, 5.7283539587355410e+00, 5.8999476138372433e+00, 6.0720627008216166e+00, 6.2447211116812200e+00, 6.4179455219559527e+00, 6.5917594442957039e+00, 6.7661872863133015e+00, 6.9412544131792480e+00, 7.1169872154661693e+00, 7.2934131828156445e+00, 7.4705609840747460e+00, 7.6484605546357463e+00, 7.8271431918122021e+00, 8.0066416592005272e+00, 8.1869903011111198e+00, 8.3682251683108984e+00, 8.5503841565041103e+00, 8.7335071591960247e+00, 8.9176362368413074e+00, 9.1028158044838392e+00, 9.2890928404578474e+00, 9.4765171191542965e+00, 9.6651414713778827e+00, 9.8550220764490426e+00, 1.0046218790968188e+01, 1.0238795520089184e+01, 1.0432820638288694e+01, 1.0628367468022887e+01, 1.0825514826405534e+01, 1.1024347652217228e+01, 1.1224957728290695e+01, 1.1427444517781534e+01, 1.1631916137256281e+01, 1.1838490495223393e+01, 1.2047296632129509e+01, 1.2258476307546671e+01, 1.2472185893139361e+01, 1.2688598647247023e+01, 1.2907907470327904e+01, 1.3130328272714728e+01, 1.3356104131088610e+01, 1.3585510473849133e+01, 1.3818861627636300e+01, 1.4056519192842705e+01, 1.4298902920011114e+01, 1.4546505073756210e+01, 1.4799909769977225e+01, 1.5059819589095412e+01, 1.5327093154858311e+01, 1.5602799824404595e+01, 1.5888302208889046e+01, 1.6185386288902521e+01, 1.6496478147418177e+01, 1.6825031348357740e+01, 1.7176287776635139e+01, 1.7558985604821832e+01, 1.7990078266499342e+01, 1.8513928608263910e+01}, + {-1.8566551582966934e+01, -1.8043192366212146e+01, -1.7612512215572043e+01, -1.7230187103675732e+01, -1.6879278311267964e+01, -1.6551055199152213e+01, -1.6240280376324659e+01, -1.5943503225988053e+01, -1.5658299727865778e+01, -1.5382885415641553e+01, -1.5115898831352473e+01, -1.4856271522065896e+01, -1.4603145590122086e+01, -1.4355819049893570e+01, -1.4113708281060786e+01, -1.3876321438029819e+01, -1.3643239129136898e+01, -1.3414100064890203e+01, -1.3188590190760220e+01, -1.2966434318726625e+01, -1.2747389586262109e+01, -1.2531240275314762e+01, -1.2317793659316827e+01, -1.2106876638246456e+01, -1.1898332985486029e+01, -1.1692021075138110e+01, -1.1487811990637235e+01, -1.1285587938886058e+01, -1.1085240911376399e+01, -1.0886671546608126e+01, -1.0689788157813780e+01, -1.0494505897387436e+01, -1.0300746035105149e+01, -1.0108435331643134e+01, -9.9175054923613413e+00, -9.7278926890529842e+00, -9.5395371395344313e+00, -9.3523827366910055e+00, -9.1663767199978832e+00, -8.9814693836739572e+00, -8.7976138165555611e+00, -8.6147656695390857e+00, -8.4328829470701354e+00, -8.2519258196777496e+00, -8.0718564549859924e+00, -7.8926388649980117e+00, -7.7142387677523603e+00, -7.5366234617083592e+00, -7.3597617114348806e+00, -7.1836236433617389e+00, -7.0081806505105702e+00, -6.8334053052569255e+00, -6.6592712792911071e+00, -6.4857532700449330e+00, -6.3128269329377309e+00, -6.1404688188693868e+00, -5.9686563164530524e+00, -5.7973675985364332e+00, -5.6265815726098278e+00, -5.4562778347421155e+00, -5.2864366267236216e+00, -5.1170387961280301e+00, -4.9480657590346588e+00, -4.7794994651782767e+00, -4.6113223653163988e+00, -4.4435173806242290e+00, -4.2760678739453368e+00, -4.1089576227421016e+00, -3.9421707936041384e+00, -3.7756919181855801e+00, -3.6095058704533836e+00, -3.4435978451389198e+00, -3.2779533372941430e+00, -3.1125581228617367e+00, -2.9473982401758851e+00, -2.7824599723168095e+00, -2.6177298302480856e+00, -2.4531945366709622e+00, -2.2888410105346408e+00, -2.1246563521456703e+00, -1.9606278288234207e+00, -1.7967428610519807e+00, -1.6329890090818511e+00, -1.4693539599375276e+00, -1.3058255147894620e+00, -1.1423915766510224e+00, -9.7904013836295944e-01, -8.1575927082952060e-01, -6.5253711147178228e-01, -4.8936185286498823e-01, -3.2622173152770212e-01, -1.6310501683142664e-01, -0.0000000000000000e+00, 1.6310501683142664e-01, 3.2622173152770212e-01, 4.8936185286498823e-01, 6.5253711147178228e-01, 8.1575927082952060e-01, 9.7904013836295944e-01, 1.1423915766510224e+00, 1.3058255147894620e+00, 1.4693539599375276e+00, 1.6329890090818511e+00, 1.7967428610519807e+00, 1.9606278288234207e+00, 2.1246563521456703e+00, 2.2888410105346408e+00, 2.4531945366709622e+00, 2.6177298302480856e+00, 2.7824599723168095e+00, 2.9473982401758851e+00, 3.1125581228617367e+00, 3.2779533372941430e+00, 3.4435978451389198e+00, 3.6095058704533836e+00, 3.7756919181855801e+00, 3.9421707936041384e+00, 4.1089576227421016e+00, 4.2760678739453368e+00, 4.4435173806242290e+00, 4.6113223653163988e+00, 4.7794994651782767e+00, 4.9480657590346588e+00, 5.1170387961280301e+00, 5.2864366267236216e+00, 5.4562778347421155e+00, 5.6265815726098278e+00, 5.7973675985364332e+00, 5.9686563164530524e+00, 6.1404688188693868e+00, 6.3128269329377309e+00, 6.4857532700449330e+00, 6.6592712792911071e+00, 6.8334053052569255e+00, 7.0081806505105702e+00, 7.1836236433617389e+00, 7.3597617114348806e+00, 7.5366234617083592e+00, 7.7142387677523603e+00, 7.8926388649980117e+00, 8.0718564549859924e+00, 8.2519258196777496e+00, 8.4328829470701354e+00, 8.6147656695390857e+00, 8.7976138165555611e+00, 8.9814693836739572e+00, 9.1663767199978832e+00, 9.3523827366910055e+00, 9.5395371395344313e+00, 9.7278926890529842e+00, 9.9175054923613413e+00, 1.0108435331643134e+01, 1.0300746035105149e+01, 1.0494505897387436e+01, 1.0689788157813780e+01, 1.0886671546608126e+01, 1.1085240911376399e+01, 1.1285587938886058e+01, 1.1487811990637235e+01, 1.1692021075138110e+01, 1.1898332985486029e+01, 1.2106876638246456e+01, 1.2317793659316827e+01, 1.2531240275314762e+01, 1.2747389586262109e+01, 1.2966434318726625e+01, 1.3188590190760220e+01, 1.3414100064890203e+01, 1.3643239129136898e+01, 1.3876321438029819e+01, 1.4113708281060786e+01, 1.4355819049893570e+01, 1.4603145590122086e+01, 1.4856271522065896e+01, 1.5115898831352473e+01, 1.5382885415641553e+01, 1.5658299727865778e+01, 1.5943503225988053e+01, 1.6240280376324659e+01, 1.6551055199152213e+01, 1.6879278311267964e+01, 1.7230187103675732e+01, 1.7612512215572043e+01, 1.8043192366212146e+01, 1.8566551582966934e+01}, + {-1.8619030592090468e+01, -1.8096159331273782e+01, -1.7665888990577489e+01, -1.7283934123310647e+01, -1.6933370634565016e+01, -1.6605475372599290e+01, -1.6295015412972358e+01, -1.5998543068078176e+01, -1.5713636367765231e+01, -1.5438512350731910e+01, -1.5171810705118517e+01, -1.4912463876600265e+01, -1.4659614689068135e+01, -1.4412561747929246e+01, -1.4170721925268760e+01, -1.3933603791786325e+01, -1.3700788312318828e+01, -1.3471914506172659e+01, -1.3246668589046763e+01, -1.3024775611596180e+01, -1.2805992923888546e+01, -1.2590104998712771e+01, -1.2376919282049462e+01, -1.2166262830933078e+01, -1.1957979562598471e+01, -1.1751927983683725e+01, -1.1547979300411118e+01, -1.1346015834038415e+01, -1.1145929683090303e+01, -1.0947621586721102e+01, -1.0750999953246895e+01, -1.0555980025269434e+01, -1.0362483158498314e+01, -1.0170436195792986e+01, -9.9797709214047838e+00, -9.7904235831297708e+00, -9.6023344722552224e+00, -9.4154475529222363e+00, -9.2297101339294976e+00, -9.0450725771408784e+00, -8.8614880375878489e+00, -8.6789122311192006e+00, -8.4973032260786319e+00, -8.3166212560112189e+00, -8.1368285508332487e+00, -7.9578891842622976e+00, -7.7797689356090070e+00, -7.6024351642886749e+00, -7.4258566956282692e+00, -7.2500037167290969e+00, -7.0748476813029546e+00, -6.9003612225343067e+00, -6.7265180731367256e+00, -6.5532929918714933e+00, -6.3806616958821749e+00, -6.2086007982735998e+00, -6.0370877504282516e+00, -5.8661007886095131e+00, -5.6956188844502709e+00, -5.5256216989684903e+00, -5.3560895397890276e+00, -5.1870033212841671e+00, -5.0183445273745217e+00, -4.8500951767577565e+00, -4.6822377903553614e+00, -4.5147553607879187e+00, -4.3476313237072048e+00, -4.1808495308294304e+00, -4.0143942245280941e+00, -3.8482500138575717e+00, -3.6824018518898707e+00, -3.5168350142570763e+00, -3.3515350788010423e+00, -3.1864879062399973e+00, -3.0216796217689894e+00, -2.8570965975176055e+00, -2.6927254357942609e+00, -2.5285529530516158e+00, -2.3645661645123681e+00, -2.2007522693989476e+00, -2.0370986367144122e+00, -1.8735927915252717e+00, -1.7102224017000158e+00, -1.5469752650598505e+00, -1.3838392969005895e+00, -1.2208025178467894e+00, -1.0578530420011503e+00, -8.9497906535386207e-01, -7.3216885441804769e-01, -5.6941073505871143e-01, -4.0669308148366978e-01, -2.4400430536582823e-01, -8.1332845066888051e-02, 8.1332845066888051e-02, 2.4400430536582823e-01, 4.0669308148366978e-01, 5.6941073505871143e-01, 7.3216885441804769e-01, 8.9497906535386207e-01, 1.0578530420011503e+00, 1.2208025178467894e+00, 1.3838392969005895e+00, 1.5469752650598505e+00, 1.7102224017000158e+00, 1.8735927915252717e+00, 2.0370986367144122e+00, 2.2007522693989476e+00, 2.3645661645123681e+00, 2.5285529530516158e+00, 2.6927254357942609e+00, 2.8570965975176055e+00, 3.0216796217689894e+00, 3.1864879062399973e+00, 3.3515350788010423e+00, 3.5168350142570763e+00, 3.6824018518898707e+00, 3.8482500138575717e+00, 4.0143942245280941e+00, 4.1808495308294304e+00, 4.3476313237072048e+00, 4.5147553607879187e+00, 4.6822377903553614e+00, 4.8500951767577565e+00, 5.0183445273745217e+00, 5.1870033212841671e+00, 5.3560895397890276e+00, 5.5256216989684903e+00, 5.6956188844502709e+00, 5.8661007886095131e+00, 6.0370877504282516e+00, 6.2086007982735998e+00, 6.3806616958821749e+00, 6.5532929918714933e+00, 6.7265180731367256e+00, 6.9003612225343067e+00, 7.0748476813029546e+00, 7.2500037167290969e+00, 7.4258566956282692e+00, 7.6024351642886749e+00, 7.7797689356090070e+00, 7.9578891842622976e+00, 8.1368285508332487e+00, 8.3166212560112189e+00, 8.4973032260786319e+00, 8.6789122311192006e+00, 8.8614880375878489e+00, 9.0450725771408784e+00, 9.2297101339294976e+00, 9.4154475529222363e+00, 9.6023344722552224e+00, 9.7904235831297708e+00, 9.9797709214047838e+00, 1.0170436195792986e+01, 1.0362483158498314e+01, 1.0555980025269434e+01, 1.0750999953246895e+01, 1.0947621586721102e+01, 1.1145929683090303e+01, 1.1346015834038415e+01, 1.1547979300411118e+01, 1.1751927983683725e+01, 1.1957979562598471e+01, 1.2166262830933078e+01, 1.2376919282049462e+01, 1.2590104998712771e+01, 1.2805992923888546e+01, 1.3024775611596180e+01, 1.3246668589046763e+01, 1.3471914506172659e+01, 1.3700788312318828e+01, 1.3933603791786325e+01, 1.4170721925268760e+01, 1.4412561747929246e+01, 1.4659614689068135e+01, 1.4912463876600265e+01, 1.5171810705118517e+01, 1.5438512350731910e+01, 1.5713636367765231e+01, 1.5998543068078176e+01, 1.6295015412972358e+01, 1.6605475372599290e+01, 1.6933370634565016e+01, 1.7283934123310647e+01, 1.7665888990577489e+01, 1.8096159331273782e+01, 1.8619030592090468e+01}, + {-1.8671366806690571e+01, -1.8148980370347783e+01, -1.7719117170958008e+01, -1.7337530106682756e+01, -1.6987309618003824e+01, -1.6659739995236801e+01, -1.6349592753466883e+01, -1.6053423116550778e+01, -1.5768811152035209e+01, -1.5493975394480826e+01, -1.5227556671125813e+01, -1.4968488320721917e+01, -1.4715913884228952e+01, -1.4469132554376165e+01, -1.4227561692518973e+01, -1.3990710282959036e+01, -1.3758159644687614e+01, -1.3529549103735965e+01, -1.3304565144176481e+01, -1.3082933053660961e+01, -1.2864410393317099e+01, -1.2648781825357542e+01, -1.2435854966991251e+01, -1.2225457031069224e+01, -1.2017432077505465e+01, -1.1811638744355296e+01, -1.1607948359555895e+01, -1.1406243357684700e+01, -1.1206415943294315e+01, -1.1008366955213159e+01, -1.0812004895879960e+01, -1.0617245097158223e+01, -1.0424008999756163e+01, -1.0232223527789033e+01, -1.0041820543476462e+01, -9.8527363696957284e+00, -9.6649113702822387e+00, -9.4782895797065567e+00, -9.2928183751587881e+00, -9.1084481852078358e+00, -8.9251322301305365e+00, -8.7428262897666009e+00, -8.5614884953828341e+00, -8.3810791425501474e+00, -8.2015605224698938e+00, -8.0228967695483639e+00, -7.8450537233223443e+00, -7.6679988030953385e+00, -7.4917008938611840e+00, -7.3161302422763823e+00, -7.1412583615998901e+00, -6.9670579446537078e+00, -6.7935027839732776e+00, -6.6205676984161617e+00, -6.4482284655834805e+00, -6.2764617594829843e+00, -6.1052450929273041e+00, -5.9345567642172057e+00, -5.7643758077087970e+00, -5.5946819479066203e+00, -5.4254555567622882e+00, -5.2566776138914113e+00, -5.0883296694508156e+00, -4.9203938094437563e+00, -4.7528526232436477e+00, -4.5856891731470037e+00, -4.4188869657842096e+00, -4.2524299252326587e+00, -4.0863023676909851e+00, -3.9204889775857690e+00, -3.7549747849933839e+00, -3.5897451442697546e+00, -3.4247857137898574e+00, -3.2600824367068570e+00, -3.0956215226480941e+00, -2.9313894302716164e+00, -2.7673728506128410e+00, -2.6035586911561817e+00, -2.4399340605712174e+00, -2.2764862540572279e+00, -2.1132027392437367e+00, -1.9500711425981514e+00, -1.7870792362946351e+00, -1.6242149255011178e+00, -1.4614662360438109e+00, -1.2988213024107587e+00, -1.1362683560579210e+00, -9.7379571398297626e-01, -8.1139176753353270e-01, -6.4904497141773709e-01, -4.8674383288637452e-01, -3.2447690105649102e-01, -1.6223275634733261e-01, -0.0000000000000000e+00, 1.6223275634733261e-01, 3.2447690105649102e-01, 4.8674383288637452e-01, 6.4904497141773709e-01, 8.1139176753353270e-01, 9.7379571398297626e-01, 1.1362683560579210e+00, 1.2988213024107587e+00, 1.4614662360438109e+00, 1.6242149255011178e+00, 1.7870792362946351e+00, 1.9500711425981514e+00, 2.1132027392437367e+00, 2.2764862540572279e+00, 2.4399340605712174e+00, 2.6035586911561817e+00, 2.7673728506128410e+00, 2.9313894302716164e+00, 3.0956215226480941e+00, 3.2600824367068570e+00, 3.4247857137898574e+00, 3.5897451442697546e+00, 3.7549747849933839e+00, 3.9204889775857690e+00, 4.0863023676909851e+00, 4.2524299252326587e+00, 4.4188869657842096e+00, 4.5856891731470037e+00, 4.7528526232436477e+00, 4.9203938094437563e+00, 5.0883296694508156e+00, 5.2566776138914113e+00, 5.4254555567622882e+00, 5.5946819479066203e+00, 5.7643758077087970e+00, 5.9345567642172057e+00, 6.1052450929273041e+00, 6.2764617594829843e+00, 6.4482284655834805e+00, 6.6205676984161617e+00, 6.7935027839732776e+00, 6.9670579446537078e+00, 7.1412583615998901e+00, 7.3161302422763823e+00, 7.4917008938611840e+00, 7.6679988030953385e+00, 7.8450537233223443e+00, 8.0228967695483639e+00, 8.2015605224698938e+00, 8.3810791425501474e+00, 8.5614884953828341e+00, 8.7428262897666009e+00, 8.9251322301305365e+00, 9.1084481852078358e+00, 9.2928183751587881e+00, 9.4782895797065567e+00, 9.6649113702822387e+00, 9.8527363696957284e+00, 1.0041820543476462e+01, 1.0232223527789033e+01, 1.0424008999756163e+01, 1.0617245097158223e+01, 1.0812004895879960e+01, 1.1008366955213159e+01, 1.1206415943294315e+01, 1.1406243357684700e+01, 1.1607948359555895e+01, 1.1811638744355296e+01, 1.2017432077505465e+01, 1.2225457031069224e+01, 1.2435854966991251e+01, 1.2648781825357542e+01, 1.2864410393317099e+01, 1.3082933053660961e+01, 1.3304565144176481e+01, 1.3529549103735965e+01, 1.3758159644687614e+01, 1.3990710282959036e+01, 1.4227561692518973e+01, 1.4469132554376165e+01, 1.4715913884228952e+01, 1.4968488320721917e+01, 1.5227556671125813e+01, 1.5493975394480826e+01, 1.5768811152035209e+01, 1.6053423116550778e+01, 1.6349592753466883e+01, 1.6659739995236801e+01, 1.6987309618003824e+01, 1.7337530106682756e+01, 1.7719117170958008e+01, 1.8148980370347783e+01, 1.8671366806690571e+01}, + {-1.8723561382058008e+01, -1.8201656675685278e+01, -1.7772197980856198e+01, -1.7390976307430105e+01, -1.7041096543327139e+01, -1.6713850376034177e+01, -1.6404013733432148e+01, -1.6108144733313441e+01, -1.5823825468638194e+01, -1.5549275960782586e+01, -1.5283138169159214e+01, -1.5024346320130698e+01, -1.4772044667297957e+01, -1.4525532987045759e+01, -1.4284229126904924e+01, -1.4047642482122557e+01, -1.3815354723529373e+01, -1.3587005481836711e+01, -1.3362281507661821e+01, -1.3140908323999378e+01, -1.2922643701525621e+01, -1.2707272490482195e+01, -1.2494602478007950e+01, -1.2284461031551617e+01, -1.2076692352553557e+01, -1.1871155209388238e+01, -1.1667721050654935e+01, -1.1466272423235269e+01, -1.1266701636724759e+01, -1.1068909628665612e+01, -1.0872804994678496e+01, -1.0678303154963148e+01, -1.0485325634312177e+01, -1.0293799437190248e+01, -1.0103656502883585e+01, -9.9148332284509078e+00, -9.7272700493753241e+00, -9.5409110695534167e+00, -9.3557037336580802e+00, -9.1715985360473766e+00, -8.9885487613184782e+00, -8.8065102523660030e+00, -8.6254412024311282e+00, -8.4453019681474064e+00, -8.2660549010220361e+00, -8.0876641951531028e+00, -7.9100957492873887e+00, -7.7333170415796193e+00, -7.5572970156311445e+00, -7.3820059765703627e+00, -7.2074154960945611e+00, -7.0334983255273515e+00, -6.8602283160613764e+00, -6.6875803454554488e+00, -6.5155302505411381e+00, -6.3440547649682282e+00, -6.1731314616830320e+00, -6.0027386996898384e+00, -5.8328555746948121e+00, -5.6634618732746507e+00, -5.4945380302499895e+00, -5.3260650889766197e+00, -5.1580246642968088e+00, -4.9903989079186992e+00, -4.8231704760145977e+00, -4.6563224988490806e+00, -4.4898385522658026e+00, -4.3237026308777766e+00, -4.1578991228200994e+00, -3.9924127859367369e+00, -3.8272287252842805e+00, -3.6623323718456740e+00, -3.4977094623559837e+00, -3.3333460201503651e+00, -3.1692283369516736e+00, -3.0053429555216815e+00, -2.8416766531057553e+00, -2.6782164256060947e+00, -2.5149494724234098e+00, -2.3518631819111540e+00, -2.1889451173902774e+00, -2.0261830036759103e+00, -1.8635647140704730e+00, -1.7010782577804868e+00, -1.5387117677168360e+00, -1.3764534886404416e+00, -1.2142917656172734e+00, -1.0522150327483684e+00, -8.9021180214204398e-01, -7.2827065309683536e-01, -5.6638022146482336e-01, -4.0452918916600705e-01, -2.4270627382517243e-01, -8.0900218503372048e-02, 8.0900218503372048e-02, 2.4270627382517243e-01, 4.0452918916600705e-01, 5.6638022146482336e-01, 7.2827065309683536e-01, 8.9021180214204398e-01, 1.0522150327483684e+00, 1.2142917656172734e+00, 1.3764534886404416e+00, 1.5387117677168360e+00, 1.7010782577804868e+00, 1.8635647140704730e+00, 2.0261830036759103e+00, 2.1889451173902774e+00, 2.3518631819111540e+00, 2.5149494724234098e+00, 2.6782164256060947e+00, 2.8416766531057553e+00, 3.0053429555216815e+00, 3.1692283369516736e+00, 3.3333460201503651e+00, 3.4977094623559837e+00, 3.6623323718456740e+00, 3.8272287252842805e+00, 3.9924127859367369e+00, 4.1578991228200994e+00, 4.3237026308777766e+00, 4.4898385522658026e+00, 4.6563224988490806e+00, 4.8231704760145977e+00, 4.9903989079186992e+00, 5.1580246642968088e+00, 5.3260650889766197e+00, 5.4945380302499895e+00, 5.6634618732746507e+00, 5.8328555746948121e+00, 6.0027386996898384e+00, 6.1731314616830320e+00, 6.3440547649682282e+00, 6.5155302505411381e+00, 6.6875803454554488e+00, 6.8602283160613764e+00, 7.0334983255273515e+00, 7.2074154960945611e+00, 7.3820059765703627e+00, 7.5572970156311445e+00, 7.7333170415796193e+00, 7.9100957492873887e+00, 8.0876641951531028e+00, 8.2660549010220361e+00, 8.4453019681474064e+00, 8.6254412024311282e+00, 8.8065102523660030e+00, 8.9885487613184782e+00, 9.1715985360473766e+00, 9.3557037336580802e+00, 9.5409110695534167e+00, 9.7272700493753241e+00, 9.9148332284509078e+00, 1.0103656502883585e+01, 1.0293799437190248e+01, 1.0485325634312177e+01, 1.0678303154963148e+01, 1.0872804994678496e+01, 1.1068909628665612e+01, 1.1266701636724759e+01, 1.1466272423235269e+01, 1.1667721050654935e+01, 1.1871155209388238e+01, 1.2076692352553557e+01, 1.2284461031551617e+01, 1.2494602478007950e+01, 1.2707272490482195e+01, 1.2922643701525621e+01, 1.3140908323999378e+01, 1.3362281507661821e+01, 1.3587005481836711e+01, 1.3815354723529373e+01, 1.4047642482122557e+01, 1.4284229126904924e+01, 1.4525532987045759e+01, 1.4772044667297957e+01, 1.5024346320130698e+01, 1.5283138169159214e+01, 1.5549275960782586e+01, 1.5823825468638194e+01, 1.6108144733313441e+01, 1.6404013733432148e+01, 1.6713850376034177e+01, 1.7041096543327139e+01, 1.7390976307430105e+01, 1.7772197980856198e+01, 1.8201656675685278e+01, 1.8723561382058008e+01}, + {-1.8775615458013544e+01, -1.8254189423434781e+01, -1.7825132627760091e+01, -1.7444273962020645e+01, -1.7094732674611997e+01, -1.6767807805810907e+01, -1.6458279669864240e+01, -1.6162709261170946e+01, -1.5878680685959477e+01, -1.5604415443478599e+01, -1.5338556618472303e+01, -1.5080039319512867e+01, -1.4828008508467775e+01, -1.4581764541755678e+01, -1.4340725750026818e+01, -1.4104401936851414e+01, -1.3872375122615423e+01, -1.3644285240693469e+01, -1.3419819306444866e+01, -1.3198703076577427e+01, -1.2980694529827234e+01, -1.2765578703092004e+01, -1.2553163552163017e+01, -1.2343276597888334e+01, -1.2135762182101830e+01, -1.1930479202418702e+01, -1.1727299227066995e+01, -1.1526104914236369e+01, -1.1326788677599657e+01, -1.1129251552471963e+01, -1.0933402226734774e+01, -1.0739156208018326e+01, -1.0546435104305445e+01, -1.0355165999524157e+01, -1.0165280909146327e+01, -9.9767163035334772e+00, -9.7894126889375794e+00, -9.6033142377998999e+00, -9.4183684613901413e+00, -9.2345259189629125e+00, -9.0517399585345863e+00, -8.8699664851432551e+00, -8.6891637530810133e+00, -8.5092921791069820e+00, -8.3303141740818543e+00, -8.1521939908263850e+00, -7.9748975863098721e+00, -7.7983924965309503e+00, -7.6226477226697984e+00, -7.4476336272751640e+00, -7.2733218394067363e+00, -7.0996851677878805e+00, -6.9266975211391140e+00, -6.7543338349621100e+00, -6.5825700041298303e+00, -6.4113828207126948e+00, -6.2407499165352709e+00, -6.0706497100141474e+00, -5.9010613568767107e+00, -5.7319647044035085e+00, -5.5633402488744599e+00, -5.3951690959323528e+00, -5.2274329236061510e+00, -5.0601139477624058e+00, -4.8931948897757946e+00, -4.7266589462300219e+00, -4.5604897604781494e+00, -4.3946713959074097e+00, -4.2291883107676789e+00, -4.0640253344354704e+00, -3.8991676449965649e+00, -3.7346007480405388e+00, -3.5703104565694619e+00, -3.4062828719311762e+00, -3.2425043656948236e+00, -3.0789615623928461e+00, -2.9156413230595541e+00, -2.7525307295016344e+00, -2.5896170692407368e+00, -2.4268878210725524e+00, -2.2643306411906372e+00, -2.1019333498267070e+00, -1.9396839183622288e+00, -1.7775704568689277e+00, -1.6155812020383324e+00, -1.4537045054627018e+00, -1.2919288222316836e+00, -1.1302426998108011e+00, -9.6863476716944097e-01, -8.0709372412735814e-01, -6.4560833088991310e-01, -4.8416739774326256e-01, -3.2275977488157320e-01, -1.6137434233903589e-01, -0.0000000000000000e+00, 1.6137434233903589e-01, 3.2275977488157320e-01, 4.8416739774326256e-01, 6.4560833088991310e-01, 8.0709372412735814e-01, 9.6863476716944097e-01, 1.1302426998108011e+00, 1.2919288222316836e+00, 1.4537045054627018e+00, 1.6155812020383324e+00, 1.7775704568689277e+00, 1.9396839183622288e+00, 2.1019333498267070e+00, 2.2643306411906372e+00, 2.4268878210725524e+00, 2.5896170692407368e+00, 2.7525307295016344e+00, 2.9156413230595541e+00, 3.0789615623928461e+00, 3.2425043656948236e+00, 3.4062828719311762e+00, 3.5703104565694619e+00, 3.7346007480405388e+00, 3.8991676449965649e+00, 4.0640253344354704e+00, 4.2291883107676789e+00, 4.3946713959074097e+00, 4.5604897604781494e+00, 4.7266589462300219e+00, 4.8931948897757946e+00, 5.0601139477624058e+00, 5.2274329236061510e+00, 5.3951690959323528e+00, 5.5633402488744599e+00, 5.7319647044035085e+00, 5.9010613568767107e+00, 6.0706497100141474e+00, 6.2407499165352709e+00, 6.4113828207126948e+00, 6.5825700041298303e+00, 6.7543338349621100e+00, 6.9266975211391140e+00, 7.0996851677878805e+00, 7.2733218394067363e+00, 7.4476336272751640e+00, 7.6226477226697984e+00, 7.7983924965309503e+00, 7.9748975863098721e+00, 8.1521939908263850e+00, 8.3303141740818543e+00, 8.5092921791069820e+00, 8.6891637530810133e+00, 8.8699664851432551e+00, 9.0517399585345863e+00, 9.2345259189629125e+00, 9.4183684613901413e+00, 9.6033142377998999e+00, 9.7894126889375794e+00, 9.9767163035334772e+00, 1.0165280909146327e+01, 1.0355165999524157e+01, 1.0546435104305445e+01, 1.0739156208018326e+01, 1.0933402226734774e+01, 1.1129251552471963e+01, 1.1326788677599657e+01, 1.1526104914236369e+01, 1.1727299227066995e+01, 1.1930479202418702e+01, 1.2135762182101830e+01, 1.2343276597888334e+01, 1.2553163552163017e+01, 1.2765578703092004e+01, 1.2980694529827234e+01, 1.3198703076577427e+01, 1.3419819306444866e+01, 1.3644285240693469e+01, 1.3872375122615423e+01, 1.4104401936851414e+01, 1.4340725750026818e+01, 1.4581764541755678e+01, 1.4828008508467775e+01, 1.5080039319512867e+01, 1.5338556618472303e+01, 1.5604415443478599e+01, 1.5878680685959477e+01, 1.6162709261170946e+01, 1.6458279669864240e+01, 1.6767807805810907e+01, 1.7094732674611997e+01, 1.7444273962020645e+01, 1.7825132627760091e+01, 1.8254189423434781e+01, 1.8775615458013544e+01}, + {-1.8827530159196098e+01, -1.8306579773944520e+01, -1.7877922302817918e+01, -1.7497424290078804e+01, -1.7148219258607661e+01, -1.6821613557585714e+01, -1.6512391861491736e+01, -1.6217118024196811e+01, -1.5933378153189908e+01, -1.5659395216751500e+01, -1.5393813418192966e+01, -1.5135568742958350e+01, -1.4883806856859362e+01, -1.4637828692771006e+01, -1.4397053061445078e+01, -1.4160990172186152e+01, -1.3929222392681286e+01, -1.3701389956978932e+01, -1.3477180143402940e+01, -1.3256318940768097e+01, -1.3038564534403923e+01, -1.2823702146512529e+01, -1.2611539900280661e+01, -1.2401905468777167e+01, -1.2194643333116042e+01, -1.1989612519093924e+01, -1.1786684713553210e+01, -1.1585742685014308e+01, -1.1386678950280542e+01, -1.1189394641517911e+01, -1.0993798537966583e+01, -1.0799806233800744e+01, -1.0607339419318674e+01, -1.0416325257045436e+01, -1.0226695837777637e+01, -1.0038387704321417e+01, -9.8513414328396713e+00, -9.6655012634583866e+00, -9.4808147731799934e+00, -9.2972325852854905e+00, -9.1147081103323924e+00, -8.9331973146145547e+00, -8.7526585125759730e+00, -8.5730521801893929e+00, -8.3943407867426210e+00, -8.2164886428367048e+00, -8.0394617627036364e+00, -7.8632277392072103e+00, -7.6877556301072998e+00, -7.5130158543520213e+00, -7.3389800973191823e+00, -7.1656212240628339e+00, -6.9929131997360230e+00, -6.8208310164601347e+00, -6.6493506259970188e+00, -6.4784488776542828e+00, -6.3081034609187254e+00, -6.1382928523689460e+00, -5.9689962664672880e+00, -5.8001936098740767e+00, -5.6318654389648133e+00, -5.4639929202639941e+00, -5.2965577935384172e+00, -5.1295423373184992e+00, -4.9629293366389069e+00, -4.7967020528099553e+00, -4.6308441950490966e+00, -4.4653398938177720e+00, -4.3001736757230296e+00, -4.1353304398559789e+00, -3.9707954354504480e+00, -3.8065542407552790e+00, -3.6425927430227989e+00, -3.4788971195240692e+00, -3.3154538195088263e+00, -3.1522495470345691e+00, -2.9892712445951148e+00, -2.8265060774842699e+00, -2.6639414188349808e+00, -2.5015648352786735e+00, -2.3393640731732996e+00, -2.1773270453521110e+00, -2.0154418183483078e+00, -1.8536966000534938e+00, -1.6920797277704067e+00, -1.5305796566226446e+00, -1.3691849482861076e+00, -1.2078842600086817e+00, -1.0466663338862598e+00, -8.8551998636459661e-01, -7.2443409793770541e-01, -5.6339760301455488e-01, -4.0239947992671032e-01, -2.4142874105030510e-01, -8.0474423016328678e-02, 8.0474423016328678e-02, 2.4142874105030510e-01, 4.0239947992671032e-01, 5.6339760301455488e-01, 7.2443409793770541e-01, 8.8551998636459661e-01, 1.0466663338862598e+00, 1.2078842600086817e+00, 1.3691849482861076e+00, 1.5305796566226446e+00, 1.6920797277704067e+00, 1.8536966000534938e+00, 2.0154418183483078e+00, 2.1773270453521110e+00, 2.3393640731732996e+00, 2.5015648352786735e+00, 2.6639414188349808e+00, 2.8265060774842699e+00, 2.9892712445951148e+00, 3.1522495470345691e+00, 3.3154538195088263e+00, 3.4788971195240692e+00, 3.6425927430227989e+00, 3.8065542407552790e+00, 3.9707954354504480e+00, 4.1353304398559789e+00, 4.3001736757230296e+00, 4.4653398938177720e+00, 4.6308441950490966e+00, 4.7967020528099553e+00, 4.9629293366389069e+00, 5.1295423373184992e+00, 5.2965577935384172e+00, 5.4639929202639941e+00, 5.6318654389648133e+00, 5.8001936098740767e+00, 5.9689962664672880e+00, 6.1382928523689460e+00, 6.3081034609187254e+00, 6.4784488776542828e+00, 6.6493506259970188e+00, 6.8208310164601347e+00, 6.9929131997360230e+00, 7.1656212240628339e+00, 7.3389800973191823e+00, 7.5130158543520213e+00, 7.6877556301072998e+00, 7.8632277392072103e+00, 8.0394617627036364e+00, 8.2164886428367048e+00, 8.3943407867426210e+00, 8.5730521801893929e+00, 8.7526585125759730e+00, 8.9331973146145547e+00, 9.1147081103323924e+00, 9.2972325852854905e+00, 9.4808147731799934e+00, 9.6655012634583866e+00, 9.8513414328396713e+00, 1.0038387704321417e+01, 1.0226695837777637e+01, 1.0416325257045436e+01, 1.0607339419318674e+01, 1.0799806233800744e+01, 1.0993798537966583e+01, 1.1189394641517911e+01, 1.1386678950280542e+01, 1.1585742685014308e+01, 1.1786684713553210e+01, 1.1989612519093924e+01, 1.2194643333116042e+01, 1.2401905468777167e+01, 1.2611539900280661e+01, 1.2823702146512529e+01, 1.3038564534403923e+01, 1.3256318940768097e+01, 1.3477180143402940e+01, 1.3701389956978932e+01, 1.3929222392681286e+01, 1.4160990172186152e+01, 1.4397053061445078e+01, 1.4637828692771006e+01, 1.4883806856859362e+01, 1.5135568742958350e+01, 1.5393813418192966e+01, 1.5659395216751500e+01, 1.5933378153189908e+01, 1.6217118024196811e+01, 1.6512391861491736e+01, 1.6821613557585714e+01, 1.7148219258607661e+01, 1.7497424290078804e+01, 1.7877922302817918e+01, 1.8306579773944520e+01, 1.8827530159196098e+01}, + {-1.8879306595344101e+01, -1.8358828872057543e+01, -1.7930568181145354e+01, -1.7550428494704086e+01, -1.7201557525065336e+01, -1.6875268886917173e+01, -1.6566351589127169e+01, -1.6271372328095570e+01, -1.5987919200699100e+01, -1.5714216635509363e+01, -1.5448909947718773e+01, -1.5190935994367434e+01, -1.4939441140940190e+01, -1.4693726893234164e+01, -1.4453212539122219e+01, -1.4217408691087410e+01, -1.3985898061893202e+01, -1.3758321184299211e+01, -1.3534365597840969e+01, -1.3313757521857125e+01, -1.3096255346825995e+01, -1.2881644478923162e+01, -1.2669733207493820e+01, -1.2460349356668459e+01, -1.2253337545746717e+01, -1.2048556927665979e+01, -1.1845879306886999e+01, -1.1645187561301928e+01, -1.1446374309916036e+01, -1.1249340780842516e+01, -1.1053995843796514e+01, -1.0860255178628208e+01, -1.0668040557095399e+01, -1.0477279219472964e+01, -1.0287903331040779e+01, -1.0099849506211216e+01, -9.9130583902203586e+00, -9.7274742900396252e+00, -9.5430448475612568e+00, -9.3597207492442038e+00, -9.1774554673313418e+00, -8.9962050285074913e+00, -8.8159278064930948e+00, -8.6365843355868694e+00, -8.4581371426023590e+00, -8.2805505950043532e+00, -8.1037907633543647e+00, -7.9278252964301190e+00, -7.7526233076005129e+00, -7.5781552712214886e+00, -7.4043929279751541e+00, -7.2313091982087343e+00, -7.0588781024451404e+00, -6.8870746883362148e+00, -6.7158749634153345e+00, -6.5452558330803203e+00, -6.3751950433020319e+00, -6.2056711276101213e+00, -6.0366633579564608e+00, -5.8681516990995659e+00, -5.7001167661909662e+00, -5.5325397852775344e+00, -5.3654025564628540e+00, -5.1986874194964612e+00, -5.0323772215824860e+00, -4.8664552872193818e+00, -4.7009053899003126e+00, -4.5357117255196737e+00, -4.3708588873453733e+00, -4.2063318424291563e+00, -4.0421159093385528e+00, -3.8781967371040955e+00, -3.7145602852845432e+00, -3.5511928050609516e+00, -3.3880808212776983e+00, -3.2252111153551550e+00, -3.0625707090045471e+00, -2.9001468486808863e+00, -2.7379269907145933e+00, -2.5758987870667562e+00, -2.4140500716568205e+00, -2.2523688472150090e+00, -2.0908432726148978e+00, -1.9294616506444018e+00, -1.7682124161759520e+00, -1.6070841246989318e+00, -1.4460654411794531e+00, -1.2851451292143858e+00, -1.1243120404481430e+00, -9.6355510422216051e-01, -8.0286331742823902e-01, -6.4222573453801035e-01, -4.8163145778170013e-01, -3.2106962745015089e-01, -1.6052941229469772e-01, -0.0000000000000000e+00, 1.6052941229469772e-01, 3.2106962745015089e-01, 4.8163145778170013e-01, 6.4222573453801035e-01, 8.0286331742823902e-01, 9.6355510422216051e-01, 1.1243120404481430e+00, 1.2851451292143858e+00, 1.4460654411794531e+00, 1.6070841246989318e+00, 1.7682124161759520e+00, 1.9294616506444018e+00, 2.0908432726148978e+00, 2.2523688472150090e+00, 2.4140500716568205e+00, 2.5758987870667562e+00, 2.7379269907145933e+00, 2.9001468486808863e+00, 3.0625707090045471e+00, 3.2252111153551550e+00, 3.3880808212776983e+00, 3.5511928050609516e+00, 3.7145602852845432e+00, 3.8781967371040955e+00, 4.0421159093385528e+00, 4.2063318424291563e+00, 4.3708588873453733e+00, 4.5357117255196737e+00, 4.7009053899003126e+00, 4.8664552872193818e+00, 5.0323772215824860e+00, 5.1986874194964612e+00, 5.3654025564628540e+00, 5.5325397852775344e+00, 5.7001167661909662e+00, 5.8681516990995659e+00, 6.0366633579564608e+00, 6.2056711276101213e+00, 6.3751950433020319e+00, 6.5452558330803203e+00, 6.7158749634153345e+00, 6.8870746883362148e+00, 7.0588781024451404e+00, 7.2313091982087343e+00, 7.4043929279751541e+00, 7.5781552712214886e+00, 7.7526233076005129e+00, 7.9278252964301190e+00, 8.1037907633543647e+00, 8.2805505950043532e+00, 8.4581371426023590e+00, 8.6365843355868694e+00, 8.8159278064930948e+00, 8.9962050285074913e+00, 9.1774554673313418e+00, 9.3597207492442038e+00, 9.5430448475612568e+00, 9.7274742900396252e+00, 9.9130583902203586e+00, 1.0099849506211216e+01, 1.0287903331040779e+01, 1.0477279219472964e+01, 1.0668040557095399e+01, 1.0860255178628208e+01, 1.1053995843796514e+01, 1.1249340780842516e+01, 1.1446374309916036e+01, 1.1645187561301928e+01, 1.1845879306886999e+01, 1.2048556927665979e+01, 1.2253337545746717e+01, 1.2460349356668459e+01, 1.2669733207493820e+01, 1.2881644478923162e+01, 1.3096255346825995e+01, 1.3313757521857125e+01, 1.3534365597840969e+01, 1.3758321184299211e+01, 1.3985898061893202e+01, 1.4217408691087410e+01, 1.4453212539122219e+01, 1.4693726893234164e+01, 1.4939441140940190e+01, 1.5190935994367434e+01, 1.5448909947718773e+01, 1.5714216635509363e+01, 1.5987919200699100e+01, 1.6271372328095570e+01, 1.6566351589127169e+01, 1.6875268886917173e+01, 1.7201557525065336e+01, 1.7550428494704086e+01, 1.7930568181145354e+01, 1.8358828872057543e+01, 1.8879306595344101e+01}, + {-1.8930945861570141e+01, -1.8410937847399730e+01, -1.7983071422125320e+01, -1.7603287762782053e+01, -1.7254748687059873e+01, -1.6928775032235986e+01, -1.6620160116009828e+01, -1.6325473460556140e+01, -1.6042305140399389e+01, -1.5768881035760351e+01, -1.5503847567102451e+01, -1.5246142457847222e+01, -1.4994912768931876e+01, -1.4749460575583919e+01, -1.4509205639853443e+01, -1.4273658974878348e+01, -1.4042403636302666e+01, -1.3815080453660714e+01, -1.3591377225971019e+01, -1.3371020401535507e+01, -1.3153768574557885e+01, -1.2939407333876543e+01, -1.2727745133777605e+01, -1.2518609948312903e+01, -1.2311846533891678e+01, -1.2107314169569506e+01, -1.1904884776447382e+01, -1.1704441340847984e+01, -1.1505876583067728e+01, -1.1309091826281094e+01, -1.1113996029812375e+01, -1.0920504958337819e+01, -1.0728540464237067e+01, -1.0538029864706095e+01, -1.0348905398685391e+01, -1.0161103751374336e+01, -9.9745656362640407e+00, -9.7892354263520396e+00, -9.6050608275979510e+00, -9.4219925888112019e+00, -9.2399842430857984e+00, -9.0589918766548454e+00, -8.8789739216625421e+00, -8.6998909698693474e+00, -8.5217056047373152e+00, -8.3443822497033171e+00, -8.1678870307509044e+00, -7.9921876516470487e+00, -7.8172532804264092e+00, -7.6430544458895735e+00, -7.4695629430384693e+00, -7.2967517465063425e+00, -7.1245949311547765e+00, -6.9530675991094046e+00, -6.7821458125915717e+00, -6.6118065319773942e+00, -6.4420275585800111e+00, -6.2727874817069420e+00, -6.1040656295934008e+00, -5.9358420238552689e+00, -5.7680973371429536e+00, -5.6008128537104387e+00, -5.4339704326429148e+00, -5.2675524735120289e+00, -5.1015418842505529e+00, -4.9359220510583919e+00, -4.7706768101697055e+00, -4.6057904213268381e+00, -4.4412475428209168e+00, -4.2770332079715754e+00, -4.1131328029295950e+00, -3.9495320456963339e+00, -3.7862169662628560e+00, -3.6231738877798154e+00, -3.4603894086764226e+00, -3.2978503856533741e+00, -3.1355439174805326e+00, -2.9734573295354325e+00, -2.8115781590234925e+00, -2.6498941408250944e+00, -2.4883931939185926e+00, -2.3270634083318020e+00, -2.1658930325776748e+00, -2.0048704615326960e+00, -1.8439842247190983e+00, -1.6832229749542722e+00, -1.5225754773327997e+00, -1.3620305985083838e+00, -1.2015772962445594e+00, -1.0412046092045326e+00, -8.8090164695175288e-01, -7.2065758013394154e-01, -5.6046163082425071e-01, -4.0030306299404111e-01, -2.4017117309244904e-01, -8.0055280708449292e-02, 8.0055280708449292e-02, 2.4017117309244904e-01, 4.0030306299404111e-01, 5.6046163082425071e-01, 7.2065758013394154e-01, 8.8090164695175288e-01, 1.0412046092045326e+00, 1.2015772962445594e+00, 1.3620305985083838e+00, 1.5225754773327997e+00, 1.6832229749542722e+00, 1.8439842247190983e+00, 2.0048704615326960e+00, 2.1658930325776748e+00, 2.3270634083318020e+00, 2.4883931939185926e+00, 2.6498941408250944e+00, 2.8115781590234925e+00, 2.9734573295354325e+00, 3.1355439174805326e+00, 3.2978503856533741e+00, 3.4603894086764226e+00, 3.6231738877798154e+00, 3.7862169662628560e+00, 3.9495320456963339e+00, 4.1131328029295950e+00, 4.2770332079715754e+00, 4.4412475428209168e+00, 4.6057904213268381e+00, 4.7706768101697055e+00, 4.9359220510583919e+00, 5.1015418842505529e+00, 5.2675524735120289e+00, 5.4339704326429148e+00, 5.6008128537104387e+00, 5.7680973371429536e+00, 5.9358420238552689e+00, 6.1040656295934008e+00, 6.2727874817069420e+00, 6.4420275585800111e+00, 6.6118065319773942e+00, 6.7821458125915717e+00, 6.9530675991094046e+00, 7.1245949311547765e+00, 7.2967517465063425e+00, 7.4695629430384693e+00, 7.6430544458895735e+00, 7.8172532804264092e+00, 7.9921876516470487e+00, 8.1678870307509044e+00, 8.3443822497033171e+00, 8.5217056047373152e+00, 8.6998909698693474e+00, 8.8789739216625421e+00, 9.0589918766548454e+00, 9.2399842430857984e+00, 9.4219925888112019e+00, 9.6050608275979510e+00, 9.7892354263520396e+00, 9.9745656362640407e+00, 1.0161103751374336e+01, 1.0348905398685391e+01, 1.0538029864706095e+01, 1.0728540464237067e+01, 1.0920504958337819e+01, 1.1113996029812375e+01, 1.1309091826281094e+01, 1.1505876583067728e+01, 1.1704441340847984e+01, 1.1904884776447382e+01, 1.2107314169569506e+01, 1.2311846533891678e+01, 1.2518609948312903e+01, 1.2727745133777605e+01, 1.2939407333876543e+01, 1.3153768574557885e+01, 1.3371020401535507e+01, 1.3591377225971019e+01, 1.3815080453660714e+01, 1.4042403636302666e+01, 1.4273658974878348e+01, 1.4509205639853443e+01, 1.4749460575583919e+01, 1.4994912768931876e+01, 1.5246142457847222e+01, 1.5503847567102451e+01, 1.5768881035760351e+01, 1.6042305140399389e+01, 1.6325473460556140e+01, 1.6620160116009828e+01, 1.6928775032235986e+01, 1.7254748687059873e+01, 1.7603287762782053e+01, 1.7983071422125320e+01, 1.8410937847399730e+01, 1.8930945861570141e+01}, + {-1.8982449038629166e+01, -1.8462907814661030e+01, -1.8035433169700678e+01, -1.7656003265287762e+01, -1.7307793941303686e+01, -1.6982133215169227e+01, -1.6673818688140226e+01, -1.6379422691596499e+01, -1.6096537266100814e+01, -1.5823389734978102e+01, -1.5558627617427760e+01, -1.5301189498098173e+01, -1.5050223129207568e+01, -1.4805031151963790e+01, -1.4565033799686276e+01, -1.4329742483675762e+01, -1.4098740600289259e+01, -1.3871669273924994e+01, -1.3648216561379414e+01, -1.3428109138379162e+01, -1.3211105801450707e+01, -1.2996992320804354e+01, -1.2785577314468604e+01, -1.2576688905294764e+01, -1.2370171985743601e+01, -1.2165885959983921e+01, -1.1963702864796298e+01, -1.1763505794009992e+01, -1.1565187568319024e+01, -1.1368649605090505e+01, -1.1173800952409410e+01, -1.0980557458945643e+01, -1.0788841056880692e+01, -1.0598579139520853e+01, -1.0409704018662802e+01, -1.0222152449492267e+01, -1.0035865212956141e+01, -9.8507867472781321e+00, -9.6668648216825712e+00, -9.4840502465221892e+00, -9.3022966149286930e+00, -9.1215600718621754e+00, -8.9417991070598717e+00, -8.7629743689023787e+00, -8.5850484966463263e+00, -8.4079859688330369e+00, -8.2317529659853896e+00, -8.0563172459604981e+00, -7.8816480305419629e+00, -7.7077159020391406e+00, -7.5344927088175595e+00, -7.3619514788185860e+00, -7.1900663402415486e+00, -7.0188124486605776e+00, -6.8481659199339457e+00, -6.6781037683378583e+00, -6.5086038494209282e+00, -6.3396448071316529e+00, -6.1712060248201084e+00, -6.0032675797578730e+00, -5.8358102008577646e+00, -5.6688152293079357e+00, -5.5022645818639999e+00, -5.3361407165684911e+00, -5.1704266006896686e+00, -5.0051056806918259e+00, -4.8401618540670963e+00, -4.6755794428746595e+00, -4.5113431688473895e+00, -4.3474381299386442e+00, -4.1838497781931396e+00, -4.0205638988360004e+00, -3.8575665904830925e+00, -3.6948442463838789e+00, -3.5323835366153280e+00, -3.3701713911519686e+00, -3.2081949837430650e+00, -3.0464417165332232e+00, -2.8848992053675047e+00, -2.7235552657264601e+00, -2.5623978992403580e+00, -2.4014152807354292e+00, -2.2405957457680694e+00, -2.0799277786058252e+00, -1.9194000006165373e+00, -1.7590011590293138e+00, -1.5987201160331019e+00, -1.4385458381804410e+00, -1.2784673860656646e+00, -1.1184739042482656e+00, -9.5855461139344544e-01, -7.9869879060299465e-01, -6.3889577991065161e-01, -4.7913496291691687e-01, -3.1940575953902500e-01, -1.5969761685235179e-01, -0.0000000000000000e+00, 1.5969761685235179e-01, 3.1940575953902500e-01, 4.7913496291691687e-01, 6.3889577991065161e-01, 7.9869879060299465e-01, 9.5855461139344544e-01, 1.1184739042482656e+00, 1.2784673860656646e+00, 1.4385458381804410e+00, 1.5987201160331019e+00, 1.7590011590293138e+00, 1.9194000006165373e+00, 2.0799277786058252e+00, 2.2405957457680694e+00, 2.4014152807354292e+00, 2.5623978992403580e+00, 2.7235552657264601e+00, 2.8848992053675047e+00, 3.0464417165332232e+00, 3.2081949837430650e+00, 3.3701713911519686e+00, 3.5323835366153280e+00, 3.6948442463838789e+00, 3.8575665904830925e+00, 4.0205638988360004e+00, 4.1838497781931396e+00, 4.3474381299386442e+00, 4.5113431688473895e+00, 4.6755794428746595e+00, 4.8401618540670963e+00, 5.0051056806918259e+00, 5.1704266006896686e+00, 5.3361407165684911e+00, 5.5022645818639999e+00, 5.6688152293079357e+00, 5.8358102008577646e+00, 6.0032675797578730e+00, 6.1712060248201084e+00, 6.3396448071316529e+00, 6.5086038494209282e+00, 6.6781037683378583e+00, 6.8481659199339457e+00, 7.0188124486605776e+00, 7.1900663402415486e+00, 7.3619514788185860e+00, 7.5344927088175595e+00, 7.7077159020391406e+00, 7.8816480305419629e+00, 8.0563172459604981e+00, 8.2317529659853896e+00, 8.4079859688330369e+00, 8.5850484966463263e+00, 8.7629743689023787e+00, 8.9417991070598717e+00, 9.1215600718621754e+00, 9.3022966149286930e+00, 9.4840502465221892e+00, 9.6668648216825712e+00, 9.8507867472781321e+00, 1.0035865212956141e+01, 1.0222152449492267e+01, 1.0409704018662802e+01, 1.0598579139520853e+01, 1.0788841056880692e+01, 1.0980557458945643e+01, 1.1173800952409410e+01, 1.1368649605090505e+01, 1.1565187568319024e+01, 1.1763505794009992e+01, 1.1963702864796298e+01, 1.2165885959983921e+01, 1.2370171985743601e+01, 1.2576688905294764e+01, 1.2785577314468604e+01, 1.2996992320804354e+01, 1.3211105801450707e+01, 1.3428109138379162e+01, 1.3648216561379414e+01, 1.3871669273924994e+01, 1.4098740600289259e+01, 1.4329742483675762e+01, 1.4565033799686276e+01, 1.4805031151963790e+01, 1.5050223129207568e+01, 1.5301189498098173e+01, 1.5558627617427760e+01, 1.5823389734978102e+01, 1.6096537266100814e+01, 1.6379422691596499e+01, 1.6673818688140226e+01, 1.6982133215169227e+01, 1.7307793941303686e+01, 1.7656003265287762e+01, 1.8035433169700678e+01, 1.8462907814661030e+01, 1.8982449038629166e+01}, + {-1.9033817193180372e+01, -1.8514739873870020e+01, -1.8087654552659949e+01, -1.7708576157582009e+01, -1.7360694468453165e+01, -1.7035344640856714e+01, -1.6727328534606457e+01, -1.6433221273899989e+01, -1.6150616853857390e+01, -1.5877744032458063e+01, -1.5613251421176075e+01, -1.5356078460791041e+01, -1.5105373590679383e+01, -1.4860440014620181e+01, -1.4620698434329638e+01, -1.4385660656810286e+01, -1.4154910416992225e+01, -1.3928089132251925e+01, -1.3704885115481808e+01, -1.3485025268316207e+01, -1.3268268588222005e+01, -1.3054401025509831e+01, -1.2843231360770561e+01, -1.2634587864551046e+01, -1.2428315564322974e+01, -1.2224273988380631e+01, -1.2022335288240422e+01, -1.1822382664331087e+01, -1.1624309036867450e+01, -1.1428015916557383e+01, -1.1233412439414929e+01, -1.1040414537288214e+01, -1.0848944221357737e+01, -1.0658928960246737e+01, -1.0470301137821307e+01, -1.0282997578470843e+01, -1.0096959129817110e+01, -9.9121302945287511e+00, -9.7284589043113154e+00, -9.5458958302732722e+00, -9.3643947247907189e+00, -9.1839117907500878e+00, -9.0044055746721732e+00, -8.8258367807379408e+00, -8.6481681031671602e+00, -8.4713640747611425e+00, -8.2953909297232951e+00, -8.1202164791264426e+00, -7.9458099976117715e+00, -7.7721421200878789e+00, -7.5991847473548857e+00, -7.4269109597125382e+00, -7.2552949377261493e+00, -7.0843118894232422e+00, -6.9139379832792587e+00, -6.7441502864247154e+00, -6.5749267075705307e+00, -6.4062459442041968e+00, -6.2380874336583796e+00, -6.0704313076963157e+00, -5.9032583502958440e+00, -5.7365499583469575e+00, -5.5702881050067488e+00, -5.4044553054813402e+00, -5.2390345850270315e+00, -5.0740094489830243e+00, -4.9093638546659628e+00, -4.7450821849723575e+00, -4.5811492235491675e+00, -4.4175501314054006e+00, -4.2542704248488947e+00, -4.0912959546425300e+00, -3.9286128862831946e+00, -3.7662076813149068e+00, -3.6040670795948389e+00, -3.4421780824374997e+00, -3.2805279365682800e+00, -3.1191041188228450e+00, -2.9578943215336770e+00, -2.7968864385493881e+00, -2.6360685518363063e+00, -2.4754289186153811e+00, -2.3149559589906059e+00, -2.1546382440280341e+00, -1.9944644842470249e+00, -1.8344235184876900e+00, -1.6745043031205911e+00, -1.5146959015666042e+00, -1.3549874740965486e+00, -1.1953682678816466e+00, -1.0358276072672234e+00, -8.7635488424319652e-01, -7.1693954908593016e-01, -5.5757110114689967e-01, -3.9823907976435802e-01, -2.3893305527481104e-01, -7.9642620101614783e-02, 7.9642620101614783e-02, 2.3893305527481104e-01, 3.9823907976435802e-01, 5.5757110114689967e-01, 7.1693954908593016e-01, 8.7635488424319652e-01, 1.0358276072672234e+00, 1.1953682678816466e+00, 1.3549874740965486e+00, 1.5146959015666042e+00, 1.6745043031205911e+00, 1.8344235184876900e+00, 1.9944644842470249e+00, 2.1546382440280341e+00, 2.3149559589906059e+00, 2.4754289186153811e+00, 2.6360685518363063e+00, 2.7968864385493881e+00, 2.9578943215336770e+00, 3.1191041188228450e+00, 3.2805279365682800e+00, 3.4421780824374997e+00, 3.6040670795948389e+00, 3.7662076813149068e+00, 3.9286128862831946e+00, 4.0912959546425300e+00, 4.2542704248488947e+00, 4.4175501314054006e+00, 4.5811492235491675e+00, 4.7450821849723575e+00, 4.9093638546659628e+00, 5.0740094489830243e+00, 5.2390345850270315e+00, 5.4044553054813402e+00, 5.5702881050067488e+00, 5.7365499583469575e+00, 5.9032583502958440e+00, 6.0704313076963157e+00, 6.2380874336583796e+00, 6.4062459442041968e+00, 6.5749267075705307e+00, 6.7441502864247154e+00, 6.9139379832792587e+00, 7.0843118894232422e+00, 7.2552949377261493e+00, 7.4269109597125382e+00, 7.5991847473548857e+00, 7.7721421200878789e+00, 7.9458099976117715e+00, 8.1202164791264426e+00, 8.2953909297232951e+00, 8.4713640747611425e+00, 8.6481681031671602e+00, 8.8258367807379408e+00, 9.0044055746721732e+00, 9.1839117907500878e+00, 9.3643947247907189e+00, 9.5458958302732722e+00, 9.7284589043113154e+00, 9.9121302945287511e+00, 1.0096959129817110e+01, 1.0282997578470843e+01, 1.0470301137821307e+01, 1.0658928960246737e+01, 1.0848944221357737e+01, 1.1040414537288214e+01, 1.1233412439414929e+01, 1.1428015916557383e+01, 1.1624309036867450e+01, 1.1822382664331087e+01, 1.2022335288240422e+01, 1.2224273988380631e+01, 1.2428315564322974e+01, 1.2634587864551046e+01, 1.2843231360770561e+01, 1.3054401025509831e+01, 1.3268268588222005e+01, 1.3485025268316207e+01, 1.3704885115481808e+01, 1.3928089132251925e+01, 1.4154910416992225e+01, 1.4385660656810286e+01, 1.4620698434329638e+01, 1.4860440014620181e+01, 1.5105373590679383e+01, 1.5356078460791041e+01, 1.5613251421176075e+01, 1.5877744032458063e+01, 1.6150616853857390e+01, 1.6433221273899989e+01, 1.6727328534606457e+01, 1.7035344640856714e+01, 1.7360694468453165e+01, 1.7708576157582009e+01, 1.8087654552659949e+01, 1.8514739873870020e+01, 1.9033817193180372e+01}, + {-1.9085051378043033e+01, -1.8566435110662020e+01, -1.8139736684916269e+01, -1.7761007579700482e+01, -1.7413451433407719e+01, -1.7088410498259837e+01, -1.6780690867902603e+01, -1.6486870443143417e+01, -1.6204545162304957e+01, -1.5931945209665145e+01, -1.5667720282583909e+01, -1.5410810672934431e+01, -1.5160365503176191e+01, -1.4915688536290588e+01, -1.4676200939552615e+01, -1.4441414913235960e+01, -1.4210914528731067e+01, -1.3984341494531598e+01, -1.3761384377966619e+01, -1.3541770305082187e+01, -1.3325258472923085e+01, -1.3111635010647520e+01, -1.2900708860246835e+01, -1.2692308438876983e+01, -1.2486278907997042e+01, -1.2282479919055724e+01, -1.2080783737378024e+01, -1.1881073669101410e+01, -1.1683242733101009e+01, -1.1487192532589896e+01, -1.1292832290695909e+01, -1.1100078021646450e+01, -1.0908851814834854e+01, -1.0719081213424776e+01, -1.0530698672582092e+01, -1.0343641085134585e+01, -1.0157849364615741e+01, -9.9732680773760247e+00, -9.7898451168372347e+00, -9.6075314140949892e+00, -9.4262806799959176e+00, -9.2460491745721143e+00, -9.0667955003389675e+00, -8.8884804164791387e+00, -8.7110666713658151e+00, -8.5345188512382073e+00, -8.3588032431445285e+00, -8.1838877105226704e+00, -8.0097415800046274e+00, -7.8363355382140769e+00, -7.6636415374829738e+00, -7.4916327095468409e+00, -7.3202832863932787e+00, -7.1495685275371788e+00, -6.9794646530814948e+00, -6.8099487819964919e+00, -6.6409988751145752e+00, -6.4725936823937991e+00, -6.3047126940519806e+00, -6.1373360952161162e+00, -5.9704447237692317e+00, -5.8040200311098342e+00, -5.6380440455680922e+00, -5.4724993382485847e+00, -5.3073689910920496e+00, -5.1426365669687621e+00, -4.9782860816339154e+00, -4.8143019773913309e+00, -4.6506690983259311e+00, -4.4873726669780289e+00, -4.3243982623437809e+00, -4.1617317990962412e+00, -3.9993595079305000e+00, -3.8372679169445236e+00, -3.6754438339745814e+00, -3.5138743298107440e+00, -3.3525467222238068e+00, -3.1914485607403469e+00, -3.0305676121073946e+00, -2.8698918463925485e+00, -2.7094094236692574e+00, -2.5491086812405244e+00, -2.3889781213574715e+00, -2.2290063993920741e+00, -2.0691823124259607e+00, -1.9094947882195137e+00, -1.7499328745276050e+00, -1.5904857287301759e+00, -1.4311426077475764e+00, -1.2718928582120677e+00, -1.1127259068682478e+00, -9.5363125117633152e-01, -7.9459845009326358e-01, -6.3561711500753826e-01, -4.7667690080438158e-01, -3.1776749703859319e-01, -1.5887861919288843e-01, -0.0000000000000000e+00, 1.5887861919288843e-01, 3.1776749703859319e-01, 4.7667690080438158e-01, 6.3561711500753826e-01, 7.9459845009326358e-01, 9.5363125117633152e-01, 1.1127259068682478e+00, 1.2718928582120677e+00, 1.4311426077475764e+00, 1.5904857287301759e+00, 1.7499328745276050e+00, 1.9094947882195137e+00, 2.0691823124259607e+00, 2.2290063993920741e+00, 2.3889781213574715e+00, 2.5491086812405244e+00, 2.7094094236692574e+00, 2.8698918463925485e+00, 3.0305676121073946e+00, 3.1914485607403469e+00, 3.3525467222238068e+00, 3.5138743298107440e+00, 3.6754438339745814e+00, 3.8372679169445236e+00, 3.9993595079305000e+00, 4.1617317990962412e+00, 4.3243982623437809e+00, 4.4873726669780289e+00, 4.6506690983259311e+00, 4.8143019773913309e+00, 4.9782860816339154e+00, 5.1426365669687621e+00, 5.3073689910920496e+00, 5.4724993382485847e+00, 5.6380440455680922e+00, 5.8040200311098342e+00, 5.9704447237692317e+00, 6.1373360952161162e+00, 6.3047126940519806e+00, 6.4725936823937991e+00, 6.6409988751145752e+00, 6.8099487819964919e+00, 6.9794646530814948e+00, 7.1495685275371788e+00, 7.3202832863932787e+00, 7.4916327095468409e+00, 7.6636415374829738e+00, 7.8363355382140769e+00, 8.0097415800046274e+00, 8.1838877105226704e+00, 8.3588032431445285e+00, 8.5345188512382073e+00, 8.7110666713658151e+00, 8.8884804164791387e+00, 9.0667955003389675e+00, 9.2460491745721143e+00, 9.4262806799959176e+00, 9.6075314140949892e+00, 9.7898451168372347e+00, 9.9732680773760247e+00, 1.0157849364615741e+01, 1.0343641085134585e+01, 1.0530698672582092e+01, 1.0719081213424776e+01, 1.0908851814834854e+01, 1.1100078021646450e+01, 1.1292832290695909e+01, 1.1487192532589896e+01, 1.1683242733101009e+01, 1.1881073669101410e+01, 1.2080783737378024e+01, 1.2282479919055724e+01, 1.2486278907997042e+01, 1.2692308438876983e+01, 1.2900708860246835e+01, 1.3111635010647520e+01, 1.3325258472923085e+01, 1.3541770305082187e+01, 1.3761384377966619e+01, 1.3984341494531598e+01, 1.4210914528731067e+01, 1.4441414913235960e+01, 1.4676200939552615e+01, 1.4915688536290588e+01, 1.5160365503176191e+01, 1.5410810672934431e+01, 1.5667720282583909e+01, 1.5931945209665145e+01, 1.6204545162304957e+01, 1.6486870443143417e+01, 1.6780690867902603e+01, 1.7088410498259837e+01, 1.7413451433407719e+01, 1.7761007579700482e+01, 1.8139736684916269e+01, 1.8566435110662020e+01, 1.9085051378043033e+01}, + {-1.9136152632446343e+01, -1.8617994596540964e+01, -1.8191680665779813e+01, -1.7813298656636132e+01, -1.7466065985601755e+01, -1.7141331960462935e+01, -1.6833906884239585e+01, -1.6540371418317267e+01, -1.6258323432990789e+01, -1.5985994530572864e+01, -1.5722035487991715e+01, -1.5465387443233377e+01, -1.5215200197812091e+01, -1.4970778070582133e+01, -1.4731542691573273e+01, -1.4497006651929539e+01, -1.4266754357415572e+01, -1.4040427805805265e+01, -1.3817715817227148e+01, -1.3598345740663659e+01, -1.3382076971394328e+01, -1.3168695816190608e+01, -1.2958011377300066e+01, -1.2749852217418379e+01, -1.2544063630985093e+01, -1.2340505391648597e+01, -1.2139049877631299e+01, -1.1939580499904540e+01, -1.1741990375159112e+01, -1.1546181198293549e+01, -1.1352062278750141e+01, -1.1159549712352600e+01, -1.0968565665937081e+01, -1.0779037756447492e+01, -1.0590898509596441e+01, -1.0404084885901707e+01, -1.0218537864062538e+01, -1.0034202073365652e+01, -9.8510254682020655e+00, -9.6689590389043136e+00, -9.4879565540345112e+00, -9.3079743300090456e+00, -9.1289710245687488e+00, -8.9509074511196953e+00, -8.7737464113997543e+00, -8.5974525442855416e+00, -8.4219921888566009e+00, -8.2473332600882276e+00, -8.0734451357601422e+00, -7.9002985533514174e+00, -7.7278655158483680e+00, -7.5561192055258362e+00, -7.3850339048770719e+00, -7.2145849239662976e+00, -7.0447485335633226e+00, -6.8755019034936238e+00, -6.7068230457014044e+00, -6.5386907615791259e+00, -6.3710845931658042e+00, -6.2039847778590458e+00, -6.0373722063233055e+00, -5.8712283833097523e+00, -5.7055353911321696e+00, -5.5402758555689235e+00, -5.3754329139836932e+00, -5.2109901854777609e+00, -5.0469317429044782e+00, -4.8832420865923929e+00, -4.7199061196376721e+00, -4.5569091246390609e+00, -4.3942367417598831e+00, -4.2318749480117184e+00, -4.0698100376633946e+00, -3.9080286036870948e+00, -3.7465175201606447e+00, -3.5852639255516232e+00, -3.4242552068148551e+00, -3.2634789842401504e+00, -3.1029230969919848e+00, -2.9425755892871246e+00, -2.7824246971601365e+00, -2.6224588357702330e+00, -2.4626665872061215e+00, -2.3030366887483824e+00, -2.1435580215515251e+00, -1.9842195997101939e+00, -1.8250105596761317e+00, -1.6659201499943919e+00, -1.5069377213289974e+00, -1.3480527167497827e+00, -1.1892546622534923e+00, -1.0305331574934382e+00, -8.7187786669305845e-01, -7.1327850971966389e-01, -5.5472485329544763e-01, -3.9620670232352440e-01, -2.3771389130732343e-01, -7.9236275842124657e-02, 7.9236275842124657e-02, 2.3771389130732343e-01, 3.9620670232352440e-01, 5.5472485329544763e-01, 7.1327850971966389e-01, 8.7187786669305845e-01, 1.0305331574934382e+00, 1.1892546622534923e+00, 1.3480527167497827e+00, 1.5069377213289974e+00, 1.6659201499943919e+00, 1.8250105596761317e+00, 1.9842195997101939e+00, 2.1435580215515251e+00, 2.3030366887483824e+00, 2.4626665872061215e+00, 2.6224588357702330e+00, 2.7824246971601365e+00, 2.9425755892871246e+00, 3.1029230969919848e+00, 3.2634789842401504e+00, 3.4242552068148551e+00, 3.5852639255516232e+00, 3.7465175201606447e+00, 3.9080286036870948e+00, 4.0698100376633946e+00, 4.2318749480117184e+00, 4.3942367417598831e+00, 4.5569091246390609e+00, 4.7199061196376721e+00, 4.8832420865923929e+00, 5.0469317429044782e+00, 5.2109901854777609e+00, 5.3754329139836932e+00, 5.5402758555689235e+00, 5.7055353911321696e+00, 5.8712283833097523e+00, 6.0373722063233055e+00, 6.2039847778590458e+00, 6.3710845931658042e+00, 6.5386907615791259e+00, 6.7068230457014044e+00, 6.8755019034936238e+00, 7.0447485335633226e+00, 7.2145849239662976e+00, 7.3850339048770719e+00, 7.5561192055258362e+00, 7.7278655158483680e+00, 7.9002985533514174e+00, 8.0734451357601422e+00, 8.2473332600882276e+00, 8.4219921888566009e+00, 8.5974525442855416e+00, 8.7737464113997543e+00, 8.9509074511196953e+00, 9.1289710245687488e+00, 9.3079743300090456e+00, 9.4879565540345112e+00, 9.6689590389043136e+00, 9.8510254682020655e+00, 1.0034202073365652e+01, 1.0218537864062538e+01, 1.0404084885901707e+01, 1.0590898509596441e+01, 1.0779037756447492e+01, 1.0968565665937081e+01, 1.1159549712352600e+01, 1.1352062278750141e+01, 1.1546181198293549e+01, 1.1741990375159112e+01, 1.1939580499904540e+01, 1.2139049877631299e+01, 1.2340505391648597e+01, 1.2544063630985093e+01, 1.2749852217418379e+01, 1.2958011377300066e+01, 1.3168695816190608e+01, 1.3382076971394328e+01, 1.3598345740663659e+01, 1.3817715817227148e+01, 1.4040427805805265e+01, 1.4266754357415572e+01, 1.4497006651929539e+01, 1.4731542691573273e+01, 1.4970778070582133e+01, 1.5215200197812091e+01, 1.5465387443233377e+01, 1.5722035487991715e+01, 1.5985994530572864e+01, 1.6258323432990789e+01, 1.6540371418317267e+01, 1.6833906884239585e+01, 1.7141331960462935e+01, 1.7466065985601755e+01, 1.7813298656636132e+01, 1.8191680665779813e+01, 1.8617994596540964e+01, 1.9136152632446343e+01}, + {-1.9187121982273521e+01, -1.8669419389135154e+01, -1.8243487580223828e+01, -1.7865450498614848e+01, -1.7518539259289700e+01, -1.7194110184967560e+01, -1.6886977763848531e+01, -1.6593725402038196e+01, -1.6311952890695306e+01, -1.6039893241994275e+01, -1.5776198306184138e+01, -1.5519810062439074e+01, -1.5269878987345788e+01, -1.5025709952340740e+01, -1.4786725047437830e+01, -1.4552437252279828e+01, -1.4322431304945502e+01, -1.4096349490675653e+01, -1.3873880880782780e+01, -1.3654753045730484e+01, -1.3438725577708846e+01, -1.3225584959886243e+01, -1.3015140453639436e+01, -1.2807220766151111e+01, -1.2601671323850574e+01, -1.2398352021647000e+01, -1.2197135349764665e+01, -1.1997904823149442e+01, -1.1800553655478529e+01, -1.1604983632531599e+01, -1.1411104149281471e+01, -1.1218831382380758e+01, -1.1028087575354093e+01, -1.0838800418181339e+01, -1.0650902506384885e+01, -1.0464330867440474e+01, -1.0279026544483804e+01, -1.0094934229009290e+01, -9.9120019356474849e+00, -9.7301807132353808e+00, -9.5494243873137332e+00, -9.3696893299405168e+00, -9.1909342533320295e+00, -9.0131200243591802e+00, -8.8362094973560179e+00, -8.6601673630569582e+00, -8.4849600117808954e+00, -8.3105554092350147e+00, -8.1369229835265475e+00, -7.9640335221538869e+00, -7.7918590779046193e+00, -7.6203728827216537e+00, -7.4495492687133176e+00, -7.2793635955820948e+00, -7.1097921838319138e+00, -6.9408122531878398e+00, -6.7724018657261427e+00, -6.6045398732686005e+00, -6.4372058686436739e+00, -6.2703801404598503e+00, -6.1040436310739281e+00, -5.9381778974699042e+00, -5.7727650747931136e+00, -5.6077878423099152e+00, -5.4432293915858283e+00, -5.2790733966951038e+00, -5.1153039862925711e+00, -4.9519057173944132e+00, -4.7888635507286939e+00, -4.6261628275290461e+00, -4.4637892476562113e+00, -4.3017288489422221e+00, -4.1399679876610396e+00, -3.9784933200376109e+00, -3.8172917847145760e+00, -3.6563505861024530e+00, -3.4956571785450063e+00, -3.3351992512368578e+00, -3.1749647138352097e+00, -3.0149416827118620e+00, -2.8551184677956569e+00, -2.6954835599590137e+00, -2.5360256189054007e+00, -2.3767334615175160e+00, -2.2175960506285199e+00, -2.0586024841810624e+00, -1.8997419847409271e+00, -1.7410038893340725e+00, -1.5823776395775344e+00, -1.4238527720762202e+00, -1.2654189090589871e+00, -1.1070657492286282e+00, -9.4878305880147162e-01, -7.9056066271324643e-01, -6.3238843596870120e-01, -4.7425629511315831e-01, -3.1615418980479731e-01, -1.5807209446693934e-01, -0.0000000000000000e+00, 1.5807209446693934e-01, 3.1615418980479731e-01, 4.7425629511315831e-01, 6.3238843596870120e-01, 7.9056066271324643e-01, 9.4878305880147162e-01, 1.1070657492286282e+00, 1.2654189090589871e+00, 1.4238527720762202e+00, 1.5823776395775344e+00, 1.7410038893340725e+00, 1.8997419847409271e+00, 2.0586024841810624e+00, 2.2175960506285199e+00, 2.3767334615175160e+00, 2.5360256189054007e+00, 2.6954835599590137e+00, 2.8551184677956569e+00, 3.0149416827118620e+00, 3.1749647138352097e+00, 3.3351992512368578e+00, 3.4956571785450063e+00, 3.6563505861024530e+00, 3.8172917847145760e+00, 3.9784933200376109e+00, 4.1399679876610396e+00, 4.3017288489422221e+00, 4.4637892476562113e+00, 4.6261628275290461e+00, 4.7888635507286939e+00, 4.9519057173944132e+00, 5.1153039862925711e+00, 5.2790733966951038e+00, 5.4432293915858283e+00, 5.6077878423099152e+00, 5.7727650747931136e+00, 5.9381778974699042e+00, 6.1040436310739281e+00, 6.2703801404598503e+00, 6.4372058686436739e+00, 6.6045398732686005e+00, 6.7724018657261427e+00, 6.9408122531878398e+00, 7.1097921838319138e+00, 7.2793635955820948e+00, 7.4495492687133176e+00, 7.6203728827216537e+00, 7.7918590779046193e+00, 7.9640335221538869e+00, 8.1369229835265475e+00, 8.3105554092350147e+00, 8.4849600117808954e+00, 8.6601673630569582e+00, 8.8362094973560179e+00, 9.0131200243591802e+00, 9.1909342533320295e+00, 9.3696893299405168e+00, 9.5494243873137332e+00, 9.7301807132353808e+00, 9.9120019356474849e+00, 1.0094934229009290e+01, 1.0279026544483804e+01, 1.0464330867440474e+01, 1.0650902506384885e+01, 1.0838800418181339e+01, 1.1028087575354093e+01, 1.1218831382380758e+01, 1.1411104149281471e+01, 1.1604983632531599e+01, 1.1800553655478529e+01, 1.1997904823149442e+01, 1.2197135349764665e+01, 1.2398352021647000e+01, 1.2601671323850574e+01, 1.2807220766151111e+01, 1.3015140453639436e+01, 1.3225584959886243e+01, 1.3438725577708846e+01, 1.3654753045730484e+01, 1.3873880880782780e+01, 1.4096349490675653e+01, 1.4322431304945502e+01, 1.4552437252279828e+01, 1.4786725047437830e+01, 1.5025709952340740e+01, 1.5269878987345788e+01, 1.5519810062439074e+01, 1.5776198306184138e+01, 1.6039893241994275e+01, 1.6311952890695306e+01, 1.6593725402038196e+01, 1.6886977763848531e+01, 1.7194110184967560e+01, 1.7518539259289700e+01, 1.7865450498614848e+01, 1.8243487580223828e+01, 1.8669419389135154e+01, 1.9187121982273521e+01}, + {-1.9237960440300323e+01, -1.8720710532447114e+01, -1.8295158499144485e+01, -1.7917464201364730e+01, -1.7570872373824393e+01, -1.7246746313979781e+01, -1.6939904671276931e+01, -1.6646933580854089e+01, -1.6365434743746000e+01, -1.6093642573904912e+01, -1.5830209988722080e+01, -1.5574079803690140e+01, -1.5324403166531194e+01, -1.5080485498011255e+01, -1.4841749345390438e+01, -1.4607708074467340e+01, -1.4377946753600369e+01, -1.4152107953707038e+01, -1.3929880995689542e+01, -1.3710993670057162e+01, -1.3495205764604879e+01, -1.3282303937699215e+01, -1.3072097608735946e+01, -1.2864415628348308e+01, -1.2659103553980440e+01, -1.2456021400878894e+01, -1.2255041770389502e+01, -1.2056048280588383e+01, -1.1858934241324912e+01, -1.1663601528470521e+01, -1.1469959621759649e+01, -1.1277924777921493e+01, -1.1087419316430047e+01, -1.0898370999572231e+01, -1.0710712491958864e+01, -1.0524380887307489e+01, -1.0339317292477098e+01, -1.0155466460457681e+01, -9.9727764654064881e+00, -9.7911984139496884e+00, -9.6106861878874543e+00, -9.4311962141946886e+00, -9.2526872588317186e+00, -9.0751202413947372e+00, -8.8984580680650804e+00, -8.7226654806754844e+00, -8.5477089200129779e+00, -8.3735564017325164e+00, -8.2001774034706933e+00, -8.0275427619319260e+00, -7.8556245788755001e+00, -7.6843961350654411e+00, -7.5138318113597080e+00, -7.3439070162139659e+00, -7.1745981189604136e+00, -7.0058823882959311e+00, -6.8377379354779668e+00, -6.6701436617824124e+00, -6.5030792098264039e+00, -6.3365249184017198e+00, -6.1704617805017721e+00, -6.0048714042581519e+00, -5.8397359765316308e+00, -5.6750382289281065e+00, -5.5107614060326373e+00, -5.3468892356747437e+00, -5.1834059010560054e+00, -5.0202960145867985e+00, -4.8575445932931558e+00, -4.6951370356673570e+00, -4.5330590998470743e+00, -4.3712968830180499e+00, -4.2098368019442765e+00, -4.0486655745377966e+00, -3.8877702023875300e+00, -3.7271379541730876e+00, -3.5667563498954848e+00, -3.4066131458619480e+00, -3.2466963203668557e+00, -3.0869940600152046e+00, -2.9274947466388688e+00, -2.7681869447595400e+00, -2.6090593895553744e+00, -2.4501009752913179e+00, -2.2913007441756847e+00, -2.1326478756079257e+00, -1.9741316757846794e+00, -1.8157415676330977e+00, -1.6574670810421992e+00, -1.4992978433645401e+00, -1.3412235701618946e+00, -1.1832340561698793e+00, -1.0253191664575543e+00, -8.6746882775900824e-01, -7.0967301995478616e-01, -5.5192176768174561e-01, -3.9420513205055796e-01, -2.3651320245058799e-01, -7.8836088422303746e-02, 7.8836088422303746e-02, 2.3651320245058799e-01, 3.9420513205055796e-01, 5.5192176768174561e-01, 7.0967301995478616e-01, 8.6746882775900824e-01, 1.0253191664575543e+00, 1.1832340561698793e+00, 1.3412235701618946e+00, 1.4992978433645401e+00, 1.6574670810421992e+00, 1.8157415676330977e+00, 1.9741316757846794e+00, 2.1326478756079257e+00, 2.2913007441756847e+00, 2.4501009752913179e+00, 2.6090593895553744e+00, 2.7681869447595400e+00, 2.9274947466388688e+00, 3.0869940600152046e+00, 3.2466963203668557e+00, 3.4066131458619480e+00, 3.5667563498954848e+00, 3.7271379541730876e+00, 3.8877702023875300e+00, 4.0486655745377966e+00, 4.2098368019442765e+00, 4.3712968830180499e+00, 4.5330590998470743e+00, 4.6951370356673570e+00, 4.8575445932931558e+00, 5.0202960145867985e+00, 5.1834059010560054e+00, 5.3468892356747437e+00, 5.5107614060326373e+00, 5.6750382289281065e+00, 5.8397359765316308e+00, 6.0048714042581519e+00, 6.1704617805017721e+00, 6.3365249184017198e+00, 6.5030792098264039e+00, 6.6701436617824124e+00, 6.8377379354779668e+00, 7.0058823882959311e+00, 7.1745981189604136e+00, 7.3439070162139659e+00, 7.5138318113597080e+00, 7.6843961350654411e+00, 7.8556245788755001e+00, 8.0275427619319260e+00, 8.2001774034706933e+00, 8.3735564017325164e+00, 8.5477089200129779e+00, 8.7226654806754844e+00, 8.8984580680650804e+00, 9.0751202413947372e+00, 9.2526872588317186e+00, 9.4311962141946886e+00, 9.6106861878874543e+00, 9.7911984139496884e+00, 9.9727764654064881e+00, 1.0155466460457681e+01, 1.0339317292477098e+01, 1.0524380887307489e+01, 1.0710712491958864e+01, 1.0898370999572231e+01, 1.1087419316430047e+01, 1.1277924777921493e+01, 1.1469959621759649e+01, 1.1663601528470521e+01, 1.1858934241324912e+01, 1.2056048280588383e+01, 1.2255041770389502e+01, 1.2456021400878894e+01, 1.2659103553980440e+01, 1.2864415628348308e+01, 1.3072097608735946e+01, 1.3282303937699215e+01, 1.3495205764604879e+01, 1.3710993670057162e+01, 1.3929880995689542e+01, 1.4152107953707038e+01, 1.4377946753600369e+01, 1.4607708074467340e+01, 1.4841749345390438e+01, 1.5080485498011255e+01, 1.5324403166531194e+01, 1.5574079803690140e+01, 1.5830209988722080e+01, 1.6093642573904912e+01, 1.6365434743746000e+01, 1.6646933580854089e+01, 1.6939904671276931e+01, 1.7246746313979781e+01, 1.7570872373824393e+01, 1.7917464201364730e+01, 1.8295158499144485e+01, 1.8720710532447114e+01, 1.9237960440300323e+01}, + {-1.9288669006428073e+01, -1.8771869057097732e+01, -1.8346694479614712e+01, -1.7969340846379055e+01, -1.7623066433928877e+01, -1.7299241474690692e+01, -1.6992688755677822e+01, -1.6699997125541856e+01, -1.6418770184323929e+01, -1.6147243739757997e+01, -1.5884071770266710e+01, -1.5628197922845580e+01, -1.5378774012459481e+01, -1.5135106005988732e+01, -1.4896616905233879e+01, -1.4662820459834590e+01, -1.4433302066419493e+01, -1.4207704579815282e+01, -1.3985717568940393e+01, -1.3767069042933601e+01, -1.3551518983907220e+01, -1.3338854224244356e+01, -1.3128884340266051e+01, -1.2921438325035480e+01, -1.2716361866052114e+01, -1.2513515097991551e+01, -1.2312770732455700e+01, -1.2114012489821327e+01, -1.1917133775310306e+01, -1.1722036554111044e+01, -1.1528630389965276e+01, -1.1336831618941112e+01, -1.1146562635737574e+01, -1.0957751274234692e+01, -1.0770330267425512e+01, -1.0584236774568581e+01, -1.0399411965548676e+01, -1.0215800654155213e+01, -1.0033350973375560e+01, -9.8520140869264541e+00, -9.6717439321652883e+00, -9.4924969902767238e+00, -9.3142320802515925e+00, -9.1369101736902376e+00, -8.9604942278913082e+00, -8.7849490350458534e+00, -8.6102410856578757e+00, -8.4363384445666423e+00, -8.2632106381612598e+00, -8.0908285515608398e+00, -7.9191643346894995e+00, -7.7481913163088629e+00, -7.5778839251852919e+00, -7.4082176176676109e+00, -7.2391688110363521e+00, -7.0707148220592551e+00, -6.9028338102518392e+00, -6.7355047253976705e+00, -6.5687072589316280e+00, -6.4024217988321039e+00, -6.2366293877054586e+00, -6.0713116837789416e+00, -5.9064509245471877e+00, -5.7420298928430569e+00, -5.5780318851261201e+00, -5.4144406818022057e+00, -5.2512405194051937e+00, -5.0884160644880927e+00, -4.9259523890845678e+00, -4.7638349476146598e+00, -4.6020495551197111e+00, -4.4405823667216309e+00, -4.2794198582106002e+00, -4.1185488076735286e+00, -3.9579562780827859e+00, -3.7976296007713630e+00, -3.6375563597264895e+00, -3.4777243766391046e+00, -3.3181216966513536e+00, -3.1587365747486800e+00, -2.9995574627469606e+00, -2.8405729968287345e+00, -2.6817719855857511e+00, -2.5231433985279939e+00, -2.3646763550219534e+00, -2.2063601136233109e+00, -2.0481840617713236e+00, -1.8901377058141628e+00, -1.7322106613361827e+00, -1.5743926437596774e+00, -1.4166734591950965e+00, -1.2590429955149371e+00, -1.1014912136276596e+00, -9.4400813892896185e-01, -7.8658385290862076e-01, -6.2920848489186076e-01, -4.7187220389486334e-01, -3.1456521057457892e-01, -1.5727772925344838e-01, -0.0000000000000000e+00, 1.5727772925344838e-01, 3.1456521057457892e-01, 4.7187220389486334e-01, 6.2920848489186076e-01, 7.8658385290862076e-01, 9.4400813892896185e-01, 1.1014912136276596e+00, 1.2590429955149371e+00, 1.4166734591950965e+00, 1.5743926437596774e+00, 1.7322106613361827e+00, 1.8901377058141628e+00, 2.0481840617713236e+00, 2.2063601136233109e+00, 2.3646763550219534e+00, 2.5231433985279939e+00, 2.6817719855857511e+00, 2.8405729968287345e+00, 2.9995574627469606e+00, 3.1587365747486800e+00, 3.3181216966513536e+00, 3.4777243766391046e+00, 3.6375563597264895e+00, 3.7976296007713630e+00, 3.9579562780827859e+00, 4.1185488076735286e+00, 4.2794198582106002e+00, 4.4405823667216309e+00, 4.6020495551197111e+00, 4.7638349476146598e+00, 4.9259523890845678e+00, 5.0884160644880927e+00, 5.2512405194051937e+00, 5.4144406818022057e+00, 5.5780318851261201e+00, 5.7420298928430569e+00, 5.9064509245471877e+00, 6.0713116837789416e+00, 6.2366293877054586e+00, 6.4024217988321039e+00, 6.5687072589316280e+00, 6.7355047253976705e+00, 6.9028338102518392e+00, 7.0707148220592551e+00, 7.2391688110363521e+00, 7.4082176176676109e+00, 7.5778839251852919e+00, 7.7481913163088629e+00, 7.9191643346894995e+00, 8.0908285515608398e+00, 8.2632106381612598e+00, 8.4363384445666423e+00, 8.6102410856578757e+00, 8.7849490350458534e+00, 8.9604942278913082e+00, 9.1369101736902376e+00, 9.3142320802515925e+00, 9.4924969902767238e+00, 9.6717439321652883e+00, 9.8520140869264541e+00, 1.0033350973375560e+01, 1.0215800654155213e+01, 1.0399411965548676e+01, 1.0584236774568581e+01, 1.0770330267425512e+01, 1.0957751274234692e+01, 1.1146562635737574e+01, 1.1336831618941112e+01, 1.1528630389965276e+01, 1.1722036554111044e+01, 1.1917133775310306e+01, 1.2114012489821327e+01, 1.2312770732455700e+01, 1.2513515097991551e+01, 1.2716361866052114e+01, 1.2921438325035480e+01, 1.3128884340266051e+01, 1.3338854224244356e+01, 1.3551518983907220e+01, 1.3767069042933601e+01, 1.3985717568940393e+01, 1.4207704579815282e+01, 1.4433302066419493e+01, 1.4662820459834590e+01, 1.4896616905233879e+01, 1.5135106005988732e+01, 1.5378774012459481e+01, 1.5628197922845580e+01, 1.5884071770266710e+01, 1.6147243739757997e+01, 1.6418770184323929e+01, 1.6699997125541856e+01, 1.6992688755677822e+01, 1.7299241474690692e+01, 1.7623066433928877e+01, 1.7969340846379055e+01, 1.8346694479614712e+01, 1.8771869057097732e+01, 1.9288669006428073e+01}, + {-1.9339248667911409e+01, -1.8822895980564734e+01, -1.8398096565132178e+01, -1.8021081501173168e+01, -1.7675122529961925e+01, -1.7351596779550405e+01, -1.7045331151092153e+01, -1.6752917191398179e+01, -1.6471960388762881e+01, -1.6200697936792103e+01, -1.5937784868895722e+01, -1.5682165658809755e+01, -1.5432992784892868e+01, -1.5189572756961194e+01, -1.4951329028681464e+01, -1.4717775731247299e+01, -1.4488498587572698e+01, -1.4263140734648266e+01, -1.4041391987855551e+01, -1.3822980573565543e+01, -1.3607666666938064e+01, -1.3395237273208020e+01, -1.3185502124544024e+01, -1.2978290355434069e+01, -1.2773447782488505e+01, -1.2570834658918320e+01, -1.2370323805730495e+01, -1.2171799044787127e+01, -1.1975153875897130e+01, -1.1780290352805242e+01, -1.1587118122520339e+01, -1.1395553599726039e+01, -1.1205519253636435e+01, -1.1016942989025184e+01, -1.0829757606576079e+01, -1.0643900330402785e+01, -1.0459312392733535e+01, -1.0275938667476471e+01, -1.0093727345768286e+01, -9.9126296477337945e+00, -9.7325995656019266e+00, -9.5535936340768206e+00, -9.3755707244836426e+00, -9.1984918597235552e+00, -9.0223200475008358e+00, -8.8470201296436706e+00, -8.6725586456412369e+00, -8.4989037087736055e+00, -8.3260248934261227e+00, -8.1538931323624819e+00, -7.9824806228866425e+00, -7.8117607409569434e+00, -7.6417079624302628e+00, -7.4722977907127222e+00, -7.3035066901782200e+00, -7.1353120247902524e+00, -6.9676920014260446e+00, -6.8006256174581203e+00, -6.6340926121968646e+00, -6.4680734218403675e+00, -6.3025491376151397e+00, -6.1375014668241503e+00, -5.9729126965475468e+00, -5.8087656597670589e+00, -5.6450437037075716e+00, -5.4817306602094709e+00, -5.3188108179631426e+00, -5.1562688964529020e+00, -4.9940900214715160e+00, -4.8322597020794342e+00, -4.6707638088937005e+00, -4.5095885536020024e+00, -4.3487204696060182e+00, -4.1881463937064671e+00, -4.0278534487497097e+00, -3.8678290271620543e+00, -3.7080607753039518e+00, -3.5485365785817580e+00, -3.3892445472592136e+00, -3.2301730029155085e+00, -3.0713104655004981e+00, -2.9126456409412849e+00, -2.7541674092575419e+00, -2.5958648131459636e+00, -2.4377270469968155e+00, -2.2797434463078550e+00, -2.1219034774632650e+00, -1.9641967278469044e+00, -1.8066128962612460e+00, -1.6491417836246915e+00, -1.4917732839215128e+00, -1.3344973753799896e+00, -1.1773041118552243e+00, -1.0201836143944896e+00, -8.6312606296338723e-01, -7.0612168831240074e-01, -5.4916076396359503e-01, -3.9223359829815591e-01, -2.3533052672581237e-01, -7.8441903917412792e-02, 7.8441903917412792e-02, 2.3533052672581237e-01, 3.9223359829815591e-01, 5.4916076396359503e-01, 7.0612168831240074e-01, 8.6312606296338723e-01, 1.0201836143944896e+00, 1.1773041118552243e+00, 1.3344973753799896e+00, 1.4917732839215128e+00, 1.6491417836246915e+00, 1.8066128962612460e+00, 1.9641967278469044e+00, 2.1219034774632650e+00, 2.2797434463078550e+00, 2.4377270469968155e+00, 2.5958648131459636e+00, 2.7541674092575419e+00, 2.9126456409412849e+00, 3.0713104655004981e+00, 3.2301730029155085e+00, 3.3892445472592136e+00, 3.5485365785817580e+00, 3.7080607753039518e+00, 3.8678290271620543e+00, 4.0278534487497097e+00, 4.1881463937064671e+00, 4.3487204696060182e+00, 4.5095885536020024e+00, 4.6707638088937005e+00, 4.8322597020794342e+00, 4.9940900214715160e+00, 5.1562688964529020e+00, 5.3188108179631426e+00, 5.4817306602094709e+00, 5.6450437037075716e+00, 5.8087656597670589e+00, 5.9729126965475468e+00, 6.1375014668241503e+00, 6.3025491376151397e+00, 6.4680734218403675e+00, 6.6340926121968646e+00, 6.8006256174581203e+00, 6.9676920014260446e+00, 7.1353120247902524e+00, 7.3035066901782200e+00, 7.4722977907127222e+00, 7.6417079624302628e+00, 7.8117607409569434e+00, 7.9824806228866425e+00, 8.1538931323624819e+00, 8.3260248934261227e+00, 8.4989037087736055e+00, 8.6725586456412369e+00, 8.8470201296436706e+00, 9.0223200475008358e+00, 9.1984918597235552e+00, 9.3755707244836426e+00, 9.5535936340768206e+00, 9.7325995656019266e+00, 9.9126296477337945e+00, 1.0093727345768286e+01, 1.0275938667476471e+01, 1.0459312392733535e+01, 1.0643900330402785e+01, 1.0829757606576079e+01, 1.1016942989025184e+01, 1.1205519253636435e+01, 1.1395553599726039e+01, 1.1587118122520339e+01, 1.1780290352805242e+01, 1.1975153875897130e+01, 1.2171799044787127e+01, 1.2370323805730495e+01, 1.2570834658918320e+01, 1.2773447782488505e+01, 1.2978290355434069e+01, 1.3185502124544024e+01, 1.3395237273208020e+01, 1.3607666666938064e+01, 1.3822980573565543e+01, 1.4041391987855551e+01, 1.4263140734648266e+01, 1.4488498587572698e+01, 1.4717775731247299e+01, 1.4951329028681464e+01, 1.5189572756961194e+01, 1.5432992784892868e+01, 1.5682165658809755e+01, 1.5937784868895722e+01, 1.6200697936792103e+01, 1.6471960388762881e+01, 1.6752917191398179e+01, 1.7045331151092153e+01, 1.7351596779550405e+01, 1.7675122529961925e+01, 1.8021081501173168e+01, 1.8398096565132178e+01, 1.8822895980564734e+01, 1.9339248667911409e+01}, +} + +// wCache computed from Chebfun. +var wCacheHermite = [][]float64{ + {1.7724538509055159e+00}, + {8.8622692545275794e-01, 8.8622692545275794e-01}, + {2.9540897515091952e-01, 1.1816359006036770e+00, 2.9540897515091952e-01}, + {8.1312835447245130e-02, 8.0491409000551273e-01, 8.0491409000551273e-01, 8.1312835447245130e-02}, + {1.9953242059045879e-02, 3.9361932315224107e-01, 9.4530872048294201e-01, 3.9361932315224107e-01, 1.9953242059045879e-02}, + {4.5300099055088682e-03, 1.5706732032285645e-01, 7.2462959522439263e-01, 7.2462959522439263e-01, 1.5706732032285645e-01, 4.5300099055088682e-03}, + {9.7178124509951806e-04, 5.4515582819127072e-02, 4.2560725261012772e-01, 8.1026461755680723e-01, 4.2560725261012772e-01, 5.4515582819127072e-02, 9.7178124509951806e-04}, + {1.9960407221136889e-04, 1.7077983007413408e-02, 2.0780232581489197e-01, 6.6114701255824115e-01, 6.6114701255824115e-01, 2.0780232581489197e-01, 1.7077983007413408e-02, 1.9960407221136889e-04}, + {3.9606977263264351e-05, 4.9436242755369481e-03, 8.8474527394376584e-02, 4.3265155900255570e-01, 7.2023521560605097e-01, 4.3265155900255570e-01, 8.8474527394376584e-02, 4.9436242755369481e-03, 3.9606977263264351e-05}, + {7.6404328552325936e-06, 1.3436457467812385e-03, 3.3874394455481120e-02, 2.4013861108231432e-01, 6.1086263373532612e-01, 6.1086263373532612e-01, 2.4013861108231432e-01, 3.3874394455481120e-02, 1.3436457467812385e-03, 7.6404328552325936e-06}, + {1.4395603937142598e-06, 3.4681946632334550e-04, 1.1911395444911524e-02, 1.1722787516770818e-01, 4.2935975235612489e-01, 6.5475928691459262e-01, 4.2935975235612489e-01, 1.1722787516770818e-01, 1.1911395444911524e-02, 3.4681946632334550e-04, 1.4395603937142598e-06}, + {2.6585516843563055e-07, 8.5736870435878019e-05, 3.9053905846290599e-03, 5.1607985615883964e-02, 2.6049231026416109e-01, 5.7013523626247942e-01, 5.7013523626247942e-01, 2.6049231026416109e-01, 5.1607985615883964e-02, 3.9053905846290599e-03, 8.5736870435878019e-05, 2.6585516843563055e-07}, + {4.8257318500731284e-08, 2.0430360402707074e-05, 1.2074599927193832e-03, 2.0862775296169932e-02, 1.4032332068702327e-01, 4.2161629689854296e-01, 6.0439318792116203e-01, 4.2161629689854296e-01, 1.4032332068702327e-01, 2.0862775296169932e-02, 1.2074599927193832e-03, 2.0430360402707074e-05, 4.8257318500731284e-08}, + {8.6285911681251554e-09, 4.7164843550189453e-06, 3.5509261355192302e-04, 7.8500547264579047e-03, 6.8505534223465281e-02, 2.7310560906424641e-01, 5.3640590971209023e-01, 5.3640590971209023e-01, 2.7310560906424641e-01, 6.8505534223465281e-02, 7.8500547264579047e-03, 3.5509261355192302e-04, 4.7164843550189453e-06, 8.6285911681251554e-09}, + {1.5224758042535219e-09, 1.0591155477110612e-06, 1.0000444123249973e-04, 2.7780688429127598e-03, 3.0780033872546117e-02, 1.5848891579593580e-01, 4.1202868749889832e-01, 5.6410030872641814e-01, 4.1202868749889832e-01, 1.5848891579593580e-01, 3.0780033872546117e-02, 2.7780688429127598e-03, 1.0000444123249973e-04, 1.0591155477110612e-06, 1.5224758042535219e-09}, + {2.6548074740111957e-10, 2.3209808448652080e-07, 2.7118600925378922e-05, 9.3228400862418201e-04, 1.2880311535509982e-02, 8.3810041398985943e-02, 2.8064745852853384e-01, 5.0792947901661334e-01, 5.0792947901661334e-01, 2.8064745852853384e-01, 8.3810041398985943e-02, 1.2880311535509982e-02, 9.3228400862418201e-04, 2.7118600925378922e-05, 2.3209808448652080e-07, 2.6548074740111957e-10}, + {4.5805789307986523e-11, 4.9770789816307401e-08, 7.1122891400212805e-06, 2.9864328669775215e-04, 5.0673499576275429e-03, 4.0920034149756306e-02, 1.7264829767009740e-01, 4.0182646947041184e-01, 5.3091793762486328e-01, 4.0182646947041184e-01, 1.7264829767009740e-01, 4.0920034149756306e-02, 5.0673499576275429e-03, 2.9864328669775215e-04, 7.1122891400212805e-06, 4.9770789816307401e-08, 4.5805789307986523e-11}, + {7.8281997721158175e-12, 1.0467205795791975e-08, 1.8106544810934246e-06, 9.1811268679294544e-05, 1.8885226302684155e-03, 1.8640042387544645e-02, 9.7301747641315411e-02, 2.8480728566997937e-01, 4.8349569472545578e-01, 4.8349569472545578e-01, 2.8480728566997937e-01, 9.7301747641315411e-02, 1.8640042387544645e-02, 1.8885226302684155e-03, 9.1811268679294544e-05, 1.8106544810934246e-06, 1.0467205795791975e-08, 7.8281997721158175e-12}, + {1.3262970944985103e-12, 2.1630510098635541e-09, 4.4882431472231438e-07, 2.7209197763161644e-05, 6.7087752140718431e-04, 7.9888667777229892e-03, 5.0810386909052110e-02, 1.8363270130699696e-01, 3.9160898861302956e-01, 5.0297488827618764e-01, 3.9160898861302956e-01, 1.8363270130699696e-01, 5.0810386909052110e-02, 7.9888667777229892e-03, 6.7087752140718431e-04, 2.7209197763161644e-05, 4.4882431472231438e-07, 2.1630510098635541e-09, 1.3262970944985103e-12}, + {2.2293936455341389e-13, 4.3993409922731442e-10, 1.0860693707692744e-07, 7.8025564785320785e-06, 2.2833863601635308e-04, 3.2437733422378532e-03, 2.4810520887463654e-02, 1.0901720602002316e-01, 2.8667550536283426e-01, 4.6224366960061009e-01, 4.6224366960061009e-01, 2.8667550536283426e-01, 1.0901720602002316e-01, 2.4810520887463654e-02, 3.2437733422378532e-03, 2.2833863601635308e-04, 7.8025564785320785e-06, 1.0860693707692744e-07, 4.3993409922731442e-10, 2.2293936455341389e-13}, + {3.7203650688184023e-14, 8.8186112420499177e-11, 2.5712301800593246e-08, 2.1718848980566754e-06, 7.4783988673100723e-05, 1.2549820417264148e-03, 1.1414065837434373e-02, 6.0179646658912296e-02, 1.9212032406699767e-01, 3.8166907361350205e-01, 4.7902370312017756e-01, 3.8166907361350205e-01, 1.9212032406699767e-01, 6.0179646658912296e-02, 1.1414065837434373e-02, 1.2549820417264148e-03, 7.4783988673100723e-05, 2.1718848980566754e-06, 2.5712301800593246e-08, 8.8186112420499177e-11, 3.7203650688184023e-14}, + {6.1671834244041516e-15, 1.7443390075479748e-11, 5.9669909860596536e-09, 5.8842875633009930e-07, 2.3655128552510423e-05, 4.6488505088425271e-04, 4.9783993350516510e-03, 3.1140370884423854e-02, 1.1910236095878249e-01, 2.8697143324690705e-01, 4.4354522643495936e-01, 4.4354522643495936e-01, 2.8697143324690705e-01, 1.1910236095878249e-01, 3.1140370884423854e-02, 4.9783993350516510e-03, 4.6488505088425271e-04, 2.3655128552510423e-05, 5.8842875633009930e-07, 5.9669909860596536e-09, 1.7443390075479748e-11, 6.1671834244041516e-15}, + {1.0160384616453285e-15, 3.4083140980305419e-12, 1.3596296504028875e-09, 1.5553393291457709e-07, 7.2492959180022684e-06, 1.6556169914187465e-04, 2.0695678749606356e-03, 1.5207084004484164e-02, 6.8890289429087329e-02, 1.9864489857802253e-01, 3.7214382487756476e-01, 4.5819658559321297e-01, 3.7214382487756476e-01, 1.9864489857802253e-01, 6.8890289429087329e-02, 1.5207084004484164e-02, 2.0695678749606356e-03, 1.6556169914187465e-04, 7.2492959180022684e-06, 1.5553393291457709e-07, 1.3596296504028875e-09, 3.4083140980305419e-12, 1.0160384616453285e-15}, + {1.6643684964891445e-16, 6.5846202430781003e-13, 3.0462542699875441e-10, 4.0189711749414533e-08, 2.1582457049023422e-06, 5.6886916364043827e-05, 8.2369248268841886e-04, 7.0483558100726791e-03, 3.7445470503230750e-02, 1.2773962178455914e-01, 2.8617953534644303e-01, 4.2693116386869923e-01, 4.2693116386869923e-01, 2.8617953534644303e-01, 1.2773962178455914e-01, 3.7445470503230750e-02, 7.0483558100726791e-03, 8.2369248268841886e-04, 5.6886916364043827e-05, 2.1582457049023422e-06, 4.0189711749414533e-08, 3.0462542699875441e-10, 6.5846202430781003e-13, 1.6643684964891445e-16}, + {2.7119235127587269e-17, 1.2588149877465385e-13, 6.7196384177062396e-11, 1.0170382503018480e-08, 6.2570324996911171e-07, 1.8915972957340510e-05, 3.1508363874548464e-04, 3.1157087201256362e-03, 1.9243098965408916e-02, 7.6888995175808827e-02, 2.0362113667812395e-01, 3.6308898927589056e-01, 4.3986872216948475e-01, 3.6308898927589056e-01, 2.0362113667812395e-01, 7.6888995175808827e-02, 1.9243098965408916e-02, 3.1157087201256362e-03, 3.1508363874548464e-04, 1.8915972957340510e-05, 6.2570324996911171e-07, 1.0170382503018480e-08, 6.7196384177062396e-11, 1.2588149877465385e-13, 2.7119235127587269e-17}, + {4.3969160947540168e-18, 2.3831486593721262e-14, 1.4609999339816088e-11, 2.5244940344905425e-09, 1.7701063373973562e-07, 6.1032917173960523e-06, 1.1622970160311058e-04, 1.3190647223238600e-03, 9.3979012911595897e-03, 4.3598227217250818e-02, 1.3511332791178782e-01, 2.8463224117678448e-01, 4.1204365059036946e-01, 4.1204365059036946e-01, 2.8463224117678448e-01, 1.3511332791178782e-01, 4.3598227217250818e-02, 9.3979012911595897e-03, 1.3190647223238600e-03, 1.1622970160311058e-04, 6.1032917173960523e-06, 1.7701063373973562e-07, 2.5244940344905425e-09, 1.4609999339816088e-11, 2.3831486593721262e-14, 4.3969160947540168e-18}, + {7.0957792932592773e-19, 4.4707724573930981e-15, 3.1341176136230566e-12, 6.1550315782317765e-10, 4.8954004096995851e-08, 1.9152809005953010e-06, 4.1467580043841186e-05, 5.3676961568811289e-04, 4.3812798357925394e-03, 2.3415933625341907e-02, 8.4173081084051971e-02, 2.0737048075100944e-01, 3.5451730409975396e-01, 4.2357728801505945e-01, 3.5451730409975396e-01, 2.0737048075100944e-01, 8.4173081084051971e-02, 2.3415933625341907e-02, 4.3812798357925394e-03, 5.3676961568811289e-04, 4.1467580043841186e-05, 1.9152809005953010e-06, 4.8954004096995851e-08, 6.1550315782317765e-10, 3.1341176136230566e-12, 4.4707724573930981e-15, 7.0957792932592773e-19}, + {1.1401393479036859e-19, 8.3159379512068002e-16, 6.6394367149096827e-13, 1.4758531682776914e-10, 1.3256825015417164e-08, 5.8577197209929782e-07, 1.4345504229714394e-05, 2.1061810002403312e-04, 1.9573312944089908e-03, 1.1968423214354838e-02, 4.9514889289898188e-02, 1.4139460978695487e-01, 2.8256139125938867e-01, 3.9860471782645146e-01, 3.9860471782645146e-01, 2.8256139125938867e-01, 1.4139460978695487e-01, 4.9514889289898188e-02, 1.1968423214354838e-02, 1.9573312944089908e-03, 2.1061810002403312e-04, 1.4345504229714394e-05, 5.8577197209929782e-07, 1.3256825015417164e-08, 1.4758531682776914e-10, 6.6394367149096827e-13, 8.3159379512068002e-16, 1.1401393479036859e-19}, + {1.8244608516739659e-20, 1.5345004446053123e-16, 1.3901072714496111e-13, 3.4841301613084286e-11, 3.5203123276007155e-09, 1.7492291299499463e-07, 4.8230734976477891e-06, 7.9909203545218356e-05, 8.4079250614026418e-04, 5.8455035452715061e-03, 2.7639655592023655e-02, 9.0768842215578197e-02, 2.1014269444921063e-01, 3.4641893907167015e-01, 4.0897117463522970e-01, 3.4641893907167015e-01, 2.1014269444921063e-01, 9.0768842215578197e-02, 2.7639655592023655e-02, 5.8455035452715061e-03, 8.4079250614026418e-04, 7.9909203545218356e-05, 4.8230734976477891e-06, 1.7492291299499463e-07, 3.5203123276007155e-09, 3.4841301613084286e-11, 1.3901072714496111e-13, 1.5345004446053123e-16, 1.8244608516739659e-20}, + {2.9082547001312504e-21, 2.8103336027509541e-17, 2.8786070805487377e-14, 8.1061862974630246e-12, 9.1785804243785856e-10, 5.1085224507759746e-08, 1.5790948873247135e-06, 2.9387252289229863e-05, 3.4831012431868588e-04, 2.7379224730676621e-03, 1.4703829704826692e-02, 5.5144176870234256e-02, 1.4673584754089000e-01, 2.8013093083921248e-01, 3.8639488954181417e-01, 3.8639488954181417e-01, 2.8013093083921248e-01, 1.4673584754089000e-01, 5.5144176870234256e-02, 1.4703829704826692e-02, 2.7379224730676621e-03, 3.4831012431868588e-04, 2.9387252289229863e-05, 1.5790948873247135e-06, 5.1085224507759746e-08, 9.1785804243785856e-10, 8.1061862974630246e-12, 2.8786070805487377e-14, 2.8103336027509541e-17, 2.9082547001312504e-21}, + {4.6189683913871598e-22, 5.1106090079270951e-18, 5.8995564987539112e-15, 1.8603735214521663e-12, 2.3524920032086692e-10, 1.4611988344910622e-08, 5.0437125589397732e-07, 1.0498602757675620e-05, 1.3952090395047032e-04, 1.2336833073068893e-03, 7.4827999140352043e-03, 3.1847230731300323e-02, 9.6717948160870412e-02, 2.1213278866876470e-01, 3.3877265789410776e-01, 3.9577855609860946e-01, 3.3877265789410776e-01, 2.1213278866876470e-01, 9.6717948160870412e-02, 3.1847230731300323e-02, 7.4827999140352043e-03, 1.2336833073068893e-03, 1.3952090395047032e-04, 1.0498602757675620e-05, 5.0437125589397732e-07, 1.4611988344910622e-08, 2.3524920032086692e-10, 1.8603735214521663e-12, 5.8995564987539112e-15, 5.1106090079270951e-18, 4.6189683913871598e-22}, + {7.3106764273841909e-23, 9.2317365365181365e-19, 1.1973440170928574e-15, 4.2150102113264756e-13, 5.9332914633966556e-11, 4.0988321647708776e-09, 1.5741677925455937e-07, 3.6505851295623875e-06, 5.4165840618199778e-05, 5.3626836552797335e-04, 3.6548903266544271e-03, 1.7553428831573435e-02, 6.0458130955912612e-02, 1.5126973407664251e-01, 2.7745814230252980e-01, 3.7523835259280258e-01, 3.7523835259280258e-01, 2.7745814230252980e-01, 1.5126973407664251e-01, 6.0458130955912612e-02, 1.7553428831573435e-02, 3.6548903266544271e-03, 5.3626836552797335e-04, 5.4165840618199778e-05, 3.6505851295623875e-06, 1.5741677925455937e-07, 4.0988321647708776e-09, 5.9332914633966556e-11, 4.2150102113264756e-13, 1.1973440170928574e-15, 9.2317365365181365e-19, 7.3106764273841909e-23}, + {1.1533162176980265e-23, 1.6570947415336692e-19, 2.4077856795579959e-16, 9.4348141590150248e-14, 1.4739809370924901e-11, 1.1289222471083366e-09, 4.8077456763232087e-08, 1.2376933672012150e-06, 2.0423684051423809e-05, 2.2544277059632773e-04, 1.7184546377609299e-03, 9.2656899706852411e-03, 3.5987982318576993e-02, 1.0206907999554145e-01, 2.1349393115029186e-01, 3.3155200075074132e-01, 3.8378526651986389e-01, 3.3155200075074132e-01, 2.1349393115029186e-01, 1.0206907999554145e-01, 3.5987982318576993e-02, 9.2656899706852411e-03, 1.7184546377609299e-03, 2.2544277059632773e-04, 2.0423684051423809e-05, 1.2376933672012150e-06, 4.8077456763232087e-08, 1.1289222471083366e-09, 1.4739809370924901e-11, 9.4348141590150248e-14, 2.4077856795579959e-16, 1.6570947415336692e-19, 1.1533162176980265e-23}, + {1.8138001119597749e-24, 2.9567089223605576e-20, 4.7999019978948293e-17, 2.0878403731160143e-14, 3.6098817474860888e-12, 3.0562520419155053e-10, 1.4387732912539959e-08, 4.0979740352245880e-07, 7.4934487833022770e-06, 9.1861189828724009e-05, 7.7981759962319987e-04, 4.6984636292665893e-03, 2.0473151727019457e-02, 6.5445134108752731e-02, 1.5511041662330927e-01, 2.7462771563513722e-01, 3.6499244699664513e-01, 3.6499244699664513e-01, 2.7462771563513722e-01, 1.5511041662330927e-01, 6.5445134108752731e-02, 2.0473151727019457e-02, 4.6984636292665893e-03, 7.7981759962319987e-04, 9.1861189828724009e-05, 7.4934487833022770e-06, 4.0979740352245880e-07, 1.4387732912539959e-08, 3.0562520419155053e-10, 3.6098817474860888e-12, 2.0878403731160143e-14, 4.7999019978948293e-17, 2.9567089223605576e-20, 1.8138001119597749e-24}, + {2.8441134634327172e-25, 5.2456527291743166e-21, 9.4898848794730163e-18, 4.5704441904182093e-15, 8.7225260125370039e-13, 8.1406956866777238e-11, 4.2239761300094312e-09, 1.3269405173066746e-07, 2.6798156546135386e-06, 3.6352769174157649e-05, 3.4234009319960727e-04, 2.2950283295840954e-03, 1.1166806590265730e-02, 4.0024775133100314e-02, 1.0687290695546242e-01, 2.1434719059607343e-01, 3.2472872157456961e-01, 3.7281997319072468e-01, 3.2472872157456961e-01, 2.1434719059607343e-01, 1.0687290695546242e-01, 4.0024775133100314e-02, 1.1166806590265730e-02, 2.2950283295840954e-03, 3.4234009319960727e-04, 3.6352769174157649e-05, 2.6798156546135386e-06, 1.3269405173066746e-07, 4.2239761300094312e-09, 8.1406956866777238e-11, 8.7225260125370039e-13, 4.5704441904182093e-15, 9.4898848794730163e-18, 5.2456527291743166e-21, 2.8441134634327172e-25}, + {4.4471534175756294e-26, 9.2564030835581952e-22, 1.8615979878080060e-18, 9.9029016869062119e-16, 2.0809126742868747e-13, 2.1353541817845700e-11, 1.2178678209557312e-09, 4.2074913231090725e-08, 9.3555700897732196e-07, 1.3997029220328986e-05, 1.4569615962636070e-04, 1.0825347566868020e-03, 5.8564259865595538e-03, 2.3425767509731743e-02, 7.0104750105177666e-02, 1.5835545375116650e-01, 2.7170124700952736e-01, 3.5554007427370893e-01, 3.5554007427370893e-01, 2.7170124700952736e-01, 1.5835545375116650e-01, 7.0104750105177666e-02, 2.3425767509731743e-02, 5.8564259865595538e-03, 1.0825347566868020e-03, 1.4569615962636070e-04, 1.3997029220328986e-05, 9.3555700897732196e-07, 4.2074913231090725e-08, 1.2178678209557312e-09, 2.1353541817845700e-11, 2.0809126742868747e-13, 9.9029016869062119e-16, 1.8615979878080060e-18, 9.2564030835581952e-22, 4.4471534175756294e-26}, + {6.9350835444886530e-27, 1.6249853271916221e-22, 3.6247269512444368e-19, 2.1248851941314958e-16, 4.9047393641852124e-14, 5.5203972646374721e-12, 3.4519062272121333e-10, 1.3079698821802362e-08, 3.1928854810032377e-07, 5.2521435771200543e-06, 6.0226951652674167e-05, 4.9417150121469438e-04, 2.9608001846029054e-03, 1.3160179977211566e-02, 4.3931362299539353e-02, 1.1117916510719518e-01, 2.1478887596478388e-01, 3.1827467975443136e-01, 3.6274375769908357e-01, 3.1827467975443136e-01, 2.1478887596478388e-01, 1.1117916510719518e-01, 4.3931362299539353e-02, 1.3160179977211566e-02, 2.9608001846029054e-03, 4.9417150121469438e-04, 6.0226951652674167e-05, 5.2521435771200543e-06, 3.1928854810032377e-07, 1.3079698821802362e-08, 3.4519062272121333e-10, 5.5203972646374721e-12, 4.9047393641852124e-14, 2.1248851941314958e-16, 3.6247269512444368e-19, 1.6249853271916221e-22, 6.9350835444886530e-27}, + {1.0787188820741241e-27, 2.8387387532094075e-23, 7.0078433305584917e-20, 4.5173712236048158e-17, 1.1428616750256895e-14, 1.4076333438452520e-12, 9.6270292926054501e-11, 3.9906528856889178e-09, 1.0665865704409148e-07, 1.9234656867323990e-06, 2.4223415120935207e-05, 2.1875759533939115e-04, 1.4463071215627061e-03, 7.1152368261340193e-03, 2.6380533520486894e-02, 7.4443983368238764e-02, 1.6108797149548099e-01, 2.6872376002892800e-01, 3.4678411786878038e-01, 3.4678411786878038e-01, 2.6872376002892800e-01, 1.6108797149548099e-01, 7.4443983368238764e-02, 2.6380533520486894e-02, 7.1152368261340193e-03, 1.4463071215627061e-03, 2.1875759533939115e-04, 2.4223415120935207e-05, 1.9234656867323990e-06, 1.0665865704409148e-07, 3.9906528856889178e-09, 9.6270292926054501e-11, 1.4076333438452520e-12, 1.1428616750256895e-14, 4.5173712236048158e-17, 7.0078433305584917e-20, 2.8387387532094075e-23, 1.0787188820741241e-27}, + {1.6737892441539538e-28, 4.9359073375904207e-24, 1.3457268201343837e-20, 9.5193204821162674e-18, 2.6340961107224671e-15, 3.5426508019791487e-13, 2.6440048769930072e-11, 1.1961664237667613e-09, 3.4915088439108438e-08, 6.8844204093401453e-07, 9.4942995361418356e-06, 9.4077279467672325e-05, 6.8405759521855724e-04, 3.7112302317141572e-03, 1.5221980837289402e-02, 4.7690071331635359e-02, 1.1503504579976950e-01, 2.1489607677746486e-01, 3.1216284886717011e-01, 3.5344263570679940e-01, 3.1216284886717011e-01, 2.1489607677746486e-01, 1.1503504579976950e-01, 4.7690071331635359e-02, 1.5221980837289402e-02, 3.7112302317141572e-03, 6.8405759521855724e-04, 9.4077279467672325e-05, 9.4942995361418356e-06, 6.8844204093401453e-07, 3.4915088439108438e-08, 1.1961664237667613e-09, 2.6440048769930072e-11, 3.5426508019791487e-13, 2.6340961107224671e-15, 9.5193204821162674e-18, 1.3457268201343837e-20, 4.9359073375904207e-24, 1.6737892441539538e-28}, + {2.5910437138470431e-29, 8.5440569637751720e-25, 2.5675933654117104e-21, 1.9891810121165382e-18, 6.0083587894908697e-16, 8.8057076452162173e-14, 7.1565280526903396e-12, 3.5256207913654460e-10, 1.1212360832275973e-08, 2.4111441636705294e-07, 3.6315761506930362e-06, 3.9369339810924932e-05, 3.1385359454133192e-04, 1.8714968295979542e-03, 8.4608880082581352e-03, 2.9312565536172355e-02, 7.8474605865404390e-02, 1.6337873271327136e-01, 2.6572825187737692e-01, 3.3864327742558936e-01, 3.3864327742558936e-01, 2.6572825187737692e-01, 1.6337873271327136e-01, 7.8474605865404390e-02, 2.9312565536172355e-02, 8.4608880082581352e-03, 1.8714968295979542e-03, 3.1385359454133192e-04, 3.9369339810924932e-05, 3.6315761506930362e-06, 2.4111441636705294e-07, 1.1212360832275973e-08, 3.5256207913654460e-10, 7.1565280526903396e-12, 8.8057076452162173e-14, 6.0083587894908697e-16, 1.9891810121165382e-18, 2.5675933654117104e-21, 8.5440569637751720e-25, 2.5910437138470431e-29}, + {4.0019596605455888e-30, 1.4726537286520423e-25, 4.8687379360130589e-22, 4.1234085375315004e-19, 1.3569875295861202e-16, 2.1629872471750215e-14, 1.9103833646809321e-12, 1.0226798927782354e-10, 3.5356816483807076e-09, 8.2726584187498191e-08, 1.3573781404870848e-06, 1.6055965736677200e-05, 1.3993025659674152e-04, 9.1423425632870857e-04, 4.5403929873032720e-03, 1.7330881362116784e-02, 5.1289872397094663e-02, 1.1848439124684401e-01, 2.1473086449008444e-01, 3.0636781693785120e-01, 3.4482208361638955e-01, 3.0636781693785120e-01, 2.1473086449008444e-01, 1.1848439124684401e-01, 5.1289872397094663e-02, 1.7330881362116784e-02, 4.5403929873032720e-03, 9.1423425632870857e-04, 1.3993025659674152e-04, 1.6055965736677200e-05, 1.3573781404870848e-06, 8.2726584187498191e-08, 3.5356816483807076e-09, 1.0226798927782354e-10, 1.9103833646809321e-12, 2.1629872471750215e-14, 1.3569875295861202e-16, 4.1234085375315004e-19, 4.8687379360130589e-22, 1.4726537286520423e-25, 4.0019596605455888e-30}, + {6.1678589258109773e-31, 2.5278698640534739e-26, 9.1778906956924963e-23, 8.4821520800863616e-20, 3.0358903478107461e-17, 5.2533377155686787e-15, 5.0327055821840466e-13, 2.9217288372333376e-11, 1.0958052288078504e-09, 2.7834715265490800e-08, 4.9636593935798231e-07, 6.3902459677354328e-06, 6.0719621077883790e-05, 4.3341227172125611e-04, 2.3571613945963252e-03, 9.8795240531885219e-03, 3.2202101288907867e-02, 8.2211269303293782e-02, 1.6528800127466756e-01, 2.6273890678229461e-01, 3.3104891389085667e-01, 3.3104891389085667e-01, 2.6273890678229461e-01, 1.6528800127466756e-01, 8.2211269303293782e-02, 3.2202101288907867e-02, 9.8795240531885219e-03, 2.3571613945963252e-03, 4.3341227172125611e-04, 6.0719621077883790e-05, 6.3902459677354328e-06, 4.9636593935798231e-07, 2.7834715265490800e-08, 1.0958052288078504e-09, 2.9217288372333376e-11, 5.0327055821840466e-13, 5.2533377155686787e-15, 3.0358903478107461e-17, 8.4821520800863616e-20, 9.1778906956924963e-23, 2.5278698640534739e-26, 6.1678589258109773e-31}, + {9.4863063307486296e-32, 4.3221460599337345e-27, 1.7203368260282161e-23, 1.7320753790913467e-20, 6.7308117032428195e-18, 1.2622032209758195e-15, 1.3092104166584946e-13, 8.2271061208164963e-12, 3.3407179153175535e-10, 9.1931960675404414e-09, 1.7777830445479720e-07, 2.4851377424115403e-06, 2.5680573077056677e-05, 1.9972435671322962e-04, 1.1860700927674253e-03, 5.4414552932418097e-03, 1.9468160151101737e-02, 5.4724809081874805e-02, 1.2156737988638795e-01, 2.1434349700188368e-01, 3.0086599386765978e-01, 3.3680296539275278e-01, 3.0086599386765978e-01, 2.1434349700188368e-01, 1.2156737988638795e-01, 5.4724809081874805e-02, 1.9468160151101737e-02, 5.4414552932418097e-03, 1.1860700927674253e-03, 1.9972435671322962e-04, 2.5680573077056677e-05, 2.4851377424115403e-06, 1.7777830445479720e-07, 9.1931960675404414e-09, 3.3407179153175535e-10, 8.2271061208164963e-12, 1.3092104166584946e-13, 1.2622032209758195e-15, 6.7308117032428195e-18, 1.7320753790913467e-20, 1.7203368260282161e-23, 4.3221460599337345e-27, 9.4863063307486296e-32}, + {1.4561153081762322e-32, 7.3621261042968285e-28, 3.2072216919050275e-24, 3.5121449558365656e-21, 1.4794099758171669e-18, 3.0015214029808191e-16, 3.3650356127923192e-14, 2.2848078971220373e-12, 1.0026000778909185e-10, 2.9831210190396358e-09, 6.2427245062815072e-08, 9.4545385422855902e-07, 1.0600171772517656e-05, 8.9597973640616782e-05, 5.7942043271566558e-04, 2.9012937752966299e-03, 1.1357866939069948e-02, 3.5033757109687119e-02, 8.5670187300246295e-02, 1.6686716582564590e-01, 2.5977339611588807e-01, 3.2394262884199604e-01, 3.2394262884199604e-01, 2.5977339611588807e-01, 1.6686716582564590e-01, 8.5670187300246295e-02, 3.5033757109687119e-02, 1.1357866939069948e-02, 2.9012937752966299e-03, 5.7942043271566558e-04, 8.9597973640616782e-05, 1.0600171772517656e-05, 9.4545385422855902e-07, 6.2427245062815072e-08, 2.9831210190396358e-09, 1.0026000778909185e-10, 2.2848078971220373e-12, 3.3650356127923192e-14, 3.0015214029808191e-16, 1.4794099758171669e-18, 3.5121449558365656e-21, 3.2072216919050275e-24, 7.3621261042968285e-28, 1.4561153081762322e-32}, + {2.2308126593779868e-33, 1.2494829120559801e-28, 5.9481747159233458e-25, 7.0737246502696336e-22, 3.2248298707326610e-19, 7.0674619157542681e-17, 8.5500874663703821e-15, 6.2620383158353876e-13, 2.9642049893157670e-11, 9.5182669412336419e-10, 2.1512839074194501e-08, 3.5225192415065300e-07, 4.2754558863972689e-06, 3.9183295448819551e-05, 2.7524242709953090e-04, 1.5001278829297612e-03, 6.4070706562040147e-03, 2.1617644433765643e-02, 5.7992746631628803e-02, 1.2432050192893590e-01, 2.1377487850201790e-01, 2.9563565196662861e-01, 3.2931845505069163e-01, 2.9563565196662861e-01, 2.1377487850201790e-01, 1.2432050192893590e-01, 5.7992746631628803e-02, 2.1617644433765643e-02, 6.4070706562040147e-03, 1.5001278829297612e-03, 2.7524242709953090e-04, 3.9183295448819551e-05, 4.2754558863972689e-06, 3.5225192415065300e-07, 2.1512839074194501e-08, 9.5182669412336419e-10, 2.9642049893157670e-11, 6.2620383158353876e-13, 8.5500874663703821e-15, 7.0674619157542681e-17, 3.2248298707326610e-19, 7.0737246502696336e-22, 5.9481747159233458e-25, 1.2494829120559801e-28, 2.2308126593779868e-33}, + {3.4113792299096508e-34, 2.1132014962696289e-29, 1.0976558019968051e-25, 1.4155042016755176e-22, 6.9737995966949200e-20, 1.6484447389507407e-17, 2.1486472823678717e-15, 1.6947076167749986e-13, 8.6391402914483532e-12, 2.9885455879923381e-10, 7.2816347565639946e-09, 1.2865324130563406e-07, 1.6869468397355139e-06, 1.6725935920653945e-05, 1.2731983755106949e-04, 7.5339673454313967e-04, 3.5010578505227864e-03, 1.2883487559777229e-02, 3.7795830992247079e-02, 8.8868227566005320e-02, 1.6816012736212269e-01, 2.5684454350651975e-01, 3.1727438491816684e-01, 3.1727438491816684e-01, 2.5684454350651975e-01, 1.6816012736212269e-01, 8.8868227566005320e-02, 3.7795830992247079e-02, 1.2883487559777229e-02, 3.5010578505227864e-03, 7.5339673454313967e-04, 1.2731983755106949e-04, 1.6725935920653945e-05, 1.6869468397355139e-06, 1.2865324130563406e-07, 7.2816347565639946e-09, 2.9885455879923381e-10, 8.6391402914483532e-12, 1.6947076167749986e-13, 2.1486472823678717e-15, 1.6484447389507407e-17, 6.9737995966949200e-20, 1.4155042016755176e-22, 1.0976558019968051e-25, 2.1132014962696289e-29, 3.4113792299096508e-34}, + {5.2074550840354642e-35, 3.5619817807815819e-30, 2.0158558166547157e-26, 2.8149547423920401e-23, 1.4966299166256593e-20, 3.8101463479230325e-18, 5.3428423961486667e-16, 4.5312676467479057e-14, 2.4836135431247532e-12, 9.2402978883643831e-11, 2.4228134937243909e-09, 4.6104364856635215e-08, 6.5181055230401887e-07, 6.9771079617906096e-06, 5.7425938238321535e-05, 3.6806169587486260e-04, 1.8562527788732503e-03, 7.4296915378901547e-03, 2.3765555762406108e-02, 6.1094386221801737e-02, 1.2677670015500209e-01, 2.1305846026514422e-01, 2.9065687385124467e-01, 3.2231167941131522e-01, 2.9065687385124467e-01, 2.1305846026514422e-01, 1.2677670015500209e-01, 6.1094386221801737e-02, 2.3765555762406108e-02, 7.4296915378901547e-03, 1.8562527788732503e-03, 3.6806169587486260e-04, 5.7425938238321535e-05, 6.9771079617906096e-06, 6.5181055230401887e-07, 4.6104364856635215e-08, 2.4228134937243909e-09, 9.2402978883643831e-11, 2.4836135431247532e-12, 4.5312676467479057e-14, 5.3428423961486667e-16, 3.8101463479230325e-18, 1.4966299166256593e-20, 2.8149547423920401e-23, 2.0158558166547157e-26, 3.5619817807815819e-30, 5.2074550840354642e-35}, + {7.9355514607740056e-36, 5.9846126933135906e-31, 3.6850360801506979e-27, 5.5645774689023294e-24, 3.1883873235051506e-21, 8.7301596011867662e-19, 1.3151596226583889e-16, 1.1975898654791956e-14, 7.0469325815459271e-13, 2.8152965378381835e-11, 7.9304674951654092e-10, 1.6225141358957786e-08, 2.4686589936697532e-07, 2.8472586917348417e-06, 2.5285990277484952e-05, 1.7515043180117349e-04, 9.5639231981941610e-04, 4.1530049119775534e-03, 1.4444961574981133e-02, 4.0479676984603939e-02, 9.1822297079285201e-02, 1.6920447194564109e-01, 2.5396154266475901e-01, 3.1100103037796278e-01, 3.1100103037796278e-01, 2.5396154266475901e-01, 1.6920447194564109e-01, 9.1822297079285201e-02, 4.0479676984603939e-02, 1.4444961574981133e-02, 4.1530049119775534e-03, 9.5639231981941610e-04, 1.7515043180117349e-04, 2.5285990277484952e-05, 2.8472586917348417e-06, 2.4686589936697532e-07, 1.6225141358957786e-08, 7.9304674951654092e-10, 2.8152965378381835e-11, 7.0469325815459271e-13, 1.1975898654791956e-14, 1.3151596226583889e-16, 8.7301596011867662e-19, 3.1883873235051506e-21, 5.5645774689023294e-24, 3.6850360801506979e-27, 5.9846126933135906e-31, 7.9355514607740056e-36}, + {1.2072872864975299e-36, 1.0023613427435658e-31, 6.7063563353463921e-28, 1.0936809436127891e-24, 6.7446743456588804e-22, 1.9836416602794039e-19, 3.2059589524003601e-17, 3.1301391441242865e-15, 1.9744849360632020e-13, 8.4575241714312574e-12, 2.5554702439987741e-10, 5.6118428733874883e-09, 9.1729613211703643e-08, 1.1378411996774051e-06, 1.0881805485674181e-05, 8.1291046453153734e-05, 4.7952088600477827e-04, 2.2536737753387727e-03, 8.5018075629547680e-03, 2.5900304438342722e-02, 6.4032496212210105e-02, 1.2896559830848855e-01, 2.1222171925816707e-01, 2.8591145169466448e-01, 3.1573389003557428e-01, 2.8591145169466448e-01, 2.1222171925816707e-01, 1.2896559830848855e-01, 6.4032496212210105e-02, 2.5900304438342722e-02, 8.5018075629547680e-03, 2.2536737753387727e-03, 4.7952088600477827e-04, 8.1291046453153734e-05, 1.0881805485674181e-05, 1.1378411996774051e-06, 9.1729613211703643e-08, 5.6118428733874883e-09, 2.5554702439987741e-10, 8.4575241714312574e-12, 1.9744849360632020e-13, 3.1301391441242865e-15, 3.2059589524003601e-17, 1.9836416602794039e-19, 6.7446743456588804e-22, 1.0936809436127891e-24, 6.7063563353463921e-28, 1.0023613427435658e-31, 1.2072872864975299e-36}, + {1.8337940485734247e-37, 1.6738016679078003e-32, 1.2152441234045103e-28, 2.1376583083600910e-25, 1.4170935995734126e-22, 4.4709843654079433e-20, 7.7423829570434533e-18, 8.0942618934651918e-16, 5.4659440318156410e-14, 2.5066555238996801e-12, 8.1118773649302876e-11, 1.9090405438119032e-09, 3.3467934040214541e-08, 4.4570299668178385e-07, 4.5816827079555368e-06, 3.6840190537807232e-05, 2.3426989210925618e-04, 1.1890117817496457e-03, 4.8532638261719538e-03, 1.6031941068412211e-02, 4.3079159156765599e-02, 9.4548935477086246e-02, 1.7003245567716402e-01, 2.5113085633200216e-01, 3.0508512920439906e-01, 3.0508512920439906e-01, 2.5113085633200216e-01, 1.7003245567716402e-01, 9.4548935477086246e-02, 4.3079159156765599e-02, 1.6031941068412211e-02, 4.8532638261719538e-03, 1.1890117817496457e-03, 2.3426989210925618e-04, 3.6840190537807232e-05, 4.5816827079555368e-06, 4.4570299668178385e-07, 3.3467934040214541e-08, 1.9090405438119032e-09, 8.1118773649302876e-11, 2.5066555238996801e-12, 5.4659440318156410e-14, 8.0942618934651918e-16, 7.7423829570434533e-18, 4.4709843654079433e-20, 1.4170935995734126e-22, 2.1376583083600910e-25, 1.2152441234045103e-28, 1.6738016679078003e-32, 1.8337940485734247e-37}, + {2.7811222326645344e-38, 2.7868913296983680e-33, 2.1929968310380126e-29, 4.1558650081686601e-26, 2.9579544865762534e-23, 9.9993599745434670e-21, 1.8530303241143367e-18, 2.0717064275729557e-16, 1.4956863300607063e-14, 7.3335422940638437e-13, 2.5381498317560184e-11, 6.3917274853532610e-10, 1.1999326533873204e-08, 1.7127604128737511e-07, 1.8891833940946794e-06, 1.6319954290330701e-05, 1.1165708931911324e-04, 6.1070259874041984e-04, 2.6911086058640649e-03, 9.6161203333211508e-03, 2.8012262602063957e-02, 6.6811317318844293e-02, 1.3091376937688559e-01, 2.1128731588244376e-01, 2.8138276384359967e-01, 3.0954302944664125e-01, 2.8138276384359967e-01, 2.1128731588244376e-01, 1.3091376937688559e-01, 6.6811317318844293e-02, 2.8012262602063957e-02, 9.6161203333211508e-03, 2.6911086058640649e-03, 6.1070259874041984e-04, 1.1165708931911324e-04, 1.6319954290330701e-05, 1.8891833940946794e-06, 1.7127604128737511e-07, 1.1999326533873204e-08, 6.3917274853532610e-10, 2.5381498317560184e-11, 7.3335422940638437e-13, 1.4956863300607063e-14, 2.0717064275729557e-16, 1.8530303241143367e-18, 9.9993599745434670e-21, 2.9579544865762534e-23, 4.1558650081686601e-26, 2.1929968310380126e-29, 2.7868913296983680e-33, 2.7811222326645344e-38}, + {4.2115420614105446e-39, 4.6271645012802355e-34, 3.9415951369162550e-30, 8.0378813038410338e-27, 6.1353803600426939e-24, 2.2196939309444735e-21, 4.3966970036273617e-19, 5.2503117409060339e-17, 4.0473768240447191e-15, 2.1189539626185899e-13, 7.8326447571213533e-12, 2.1076390184671402e-10, 4.2306685774284424e-09, 6.4623052172886120e-08, 7.6355680403038401e-07, 7.0741004987582161e-06, 5.1975998082926043e-05, 3.0574624681119092e-04, 1.4514479978625793e-03, 5.5977022679341544e-03, 1.7635166965733341e-02, 4.5590184103438805e-02, 9.7064055572858784e-02, 1.7067182934440731e-01, 2.4835688537420786e-01, 2.9949402485158516e-01, 2.9949402485158516e-01, 2.4835688537420786e-01, 1.7067182934440731e-01, 9.7064055572858784e-02, 4.5590184103438805e-02, 1.7635166965733341e-02, 5.5977022679341544e-03, 1.4514479978625793e-03, 3.0574624681119092e-04, 5.1975998082926043e-05, 7.0741004987582161e-06, 7.6355680403038401e-07, 6.4623052172886120e-08, 4.2306685774284424e-09, 2.1076390184671402e-10, 7.8326447571213533e-12, 2.1189539626185899e-13, 4.0473768240447191e-15, 5.2503117409060339e-17, 4.3966970036273617e-19, 2.2196939309444735e-21, 6.1353803600426939e-24, 8.0378813038410338e-27, 3.9415951369162550e-30, 4.6271645012802355e-34, 4.2115420614105446e-39}, + {6.3684623301529066e-40, 7.6617679179706699e-35, 7.0570663748570958e-31, 1.5468771288046908e-27, 1.2648661239395541e-24, 4.8919455331107564e-22, 1.0345305017520525e-19, 1.3179732316466649e-17, 1.0835445640249948e-15, 6.0495805864229647e-14, 2.3852254108327101e-12, 6.8487736158296791e-11, 1.4678463337326563e-09, 2.3957838556591937e-08, 3.0275650879319551e-07, 3.0032131335980235e-06, 2.3654729185615187e-05, 1.4937604708377004e-04, 7.6242846753152228e-04, 3.1668653729621131e-03, 1.0765666029311394e-02, 3.0093535038790555e-02, 6.9436105549292540e-02, 1.3264501499247186e-01, 2.1027400626010295e-01, 2.7705564403537380e-01, 3.0370259492878027e-01, 2.7705564403537380e-01, 2.1027400626010295e-01, 1.3264501499247186e-01, 6.9436105549292540e-02, 3.0093535038790555e-02, 1.0765666029311394e-02, 3.1668653729621131e-03, 7.6242846753152228e-04, 1.4937604708377004e-04, 2.3654729185615187e-05, 3.0032131335980235e-06, 3.0275650879319551e-07, 2.3957838556591937e-08, 1.4678463337326563e-09, 6.8487736158296791e-11, 2.3852254108327101e-12, 6.0495805864229647e-14, 1.0835445640249948e-15, 1.3179732316466649e-17, 1.0345305017520525e-19, 4.8919455331107564e-22, 1.2648661239395541e-24, 1.5468771288046908e-27, 7.0570663748570958e-31, 7.6617679179706699e-35, 6.3684623301529066e-40}, + {9.6165697698301258e-41, 1.2653200760168758e-35, 1.2587808691128722e-31, 2.9626275871495710e-28, 2.5923371557456032e-25, 1.0706490586422193e-22, 2.4146919999727056e-20, 3.2782519697898691e-18, 2.8709892632049820e-16, 1.7073406733468467e-14, 7.1713449978551876e-13, 2.1943984676811026e-11, 5.0147398704735039e-10, 8.7334448358337394e-09, 1.1786188465819090e-07, 1.2498100284112936e-06, 1.0535444441825744e-05, 7.1294347272485073e-05, 3.9051617266315898e-04, 1.7435254219654911e-03, 6.3820594170464536e-03, 1.9246441370539501e-02, 4.8010306161295493e-02, 9.9382787160472649e-02, 1.7114652799601413e-01, 2.4564247050424473e-01, 2.9419908452729160e-01, 2.9419908452729160e-01, 2.4564247050424473e-01, 1.7114652799601413e-01, 9.9382787160472649e-02, 4.8010306161295493e-02, 1.9246441370539501e-02, 6.3820594170464536e-03, 1.7435254219654911e-03, 3.9051617266315898e-04, 7.1294347272485073e-05, 1.0535444441825744e-05, 1.2498100284112936e-06, 1.1786188465819090e-07, 8.7334448358337394e-09, 5.0147398704735039e-10, 2.1943984676811026e-11, 7.1713449978551876e-13, 1.7073406733468467e-14, 2.8709892632049820e-16, 3.2782519697898691e-18, 2.4146919999727056e-20, 1.0706490586422193e-22, 2.5923371557456032e-25, 2.9626275871495710e-28, 1.2587808691128722e-31, 1.2653200760168758e-35, 9.6165697698301258e-41}, + {1.4501627690036662e-41, 2.0843249634724133e-36, 2.2371881417054147e-32, 5.6477366517509067e-29, 5.2828491369827090e-26, 2.3275184070080019e-23, 5.5924703344128403e-21, 8.0822735455939761e-19, 7.5316452507313807e-17, 4.7652984604189149e-15, 2.1297535284773726e-13, 6.9364439628016448e-12, 1.6879993347401012e-10, 3.1324958261028878e-09, 4.5081881972300138e-08, 5.1027034733995817e-07, 4.5962183144073910e-06, 3.3274977701846682e-05, 1.9525422369452320e-04, 9.3526439804451304e-04, 3.6789367196008232e-03, 1.1943896271882769e-02, 3.2137739232619873e-02, 7.1912783366758826e-02, 1.3418063914176925e-01, 2.0919736551904625e-01, 2.7291625193942631e-01, 2.9818072956643887e-01, 2.7291625193942631e-01, 2.0919736551904625e-01, 1.3418063914176925e-01, 7.1912783366758826e-02, 3.2137739232619873e-02, 1.1943896271882769e-02, 3.6789367196008232e-03, 9.3526439804451304e-04, 1.9525422369452320e-04, 3.3274977701846682e-05, 4.5962183144073910e-06, 5.1027034733995817e-07, 4.5081881972300138e-08, 3.1324958261028878e-09, 1.6879993347401012e-10, 6.9364439628016448e-12, 2.1297535284773726e-13, 4.7652984604189149e-15, 7.5316452507313807e-17, 8.0822735455939761e-19, 5.5924703344128403e-21, 2.3275184070080019e-23, 5.2828491369827090e-26, 5.6477366517509067e-29, 2.2371881417054147e-32, 2.0843249634724133e-36, 1.4501627690036662e-41}, + {2.1839473796203715e-42, 3.4249840843882790e-37, 3.9621540898960065e-33, 1.0717993883210793e-29, 1.0706713589643687e-26, 5.0270999187295385e-24, 1.2855363897049299e-21, 1.9756668115390835e-19, 1.9569261785647621e-17, 1.3158561251396991e-15, 6.2504456297525029e-14, 2.1641925885012134e-12, 5.6013978504685036e-11, 1.1062006976882208e-09, 1.6954324255991913e-08, 2.0454464536460739e-07, 1.9657534004009810e-06, 1.5201081492284489e-05, 9.5395991047773378e-05, 4.8937293565704996e-04, 2.0647475636031381e-03, 7.2020522320410518e-03, 2.0858574140157814e-02, 5.0338397424815960e-02, 1.0151939271798682e-01, 1.7147724762127156e-01, 2.4298927099272355e-01, 2.8917508433514816e-01, 2.8917508433514816e-01, 2.4298927099272355e-01, 1.7147724762127156e-01, 1.0151939271798682e-01, 5.0338397424815960e-02, 2.0858574140157814e-02, 7.2020522320410518e-03, 2.0647475636031381e-03, 4.8937293565704996e-04, 9.5395991047773378e-05, 1.5201081492284489e-05, 1.9657534004009810e-06, 2.0454464536460739e-07, 1.6954324255991913e-08, 1.1062006976882208e-09, 5.6013978504685036e-11, 2.1641925885012134e-12, 6.2504456297525029e-14, 1.3158561251396991e-15, 1.9569261785647621e-17, 1.9756668115390835e-19, 1.2855363897049299e-21, 5.0270999187295385e-24, 1.0706713589643687e-26, 1.0717993883210793e-29, 3.9621540898960065e-33, 3.4249840843882790e-37, 2.1839473796203715e-42}, + {3.2848343922234264e-43, 5.6145192176094857e-38, 6.9933335612180924e-34, 2.0251468211785233e-30, 2.1584037474070782e-27, 1.0789794198158127e-24, 2.9336812927661561e-22, 4.7897086011228863e-20, 5.0376705984946099e-18, 3.5961584198415702e-16, 1.8135512160129682e-14, 6.6680503871104131e-13, 1.8333727853050702e-11, 3.8483200507286178e-10, 6.2732332422802088e-09, 8.0560041690845556e-08, 8.2486418628805857e-07, 6.8030638512964077e-06, 4.5587459694050582e-05, 2.5003668451320217e-04, 1.1295333257645079e-03, 4.2250842236442390e-03, 1.3144726459581649e-02, 3.4139801128400288e-02, 7.4247675370613914e-02, 1.3553970687329148e-01, 2.0807036460654699e-01, 2.6895194980711801e-01, 2.9294948869685189e-01, 2.6895194980711801e-01, 2.0807036460654699e-01, 1.3553970687329148e-01, 7.4247675370613914e-02, 3.4139801128400288e-02, 1.3144726459581649e-02, 4.2250842236442390e-03, 1.1295333257645079e-03, 2.5003668451320217e-04, 4.5587459694050582e-05, 6.8030638512964077e-06, 8.2486418628805857e-07, 8.0560041690845556e-08, 6.2732332422802088e-09, 3.8483200507286178e-10, 1.8333727853050702e-11, 6.6680503871104131e-13, 1.8135512160129682e-14, 3.5961584198415702e-16, 5.0376705984946099e-18, 4.7897086011228863e-20, 2.9336812927661561e-22, 1.0789794198158127e-24, 2.1584037474070782e-27, 2.0251468211785233e-30, 6.9933335612180924e-34, 5.6145192176094857e-38, 3.2848343922234264e-43}, + {4.9345427975166703e-44, 9.1824526100660134e-39, 1.2302868650409080e-34, 3.8103303738430430e-31, 4.3288355988163862e-28, 2.3018029777481733e-25, 6.6480276615029978e-23, 1.1519651049881098e-20, 1.2852645022546249e-18, 9.7305218355116897e-17, 5.2042716465726346e-15, 2.0297402247949017e-13, 5.9217773854289703e-12, 1.3196011058824996e-10, 2.2850766766300011e-09, 3.1195246571716635e-08, 3.3984745324530809e-07, 2.9851306091787731e-06, 2.1327339454200749e-05, 1.2486893055641099e-04, 6.0296061313673489e-04, 2.4143454547297083e-03, 8.0534582747568747e-03, 2.2465314158278335e-02, 5.2574374089316610e-02, 1.0348723259331935e-01, 1.7168192789310016e-01, 2.4039805219536928e-01, 2.8439970531426456e-01, 2.8439970531426456e-01, 2.4039805219536928e-01, 1.7168192789310016e-01, 1.0348723259331935e-01, 5.2574374089316610e-02, 2.2465314158278335e-02, 8.0534582747568747e-03, 2.4143454547297083e-03, 6.0296061313673489e-04, 1.2486893055641099e-04, 2.1327339454200749e-05, 2.9851306091787731e-06, 3.3984745324530809e-07, 3.1195246571716635e-08, 2.2850766766300011e-09, 1.3196011058824996e-10, 5.9217773854289703e-12, 2.0297402247949017e-13, 5.2042716465726346e-15, 9.7305218355116897e-17, 1.2852645022546249e-18, 1.1519651049881098e-20, 6.6480276615029978e-23, 2.3018029777481733e-25, 4.3288355988163862e-28, 3.8103303738430430e-31, 1.2302868650409080e-34, 9.1824526100660134e-39, 4.9345427975166703e-44}, + {7.4038563068673450e-45, 1.4983962534795572e-39, 2.1574506027269642e-35, 7.1398344998607888e-32, 8.6385560494218303e-29, 4.8816444464632883e-26, 1.4963121942445614e-23, 2.7492726789010400e-21, 3.2508143970587746e-19, 2.6076354448061946e-17, 1.4776310161414783e-15, 6.1066717751743867e-14, 1.8884472351365658e-12, 4.4624672633249920e-11, 8.1989628692240572e-10, 1.1884210228039399e-08, 1.3757431403862670e-07, 1.2852403270784334e-06, 9.7761956199732341e-06, 6.1008880084875632e-05, 3.1439538907451493e-04, 1.3453332060777454e-03, 4.8029120328152543e-03, 1.4362559357587188e-02, 3.6095769719147547e-02, 7.6447309674074940e-02, 1.3673928335964028e-01, 2.0690383287647826e-01, 2.6515118763397444e-01, 2.8798424312571891e-01, 2.6515118763397444e-01, 2.0690383287647826e-01, 1.3673928335964028e-01, 7.6447309674074940e-02, 3.6095769719147547e-02, 1.4362559357587188e-02, 4.8029120328152543e-03, 1.3453332060777454e-03, 3.1439538907451493e-04, 6.1008880084875632e-05, 9.7761956199732341e-06, 1.2852403270784334e-06, 1.3757431403862670e-07, 1.1884210228039399e-08, 8.1989628692240572e-10, 4.4624672633249920e-11, 1.8884472351365658e-12, 6.1066717751743867e-14, 1.4776310161414783e-15, 2.6076354448061946e-17, 3.2508143970587746e-19, 2.7492726789010400e-21, 1.4963121942445614e-23, 4.8816444464632883e-26, 8.6385560494218303e-29, 7.1398344998607888e-32, 2.1574506027269642e-35, 1.4983962534795572e-39, 7.4038563068673450e-45}, + {1.1095872479683389e-45, 2.4397475881451687e-40, 3.7716267271207567e-36, 1.3325596117642357e-32, 1.7155731476717639e-29, 1.0294059971650915e-26, 3.3457569557525580e-24, 6.5125672574964802e-22, 8.1536404730238284e-20, 6.9232479095776861e-18, 4.1524441096940554e-16, 1.8166245762596555e-14, 5.9484305160561044e-13, 1.4889573490628030e-11, 2.8993590128077474e-10, 4.4568227752259551e-09, 5.4755546192766962e-08, 5.4335161342049202e-07, 4.3942869362670327e-06, 2.9187419041555301e-05, 1.6027733468184521e-04, 7.3177355696550823e-04, 2.7913248289530633e-03, 8.9321783603078207e-03, 2.4061272766109355e-02, 5.4718970932182816e-02, 1.0529876369778575e-01, 1.7177615691888495e-01, 2.3786890495865878e-01, 2.7985311752282899e-01, 2.7985311752282899e-01, 2.3786890495865878e-01, 1.7177615691888495e-01, 1.0529876369778575e-01, 5.4718970932182816e-02, 2.4061272766109355e-02, 8.9321783603078207e-03, 2.7913248289530633e-03, 7.3177355696550823e-04, 1.6027733468184521e-04, 2.9187419041555301e-05, 4.3942869362670327e-06, 5.4335161342049202e-07, 5.4755546192766962e-08, 4.4568227752259551e-09, 2.8993590128077474e-10, 1.4889573490628030e-11, 5.9484305160561044e-13, 1.8166245762596555e-14, 4.1524441096940554e-16, 6.9232479095776861e-18, 8.1536404730238284e-20, 6.5125672574964802e-22, 3.3457569557525580e-24, 1.0294059971650915e-26, 1.7155731476717639e-29, 1.3325596117642357e-32, 3.7716267271207567e-36, 2.4397475881451687e-40, 1.1095872479683389e-45}, + {1.6610070486206728e-46, 3.9640620009950677e-41, 6.5736876067220763e-37, 2.4774746124224036e-33, 3.3910839755167296e-30, 2.1587655850502334e-27, 7.4335800238463694e-25, 1.5315980968945761e-22, 2.0285571447032586e-20, 1.8216160573946239e-18, 1.1553699025986796e-16, 5.3454835391987630e-15, 1.8515162945489592e-13, 4.9041814317738659e-12, 1.0110041892763622e-10, 1.6462612023799091e-09, 2.1440032177267756e-08, 2.2570860520414515e-07, 1.9382734960996544e-06, 1.3684069297535329e-05, 7.9958097609494878e-05, 3.8892085371592777e-04, 1.5825583090958971e-03, 5.4099296624677247e-03, 1.5592290312662006e-02, 3.8002651439240136e-02, 7.8518270158397185e-02, 1.3779465152760539e-01, 2.0570683105394089e-01, 2.6150339781427412e-01, 2.8326318995972372e-01, 2.6150339781427412e-01, 2.0570683105394089e-01, 1.3779465152760539e-01, 7.8518270158397185e-02, 3.8002651439240136e-02, 1.5592290312662006e-02, 5.4099296624677247e-03, 1.5825583090958971e-03, 3.8892085371592777e-04, 7.9958097609494878e-05, 1.3684069297535329e-05, 1.9382734960996544e-06, 2.2570860520414515e-07, 2.1440032177267756e-08, 1.6462612023799091e-09, 1.0110041892763622e-10, 4.9041814317738659e-12, 1.8515162945489592e-13, 5.3454835391987630e-15, 1.1553699025986796e-16, 1.8216160573946239e-18, 2.0285571447032586e-20, 1.5315980968945761e-22, 7.4335800238463694e-25, 2.1587655850502334e-27, 3.3910839755167296e-30, 2.4774746124224036e-33, 6.5736876067220763e-37, 3.9640620009950677e-41, 1.6610070486206728e-46}, + {2.4837138180536654e-47, 6.4274569671736483e-42, 1.1424028966725505e-37, 4.5888574043976661e-34, 6.6725110959391675e-31, 4.5029239074522869e-28, 1.6414116353925588e-25, 3.5767852999576706e-23, 5.0073739324943669e-21, 4.7513038441234886e-19, 3.1838887747718650e-17, 1.5564176512276732e-15, 5.6970949884188746e-14, 1.5952148801760892e-12, 3.4779437587729222e-11, 5.9926928642653631e-10, 8.2638647618516911e-09, 9.2185737335790556e-08, 8.3956368818335782e-07, 6.2919256841286273e-06, 3.9066932688710276e-05, 2.0215217999457319e-04, 8.7616004129601344e-04, 3.1945104951283309e-03, 9.8342822671495106e-03, 2.5641844544669879e-02, 5.6773556441129344e-02, 1.0696556035928920e-01, 1.7177351127893237e-01, 2.3540141376649018e-01, 2.7551763457131306e-01, 2.7551763457131306e-01, 2.3540141376649018e-01, 1.7177351127893237e-01, 1.0696556035928920e-01, 5.6773556441129344e-02, 2.5641844544669879e-02, 9.8342822671495106e-03, 3.1945104951283309e-03, 8.7616004129601344e-04, 2.0215217999457319e-04, 3.9066932688710276e-05, 6.2919256841286273e-06, 8.3956368818335782e-07, 9.2185737335790556e-08, 8.2638647618516911e-09, 5.9926928642653631e-10, 3.4779437587729222e-11, 1.5952148801760892e-12, 5.6970949884188746e-14, 1.5564176512276732e-15, 3.1838887747718650e-17, 4.7513038441234886e-19, 5.0073739324943669e-21, 3.5767852999576706e-23, 1.6414116353925588e-25, 4.5029239074522869e-28, 6.6725110959391675e-31, 4.5888574043976661e-34, 1.1424028966725505e-37, 6.4274569671736483e-42, 2.4837138180536654e-47}, + {3.7099206361930349e-48, 1.0400778615224128e-42, 1.9796804708319897e-38, 8.4687478191905945e-35, 1.3071305930820806e-31, 9.3437837175659029e-29, 3.6027426635285024e-26, 8.2963863116210883e-24, 1.2266629909143781e-21, 1.2288435628835336e-19, 8.6925536958459408e-18, 4.4857058689315790e-16, 1.7335817955789140e-14, 5.1265062385198317e-13, 1.1808921844569749e-11, 2.1508698297874976e-10, 3.1371929535383148e-09, 3.7041625984897139e-08, 3.5734732949990906e-07, 2.8393114498469317e-06, 1.8709113003788699e-05, 1.0284880800685653e-04, 4.7411702610320811e-04, 1.8409222622442125e-03, 6.0436044551375788e-03, 1.6829299199652096e-02, 3.9858264027817066e-02, 8.0467087994200825e-02, 1.3871950817658463e-01, 2.0448695346897386e-01, 2.5799889943138321e-01, 2.7876694884925185e-01, 2.5799889943138321e-01, 2.0448695346897386e-01, 1.3871950817658463e-01, 8.0467087994200825e-02, 3.9858264027817066e-02, 1.6829299199652096e-02, 6.0436044551375788e-03, 1.8409222622442125e-03, 4.7411702610320811e-04, 1.0284880800685653e-04, 1.8709113003788699e-05, 2.8393114498469317e-06, 3.5734732949990906e-07, 3.7041625984897139e-08, 3.1371929535383148e-09, 2.1508698297874976e-10, 1.1808921844569749e-11, 5.1265062385198317e-13, 1.7335817955789140e-14, 4.4857058689315790e-16, 8.6925536958459408e-18, 1.2288435628835336e-19, 1.2266629909143781e-21, 8.2963863116210883e-24, 3.6027426635285024e-26, 9.3437837175659029e-29, 1.3071305930820806e-31, 8.4687478191905945e-35, 1.9796804708319897e-38, 1.0400778615224128e-42, 3.7099206361930349e-48}, + {5.5357065358570184e-49, 1.6797479901081275e-43, 3.4211380112558623e-39, 1.5573906246297621e-35, 2.5496608991129390e-32, 1.9291035954649827e-29, 7.8617977889259561e-27, 1.9117068833006383e-24, 2.9828627842798555e-22, 3.1522545665038165e-20, 2.3518847106758435e-18, 1.2800933913224359e-16, 5.2186237265908379e-15, 1.6283407307097284e-13, 3.9591777669477542e-12, 7.6152172501454727e-11, 1.1736167423215493e-09, 1.4651253164761138e-08, 1.4955329367272515e-07, 1.2583402510311900e-06, 8.7884992308503793e-06, 5.1259291357862856e-05, 2.5098369851306242e-04, 1.0363290995075809e-03, 3.6225869785344623e-03, 1.0756040509879146e-02, 2.7203128953688913e-02, 5.8739981964099283e-02, 1.0849834930618682e-01, 1.7168584234908363e-01, 2.3299478606267793e-01, 2.7137742494130401e-01, 2.7137742494130401e-01, 2.3299478606267793e-01, 1.7168584234908363e-01, 1.0849834930618682e-01, 5.8739981964099283e-02, 2.7203128953688913e-02, 1.0756040509879146e-02, 3.6225869785344623e-03, 1.0363290995075809e-03, 2.5098369851306242e-04, 5.1259291357862856e-05, 8.7884992308503793e-06, 1.2583402510311900e-06, 1.4955329367272515e-07, 1.4651253164761138e-08, 1.1736167423215493e-09, 7.6152172501454727e-11, 3.9591777669477542e-12, 1.6283407307097284e-13, 5.2186237265908379e-15, 1.2800933913224359e-16, 2.3518847106758435e-18, 3.1522545665038165e-20, 2.9828627842798555e-22, 1.9117068833006383e-24, 7.8617977889259561e-27, 1.9291035954649827e-29, 2.5496608991129390e-32, 1.5573906246297621e-35, 3.4211380112558623e-39, 1.6797479901081275e-43, 5.5357065358570184e-49}, + {8.2516107962538437e-50, 2.7076758452831307e-44, 5.8962844659788279e-40, 2.8541849032786616e-36, 4.9525862550205175e-33, 3.9632869870747322e-30, 1.7059115810757949e-27, 4.3769741948718935e-25, 7.2016107891350715e-23, 8.0222187354240242e-21, 6.3078910455861518e-19, 3.6181996190429121e-17, 1.5546635722380968e-15, 5.1139174817165822e-14, 1.3112516106390246e-12, 2.6608653477929730e-11, 4.3286561534485417e-10, 5.7075829327787572e-09, 6.1577962214505752e-08, 5.4804560350180002e-07, 4.0522493910237441e-06, 2.5045342890495838e-05, 1.3008291629845118e-04, 5.7039896752377221e-04, 2.1199816320368434e-03, 6.7014045380057391e-03, 1.8069433112703592e-02, 4.1661108762478506e-02, 8.2300163369735294e-02, 1.3952613948284390e-01, 2.0325057415444170e-01, 2.5462881185279007e-01, 2.7447822655926341e-01, 2.5462881185279007e-01, 2.0325057415444170e-01, 1.3952613948284390e-01, 8.2300163369735294e-02, 4.1661108762478506e-02, 1.8069433112703592e-02, 6.7014045380057391e-03, 2.1199816320368434e-03, 5.7039896752377221e-04, 1.3008291629845118e-04, 2.5045342890495838e-05, 4.0522493910237441e-06, 5.4804560350180002e-07, 6.1577962214505752e-08, 5.7075829327787572e-09, 4.3286561534485417e-10, 2.6608653477929730e-11, 1.3112516106390246e-12, 5.1139174817165822e-14, 1.5546635722380968e-15, 3.6181996190429121e-17, 6.3078910455861518e-19, 8.0222187354240242e-21, 7.2016107891350715e-23, 4.3769741948718935e-25, 1.7059115810757949e-27, 3.9632869870747322e-30, 4.9525862550205175e-33, 2.8541849032786616e-36, 5.8962844659788279e-40, 2.7076758452831307e-44, 8.2516107962538437e-50}, + {1.2287768797135238e-50, 4.3565748909654033e-45, 1.0135609150438053e-40, 5.2133092407201474e-37, 9.5811571508986169e-34, 8.1036840367508257e-31, 3.6813492354788247e-28, 9.9592645616067056e-26, 1.7266548206330479e-23, 2.0259038600763283e-21, 1.6775151863814584e-19, 1.0132362352411122e-17, 4.5848634437116816e-16, 1.5885532676287405e-14, 4.2916420558156765e-13, 9.1795670585092616e-12, 1.5747988216738595e-10, 2.1910095676436381e-09, 2.4958591861839229e-08, 2.3470996573719479e-07, 1.8351979221091958e-06, 1.2005278344250187e-05, 6.6061130219886947e-05, 3.0721561121964142e-04, 1.2123596600232957e-03, 4.0741349478589858e-03, 1.1693944851274627e-02, 2.8741855098732765e-02, 6.0620459149597836e-02, 1.0990705313380535e-01, 1.7152351798443127e-01, 2.3064795199119065e-01, 2.6741826939146512e-01, 2.6741826939146512e-01, 2.3064795199119065e-01, 1.7152351798443127e-01, 1.0990705313380535e-01, 6.0620459149597836e-02, 2.8741855098732765e-02, 1.1693944851274627e-02, 4.0741349478589858e-03, 1.2123596600232957e-03, 3.0721561121964142e-04, 6.6061130219886947e-05, 1.2005278344250187e-05, 1.8351979221091958e-06, 2.3470996573719479e-07, 2.4958591861839229e-08, 2.1910095676436381e-09, 1.5747988216738595e-10, 9.1795670585092616e-12, 4.2916420558156765e-13, 1.5885532676287405e-14, 4.5848634437116816e-16, 1.0132362352411122e-17, 1.6775151863814584e-19, 2.0259038600763283e-21, 1.7266548206330479e-23, 9.9592645616067056e-26, 3.6813492354788247e-28, 8.1036840367508257e-31, 9.5811571508986169e-34, 5.2133092407201474e-37, 1.0135609150438053e-40, 4.3565748909654033e-45, 1.2287768797135238e-50}, + {1.8280449098224982e-51, 6.9969776104465074e-46, 1.7378601313821812e-41, 9.4914073654790101e-38, 1.8462398438517290e-34, 1.6492772853150654e-31, 7.9020561032723045e-29, 2.2524636987884908e-26, 4.1119507972824725e-24, 5.0779932729853307e-22, 4.4245805201641825e-20, 2.8120140377689001e-18, 1.3389362360428643e-16, 4.8824398317753951e-15, 1.3886060911907966e-13, 3.1279303248480510e-12, 5.6537332414960619e-11, 8.2920364429410743e-10, 9.9634336551576826e-09, 9.8898818048931736e-08, 8.1685444112022656e-07, 5.6493811974978918e-06, 3.2895750894750603e-05, 1.6204473635815332e-04, 6.7809290318947399e-04, 2.4191591440605796e-03, 7.3808332831545517e-03, 1.9308982903048826e-02, 4.3410259562275427e-02, 8.4023710374037747e-02, 1.4022557730554358e-01, 2.0200304815121278e-01, 2.5138497704677004e-01, 2.7038153661061759e-01, 2.5138497704677004e-01, 2.0200304815121278e-01, 1.4022557730554358e-01, 8.4023710374037747e-02, 4.3410259562275427e-02, 1.9308982903048826e-02, 7.3808332831545517e-03, 2.4191591440605796e-03, 6.7809290318947399e-04, 1.6204473635815332e-04, 3.2895750894750603e-05, 5.6493811974978918e-06, 8.1685444112022656e-07, 9.8898818048931736e-08, 9.9634336551576826e-09, 8.2920364429410743e-10, 5.6537332414960619e-11, 3.1279303248480510e-12, 1.3886060911907966e-13, 4.8824398317753951e-15, 1.3389362360428643e-16, 2.8120140377689001e-18, 4.4245805201641825e-20, 5.0779932729853307e-22, 4.1119507972824725e-24, 2.2524636987884908e-26, 7.9020561032723045e-29, 1.6492772853150654e-31, 1.8462398438517290e-34, 9.4914073654790101e-38, 1.7378601313821812e-41, 6.9969776104465074e-46, 1.8280449098224982e-51}, + {2.7170067116730165e-52, 1.1217925177026293e-46, 2.9723642655668546e-42, 1.7225457466828413e-38, 3.5439568636689488e-35, 3.3415178524750795e-32, 1.6874060730443393e-29, 5.0645263679858964e-27, 9.7283658177698223e-25, 1.2635945997114491e-22, 1.1577247535043669e-20, 7.7362132775431355e-19, 3.8731516902515290e-17, 1.4852494321530914e-15, 4.4433093884802028e-14, 1.0531630647084200e-12, 2.0038587880644725e-11, 3.0952986928769617e-10, 3.9193048318854111e-09, 4.1023319776043747e-08, 3.5754993018691617e-07, 2.6114965376035973e-06, 1.6073154232928773e-05, 8.3767928571091071e-05, 3.7124104714178821e-04, 1.4042112162131032e-03, 4.5476632686124660e-03, 1.2644719871722365e-02, 3.0255311010248965e-02, 6.2417460794691487e-02, 1.1120083831262205e-01, 1.7129562704597320e-01, 2.2835964147332644e-01, 2.6362735600964210e-01, 2.6362735600964210e-01, 2.2835964147332644e-01, 1.7129562704597320e-01, 1.1120083831262205e-01, 6.2417460794691487e-02, 3.0255311010248965e-02, 1.2644719871722365e-02, 4.5476632686124660e-03, 1.4042112162131032e-03, 3.7124104714178821e-04, 8.3767928571091071e-05, 1.6073154232928773e-05, 2.6114965376035973e-06, 3.5754993018691617e-07, 4.1023319776043747e-08, 3.9193048318854111e-09, 3.0952986928769617e-10, 2.0038587880644725e-11, 1.0531630647084200e-12, 4.4433093884802028e-14, 1.4852494321530914e-15, 3.8731516902515290e-17, 7.7362132775431355e-19, 1.1577247535043669e-20, 1.2635945997114491e-22, 9.7283658177698223e-25, 5.0645263679858964e-27, 1.6874060730443393e-29, 3.3415178524750795e-32, 3.5439568636689488e-35, 1.7225457466828413e-38, 2.9723642655668546e-42, 1.1217925177026293e-46, 2.7170067116730165e-52}, + {4.0345457983197185e-53, 1.7954384298058220e-47, 5.0715303590978945e-43, 3.1165183087668226e-39, 6.7773962594083074e-36, 6.7403932258482419e-33, 3.5851439372856567e-30, 1.1322450883416873e-27, 2.2869723112554000e-25, 3.1221586704548222e-23, 3.0058381695419005e-21, 2.1103468793130292e-19, 1.1100994988590987e-17, 4.4732478501982463e-16, 1.4065409569369246e-14, 3.5050786947688594e-13, 7.0144682351913210e-12, 1.1401392553489413e-10, 1.5199381740983112e-09, 1.6759992864221019e-08, 1.5399292502874990e-07, 1.1865872353918687e-06, 7.7110412769679424e-06, 4.2469576433922949e-05, 1.9909609055329152e-04, 7.9743820114063489e-04, 2.7377658998792736e-03, 8.0794563303749761e-03, 2.0544655922552182e-02, 4.5105267291699995e-02, 8.5643719556781017e-02, 1.4082773794401451e-01, 2.0074887688731419e-01, 2.4825988992112150e-01, 2.6646296361626087e-01, 2.4825988992112150e-01, 2.0074887688731419e-01, 1.4082773794401451e-01, 8.5643719556781017e-02, 4.5105267291699995e-02, 2.0544655922552182e-02, 8.0794563303749761e-03, 2.7377658998792736e-03, 7.9743820114063489e-04, 1.9909609055329152e-04, 4.2469576433922949e-05, 7.7110412769679424e-06, 1.1865872353918687e-06, 1.5399292502874990e-07, 1.6759992864221019e-08, 1.5199381740983112e-09, 1.1401392553489413e-10, 7.0144682351913210e-12, 3.5050786947688594e-13, 1.4065409569369246e-14, 4.4732478501982463e-16, 1.1100994988590987e-17, 2.1103468793130292e-19, 3.0058381695419005e-21, 3.1221586704548222e-23, 2.2869723112554000e-25, 1.1322450883416873e-27, 3.5851439372856567e-30, 6.7403932258482419e-33, 6.7773962594083074e-36, 3.1165183087668226e-39, 5.0715303590978945e-43, 1.7954384298058220e-47, 4.0345457983197185e-53}, + {5.9856092466933942e-54, 2.8688168912332612e-48, 8.6328113687066931e-44, 5.6216222243961033e-40, 1.2913788025337670e-36, 1.3538428107777088e-33, 7.5798318604310986e-31, 2.5172693785018537e-28, 5.3430216209626571e-26, 7.6615923972613038e-24, 7.7454736745174986e-22, 5.7095124323046545e-20, 3.1533210598724162e-18, 1.3342434681247850e-16, 4.4061175397950322e-15, 1.1534952560183679e-13, 2.4259623022354819e-12, 4.1457910332486197e-11, 5.8137344484280929e-10, 6.7473312881324816e-09, 6.5292934189484169e-08, 5.3024856335051780e-07, 3.6344904047182492e-06, 2.1131233267306212e-05, 1.0466994285006789e-04, 4.4339999663332603e-04, 1.6117353953558448e-03, 5.0416367476379337e-03, 1.3605327560618538e-02, 3.1741278190050709e-02, 6.4133640985369098e-02, 1.1238816501981971e-01, 1.7101015293603891e-01, 2.2612844383734518e-01, 2.5999310620316046e-01, 2.5999310620316046e-01, 2.2612844383734518e-01, 1.7101015293603891e-01, 1.1238816501981971e-01, 6.4133640985369098e-02, 3.1741278190050709e-02, 1.3605327560618538e-02, 5.0416367476379337e-03, 1.6117353953558448e-03, 4.4339999663332603e-04, 1.0466994285006789e-04, 2.1131233267306212e-05, 3.6344904047182492e-06, 5.3024856335051780e-07, 6.5292934189484169e-08, 6.7473312881324816e-09, 5.8137344484280929e-10, 4.1457910332486197e-11, 2.4259623022354819e-12, 1.1534952560183679e-13, 4.4061175397950322e-15, 1.3342434681247850e-16, 3.1533210598724162e-18, 5.7095124323046545e-20, 7.7454736745174986e-22, 7.6615923972613038e-24, 5.3430216209626571e-26, 2.5172693785018537e-28, 7.5798318604310986e-31, 1.3538428107777088e-33, 1.2913788025337670e-36, 5.6216222243961033e-40, 8.6328113687066931e-44, 2.8688168912332612e-48, 5.9856092466933942e-54}, + {8.8724008630942898e-55, 4.5764336789075590e-49, 1.4661118038718265e-44, 1.0110662325251453e-40, 2.4518913381167023e-37, 2.7079520650401302e-34, 1.5949041770861358e-31, 5.5663539164360154e-29, 1.2407683405472676e-26, 1.8675901831656063e-24, 1.9812686302523555e-22, 1.5323733317270031e-20, 8.8796168315044913e-19, 3.9423704233496054e-17, 1.3663145902821194e-15, 3.7548696680658361e-14, 8.2926419028182389e-13, 1.4887527478920644e-11, 2.1942330999743630e-10, 2.6779761171072075e-09, 2.7267833016134243e-08, 2.3316541347245123e-07, 1.6840172739131284e-06, 1.0325059077129107e-05, 5.3979561403797981e-05, 2.4157232920980263e-04, 9.2859086457657155e-04, 3.0750221611855083e-03, 8.7949222136699829e-03, 2.1773546737772456e-02, 4.6746077576099838e-02, 8.7165933915876653e-02, 1.4134154505606342e-01, 1.9949184460058894e-01, 2.4524663594920437e-01, 2.6270996412870795e-01, 2.4524663594920437e-01, 1.9949184460058894e-01, 1.4134154505606342e-01, 8.7165933915876653e-02, 4.6746077576099838e-02, 2.1773546737772456e-02, 8.7949222136699829e-03, 3.0750221611855083e-03, 9.2859086457657155e-04, 2.4157232920980263e-04, 5.3979561403797981e-05, 1.0325059077129107e-05, 1.6840172739131284e-06, 2.3316541347245123e-07, 2.7267833016134243e-08, 2.6779761171072075e-09, 2.1942330999743630e-10, 1.4887527478920644e-11, 8.2926419028182389e-13, 3.7548696680658361e-14, 1.3663145902821194e-15, 3.9423704233496054e-17, 8.8796168315044913e-19, 1.5323733317270031e-20, 1.9812686302523555e-22, 1.8675901831656063e-24, 1.2407683405472676e-26, 5.5663539164360154e-29, 1.5949041770861358e-31, 2.7079520650401302e-34, 2.4518913381167023e-37, 1.0110662325251453e-40, 1.4661118038718265e-44, 4.5764336789075590e-49, 8.8724008630942898e-55}, + {1.3140200635759138e-55, 7.2888760600699374e-50, 2.4843223778452137e-45, 1.8132393982490279e-41, 4.6392142210443241e-38, 5.3944805170903356e-35, 3.3402996562304201e-32, 1.2244058147622891e-29, 2.8644542990100537e-27, 4.5229388132654362e-25, 5.0319775906458023e-23, 4.0808135693241622e-21, 2.4793963766166604e-19, 1.1542667556483506e-17, 4.1953024073558444e-16, 1.2094094650388391e-14, 2.8026693289669983e-13, 5.2816149659273362e-12, 8.1749589868013172e-11, 1.0483088420892190e-09, 1.1221758911496157e-08, 1.0094315168892042e-07, 7.6747273751899334e-07, 4.9572490208738044e-06, 2.7325285268221331e-05, 1.2904853700328517e-04, 5.2397811821303173e-04, 1.8346879155592502e-03, 5.5544997811365557e-03, 1.4572966566065007e-02, 3.3197971745097789e-02, 6.5771771087721614e-02, 1.1347683695023611e-01, 1.7067412122709255e-01, 2.2395285395671372e-01, 2.5650502626034899e-01, 2.5650502626034899e-01, 2.2395285395671372e-01, 1.7067412122709255e-01, 1.1347683695023611e-01, 6.5771771087721614e-02, 3.3197971745097789e-02, 1.4572966566065007e-02, 5.5544997811365557e-03, 1.8346879155592502e-03, 5.2397811821303173e-04, 1.2904853700328517e-04, 2.7325285268221331e-05, 4.9572490208738044e-06, 7.6747273751899334e-07, 1.0094315168892042e-07, 1.1221758911496157e-08, 1.0483088420892190e-09, 8.1749589868013172e-11, 5.2816149659273362e-12, 2.8026693289669983e-13, 1.2094094650388391e-14, 4.1953024073558444e-16, 1.1542667556483506e-17, 2.4793963766166604e-19, 4.0808135693241622e-21, 5.0319775906458023e-23, 4.5229388132654362e-25, 2.8644542990100537e-27, 1.2244058147622891e-29, 3.3402996562304201e-32, 5.3944805170903356e-35, 4.6392142210443241e-38, 1.8132393982490279e-41, 2.4843223778452137e-45, 7.2888760600699374e-50, 1.3140200635759138e-55}, + {1.9444622230234342e-56, 1.1590959320007943e-50, 4.2004740254236363e-46, 3.2427888315124139e-42, 8.7482381269078278e-39, 1.0703814562172511e-35, 6.9640785632250250e-33, 2.6794918791965289e-30, 6.5751748013020018e-28, 1.0884570120961755e-25, 1.2691625603633038e-23, 1.0785433636173751e-21, 6.8663309606135431e-20, 3.3495959873429566e-18, 1.2758954586949696e-16, 3.8555242748433330e-15, 9.3683796134838034e-14, 1.8518064702871477e-12, 3.0076840393622017e-11, 4.0491316393465588e-10, 4.5529601729418187e-09, 4.3045713494096147e-08, 3.4420843484101099e-07, 2.3399997161498497e-06, 1.3586053874631190e-05, 6.7639272623934896e-05, 2.8977924888595573e-04, 1.0716281610696826e-03, 3.4300764387647066e-03, 9.5249775695009746e-03, 2.2993107110436964e-02, 4.8332960504809425e-02, 8.8595835021937436e-02, 1.4177503840549346e-01, 1.9823513131250983e-01, 2.4233883536068279e-01, 2.5911119749680783e-01, 2.4233883536068279e-01, 1.9823513131250983e-01, 1.4177503840549346e-01, 8.8595835021937436e-02, 4.8332960504809425e-02, 2.2993107110436964e-02, 9.5249775695009746e-03, 3.4300764387647066e-03, 1.0716281610696826e-03, 2.8977924888595573e-04, 6.7639272623934896e-05, 1.3586053874631190e-05, 2.3399997161498497e-06, 3.4420843484101099e-07, 4.3045713494096147e-08, 4.5529601729418187e-09, 4.0491316393465588e-10, 3.0076840393622017e-11, 1.8518064702871477e-12, 9.3683796134838034e-14, 3.8555242748433330e-15, 1.2758954586949696e-16, 3.3495959873429566e-18, 6.8663309606135431e-20, 1.0785433636173751e-21, 1.2691625603633038e-23, 1.0884570120961755e-25, 6.5751748013020018e-28, 2.6794918791965289e-30, 6.9640785632250250e-33, 1.0703814562172511e-35, 8.7482381269078278e-39, 3.2427888315124139e-42, 4.2004740254236363e-46, 1.1590959320007943e-50, 1.9444622230234342e-56}, + {2.8750275727924455e-57, 1.8404303463880958e-51, 7.0869721836637015e-47, 5.7836152624626662e-43, 1.6442414677949876e-39, 2.1156822123723002e-36, 1.4455024437001548e-33, 5.8345675304162565e-31, 1.5008973228057372e-28, 2.6033049503053747e-26, 3.1794998286708481e-24, 2.8296018603048517e-22, 1.8863727782270500e-20, 9.6365678168475681e-19, 3.8443430855465295e-17, 1.2168900581339222e-15, 3.0981886195643928e-14, 6.4188571380482567e-13, 1.0931590521335809e-11, 1.5438256127811863e-10, 1.8219509376836273e-09, 1.8089441547445238e-08, 1.5199860776329110e-07, 1.0865550828327965e-06, 6.6384540614267379e-06, 3.4806103755504017e-05, 1.5717296348585755e-04, 6.1320670594855193e-04, 2.0727405318696742e-03, 6.0846962089377739e-03, 1.5545067446090813e-02, 3.4623986133714632e-02, 6.7334688728284187e-02, 1.1447404988622129e-01, 1.7029372558220210e-01, 2.2183130791546488e-01, 2.5315358016164968e-01, 2.5315358016164968e-01, 2.2183130791546488e-01, 1.7029372558220210e-01, 1.1447404988622129e-01, 6.7334688728284187e-02, 3.4623986133714632e-02, 1.5545067446090813e-02, 6.0846962089377739e-03, 2.0727405318696742e-03, 6.1320670594855193e-04, 1.5717296348585755e-04, 3.4806103755504017e-05, 6.6384540614267379e-06, 1.0865550828327965e-06, 1.5199860776329110e-07, 1.8089441547445238e-08, 1.8219509376836273e-09, 1.5438256127811863e-10, 1.0931590521335809e-11, 6.4188571380482567e-13, 3.0981886195643928e-14, 1.2168900581339222e-15, 3.8443430855465295e-17, 9.6365678168475681e-19, 1.8863727782270500e-20, 2.8296018603048517e-22, 3.1794998286708481e-24, 2.6033049503053747e-26, 1.5008973228057372e-28, 5.8345675304162565e-31, 1.4455024437001548e-33, 2.1156822123723002e-36, 1.6442414677949876e-39, 5.7836152624626662e-43, 7.0869721836637015e-47, 1.8404303463880958e-51, 2.8750275727924455e-57}, + {4.2475403944235563e-58, 2.9179360026092975e-52, 1.1932102199256711e-47, 1.0287869477179010e-43, 3.0804483195558287e-40, 4.1660662393372492e-37, 2.9874354212480538e-34, 1.2642951712027768e-31, 3.4074887052468082e-29, 6.1891475308279466e-27, 7.9129760878551264e-25, 7.3704570195170156e-23, 5.1421792395941592e-21, 2.7491455795179009e-19, 1.1478770068871720e-17, 3.8036255791351365e-16, 1.0139883410013013e-14, 2.2003659842875677e-13, 3.9263803072919160e-12, 5.8125114501326569e-11, 7.1939577649798698e-10, 7.4947098368604126e-09, 6.6118669991811844e-08, 4.9655916977568413e-07, 3.1895150634568674e-06, 1.7594600636505465e-05, 8.3660559585237938e-05, 3.4399085887424382e-04, 1.2265540580803703e-03, 3.8020227522452721e-03, 1.0267477817470316e-02, 2.4201116175054306e-02, 4.9866450712457495e-02, 8.9938636734284719e-02, 1.4213547000895149e-01, 1.9698140672796691e-01, 2.3953059321276829e-01, 2.5565638153018372e-01, 2.3953059321276829e-01, 1.9698140672796691e-01, 1.4213547000895149e-01, 8.9938636734284719e-02, 4.9866450712457495e-02, 2.4201116175054306e-02, 1.0267477817470316e-02, 3.8020227522452721e-03, 1.2265540580803703e-03, 3.4399085887424382e-04, 8.3660559585237938e-05, 1.7594600636505465e-05, 3.1895150634568674e-06, 4.9655916977568413e-07, 6.6118669991811844e-08, 7.4947098368604126e-09, 7.1939577649798698e-10, 5.8125114501326569e-11, 3.9263803072919160e-12, 2.2003659842875677e-13, 1.0139883410013013e-14, 3.8036255791351365e-16, 1.1478770068871720e-17, 2.7491455795179009e-19, 5.1421792395941592e-21, 7.3704570195170156e-23, 7.9129760878551264e-25, 6.1891475308279466e-27, 3.4074887052468082e-29, 1.2642951712027768e-31, 2.9874354212480538e-34, 4.1660662393372492e-37, 3.0804483195558287e-40, 1.0287869477179010e-43, 1.1932102199256711e-47, 2.9179360026092975e-52, 4.2475403944235563e-58}, + {6.2703784480694208e-59, 4.6195869591589206e-53, 2.0048780070281735e-48, 1.8252564480138844e-44, 5.7530583850395732e-41, 8.1734457929853433e-38, 6.1482072743115000e-35, 2.7266171296454801e-32, 7.6951427469170207e-30, 1.4628329302419815e-27, 1.9567429736662381e-25, 1.9064520843927174e-23, 1.3911463582850983e-21, 7.7788589853855015e-20, 3.3973551764091287e-18, 1.1777094633733961e-16, 3.2852244087268414e-15, 7.4617858659486148e-14, 1.3941377125806722e-12, 2.1618054623290873e-11, 2.8038686778996357e-10, 3.0626832246516170e-09, 2.8344707359971740e-08, 2.2345250981121576e-07, 1.5076264668245447e-06, 8.7420837008076225e-06, 4.3727831577546010e-05, 1.8929762178671690e-04, 7.1126362441827832e-04, 2.3254926708230895e-03, 6.6306857259903285e-03, 1.6519285009994170e-02, 3.6018246356681126e-02, 6.8825257394126579e-02, 1.1538643824874496e-01, 1.6987443543948361e-01, 2.1976221051624720e-01, 2.4993008013933904e-01, 2.4993008013933904e-01, 2.1976221051624720e-01, 1.6987443543948361e-01, 1.1538643824874496e-01, 6.8825257394126579e-02, 3.6018246356681126e-02, 1.6519285009994170e-02, 6.6306857259903285e-03, 2.3254926708230895e-03, 7.1126362441827832e-04, 1.8929762178671690e-04, 4.3727831577546010e-05, 8.7420837008076225e-06, 1.5076264668245447e-06, 2.2345250981121576e-07, 2.8344707359971740e-08, 3.0626832246516170e-09, 2.8038686778996357e-10, 2.1618054623290873e-11, 1.3941377125806722e-12, 7.4617858659486148e-14, 3.2852244087268414e-15, 1.1777094633733961e-16, 3.3973551764091287e-18, 7.7788589853855015e-20, 1.3911463582850983e-21, 1.9064520843927174e-23, 1.9567429736662381e-25, 1.4628329302419815e-27, 7.6951427469170207e-30, 2.7266171296454801e-32, 6.1482072743115000e-35, 8.1734457929853433e-38, 5.7530583850395732e-41, 1.8252564480138844e-44, 2.0048780070281735e-48, 4.6195869591589206e-53, 6.2703784480694208e-59}, + {9.2494982219878178e-60, 7.3032412797370021e-54, 3.3619702764053515e-49, 3.2301359968277160e-45, 1.0711545066976377e-41, 1.5978109726748470e-38, 1.2601224816663446e-35, 5.8531004842511326e-33, 1.7288387765755684e-30, 3.4377966700873511e-28, 4.8085158087733593e-26, 4.8977600911363362e-24, 3.7358525784193159e-22, 2.1835856119475800e-20, 9.9692083309512582e-19, 3.6131260931106432e-17, 1.0539595203667931e-15, 2.5039803161790368e-14, 4.8951189293680036e-13, 7.9452485251106098e-12, 1.0791168663568375e-10, 1.2349280054594245e-09, 1.1980389793173491e-08, 9.9059473817560524e-08, 7.0144004582899757e-07, 4.2716344520701190e-06, 2.2456298833005965e-05, 1.0225119927510267e-04, 4.0444792546155510e-04, 1.3933051824601373e-03, 4.1899160223157692e-03, 1.1020394106207396e-02, 2.5395651463267135e-02, 5.1347296466210786e-02, 9.1199284542961764e-02, 1.4242938912607919e-01, 1.9573290855318265e-01, 2.3681645470932214e-01, 2.5233616878303844e-01, 2.3681645470932214e-01, 1.9573290855318265e-01, 1.4242938912607919e-01, 9.1199284542961764e-02, 5.1347296466210786e-02, 2.5395651463267135e-02, 1.1020394106207396e-02, 4.1899160223157692e-03, 1.3933051824601373e-03, 4.0444792546155510e-04, 1.0225119927510267e-04, 2.2456298833005965e-05, 4.2716344520701190e-06, 7.0144004582899757e-07, 9.9059473817560524e-08, 1.1980389793173491e-08, 1.2349280054594245e-09, 1.0791168663568375e-10, 7.9452485251106098e-12, 4.8951189293680036e-13, 2.5039803161790368e-14, 1.0539595203667931e-15, 3.6131260931106432e-17, 9.9692083309512582e-19, 2.1835856119475800e-20, 3.7358525784193159e-22, 4.8977600911363362e-24, 4.8085158087733593e-26, 3.4377966700873511e-28, 1.7288387765755684e-30, 5.8531004842511326e-33, 1.2601224816663446e-35, 1.5978109726748470e-38, 1.0711545066976377e-41, 3.2301359968277160e-45, 3.3619702764053515e-49, 7.3032412797370021e-54, 9.2494982219878178e-60}, + {1.3633833300020003e-60, 1.1529935596394474e-54, 5.6267053619996539e-50, 5.7021852730627675e-46, 1.9884044482437607e-42, 3.1126000220972273e-39, 2.5723712996578709e-36, 1.2507839519363874e-33, 3.8645811266244288e-31, 8.0343028910788638e-29, 1.1744629608333255e-26, 1.2499248537371909e-24, 9.9604705585733289e-23, 6.0820538195831629e-21, 2.9010288549385599e-19, 1.0985973435650033e-17, 3.3490712214349002e-16, 8.3173189675616162e-15, 1.7001957813551391e-13, 2.8865604962002583e-12, 4.1025651516570179e-11, 4.9151895982232822e-10, 4.9945929385487262e-09, 4.3280820924798808e-08, 3.2138167253993492e-07, 2.0537028582318748e-06, 1.1336998395832870e-05, 5.4246298804851998e-05, 2.2565979982055683e-04, 8.1827502694065590e-04, 2.5924825356809312e-03, 7.1909572204228826e-03, 1.7493488621590211e-02, 3.7379964305875417e-02, 7.0246334697072893e-02, 1.1622011916471321e-01, 1.6942108833811217e-01, 2.1774395641632643e-01, 2.4682659213344721e-01, 2.4682659213344721e-01, 2.1774395641632643e-01, 1.6942108833811217e-01, 1.1622011916471321e-01, 7.0246334697072893e-02, 3.7379964305875417e-02, 1.7493488621590211e-02, 7.1909572204228826e-03, 2.5924825356809312e-03, 8.1827502694065590e-04, 2.2565979982055683e-04, 5.4246298804851998e-05, 1.1336998395832870e-05, 2.0537028582318748e-06, 3.2138167253993492e-07, 4.3280820924798808e-08, 4.9945929385487262e-09, 4.9151895982232822e-10, 4.1025651516570179e-11, 2.8865604962002583e-12, 1.7001957813551391e-13, 8.3173189675616162e-15, 3.3490712214349002e-16, 1.0985973435650033e-17, 2.9010288549385599e-19, 6.0820538195831629e-21, 9.9604705585733289e-23, 1.2499248537371909e-24, 1.1744629608333255e-26, 8.0343028910788638e-29, 3.8645811266244288e-31, 1.2507839519363874e-33, 2.5723712996578709e-36, 3.1126000220972273e-39, 1.9884044482437607e-42, 5.7021852730627675e-46, 5.6267053619996539e-50, 1.1529935596394474e-54, 1.3633833300020003e-60}, + {2.0081683556012850e-61, 1.8178162551753148e-55, 9.3991295413480502e-51, 1.0041756149620635e-46, 3.6803258437880526e-43, 6.0427427569366402e-40, 5.2306055163095921e-37, 2.6610906118130193e-34, 8.5963278572927171e-32, 1.8674862726204788e-29, 2.8515675215544967e-27, 3.1692521338966959e-25, 2.6370712657175804e-23, 1.6812873372296920e-21, 8.3735311688359131e-20, 3.3113569430928055e-18, 1.0543294854998749e-16, 2.7353878696405856e-15, 5.8430667493651178e-14, 1.0369888470878425e-12, 1.5412284525394938e-11, 1.9317783962508064e-10, 2.0546146868576734e-09, 1.8645196384240901e-08, 1.4507140693109981e-07, 9.7197681673778427e-07, 5.6294099461087388e-06, 2.8280775482696968e-05, 1.2361276486093516e-04, 4.7135721157038344e-04, 1.5717570688376730e-03, 4.5927856260634522e-03, 1.1781817217642985e-02, 2.6575061210558436e-02, 5.2776416531222697e-02, 9.2382459021801644e-02, 1.4266271740044509e-01, 1.9449150803253865e-01, 2.3419136519193123e-01, 2.4914204006426580e-01, 2.3419136519193123e-01, 1.9449150803253865e-01, 1.4266271740044509e-01, 9.2382459021801644e-02, 5.2776416531222697e-02, 2.6575061210558436e-02, 1.1781817217642985e-02, 4.5927856260634522e-03, 1.5717570688376730e-03, 4.7135721157038344e-04, 1.2361276486093516e-04, 2.8280775482696968e-05, 5.6294099461087388e-06, 9.7197681673778427e-07, 1.4507140693109981e-07, 1.8645196384240901e-08, 2.0546146868576734e-09, 1.9317783962508064e-10, 1.5412284525394938e-11, 1.0369888470878425e-12, 5.8430667493651178e-14, 2.7353878696405856e-15, 1.0543294854998749e-16, 3.3113569430928055e-18, 8.3735311688359131e-20, 1.6812873372296920e-21, 2.6370712657175804e-23, 3.1692521338966959e-25, 2.8515675215544967e-27, 1.8674862726204788e-29, 8.5963278572927171e-32, 2.6610906118130193e-34, 5.2306055163095921e-37, 6.0427427569366402e-40, 3.6803258437880526e-43, 1.0041756149620635e-46, 9.3991295413480502e-51, 1.8178162551753148e-55, 2.0081683556012850e-61}, + {2.9557746032980847e-62, 2.8621845857326094e-56, 1.5671564937749406e-51, 1.7642057043388989e-47, 6.7924330161546228e-44, 1.1692076998197370e-40, 1.0595146928277511e-37, 5.6371927794771982e-35, 1.9029906100319421e-32, 4.3178173430220290e-30, 6.8834570436337191e-28, 7.9851871981733358e-26, 6.9341198195289992e-24, 4.6134710745539610e-22, 2.3978402756179082e-20, 9.8965289896201795e-19, 3.2891620143645649e-17, 8.9094610406663587e-16, 1.9875208346984979e-14, 3.6848498201591518e-13, 5.7232797185020048e-12, 7.4997199146582833e-11, 8.3430559260867452e-10, 7.9229232891502669e-09, 6.4544629501196559e-08, 4.5305355658612973e-07, 2.7507246274012478e-06, 1.4496444191129691e-05, 6.6517412418153150e-05, 2.6647788669335111e-04, 9.3431768696117658e-04, 2.8731975330897244e-03, 7.7640394053996482e-03, 1.8465751154427907e-02, 3.8708599914838084e-02, 7.1600747691843394e-02, 1.1698073380429937e-01, 1.6893796927590174e-01, 2.1577494627433041e-01, 2.4383585380721171e-01, 2.4383585380721171e-01, 2.1577494627433041e-01, 1.6893796927590174e-01, 1.1698073380429937e-01, 7.1600747691843394e-02, 3.8708599914838084e-02, 1.8465751154427907e-02, 7.7640394053996482e-03, 2.8731975330897244e-03, 9.3431768696117658e-04, 2.6647788669335111e-04, 6.6517412418153150e-05, 1.4496444191129691e-05, 2.7507246274012478e-06, 4.5305355658612973e-07, 6.4544629501196559e-08, 7.9229232891502669e-09, 8.3430559260867452e-10, 7.4997199146582833e-11, 5.7232797185020048e-12, 3.6848498201591518e-13, 1.9875208346984979e-14, 8.9094610406663587e-16, 3.2891620143645649e-17, 9.8965289896201795e-19, 2.3978402756179082e-20, 4.6134710745539610e-22, 6.9341198195289992e-24, 7.9851871981733358e-26, 6.8834570436337191e-28, 4.3178173430220290e-30, 1.9029906100319421e-32, 5.6371927794771982e-35, 1.0595146928277511e-37, 1.1692076998197370e-40, 6.7924330161546228e-44, 1.7642057043388989e-47, 1.5671564937749406e-51, 2.8621845857326094e-56, 2.9557746032980847e-62}, + {4.3474845662635656e-63, 4.5007211282481250e-57, 2.6082298377217237e-52, 3.0923065202135848e-48, 1.2501139575481106e-44, 2.2549072526181938e-41, 2.1381421402290456e-38, 1.1891459359657575e-35, 4.1929734266120318e-33, 9.9316879214599191e-31, 1.6522218331862429e-28, 1.9995631822582135e-26, 1.8111771920709664e-24, 1.2568606780858601e-22, 6.8135449122040696e-21, 2.9333425183931587e-19, 1.0170733571061197e-17, 2.8746837567251872e-16, 6.6931269313103119e-15, 1.2955204220510481e-13, 2.1014796586114549e-12, 2.8770619925838150e-11, 3.3453423873608581e-10, 3.3221419859886598e-09, 2.8316197051829986e-08, 2.0807020978532919e-07, 1.3232911149144323e-06, 7.3096953196703488e-06, 3.5180651840387621e-05, 1.4793874164100584e-04, 5.4489132381766836e-04, 1.7617305058156662e-03, 5.0096471937478518e-03, 1.2549959027149010e-02, 2.7737938219946516e-02, 5.4154863728585530e-02, 9.3492582227695284e-02, 1.4284081532237788e-01, 1.9325876496080116e-01, 2.3165063428423818e-01, 2.4606621240915144e-01, 2.3165063428423818e-01, 1.9325876496080116e-01, 1.4284081532237788e-01, 9.3492582227695284e-02, 5.4154863728585530e-02, 2.7737938219946516e-02, 1.2549959027149010e-02, 5.0096471937478518e-03, 1.7617305058156662e-03, 5.4489132381766836e-04, 1.4793874164100584e-04, 3.5180651840387621e-05, 7.3096953196703488e-06, 1.3232911149144323e-06, 2.0807020978532919e-07, 2.8316197051829986e-08, 3.3221419859886598e-09, 3.3453423873608581e-10, 2.8770619925838150e-11, 2.1014796586114549e-12, 1.2955204220510481e-13, 6.6931269313103119e-15, 2.8746837567251872e-16, 1.0170733571061197e-17, 2.9333425183931587e-19, 6.8135449122040696e-21, 1.2568606780858601e-22, 1.8111771920709664e-24, 1.9995631822582135e-26, 1.6522218331862429e-28, 9.9316879214599191e-31, 4.1929734266120318e-33, 1.1891459359657575e-35, 2.1381421402290456e-38, 2.2549072526181938e-41, 1.2501139575481106e-44, 3.0923065202135848e-48, 2.6082298377217237e-52, 4.5007211282481250e-57, 4.3474845662635656e-63}, + {6.3900846179356680e-64, 7.0683040654635165e-58, 4.3331628156671634e-53, 5.4079341607686490e-49, 2.2944871434121997e-45, 4.3348761233697938e-42, 4.2990971075609177e-39, 2.4981476114804934e-36, 9.1963660505689469e-34, 2.2729303616459228e-31, 3.9439087540838148e-29, 4.9770348134757658e-27, 4.7000291498915663e-25, 3.4001352768447133e-23, 1.9215431432889354e-21, 8.6245303609378974e-20, 3.1179884254074804e-18, 9.1905096520186247e-17, 2.2320593837338383e-15, 4.5078424718756776e-14, 7.6319902510210860e-13, 1.0909613183044814e-11, 1.3250311215425566e-10, 1.3750709116496800e-09, 1.2253983047111421e-08, 9.4193245001969527e-08, 6.2702226836829128e-07, 3.6275480887435970e-06, 1.8297490531324017e-05, 8.0695629747031377e-05, 3.1195003282250721e-04, 1.0594217898549964e-03, 3.1670839271362595e-03, 8.3485090964466376e-03, 1.9434337138642246e-02, 4.0003826723007251e-02, 7.2891273924741068e-02, 1.1767348589341342e-01, 1.6842887908813681e-01, 2.1385359898330383e-01, 2.4095120319809515e-01, 2.4095120319809515e-01, 2.1385359898330383e-01, 1.6842887908813681e-01, 1.1767348589341342e-01, 7.2891273924741068e-02, 4.0003826723007251e-02, 1.9434337138642246e-02, 8.3485090964466376e-03, 3.1670839271362595e-03, 1.0594217898549964e-03, 3.1195003282250721e-04, 8.0695629747031377e-05, 1.8297490531324017e-05, 3.6275480887435970e-06, 6.2702226836829128e-07, 9.4193245001969527e-08, 1.2253983047111421e-08, 1.3750709116496800e-09, 1.3250311215425566e-10, 1.0909613183044814e-11, 7.6319902510210860e-13, 4.5078424718756776e-14, 2.2320593837338383e-15, 9.1905096520186247e-17, 3.1179884254074804e-18, 8.6245303609378974e-20, 1.9215431432889354e-21, 3.4001352768447133e-23, 4.7000291498915663e-25, 4.9770348134757658e-27, 3.9439087540838148e-29, 2.2729303616459228e-31, 9.1963660505689469e-34, 2.4981476114804934e-36, 4.2990971075609177e-39, 4.3348761233697938e-42, 2.2944871434121997e-45, 5.4079341607686490e-49, 4.3331628156671634e-53, 7.0683040654635165e-58, 6.3900846179356680e-64}, + {9.3860543034002427e-65, 1.1086857074759456e-58, 7.1863132033979924e-54, 9.4366281490374702e-50, 4.2000954414179859e-46, 8.3074192361133957e-43, 8.6131947009295395e-40, 5.2269922366851146e-37, 2.0080025620200044e-34, 5.1761145427794598e-32, 9.3634938532685839e-30, 1.2315531785339706e-27, 1.2119297214386231e-25, 9.1354157424215784e-24, 5.3793647773372928e-22, 2.5158646274622071e-20, 9.4786222458398701e-19, 2.9120616998176371e-17, 7.3730974398680154e-16, 1.5527783781178122e-14, 2.7422533133249144e-13, 4.0903372275217891e-12, 5.1859074150534959e-11, 5.6202961151004291e-10, 5.2329996549801057e-09, 4.2048817138133669e-08, 2.9276307349429699e-07, 1.7725651070157471e-06, 9.3629045679147633e-06, 4.3270500380986358e-05, 1.7541290219541701e-04, 6.2518907824834233e-04, 1.9629978285824797e-03, 5.4395127563656737e-03, 1.3323152028369395e-02, 2.8883095437764291e-02, 5.5483794234023616e-02, 9.4533826153130718e-02, 1.4296854105472981e-01, 1.9203597399663150e-01, 2.2918990372570339e-01, 2.4310155924759538e-01, 2.2918990372570339e-01, 1.9203597399663150e-01, 1.4296854105472981e-01, 9.4533826153130718e-02, 5.5483794234023616e-02, 2.8883095437764291e-02, 1.3323152028369395e-02, 5.4395127563656737e-03, 1.9629978285824797e-03, 6.2518907824834233e-04, 1.7541290219541701e-04, 4.3270500380986358e-05, 9.3629045679147633e-06, 1.7725651070157471e-06, 2.9276307349429699e-07, 4.2048817138133669e-08, 5.2329996549801057e-09, 5.6202961151004291e-10, 5.1859074150534959e-11, 4.0903372275217891e-12, 2.7422533133249144e-13, 1.5527783781178122e-14, 7.3730974398680154e-16, 2.9120616998176371e-17, 9.4786222458398701e-19, 2.5158646274622071e-20, 5.3793647773372928e-22, 9.1354157424215784e-24, 1.2119297214386231e-25, 1.2315531785339706e-27, 9.3634938532685839e-30, 5.1761145427794598e-32, 2.0080025620200044e-34, 5.2269922366851146e-37, 8.6131947009295395e-40, 8.3074192361133957e-43, 4.2000954414179859e-46, 9.4366281490374702e-50, 7.1863132033979924e-54, 1.1086857074759456e-58, 9.3860543034002427e-65}, + {1.3777591125358009e-65, 1.7368921661372738e-59, 1.1897755678170730e-54, 1.6430818957997274e-50, 7.6682284731962107e-47, 1.5871807417910754e-43, 1.7196165366502119e-40, 1.0893693911932259e-37, 4.3652562606795252e-35, 1.1730726684546622e-32, 2.2113391943206024e-30, 3.0299940661257904e-28, 3.1056775475544893e-26, 2.4381144772606556e-24, 1.4951761449964922e-22, 7.2828478980006098e-21, 2.8579464976920660e-19, 9.1468094747747248e-18, 2.4130464210357486e-16, 5.2963672903976192e-15, 9.7511119835367196e-14, 1.5167942114683800e-12, 2.0061976506906991e-11, 2.2691700569827051e-10, 2.2060316533485200e-09, 1.8517359090727501e-08, 1.3475150826592070e-07, 8.5321092475315403e-07, 4.7158906386790063e-06, 2.2820419642920848e-05, 9.6932540256516268e-05, 3.6225322463531061e-04, 1.1935740511675038e-03, 3.4735556703184827e-03, 8.9429974621500780e-03, 2.0397690515966099e-02, 4.1265501456996284e-02, 7.4120627126827321e-02, 1.1830317740926892e-01, 1.6789719350811264e-01, 2.1197836082996782e-01, 2.3816651641238701e-01, 2.3816651641238701e-01, 2.1197836082996782e-01, 1.6789719350811264e-01, 1.1830317740926892e-01, 7.4120627126827321e-02, 4.1265501456996284e-02, 2.0397690515966099e-02, 8.9429974621500780e-03, 3.4735556703184827e-03, 1.1935740511675038e-03, 3.6225322463531061e-04, 9.6932540256516268e-05, 2.2820419642920848e-05, 4.7158906386790063e-06, 8.5321092475315403e-07, 1.3475150826592070e-07, 1.8517359090727501e-08, 2.2060316533485200e-09, 2.2691700569827051e-10, 2.0061976506906991e-11, 1.5167942114683800e-12, 9.7511119835367196e-14, 5.2963672903976192e-15, 2.4130464210357486e-16, 9.1468094747747248e-18, 2.8579464976920660e-19, 7.2828478980006098e-21, 1.4951761449964922e-22, 2.4381144772606556e-24, 3.1056775475544893e-26, 3.0299940661257904e-28, 2.2113391943206024e-30, 1.1730726684546622e-32, 4.3652562606795252e-35, 1.0893693911932259e-37, 1.7196165366502119e-40, 1.5871807417910754e-43, 7.6682284731962107e-47, 1.6430818957997274e-50, 1.1897755678170730e-54, 1.7368921661372738e-59, 1.3777591125358009e-65}, + {2.0210775781982523e-66, 2.7178104548553350e-60, 1.9665137729345701e-55, 2.8548162606098395e-51, 1.3964239783926081e-47, 3.0233321269411514e-44, 3.4214653414754691e-41, 2.2616501773134073e-38, 9.4491938966483701e-36, 2.6460383187052969e-33, 5.1955440071780227e-31, 7.4129920915228913e-29, 7.9104233673873923e-27, 6.4645977792616403e-25, 4.1267488231576369e-23, 2.0924604014548367e-21, 8.5484498659455372e-20, 2.8486537373202696e-18, 7.8262318929365957e-17, 1.7892942386135024e-15, 3.4323564970059177e-14, 5.5646126660265747e-13, 7.6736928514695270e-12, 9.0529279992180488e-11, 9.1835433159763121e-10, 8.0473976876877841e-09, 6.1165350599767583e-08, 4.0472265409701691e-07, 2.3390768958015489e-06, 1.1842716592385991e-05, 5.2665815424842040e-05, 2.0620794316657292e-04, 7.1235629871549161e-04, 2.1752890413369533e-03, 5.8813993717320096e-03, 1.4099847351552907e-02, 3.0009543309201085e-02, 5.6764441788522510e-02, 9.5510122550246740e-02, 1.4305030254196435e-01, 1.9082420376099704e-01, 2.2680511848210408e-01, 2.4024154090350588e-01, 2.2680511848210408e-01, 1.9082420376099704e-01, 1.4305030254196435e-01, 9.5510122550246740e-02, 5.6764441788522510e-02, 3.0009543309201085e-02, 1.4099847351552907e-02, 5.8813993717320096e-03, 2.1752890413369533e-03, 7.1235629871549161e-04, 2.0620794316657292e-04, 5.2665815424842040e-05, 1.1842716592385991e-05, 2.3390768958015489e-06, 4.0472265409701691e-07, 6.1165350599767583e-08, 8.0473976876877841e-09, 9.1835433159763121e-10, 9.0529279992180488e-11, 7.6736928514695270e-12, 5.5646126660265747e-13, 3.4323564970059177e-14, 1.7892942386135024e-15, 7.8262318929365957e-17, 2.8486537373202696e-18, 8.5484498659455372e-20, 2.0924604014548367e-21, 4.1267488231576369e-23, 6.4645977792616403e-25, 7.9104233673873923e-27, 7.4129920915228913e-29, 5.1955440071780227e-31, 2.6460383187052969e-33, 9.4491938966483701e-36, 2.2616501773134073e-38, 3.4214653414754691e-41, 3.0233321269411514e-44, 1.3964239783926081e-47, 2.8548162606098395e-51, 1.9665137729345701e-55, 2.7178104548553350e-60, 2.0210775781982523e-66}, + {2.9629045151469795e-67, 4.2477382853725514e-61, 3.2450153429194443e-56, 4.9498576868697659e-52, 2.5365833564005594e-48, 5.7421164166187080e-45, 6.7848084979774069e-42, 4.6777688454197694e-39, 2.0368541188744583e-36, 5.9410439274149082e-34, 1.2145487671367711e-31, 1.8036964134319502e-29, 2.0029387907481775e-27, 1.7031624106751895e-25, 1.1312252871807839e-23, 5.9680464287706203e-22, 2.5370441167173625e-20, 8.7983250076979868e-19, 2.5159793892190254e-17, 5.9885746170489713e-16, 1.1962793877597350e-14, 2.0202353514446467e-13, 2.9029728072990475e-12, 3.5699318546714651e-11, 3.7765043235634349e-10, 3.4525199163835126e-09, 2.7390187380396967e-08, 1.8926893464082190e-07, 1.1429783024859512e-06, 6.0502321414091725e-06, 2.8148083952665619e-05, 1.1537557343902387e-04, 4.1754273548549582e-04, 1.3367210462102556e-03, 3.7920023944900709e-03, 9.5461945478795308e-03, 2.1354422319535372e-02, 4.2493637239894133e-02, 7.5291446661321912e-02, 1.1887424153508566e-01, 1.6734591429857545e-01, 2.1014771223832399e-01, 2.3547615304001107e-01, 2.3547615304001107e-01, 2.1014771223832399e-01, 1.6734591429857545e-01, 1.1887424153508566e-01, 7.5291446661321912e-02, 4.2493637239894133e-02, 2.1354422319535372e-02, 9.5461945478795308e-03, 3.7920023944900709e-03, 1.3367210462102556e-03, 4.1754273548549582e-04, 1.1537557343902387e-04, 2.8148083952665619e-05, 6.0502321414091725e-06, 1.1429783024859512e-06, 1.8926893464082190e-07, 2.7390187380396967e-08, 3.4525199163835126e-09, 3.7765043235634349e-10, 3.5699318546714651e-11, 2.9029728072990475e-12, 2.0202353514446467e-13, 1.1962793877597350e-14, 5.9885746170489713e-16, 2.5159793892190254e-17, 8.7983250076979868e-19, 2.5370441167173625e-20, 5.9680464287706203e-22, 1.1312252871807839e-23, 1.7031624106751895e-25, 2.0029387907481775e-27, 1.8036964134319502e-29, 1.2145487671367711e-31, 5.9410439274149082e-34, 2.0368541188744583e-36, 4.6777688454197694e-39, 6.7848084979774069e-42, 5.7421164166187080e-45, 2.5365833564005594e-48, 4.9498576868697659e-52, 3.2450153429194443e-56, 4.2477382853725514e-61, 2.9629045151469795e-67}, + {4.3409286059314790e-68, 6.6312997992786490e-62, 5.3461191685641914e-57, 8.5648796438497824e-53, 4.5963493020491623e-49, 1.0874550734954457e-45, 1.3410304270363433e-42, 9.6394008578235831e-40, 4.3726474538903734e-37, 1.3279095802116780e-34, 2.8252406271755742e-32, 4.3652040547608271e-30, 5.0421784821017282e-28, 4.4592405404333692e-26, 3.0802364578690691e-24, 1.6900522980387141e-22, 7.4723281435460732e-21, 2.6954831586023608e-19, 8.0190167662890588e-18, 1.9861050466676079e-16, 4.1293419627929950e-15, 7.2600749267287114e-14, 1.0864518129258071e-12, 1.3919025655825987e-11, 1.5345768250281952e-10, 1.4627430245954727e-09, 1.2104826477830397e-08, 8.7294781098733113e-08, 5.5045426913594814e-07, 3.0442062696033981e-06, 1.4805735210956500e-05, 6.3482017172793501e-05, 2.4048437850905004e-04, 8.0646696699679095e-04, 2.3982976827574042e-03, 6.3343363657207474e-03, 1.4878611633370075e-02, 3.1116468918540825e-02, 5.7998096102851303e-02, 9.6425173608541109e-02, 1.4309010371318212e-01, 1.8962432993080802e-01, 2.2449250076685384e-01, 2.3748014388162669e-01, 2.2449250076685384e-01, 1.8962432993080802e-01, 1.4309010371318212e-01, 9.6425173608541109e-02, 5.7998096102851303e-02, 3.1116468918540825e-02, 1.4878611633370075e-02, 6.3343363657207474e-03, 2.3982976827574042e-03, 8.0646696699679095e-04, 2.4048437850905004e-04, 6.3482017172793501e-05, 1.4805735210956500e-05, 3.0442062696033981e-06, 5.5045426913594814e-07, 8.7294781098733113e-08, 1.2104826477830397e-08, 1.4627430245954727e-09, 1.5345768250281952e-10, 1.3919025655825987e-11, 1.0864518129258071e-12, 7.2600749267287114e-14, 4.1293419627929950e-15, 1.9861050466676079e-16, 8.0190167662890588e-18, 2.6954831586023608e-19, 7.4723281435460732e-21, 1.6900522980387141e-22, 3.0802364578690691e-24, 4.4592405404333692e-26, 5.0421784821017282e-28, 4.3652040547608271e-30, 2.8252406271755742e-32, 1.3279095802116780e-34, 4.3726474538903734e-37, 9.6394008578235831e-40, 1.3410304270363433e-42, 1.0874550734954457e-45, 4.5963493020491623e-49, 8.5648796438497824e-53, 5.3461191685641914e-57, 6.6312997992786490e-62, 4.3409286059314790e-68}, + {6.3559888804815291e-69, 1.0340740401651512e-62, 8.7937979910383930e-58, 1.4790458246095511e-53, 8.3086543388025186e-50, 2.0536646110581859e-46, 2.6420736294829820e-43, 1.9792151722732658e-40, 9.3494545988123451e-38, 2.9549868117171349e-35, 6.5403217012580441e-33, 1.0509161650154305e-30, 1.2621393343519558e-28, 1.1604245678013870e-26, 8.3325690961981494e-25, 4.7526132981917159e-23, 2.1844800072999790e-21, 8.1927992139953961e-20, 2.5344499212676499e-18, 6.5284978547093747e-17, 1.4120140414140493e-15, 2.5832194339375668e-14, 4.0236781196418743e-13, 5.3673492268073417e-12, 6.1636566122784830e-11, 6.1219783545440359e-10, 5.2813629715600939e-09, 3.9723156884506070e-08, 2.6137484697367874e-07, 1.5091682442228327e-06, 7.6676762452478550e-06, 3.4365246906918278e-05, 1.3616684443587397e-04, 4.7795191142819410e-04, 1.4887726540954260e-03, 4.1217965699966519e-03, 1.0156852342094170e-02, 2.2303298514796874e-02, 4.3688380057289714e-02, 7.6406289996198792e-02, 1.1939077299329898e-01, 1.6677771361921795e-01, 2.0836017261496417e-01, 2.3287490818454673e-01, 2.3287490818454673e-01, 2.0836017261496417e-01, 1.6677771361921795e-01, 1.1939077299329898e-01, 7.6406289996198792e-02, 4.3688380057289714e-02, 2.2303298514796874e-02, 1.0156852342094170e-02, 4.1217965699966519e-03, 1.4887726540954260e-03, 4.7795191142819410e-04, 1.3616684443587397e-04, 3.4365246906918278e-05, 7.6676762452478550e-06, 1.5091682442228327e-06, 2.6137484697367874e-07, 3.9723156884506070e-08, 5.2813629715600939e-09, 6.1219783545440359e-10, 6.1636566122784830e-11, 5.3673492268073417e-12, 4.0236781196418743e-13, 2.5832194339375668e-14, 1.4120140414140493e-15, 6.5284978547093747e-17, 2.5344499212676499e-18, 8.1927992139953961e-20, 2.1844800072999790e-21, 4.7526132981917159e-23, 8.3325690961981494e-25, 1.1604245678013870e-26, 1.2621393343519558e-28, 1.0509161650154305e-30, 6.5403217012580441e-33, 2.9549868117171349e-35, 9.3494545988123451e-38, 1.9792151722732658e-40, 2.6420736294829820e-43, 2.0536646110581859e-46, 8.3086543388025186e-50, 1.4790458246095511e-53, 8.7937979910383930e-58, 1.0340740401651512e-62, 6.3559888804815291e-69}, + {9.3008818390890492e-70, 1.6107424492415425e-63, 1.4442544724939497e-58, 2.5491245644508241e-54, 1.4983841626026885e-50, 3.8676878782479128e-47, 5.1890175350658309e-44, 4.0494895783343356e-41, 1.9912326515858821e-38, 6.5473365822875601e-36, 1.5069227943967880e-33, 2.5171173318424500e-31, 3.1418754018247846e-29, 3.0018077177700208e-27, 2.2397389074987337e-25, 1.3273883998725675e-23, 6.3398444713628853e-22, 2.4709662681137447e-20, 7.9447537335212530e-19, 2.1273958174343124e-17, 4.7841544346425597e-16, 9.1026391570176184e-15, 1.4750035153523922e-13, 2.0475389185298693e-12, 2.4477459246779186e-11, 2.5318768471063941e-10, 2.2756270244146732e-09, 1.7840153336747013e-08, 1.2241314031279016e-07, 7.3745467763804806e-07, 3.9114112665063118e-06, 1.8311113911126260e-05, 7.5833505293245319e-05, 2.7838967822704579e-04, 9.0756465037858196e-04, 2.6316863728237144e-03, 6.7973713273565750e-03, 1.5658123034423620e-02, 3.2203216875107243e-02, 5.9186084836389256e-02, 9.7282463095519897e-02, 1.4309158549116330e-01, 1.8843706331894564e-01, 2.2224852664936542e-01, 2.3481182765823758e-01, 2.2224852664936542e-01, 1.8843706331894564e-01, 1.4309158549116330e-01, 9.7282463095519897e-02, 5.9186084836389256e-02, 3.2203216875107243e-02, 1.5658123034423620e-02, 6.7973713273565750e-03, 2.6316863728237144e-03, 9.0756465037858196e-04, 2.7838967822704579e-04, 7.5833505293245319e-05, 1.8311113911126260e-05, 3.9114112665063118e-06, 7.3745467763804806e-07, 1.2241314031279016e-07, 1.7840153336747013e-08, 2.2756270244146732e-09, 2.5318768471063941e-10, 2.4477459246779186e-11, 2.0475389185298693e-12, 1.4750035153523922e-13, 9.1026391570176184e-15, 4.7841544346425597e-16, 2.1273958174343124e-17, 7.9447537335212530e-19, 2.4709662681137447e-20, 6.3398444713628853e-22, 1.3273883998725675e-23, 2.2397389074987337e-25, 3.0018077177700208e-27, 3.1418754018247846e-29, 2.5171173318424500e-31, 1.5069227943967880e-33, 6.5473365822875601e-36, 1.9912326515858821e-38, 4.0494895783343356e-41, 5.1890175350658309e-44, 3.8676878782479128e-47, 1.4983841626026885e-50, 2.5491245644508241e-54, 1.4442544724939497e-58, 1.6107424492415425e-63, 9.3008818390890492e-70}, + {1.3602242492354518e-70, 2.5062893896000025e-64, 2.3683907001837810e-59, 4.3849662998245842e-55, 2.6959438737993594e-51, 7.2644220875022382e-48, 1.0159844536444225e-44, 8.2566412936940675e-42, 4.2246144598021515e-39, 1.4445590039286314e-36, 3.4560072588078828e-34, 5.9987185516144465e-32, 7.7788491872908368e-30, 7.7199678213751262e-28, 5.9827510138490597e-26, 3.6826729053156295e-24, 1.8269179382831153e-22, 7.3963423583597857e-21, 2.4705505922880106e-19, 6.8737797990960140e-18, 1.6064742942702627e-16, 3.1773129599637848e-15, 5.3533724861984214e-14, 7.7293031086018118e-13, 9.6137828691596686e-12, 1.0350233726240316e-10, 9.6863849248805751e-10, 7.9104166149104796e-09, 5.6567852900930044e-08, 3.5533045829496680e-07, 1.9661408494659142e-06, 9.6077760741794566e-06, 4.1557921102543606e-05, 1.5944214368480690e-04, 5.4359224952962480e-04, 1.6496055361812409e-03, 4.4622998595035017e-03, 1.0773786624642434e-02, 2.3243228173755130e-02, 4.4849988132390606e-02, 7.7467627605512762e-02, 1.1985655590239072e-01, 1.6619497260995916e-01, 2.0661430370392464e-01, 2.3035797018194470e-01, 2.3035797018194470e-01, 2.0661430370392464e-01, 1.6619497260995916e-01, 1.1985655590239072e-01, 7.7467627605512762e-02, 4.4849988132390606e-02, 2.3243228173755130e-02, 1.0773786624642434e-02, 4.4622998595035017e-03, 1.6496055361812409e-03, 5.4359224952962480e-04, 1.5944214368480690e-04, 4.1557921102543606e-05, 9.6077760741794566e-06, 1.9661408494659142e-06, 3.5533045829496680e-07, 5.6567852900930044e-08, 7.9104166149104796e-09, 9.6863849248805751e-10, 1.0350233726240316e-10, 9.6137828691596686e-12, 7.7293031086018118e-13, 5.3533724861984214e-14, 3.1773129599637848e-15, 1.6064742942702627e-16, 6.8737797990960140e-18, 2.4705505922880106e-19, 7.3963423583597857e-21, 1.8269179382831153e-22, 3.6826729053156295e-24, 5.9827510138490597e-26, 7.7199678213751262e-28, 7.7788491872908368e-30, 5.9987185516144465e-32, 3.4560072588078828e-34, 1.4445590039286314e-36, 4.2246144598021515e-39, 8.2566412936940675e-42, 1.0159844536444225e-44, 7.2644220875022382e-48, 2.6959438737993594e-51, 4.3849662998245842e-55, 2.3683907001837810e-59, 2.5062893896000025e-64, 1.3602242492354518e-70}, + {1.9881401943823065e-71, 3.8956133082883524e-65, 3.8780907613890165e-60, 7.5287596024697438e-56, 4.8396443307633869e-52, 1.3608233728823463e-48, 1.9832504849666674e-45, 1.6777720088426207e-42, 8.9292665279968075e-40, 3.1739897948436054e-37, 7.8902747437194502e-35, 1.4225885948951900e-32, 1.9157413956045486e-30, 1.9741018729702676e-28, 1.5883597138828314e-26, 1.0150605078465530e-24, 5.2280336522983695e-23, 2.1976422794092572e-21, 7.6226000038011678e-20, 2.2026235762112506e-18, 5.3473142908729109e-17, 1.0988447789132501e-15, 1.9241100890740006e-14, 2.8879825636852583e-13, 3.7354214836948911e-12, 4.1834945759406555e-11, 4.0743696574618951e-10, 3.4640710439123456e-09, 2.5801094931709852e-08, 1.6888360171753998e-07, 9.7426112561417961e-07, 4.9661767693609960e-06, 2.2420154669404182e-05, 8.9832774694917811e-05, 3.2005763736769638e-04, 1.0156641399211783e-03, 2.8750919999992967e-03, 7.2695749936617917e-03, 1.6437166647437267e-02, 3.3269271876221002e-02, 6.0329758617287225e-02, 9.8085267668094472e-02, 1.4305806223178333e-01, 1.8726297375534309e-01, 2.2006990496442211e-01, 2.3223147790375134e-01, 2.2006990496442211e-01, 1.8726297375534309e-01, 1.4305806223178333e-01, 9.8085267668094472e-02, 6.0329758617287225e-02, 3.3269271876221002e-02, 1.6437166647437267e-02, 7.2695749936617917e-03, 2.8750919999992967e-03, 1.0156641399211783e-03, 3.2005763736769638e-04, 8.9832774694917811e-05, 2.2420154669404182e-05, 4.9661767693609960e-06, 9.7426112561417961e-07, 1.6888360171753998e-07, 2.5801094931709852e-08, 3.4640710439123456e-09, 4.0743696574618951e-10, 4.1834945759406555e-11, 3.7354214836948911e-12, 2.8879825636852583e-13, 1.9241100890740006e-14, 1.0988447789132501e-15, 5.3473142908729109e-17, 2.2026235762112506e-18, 7.6226000038011678e-20, 2.1976422794092572e-21, 5.2280336522983695e-23, 1.0150605078465530e-24, 1.5883597138828314e-26, 1.9741018729702676e-28, 1.9157413956045486e-30, 1.4225885948951900e-32, 7.8902747437194502e-35, 3.1739897948436054e-37, 8.9292665279968075e-40, 1.6777720088426207e-42, 1.9832504849666674e-45, 1.3608233728823463e-48, 4.8396443307633869e-52, 7.5287596024697438e-56, 3.8780907613890165e-60, 3.8956133082883524e-65, 1.9881401943823065e-71}, + {2.9042780793285192e-72, 6.0487911085991875e-66, 6.3408840552698421e-61, 1.2902630736739495e-56, 8.6686227081665284e-53, 2.5425883339495936e-49, 3.8599589978240019e-46, 3.3979613434850632e-43, 1.8803612804682350e-40, 6.9456401083003465e-38, 1.7934288277345599e-35, 3.3574581848271432e-33, 4.6935588729781351e-31, 5.0199340944280284e-29, 4.1917802591871942e-27, 2.7800091791127284e-25, 1.4859465721519723e-23, 6.4827357579899811e-22, 2.3339160328683892e-20, 7.0010683610304173e-19, 1.7647313333962599e-17, 3.7660828360044482e-16, 6.8501492079314778e-15, 1.0683188551398555e-13, 1.4362003723050719e-12, 1.6723593784919510e-11, 1.6940433392992703e-10, 1.4986355561051177e-09, 1.1619214278627516e-08, 7.9204993538763526e-08, 4.7607676418369897e-07, 2.5297850142327841e-06, 1.1912329247318932e-05, 4.9812715968551620e-05, 1.8533007239769129e-04, 6.1455372697219728e-04, 1.8190665842030779e-03, 4.8128687057527163e-03, 1.1395877807434502e-02, 2.4173252104118973e-02, 4.5978813889354229e-02, 7.8477839811903538e-02, 1.2027508931592504e-01, 1.6559981501591434e-01, 2.0490871177338488e-01, 2.2792088322788109e-01, 2.2792088322788109e-01, 2.0490871177338488e-01, 1.6559981501591434e-01, 1.2027508931592504e-01, 7.8477839811903538e-02, 4.5978813889354229e-02, 2.4173252104118973e-02, 1.1395877807434502e-02, 4.8128687057527163e-03, 1.8190665842030779e-03, 6.1455372697219728e-04, 1.8533007239769129e-04, 4.9812715968551620e-05, 1.1912329247318932e-05, 2.5297850142327841e-06, 4.7607676418369897e-07, 7.9204993538763526e-08, 1.1619214278627516e-08, 1.4986355561051177e-09, 1.6940433392992703e-10, 1.6723593784919510e-11, 1.4362003723050719e-12, 1.0683188551398555e-13, 6.8501492079314778e-15, 3.7660828360044482e-16, 1.7647313333962599e-17, 7.0010683610304173e-19, 2.3339160328683892e-20, 6.4827357579899811e-22, 1.4859465721519723e-23, 2.7800091791127284e-25, 4.1917802591871942e-27, 5.0199340944280284e-29, 4.6935588729781351e-31, 3.3574581848271432e-33, 1.7934288277345599e-35, 6.9456401083003465e-38, 1.8803612804682350e-40, 3.3979613434850632e-43, 3.8599589978240019e-46, 2.5425883339495936e-49, 8.6686227081665284e-53, 1.2902630736739495e-56, 6.3408840552698421e-61, 6.0487911085991875e-66, 2.9042780793285192e-72}, + {4.2402214052951246e-73, 9.3824834253827312e-67, 1.0352869434490524e-61, 2.2072219195734482e-57, 1.5493136809731731e-53, 4.7385536981365373e-50, 7.4907905142626159e-47, 6.8594377885386513e-44, 3.9454427601608861e-41, 1.5138792655234332e-38, 4.0587293642249081e-36, 7.8867039514681461e-34, 1.1440858552314813e-31, 1.2695564683626133e-29, 1.0997785424357608e-27, 7.5663389636387123e-26, 4.1954427268621758e-24, 1.8988470634740822e-22, 7.0927393378883720e-21, 2.2077343775414074e-19, 5.7754643743238307e-18, 1.2794126341282052e-16, 2.4162049041525693e-15, 3.9134647294064509e-14, 5.4654903154799270e-13, 6.6135809154494093e-12, 6.9642829049519196e-11, 6.4070330827294555e-10, 5.1680095336388813e-09, 3.6666857282366239e-08, 2.2949550926387024e-07, 1.2704896429597333e-06, 6.2359369667152816e-06, 2.7195889773576724e-05, 1.0558960284417518e-04, 3.6560795714255136e-04, 1.1307532404246092e-03, 3.1281305245610394e-03, 7.7500451541012766e-03, 1.7214629493700298e-02, 3.4314242859408567e-02, 6.1430478646654310e-02, 9.8836668138780004e-02, 1.4299255414069270e-01, 1.8610251044108347e-01, 2.1795355826999802e-01, 2.2973436523811983e-01, 2.1795355826999802e-01, 1.8610251044108347e-01, 1.4299255414069270e-01, 9.8836668138780004e-02, 6.1430478646654310e-02, 3.4314242859408567e-02, 1.7214629493700298e-02, 7.7500451541012766e-03, 3.1281305245610394e-03, 1.1307532404246092e-03, 3.6560795714255136e-04, 1.0558960284417518e-04, 2.7195889773576724e-05, 6.2359369667152816e-06, 1.2704896429597333e-06, 2.2949550926387024e-07, 3.6666857282366239e-08, 5.1680095336388813e-09, 6.4070330827294555e-10, 6.9642829049519196e-11, 6.6135809154494093e-12, 5.4654903154799270e-13, 3.9134647294064509e-14, 2.4162049041525693e-15, 1.2794126341282052e-16, 5.7754643743238307e-18, 2.2077343775414074e-19, 7.0927393378883720e-21, 1.8988470634740822e-22, 4.1954427268621758e-24, 7.5663389636387123e-26, 1.0997785424357608e-27, 1.2695564683626133e-29, 1.1440858552314813e-31, 7.8867039514681461e-34, 4.0587293642249081e-36, 1.5138792655234332e-38, 3.9454427601608861e-41, 6.8594377885386513e-44, 7.4907905142626159e-47, 4.7385536981365373e-50, 1.5493136809731731e-53, 2.2072219195734482e-57, 1.0352869434490524e-61, 9.3824834253827312e-67, 4.2402214052951246e-73}, + {6.1873167292600330e-74, 1.4538901947049863e-67, 1.6879603995600424e-62, 3.7691324369200321e-58, 2.7631164912569130e-54, 8.8091139694466722e-51, 1.4495623366344723e-47, 1.3802919462863240e-44, 8.2491698349502409e-42, 3.2868281039958480e-39, 9.1463558192668670e-37, 1.8440635697521863e-34, 2.7749265480534503e-32, 3.1936039953280896e-30, 2.8689474946571079e-28, 2.0467667970915599e-26, 1.1768586219954579e-24, 5.5235547418541776e-23, 2.1397391826730893e-21, 6.9081875027574077e-20, 1.8747446593629021e-18, 4.3090894092529427e-17, 8.4454653993109795e-16, 1.4199548095965024e-14, 2.0591425994119171e-13, 2.5880423909347226e-12, 2.8316127909785268e-11, 2.7076622359247714e-10, 2.2709635043178179e-09, 1.6760660123885240e-08, 1.0917307724251056e-07, 6.2927723529831787e-07, 3.2175123782368650e-06, 1.4625147457368242e-05, 5.9216205461426278e-05, 2.1395132199714689e-04, 6.9090534092963924e-04, 1.9969762869401319e-03, 5.1728592008298650e-03, 1.2022070950665343e-02, 2.5092532015162070e-02, 4.7075288211797156e-02, 7.9439215172105435e-02, 1.2064961060726002e-01, 1.6499413655200360e-01, 2.0324204888941669e-01, 2.2555951425452636e-01, 2.2555951425452636e-01, 2.0324204888941669e-01, 1.6499413655200360e-01, 1.2064961060726002e-01, 7.9439215172105435e-02, 4.7075288211797156e-02, 2.5092532015162070e-02, 1.2022070950665343e-02, 5.1728592008298650e-03, 1.9969762869401319e-03, 6.9090534092963924e-04, 2.1395132199714689e-04, 5.9216205461426278e-05, 1.4625147457368242e-05, 3.2175123782368650e-06, 6.2927723529831787e-07, 1.0917307724251056e-07, 1.6760660123885240e-08, 2.2709635043178179e-09, 2.7076622359247714e-10, 2.8316127909785268e-11, 2.5880423909347226e-12, 2.0591425994119171e-13, 1.4199548095965024e-14, 8.4454653993109795e-16, 4.3090894092529427e-17, 1.8747446593629021e-18, 6.9081875027574077e-20, 2.1397391826730893e-21, 5.5235547418541776e-23, 1.1768586219954579e-24, 2.0467667970915599e-26, 2.8689474946571079e-28, 3.1936039953280896e-30, 2.7749265480534503e-32, 1.8440635697521863e-34, 9.1463558192668670e-37, 3.2868281039958480e-39, 8.2491698349502409e-42, 1.3802919462863240e-44, 1.4495623366344723e-47, 8.8091139694466722e-51, 2.7631164912569130e-54, 3.7691324369200321e-58, 1.6879603995600424e-62, 1.4538901947049863e-67, 6.1873167292600330e-74}, + {9.0236831042710006e-75, 2.2507013266634397e-68, 2.7483088481763178e-63, 6.4250837772781210e-59, 4.9175305451785707e-55, 1.6336381889925197e-51, 2.7972683193869001e-48, 2.7688066162395138e-45, 1.7187588390664908e-42, 7.1089100355543671e-40, 2.0525562261562526e-37, 4.2923202100065188e-35, 6.6976892723501377e-33, 7.9915865248767542e-31, 7.4422174735850754e-29, 5.5036367600342068e-27, 3.2802180350829561e-25, 1.5959112775571386e-23, 6.4090652642750824e-22, 2.1453091893671746e-20, 6.0370235645633800e-19, 1.4391241588665120e-17, 2.9258946262067771e-16, 5.1042859875473367e-15, 7.6822356519145676e-14, 1.0023990331996466e-12, 1.1389647007504889e-11, 1.1314327929338598e-10, 9.8619913092006371e-10, 7.5672777489105014e-09, 5.1267694307391355e-08, 3.0750156860401326e-07, 1.6368618884967503e-06, 7.7499739996840847e-06, 3.2702654980222023e-05, 1.2321031502033358e-04, 4.1514601828721595e-04, 1.2527946608682095e-03, 3.3904013872216063e-03, 8.2379096963313674e-03, 1.7989495266934163e-02, 3.5337848644927512e-02, 6.2489606495141174e-02, 9.9539560539641095e-02, 1.4289781614596173e-01, 1.8495601933162914e-01, 2.1589660563060412e-01, 2.2731610876192898e-01, 2.1589660563060412e-01, 1.8495601933162914e-01, 1.4289781614596173e-01, 9.9539560539641095e-02, 6.2489606495141174e-02, 3.5337848644927512e-02, 1.7989495266934163e-02, 8.2379096963313674e-03, 3.3904013872216063e-03, 1.2527946608682095e-03, 4.1514601828721595e-04, 1.2321031502033358e-04, 3.2702654980222023e-05, 7.7499739996840847e-06, 1.6368618884967503e-06, 3.0750156860401326e-07, 5.1267694307391355e-08, 7.5672777489105014e-09, 9.8619913092006371e-10, 1.1314327929338598e-10, 1.1389647007504889e-11, 1.0023990331996466e-12, 7.6822356519145676e-14, 5.1042859875473367e-15, 2.9258946262067771e-16, 1.4391241588665120e-17, 6.0370235645633800e-19, 2.1453091893671746e-20, 6.4090652642750824e-22, 1.5959112775571386e-23, 3.2802180350829561e-25, 5.5036367600342068e-27, 7.4422174735850754e-29, 7.9915865248767542e-31, 6.6976892723501377e-33, 4.2923202100065188e-35, 2.0525562261562526e-37, 7.1089100355543671e-40, 1.7187588390664908e-42, 2.7688066162395138e-45, 2.7972683193869001e-48, 1.6336381889925197e-51, 4.9175305451785707e-55, 6.4250837772781210e-59, 2.7483088481763178e-63, 2.2507013266634397e-68, 9.0236831042710006e-75}, + {1.3153371477011018e-75, 3.4808413877180985e-69, 4.4687024216810169e-64, 1.0933824737518103e-59, 8.7337328359193298e-56, 3.0222939315022155e-52, 5.3832225069701608e-49, 5.5370648197825761e-46, 3.5689385617810602e-43, 1.5317989647111863e-40, 4.5874016658583215e-38, 9.9468000592214207e-36, 1.6088732079384737e-33, 1.9895468942695488e-31, 1.9199707067949033e-29, 1.4712415549741861e-27, 9.0859656470487372e-26, 4.5806010985499422e-24, 1.9062601886875492e-22, 6.6129511764811165e-21, 1.9288793268371580e-19, 4.7668311711866824e-18, 1.0049051491574811e-16, 1.8181691304932292e-15, 2.8387673951693530e-14, 3.8436817248766534e-13, 4.5333033745839362e-12, 4.6760103859850812e-11, 4.2335937835110236e-10, 3.3755847311277282e-09, 2.3773662147574315e-08, 1.4829694050050112e-07, 8.2135445478328264e-07, 4.0482331787772522e-06, 1.7791805918220274e-05, 6.9854324445415533e-05, 2.4541809273052672e-04, 7.7269582168165273e-04, 2.1831319760967165e-03, 5.5416312894389780e-03, 1.2651375112800185e-02, 2.6000340271244451e-02, 4.8139906731089997e-02, 8.0353950080642028e-02, 1.2098311686251535e-01, 1.6437963059849708e-01, 2.0161301347923419e-01, 2.2327002349753469e-01, 2.2327002349753469e-01, 2.0161301347923419e-01, 1.6437963059849708e-01, 1.2098311686251535e-01, 8.0353950080642028e-02, 4.8139906731089997e-02, 2.6000340271244451e-02, 1.2651375112800185e-02, 5.5416312894389780e-03, 2.1831319760967165e-03, 7.7269582168165273e-04, 2.4541809273052672e-04, 6.9854324445415533e-05, 1.7791805918220274e-05, 4.0482331787772522e-06, 8.2135445478328264e-07, 1.4829694050050112e-07, 2.3773662147574315e-08, 3.3755847311277282e-09, 4.2335937835110236e-10, 4.6760103859850812e-11, 4.5333033745839362e-12, 3.8436817248766534e-13, 2.8387673951693530e-14, 1.8181691304932292e-15, 1.0049051491574811e-16, 4.7668311711866824e-18, 1.9288793268371580e-19, 6.6129511764811165e-21, 1.9062601886875492e-22, 4.5806010985499422e-24, 9.0859656470487372e-26, 1.4712415549741861e-27, 1.9199707067949033e-29, 1.9895468942695488e-31, 1.6088732079384737e-33, 9.9468000592214207e-36, 4.5874016658583215e-38, 1.5317989647111863e-40, 3.5689385617810602e-43, 5.5370648197825761e-46, 5.3832225069701608e-49, 3.0222939315022155e-52, 8.7337328359193298e-56, 1.0933824737518103e-59, 4.4687024216810169e-64, 3.4808413877180985e-69, 1.3153371477011018e-75}, + {1.9163113126364858e-76, 5.3782147987051925e-70, 7.2563879227687952e-65, 1.8575257861979059e-60, 1.5480113585024239e-56, 5.5781996438680938e-53, 1.0331986095466757e-49, 1.1039698088171895e-46, 7.3860282667906572e-44, 3.2885519707581838e-41, 1.0211695752712912e-38, 2.2950262940501390e-36, 3.8466556677503065e-34, 4.9282126606183490e-32, 4.9266058774066898e-30, 3.9104187247799965e-28, 2.5014139383687256e-26, 1.3062311410367629e-24, 5.6310279110780034e-23, 2.0237140711644305e-21, 6.1159230112779824e-20, 1.5662392354042098e-18, 3.4222031640236014e-17, 6.4188994417848841e-16, 1.0392178377829332e-14, 1.4594559933116930e-13, 1.7858814626910534e-12, 1.9118156866346926e-11, 1.7970567599571068e-10, 1.4881403983681883e-09, 1.0889411432936255e-08, 7.0605103886976605e-08, 4.0665248009122635e-07, 2.0852201445349388e-06, 9.5392954689367993e-06, 3.9005661581998708e-05, 1.4279713128781597e-04, 4.6876282593032669e-04, 1.3817279615374414e-03, 3.6614915226082989e-03, 8.7323289056329013e-03, 1.8760838951499537e-02, 3.6339904964249992e-02, 6.3508495757082825e-02, 1.0019666687230201e-01, 1.4277636364566415e-01, 1.8382375801093334e-01, 2.1389634702935822e-01, 2.2497264372314615e-01, 2.1389634702935822e-01, 1.8382375801093334e-01, 1.4277636364566415e-01, 1.0019666687230201e-01, 6.3508495757082825e-02, 3.6339904964249992e-02, 1.8760838951499537e-02, 8.7323289056329013e-03, 3.6614915226082989e-03, 1.3817279615374414e-03, 4.6876282593032669e-04, 1.4279713128781597e-04, 3.9005661581998708e-05, 9.5392954689367993e-06, 2.0852201445349388e-06, 4.0665248009122635e-07, 7.0605103886976605e-08, 1.0889411432936255e-08, 1.4881403983681883e-09, 1.7970567599571068e-10, 1.9118156866346926e-11, 1.7858814626910534e-12, 1.4594559933116930e-13, 1.0392178377829332e-14, 6.4188994417848841e-16, 3.4222031640236014e-17, 1.5662392354042098e-18, 6.1159230112779824e-20, 2.0237140711644305e-21, 5.6310279110780034e-23, 1.3062311410367629e-24, 2.5014139383687256e-26, 3.9104187247799965e-28, 4.9266058774066898e-30, 4.9282126606183490e-32, 3.8466556677503065e-34, 2.2950262940501390e-36, 1.0211695752712912e-38, 3.2885519707581838e-41, 7.3860282667906572e-44, 1.1039698088171895e-46, 1.0331986095466757e-49, 5.5781996438680938e-53, 1.5480113585024239e-56, 1.8575257861979059e-60, 7.2563879227687952e-65, 5.3782147987051925e-70, 1.9163113126364858e-76}, + {2.7904525118679737e-77, 8.3020782212471425e-71, 1.1767736856636937e-65, 3.1505048454950654e-61, 2.7383297861245024e-57, 1.0271804264134620e-53, 1.9777901946758928e-50, 2.1945724897613748e-47, 1.5235549200899557e-44, 7.0346474438870195e-42, 2.2642373940609524e-39, 5.2728051887223330e-37, 9.1548141716730934e-35, 1.2147369169275739e-32, 1.2575027798926635e-30, 1.0335182999889521e-28, 6.8454256421150675e-27, 3.7013456293648089e-25, 1.6522412624655730e-23, 6.1491894101104838e-22, 1.9247067870562822e-20, 5.1057396537975428e-19, 1.1557955215269003e-17, 2.2464616952811288e-16, 3.7697131696054083e-15, 5.4886703549372233e-14, 6.9650658814205409e-13, 7.7347769030963229e-12, 7.5445969018975008e-11, 6.4855152005816811e-10, 4.9282840753506927e-09, 3.3196572232173258e-08, 1.9871572271899896e-07, 1.0595200143943266e-06, 5.0423148877264742e-06, 2.1459377904439359e-05, 8.1811800690556602e-05, 2.7983364446273394e-04, 8.5995448443042602e-04, 2.3773109222215024e-03, 5.9185523609855805e-03, 1.3282862169963864e-02, 2.6896050260216100e-02, 4.9173217905643024e-02, 8.1224149327040002e-02, 1.2127838443962285e-01, 1.6375781072963536e-01, 2.0002035034474053e-01, 2.2104883827723254e-01, 2.2104883827723254e-01, 2.0002035034474053e-01, 1.6375781072963536e-01, 1.2127838443962285e-01, 8.1224149327040002e-02, 4.9173217905643024e-02, 2.6896050260216100e-02, 1.3282862169963864e-02, 5.9185523609855805e-03, 2.3773109222215024e-03, 8.5995448443042602e-04, 2.7983364446273394e-04, 8.1811800690556602e-05, 2.1459377904439359e-05, 5.0423148877264742e-06, 1.0595200143943266e-06, 1.9871572271899896e-07, 3.3196572232173258e-08, 4.9282840753506927e-09, 6.4855152005816811e-10, 7.5445969018975008e-11, 7.7347769030963229e-12, 6.9650658814205409e-13, 5.4886703549372233e-14, 3.7697131696054083e-15, 2.2464616952811288e-16, 1.1557955215269003e-17, 5.1057396537975428e-19, 1.9247067870562822e-20, 6.1491894101104838e-22, 1.6522412624655730e-23, 3.7013456293648089e-25, 6.8454256421150675e-27, 1.0335182999889521e-28, 1.2575027798926635e-30, 1.2147369169275739e-32, 9.1548141716730934e-35, 5.2728051887223330e-37, 2.2642373940609524e-39, 7.0346474438870195e-42, 1.5235549200899557e-44, 2.1945724897613748e-47, 1.9777901946758928e-50, 1.0271804264134620e-53, 2.7383297861245024e-57, 3.1505048454950654e-61, 1.1767736856636937e-65, 8.3020782212471425e-71, 2.7904525118679737e-77}, + {4.0613138578260408e-78, 1.2803753168202646e-71, 1.9059379634157273e-66, 5.3348322229477923e-62, 4.8344851717020582e-58, 1.8871785659984032e-54, 3.7761789448607101e-51, 4.3499235924727088e-48, 3.1326162048099509e-45, 1.4994923130410846e-42, 5.0011700959096005e-40, 1.2063719426097628e-37, 2.1689987827926264e-35, 2.9797144315839396e-33, 3.1931805290733206e-31, 2.7165497805935431e-29, 1.8623802130980743e-27, 1.0423117478273709e-25, 4.8161473163605573e-24, 1.8555204994489541e-22, 6.0128622969968872e-21, 1.6515980171005252e-19, 3.8719360930637078e-18, 7.7952821069111630e-17, 1.3552585228326797e-15, 2.0448819688025393e-14, 2.6898645575023506e-13, 3.0973073233390342e-12, 3.1335844312742886e-11, 2.7949011969950757e-10, 2.2044098210910168e-09, 1.5418168139637173e-08, 9.5872357774191023e-08, 5.3122836336339743e-07, 2.6285303500427774e-06, 1.1636493707975660e-05, 4.6170574104968263e-05, 1.6444759671629532e-04, 5.2653510513586970e-04, 1.5174715210062894e-03, 3.9409789851024037e-03, 9.2324971205438137e-03, 1.9527821414966836e-02, 3.7320312768871315e-02, 6.4488485276268173e-02, 1.0081054546716739e-01, 1.4263049549711082e-01, 1.8270590844100287e-01, 2.1195024923496616e-01, 2.2270019277644792e-01, 2.1195024923496616e-01, 1.8270590844100287e-01, 1.4263049549711082e-01, 1.0081054546716739e-01, 6.4488485276268173e-02, 3.7320312768871315e-02, 1.9527821414966836e-02, 9.2324971205438137e-03, 3.9409789851024037e-03, 1.5174715210062894e-03, 5.2653510513586970e-04, 1.6444759671629532e-04, 4.6170574104968263e-05, 1.1636493707975660e-05, 2.6285303500427774e-06, 5.3122836336339743e-07, 9.5872357774191023e-08, 1.5418168139637173e-08, 2.2044098210910168e-09, 2.7949011969950757e-10, 3.1335844312742886e-11, 3.0973073233390342e-12, 2.6898645575023506e-13, 2.0448819688025393e-14, 1.3552585228326797e-15, 7.7952821069111630e-17, 3.8719360930637078e-18, 1.6515980171005252e-19, 6.0128622969968872e-21, 1.8555204994489541e-22, 4.8161473163605573e-24, 1.0423117478273709e-25, 1.8623802130980743e-27, 2.7165497805935431e-29, 3.1931805290733206e-31, 2.9797144315839396e-33, 2.1689987827926264e-35, 1.2063719426097628e-37, 5.0011700959096005e-40, 1.4994923130410846e-42, 3.1326162048099509e-45, 4.3499235924727088e-48, 3.7761789448607101e-51, 1.8871785659984032e-54, 4.8344851717020582e-58, 5.3348322229477923e-62, 1.9059379634157273e-66, 1.2803753168202646e-71, 4.0613138578260408e-78}, + {5.9080678650312624e-79, 1.9728605748792453e-72, 3.0830289900033436e-67, 9.0192223036937046e-63, 8.5188830817618133e-59, 3.4594779364755318e-55, 7.1915294634635365e-52, 8.5975639548257647e-49, 6.4207252053484628e-46, 3.1852178778360094e-43, 1.1004706827142279e-40, 2.7487848843571218e-38, 5.1162326043852910e-36, 7.2745725968876294e-34, 8.0674342787094055e-32, 7.1018122263849361e-30, 5.0377911662132328e-28, 2.9173500726293596e-26, 1.3948415260687786e-24, 5.5610269616591533e-23, 1.8649976751302685e-21, 5.3023161831319081e-20, 1.2868329211211647e-18, 2.6824921647604057e-17, 4.8298353217030778e-16, 7.5488968779152708e-15, 1.0288749373509957e-13, 1.2278785144101270e-12, 1.2879038257315668e-11, 1.1913006349290762e-10, 9.7479212538717177e-10, 7.0758572838895756e-09, 4.5681275084849536e-08, 2.6290974837537234e-07, 1.3517971591103712e-06, 6.2215248177778678e-06, 2.5676159384549134e-05, 9.5171627785509925e-05, 3.1729197104330006e-04, 9.5269218854862072e-04, 2.5792732600590893e-03, 6.3030002856080628e-03, 1.3915665220231790e-02, 2.7779127385933564e-02, 5.0175812677428613e-02, 8.2051827391224449e-02, 1.2153798684410418e-01, 1.6313003050278282e-01, 1.9846285025418653e-01, 2.1889262958743932e-01, 2.1889262958743932e-01, 1.9846285025418653e-01, 1.6313003050278282e-01, 1.2153798684410418e-01, 8.2051827391224449e-02, 5.0175812677428613e-02, 2.7779127385933564e-02, 1.3915665220231790e-02, 6.3030002856080628e-03, 2.5792732600590893e-03, 9.5269218854862072e-04, 3.1729197104330006e-04, 9.5171627785509925e-05, 2.5676159384549134e-05, 6.2215248177778678e-06, 1.3517971591103712e-06, 2.6290974837537234e-07, 4.5681275084849536e-08, 7.0758572838895756e-09, 9.7479212538717177e-10, 1.1913006349290762e-10, 1.2879038257315668e-11, 1.2278785144101270e-12, 1.0288749373509957e-13, 7.5488968779152708e-15, 4.8298353217030778e-16, 2.6824921647604057e-17, 1.2868329211211647e-18, 5.3023161831319081e-20, 1.8649976751302685e-21, 5.5610269616591533e-23, 1.3948415260687786e-24, 2.9173500726293596e-26, 5.0377911662132328e-28, 7.1018122263849361e-30, 8.0674342787094055e-32, 7.2745725968876294e-34, 5.1162326043852910e-36, 2.7487848843571218e-38, 1.1004706827142279e-40, 3.1852178778360094e-43, 6.4207252053484628e-46, 8.5975639548257647e-49, 7.1915294634635365e-52, 3.4594779364755318e-55, 8.5188830817618133e-59, 9.0192223036937046e-63, 3.0830289900033436e-67, 1.9728605748792453e-72, 5.9080678650312624e-79}, + {8.5904309894818364e-80, 3.0371816846686698e-73, 4.9809124279561082e-68, 1.5224294774877133e-63, 1.4982961830544962e-59, 6.3278572616256388e-56, 1.3661743924144741e-52, 1.6945475116309319e-49, 1.3119398711365523e-46, 6.7430272036894988e-44, 2.4125325785224105e-41, 6.2381218594744620e-39, 1.2015973481338649e-36, 1.7677477939830743e-34, 2.0280915379277212e-32, 1.8467949790116279e-30, 1.3550808933459723e-28, 8.1168066229507355e-27, 4.0142573977672800e-25, 1.6555633107937502e-23, 5.7440707561477782e-22, 1.6897039658922656e-20, 4.2436086794049572e-19, 9.1557867438886624e-18, 1.7065546359370669e-16, 2.7618433228960722e-15, 3.8986379094133088e-14, 4.8201156943039955e-13, 5.2391878407492571e-12, 5.0236198872007664e-11, 4.2625383198445261e-10, 3.2096074629923419e-09, 2.1502703382505708e-08, 1.2847504869574726e-07, 6.8606640833299067e-07, 3.2808733242412502e-06, 1.4075589850899586e-05, 5.4263099453546539e-05, 1.8825409449540776e-04, 5.8852552673756763e-04, 1.6599244925103198e-03, 4.2284362004214454e-03, 9.7376438372710882e-03, 2.0289684052787870e-02, 3.8279047715437671e-02, 6.5430893699439191e-02, 1.0138360090162955e-01, 1.4246231456883673e-01, 1.8160258790817957e-01, 2.1005593297000114e-01, 2.2049524037272045e-01, 2.1005593297000114e-01, 1.8160258790817957e-01, 1.4246231456883673e-01, 1.0138360090162955e-01, 6.5430893699439191e-02, 3.8279047715437671e-02, 2.0289684052787870e-02, 9.7376438372710882e-03, 4.2284362004214454e-03, 1.6599244925103198e-03, 5.8852552673756763e-04, 1.8825409449540776e-04, 5.4263099453546539e-05, 1.4075589850899586e-05, 3.2808733242412502e-06, 6.8606640833299067e-07, 1.2847504869574726e-07, 2.1502703382505708e-08, 3.2096074629923419e-09, 4.2625383198445261e-10, 5.0236198872007664e-11, 5.2391878407492571e-12, 4.8201156943039955e-13, 3.8986379094133088e-14, 2.7618433228960722e-15, 1.7065546359370669e-16, 9.1557867438886624e-18, 4.2436086794049572e-19, 1.6897039658922656e-20, 5.7440707561477782e-22, 1.6555633107937502e-23, 4.0142573977672800e-25, 8.1168066229507355e-27, 1.3550808933459723e-28, 1.8467949790116279e-30, 2.0280915379277212e-32, 1.7677477939830743e-34, 1.2015973481338649e-36, 6.2381218594744620e-39, 2.4125325785224105e-41, 6.7430272036894988e-44, 1.3119398711365523e-46, 1.6945475116309319e-49, 1.3661743924144741e-52, 6.3278572616256388e-56, 1.4982961830544962e-59, 1.5224294774877133e-63, 4.9809124279561082e-68, 3.0371816846686698e-73, 8.5904309894818364e-80}, + {1.2484709934169793e-80, 4.6716134267455262e-74, 8.0373302337190505e-69, 2.5658825214250866e-64, 2.6303256479665557e-60, 1.1549629962198519e-56, 2.5889667003232748e-53, 3.3307225187898004e-50, 2.6725211308631837e-47, 1.4227172891228852e-44, 5.2696956176078606e-42, 1.4101103127648418e-39, 2.8100935042395224e-37, 4.2761357132188511e-35, 5.0736585413756089e-33, 4.7776103023740991e-31, 3.6248608340202214e-29, 2.2451158851842135e-27, 1.1481416337131872e-25, 4.8966201179064703e-24, 1.7569837815084929e-22, 5.3457088341630912e-21, 1.3887935290404047e-19, 3.1001141967930157e-18, 5.9794936879871788e-17, 1.0016087747850758e-15, 1.4637583603666311e-14, 1.8740601774404304e-13, 2.1099943426302045e-12, 2.0963143669741310e-11, 1.8436168972317116e-10, 1.4393514257953216e-09, 1.0001836240436016e-08, 6.2007747893151711e-08, 3.4372586316527799e-07, 1.7070358456037084e-06, 7.6089581259975007e-06, 3.0491388427439179e-05, 1.1001458276280751e-04, 3.5787758856259302e-04, 1.0509023763580526e-03, 2.7887647298672400e-03, 6.6943659482095498e-03, 1.4548976670515633e-02, 2.8649120680685196e-02, 5.1148315515202297e-02, 8.2838910302204208e-02, 1.2176431106358794e-01, 1.6249750087283824e-01, 1.9693934921359804e-01, 2.1679829114353039e-01, 2.1679829114353039e-01, 1.9693934921359804e-01, 1.6249750087283824e-01, 1.2176431106358794e-01, 8.2838910302204208e-02, 5.1148315515202297e-02, 2.8649120680685196e-02, 1.4548976670515633e-02, 6.6943659482095498e-03, 2.7887647298672400e-03, 1.0509023763580526e-03, 3.5787758856259302e-04, 1.1001458276280751e-04, 3.0491388427439179e-05, 7.6089581259975007e-06, 1.7070358456037084e-06, 3.4372586316527799e-07, 6.2007747893151711e-08, 1.0001836240436016e-08, 1.4393514257953216e-09, 1.8436168972317116e-10, 2.0963143669741310e-11, 2.1099943426302045e-12, 1.8740601774404304e-13, 1.4637583603666311e-14, 1.0016087747850758e-15, 5.9794936879871788e-17, 3.1001141967930157e-18, 1.3887935290404047e-19, 5.3457088341630912e-21, 1.7569837815084929e-22, 4.8966201179064703e-24, 1.1481416337131872e-25, 2.2451158851842135e-27, 3.6248608340202214e-29, 4.7776103023740991e-31, 5.0736585413756089e-33, 4.2761357132188511e-35, 2.8100935042395224e-37, 1.4101103127648418e-39, 5.2696956176078606e-42, 1.4227172891228852e-44, 2.6725211308631837e-47, 3.3307225187898004e-50, 2.5889667003232748e-53, 1.1549629962198519e-56, 2.6303256479665557e-60, 2.5658825214250866e-64, 8.0373302337190505e-69, 4.6716134267455262e-74, 1.2484709934169793e-80}, + {1.8135909934565948e-81, 7.1794482518779405e-75, 1.2953741930788741e-69, 4.3179663130756179e-65, 4.6092689309993016e-61, 2.1035897073764635e-57, 4.8944169739176386e-54, 6.5290610509647759e-51, 5.4278702104818919e-48, 2.9919651066058538e-45, 1.1469498354442222e-42, 3.1751925459280292e-40, 6.5444038132328712e-38, 1.0297652702618718e-35, 1.2632131984833186e-33, 1.2296697906080111e-31, 9.6441699135755975e-30, 6.1744578340056585e-28, 3.2639881507273933e-26, 1.4390083206149803e-24, 5.3380455822882838e-23, 1.6792427517695717e-21, 4.5112507797362053e-20, 1.0414929706906582e-18, 2.0779783402868767e-17, 3.6013157967372950e-16, 5.4464951383584157e-15, 7.2181098533397167e-14, 8.4145383929577368e-13, 8.6584557144940455e-12, 7.8890516800983647e-11, 6.3831524130277722e-10, 4.5984942968861874e-09, 2.9567316716160832e-08, 1.7005133441347446e-07, 8.7658428229201604e-07, 4.0574245645905015e-06, 1.6891865749199694e-05, 6.3348592408607267e-05, 2.1430344005210969e-04, 6.5478304395432502e-04, 1.8089687249743006e-03, 4.5234328605134695e-03, 1.0247034345774014e-02, 2.1045743544451385e-02, 3.9216150726808105e-02, 6.6337015149646864e-02, 1.0191809344727074e-01, 1.4227374613665661e-01, 1.8051385843527265e-01, 2.0821116124461711e-01, 2.1835450988366478e-01, 2.0821116124461711e-01, 1.8051385843527265e-01, 1.4227374613665661e-01, 1.0191809344727074e-01, 6.6337015149646864e-02, 3.9216150726808105e-02, 2.1045743544451385e-02, 1.0247034345774014e-02, 4.5234328605134695e-03, 1.8089687249743006e-03, 6.5478304395432502e-04, 2.1430344005210969e-04, 6.3348592408607267e-05, 1.6891865749199694e-05, 4.0574245645905015e-06, 8.7658428229201604e-07, 1.7005133441347446e-07, 2.9567316716160832e-08, 4.5984942968861874e-09, 6.3831524130277722e-10, 7.8890516800983647e-11, 8.6584557144940455e-12, 8.4145383929577368e-13, 7.2181098533397167e-14, 5.4464951383584157e-15, 3.6013157967372950e-16, 2.0779783402868767e-17, 1.0414929706906582e-18, 4.5112507797362053e-20, 1.6792427517695717e-21, 5.3380455822882838e-23, 1.4390083206149803e-24, 3.2639881507273933e-26, 6.1744578340056585e-28, 9.6441699135755975e-30, 1.2296697906080111e-31, 1.2632131984833186e-33, 1.0297652702618718e-35, 6.5444038132328712e-38, 3.1751925459280292e-40, 1.1469498354442222e-42, 2.9919651066058538e-45, 5.4278702104818919e-48, 6.5290610509647759e-51, 4.8944169739176386e-54, 2.1035897073764635e-57, 4.6092689309993016e-61, 4.3179663130756179e-65, 1.2953741930788741e-69, 7.1794482518779405e-75, 1.8135909934565948e-81}, + {2.6333035610382397e-82, 1.1024259296315383e-75, 2.0852967445741233e-70, 7.2556400241843898e-66, 8.0626671773555472e-62, 3.8234147683158063e-58, 9.2309809923115915e-55, 1.2764717039702522e-51, 1.0991625015027042e-48, 6.2718288470036324e-46, 2.4875851238977396e-43, 7.1225496037923785e-41, 1.5178899706379763e-38, 2.4689751624056617e-36, 3.1303492079755755e-34, 3.1491543092696820e-32, 2.5522940793940470e-30, 1.6885482670813982e-28, 9.2239272353929576e-27, 4.2024365472164892e-25, 1.6110964547970300e-23, 5.2383797573874037e-22, 1.4547178325694397e-20, 3.4721710760327322e-19, 7.1634722023972862e-18, 1.2840032078315100e-16, 2.0088075710888178e-15, 2.7546357750311648e-14, 3.3235533916670117e-13, 3.5405078866592410e-12, 3.3406627081403544e-11, 2.8000417787301215e-10, 2.0903260822482034e-09, 1.3932720755460754e-08, 8.3098897726797486e-08, 4.4440079875949290e-07, 2.1349200492771325e-06, 9.2289528191432300e-06, 3.5954963665620299e-05, 1.2641879089097217e-04, 4.0166542717281779e-04, 1.1545621668817155e-03, 3.0055192270927668e-03, 7.0920553324460628e-03, 1.5182046088138676e-02, 2.9505655023499801e-02, 5.2091376675144491e-02, 8.3587237918301055e-02, 1.2195957249370640e-01, 1.6186130554382056e-01, 1.9544872749879730e-01, 2.1476292059027455e-01, 2.1476292059027455e-01, 1.9544872749879730e-01, 1.6186130554382056e-01, 1.2195957249370640e-01, 8.3587237918301055e-02, 5.2091376675144491e-02, 2.9505655023499801e-02, 1.5182046088138676e-02, 7.0920553324460628e-03, 3.0055192270927668e-03, 1.1545621668817155e-03, 4.0166542717281779e-04, 1.2641879089097217e-04, 3.5954963665620299e-05, 9.2289528191432300e-06, 2.1349200492771325e-06, 4.4440079875949290e-07, 8.3098897726797486e-08, 1.3932720755460754e-08, 2.0903260822482034e-09, 2.8000417787301215e-10, 3.3406627081403544e-11, 3.5405078866592410e-12, 3.3235533916670117e-13, 2.7546357750311648e-14, 2.0088075710888178e-15, 1.2840032078315100e-16, 7.1634722023972862e-18, 3.4721710760327322e-19, 1.4547178325694397e-20, 5.2383797573874037e-22, 1.6110964547970300e-23, 4.2024365472164892e-25, 9.2239272353929576e-27, 1.6885482670813982e-28, 2.5522940793940470e-30, 3.1491543092696820e-32, 3.1303492079755755e-34, 2.4689751624056617e-36, 1.5178899706379763e-38, 7.1225496037923785e-41, 2.4875851238977396e-43, 6.2718288470036324e-46, 1.0991625015027042e-48, 1.2764717039702522e-51, 9.2309809923115915e-55, 3.8234147683158063e-58, 8.0626671773555472e-62, 7.2556400241843898e-66, 2.0852967445741233e-70, 1.1024259296315383e-75, 2.6333035610382397e-82}, + {3.8217861138085193e-83, 1.6914062097101716e-76, 3.3530353599320843e-71, 1.2174103962049957e-66, 1.4078704255855603e-62, 6.9351300068921097e-59, 1.7369401373650657e-55, 2.4890859009540812e-52, 2.2194272123488213e-49, 1.3105586296104345e-46, 5.3766702664810952e-44, 1.5917657474423608e-41, 3.5064188455904165e-39, 5.8941611353204651e-37, 7.7216030296457281e-35, 8.0254188497506414e-33, 6.7194313102734894e-31, 4.5922904136653062e-29, 2.5914755539513213e-27, 1.2197280334801351e-25, 4.8310543796668917e-24, 1.6229893391874090e-22, 4.6574324658183078e-21, 1.1488922069252337e-19, 2.4500971300072567e-18, 4.5403372361053743e-17, 7.3453513452694623e-16, 1.0418125668654998e-14, 1.3004299981305270e-13, 1.4335908364459435e-12, 1.4002082648585132e-11, 1.2152299982982779e-10, 9.3968905695997315e-10, 6.4898261604097228e-09, 4.0121667112572270e-08, 2.2249156377389857e-07, 1.1087989233089753e-06, 4.9744232013977632e-06, 2.0121686738026826e-05, 7.3491681493347192e-05, 2.4267655305986469e-04, 7.2534332143885018e-04, 1.9644706290361147e-03, 4.8255384821498035e-03, 1.0759969971184533e-02, 2.1795386765479520e-02, 4.0131719533568026e-02, 6.7208115842432761e-02, 1.0241614803131452e-01, 1.4206655437043109e-01, 1.7943973488563147e-01, 2.0641382873539532e-01, 2.1627494312286819e-01, 2.0641382873539532e-01, 1.7943973488563147e-01, 1.4206655437043109e-01, 1.0241614803131452e-01, 6.7208115842432761e-02, 4.0131719533568026e-02, 2.1795386765479520e-02, 1.0759969971184533e-02, 4.8255384821498035e-03, 1.9644706290361147e-03, 7.2534332143885018e-04, 2.4267655305986469e-04, 7.3491681493347192e-05, 2.0121686738026826e-05, 4.9744232013977632e-06, 1.1087989233089753e-06, 2.2249156377389857e-07, 4.0121667112572270e-08, 6.4898261604097228e-09, 9.3968905695997315e-10, 1.2152299982982779e-10, 1.4002082648585132e-11, 1.4335908364459435e-12, 1.3004299981305270e-13, 1.0418125668654998e-14, 7.3453513452694623e-16, 4.5403372361053743e-17, 2.4500971300072567e-18, 1.1488922069252337e-19, 4.6574324658183078e-21, 1.6229893391874090e-22, 4.8310543796668917e-24, 1.2197280334801351e-25, 2.5914755539513213e-27, 4.5922904136653062e-29, 6.7194313102734894e-31, 8.0254188497506414e-33, 7.7216030296457281e-35, 5.8941611353204651e-37, 3.5064188455904165e-39, 1.5917657474423608e-41, 5.3766702664810952e-44, 1.3105586296104345e-46, 2.2194272123488213e-49, 2.4890859009540812e-52, 1.7369401373650657e-55, 6.9351300068921097e-59, 1.4078704255855603e-62, 1.2174103962049957e-66, 3.3530353599320843e-71, 1.6914062097101716e-76, 3.8217861138085193e-83}, + {5.5441992722068482e-84, 2.5929395481292082e-77, 5.3853541853574509e-72, 2.0397343220146265e-67, 2.4541249535874453e-63, 1.2554100822781216e-59, 3.2608376921091931e-56, 4.8412365544964550e-53, 4.4687726007935870e-50, 2.7300300393618730e-47, 1.1581833176995228e-44, 3.5442966005156755e-42, 8.0681149793680242e-40, 1.4011614007496688e-37, 1.8960834059704929e-35, 2.0353977109818878e-33, 1.7599996574525402e-31, 1.2422004027168656e-29, 7.2392001895975213e-28, 3.5188457649983255e-26, 1.4394549700596331e-24, 4.9949088636257322e-23, 1.4806823585568918e-21, 3.7736012205435806e-20, 8.3155142767475590e-19, 1.5925756694175446e-17, 2.6632797443869722e-16, 3.9055385475699820e-15, 5.0416061378516563e-14, 5.7492300646009343e-13, 5.8103188163962404e-12, 5.2193608370012943e-11, 4.1786070059665728e-10, 2.9889202437814213e-09, 1.9144674266312151e-08, 1.1003547442210821e-07, 5.6858218763614167e-07, 2.6459673129317030e-06, 1.1106993480718368e-05, 4.2117165655971054e-05, 1.4445933891050312e-04, 4.4872081587300148e-04, 1.2636334832367285e-03, 3.2292611575356744e-03, 7.4954912038533066e-03, 1.5814177885623497e-02, 3.0348423943327270e-02, 5.3005665528953826e-02, 8.4298566514348958e-02, 1.2212582857840716e-01, 1.6122241452497918e-01, 1.9398990851223818e-01, 2.1278380261127008e-01, 2.1278380261127008e-01, 1.9398990851223818e-01, 1.6122241452497918e-01, 1.2212582857840716e-01, 8.4298566514348958e-02, 5.3005665528953826e-02, 3.0348423943327270e-02, 1.5814177885623497e-02, 7.4954912038533066e-03, 3.2292611575356744e-03, 1.2636334832367285e-03, 4.4872081587300148e-04, 1.4445933891050312e-04, 4.2117165655971054e-05, 1.1106993480718368e-05, 2.6459673129317030e-06, 5.6858218763614167e-07, 1.1003547442210821e-07, 1.9144674266312151e-08, 2.9889202437814213e-09, 4.1786070059665728e-10, 5.2193608370012943e-11, 5.8103188163962404e-12, 5.7492300646009343e-13, 5.0416061378516563e-14, 3.9055385475699820e-15, 2.6632797443869722e-16, 1.5925756694175446e-17, 8.3155142767475590e-19, 3.7736012205435806e-20, 1.4806823585568918e-21, 4.9949088636257322e-23, 1.4394549700596331e-24, 3.5188457649983255e-26, 7.2392001895975213e-28, 1.2422004027168656e-29, 1.7599996574525402e-31, 2.0353977109818878e-33, 1.8960834059704929e-35, 1.4011614007496688e-37, 8.0681149793680242e-40, 3.5442966005156755e-42, 1.1581833176995228e-44, 2.7300300393618730e-47, 4.4687726007935870e-50, 4.8412365544964550e-53, 3.2608376921091931e-56, 1.2554100822781216e-59, 2.4541249535874453e-63, 2.0397343220146265e-67, 5.3853541853574509e-72, 2.5929395481292082e-77, 5.5441992722068482e-84}, + {8.0393570948066263e-85, 3.9718103441759187e-78, 8.6398120096864360e-73, 3.4126815525065270e-68, 4.2706414980124341e-64, 2.2680834264069969e-60, 6.1079802227760500e-57, 9.3924613692270336e-54, 8.9727413440350903e-51, 5.6695759907967620e-48, 2.4865399657656492e-45, 7.8635083915713631e-43, 1.8492505278934263e-40, 3.3170216420826621e-38, 4.6353055637591542e-36, 5.1377976964188761e-34, 4.5868230110636832e-32, 3.3422916829863083e-30, 2.0109122099933846e-28, 1.0091662170872907e-26, 4.2622901606926843e-25, 1.5271754441949008e-23, 4.6750298903216843e-22, 1.2305362144434042e-20, 2.8009656241231101e-19, 5.5420769366655970e-18, 9.5769111189688996e-17, 1.4514991221804437e-15, 1.9370075854564139e-14, 2.2840535977994185e-13, 2.3875175115445612e-12, 2.2189005868460593e-11, 1.8384761407124325e-10, 1.3614036372254147e-09, 9.0305672540467943e-09, 5.3771344014689486e-08, 2.8795698296534307e-07, 1.3893404522738127e-06, 6.0491308542217258e-06, 2.3802318133010187e-05, 8.4755918374596230e-05, 2.7344820329821672e-04, 8.0022923976588462e-04, 2.1262829728506513e-03, 5.1343246513282466e-03, 1.1275787985601648e-02, 2.2538065887400437e-02, 4.1025901106205930e-02, 6.8045431494172207e-02, 1.0287976270898229e-01, 1.4184235712795296e-01, 1.7838019194959490e-01, 2.0466195210272575e-01, 2.1425368197218711e-01, 2.0466195210272575e-01, 1.7838019194959490e-01, 1.4184235712795296e-01, 1.0287976270898229e-01, 6.8045431494172207e-02, 4.1025901106205930e-02, 2.2538065887400437e-02, 1.1275787985601648e-02, 5.1343246513282466e-03, 2.1262829728506513e-03, 8.0022923976588462e-04, 2.7344820329821672e-04, 8.4755918374596230e-05, 2.3802318133010187e-05, 6.0491308542217258e-06, 1.3893404522738127e-06, 2.8795698296534307e-07, 5.3771344014689486e-08, 9.0305672540467943e-09, 1.3614036372254147e-09, 1.8384761407124325e-10, 2.2189005868460593e-11, 2.3875175115445612e-12, 2.2840535977994185e-13, 1.9370075854564139e-14, 1.4514991221804437e-15, 9.5769111189688996e-17, 5.5420769366655970e-18, 2.8009656241231101e-19, 1.2305362144434042e-20, 4.6750298903216843e-22, 1.5271754441949008e-23, 4.2622901606926843e-25, 1.0091662170872907e-26, 2.0109122099933846e-28, 3.3422916829863083e-30, 4.5868230110636832e-32, 5.1377976964188761e-34, 4.6353055637591542e-36, 3.3170216420826621e-38, 1.8492505278934263e-40, 7.8635083915713631e-43, 2.4865399657656492e-45, 5.6695759907967620e-48, 8.9727413440350903e-51, 9.3924613692270336e-54, 6.1079802227760500e-57, 2.2680834264069969e-60, 4.2706414980124341e-64, 3.4126815525065270e-68, 8.6398120096864360e-73, 3.9718103441759187e-78, 8.0393570948066263e-85}, + {1.1652438369940990e-85, 6.0791348825232945e-79, 1.3845734727539209e-73, 5.7018195541180805e-69, 7.4193203262024338e-65, 4.0896774498494807e-61, 1.1415803801508950e-57, 1.8177229307902597e-54, 1.7966861107994258e-51, 1.1738936354016808e-48, 5.3209955905676318e-46, 1.7384628972964638e-43, 4.2224503669018324e-41, 7.8205013430131660e-39, 1.1282489276123687e-36, 1.2908866148089198e-34, 1.1895168657985647e-32, 8.9460231384332668e-31, 5.5552056820850460e-29, 2.8773904696541066e-27, 1.2543771045577858e-25, 4.6393197457827112e-24, 1.4661278293822309e-22, 3.9843331940864138e-21, 9.3649180986702086e-20, 1.9137000334222806e-18, 3.4159437284687078e-17, 5.3490074750121478e-16, 7.3765684098315642e-15, 8.9908236810354557e-14, 9.7167575155334535e-13, 9.3392850013870488e-12, 8.0050126851044650e-11, 6.1341491782010079e-10, 4.2120058561600563e-09, 2.5970629339726590e-08, 1.4407085283844865e-07, 7.2034690286882965e-07, 3.2515206739898432e-06, 1.3269605500302639e-05, 4.9028384509802042e-05, 1.6420793698012457e-04, 4.9909954967131240e-04, 1.3780641953787555e-03, 3.4597075988944920e-03, 7.9041144380998778e-03, 1.6444728895483641e-02, 3.1177182981317560e-02, 5.3891864826823496e-02, 8.4974571583542949e-02, 1.2226499127815092e-01, 1.6058169612107806e-01, 1.9256185751562635e-01, 2.1085839371676188e-01, 2.1085839371676188e-01, 1.9256185751562635e-01, 1.6058169612107806e-01, 1.2226499127815092e-01, 8.4974571583542949e-02, 5.3891864826823496e-02, 3.1177182981317560e-02, 1.6444728895483641e-02, 7.9041144380998778e-03, 3.4597075988944920e-03, 1.3780641953787555e-03, 4.9909954967131240e-04, 1.6420793698012457e-04, 4.9028384509802042e-05, 1.3269605500302639e-05, 3.2515206739898432e-06, 7.2034690286882965e-07, 1.4407085283844865e-07, 2.5970629339726590e-08, 4.2120058561600563e-09, 6.1341491782010079e-10, 8.0050126851044650e-11, 9.3392850013870488e-12, 9.7167575155334535e-13, 8.9908236810354557e-14, 7.3765684098315642e-15, 5.3490074750121478e-16, 3.4159437284687078e-17, 1.9137000334222806e-18, 9.3649180986702086e-20, 3.9843331940864138e-21, 1.4661278293822309e-22, 4.6393197457827112e-24, 1.2543771045577858e-25, 2.8773904696541066e-27, 5.5552056820850460e-29, 8.9460231384332668e-31, 1.1895168657985647e-32, 1.2908866148089198e-34, 1.1282489276123687e-36, 7.8205013430131660e-39, 4.2224503669018324e-41, 1.7384628972964638e-43, 5.3209955905676318e-46, 1.1738936354016808e-48, 1.7966861107994258e-51, 1.8177229307902597e-54, 1.1415803801508950e-57, 4.0896774498494807e-61, 7.4193203262024338e-65, 5.7018195541180805e-69, 1.3845734727539209e-73, 6.0791348825232945e-79, 1.1652438369940990e-85}, + {1.6882167305707454e-86, 9.2973163909464803e-80, 2.2164453269063499e-74, 9.5134149540243336e-70, 1.2868308966878782e-65, 7.3601988558208524e-62, 2.1289805828564999e-58, 3.5092885496818465e-55, 3.5879758763817130e-52, 2.4233946264708683e-49, 1.1349953099138248e-46, 3.8300452415564833e-44, 9.6052219657335494e-42, 1.8364466079421476e-39, 2.7344551836642605e-37, 3.2286335472886435e-35, 3.0699209573361954e-33, 2.3822649787982913e-31, 1.5263559111336781e-29, 8.1574699196788167e-28, 3.6694695554120368e-26, 1.4004790074896691e-24, 4.5675182897648129e-23, 1.2811473098169559e-21, 3.1084252235905216e-20, 6.5579821121285801e-19, 1.2087664560459120e-17, 1.9548969486564158e-16, 2.7849389834496225e-15, 3.5072844186621564e-14, 3.9175124016391924e-13, 3.8925586774167020e-12, 3.4501563168365539e-11, 2.7347438232977245e-10, 1.9430095134453053e-09, 1.2400464068693708e-08, 7.1228670517261927e-08, 3.6889724023685680e-07, 1.7254610364884881e-06, 7.2997812630457740e-06, 2.7971738168589429e-05, 9.7203453180453000e-05, 3.0668682564469456e-04, 8.7945145983116615e-04, 2.2942465962944290e-03, 5.4493669764638540e-03, 1.1793861247331682e-02, 2.3273293687959880e-02, 4.1898884894253120e-02, 6.8850165394430590e-02, 1.0331081665178690e-01, 1.4160263924602950e-01, 1.7733517017411166e-01, 2.0295366115211383e-01, 2.1228805186235042e-01, 2.0295366115211383e-01, 1.7733517017411166e-01, 1.4160263924602950e-01, 1.0331081665178690e-01, 6.8850165394430590e-02, 4.1898884894253120e-02, 2.3273293687959880e-02, 1.1793861247331682e-02, 5.4493669764638540e-03, 2.2942465962944290e-03, 8.7945145983116615e-04, 3.0668682564469456e-04, 9.7203453180453000e-05, 2.7971738168589429e-05, 7.2997812630457740e-06, 1.7254610364884881e-06, 3.6889724023685680e-07, 7.1228670517261927e-08, 1.2400464068693708e-08, 1.9430095134453053e-09, 2.7347438232977245e-10, 3.4501563168365539e-11, 3.8925586774167020e-12, 3.9175124016391924e-13, 3.5072844186621564e-14, 2.7849389834496225e-15, 1.9548969486564158e-16, 1.2087664560459120e-17, 6.5579821121285801e-19, 3.1084252235905216e-20, 1.2811473098169559e-21, 4.5675182897648129e-23, 1.4004790074896691e-24, 3.6694695554120368e-26, 8.1574699196788167e-28, 1.5263559111336781e-29, 2.3822649787982913e-31, 3.0699209573361954e-33, 3.2286335472886435e-35, 2.7344551836642605e-37, 1.8364466079421476e-39, 9.6052219657335494e-42, 3.8300452415564833e-44, 1.1349953099138248e-46, 2.4233946264708683e-49, 3.5879758763817130e-52, 3.5092885496818465e-55, 2.1289805828564999e-58, 7.3601988558208524e-62, 1.2868308966878782e-65, 9.5134149540243336e-70, 2.2164453269063499e-74, 9.2973163909464803e-80, 1.6882167305707454e-86}, + {2.4448842535551943e-87, 1.4208271558885895e-80, 3.5443349838315051e-75, 1.5851638341206613e-70, 2.2283154783345243e-66, 1.3221294591344122e-62, 3.9619475088358356e-59, 6.7588233504303362e-56, 7.1462236088717712e-53, 4.9883667718148639e-50, 2.4133632044032138e-47, 8.4092583458821788e-45, 2.1769699583039015e-42, 4.2954616661119346e-40, 6.5994654800159303e-38, 8.0390389893761170e-36, 7.8853213936624651e-34, 6.3119668181308563e-32, 4.1716030615092882e-30, 2.2997378701939073e-28, 1.0671290531221681e-26, 4.2015271606281150e-25, 1.4137224274155160e-23, 4.0914965094167889e-22, 1.0244196283925887e-20, 2.2306211570300883e-19, 4.2441255956981095e-18, 7.0866359430444936e-17, 1.0425344386668410e-15, 1.3561256356020877e-14, 1.5649369927618164e-13, 1.6069042876497942e-12, 1.4722456305780643e-11, 1.2066201440627706e-10, 8.8669552925941743e-10, 5.8549609302492589e-09, 3.4807738736531026e-08, 1.8664547970988355e-07, 9.0421645542748592e-07, 3.9637332341743650e-06, 1.5744241598181718e-05, 5.6738856687547051e-05, 1.8573262875095809e-04, 5.5284802877925447e-04, 1.4977892627292288e-03, 3.6965702725171162e-03, 8.3173850369341346e-03, 1.7073105881727814e-02, 3.1991743583371472e-02, 5.4750665778331979e-02, 8.5616850779843184e-02, 1.2237883847025718e-01, 1.5993992755454783e-01, 1.9116358027866243e-01, 2.0898430851629271e-01, 2.0898430851629271e-01, 1.9116358027866243e-01, 1.5993992755454783e-01, 1.2237883847025718e-01, 8.5616850779843184e-02, 5.4750665778331979e-02, 3.1991743583371472e-02, 1.7073105881727814e-02, 8.3173850369341346e-03, 3.6965702725171162e-03, 1.4977892627292288e-03, 5.5284802877925447e-04, 1.8573262875095809e-04, 5.6738856687547051e-05, 1.5744241598181718e-05, 3.9637332341743650e-06, 9.0421645542748592e-07, 1.8664547970988355e-07, 3.4807738736531026e-08, 5.8549609302492589e-09, 8.8669552925941743e-10, 1.2066201440627706e-10, 1.4722456305780643e-11, 1.6069042876497942e-12, 1.5649369927618164e-13, 1.3561256356020877e-14, 1.0425344386668410e-15, 7.0866359430444936e-17, 4.2441255956981095e-18, 2.2306211570300883e-19, 1.0244196283925887e-20, 4.0914965094167889e-22, 1.4137224274155160e-23, 4.2015271606281150e-25, 1.0671290531221681e-26, 2.2997378701939073e-28, 4.1716030615092882e-30, 6.3119668181308563e-32, 7.8853213936624651e-34, 8.0390389893761170e-36, 6.5994654800159303e-38, 4.2954616661119346e-40, 2.1769699583039015e-42, 8.4092583458821788e-45, 2.4133632044032138e-47, 4.9883667718148639e-50, 7.1462236088717712e-53, 6.7588233504303362e-56, 3.9619475088358356e-59, 1.3221294591344122e-62, 2.2283154783345243e-66, 1.5851638341206613e-70, 3.5443349838315051e-75, 1.4208271558885895e-80, 2.4448842535551943e-87}, + {3.5392388249213494e-88, 2.1696906628474067e-81, 5.6618251917679648e-76, 2.6377634936769698e-71, 3.8524845909450548e-67, 2.3705848077171715e-63, 7.3575399530382127e-60, 1.2986758900322505e-56, 1.4196212763395569e-53, 1.0238881258836751e-50, 5.1156622686963731e-48, 1.8401448448645002e-45, 4.9161713392811270e-43, 1.0008264983378071e-40, 1.5861732912787765e-38, 1.9928674928468924e-36, 2.0159688321556722e-34, 1.6641520867485548e-32, 1.1341833636634616e-30, 6.4478013617261386e-29, 3.0854328584335985e-27, 1.2528407416044293e-25, 4.3478662125855451e-24, 1.2979585113660281e-22, 3.3525506308968111e-21, 7.5318707919556725e-20, 1.4788148820660904e-18, 2.5485379935372649e-17, 3.8703599993584500e-16, 5.1983189715882119e-15, 6.1952864130014014e-14, 6.5714753453597697e-13, 6.2212201579575959e-12, 5.2699881035078001e-11, 4.0039253602146504e-10, 2.7342851107604089e-09, 1.6816952694545013e-08, 9.3323608375261539e-08, 4.6806643299789927e-07, 2.1250386338304275e-06, 8.7455216612331247e-06, 3.2668449881324752e-05, 1.1089473739894331e-04, 3.4245439902397305e-04, 9.6300903314221480e-04, 2.4681920354686017e-03, 5.7702467735466509e-03, 1.2313597617381173e-02, 2.4000639085914963e-02, 4.2750896794915914e-02, 6.9623487033404263e-02, 1.0371107766286002e-01, 1.4134876449586573e-01, 1.7630458117164949e-01, 2.0128719075538343e-01, 2.1037554689061755e-01, 2.0128719075538343e-01, 1.7630458117164949e-01, 1.4134876449586573e-01, 1.0371107766286002e-01, 6.9623487033404263e-02, 4.2750896794915914e-02, 2.4000639085914963e-02, 1.2313597617381173e-02, 5.7702467735466509e-03, 2.4681920354686017e-03, 9.6300903314221480e-04, 3.4245439902397305e-04, 1.1089473739894331e-04, 3.2668449881324752e-05, 8.7455216612331247e-06, 2.1250386338304275e-06, 4.6806643299789927e-07, 9.3323608375261539e-08, 1.6816952694545013e-08, 2.7342851107604089e-09, 4.0039253602146504e-10, 5.2699881035078001e-11, 6.2212201579575959e-12, 6.5714753453597697e-13, 6.1952864130014014e-14, 5.1983189715882119e-15, 3.8703599993584500e-16, 2.5485379935372649e-17, 1.4788148820660904e-18, 7.5318707919556725e-20, 3.3525506308968111e-21, 1.2979585113660281e-22, 4.3478662125855451e-24, 1.2528407416044293e-25, 3.0854328584335985e-27, 6.4478013617261386e-29, 1.1341833636634616e-30, 1.6641520867485548e-32, 2.0159688321556722e-34, 1.9928674928468924e-36, 1.5861732912787765e-38, 1.0008264983378071e-40, 4.9161713392811270e-43, 1.8401448448645002e-45, 5.1156622686963731e-48, 1.0238881258836751e-50, 1.4196212763395569e-53, 1.2986758900322505e-56, 7.3575399530382127e-60, 2.3705848077171715e-63, 3.8524845909450548e-67, 2.6377634936769698e-71, 5.6618251917679648e-76, 2.1696906628474067e-81, 3.5392388249213494e-88}, + {5.1213633747657793e-89, 3.3107952448155878e-82, 9.0350209598558634e-77, 4.3835962164609016e-72, 6.6500528211701889e-68, 4.2427446781122925e-64, 1.3635093884813276e-60, 2.4895722182831332e-57, 2.8129093907478575e-54, 2.0956899110692340e-51, 1.0810706995222149e-48, 4.0133902027335798e-46, 1.1062614025677837e-43, 2.3230252252301317e-41, 3.7968846438904689e-39, 4.9189778171570439e-37, 5.1304565438169636e-35, 4.3662939232282773e-33, 3.0678714585911782e-31, 1.7980362370024124e-29, 8.8704657684441925e-28, 3.7135654602235681e-26, 1.3288244259482261e-24, 4.0906197763453875e-23, 1.0896574554298035e-21, 2.5250019651414982e-20, 5.1142598161040868e-19, 9.0937679770517361e-18, 1.4251779817419312e-16, 1.9757601287853092e-15, 2.4309836206138916e-14, 2.6627832873106297e-13, 2.6038192973897978e-12, 2.2788951363311533e-11, 1.7893870863289438e-10, 1.2632724994941663e-09, 8.0347791732044002e-09, 4.6125099246668157e-08, 2.3940078640211405e-07, 1.1251692413517793e-06, 4.7955457442441056e-06, 1.8559162409889888e-05, 6.5298413383660050e-05, 2.0909754829024987e-04, 6.1000345990479894e-04, 1.6227318637929411e-03, 3.9395573314086755e-03, 8.7347828708895063e-03, 1.7698763026162554e-02, 3.2791967492410569e-02, 5.5582763848207158e-02, 8.6226926941764842e-02, 1.2246902437683259e-01, 1.5929780439003277e-01, 1.8979412167575810e-01, 2.0715930730796278e-01, 2.0715930730796278e-01, 1.8979412167575810e-01, 1.5929780439003277e-01, 1.2246902437683259e-01, 8.6226926941764842e-02, 5.5582763848207158e-02, 3.2791967492410569e-02, 1.7698763026162554e-02, 8.7347828708895063e-03, 3.9395573314086755e-03, 1.6227318637929411e-03, 6.1000345990479894e-04, 2.0909754829024987e-04, 6.5298413383660050e-05, 1.8559162409889888e-05, 4.7955457442441056e-06, 1.1251692413517793e-06, 2.3940078640211405e-07, 4.6125099246668157e-08, 8.0347791732044002e-09, 1.2632724994941663e-09, 1.7893870863289438e-10, 2.2788951363311533e-11, 2.6038192973897978e-12, 2.6627832873106297e-13, 2.4309836206138916e-14, 1.9757601287853092e-15, 1.4251779817419312e-16, 9.0937679770517361e-18, 5.1142598161040868e-19, 2.5250019651414982e-20, 1.0896574554298035e-21, 4.0906197763453875e-23, 1.3288244259482261e-24, 3.7135654602235681e-26, 8.8704657684441925e-28, 1.7980362370024124e-29, 3.0678714585911782e-31, 4.3662939232282773e-33, 5.1304565438169636e-35, 4.9189778171570439e-37, 3.7968846438904689e-39, 2.3230252252301317e-41, 1.1062614025677837e-43, 4.0133902027335798e-46, 1.0810706995222149e-48, 2.0956899110692340e-51, 2.8129093907478575e-54, 2.4895722182831332e-57, 1.3635093884813276e-60, 4.2427446781122925e-64, 6.6500528211701889e-68, 4.3835962164609016e-72, 9.0350209598558634e-77, 3.3107952448155878e-82, 5.1213633747657793e-89}, + {7.4077801156809802e-90, 5.0483520825696067e-83, 1.4403225795247276e-77, 7.2755698062212851e-73, 1.1461458182067259e-68, 7.5798509757209669e-65, 2.5217356180713449e-61, 4.7616681817655899e-58, 5.5596107723280791e-55, 4.2776169290546349e-52, 2.2777250019423805e-49, 8.7248851122544073e-47, 2.4806792113142151e-44, 5.3718421575826214e-42, 9.0525141699026487e-40, 1.2089985963915576e-37, 1.2997822407575913e-35, 1.1401487006660065e-33, 8.2566517430946983e-32, 4.9874725361855554e-30, 2.5360177279806859e-28, 1.0943086662261828e-26, 4.0363441926925487e-25, 1.2809131432068308e-23, 3.5178503719335083e-22, 8.4054498872392565e-21, 1.7557265568072654e-19, 3.2200557928719378e-18, 5.2060944517170957e-17, 7.4470753817100703e-16, 9.4565868275202180e-15, 1.0692722214257240e-13, 1.0796165415752499e-12, 9.7589319582302090e-12, 7.9162851028857836e-11, 5.7753749442476326e-10, 3.7971425911450754e-09, 2.2540365079384215e-08, 1.2101463098116854e-07, 5.8853747125042215e-07, 2.5965756360441134e-06, 1.0406346919868978e-05, 3.7931294208686378e-05, 1.2588825538260341e-04, 3.8080638386839771e-04, 1.0508900454889139e-03, 2.6479410521627993e-03, 6.0965525061442453e-03, 1.2834439196438882e-02, 2.4719722908456396e-02, 4.3582193779905874e-02, 7.0366531191907819e-02, 1.0408220923468044e-01, 1.4108198634981012e-01, 1.7528831212387214e-01, 1.9966087345702854e-01, 2.0851381638716077e-01, 1.9966087345702854e-01, 1.7528831212387214e-01, 1.4108198634981012e-01, 1.0408220923468044e-01, 7.0366531191907819e-02, 4.3582193779905874e-02, 2.4719722908456396e-02, 1.2834439196438882e-02, 6.0965525061442453e-03, 2.6479410521627993e-03, 1.0508900454889139e-03, 3.8080638386839771e-04, 1.2588825538260341e-04, 3.7931294208686378e-05, 1.0406346919868978e-05, 2.5965756360441134e-06, 5.8853747125042215e-07, 1.2101463098116854e-07, 2.2540365079384215e-08, 3.7971425911450754e-09, 5.7753749442476326e-10, 7.9162851028857836e-11, 9.7589319582302090e-12, 1.0796165415752499e-12, 1.0692722214257240e-13, 9.4565868275202180e-15, 7.4470753817100703e-16, 5.2060944517170957e-17, 3.2200557928719378e-18, 1.7557265568072654e-19, 8.4054498872392565e-21, 3.5178503719335083e-22, 1.2809131432068308e-23, 4.0363441926925487e-25, 1.0943086662261828e-26, 2.5360177279806859e-28, 4.9874725361855554e-30, 8.2566517430946983e-32, 1.1401487006660065e-33, 1.2997822407575913e-35, 1.2089985963915576e-37, 9.0525141699026487e-40, 5.3718421575826214e-42, 2.4806792113142151e-44, 8.7248851122544073e-47, 2.2777250019423805e-49, 4.2776169290546349e-52, 5.5596107723280791e-55, 4.7616681817655899e-58, 2.5217356180713449e-61, 7.5798509757209669e-65, 1.1461458182067259e-68, 7.2755698062212851e-73, 1.4403225795247276e-77, 5.0483520825696067e-83, 7.4077801156809802e-90}, + {1.0710750710094196e-90, 7.6922700260785516e-84, 2.2937970374962485e-78, 1.2060181138762046e-73, 1.9724028846801179e-69, 1.3517892214658933e-65, 4.6544766331713673e-62, 9.0869836287455904e-59, 1.0961147706353286e-55, 8.7075616610856478e-53, 4.7848109229537450e-50, 1.8906897473607166e-47, 5.5435860303288234e-45, 1.2376390647546546e-42, 2.1498363403641766e-40, 2.9591207501866347e-38, 3.2783946198859832e-36, 2.9632924702764426e-34, 2.2111690104503776e-32, 1.3762537782433349e-30, 7.2106896606964717e-29, 3.2061793655442875e-27, 1.2186704300488311e-25, 3.9856906328389221e-24, 1.1282136742777468e-22, 2.7788009433178836e-21, 5.9840605797879746e-20, 1.1316516319423812e-18, 1.8868897366381483e-17, 2.7841156852775031e-16, 3.6474708837523359e-15, 4.2559572408720686e-14, 4.4353966285433845e-13, 4.1393133324428903e-12, 3.4675788374516700e-11, 2.6132836673568577e-10, 1.7753911292124313e-09, 1.0893439091005499e-08, 6.0471668709771245e-08, 3.0419237917584698e-07, 1.3886494911822552e-06, 5.7606576662754425e-06, 2.1743312833175104e-05, 7.4756242475529144e-05, 2.3436272202084139e-04, 6.7059411024834642e-04, 1.7528045021959946e-03, 4.1883749721869905e-03, 9.1558081843385875e-03, 1.8321199420242032e-02, 3.3577761609077682e-02, 5.6388855176296548e-02, 8.6806251150572486e-02, 1.2253708910746171e-01, 1.5865594890874077e-01, 1.8845256425575369e-01, 2.0538128483764440e-01, 2.0538128483764440e-01, 1.8845256425575369e-01, 1.5865594890874077e-01, 1.2253708910746171e-01, 8.6806251150572486e-02, 5.6388855176296548e-02, 3.3577761609077682e-02, 1.8321199420242032e-02, 9.1558081843385875e-03, 4.1883749721869905e-03, 1.7528045021959946e-03, 6.7059411024834642e-04, 2.3436272202084139e-04, 7.4756242475529144e-05, 2.1743312833175104e-05, 5.7606576662754425e-06, 1.3886494911822552e-06, 3.0419237917584698e-07, 6.0471668709771245e-08, 1.0893439091005499e-08, 1.7753911292124313e-09, 2.6132836673568577e-10, 3.4675788374516700e-11, 4.1393133324428903e-12, 4.4353966285433845e-13, 4.2559572408720686e-14, 3.6474708837523359e-15, 2.7841156852775031e-16, 1.8868897366381483e-17, 1.1316516319423812e-18, 5.9840605797879746e-20, 2.7788009433178836e-21, 1.1282136742777468e-22, 3.9856906328389221e-24, 1.2186704300488311e-25, 3.2061793655442875e-27, 7.2106896606964717e-29, 1.3762537782433349e-30, 2.2111690104503776e-32, 2.9632924702764426e-34, 3.2783946198859832e-36, 2.9591207501866347e-38, 2.1498363403641766e-40, 1.2376390647546546e-42, 5.5435860303288234e-45, 1.8906897473607166e-47, 4.7848109229537450e-50, 8.7075616610856478e-53, 1.0961147706353286e-55, 9.0869836287455904e-59, 4.6544766331713673e-62, 1.3517892214658933e-65, 1.9724028846801179e-69, 1.2060181138762046e-73, 2.2937970374962485e-78, 7.6922700260785516e-84, 1.0710750710094196e-90}, + {1.5480449561254974e-91, 1.1712554562855694e-84, 3.6493992259071536e-79, 1.9966381452254604e-74, 3.3892412733092808e-70, 2.4065988574277261e-66, 8.5740429722944209e-63, 1.7303021840396506e-59, 2.1557967924444521e-56, 1.7677871947095523e-53, 1.0022253044363931e-50, 4.0842818848410062e-48, 1.2346472555075369e-45, 2.8411408701159342e-43, 5.0858613958959180e-41, 7.2130038186701857e-39, 8.2330481300630906e-37, 7.6663204905842568e-35, 5.8928891499709780e-33, 3.7782612371775474e-31, 2.0392097722330042e-29, 9.3406997569354054e-28, 3.6577061009128777e-26, 1.2325099622415151e-24, 3.5948795028461328e-23, 9.1244425221919135e-22, 2.0251548550899527e-20, 3.9477817506225531e-19, 6.7863601469508643e-18, 1.0325389659471167e-16, 1.3951643164647175e-15, 1.6793350772844097e-14, 1.8058345392733700e-13, 1.7393402348430495e-12, 1.5041987406688428e-11, 1.1705945482958366e-10, 8.2144797343634809e-10, 5.2077334277669068e-09, 2.9879393170121428e-08, 1.5539942997674910e-07, 7.3371456445731177e-07, 3.1491925110163785e-06, 1.2303027527173753e-05, 4.3799266325778880e-05, 1.4224028492262314e-04, 4.2179171252798944e-04, 1.1430722829481254e-03, 2.8333080652480614e-03, 6.4278810024544141e-03, 1.3355861419689084e-02, 2.5430213894352387e-02, 4.4393059115154253e-02, 7.1080397415348953e-02, 1.0442577716745464e-01, 1.4080345768904715e-01, 1.7428622967828752e-01, 1.9807313269914872e-01, 2.0670065276640287e-01, 1.9807313269914872e-01, 1.7428622967828752e-01, 1.4080345768904715e-01, 1.0442577716745464e-01, 7.1080397415348953e-02, 4.4393059115154253e-02, 2.5430213894352387e-02, 1.3355861419689084e-02, 6.4278810024544141e-03, 2.8333080652480614e-03, 1.1430722829481254e-03, 4.2179171252798944e-04, 1.4224028492262314e-04, 4.3799266325778880e-05, 1.2303027527173753e-05, 3.1491925110163785e-06, 7.3371456445731177e-07, 1.5539942997674910e-07, 2.9879393170121428e-08, 5.2077334277669068e-09, 8.2144797343634809e-10, 1.1705945482958366e-10, 1.5041987406688428e-11, 1.7393402348430495e-12, 1.8058345392733700e-13, 1.6793350772844097e-14, 1.3951643164647175e-15, 1.0325389659471167e-16, 6.7863601469508643e-18, 3.9477817506225531e-19, 2.0251548550899527e-20, 9.1244425221919135e-22, 3.5948795028461328e-23, 1.2325099622415151e-24, 3.6577061009128777e-26, 9.3406997569354054e-28, 2.0392097722330042e-29, 3.7782612371775474e-31, 5.8928891499709780e-33, 7.6663204905842568e-35, 8.2330481300630906e-37, 7.2130038186701857e-39, 5.0858613958959180e-41, 2.8411408701159342e-43, 1.2346472555075369e-45, 4.0842818848410062e-48, 1.0022253044363931e-50, 1.7677871947095523e-53, 2.1557967924444521e-56, 1.7303021840396506e-59, 8.5740429722944209e-63, 2.4065988574277261e-66, 3.3892412733092808e-70, 1.9966381452254604e-74, 3.6493992259071536e-79, 1.1712554562855694e-84, 1.5480449561254974e-91}, + {2.2365648981246453e-92, 1.7821550800540237e-85, 5.8004986924644819e-80, 3.3015035960765624e-75, 5.8152759548633637e-71, 4.2771691981814217e-67, 1.5763666548556604e-63, 3.2876134769273718e-60, 4.2297673811987948e-57, 3.5794857851611975e-54, 2.0932606053442080e-51, 8.7956536234027020e-49, 2.7406328866050857e-46, 6.4989825715662458e-44, 1.1986003025152256e-41, 1.7511205172582050e-39, 2.0587364582129049e-37, 1.9743896190133811e-35, 1.5630006293499951e-33, 1.0320466636328443e-31, 5.7365178511704523e-30, 2.7061869712127610e-28, 1.0914439534101697e-26, 3.7881611827990218e-25, 1.1381700734483244e-23, 2.9761942889320718e-22, 6.8061278108013458e-21, 1.3672374402361970e-19, 2.4223988311307281e-18, 3.7993465086131341e-17, 5.2930247423722938e-16, 6.5702357143564891e-15, 7.2875563565483730e-14, 7.2418684802603713e-13, 6.4631097928536238e-12, 5.1919141781420298e-11, 3.7618946881237821e-10, 2.4632483182140787e-09, 1.4601515540917063e-08, 7.8484291703314789e-08, 3.8310233242483633e-07, 1.7005728326428347e-06, 6.8734922472265778e-06, 2.5326195751014174e-05, 8.5160665584721077e-05, 2.6158391341408045e-04, 7.3463960542667715e-04, 1.8879100806443562e-03, 4.4427288798279318e-03, 9.5799818951133077e-03, 1.8939956587000626e-02, 3.4349073289602634e-02, 5.7169633542064863e-02, 8.7356205785880797e-02, 1.2258446739609345e-01, 1.5801491756025524e-01, 1.8713802680418945e-01, 2.0364826010006534e-01, 2.0364826010006534e-01, 1.8713802680418945e-01, 1.5801491756025524e-01, 1.2258446739609345e-01, 8.7356205785880797e-02, 5.7169633542064863e-02, 3.4349073289602634e-02, 1.8939956587000626e-02, 9.5799818951133077e-03, 4.4427288798279318e-03, 1.8879100806443562e-03, 7.3463960542667715e-04, 2.6158391341408045e-04, 8.5160665584721077e-05, 2.5326195751014174e-05, 6.8734922472265778e-06, 1.7005728326428347e-06, 3.8310233242483633e-07, 7.8484291703314789e-08, 1.4601515540917063e-08, 2.4632483182140787e-09, 3.7618946881237821e-10, 5.1919141781420298e-11, 6.4631097928536238e-12, 7.2418684802603713e-13, 7.2875563565483730e-14, 6.5702357143564891e-15, 5.2930247423722938e-16, 3.7993465086131341e-17, 2.4223988311307281e-18, 1.3672374402361970e-19, 6.8061278108013458e-21, 2.9761942889320718e-22, 1.1381700734483244e-23, 3.7881611827990218e-25, 1.0914439534101697e-26, 2.7061869712127610e-28, 5.7365178511704523e-30, 1.0320466636328443e-31, 1.5630006293499951e-33, 1.9743896190133811e-35, 2.0587364582129049e-37, 1.7511205172582050e-39, 1.1986003025152256e-41, 6.4989825715662458e-44, 2.7406328866050857e-46, 8.7956536234027020e-49, 2.0932606053442080e-51, 3.5794857851611975e-54, 4.2297673811987948e-57, 3.2876134769273718e-60, 1.5763666548556604e-63, 4.2771691981814217e-67, 5.8152759548633637e-71, 3.3015035960765624e-75, 5.8004986924644819e-80, 1.7821550800540237e-85, 2.2365648981246453e-92}, + {3.2301009543101099e-93, 2.7098206745663592e-86, 9.2107100141581600e-81, 5.4525421540759655e-76, 9.9634282798974572e-72, 7.5888934406190700e-68, 2.8926678180441972e-64, 6.2331956354059190e-61, 8.2793896913033925e-58, 7.2291385544928827e-55, 4.3597174343439006e-52, 1.8884218782951360e-49, 6.0637045694189279e-47, 1.4814159278355307e-44, 2.8142461042205111e-42, 4.2343947760097721e-40, 5.1264009327908215e-38, 5.0622696862483853e-36, 4.1261954854591773e-34, 2.8051622162519962e-32, 1.6053724151348174e-30, 7.7976718238941548e-29, 3.2382364130273421e-27, 1.1573493767550765e-25, 3.5810407352214098e-24, 9.6443805701337253e-23, 2.2718330011553644e-21, 4.7015694865721316e-20, 8.5828869554158906e-19, 1.3872615165495405e-17, 1.9920232649990639e-16, 2.5491665563098012e-15, 2.9155331883629833e-14, 2.9881593623355600e-13, 2.7511620846328702e-12, 2.2805223736764051e-11, 1.7055424914056455e-10, 1.1530186653890739e-09, 7.0587498965529012e-09, 3.9196764143747362e-08, 1.9772532357280954e-07, 9.0734367403526114e-07, 3.7926166158590859e-06, 1.4457032475544561e-05, 5.0311336988073622e-05, 1.6000468687262702e-04, 4.6545282707817341e-04, 1.2395239105761761e-03, 3.0241014828653783e-03, 6.7638384706753211e-03, 1.3877372041544333e-02, 2.6131824932046500e-02, 4.5183798113816530e-02, 7.1766149805041285e-02, 1.0474325576824089e-01, 1.4051423956652490e-01, 1.7329818332155345e-01, 1.9652247660560301e-01, 2.0493398052053613e-01, 1.9652247660560301e-01, 1.7329818332155345e-01, 1.4051423956652490e-01, 1.0474325576824089e-01, 7.1766149805041285e-02, 4.5183798113816530e-02, 2.6131824932046500e-02, 1.3877372041544333e-02, 6.7638384706753211e-03, 3.0241014828653783e-03, 1.2395239105761761e-03, 4.6545282707817341e-04, 1.6000468687262702e-04, 5.0311336988073622e-05, 1.4457032475544561e-05, 3.7926166158590859e-06, 9.0734367403526114e-07, 1.9772532357280954e-07, 3.9196764143747362e-08, 7.0587498965529012e-09, 1.1530186653890739e-09, 1.7055424914056455e-10, 2.2805223736764051e-11, 2.7511620846328702e-12, 2.9881593623355600e-13, 2.9155331883629833e-14, 2.5491665563098012e-15, 1.9920232649990639e-16, 1.3872615165495405e-17, 8.5828869554158906e-19, 4.7015694865721316e-20, 2.2718330011553644e-21, 9.6443805701337253e-23, 3.5810407352214098e-24, 1.1573493767550765e-25, 3.2382364130273421e-27, 7.7976718238941548e-29, 1.6053724151348174e-30, 2.8051622162519962e-32, 4.1261954854591773e-34, 5.0622696862483853e-36, 5.1264009327908215e-38, 4.2343947760097721e-40, 2.8142461042205111e-42, 1.4814159278355307e-44, 6.0637045694189279e-47, 1.8884218782951360e-49, 4.3597174343439006e-52, 7.2291385544928827e-55, 8.2793896913033925e-58, 6.2331956354059190e-61, 2.8926678180441972e-64, 7.5888934406190700e-68, 9.9634282798974572e-72, 5.4525421540759655e-76, 9.2107100141581600e-81, 2.7098206745663592e-86, 3.2301009543101099e-93}, + {4.6632605618348153e-94, 4.1175713624143213e-87, 1.4612038470881841e-81, 8.9943320432041730e-77, 1.7046189545614933e-72, 1.3442523656293476e-68, 5.2981258920312120e-65, 1.1793052736766146e-61, 1.6168482075284075e-58, 1.4562812961539782e-55, 9.0550269871980438e-53, 4.0423080380262144e-50, 1.3372947653240557e-47, 3.3652104040755819e-45, 6.5834566491742290e-43, 1.0199300069374435e-40, 1.2712364015219454e-38, 1.2922794919134986e-36, 1.0842626381128112e-34, 7.5875981466261195e-33, 4.4697458344428785e-31, 2.2348156961076159e-29, 9.5537375722030760e-28, 3.5151519348961093e-26, 1.1197954114046576e-24, 3.1052469143218520e-23, 7.5325222776132763e-22, 1.6054837533511592e-20, 3.0189715471734914e-19, 5.0270892648593941e-18, 7.4380949511123831e-17, 9.8097342377809155e-16, 1.1565317290963977e-14, 1.2221338000525176e-13, 1.1603996128858022e-12, 9.9222265232533288e-12, 7.6565621148965857e-11, 5.3422379271962827e-10, 3.3764133497574799e-09, 1.9362011885244885e-08, 1.0089574633621321e-07, 4.7845042712908339e-07, 2.0673284334051564e-06, 8.1491561908568428e-06, 2.9337744635072858e-05, 9.6558931405380603e-05, 2.9081250785794189e-04, 8.0215126322350460e-04, 2.0279429361286859e-03, 4.7023255147965815e-03, 1.0006845717689308e-02, 1.9554616052364186e-02, 3.5105886050128668e-02, 5.7925787803644498e-02, 8.7878107549790321e-02, 1.2261249660444425e-01, 1.5737520760258733e-01, 1.8584966291329158e-01, 2.0195836706954076e-01, 2.0195836706954076e-01, 1.8584966291329158e-01, 1.5737520760258733e-01, 1.2261249660444425e-01, 8.7878107549790321e-02, 5.7925787803644498e-02, 3.5105886050128668e-02, 1.9554616052364186e-02, 1.0006845717689308e-02, 4.7023255147965815e-03, 2.0279429361286859e-03, 8.0215126322350460e-04, 2.9081250785794189e-04, 9.6558931405380603e-05, 2.9337744635072858e-05, 8.1491561908568428e-06, 2.0673284334051564e-06, 4.7845042712908339e-07, 1.0089574633621321e-07, 1.9362011885244885e-08, 3.3764133497574799e-09, 5.3422379271962827e-10, 7.6565621148965857e-11, 9.9222265232533288e-12, 1.1603996128858022e-12, 1.2221338000525176e-13, 1.1565317290963977e-14, 9.8097342377809155e-16, 7.4380949511123831e-17, 5.0270892648593941e-18, 3.0189715471734914e-19, 1.6054837533511592e-20, 7.5325222776132763e-22, 3.1052469143218520e-23, 1.1197954114046576e-24, 3.5151519348961093e-26, 9.5537375722030760e-28, 2.2348156961076159e-29, 4.4697458344428785e-31, 7.5875981466261195e-33, 1.0842626381128112e-34, 1.2922794919134986e-36, 1.2712364015219454e-38, 1.0199300069374435e-40, 6.5834566491742290e-43, 3.3652104040755819e-45, 1.3372947653240557e-47, 4.0423080380262144e-50, 9.0550269871980438e-53, 1.4562812961539782e-55, 1.6168482075284075e-58, 1.1793052736766146e-61, 5.2981258920312120e-65, 1.3442523656293476e-68, 1.7046189545614933e-72, 8.9943320432041730e-77, 1.4612038470881841e-81, 4.1175713624143213e-87, 4.6632605618348153e-94}, + {6.7298368161176175e-95, 6.2524679295400819e-88, 2.3159244482213129e-82, 1.4819345628019795e-77, 2.9122929849292479e-73, 2.3772467547464570e-69, 9.6859162631794203e-66, 2.2265944526096699e-62, 3.1502482452041196e-59, 2.9262669926463904e-56, 1.8755830649756743e-53, 8.6273958082206037e-51, 2.9399528685004811e-48, 7.6185958106575033e-46, 1.5345315352659727e-43, 2.4472631035773749e-41, 3.1395792592468297e-39, 3.2847155364958309e-37, 2.8362637361915701e-35, 2.0425551530268673e-33, 1.2382461823632275e-31, 6.3712964630586884e-30, 2.8030942195831802e-28, 1.0614795301061955e-26, 3.4805041051243282e-25, 9.9351833121692472e-24, 2.4810981347002888e-22, 5.4448704650642035e-21, 1.0543376862850843e-19, 1.8081886383358570e-18, 2.7559344338025971e-17, 3.7447612695692442e-16, 4.5495653050067822e-15, 4.9552804559564594e-14, 4.8505588604403995e-13, 4.2769240959330674e-12, 3.4041116737305440e-11, 2.4505079134311513e-10, 1.5983528945271918e-09, 9.4619152361816427e-09, 5.0915075227638090e-08, 2.4939923966935258e-07, 1.1135208095853982e-06, 4.5371664146194656e-06, 1.6890448115948282e-05, 5.7506280394736890e-05, 1.7923272339346707e-04, 5.1182575908404512e-04, 1.3402041554580024e-03, 3.2201249358166924e-03, 7.1040413328426078e-03, 1.4398510037728523e-02, 2.6824309528990144e-02, 4.5954734368354178e-02, 7.2424817070363218e-02, 1.0503603365193327e-01, 1.4021530912606431e-01, 1.7232400830089628e-01, 1.9500749227238295e-01, 2.0321184623044758e-01, 1.9500749227238295e-01, 1.7232400830089628e-01, 1.4021530912606431e-01, 1.0503603365193327e-01, 7.2424817070363218e-02, 4.5954734368354178e-02, 2.6824309528990144e-02, 1.4398510037728523e-02, 7.1040413328426078e-03, 3.2201249358166924e-03, 1.3402041554580024e-03, 5.1182575908404512e-04, 1.7923272339346707e-04, 5.7506280394736890e-05, 1.6890448115948282e-05, 4.5371664146194656e-06, 1.1135208095853982e-06, 2.4939923966935258e-07, 5.0915075227638090e-08, 9.4619152361816427e-09, 1.5983528945271918e-09, 2.4505079134311513e-10, 3.4041116737305440e-11, 4.2769240959330674e-12, 4.8505588604403995e-13, 4.9552804559564594e-14, 4.5495653050067822e-15, 3.7447612695692442e-16, 2.7559344338025971e-17, 1.8081886383358570e-18, 1.0543376862850843e-19, 5.4448704650642035e-21, 2.4810981347002888e-22, 9.9351833121692472e-24, 3.4805041051243282e-25, 1.0614795301061955e-26, 2.8030942195831802e-28, 6.3712964630586884e-30, 1.2382461823632275e-31, 2.0425551530268673e-33, 2.8362637361915701e-35, 3.2847155364958309e-37, 3.1395792592468297e-39, 2.4472631035773749e-41, 1.5345315352659727e-43, 7.6185958106575033e-46, 2.9399528685004811e-48, 8.6273958082206037e-51, 1.8755830649756743e-53, 2.9262669926463904e-56, 3.1502482452041196e-59, 2.2265944526096699e-62, 9.6859162631794203e-66, 2.3772467547464570e-69, 2.9122929849292479e-73, 1.4819345628019795e-77, 2.3159244482213129e-82, 6.2524679295400819e-88, 6.7298368161176175e-95}, + {9.7087403173561320e-96, 9.4880223969421335e-89, 3.6672428899258345e-83, 2.4388595277598848e-78, 4.9686800178709975e-74, 4.1972934212808472e-70, 1.7675264508544507e-66, 4.1953576796012743e-63, 6.1240687137526128e-60, 5.8655575443381544e-57, 3.8745058915294428e-54, 1.8359883902918249e-51, 6.4431660432386704e-49, 1.7190498209667764e-46, 3.5641227393846403e-44, 5.8499085615955162e-42, 7.7228330960795927e-40, 8.3138040908205878e-38, 7.3861592386371398e-36, 5.4726905931533611e-34, 3.4133817510443908e-32, 1.8070157219004075e-30, 8.1797979499699255e-29, 3.1872062136052619e-27, 1.0753877987999934e-25, 3.1590858369572161e-24, 8.1196497360506958e-23, 1.8341746417696775e-21, 3.6563781425498920e-20, 6.4565140315879466e-19, 1.0133911369582986e-17, 1.4182835695860085e-16, 1.7750978597330652e-15, 1.9921528797000957e-14, 2.0097524571107850e-13, 1.8267486127018911e-12, 1.4991784686824891e-11, 1.1130625000696823e-10, 7.4897520452156729e-10, 4.5753933756254367e-09, 2.5414386492665182e-08, 1.2854272339650551e-07, 5.9280419576037410e-07, 2.4957777427586521e-06, 9.6033945516455336e-06, 3.3808196410240332e-05, 1.0899702609675318e-04, 3.2209543490435076e-04, 8.7313245576434379e-04, 2.1727898312954579e-03, 4.9668732525919509e-03, 1.0435962135902662e-02, 2.0164796980741757e-02, 3.5848215647758121e-02, 5.8657999750043426e-02, 8.8373210437321048e-02, 1.2262242405763166e-01, 1.5673726302678062e-01, 1.8458665957131964e-01, 2.0030984626187961e-01, 2.0030984626187961e-01, 1.8458665957131964e-01, 1.5673726302678062e-01, 1.2262242405763166e-01, 8.8373210437321048e-02, 5.8657999750043426e-02, 3.5848215647758121e-02, 2.0164796980741757e-02, 1.0435962135902662e-02, 4.9668732525919509e-03, 2.1727898312954579e-03, 8.7313245576434379e-04, 3.2209543490435076e-04, 1.0899702609675318e-04, 3.3808196410240332e-05, 9.6033945516455336e-06, 2.4957777427586521e-06, 5.9280419576037410e-07, 1.2854272339650551e-07, 2.5414386492665182e-08, 4.5753933756254367e-09, 7.4897520452156729e-10, 1.1130625000696823e-10, 1.4991784686824891e-11, 1.8267486127018911e-12, 2.0097524571107850e-13, 1.9921528797000957e-14, 1.7750978597330652e-15, 1.4182835695860085e-16, 1.0133911369582986e-17, 6.4565140315879466e-19, 3.6563781425498920e-20, 1.8341746417696775e-21, 8.1196497360506958e-23, 3.1590858369572161e-24, 1.0753877987999934e-25, 3.1872062136052619e-27, 8.1797979499699255e-29, 1.8070157219004075e-30, 3.4133817510443908e-32, 5.4726905931533611e-34, 7.3861592386371398e-36, 8.3138040908205878e-38, 7.7228330960795927e-40, 5.8499085615955162e-42, 3.5641227393846403e-44, 1.7190498209667764e-46, 6.4431660432386704e-49, 1.8359883902918249e-51, 3.8745058915294428e-54, 5.8655575443381544e-57, 6.1240687137526128e-60, 4.1953576796012743e-63, 1.7675264508544507e-66, 4.1972934212808472e-70, 4.9686800178709975e-74, 2.4388595277598848e-78, 3.6672428899258345e-83, 9.4880223969421335e-89, 9.7087403173561320e-96}, + {1.4001253071178789e-96, 1.4388577548096490e-89, 5.8017947700800046e-84, 4.0091236159545663e-79, 8.4655265882771739e-75, 7.3990554223004025e-71, 3.2196574821489126e-67, 7.8890210982671253e-64, 1.1878725902550843e-60, 1.1728639625604033e-57, 7.9826611475407281e-55, 3.8960048884898755e-52, 1.4077485752140258e-49, 3.8661220025482209e-47, 8.2491446524855651e-45, 1.3931625443392332e-42, 1.8922123418053773e-40, 2.0955223902923607e-38, 1.9150597358365338e-36, 1.4595508732329443e-34, 9.3637976764322119e-33, 5.0989613303209105e-31, 2.3742569610821154e-29, 9.5165969692199733e-28, 3.3033284608828233e-26, 9.9838789745986388e-25, 2.6403982498871405e-23, 6.1378568842560367e-22, 1.2592940912286238e-20, 2.2889503956241953e-19, 3.6986721862085567e-18, 5.3301125275267336e-17, 6.8703687643915730e-16, 7.9423755813393362e-15, 8.2552749332412685e-14, 7.7326044861505372e-13, 6.5412509847214547e-12, 5.0072069799282932e-11, 3.4747667141215967e-10, 2.1897184637878725e-09, 1.2550651872012550e-08, 6.5522732997355584e-08, 3.1199715417437437e-07, 1.3566980827714974e-06, 5.3937313862223019e-06, 1.9625894008346668e-05, 6.5422509840297027e-05, 1.9997290405207970e-04, 5.6094024606844449e-04, 1.4450639870005968e-03, 3.4211784137958604e-03, 7.4481168960531027e-03, 1.4918844448036933e-02, 2.7507458506267436e-02, 4.6706206412519734e-02, 7.3057392793912337e-02, 1.0530541916565815e-01, 1.3990756676688021e-01, 1.7136352815479530e-01, 1.9352684051681762e-01, 2.0153240948474130e-01, 1.9352684051681762e-01, 1.7136352815479530e-01, 1.3990756676688021e-01, 1.0530541916565815e-01, 7.3057392793912337e-02, 4.6706206412519734e-02, 2.7507458506267436e-02, 1.4918844448036933e-02, 7.4481168960531027e-03, 3.4211784137958604e-03, 1.4450639870005968e-03, 5.6094024606844449e-04, 1.9997290405207970e-04, 6.5422509840297027e-05, 1.9625894008346668e-05, 5.3937313862223019e-06, 1.3566980827714974e-06, 3.1199715417437437e-07, 6.5522732997355584e-08, 1.2550651872012550e-08, 2.1897184637878725e-09, 3.4747667141215967e-10, 5.0072069799282932e-11, 6.5412509847214547e-12, 7.7326044861505372e-13, 8.2552749332412685e-14, 7.9423755813393362e-15, 6.8703687643915730e-16, 5.3301125275267336e-17, 3.6986721862085567e-18, 2.2889503956241953e-19, 1.2592940912286238e-20, 6.1378568842560367e-22, 2.6403982498871405e-23, 9.9838789745986388e-25, 3.3033284608828233e-26, 9.5165969692199733e-28, 2.3742569610821154e-29, 5.0989613303209105e-31, 9.3637976764322119e-33, 1.4595508732329443e-34, 1.9150597358365338e-36, 2.0955223902923607e-38, 1.8922123418053773e-40, 1.3931625443392332e-42, 8.2491446524855651e-45, 3.8661220025482209e-47, 1.4077485752140258e-49, 3.8960048884898755e-52, 7.9826611475407281e-55, 1.1728639625604033e-57, 1.1878725902550843e-60, 7.8890210982671253e-64, 3.2196574821489126e-67, 7.3990554223004025e-71, 8.4655265882771739e-75, 4.0091236159545663e-79, 5.8017947700800046e-84, 1.4388577548096490e-89, 1.4001253071178789e-96}, + {2.0184534275095049e-97, 2.1806296158265287e-90, 9.1706055028522197e-85, 6.5830036453656527e-80, 1.4403978976524620e-75, 1.3022823162971665e-71, 5.8544142858486073e-68, 1.4805274033207088e-64, 2.2990511219174665e-61, 2.3396177274687451e-58, 1.6403928051497794e-55, 8.2441788250067191e-53, 3.0664667336421114e-50, 8.6667923231989335e-48, 1.9026918231732264e-45, 3.3057067086043009e-43, 4.6182598989607685e-41, 5.2602254003426042e-39, 4.9438860107310490e-37, 3.8749094400485918e-35, 2.5564844139368277e-33, 1.4316070974387265e-31, 6.8553849798952103e-30, 2.8259664729965746e-28, 1.0088930738432750e-26, 3.1364243262134751e-25, 8.5327296120897214e-24, 2.0406372113926846e-22, 4.3078486936244584e-21, 8.0577481866273284e-20, 1.3400866628758495e-18, 1.9879461273563199e-17, 2.6381930823541892e-16, 3.1406382865933653e-15, 3.3622360761898003e-14, 3.2444814316722348e-13, 2.8281489919728500e-12, 2.2313290142958860e-11, 1.5963585528134907e-10, 1.0373981456665397e-09, 6.1333415530709063e-09, 3.3038743448338228e-08, 1.6237364967913452e-07, 7.2898765543366947e-07, 2.9932498983591025e-06, 1.1252541495603299e-05, 3.8767965827716168e-05, 1.2251950121646584e-04, 3.5547512496610876e-04, 9.4757899341760905e-04, 2.3223308982827312e-03, 5.2360833859067743e-03, 1.0866914248342787e-02, 2.0770153886127483e-02, 3.6576106509803016e-02, 5.9366942312670930e-02, 8.8842708636295842e-02, 1.2261541377174207e-01, 1.5610147984994696e-01, 1.8334823578007414e-01, 1.9870103704081624e-01, 1.9870103704081624e-01, 1.8334823578007414e-01, 1.5610147984994696e-01, 1.2261541377174207e-01, 8.8842708636295842e-02, 5.9366942312670930e-02, 3.6576106509803016e-02, 2.0770153886127483e-02, 1.0866914248342787e-02, 5.2360833859067743e-03, 2.3223308982827312e-03, 9.4757899341760905e-04, 3.5547512496610876e-04, 1.2251950121646584e-04, 3.8767965827716168e-05, 1.1252541495603299e-05, 2.9932498983591025e-06, 7.2898765543366947e-07, 1.6237364967913452e-07, 3.3038743448338228e-08, 6.1333415530709063e-09, 1.0373981456665397e-09, 1.5963585528134907e-10, 2.2313290142958860e-11, 2.8281489919728500e-12, 3.2444814316722348e-13, 3.3622360761898003e-14, 3.1406382865933653e-15, 2.6381930823541892e-16, 1.9879461273563199e-17, 1.3400866628758495e-18, 8.0577481866273284e-20, 4.3078486936244584e-21, 2.0406372113926846e-22, 8.5327296120897214e-24, 3.1364243262134751e-25, 1.0088930738432750e-26, 2.8259664729965746e-28, 6.8553849798952103e-30, 1.4316070974387265e-31, 2.5564844139368277e-33, 3.8749094400485918e-35, 4.9438860107310490e-37, 5.2602254003426042e-39, 4.6182598989607685e-41, 3.3057067086043009e-43, 1.9026918231732264e-45, 8.6667923231989335e-48, 3.0664667336421114e-50, 8.2441788250067191e-53, 1.6403928051497794e-55, 2.3396177274687451e-58, 2.2990511219174665e-61, 1.4805274033207088e-64, 5.8544142858486073e-68, 1.3022823162971665e-71, 1.4403978976524620e-75, 6.5830036453656527e-80, 9.1706055028522197e-85, 2.1806296158265287e-90, 2.0184534275095049e-97}, + {2.9088440757674062e-98, 3.3027195553941757e-91, 1.4482784276490109e-85, 1.0797361898132115e-80, 2.4475687753038470e-76, 2.2885780042663531e-72, 1.0626701542492299e-68, 2.7730751722659017e-65, 4.4400764524986828e-62, 4.6560392499732150e-59, 3.3622797072552750e-56, 1.7396913258105826e-53, 6.6597646076210362e-51, 1.9366833085713306e-48, 4.3737554297590874e-46, 7.8155861441480535e-44, 1.1228680356492188e-41, 1.3151165218678305e-39, 1.2708875196505519e-37, 1.0241410150378061e-35, 6.9469156975836022e-34, 3.9996687161846431e-32, 1.9692128985290527e-30, 8.3465290951830949e-29, 3.0639885163656867e-27, 9.7951708742326283e-26, 2.7405597239380626e-24, 6.7411887298015296e-23, 1.4638683297363268e-21, 2.8169790254203712e-20, 4.8205257099851608e-19, 7.3591325007878809e-18, 1.0052255425278666e-16, 1.2319403285686423e-15, 1.3580008734485746e-14, 1.3496086984992707e-13, 1.2118575324056077e-12, 9.8514672314148016e-12, 7.2637761188053839e-11, 4.8661361388782973e-10, 2.9666085963352118e-09, 1.6482913905846427e-08, 8.3579939555984911e-08, 3.8727287415554441e-07, 1.6416874675897103e-06, 6.3737479499140128e-06, 2.2686436750985634e-05, 7.4097922186640899e-05, 2.2227085873416057e-04, 6.1281987967776825e-04, 1.5540467884754450e-03, 3.6270593070595858e-03, 7.7957038787030220e-03, 1.5437973179493971e-02, 2.8181096910943754e-02, 4.7438564768728979e-02, 7.3664835869183778e-02, 1.0555264545810959e-01, 1.3959184263252383e-01, 1.7041655690534233e-01, 1.9207925104318502e-01, 1.9989393461088162e-01, 1.9207925104318502e-01, 1.7041655690534233e-01, 1.3959184263252383e-01, 1.0555264545810959e-01, 7.3664835869183778e-02, 4.7438564768728979e-02, 2.8181096910943754e-02, 1.5437973179493971e-02, 7.7957038787030220e-03, 3.6270593070595858e-03, 1.5540467884754450e-03, 6.1281987967776825e-04, 2.2227085873416057e-04, 7.4097922186640899e-05, 2.2686436750985634e-05, 6.3737479499140128e-06, 1.6416874675897103e-06, 3.8727287415554441e-07, 8.3579939555984911e-08, 1.6482913905846427e-08, 2.9666085963352118e-09, 4.8661361388782973e-10, 7.2637761188053839e-11, 9.8514672314148016e-12, 1.2118575324056077e-12, 1.3496086984992707e-13, 1.3580008734485746e-14, 1.2319403285686423e-15, 1.0052255425278666e-16, 7.3591325007878809e-18, 4.8205257099851608e-19, 2.8169790254203712e-20, 1.4638683297363268e-21, 6.7411887298015296e-23, 2.7405597239380626e-24, 9.7951708742326283e-26, 3.0639885163656867e-27, 8.3465290951830949e-29, 1.9692128985290527e-30, 3.9996687161846431e-32, 6.9469156975836022e-34, 1.0241410150378061e-35, 1.2708875196505519e-37, 1.3151165218678305e-39, 1.1228680356492188e-41, 7.8155861441480535e-44, 4.3737554297590874e-46, 1.9366833085713306e-48, 6.6597646076210362e-51, 1.7396913258105826e-53, 3.3622797072552750e-56, 4.6560392499732150e-59, 4.4400764524986828e-62, 2.7730751722659017e-65, 1.0626701542492299e-68, 2.2885780042663531e-72, 2.4475687753038470e-76, 1.0797361898132115e-80, 1.4482784276490109e-85, 3.3027195553941757e-91, 2.9088440757674062e-98}, + {4.1905794490628812e-99, 4.9990906972957580e-92, 2.2852295477811565e-86, 1.7690369566797577e-81, 4.1535499466158161e-77, 4.0157584892449402e-73, 1.9255984704437394e-69, 5.1840723409278860e-66, 8.5567547361303599e-63, 9.2443848020406234e-60, 6.8742017262988808e-57, 3.6611032011247543e-54, 1.4421371050636836e-51, 4.3141707603430363e-49, 1.0020507711410342e-46, 1.8412712525866596e-44, 2.7198617815524323e-42, 3.2749113002444449e-40, 3.2533264664077919e-38, 2.6949141835666013e-36, 1.8790207698162015e-34, 1.1120314056802636e-32, 5.6279071396682005e-31, 2.4520940513432773e-29, 9.2537661461189014e-28, 3.0414019572106789e-26, 8.7492009712123219e-25, 2.2129732702532020e-23, 4.9419868423536690e-22, 9.7813379414413797e-21, 1.7218091698469169e-19, 2.7043296085128987e-18, 3.8011128040478799e-17, 4.7943347392243567e-16, 5.4401721259012553e-15, 5.5664982903187763e-14, 5.1473099468312146e-13, 4.3100503800704298e-12, 3.2741601230785952e-11, 2.2604055819337785e-10, 1.4204990214913607e-09, 8.1379035349171669e-09, 4.2560154044109738e-08, 2.0345626953177357e-07, 8.9008863258739004e-07, 3.5675339063854564e-06, 1.3113467580430861e-05, 4.4247522456022853e-05, 1.3716931938884588e-04, 3.9098949747131122e-04, 1.0254795244170039e-03, 2.4764405325003970e-03, 5.5096709995779728e-03, 1.1299305506959472e-02, 2.1370374426895520e-02, 3.7289628484137964e-02, 6.0053278089003327e-02, 8.9287739344200062e-02, 1.2259255262751995e-01, 1.5546821084992313e-01, 1.8213364120711689e-01, 1.9713037059257607e-01, 1.9713037059257607e-01, 1.8213364120711689e-01, 1.5546821084992313e-01, 1.2259255262751995e-01, 8.9287739344200062e-02, 6.0053278089003327e-02, 3.7289628484137964e-02, 2.1370374426895520e-02, 1.1299305506959472e-02, 5.5096709995779728e-03, 2.4764405325003970e-03, 1.0254795244170039e-03, 3.9098949747131122e-04, 1.3716931938884588e-04, 4.4247522456022853e-05, 1.3113467580430861e-05, 3.5675339063854564e-06, 8.9008863258739004e-07, 2.0345626953177357e-07, 4.2560154044109738e-08, 8.1379035349171669e-09, 1.4204990214913607e-09, 2.2604055819337785e-10, 3.2741601230785952e-11, 4.3100503800704298e-12, 5.1473099468312146e-13, 5.5664982903187763e-14, 5.4401721259012553e-15, 4.7943347392243567e-16, 3.8011128040478799e-17, 2.7043296085128987e-18, 1.7218091698469169e-19, 9.7813379414413797e-21, 4.9419868423536690e-22, 2.2129732702532020e-23, 8.7492009712123219e-25, 3.0414019572106789e-26, 9.2537661461189014e-28, 2.4520940513432773e-29, 5.6279071396682005e-31, 1.1120314056802636e-32, 1.8790207698162015e-34, 2.6949141835666013e-36, 3.2533264664077919e-38, 3.2749113002444449e-40, 2.7198617815524323e-42, 1.8412712525866596e-44, 1.0020507711410342e-46, 4.3141707603430363e-49, 1.4421371050636836e-51, 3.6611032011247543e-54, 6.8742017262988808e-57, 9.2443848020406234e-60, 8.5567547361303599e-63, 5.1840723409278860e-66, 1.9255984704437394e-69, 4.0157584892449402e-73, 4.1535499466158161e-77, 1.7690369566797577e-81, 2.2852295477811565e-86, 4.9990906972957580e-92, 4.1905794490628812e-99}, + {6.0350604964534262e-100, 7.5621198682031623e-93, 3.6027698446759891e-87, 2.8952659291406100e-82, 7.0395367135995835e-78, 7.0359072121742493e-74, 3.4833403833073089e-70, 9.6729013253984892e-67, 1.6455761362144333e-63, 1.8312341591411876e-60, 1.4019398864694188e-57, 7.6839475145600301e-55, 3.1138694261390015e-52, 9.5806542034971832e-50, 2.2882121049633724e-47, 4.3227155768633621e-45, 6.5638401618338331e-43, 8.1233879274180601e-41, 8.2938969771250512e-39, 7.0606944403026099e-37, 5.0593403396440372e-35, 3.0770662798790086e-33, 1.6004068212453668e-31, 7.1663558200524862e-30, 2.7795790004930404e-28, 9.3899224442264679e-27, 2.7766379169834465e-25, 7.2198960174204195e-24, 1.6577060031062816e-22, 3.3737146353721905e-21, 6.1074208727145320e-20, 9.8664119741289685e-19, 1.4266141735959953e-17, 1.8513770722928222e-16, 2.1618705462400890e-15, 2.2768505441090677e-14, 2.1674951892336612e-13, 1.8688765345567561e-12, 1.4622404081860438e-11, 1.0399946851470756e-10, 6.7347582712586187e-10, 3.9769084715886220e-09, 2.1444167115213114e-08, 1.0572466663977363e-07, 4.7716606625319424e-07, 1.9736622489528508e-06, 7.4891717673847164e-06, 2.6095502713919602e-05, 8.3569751965942746e-05, 2.4616923611611111e-04, 6.6748228082773623e-04, 1.6670890148279265e-03, 3.8375633568742918e-03, 8.1464528080591927e-03, 1.5955521786480558e-02, 2.8845081137418717e-02, 4.8152169340609514e-02, 7.4248071076568556e-02, 1.0577887521500248e-01, 1.3926890249425167e-01, 1.6948290095730328e-01, 1.9066351798670744e-01, 1.9829478313399460e-01, 1.9066351798670744e-01, 1.6948290095730328e-01, 1.3926890249425167e-01, 1.0577887521500248e-01, 7.4248071076568556e-02, 4.8152169340609514e-02, 2.8845081137418717e-02, 1.5955521786480558e-02, 8.1464528080591927e-03, 3.8375633568742918e-03, 1.6670890148279265e-03, 6.6748228082773623e-04, 2.4616923611611111e-04, 8.3569751965942746e-05, 2.6095502713919602e-05, 7.4891717673847164e-06, 1.9736622489528508e-06, 4.7716606625319424e-07, 1.0572466663977363e-07, 2.1444167115213114e-08, 3.9769084715886220e-09, 6.7347582712586187e-10, 1.0399946851470756e-10, 1.4622404081860438e-11, 1.8688765345567561e-12, 2.1674951892336612e-13, 2.2768505441090677e-14, 2.1618705462400890e-15, 1.8513770722928222e-16, 1.4266141735959953e-17, 9.8664119741289685e-19, 6.1074208727145320e-20, 3.3737146353721905e-21, 1.6577060031062816e-22, 7.2198960174204195e-24, 2.7766379169834465e-25, 9.3899224442264679e-27, 2.7795790004930404e-28, 7.1663558200524862e-30, 1.6004068212453668e-31, 3.0770662798790086e-33, 5.0593403396440372e-35, 7.0606944403026099e-37, 8.2938969771250512e-39, 8.1233879274180601e-41, 6.5638401618338331e-43, 4.3227155768633621e-45, 2.2882121049633724e-47, 9.5806542034971832e-50, 3.1138694261390015e-52, 7.6839475145600301e-55, 1.4019398864694188e-57, 1.8312341591411876e-60, 1.6455761362144333e-63, 9.6729013253984892e-67, 3.4833403833073089e-70, 7.0359072121742493e-74, 7.0395367135995835e-78, 2.8952659291406100e-82, 3.6027698446759891e-87, 7.5621198682031623e-93, 6.0350604964534262e-100}, + {8.6885048841104336e-101, 1.1432282229672125e-93, 5.6751482819801390e-88, 4.7334609039691596e-83, 1.1915620124280458e-78, 1.2309273526337388e-74, 6.2907076772692688e-71, 1.8014846076367508e-67, 3.1581319803836728e-64, 3.6193344722347900e-61, 2.8521414298372380e-58, 1.6084468211903416e-55, 6.7043872367938317e-53, 2.1211541634033625e-50, 5.2082971293259102e-48, 1.0113496653683935e-45, 1.5782902465389378e-43, 2.0072591434893221e-41, 2.1058526230258254e-39, 1.8420302384806772e-37, 1.3561579038335388e-35, 8.4745466577882083e-34, 4.5287460314884707e-32, 2.0836578377129600e-30, 8.3043823092881025e-29, 2.8828182366037129e-27, 8.7606149843747518e-26, 2.3412386562212859e-24, 5.5254399484537480e-23, 1.1560142775887639e-21, 2.1516151218938123e-20, 3.5742061956149856e-19, 5.3150514071326065e-18, 7.0949360015714532e-17, 8.5234045323955501e-16, 9.2369780981720531e-15, 9.0500846874230352e-14, 8.0327883964150772e-13, 6.4713186612400961e-12, 4.7401870432354588e-11, 3.1621598261836951e-10, 1.9240529197354846e-09, 1.0693195796935537e-08, 5.4353072977389075e-08, 2.5298490233788676e-07, 1.0794646043238905e-06, 4.2268677400739964e-06, 1.5203524203072556e-05, 5.0277271260002348e-05, 1.5298771765756425e-04, 4.2867197747952282e-04, 1.1068159448702048e-03, 2.6349882348356921e-03, 5.7873557283189625e-03, 1.1732759367031630e-02, 2.1965177289949588e-02, 3.7988873885061170e-02, 6.0717658137057637e-02, 8.9709385493087268e-02, 1.2255485603934885e-01, 1.5483776980551858e-01, 1.8094215487742904e-01, 1.9559636350108756e-01, 1.9559636350108756e-01, 1.8094215487742904e-01, 1.5483776980551858e-01, 1.2255485603934885e-01, 8.9709385493087268e-02, 6.0717658137057637e-02, 3.7988873885061170e-02, 2.1965177289949588e-02, 1.1732759367031630e-02, 5.7873557283189625e-03, 2.6349882348356921e-03, 1.1068159448702048e-03, 4.2867197747952282e-04, 1.5298771765756425e-04, 5.0277271260002348e-05, 1.5203524203072556e-05, 4.2268677400739964e-06, 1.0794646043238905e-06, 2.5298490233788676e-07, 5.4353072977389075e-08, 1.0693195796935537e-08, 1.9240529197354846e-09, 3.1621598261836951e-10, 4.7401870432354588e-11, 6.4713186612400961e-12, 8.0327883964150772e-13, 9.0500846874230352e-14, 9.2369780981720531e-15, 8.5234045323955501e-16, 7.0949360015714532e-17, 5.3150514071326065e-18, 3.5742061956149856e-19, 2.1516151218938123e-20, 1.1560142775887639e-21, 5.5254399484537480e-23, 2.3412386562212859e-24, 8.7606149843747518e-26, 2.8828182366037129e-27, 8.3043823092881025e-29, 2.0836578377129600e-30, 4.5287460314884707e-32, 8.4745466577882083e-34, 1.3561579038335388e-35, 1.8420302384806772e-37, 2.1058526230258254e-39, 2.0072591434893221e-41, 1.5782902465389378e-43, 1.0113496653683935e-45, 5.2082971293259102e-48, 2.1211541634033625e-50, 6.7043872367938317e-53, 1.6084468211903416e-55, 2.8521414298372380e-58, 3.6193344722347900e-61, 3.1581319803836728e-64, 1.8014846076367508e-67, 6.2907076772692688e-71, 1.2309273526337388e-74, 1.1915620124280458e-78, 4.7334609039691596e-83, 5.6751482819801390e-88, 1.1432282229672125e-93, 8.6885048841104336e-101}, + {1.2504497509175530e-101, 1.7272798059471284e-94, 8.9321681572258524e-89, 7.7306185241136030e-84, 2.0143957652711162e-79, 2.1503714733677984e-75, 1.1341924208630308e-71, 3.3489139011900278e-68, 6.0486548964206330e-65, 7.1375092946576251e-62, 5.7884563375067011e-59, 3.3581166223962448e-56, 1.4394641949298623e-53, 4.6821808383361703e-51, 1.1817054440721172e-48, 2.3581659156082481e-46, 3.7814427940915093e-44, 4.9411031115925398e-42, 5.3255303775590573e-40, 4.7854390680281889e-38, 3.6191883446065631e-36, 2.3232083386416384e-34, 1.2753331411048401e-32, 6.0277753850946330e-31, 2.4679773241853991e-29, 8.8019567691972675e-28, 2.7482489212126092e-26, 7.5468218903320873e-25, 1.8303134636337642e-23, 3.9355990860983814e-22, 7.5293161638815711e-21, 1.2857997786762843e-19, 1.9659326888507207e-18, 2.6986511907298130e-17, 3.3344414303302576e-16, 3.7173303125266623e-15, 3.7473954472956373e-14, 3.4230094493503872e-13, 2.8385303725081926e-12, 2.1406920290521382e-11, 1.4706331273477511e-10, 9.2173940967721533e-10, 5.2781663937137130e-09, 2.7650497045037171e-08, 1.3267855842580783e-07, 5.8380944276295039e-07, 2.3581561724849069e-06, 8.7524468034552877e-06, 2.9876790536001972e-05, 9.3874435720364848e-05, 2.7170762628015821e-04, 7.2493929742724068e-04, 1.7841208326818967e-03, 4.0524855186172149e-03, 8.5000263041808636e-03, 1.6471142241660967e-02, 2.9499296248305443e-02, 4.8847387114452009e-02, 7.4807989768816377e-02, 1.0598520508123921e-01, 1.3893945309094766e-01, 1.6856236074260383e-01, 1.8927849580179334e-01, 1.9673340688884505e-01, 1.8927849580179334e-01, 1.6856236074260383e-01, 1.3893945309094766e-01, 1.0598520508123921e-01, 7.4807989768816377e-02, 4.8847387114452009e-02, 2.9499296248305443e-02, 1.6471142241660967e-02, 8.5000263041808636e-03, 4.0524855186172149e-03, 1.7841208326818967e-03, 7.2493929742724068e-04, 2.7170762628015821e-04, 9.3874435720364848e-05, 2.9876790536001972e-05, 8.7524468034552877e-06, 2.3581561724849069e-06, 5.8380944276295039e-07, 1.3267855842580783e-07, 2.7650497045037171e-08, 5.2781663937137130e-09, 9.2173940967721533e-10, 1.4706331273477511e-10, 2.1406920290521382e-11, 2.8385303725081926e-12, 3.4230094493503872e-13, 3.7473954472956373e-14, 3.7173303125266623e-15, 3.3344414303302576e-16, 2.6986511907298130e-17, 1.9659326888507207e-18, 1.2857997786762843e-19, 7.5293161638815711e-21, 3.9355990860983814e-22, 1.8303134636337642e-23, 7.5468218903320873e-25, 2.7482489212126092e-26, 8.8019567691972675e-28, 2.4679773241853991e-29, 6.0277753850946330e-31, 1.2753331411048401e-32, 2.3232083386416384e-34, 3.6191883446065631e-36, 4.7854390680281889e-38, 5.3255303775590573e-40, 4.9411031115925398e-42, 3.7814427940915093e-44, 2.3581659156082481e-46, 1.1817054440721172e-48, 4.6821808383361703e-51, 1.4394641949298623e-53, 3.3581166223962448e-56, 5.7884563375067011e-59, 7.1375092946576251e-62, 6.0486548964206330e-65, 3.3489139011900278e-68, 1.1341924208630308e-71, 2.1503714733677984e-75, 2.0143957652711162e-79, 7.7306185241136030e-84, 8.9321681572258524e-89, 1.7272798059471284e-94, 1.2504497509175530e-101}, + {1.7990659801093241e-102, 2.6081724024084728e-95, 1.4046897713151180e-89, 1.2612494833385409e-84, 3.4012300869368197e-80, 3.7512158688048432e-76, 2.0415857972441075e-72, 6.2142441618306433e-69, 1.1561551640964042e-65, 1.4044672577405165e-62, 1.1719785012130235e-59, 6.9930729240520693e-57, 3.0820773833392742e-54, 1.0304862520557101e-51, 2.6727437517360924e-49, 5.4802170289787664e-47, 9.0280401387865924e-45, 1.2117795341306277e-42, 1.3414974817643660e-40, 1.2380855579763670e-38, 9.6167080679676503e-37, 6.3399135263665769e-35, 3.5743788958794533e-33, 1.7351030202821157e-31, 7.2965450067684075e-30, 2.6729236200580738e-28, 8.5728304837693986e-27, 2.4184034596476935e-25, 6.0259840320064904e-24, 1.3313678590335932e-22, 2.6174575839348305e-21, 4.5940076773297253e-20, 7.2201073169282769e-19, 1.0189332304232922e-17, 1.2945481593393717e-16, 1.4842238375138792e-15, 1.5390497303535517e-14, 1.4463473211904274e-13, 1.2342144866005691e-12, 9.5803165087358731e-12, 6.7757804877745394e-11, 4.3731866598484108e-10, 2.5793972294264184e-09, 1.3921907152935201e-08, 6.8845811221543303e-08, 3.1228729861789030e-07, 1.3007470032382014e-06, 4.9799245325909927e-06, 1.7540485848093888e-05, 5.6887437600402582e-05, 1.7001408826280900e-04, 4.6855153780841227e-04, 1.1915638144571682e-03, 2.7978394016057863e-03, 6.0688624069258814e-03, 1.2166918864469335e-02, 2.2554310167824408e-02, 3.8673954810636818e-02, 6.1360721004490068e-02, 9.0108678376448870e-02, 1.2250327316413555e-01, 1.5421043529835440e-01, 1.7977308390779931e-01, 1.9409761186408808e-01, 1.9409761186408808e-01, 1.7977308390779931e-01, 1.5421043529835440e-01, 1.2250327316413555e-01, 9.0108678376448870e-02, 6.1360721004490068e-02, 3.8673954810636818e-02, 2.2554310167824408e-02, 1.2166918864469335e-02, 6.0688624069258814e-03, 2.7978394016057863e-03, 1.1915638144571682e-03, 4.6855153780841227e-04, 1.7001408826280900e-04, 5.6887437600402582e-05, 1.7540485848093888e-05, 4.9799245325909927e-06, 1.3007470032382014e-06, 3.1228729861789030e-07, 6.8845811221543303e-08, 1.3921907152935201e-08, 2.5793972294264184e-09, 4.3731866598484108e-10, 6.7757804877745394e-11, 9.5803165087358731e-12, 1.2342144866005691e-12, 1.4463473211904274e-13, 1.5390497303535517e-14, 1.4842238375138792e-15, 1.2945481593393717e-16, 1.0189332304232922e-17, 7.2201073169282769e-19, 4.5940076773297253e-20, 2.6174575839348305e-21, 1.3313678590335932e-22, 6.0259840320064904e-24, 2.4184034596476935e-25, 8.5728304837693986e-27, 2.6729236200580738e-28, 7.2965450067684075e-30, 1.7351030202821157e-31, 3.5743788958794533e-33, 6.3399135263665769e-35, 9.6167080679676503e-37, 1.2380855579763670e-38, 1.3414974817643660e-40, 1.2117795341306277e-42, 9.0280401387865924e-45, 5.4802170289787664e-47, 2.6727437517360924e-49, 1.0304862520557101e-51, 3.0820773833392742e-54, 6.9930729240520693e-57, 1.1719785012130235e-59, 1.4044672577405165e-62, 1.1561551640964042e-65, 6.2142441618306433e-69, 2.0415857972441075e-72, 3.7512158688048432e-76, 3.4012300869368197e-80, 1.2612494833385409e-84, 1.4046897713151180e-89, 2.6081724024084728e-95, 1.7990659801093241e-102}, + {2.5875539364524082e-103, 3.9360184590802221e-96, 2.2072552957748285e-90, 2.0556308729779607e-85, 5.7358476340730861e-81, 6.5345649901409931e-77, 3.6690360645455800e-73, 1.1510510197511481e-69, 2.2055377414515242e-66, 2.7576366331120112e-63, 2.3673174707161052e-60, 1.4525786040323095e-57, 6.5811912152939833e-55, 2.2613773295130902e-52, 6.0264301132977530e-50, 1.2693840763809051e-47, 2.1479177879979361e-45, 2.9609218353788539e-43, 3.3661609053282785e-41, 3.1901478352848241e-39, 2.5443979671277979e-37, 1.7223946532210455e-35, 9.9710553873521448e-34, 4.9700994335207590e-32, 2.1462063060723877e-30, 8.0737792155578718e-29, 2.6593692402816157e-27, 7.7051505318327598e-26, 1.9720496638158951e-24, 4.4757971347544071e-23, 9.0403370335874384e-22, 1.6303640703529370e-20, 2.6332049182645191e-19, 3.8194419802784429e-18, 4.9883327330781313e-17, 5.8802277275507751e-16, 6.2702394771473180e-15, 6.0607257135908391e-14, 5.3204907075388442e-13, 4.2495506587750072e-12, 3.0933020393247358e-11, 2.0552435298786022e-10, 1.2482251818681576e-09, 6.9389671445373625e-09, 3.5351823460523453e-08, 1.6525270457753961e-07, 7.0953503060139187e-07, 2.8010603367707380e-06, 1.0176471541446871e-05, 3.4054184172402124e-05, 1.0504748699764762e-04, 2.9892250594151955e-04, 7.8519722061027154e-04, 1.9050667392793649e-03, 4.2716207417923171e-03, 8.8560992639436561e-03, 1.6984511709158091e-02, 3.0143653484891619e-02, 4.9524590136894565e-02, 7.5345450641660414e-02, 1.0617266978963312e-01, 1.3860414698078849e-01, 1.6765473214361890e-01, 1.8792309546385810e-01, 1.9520834171916421e-01, 1.8792309546385810e-01, 1.6765473214361890e-01, 1.3860414698078849e-01, 1.0617266978963312e-01, 7.5345450641660414e-02, 4.9524590136894565e-02, 3.0143653484891619e-02, 1.6984511709158091e-02, 8.8560992639436561e-03, 4.2716207417923171e-03, 1.9050667392793649e-03, 7.8519722061027154e-04, 2.9892250594151955e-04, 1.0504748699764762e-04, 3.4054184172402124e-05, 1.0176471541446871e-05, 2.8010603367707380e-06, 7.0953503060139187e-07, 1.6525270457753961e-07, 3.5351823460523453e-08, 6.9389671445373625e-09, 1.2482251818681576e-09, 2.0552435298786022e-10, 3.0933020393247358e-11, 4.2495506587750072e-12, 5.3204907075388442e-13, 6.0607257135908391e-14, 6.2702394771473180e-15, 5.8802277275507751e-16, 4.9883327330781313e-17, 3.8194419802784429e-18, 2.6332049182645191e-19, 1.6303640703529370e-20, 9.0403370335874384e-22, 4.4757971347544071e-23, 1.9720496638158951e-24, 7.7051505318327598e-26, 2.6593692402816157e-27, 8.0737792155578718e-29, 2.1462063060723877e-30, 4.9700994335207590e-32, 9.9710553873521448e-34, 1.7223946532210455e-35, 2.5443979671277979e-37, 3.1901478352848241e-39, 3.3661609053282785e-41, 2.9609218353788539e-43, 2.1479177879979361e-45, 1.2693840763809051e-47, 6.0264301132977530e-50, 2.2613773295130902e-52, 6.5811912152939833e-55, 1.4525786040323095e-57, 2.3673174707161052e-60, 2.7576366331120112e-63, 2.2055377414515242e-66, 1.1510510197511481e-69, 3.6690360645455800e-73, 6.5345649901409931e-77, 5.7358476340730861e-81, 2.0556308729779607e-85, 2.2072552957748285e-90, 3.9360184590802221e-96, 2.5875539364524082e-103}, + {3.7204460108518457e-104, 5.9364731594787663e-97, 3.4655965116643281e-91, 3.3469757581791224e-86, 9.6613261772636215e-82, 1.1367258528662723e-77, 6.5833865033387550e-74, 2.1283034461639501e-70, 4.1991937638649886e-67, 5.4030149717578019e-64, 4.7707625290237234e-61, 3.0097211186016156e-58, 1.4015247946309535e-55, 4.9483338463613849e-53, 1.3546817753059001e-50, 2.9307665929739616e-48, 5.0927511908300209e-46, 7.2087130229885203e-44, 8.4144007328158726e-42, 8.1870801342500945e-40, 6.7037119216509246e-38, 4.6587143166611642e-36, 2.7687058280430152e-34, 1.4168038025321554e-32, 6.2811433857681812e-31, 2.4259782593432643e-29, 8.2046076950332880e-28, 2.4409654886964413e-26, 6.4156025663739209e-25, 1.4954510277528916e-23, 3.1025363444064255e-22, 5.7477855676921120e-21, 9.5376732466503112e-20, 1.4215508257408722e-18, 1.9080516525917262e-17, 2.3119223992445814e-16, 2.5344536275316043e-15, 2.5189945152766989e-14, 2.2742721378405763e-13, 1.8685821935956322e-12, 1.3994739517759176e-11, 9.5692629429270517e-11, 5.9825297159286590e-10, 3.4243028086561824e-09, 1.7967512803433057e-08, 8.6525026250843954e-08, 3.8283102346903316e-07, 1.5578439536677208e-06, 5.8357960655860304e-06, 2.0142490747188856e-05, 6.4107957353545819e-05, 1.8828587640798520e-04, 5.1065276380199355e-04, 1.2796927737216395e-03, 2.9648560622765260e-03, 6.3539216222626869e-03, 1.2601446134450314e-02, 2.3137547830647125e-02, 3.9345000709058629e-02, 6.1983091960651798e-02, 9.0486600174251544e-02, 1.2243869169055180e-01, 1.5358645412541436e-01, 1.7862576228606980e-01, 1.9263278589714239e-01, 1.9263278589714239e-01, 1.7862576228606980e-01, 1.5358645412541436e-01, 1.2243869169055180e-01, 9.0486600174251544e-02, 6.1983091960651798e-02, 3.9345000709058629e-02, 2.3137547830647125e-02, 1.2601446134450314e-02, 6.3539216222626869e-03, 2.9648560622765260e-03, 1.2796927737216395e-03, 5.1065276380199355e-04, 1.8828587640798520e-04, 6.4107957353545819e-05, 2.0142490747188856e-05, 5.8357960655860304e-06, 1.5578439536677208e-06, 3.8283102346903316e-07, 8.6525026250843954e-08, 1.7967512803433057e-08, 3.4243028086561824e-09, 5.9825297159286590e-10, 9.5692629429270517e-11, 1.3994739517759176e-11, 1.8685821935956322e-12, 2.2742721378405763e-13, 2.5189945152766989e-14, 2.5344536275316043e-15, 2.3119223992445814e-16, 1.9080516525917262e-17, 1.4215508257408722e-18, 9.5376732466503112e-20, 5.7477855676921120e-21, 3.1025363444064255e-22, 1.4954510277528916e-23, 6.4156025663739209e-25, 2.4409654886964413e-26, 8.2046076950332880e-28, 2.4259782593432643e-29, 6.2811433857681812e-31, 1.4168038025321554e-32, 2.7687058280430152e-34, 4.6587143166611642e-36, 6.7037119216509246e-38, 8.1870801342500945e-40, 8.4144007328158726e-42, 7.2087130229885203e-44, 5.0927511908300209e-46, 2.9307665929739616e-48, 1.3546817753059001e-50, 4.9483338463613849e-53, 1.4015247946309535e-55, 3.0097211186016156e-58, 4.7707625290237234e-61, 5.4030149717578019e-64, 4.1991937638649886e-67, 2.1283034461639501e-70, 6.5833865033387550e-74, 1.1367258528662723e-77, 9.6613261772636215e-82, 3.3469757581791224e-86, 3.4655965116643281e-91, 5.9364731594787663e-97, 3.7204460108518457e-104}, + {5.3476826111026365e-105, 8.9485710679509321e-98, 5.4370243471100807e-92, 5.4441378603550616e-87, 1.6254006780310087e-82, 1.9746831356131776e-78, 1.1794217215696164e-74, 3.9284007348254153e-71, 7.9796183204186807e-68, 1.0563843092209409e-64, 9.5924087114315112e-62, 6.2207574186530967e-59, 2.9767954168841160e-56, 1.0797369730934170e-53, 3.0360436451965334e-51, 6.7450137912280108e-49, 1.2034270735300903e-46, 1.7487964745761127e-44, 2.0954606929273772e-42, 2.0928182450743565e-40, 1.7589155981687000e-38, 1.2546216106083190e-36, 7.6531182757967849e-35, 4.0196809205772165e-33, 1.8291657781800354e-31, 7.2519108515928950e-30, 2.5176731485459177e-28, 7.6897052483356061e-27, 2.0750476694679341e-25, 4.9664572942742541e-24, 1.0580876836793333e-22, 2.0131999550178635e-21, 3.4313613065500532e-20, 5.2539364144662411e-19, 7.2456324501572317e-18, 9.0217967422636200e-17, 1.0165109952415262e-15, 1.0385841011593362e-14, 9.6411044899350535e-14, 8.1461816331285264e-13, 6.2756146921948126e-12, 4.4148505508362490e-11, 2.8403341656010478e-10, 1.6734368028761769e-09, 9.0404035956869064e-09, 4.4835197499650446e-08, 2.0435322677073055e-07, 8.5687946165889204e-07, 3.3086178947400949e-06, 1.1774562755908359e-05, 3.8651667203812415e-05, 1.1712338225370822e-04, 3.2784720468186990e-04, 8.4825701574449603e-04, 2.0298461578116241e-03, 4.4947646714684642e-03, 9.2143589576985860e-03, 1.7495331329372001e-02, 3.0778087957022211e-02, 5.0184153739443245e-02, 7.5861280569172768e-02, 1.0634224601517195e-01, 1.3826358695373833e-01, 1.6675980772407939e-01, 1.8659628095711822e-01, 1.9371820170604062e-01, 1.8659628095711822e-01, 1.6675980772407939e-01, 1.3826358695373833e-01, 1.0634224601517195e-01, 7.5861280569172768e-02, 5.0184153739443245e-02, 3.0778087957022211e-02, 1.7495331329372001e-02, 9.2143589576985860e-03, 4.4947646714684642e-03, 2.0298461578116241e-03, 8.4825701574449603e-04, 3.2784720468186990e-04, 1.1712338225370822e-04, 3.8651667203812415e-05, 1.1774562755908359e-05, 3.3086178947400949e-06, 8.5687946165889204e-07, 2.0435322677073055e-07, 4.4835197499650446e-08, 9.0404035956869064e-09, 1.6734368028761769e-09, 2.8403341656010478e-10, 4.4148505508362490e-11, 6.2756146921948126e-12, 8.1461816331285264e-13, 9.6411044899350535e-14, 1.0385841011593362e-14, 1.0165109952415262e-15, 9.0217967422636200e-17, 7.2456324501572317e-18, 5.2539364144662411e-19, 3.4313613065500532e-20, 2.0131999550178635e-21, 1.0580876836793333e-22, 4.9664572942742541e-24, 2.0750476694679341e-25, 7.6897052483356061e-27, 2.5176731485459177e-28, 7.2519108515928950e-30, 1.8291657781800354e-31, 4.0196809205772165e-33, 7.6531182757967849e-35, 1.2546216106083190e-36, 1.7589155981687000e-38, 2.0928182450743565e-40, 2.0954606929273772e-42, 1.7487964745761127e-44, 1.2034270735300903e-46, 6.7450137912280108e-49, 3.0360436451965334e-51, 1.0797369730934170e-53, 2.9767954168841160e-56, 6.2207574186530967e-59, 9.5924087114315112e-62, 1.0563843092209409e-64, 7.9796183204186807e-68, 3.9284007348254153e-71, 1.1794217215696164e-74, 1.9746831356131776e-78, 1.6254006780310087e-82, 5.4441378603550616e-87, 5.4370243471100807e-92, 8.9485710679509321e-98, 5.3476826111026365e-105}, + {7.6842766516367719e-106, 1.3481426814084330e-98, 8.5232824201455338e-93, 8.8466828631703380e-88, 2.7313386049487823e-83, 3.4257032455364114e-79, 2.1096988030040495e-75, 7.2385503439630423e-72, 1.5134726683009566e-68, 2.0611376551597914e-65, 1.9243761113547505e-62, 1.2826427266230406e-59, 6.3061655444515630e-57, 2.3494568244414183e-54, 6.7840814198640183e-52, 1.5474546466895863e-49, 2.8342684935250220e-47, 4.2276037377430170e-45, 5.1990976532787586e-43, 5.3289760352121873e-41, 4.5962221753185640e-39, 3.3643504079348503e-37, 2.1059885157863759e-35, 1.1351213650894055e-33, 5.3008778122412928e-32, 2.1567929048213211e-30, 7.6849291812936124e-29, 2.4091492702687982e-27, 6.6731359742375955e-26, 1.6395930158211436e-24, 3.5862705417926132e-23, 7.0063164858326786e-22, 1.2263229445163221e-20, 1.9284904334361852e-19, 2.7319104369658748e-18, 3.4946872798000184e-17, 4.0459872349113726e-16, 4.2484216574797647e-15, 4.0538431929767204e-14, 3.5215468617192942e-13, 2.7897431630242835e-12, 2.0185811443148509e-11, 1.3360415395259884e-10, 8.0999556201008525e-10, 4.5039223844610038e-09, 2.2996588427898263e-08, 1.0794018969942840e-07, 4.6622930297370394e-07, 1.8549414274389103e-06, 6.8039737747046242e-06, 2.3027980530130599e-05, 7.1968372723672767e-05, 2.0783849443716974e-04, 5.5499593798384811e-04, 1.3711669594184176e-03, 3.1358975655376973e-03, 6.6422701758844281e-03, 1.3036021883614270e-02, 2.3714690293508239e-02, 4.0002156173129341e-02, 6.2585382403901088e-02, 9.0844086374182967e-02, 1.2236194224535350e-01, 1.5296604436543901e-01, 1.7749954969646717e-01, 1.9120062497846860e-01, 1.9120062497846860e-01, 1.7749954969646717e-01, 1.5296604436543901e-01, 1.2236194224535350e-01, 9.0844086374182967e-02, 6.2585382403901088e-02, 4.0002156173129341e-02, 2.3714690293508239e-02, 1.3036021883614270e-02, 6.6422701758844281e-03, 3.1358975655376973e-03, 1.3711669594184176e-03, 5.5499593798384811e-04, 2.0783849443716974e-04, 7.1968372723672767e-05, 2.3027980530130599e-05, 6.8039737747046242e-06, 1.8549414274389103e-06, 4.6622930297370394e-07, 1.0794018969942840e-07, 2.2996588427898263e-08, 4.5039223844610038e-09, 8.0999556201008525e-10, 1.3360415395259884e-10, 2.0185811443148509e-11, 2.7897431630242835e-12, 3.5215468617192942e-13, 4.0538431929767204e-14, 4.2484216574797647e-15, 4.0459872349113726e-16, 3.4946872798000184e-17, 2.7319104369658748e-18, 1.9284904334361852e-19, 1.2263229445163221e-20, 7.0063164858326786e-22, 3.5862705417926132e-23, 1.6395930158211436e-24, 6.6731359742375955e-26, 2.4091492702687982e-27, 7.6849291812936124e-29, 2.1567929048213211e-30, 5.3008778122412928e-32, 1.1351213650894055e-33, 2.1059885157863759e-35, 3.3643504079348503e-37, 4.5962221753185640e-39, 5.3289760352121873e-41, 5.1990976532787586e-43, 4.2276037377430170e-45, 2.8342684935250220e-47, 1.5474546466895863e-49, 6.7840814198640183e-52, 2.3494568244414183e-54, 6.3061655444515630e-57, 1.2826427266230406e-59, 1.9243761113547505e-62, 2.0611376551597914e-65, 1.5134726683009566e-68, 7.2385503439630423e-72, 2.1096988030040495e-75, 3.4257032455364114e-79, 2.7313386049487823e-83, 8.8466828631703380e-88, 8.5232824201455338e-93, 1.3481426814084330e-98, 7.6842766516367719e-106}, + {1.1038467599988350e-106, 2.0299162819709644e-99, 1.3351165545454540e-93, 1.4361908901012819e-88, 4.5844662610976337e-84, 5.9349976525016213e-80, 3.7680124485137400e-76, 1.3315304198313815e-72, 2.8651973069480425e-69, 4.0133192434618745e-66, 3.8520167842143179e-63, 2.6383248122689808e-60, 1.3324956798179218e-57, 5.0982905111217610e-55, 1.5114881547668727e-52, 3.5392080595751209e-50, 6.6532981134843764e-48, 1.0184623032786348e-45, 1.2852633429954566e-43, 1.3517324859318610e-41, 1.1962163965744953e-39, 8.9837835745312106e-38, 5.7697747333366196e-36, 3.1907496278196311e-34, 1.5288163843577720e-32, 6.3824723629696159e-31, 2.3335393536670584e-29, 7.5069091034254989e-28, 2.1339408990452690e-26, 5.3812272933845995e-25, 1.2081587782243251e-23, 2.4230032186653206e-22, 4.3541619756512954e-21, 7.0308758150274706e-20, 1.0228495371481795e-18, 1.3439170617083339e-17, 1.5983699268748500e-16, 1.7244201781932836e-15, 1.6909213145415565e-14, 1.5097790665682497e-13, 1.2295731019067163e-12, 9.1482393782595353e-12, 6.2274132191241200e-11, 3.8838846452764459e-10, 2.2221554698762070e-09, 1.1677641217752186e-08, 5.6428156340858430e-08, 2.5098662449728381e-07, 1.0285882365095455e-06, 3.8874166532037593e-06, 1.3560417245137210e-05, 4.3693239040909913e-05, 1.3013545776424483e-04, 3.5851189054336881e-04, 9.1411456482270634e-04, 2.1583740072268734e-03, 4.7217142757868197e-03, 9.5745050499428906e-03, 1.8003325023065602e-02, 3.1402556502212124e-02, 5.0826454983412143e-02, 7.6356275486723038e-02, 1.0649485597288683e-01, 1.3791833004859055e-01, 1.6587737779249406e-01, 1.8529706602349078e-01, 1.9226167387366441e-01, 1.8529706602349078e-01, 1.6587737779249406e-01, 1.3791833004859055e-01, 1.0649485597288683e-01, 7.6356275486723038e-02, 5.0826454983412143e-02, 3.1402556502212124e-02, 1.8003325023065602e-02, 9.5745050499428906e-03, 4.7217142757868197e-03, 2.1583740072268734e-03, 9.1411456482270634e-04, 3.5851189054336881e-04, 1.3013545776424483e-04, 4.3693239040909913e-05, 1.3560417245137210e-05, 3.8874166532037593e-06, 1.0285882365095455e-06, 2.5098662449728381e-07, 5.6428156340858430e-08, 1.1677641217752186e-08, 2.2221554698762070e-09, 3.8838846452764459e-10, 6.2274132191241200e-11, 9.1482393782595353e-12, 1.2295731019067163e-12, 1.5097790665682497e-13, 1.6909213145415565e-14, 1.7244201781932836e-15, 1.5983699268748500e-16, 1.3439170617083339e-17, 1.0228495371481795e-18, 7.0308758150274706e-20, 4.3541619756512954e-21, 2.4230032186653206e-22, 1.2081587782243251e-23, 5.3812272933845995e-25, 2.1339408990452690e-26, 7.5069091034254989e-28, 2.3335393536670584e-29, 6.3824723629696159e-31, 1.5288163843577720e-32, 3.1907496278196311e-34, 5.7697747333366196e-36, 8.9837835745312106e-38, 1.1962163965744953e-39, 1.3517324859318610e-41, 1.2852633429954566e-43, 1.0184623032786348e-45, 6.6532981134843764e-48, 3.5392080595751209e-50, 1.5114881547668727e-52, 5.0982905111217610e-55, 1.3324956798179218e-57, 2.6383248122689808e-60, 3.8520167842143179e-63, 4.0133192434618745e-66, 2.8651973069480425e-69, 1.3315304198313815e-72, 3.7680124485137400e-76, 5.9349976525016213e-80, 4.5844662610976337e-84, 1.4361908901012819e-88, 1.3351165545454540e-93, 2.0299162819709644e-99, 1.1038467599988350e-106}, + {1.5852022154122762e-107, 3.0548054158892936e-100, 2.0897891620152027e-94, 2.3293228753706694e-89, 7.6861123200181953e-85, 1.0268748980780725e-80, 6.7197562830108496e-77, 2.4452549463378667e-73, 5.4141833815112683e-70, 7.7987351892856256e-67, 7.6937052841722558e-64, 5.4140880882527221e-61, 2.8084445413684342e-58, 1.1033315179441334e-55, 3.3578943438527196e-53, 8.0698691825802516e-51, 1.5567833435482675e-48, 2.4451923543925048e-46, 3.1658838545522830e-44, 3.4158346081733210e-42, 3.1009657171113824e-40, 2.3889887847651522e-38, 1.5738945493185839e-36, 8.9283867523289446e-35, 4.3884114191019410e-33, 1.8794344951812523e-31, 7.0495273821073143e-30, 2.3266903412110293e-28, 6.7861521642478146e-27, 1.7559922329924036e-25, 4.0458189399870260e-24, 8.3276681875539800e-23, 1.5360712580259943e-21, 2.5462929950511611e-20, 3.8033125448314512e-19, 5.1314188262140908e-18, 6.2679375130394878e-17, 6.9461573699177854e-16, 6.9976953274028973e-15, 6.4202984348233192e-14, 5.3739121421360399e-13, 4.1101386023109489e-12, 2.8767484176405797e-11, 1.8451534167067902e-10, 1.0859592046532814e-09, 5.8718148797495608e-09, 2.9201210196159125e-08, 1.3370799258052363e-07, 5.6424627677752911e-07, 2.1965028260725411e-06, 7.8943275081059988e-06, 2.6215639412143949e-05, 8.0497734201318759e-05, 2.2870525172954362e-04, 6.0159714197281571e-04, 1.4659454148941060e-03, 3.3108212147861167e-03, 6.9336514656727563e-03, 1.3470344826444706e-02, 2.4285561078700165e-02, 4.0645578943455961e-02, 6.3168189419948478e-02, 9.1182028088582376e-02, 1.2227380245007502e-01, 1.5234939813711931e-01, 1.7639383039152406e-01, 1.8979993309264909e-01, 1.8979993309264909e-01, 1.7639383039152406e-01, 1.5234939813711931e-01, 1.2227380245007502e-01, 9.1182028088582376e-02, 6.3168189419948478e-02, 4.0645578943455961e-02, 2.4285561078700165e-02, 1.3470344826444706e-02, 6.9336514656727563e-03, 3.3108212147861167e-03, 1.4659454148941060e-03, 6.0159714197281571e-04, 2.2870525172954362e-04, 8.0497734201318759e-05, 2.6215639412143949e-05, 7.8943275081059988e-06, 2.1965028260725411e-06, 5.6424627677752911e-07, 1.3370799258052363e-07, 2.9201210196159125e-08, 5.8718148797495608e-09, 1.0859592046532814e-09, 1.8451534167067902e-10, 2.8767484176405797e-11, 4.1101386023109489e-12, 5.3739121421360399e-13, 6.4202984348233192e-14, 6.9976953274028973e-15, 6.9461573699177854e-16, 6.2679375130394878e-17, 5.1314188262140908e-18, 3.8033125448314512e-19, 2.5462929950511611e-20, 1.5360712580259943e-21, 8.3276681875539800e-23, 4.0458189399870260e-24, 1.7559922329924036e-25, 6.7861521642478146e-27, 2.3266903412110293e-28, 7.0495273821073143e-30, 1.8794344951812523e-31, 4.3884114191019410e-33, 8.9283867523289446e-35, 1.5738945493185839e-36, 2.3889887847651522e-38, 3.1009657171113824e-40, 3.4158346081733210e-42, 3.1658838545522830e-44, 2.4451923543925048e-46, 1.5567833435482675e-48, 8.0698691825802516e-51, 3.3578943438527196e-53, 1.1033315179441334e-55, 2.8084445413684342e-58, 5.4140880882527221e-61, 7.6937052841722558e-64, 7.7987351892856256e-67, 5.4141833815112683e-70, 2.4452549463378667e-73, 6.7197562830108496e-77, 1.0268748980780725e-80, 7.6861123200181953e-85, 2.3293228753706694e-89, 2.0897891620152027e-94, 3.0548054158892936e-100, 1.5852022154122762e-107}, + {2.2757903447048717e-108, 4.5946784737513260e-101, 3.2685938252533535e-95, 3.7743169785683037e-90, 1.2871697383667851e-85, 1.7743864842451219e-81, 1.1966100169534770e-77, 4.4831207104684604e-74, 1.0212230702897007e-70, 1.5124472591580667e-67, 1.5333631698716670e-64, 1.1084367892237507e-61, 5.9044668946443965e-59, 2.3813770140907575e-56, 7.4386721348341212e-54, 1.8345006104189449e-51, 3.6310691969704462e-49, 5.8508598523019220e-47, 7.7706802795811407e-45, 8.5997500074472335e-43, 8.0073315846684445e-41, 6.3269186795493014e-39, 4.2749818807535224e-37, 2.4872103396508171e-35, 1.2538186619197742e-33, 5.5075144968159152e-32, 2.1188905321706446e-30, 7.1735092247885270e-29, 2.1463025081080465e-27, 5.6976909711813352e-26, 1.3468870756541617e-24, 2.8447276912580344e-23, 5.3848024996122255e-22, 9.1613793530553680e-21, 1.4046424779365027e-19, 1.9456017248888693e-18, 2.4401660157799310e-17, 2.7770723790106855e-16, 2.8735526657240152e-15, 2.7084363045358423e-14, 2.3293514464982674e-13, 1.8309133143528682e-12, 1.3172552368556761e-11, 8.6866283016645484e-11, 5.2575217351973056e-10, 2.9240918874514531e-09, 1.4961568756142573e-08, 7.0502109098437831e-08, 3.0626482923803324e-07, 1.2276189268114097e-06, 4.5443796787236290e-06, 1.5548071919772645e-05, 4.9202833580003181e-05, 1.4411581751672914e-04, 3.9094357332687408e-04, 9.8276091717415027e-04, 2.2905612451458858e-03, 4.9522684042317359e-03, 9.9362495542868867e-03, 1.8508238320820009e-02, 3.2017035703904927e-02, 5.1451871301553709e-02, 7.6831201307210703e-02, 1.0663137077642493e-01, 1.3756889121351917e-01, 1.6500723131965989e-01, 1.8402451115016699e-01, 1.9083751332645207e-01, 1.8402451115016699e-01, 1.6500723131965989e-01, 1.3756889121351917e-01, 1.0663137077642493e-01, 7.6831201307210703e-02, 5.1451871301553709e-02, 3.2017035703904927e-02, 1.8508238320820009e-02, 9.9362495542868867e-03, 4.9522684042317359e-03, 2.2905612451458858e-03, 9.8276091717415027e-04, 3.9094357332687408e-04, 1.4411581751672914e-04, 4.9202833580003181e-05, 1.5548071919772645e-05, 4.5443796787236290e-06, 1.2276189268114097e-06, 3.0626482923803324e-07, 7.0502109098437831e-08, 1.4961568756142573e-08, 2.9240918874514531e-09, 5.2575217351973056e-10, 8.6866283016645484e-11, 1.3172552368556761e-11, 1.8309133143528682e-12, 2.3293514464982674e-13, 2.7084363045358423e-14, 2.8735526657240152e-15, 2.7770723790106855e-16, 2.4401660157799310e-17, 1.9456017248888693e-18, 1.4046424779365027e-19, 9.1613793530553680e-21, 5.3848024996122255e-22, 2.8447276912580344e-23, 1.3468870756541617e-24, 5.6976909711813352e-26, 2.1463025081080465e-27, 7.1735092247885270e-29, 2.1188905321706446e-30, 5.5075144968159152e-32, 1.2538186619197742e-33, 2.4872103396508171e-35, 4.2749818807535224e-37, 6.3269186795493014e-39, 8.0073315846684445e-41, 8.5997500074472335e-43, 7.7706802795811407e-45, 5.8508598523019220e-47, 3.6310691969704462e-49, 1.8345006104189449e-51, 7.4386721348341212e-54, 2.3813770140907575e-56, 5.9044668946443965e-59, 1.1084367892237507e-61, 1.5333631698716670e-64, 1.5124472591580667e-67, 1.0212230702897007e-70, 4.4831207104684604e-74, 1.1966100169534770e-77, 1.7743864842451219e-81, 1.2871697383667851e-85, 3.7743169785683037e-90, 3.2685938252533535e-95, 4.5946784737513260e-101, 2.2757903447048717e-108}, + {3.2662778348790219e-109, 6.9071006009219448e-102, 5.1085629363787234e-96, 6.1100313027084669e-91, 2.1531900867437274e-86, 3.0621042209000059e-82, 2.1277376772398947e-78, 8.2059605065764682e-75, 1.9227730563170089e-71, 2.9274096096614171e-68, 3.0495045268798647e-65, 2.2641169845080718e-62, 1.2382980686348502e-59, 5.1263348642622049e-57, 1.6432629457353511e-54, 4.1579427709675079e-52, 8.4425869514003785e-50, 1.3953581486228228e-47, 1.9006681419175218e-45, 2.1571532321739302e-43, 2.0597137897723631e-41, 1.6688589526897371e-39, 1.1562775861404743e-37, 6.8982672254135044e-36, 3.5658879405329104e-34, 1.6062235506206207e-32, 6.3371488059404152e-31, 2.2002659780562692e-29, 6.7518197536098842e-28, 1.8384352926742758e-26, 4.4579796693281321e-25, 9.6593405936315995e-24, 1.8759587883105718e-22, 3.2750072247643929e-21, 5.1531219168800766e-20, 7.3260730719021186e-19, 9.4321973070076218e-18, 1.1021086847913827e-16, 1.1710396791414340e-15, 1.1336050130083279e-14, 1.0014937399406310e-13, 8.0878754293572482e-13, 5.9796723109076469e-12, 4.0531324359847441e-11, 2.5220174708373236e-10, 1.4423973477091834e-09, 7.5910433713044797e-09, 3.6801425167297173e-08, 1.6451664884983423e-07, 6.7880160807256645e-07, 2.5872670138074200e-06, 9.1170822839813128e-06, 2.9724333423383228e-05, 8.9724509010453385e-05, 2.5091729952798149e-04, 6.5046837318858926e-04, 1.5639824929501397e-03, 3.4894828544320858e-03, 7.2278157943492030e-03, 1.3904131095041473e-02, 2.4850005571417737e-02, 4.1275438102408031e-02, 6.3732095470061270e-02, 9.1501274267677846e-02, 1.2217500065832824e-01, 1.5173668408251911e-01, 1.7530801211052990e-01, 1.8842957463583779e-01, 1.8842957463583779e-01, 1.7530801211052990e-01, 1.5173668408251911e-01, 1.2217500065832824e-01, 9.1501274267677846e-02, 6.3732095470061270e-02, 4.1275438102408031e-02, 2.4850005571417737e-02, 1.3904131095041473e-02, 7.2278157943492030e-03, 3.4894828544320858e-03, 1.5639824929501397e-03, 6.5046837318858926e-04, 2.5091729952798149e-04, 8.9724509010453385e-05, 2.9724333423383228e-05, 9.1170822839813128e-06, 2.5872670138074200e-06, 6.7880160807256645e-07, 1.6451664884983423e-07, 3.6801425167297173e-08, 7.5910433713044797e-09, 1.4423973477091834e-09, 2.5220174708373236e-10, 4.0531324359847441e-11, 5.9796723109076469e-12, 8.0878754293572482e-13, 1.0014937399406310e-13, 1.1336050130083279e-14, 1.1710396791414340e-15, 1.1021086847913827e-16, 9.4321973070076218e-18, 7.3260730719021186e-19, 5.1531219168800766e-20, 3.2750072247643929e-21, 1.8759587883105718e-22, 9.6593405936315995e-24, 4.4579796693281321e-25, 1.8384352926742758e-26, 6.7518197536098842e-28, 2.2002659780562692e-29, 6.3371488059404152e-31, 1.6062235506206207e-32, 3.5658879405329104e-34, 6.8982672254135044e-36, 1.1562775861404743e-37, 1.6688589526897371e-39, 2.0597137897723631e-41, 2.1571532321739302e-43, 1.9006681419175218e-45, 1.3953581486228228e-47, 8.4425869514003785e-50, 4.1579427709675079e-52, 1.6432629457353511e-54, 5.1263348642622049e-57, 1.2382980686348502e-59, 2.2641169845080718e-62, 3.0495045268798647e-65, 2.9274096096614171e-68, 1.9227730563170089e-71, 8.2059605065764682e-75, 2.1277376772398947e-78, 3.0621042209000059e-82, 2.1531900867437274e-86, 6.1100313027084669e-91, 5.1085629363787234e-96, 6.9071006009219448e-102, 3.2662778348790219e-109}, + {4.6865023080529104e-110, 1.0377874004830612e-102, 7.9784749096307812e-97, 9.8821174227967692e-92, 3.5979287498244655e-87, 5.2776428357398472e-83, 3.7779666227111211e-79, 1.4996171154683470e-75, 3.6138115204304974e-72, 5.6551650475163530e-69, 6.0520249291763858e-66, 4.6142654439156290e-63, 2.5906808193011388e-60, 1.1006724998865391e-57, 3.6200846949796910e-55, 9.3965049756134747e-53, 1.9569075431422824e-50, 3.3168917267338703e-48, 4.6329566465533973e-46, 5.3914438385767737e-44, 5.2781068509974114e-42, 4.3845152623372787e-40, 3.1144817985274696e-38, 1.9049498787300406e-36, 1.0095682854224567e-34, 4.6623959142602483e-33, 1.8860299651335772e-31, 6.7143368715209606e-30, 2.1127537039024262e-28, 5.8994042231272372e-27, 1.4671212494779564e-25, 3.2605011152464131e-24, 6.4955255161731863e-23, 1.1633403477038459e-21, 1.8781142293296228e-20, 2.7399173517222677e-19, 3.6203893599581944e-18, 4.3421867882952047e-17, 4.7366003944880216e-16, 4.7080515903807368e-15, 4.2715858467937535e-14, 3.5433804833163948e-13, 2.6914605808295047e-12, 1.8746383733203776e-11, 1.1989016690827638e-10, 7.0489725875624514e-10, 3.8145955545353021e-09, 1.9020527069551235e-08, 8.7475726975743740e-08, 3.7140992001185702e-07, 1.4571432947497977e-06, 5.2867540339888927e-06, 1.7751862632560425e-05, 5.5204240789547246e-05, 1.5909525194144218e-04, 4.2516612395155680e-04, 1.0541825457525329e-03, 2.4263153829887293e-03, 5.1862282813377051e-03, 1.0299316731984193e-02, 1.9009837222668049e-02, 3.2621520059018146e-02, 5.2060779315091815e-02, 7.7286794858634558e-02, 1.0675261357345991e-01, 1.3721574664493244e-01, 1.6414915672894112e-01, 1.8277772077559612e-01, 1.8944453877662401e-01, 1.8277772077559612e-01, 1.6414915672894112e-01, 1.3721574664493244e-01, 1.0675261357345991e-01, 7.7286794858634558e-02, 5.2060779315091815e-02, 3.2621520059018146e-02, 1.9009837222668049e-02, 1.0299316731984193e-02, 5.1862282813377051e-03, 2.4263153829887293e-03, 1.0541825457525329e-03, 4.2516612395155680e-04, 1.5909525194144218e-04, 5.5204240789547246e-05, 1.7751862632560425e-05, 5.2867540339888927e-06, 1.4571432947497977e-06, 3.7140992001185702e-07, 8.7475726975743740e-08, 1.9020527069551235e-08, 3.8145955545353021e-09, 7.0489725875624514e-10, 1.1989016690827638e-10, 1.8746383733203776e-11, 2.6914605808295047e-12, 3.5433804833163948e-13, 4.2715858467937535e-14, 4.7080515903807368e-15, 4.7366003944880216e-16, 4.3421867882952047e-17, 3.6203893599581944e-18, 2.7399173517222677e-19, 1.8781142293296228e-20, 1.1633403477038459e-21, 6.4955255161731863e-23, 3.2605011152464131e-24, 1.4671212494779564e-25, 5.8994042231272372e-27, 2.1127537039024262e-28, 6.7143368715209606e-30, 1.8860299651335772e-31, 4.6623959142602483e-33, 1.0095682854224567e-34, 1.9049498787300406e-36, 3.1144817985274696e-38, 4.3845152623372787e-40, 5.2781068509974114e-42, 5.3914438385767737e-44, 4.6329566465533973e-46, 3.3168917267338703e-48, 1.9569075431422824e-50, 9.3965049756134747e-53, 3.6200846949796910e-55, 1.1006724998865391e-57, 2.5906808193011388e-60, 4.6142654439156290e-63, 6.0520249291763858e-66, 5.6551650475163530e-69, 3.6138115204304974e-72, 1.4996171154683470e-75, 3.7779666227111211e-79, 5.2776428357398472e-83, 3.5979287498244655e-87, 9.8821174227967692e-92, 7.9784749096307812e-97, 1.0377874004830612e-102, 4.6865023080529104e-110}, + {6.7223469064836171e-111, 1.5584604318709814e-103, 1.2451690475064742e-97, 1.5968463027613036e-92, 6.0055451530824495e-88, 9.0848000543271587e-84, 6.6985500695669678e-80, 2.7361658102621640e-76, 6.7802095889475983e-73, 1.0903770909317098e-69, 1.1985921850382964e-66, 9.3828601952142795e-64, 5.4070585225542087e-61, 2.3572025385780174e-58, 7.9532902157128368e-56, 2.1173804777066541e-53, 4.5220720973223149e-51, 7.8591635665593126e-49, 1.1254750686853198e-46, 1.3427041430602204e-44, 1.3474889050314146e-42, 1.1474212047422846e-40, 8.3547107388260308e-39, 5.2380609435106477e-37, 2.8455586990614318e-35, 1.3470860626931207e-33, 5.5860425698193572e-32, 2.0386781124262974e-30, 6.5767258559351848e-29, 1.8828451569167714e-27, 4.8012341582972026e-26, 1.0941854437188646e-24, 2.2355486477720061e-23, 4.1066490153458769e-22, 6.8008865930090286e-21, 1.0178867789337611e-19, 1.3800519281469149e-18, 1.6985968059071478e-17, 1.9017680123139647e-16, 1.9404932122013048e-15, 1.8076531130346059e-14, 1.5398466784483034e-13, 1.2013344715990716e-12, 8.5959906732140100e-12, 5.6487797699597178e-11, 3.4133713929443775e-10, 1.8988505331522261e-09, 9.7353434088062900e-09, 4.6047775382709491e-08, 2.0113005931537178e-07, 8.1197441052941798e-07, 3.0322448415500775e-06, 1.0482793298607957e-05, 3.3573050144199230e-05, 9.9676496285740638e-05, 2.7450358985306201e-04, 7.0161767403489428e-04, 1.6652282490644866e-03, 3.6717374087279781e-03, 7.5245206122160650e-03, 1.4337113630217399e-02, 2.5407889466847185e-02, 4.1891912442268933e-02, 6.4277668190634463e-02, 9.1802633810630571e-02, 1.2206621940114575e-01, 1.5112804960523191e-01, 1.7424152504403007e-01, 1.8708847054904945e-01, 1.8708847054904945e-01, 1.7424152504403007e-01, 1.5112804960523191e-01, 1.2206621940114575e-01, 9.1802633810630571e-02, 6.4277668190634463e-02, 4.1891912442268933e-02, 2.5407889466847185e-02, 1.4337113630217399e-02, 7.5245206122160650e-03, 3.6717374087279781e-03, 1.6652282490644866e-03, 7.0161767403489428e-04, 2.7450358985306201e-04, 9.9676496285740638e-05, 3.3573050144199230e-05, 1.0482793298607957e-05, 3.0322448415500775e-06, 8.1197441052941798e-07, 2.0113005931537178e-07, 4.6047775382709491e-08, 9.7353434088062900e-09, 1.8988505331522261e-09, 3.4133713929443775e-10, 5.6487797699597178e-11, 8.5959906732140100e-12, 1.2013344715990716e-12, 1.5398466784483034e-13, 1.8076531130346059e-14, 1.9404932122013048e-15, 1.9017680123139647e-16, 1.6985968059071478e-17, 1.3800519281469149e-18, 1.0178867789337611e-19, 6.8008865930090286e-21, 4.1066490153458769e-22, 2.2355486477720061e-23, 1.0941854437188646e-24, 4.8012341582972026e-26, 1.8828451569167714e-27, 6.5767258559351848e-29, 2.0386781124262974e-30, 5.5860425698193572e-32, 1.3470860626931207e-33, 2.8455586990614318e-35, 5.2380609435106477e-37, 8.3547107388260308e-39, 1.1474212047422846e-40, 1.3474889050314146e-42, 1.3427041430602204e-44, 1.1254750686853198e-46, 7.8591635665593126e-49, 4.5220720973223149e-51, 2.1173804777066541e-53, 7.9532902157128368e-56, 2.3572025385780174e-58, 5.4070585225542087e-61, 9.3828601952142795e-64, 1.1985921850382964e-66, 1.0903770909317098e-69, 6.7802095889475983e-73, 2.7361658102621640e-76, 6.6985500695669678e-80, 9.0848000543271587e-84, 6.0055451530824495e-88, 1.5968463027613036e-92, 1.2451690475064742e-97, 1.5584604318709814e-103, 6.7223469064836171e-111}, + {9.6398630558977581e-112, 2.3391641752283700e-104, 1.9419047430148712e-98, 2.5780282869707508e-93, 1.0013546946979084e-88, 1.5618992863642802e-84, 1.1860256149765069e-80, 4.9845319901386102e-77, 1.2699036539452659e-73, 2.0984019099670130e-70, 2.3689362034001624e-67, 1.9037493843202249e-64, 1.1258502033609599e-61, 5.0354502440866812e-59, 1.7426389319046294e-56, 4.7576590995159999e-54, 1.0418263136743596e-51, 1.8562658771588515e-49, 2.7249577678833700e-47, 3.3321800978024594e-45, 3.4274481444478336e-43, 2.9912154191216358e-41, 2.2321555171303588e-39, 1.4342596614707723e-37, 7.9853025164866527e-36, 3.8743074669761106e-34, 1.6466139693318358e-32, 6.1594817750585881e-31, 2.0367481580156025e-29, 5.9772735819833118e-28, 1.5625565508848433e-26, 3.6509499167114885e-25, 7.6484446772058021e-24, 1.4407768646001281e-22, 2.4470614433838565e-21, 3.7566695291667047e-20, 5.2249355965739373e-19, 6.5981079437776417e-18, 7.5804607661939761e-17, 7.9383130347919212e-16, 7.5907028620400909e-15, 6.6385260183760165e-14, 5.3182112719426004e-13, 3.9083095195736355e-12, 2.6383151459347353e-11, 1.6380456665860958e-10, 9.3648087516475362e-10, 4.9354207551905105e-09, 2.4002106969319454e-08, 1.0781831043581527e-07, 4.4775845772911881e-07, 1.7205483203483572e-06, 6.1220977817639379e-06, 2.0186382119025494e-05, 6.1721031633452369e-05, 1.7510316724439029e-04, 4.6120030826672870e-04, 1.1283616065624156e-03, 2.5655409728187234e-03, 5.4233979404253157e-03, 1.0663442942343464e-02, 1.9507907091601058e-02, 3.3216020285214413e-02, 5.2653553807060320e-02, 7.7723764833089265e-02, 1.0685936247311774e-01, 1.3685933683570478e-01, 1.6330294257556086e-01, 1.8155584069555794e-01, 1.8808162842571305e-01, 1.8155584069555794e-01, 1.6330294257556086e-01, 1.3685933683570478e-01, 1.0685936247311774e-01, 7.7723764833089265e-02, 5.2653553807060320e-02, 3.3216020285214413e-02, 1.9507907091601058e-02, 1.0663442942343464e-02, 5.4233979404253157e-03, 2.5655409728187234e-03, 1.1283616065624156e-03, 4.6120030826672870e-04, 1.7510316724439029e-04, 6.1721031633452369e-05, 2.0186382119025494e-05, 6.1220977817639379e-06, 1.7205483203483572e-06, 4.4775845772911881e-07, 1.0781831043581527e-07, 2.4002106969319454e-08, 4.9354207551905105e-09, 9.3648087516475362e-10, 1.6380456665860958e-10, 2.6383151459347353e-11, 3.9083095195736355e-12, 5.3182112719426004e-13, 6.6385260183760165e-14, 7.5907028620400909e-15, 7.9383130347919212e-16, 7.5804607661939761e-17, 6.5981079437776417e-18, 5.2249355965739373e-19, 3.7566695291667047e-20, 2.4470614433838565e-21, 1.4407768646001281e-22, 7.6484446772058021e-24, 3.6509499167114885e-25, 1.5625565508848433e-26, 5.9772735819833118e-28, 2.0367481580156025e-29, 6.1594817750585881e-31, 1.6466139693318358e-32, 3.8743074669761106e-34, 7.9853025164866527e-36, 1.4342596614707723e-37, 2.2321555171303588e-39, 2.9912154191216358e-41, 3.4274481444478336e-43, 3.3321800978024594e-45, 2.7249577678833700e-47, 1.8562658771588515e-49, 1.0418263136743596e-51, 4.7576590995159999e-54, 1.7426389319046294e-56, 5.0354502440866812e-59, 1.1258502033609599e-61, 1.9037493843202249e-64, 2.3689362034001624e-67, 2.0984019099670130e-70, 1.2699036539452659e-73, 4.9845319901386102e-77, 1.1860256149765069e-80, 1.5618992863642802e-84, 1.0013546946979084e-88, 2.5780282869707508e-93, 1.9419047430148712e-98, 2.3391641752283700e-104, 9.6398630558977581e-112}, + {1.3819748652176074e-112, 3.5091818441132373e-105, 3.0263733342631031e-99, 4.1584216000446123e-94, 1.6678802978259982e-89, 2.6820059816501053e-85, 2.0970348613054561e-81, 9.0664032095201726e-78, 2.3744232682771987e-74, 4.0308051146214329e-71, 4.6725947222676983e-68, 3.8542403780632908e-65, 2.3387627697862867e-62, 1.0729932979377662e-59, 3.8081687860913558e-57, 1.0660224990923822e-54, 2.3931046396310541e-52, 4.3706076964057967e-50, 6.5758217028615195e-48, 8.2408262629145279e-46, 8.6863577038588966e-44, 7.7681876124982396e-42, 5.9400458445057631e-40, 3.9109426504580767e-38, 2.2311802993712928e-36, 1.1092621876592673e-34, 4.8310493095269011e-33, 1.8519160989732117e-31, 6.2757371777744156e-30, 1.8875929093999227e-28, 5.0576726716251256e-27, 1.2113423787195963e-25, 2.6014811007021294e-24, 5.0242965481154138e-23, 8.7498945768853231e-22, 1.3775031653677140e-20, 1.9649805509896429e-19, 2.5453305256296733e-18, 3.0000691187992888e-17, 3.2236051617172698e-16, 3.1633284490034087e-15, 2.8395986506952882e-14, 2.3353492711597277e-13, 1.7622103628998908e-12, 1.2216962997815707e-11, 7.7914682997538544e-11, 4.5765854976073951e-10, 2.4786353105487376e-09, 1.2390357485809571e-08, 5.7223858055497259e-08, 2.4439179961675454e-07, 9.6600646013167157e-07, 3.5367142158469601e-06, 1.2002319438047467e-05, 3.7780839366269368e-05, 1.1038074912944360e-04, 2.9949084760834345e-04, 7.5504927141389195e-04, 1.7696288232331070e-03, 3.8574393750280067e-03, 7.8235307009575233e-03, 1.4769041560724656e-02, 2.5959097306055404e-02, 4.2495188992312062e-02, 6.4805460287971808e-02, 9.2086877576565612e-02, 1.2194809856528342e-01, 1.5052362288934179e-01, 1.7319382084353874e-01, 1.8577559474964558e-01, 1.8577559474964558e-01, 1.7319382084353874e-01, 1.5052362288934179e-01, 1.2194809856528342e-01, 9.2086877576565612e-02, 6.4805460287971808e-02, 4.2495188992312062e-02, 2.5959097306055404e-02, 1.4769041560724656e-02, 7.8235307009575233e-03, 3.8574393750280067e-03, 1.7696288232331070e-03, 7.5504927141389195e-04, 2.9949084760834345e-04, 1.1038074912944360e-04, 3.7780839366269368e-05, 1.2002319438047467e-05, 3.5367142158469601e-06, 9.6600646013167157e-07, 2.4439179961675454e-07, 5.7223858055497259e-08, 1.2390357485809571e-08, 2.4786353105487376e-09, 4.5765854976073951e-10, 7.7914682997538544e-11, 1.2216962997815707e-11, 1.7622103628998908e-12, 2.3353492711597277e-13, 2.8395986506952882e-14, 3.1633284490034087e-15, 3.2236051617172698e-16, 3.0000691187992888e-17, 2.5453305256296733e-18, 1.9649805509896429e-19, 1.3775031653677140e-20, 8.7498945768853231e-22, 5.0242965481154138e-23, 2.6014811007021294e-24, 1.2113423787195963e-25, 5.0576726716251256e-27, 1.8875929093999227e-28, 6.2757371777744156e-30, 1.8519160989732117e-31, 4.8310493095269011e-33, 1.1092621876592673e-34, 2.2311802993712928e-36, 3.9109426504580767e-38, 5.9400458445057631e-40, 7.7681876124982396e-42, 8.6863577038588966e-44, 8.2408262629145279e-46, 6.5758217028615195e-48, 4.3706076964057967e-50, 2.3931046396310541e-52, 1.0660224990923822e-54, 3.8081687860913558e-57, 1.0729932979377662e-59, 2.3387627697862867e-62, 3.8542403780632908e-65, 4.6725947222676983e-68, 4.0308051146214329e-71, 2.3744232682771987e-74, 9.0664032095201726e-78, 2.0970348613054561e-81, 2.6820059816501053e-85, 1.6678802978259982e-89, 4.1584216000446123e-94, 3.0263733342631031e-99, 3.5091818441132373e-105, 1.3819748652176074e-112}, + {1.9806611743021416e-113, 5.2617952692292333e-106, 4.7131990325935266e-100, 6.7017830703194019e-95, 2.7751659416516980e-90, 4.5998341384092458e-86, 3.7027394072850406e-82, 1.6465801492558192e-78, 4.4321525706156201e-75, 7.7285235953959866e-72, 9.1980779235827154e-69, 7.7863635474467061e-66, 4.8472018976182706e-63, 2.2808008160100623e-60, 8.3001996570148669e-58, 2.3819600570060440e-55, 5.4809275321322830e-53, 1.0258876994968507e-50, 1.5817079781846762e-48, 2.0310845466149993e-46, 2.1935503204230003e-44, 2.0098426331457899e-42, 1.5745331638769155e-40, 1.0620797611432563e-38, 6.2076082159887624e-37, 3.1618692048946272e-35, 1.4108563317113768e-33, 5.5412911024876112e-32, 1.9240852596678829e-30, 5.9301271167711558e-29, 1.6282950449666844e-27, 3.9967858207858083e-26, 8.7976197776883766e-25, 1.7416595619626179e-23, 3.1094324529576228e-22, 5.0189377569399244e-21, 7.3412947992638873e-20, 9.7524056424221390e-19, 1.1789993455088293e-17, 1.2995830094215584e-16, 1.3084437330245737e-15, 1.2052816831862512e-14, 1.0173726615206055e-13, 7.8806482946078899e-13, 5.6095283428337204e-12, 3.6739040139866195e-11, 2.2165913480620041e-10, 1.2333492148378478e-09, 6.3355479710981103e-09, 3.0075005874343488e-08, 1.3205310627276386e-07, 5.3676540058539977e-07, 2.0214361392302868e-06, 7.0582654033955854e-06, 2.2866437400066508e-05, 6.8776486666748005e-05, 1.9216752502494505e-04, 4.9906383375612176e-04, 1.2052761990741546e-03, 2.7081400657517538e-03, 5.6635846018365278e-03, 1.1028376452466447e-02, 2.0002251583713944e-02, 3.3800561758698749e-02, 5.3230566834836512e-02, 7.8142792739003333e-02, 1.0695235327964076e-01, 1.3650006936059866e-01, 1.6246837812900003e-01, 1.8035805565273866e-01, 1.8674771616737459e-01, 1.8035805565273866e-01, 1.6246837812900003e-01, 1.3650006936059866e-01, 1.0695235327964076e-01, 7.8142792739003333e-02, 5.3230566834836512e-02, 3.3800561758698749e-02, 2.0002251583713944e-02, 1.1028376452466447e-02, 5.6635846018365278e-03, 2.7081400657517538e-03, 1.2052761990741546e-03, 4.9906383375612176e-04, 1.9216752502494505e-04, 6.8776486666748005e-05, 2.2866437400066508e-05, 7.0582654033955854e-06, 2.0214361392302868e-06, 5.3676540058539977e-07, 1.3205310627276386e-07, 3.0075005874343488e-08, 6.3355479710981103e-09, 1.2333492148378478e-09, 2.2165913480620041e-10, 3.6739040139866195e-11, 5.6095283428337204e-12, 7.8806482946078899e-13, 1.0173726615206055e-13, 1.2052816831862512e-14, 1.3084437330245737e-15, 1.2995830094215584e-16, 1.1789993455088293e-17, 9.7524056424221390e-19, 7.3412947992638873e-20, 5.0189377569399244e-21, 3.1094324529576228e-22, 1.7416595619626179e-23, 8.7976197776883766e-25, 3.9967858207858083e-26, 1.6282950449666844e-27, 5.9301271167711558e-29, 1.9240852596678829e-30, 5.5412911024876112e-32, 1.4108563317113768e-33, 3.1618692048946272e-35, 6.2076082159887624e-37, 1.0620797611432563e-38, 1.5745331638769155e-40, 2.0098426331457899e-42, 2.1935503204230003e-44, 2.0310845466149993e-46, 1.5817079781846762e-48, 1.0258876994968507e-50, 5.4809275321322830e-53, 2.3819600570060440e-55, 8.3001996570148669e-58, 2.2808008160100623e-60, 4.8472018976182706e-63, 7.7863635474467061e-66, 9.1980779235827154e-69, 7.7285235953959866e-72, 4.4321525706156201e-75, 1.6465801492558192e-78, 3.7027394072850406e-82, 4.5998341384092458e-86, 2.7751659416516980e-90, 6.7017830703194019e-95, 4.7131990325935266e-100, 5.2617952692292333e-106, 1.9806611743021416e-113}, + {2.8379348362554196e-114, 7.8858321167381958e-107, 7.3351907294176643e-101, 1.0791401722330717e-95, 4.6128120689561502e-91, 7.8796483529297319e-87, 6.5291103196563761e-83, 2.9859071017101074e-79, 8.2594238150373050e-76, 1.4791530184295327e-72, 1.8070968918430098e-69, 1.5696742395566467e-66, 1.0023248619238131e-63, 4.8364134393087594e-61, 1.8044278404363096e-58, 5.3077896463877236e-56, 1.2516691340073944e-53, 2.4006692740362835e-51, 3.7923450617699092e-49, 4.9890808610628276e-47, 5.5197834921993867e-45, 5.1808064286331934e-43, 4.1575196368970433e-41, 2.8726311560209485e-39, 1.7198340431536187e-37, 8.9732693547519472e-36, 4.1015179356507749e-34, 1.6502257188992863e-32, 5.8701285325766118e-31, 1.8535450041434515e-29, 5.2145562564115323e-28, 1.3115164390064590e-26, 2.9583134344508206e-25, 6.0020532911752611e-24, 1.0982988908956421e-22, 1.8172013379429154e-21, 2.7250115798124682e-20, 3.7116593876307894e-19, 4.6014038935013638e-18, 5.2019302408782819e-17, 5.3723712748625257e-16, 5.0771526984812688e-15, 4.3975029340499356e-14, 3.4959048726655372e-13, 2.5543256450392521e-12, 1.7175688761100677e-11, 1.0641335972971535e-10, 6.0815188314211019e-10, 3.2093758879421831e-09, 1.5654930566151192e-08, 7.0648903615829459e-08, 2.9522889815634413e-07, 1.1433046682221214e-06, 4.1062137791532273e-06, 1.3686795544658825e-05, 4.2366755055396916e-05, 1.2186350361528871e-04, 3.2590355495495157e-04, 8.1076372459361551e-04, 1.8771268090367514e-03, 4.0464432735401257e-03, 8.1246183048277309e-03, 1.5199679576417248e-02, 2.6503531097710236e-02, 4.3085461690763743e-02, 6.5316009514185674e-02, 9.2354740298272661e-02, 1.2182123832712786e-01, 1.4992351472225099e-01, 1.7216437167539980e-01, 1.8448997083421120e-01, 1.8448997083421120e-01, 1.7216437167539980e-01, 1.4992351472225099e-01, 1.2182123832712786e-01, 9.2354740298272661e-02, 6.5316009514185674e-02, 4.3085461690763743e-02, 2.6503531097710236e-02, 1.5199679576417248e-02, 8.1246183048277309e-03, 4.0464432735401257e-03, 1.8771268090367514e-03, 8.1076372459361551e-04, 3.2590355495495157e-04, 1.2186350361528871e-04, 4.2366755055396916e-05, 1.3686795544658825e-05, 4.1062137791532273e-06, 1.1433046682221214e-06, 2.9522889815634413e-07, 7.0648903615829459e-08, 1.5654930566151192e-08, 3.2093758879421831e-09, 6.0815188314211019e-10, 1.0641335972971535e-10, 1.7175688761100677e-11, 2.5543256450392521e-12, 3.4959048726655372e-13, 4.3975029340499356e-14, 5.0771526984812688e-15, 5.3723712748625257e-16, 5.2019302408782819e-17, 4.6014038935013638e-18, 3.7116593876307894e-19, 2.7250115798124682e-20, 1.8172013379429154e-21, 1.0982988908956421e-22, 6.0020532911752611e-24, 2.9583134344508206e-25, 1.3115164390064590e-26, 5.2145562564115323e-28, 1.8535450041434515e-29, 5.8701285325766118e-31, 1.6502257188992863e-32, 4.1015179356507749e-34, 8.9732693547519472e-36, 1.7198340431536187e-37, 2.8726311560209485e-39, 4.1575196368970433e-41, 5.1808064286331934e-43, 5.5197834921993867e-45, 4.9890808610628276e-47, 3.7923450617699092e-49, 2.4006692740362835e-51, 1.2516691340073944e-53, 5.3077896463877236e-56, 1.8044278404363096e-58, 4.8364134393087594e-61, 1.0023248619238131e-63, 1.5696742395566467e-66, 1.8070968918430098e-69, 1.4791530184295327e-72, 8.2594238150373050e-76, 2.9859071017101074e-79, 6.5291103196563761e-83, 7.8796483529297319e-87, 4.6128120689561502e-91, 1.0791401722330717e-95, 7.3351907294176643e-101, 7.8858321167381958e-107, 2.8379348362554196e-114}, + {4.0651653045385065e-115, 1.1812699945481087e-107, 1.1408091037467098e-101, 1.7361831916251206e-96, 7.6595061701919539e-92, 1.3482180200386414e-87, 1.1497555722475321e-83, 5.4065905193630812e-80, 1.5366409186618650e-76, 2.8258657002435720e-73, 3.5434157687072630e-70, 3.1577316852342737e-67, 2.0680029879339054e-64, 1.0231020536481417e-61, 3.9127659587819162e-59, 1.1795593319147925e-56, 2.8502626581292134e-54, 5.6008912228881934e-52, 9.0638661704615042e-50, 1.2214291755276681e-47, 1.3841464531877442e-45, 1.3306007915064349e-43, 1.0936052280580312e-41, 7.7388088770231391e-40, 4.7451186753733802e-38, 2.5356047070173512e-36, 1.1870121009809329e-34, 4.8915667031805749e-33, 1.7822371990214424e-31, 5.7644513660319519e-30, 1.6612582615477246e-28, 4.2804618347791540e-27, 9.8922322140449142e-26, 2.0564738212957134e-24, 3.8562115828650105e-23, 6.5389458924467930e-22, 1.0050517825377878e-20, 1.4033245536407663e-19, 1.7836445099325982e-18, 2.0676254282785005e-17, 2.1899168813282935e-16, 2.1227770911527276e-15, 1.8861860904057362e-14, 1.5385347856793465e-13, 1.1536439246054796e-12, 7.9623160515403962e-12, 5.0644993569234348e-11, 2.9720520664121096e-10, 1.6108731738857700e-09, 8.0720587699486656e-09, 3.7430932220185756e-08, 1.6076054796089227e-07, 6.4000756781336375e-07, 2.3636229043243477e-06, 8.1033917859954005e-06, 2.5807006976135383e-05, 7.6393528572820399e-05, 2.1031479179566012e-04, 5.3877140763670364e-04, 1.2849006257472789e-03, 2.8540126420656033e-03, 5.9065989999834033e-03, 1.1393877212953164e-02, 2.0492691616955331e-02, 3.4375183073736520e-02, 5.3792186966533914e-02, 7.8544533849893697e-02, 1.0703228204562122e-01, 1.3613832142377319e-01, 1.6164525387078738e-01, 1.7918358709477061e-01, 1.8544178808228795e-01, 1.7918358709477061e-01, 1.6164525387078738e-01, 1.3613832142377319e-01, 1.0703228204562122e-01, 7.8544533849893697e-02, 5.3792186966533914e-02, 3.4375183073736520e-02, 2.0492691616955331e-02, 1.1393877212953164e-02, 5.9065989999834033e-03, 2.8540126420656033e-03, 1.2849006257472789e-03, 5.3877140763670364e-04, 2.1031479179566012e-04, 7.6393528572820399e-05, 2.5807006976135383e-05, 8.1033917859954005e-06, 2.3636229043243477e-06, 6.4000756781336375e-07, 1.6076054796089227e-07, 3.7430932220185756e-08, 8.0720587699486656e-09, 1.6108731738857700e-09, 2.9720520664121096e-10, 5.0644993569234348e-11, 7.9623160515403962e-12, 1.1536439246054796e-12, 1.5385347856793465e-13, 1.8861860904057362e-14, 2.1227770911527276e-15, 2.1899168813282935e-16, 2.0676254282785005e-17, 1.7836445099325982e-18, 1.4033245536407663e-19, 1.0050517825377878e-20, 6.5389458924467930e-22, 3.8562115828650105e-23, 2.0564738212957134e-24, 9.8922322140449142e-26, 4.2804618347791540e-27, 1.6612582615477246e-28, 5.7644513660319519e-30, 1.7822371990214424e-31, 4.8915667031805749e-33, 1.1870121009809329e-34, 2.5356047070173512e-36, 4.7451186753733802e-38, 7.7388088770231391e-40, 1.0936052280580312e-41, 1.3306007915064349e-43, 1.3841464531877442e-45, 1.2214291755276681e-47, 9.0638661704615042e-50, 5.6008912228881934e-52, 2.8502626581292134e-54, 1.1795593319147925e-56, 3.9127659587819162e-59, 1.0231020536481417e-61, 2.0680029879339054e-64, 3.1577316852342737e-67, 3.5434157687072630e-70, 2.8258657002435720e-73, 1.5366409186618650e-76, 5.4065905193630812e-80, 1.1497555722475321e-83, 1.3482180200386414e-87, 7.6595061701919539e-92, 1.7361831916251206e-96, 1.1408091037467098e-101, 1.1812699945481087e-107, 4.0651653045385065e-115}, + {5.8215540266145185e-116, 1.7686479321265132e-108, 1.7730623068856681e-102, 2.7909232189455364e-97, 1.2705722231489315e-92, 2.3041370774073117e-88, 2.0220172247445533e-84, 9.7753535494291230e-81, 2.8542469937135876e-77, 5.3891664187060082e-74, 6.9347342664174447e-71, 6.3393303649456501e-68, 4.2572743226051364e-65, 2.1591730776951801e-62, 8.4632278622572117e-60, 2.6143765867593842e-57, 6.4722677680216748e-55, 1.3028416632725528e-52, 2.1595419825453231e-50, 2.9805109745607960e-48, 3.4589808905752308e-46, 3.4051398010375247e-44, 2.8658496493850430e-42, 2.0766525261834300e-40, 1.3038602059242759e-38, 7.1344872719593792e-37, 3.4201248592076866e-35, 1.4432903376167608e-33, 5.3852783517497647e-32, 1.7838570362707828e-30, 5.2653274547677795e-29, 1.3896193908215000e-27, 3.2896623243386845e-26, 7.0060070837042623e-25, 1.3459870964148325e-23, 2.3386559482775554e-22, 3.6836215601895347e-21, 5.2713950568645777e-20, 6.8677255495973648e-19, 8.1615638298029365e-18, 8.8631701623207850e-17, 8.8103300045560730e-16, 8.0291277303592449e-15, 6.7183131113433536e-14, 5.1685673461842002e-13, 3.6606905840155156e-12, 2.3898379902347417e-11, 1.4397371489675669e-10, 8.0125910717950545e-10, 4.1235783120777111e-09, 1.9642460747885040e-08, 8.6680352990322611e-08, 3.5465537239549829e-07, 1.3464428002356888e-06, 4.7465352780258519e-06, 1.5547603684619328e-05, 4.7349798947666790e-05, 1.3415011473384580e-04, 3.5376394702118597e-04, 8.6875807961727194e-04, 1.9876616088445901e-03, 4.2386040557315851e-03, 8.4275632150598145e-03, 1.5628807300276451e-02, 2.7041109022394049e-02, 4.3662930188759774e-02, 6.5809838711917215e-02, 9.2606922401635969e-02, 1.2168620186278144e-01, 1.4932782014181728e-01, 1.7115266931753381e-01, 1.8323066902877375e-01, 1.8323066902877375e-01, 1.7115266931753381e-01, 1.4932782014181728e-01, 1.2168620186278144e-01, 9.2606922401635969e-02, 6.5809838711917215e-02, 4.3662930188759774e-02, 2.7041109022394049e-02, 1.5628807300276451e-02, 8.4275632150598145e-03, 4.2386040557315851e-03, 1.9876616088445901e-03, 8.6875807961727194e-04, 3.5376394702118597e-04, 1.3415011473384580e-04, 4.7349798947666790e-05, 1.5547603684619328e-05, 4.7465352780258519e-06, 1.3464428002356888e-06, 3.5465537239549829e-07, 8.6680352990322611e-08, 1.9642460747885040e-08, 4.1235783120777111e-09, 8.0125910717950545e-10, 1.4397371489675669e-10, 2.3898379902347417e-11, 3.6606905840155156e-12, 5.1685673461842002e-13, 6.7183131113433536e-14, 8.0291277303592449e-15, 8.8103300045560730e-16, 8.8631701623207850e-17, 8.1615638298029365e-18, 6.8677255495973648e-19, 5.2713950568645777e-20, 3.6836215601895347e-21, 2.3386559482775554e-22, 1.3459870964148325e-23, 7.0060070837042623e-25, 3.2896623243386845e-26, 1.3896193908215000e-27, 5.2653274547677795e-29, 1.7838570362707828e-30, 5.3852783517497647e-32, 1.4432903376167608e-33, 3.4201248592076866e-35, 7.1344872719593792e-37, 1.3038602059242759e-38, 2.0766525261834300e-40, 2.8658496493850430e-42, 3.4051398010375247e-44, 3.4589808905752308e-46, 2.9805109745607960e-48, 2.1595419825453231e-50, 1.3028416632725528e-52, 6.4722677680216748e-55, 2.6143765867593842e-57, 8.4632278622572117e-60, 2.1591730776951801e-62, 4.2572743226051364e-65, 6.3393303649456501e-68, 6.9347342664174447e-71, 5.3891664187060082e-74, 2.8542469937135876e-77, 9.7753535494291230e-81, 2.0220172247445533e-84, 2.3041370774073117e-88, 1.2705722231489315e-92, 2.7909232189455364e-97, 1.7730623068856681e-102, 1.7686479321265132e-108, 5.8215540266145185e-116}, + {8.3346219931731252e-117, 2.6468336179684675e-109, 2.7538984203799183e-103, 4.4826957080916534e-98, 2.1055559670183425e-93, 3.9333042153463284e-89, 3.5513952096001502e-85, 1.7648636462384819e-81, 5.2931716200065506e-78, 1.0259659682881671e-74, 1.3546124768341285e-71, 1.2700634063455813e-68, 8.7450484044987438e-66, 4.5461329246587614e-63, 1.8260394178147789e-60, 5.7792816013390868e-58, 1.4656166079834788e-55, 3.0217106412347761e-53, 5.1294451668154943e-51, 7.2494810877533628e-49, 8.6147071643386152e-47, 8.6832052790729524e-45, 7.4822992810294955e-43, 5.5510153038363309e-41, 3.5683132140145833e-39, 1.9990336800405551e-37, 9.8114235481332920e-36, 4.2392471038699379e-34, 1.6195898700068922e-32, 5.4933861932302487e-31, 1.6604056318842839e-29, 4.4876913417614677e-28, 1.0880533660044361e-26, 2.3734409390889848e-25, 4.6708788240159748e-24, 8.3141586271431848e-23, 1.3417423881673005e-21, 1.9674928839115667e-20, 2.6269310713002712e-19, 3.1997441855901569e-18, 3.5620366003569210e-17, 3.6302240823037884e-16, 3.3924183801506980e-15, 2.9112006503092275e-14, 2.2973505987627707e-13, 1.6693328537504025e-12, 1.1182840247910251e-11, 6.9144057864820654e-11, 3.9502105053420148e-10, 2.0873156939372195e-09, 1.0211061576622443e-08, 4.6286545842406255e-08, 1.9458139349161944e-07, 7.5918662435991949e-07, 2.7511365949804849e-06, 9.2658749369498393e-06, 2.9023198119388909e-05, 8.4594658849625380e-05, 2.2956989796967087e-04, 5.8033480492528523e-04, 1.3672056490331354e-03, 3.0030570133818706e-03, 6.1522556633449429e-03, 1.1759716605478240e-02, 2.0979064379787655e-02, 3.4939934715514299e-02, 5.4338778627529040e-02, 7.8929618144152600e-02, 1.0709980745724954e-01, 1.3577444219071524e-01, 1.6083336191837752e-01, 1.7803169108709616e-01, 1.8416287919896177e-01, 1.7803169108709616e-01, 1.6083336191837752e-01, 1.3577444219071524e-01, 1.0709980745724954e-01, 7.8929618144152600e-02, 5.4338778627529040e-02, 3.4939934715514299e-02, 2.0979064379787655e-02, 1.1759716605478240e-02, 6.1522556633449429e-03, 3.0030570133818706e-03, 1.3672056490331354e-03, 5.8033480492528523e-04, 2.2956989796967087e-04, 8.4594658849625380e-05, 2.9023198119388909e-05, 9.2658749369498393e-06, 2.7511365949804849e-06, 7.5918662435991949e-07, 1.9458139349161944e-07, 4.6286545842406255e-08, 1.0211061576622443e-08, 2.0873156939372195e-09, 3.9502105053420148e-10, 6.9144057864820654e-11, 1.1182840247910251e-11, 1.6693328537504025e-12, 2.2973505987627707e-13, 2.9112006503092275e-14, 3.3924183801506980e-15, 3.6302240823037884e-16, 3.5620366003569210e-17, 3.1997441855901569e-18, 2.6269310713002712e-19, 1.9674928839115667e-20, 1.3417423881673005e-21, 8.3141586271431848e-23, 4.6708788240159748e-24, 2.3734409390889848e-25, 1.0880533660044361e-26, 4.4876913417614677e-28, 1.6604056318842839e-29, 5.4933861932302487e-31, 1.6195898700068922e-32, 4.2392471038699379e-34, 9.8114235481332920e-36, 1.9990336800405551e-37, 3.5683132140145833e-39, 5.5510153038363309e-41, 7.4822992810294955e-43, 8.6832052790729524e-45, 8.6147071643386152e-47, 7.2494810877533628e-49, 5.1294451668154943e-51, 3.0217106412347761e-53, 1.4656166079834788e-55, 5.7792816013390868e-58, 1.8260394178147789e-60, 4.5461329246587614e-63, 8.7450484044987438e-66, 1.2700634063455813e-68, 1.3546124768341285e-71, 1.0259659682881671e-74, 5.2931716200065506e-78, 1.7648636462384819e-81, 3.5513952096001502e-85, 3.9333042153463284e-89, 2.1055559670183425e-93, 4.4826957080916534e-98, 2.7538984203799183e-103, 2.6468336179684675e-109, 8.3346219931731252e-117}, + {1.1929450990497388e-117, 3.9591990974598804e-110, 4.2745275541790886e-104, 7.1940582732963705e-99, 3.4858463341267156e-94, 6.7067764488470954e-90, 6.2295239916515678e-86, 3.1817588164569700e-82, 9.8006355361055656e-79, 1.9498222863573950e-75, 2.6411200905371024e-72, 2.5394077671157272e-69, 1.7924826309087973e-66, 9.5498361457830398e-64, 3.9302490205746199e-61, 1.2742413782141750e-58, 3.3097280501169341e-56, 6.9880745770528625e-54, 1.2146673922184433e-51, 1.7576627452371236e-49, 2.1383500879761454e-47, 2.2064997583491492e-45, 1.9463790072121561e-43, 1.4781646220486795e-41, 9.7267315160133413e-40, 5.5780033470752983e-38, 2.8025392714968451e-36, 1.2395973767055291e-34, 4.8482501635459064e-33, 1.6835590125100971e-31, 5.2099674531110126e-30, 1.4417990594032542e-28, 3.5795224098780112e-27, 7.9961758900246410e-26, 1.6116510554151974e-24, 2.9383411496603336e-23, 4.8574792709615864e-22, 7.2973076814277955e-21, 9.9829502923346154e-20, 1.2460703643781112e-18, 1.4216815546927034e-17, 1.4851721687462022e-16, 1.4228468795430129e-15, 1.2519744100239038e-14, 1.0132054243548976e-13, 7.5515422033135666e-13, 5.1897461393175068e-12, 3.2925485308161026e-11, 1.9304840630938534e-10, 1.0471078941135214e-09, 5.2592465173501358e-09, 2.4482298403820274e-08, 1.0571641536621842e-07, 4.2377549476354214e-07, 1.5781624324532756e-06, 5.4637147044287493e-06, 1.7596343655070067e-05, 5.2748866067347142e-05, 1.4726499921039843e-04, 3.8309201801330436e-04, 9.2902602860733265e-04, 2.1011697743361312e-03, 4.4337774736073364e-03, 8.7321528128579372e-03, 1.6056218663448245e-02, 2.7571764216085648e-02, 4.4227798774476149e-02, 6.6287455917162549e-02, 9.2844091734104794e-02, 1.2154351785304160e-01, 1.4873661992593393e-01, 1.7015822429768401e-01, 1.8199680336473223e-01, 1.8199680336473223e-01, 1.7015822429768401e-01, 1.4873661992593393e-01, 1.2154351785304160e-01, 9.2844091734104794e-02, 6.6287455917162549e-02, 4.4227798774476149e-02, 2.7571764216085648e-02, 1.6056218663448245e-02, 8.7321528128579372e-03, 4.4337774736073364e-03, 2.1011697743361312e-03, 9.2902602860733265e-04, 3.8309201801330436e-04, 1.4726499921039843e-04, 5.2748866067347142e-05, 1.7596343655070067e-05, 5.4637147044287493e-06, 1.5781624324532756e-06, 4.2377549476354214e-07, 1.0571641536621842e-07, 2.4482298403820274e-08, 5.2592465173501358e-09, 1.0471078941135214e-09, 1.9304840630938534e-10, 3.2925485308161026e-11, 5.1897461393175068e-12, 7.5515422033135666e-13, 1.0132054243548976e-13, 1.2519744100239038e-14, 1.4228468795430129e-15, 1.4851721687462022e-16, 1.4216815546927034e-17, 1.2460703643781112e-18, 9.9829502923346154e-20, 7.2973076814277955e-21, 4.8574792709615864e-22, 2.9383411496603336e-23, 1.6116510554151974e-24, 7.9961758900246410e-26, 3.5795224098780112e-27, 1.4417990594032542e-28, 5.2099674531110126e-30, 1.6835590125100971e-31, 4.8482501635459064e-33, 1.2395973767055291e-34, 2.8025392714968451e-36, 5.5780033470752983e-38, 9.7267315160133413e-40, 1.4781646220486795e-41, 1.9463790072121561e-43, 2.2064997583491492e-45, 2.1383500879761454e-47, 1.7576627452371236e-49, 1.2146673922184433e-51, 6.9880745770528625e-54, 3.3097280501169341e-56, 1.2742413782141750e-58, 3.9302490205746199e-61, 9.5498361457830398e-64, 1.7924826309087973e-66, 2.5394077671157272e-69, 2.6411200905371024e-72, 1.9498222863573950e-75, 9.8006355361055656e-79, 3.1817588164569700e-82, 6.2295239916515678e-86, 6.7067764488470954e-90, 3.4858463341267156e-94, 7.1940582732963705e-99, 4.2745275541790886e-104, 3.9591990974598804e-110, 1.1929450990497388e-117}, + {1.7070406181366590e-118, 5.9195113844414591e-111, 6.6305252022274385e-105, 1.1536024679706741e-99, 5.7653910975637400e-95, 1.1423077010030593e-90, 1.0913377348991997e-86, 5.7280704066660911e-83, 1.8118187632234171e-79, 3.6992788142779886e-76, 5.1399529790115008e-73, 5.0672863794680850e-70, 3.6662464654865143e-67, 2.0015272638354942e-64, 8.4387742209978957e-62, 2.8023099391369100e-59, 7.4539706347406648e-57, 1.6114689883841890e-54, 2.8677408135139503e-52, 4.2481015098521193e-50, 5.2903245181279725e-48, 5.5876178971908134e-46, 5.0448907217391667e-44, 3.9213661446271294e-42, 2.6409880203075402e-40, 1.5501131114814050e-38, 7.9712569158416828e-37, 3.6087469701637568e-35, 1.4446952835847923e-33, 5.1351616577255980e-32, 1.6267414726790182e-30, 4.6086441078964235e-29, 1.1714111882873408e-27, 2.6792736258069186e-26, 5.5296079664300731e-25, 1.0324183959837516e-23, 1.7479927721363103e-22, 2.6897676451867309e-21, 3.7695192606286801e-20, 4.8205800888162673e-19, 5.6356840948811206e-18, 6.0335058787737898e-17, 5.9246665636288388e-16, 5.3441830122937569e-15, 4.4343905593075405e-14, 3.3891924837505246e-13, 2.3889528428660744e-12, 1.5547996800001229e-11, 9.3534621545646173e-11, 5.2065241132424465e-10, 2.6842310976125569e-09, 1.2828665113850952e-08, 5.6885421998531753e-08, 2.3421973604647242e-07, 8.9613156437377830e-07, 3.1882138059205163e-06, 1.0554357586582146e-05, 3.2530204545596872e-05, 9.3401898795249160e-05, 2.4995620584101932e-04, 6.2376294512410423e-04, 1.4521587444586976e-03, 3.1551701974875863e-03, 6.4003731513496125e-03, 1.2125677167472506e-02, 2.1461222380505476e-02, 3.5494877838398289e-02, 5.4870701544829148e-02, 7.9298651231443446e-02, 1.0715555306319222e-01, 1.3540875492462576e-01, 1.6003249638444184e-01, 1.7690165636825916e-01, 1.8291007049692826e-01, 1.7690165636825916e-01, 1.6003249638444184e-01, 1.3540875492462576e-01, 1.0715555306319222e-01, 7.9298651231443446e-02, 5.4870701544829148e-02, 3.5494877838398289e-02, 2.1461222380505476e-02, 1.2125677167472506e-02, 6.4003731513496125e-03, 3.1551701974875863e-03, 1.4521587444586976e-03, 6.2376294512410423e-04, 2.4995620584101932e-04, 9.3401898795249160e-05, 3.2530204545596872e-05, 1.0554357586582146e-05, 3.1882138059205163e-06, 8.9613156437377830e-07, 2.3421973604647242e-07, 5.6885421998531753e-08, 1.2828665113850952e-08, 2.6842310976125569e-09, 5.2065241132424465e-10, 9.3534621545646173e-11, 1.5547996800001229e-11, 2.3889528428660744e-12, 3.3891924837505246e-13, 4.4343905593075405e-14, 5.3441830122937569e-15, 5.9246665636288388e-16, 6.0335058787737898e-17, 5.6356840948811206e-18, 4.8205800888162673e-19, 3.7695192606286801e-20, 2.6897676451867309e-21, 1.7479927721363103e-22, 1.0324183959837516e-23, 5.5296079664300731e-25, 2.6792736258069186e-26, 1.1714111882873408e-27, 4.6086441078964235e-29, 1.6267414726790182e-30, 5.1351616577255980e-32, 1.4446952835847923e-33, 3.6087469701637568e-35, 7.9712569158416828e-37, 1.5501131114814050e-38, 2.6409880203075402e-40, 3.9213661446271294e-42, 5.0448907217391667e-44, 5.5876178971908134e-46, 5.2903245181279725e-48, 4.2481015098521193e-50, 2.8677408135139503e-52, 1.6114689883841890e-54, 7.4539706347406648e-57, 2.8023099391369100e-59, 8.4387742209978957e-62, 2.0015272638354942e-64, 3.6662464654865143e-67, 5.0672863794680850e-70, 5.1399529790115008e-73, 3.6992788142779886e-76, 1.8118187632234171e-79, 5.7280704066660911e-83, 1.0913377348991997e-86, 1.1423077010030593e-90, 5.7653910975637400e-95, 1.1536024679706741e-99, 6.6305252022274385e-105, 5.9195113844414591e-111, 1.7070406181366590e-118}, + {2.4420658728359029e-119, 8.8463582669186499e-112, 1.0278520435124409e-105, 1.8483749220636043e-100, 9.5264999562099965e-96, 1.9434401044261462e-91, 1.9094951070499896e-87, 1.0297738588062730e-83, 3.3443041190506409e-80, 7.0066129472632568e-77, 9.9847674734222346e-74, 1.0091718959432019e-70, 7.4829681064377069e-68, 4.1855384000761587e-65, 1.8075959008515128e-62, 6.1472579038779528e-60, 1.6742548573659892e-57, 3.7056307854458431e-55, 6.7504839696392484e-53, 1.0235353311199910e-50, 1.3045775870281223e-48, 1.4101600092151863e-46, 1.3029538434289154e-44, 1.0364256329737640e-42, 7.1430632340356861e-41, 4.2904029597408759e-39, 2.2577848908542067e-37, 1.0460259894518416e-35, 4.2855476518701719e-34, 1.5590004744721381e-32, 5.0546933927274757e-31, 1.4657489608244835e-29, 3.8136046756805110e-28, 8.9292832689033937e-27, 1.8867047659679220e-25, 3.6067468226756066e-24, 6.2530721763179845e-23, 9.8539255836953708e-22, 1.4143965820612745e-20, 1.8527994733871280e-19, 2.2190951508494865e-18, 2.4342129329346826e-17, 2.4494846944487187e-16, 2.2645381737872469e-15, 1.9261422339406544e-14, 1.5093097961491213e-13, 1.0909182729913857e-12, 7.2818111329385306e-12, 4.4936440478669596e-11, 2.5663720011644112e-10, 1.3577644240845783e-09, 6.6605391288638309e-09, 3.0321186483039541e-08, 1.2819858780710668e-07, 5.0378676249733306e-07, 1.8413731465659074e-06, 6.2640223021607951e-06, 1.9844802959774770e-05, 5.8582692413005888e-05, 1.6123158507144338e-04, 4.1390553680515079e-04, 9.9155807247580142e-04, 2.2175853317597280e-03, 4.6318204121044990e-03, 9.0381820758826531e-03, 1.6481721286763326e-02, 2.8095443629279886e-02, 4.4780275406602559e-02, 6.6749354510874270e-02, 9.3066885205695463e-02, 1.2139368280029710e-01, 1.4814998194065979e-01, 1.6918056507168472e-01, 1.8078752906102052e-01, 1.8078752906102052e-01, 1.6918056507168472e-01, 1.4814998194065979e-01, 1.2139368280029710e-01, 9.3066885205695463e-02, 6.6749354510874270e-02, 4.4780275406602559e-02, 2.8095443629279886e-02, 1.6481721286763326e-02, 9.0381820758826531e-03, 4.6318204121044990e-03, 2.2175853317597280e-03, 9.9155807247580142e-04, 4.1390553680515079e-04, 1.6123158507144338e-04, 5.8582692413005888e-05, 1.9844802959774770e-05, 6.2640223021607951e-06, 1.8413731465659074e-06, 5.0378676249733306e-07, 1.2819858780710668e-07, 3.0321186483039541e-08, 6.6605391288638309e-09, 1.3577644240845783e-09, 2.5663720011644112e-10, 4.4936440478669596e-11, 7.2818111329385306e-12, 1.0909182729913857e-12, 1.5093097961491213e-13, 1.9261422339406544e-14, 2.2645381737872469e-15, 2.4494846944487187e-16, 2.4342129329346826e-17, 2.2190951508494865e-18, 1.8527994733871280e-19, 1.4143965820612745e-20, 9.8539255836953708e-22, 6.2530721763179845e-23, 3.6067468226756066e-24, 1.8867047659679220e-25, 8.9292832689033937e-27, 3.8136046756805110e-28, 1.4657489608244835e-29, 5.0546933927274757e-31, 1.5590004744721381e-32, 4.2855476518701719e-34, 1.0460259894518416e-35, 2.2577848908542067e-37, 4.2904029597408759e-39, 7.1430632340356861e-41, 1.0364256329737640e-42, 1.3029538434289154e-44, 1.4101600092151863e-46, 1.3045775870281223e-48, 1.0235353311199910e-50, 6.7504839696392484e-53, 3.7056307854458431e-55, 1.6742548573659892e-57, 6.1472579038779528e-60, 1.8075959008515128e-62, 4.1855384000761587e-65, 7.4829681064377069e-68, 1.0091718959432019e-70, 9.9847674734222346e-74, 7.0066129472632568e-77, 3.3443041190506409e-80, 1.0297738588062730e-83, 1.9094951070499896e-87, 1.9434401044261462e-91, 9.5264999562099965e-96, 1.8483749220636043e-100, 1.0278520435124409e-105, 8.8463582669186499e-112, 2.4420658728359029e-119}, + {3.4927077138614495e-120, 1.3214344265685972e-112, 1.5923529644019419e-106, 2.9592365392916602e-101, 1.5726312834383212e-96, 3.3028107528503361e-92, 3.3368715475506461e-88, 1.8487368270391726e-84, 6.1636129673212566e-81, 1.3248817176167857e-77, 1.9361289427704634e-74, 2.0059128285660820e-71, 1.5241335107478225e-68, 8.7332836494574003e-66, 3.8627717414010648e-63, 1.3451211690839924e-60, 3.7506692343030420e-58, 8.4975513070583486e-56, 1.5843787624675853e-53, 2.4585380900294205e-51, 3.2067130430374953e-49, 3.5468958347722111e-47, 3.3533561409072355e-45, 2.7292702435888796e-43, 1.9246140375840066e-41, 1.1827867549833032e-39, 6.3685955808210726e-38, 3.0190103270136603e-36, 1.2656167558393507e-34, 4.7112145637232019e-33, 1.5631232313432506e-31, 4.6386822641081590e-30, 1.2351960569462707e-28, 2.9601529366809405e-27, 6.4022761029959671e-26, 1.2529044419038621e-24, 2.2238719447561208e-23, 3.5882695810709981e-22, 5.2741804743987912e-21, 7.0757399180811555e-20, 8.6802800075429983e-19, 9.7541289549630027e-18, 1.0056284258182538e-16, 9.5266259491509481e-16, 8.3044572801891268e-15, 6.6701332750751410e-14, 4.9425874408492004e-13, 3.3828553008734636e-12, 2.1409348303068694e-11, 1.2542010220460425e-10, 6.8076912279459116e-10, 3.4268964379715692e-09, 1.6011995715635929e-08, 6.9500026302554605e-08, 2.8044586426011501e-07, 1.0528006766858483e-06, 3.6792955563634022e-06, 1.1977707839841136e-05, 3.6343264722217326e-05, 1.0283673489115176e-04, 2.7149548605395329e-04, 6.6906197625873226e-04, 1.5397243486054463e-03, 3.3102482665201089e-03, 6.6507742518744171e-03, 1.2491552298533356e-02, 2.1939032537498546e-02, 3.6040083142086628e-02, 5.5388310278285176e-02, 7.9652215262150924e-02, 1.0720010935792797e-01, 1.3504155894527325e-01, 1.5924245367972575e-01, 1.7579280253635429e-01, 1.8168248613117691e-01, 1.7579280253635429e-01, 1.5924245367972575e-01, 1.3504155894527325e-01, 1.0720010935792797e-01, 7.9652215262150924e-02, 5.5388310278285176e-02, 3.6040083142086628e-02, 2.1939032537498546e-02, 1.2491552298533356e-02, 6.6507742518744171e-03, 3.3102482665201089e-03, 1.5397243486054463e-03, 6.6906197625873226e-04, 2.7149548605395329e-04, 1.0283673489115176e-04, 3.6343264722217326e-05, 1.1977707839841136e-05, 3.6792955563634022e-06, 1.0528006766858483e-06, 2.8044586426011501e-07, 6.9500026302554605e-08, 1.6011995715635929e-08, 3.4268964379715692e-09, 6.8076912279459116e-10, 1.2542010220460425e-10, 2.1409348303068694e-11, 3.3828553008734636e-12, 4.9425874408492004e-13, 6.6701332750751410e-14, 8.3044572801891268e-15, 9.5266259491509481e-16, 1.0056284258182538e-16, 9.7541289549630027e-18, 8.6802800075429983e-19, 7.0757399180811555e-20, 5.2741804743987912e-21, 3.5882695810709981e-22, 2.2238719447561208e-23, 1.2529044419038621e-24, 6.4022761029959671e-26, 2.9601529366809405e-27, 1.2351960569462707e-28, 4.6386822641081590e-30, 1.5631232313432506e-31, 4.7112145637232019e-33, 1.2656167558393507e-34, 3.0190103270136603e-36, 6.3685955808210726e-38, 1.1827867549833032e-39, 1.9246140375840066e-41, 2.7292702435888796e-43, 3.3533561409072355e-45, 3.5468958347722111e-47, 3.2067130430374953e-49, 2.4585380900294205e-51, 1.5843787624675853e-53, 8.4975513070583486e-56, 3.7506692343030420e-58, 1.3451211690839924e-60, 3.8627717414010648e-63, 8.7332836494574003e-66, 1.5241335107478225e-68, 2.0059128285660820e-71, 1.9361289427704634e-74, 1.3248817176167857e-77, 6.1636129673212566e-81, 1.8487368270391726e-84, 3.3368715475506461e-88, 3.3028107528503361e-92, 1.5726312834383212e-96, 2.9592365392916602e-101, 1.5923529644019419e-106, 1.3214344265685972e-112, 3.4927077138614495e-120}, + {4.9941282442606218e-121, 1.9730195235183967e-113, 2.4653426103610859e-107, 4.7340081105291807e-102, 2.5936668261705122e-97, 5.6069447675960520e-93, 5.8240937771374570e-89, 3.3144783626996768e-85, 1.1342570222437056e-81, 2.5011096149430186e-78, 3.7476379174495528e-75, 3.9794814788876447e-72, 3.0979908735545725e-69, 1.8182439901095753e-66, 8.2354102738652040e-64, 2.9360923690156291e-61, 8.3803809757287599e-59, 1.9432660775004502e-56, 3.7079038793856585e-54, 5.8875467910577051e-52, 7.8572573935602256e-50, 8.8917221680510199e-48, 8.6005009516161168e-46, 7.1611639319733097e-44, 5.1661373788013124e-42, 3.2479669251550536e-40, 1.7890987177636214e-38, 8.6765699223362474e-37, 3.7212625316226216e-35, 1.4172340427766930e-33, 4.8110787981190828e-32, 1.4608586938294995e-30, 3.9805330733973355e-29, 9.7620761562971344e-28, 2.1608244949042565e-26, 4.3281046749583524e-25, 7.8636681438025253e-24, 1.2989130984240299e-22, 1.9546850118180088e-21, 2.6851626691585123e-20, 3.3733593511587544e-19, 3.8824303202657657e-18, 4.1001349905289425e-17, 3.9793051828221563e-16, 3.5542824359476288e-15, 2.9256051436471688e-14, 2.2220151125790449e-13, 1.5590549255574669e-12, 1.0116812009960419e-11, 6.0778437594159535e-11, 3.3838207012562939e-10, 1.7475098827142176e-09, 8.3784654573163473e-09, 3.7324734098992270e-08, 1.5461411843105312e-07, 5.9598254897039207e-07, 2.1391519688131322e-06, 7.1539515355890577e-06, 2.2304926470707147e-05, 6.4869805018180065e-05, 1.7607226778935711e-04, 4.4622007110453903e-04, 1.0563416857043819e-03, 2.3368400915518292e-03, 4.8325911868397145e-03, 9.3454535527143379e-03, 1.6905135871613127e-02, 2.8612106958160764e-02, 4.5320570847252710e-02, 6.7196013411209815e-02, 9.3275910346104995e-02, 1.2123716317285059e-01, 1.4756796236123393e-01, 1.6821923724022270e-01, 1.7960204009494329e-01, 1.7960204009494329e-01, 1.6821923724022270e-01, 1.4756796236123393e-01, 1.2123716317285059e-01, 9.3275910346104995e-02, 6.7196013411209815e-02, 4.5320570847252710e-02, 2.8612106958160764e-02, 1.6905135871613127e-02, 9.3454535527143379e-03, 4.8325911868397145e-03, 2.3368400915518292e-03, 1.0563416857043819e-03, 4.4622007110453903e-04, 1.7607226778935711e-04, 6.4869805018180065e-05, 2.2304926470707147e-05, 7.1539515355890577e-06, 2.1391519688131322e-06, 5.9598254897039207e-07, 1.5461411843105312e-07, 3.7324734098992270e-08, 8.3784654573163473e-09, 1.7475098827142176e-09, 3.3838207012562939e-10, 6.0778437594159535e-11, 1.0116812009960419e-11, 1.5590549255574669e-12, 2.2220151125790449e-13, 2.9256051436471688e-14, 3.5542824359476288e-15, 3.9793051828221563e-16, 4.1001349905289425e-17, 3.8824303202657657e-18, 3.3733593511587544e-19, 2.6851626691585123e-20, 1.9546850118180088e-21, 1.2989130984240299e-22, 7.8636681438025253e-24, 4.3281046749583524e-25, 2.1608244949042565e-26, 9.7620761562971344e-28, 3.9805330733973355e-29, 1.4608586938294995e-30, 4.8110787981190828e-32, 1.4172340427766930e-33, 3.7212625316226216e-35, 8.6765699223362474e-37, 1.7890987177636214e-38, 3.2479669251550536e-40, 5.1661373788013124e-42, 7.1611639319733097e-44, 8.6005009516161168e-46, 8.8917221680510199e-48, 7.8572573935602256e-50, 5.8875467910577051e-52, 3.7079038793856585e-54, 1.9432660775004502e-56, 8.3803809757287599e-59, 2.9360923690156291e-61, 8.2354102738652040e-64, 1.8182439901095753e-66, 3.0979908735545725e-69, 3.9794814788876447e-72, 3.7476379174495528e-75, 2.5011096149430186e-78, 1.1342570222437056e-81, 3.3144783626996768e-85, 5.8240937771374570e-89, 5.6069447675960520e-93, 2.5936668261705122e-97, 4.7340081105291807e-102, 2.4653426103610859e-107, 1.9730195235183967e-113, 4.9941282442606218e-121}, + {7.1392222017713907e-122, 2.9445845110667619e-114, 3.8145868837135596e-108, 7.5673169898909099e-103, 4.2736593644380303e-98, 9.5083335143727237e-94, 1.0152930470452851e-89, 5.9342954899998552e-86, 2.0842120266141319e-82, 4.7139344340961388e-79, 7.2413131304484502e-76, 7.8798610228883591e-73, 6.2842892805603737e-70, 3.7773465198180638e-67, 1.7517513408453002e-64, 6.3932209199477197e-62, 1.8676726441679446e-59, 4.4319273103122463e-57, 8.6528507374176976e-55, 1.4056977850593077e-52, 1.9192002948401386e-50, 2.2217716370141584e-48, 2.1982691386986115e-46, 1.8722764372760468e-44, 1.3815703248778117e-42, 8.8845643289761640e-41, 5.0058533566520875e-39, 2.4832338706643681e-37, 1.0894227474485724e-35, 4.2442335712525587e-34, 1.4739090369348960e-32, 4.5785676785685073e-31, 1.2763864929327656e-29, 3.2028196423033392e-28, 7.2542458795704827e-27, 1.4869262820581125e-25, 2.7648741131715751e-24, 4.6744604380487021e-23, 7.2007069149677438e-22, 1.0126623472614820e-20, 1.3025790505179032e-19, 1.5351372541981349e-18, 1.6603563330241997e-17, 1.6505566788948694e-16, 1.5102835946897961e-15, 1.2737138463928603e-14, 9.9133825544714478e-14, 7.1289732797212971e-13, 4.7421458438831827e-12, 2.9209512270101235e-11, 1.6676562560887225e-10, 8.8333847125166249e-10, 4.3447745740955300e-09, 1.9860254178505552e-08, 8.4433687619112637e-08, 3.3409895046160263e-07, 1.2312829806627210e-06, 4.2290221665164350e-06, 1.3544999036061644e-05, 4.0477621043373221e-05, 1.1292006863438276e-04, 2.9420790203745482e-04, 7.1623536508659178e-04, 1.6298641009901027e-03, 3.4681866693627482e-03, 6.9032861428781267e-03, 1.2857145952636101e-02, 2.2412375310366960e-02, 3.6575629838591243e-02, 5.5891953828813568e-02, 7.9990869817108165e-02, 1.0723403572962083e-01, 1.3467313142650547e-01, 1.5846303276659124e-01, 1.7470447835636663e-01, 1.8047929085878514e-01, 1.7470447835636663e-01, 1.5846303276659124e-01, 1.3467313142650547e-01, 1.0723403572962083e-01, 7.9990869817108165e-02, 5.5891953828813568e-02, 3.6575629838591243e-02, 2.2412375310366960e-02, 1.2857145952636101e-02, 6.9032861428781267e-03, 3.4681866693627482e-03, 1.6298641009901027e-03, 7.1623536508659178e-04, 2.9420790203745482e-04, 1.1292006863438276e-04, 4.0477621043373221e-05, 1.3544999036061644e-05, 4.2290221665164350e-06, 1.2312829806627210e-06, 3.3409895046160263e-07, 8.4433687619112637e-08, 1.9860254178505552e-08, 4.3447745740955300e-09, 8.8333847125166249e-10, 1.6676562560887225e-10, 2.9209512270101235e-11, 4.7421458438831827e-12, 7.1289732797212971e-13, 9.9133825544714478e-14, 1.2737138463928603e-14, 1.5102835946897961e-15, 1.6505566788948694e-16, 1.6603563330241997e-17, 1.5351372541981349e-18, 1.3025790505179032e-19, 1.0126623472614820e-20, 7.2007069149677438e-22, 4.6744604380487021e-23, 2.7648741131715751e-24, 1.4869262820581125e-25, 7.2542458795704827e-27, 3.2028196423033392e-28, 1.2763864929327656e-29, 4.5785676785685073e-31, 1.4739090369348960e-32, 4.2442335712525587e-34, 1.0894227474485724e-35, 2.4832338706643681e-37, 5.0058533566520875e-39, 8.8845643289761640e-41, 1.3815703248778117e-42, 1.8722764372760468e-44, 2.1982691386986115e-46, 2.2217716370141584e-48, 1.9192002948401386e-50, 1.4056977850593077e-52, 8.6528507374176976e-55, 4.4319273103122463e-57, 1.8676726441679446e-59, 6.3932209199477197e-62, 1.7517513408453002e-64, 3.7773465198180638e-67, 6.2842892805603737e-70, 7.8798610228883591e-73, 7.2413131304484502e-76, 4.7139344340961388e-79, 2.0842120266141319e-82, 5.9342954899998552e-86, 1.0152930470452851e-89, 9.5083335143727237e-94, 4.2736593644380303e-98, 7.5673169898909099e-103, 3.8145868837135596e-108, 2.9445845110667619e-114, 7.1392222017713907e-122}, + {1.0203215419405115e-122, 4.3926409088220260e-115, 5.8986558173681245e-109, 1.2087105293093391e-103, 7.0353980850250737e-99, 1.6107326288260005e-94, 1.7678067289525790e-90, 1.0610697100358954e-86, 3.8241442068780522e-83, 8.8702923923721366e-80, 1.3967624162820115e-76, 1.5573928888055416e-73, 1.2722188115916827e-70, 7.8305641247237068e-68, 3.7176883954596755e-65, 1.3887513560879043e-62, 4.1517737028880682e-60, 1.0080675510766497e-57, 2.0135706193376487e-55, 3.3463102229914590e-53, 4.6733192109921242e-51, 5.5335945022909141e-49, 5.5997707655432161e-47, 4.8778201649868724e-45, 3.6811705155316592e-43, 2.4210413787496984e-41, 1.3950773628177882e-39, 7.0777866064732306e-38, 3.1757468989046869e-36, 1.2654132053176338e-34, 4.4947480753641788e-33, 1.4281952005441561e-31, 4.0727582182469552e-30, 1.0454808582283026e-28, 2.4226185736538330e-27, 5.0807355599009919e-26, 9.6670785467690252e-25, 1.6725361565602745e-23, 2.6368638947823986e-22, 3.7957111549106315e-21, 4.9980289800251531e-20, 6.0306098179642906e-19, 6.6786804983364280e-18, 6.7991402460144679e-17, 6.3720317811650348e-16, 5.5049284400726915e-15, 4.3896449685818035e-14, 3.2346882306340970e-13, 2.2052168865195276e-12, 1.3923473891503035e-11, 8.1499619365601122e-11, 4.4267370542157585e-10, 2.2331409933577818e-09, 1.0471618689062924e-08, 4.5678915072122709e-08, 1.8549839541616252e-07, 7.0175441742037147e-07, 2.4747420668926454e-06, 8.1402071214919003e-06, 2.4988785980142873e-05, 7.1628474554958981e-05, 1.9180837279585649e-04, 4.8004901932197877e-04, 1.1233614820028411e-03, 2.4588639421196687e-03, 5.0359498094177816e-03, 9.6537773093780983e-03, 1.7326295602536231e-02, 2.9121725644242560e-02, 4.5848897885251948e-02, 6.7627897299374851e-02, 9.3471746781564918e-02, 1.2107439739077461e-01, 1.4699060677873937e-01, 1.6727380280253201e-01, 1.7843956694581845e-01, 1.7843956694581845e-01, 1.6727380280253201e-01, 1.4699060677873937e-01, 1.2107439739077461e-01, 9.3471746781564918e-02, 6.7627897299374851e-02, 4.5848897885251948e-02, 2.9121725644242560e-02, 1.7326295602536231e-02, 9.6537773093780983e-03, 5.0359498094177816e-03, 2.4588639421196687e-03, 1.1233614820028411e-03, 4.8004901932197877e-04, 1.9180837279585649e-04, 7.1628474554958981e-05, 2.4988785980142873e-05, 8.1402071214919003e-06, 2.4747420668926454e-06, 7.0175441742037147e-07, 1.8549839541616252e-07, 4.5678915072122709e-08, 1.0471618689062924e-08, 2.2331409933577818e-09, 4.4267370542157585e-10, 8.1499619365601122e-11, 1.3923473891503035e-11, 2.2052168865195276e-12, 3.2346882306340970e-13, 4.3896449685818035e-14, 5.5049284400726915e-15, 6.3720317811650348e-16, 6.7991402460144679e-17, 6.6786804983364280e-18, 6.0306098179642906e-19, 4.9980289800251531e-20, 3.7957111549106315e-21, 2.6368638947823986e-22, 1.6725361565602745e-23, 9.6670785467690252e-25, 5.0807355599009919e-26, 2.4226185736538330e-27, 1.0454808582283026e-28, 4.0727582182469552e-30, 1.4281952005441561e-31, 4.4947480753641788e-33, 1.2654132053176338e-34, 3.1757468989046869e-36, 7.0777866064732306e-38, 1.3950773628177882e-39, 2.4210413787496984e-41, 3.6811705155316592e-43, 4.8778201649868724e-45, 5.5997707655432161e-47, 5.5335945022909141e-49, 4.6733192109921242e-51, 3.3463102229914590e-53, 2.0135706193376487e-55, 1.0080675510766497e-57, 4.1517737028880682e-60, 1.3887513560879043e-62, 3.7176883954596755e-65, 7.8305641247237068e-68, 1.2722188115916827e-70, 1.5573928888055416e-73, 1.3967624162820115e-76, 8.8702923923721366e-80, 3.8241442068780522e-83, 1.0610697100358954e-86, 1.7678067289525790e-90, 1.6107326288260005e-94, 7.0353980850250737e-99, 1.2087105293093391e-103, 5.8986558173681245e-109, 4.3926409088220260e-115, 1.0203215419405115e-122}, + {1.4578716888574380e-123, 6.5499584195542182e-116, 9.1158441302395916e-110, 1.9291851130201365e-104, 1.1571376888010415e-99, 2.7257668732866951e-95, 3.0744291780743119e-91, 1.8947250431186403e-87, 7.0064183028413687e-84, 1.6664955389849393e-80, 2.6895662316444978e-77, 3.0723812680200150e-74, 2.5704405332276809e-71, 1.6198772061572697e-68, 7.8722498229365745e-66, 3.0095177392268181e-63, 9.2061099904566106e-61, 2.2868504296047653e-58, 4.6726874994563693e-56, 7.9427931843455534e-54, 1.1344972574084324e-51, 1.3738127684763008e-49, 1.4217090927665081e-47, 1.2663997582044745e-45, 9.7729455955061106e-44, 6.5725138972034875e-42, 3.8727324373725659e-40, 2.0091450762048232e-38, 9.2185663859103873e-37, 3.7563551936945986e-35, 1.3644995796552897e-33, 4.4341465741479497e-32, 1.2932715429724819e-30, 3.3956536214966241e-29, 8.0487680064663208e-28, 1.7268001245109222e-26, 3.3613905413108243e-25, 5.9504202589874584e-24, 9.5995603721747768e-23, 1.4141461815469168e-21, 1.9058394524305284e-20, 2.3538938440623925e-19, 2.6687563232163005e-18, 2.7817760484437033e-17, 2.6696608032295694e-16, 2.3621238776008329e-15, 1.9293848215014542e-14, 1.4565613270987712e-13, 1.0174797099588637e-12, 6.5837630407380247e-12, 3.9501281887181556e-11, 2.1996223199610065e-10, 1.1378158851290800e-09, 5.4720083734809282e-09, 2.4485807329829557e-08, 1.0202255589712521e-07, 3.9608954710479925e-07, 1.4337991258427923e-06, 4.8422272544211524e-06, 1.5265488972373680e-05, 4.4948480076886716e-05, 1.2367217082799177e-04, 3.1811200186972611e-04, 7.6528399238001590e-04, 1.7225370790285232e-03, 3.6288805291928589e-03, 7.1577405214717574e-03, 1.3222272319718250e-02, 2.2881143871485050e-02, 3.7101604703410701e-02, 5.6381975314828768e-02, 8.0315152775434245e-02, 1.0725786228191081e-01, 1.3430372904700771e-01, 1.5769403536946561e-01, 1.7363606017905039e-01, 1.7929968765055787e-01, 1.7363606017905039e-01, 1.5769403536946561e-01, 1.3430372904700771e-01, 1.0725786228191081e-01, 8.0315152775434245e-02, 5.6381975314828768e-02, 3.7101604703410701e-02, 2.2881143871485050e-02, 1.3222272319718250e-02, 7.1577405214717574e-03, 3.6288805291928589e-03, 1.7225370790285232e-03, 7.6528399238001590e-04, 3.1811200186972611e-04, 1.2367217082799177e-04, 4.4948480076886716e-05, 1.5265488972373680e-05, 4.8422272544211524e-06, 1.4337991258427923e-06, 3.9608954710479925e-07, 1.0202255589712521e-07, 2.4485807329829557e-08, 5.4720083734809282e-09, 1.1378158851290800e-09, 2.1996223199610065e-10, 3.9501281887181556e-11, 6.5837630407380247e-12, 1.0174797099588637e-12, 1.4565613270987712e-13, 1.9293848215014542e-14, 2.3621238776008329e-15, 2.6696608032295694e-16, 2.7817760484437033e-17, 2.6687563232163005e-18, 2.3538938440623925e-19, 1.9058394524305284e-20, 1.4141461815469168e-21, 9.5995603721747768e-23, 5.9504202589874584e-24, 3.3613905413108243e-25, 1.7268001245109222e-26, 8.0487680064663208e-28, 3.3956536214966241e-29, 1.2932715429724819e-30, 4.4341465741479497e-32, 1.3644995796552897e-33, 3.7563551936945986e-35, 9.2185663859103873e-37, 2.0091450762048232e-38, 3.8727324373725659e-40, 6.5725138972034875e-42, 9.7729455955061106e-44, 1.2663997582044745e-45, 1.4217090927665081e-47, 1.3738127684763008e-49, 1.1344972574084324e-51, 7.9427931843455534e-54, 4.6726874994563693e-56, 2.2868504296047653e-58, 9.2061099904566106e-61, 3.0095177392268181e-63, 7.8722498229365745e-66, 1.6198772061572697e-68, 2.5704405332276809e-71, 3.0723812680200150e-74, 2.6895662316444978e-77, 1.6664955389849393e-80, 7.0064183028413687e-84, 1.8947250431186403e-87, 3.0744291780743119e-91, 2.7257668732866951e-95, 1.1571376888010415e-99, 1.9291851130201365e-104, 9.1158441302395916e-110, 6.5499584195542182e-116, 1.4578716888574380e-123}, + {2.0825660478904760e-124, 9.7625806330567035e-117, 1.4079328290981535e-110, 3.0768081483238432e-105, 1.9014873630323964e-100, 4.6079244634146070e-96, 5.3405557808694215e-92, 3.3789567793532434e-88, 1.2818424753415062e-84, 3.1260093916222602e-81, 5.1701750558611924e-78, 6.0500487002887184e-75, 5.1832685019930213e-72, 3.3439902942647502e-69, 1.6632668027272507e-66, 6.5065315377220389e-64, 2.0362992343457651e-61, 5.1742950935108869e-59, 1.0813687999683845e-56, 1.8798749780879993e-54, 2.7458133331828386e-52, 3.3999899766205468e-50, 3.5976656083923711e-48, 3.2766076271604045e-46, 2.5853058405449532e-44, 1.7776460048844266e-42, 1.0709222498944708e-40, 5.6804446369555694e-39, 2.6648525467274738e-37, 1.1102669670225965e-35, 4.1238340545301011e-34, 1.3703279298000201e-32, 4.0870885738671846e-31, 1.0974483844909332e-29, 2.6604572771951219e-28, 5.8380527272929378e-27, 1.1624651194307257e-25, 2.1051475426760218e-24, 3.4745776974200654e-23, 5.2372761374065798e-22, 7.2227982269547378e-21, 9.1298647949536611e-20, 1.0594921794825161e-18, 1.1305197522298609e-17, 1.1108048214201895e-16, 1.0064014746615927e-15, 8.4185702868695228e-15, 6.5097729971311742e-14, 4.6585402153758067e-13, 3.0885703725214258e-12, 1.8990163158421596e-11, 1.0838710379194289e-10, 5.7477002127859619e-10, 2.8342947222693205e-09, 1.3006943860141712e-08, 5.5591582741553296e-08, 2.2143724484223221e-07, 8.2259408138485364e-07, 2.8515507236878458e-06, 9.2296922270054013e-06, 2.7908549833980887e-05, 7.8876670613220481e-05, 2.0846012412302649e-04, 5.1540364930051158e-04, 1.1925993797900470e-03, 2.5835851277422653e-03, 5.2417582224628060e-03, 9.9629708516368199e-03, 1.7745045563417383e-02, 2.9624281938924940e-02, 4.6365470641524055e-02, 6.8045456872924986e-02, 9.3654947635056565e-02, 1.2090579766618584e-01, 1.4641795120378570e-01, 1.6634383944546130e-01, 1.7729937449709982e-01, 1.7729937449709982e-01, 1.6634383944546130e-01, 1.4641795120378570e-01, 1.2090579766618584e-01, 9.3654947635056565e-02, 6.8045456872924986e-02, 4.6365470641524055e-02, 2.9624281938924940e-02, 1.7745045563417383e-02, 9.9629708516368199e-03, 5.2417582224628060e-03, 2.5835851277422653e-03, 1.1925993797900470e-03, 5.1540364930051158e-04, 2.0846012412302649e-04, 7.8876670613220481e-05, 2.7908549833980887e-05, 9.2296922270054013e-06, 2.8515507236878458e-06, 8.2259408138485364e-07, 2.2143724484223221e-07, 5.5591582741553296e-08, 1.3006943860141712e-08, 2.8342947222693205e-09, 5.7477002127859619e-10, 1.0838710379194289e-10, 1.8990163158421596e-11, 3.0885703725214258e-12, 4.6585402153758067e-13, 6.5097729971311742e-14, 8.4185702868695228e-15, 1.0064014746615927e-15, 1.1108048214201895e-16, 1.1305197522298609e-17, 1.0594921794825161e-18, 9.1298647949536611e-20, 7.2227982269547378e-21, 5.2372761374065798e-22, 3.4745776974200654e-23, 2.1051475426760218e-24, 1.1624651194307257e-25, 5.8380527272929378e-27, 2.6604572771951219e-28, 1.0974483844909332e-29, 4.0870885738671846e-31, 1.3703279298000201e-32, 4.1238340545301011e-34, 1.1102669670225965e-35, 2.6648525467274738e-37, 5.6804446369555694e-39, 1.0709222498944708e-40, 1.7776460048844266e-42, 2.5853058405449532e-44, 3.2766076271604045e-46, 3.5976656083923711e-48, 3.3999899766205468e-50, 2.7458133331828386e-52, 1.8798749780879993e-54, 1.0813687999683845e-56, 5.1742950935108869e-59, 2.0362992343457651e-61, 6.5065315377220389e-64, 1.6632668027272507e-66, 3.3439902942647502e-69, 5.1832685019930213e-72, 6.0500487002887184e-75, 5.1701750558611924e-78, 3.1260093916222602e-81, 1.2818424753415062e-84, 3.3789567793532434e-88, 5.3405557808694215e-92, 4.6079244634146070e-96, 1.9014873630323964e-100, 3.0768081483238432e-105, 1.4079328290981535e-110, 9.7625806330567035e-117, 2.0825660478904760e-124}, + {2.9742440544925765e-125, 1.4544742104415291e-117, 2.1732568643306002e-111, 4.9034921609592363e-106, 3.1218947762576099e-101, 7.7817715084363300e-97, 9.2663025096531715e-93, 6.0181049060844634e-89, 2.3418402716705127e-85, 5.8546944803309517e-82, 9.9220223776303372e-79, 1.1892107956658327e-75, 1.0431826368600407e-72, 6.8889436382474771e-70, 3.5064990884120332e-67, 1.4034428812712122e-64, 4.4930692768932806e-62, 1.1677337858216425e-59, 2.4957603118464674e-57, 4.4365856613493741e-55, 6.6258941032515879e-53, 8.3883165922512944e-51, 9.0744120512086595e-49, 8.4490059406933366e-47, 6.8149889325650219e-45, 4.7903177946790465e-43, 2.9501316492565748e-41, 1.5996806743635201e-39, 7.6718304654322104e-38, 3.2676791768964119e-36, 1.2408362449919783e-34, 4.2155847725706856e-33, 1.2855517878737815e-31, 3.5296150194332557e-30, 8.7497557637466758e-29, 1.9635223775022683e-27, 3.9986259229284162e-26, 7.4065187877720327e-25, 1.2504748686909515e-23, 1.9282493305400296e-22, 2.7207846792186873e-21, 3.5191108460642354e-20, 4.1792457685713468e-19, 4.5641951147736119e-18, 4.5905709762107554e-17, 4.2579719891425731e-16, 3.6469920289222789e-15, 2.8879673414801644e-14, 2.1167713706852141e-13, 1.4376384719405419e-12, 9.0565354971087218e-12, 5.2969771654748994e-11, 2.8789912587990587e-10, 1.4553534068219742e-09, 6.8479451315824872e-09, 3.0015309064632456e-08, 1.2263753200782247e-07, 4.6740187357094381e-07, 1.6627017535681513e-06, 5.5239309109102710e-06, 1.7148598641483128e-05, 4.9770974063404784e-05, 1.3511264030161956e-04, 3.4322471703307256e-04, 8.1620625227316382e-04, 1.8177000254213835e-03, 3.7922249171946417e-03, 7.4139737035166485e-03, 1.3586755499761058e-02, 2.3345243317359717e-02, 3.7618101204680170e-02, 5.6858711709023881e-02, 8.0625581158863605e-02, 1.0727209153833471e-01, 1.3393358950744624e-01, 1.5693526614765907e-01, 1.7258695046281516e-01, 1.7814291547216715e-01, 1.7258695046281516e-01, 1.5693526614765907e-01, 1.3393358950744624e-01, 1.0727209153833471e-01, 8.0625581158863605e-02, 5.6858711709023881e-02, 3.7618101204680170e-02, 2.3345243317359717e-02, 1.3586755499761058e-02, 7.4139737035166485e-03, 3.7922249171946417e-03, 1.8177000254213835e-03, 8.1620625227316382e-04, 3.4322471703307256e-04, 1.3511264030161956e-04, 4.9770974063404784e-05, 1.7148598641483128e-05, 5.5239309109102710e-06, 1.6627017535681513e-06, 4.6740187357094381e-07, 1.2263753200782247e-07, 3.0015309064632456e-08, 6.8479451315824872e-09, 1.4553534068219742e-09, 2.8789912587990587e-10, 5.2969771654748994e-11, 9.0565354971087218e-12, 1.4376384719405419e-12, 2.1167713706852141e-13, 2.8879673414801644e-14, 3.6469920289222789e-15, 4.2579719891425731e-16, 4.5905709762107554e-17, 4.5641951147736119e-18, 4.1792457685713468e-19, 3.5191108460642354e-20, 2.7207846792186873e-21, 1.9282493305400296e-22, 1.2504748686909515e-23, 7.4065187877720327e-25, 3.9986259229284162e-26, 1.9635223775022683e-27, 8.7497557637466758e-29, 3.5296150194332557e-30, 1.2855517878737815e-31, 4.2155847725706856e-33, 1.2408362449919783e-34, 3.2676791768964119e-36, 7.6718304654322104e-38, 1.5996806743635201e-39, 2.9501316492565748e-41, 4.7903177946790465e-43, 6.8149889325650219e-45, 8.4490059406933366e-47, 9.0744120512086595e-49, 8.3883165922512944e-51, 6.6258941032515879e-53, 4.4365856613493741e-55, 2.4957603118464674e-57, 1.1677337858216425e-59, 4.4930692768932806e-62, 1.4034428812712122e-64, 3.5064990884120332e-67, 6.8889436382474771e-70, 1.0431826368600407e-72, 1.1892107956658327e-75, 9.9220223776303372e-79, 5.8546944803309517e-82, 2.3418402716705127e-85, 6.0181049060844634e-89, 9.2663025096531715e-93, 7.7817715084363300e-97, 3.1218947762576099e-101, 4.9034921609592363e-106, 2.1732568643306002e-111, 1.4544742104415291e-117, 2.9742440544925765e-125}, + {4.2467223153569913e-126, 2.1660313165253327e-118, 3.3526412389934468e-112, 7.8089506311734750e-107, 5.1211062371557049e-102, 1.3128438701986923e-97, 1.6059434510399780e-93, 1.0704932710164072e-89, 4.2723909537910979e-86, 1.0948479687576274e-82, 1.9009714466058216e-79, 2.3333732870895970e-76, 2.0954987289754821e-73, 1.4163011238027347e-70, 7.3764205708401192e-68, 3.0202620912677113e-65, 9.8899383346021114e-63, 2.6286294129074487e-60, 5.7447123101943819e-58, 1.0441146661857655e-55, 1.5941894796140349e-53, 2.0631744724119192e-51, 2.2815057723526744e-49, 2.1713655679015281e-47, 1.7902127496153674e-45, 1.2862015727088547e-43, 8.0963481474532886e-42, 4.4873140335977730e-40, 2.1997031006119584e-38, 9.5769420875142906e-37, 3.7173934630972095e-35, 1.2910298923887236e-33, 4.0247941719917949e-32, 1.1297479501227750e-30, 2.8633730681601511e-29, 6.5701662464695220e-28, 1.3681807173905664e-26, 2.5916454156396681e-25, 4.4751190749666469e-24, 7.0583497822483184e-23, 1.0188011695097018e-21, 1.3481278810188344e-20, 1.6381331947152628e-19, 1.8307185107770479e-18, 1.8844546640240470e-17, 1.7891286411123497e-16, 1.5687514682212088e-15, 1.2719076381502738e-14, 9.5465675547568851e-14, 6.6405134257786806e-13, 4.2851307836098596e-12, 2.5677582201989908e-11, 1.4301024597508902e-10, 7.4092720692344339e-10, 3.5737970851749710e-09, 1.6060537813990750e-08, 6.7293992111962037e-08, 2.6306912128825106e-07, 9.6009499955544809e-07, 3.2731466120984474e-06, 1.0429494937549579e-05, 3.1076452822469759e-05, 8.6632019755194801e-05, 2.2604661890533189e-04, 5.5229314310309603e-04, 1.2640347665701273e-03, 2.7109305106750477e-03, 5.4498805064709423e-03, 1.0272859026411405e-02, 1.8161242168807858e-02, 3.0119768029475406e-02, 4.6870503949025956e-02, 6.8449129121212759e-02, 9.3826040853472042e-02, 1.2073175170965833e-01, 1.4585002297738520e-01, 1.6542893986636190e-01, 1.7618076008397315e-01, 1.7618076008397315e-01, 1.6542893986636190e-01, 1.4585002297738520e-01, 1.2073175170965833e-01, 9.3826040853472042e-02, 6.8449129121212759e-02, 4.6870503949025956e-02, 3.0119768029475406e-02, 1.8161242168807858e-02, 1.0272859026411405e-02, 5.4498805064709423e-03, 2.7109305106750477e-03, 1.2640347665701273e-03, 5.5229314310309603e-04, 2.2604661890533189e-04, 8.6632019755194801e-05, 3.1076452822469759e-05, 1.0429494937549579e-05, 3.2731466120984474e-06, 9.6009499955544809e-07, 2.6306912128825106e-07, 6.7293992111962037e-08, 1.6060537813990750e-08, 3.5737970851749710e-09, 7.4092720692344339e-10, 1.4301024597508902e-10, 2.5677582201989908e-11, 4.2851307836098596e-12, 6.6405134257786806e-13, 9.5465675547568851e-14, 1.2719076381502738e-14, 1.5687514682212088e-15, 1.7891286411123497e-16, 1.8844546640240470e-17, 1.8307185107770479e-18, 1.6381331947152628e-19, 1.3481278810188344e-20, 1.0188011695097018e-21, 7.0583497822483184e-23, 4.4751190749666469e-24, 2.5916454156396681e-25, 1.3681807173905664e-26, 6.5701662464695220e-28, 2.8633730681601511e-29, 1.1297479501227750e-30, 4.0247941719917949e-32, 1.2910298923887236e-33, 3.7173934630972095e-35, 9.5769420875142906e-37, 2.1997031006119584e-38, 4.4873140335977730e-40, 8.0963481474532886e-42, 1.2862015727088547e-43, 1.7902127496153674e-45, 2.1713655679015281e-47, 2.2815057723526744e-49, 2.0631744724119192e-51, 1.5941894796140349e-53, 1.0441146661857655e-55, 5.7447123101943819e-58, 2.6286294129074487e-60, 9.8899383346021114e-63, 3.0202620912677113e-65, 7.3764205708401192e-68, 1.4163011238027347e-70, 2.0954987289754821e-73, 2.3333732870895970e-76, 1.9009714466058216e-79, 1.0948479687576274e-82, 4.2723909537910979e-86, 1.0704932710164072e-89, 1.6059434510399780e-93, 1.3128438701986923e-97, 5.1211062371557049e-102, 7.8089506311734750e-107, 3.3526412389934468e-112, 2.1660313165253327e-118, 4.2467223153569913e-126}, + {6.0622191716662980e-127, 3.2243541187800939e-119, 5.1690742816237208e-113, 1.2426977160105404e-107, 8.3933287533777738e-103, 2.2126569238728289e-98, 2.7801189404282378e-94, 1.9017852686354782e-90, 7.7836404960844694e-87, 2.0443095742420186e-83, 3.6361329490246816e-80, 4.5702928776404487e-77, 4.2014053957085256e-74, 2.9059246516402931e-71, 1.5484204394570369e-68, 6.4850166385488236e-66, 2.1717290123179292e-63, 5.9022979463583546e-61, 1.3188160319392796e-58, 2.4504276066974761e-56, 3.8244861009984640e-54, 5.0591506359259702e-52, 5.7180427835175108e-50, 5.5619189779622956e-48, 4.6865094097082296e-46, 3.4411166261243821e-44, 2.2137173158797545e-42, 1.2539021346574782e-40, 6.2819019919798964e-39, 2.7952039819044771e-37, 1.1089145782361913e-35, 3.9362772026982286e-34, 1.2543049763002862e-32, 3.5989403271252947e-31, 9.3246229360624703e-30, 2.1873567871874991e-28, 4.6570323992852519e-27, 9.0198508148124766e-26, 1.5926655666987673e-24, 2.5689779244357800e-23, 3.7925166697437060e-22, 5.1332963733171119e-21, 6.3810270087780860e-20, 7.2960970893548457e-19, 7.6848696141461809e-18, 7.4667368566800348e-17, 6.7010236404093807e-16, 5.5616305380816712e-15, 4.2738351786402332e-14, 3.0441295544509839e-13, 2.0118060311112926e-12, 1.2348350013212526e-11, 7.0457887005315459e-11, 3.7404445985544352e-10, 1.8490262742729560e-09, 8.5176899942265963e-09, 3.6590845237002989e-08, 1.4668615688059134e-07, 5.4909587760916178e-07, 1.9204753233550013e-06, 6.2793321142086111e-06, 1.9203890628511156e-05, 5.4960123823238632e-05, 1.4726036700166861e-04, 3.6956136752144001e-04, 8.6899815474605370e-04, 1.9153075674406669e-03, 3.9581151034971717e-03, 7.6718266966305298e-03, 1.3950429172087464e-02, 2.3804589918929770e-02, 3.8125218704480275e-02, 5.7322493628469834e-02, 8.0922651951388633e-02, 1.0727720003748800e-01, 1.3356293292585539e-01, 1.5618653283532280e-01, 1.7155657639082103e-01, 1.7700824722075201e-01, 1.7155657639082103e-01, 1.5618653283532280e-01, 1.3356293292585539e-01, 1.0727720003748800e-01, 8.0922651951388633e-02, 5.7322493628469834e-02, 3.8125218704480275e-02, 2.3804589918929770e-02, 1.3950429172087464e-02, 7.6718266966305298e-03, 3.9581151034971717e-03, 1.9153075674406669e-03, 8.6899815474605370e-04, 3.6956136752144001e-04, 1.4726036700166861e-04, 5.4960123823238632e-05, 1.9203890628511156e-05, 6.2793321142086111e-06, 1.9204753233550013e-06, 5.4909587760916178e-07, 1.4668615688059134e-07, 3.6590845237002989e-08, 8.5176899942265963e-09, 1.8490262742729560e-09, 3.7404445985544352e-10, 7.0457887005315459e-11, 1.2348350013212526e-11, 2.0118060311112926e-12, 3.0441295544509839e-13, 4.2738351786402332e-14, 5.5616305380816712e-15, 6.7010236404093807e-16, 7.4667368566800348e-17, 7.6848696141461809e-18, 7.2960970893548457e-19, 6.3810270087780860e-20, 5.1332963733171119e-21, 3.7925166697437060e-22, 2.5689779244357800e-23, 1.5926655666987673e-24, 9.0198508148124766e-26, 4.6570323992852519e-27, 2.1873567871874991e-28, 9.3246229360624703e-30, 3.5989403271252947e-31, 1.2543049763002862e-32, 3.9362772026982286e-34, 1.1089145782361913e-35, 2.7952039819044771e-37, 6.2819019919798964e-39, 1.2539021346574782e-40, 2.2137173158797545e-42, 3.4411166261243821e-44, 4.6865094097082296e-46, 5.5619189779622956e-48, 5.7180427835175108e-50, 5.0591506359259702e-52, 3.8244861009984640e-54, 2.4504276066974761e-56, 1.3188160319392796e-58, 5.9022979463583546e-61, 2.1717290123179292e-63, 6.4850166385488236e-66, 1.5484204394570369e-68, 2.9059246516402931e-71, 4.2014053957085256e-74, 4.5702928776404487e-77, 3.6361329490246816e-80, 2.0443095742420186e-83, 7.7836404960844694e-87, 1.9017852686354782e-90, 2.7801189404282378e-94, 2.2126569238728289e-98, 8.3933287533777738e-103, 1.2426977160105404e-107, 5.1690742816237208e-113, 3.2243541187800939e-119, 6.0622191716662980e-127}, + {8.6518898286288247e-128, 4.7977981754547922e-120, 7.9650930361988897e-114, 1.9761840987326553e-108, 1.3744652069324438e-103, 3.7255148645554058e-99, 4.8074121331969427e-95, 3.3744153060134342e-91, 1.4161180265335159e-87, 3.8114504571794760e-84, 6.9438585136020447e-81, 8.9360817516471687e-78, 8.4079759000226087e-75, 5.9504405763416772e-72, 3.2435033695316742e-69, 1.3893312175841125e-66, 4.7576408366455308e-64, 1.3220024862368775e-61, 3.0197052622687561e-59, 5.7351470833255443e-57, 9.1486995119191431e-55, 1.2368470663040083e-52, 1.4286078076592960e-50, 1.4200335880405776e-48, 1.2226957787809403e-46, 9.1739205502621965e-45, 6.0306042099204429e-43, 3.4904884601063066e-41, 1.7869095381531890e-39, 8.1249855483381444e-38, 3.2939528684311649e-36, 1.1948989473488384e-34, 3.8912956469188826e-33, 1.1411267330350244e-31, 3.0219294698888464e-30, 7.2459465976943397e-29, 1.5770256477583313e-27, 3.1226061139317796e-26, 5.6372579181684656e-25, 9.2975592528325581e-24, 1.4036014280320261e-22, 1.9429670019227641e-21, 2.4703591186430466e-20, 2.8894203773544814e-19, 3.1135796480328694e-18, 3.0953725694775336e-17, 2.8427562189767261e-16, 2.4147784190996735e-15, 1.8994699453982887e-14, 1.3851048606782092e-13, 9.3729953674226721e-13, 5.8917523372705995e-12, 3.4433525991626855e-11, 1.8726953725774312e-10, 9.4854377303416358e-10, 4.4780357696096071e-09, 1.9718477984120434e-08, 8.1042320257489110e-08, 3.1108717616071734e-07, 1.1159535961120921e-06, 3.7432563998726419e-06, 1.1746874098316171e-05, 3.4504766489542566e-05, 9.4911766414585672e-05, 2.4458580745649063e-04, 5.9072464709476020e-04, 1.3376446613946990e-03, 2.8408258176521148e-03, 5.6601830605110866e-03, 1.0583273905359803e-02, 1.8574752611538813e-02, 3.0608185223036027e-02, 4.7364212800332400e-02, 6.8839337618374755e-02, 9.3985530465238165e-02, 1.2055262431349997e-01, 1.4528684159808489e-01, 1.6452871112826625e-01, 1.7508305167467292e-01, 1.7508305167467292e-01, 1.6452871112826625e-01, 1.4528684159808489e-01, 1.2055262431349997e-01, 9.3985530465238165e-02, 6.8839337618374755e-02, 4.7364212800332400e-02, 3.0608185223036027e-02, 1.8574752611538813e-02, 1.0583273905359803e-02, 5.6601830605110866e-03, 2.8408258176521148e-03, 1.3376446613946990e-03, 5.9072464709476020e-04, 2.4458580745649063e-04, 9.4911766414585672e-05, 3.4504766489542566e-05, 1.1746874098316171e-05, 3.7432563998726419e-06, 1.1159535961120921e-06, 3.1108717616071734e-07, 8.1042320257489110e-08, 1.9718477984120434e-08, 4.4780357696096071e-09, 9.4854377303416358e-10, 1.8726953725774312e-10, 3.4433525991626855e-11, 5.8917523372705995e-12, 9.3729953674226721e-13, 1.3851048606782092e-13, 1.8994699453982887e-14, 2.4147784190996735e-15, 2.8427562189767261e-16, 3.0953725694775336e-17, 3.1135796480328694e-18, 2.8894203773544814e-19, 2.4703591186430466e-20, 1.9429670019227641e-21, 1.4036014280320261e-22, 9.2975592528325581e-24, 5.6372579181684656e-25, 3.1226061139317796e-26, 1.5770256477583313e-27, 7.2459465976943397e-29, 3.0219294698888464e-30, 1.1411267330350244e-31, 3.8912956469188826e-33, 1.1948989473488384e-34, 3.2939528684311649e-36, 8.1249855483381444e-38, 1.7869095381531890e-39, 3.4904884601063066e-41, 6.0306042099204429e-43, 9.1739205502621965e-45, 1.2226957787809403e-46, 1.4200335880405776e-48, 1.4286078076592960e-50, 1.2368470663040083e-52, 9.1486995119191431e-55, 5.7351470833255443e-57, 3.0197052622687561e-59, 1.3220024862368775e-61, 4.7576408366455308e-64, 1.3893312175841125e-66, 3.2435033695316742e-69, 5.9504405763416772e-72, 8.4079759000226087e-75, 8.9360817516471687e-78, 6.9438585136020447e-81, 3.8114504571794760e-84, 1.4161180265335159e-87, 3.3744153060134342e-91, 4.8074121331969427e-95, 3.7255148645554058e-99, 1.3744652069324438e-103, 1.9761840987326553e-108, 7.9650930361988897e-114, 4.7977981754547922e-120, 8.6518898286288247e-128}, + {1.2345052237856376e-128, 7.1361565819334150e-121, 1.2266594150983389e-114, 3.1403768309606574e-109, 2.2488806415651994e-104, 6.2666361422341182e-100, 8.3038517132199445e-96, 5.9799996465821154e-92, 2.5729286682716097e-88, 7.0956475615088519e-85, 1.3239358802678529e-81, 1.7442238644011473e-78, 1.6795285148575302e-75, 1.2160739161745740e-72, 6.7800483155694390e-70, 2.9698887117979696e-67, 1.0398334915263462e-64, 2.9537631885955336e-62, 6.8964075076110458e-60, 1.3386610121664405e-57, 2.1822972256453033e-55, 3.0148592722499396e-53, 3.5582391595026354e-51, 3.6138684655576511e-49, 3.1792871272966973e-47, 2.4372213779029665e-45, 1.6369116080171861e-43, 9.6799943605644117e-42, 5.0631425091072337e-40, 2.3522144528005868e-38, 9.7436152093981038e-37, 3.6115822674301904e-35, 1.2018288490038798e-33, 3.6015212879811887e-32, 9.7468625406557925e-31, 2.3885355396506504e-29, 5.3132702519188496e-28, 1.0753756973350715e-26, 1.9845716557598769e-25, 3.3462806594548906e-24, 5.1650319326919827e-23, 7.3109577835953338e-22, 9.5059376788875581e-21, 1.1371572178214573e-19, 1.2534183670047640e-18, 1.2747621562807485e-17, 1.1978221703435283e-16, 1.0411788127158037e-15, 8.3817954183785831e-15, 6.2561571481732302e-14, 4.3340112417705868e-13, 2.7894047381925510e-12, 1.6694572089431568e-11, 9.2995420785846948e-11, 4.8253510985881196e-10, 2.3340778029825478e-09, 1.0532686874011172e-08, 4.4371096492273068e-08, 1.7461444759106688e-07, 6.4230905783791856e-07, 2.2097354109635801e-06, 7.1138004485475131e-06, 2.1441047304603760e-05, 6.0530803203101914e-05, 1.6013349936228681e-04, 3.9713567276994117e-04, 9.2365343040052964e-04, 2.0153124277213861e-03, 4.1264467864295497e-03, 7.9311452492789869e-03, 1.4313136262234679e-02, 2.4259110409796711e-02, 3.8623061726879737e-02, 5.7773645171755317e-02, 8.1206842893413358e-02, 1.0727363982645181e-01, 1.3319196312197995e-01, 1.5544764635273797e-01, 1.7054438857615731e-01, 1.7589498780426926e-01, 1.7054438857615731e-01, 1.5544764635273797e-01, 1.3319196312197995e-01, 1.0727363982645181e-01, 8.1206842893413358e-02, 5.7773645171755317e-02, 3.8623061726879737e-02, 2.4259110409796711e-02, 1.4313136262234679e-02, 7.9311452492789869e-03, 4.1264467864295497e-03, 2.0153124277213861e-03, 9.2365343040052964e-04, 3.9713567276994117e-04, 1.6013349936228681e-04, 6.0530803203101914e-05, 2.1441047304603760e-05, 7.1138004485475131e-06, 2.2097354109635801e-06, 6.4230905783791856e-07, 1.7461444759106688e-07, 4.4371096492273068e-08, 1.0532686874011172e-08, 2.3340778029825478e-09, 4.8253510985881196e-10, 9.2995420785846948e-11, 1.6694572089431568e-11, 2.7894047381925510e-12, 4.3340112417705868e-13, 6.2561571481732302e-14, 8.3817954183785831e-15, 1.0411788127158037e-15, 1.1978221703435283e-16, 1.2747621562807485e-17, 1.2534183670047640e-18, 1.1371572178214573e-19, 9.5059376788875581e-21, 7.3109577835953338e-22, 5.1650319326919827e-23, 3.3462806594548906e-24, 1.9845716557598769e-25, 1.0753756973350715e-26, 5.3132702519188496e-28, 2.3885355396506504e-29, 9.7468625406557925e-31, 3.6015212879811887e-32, 1.2018288490038798e-33, 3.6115822674301904e-35, 9.7436152093981038e-37, 2.3522144528005868e-38, 5.0631425091072337e-40, 9.6799943605644117e-42, 1.6369116080171861e-43, 2.4372213779029665e-45, 3.1792871272966973e-47, 3.6138684655576511e-49, 3.5582391595026354e-51, 3.0148592722499396e-53, 2.1822972256453033e-55, 1.3386610121664405e-57, 6.8964075076110458e-60, 2.9537631885955336e-62, 1.0398334915263462e-64, 2.9698887117979696e-67, 6.7800483155694390e-70, 1.2160739161745740e-72, 1.6795285148575302e-75, 1.7442238644011473e-78, 1.3239358802678529e-81, 7.0956475615088519e-85, 2.5729286682716097e-88, 5.9799996465821154e-92, 8.3038517132199445e-96, 6.2666361422341182e-100, 2.2488806415651994e-104, 3.1403768309606574e-109, 1.2266594150983389e-114, 7.1361565819334150e-121, 1.2345052237856376e-128}, + {1.7610777213868225e-129, 1.0609912453053086e-121, 1.8880558326632475e-115, 4.9869144791066677e-110, 3.6765138012657772e-105, 1.0530846293412266e-100, 1.4327597465974048e-96, 1.0584620865577655e-92, 4.6684664948676272e-89, 1.3190436630179440e-85, 2.5202632570592097e-82, 3.3987392362121908e-79, 3.3488181154099359e-76, 2.4804288326920011e-73, 1.4143430079239634e-70, 6.3346915410241234e-68, 2.2674306256941818e-65, 6.5836081498721399e-63, 1.5709872468845785e-60, 3.1162632356321267e-58, 5.1910061298697851e-56, 7.3273399650957289e-54, 8.8354796635334199e-52, 9.1677552430019203e-50, 8.2395121572045278e-48, 6.4526516804970545e-46, 4.4272600478065905e-44, 2.6745508857556167e-42, 1.4291089046778579e-40, 6.7826401946708970e-39, 2.8703150932676095e-37, 1.0869482703973487e-35, 3.6955025716069553e-34, 1.1315067191371783e-32, 3.1289601063429292e-31, 7.8353356972027161e-30, 1.7811808982463465e-28, 3.6843324819342597e-27, 6.9494876383385912e-26, 1.1977696964648504e-24, 1.8899444794564548e-23, 2.7350044749786203e-22, 3.6360647433609545e-21, 4.4479270726420680e-20, 5.0139935781581053e-19, 5.2157884028434802e-18, 5.0135017597656447e-17, 4.4585078370462008e-16, 3.6726238537048878e-15, 2.8053332193363147e-14, 1.9891563745557595e-13, 1.3105682814703333e-12, 8.0308637715632703e-12, 4.5809917511320124e-11, 2.4345153103464099e-10, 1.2063179828327093e-09, 5.5773560719102751e-09, 2.4077676519331747e-08, 9.7119175861531978e-08, 3.6624118990378204e-07, 1.2919701008614705e-06, 4.2657607173255093e-06, 1.3189244631563864e-05, 3.8205770006826046e-05, 1.0373273668170783e-04, 2.6409447862081663e-04, 6.3070332659971552e-04, 1.4134038747122414e-03, 2.9731958710714898e-03, 5.8725347587191210e-03, 1.0894054653347555e-02, 1.8985454327504647e-02, 3.1089543185356148e-02, 4.7846811856586229e-02, 6.9216492829879864e-02, 9.4133897771831843e-02, 1.2036875882166113e-01, 1.4472841947349580e-01, 1.6364277404586250e-01, 1.7400560617482017e-01, 1.7400560617482017e-01, 1.6364277404586250e-01, 1.4472841947349580e-01, 1.2036875882166113e-01, 9.4133897771831843e-02, 6.9216492829879864e-02, 4.7846811856586229e-02, 3.1089543185356148e-02, 1.8985454327504647e-02, 1.0894054653347555e-02, 5.8725347587191210e-03, 2.9731958710714898e-03, 1.4134038747122414e-03, 6.3070332659971552e-04, 2.6409447862081663e-04, 1.0373273668170783e-04, 3.8205770006826046e-05, 1.3189244631563864e-05, 4.2657607173255093e-06, 1.2919701008614705e-06, 3.6624118990378204e-07, 9.7119175861531978e-08, 2.4077676519331747e-08, 5.5773560719102751e-09, 1.2063179828327093e-09, 2.4345153103464099e-10, 4.5809917511320124e-11, 8.0308637715632703e-12, 1.3105682814703333e-12, 1.9891563745557595e-13, 2.8053332193363147e-14, 3.6726238537048878e-15, 4.4585078370462008e-16, 5.0135017597656447e-17, 5.2157884028434802e-18, 5.0139935781581053e-19, 4.4479270726420680e-20, 3.6360647433609545e-21, 2.7350044749786203e-22, 1.8899444794564548e-23, 1.1977696964648504e-24, 6.9494876383385912e-26, 3.6843324819342597e-27, 1.7811808982463465e-28, 7.8353356972027161e-30, 3.1289601063429292e-31, 1.1315067191371783e-32, 3.6955025716069553e-34, 1.0869482703973487e-35, 2.8703150932676095e-37, 6.7826401946708970e-39, 1.4291089046778579e-40, 2.6745508857556167e-42, 4.4272600478065905e-44, 6.4526516804970545e-46, 8.2395121572045278e-48, 9.1677552430019203e-50, 8.8354796635334199e-52, 7.3273399650957289e-54, 5.1910061298697851e-56, 3.1162632356321267e-58, 1.5709872468845785e-60, 6.5836081498721399e-63, 2.2674306256941818e-65, 6.3346915410241234e-68, 1.4143430079239634e-70, 2.4804288326920011e-73, 3.3488181154099359e-76, 3.3987392362121908e-79, 2.5202632570592097e-82, 1.3190436630179440e-85, 4.6684664948676272e-89, 1.0584620865577655e-92, 1.4327597465974048e-96, 1.0530846293412266e-100, 3.6765138012657772e-105, 4.9869144791066677e-110, 1.8880558326632475e-115, 1.0609912453053086e-121, 1.7610777213868225e-129}, + {2.5117056700120872e-130, 1.5768344953215994e-122, 2.9044636530400262e-116, 7.9137283674998714e-111, 6.0054708822621273e-106, 1.7679796472043246e-101, 2.4694368635244847e-97, 1.8712284923478763e-93, 8.4595142859097527e-90, 2.4484925972797376e-86, 4.7901098788291739e-83, 6.6115362451933797e-80, 6.6651975922997095e-77, 5.0496259060528478e-74, 2.9443577961646315e-71, 1.3482570840246656e-68, 4.9330325826042063e-66, 1.4638938206976037e-63, 3.5696603658904023e-61, 7.2351735603462302e-59, 1.2313651255661928e-56, 1.7756983991411928e-54, 2.1873288432589287e-52, 2.3183952076674861e-50, 2.1283904185528713e-48, 1.7025628600075561e-46, 1.1931897574643388e-44, 7.3626408195179616e-43, 4.0184547253394729e-41, 1.9480947197049647e-39, 8.4210939788616602e-38, 3.2575341809749061e-36, 1.1313879341749972e-34, 3.5389381244383855e-33, 9.9980778309899927e-32, 2.5579997011243763e-30, 5.9416331503292959e-29, 1.2558645009560268e-27, 2.4207882624773725e-26, 4.2641635772547449e-25, 6.8770962222233684e-24, 1.0173048420715203e-22, 1.3826289575432440e-21, 1.7292550621372860e-20, 1.9932479444365377e-19, 2.1204345027937428e-18, 2.0846204533947437e-17, 1.8963226940193161e-16, 1.5980648038540025e-15, 1.2489882385266198e-14, 9.0627897868794926e-14, 6.1113514542896781e-13, 3.8334734795673616e-12, 2.2387867842316195e-11, 1.2183208011102774e-10, 6.1827585936607041e-10, 2.9281826160122555e-09, 1.2951325071150348e-08, 5.3532512893353530e-08, 2.0690866853712093e-07, 7.4825803592771974e-07, 2.5332274890078433e-06, 8.0328671931181133e-06, 2.3869848947287937e-05, 6.6497705172595715e-05, 1.7374941584438457e-04, 4.2595976788697434e-04, 9.8016363676181151e-04, 2.1176656262735217e-03, 4.2971163011999540e-03, 8.1917798784339399e-03, 1.4674728608435711e-02, 2.4708741311255288e-02, 3.9111739287652818e-02, 5.8212483797557772e-02, 8.1478613249930595e-02, 1.0726183985947185e-01, 1.3282086880025051e-01, 1.5471842089261012e-01, 1.6954985984858575e-01, 1.7480247235206883e-01, 1.6954985984858575e-01, 1.5471842089261012e-01, 1.3282086880025051e-01, 1.0726183985947185e-01, 8.1478613249930595e-02, 5.8212483797557772e-02, 3.9111739287652818e-02, 2.4708741311255288e-02, 1.4674728608435711e-02, 8.1917798784339399e-03, 4.2971163011999540e-03, 2.1176656262735217e-03, 9.8016363676181151e-04, 4.2595976788697434e-04, 1.7374941584438457e-04, 6.6497705172595715e-05, 2.3869848947287937e-05, 8.0328671931181133e-06, 2.5332274890078433e-06, 7.4825803592771974e-07, 2.0690866853712093e-07, 5.3532512893353530e-08, 1.2951325071150348e-08, 2.9281826160122555e-09, 6.1827585936607041e-10, 1.2183208011102774e-10, 2.2387867842316195e-11, 3.8334734795673616e-12, 6.1113514542896781e-13, 9.0627897868794926e-14, 1.2489882385266198e-14, 1.5980648038540025e-15, 1.8963226940193161e-16, 2.0846204533947437e-17, 2.1204345027937428e-18, 1.9932479444365377e-19, 1.7292550621372860e-20, 1.3826289575432440e-21, 1.0173048420715203e-22, 6.8770962222233684e-24, 4.2641635772547449e-25, 2.4207882624773725e-26, 1.2558645009560268e-27, 5.9416331503292959e-29, 2.5579997011243763e-30, 9.9980778309899927e-32, 3.5389381244383855e-33, 1.1313879341749972e-34, 3.2575341809749061e-36, 8.4210939788616602e-38, 1.9480947197049647e-39, 4.0184547253394729e-41, 7.3626408195179616e-43, 1.1931897574643388e-44, 1.7025628600075561e-46, 2.1283904185528713e-48, 2.3183952076674861e-50, 2.1873288432589287e-52, 1.7756983991411928e-54, 1.2313651255661928e-56, 7.2351735603462302e-59, 3.5696603658904023e-61, 1.4638938206976037e-63, 4.9330325826042063e-66, 1.3482570840246656e-68, 2.9443577961646315e-71, 5.0496259060528478e-74, 6.6651975922997095e-77, 6.6115362451933797e-80, 4.7901098788291739e-83, 2.4484925972797376e-86, 8.4595142859097527e-90, 1.8712284923478763e-93, 2.4694368635244847e-97, 1.7679796472043246e-101, 6.0054708822621273e-106, 7.9137283674998714e-111, 2.9044636530400262e-116, 1.5768344953215994e-122, 2.5117056700120872e-130}, + {3.5814970887800193e-131, 2.3425513711144864e-123, 4.4656005878580503e-117, 1.2549679546936818e-111, 9.8017329285864726e-107, 2.9653839872557489e-102, 4.2516584957198355e-98, 3.3041628702723710e-94, 1.5309029297604490e-90, 4.5385580031078324e-87, 9.0901963341946014e-84, 1.2839971949179289e-80, 1.3242215741981033e-77, 1.0260459032147593e-74, 6.1171687686353920e-72, 2.8634705175373264e-69, 1.0708169155525760e-66, 3.2473167974844921e-64, 8.0909309792517176e-62, 1.6754390708913517e-59, 2.9129572580930014e-57, 4.2909222783948995e-55, 5.3988684348783699e-53, 5.8447003073435629e-51, 5.4802004204685326e-49, 4.4772141969183521e-47, 3.2045539320239441e-45, 2.0194963974060789e-43, 1.1256982521722169e-41, 5.5735541782797091e-40, 2.4607034140503088e-38, 9.7221219580876439e-37, 3.4489022958731964e-35, 1.1019416508568278e-33, 3.1800971964673699e-32, 8.3116537305566989e-31, 1.9723475111279380e-29, 4.2593300365187824e-28, 8.3889785533018652e-27, 1.5099943444312937e-25, 2.4887063965856610e-24, 3.7625921372478096e-23, 5.2269932699489526e-22, 6.6828358472667806e-21, 7.8752810946470447e-20, 8.5660876502561181e-19, 8.6117182742222153e-18, 8.0118871420831184e-17, 6.9061126848313650e-16, 5.5217099395406411e-15, 4.0993475210626060e-14, 2.8287311125546069e-13, 1.8159956877481757e-12, 1.0856048964794633e-11, 6.0482344698906487e-11, 3.1429016861706717e-10, 1.5244189642430853e-09, 6.9064794339712537e-09, 2.9246755983618971e-08, 1.1583508882541563e-07, 4.2933935551544649e-07, 1.4900490066410718e-06, 4.8446895241968929e-06, 1.4764162429716271e-05, 4.2191721743284952e-05, 1.1311130499099743e-04, 2.8458825008902025e-04, 6.7223242445783719e-04, 1.4912851650067261e-03, 3.1079648052231286e-03, 6.0868070844442837e-03, 1.1205047384266207e-02, 1.9393234478244935e-02, 3.1563859231069517e-02, 4.8318515012084520e-02, 6.9580992429206442e-02, 9.4271602476518737e-02, 1.2018047849522055e-01, 1.4417476260347803e-01, 1.6277076260081147e-01, 1.7294780784506847e-01, 1.7294780784506847e-01, 1.6277076260081147e-01, 1.4417476260347803e-01, 1.2018047849522055e-01, 9.4271602476518737e-02, 6.9580992429206442e-02, 4.8318515012084520e-02, 3.1563859231069517e-02, 1.9393234478244935e-02, 1.1205047384266207e-02, 6.0868070844442837e-03, 3.1079648052231286e-03, 1.4912851650067261e-03, 6.7223242445783719e-04, 2.8458825008902025e-04, 1.1311130499099743e-04, 4.2191721743284952e-05, 1.4764162429716271e-05, 4.8446895241968929e-06, 1.4900490066410718e-06, 4.2933935551544649e-07, 1.1583508882541563e-07, 2.9246755983618971e-08, 6.9064794339712537e-09, 1.5244189642430853e-09, 3.1429016861706717e-10, 6.0482344698906487e-11, 1.0856048964794633e-11, 1.8159956877481757e-12, 2.8287311125546069e-13, 4.0993475210626060e-14, 5.5217099395406411e-15, 6.9061126848313650e-16, 8.0118871420831184e-17, 8.6117182742222153e-18, 8.5660876502561181e-19, 7.8752810946470447e-20, 6.6828358472667806e-21, 5.2269932699489526e-22, 3.7625921372478096e-23, 2.4887063965856610e-24, 1.5099943444312937e-25, 8.3889785533018652e-27, 4.2593300365187824e-28, 1.9723475111279380e-29, 8.3116537305566989e-31, 3.1800971964673699e-32, 1.1019416508568278e-33, 3.4489022958731964e-35, 9.7221219580876439e-37, 2.4607034140503088e-38, 5.5735541782797091e-40, 1.1256982521722169e-41, 2.0194963974060789e-43, 3.2045539320239441e-45, 4.4772141969183521e-47, 5.4802004204685326e-49, 5.8447003073435629e-51, 5.3988684348783699e-53, 4.2909222783948995e-55, 2.9129572580930014e-57, 1.6754390708913517e-59, 8.0909309792517176e-62, 3.2473167974844921e-64, 1.0708169155525760e-66, 2.8634705175373264e-69, 6.1171687686353920e-72, 1.0260459032147593e-74, 1.3242215741981033e-77, 1.2839971949179289e-80, 9.0901963341946014e-84, 4.5385580031078324e-87, 1.5309029297604490e-90, 3.3041628702723710e-94, 4.2516584957198355e-98, 2.9653839872557489e-102, 9.8017329285864726e-107, 1.2549679546936818e-111, 4.4656005878580503e-117, 2.3425513711144864e-123, 3.5814970887800193e-131}, + {5.1058382388659269e-132, 3.4787452134261360e-124, 6.8621328476606254e-118, 1.9887929527241800e-112, 1.5984806988768767e-107, 4.9691113060541562e-103, 7.3123967185564915e-99, 5.8275341127995904e-95, 2.7668599413210135e-91, 8.4008516795919007e-88, 1.7224108182682644e-84, 2.4894935837631581e-81, 2.6262929329466987e-78, 2.0809367058140554e-75, 1.2683653376027615e-72, 6.0687062439892660e-70, 2.3192577160038707e-67, 7.1865618890614741e-65, 1.8293638224274986e-62, 3.8697820973543049e-60, 6.8723829518191775e-58, 1.0339639913382959e-55, 1.3286530592326351e-53, 1.4689382904493016e-51, 1.4065458992870208e-49, 1.1734649400073276e-47, 8.5768492248869891e-46, 5.5194857702963127e-44, 3.1417689022491827e-42, 1.5884965434373284e-40, 7.1618254982458697e-39, 2.8896676701682861e-37, 1.0469000850542053e-35, 3.4161633966903074e-34, 1.0069252468038614e-32, 2.6880974156578509e-31, 6.5158094363462302e-30, 1.4374174204375062e-28, 2.8922727144899803e-27, 5.3189806528533866e-26, 8.9574942952228153e-25, 1.3838820621840956e-23, 1.9647377828565719e-22, 2.5674274750397857e-21, 3.0926768131345034e-20, 3.4389885933401063e-19, 3.5348317750763591e-18, 3.3627744521880394e-17, 2.9643952991648909e-16, 2.4242278762902340e-15, 1.8410778220221309e-14, 1.2997777867558265e-13, 8.5384118147611980e-13, 5.2237944008745323e-12, 2.9789583264039043e-11, 1.5847474437596250e-10, 7.8704836352169759e-10, 3.6517281221510981e-09, 1.5839569546032163e-08, 6.4270494029387501e-08, 2.4409702642671850e-07, 8.6823986929119786e-07, 2.8938252044645185e-06, 9.0422158488303162e-06, 2.6500151909252169e-05, 7.2875309659252541e-05, 1.8812470050977485e-04, 4.5604422468456632e-04, 1.0385182654144745e-03, 2.2223166735266457e-03, 4.4700208091087738e-03, 8.4535858780912364e-03, 1.5035066629455310e-02, 2.5153428292907908e-02, 3.9591364280961522e-02, 5.8639320239639699e-02, 8.1738404552485058e-02, 1.0724220730838535e-01, 1.3244982464015054e-01, 1.5399867398459949e-01, 1.6857248411687309e-01, 1.7373006454622800e-01, 1.6857248411687309e-01, 1.5399867398459949e-01, 1.3244982464015054e-01, 1.0724220730838535e-01, 8.1738404552485058e-02, 5.8639320239639699e-02, 3.9591364280961522e-02, 2.5153428292907908e-02, 1.5035066629455310e-02, 8.4535858780912364e-03, 4.4700208091087738e-03, 2.2223166735266457e-03, 1.0385182654144745e-03, 4.5604422468456632e-04, 1.8812470050977485e-04, 7.2875309659252541e-05, 2.6500151909252169e-05, 9.0422158488303162e-06, 2.8938252044645185e-06, 8.6823986929119786e-07, 2.4409702642671850e-07, 6.4270494029387501e-08, 1.5839569546032163e-08, 3.6517281221510981e-09, 7.8704836352169759e-10, 1.5847474437596250e-10, 2.9789583264039043e-11, 5.2237944008745323e-12, 8.5384118147611980e-13, 1.2997777867558265e-13, 1.8410778220221309e-14, 2.4242278762902340e-15, 2.9643952991648909e-16, 3.3627744521880394e-17, 3.5348317750763591e-18, 3.4389885933401063e-19, 3.0926768131345034e-20, 2.5674274750397857e-21, 1.9647377828565719e-22, 1.3838820621840956e-23, 8.9574942952228153e-25, 5.3189806528533866e-26, 2.8922727144899803e-27, 1.4374174204375062e-28, 6.5158094363462302e-30, 2.6880974156578509e-31, 1.0069252468038614e-32, 3.4161633966903074e-34, 1.0469000850542053e-35, 2.8896676701682861e-37, 7.1618254982458697e-39, 1.5884965434373284e-40, 3.1417689022491827e-42, 5.5194857702963127e-44, 8.5768492248869891e-46, 1.1734649400073276e-47, 1.4065458992870208e-49, 1.4689382904493016e-51, 1.3286530592326351e-53, 1.0339639913382959e-55, 6.8723829518191775e-58, 3.8697820973543049e-60, 1.8293638224274986e-62, 7.1865618890614741e-65, 2.3192577160038707e-67, 6.0687062439892660e-70, 1.2683653376027615e-72, 2.0809367058140554e-75, 2.6262929329466987e-78, 2.4894935837631581e-81, 1.7224108182682644e-84, 8.4008516795919007e-88, 2.7668599413210135e-91, 5.8275341127995904e-95, 7.3123967185564915e-99, 4.9691113060541562e-103, 1.5984806988768767e-107, 1.9887929527241800e-112, 6.8621328476606254e-118, 3.4787452134261360e-124, 5.1058382388659269e-132}, + {7.2774136808374355e-133, 5.1640253363781065e-125, 1.0539163395229755e-118, 3.1495974864069521e-113, 2.6047400909049849e-108, 8.3190735956096083e-104, 1.2563394260844383e-99, 1.0266029334944310e-95, 4.9942483588606006e-92, 1.5528225080749898e-88, 3.2586916028699435e-85, 4.8189357949651464e-82, 5.1995900683110418e-79, 4.2125456733725475e-76, 2.6247146396219082e-73, 1.2834925357232391e-70, 5.0121772980919659e-68, 1.5867585378958465e-65, 4.1261409970889649e-63, 8.9152934736506373e-61, 1.6170383864591641e-58, 2.4845512749608618e-56, 3.2602867516914131e-54, 3.6806734534292869e-52, 3.5986560950072034e-50, 3.0655422197589668e-48, 2.2877484525825812e-46, 1.5032084002307616e-44, 8.7364621051992394e-43, 4.5101690564191873e-41, 2.0762677615749785e-39, 8.5540504547638604e-38, 3.1645195547118431e-36, 1.0544772050999357e-34, 3.1740376151073218e-33, 8.6536469704170907e-32, 2.1423361912655937e-30, 4.8272033657573108e-29, 9.9214758418835271e-28, 1.8639024742210292e-26, 3.2068221113110570e-25, 5.0619653821736361e-24, 7.3433969692709968e-23, 9.8063138469438635e-22, 1.2072647224673922e-20, 1.3721655943148051e-19, 1.4417902155501092e-18, 1.4022988180739114e-17, 1.2639871956315117e-16, 1.0570613866427036e-15, 8.2106561126223668e-15, 5.9294550957769600e-14, 3.9849788475246675e-13, 2.4946167855672290e-12, 1.4558577681248529e-11, 7.9272325104664409e-11, 4.0303485756427884e-10, 1.9146717079546461e-09, 8.5049436556100333e-09, 3.5346942618254887e-08, 1.3752997102467001e-07, 5.0124990214178011e-07, 1.7121991444326337e-06, 5.4842169146680313e-06, 1.6479308921225968e-05, 4.6474831646589210e-05, 1.2306336370474281e-04, 3.0608156336295680e-04, 7.1531332284984861e-04, 1.5712593917201550e-03, 3.2450562679797843e-03, 6.3028742438160333e-03, 1.1516105006399560e-02, 1.9797989451736150e-02, 3.2031157662458190e-02, 4.8779535009276516e-02, 6.9933221621689870e-02, 9.4399083753525778e-02, 1.1998808778160919e-01, 1.4362587120152381e-01, 1.6191232338499803e-01, 1.7190906682322146e-01, 1.7190906682322146e-01, 1.6191232338499803e-01, 1.4362587120152381e-01, 1.1998808778160919e-01, 9.4399083753525778e-02, 6.9933221621689870e-02, 4.8779535009276516e-02, 3.2031157662458190e-02, 1.9797989451736150e-02, 1.1516105006399560e-02, 6.3028742438160333e-03, 3.2450562679797843e-03, 1.5712593917201550e-03, 7.1531332284984861e-04, 3.0608156336295680e-04, 1.2306336370474281e-04, 4.6474831646589210e-05, 1.6479308921225968e-05, 5.4842169146680313e-06, 1.7121991444326337e-06, 5.0124990214178011e-07, 1.3752997102467001e-07, 3.5346942618254887e-08, 8.5049436556100333e-09, 1.9146717079546461e-09, 4.0303485756427884e-10, 7.9272325104664409e-11, 1.4558577681248529e-11, 2.4946167855672290e-12, 3.9849788475246675e-13, 5.9294550957769600e-14, 8.2106561126223668e-15, 1.0570613866427036e-15, 1.2639871956315117e-16, 1.4022988180739114e-17, 1.4417902155501092e-18, 1.3721655943148051e-19, 1.2072647224673922e-20, 9.8063138469438635e-22, 7.3433969692709968e-23, 5.0619653821736361e-24, 3.2068221113110570e-25, 1.8639024742210292e-26, 9.9214758418835271e-28, 4.8272033657573108e-29, 2.1423361912655937e-30, 8.6536469704170907e-32, 3.1740376151073218e-33, 1.0544772050999357e-34, 3.1645195547118431e-36, 8.5540504547638604e-38, 2.0762677615749785e-39, 4.5101690564191873e-41, 8.7364621051992394e-43, 1.5032084002307616e-44, 2.2877484525825812e-46, 3.0655422197589668e-48, 3.5986560950072034e-50, 3.6806734534292869e-52, 3.2602867516914131e-54, 2.4845512749608618e-56, 1.6170383864591641e-58, 8.9152934736506373e-61, 4.1261409970889649e-63, 1.5867585378958465e-65, 5.0121772980919659e-68, 1.2834925357232391e-70, 2.6247146396219082e-73, 4.2125456733725475e-76, 5.1995900683110418e-79, 4.8189357949651464e-82, 3.2586916028699435e-85, 1.5528225080749898e-88, 4.9942483588606006e-92, 1.0266029334944310e-95, 1.2563394260844383e-99, 8.3190735956096083e-104, 2.6047400909049849e-108, 3.1495974864069521e-113, 1.0539163395229755e-118, 5.1640253363781065e-125, 7.2774136808374355e-133}, + {1.0370401330404128e-133, 7.6628104007938171e-126, 1.6177944458582779e-119, 4.9846209741944082e-114, 4.2410903981966999e-109, 1.3914702767711137e-104, 2.1562790735643016e-100, 1.8064249655941844e-96, 9.0033176079341812e-93, 2.8662892545517945e-89, 6.1560200907369249e-86, 9.3130571849846176e-83, 1.0276539331534194e-79, 8.5120283276029899e-77, 5.4209234698248101e-74, 2.7089105182625548e-71, 1.0808323828410104e-68, 3.4954669585711314e-66, 9.2841597125229309e-64, 2.0487495492161133e-61, 3.7947795686740356e-59, 5.9537760035157825e-57, 7.9771959541897771e-55, 9.1949435242106659e-53, 9.1785078949346243e-51, 7.9824553719798949e-49, 6.0817267689790556e-47, 4.0796548388663509e-45, 2.4206136388252030e-43, 1.2757690988603576e-41, 5.9959663570350600e-40, 2.5220557090360086e-38, 9.5260156082741867e-37, 3.2409917090630152e-35, 9.9611495020508274e-34, 2.7731632192036800e-32, 7.0108006530723495e-31, 1.6132689567876035e-29, 3.3864807517869285e-28, 6.4981402796424245e-27, 1.1420079983768409e-25, 1.8415308229503966e-24, 2.7293664944237734e-23, 3.7240665643118182e-22, 4.6849502295754945e-21, 5.4418440370928148e-20, 5.8442290512558873e-19, 5.8103464142089000e-18, 5.3541848627525126e-17, 4.5782053131046985e-16, 3.6364250808804760e-15, 2.6857950742667181e-14, 1.8463211087063347e-13, 1.1824213225107695e-12, 7.0605885367663953e-12, 3.9342842554083200e-11, 2.0472924906259976e-10, 9.9563021167170463e-10, 4.5281139927096718e-09, 1.9271612548094547e-08, 7.6800568196628212e-08, 2.8675127848315921e-07, 1.0036330972927129e-06, 3.2945281705899829e-06, 1.0147672170741122e-05, 2.9341866948530294e-05, 7.9677853191228106e-05, 2.0327512248096151e-04, 4.8739807702018396e-04, 1.0987048493532403e-03, 2.3292137543048106e-03, 4.6450584683976901e-03, 8.7164233107623907e-03, 1.5394018995268760e-02, 2.5593125567577809e-02, 4.0062052918626051e-02, 5.9054458453798808e-02, 8.1986641314913386e-02, 1.0721512879081883e-01, 1.3207899230191014e-01, 1.5328822654091181e-01, 1.6761177530123578e-01, 1.7267715506412973e-01, 1.6761177530123578e-01, 1.5328822654091181e-01, 1.3207899230191014e-01, 1.0721512879081883e-01, 8.1986641314913386e-02, 5.9054458453798808e-02, 4.0062052918626051e-02, 2.5593125567577809e-02, 1.5394018995268760e-02, 8.7164233107623907e-03, 4.6450584683976901e-03, 2.3292137543048106e-03, 1.0987048493532403e-03, 4.8739807702018396e-04, 2.0327512248096151e-04, 7.9677853191228106e-05, 2.9341866948530294e-05, 1.0147672170741122e-05, 3.2945281705899829e-06, 1.0036330972927129e-06, 2.8675127848315921e-07, 7.6800568196628212e-08, 1.9271612548094547e-08, 4.5281139927096718e-09, 9.9563021167170463e-10, 2.0472924906259976e-10, 3.9342842554083200e-11, 7.0605885367663953e-12, 1.1824213225107695e-12, 1.8463211087063347e-13, 2.6857950742667181e-14, 3.6364250808804760e-15, 4.5782053131046985e-16, 5.3541848627525126e-17, 5.8103464142089000e-18, 5.8442290512558873e-19, 5.4418440370928148e-20, 4.6849502295754945e-21, 3.7240665643118182e-22, 2.7293664944237734e-23, 1.8415308229503966e-24, 1.1420079983768409e-25, 6.4981402796424245e-27, 3.3864807517869285e-28, 1.6132689567876035e-29, 7.0108006530723495e-31, 2.7731632192036800e-32, 9.9611495020508274e-34, 3.2409917090630152e-35, 9.5260156082741867e-37, 2.5220557090360086e-38, 5.9959663570350600e-40, 1.2757690988603576e-41, 2.4206136388252030e-43, 4.0796548388663509e-45, 6.0817267689790556e-47, 7.9824553719798949e-49, 9.1785078949346243e-51, 9.1949435242106659e-53, 7.9771959541897771e-55, 5.9537760035157825e-57, 3.7947795686740356e-59, 2.0487495492161133e-61, 9.2841597125229309e-64, 3.4954669585711314e-66, 1.0808323828410104e-68, 2.7089105182625548e-71, 5.4209234698248101e-74, 8.5120283276029899e-77, 1.0276539331534194e-79, 9.3130571849846176e-83, 6.1560200907369249e-86, 2.8662892545517945e-89, 9.0033176079341812e-93, 1.8064249655941844e-96, 2.1562790735643016e-100, 1.3914702767711137e-104, 4.2410903981966999e-109, 4.9846209741944082e-114, 1.6177944458582779e-119, 7.6628104007938171e-126, 1.0370401330404128e-133}, + {1.4774864044730919e-134, 1.1366413967312580e-126, 2.4820647345980668e-120, 7.8835864352328026e-115, 6.9000209771443205e-110, 2.3253044708336631e-105, 3.6970767260897540e-101, 3.1749907175216285e-97, 1.6210276225797838e-93, 5.2835329659655297e-90, 1.1612190047837748e-86, 1.7969751555347008e-83, 2.0276116391228268e-80, 1.7168527133451101e-77, 1.1174481216103580e-74, 5.7057155838516782e-72, 2.3257094876339456e-69, 7.6827297329990042e-67, 2.0840476902701378e-64, 4.6963320200403117e-62, 8.8821741614196649e-60, 1.4228297251266947e-57, 1.9462991520350709e-55, 2.2902568991273256e-53, 2.3338081888304624e-51, 2.0719270806826472e-49, 1.6113919045974023e-47, 1.1033912986165171e-45, 6.6828682986466127e-44, 3.5953723054115794e-42, 1.7249314720204933e-40, 7.4065841467302406e-39, 2.8558675123113318e-37, 9.9193674854686742e-36, 3.1125293650397015e-34, 8.8470553643068575e-33, 2.2836747845517017e-31, 5.3659089984759047e-30, 1.1502283587852324e-28, 2.2540053407015112e-27, 4.0457517920854419e-26, 6.6636084030909077e-25, 1.0088605806727544e-23, 1.4062620052335121e-22, 1.8074912939358217e-21, 2.1452843610753105e-20, 2.3544032965183590e-19, 2.3923239898564218e-18, 2.2533431601785240e-17, 1.9696954324441430e-16, 1.5995738956856818e-15, 1.2080546491164034e-14, 8.4930831160690606e-14, 5.5633632513833882e-13, 3.3984267451196722e-12, 1.9374997522123724e-11, 1.0317252591614767e-10, 5.1352562907714339e-10, 2.3907560585436029e-09, 1.0417563656335543e-08, 4.2512972951519652e-08, 1.6257453952247463e-07, 5.8290254892118051e-07, 1.9605333794325452e-06, 6.1886554017466215e-06, 1.8342475402473601e-05, 5.1067234537777706e-05, 1.3360429556693264e-04, 3.2858768305186580e-04, 7.5994560780524184e-04, 1.6532956640381497e-03, 3.3843936084184865e-03, 6.5206132604078895e-03, 1.1827087059306185e-02, 2.0199624381625723e-02, 3.2491469153777909e-02, 4.9230083099421298e-02, 7.0273553473008815e-02, 9.4516761260745735e-02, 1.1979187349505478e-01, 1.4308174026017673e-01, 1.6106711507035643e-01, 1.7088881774276651e-01, 1.7088881774276651e-01, 1.6106711507035643e-01, 1.4308174026017673e-01, 1.1979187349505478e-01, 9.4516761260745735e-02, 7.0273553473008815e-02, 4.9230083099421298e-02, 3.2491469153777909e-02, 2.0199624381625723e-02, 1.1827087059306185e-02, 6.5206132604078895e-03, 3.3843936084184865e-03, 1.6532956640381497e-03, 7.5994560780524184e-04, 3.2858768305186580e-04, 1.3360429556693264e-04, 5.1067234537777706e-05, 1.8342475402473601e-05, 6.1886554017466215e-06, 1.9605333794325452e-06, 5.8290254892118051e-07, 1.6257453952247463e-07, 4.2512972951519652e-08, 1.0417563656335543e-08, 2.3907560585436029e-09, 5.1352562907714339e-10, 1.0317252591614767e-10, 1.9374997522123724e-11, 3.3984267451196722e-12, 5.5633632513833882e-13, 8.4930831160690606e-14, 1.2080546491164034e-14, 1.5995738956856818e-15, 1.9696954324441430e-16, 2.2533431601785240e-17, 2.3923239898564218e-18, 2.3544032965183590e-19, 2.1452843610753105e-20, 1.8074912939358217e-21, 1.4062620052335121e-22, 1.0088605806727544e-23, 6.6636084030909077e-25, 4.0457517920854419e-26, 2.2540053407015112e-27, 1.1502283587852324e-28, 5.3659089984759047e-30, 2.2836747845517017e-31, 8.8470553643068575e-33, 3.1125293650397015e-34, 9.9193674854686742e-36, 2.8558675123113318e-37, 7.4065841467302406e-39, 1.7249314720204933e-40, 3.5953723054115794e-42, 6.6828682986466127e-44, 1.1033912986165171e-45, 1.6113919045974023e-47, 2.0719270806826472e-49, 2.3338081888304624e-51, 2.2902568991273256e-53, 1.9462991520350709e-55, 1.4228297251266947e-57, 8.8821741614196649e-60, 4.6963320200403117e-62, 2.0840476902701378e-64, 7.6827297329990042e-67, 2.3257094876339456e-69, 5.7057155838516782e-72, 1.1174481216103580e-74, 1.7168527133451101e-77, 2.0276116391228268e-80, 1.7969751555347008e-83, 1.1612190047837748e-86, 5.2835329659655297e-90, 1.6210276225797838e-93, 3.1749907175216285e-97, 3.6970767260897540e-101, 2.3253044708336631e-105, 6.9000209771443205e-110, 7.8835864352328026e-115, 2.4820647345980668e-120, 1.1366413967312580e-126, 1.4774864044730919e-134}, + {2.1045621159574830e-135, 1.6853736680140806e-127, 3.8060787191717414e-121, 1.2460431717780355e-115, 1.1217254900384875e-110, 3.8823686733906794e-106, 6.3324559268876792e-102, 5.5741078533835752e-98, 2.9150063258205350e-94, 9.7261605479925101e-91, 2.1872204017818973e-87, 3.4618487459964773e-84, 3.9938420292542256e-81, 3.4566329048643892e-78, 2.2990777865226915e-75, 1.1993601521489046e-72, 4.9937669382694245e-70, 1.6848180938195073e-67, 4.6671413158696264e-65, 1.0738850147584223e-62, 2.0736313112573398e-60, 3.3911184321991622e-58, 4.7353070830108189e-56, 5.6878446259603137e-54, 5.9160971507025675e-52, 5.3608992748856614e-50, 4.2554770940703958e-48, 2.9740995846398285e-46, 1.8385123238649587e-44, 1.0095495376276113e-42, 4.9435800520554766e-41, 2.1666198058800618e-39, 8.5272688786829149e-38, 3.0232780766836873e-36, 9.6838410701764544e-35, 2.8099176317436489e-33, 7.4047930191407272e-32, 1.7763620673555590e-30, 3.8878538387006395e-29, 7.7794521016127823e-28, 1.4259174843705503e-26, 2.3985064022625709e-25, 3.7088241471290263e-24, 5.2806166677136793e-23, 6.9334558099800012e-22, 8.4073193071442628e-21, 9.4275495388536763e-20, 9.7888471796527459e-19, 9.4228636835633407e-18, 8.4188202692459649e-17, 6.9888828000995662e-16, 5.3963258195263796e-15, 3.8792170840235010e-14, 2.5986297789613529e-13, 1.6235905955395716e-12, 9.4688541385973895e-12, 5.1587531828242437e-11, 2.6274698033796913e-10, 1.2519243488472937e-09, 5.5840692373466946e-09, 2.3330544086080361e-08, 9.1359564208430839e-08, 3.3548824403388151e-07, 1.1558985161302230e-06, 3.7384592935259604e-06, 1.1355193773739383e-05, 3.2404937824118138e-05, 8.6919300398468442e-05, 2.1921561912382546e-04, 5.2002884998328185e-04, 1.1607090699966350e-03, 2.4383039027033393e-03, 4.8221285878206101e-03, 8.9801569838840641e-03, 1.5751462301844443e-02, 2.6027795319202608e-02, 4.0523924217918790e-02, 5.9458195592787075e-02, 8.2223731723011229e-02, 1.0718097152174927e-01, 1.3170852135471239e-01, 1.5258690288545360e-01, 1.6666726633087006e-01, 1.7164316012362582e-01, 1.6666726633087006e-01, 1.5258690288545360e-01, 1.3170852135471239e-01, 1.0718097152174927e-01, 8.2223731723011229e-02, 5.9458195592787075e-02, 4.0523924217918790e-02, 2.6027795319202608e-02, 1.5751462301844443e-02, 8.9801569838840641e-03, 4.8221285878206101e-03, 2.4383039027033393e-03, 1.1607090699966350e-03, 5.2002884998328185e-04, 2.1921561912382546e-04, 8.6919300398468442e-05, 3.2404937824118138e-05, 1.1355193773739383e-05, 3.7384592935259604e-06, 1.1558985161302230e-06, 3.3548824403388151e-07, 9.1359564208430839e-08, 2.3330544086080361e-08, 5.5840692373466946e-09, 1.2519243488472937e-09, 2.6274698033796913e-10, 5.1587531828242437e-11, 9.4688541385973895e-12, 1.6235905955395716e-12, 2.5986297789613529e-13, 3.8792170840235010e-14, 5.3963258195263796e-15, 6.9888828000995662e-16, 8.4188202692459649e-17, 9.4228636835633407e-18, 9.7888471796527459e-19, 9.4275495388536763e-20, 8.4073193071442628e-21, 6.9334558099800012e-22, 5.2806166677136793e-23, 3.7088241471290263e-24, 2.3985064022625709e-25, 1.4259174843705503e-26, 7.7794521016127823e-28, 3.8878538387006395e-29, 1.7763620673555590e-30, 7.4047930191407272e-32, 2.8099176317436489e-33, 9.6838410701764544e-35, 3.0232780766836873e-36, 8.5272688786829149e-38, 2.1666198058800618e-39, 4.9435800520554766e-41, 1.0095495376276113e-42, 1.8385123238649587e-44, 2.9740995846398285e-46, 4.2554770940703958e-48, 5.3608992748856614e-50, 5.9160971507025675e-52, 5.6878446259603137e-54, 4.7353070830108189e-56, 3.3911184321991622e-58, 2.0736313112573398e-60, 1.0738850147584223e-62, 4.6671413158696264e-65, 1.6848180938195073e-67, 4.9937669382694245e-70, 1.1993601521489046e-72, 2.2990777865226915e-75, 3.4566329048643892e-78, 3.9938420292542256e-81, 3.4618487459964773e-84, 2.1872204017818973e-87, 9.7261605479925101e-91, 2.9150063258205350e-94, 5.5741078533835752e-98, 6.3324559268876792e-102, 3.8823686733906794e-106, 1.1217254900384875e-110, 1.2460431717780355e-115, 3.8060787191717414e-121, 1.6853736680140806e-127, 2.1045621159574830e-135}, + {2.9971690491012730e-136, 2.4980891398206762e-128, 5.8333713614299987e-122, 1.9681709423933214e-116, 1.8221727762675135e-111, 6.4763280099261484e-107, 1.0835544161526790e-102, 9.7751589620462579e-99, 5.2354686514639054e-95, 1.7880404661796150e-91, 4.1137899834361915e-88, 6.6588269447352457e-85, 7.8536797447719853e-82, 6.9470795412027442e-79, 4.7212966724403236e-76, 2.5160708333635340e-73, 1.0700081200070465e-70, 3.6866210764241453e-68, 1.0427591853094809e-65, 2.4496158809944983e-63, 4.8287654459243867e-61, 8.0607602578177551e-59, 1.1488941335553380e-56, 1.4084920383852964e-54, 1.4951953571335084e-52, 1.3827452604659908e-50, 1.1201727218381219e-48, 7.9894861866156147e-47, 5.0402806679659781e-45, 2.8245056542381498e-43, 1.4115238161648369e-41, 6.3134908835445427e-40, 2.5359952829354267e-38, 9.1766156441607901e-37, 3.0000961317861622e-35, 8.8855426938068462e-34, 2.3901684056219713e-32, 5.8532507898005387e-31, 1.3078348727191383e-29, 2.6717694287109624e-28, 5.0001529132188371e-27, 8.5882149512444349e-26, 1.3561502945339099e-24, 1.9719885628376035e-23, 2.6445905466631306e-22, 3.2756544281813711e-21, 3.7524614126630812e-20, 3.9808239456321635e-19, 3.9155933049886526e-18, 3.5751188594220651e-17, 3.0333673764885698e-16, 2.3941367575799993e-15, 1.7594869510962716e-14, 1.2051394761470136e-13, 7.6998498930386894e-13, 4.5928264710545402e-12, 2.5595903423630225e-11, 1.3337516615570700e-10, 6.5027567060176707e-10, 2.9684197043117582e-09, 1.2694911467897228e-08, 5.0894009383117858e-08, 1.9137169385842292e-07, 6.7528978068278956e-07, 2.2372679339319808e-06, 6.9624497238718160e-06, 2.0361547224732169e-05, 5.5980964406792492e-05, 1.4474894898356766e-04, 3.5211870018385556e-04, 8.0612713585123284e-04, 1.7373614851938118e-03, 3.5259000508765289e-03, 6.7399040525805923e-03, 1.2137859543972172e-02, 2.0598052684982535e-02, 3.2944830178350461e-02, 4.9670368744572549e-02, 7.0602349240131604e-02, 9.4625036098936688e-02, 1.1959210591508003e-01, 1.4254236006576013e-01, 1.6023480790396424e-01, 1.6988651844048314e-01, 1.6988651844048314e-01, 1.6023480790396424e-01, 1.4254236006576013e-01, 1.1959210591508003e-01, 9.4625036098936688e-02, 7.0602349240131604e-02, 4.9670368744572549e-02, 3.2944830178350461e-02, 2.0598052684982535e-02, 1.2137859543972172e-02, 6.7399040525805923e-03, 3.5259000508765289e-03, 1.7373614851938118e-03, 8.0612713585123284e-04, 3.5211870018385556e-04, 1.4474894898356766e-04, 5.5980964406792492e-05, 2.0361547224732169e-05, 6.9624497238718160e-06, 2.2372679339319808e-06, 6.7528978068278956e-07, 1.9137169385842292e-07, 5.0894009383117858e-08, 1.2694911467897228e-08, 2.9684197043117582e-09, 6.5027567060176707e-10, 1.3337516615570700e-10, 2.5595903423630225e-11, 4.5928264710545402e-12, 7.6998498930386894e-13, 1.2051394761470136e-13, 1.7594869510962716e-14, 2.3941367575799993e-15, 3.0333673764885698e-16, 3.5751188594220651e-17, 3.9155933049886526e-18, 3.9808239456321635e-19, 3.7524614126630812e-20, 3.2756544281813711e-21, 2.6445905466631306e-22, 1.9719885628376035e-23, 1.3561502945339099e-24, 8.5882149512444349e-26, 5.0001529132188371e-27, 2.6717694287109624e-28, 1.3078348727191383e-29, 5.8532507898005387e-31, 2.3901684056219713e-32, 8.8855426938068462e-34, 3.0000961317861622e-35, 9.1766156441607901e-37, 2.5359952829354267e-38, 6.3134908835445427e-40, 1.4115238161648369e-41, 2.8245056542381498e-43, 5.0402806679659781e-45, 7.9894861866156147e-47, 1.1201727218381219e-48, 1.3827452604659908e-50, 1.4951953571335084e-52, 1.4084920383852964e-54, 1.1488941335553380e-56, 8.0607602578177551e-59, 4.8287654459243867e-61, 2.4496158809944983e-63, 1.0427591853094809e-65, 3.6866210764241453e-68, 1.0700081200070465e-70, 2.5160708333635340e-73, 4.7212966724403236e-76, 6.9470795412027442e-79, 7.8536797447719853e-82, 6.6588269447352457e-85, 4.1137899834361915e-88, 1.7880404661796150e-91, 5.2354686514639054e-95, 9.7751589620462579e-99, 1.0835544161526790e-102, 6.4763280099261484e-107, 1.8221727762675135e-111, 1.9681709423933214e-116, 5.8333713614299987e-122, 2.4980891398206762e-128, 2.9971690491012730e-136}, + {4.2674931553342203e-137, 3.7013509844210040e-129, 8.9359543576021383e-123, 3.1068184196664260e-117, 2.9577586950025811e-112, 1.0793940202510381e-107, 1.8522459789363982e-103, 1.7123515642355668e-99, 9.3917005928096861e-96, 3.2827539517233995e-92, 7.7262644929909970e-89, 1.2788460726412831e-85, 1.5418407850274678e-82, 1.3937615371156682e-79, 9.6774116872500576e-77, 5.2679228724311439e-74, 2.2879261623118261e-71, 8.0492001695776603e-69, 2.3244392181338319e-66, 5.5743129455028007e-64, 1.1216194835766520e-61, 1.9110201175931197e-59, 2.7798349876894280e-57, 3.4779129275742834e-55, 3.7676299883874885e-53, 3.5555263388415704e-51, 2.9391917507565755e-49, 2.1391283000208420e-47, 1.3770363396814081e-45, 7.8742105891358037e-44, 4.0154223770167576e-42, 1.8327311167318893e-40, 7.5123280800309780e-39, 2.7740812006389936e-37, 9.2554744703184908e-36, 2.7976499634157274e-34, 7.6807810254033586e-33, 1.9198421026192681e-31, 4.3786397679911876e-30, 9.1312863995714357e-29, 1.7445924812851179e-27, 3.0593178878006020e-26, 4.9326008142373812e-25, 7.3241393698795336e-24, 1.0030774102469258e-22, 1.2689360428385754e-21, 1.4847983173617774e-20, 1.6090879587826797e-19, 1.6169926387796005e-18, 1.5085327113052835e-17, 1.3079623075775175e-16, 1.0550654299237249e-15, 7.9256160807813284e-15, 5.5495687412198589e-14, 3.6252638108375508e-13, 2.2112377011770522e-12, 1.2603426258460018e-11, 6.7177337738006964e-11, 3.3507655233538448e-10, 1.5650990540810345e-09, 6.8499863308168436e-09, 2.8109038530404097e-08, 1.0820676942101237e-07, 3.9097121047484011e-07, 1.3265796796150300e-06, 4.2288616562734994e-06, 1.2670859378200327e-05, 3.5699320251985919e-05, 9.4613317406319364e-05, 2.3596028278015030e-04, 5.5394259248142631e-04, 1.2245148633746915e-03, 2.5495331679026910e-03, 5.0011317639987000e-03, 9.2446564129297221e-03, 1.6107280751087583e-02, 2.6457407162359760e-02, 4.0977099534106338e-02, 5.9850822005640535e-02, 8.2450068298432835e-02, 1.0714008439362262e-01, 1.3133855013394508e-01, 1.5189453076872492e-01, 1.6573850820195182e-01, 1.7062752012289428e-01, 1.6573850820195182e-01, 1.5189453076872492e-01, 1.3133855013394508e-01, 1.0714008439362262e-01, 8.2450068298432835e-02, 5.9850822005640535e-02, 4.0977099534106338e-02, 2.6457407162359760e-02, 1.6107280751087583e-02, 9.2446564129297221e-03, 5.0011317639987000e-03, 2.5495331679026910e-03, 1.2245148633746915e-03, 5.5394259248142631e-04, 2.3596028278015030e-04, 9.4613317406319364e-05, 3.5699320251985919e-05, 1.2670859378200327e-05, 4.2288616562734994e-06, 1.3265796796150300e-06, 3.9097121047484011e-07, 1.0820676942101237e-07, 2.8109038530404097e-08, 6.8499863308168436e-09, 1.5650990540810345e-09, 3.3507655233538448e-10, 6.7177337738006964e-11, 1.2603426258460018e-11, 2.2112377011770522e-12, 3.6252638108375508e-13, 5.5495687412198589e-14, 7.9256160807813284e-15, 1.0550654299237249e-15, 1.3079623075775175e-16, 1.5085327113052835e-17, 1.6169926387796005e-18, 1.6090879587826797e-19, 1.4847983173617774e-20, 1.2689360428385754e-21, 1.0030774102469258e-22, 7.3241393698795336e-24, 4.9326008142373812e-25, 3.0593178878006020e-26, 1.7445924812851179e-27, 9.1312863995714357e-29, 4.3786397679911876e-30, 1.9198421026192681e-31, 7.6807810254033586e-33, 2.7976499634157274e-34, 9.2554744703184908e-36, 2.7740812006389936e-37, 7.5123280800309780e-39, 1.8327311167318893e-40, 4.0154223770167576e-42, 7.8742105891358037e-44, 1.3770363396814081e-45, 2.1391283000208420e-47, 2.9391917507565755e-49, 3.5555263388415704e-51, 3.7676299883874885e-53, 3.4779129275742834e-55, 2.7798349876894280e-57, 1.9110201175931197e-59, 1.1216194835766520e-61, 5.5743129455028007e-64, 2.3244392181338319e-66, 8.0492001695776603e-69, 2.2879261623118261e-71, 5.2679228724311439e-74, 9.6774116872500576e-77, 1.3937615371156682e-79, 1.5418407850274678e-82, 1.2788460726412831e-85, 7.7262644929909970e-89, 3.2827539517233995e-92, 9.3917005928096861e-96, 1.7123515642355668e-99, 1.8522459789363982e-103, 1.0793940202510381e-107, 2.9577586950025811e-112, 3.1068184196664260e-117, 8.9359543576021383e-123, 3.7013509844210040e-129, 4.2674931553342203e-137}, + {6.0750158130606195e-138, 5.4821992024733287e-130, 1.3681822165982846e-123, 4.9011169950359405e-118, 4.7974396933811439e-113, 1.7974392277078273e-108, 3.1631548152333414e-104, 2.9963165563522804e-100, 1.6827169561417482e-96, 6.0190850814126162e-93, 1.4490438595507066e-89, 2.4523185664718153e-86, 3.0220219471047618e-83, 2.7913874973199548e-80, 1.9799592744971097e-77, 1.1008005267477927e-74, 4.8820589020655159e-72, 1.7536229837285863e-69, 5.1696909850843693e-67, 1.2654633658209892e-64, 2.5987959219621812e-62, 4.5188057419567269e-60, 6.7077790006444227e-58, 8.5635704641083388e-56, 9.4658821709007862e-54, 9.1146156997272630e-52, 7.6876441303763667e-50, 5.7085575439180572e-48, 3.7493520841061347e-46, 2.1874580274727376e-44, 1.1381244408182845e-42, 5.3001743821412355e-41, 2.2167101442428974e-39, 8.3523638615101674e-38, 2.8435471995138850e-36, 8.7709151746020293e-35, 2.4573526663074424e-33, 6.2684680341301147e-32, 1.4591317861612538e-30, 3.1058077266730593e-29, 6.0569508661768345e-28, 1.0842625724312578e-26, 1.7847202502838671e-25, 2.7056507791212747e-24, 3.7836354660151275e-23, 4.8878185643771254e-22, 5.8409861850177518e-21, 6.4652715404585129e-20, 6.6366701688022747e-19, 6.3252994285961157e-18, 5.6034658987730242e-17, 4.6187988803389262e-16, 3.5458950811944735e-15, 2.5377705512106429e-14, 1.6946972716989475e-13, 1.0568382827043380e-12, 6.1595020440963285e-12, 3.3576005591117169e-11, 1.7130382466099029e-10, 8.1856149500888656e-10, 3.6657050674739318e-09, 1.5393813958417279e-08, 6.0654560255829627e-08, 2.2435783940914669e-07, 7.7946793854749263e-07, 2.5447213452537048e-06, 7.8101702177205490e-06, 2.2544487920551540e-05, 6.1227929783044720e-05, 1.5651161607055494e-04, 3.7668553922014524e-04, 8.5385410230442147e-04, 1.8234228920144958e-03, 3.6694988559735154e-03, 6.9606294949961902e-03, 1.2448294747794275e-02, 2.0993195618512490e-02, 3.3391282475767885e-02, 5.0100599356951693e-02, 7.0919958702876942e-02, 9.4724291720265918e-02, 1.1938903980933140e-01, 1.4200771666714165e-01, 1.5941508322714990e-01, 1.6890164874640598e-01, 1.6890164874640598e-01, 1.5941508322714990e-01, 1.4200771666714165e-01, 1.1938903980933140e-01, 9.4724291720265918e-02, 7.0919958702876942e-02, 5.0100599356951693e-02, 3.3391282475767885e-02, 2.0993195618512490e-02, 1.2448294747794275e-02, 6.9606294949961902e-03, 3.6694988559735154e-03, 1.8234228920144958e-03, 8.5385410230442147e-04, 3.7668553922014524e-04, 1.5651161607055494e-04, 6.1227929783044720e-05, 2.2544487920551540e-05, 7.8101702177205490e-06, 2.5447213452537048e-06, 7.7946793854749263e-07, 2.2435783940914669e-07, 6.0654560255829627e-08, 1.5393813958417279e-08, 3.6657050674739318e-09, 8.1856149500888656e-10, 1.7130382466099029e-10, 3.3576005591117169e-11, 6.1595020440963285e-12, 1.0568382827043380e-12, 1.6946972716989475e-13, 2.5377705512106429e-14, 3.5458950811944735e-15, 4.6187988803389262e-16, 5.6034658987730242e-17, 6.3252994285961157e-18, 6.6366701688022747e-19, 6.4652715404585129e-20, 5.8409861850177518e-21, 4.8878185643771254e-22, 3.7836354660151275e-23, 2.7056507791212747e-24, 1.7847202502838671e-25, 1.0842625724312578e-26, 6.0569508661768345e-28, 3.1058077266730593e-29, 1.4591317861612538e-30, 6.2684680341301147e-32, 2.4573526663074424e-33, 8.7709151746020293e-35, 2.8435471995138850e-36, 8.3523638615101674e-38, 2.2167101442428974e-39, 5.3001743821412355e-41, 1.1381244408182845e-42, 2.1874580274727376e-44, 3.7493520841061347e-46, 5.7085575439180572e-48, 7.6876441303763667e-50, 9.1146156997272630e-52, 9.4658821709007862e-54, 8.5635704641083388e-56, 6.7077790006444227e-58, 4.5188057419567269e-60, 2.5987959219621812e-62, 1.2654633658209892e-64, 5.1696909850843693e-67, 1.7536229837285863e-69, 4.8820589020655159e-72, 1.1008005267477927e-74, 1.9799592744971097e-77, 2.7913874973199548e-80, 3.0220219471047618e-83, 2.4523185664718153e-86, 1.4490438595507066e-89, 6.0190850814126162e-93, 1.6827169561417482e-96, 2.9963165563522804e-100, 3.1631548152333414e-104, 1.7974392277078273e-108, 4.7974396933811439e-113, 4.9011169950359405e-118, 1.3681822165982846e-123, 5.4821992024733287e-130, 6.0750158130606195e-138}, + {8.6464098495106045e-139, 8.1169547967150641e-131, 2.0937788694250258e-124, 7.7268624062801043e-119, 7.7755878030242305e-114, 2.9905793066209871e-109, 5.3966031917331080e-105, 5.2373672835160608e-101, 3.0113519152678094e-97, 1.1021983838887256e-93, 2.7138416423119788e-90, 4.6954865769208796e-87, 5.9136418179343394e-84, 5.5809142352163536e-81, 4.0435337904295643e-78, 2.2958300915077279e-75, 1.0396325878228644e-72, 3.8123200620819477e-70, 1.1471867481155006e-67, 2.8660528596806035e-65, 6.0065917977528455e-63, 1.0657711610182893e-60, 1.6142564784909037e-58, 2.1026978884308611e-56, 2.3713251069838819e-54, 2.3294898984397351e-52, 2.0044580918502007e-50, 1.5184626573152095e-48, 1.0174299157427975e-46, 6.0556195147012746e-45, 3.2142710908365357e-43, 1.5270851777984907e-41, 6.5158604619910054e-40, 2.5048070243067333e-38, 8.7004606571271586e-37, 2.7381749245865647e-35, 7.8277738587896100e-34, 2.0375540992709603e-32, 4.8399847326203970e-31, 1.0513633818680897e-29, 2.0926202706959383e-28, 3.8234939104131151e-27, 6.4242027780709820e-26, 9.9421354277925673e-25, 1.4194294864852321e-23, 1.8722162613285435e-22, 2.2845745768934510e-21, 2.5824265914439110e-20, 2.7074430614342264e-19, 2.6357601492491789e-18, 2.3853221384019439e-17, 2.0087998156976881e-16, 1.5758126400353855e-15, 1.1525451076836792e-14, 7.8665152475648879e-14, 5.0146808941799565e-13, 2.9880423319270495e-12, 1.6654840593814865e-11, 8.6899012302376471e-11, 4.2472082249711324e-10, 1.9457386067825712e-09, 8.3602716973645751e-09, 3.3710054470838133e-08, 1.2762506765080952e-07, 4.5391122547936338e-07, 1.5173031250618367e-06, 4.7690949847434419e-06, 1.4100857760918970e-05, 3.9234961307384339e-05, 1.0277324714018339e-04, 2.5352235086933272e-04, 5.8914391280362889e-04, 1.2901045250613646e-03, 2.6628467710093206e-03, 5.1819700035925865e-03, 9.5097957728564348e-03, 1.6461365836824633e-02, 2.6881937632071830e-02, 4.1421702134247403e-02, 6.0232621258249110e-02, 8.2666028537237118e-02, 1.0709279898985245e-01, 1.3096920653341185e-01, 1.5121094137038713e-01, 1.6482506909185640e-01, 1.6962969836778974e-01, 1.6482506909185640e-01, 1.5121094137038713e-01, 1.3096920653341185e-01, 1.0709279898985245e-01, 8.2666028537237118e-02, 6.0232621258249110e-02, 4.1421702134247403e-02, 2.6881937632071830e-02, 1.6461365836824633e-02, 9.5097957728564348e-03, 5.1819700035925865e-03, 2.6628467710093206e-03, 1.2901045250613646e-03, 5.8914391280362889e-04, 2.5352235086933272e-04, 1.0277324714018339e-04, 3.9234961307384339e-05, 1.4100857760918970e-05, 4.7690949847434419e-06, 1.5173031250618367e-06, 4.5391122547936338e-07, 1.2762506765080952e-07, 3.3710054470838133e-08, 8.3602716973645751e-09, 1.9457386067825712e-09, 4.2472082249711324e-10, 8.6899012302376471e-11, 1.6654840593814865e-11, 2.9880423319270495e-12, 5.0146808941799565e-13, 7.8665152475648879e-14, 1.1525451076836792e-14, 1.5758126400353855e-15, 2.0087998156976881e-16, 2.3853221384019439e-17, 2.6357601492491789e-18, 2.7074430614342264e-19, 2.5824265914439110e-20, 2.2845745768934510e-21, 1.8722162613285435e-22, 1.4194294864852321e-23, 9.9421354277925673e-25, 6.4242027780709820e-26, 3.8234939104131151e-27, 2.0926202706959383e-28, 1.0513633818680897e-29, 4.8399847326203970e-31, 2.0375540992709603e-32, 7.8277738587896100e-34, 2.7381749245865647e-35, 8.7004606571271586e-37, 2.5048070243067333e-38, 6.5158604619910054e-40, 1.5270851777984907e-41, 3.2142710908365357e-43, 6.0556195147012746e-45, 1.0174299157427975e-46, 1.5184626573152095e-48, 2.0044580918502007e-50, 2.3294898984397351e-52, 2.3713251069838819e-54, 2.1026978884308611e-56, 1.6142564784909037e-58, 1.0657711610182893e-60, 6.0065917977528455e-63, 2.8660528596806035e-65, 1.1471867481155006e-67, 3.8123200620819477e-70, 1.0396325878228644e-72, 2.2958300915077279e-75, 4.0435337904295643e-78, 5.5809142352163536e-81, 5.9136418179343394e-84, 4.6954865769208796e-87, 2.7138416423119788e-90, 1.1021983838887256e-93, 3.0113519152678094e-97, 5.2373672835160608e-101, 5.3966031917331080e-105, 2.9905793066209871e-109, 7.7755878030242305e-114, 7.7268624062801043e-119, 2.0937788694250258e-124, 8.1169547967150641e-131, 8.6464098495106045e-139}, + {1.2303789814620092e-139, 1.2013699333289992e-131, 3.2026074548384006e-125, 1.2174269794916373e-119, 1.2593229738553804e-114, 4.9714964520806193e-110, 9.1982052962411378e-106, 9.1447911140134055e-102, 5.3827092462530275e-98, 2.0157286790487118e-94, 5.0755707227503414e-91, 8.9771058574961900e-88, 1.1553649373808784e-84, 1.1139151556417037e-81, 8.2429409894791420e-79, 4.7790526311204645e-76, 2.2094400576899919e-73, 8.2703192545553517e-71, 2.5400223834270154e-68, 6.4759951809357819e-66, 1.3849218619189611e-63, 2.5072557278333359e-61, 3.8744806525565368e-59, 5.1487100357555966e-57, 5.9234211353878837e-55, 5.9358962183919884e-53, 5.2102035909462387e-51, 4.0261165631274628e-49, 2.7517389408826910e-47, 1.6706338169898752e-45, 9.0454023907569489e-44, 4.3836632815273276e-42, 1.9080203924026029e-40, 7.4822875434667983e-39, 2.6513404940738975e-37, 8.5126426420369604e-36, 2.4827942651601884e-34, 6.5937510349118087e-33, 1.5981308016388612e-31, 3.5423572866413238e-30, 7.1949797524882649e-29, 1.3416207816913450e-27, 2.3006552131922817e-26, 3.6342070015972533e-25, 5.2963698057770957e-24, 7.1317120414745996e-23, 8.8849961119116762e-22, 1.0255026540751254e-20, 1.0979177006155230e-19, 1.0916029509464340e-18, 1.0090271979231116e-17, 8.6804078056359369e-17, 6.9567797833146074e-16, 5.1989584985238723e-15, 3.6262025536343989e-14, 2.3625593061240154e-13, 1.4389854608144821e-12, 8.1997932243736651e-12, 4.3745620487604465e-11, 2.1864887185791365e-10, 1.0245209689572339e-09, 4.5031898910426613e-09, 1.8577866622072818e-08, 7.1975399855994780e-08, 2.6200414925731448e-07, 8.9655811991941417e-07, 2.8853130691641410e-06, 8.7365058018499081e-06, 2.4899323348910079e-05, 6.6819890242436042e-05, 1.6890601339725517e-04, 4.0229796846567709e-04, 9.0312111074868030e-04, 1.9114445894976445e-03, 3.8151134691487313e-03, 7.1826754657021994e-03, 1.2758271065775782e-02, 2.1384981853074116e-02, 3.3830872556682462e-02, 5.0520980072118506e-02, 7.1226720494510898e-02, 9.4814894788900164e-02, 1.1918291538647637e-01, 1.4147779230279267e-01, 1.5860763301741698e-01, 1.6793370935002905e-01, 1.6793370935002905e-01, 1.5860763301741698e-01, 1.4147779230279267e-01, 1.1918291538647637e-01, 9.4814894788900164e-02, 7.1226720494510898e-02, 5.0520980072118506e-02, 3.3830872556682462e-02, 2.1384981853074116e-02, 1.2758271065775782e-02, 7.1826754657021994e-03, 3.8151134691487313e-03, 1.9114445894976445e-03, 9.0312111074868030e-04, 4.0229796846567709e-04, 1.6890601339725517e-04, 6.6819890242436042e-05, 2.4899323348910079e-05, 8.7365058018499081e-06, 2.8853130691641410e-06, 8.9655811991941417e-07, 2.6200414925731448e-07, 7.1975399855994780e-08, 1.8577866622072818e-08, 4.5031898910426613e-09, 1.0245209689572339e-09, 2.1864887185791365e-10, 4.3745620487604465e-11, 8.1997932243736651e-12, 1.4389854608144821e-12, 2.3625593061240154e-13, 3.6262025536343989e-14, 5.1989584985238723e-15, 6.9567797833146074e-16, 8.6804078056359369e-17, 1.0090271979231116e-17, 1.0916029509464340e-18, 1.0979177006155230e-19, 1.0255026540751254e-20, 8.8849961119116762e-22, 7.1317120414745996e-23, 5.2963698057770957e-24, 3.6342070015972533e-25, 2.3006552131922817e-26, 1.3416207816913450e-27, 7.1949797524882649e-29, 3.5423572866413238e-30, 1.5981308016388612e-31, 6.5937510349118087e-33, 2.4827942651601884e-34, 8.5126426420369604e-36, 2.6513404940738975e-37, 7.4822875434667983e-39, 1.9080203924026029e-40, 4.3836632815273276e-42, 9.0454023907569489e-44, 1.6706338169898752e-45, 2.7517389408826910e-47, 4.0261165631274628e-49, 5.2102035909462387e-51, 5.9358962183919884e-53, 5.9234211353878837e-55, 5.1487100357555966e-57, 3.8744806525565368e-59, 2.5072557278333359e-61, 1.3849218619189611e-63, 6.4759951809357819e-66, 2.5400223834270154e-68, 8.2703192545553517e-71, 2.2094400576899919e-73, 4.7790526311204645e-76, 8.2429409894791420e-79, 1.1139151556417037e-81, 1.1553649373808784e-84, 8.9771058574961900e-88, 5.0755707227503414e-91, 2.0157286790487118e-94, 5.3827092462530275e-98, 9.1447911140134055e-102, 9.1982052962411378e-106, 4.9714964520806193e-110, 1.2593229738553804e-114, 1.2174269794916373e-119, 3.2026074548384006e-125, 1.2013699333289992e-131, 1.2303789814620092e-139}, + {1.7504813313443110e-140, 1.7774902414670824e-132, 4.8962631916290320e-126, 1.9169773412509448e-120, 2.0380950317636651e-115, 8.2575913221058373e-111, 1.5662913179616934e-106, 1.5950515939148060e-102, 9.6102475509992629e-99, 3.6817405361106414e-95, 9.4795771929584613e-92, 1.7137636253252277e-88, 2.2537069207131266e-85, 2.2195670363270061e-82, 1.6773665243938764e-79, 9.9294168393320748e-77, 4.6861855398798507e-74, 1.7903790379405142e-71, 5.6115831515377673e-69, 1.4599152900352242e-66, 3.1854832448751424e-64, 5.8835568128153365e-62, 9.2750122555037185e-60, 1.2572829274411131e-57, 1.4754337744917936e-55, 1.5080977336171035e-53, 1.3501492314506362e-51, 1.0641162728147897e-49, 7.4179019446614824e-48, 4.5933036667242678e-46, 2.5365532103719637e-44, 1.2538070457653651e-42, 5.5662423908008861e-41, 2.2264349328620495e-39, 8.0473188469528885e-38, 2.6355807192340085e-36, 7.8414692242533960e-35, 2.1244914229476255e-33, 5.2531973592621732e-32, 1.1880047374923401e-30, 2.4620531629619134e-29, 4.6845665497518896e-28, 8.1977521328279625e-27, 1.3215706261902287e-25, 1.9657684577473083e-24, 2.7018364834425692e-23, 3.4361611658856167e-22, 4.0489821139593706e-21, 4.4260400812843420e-20, 4.4935788616135659e-19, 4.2418977594565075e-18, 3.7271474634420088e-17, 3.0512318816558229e-16, 2.3295237031463167e-15, 1.6601293173811213e-14, 1.1052712006706022e-13, 6.8801511055288008e-13, 4.0073848073937339e-12, 2.1856088643011424e-11, 1.1169403547356809e-10, 5.3519948055672733e-10, 2.4060047025435626e-09, 1.0153711719361421e-08, 4.0247544813147544e-08, 1.4992205080398724e-07, 5.2506826823537642e-07, 1.7297783253854633e-06, 5.3626317222650889e-06, 1.5651476474775071e-05, 4.3021779350373374e-05, 1.1141208654585957e-04, 2.7191419917337988e-04, 6.2563601676209426e-04, 1.3574588134771591e-03, 2.7781892530593399e-03, 5.3645468312921761e-03, 9.7754538393799058e-03, 1.6813616037549516e-02, 2.7301369702544091e-02, 4.1857856809001823e-02, 6.0603870172343872e-02, 8.2871975523587077e-02, 1.0703943053616907e-01, 1.3060060873789656e-01, 1.5053596929119434e-01, 1.6392653352569631e-01, 1.6864917988011466e-01, 1.6392653352569631e-01, 1.5053596929119434e-01, 1.3060060873789656e-01, 1.0703943053616907e-01, 8.2871975523587077e-02, 6.0603870172343872e-02, 4.1857856809001823e-02, 2.7301369702544091e-02, 1.6813616037549516e-02, 9.7754538393799058e-03, 5.3645468312921761e-03, 2.7781892530593399e-03, 1.3574588134771591e-03, 6.2563601676209426e-04, 2.7191419917337988e-04, 1.1141208654585957e-04, 4.3021779350373374e-05, 1.5651476474775071e-05, 5.3626317222650889e-06, 1.7297783253854633e-06, 5.2506826823537642e-07, 1.4992205080398724e-07, 4.0247544813147544e-08, 1.0153711719361421e-08, 2.4060047025435626e-09, 5.3519948055672733e-10, 1.1169403547356809e-10, 2.1856088643011424e-11, 4.0073848073937339e-12, 6.8801511055288008e-13, 1.1052712006706022e-13, 1.6601293173811213e-14, 2.3295237031463167e-15, 3.0512318816558229e-16, 3.7271474634420088e-17, 4.2418977594565075e-18, 4.4935788616135659e-19, 4.4260400812843420e-20, 4.0489821139593706e-21, 3.4361611658856167e-22, 2.7018364834425692e-23, 1.9657684577473083e-24, 1.3215706261902287e-25, 8.1977521328279625e-27, 4.6845665497518896e-28, 2.4620531629619134e-29, 1.1880047374923401e-30, 5.2531973592621732e-32, 2.1244914229476255e-33, 7.8414692242533960e-35, 2.6355807192340085e-36, 8.0473188469528885e-38, 2.2264349328620495e-39, 5.5662423908008861e-41, 1.2538070457653651e-42, 2.5365532103719637e-44, 4.5933036667242678e-46, 7.4179019446614824e-48, 1.0641162728147897e-49, 1.3501492314506362e-51, 1.5080977336171035e-53, 1.4754337744917936e-55, 1.2572829274411131e-57, 9.2750122555037185e-60, 5.8835568128153365e-62, 3.1854832448751424e-64, 1.4599152900352242e-66, 5.6115831515377673e-69, 1.7903790379405142e-71, 4.6861855398798507e-74, 9.9294168393320748e-77, 1.6773665243938764e-79, 2.2195670363270061e-82, 2.2537069207131266e-85, 1.7137636253252277e-88, 9.4795771929584613e-92, 3.6817405361106414e-95, 9.6102475509992629e-99, 1.5950515939148060e-102, 1.5662913179616934e-106, 8.2575913221058373e-111, 2.0380950317636651e-115, 1.9169773412509448e-120, 4.8962631916290320e-126, 1.7774902414670824e-132, 1.7504813313443110e-140}, + {2.4899600964326729e-141, 2.6289723724457029e-133, 7.4819712112270593e-127, 3.0166712841087998e-121, 3.2960842775717504e-116, 1.3704328437984587e-111, 2.6646059822111242e-107, 2.7792048294771247e-103, 1.7138296773072837e-99, 6.7162796391421331e-96, 1.7680841960979503e-92, 3.2668637275061076e-89, 4.3893173430676675e-86, 4.4153132623096831e-83, 3.4072707861884866e-80, 2.0591798858084703e-77, 9.9197548192127678e-75, 3.8678293788234498e-72, 1.2370523208691571e-69, 3.2836627133699974e-67, 7.3095353354239491e-65, 1.3772094187709065e-62, 2.2145636638702121e-60, 3.0619202170369175e-58, 3.6647661995973869e-56, 3.8203649763779160e-54, 3.4881351774083147e-52, 2.8036775536310555e-50, 1.9931613619579773e-48, 1.2586567146117010e-46, 7.0884044215753474e-45, 3.5732404426806206e-43, 1.6178126120857497e-41, 6.5996510428781978e-40, 2.4328759328467202e-38, 8.1267763573550637e-37, 2.4662127220461684e-35, 6.8155261813509929e-34, 1.7191030917484011e-32, 3.9660195668953352e-31, 8.3853154776461475e-30, 1.6278171201629848e-28, 2.9065390998814081e-27, 4.7813433896247487e-26, 7.2578010107444783e-25, 1.0180797851831930e-23, 1.3215548441960911e-22, 1.5895976396503745e-21, 1.7738996763753002e-20, 1.8387513781865510e-19, 1.7723693479759404e-18, 1.5903120371435548e-17, 1.3296671955521453e-16, 1.0369288823537636e-15, 7.5490426637877302e-15, 5.1350286901144194e-14, 3.2662837995375004e-13, 1.9442795471244843e-12, 1.0838609818985724e-11, 5.6623712315092519e-11, 2.7740673531720516e-10, 1.2752593807305187e-09, 5.5042412134787782e-09, 2.2317961616833082e-08, 8.5054483756057923e-08, 3.0481775749836127e-07, 1.0277468837741270e-06, 3.2615617411254204e-06, 9.7462566160282362e-06, 2.7434125933222057e-05, 7.2768434100256330e-05, 1.8194526534270113e-04, 4.2896461357756435e-04, 9.5392124328337667e-04, 2.0013900802573659e-03, 3.9626676572752555e-03, 7.4059308800968815e-03, 1.3067672819155697e-02, 2.1773347066246198e-02, 3.4263651242794235e-02, 5.0931713552683139e-02, 7.1522962430052642e-02, 9.4897195996236208e-02, 1.1897395918444152e-01, 1.4095256578997853e-01, 1.5781215945203400e-01, 1.6698222073712451e-01, 1.6698222073712451e-01, 1.5781215945203400e-01, 1.4095256578997853e-01, 1.1897395918444152e-01, 9.4897195996236208e-02, 7.1522962430052642e-02, 5.0931713552683139e-02, 3.4263651242794235e-02, 2.1773347066246198e-02, 1.3067672819155697e-02, 7.4059308800968815e-03, 3.9626676572752555e-03, 2.0013900802573659e-03, 9.5392124328337667e-04, 4.2896461357756435e-04, 1.8194526534270113e-04, 7.2768434100256330e-05, 2.7434125933222057e-05, 9.7462566160282362e-06, 3.2615617411254204e-06, 1.0277468837741270e-06, 3.0481775749836127e-07, 8.5054483756057923e-08, 2.2317961616833082e-08, 5.5042412134787782e-09, 1.2752593807305187e-09, 2.7740673531720516e-10, 5.6623712315092519e-11, 1.0838609818985724e-11, 1.9442795471244843e-12, 3.2662837995375004e-13, 5.1350286901144194e-14, 7.5490426637877302e-15, 1.0369288823537636e-15, 1.3296671955521453e-16, 1.5903120371435548e-17, 1.7723693479759404e-18, 1.8387513781865510e-19, 1.7738996763753002e-20, 1.5895976396503745e-21, 1.3215548441960911e-22, 1.0180797851831930e-23, 7.2578010107444783e-25, 4.7813433896247487e-26, 2.9065390998814081e-27, 1.6278171201629848e-28, 8.3853154776461475e-30, 3.9660195668953352e-31, 1.7191030917484011e-32, 6.8155261813509929e-34, 2.4662127220461684e-35, 8.1267763573550637e-37, 2.4328759328467202e-38, 6.5996510428781978e-40, 1.6178126120857497e-41, 3.5732404426806206e-43, 7.0884044215753474e-45, 1.2586567146117010e-46, 1.9931613619579773e-48, 2.8036775536310555e-50, 3.4881351774083147e-52, 3.8203649763779160e-54, 3.6647661995973869e-56, 3.0619202170369175e-58, 2.2145636638702121e-60, 1.3772094187709065e-62, 7.3095353354239491e-65, 3.2836627133699974e-67, 1.2370523208691571e-69, 3.8678293788234498e-72, 9.9197548192127678e-75, 2.0591798858084703e-77, 3.4072707861884866e-80, 4.4153132623096831e-83, 4.3893173430676675e-86, 3.2668637275061076e-89, 1.7680841960979503e-92, 6.7162796391421331e-96, 1.7138296773072837e-99, 2.7792048294771247e-103, 2.6646059822111242e-107, 1.3704328437984587e-111, 3.2960842775717504e-116, 3.0166712841087998e-121, 7.4819712112270593e-127, 2.6289723724457029e-133, 2.4899600964326729e-141}, + {3.5411506471568517e-142, 3.8870007298929211e-134, 1.1427720218874746e-127, 4.7443699591186030e-122, 5.3267445942905176e-117, 2.2724999081578913e-112, 4.5288568274049433e-108, 4.8374430266711206e-104, 3.0528486739600850e-100, 1.2236703652880107e-96, 3.2933121419749483e-93, 6.2184654173606399e-90, 8.5354199357192903e-87, 8.7687858501113383e-84, 6.9091769993084969e-81, 4.2624770595798820e-78, 2.0957319191157142e-75, 8.3387106103658512e-73, 2.7211703761612434e-70, 7.3690229255476969e-68, 1.6733234438392451e-65, 3.2158114928338939e-63, 5.2740829263623727e-61, 7.4369351842678165e-59, 9.0774918435864705e-57, 9.6499842697585386e-55, 8.9847110119503318e-53, 7.3640839458387673e-51, 5.3383547450946618e-49, 3.4375135972727117e-47, 1.9740530949677369e-45, 1.0147285474798106e-43, 4.6848975802870826e-42, 1.9488875555428468e-40, 7.3264228854645894e-39, 2.4958088668373114e-37, 7.7243461606513683e-36, 2.1771495752866995e-34, 5.6010600122601367e-33, 1.3180336788235122e-31, 2.8426307813064235e-30, 5.6294266388452469e-29, 1.0254685909108741e-27, 1.7211387969394399e-26, 2.6657834170950206e-25, 3.8158515821307025e-24, 5.0550170089602786e-23, 6.2057205211001172e-22, 7.0687611828654942e-21, 7.4798012691484967e-20, 7.3607060012414608e-19, 6.7436191474716113e-18, 5.7576889770247240e-17, 4.5856377569387674e-16, 3.4098950541891060e-15, 2.3694365058853221e-14, 1.5398051925046748e-13, 9.3656673457701801e-13, 5.3355866239683074e-12, 2.8490354792258560e-11, 1.4268284555926340e-10, 6.7061742381683788e-10, 2.9598086074993327e-09, 1.2273853303242205e-08, 4.7847173987299635e-08, 1.7543109823449902e-07, 6.0525229343483686e-07, 1.9657973702696829e-06, 6.0130527402628209e-06, 1.7329090398329860e-05, 4.7069644542722322e-05, 1.2054246571768105e-04, 2.9114733811626920e-04, 6.6342074803749660e-04, 1.4265570512383724e-03, 2.8955046143597550e-03, 5.5487673845870103e-03, 1.0041513921437970e-02, 1.7163936516514416e-02, 2.7715692333499325e-02, 4.2285689519455438e-02, 6.0964838880386028e-02, 8.3068258519182064e-02, 1.0698027879398084e-01, 1.3023286590097533e-01, 1.4986945253577164e-01, 1.6304250159157527e-01, 1.6768547028079969e-01, 1.6304250159157527e-01, 1.4986945253577164e-01, 1.3023286590097533e-01, 1.0698027879398084e-01, 8.3068258519182064e-02, 6.0964838880386028e-02, 4.2285689519455438e-02, 2.7715692333499325e-02, 1.7163936516514416e-02, 1.0041513921437970e-02, 5.5487673845870103e-03, 2.8955046143597550e-03, 1.4265570512383724e-03, 6.6342074803749660e-04, 2.9114733811626920e-04, 1.2054246571768105e-04, 4.7069644542722322e-05, 1.7329090398329860e-05, 6.0130527402628209e-06, 1.9657973702696829e-06, 6.0525229343483686e-07, 1.7543109823449902e-07, 4.7847173987299635e-08, 1.2273853303242205e-08, 2.9598086074993327e-09, 6.7061742381683788e-10, 1.4268284555926340e-10, 2.8490354792258560e-11, 5.3355866239683074e-12, 9.3656673457701801e-13, 1.5398051925046748e-13, 2.3694365058853221e-14, 3.4098950541891060e-15, 4.5856377569387674e-16, 5.7576889770247240e-17, 6.7436191474716113e-18, 7.3607060012414608e-19, 7.4798012691484967e-20, 7.0687611828654942e-21, 6.2057205211001172e-22, 5.0550170089602786e-23, 3.8158515821307025e-24, 2.6657834170950206e-25, 1.7211387969394399e-26, 1.0254685909108741e-27, 5.6294266388452469e-29, 2.8426307813064235e-30, 1.3180336788235122e-31, 5.6010600122601367e-33, 2.1771495752866995e-34, 7.7243461606513683e-36, 2.4958088668373114e-37, 7.3264228854645894e-39, 1.9488875555428468e-40, 4.6848975802870826e-42, 1.0147285474798106e-43, 1.9740530949677369e-45, 3.4375135972727117e-47, 5.3383547450946618e-49, 7.3640839458387673e-51, 8.9847110119503318e-53, 9.6499842697585386e-55, 9.0774918435864705e-57, 7.4369351842678165e-59, 5.2740829263623727e-61, 3.2158114928338939e-63, 1.6733234438392451e-65, 7.3690229255476969e-68, 2.7211703761612434e-70, 8.3387106103658512e-73, 2.0957319191157142e-75, 4.2624770595798820e-78, 6.9091769993084969e-81, 8.7687858501113383e-84, 8.5354199357192903e-87, 6.2184654173606399e-90, 3.2933121419749483e-93, 1.2236703652880107e-96, 3.0528486739600850e-100, 4.8374430266711206e-104, 4.5288568274049433e-108, 2.2724999081578913e-112, 5.3267445942905176e-117, 4.7443699591186030e-122, 1.1427720218874746e-127, 3.8870007298929211e-134, 3.5411506471568517e-142}, + {5.0351722883464185e-143, 5.7450587562745078e-135, 1.7446064596498268e-128, 7.4571213334341600e-123, 8.6023715273839571e-118, 3.7652628313310755e-113, 7.6903016009308287e-109, 8.4113401468636500e-105, 5.4319085709594968e-101, 2.2267204629384821e-97, 6.1261103396048387e-94, 1.1819905626126024e-90, 1.6572504238354695e-87, 1.7386395392283553e-84, 1.3986045504550338e-81, 8.8071523423621673e-79, 4.4190897787947332e-76, 1.7941108043227645e-73, 5.9730812278268291e-71, 1.6500317832456593e-68, 3.8217018216862523e-66, 7.4907171097897077e-64, 1.2528614722567282e-61, 1.8015494058808057e-59, 2.2422904341536794e-57, 2.4305731255545130e-55, 2.3074311289682700e-53, 1.9283073358698602e-51, 1.4252524566058730e-49, 9.3573522665893741e-48, 5.4788838446141128e-46, 2.8715169045497604e-44, 1.3517494625509147e-42, 5.7335891630321996e-41, 2.1977946695381225e-39, 7.6344180491439718e-38, 2.4094190488253342e-36, 6.9253812367067252e-35, 1.8169855856152196e-33, 4.3607057687085942e-32, 9.5923503135464682e-31, 1.9376278309334056e-29, 3.6004726047782310e-28, 6.1647472746508888e-27, 9.7413623207618448e-26, 1.4227116244089339e-24, 1.9231607886931175e-23, 2.4093040723082529e-22, 2.8008499497491982e-21, 3.0250061661788475e-20, 3.0387132211276073e-19, 2.8421271873321773e-18, 2.4775756264214477e-17, 2.0149141590187015e-16, 1.5301273364381654e-15, 1.0859626897815736e-14, 7.2089869379341516e-14, 4.4796392616415365e-13, 2.6076028723419556e-12, 1.4228958097317545e-11, 7.2832614256562299e-11, 3.4992319867238825e-10, 1.5789636824184370e-09, 6.6952823181138107e-09, 2.6692828097969734e-08, 1.0010785492509061e-07, 3.5334287745169781e-07, 1.1742867585331092e-06, 3.6760831094679487e-06, 1.0844326360928105e-05, 3.0156999060878010e-05, 7.9084957328144794e-05, 1.9564188997236542e-04, 4.5669297388226392e-04, 1.0062461311647175e-03, 2.0932217887326024e-03, 4.1120856339170011e-03, 7.6302877130003874e-03, 1.3376390072548504e-02, 2.2158233552618596e-02, 3.4689673239772116e-02, 5.1332999819585050e-02, 7.1809001831171768e-02, 9.4971530833224349e-02, 1.1876238489882553e-01, 1.4043201287954626e-01, 1.5702837449220031e-01, 1.6604672219204664e-01, 1.6604672219204664e-01, 1.5702837449220031e-01, 1.4043201287954626e-01, 1.1876238489882553e-01, 9.4971530833224349e-02, 7.1809001831171768e-02, 5.1332999819585050e-02, 3.4689673239772116e-02, 2.2158233552618596e-02, 1.3376390072548504e-02, 7.6302877130003874e-03, 4.1120856339170011e-03, 2.0932217887326024e-03, 1.0062461311647175e-03, 4.5669297388226392e-04, 1.9564188997236542e-04, 7.9084957328144794e-05, 3.0156999060878010e-05, 1.0844326360928105e-05, 3.6760831094679487e-06, 1.1742867585331092e-06, 3.5334287745169781e-07, 1.0010785492509061e-07, 2.6692828097969734e-08, 6.6952823181138107e-09, 1.5789636824184370e-09, 3.4992319867238825e-10, 7.2832614256562299e-11, 1.4228958097317545e-11, 2.6076028723419556e-12, 4.4796392616415365e-13, 7.2089869379341516e-14, 1.0859626897815736e-14, 1.5301273364381654e-15, 2.0149141590187015e-16, 2.4775756264214477e-17, 2.8421271873321773e-18, 3.0387132211276073e-19, 3.0250061661788475e-20, 2.8008499497491982e-21, 2.4093040723082529e-22, 1.9231607886931175e-23, 1.4227116244089339e-24, 9.7413623207618448e-26, 6.1647472746508888e-27, 3.6004726047782310e-28, 1.9376278309334056e-29, 9.5923503135464682e-31, 4.3607057687085942e-32, 1.8169855856152196e-33, 6.9253812367067252e-35, 2.4094190488253342e-36, 7.6344180491439718e-38, 2.1977946695381225e-39, 5.7335891630321996e-41, 1.3517494625509147e-42, 2.8715169045497604e-44, 5.4788838446141128e-46, 9.3573522665893741e-48, 1.4252524566058730e-49, 1.9283073358698602e-51, 2.3074311289682700e-53, 2.4305731255545130e-55, 2.2422904341536794e-57, 1.8015494058808057e-59, 1.2528614722567282e-61, 7.4907171097897077e-64, 3.8217018216862523e-66, 1.6500317832456593e-68, 5.9730812278268291e-71, 1.7941108043227645e-73, 4.4190897787947332e-76, 8.8071523423621673e-79, 1.3986045504550338e-81, 1.7386395392283553e-84, 1.6572504238354695e-87, 1.1819905626126024e-90, 6.1261103396048387e-94, 2.2267204629384821e-97, 5.4319085709594968e-101, 8.4113401468636500e-105, 7.6903016009308287e-109, 3.7652628313310755e-113, 8.6023715273839571e-118, 7.4571213334341600e-123, 1.7446064596498268e-128, 5.7450587562745078e-135, 5.0351722883464185e-143}, + {7.1581854941568756e-144, 8.4884228757564859e-136, 2.6621446843016668e-129, 1.1714088250630149e-123, 1.3882583385637704e-118, 6.2335512554508696e-114, 1.3046719672955675e-109, 1.4610767163662094e-105, 9.6541517663049285e-102, 4.0470443036783296e-98, 1.1380585129708444e-94, 2.2435189643567695e-91, 3.2128730776926215e-88, 3.4417484237908715e-85, 2.8263134922810747e-82, 1.8164480123517544e-79, 9.3003877258546557e-77, 3.8523675927861067e-74, 1.3083561453477787e-71, 3.6865159997894300e-69, 8.7082600252251548e-67, 1.7406436581415539e-64, 2.9687147399709626e-62, 4.3527424404558593e-60, 5.5237929617045550e-58, 6.1047069753060061e-56, 5.9085581038387938e-54, 5.0340269517910206e-52, 3.7932466358096469e-50, 2.5389205160417814e-48, 1.5155318342592620e-46, 8.0977464419800098e-45, 3.8862848936787104e-43, 1.6805797332715199e-41, 6.5678744364293848e-40, 2.3261212178440308e-38, 7.4851978878895327e-37, 2.1937508830604144e-35, 5.8690540840121578e-34, 1.4363784560339465e-32, 3.2222344142269078e-31, 6.6381799678904965e-30, 1.2580944858403407e-28, 2.1972252658847511e-27, 3.5417421260548565e-26, 5.2769903994937601e-25, 7.2776858868650826e-24, 9.3028399771791796e-23, 1.1035696761428192e-21, 1.2163644574829813e-20, 1.2470907989461904e-19, 1.1906056130964038e-18, 1.0595326417660698e-17, 8.7974278780040251e-17, 6.8216435985574468e-16, 4.9441425800883030e-15, 3.3521165632319237e-14, 2.1277112806959519e-13, 1.2653006101080342e-12, 7.0545233223348931e-12, 3.6899828977436854e-11, 1.8119180456089166e-10, 8.3573910554417999e-10, 3.6229939665804831e-09, 1.4769397910223943e-08, 5.6647039057714555e-08, 2.0451241808924649e-07, 6.9532414269249713e-07, 2.2272343809174102e-06, 6.7240427138149140e-06, 1.9140150173987354e-05, 5.1388360015799239e-05, 1.3017662891537081e-04, 3.1123241184750341e-04, 7.0249863037702334e-04, 1.4973772242764213e-03, 3.0147364453737358e-03, 5.7345384962421463e-03, 1.0307863786080675e-02, 1.7512238829626020e-02, 2.8124900042797892e-02, 4.2705327076181680e-02, 6.1315790894116422e-02, 8.3255213529058528e-02, 1.0691562889960281e-01, 1.2986607877253428e-01, 1.4921123248756085e-01, 1.6217258820124303e-01, 1.6673809474249007e-01, 1.6217258820124303e-01, 1.4921123248756085e-01, 1.2986607877253428e-01, 1.0691562889960281e-01, 8.3255213529058528e-02, 6.1315790894116422e-02, 4.2705327076181680e-02, 2.8124900042797892e-02, 1.7512238829626020e-02, 1.0307863786080675e-02, 5.7345384962421463e-03, 3.0147364453737358e-03, 1.4973772242764213e-03, 7.0249863037702334e-04, 3.1123241184750341e-04, 1.3017662891537081e-04, 5.1388360015799239e-05, 1.9140150173987354e-05, 6.7240427138149140e-06, 2.2272343809174102e-06, 6.9532414269249713e-07, 2.0451241808924649e-07, 5.6647039057714555e-08, 1.4769397910223943e-08, 3.6229939665804831e-09, 8.3573910554417999e-10, 1.8119180456089166e-10, 3.6899828977436854e-11, 7.0545233223348931e-12, 1.2653006101080342e-12, 2.1277112806959519e-13, 3.3521165632319237e-14, 4.9441425800883030e-15, 6.8216435985574468e-16, 8.7974278780040251e-17, 1.0595326417660698e-17, 1.1906056130964038e-18, 1.2470907989461904e-19, 1.2163644574829813e-20, 1.1035696761428192e-21, 9.3028399771791796e-23, 7.2776858868650826e-24, 5.2769903994937601e-25, 3.5417421260548565e-26, 2.1972252658847511e-27, 1.2580944858403407e-28, 6.6381799678904965e-30, 3.2222344142269078e-31, 1.4363784560339465e-32, 5.8690540840121578e-34, 2.1937508830604144e-35, 7.4851978878895327e-37, 2.3261212178440308e-38, 6.5678744364293848e-40, 1.6805797332715199e-41, 3.8862848936787104e-43, 8.0977464419800098e-45, 1.5155318342592620e-46, 2.5389205160417814e-48, 3.7932466358096469e-50, 5.0340269517910206e-52, 5.9085581038387938e-54, 6.1047069753060061e-56, 5.5237929617045550e-58, 4.3527424404558593e-60, 2.9687147399709626e-62, 1.7406436581415539e-64, 8.7082600252251548e-67, 3.6865159997894300e-69, 1.3083561453477787e-71, 3.8523675927861067e-74, 9.3003877258546557e-77, 1.8164480123517544e-79, 2.8263134922810747e-82, 3.4417484237908715e-85, 3.2128730776926215e-88, 2.2435189643567695e-91, 1.1380585129708444e-94, 4.0470443036783296e-98, 9.6541517663049285e-102, 1.4610767163662094e-105, 1.3046719672955675e-109, 6.2335512554508696e-114, 1.3882583385637704e-118, 1.1714088250630149e-123, 2.6621446843016668e-129, 8.4884228757564859e-136, 7.1581854941568756e-144}, + {1.0174451907169722e-144, 1.2537577338109092e-136, 4.0603558490313254e-130, 1.8390471781108747e-124, 2.2388300710588648e-119, 1.0311647067706544e-114, 2.2113953581884588e-110, 2.5353839157043305e-106, 1.7139381704010506e-102, 7.3466025769339733e-99, 2.1114364896149106e-95, 4.2524253414775605e-92, 6.2193919080044227e-89, 6.8022938891305936e-86, 5.7017766571657716e-83, 3.7396644213938176e-80, 1.9536604993085239e-77, 8.2555014673420022e-75, 2.8598818663126844e-72, 8.2184808615623598e-70, 1.9797683901166225e-67, 4.0351646934878695e-65, 7.0170567960964978e-63, 1.0489546649192595e-60, 1.3571109461554121e-58, 1.5290034639304410e-56, 1.5086081632928153e-54, 1.3102411068553504e-52, 1.0064229300129089e-50, 6.8667092650473948e-49, 4.1782480984927090e-47, 2.2757544084791531e-45, 1.1133537204234619e-43, 4.9079810854674800e-42, 1.9553490062333371e-40, 7.0599294307578851e-39, 2.3160882385061203e-37, 6.9205465629360576e-36, 1.8877397396823247e-34, 4.7107012996283542e-33, 1.0775571184918142e-31, 2.2637292363656048e-30, 4.3753093336081546e-29, 7.7932715085212503e-28, 1.2812781788064907e-26, 1.9472758171895140e-25, 2.7395824646129918e-24, 3.5726754325441841e-23, 4.3241778048815671e-22, 4.8633316486835449e-21, 5.0883502730989637e-20, 4.9579227287808755e-19, 4.5034462009468205e-18, 3.8170938055666007e-17, 3.0217745531718828e-16, 2.2362025898948135e-15, 1.5482439389379285e-14, 1.0036629079256339e-13, 6.0964973515510935e-13, 3.4723560883860410e-12, 1.8557142556642682e-11, 9.3114559517381624e-11, 4.3894092072618305e-10, 1.9450249932898343e-09, 8.1060721426662619e-09, 3.1789582778002615e-08, 1.1737053608502818e-07, 4.0816183881635333e-07, 1.3374965511498204e-06, 4.1315876560548306e-06, 1.2035714382322826e-05, 3.3076061707490808e-05, 8.5780643722862892e-05, 2.1000778733594350e-04, 4.8548944122296688e-04, 1.0600860254999084e-03, 2.1869011800911028e-03, 4.2632921737953853e-03, 7.8556410099729287e-03, 1.3684318450535705e-02, 2.2539589851423701e-02, 3.5108996740976929e-02, 5.1725036108245200e-02, 7.2085145846744095e-02, 9.5038220322125194e-02, 1.1854839415593066e-01, 1.3991610657942335e-01, 1.5625599948674623e-01, 1.6512677086080088e-01, 1.6512677086080088e-01, 1.5625599948674623e-01, 1.3991610657942335e-01, 1.1854839415593066e-01, 9.5038220322125194e-02, 7.2085145846744095e-02, 5.1725036108245200e-02, 3.5108996740976929e-02, 2.2539589851423701e-02, 1.3684318450535705e-02, 7.8556410099729287e-03, 4.2632921737953853e-03, 2.1869011800911028e-03, 1.0600860254999084e-03, 4.8548944122296688e-04, 2.1000778733594350e-04, 8.5780643722862892e-05, 3.3076061707490808e-05, 1.2035714382322826e-05, 4.1315876560548306e-06, 1.3374965511498204e-06, 4.0816183881635333e-07, 1.1737053608502818e-07, 3.1789582778002615e-08, 8.1060721426662619e-09, 1.9450249932898343e-09, 4.3894092072618305e-10, 9.3114559517381624e-11, 1.8557142556642682e-11, 3.4723560883860410e-12, 6.0964973515510935e-13, 1.0036629079256339e-13, 1.5482439389379285e-14, 2.2362025898948135e-15, 3.0217745531718828e-16, 3.8170938055666007e-17, 4.5034462009468205e-18, 4.9579227287808755e-19, 5.0883502730989637e-20, 4.8633316486835449e-21, 4.3241778048815671e-22, 3.5726754325441841e-23, 2.7395824646129918e-24, 1.9472758171895140e-25, 1.2812781788064907e-26, 7.7932715085212503e-28, 4.3753093336081546e-29, 2.2637292363656048e-30, 1.0775571184918142e-31, 4.7107012996283542e-33, 1.8877397396823247e-34, 6.9205465629360576e-36, 2.3160882385061203e-37, 7.0599294307578851e-39, 1.9553490062333371e-40, 4.9079810854674800e-42, 1.1133537204234619e-43, 2.2757544084791531e-45, 4.1782480984927090e-47, 6.8667092650473948e-49, 1.0064229300129089e-50, 1.3102411068553504e-52, 1.5086081632928153e-54, 1.5290034639304410e-56, 1.3571109461554121e-58, 1.0489546649192595e-60, 7.0170567960964978e-63, 4.0351646934878695e-65, 1.9797683901166225e-67, 8.2184808615623598e-70, 2.8598818663126844e-72, 8.2555014673420022e-75, 1.9536604993085239e-77, 3.7396644213938176e-80, 5.7017766571657716e-83, 6.8022938891305936e-86, 6.2193919080044227e-89, 4.2524253414775605e-92, 2.1114364896149106e-95, 7.3466025769339733e-99, 1.7139381704010506e-102, 2.5353839157043305e-106, 2.2113953581884588e-110, 1.0311647067706544e-114, 2.2388300710588648e-119, 1.8390471781108747e-124, 4.0603558490313254e-130, 1.2537577338109092e-136, 1.0174451907169722e-144}, + {1.4459034710264201e-145, 1.8512101069007797e-137, 6.1900866973604703e-131, 2.8855379169821182e-125, 3.6080591054052492e-120, 1.7044183943684018e-115, 3.7449189704395232e-111, 4.3952304904350605e-107, 3.0394872358078098e-103, 1.3320382883615053e-99, 3.9122879439382170e-96, 8.0489834136101609e-93, 1.2021477111483726e-89, 1.3422872316499288e-86, 1.1483443011896613e-83, 7.6855073087396857e-81, 4.0962408560880496e-78, 1.7656535944547459e-75, 6.2384154226153306e-73, 1.8282206685181686e-70, 4.4907236877039048e-68, 9.3322988518723512e-66, 1.6545283606525458e-63, 2.5213872637605977e-61, 3.3253581541518404e-59, 3.8190282366232640e-57, 3.8408503131563961e-55, 3.4001469878023392e-53, 2.6620432033111890e-51, 1.8512591668862315e-49, 1.1481424339931328e-47, 6.3739969672637270e-46, 3.1784051437766470e-44, 1.4281570152975713e-42, 5.7996825799748193e-41, 2.1345161706875471e-39, 7.1381873166360108e-38, 2.1743217660681791e-36, 6.0463752750772134e-35, 1.5382579845230378e-33, 3.5875473238148687e-32, 7.6845885182041777e-31, 1.5145049680016594e-29, 2.7509103704580098e-28, 4.6123845343733745e-27, 7.1493666161606643e-26, 1.0259279798609206e-24, 1.3647547675188007e-23, 1.6851209810753113e-22, 1.9336042594232875e-21, 2.0642309881609900e-20, 2.0524462477993889e-19, 1.9026226109394554e-18, 1.6459732365754106e-17, 1.3300948716108394e-16, 1.0048759007103044e-15, 7.1035141604691271e-15, 4.7022739273699201e-14, 2.9170375040074331e-13, 1.6970108678299655e-12, 9.2646537879215591e-12, 4.7495690973542646e-11, 2.2878306073735174e-10, 1.0360690148079607e-09, 4.4135301064719171e-09, 1.7694607842914065e-08, 6.6798391472451806e-08, 2.3755404518235753e-07, 7.9619631902655087e-07, 2.5160446644029356e-06, 7.4993851915062359e-06, 2.1091170590509833e-05, 5.5987643740857493e-05, 1.4032641744066531e-04, 3.3217919994016825e-04, 7.4286891131823533e-04, 1.5698960784933606e-03, 3.1358280493826080e-03, 5.9217687653631513e-03, 1.0574395576910816e-02, 1.7858440641500769e-02, 2.8528992504062382e-02, 4.3116896847977884e-02, 6.1656983184778281e-02, 8.3433163844430863e-02, 1.0684575215294285e-01, 1.2950034028006346e-01, 1.4856115387707583e-01, 1.6131642239308974e-01, 1.6580659700649841e-01, 1.6131642239308974e-01, 1.4856115387707583e-01, 1.2950034028006346e-01, 1.0684575215294285e-01, 8.3433163844430863e-02, 6.1656983184778281e-02, 4.3116896847977884e-02, 2.8528992504062382e-02, 1.7858440641500769e-02, 1.0574395576910816e-02, 5.9217687653631513e-03, 3.1358280493826080e-03, 1.5698960784933606e-03, 7.4286891131823533e-04, 3.3217919994016825e-04, 1.4032641744066531e-04, 5.5987643740857493e-05, 2.1091170590509833e-05, 7.4993851915062359e-06, 2.5160446644029356e-06, 7.9619631902655087e-07, 2.3755404518235753e-07, 6.6798391472451806e-08, 1.7694607842914065e-08, 4.4135301064719171e-09, 1.0360690148079607e-09, 2.2878306073735174e-10, 4.7495690973542646e-11, 9.2646537879215591e-12, 1.6970108678299655e-12, 2.9170375040074331e-13, 4.7022739273699201e-14, 7.1035141604691271e-15, 1.0048759007103044e-15, 1.3300948716108394e-16, 1.6459732365754106e-17, 1.9026226109394554e-18, 2.0524462477993889e-19, 2.0642309881609900e-20, 1.9336042594232875e-21, 1.6851209810753113e-22, 1.3647547675188007e-23, 1.0259279798609206e-24, 7.1493666161606643e-26, 4.6123845343733745e-27, 2.7509103704580098e-28, 1.5145049680016594e-29, 7.6845885182041777e-31, 3.5875473238148687e-32, 1.5382579845230378e-33, 6.0463752750772134e-35, 2.1743217660681791e-36, 7.1381873166360108e-38, 2.1345161706875471e-39, 5.7996825799748193e-41, 1.4281570152975713e-42, 3.1784051437766470e-44, 6.3739969672637270e-46, 1.1481424339931328e-47, 1.8512591668862315e-49, 2.6620432033111890e-51, 3.4001469878023392e-53, 3.8408503131563961e-55, 3.8190282366232640e-57, 3.3253581541518404e-59, 2.5213872637605977e-61, 1.6545283606525458e-63, 9.3322988518723512e-66, 4.4907236877039048e-68, 1.8282206685181686e-70, 6.2384154226153306e-73, 1.7656535944547459e-75, 4.0962408560880496e-78, 7.6855073087396857e-81, 1.1483443011896613e-83, 1.3422872316499288e-86, 1.2021477111483726e-89, 8.0489834136101609e-93, 3.9122879439382170e-96, 1.3320382883615053e-99, 3.0394872358078098e-103, 4.3952304904350605e-107, 3.7449189704395232e-111, 1.7044183943684018e-115, 3.6080591054052492e-120, 2.8855379169821182e-125, 6.1900866973604703e-131, 1.8512101069007797e-137, 1.4459034710264201e-145}, + {2.0544167081187589e-146, 2.7324651628287789e-138, 9.4326009424734410e-132, 4.5249380509459828e-126, 5.8107301413051742e-121, 2.8150324044562284e-116, 6.3362635154258981e-112, 7.6118645291179184e-108, 5.3843632439536920e-104, 2.4123127079122074e-100, 7.2398333677694101e-97, 1.5214189335297059e-93, 2.3202235060376314e-90, 2.6445775673882037e-87, 2.3089447193822174e-84, 1.5767056174162126e-81, 8.5727195865402764e-79, 3.7689704357176965e-76, 1.3580443028284028e-73, 4.0582349306406949e-71, 1.0163600799789738e-68, 2.1532917098122703e-66, 3.8916837271887350e-64, 6.0453772000204261e-62, 8.1267907500285513e-60, 9.5128584361969727e-58, 9.7509710005032432e-56, 8.7976987433650472e-54, 7.0198773756157181e-52, 4.9753094376640113e-50, 3.1447462107627518e-48, 1.7792627000157171e-46, 9.0423237558527988e-45, 4.1409133307449204e-43, 1.7138906209368488e-41, 6.4290783512879458e-40, 2.1913996777475932e-38, 6.8039020082108794e-37, 1.9286270378988431e-35, 5.0017461082503641e-34, 1.1891915619808499e-32, 2.5969337466904165e-31, 5.2182308893507914e-30, 9.6642798753295627e-29, 1.6523003694364310e-27, 2.6117599911695471e-26, 3.8222432521976105e-25, 5.1859356642906214e-24, 6.5314813585357555e-23, 7.6453095155047312e-22, 8.3267040963735343e-21, 8.4472663315088944e-20, 7.9904365646153140e-19, 7.0543936381041909e-18, 5.8181634606657441e-17, 4.4867423723460479e-16, 3.2378602233952898e-15, 2.1883227889949076e-14, 1.3861757281246388e-13, 8.2354944810071531e-13, 4.5921996541535561e-12, 2.4048711144413950e-11, 1.1835015186215515e-10, 5.4765134657351679e-10, 2.3841694011026308e-09, 9.7699965359482599e-09, 3.7704288545104245e-08, 1.3709740387891837e-07, 4.6989603841203290e-07, 1.5187614573110066e-06, 4.6308779212753262e-06, 1.3325507543076759e-05, 3.6199433343496547e-05, 9.2866446344988979e-05, 2.2505423008074610e-04, 5.1535932107027135e-04, 1.1154298676886345e-03, 2.2823888738018917e-03, 4.4162127170279562e-03, 8.0818888889421375e-03, 1.3991358954534535e-02, 2.2917370391076095e-02, 3.5521683059969993e-02, 5.2108016747135361e-02, 7.2351691768296089e-02, 9.5097571709914869e-02, 1.1833217723448959e-01, 1.3940481744965749e-01, 1.5549476479437641e-01, 1.6422194087055850e-01, 1.6422194087055850e-01, 1.5549476479437641e-01, 1.3940481744965749e-01, 1.1833217723448959e-01, 9.5097571709914869e-02, 7.2351691768296089e-02, 5.2108016747135361e-02, 3.5521683059969993e-02, 2.2917370391076095e-02, 1.3991358954534535e-02, 8.0818888889421375e-03, 4.4162127170279562e-03, 2.2823888738018917e-03, 1.1154298676886345e-03, 5.1535932107027135e-04, 2.2505423008074610e-04, 9.2866446344988979e-05, 3.6199433343496547e-05, 1.3325507543076759e-05, 4.6308779212753262e-06, 1.5187614573110066e-06, 4.6989603841203290e-07, 1.3709740387891837e-07, 3.7704288545104245e-08, 9.7699965359482599e-09, 2.3841694011026308e-09, 5.4765134657351679e-10, 1.1835015186215515e-10, 2.4048711144413950e-11, 4.5921996541535561e-12, 8.2354944810071531e-13, 1.3861757281246388e-13, 2.1883227889949076e-14, 3.2378602233952898e-15, 4.4867423723460479e-16, 5.8181634606657441e-17, 7.0543936381041909e-18, 7.9904365646153140e-19, 8.4472663315088944e-20, 8.3267040963735343e-21, 7.6453095155047312e-22, 6.5314813585357555e-23, 5.1859356642906214e-24, 3.8222432521976105e-25, 2.6117599911695471e-26, 1.6523003694364310e-27, 9.6642798753295627e-29, 5.2182308893507914e-30, 2.5969337466904165e-31, 1.1891915619808499e-32, 5.0017461082503641e-34, 1.9286270378988431e-35, 6.8039020082108794e-37, 2.1913996777475932e-38, 6.4290783512879458e-40, 1.7138906209368488e-41, 4.1409133307449204e-43, 9.0423237558527988e-45, 1.7792627000157171e-46, 3.1447462107627518e-48, 4.9753094376640113e-50, 7.0198773756157181e-52, 8.7976987433650472e-54, 9.7509710005032432e-56, 9.5128584361969727e-58, 8.1267907500285513e-60, 6.0453772000204261e-62, 3.8916837271887350e-64, 2.1532917098122703e-66, 1.0163600799789738e-68, 4.0582349306406949e-71, 1.3580443028284028e-73, 3.7689704357176965e-76, 8.5727195865402764e-79, 1.5767056174162126e-81, 2.3089447193822174e-84, 2.6445775673882037e-87, 2.3202235060376314e-90, 1.5214189335297059e-93, 7.2398333677694101e-97, 2.4123127079122074e-100, 5.3843632439536920e-104, 7.6118645291179184e-108, 6.3362635154258981e-112, 2.8150324044562284e-116, 5.8107301413051742e-121, 4.5249380509459828e-126, 9.4326009424734410e-132, 2.7324651628287789e-138, 2.0544167081187589e-146}, + {2.9184983704075192e-147, 4.0319183713400766e-139, 1.4367134541050939e-132, 7.0917398018507910e-127, 9.3517988737392972e-122, 4.6457185244440549e-117, 1.0711309190325783e-112, 1.3169706905085093e-108, 9.5280026251390744e-105, 4.3635736981957750e-101, 1.3380638102406329e-97, 2.8718782241763001e-94, 4.4716757994553476e-91, 5.2022930902389893e-88, 4.6349150479031114e-85, 3.2290491038758581e-82, 1.7908398704126536e-79, 8.0297842302329272e-77, 2.9503683873426791e-74, 8.9893224354049310e-72, 2.2951885774902920e-69, 4.9569512961693677e-67, 9.1317952402850698e-65, 1.4458391823512865e-62, 1.9809319471106229e-60, 2.3631742826980710e-58, 2.4686029155016893e-56, 2.2697566491840546e-54, 1.8456028929462080e-52, 1.3329759770755586e-50, 8.5857720828783205e-49, 4.9502403838758848e-47, 2.5636716593985549e-45, 1.1964123882499316e-43, 5.0463692733981642e-42, 1.9291541526211061e-40, 6.7015535541500665e-39, 2.1206217889043141e-37, 6.1266403471398839e-36, 1.6195131761876436e-34, 3.9248683542722297e-33, 8.7371187009076405e-32, 1.7897414312928308e-30, 3.3792749075968173e-29, 5.8905961617051956e-28, 9.4940326558644130e-27, 1.4168234014649860e-25, 1.9603740051045881e-24, 2.5181065241794600e-23, 3.0063944491537587e-22, 3.3400431583218902e-21, 3.4567219838648987e-20, 3.3360382939472660e-19, 3.0052255828362505e-18, 2.5293356487116101e-17, 1.9906862214252033e-16, 1.4663260946610058e-15, 1.0116632951507467e-14, 6.5425658781468336e-14, 3.9689851927958321e-13, 2.2600968959480387e-12, 1.2088512678946103e-11, 6.0769364101383090e-11, 2.8728746426712136e-10, 1.2779384152123448e-09, 5.3517155996766336e-09, 2.1109723472766886e-08, 7.8466356162788103e-08, 2.7497279026009702e-07, 9.0883362098124687e-07, 2.8342636150206807e-06, 8.3429573893995674e-06, 2.3188718962635865e-05, 6.0877111145275987e-05, 1.5100325433613592e-04, 3.5399662151566394e-04, 7.8452960713547043e-04, 1.6440892137594167e-03, 3.2587225571780792e-03, 6.1103686178933300e-03, 1.0841005727093818e-02, 1.8202465449941120e-02, 2.8927974168057351e-02, 4.3520526497899684e-02, 6.1988666273243780e-02, 8.3602420563279559e-02, 1.0677090675896843e-01, 1.2913573606742534e-01, 1.4791906474448899e-01, 1.6047364667465450e-01, 1.6489053845950130e-01, 1.6047364667465450e-01, 1.4791906474448899e-01, 1.2913573606742534e-01, 1.0677090675896843e-01, 8.3602420563279559e-02, 6.1988666273243780e-02, 4.3520526497899684e-02, 2.8927974168057351e-02, 1.8202465449941120e-02, 1.0841005727093818e-02, 6.1103686178933300e-03, 3.2587225571780792e-03, 1.6440892137594167e-03, 7.8452960713547043e-04, 3.5399662151566394e-04, 1.5100325433613592e-04, 6.0877111145275987e-05, 2.3188718962635865e-05, 8.3429573893995674e-06, 2.8342636150206807e-06, 9.0883362098124687e-07, 2.7497279026009702e-07, 7.8466356162788103e-08, 2.1109723472766886e-08, 5.3517155996766336e-09, 1.2779384152123448e-09, 2.8728746426712136e-10, 6.0769364101383090e-11, 1.2088512678946103e-11, 2.2600968959480387e-12, 3.9689851927958321e-13, 6.5425658781468336e-14, 1.0116632951507467e-14, 1.4663260946610058e-15, 1.9906862214252033e-16, 2.5293356487116101e-17, 3.0052255828362505e-18, 3.3360382939472660e-19, 3.4567219838648987e-20, 3.3400431583218902e-21, 3.0063944491537587e-22, 2.5181065241794600e-23, 1.9603740051045881e-24, 1.4168234014649860e-25, 9.4940326558644130e-27, 5.8905961617051956e-28, 3.3792749075968173e-29, 1.7897414312928308e-30, 8.7371187009076405e-32, 3.9248683542722297e-33, 1.6195131761876436e-34, 6.1266403471398839e-36, 2.1206217889043141e-37, 6.7015535541500665e-39, 1.9291541526211061e-40, 5.0463692733981642e-42, 1.1964123882499316e-43, 2.5636716593985549e-45, 4.9502403838758848e-47, 8.5857720828783205e-49, 1.3329759770755586e-50, 1.8456028929462080e-52, 2.2697566491840546e-54, 2.4686029155016893e-56, 2.3631742826980710e-58, 1.9809319471106229e-60, 1.4458391823512865e-62, 9.1317952402850698e-65, 4.9569512961693677e-67, 2.2951885774902920e-69, 8.9893224354049310e-72, 2.9503683873426791e-74, 8.0297842302329272e-77, 1.7908398704126536e-79, 3.2290491038758581e-82, 4.6349150479031114e-85, 5.2022930902389893e-88, 4.4716757994553476e-91, 2.8718782241763001e-94, 1.3380638102406329e-97, 4.3635736981957750e-101, 9.5280026251390744e-105, 1.3169706905085093e-108, 1.0711309190325783e-112, 4.6457185244440549e-117, 9.3517988737392972e-122, 7.0917398018507910e-127, 1.4367134541050939e-132, 4.0319183713400766e-139, 2.9184983704075192e-147}, + {4.1452696623483395e-148, 5.9474161464872244e-140, 2.1873318060197500e-133, 1.1108350634945189e-127, 1.5040760324474137e-122, 7.6610437292542439e-118, 1.8091479691129481e-113, 2.2763600768872421e-109, 1.6842534274181958e-105, 7.8840222434465455e-102, 2.4699093339298307e-98, 5.4137540405290719e-95, 8.6056883186768174e-92, 1.0218043358339510e-88, 9.2888951681828944e-86, 6.6016471696136248e-83, 3.7342898142071596e-80, 1.7074874775824880e-77, 6.3969105456232966e-75, 1.9870439601235429e-72, 5.1717638304628555e-70, 1.1385038568984282e-67, 2.1376722221415430e-65, 3.4493784123174178e-63, 4.8161711078239858e-61, 5.8549015274027961e-59, 6.2323324068554731e-57, 5.8390470979220446e-55, 4.8378847700931107e-53, 3.5603170842517748e-51, 2.3366431061277383e-49, 1.3727341637645679e-47, 7.2439067732577147e-46, 3.4446682433867826e-44, 1.4805046972403839e-42, 5.7672996866961233e-41, 2.0415908964489771e-39, 6.5835338360421613e-38, 1.9383756218147382e-36, 5.2220236908204409e-35, 1.2898503021552704e-33, 2.9266129491084507e-32, 6.1107571504811921e-31, 1.1761496941464036e-29, 2.0900714057742614e-28, 3.4343583117038137e-27, 5.2255927032642325e-26, 7.3725440555518383e-25, 9.6570947115181529e-24, 1.1758429681040065e-22, 1.3323707929307384e-21, 1.4065250811244644e-20, 1.3847330443129062e-19, 1.2726463913998945e-18, 1.0928940877684042e-17, 8.7773275665944823e-17, 6.5982162774306465e-16, 4.6464228722152545e-15, 3.0673938466320995e-14, 1.8997359653204635e-13, 1.1045578960219544e-12, 6.0330789028505752e-12, 3.0975214481618230e-11, 1.4957890384694261e-10, 6.7975116544323199e-10, 2.9085970464514601e-09, 1.1724370655087347e-08, 4.4542518892262074e-08, 1.5956404054013332e-07, 5.3920679976732085e-07, 1.7195329738679880e-06, 5.1768455512555845e-06, 1.4718871925099586e-05, 3.9535219175273295e-05, 1.0035307023681430e-04, 2.4079185627092926e-04, 5.4630685564139225e-04, 1.1722653593393563e-03, 2.3796447518820959e-03, 4.5707734636933712e-03, 8.3089325331250057e-03, 1.4297417780659441e-02, 2.3291535150151157e-02, 3.5927796289914674e-02, 5.2482133056536061e-02, 7.2608927339705281e-02, 9.5149879125439124e-02, 1.1811391373984721e-01, 1.3889811387154746e-01, 1.5474440942350939e-01, 1.6333182250163769e-01, 1.6333182250163769e-01, 1.5474440942350939e-01, 1.3889811387154746e-01, 1.1811391373984721e-01, 9.5149879125439124e-02, 7.2608927339705281e-02, 5.2482133056536061e-02, 3.5927796289914674e-02, 2.3291535150151157e-02, 1.4297417780659441e-02, 8.3089325331250057e-03, 4.5707734636933712e-03, 2.3796447518820959e-03, 1.1722653593393563e-03, 5.4630685564139225e-04, 2.4079185627092926e-04, 1.0035307023681430e-04, 3.9535219175273295e-05, 1.4718871925099586e-05, 5.1768455512555845e-06, 1.7195329738679880e-06, 5.3920679976732085e-07, 1.5956404054013332e-07, 4.4542518892262074e-08, 1.1724370655087347e-08, 2.9085970464514601e-09, 6.7975116544323199e-10, 1.4957890384694261e-10, 3.0975214481618230e-11, 6.0330789028505752e-12, 1.1045578960219544e-12, 1.8997359653204635e-13, 3.0673938466320995e-14, 4.6464228722152545e-15, 6.5982162774306465e-16, 8.7773275665944823e-17, 1.0928940877684042e-17, 1.2726463913998945e-18, 1.3847330443129062e-19, 1.4065250811244644e-20, 1.3323707929307384e-21, 1.1758429681040065e-22, 9.6570947115181529e-24, 7.3725440555518383e-25, 5.2255927032642325e-26, 3.4343583117038137e-27, 2.0900714057742614e-28, 1.1761496941464036e-29, 6.1107571504811921e-31, 2.9266129491084507e-32, 1.2898503021552704e-33, 5.2220236908204409e-35, 1.9383756218147382e-36, 6.5835338360421613e-38, 2.0415908964489771e-39, 5.7672996866961233e-41, 1.4805046972403839e-42, 3.4446682433867826e-44, 7.2439067732577147e-46, 1.3727341637645679e-47, 2.3366431061277383e-49, 3.5603170842517748e-51, 4.8378847700931107e-53, 5.8390470979220446e-55, 6.2323324068554731e-57, 5.8549015274027961e-59, 4.8161711078239858e-61, 3.4493784123174178e-63, 2.1376722221415430e-65, 1.1385038568984282e-67, 5.1717638304628555e-70, 1.9870439601235429e-72, 6.3969105456232966e-75, 1.7074874775824880e-77, 3.7342898142071596e-80, 6.6016471696136248e-83, 9.2888951681828944e-86, 1.0218043358339510e-88, 8.6056883186768174e-92, 5.4137540405290719e-95, 2.4699093339298307e-98, 7.8840222434465455e-102, 1.6842534274181958e-105, 2.2763600768872421e-109, 1.8091479691129481e-113, 7.6610437292542439e-118, 1.5040760324474137e-122, 1.1108350634945189e-127, 2.1873318060197500e-133, 5.9474161464872244e-140, 4.1452696623483395e-148}, + {5.8866637956879832e-149, 8.7701238593349446e-141, 3.3286398376690490e-134, 1.7390228685740816e-128, 2.4174491971248305e-123, 1.2623847464849609e-118, 3.0530327446766110e-114, 3.9308789125198654e-110, 2.9740999490947605e-106, 1.4228368487505154e-102, 4.5535119727458115e-99, 1.0191828364399763e-95, 1.6537960518565174e-92, 2.0039262792917714e-89, 1.8586066284522124e-86, 1.3473832322197353e-83, 7.7728521820677718e-81, 3.6240329528761601e-78, 1.3842194496021173e-75, 4.3831680288373217e-73, 1.1628357927637541e-70, 2.6089921702855559e-68, 4.9923292649319471e-66, 8.2091330064948600e-64, 1.1679600204323236e-61, 1.4467547750792869e-59, 1.5691297806630218e-57, 1.4978576876165396e-55, 1.2644313857762022e-53, 9.4805533849020122e-52, 6.3392777437739552e-50, 3.7943396524379168e-48, 2.0399882317508400e-46, 9.8835394906743943e-45, 4.3280559299142535e-43, 1.7178434457904729e-41, 6.1961228512356421e-40, 2.0359401385923293e-38, 6.1082242612809361e-37, 1.6768933675263854e-35, 4.2210054325158127e-34, 9.7605477823793654e-33, 2.0771142264898199e-31, 4.0748381699253249e-30, 7.3810648870417183e-29, 1.2363547377218958e-27, 1.9178022081467005e-26, 2.7586033246049575e-25, 3.6843129796217172e-24, 4.5743951370215857e-23, 5.2859323137468154e-22, 5.6910915175835955e-21, 5.7148760619818976e-20, 5.3577677281181046e-19, 4.6939007358067331e-18, 3.8463054439056453e-17, 2.9504021972772029e-16, 2.1202927606877813e-15, 1.4286304928072976e-14, 9.0316979019406731e-14, 5.3609851542957339e-13, 2.9897229802024487e-12, 1.5674715085860065e-11, 7.7305137154009676e-11, 3.5884068378224706e-10, 1.5685984370316076e-09, 6.4603917825466764e-09, 2.5081389998281072e-08, 9.1830644706366585e-08, 3.1721513586827257e-07, 1.0342536339020313e-06, 3.1840053712593505e-06, 9.2587247391013518e-06, 2.5439403557345701e-05, 6.6066258510845340e-05, 1.6221813086114782e-04, 3.7669274161032700e-04, 8.2747754872833888e-04, 1.7199311750936504e-03, 3.3833630340537615e-03, 6.3002503573431189e-03, 1.1107594867856934e-02, 1.8544242319012489e-02, 2.9321853906612717e-02, 4.3916343744405027e-02, 6.2311084328469719e-02, 8.3763283089409293e-02, 1.0669133852506041e-01, 1.2877234499448006e-01, 1.4728481639742919e-01, 1.5964391640203837e-01, 1.6398949726573361e-01, 1.5964391640203837e-01, 1.4728481639742919e-01, 1.2877234499448006e-01, 1.0669133852506041e-01, 8.3763283089409293e-02, 6.2311084328469719e-02, 4.3916343744405027e-02, 2.9321853906612717e-02, 1.8544242319012489e-02, 1.1107594867856934e-02, 6.3002503573431189e-03, 3.3833630340537615e-03, 1.7199311750936504e-03, 8.2747754872833888e-04, 3.7669274161032700e-04, 1.6221813086114782e-04, 6.6066258510845340e-05, 2.5439403557345701e-05, 9.2587247391013518e-06, 3.1840053712593505e-06, 1.0342536339020313e-06, 3.1721513586827257e-07, 9.1830644706366585e-08, 2.5081389998281072e-08, 6.4603917825466764e-09, 1.5685984370316076e-09, 3.5884068378224706e-10, 7.7305137154009676e-11, 1.5674715085860065e-11, 2.9897229802024487e-12, 5.3609851542957339e-13, 9.0316979019406731e-14, 1.4286304928072976e-14, 2.1202927606877813e-15, 2.9504021972772029e-16, 3.8463054439056453e-17, 4.6939007358067331e-18, 5.3577677281181046e-19, 5.7148760619818976e-20, 5.6910915175835955e-21, 5.2859323137468154e-22, 4.5743951370215857e-23, 3.6843129796217172e-24, 2.7586033246049575e-25, 1.9178022081467005e-26, 1.2363547377218958e-27, 7.3810648870417183e-29, 4.0748381699253249e-30, 2.0771142264898199e-31, 9.7605477823793654e-33, 4.2210054325158127e-34, 1.6768933675263854e-35, 6.1082242612809361e-37, 2.0359401385923293e-38, 6.1961228512356421e-40, 1.7178434457904729e-41, 4.3280559299142535e-43, 9.8835394906743943e-45, 2.0399882317508400e-46, 3.7943396524379168e-48, 6.3392777437739552e-50, 9.4805533849020122e-52, 1.2644313857762022e-53, 1.4978576876165396e-55, 1.5691297806630218e-57, 1.4467547750792869e-59, 1.1679600204323236e-61, 8.2091330064948600e-64, 4.9923292649319471e-66, 2.6089921702855559e-68, 1.1628357927637541e-70, 4.3831680288373217e-73, 1.3842194496021173e-75, 3.6240329528761601e-78, 7.7728521820677718e-81, 1.3473832322197353e-83, 1.8586066284522124e-86, 2.0039262792917714e-89, 1.6537960518565174e-92, 1.0191828364399763e-95, 4.5535119727458115e-99, 1.4228368487505154e-102, 2.9740999490947605e-106, 3.9308789125198654e-110, 3.0530327446766110e-114, 1.2623847464849609e-118, 2.4174491971248305e-123, 1.7390228685740816e-128, 3.3286398376690490e-134, 8.7701238593349446e-141, 5.8866637956879832e-149}, + {8.3581373975539108e-150, 1.2928412877755577e-141, 5.0632382588324120e-135, 2.7209602221952139e-129, 3.8829389622015062e-124, 2.0785832875875387e-119, 5.1477595408996125e-115, 6.7815072200124497e-111, 5.2462701695642363e-107, 2.5648912231375885e-103, 8.3845258592424195e-100, 1.9161630252069163e-96, 3.1736968736455641e-93, 3.9241298067673186e-90, 3.7129493377218318e-87, 2.7453553081368732e-84, 1.6150344379416257e-81, 7.6774327866656284e-79, 2.9894343828423281e-76, 9.6489070550182607e-74, 2.6089586336270140e-71, 5.9654008943367430e-69, 1.1631966527487701e-66, 1.9489490740739864e-64, 2.8252664298663074e-62, 3.5656104439409607e-60, 3.9399315442250632e-58, 3.8315828065199010e-56, 3.2951200002417535e-54, 2.5169328462380233e-52, 1.7144956007470846e-50, 1.0454204091183458e-48, 5.7258874684495484e-47, 2.8261341310391440e-45, 1.2607977361040919e-43, 5.0982121558902017e-42, 1.8734745650648728e-40, 6.2719136180711063e-39, 1.9172254945419127e-37, 5.3629616050774624e-36, 1.3755486543958331e-34, 3.2412811142581749e-33, 7.0292474203881568e-32, 1.4053678782835759e-30, 2.5945192595304142e-29, 4.4296347519346036e-28, 7.0039976811745699e-27, 1.0270246629696484e-25, 1.3983996188477357e-24, 1.7702189074849013e-23, 2.0857890645994067e-22, 2.2900155277371847e-21, 2.3452218050389733e-20, 2.2425235675550114e-19, 2.0040402270860207e-18, 1.6752540366716003e-17, 1.3110796195605400e-16, 9.6139706301947510e-16, 6.6105224464386113e-15, 4.2652608433469510e-14, 2.5842479214605026e-13, 1.4712572098023350e-12, 7.8755658569412608e-12, 3.9661851656268533e-11, 1.8802196827204209e-10, 8.3950345085448172e-10, 3.5321294226177634e-09, 1.4010751708171831e-08, 5.2419925848831286e-08, 1.8506755890537394e-07, 6.1679613744986908e-07, 1.9413286157507076e-06, 5.7724680860172742e-06, 1.6221044402072930e-05, 4.3091495767535577e-05, 1.0825095642068624e-04, 2.5723066429963950e-04, 5.7833524878596126e-04, 1.2305790314187559e-03, 2.4786280618533298e-03, 4.7269014592664482e-03, 8.5366761761569536e-03, 1.4602406139195508e-02, 2.3662049334306538e-02, 3.6327402988086469e-02, 5.2847573265457019e-02, 7.2857131060649991e-02, 9.5195424202311488e-02, 1.1789377323403843e-01, 1.3839596229316664e-01, 1.5400468068882942e-01, 1.6245602140829696e-01, 1.6245602140829696e-01, 1.5400468068882942e-01, 1.3839596229316664e-01, 1.1789377323403843e-01, 9.5195424202311488e-02, 7.2857131060649991e-02, 5.2847573265457019e-02, 3.6327402988086469e-02, 2.3662049334306538e-02, 1.4602406139195508e-02, 8.5366761761569536e-03, 4.7269014592664482e-03, 2.4786280618533298e-03, 1.2305790314187559e-03, 5.7833524878596126e-04, 2.5723066429963950e-04, 1.0825095642068624e-04, 4.3091495767535577e-05, 1.6221044402072930e-05, 5.7724680860172742e-06, 1.9413286157507076e-06, 6.1679613744986908e-07, 1.8506755890537394e-07, 5.2419925848831286e-08, 1.4010751708171831e-08, 3.5321294226177634e-09, 8.3950345085448172e-10, 1.8802196827204209e-10, 3.9661851656268533e-11, 7.8755658569412608e-12, 1.4712572098023350e-12, 2.5842479214605026e-13, 4.2652608433469510e-14, 6.6105224464386113e-15, 9.6139706301947510e-16, 1.3110796195605400e-16, 1.6752540366716003e-17, 2.0040402270860207e-18, 2.2425235675550114e-19, 2.3452218050389733e-20, 2.2900155277371847e-21, 2.0857890645994067e-22, 1.7702189074849013e-23, 1.3983996188477357e-24, 1.0270246629696484e-25, 7.0039976811745699e-27, 4.4296347519346036e-28, 2.5945192595304142e-29, 1.4053678782835759e-30, 7.0292474203881568e-32, 3.2412811142581749e-33, 1.3755486543958331e-34, 5.3629616050774624e-36, 1.9172254945419127e-37, 6.2719136180711063e-39, 1.8734745650648728e-40, 5.0982121558902017e-42, 1.2607977361040919e-43, 2.8261341310391440e-45, 5.7258874684495484e-47, 1.0454204091183458e-48, 1.7144956007470846e-50, 2.5169328462380233e-52, 3.2951200002417535e-54, 3.8315828065199010e-56, 3.9399315442250632e-58, 3.5656104439409607e-60, 2.8252664298663074e-62, 1.9489490740739864e-64, 1.1631966527487701e-66, 5.9654008943367430e-69, 2.6089586336270140e-71, 9.6489070550182607e-74, 2.9894343828423281e-76, 7.6774327866656284e-79, 1.6150344379416257e-81, 2.7453553081368732e-84, 3.7129493377218318e-87, 3.9241298067673186e-90, 3.1736968736455641e-93, 1.9161630252069163e-96, 8.3845258592424195e-100, 2.5648912231375885e-103, 5.2462701695642363e-107, 6.7815072200124497e-111, 5.1477595408996125e-115, 2.0785832875875387e-119, 3.8829389622015062e-124, 2.7209602221952139e-129, 5.0632382588324120e-135, 1.2928412877755577e-141, 8.3581373975539108e-150}, + {1.1865178694667318e-150, 1.9052328091840223e-142, 7.6984112043987381e-136, 4.2550288152769099e-130, 6.2327840907767578e-125, 3.4199371076928271e-120, 8.6723736530813987e-116, 1.1688387166643387e-111, 9.2447904963657574e-108, 4.6184277629201267e-104, 1.5419925530578493e-100, 3.5978676971165183e-97, 6.0819398055170106e-94, 7.6728915952440279e-91, 7.4056905596969795e-88, 5.5844689207576789e-85, 3.3498078614715179e-82, 1.6234441963286573e-79, 6.4436381052523653e-77, 2.1197593898507255e-74, 5.8410998823252364e-72, 1.3609591582325947e-69, 2.7039668570857215e-67, 4.6159532490505087e-65, 6.8172254689772145e-63, 8.7649300109604261e-61, 9.8662587260951024e-59, 9.7741261753796815e-57, 8.5624277958175666e-55, 6.6621826190749697e-53, 4.6227110569813219e-51, 2.8712161421730314e-49, 1.6018948070503715e-47, 8.0538675955345321e-46, 3.6600273200497822e-44, 1.5076237023555035e-42, 5.6437809696463000e-41, 1.9247883296069542e-39, 5.9942100762419949e-38, 1.7082702187606927e-36, 4.4641638317895058e-35, 1.0718010386176091e-33, 2.3684402708428834e-32, 4.8253003329308802e-31, 9.0781689354637632e-30, 1.5795898083977327e-28, 2.5455821620542874e-27, 3.8046791468512480e-26, 5.2807723431418099e-25, 6.8148555847519964e-24, 8.1865279023956756e-23, 9.1644244237263828e-22, 9.5703407786302617e-21, 9.3325018346830289e-20, 8.5060423271066705e-19, 7.2528021781457044e-18, 5.7903374085298744e-17, 4.3318599899726389e-16, 3.0391558780794568e-15, 2.0010535409370048e-14, 1.2373574238435096e-13, 7.1903669458823460e-13, 3.9291706318326725e-12, 2.0202524727399665e-11, 9.7794253591584735e-11, 4.4592266183083370e-10, 1.9163195825780139e-09, 7.7651658482449274e-09, 2.9683092240535501e-08, 1.0708625929490390e-07, 3.6475807440990068e-07, 1.1735270767794228e-06, 3.5674612381232805e-06, 1.0250735219808427e-05, 2.7849862113005195e-05, 7.1564447183165722e-05, 1.7398159469356308e-04, 4.0027477960329739e-04, 8.7170842819435444e-04, 1.7973955409015775e-03, 3.5096925793779445e-03, 6.4913282065116552e-03, 1.1374067733309335e-02, 1.8883705620831706e-02, 2.9710644677922813e-02, 4.4304476145580723e-02, 6.2624475272894761e-02, 8.3916039610710105e-02, 1.0660728151712012e-01, 1.2841023960066572e-01, 1.4665826336478710e-01, 1.5882689919380447e-01, 1.6310306755078369e-01, 1.5882689919380447e-01, 1.4665826336478710e-01, 1.2841023960066572e-01, 1.0660728151712012e-01, 8.3916039610710105e-02, 6.2624475272894761e-02, 4.4304476145580723e-02, 2.9710644677922813e-02, 1.8883705620831706e-02, 1.1374067733309335e-02, 6.4913282065116552e-03, 3.5096925793779445e-03, 1.7973955409015775e-03, 8.7170842819435444e-04, 4.0027477960329739e-04, 1.7398159469356308e-04, 7.1564447183165722e-05, 2.7849862113005195e-05, 1.0250735219808427e-05, 3.5674612381232805e-06, 1.1735270767794228e-06, 3.6475807440990068e-07, 1.0708625929490390e-07, 2.9683092240535501e-08, 7.7651658482449274e-09, 1.9163195825780139e-09, 4.4592266183083370e-10, 9.7794253591584735e-11, 2.0202524727399665e-11, 3.9291706318326725e-12, 7.1903669458823460e-13, 1.2373574238435096e-13, 2.0010535409370048e-14, 3.0391558780794568e-15, 4.3318599899726389e-16, 5.7903374085298744e-17, 7.2528021781457044e-18, 8.5060423271066705e-19, 9.3325018346830289e-20, 9.5703407786302617e-21, 9.1644244237263828e-22, 8.1865279023956756e-23, 6.8148555847519964e-24, 5.2807723431418099e-25, 3.8046791468512480e-26, 2.5455821620542874e-27, 1.5795898083977327e-28, 9.0781689354637632e-30, 4.8253003329308802e-31, 2.3684402708428834e-32, 1.0718010386176091e-33, 4.4641638317895058e-35, 1.7082702187606927e-36, 5.9942100762419949e-38, 1.9247883296069542e-39, 5.6437809696463000e-41, 1.5076237023555035e-42, 3.6600273200497822e-44, 8.0538675955345321e-46, 1.6018948070503715e-47, 2.8712161421730314e-49, 4.6227110569813219e-51, 6.6621826190749697e-53, 8.5624277958175666e-55, 9.7741261753796815e-57, 9.8662587260951024e-59, 8.7649300109604261e-61, 6.8172254689772145e-63, 4.6159532490505087e-65, 2.7039668570857215e-67, 1.3609591582325947e-69, 5.8410998823252364e-72, 2.1197593898507255e-74, 6.4436381052523653e-77, 1.6234441963286573e-79, 3.3498078614715179e-82, 5.5844689207576789e-85, 7.4056905596969795e-88, 7.6728915952440279e-91, 6.0819398055170106e-94, 3.5978676971165183e-97, 1.5419925530578493e-100, 4.6184277629201267e-104, 9.2447904963657574e-108, 1.1688387166643387e-111, 8.6723736530813987e-116, 3.4199371076928271e-120, 6.2327840907767578e-125, 4.2550288152769099e-130, 7.6984112043987381e-136, 1.9052328091840223e-142, 1.1865178694667318e-150}, + {1.6840859823147192e-151, 2.8068259915465668e-143, 1.1700024361722009e-136, 6.6504100620446623e-131, 9.9982626870689096e-126, 5.6227251746796540e-121, 1.4598025546816272e-116, 2.0126980605111617e-112, 1.6274180017356631e-108, 8.3068317564996415e-105, 2.8324541894274240e-101, 6.7467686874093196e-98, 1.1639059887066096e-94, 1.4980806006797597e-91, 1.4748024918249946e-88, 1.1340919960793407e-85, 6.9358925722736469e-83, 3.4266063564656041e-80, 1.3862443412766689e-77, 4.6475320184424221e-75, 1.3049987561313226e-72, 3.0981254141048187e-70, 6.2713089100746324e-68, 1.0906635714604883e-65, 1.6409070764036964e-63, 2.1490689833897993e-61, 2.4641241627782225e-59, 2.4864657741894790e-57, 2.2186336768274302e-55, 1.7582563693437111e-53, 1.2426111111041695e-51, 7.8609642161410873e-50, 4.4670071717223134e-48, 2.2875134062797375e-46, 1.0588298166277823e-44, 4.4424843586907703e-43, 1.6939665809360599e-41, 5.8848055182020130e-40, 1.8668536705967508e-38, 5.4197686272780061e-37, 1.4428750537835282e-35, 3.5292920298964982e-34, 7.9458957717354865e-33, 1.6494369134608046e-31, 3.1620314656015991e-30, 5.6065555004969651e-29, 9.2077125425461603e-28, 1.4025749559057771e-26, 1.9841800348065493e-25, 2.6100548891439468e-24, 3.1962255598539348e-23, 3.6477448742277230e-22, 3.8838880473136030e-21, 3.8618679709476893e-20, 3.5894545533623586e-19, 3.1214143458455917e-18, 2.5417847367765562e-17, 1.9397457159226965e-16, 1.3883744241015343e-15, 9.3270625462533699e-15, 5.8852482736096351e-14, 3.4902504651461380e-13, 1.9466883562172841e-12, 1.0217552929953939e-11, 5.0496076724281894e-11, 2.3510718451740779e-10, 1.0318035977700679e-09, 4.2703647703012249e-09, 1.6675261164947539e-08, 6.1462809064451552e-08, 2.1392739679622303e-07, 7.0340742267172300e-07, 2.1857314406758851e-06, 6.4208055079598766e-06, 1.7837324122194181e-05, 4.6876297088489141e-05, 1.1657026717177768e-04, 2.7438000977925001e-04, 6.1144669240944507e-04, 1.2903563124214057e-03, 2.5792975144676013e-03, 4.8845246714536682e-03, 8.7650270802736002e-03, 1.4906240076216418e-02, 2.4028883068628805e-02, 3.6720571883816493e-02, 5.3204522444878222e-02, 7.3096572483403829e-02, 9.5234476669428525e-02, 1.1767191582495477e-01, 1.3789832745338026e-01, 1.5327533388369177e-01, 1.6159415788497841e-01, 1.6159415788497841e-01, 1.5327533388369177e-01, 1.3789832745338026e-01, 1.1767191582495477e-01, 9.5234476669428525e-02, 7.3096572483403829e-02, 5.3204522444878222e-02, 3.6720571883816493e-02, 2.4028883068628805e-02, 1.4906240076216418e-02, 8.7650270802736002e-03, 4.8845246714536682e-03, 2.5792975144676013e-03, 1.2903563124214057e-03, 6.1144669240944507e-04, 2.7438000977925001e-04, 1.1657026717177768e-04, 4.6876297088489141e-05, 1.7837324122194181e-05, 6.4208055079598766e-06, 2.1857314406758851e-06, 7.0340742267172300e-07, 2.1392739679622303e-07, 6.1462809064451552e-08, 1.6675261164947539e-08, 4.2703647703012249e-09, 1.0318035977700679e-09, 2.3510718451740779e-10, 5.0496076724281894e-11, 1.0217552929953939e-11, 1.9466883562172841e-12, 3.4902504651461380e-13, 5.8852482736096351e-14, 9.3270625462533699e-15, 1.3883744241015343e-15, 1.9397457159226965e-16, 2.5417847367765562e-17, 3.1214143458455917e-18, 3.5894545533623586e-19, 3.8618679709476893e-20, 3.8838880473136030e-21, 3.6477448742277230e-22, 3.1962255598539348e-23, 2.6100548891439468e-24, 1.9841800348065493e-25, 1.4025749559057771e-26, 9.2077125425461603e-28, 5.6065555004969651e-29, 3.1620314656015991e-30, 1.6494369134608046e-31, 7.9458957717354865e-33, 3.5292920298964982e-34, 1.4428750537835282e-35, 5.4197686272780061e-37, 1.8668536705967508e-38, 5.8848055182020130e-40, 1.6939665809360599e-41, 4.4424843586907703e-43, 1.0588298166277823e-44, 2.2875134062797375e-46, 4.4670071717223134e-48, 7.8609642161410873e-50, 1.2426111111041695e-51, 1.7582563693437111e-53, 2.2186336768274302e-55, 2.4864657741894790e-57, 2.4641241627782225e-59, 2.1490689833897993e-61, 1.6409070764036964e-63, 1.0906635714604883e-65, 6.2713089100746324e-68, 3.0981254141048187e-70, 1.3049987561313226e-72, 4.6475320184424221e-75, 1.3862443412766689e-77, 3.4266063564656041e-80, 6.9358925722736469e-83, 1.1340919960793407e-85, 1.4748024918249946e-88, 1.4980806006797597e-91, 1.1639059887066096e-94, 6.7467686874093196e-98, 2.8324541894274240e-101, 8.3068317564996415e-105, 1.6274180017356631e-108, 2.0126980605111617e-112, 1.4598025546816272e-116, 5.6227251746796540e-121, 9.9982626870689096e-126, 6.6504100620446623e-131, 1.1700024361722009e-136, 2.8068259915465668e-143, 1.6840859823147192e-151}, + {2.3899020087783538e-152, 4.1337932844079439e-144, 1.7774077118017352e-137, 1.0388721680141190e-131, 1.6028413383110423e-126, 9.2375467812799180e-122, 2.4552181378752603e-117, 3.4625987620456931e-113, 2.8619431556076958e-109, 1.4924416386535932e-105, 5.1966730435893490e-102, 1.2635422959480214e-98, 2.2243270327788831e-95, 2.9206395863825604e-92, 2.9324498160004818e-89, 2.2993488113263748e-86, 1.4336286376453945e-83, 7.2194564657826763e-81, 2.9766194663244294e-78, 1.0169377873705381e-75, 2.9095299074235018e-73, 7.0373804171328241e-71, 1.4512217440971957e-68, 2.5709836724164109e-66, 3.9400295587538806e-64, 5.2559492672815257e-62, 6.1380579859214437e-60, 6.3081846096424608e-58, 5.7325826101059963e-56, 4.6268156176755226e-54, 3.3301662675561347e-52, 2.1455339764954737e-50, 1.2416693105547687e-48, 6.4756889941564796e-47, 3.0527217350206308e-45, 1.3044685923509235e-43, 5.0660482804550958e-42, 1.7925263383158762e-40, 5.7919770166825449e-39, 1.7127600543267554e-37, 4.6447431828997982e-36, 1.1573309534274821e-34, 2.6544306695450948e-33, 5.6136594541327730e-32, 1.0964361374105204e-30, 1.9808277135032592e-29, 3.3148509472564812e-28, 5.1455269820153546e-27, 7.4183584908683151e-26, 9.9456309833303069e-25, 1.2413968193571878e-23, 1.4441897483451718e-22, 1.5675836145616411e-21, 1.5891496108132932e-20, 1.5060515461273932e-19, 1.3355156911983980e-18, 1.1090885964042391e-17, 8.6327149787564008e-17, 6.3027647004538790e-16, 4.3195605416094461e-15, 2.7808623921464611e-14, 1.6828396856093499e-13, 9.5787095713446750e-13, 5.1314070230067691e-12, 2.5887038946092999e-11, 1.2305056649947358e-10, 5.5140053605655075e-10, 2.3304976685688244e-09, 9.2946430660480328e-09, 3.4995595911608765e-08, 1.2444418429985038e-07, 4.1810988437722446e-07, 1.3277780039510742e-06, 3.9868978854768734e-06, 1.1323113503918158e-05, 3.0426750494245559e-05, 7.7380888614623922e-05, 1.8630373980043952e-04, 4.2474911952990744e-04, 9.1721684584915764e-04, 1.8764550081725386e-03, 3.6376544190370392e-03, 6.6835183409171238e-03, 1.1640333062329629e-02, 1.9220794786116900e-02, 3.0094363212091947e-02, 4.4685050904584946e-02, 6.2929070893539232e-02, 8.4060967557359437e-02, 1.0651895867711307e-01, 1.2804948653534245e-01, 1.4603926334720602e-01, 1.5802227437713226e-01, 1.6223085863339984e-01, 1.5802227437713226e-01, 1.4603926334720602e-01, 1.2804948653534245e-01, 1.0651895867711307e-01, 8.4060967557359437e-02, 6.2929070893539232e-02, 4.4685050904584946e-02, 3.0094363212091947e-02, 1.9220794786116900e-02, 1.1640333062329629e-02, 6.6835183409171238e-03, 3.6376544190370392e-03, 1.8764550081725386e-03, 9.1721684584915764e-04, 4.2474911952990744e-04, 1.8630373980043952e-04, 7.7380888614623922e-05, 3.0426750494245559e-05, 1.1323113503918158e-05, 3.9868978854768734e-06, 1.3277780039510742e-06, 4.1810988437722446e-07, 1.2444418429985038e-07, 3.4995595911608765e-08, 9.2946430660480328e-09, 2.3304976685688244e-09, 5.5140053605655075e-10, 1.2305056649947358e-10, 2.5887038946092999e-11, 5.1314070230067691e-12, 9.5787095713446750e-13, 1.6828396856093499e-13, 2.7808623921464611e-14, 4.3195605416094461e-15, 6.3027647004538790e-16, 8.6327149787564008e-17, 1.1090885964042391e-17, 1.3355156911983980e-18, 1.5060515461273932e-19, 1.5891496108132932e-20, 1.5675836145616411e-21, 1.4441897483451718e-22, 1.2413968193571878e-23, 9.9456309833303069e-25, 7.4183584908683151e-26, 5.1455269820153546e-27, 3.3148509472564812e-28, 1.9808277135032592e-29, 1.0964361374105204e-30, 5.6136594541327730e-32, 2.6544306695450948e-33, 1.1573309534274821e-34, 4.6447431828997982e-36, 1.7127600543267554e-37, 5.7919770166825449e-39, 1.7925263383158762e-40, 5.0660482804550958e-42, 1.3044685923509235e-43, 3.0527217350206308e-45, 6.4756889941564796e-47, 1.2416693105547687e-48, 2.1455339764954737e-50, 3.3301662675561347e-52, 4.6268156176755226e-54, 5.7325826101059963e-56, 6.3081846096424608e-58, 6.1380579859214437e-60, 5.2559492672815257e-62, 3.9400295587538806e-64, 2.5709836724164109e-66, 1.4512217440971957e-68, 7.0373804171328241e-71, 2.9095299074235018e-73, 1.0169377873705381e-75, 2.9766194663244294e-78, 7.2194564657826763e-81, 1.4336286376453945e-83, 2.2993488113263748e-86, 2.9324498160004818e-89, 2.9206395863825604e-92, 2.2243270327788831e-95, 1.2635422959480214e-98, 5.1966730435893490e-102, 1.4924416386535932e-105, 2.8619431556076958e-109, 3.4625987620456931e-113, 2.4552181378752603e-117, 9.2375467812799180e-122, 1.6028413383110423e-126, 1.0388721680141190e-131, 1.7774077118017352e-137, 4.1337932844079439e-144, 2.3899020087783538e-152}, + {3.3909583926202969e-153, 6.0862398111746403e-145, 2.6990049104808299e-138, 1.6219807504695568e-132, 2.5679266269176032e-127, 1.5165281109964923e-122, 4.1260001698114066e-118, 5.9515348152406019e-114, 5.0279031031404388e-110, 2.6784561524395333e-106, 9.5230206639834012e-103, 2.3633738761330501e-99, 4.2451210579798656e-96, 5.6858261506014681e-93, 5.8218672370402156e-90, 4.6543449390713426e-87, 2.9582182277022238e-84, 1.5183294739007438e-81, 6.3795487359338829e-79, 2.2208089866950920e-76, 6.4735410582641528e-74, 1.5951103254298808e-71, 3.3507196700207861e-69, 6.0464069117443835e-67, 9.4376753651859668e-65, 1.2822191213791653e-62, 1.5249989655376484e-60, 1.5960849625455376e-58, 1.4770796663837213e-56, 1.2140312147914462e-54, 8.8982101270994950e-53, 5.8379315269148491e-51, 3.4404622652833074e-49, 1.8272036259234053e-47, 8.7716947482766774e-46, 3.8170926065847122e-44, 1.5096656333028563e-42, 5.4400265472252386e-41, 1.7901934646856910e-39, 5.3916646781027312e-38, 1.4892193296848201e-36, 3.7795868784349260e-35, 8.8301666493717958e-34, 1.9022911023392480e-32, 3.7850530748490676e-31, 6.9665700818714156e-30, 1.1878115612451122e-28, 1.8786842016880562e-27, 2.7599602414845152e-26, 3.7707755724079553e-25, 4.7967389479007740e-24, 5.6876402480164174e-23, 6.2928558569586138e-22, 6.5032337700285951e-21, 6.2833568961437137e-20, 5.6810615766852734e-19, 4.8108093342629945e-18, 3.8186952800271027e-17, 2.8435455634715359e-16, 1.9878218878928244e-15, 1.3054944744238950e-14, 8.0602086244990039e-14, 4.6813428453581271e-13, 2.5592533379055519e-12, 1.3177335517890257e-11, 6.3937241128218932e-11, 2.9249655637661996e-10, 1.2622501489006109e-09, 5.1408413936157202e-09, 1.9768915482746416e-08, 7.1808683672368473e-08, 2.4648607700088249e-07, 7.9982594734022375e-07, 2.4543893859357136e-06, 7.1249965705005385e-06, 1.9573063938461480e-05, 5.0897601014117974e-05, 1.2532087255275024e-04, 2.9224860429386435e-04, 6.4564239421835911e-04, 1.3515815953737001e-03, 2.6816113762841770e-03, 5.0435720589444479e-03, 8.9938955083231700e-03, 1.5208840297800851e-02, 2.4392011104876491e-02, 3.7107373608297196e-02, 5.3553162455639902e-02, 7.3327512502661077e-02, 9.5267294910895362e-02, 1.1744849271751398e-01, 1.3740517258624155e-01, 1.5255613196758108e-01, 1.6074586617490177e-01, 1.6074586617490177e-01, 1.5255613196758108e-01, 1.3740517258624155e-01, 1.1744849271751398e-01, 9.5267294910895362e-02, 7.3327512502661077e-02, 5.3553162455639902e-02, 3.7107373608297196e-02, 2.4392011104876491e-02, 1.5208840297800851e-02, 8.9938955083231700e-03, 5.0435720589444479e-03, 2.6816113762841770e-03, 1.3515815953737001e-03, 6.4564239421835911e-04, 2.9224860429386435e-04, 1.2532087255275024e-04, 5.0897601014117974e-05, 1.9573063938461480e-05, 7.1249965705005385e-06, 2.4543893859357136e-06, 7.9982594734022375e-07, 2.4648607700088249e-07, 7.1808683672368473e-08, 1.9768915482746416e-08, 5.1408413936157202e-09, 1.2622501489006109e-09, 2.9249655637661996e-10, 6.3937241128218932e-11, 1.3177335517890257e-11, 2.5592533379055519e-12, 4.6813428453581271e-13, 8.0602086244990039e-14, 1.3054944744238950e-14, 1.9878218878928244e-15, 2.8435455634715359e-16, 3.8186952800271027e-17, 4.8108093342629945e-18, 5.6810615766852734e-19, 6.2833568961437137e-20, 6.5032337700285951e-21, 6.2928558569586138e-22, 5.6876402480164174e-23, 4.7967389479007740e-24, 3.7707755724079553e-25, 2.7599602414845152e-26, 1.8786842016880562e-27, 1.1878115612451122e-28, 6.9665700818714156e-30, 3.7850530748490676e-31, 1.9022911023392480e-32, 8.8301666493717958e-34, 3.7795868784349260e-35, 1.4892193296848201e-36, 5.3916646781027312e-38, 1.7901934646856910e-39, 5.4400265472252386e-41, 1.5096656333028563e-42, 3.8170926065847122e-44, 8.7716947482766774e-46, 1.8272036259234053e-47, 3.4404622652833074e-49, 5.8379315269148491e-51, 8.8982101270994950e-53, 1.2140312147914462e-54, 1.4770796663837213e-56, 1.5960849625455376e-58, 1.5249989655376484e-60, 1.2822191213791653e-62, 9.4376753651859668e-65, 6.0464069117443835e-67, 3.3507196700207861e-69, 1.5951103254298808e-71, 6.4735410582641528e-74, 2.2208089866950920e-76, 6.3795487359338829e-79, 1.5183294739007438e-81, 2.9582182277022238e-84, 4.6543449390713426e-87, 5.8218672370402156e-90, 5.6858261506014681e-93, 4.2451210579798656e-96, 2.3633738761330501e-99, 9.5230206639834012e-103, 2.6784561524395333e-106, 5.0279031031404388e-110, 5.9515348152406019e-114, 4.1260001698114066e-118, 1.5165281109964923e-122, 2.5679266269176032e-127, 1.6219807504695568e-132, 2.6990049104808299e-138, 6.0862398111746403e-145, 3.3909583926202969e-153}, + {4.8105196926800447e-154, 8.9581349097014215e-146, 4.0967387783316221e-139, 2.5310532151069106e-133, 4.1115283174204790e-128, 2.4878902559132056e-123, 6.9281121543161367e-119, 1.0220279314543827e-114, 8.8243129868960541e-111, 4.8017711254332563e-107, 1.7430737935309201e-103, 4.4149829449283152e-100, 8.0909195748902241e-97, 1.1053200966532163e-93, 1.1540787556182570e-90, 9.4062445961729118e-88, 6.0938287850722912e-85, 3.1875459729105427e-82, 1.3647333597873649e-79, 4.8404013281274901e-77, 1.4373955207015468e-74, 3.6078416607613653e-72, 7.7193542145188385e-70, 1.4187152411878090e-67, 2.2552327816162141e-65, 3.1202888315880434e-63, 3.7791134625824903e-61, 4.0276289664497742e-59, 3.7954127913999138e-57, 3.1764227614962876e-55, 2.3706043434701509e-53, 1.5836556658561472e-51, 9.5030686706332782e-50, 5.1390369637842554e-48, 2.5120644517965854e-46, 1.1131134062886865e-44, 4.4828688752777018e-43, 1.6449624113929946e-41, 5.5124888578291881e-40, 1.6907462404862362e-38, 4.7559672339276421e-37, 1.2293279880804420e-35, 2.9252024556839558e-34, 6.4187377483908620e-33, 1.3009300303447977e-31, 2.4391335868389452e-30, 4.2366796233867587e-29, 6.8268728000449227e-28, 1.0218585868330291e-26, 1.4225584486944289e-25, 1.8440385833763509e-24, 2.2283071036811595e-23, 2.5127294052122314e-22, 2.6467919286881548e-21, 2.6068354747780742e-20, 2.4028313064323887e-19, 2.0745586965632990e-18, 1.6791123823339180e-17, 1.2750493352152407e-16, 9.0906021055959760e-16, 6.0895673953539301e-15, 3.8353345411384518e-14, 2.2726043918949056e-13, 1.2676970629687990e-12, 6.6608945127799692e-12, 3.2985045445873824e-11, 1.5402785642655144e-10, 6.7857514014962344e-10, 2.8217661921664192e-09, 1.1080667611835489e-08, 4.1107393732952725e-08, 1.4413206230487042e-07, 4.7781084115403341e-07, 1.4981838617872995e-06, 4.4446553339045300e-06, 1.2480054945286184e-05, 3.3176731522024002e-05, 8.3524630257267974e-05, 1.9919419791658306e-04, 4.5012132211052618e-04, 9.6399635747843960e-04, 1.9570814745659979e-03, 3.7671919910449735e-03, 6.8767389146135380e-03, 1.1906303498193138e-02, 1.9555454063496128e-02, 3.0473029715843637e-02, 4.5058194694576482e-02, 6.3225096957716942e-02, 8.4198334040706369e-02, 1.0642658240453728e-01, 1.2769014695749564e-01, 1.4542767716486577e-01, 1.5722973246415300e-01, 1.6137249430200609e-01, 1.5722973246415300e-01, 1.4542767716486577e-01, 1.2769014695749564e-01, 1.0642658240453728e-01, 8.4198334040706369e-02, 6.3225096957716942e-02, 4.5058194694576482e-02, 3.0473029715843637e-02, 1.9555454063496128e-02, 1.1906303498193138e-02, 6.8767389146135380e-03, 3.7671919910449735e-03, 1.9570814745659979e-03, 9.6399635747843960e-04, 4.5012132211052618e-04, 1.9919419791658306e-04, 8.3524630257267974e-05, 3.3176731522024002e-05, 1.2480054945286184e-05, 4.4446553339045300e-06, 1.4981838617872995e-06, 4.7781084115403341e-07, 1.4413206230487042e-07, 4.1107393732952725e-08, 1.1080667611835489e-08, 2.8217661921664192e-09, 6.7857514014962344e-10, 1.5402785642655144e-10, 3.2985045445873824e-11, 6.6608945127799692e-12, 1.2676970629687990e-12, 2.2726043918949056e-13, 3.8353345411384518e-14, 6.0895673953539301e-15, 9.0906021055959760e-16, 1.2750493352152407e-16, 1.6791123823339180e-17, 2.0745586965632990e-18, 2.4028313064323887e-19, 2.6068354747780742e-20, 2.6467919286881548e-21, 2.5127294052122314e-22, 2.2283071036811595e-23, 1.8440385833763509e-24, 1.4225584486944289e-25, 1.0218585868330291e-26, 6.8268728000449227e-28, 4.2366796233867587e-29, 2.4391335868389452e-30, 1.3009300303447977e-31, 6.4187377483908620e-33, 2.9252024556839558e-34, 1.2293279880804420e-35, 4.7559672339276421e-37, 1.6907462404862362e-38, 5.5124888578291881e-40, 1.6449624113929946e-41, 4.4828688752777018e-43, 1.1131134062886865e-44, 2.5120644517965854e-46, 5.1390369637842554e-48, 9.5030686706332782e-50, 1.5836556658561472e-51, 2.3706043434701509e-53, 3.1764227614962876e-55, 3.7954127913999138e-57, 4.0276289664497742e-59, 3.7791134625824903e-61, 3.1202888315880434e-63, 2.2552327816162141e-65, 1.4187152411878090e-67, 7.7193542145188385e-70, 3.6078416607613653e-72, 1.4373955207015468e-74, 4.8404013281274901e-77, 1.3647333597873649e-79, 3.1875459729105427e-82, 6.0938287850722912e-85, 9.4062445961729118e-88, 1.1540787556182570e-90, 1.1053200966532163e-93, 8.0909195748902241e-97, 4.4149829449283152e-100, 1.7430737935309201e-103, 4.8017711254332563e-107, 8.8243129868960541e-111, 1.0220279314543827e-114, 6.9281121543161367e-119, 2.4878902559132056e-123, 4.1115283174204790e-128, 2.5310532151069106e-133, 4.0967387783316221e-139, 8.9581349097014215e-146, 4.8105196926800447e-154}, + {6.8232197942250040e-155, 1.3181218114180107e-146, 6.2157350428501506e-140, 3.9475798303387850e-134, 6.5789265659620338e-129, 4.0785124308845132e-124, 1.1623859612267819e-119, 1.7535057075593614e-115, 1.5472021309193150e-111, 8.5990905704820439e-108, 3.1867892204083499e-104, 8.2372979129162400e-101, 1.5400245034982435e-97, 2.1456921017005163e-94, 2.2843171180826872e-91, 1.8979497846368726e-88, 1.2532102545185035e-85, 6.6801061673807505e-83, 2.9141025510545569e-80, 1.0529633740939257e-77, 3.1851858054210446e-75, 8.1431135103329952e-73, 1.7744839092477200e-70, 3.3212610596524388e-68, 5.3763688423964646e-66, 7.5746019148953009e-64, 9.3412200164700803e-62, 1.0136702052099045e-59, 9.7258603579728974e-58, 8.2874406983788114e-56, 6.2972157268746326e-54, 4.2830642136217272e-52, 2.6167460089856425e-50, 1.4407389710981317e-48, 7.1704184113766286e-47, 3.2349665837355912e-45, 1.3265135880257318e-43, 4.9561856762703143e-42, 1.6911721771605448e-40, 5.2817945954838791e-39, 1.5129382111557171e-37, 3.9824232345150253e-36, 9.6505627399970417e-35, 2.1566756583641779e-33, 4.4519543419059356e-32, 8.5019504368590908e-31, 1.5042535921639604e-29, 2.4692068347694563e-28, 3.7652687650201339e-27, 5.3404226168220292e-26, 7.0535560842160286e-25, 8.6851943617712193e-24, 9.9804891048351136e-23, 1.0714309730247980e-21, 1.0755595219737973e-20, 1.0105554063847399e-19, 8.8944609945993243e-19, 7.3396140181061249e-18, 5.6828205180213369e-17, 4.1316021764480691e-16, 2.8225916935311505e-15, 1.8132136826440378e-14, 1.0959822792780298e-13, 6.2370678258135157e-13, 3.3437645093788376e-12, 1.6897122210470246e-11, 8.0527347789629487e-11, 3.6211627179619072e-10, 1.5372205783801174e-09, 6.1632086713433375e-09, 2.3347964326766498e-08, 8.3606844554454458e-08, 2.8310992931625352e-07, 9.0687938435499206e-07, 2.7490144224436228e-06, 7.8882549269903193e-06, 2.1433661822155404e-05, 5.5163316323048505e-05, 1.3451233819198536e-04, 3.1084451589835123e-04, 6.8092260658474482e-04, 1.4142383035108275e-03, 2.7855275571971620e-03, 5.2039736325766575e-03, 9.2231946903286923e-03, 1.5510131997231313e-02, 2.4751412543080331e-02, 3.7487880444774385e-02, 5.3893671909463224e-02, 7.3550203638163128e-02, 9.5294126497036155e-02, 1.1722364672954393e-01, 1.3691645960749019e-01, 1.5184684526785858e-01, 1.5991079381814263e-01, 1.5991079381814263e-01, 1.5184684526785858e-01, 1.3691645960749019e-01, 1.1722364672954393e-01, 9.5294126497036155e-02, 7.3550203638163128e-02, 5.3893671909463224e-02, 3.7487880444774385e-02, 2.4751412543080331e-02, 1.5510131997231313e-02, 9.2231946903286923e-03, 5.2039736325766575e-03, 2.7855275571971620e-03, 1.4142383035108275e-03, 6.8092260658474482e-04, 3.1084451589835123e-04, 1.3451233819198536e-04, 5.5163316323048505e-05, 2.1433661822155404e-05, 7.8882549269903193e-06, 2.7490144224436228e-06, 9.0687938435499206e-07, 2.8310992931625352e-07, 8.3606844554454458e-08, 2.3347964326766498e-08, 6.1632086713433375e-09, 1.5372205783801174e-09, 3.6211627179619072e-10, 8.0527347789629487e-11, 1.6897122210470246e-11, 3.3437645093788376e-12, 6.2370678258135157e-13, 1.0959822792780298e-13, 1.8132136826440378e-14, 2.8225916935311505e-15, 4.1316021764480691e-16, 5.6828205180213369e-17, 7.3396140181061249e-18, 8.8944609945993243e-19, 1.0105554063847399e-19, 1.0755595219737973e-20, 1.0714309730247980e-21, 9.9804891048351136e-23, 8.6851943617712193e-24, 7.0535560842160286e-25, 5.3404226168220292e-26, 3.7652687650201339e-27, 2.4692068347694563e-28, 1.5042535921639604e-29, 8.5019504368590908e-31, 4.4519543419059356e-32, 2.1566756583641779e-33, 9.6505627399970417e-35, 3.9824232345150253e-36, 1.5129382111557171e-37, 5.2817945954838791e-39, 1.6911721771605448e-40, 4.9561856762703143e-42, 1.3265135880257318e-43, 3.2349665837355912e-45, 7.1704184113766286e-47, 1.4407389710981317e-48, 2.6167460089856425e-50, 4.2830642136217272e-52, 6.2972157268746326e-54, 8.2874406983788114e-56, 9.7258603579728974e-58, 1.0136702052099045e-59, 9.3412200164700803e-62, 7.5746019148953009e-64, 5.3763688423964646e-66, 3.3212610596524388e-68, 1.7744839092477200e-70, 8.1431135103329952e-73, 3.1851858054210446e-75, 1.0529633740939257e-77, 2.9141025510545569e-80, 6.6801061673807505e-83, 1.2532102545185035e-85, 1.8979497846368726e-88, 2.2843171180826872e-91, 2.1456921017005163e-94, 1.5400245034982435e-97, 8.2372979129162400e-101, 3.1867892204083499e-104, 8.5990905704820439e-108, 1.5472021309193150e-111, 1.7535057075593614e-115, 1.1623859612267819e-119, 4.0785124308845132e-124, 6.5789265659620338e-129, 3.9475798303387850e-134, 6.2157350428501506e-140, 1.3181218114180107e-146, 6.8232197942250040e-155}, + {9.6764302762857911e-156, 1.9389386338649253e-147, 9.4268794388387584e-141, 6.1537049528839255e-135, 1.0520595245806230e-129, 6.6813621694344271e-125, 1.9486722540934962e-120, 3.0058398378782854e-116, 2.7101250640991562e-112, 1.5383037549430030e-108, 5.8195869131646608e-105, 1.5349872474118010e-101, 2.9274184968148517e-98, 4.1594648723850271e-95, 4.5147260427833628e-92, 3.8235833994762416e-89, 2.5729913678738507e-86, 1.3975076314494611e-83, 6.2111050589991735e-81, 2.2862048443444402e-78, 7.0441083482496365e-76, 1.8341247494924424e-73, 4.0702482203595230e-71, 7.7576584194845979e-69, 1.2786993882275677e-66, 1.8342905501305085e-64, 2.3031479777875351e-62, 2.5445408528816102e-60, 2.4855538228455434e-58, 2.1561995344944781e-56, 1.6679549705866419e-54, 1.1549259780000125e-52, 7.1833013403181687e-51, 4.0263574453603144e-49, 2.0400456628439797e-47, 9.3700002807816908e-46, 3.9116867251382951e-44, 1.4879647423347193e-42, 5.1693708373553046e-41, 1.6438042759677152e-39, 4.7942896465195374e-38, 1.2849980190682212e-36, 3.1708729314553754e-35, 7.2161081218241727e-34, 1.5169921976469880e-32, 2.9504597948207525e-31, 5.3168727228967571e-30, 8.8896336943576362e-29, 1.3808362593425483e-27, 1.9951324606202683e-26, 2.6846378493690218e-25, 3.3679964757574780e-24, 3.9436002250852672e-23, 4.3140992488603084e-22, 4.4134945997917874e-21, 4.2263869813792336e-20, 3.7916648002202093e-19, 3.1895272336827489e-18, 2.5176935915196902e-17, 1.8663270859468551e-16, 1.3001503435609439e-15, 8.5176175587843442e-15, 5.2510379021912937e-14, 3.0482099219006810e-13, 1.6671499873186635e-12, 8.5956677592000092e-12, 4.1801607084826671e-11, 1.9183890700529380e-10, 8.3123118452689150e-10, 3.4021150696080136e-09, 1.3158571431631216e-08, 4.8115154735048105e-08, 1.6639485157072335e-07, 5.4443385920665998e-07, 1.6859754012772494e-06, 4.9431447402619969e-06, 1.3725819438547434e-05, 3.6106464014912190e-05, 9.0004542316217840e-05, 2.1266213156628891e-04, 4.7639613833099480e-04, 1.0120395216254993e-03, 2.0392461173393923e-03, 3.8982490246164416e-03, 7.0709100790306376e-03, 1.2171895486539193e-02, 1.9887632287530231e-02, 3.0846667595353164e-02, 4.5424033501544080e-02, 6.3512773332392206e-02, 8.4328396273560896e-02, 1.0633035510412364e-01, 1.2733227690715612e-01, 1.4482336870308740e-01, 1.5644897465655389e-01, 1.6052761213288572e-01, 1.5644897465655389e-01, 1.4482336870308740e-01, 1.2733227690715612e-01, 1.0633035510412364e-01, 8.4328396273560896e-02, 6.3512773332392206e-02, 4.5424033501544080e-02, 3.0846667595353164e-02, 1.9887632287530231e-02, 1.2171895486539193e-02, 7.0709100790306376e-03, 3.8982490246164416e-03, 2.0392461173393923e-03, 1.0120395216254993e-03, 4.7639613833099480e-04, 2.1266213156628891e-04, 9.0004542316217840e-05, 3.6106464014912190e-05, 1.3725819438547434e-05, 4.9431447402619969e-06, 1.6859754012772494e-06, 5.4443385920665998e-07, 1.6639485157072335e-07, 4.8115154735048105e-08, 1.3158571431631216e-08, 3.4021150696080136e-09, 8.3123118452689150e-10, 1.9183890700529380e-10, 4.1801607084826671e-11, 8.5956677592000092e-12, 1.6671499873186635e-12, 3.0482099219006810e-13, 5.2510379021912937e-14, 8.5176175587843442e-15, 1.3001503435609439e-15, 1.8663270859468551e-16, 2.5176935915196902e-17, 3.1895272336827489e-18, 3.7916648002202093e-19, 4.2263869813792336e-20, 4.4134945997917874e-21, 4.3140992488603084e-22, 3.9436002250852672e-23, 3.3679964757574780e-24, 2.6846378493690218e-25, 1.9951324606202683e-26, 1.3808362593425483e-27, 8.8896336943576362e-29, 5.3168727228967571e-30, 2.9504597948207525e-31, 1.5169921976469880e-32, 7.2161081218241727e-34, 3.1708729314553754e-35, 1.2849980190682212e-36, 4.7942896465195374e-38, 1.6438042759677152e-39, 5.1693708373553046e-41, 1.4879647423347193e-42, 3.9116867251382951e-44, 9.3700002807816908e-46, 2.0400456628439797e-47, 4.0263574453603144e-49, 7.1833013403181687e-51, 1.1549259780000125e-52, 1.6679549705866419e-54, 2.1561995344944781e-56, 2.4855538228455434e-58, 2.5445408528816102e-60, 2.3031479777875351e-62, 1.8342905501305085e-64, 1.2786993882275677e-66, 7.7576584194845979e-69, 4.0702482203595230e-71, 1.8341247494924424e-73, 7.0441083482496365e-76, 2.2862048443444402e-78, 6.2111050589991735e-81, 1.3975076314494611e-83, 2.5729913678738507e-86, 3.8235833994762416e-89, 4.5147260427833628e-92, 4.1594648723850271e-95, 2.9274184968148517e-98, 1.5349872474118010e-101, 5.8195869131646608e-105, 1.5383037549430030e-108, 2.7101250640991562e-112, 3.0058398378782854e-116, 1.9486722540934962e-120, 6.6813621694344271e-125, 1.0520595245806230e-129, 6.1537049528839255e-135, 9.4268794388387584e-141, 1.9389386338649253e-147, 9.6764302762857911e-156}, + {1.3720504154302014e-156, 2.8513090679363871e-148, 1.4291119261031478e-141, 9.5878345367776407e-136, 1.6813631090843168e-130, 1.0937641473652881e-125, 3.2642500496954800e-121, 5.1480442370317754e-117, 4.7425471562207601e-113, 2.7489983469746781e-109, 1.0615412978825736e-105, 2.8568935742124688e-102, 5.5574407262791218e-99, 8.0520048626328837e-96, 8.9097729474744936e-93, 7.6909567014190078e-90, 5.2740027603411657e-87, 2.9186112720938588e-84, 1.3214406564729561e-81, 4.9544462772840985e-79, 1.5547429149839197e-76, 4.1226034386806711e-74, 9.3161574688297957e-72, 1.8079563460381452e-69, 3.0341692292606370e-67, 4.4312923121519367e-65, 5.6644240327335667e-63, 6.3708774357395162e-61, 6.3351435391240280e-59, 5.5944362188420675e-57, 4.4053385520999193e-55, 3.1050807666511750e-53, 1.9659178072617245e-51, 1.1217013968671671e-49, 5.7853802707668581e-48, 2.7049816006551789e-46, 1.1495533915103732e-44, 4.4515141949278675e-43, 1.5743976688633690e-41, 5.0968507385634822e-40, 1.5134439954515047e-38, 4.1300163134837491e-37, 1.0376574212671890e-35, 2.4044973436406753e-34, 5.1472183288770750e-33, 1.0194603568070278e-31, 1.8709115794220601e-30, 3.1858380070837839e-29, 5.0402581729336372e-28, 7.4179265516977060e-27, 1.0167813330369454e-25, 1.2995016885518635e-24, 1.5502266336408172e-23, 1.7279241662380531e-22, 1.8012995272732974e-21, 1.7578400079602021e-20, 1.6072599968378759e-19, 1.3780640314290736e-18, 1.1088556613183840e-17, 8.3797787500377154e-17, 5.9519054533347666e-16, 3.9759844018964598e-15, 2.4996755476537754e-14, 1.4799417664726766e-13, 8.2563190162426826e-13, 4.3426586703108686e-12, 2.1547012918303077e-11, 1.0090299262094598e-10, 4.4618936758916388e-10, 1.8639520759198730e-09, 7.3594054861502447e-09, 2.7474235203608662e-08, 9.7018924643039030e-08, 3.2418977135736030e-07, 1.0254381425692049e-06, 3.0713815320154091e-06, 8.7138650801478641e-06, 2.3424552293210665e-05, 5.9681270208738333e-05, 1.4415391428196787e-04, 3.3017517124886084e-04, 7.1728665634025713e-04, 1.4783089544886255e-03, 2.8910036930282720e-03, 5.3656605093971325e-03, 9.4528407852602792e-03, 1.5810044685497838e-02, 2.5107070566959051e-02, 3.7862166097742164e-02, 5.4226226141723462e-02, 7.3764890309958767e-02, 9.5315208688082131e-02, 1.1699751277485990e-01, 1.3643214928471140e-01, 1.5114725119507466e-01, 1.5908860103657232e-01, 1.5908860103657232e-01, 1.5114725119507466e-01, 1.3643214928471140e-01, 1.1699751277485990e-01, 9.5315208688082131e-02, 7.3764890309958767e-02, 5.4226226141723462e-02, 3.7862166097742164e-02, 2.5107070566959051e-02, 1.5810044685497838e-02, 9.4528407852602792e-03, 5.3656605093971325e-03, 2.8910036930282720e-03, 1.4783089544886255e-03, 7.1728665634025713e-04, 3.3017517124886084e-04, 1.4415391428196787e-04, 5.9681270208738333e-05, 2.3424552293210665e-05, 8.7138650801478641e-06, 3.0713815320154091e-06, 1.0254381425692049e-06, 3.2418977135736030e-07, 9.7018924643039030e-08, 2.7474235203608662e-08, 7.3594054861502447e-09, 1.8639520759198730e-09, 4.4618936758916388e-10, 1.0090299262094598e-10, 2.1547012918303077e-11, 4.3426586703108686e-12, 8.2563190162426826e-13, 1.4799417664726766e-13, 2.4996755476537754e-14, 3.9759844018964598e-15, 5.9519054533347666e-16, 8.3797787500377154e-17, 1.1088556613183840e-17, 1.3780640314290736e-18, 1.6072599968378759e-19, 1.7578400079602021e-20, 1.8012995272732974e-21, 1.7279241662380531e-22, 1.5502266336408172e-23, 1.2995016885518635e-24, 1.0167813330369454e-25, 7.4179265516977060e-27, 5.0402581729336372e-28, 3.1858380070837839e-29, 1.8709115794220601e-30, 1.0194603568070278e-31, 5.1472183288770750e-33, 2.4044973436406753e-34, 1.0376574212671890e-35, 4.1300163134837491e-37, 1.5134439954515047e-38, 5.0968507385634822e-40, 1.5743976688633690e-41, 4.4515141949278675e-43, 1.1495533915103732e-44, 2.7049816006551789e-46, 5.7853802707668581e-48, 1.1217013968671671e-49, 1.9659178072617245e-51, 3.1050807666511750e-53, 4.4053385520999193e-55, 5.5944362188420675e-57, 6.3351435391240280e-59, 6.3708774357395162e-61, 5.6644240327335667e-63, 4.4312923121519367e-65, 3.0341692292606370e-67, 1.8079563460381452e-69, 9.3161574688297957e-72, 4.1226034386806711e-74, 1.5547429149839197e-76, 4.9544462772840985e-79, 1.3214406564729561e-81, 2.9186112720938588e-84, 5.2740027603411657e-87, 7.6909567014190078e-90, 8.9097729474744936e-93, 8.0520048626328837e-96, 5.5574407262791218e-99, 2.8568935742124688e-102, 1.0615412978825736e-105, 2.7489983469746781e-109, 4.7425471562207601e-113, 5.1480442370317754e-117, 3.2642500496954800e-121, 1.0937641473652881e-125, 1.6813631090843168e-130, 9.5878345367776407e-136, 1.4291119261031478e-141, 2.8513090679363871e-148, 1.3720504154302014e-156}, + {1.9451569748580915e-157, 4.1917692496623074e-149, 2.1656533203264049e-142, 1.4930848367233329e-136, 2.6854744034643652e-131, 1.7892892532014627e-126, 5.4637061901241444e-122, 8.8092712504606827e-118, 8.2912095929290215e-114, 4.9074274510768621e-110, 1.9341588617846345e-106, 5.3107713773093621e-103, 1.0536661811562218e-99, 1.5565848726847315e-96, 1.7557722156935769e-93, 1.5446161289516271e-90, 1.0792867414624379e-87, 6.0849467639302215e-85, 2.8063950432169120e-82, 1.0716703469936493e-79, 3.4248444263060510e-77, 9.2475643800642814e-75, 2.1277914455786410e-72, 4.2042110347158325e-70, 7.1831202945319969e-68, 1.0679652291289812e-65, 1.3896846788334397e-63, 1.5910268843395548e-61, 1.6104220743828299e-59, 1.4475542666378789e-57, 1.1602357060613541e-55, 8.3238465917891379e-54, 5.3641275790400676e-52, 3.1152601083577022e-50, 1.6354424962643853e-48, 7.7832174172965086e-47, 3.3668417110773493e-45, 1.3271170300689291e-43, 4.7778763656316077e-42, 1.5745422805731105e-40, 4.7595446906951574e-39, 1.3222509215279862e-37, 3.3821840940140512e-36, 7.9793659216047449e-35, 1.7391569791608673e-33, 3.5073691468931601e-32, 6.5544111912453122e-31, 1.1365779583643404e-29, 1.8312631014871582e-28, 2.7449324565145490e-27, 3.8322872065908508e-26, 4.9890778549827656e-25, 6.0629582449560457e-24, 6.8848488569478251e-23, 7.3125997647970303e-22, 7.2714081831677253e-21, 6.7751229891684194e-20, 5.9201437592343701e-19, 4.8552433914811921e-18, 3.7401100817855975e-17, 2.7081193971598301e-16, 1.8444288831090382e-15, 1.1823696121971421e-14, 7.1386313730701460e-14, 4.0616946929687980e-13, 2.1791052221508088e-12, 1.1029706356088577e-11, 5.2697432068365651e-11, 2.3777643019834690e-10, 1.0136912013567245e-09, 4.0850156582808148e-09, 1.5567430501187781e-08, 5.6124175036636782e-08, 1.9149546201420412e-07, 6.1858506291091545e-07, 1.8924364481789124e-06, 5.4848459956508166e-06, 1.5064725177098550e-05, 3.9222592074287836e-05, 9.6829305369002766e-05, 2.2671622856088540e-04, 5.0357752441741071e-04, 1.0613379467370166e-03, 2.1229194690909154e-03, 4.0307696130016573e-03, 7.2659539954360898e-03, 1.2437029172215985e-02, 2.0217282655364367e-02, 3.1215303196211058e-02, 4.5782692483561545e-02, 6.3792314106331613e-02, 8.4451401972617260e-02, 1.0623046970193420e-01, 1.2697592765070259e-01, 1.4422620485622731e-01, 1.5567971237666092e-01, 1.5969586284722317e-01, 1.5567971237666092e-01, 1.4422620485622731e-01, 1.2697592765070259e-01, 1.0623046970193420e-01, 8.4451401972617260e-02, 6.3792314106331613e-02, 4.5782692483561545e-02, 3.1215303196211058e-02, 2.0217282655364367e-02, 1.2437029172215985e-02, 7.2659539954360898e-03, 4.0307696130016573e-03, 2.1229194690909154e-03, 1.0613379467370166e-03, 5.0357752441741071e-04, 2.2671622856088540e-04, 9.6829305369002766e-05, 3.9222592074287836e-05, 1.5064725177098550e-05, 5.4848459956508166e-06, 1.8924364481789124e-06, 6.1858506291091545e-07, 1.9149546201420412e-07, 5.6124175036636782e-08, 1.5567430501187781e-08, 4.0850156582808148e-09, 1.0136912013567245e-09, 2.3777643019834690e-10, 5.2697432068365651e-11, 1.1029706356088577e-11, 2.1791052221508088e-12, 4.0616946929687980e-13, 7.1386313730701460e-14, 1.1823696121971421e-14, 1.8444288831090382e-15, 2.7081193971598301e-16, 3.7401100817855975e-17, 4.8552433914811921e-18, 5.9201437592343701e-19, 6.7751229891684194e-20, 7.2714081831677253e-21, 7.3125997647970303e-22, 6.8848488569478251e-23, 6.0629582449560457e-24, 4.9890778549827656e-25, 3.8322872065908508e-26, 2.7449324565145490e-27, 1.8312631014871582e-28, 1.1365779583643404e-29, 6.5544111912453122e-31, 3.5073691468931601e-32, 1.7391569791608673e-33, 7.9793659216047449e-35, 3.3821840940140512e-36, 1.3222509215279862e-37, 4.7595446906951574e-39, 1.5745422805731105e-40, 4.7778763656316077e-42, 1.3271170300689291e-43, 3.3668417110773493e-45, 7.7832174172965086e-47, 1.6354424962643853e-48, 3.1152601083577022e-50, 5.3641275790400676e-52, 8.3238465917891379e-54, 1.1602357060613541e-55, 1.4475542666378789e-57, 1.6104220743828299e-59, 1.5910268843395548e-61, 1.3896846788334397e-63, 1.0679652291289812e-65, 7.1831202945319969e-68, 4.2042110347158325e-70, 2.1277914455786410e-72, 9.2475643800642814e-75, 3.4248444263060510e-77, 1.0716703469936493e-79, 2.8063950432169120e-82, 6.0849467639302215e-85, 1.0792867414624379e-87, 1.5446161289516271e-90, 1.7557722156935769e-93, 1.5565848726847315e-96, 1.0536661811562218e-99, 5.3107713773093621e-103, 1.9341588617846345e-106, 4.9074274510768621e-110, 8.2912095929290215e-114, 8.8092712504606827e-118, 5.4637061901241444e-122, 1.7892892532014627e-126, 2.6854744034643652e-131, 1.4930848367233329e-136, 2.1656533203264049e-142, 4.1917692496623074e-149, 1.9451569748580915e-157}, + {2.7572081394930497e-158, 6.1606195891114038e-150, 3.2804813831912987e-143, 2.3239698294632731e-137, 4.2866809471010448e-132, 2.9250839726119467e-127, 9.1380522604480418e-123, 1.5061298645822260e-118, 1.4481443283610901e-114, 8.7515402609102180e-111, 3.5201601974984495e-107, 9.8605307314410817e-104, 1.9951459370163873e-100, 3.0050341197440912e-97, 3.4549517863933081e-94, 3.0974015995404665e-91, 2.2051316618251230e-88, 1.2664932443877347e-85, 5.9494906351077990e-83, 2.3137758798623088e-80, 7.5297591329388192e-78, 2.0701649292513591e-75, 4.8496085133984147e-73, 9.7550576247941725e-71, 1.6966738887834285e-68, 2.5677846130096429e-66, 3.4010587398231950e-64, 3.9632860731065032e-62, 4.0830488118084828e-60, 3.7353956966630745e-58, 3.0471769779359536e-56, 2.2249520894879323e-54, 1.4592805785267631e-52, 8.6253646389571326e-51, 4.6085517173721152e-49, 2.2322309293391554e-47, 9.8278883256522070e-46, 3.9428752392560041e-44, 1.4448263309190163e-42, 4.8464578191552559e-41, 1.4912109536234187e-39, 4.2170331394849629e-38, 1.0980633083650227e-36, 2.6372704388350129e-35, 5.8519678162563370e-34, 1.2015551933775674e-32, 2.2862239823374585e-31, 4.0367549228098398e-30, 6.6230590346823284e-29, 1.0109795409268771e-27, 1.4374775988383664e-26, 1.9060160602736751e-25, 2.3593174689076554e-24, 2.7291375088225280e-23, 2.9530245244292184e-22, 2.9916750627894004e-21, 2.8402168199630962e-20, 2.5289725099536307e-19, 2.1136880764547752e-18, 1.6594882054957410e-17, 1.2247874128456919e-16, 8.5035945941928308e-16, 5.5576041209463139e-15, 3.4212940713768145e-14, 1.9850553217879612e-13, 1.0861345804029464e-12, 5.6073947890454799e-12, 2.7329486591769151e-11, 1.2580856861713816e-10, 5.4727113377318889e-10, 2.2506273484860213e-09, 8.7538457447490308e-09, 3.2215483374955876e-08, 1.1221944492414074e-07, 3.7014154510322367e-07, 1.1564156154340975e-06, 3.4233275145786425e-06, 9.6051781722267405e-06, 2.5551197899130104e-05, 6.4459196331247565e-05, 1.5425452576992943e-04, 3.5024735925131938e-04, 7.5473297532327498e-04, 1.5437752230132358e-03, 2.9979972233121189e-03, 5.5285649600795095e-03, 9.6827528386239439e-03, 1.6108512025371353e-02, 2.5458972192611309e-02, 3.8230305479849361e-02, 5.4550997194724032e-02, 7.3971809106191291e-02, 9.5330768912038982e-02, 1.1677021831583778e-01, 1.3595220139257186e-01, 1.5045713397116045e-01, 1.5827896015320714e-01, 1.5827896015320714e-01, 1.5045713397116045e-01, 1.3595220139257186e-01, 1.1677021831583778e-01, 9.5330768912038982e-02, 7.3971809106191291e-02, 5.4550997194724032e-02, 3.8230305479849361e-02, 2.5458972192611309e-02, 1.6108512025371353e-02, 9.6827528386239439e-03, 5.5285649600795095e-03, 2.9979972233121189e-03, 1.5437752230132358e-03, 7.5473297532327498e-04, 3.5024735925131938e-04, 1.5425452576992943e-04, 6.4459196331247565e-05, 2.5551197899130104e-05, 9.6051781722267405e-06, 3.4233275145786425e-06, 1.1564156154340975e-06, 3.7014154510322367e-07, 1.1221944492414074e-07, 3.2215483374955876e-08, 8.7538457447490308e-09, 2.2506273484860213e-09, 5.4727113377318889e-10, 1.2580856861713816e-10, 2.7329486591769151e-11, 5.6073947890454799e-12, 1.0861345804029464e-12, 1.9850553217879612e-13, 3.4212940713768145e-14, 5.5576041209463139e-15, 8.5035945941928308e-16, 1.2247874128456919e-16, 1.6594882054957410e-17, 2.1136880764547752e-18, 2.5289725099536307e-19, 2.8402168199630962e-20, 2.9916750627894004e-21, 2.9530245244292184e-22, 2.7291375088225280e-23, 2.3593174689076554e-24, 1.9060160602736751e-25, 1.4374775988383664e-26, 1.0109795409268771e-27, 6.6230590346823284e-29, 4.0367549228098398e-30, 2.2862239823374585e-31, 1.2015551933775674e-32, 5.8519678162563370e-34, 2.6372704388350129e-35, 1.0980633083650227e-36, 4.2170331394849629e-38, 1.4912109536234187e-39, 4.8464578191552559e-41, 1.4448263309190163e-42, 3.9428752392560041e-44, 9.8278883256522070e-46, 2.2322309293391554e-47, 4.6085517173721152e-49, 8.6253646389571326e-51, 1.4592805785267631e-52, 2.2249520894879323e-54, 3.0471769779359536e-56, 3.7353956966630745e-58, 4.0830488118084828e-60, 3.9632860731065032e-62, 3.4010587398231950e-64, 2.5677846130096429e-66, 1.6966738887834285e-68, 9.7550576247941725e-71, 4.8496085133984147e-73, 2.0701649292513591e-75, 7.5297591329388192e-78, 2.3137758798623088e-80, 5.9494906351077990e-83, 1.2664932443877347e-85, 2.2051316618251230e-88, 3.0974015995404665e-91, 3.4549517863933081e-94, 3.0050341197440912e-97, 1.9951459370163873e-100, 9.8605307314410817e-104, 3.5201601974984495e-107, 8.7515402609102180e-111, 1.4481443283610901e-114, 1.5061298645822260e-118, 9.1380522604480418e-123, 2.9250839726119467e-127, 4.2866809471010448e-132, 2.3239698294632731e-137, 3.2804813831912987e-143, 6.1606195891114038e-150, 2.7572081394930497e-158}, + {3.9076471690941080e-159, 9.0516231985655450e-151, 4.9672234319145855e-144, 3.6154341661312203e-138, 6.8385535268994495e-133, 4.7785893786651104e-128, 1.5271628772769884e-123, 2.5728411822428113e-119, 2.5269536248805626e-115, 1.5590872025715406e-111, 6.3995909265162004e-108, 1.8286346030132772e-104, 3.7730702714400253e-101, 5.7934780549600130e-98, 6.7888152108219864e-95, 6.2017960981784824e-92, 4.4982131286438984e-89, 2.6316100628013750e-86, 1.2590645102017268e-83, 4.9863539974326119e-81, 1.6522944213413452e-78, 4.6250118175679923e-76, 1.1030078970560833e-73, 2.2585685158900422e-71, 3.9985750751823772e-69, 6.1594934342804038e-67, 8.3034758916801791e-65, 9.8479077342924136e-63, 1.0325295240318946e-60, 9.6133222464273388e-59, 7.9807919503856858e-57, 5.9302840185272367e-55, 3.9582000609173701e-53, 2.3808961922219179e-51, 1.2945943475503535e-49, 6.3814434194007278e-48, 2.8592815645992017e-46, 1.1674410264648282e-44, 4.3538446893851820e-43, 1.4863772701012763e-41, 4.6548397931087811e-40, 1.3398281145584983e-38, 3.5510998957536425e-37, 8.6816489289737604e-36, 1.9610184560405483e-34, 4.0989946034555524e-33, 7.9401630700838486e-32, 1.4273966207691636e-30, 2.3845069143279796e-29, 3.7062734865446578e-28, 5.3663645149930618e-27, 7.2463592171380759e-26, 9.1353566359276092e-25, 1.0763247315298265e-23, 1.1863095918086436e-22, 1.2243177639523886e-21, 1.1841779286732196e-20, 1.0743199749303155e-19, 9.1494332489911347e-19, 7.3203566611052359e-18, 5.5063768554293231e-17, 3.8967149070515473e-16, 2.5960894208342548e-15, 1.6293142388397836e-14, 9.6386743368990212e-14, 5.3778391218729220e-13, 2.8314924455552075e-12, 1.4075632287720228e-11, 6.6097087557103094e-11, 2.9333592912411779e-10, 1.2308733220895705e-09, 4.8855519350876319e-09, 1.8350327790289198e-08, 6.5248828381395632e-08, 2.1971536691628579e-07, 7.0090428369282574e-07, 2.1189035330905069e-06, 6.0723051489799535e-06, 1.6501142336395539e-05, 4.2531734642799478e-05, 1.0400739885143485e-04, 2.4136469790269507e-04, 5.3166865805501619e-04, 1.1118823380073424e-03, 2.2080714903093502e-03, 4.1646982803793314e-03, 7.4617948415810062e-03, 1.2701628295481309e-02, 2.0544362511894173e-02, 3.1578965559564402e-02, 4.6134295845117745e-02, 6.4063927714297891e-02, 8.4567589743710897e-02, 1.0612711013185427e-01, 1.2662114600203433e-01, 1.4363605547026137e-01, 1.5492166682336009e-01, 1.5887690970441684e-01, 1.5492166682336009e-01, 1.4363605547026137e-01, 1.2662114600203433e-01, 1.0612711013185427e-01, 8.4567589743710897e-02, 6.4063927714297891e-02, 4.6134295845117745e-02, 3.1578965559564402e-02, 2.0544362511894173e-02, 1.2701628295481309e-02, 7.4617948415810062e-03, 4.1646982803793314e-03, 2.2080714903093502e-03, 1.1118823380073424e-03, 5.3166865805501619e-04, 2.4136469790269507e-04, 1.0400739885143485e-04, 4.2531734642799478e-05, 1.6501142336395539e-05, 6.0723051489799535e-06, 2.1189035330905069e-06, 7.0090428369282574e-07, 2.1971536691628579e-07, 6.5248828381395632e-08, 1.8350327790289198e-08, 4.8855519350876319e-09, 1.2308733220895705e-09, 2.9333592912411779e-10, 6.6097087557103094e-11, 1.4075632287720228e-11, 2.8314924455552075e-12, 5.3778391218729220e-13, 9.6386743368990212e-14, 1.6293142388397836e-14, 2.5960894208342548e-15, 3.8967149070515473e-16, 5.5063768554293231e-17, 7.3203566611052359e-18, 9.1494332489911347e-19, 1.0743199749303155e-19, 1.1841779286732196e-20, 1.2243177639523886e-21, 1.1863095918086436e-22, 1.0763247315298265e-23, 9.1353566359276092e-25, 7.2463592171380759e-26, 5.3663645149930618e-27, 3.7062734865446578e-28, 2.3845069143279796e-29, 1.4273966207691636e-30, 7.9401630700838486e-32, 4.0989946034555524e-33, 1.9610184560405483e-34, 8.6816489289737604e-36, 3.5510998957536425e-37, 1.3398281145584983e-38, 4.6548397931087811e-40, 1.4863772701012763e-41, 4.3538446893851820e-43, 1.1674410264648282e-44, 2.8592815645992017e-46, 6.3814434194007278e-48, 1.2945943475503535e-49, 2.3808961922219179e-51, 3.9582000609173701e-53, 5.9302840185272367e-55, 7.9807919503856858e-57, 9.6133222464273388e-59, 1.0325295240318946e-60, 9.8479077342924136e-63, 8.3034758916801791e-65, 6.1594934342804038e-67, 3.9985750751823772e-69, 2.2585685158900422e-71, 1.1030078970560833e-73, 4.6250118175679923e-76, 1.6522944213413452e-78, 4.9863539974326119e-81, 1.2590645102017268e-83, 2.6316100628013750e-86, 4.4982131286438984e-89, 6.2017960981784824e-92, 6.7888152108219864e-95, 5.7934780549600130e-98, 3.7730702714400253e-101, 1.8286346030132772e-104, 6.3995909265162004e-108, 1.5590872025715406e-111, 2.5269536248805626e-115, 2.5728411822428113e-119, 1.5271628772769884e-123, 4.7785893786651104e-128, 6.8385535268994495e-133, 3.6154341661312203e-138, 4.9672234319145855e-144, 9.0516231985655450e-151, 3.9076471690941080e-159}, + {5.5372309477634655e-160, 1.3295499920372636e-151, 7.5182851789608105e-145, 5.6218117631932678e-139, 1.0903164404085858e-133, 7.8013060714659609e-129, 2.5502660858886434e-124, 4.3913191972243959e-120, 4.4053240904063359e-116, 2.7746976743925027e-112, 1.1621599260631149e-108, 3.3872112245822123e-105, 7.1263773535131733e-102, 1.1154449265558409e-98, 1.3320789562852151e-95, 1.2398999039839109e-92, 9.1613585633591115e-90, 5.4590825264344227e-87, 2.6598715295190543e-84, 1.0726407876436278e-81, 3.6188278671651930e-79, 1.0312393292677344e-76, 2.5035350436180196e-74, 5.2179989944251382e-72, 9.4025005576362417e-70, 1.4740979038429450e-67, 2.0223861173713801e-65, 2.4409225876304963e-63, 2.6043821060405426e-61, 2.4675003119821257e-59, 2.0845067543701599e-57, 1.5761631000101791e-55, 1.0705056723174281e-53, 6.5523461103489109e-52, 3.6254089691585309e-50, 1.8184989576075493e-48, 8.2913990414809887e-47, 3.4450097830357403e-45, 1.3074430076121838e-43, 4.5423930481987850e-42, 1.4477028628289723e-40, 4.2408968311262046e-39, 1.1439892419798912e-37, 2.8466218480726145e-36, 6.5448147609160573e-35, 1.3925226088255375e-33, 2.7459089931491756e-32, 5.0252446557042918e-31, 8.5465806757782117e-30, 1.3525065257212417e-28, 1.9939689031724527e-27, 2.7417253568038711e-26, 3.5198681528057952e-25, 4.2235075145104786e-24, 4.7412259196608422e-23, 4.9840723225381343e-22, 4.9106724438195655e-21, 4.5386744987288709e-20, 3.9382188462775671e-19, 3.2106160083645321e-18, 2.4610138689948007e-17, 1.7749316371092158e-16, 1.2052626919006545e-15, 7.7106596673007474e-15, 4.6502415038307999e-14, 2.6453661839732785e-13, 1.4202436007691954e-12, 7.2000553706787476e-12, 3.4484441377850428e-11, 1.5611080651132002e-10, 6.6828734274332115e-10, 2.7064654297770221e-09, 1.0373610614267088e-08, 3.7645745874679117e-08, 1.2939635385192320e-07, 4.2140690642224546e-07, 1.3007683229247929e-06, 3.8067496326313364e-06, 1.0565607635971951e-05, 2.7819080771995885e-05, 6.9504723426630250e-05, 1.6482276370905397e-04, 3.7106723611638040e-04, 7.9325913151483628e-04, 1.6106180017909323e-03, 3.1064654644112318e-03, 5.6926204501420372e-03, 9.9128527364234706e-03, 1.6405471669264392e-02, 2.5807108029946707e-02, 3.8592374515300572e-02, 5.4868153810335302e-02, 7.4171189043357108e-02, 9.5341025218153283e-02, 1.1654188378760408e-01, 1.3547657485442111e-01, 1.4977628436985038e-01, 1.5748155504372183e-01, 1.5748155504372183e-01, 1.4977628436985038e-01, 1.3547657485442111e-01, 1.1654188378760408e-01, 9.5341025218153283e-02, 7.4171189043357108e-02, 5.4868153810335302e-02, 3.8592374515300572e-02, 2.5807108029946707e-02, 1.6405471669264392e-02, 9.9128527364234706e-03, 5.6926204501420372e-03, 3.1064654644112318e-03, 1.6106180017909323e-03, 7.9325913151483628e-04, 3.7106723611638040e-04, 1.6482276370905397e-04, 6.9504723426630250e-05, 2.7819080771995885e-05, 1.0565607635971951e-05, 3.8067496326313364e-06, 1.3007683229247929e-06, 4.2140690642224546e-07, 1.2939635385192320e-07, 3.7645745874679117e-08, 1.0373610614267088e-08, 2.7064654297770221e-09, 6.6828734274332115e-10, 1.5611080651132002e-10, 3.4484441377850428e-11, 7.2000553706787476e-12, 1.4202436007691954e-12, 2.6453661839732785e-13, 4.6502415038307999e-14, 7.7106596673007474e-15, 1.2052626919006545e-15, 1.7749316371092158e-16, 2.4610138689948007e-17, 3.2106160083645321e-18, 3.9382188462775671e-19, 4.5386744987288709e-20, 4.9106724438195655e-21, 4.9840723225381343e-22, 4.7412259196608422e-23, 4.2235075145104786e-24, 3.5198681528057952e-25, 2.7417253568038711e-26, 1.9939689031724527e-27, 1.3525065257212417e-28, 8.5465806757782117e-30, 5.0252446557042918e-31, 2.7459089931491756e-32, 1.3925226088255375e-33, 6.5448147609160573e-35, 2.8466218480726145e-36, 1.1439892419798912e-37, 4.2408968311262046e-39, 1.4477028628289723e-40, 4.5423930481987850e-42, 1.3074430076121838e-43, 3.4450097830357403e-45, 8.2913990414809887e-47, 1.8184989576075493e-48, 3.6254089691585309e-50, 6.5523461103489109e-52, 1.0705056723174281e-53, 1.5761631000101791e-55, 2.0845067543701599e-57, 2.4675003119821257e-59, 2.6043821060405426e-61, 2.4409225876304963e-63, 2.0223861173713801e-65, 1.4740979038429450e-67, 9.4025005576362417e-70, 5.2179989944251382e-72, 2.5035350436180196e-74, 1.0312393292677344e-76, 3.6188278671651930e-79, 1.0726407876436278e-81, 2.6598715295190543e-84, 5.4590825264344227e-87, 9.1613585633591115e-90, 1.2398999039839109e-92, 1.3320789562852151e-95, 1.1154449265558409e-98, 7.1263773535131733e-102, 3.3872112245822123e-105, 1.1621599260631149e-108, 2.7746976743925027e-112, 4.4053240904063359e-116, 4.3913191972243959e-120, 2.5502660858886434e-124, 7.8013060714659609e-129, 1.0903164404085858e-133, 5.6218117631932678e-139, 7.5182851789608105e-145, 1.3295499920372636e-151, 5.5372309477634655e-160}, + {7.8451635230016858e-161, 1.9523607750140259e-152, 1.1375077401246616e-145, 8.7373530318096058e-140, 1.7373540565570015e-134, 1.2727518873570116e-129, 4.2555627733290781e-125, 7.4887926040201802e-121, 7.6728599246194710e-117, 4.9331494690374170e-113, 2.1081805704508371e-109, 6.2668746307989698e-106, 1.3443162713188522e-102, 2.1447717307711369e-99, 2.6100910182768806e-96, 2.4752041309788718e-93, 1.8629470575327606e-90, 1.1305871177614866e-87, 5.6095106427386894e-85, 2.3032570747054949e-82, 7.9109829843002634e-80, 2.2948435687570354e-77, 5.6707499982586783e-75, 1.2029596296647568e-72, 2.2060845936398770e-70, 3.5197550034683429e-68, 4.9140189431762165e-66, 6.0352629400444085e-64, 6.5524291595185267e-62, 6.3168313216462770e-60, 5.4297718879402538e-58, 4.1774383436193032e-56, 2.8868574992210366e-54, 1.7978766039740882e-52, 1.0121575932082767e-50, 5.1657784424151435e-49, 2.3965562741555340e-47, 1.0131990990489010e-45, 3.9127390924870208e-44, 1.3832722270346481e-42, 4.4862136218811265e-41, 1.3373657357984576e-39, 3.6713213079441595e-38, 9.2972768440223579e-37, 2.1755444131733555e-35, 4.7112703089400342e-34, 9.4560355326075165e-33, 1.7615330473782583e-31, 3.0497304146140982e-30, 4.9132641478669298e-29, 7.3745987634168783e-28, 1.0324336757120609e-26, 1.3496248520015288e-25, 1.6490733800656049e-24, 1.8852558386853772e-23, 2.0184180321625388e-22, 2.0255846228536046e-21, 1.9070317011573267e-20, 1.6857232563417842e-19, 1.4001409738252677e-18, 1.0935411714915941e-17, 8.0367861053116616e-17, 5.5616740488492008e-16, 3.6264613629986606e-15, 2.2293626576566599e-14, 1.2928616191624445e-13, 7.0768307534960783e-13, 3.6582348996540792e-12, 1.7867762742843070e-11, 8.2498114987726634e-11, 3.6024058170237729e-10, 1.4883529382284672e-09, 5.8205576663344680e-09, 2.1554622191079048e-08, 7.5613014701765766e-08, 2.5135518772343285e-07, 7.9206548159012504e-07, 2.3667653844440894e-06, 6.7081316695963449e-06, 1.8039486708167727e-05, 4.6040475362243668e-05, 1.1154709040626857e-04, 2.5661526702463013e-04, 5.6067195570805187e-04, 1.1636625437784563e-03, 2.2946716387392549e-03, 4.2999800431004790e-03, 7.6583588130546571e-03, 1.2965620087982580e-02, 2.0868833143304531e-02, 3.1937686193532246e-02, 4.6478966725271985e-02, 6.4327817062627538e-02, 8.4677189450608162e-02, 1.0602045179435517e-01, 1.2626797462143288e-01, 1.4305279328441931e-01, 1.5417456855130846e-01, 1.5807042792926745e-01, 1.5417456855130846e-01, 1.4305279328441931e-01, 1.2626797462143288e-01, 1.0602045179435517e-01, 8.4677189450608162e-02, 6.4327817062627538e-02, 4.6478966725271985e-02, 3.1937686193532246e-02, 2.0868833143304531e-02, 1.2965620087982580e-02, 7.6583588130546571e-03, 4.2999800431004790e-03, 2.2946716387392549e-03, 1.1636625437784563e-03, 5.6067195570805187e-04, 2.5661526702463013e-04, 1.1154709040626857e-04, 4.6040475362243668e-05, 1.8039486708167727e-05, 6.7081316695963449e-06, 2.3667653844440894e-06, 7.9206548159012504e-07, 2.5135518772343285e-07, 7.5613014701765766e-08, 2.1554622191079048e-08, 5.8205576663344680e-09, 1.4883529382284672e-09, 3.6024058170237729e-10, 8.2498114987726634e-11, 1.7867762742843070e-11, 3.6582348996540792e-12, 7.0768307534960783e-13, 1.2928616191624445e-13, 2.2293626576566599e-14, 3.6264613629986606e-15, 5.5616740488492008e-16, 8.0367861053116616e-17, 1.0935411714915941e-17, 1.4001409738252677e-18, 1.6857232563417842e-19, 1.9070317011573267e-20, 2.0255846228536046e-21, 2.0184180321625388e-22, 1.8852558386853772e-23, 1.6490733800656049e-24, 1.3496248520015288e-25, 1.0324336757120609e-26, 7.3745987634168783e-28, 4.9132641478669298e-29, 3.0497304146140982e-30, 1.7615330473782583e-31, 9.4560355326075165e-33, 4.7112703089400342e-34, 2.1755444131733555e-35, 9.2972768440223579e-37, 3.6713213079441595e-38, 1.3373657357984576e-39, 4.4862136218811265e-41, 1.3832722270346481e-42, 3.9127390924870208e-44, 1.0131990990489010e-45, 2.3965562741555340e-47, 5.1657784424151435e-49, 1.0121575932082767e-50, 1.7978766039740882e-52, 2.8868574992210366e-54, 4.1774383436193032e-56, 5.4297718879402538e-58, 6.3168313216462770e-60, 6.5524291595185267e-62, 6.0352629400444085e-64, 4.9140189431762165e-66, 3.5197550034683429e-68, 2.2060845936398770e-70, 1.2029596296647568e-72, 5.6707499982586783e-75, 2.2948435687570354e-77, 7.9109829843002634e-80, 2.3032570747054949e-82, 5.6095106427386894e-85, 1.1305871177614866e-87, 1.8629470575327606e-90, 2.4752041309788718e-93, 2.6100910182768806e-96, 2.1447717307711369e-99, 1.3443162713188522e-102, 6.2668746307989698e-106, 2.1081805704508371e-109, 4.9331494690374170e-113, 7.6728599246194710e-117, 7.4887926040201802e-121, 4.2555627733290781e-125, 1.2727518873570116e-129, 1.7373540565570015e-134, 8.7373530318096058e-140, 1.1375077401246616e-145, 1.9523607750140259e-152, 7.8451635230016858e-161}, + {1.1113325242665607e-161, 2.8661157405088651e-153, 1.7203699801925772e-146, 1.3572912678569801e-140, 2.7667745801693423e-135, 2.0750643806729351e-130, 7.0958232027421688e-126, 1.2760468594731325e-121, 1.3351777371855847e-117, 8.7619375020369923e-114, 3.8201658326880149e-110, 1.1581310985408031e-106, 2.5327817240407812e-103, 4.1185419255140006e-100, 5.1071272449783039e-97, 4.9339716820592914e-94, 3.7824070114676548e-91, 2.3376600104580566e-88, 1.1809947785806983e-85, 4.9369057800338342e-83, 1.7261669173831611e-80, 5.0968500275659627e-78, 1.2818807628470368e-75, 2.7674728413631406e-73, 5.1647694116231104e-71, 8.3851919880334988e-69, 1.1912098546399618e-66, 1.4886103795423663e-64, 1.6443955400649481e-62, 1.6129133242366921e-60, 1.4105633288272223e-58, 1.1041151603377387e-56, 7.7628198468094521e-55, 4.9186136364477312e-53, 2.8172193314312900e-51, 1.4628544044995270e-49, 6.9047962388108693e-48, 2.9700444136624115e-46, 1.1669783057995060e-44, 4.1977240232717920e-43, 1.3852328747381678e-41, 4.2018792516358609e-40, 1.1737667874934990e-38, 3.0248112870289189e-37, 7.2029787582674604e-36, 1.5874640120654814e-34, 3.2427846726141820e-33, 6.1484526840191010e-32, 1.0834946554226288e-30, 1.7768523467499803e-29, 2.7149541158618372e-28, 3.8695229489123667e-27, 5.1500223036312467e-26, 6.4071917092815282e-25, 7.4586793696524265e-24, 8.1320524064342075e-23, 8.3113512372523795e-22, 7.9697999021291434e-21, 7.1759828546746257e-20, 6.0717113565204395e-19, 4.8312403419891758e-18, 3.6176893189785955e-17, 2.5510691957075621e-16, 1.6951627656128116e-15, 1.0621010070430722e-14, 6.2782746989491113e-14, 3.5033054765081019e-13, 1.8463363234967078e-12, 9.1951726021293097e-12, 4.3294831001094053e-11, 1.9281472420443613e-10, 8.1257537810009703e-10, 3.2418174605425769e-09, 1.2248647054749650e-08, 4.3845698417608257e-08, 1.4875155394404803e-07, 4.7845376510326057e-07, 1.4594959469005024e-06, 4.2236041008124797e-06, 1.1598624726140732e-05, 3.0233694291010849e-05, 7.4825364488004140e-05, 1.7586687773524874e-04, 3.9264033171199677e-04, 8.3286186061158249e-04, 1.6788174607182051e-03, 3.2163656781061659e-03, 5.8577616753894349e-03, 1.0143065156003795e-02, 1.6700865101051256e-02, 2.6151472056325592e-02, 3.8948449958622955e-02, 5.5177861430971059e-02, 7.4363251819021731e-02, 9.5346186707308309e-02, 1.1631262299580138e-01, 1.3500522787142605e-01, 1.4910449946872065e-01, 1.5669608061804552e-01, 1.5669608061804552e-01, 1.4910449946872065e-01, 1.3500522787142605e-01, 1.1631262299580138e-01, 9.5346186707308309e-02, 7.4363251819021731e-02, 5.5177861430971059e-02, 3.8948449958622955e-02, 2.6151472056325592e-02, 1.6700865101051256e-02, 1.0143065156003795e-02, 5.8577616753894349e-03, 3.2163656781061659e-03, 1.6788174607182051e-03, 8.3286186061158249e-04, 3.9264033171199677e-04, 1.7586687773524874e-04, 7.4825364488004140e-05, 3.0233694291010849e-05, 1.1598624726140732e-05, 4.2236041008124797e-06, 1.4594959469005024e-06, 4.7845376510326057e-07, 1.4875155394404803e-07, 4.3845698417608257e-08, 1.2248647054749650e-08, 3.2418174605425769e-09, 8.1257537810009703e-10, 1.9281472420443613e-10, 4.3294831001094053e-11, 9.1951726021293097e-12, 1.8463363234967078e-12, 3.5033054765081019e-13, 6.2782746989491113e-14, 1.0621010070430722e-14, 1.6951627656128116e-15, 2.5510691957075621e-16, 3.6176893189785955e-17, 4.8312403419891758e-18, 6.0717113565204395e-19, 7.1759828546746257e-20, 7.9697999021291434e-21, 8.3113512372523795e-22, 8.1320524064342075e-23, 7.4586793696524265e-24, 6.4071917092815282e-25, 5.1500223036312467e-26, 3.8695229489123667e-27, 2.7149541158618372e-28, 1.7768523467499803e-29, 1.0834946554226288e-30, 6.1484526840191010e-32, 3.2427846726141820e-33, 1.5874640120654814e-34, 7.2029787582674604e-36, 3.0248112870289189e-37, 1.1737667874934990e-38, 4.2018792516358609e-40, 1.3852328747381678e-41, 4.1977240232717920e-43, 1.1669783057995060e-44, 2.9700444136624115e-46, 6.9047962388108693e-48, 1.4628544044995270e-49, 2.8172193314312900e-51, 4.9186136364477312e-53, 7.7628198468094521e-55, 1.1041151603377387e-56, 1.4105633288272223e-58, 1.6129133242366921e-60, 1.6443955400649481e-62, 1.4886103795423663e-64, 1.1912098546399618e-66, 8.3851919880334988e-69, 5.1647694116231104e-71, 2.7674728413631406e-73, 1.2818807628470368e-75, 5.0968500275659627e-78, 1.7261669173831611e-80, 4.9369057800338342e-83, 1.1809947785806983e-85, 2.3376600104580566e-88, 3.7824070114676548e-91, 4.9339716820592914e-94, 5.1071272449783039e-97, 4.1185419255140006e-100, 2.5327817240407812e-103, 1.1581310985408031e-106, 3.8201658326880149e-110, 8.7619375020369923e-114, 1.3351777371855847e-117, 1.2760468594731325e-121, 7.0958232027421688e-126, 2.0750643806729351e-130, 2.7667745801693423e-135, 1.3572912678569801e-140, 1.7203699801925772e-146, 2.8661157405088651e-153, 1.1113325242665607e-161}, + {1.5740526693584465e-162, 4.2063621518212007e-154, 2.6008944296538456e-147, 2.1074517218240589e-141, 4.4036325515199439e-136, 3.3809077673415763e-131, 1.1822946408488032e-126, 2.1725144459735252e-122, 2.3212763347728001e-118, 1.5547020684816359e-114, 6.9150182989560957e-111, 2.1377995126059837e-107, 4.7660941708469085e-104, 7.8984266909061953e-101, 9.9792660546750878e-98, 9.8208576850538984e-95, 7.6677750665974574e-92, 4.8256764019125120e-89, 2.4821990706514334e-86, 1.0563282231662235e-83, 3.7595217722773437e-81, 1.1298318188883590e-78, 2.8919012660409682e-76, 6.3534513888384988e-74, 1.2065320173749644e-71, 1.9931390693715852e-69, 2.8809012333842463e-67, 3.6628479225209667e-65, 4.1164923961054212e-63, 4.1077464167348542e-61, 3.6546677508675100e-59, 2.9102221244239064e-57, 2.0815358697976881e-55, 1.3417085980893448e-53, 7.8178603818978630e-52, 4.1297412217775072e-50, 1.9830414431093633e-48, 8.6778002491153641e-47, 3.4688352621558211e-45, 1.2694602644562695e-43, 4.2621053825441441e-42, 1.3153901362816908e-40, 3.7386729623017851e-39, 9.8033645273483504e-38, 2.3754629195463299e-36, 5.3274424573468086e-35, 1.1074717912785746e-33, 2.1369895498120545e-32, 3.8327370697542584e-31, 6.3974120073582433e-30, 9.9497591435745215e-29, 1.4435514631174776e-27, 1.9558597204465646e-26, 2.4773098248022596e-25, 2.9362302035583120e-24, 3.2596930342072210e-23, 3.3925841234631972e-22, 3.3130211274194918e-21, 3.0381735933104597e-20, 2.6183914995557019e-19, 2.1223329298239927e-18, 1.6190413502935239e-17, 1.1632214089861438e-16, 7.8760411702639125e-16, 5.0287848550079939e-15, 3.0295892003599562e-14, 1.7231158339195911e-13, 9.2573881503227024e-13, 4.7003287276740161e-12, 2.2565549953554105e-11, 1.0248110528690129e-10, 4.4046822285487214e-10, 1.7924282778278772e-09, 6.9087593674811365e-09, 2.5232222625609405e-08, 8.7350604983433712e-08, 2.8673524946820525e-07, 8.9277708976484127e-07, 2.6374622880097546e-06, 7.3949955626738131e-06, 1.9684213310007427e-05, 4.9755352753869857e-05, 1.1945642608697544e-04, 2.7247518029396975e-04, 5.9058909090482672e-04, 1.2166676013683477e-03, 2.3826889355841037e-03, 4.4365604655715969e-03, 7.8555741198391739e-03, 1.3228935168893997e-02, 2.1190659578816773e-02, 3.2291498859030154e-02, 4.6816827098479806e-02, 6.4584179655610197e-02, 8.4780422567999614e-02, 1.0591066198925958e-01, 1.2591645229378781e-01, 1.4247629387217531e-01, 1.5343815707202285e-01, 1.5727610417082902e-01, 1.5343815707202285e-01, 1.4247629387217531e-01, 1.2591645229378781e-01, 1.0591066198925958e-01, 8.4780422567999614e-02, 6.4584179655610197e-02, 4.6816827098479806e-02, 3.2291498859030154e-02, 2.1190659578816773e-02, 1.3228935168893997e-02, 7.8555741198391739e-03, 4.4365604655715969e-03, 2.3826889355841037e-03, 1.2166676013683477e-03, 5.9058909090482672e-04, 2.7247518029396975e-04, 1.1945642608697544e-04, 4.9755352753869857e-05, 1.9684213310007427e-05, 7.3949955626738131e-06, 2.6374622880097546e-06, 8.9277708976484127e-07, 2.8673524946820525e-07, 8.7350604983433712e-08, 2.5232222625609405e-08, 6.9087593674811365e-09, 1.7924282778278772e-09, 4.4046822285487214e-10, 1.0248110528690129e-10, 2.2565549953554105e-11, 4.7003287276740161e-12, 9.2573881503227024e-13, 1.7231158339195911e-13, 3.0295892003599562e-14, 5.0287848550079939e-15, 7.8760411702639125e-16, 1.1632214089861438e-16, 1.6190413502935239e-17, 2.1223329298239927e-18, 2.6183914995557019e-19, 3.0381735933104597e-20, 3.3130211274194918e-21, 3.3925841234631972e-22, 3.2596930342072210e-23, 2.9362302035583120e-24, 2.4773098248022596e-25, 1.9558597204465646e-26, 1.4435514631174776e-27, 9.9497591435745215e-29, 6.3974120073582433e-30, 3.8327370697542584e-31, 2.1369895498120545e-32, 1.1074717912785746e-33, 5.3274424573468086e-35, 2.3754629195463299e-36, 9.8033645273483504e-38, 3.7386729623017851e-39, 1.3153901362816908e-40, 4.2621053825441441e-42, 1.2694602644562695e-43, 3.4688352621558211e-45, 8.6778002491153641e-47, 1.9830414431093633e-48, 4.1297412217775072e-50, 7.8178603818978630e-52, 1.3417085980893448e-53, 2.0815358697976881e-55, 2.9102221244239064e-57, 3.6546677508675100e-59, 4.1077464167348542e-61, 4.1164923961054212e-63, 3.6628479225209667e-65, 2.8809012333842463e-67, 1.9931390693715852e-69, 1.2065320173749644e-71, 6.3534513888384988e-74, 2.8919012660409682e-76, 1.1298318188883590e-78, 3.7595217722773437e-81, 1.0563282231662235e-83, 2.4821990706514334e-86, 4.8256764019125120e-89, 7.6677750665974574e-92, 9.8208576850538984e-95, 9.9792660546750878e-98, 7.8984266909061953e-101, 4.7660941708469085e-104, 2.1377995126059837e-107, 6.9150182989560957e-111, 1.5547020684816359e-114, 2.3212763347728001e-118, 2.1725144459735252e-122, 1.1822946408488032e-126, 3.3809077673415763e-131, 4.4036325515199439e-136, 2.1074517218240589e-141, 2.6008944296538456e-147, 4.2063621518212007e-154, 1.5740526693584465e-162}, + {2.2290934963031539e-163, 6.1716304223418473e-155, 3.9305958509063355e-148, 3.2706601334834755e-142, 7.0049069648137550e-137, 5.5049260050287900e-132, 1.9684692530020812e-127, 3.6957545112422320e-123, 4.0320327117616306e-119, 2.7559362749699724e-115, 1.2503894738744883e-111, 3.9416969862084461e-108, 8.9577890237321700e-105, 1.5127860735379895e-101, 1.9472732376896783e-98, 1.9519789398323314e-95, 1.5520652579926001e-92, 9.9458309202670908e-90, 5.2083206235820379e-87, 2.2562215375682347e-84, 8.1731118972592471e-82, 2.4997514837476365e-79, 6.5111285362111366e-77, 1.4555888776738779e-74, 2.8125155025369667e-72, 4.7271089337772468e-70, 6.9513137370020262e-68, 8.9912466505154563e-66, 1.0279594830695334e-63, 1.0434894316959833e-61, 9.4440639857201346e-60, 7.6499247670821092e-58, 5.5658406725957325e-56, 3.6493796373809251e-54, 2.1630323514364711e-52, 1.1622901525905010e-50, 5.6773339224732908e-49, 2.5272570465088243e-47, 1.0276815273410889e-45, 3.8259457909463708e-44, 1.3067728287128299e-42, 4.1029828415971428e-41, 1.1864415902523173e-39, 3.1652198121078916e-38, 7.8035886293155777e-37, 1.7807430428966829e-35, 3.7667945725159055e-34, 7.3963969744653024e-33, 1.3499836949356773e-31, 2.2932424003565328e-30, 3.6300293183361797e-29, 5.3605436078106824e-28, 7.3930155412655720e-27, 9.5323773039462743e-26, 1.1502145928125925e-24, 1.3000662757028629e-23, 1.3776941782313042e-22, 1.3699807056265559e-21, 1.2794012136597428e-20, 1.1229742763811151e-19, 9.2710336687274256e-19, 7.2042972150393114e-18, 5.2729781171856177e-17, 3.6375048889083554e-16, 2.3664867578847666e-15, 1.4528301518132017e-14, 8.4213476872404286e-14, 4.6114644502136799e-13, 2.3867692880717110e-12, 1.1681801468249808e-11, 5.4092941845487156e-11, 2.3708105480750139e-10, 9.8392832670094020e-10, 3.8682673753498617e-09, 1.4411972185221586e-08, 5.0903013962041357e-08, 1.7050141340191249e-07, 5.4177677321026202e-07, 1.6336412605871983e-06, 4.6759044289293238e-06, 1.2707753951032874e-05, 3.2800534876023489e-05, 8.0428506528979537e-05, 1.8739476963256670e-04, 4.1497155710923123e-04, 8.7353709789879039e-04, 1.7483531042542699e-03, 3.3276551358222884e-03, 6.0239245919995622e-03, 1.0373317514267365e-02, 1.6994637482018023e-02, 2.6492061401939205e-02, 3.9298609227795579e-02, 5.5480282208033298e-02, 7.4548212057078664e-02, 9.5346453940664169e-02, 1.1608254348974273e-01, 1.3453811804025481e-01, 1.4844158241213595e-01, 1.5592224232989221e-01, 1.5592224232989221e-01, 1.4844158241213595e-01, 1.3453811804025481e-01, 1.1608254348974273e-01, 9.5346453940664169e-02, 7.4548212057078664e-02, 5.5480282208033298e-02, 3.9298609227795579e-02, 2.6492061401939205e-02, 1.6994637482018023e-02, 1.0373317514267365e-02, 6.0239245919995622e-03, 3.3276551358222884e-03, 1.7483531042542699e-03, 8.7353709789879039e-04, 4.1497155710923123e-04, 1.8739476963256670e-04, 8.0428506528979537e-05, 3.2800534876023489e-05, 1.2707753951032874e-05, 4.6759044289293238e-06, 1.6336412605871983e-06, 5.4177677321026202e-07, 1.7050141340191249e-07, 5.0903013962041357e-08, 1.4411972185221586e-08, 3.8682673753498617e-09, 9.8392832670094020e-10, 2.3708105480750139e-10, 5.4092941845487156e-11, 1.1681801468249808e-11, 2.3867692880717110e-12, 4.6114644502136799e-13, 8.4213476872404286e-14, 1.4528301518132017e-14, 2.3664867578847666e-15, 3.6375048889083554e-16, 5.2729781171856177e-17, 7.2042972150393114e-18, 9.2710336687274256e-19, 1.1229742763811151e-19, 1.2794012136597428e-20, 1.3699807056265559e-21, 1.3776941782313042e-22, 1.3000662757028629e-23, 1.1502145928125925e-24, 9.5323773039462743e-26, 7.3930155412655720e-27, 5.3605436078106824e-28, 3.6300293183361797e-29, 2.2932424003565328e-30, 1.3499836949356773e-31, 7.3963969744653024e-33, 3.7667945725159055e-34, 1.7807430428966829e-35, 7.8035886293155777e-37, 3.1652198121078916e-38, 1.1864415902523173e-39, 4.1029828415971428e-41, 1.3067728287128299e-42, 3.8259457909463708e-44, 1.0276815273410889e-45, 2.5272570465088243e-47, 5.6773339224732908e-49, 1.1622901525905010e-50, 2.1630323514364711e-52, 3.6493796373809251e-54, 5.5658406725957325e-56, 7.6499247670821092e-58, 9.4440639857201346e-60, 1.0434894316959833e-61, 1.0279594830695334e-63, 8.9912466505154563e-66, 6.9513137370020262e-68, 4.7271089337772468e-70, 2.8125155025369667e-72, 1.4555888776738779e-74, 6.5111285362111366e-77, 2.4997514837476365e-79, 8.1731118972592471e-82, 2.2562215375682347e-84, 5.2083206235820379e-87, 9.9458309202670908e-90, 1.5520652579926001e-92, 1.9519789398323314e-95, 1.9472732376896783e-98, 1.5127860735379895e-101, 8.9577890237321700e-105, 3.9416969862084461e-108, 1.2503894738744883e-111, 2.7559362749699724e-115, 4.0320327117616306e-119, 3.6957545112422320e-123, 1.9684692530020812e-127, 5.5049260050287900e-132, 7.0049069648137550e-137, 3.2706601334834755e-142, 3.9305958509063355e-148, 6.1716304223418473e-155, 2.2290934963031539e-163}, +} diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/hermite_test.go b/vendor/gonum.org/v1/gonum/integrate/quad/hermite_test.go new file mode 100644 index 00000000..d74b82dc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/hermite_test.go @@ -0,0 +1,251 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package quad + +import ( + "fmt" + "math" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestHermite(t *testing.T) { + for cas, test := range []struct { + n int + f func(float64) float64 + ev float64 + tol float64 + }{ + { + n: 2, + f: func(x float64) float64 { return 1 }, + ev: math.SqrtPi, + tol: 1e-14, + }, + { + n: 4, + f: func(x float64) float64 { return math.Exp(-2 * 0.5 * x) }, + ev: math.SqrtPi * math.Exp(0.25), + tol: 1e-4, + }, + { + n: 9, + f: func(x float64) float64 { return math.Exp(-2 * 0.5 * x) }, + ev: math.SqrtPi * math.Exp(0.25), + tol: 1e-12, + }, + { + n: 10, + f: func(x float64) float64 { return math.Exp(-2 * 0.5 * x) }, + ev: math.SqrtPi * math.Exp(0.25), + tol: 1e-12, + }, + { + n: 15, + f: func(x float64) float64 { return math.Exp(-2 * 2 * x) }, + ev: math.SqrtPi * math.Exp(4), + tol: 1e-4, + }, + { + n: 22, + f: func(x float64) float64 { return math.Exp(-2 * 2 * x) }, + ev: math.SqrtPi * math.Exp(4), + tol: 1e-12, + }, + { + n: 21, + f: func(x float64) float64 { return math.Exp(-2 * 2 * x) }, + ev: math.SqrtPi * math.Exp(4), + tol: 1e-12, + }, + } { + ev := Fixed(test.f, math.Inf(-1), math.Inf(1), test.n, Hermite{}, 0) + if !floats.EqualWithinAbsOrRel(test.ev, ev, test.tol, test.tol) { + t.Errorf("Case %d: expected value mismatch.\nWant %v\ngot %v", cas, test.ev, ev) + } + } +} + +func TestHermiteLocations(t *testing.T) { + // Test the hermite locations and weights against other precomputed table. + // Data from http://dlmf.nist.gov/3.5. + for _, test := range []struct { + n int + x []float64 + w []float64 + }{ + // Evaluated from Chebfun. + { + n: 5, + x: []float64{-0.202018287045609e1, -0.958572464613819, 0, 0.958572464613819, 0.202018287045609e1}, + w: []float64{0.199532420590459e-1, 0.393619323152241, 0.945308720482942, 0.393619323152241, 0.199532420590459e-1}, + }, + { + n: 10, + x: []float64{-0.343615911883773760e1, -0.253273167423278980e1, -0.175668364929988177e1, -0.103661082978951365e1, -0.342901327223704609, 0.342901327223704609, 0.103661082978951365e1, 0.175668364929988177e1, 0.253273167423278980e1, 0.343615911883773760e1}, + w: []float64{0.764043285523262063e-5, 0.134364574678123269e-2, 0.338743944554810631e-1, 0.240138611082314686, 0.610862633735325799, 0.610862633735325799, 0.240138611082314686, 0.338743944554810631e-1, 0.134364574678123269e-2, 0.764043285523262063e-5}, + }, + { + n: 215, + x: []float64{-2.0083110126223993e+01, -1.9573161931385755e+01, -1.9153731166695263e+01, -1.8781558404513735e+01, -1.8440108632764016e+01, -1.8120857960601569e+01, -1.7818692349773503e+01, -1.7530242081974308e+01, -1.7253139752773148e+01, -1.6985642449377284e+01, -1.6726420346886542e+01, -1.6474429782282726e+01, -1.6228832750513551e+01, -1.5988943547145137e+01, -1.5754192102761674e+01, -1.5524098014731747e+01, -1.5298251677453143e+01, -1.5076300264808333e+01, -1.4857937115425768e+01, -1.4642893558208563e+01, -1.4430932522616979e+01, -1.4221843477251845e+01, -1.4015438372554696e+01, -1.3811548353270942e+01, -1.3610021068540190e+01, -1.3410718451340038e+01, -1.3213514870431910e+01, -1.3018295580800100e+01, -1.2824955415404188e+01, -1.2633397673617059e+01, -1.2443533171189967e+01, -1.2255279423804318e+01, -1.2068559941826503e+01, -1.1883303618198463e+01, -1.1699444194777641e+01, -1.1516919795109878e+01, -1.1335672513742256e+01, -1.1155648053883823e+01, -1.0976795406593546e+01, -1.0799066565787168e+01, -1.0622416274262394e+01, -1.0446801796686490e+01, -1.0272182716104577e+01, -1.0098520751035824e+01, -9.9257795906487338e+00, -9.7539247458611111e+00, -9.5829234145081710e+00, -9.4127443589734394e+00, -9.2433577948895387e+00, -9.0747352896969389e+00, -8.9068496700026394e+00, -8.7396749368126798e+00, -8.5731861878255415e+00, -8.4073595460710955e+00, -8.2421720942637187e+00, -8.0776018143113824e+00, -7.9136275314855800e+00, -7.7502288628124383e+00, -7.5873861692931381e+00, -7.4250805116042331e+00, -7.2632936089653120e+00, -7.1020078008938672e+00, -6.9412060115960434e+00, -6.7808717167671544e+00, -6.6209889125982082e+00, -6.4615420868046280e+00, -6.3025161915109100e+00, -6.1438966178406549e+00, -5.9856691720754620e+00, -5.8278200532585673e+00, -5.6703358321303936e+00, -5.5132034312931157e+00, -5.3564101065103049e+00, -5.1999434290559226e+00, -5.0437912690340267e+00, -4.8879417795972326e+00, -4.7323833819978187e+00, -4.5771047514106780e+00, -4.4220948034722349e+00, -4.2673426814837114e+00, -4.1128377442311503e+00, -3.9585695543782120e+00, -3.8045278673909002e+00, -3.6507026209565665e+00, -3.4970839248619634e+00, -3.3436620512978501e+00, -3.1904274255596032e+00, -3.0373706171156218e+00, -2.8844823310168755e+00, -2.7317533996228827e+00, -2.5791747746208049e+00, -2.4267375193157439e+00, -2.2744328011717010e+00, -2.1222518845837395e+00, -1.9701861238629792e+00, -1.8182269564169717e+00, -1.6663658961089640e+00, -1.5145945267802365e+00, -1.3629044959205205e+00, -1.2112875084719879e+00, -1.0597353207530273e+00, -9.0823973448851325e-01, -7.5679259093351370e-01, -6.0538576507805808e-01, -4.5401115992078167e-01, -3.0266070079942864e-01, -1.5132632976672361e-01, 7.9483151672010196e-15, 1.5132632976672361e-01, 3.0266070079942864e-01, 4.5401115992078167e-01, 6.0538576507805808e-01, 7.5679259093351370e-01, 9.0823973448851325e-01, 1.0597353207530273e+00, 1.2112875084719879e+00, 1.3629044959205205e+00, 1.5145945267802365e+00, 1.6663658961089640e+00, 1.8182269564169717e+00, 1.9701861238629792e+00, 2.1222518845837395e+00, 2.2744328011717010e+00, 2.4267375193157439e+00, 2.5791747746208049e+00, 2.7317533996228827e+00, 2.8844823310168755e+00, 3.0373706171156218e+00, 3.1904274255596032e+00, 3.3436620512978501e+00, 3.4970839248619634e+00, 3.6507026209565665e+00, 3.8045278673909002e+00, 3.9585695543782120e+00, 4.1128377442311503e+00, 4.2673426814837114e+00, 4.4220948034722349e+00, 4.5771047514106780e+00, 4.7323833819978187e+00, 4.8879417795972326e+00, 5.0437912690340267e+00, 5.1999434290559226e+00, 5.3564101065103049e+00, 5.5132034312931157e+00, 5.6703358321303936e+00, 5.8278200532585673e+00, 5.9856691720754620e+00, 6.1438966178406549e+00, 6.3025161915109100e+00, 6.4615420868046280e+00, 6.6209889125982082e+00, 6.7808717167671544e+00, 6.9412060115960434e+00, 7.1020078008938672e+00, 7.2632936089653120e+00, 7.4250805116042331e+00, 7.5873861692931381e+00, 7.7502288628124383e+00, 7.9136275314855800e+00, 8.0776018143113824e+00, 8.2421720942637187e+00, 8.4073595460710955e+00, 8.5731861878255415e+00, 8.7396749368126798e+00, 8.9068496700026394e+00, 9.0747352896969389e+00, 9.2433577948895387e+00, 9.4127443589734394e+00, 9.5829234145081710e+00, 9.7539247458611111e+00, 9.9257795906487338e+00, 1.0098520751035824e+01, 1.0272182716104577e+01, 1.0446801796686490e+01, 1.0622416274262394e+01, 1.0799066565787168e+01, 1.0976795406593546e+01, 1.1155648053883823e+01, 1.1335672513742256e+01, 1.1516919795109878e+01, 1.1699444194777641e+01, 1.1883303618198463e+01, 1.2068559941826503e+01, 1.2255279423804318e+01, 1.2443533171189967e+01, 1.2633397673617059e+01, 1.2824955415404188e+01, 1.3018295580800100e+01, 1.3213514870431910e+01, 1.3410718451340038e+01, 1.3610021068540190e+01, 1.3811548353270942e+01, 1.4015438372554696e+01, 1.4221843477251845e+01, 1.4430932522616979e+01, 1.4642893558208563e+01, 1.4857937115425768e+01, 1.5076300264808333e+01, 1.5298251677453143e+01, 1.5524098014731747e+01, 1.5754192102761674e+01, 1.5988943547145137e+01, 1.6228832750513551e+01, 1.6474429782282726e+01, 1.6726420346886542e+01, 1.6985642449377284e+01, 1.7253139752773148e+01, 1.7530242081974308e+01, 1.7818692349773503e+01, 1.8120857960601569e+01, 1.8440108632764016e+01, 1.8781558404513735e+01, 1.9153731166695263e+01, 1.9573161931385755e+01, 2.0083110126223993e+01}, + w: []float64{4.0474005560499094e-176, 1.8797130400856443e-167, 1.8432377040276421e-160, 2.2601442864626069e-154, 6.9363023753259492e-149, 7.6575370428605554e-144, 3.7894855074137878e-139, 9.7310398950542353e-135, 1.4382941114934084e-130, 1.3214094652141891e-126, 8.0053233705919762e-123, 3.3506484324551954e-119, 1.0061133084529732e-115, 2.2355880918528976e-112, 3.7723274691873339e-109, 4.9410774014014167e-106, 5.1189805080467357e-103, 4.2633269887655389e-100, 2.8951564896303124e-97, 1.6231768954981774e-94, 7.5966487579367170e-92, 2.9971587600601123e-89, 1.0056653752640396e-86, 2.8926565116618279e-84, 7.1838069610206879e-82, 1.5504440487214177e-79, 2.9253709118548054e-77, 4.8516529695481360e-75, 7.1080340648382430e-73, 9.2417798747589595e-71, 1.0709039437896534e-68, 1.1102986726619406e-66, 1.0337280935884043e-64, 8.6720569345151135e-63, 6.5759615285599325e-61, 4.5206307708839604e-59, 2.8251413443094276e-57, 1.6091856250751163e-55, 8.3743579179261028e-54, 3.9908716881614503e-52, 1.7453732998154445e-50, 7.0192904730947679e-49, 2.6008368230936308e-47, 8.8947358191690260e-46, 2.8125213532676820e-44, 8.2357837374304705e-43, 2.2368010157343200e-41, 5.6428177886700861e-40, 1.3240736407971940e-38, 2.8936578029605094e-37, 5.8971855560501346e-36, 1.1220768467833071e-34, 1.9956009474900652e-33, 3.3209946083724174e-32, 5.1767166839129889e-31, 7.5658951790722304e-30, 1.0377543674300410e-28, 1.3370496163293642e-27, 1.6195422525877890e-26, 1.8458039741402227e-25, 1.9809275961773415e-24, 2.0034006172471768e-23, 1.9107136033126365e-22, 1.7196934641222891e-21, 1.4615728740382834e-20, 1.1737567188678477e-19, 8.9122322093114715e-19, 6.4017277272147784e-18, 4.3526236743179514e-17, 2.8027154496363443e-16, 1.7100226833829111e-15, 9.8907988394494626e-15, 5.4258798698008971e-14, 2.8243097014577004e-13, 1.3955439320917938e-12, 6.5484943121277863e-12, 2.9192823809511808e-11, 1.2368298646403665e-10, 4.9819378483709125e-10, 1.9084879833147422e-09, 6.9554442384546823e-09, 2.4123461087320678e-08, 7.9645691304111948e-08, 2.5038904484412268e-07, 7.4974774628062337e-07, 2.1388110362272039e-06, 5.8142267442915587e-06, 1.5065139508846480e-05, 3.7214305501073257e-05, 8.7657861198914500e-05, 1.9692436368292282e-04, 4.2200152760283493e-04, 8.6279569789330843e-04, 1.6832545363270029e-03, 3.1340302956109622e-03, 5.5696401904272858e-03, 9.4487851093380676e-03, 1.5303805411902717e-02, 2.3666975130344652e-02, 3.4949960453868167e-02, 4.9288724246681882e-02, 6.6386134961517171e-02, 8.5401153510804823e-02, 1.0493731687783339e-01, 1.2316720474285285e-01, 1.3809371553328023e-01, 1.4790300421921079e-01, 1.5132498974070285e-01, 1.4790300421921079e-01, 1.3809371553328023e-01, 1.2316720474285285e-01, 1.0493731687783339e-01, 8.5401153510804823e-02, 6.6386134961517171e-02, 4.9288724246681882e-02, 3.4949960453868167e-02, 2.3666975130344652e-02, 1.5303805411902717e-02, 9.4487851093380676e-03, 5.5696401904272858e-03, 3.1340302956109622e-03, 1.6832545363270029e-03, 8.6279569789330843e-04, 4.2200152760283493e-04, 1.9692436368292282e-04, 8.7657861198914500e-05, 3.7214305501073257e-05, 1.5065139508846480e-05, 5.8142267442915587e-06, 2.1388110362272039e-06, 7.4974774628062337e-07, 2.5038904484412268e-07, 7.9645691304111948e-08, 2.4123461087320678e-08, 6.9554442384546823e-09, 1.9084879833147422e-09, 4.9819378483709125e-10, 1.2368298646403665e-10, 2.9192823809511808e-11, 6.5484943121277863e-12, 1.3955439320917938e-12, 2.8243097014577004e-13, 5.4258798698008971e-14, 9.8907988394494626e-15, 1.7100226833829111e-15, 2.8027154496363443e-16, 4.3526236743179514e-17, 6.4017277272147784e-18, 8.9122322093114715e-19, 1.1737567188678477e-19, 1.4615728740382834e-20, 1.7196934641222891e-21, 1.9107136033126365e-22, 2.0034006172471768e-23, 1.9809275961773415e-24, 1.8458039741402227e-25, 1.6195422525877890e-26, 1.3370496163293642e-27, 1.0377543674300410e-28, 7.5658951790722304e-30, 5.1767166839129889e-31, 3.3209946083724174e-32, 1.9956009474900652e-33, 1.1220768467833071e-34, 5.8971855560501346e-36, 2.8936578029605094e-37, 1.3240736407971940e-38, 5.6428177886700861e-40, 2.2368010157343200e-41, 8.2357837374304705e-43, 2.8125213532676820e-44, 8.8947358191690260e-46, 2.6008368230936308e-47, 7.0192904730947679e-49, 1.7453732998154445e-50, 3.9908716881614503e-52, 8.3743579179261028e-54, 1.6091856250751163e-55, 2.8251413443094276e-57, 4.5206307708839604e-59, 6.5759615285599325e-61, 8.6720569345151135e-63, 1.0337280935884043e-64, 1.1102986726619406e-66, 1.0709039437896534e-68, 9.2417798747589595e-71, 7.1080340648382430e-73, 4.8516529695481360e-75, 2.9253709118548054e-77, 1.5504440487214177e-79, 7.1838069610206879e-82, 2.8926565116618279e-84, 1.0056653752640396e-86, 2.9971587600601123e-89, 7.5966487579367170e-92, 1.6231768954981774e-94, 2.8951564896303124e-97, 4.2633269887655389e-100, 5.1189805080467357e-103, 4.9410774014014167e-106, 3.7723274691873339e-109, 2.2355880918528976e-112, 1.0061133084529732e-115, 3.3506484324551954e-119, 8.0053233705919762e-123, 1.3214094652141891e-126, 1.4382941114934084e-130, 9.7310398950542353e-135, 3.7894855074137878e-139, 7.6575370428605554e-144, 6.9363023753259492e-149, 2.2601442864626069e-154, 1.8432377040276421e-160, 1.8797130400856443e-167, 4.0474005560499094e-176}, + }, + { + n: 216, + x: []float64{-2.0131752068397390e+01, -1.9622211733828486e+01, -1.9203122650098184e+01, -1.8831257901839155e+01, -1.8490094811217439e+01, -1.8171115805943941e+01, -1.7869210618319627e+01, -1.7581012003064874e+01, -1.7304154286393636e+01, -1.7036895825521608e+01, -1.6777907762072694e+01, -1.6526147190139376e+01, -1.6280776711860355e+01, -1.6041111119395726e+01, -1.5806580756275796e+01, -1.5576705568204593e+01, -1.5351076247103551e+01, -1.5129340223792830e+01, -1.4911191060978103e+01, -1.4696360284715409e+01, -1.4484610999323769e+01, -1.4275732829628778e+01, -1.4069537866591046e+01, -1.3865857382137794e+01, -1.3664539141187824e+01, -1.3465445182689793e+01, -1.3268449972893279e+01, -1.3073438856897617e+01, -1.2880306751340244e+01, -1.2688957033629340e+01, -1.2499300592587632e+01, -1.2311255012587219e+01, -1.2124743868808109e+01, -1.1939696115566026e+01, -1.1756045553033841e+01, -1.1573730360348824e+01, -1.1392692685219812e+01, -1.1212878281848150e+01, -1.1034236190346626e+01, -1.0856718451952171e+01, -1.0680279855235202e+01, -1.0504877709252620e+01, -1.0330471640205081e+01, -1.0157023408668081e+01, -9.9844967448895385e+00, -9.8128572000013108e+00, -9.6420720112891818e+00, -9.4721099799172528e+00, -9.3029413597147883e+00, -9.1345377558145096e+00, -8.9668720320849413e+00, -8.7999182264315081e+00, -8.6336514731539875e+00, -8.4680479316454296e+00, -8.3030847208017082e+00, -8.1387398585838486e+00, -7.9749922062384426e+00, -7.8118214167366684e+00, -7.6492078870405447e+00, -7.4871327138470951e+00, -7.3255776524981444e+00, -7.1645250787759087e+00, -7.0039579533331269e+00, -6.8438597885318986e+00, -6.6842146174875827e+00, -6.5250069651340752e+00, -6.3662218211444577e+00, -6.2078446145563948e+00, -6.0498611899661094e+00, -5.8922577851667635e+00, -5.7350210101185848e+00, -5.5781378271479722e+00, -5.4215955322816969e+00, -5.2653817376305465e+00, -5.1094843547439881e+00, -4.9538915788638089e+00, -4.7985918740108131e+00, -4.6435739588438905e+00, -4.4888267932355790e+00, -4.3343395655126109e+00, -4.1801016803139959e+00, -4.0261027470226392e+00, -3.8723325687298416e+00, -3.7187811316950210e+00, -3.5654385952656149e+00, -3.4122952822245907e+00, -3.2593416695353823e+00, -3.1065683794558021e+00, -2.9539661709946619e+00, -2.8015259316863266e+00, -2.6492386696600243e+00, -2.4970955059821409e+00, -2.3450876672510903e+00, -2.1932064784252856e+00, -2.0414433558661624e+00, -1.8897898005787916e+00, -1.7382373916337388e+00, -1.5867777797546210e+00, -1.4354026810562848e+00, -1.2841038709195900e+00, -1.1328731779888348e+00, -9.8170247827895785e-01, -8.3058368937955573e-01, -6.7950876474356448e-01, -5.2846968804856509e-01, -3.7745846761911317e-01, -2.2646713089859094e-01, -7.5487718959414210e-02, 7.5487718959414210e-02, 2.2646713089859094e-01, 3.7745846761911317e-01, 5.2846968804856509e-01, 6.7950876474356448e-01, 8.3058368937955573e-01, 9.8170247827895785e-01, 1.1328731779888348e+00, 1.2841038709195900e+00, 1.4354026810562848e+00, 1.5867777797546210e+00, 1.7382373916337388e+00, 1.8897898005787916e+00, 2.0414433558661624e+00, 2.1932064784252856e+00, 2.3450876672510903e+00, 2.4970955059821409e+00, 2.6492386696600243e+00, 2.8015259316863266e+00, 2.9539661709946619e+00, 3.1065683794558021e+00, 3.2593416695353823e+00, 3.4122952822245907e+00, 3.5654385952656149e+00, 3.7187811316950210e+00, 3.8723325687298416e+00, 4.0261027470226392e+00, 4.1801016803139959e+00, 4.3343395655126109e+00, 4.4888267932355790e+00, 4.6435739588438905e+00, 4.7985918740108131e+00, 4.9538915788638089e+00, 5.1094843547439881e+00, 5.2653817376305465e+00, 5.4215955322816969e+00, 5.5781378271479722e+00, 5.7350210101185848e+00, 5.8922577851667635e+00, 6.0498611899661094e+00, 6.2078446145563948e+00, 6.3662218211444577e+00, 6.5250069651340752e+00, 6.6842146174875827e+00, 6.8438597885318986e+00, 7.0039579533331269e+00, 7.1645250787759087e+00, 7.3255776524981444e+00, 7.4871327138470951e+00, 7.6492078870405447e+00, 7.8118214167366684e+00, 7.9749922062384426e+00, 8.1387398585838486e+00, 8.3030847208017082e+00, 8.4680479316454296e+00, 8.6336514731539875e+00, 8.7999182264315081e+00, 8.9668720320849413e+00, 9.1345377558145096e+00, 9.3029413597147883e+00, 9.4721099799172528e+00, 9.6420720112891818e+00, 9.8128572000013108e+00, 9.9844967448895385e+00, 1.0157023408668081e+01, 1.0330471640205081e+01, 1.0504877709252620e+01, 1.0680279855235202e+01, 1.0856718451952171e+01, 1.1034236190346626e+01, 1.1212878281848150e+01, 1.1392692685219812e+01, 1.1573730360348824e+01, 1.1756045553033841e+01, 1.1939696115566026e+01, 1.2124743868808109e+01, 1.2311255012587219e+01, 1.2499300592587632e+01, 1.2688957033629340e+01, 1.2880306751340244e+01, 1.3073438856897617e+01, 1.3268449972893279e+01, 1.3465445182689793e+01, 1.3664539141187824e+01, 1.3865857382137794e+01, 1.4069537866591046e+01, 1.4275732829628778e+01, 1.4484610999323769e+01, 1.4696360284715409e+01, 1.4911191060978103e+01, 1.5129340223792830e+01, 1.5351076247103551e+01, 1.5576705568204593e+01, 1.5806580756275796e+01, 1.6041111119395726e+01, 1.6280776711860355e+01, 1.6526147190139376e+01, 1.6777907762072694e+01, 1.7036895825521608e+01, 1.7304154286393636e+01, 1.7581012003064874e+01, 1.7869210618319627e+01, 1.8171115805943941e+01, 1.8490094811217439e+01, 1.8831257901839155e+01, 1.9203122650098184e+01, 1.9622211733828486e+01, 2.0131752068397390e+01}, + w: []float64{5.7186844211118222e-177, 2.7466189949527236e-168, 2.7698274929964049e-161, 3.4828172461418377e-155, 1.0940903755394791e-149, 1.2347606047124676e-144, 6.2404773612052171e-140, 1.6353340891378212e-135, 2.4650950171742754e-131, 2.3085411036710099e-127, 1.4249650100034198e-123, 6.0746030482858092e-120, 1.8572077169453742e-116, 4.2005766103289114e-113, 7.2131362796894811e-110, 9.6125997143450870e-107, 1.0130358260780602e-103, 8.5810245129266594e-101, 5.9257988910096090e-98, 3.3780606107607827e-95, 1.6073077596553874e-92, 6.4463886647737192e-90, 2.1986159587286647e-87, 6.4275556938243753e-85, 1.6222763835321407e-82, 3.5581101139323407e-80, 6.8220148646876484e-78, 1.1496573365594917e-75, 1.7114200608857651e-73, 2.2608688324572314e-71, 2.6617645198762597e-69, 2.8038024736345674e-67, 2.6521234350652613e-65, 2.2603869398967457e-63, 1.7413601437152754e-61, 1.2161701083247541e-59, 7.7214787759599970e-58, 4.4681959655564470e-56, 2.3623580471674404e-54, 1.1437576644069702e-52, 5.0819691921164956e-51, 2.0764486091263794e-49, 7.8168818968667932e-48, 2.7161609526051418e-46, 8.7263192332605962e-45, 2.5963610791198993e-43, 7.1651564650842932e-42, 1.8367370768736730e-40, 4.3795689659428445e-39, 9.7263842188046952e-38, 2.0144288376257676e-36, 3.8953956971431042e-35, 7.0411654624671892e-34, 1.1909731529300876e-32, 1.8870059773886237e-31, 2.8034152482012231e-30, 3.9088957466494064e-29, 5.1199371899987404e-28, 6.3051173258996659e-27, 7.3062988441733997e-26, 7.9729602997232079e-25, 8.1994951837475763e-24, 7.9526775811935095e-23, 7.2794477168595113e-22, 6.2925924422563063e-21, 5.1402243977739270e-20, 3.9702645520078747e-19, 2.9013105636885269e-18, 2.0070043240260125e-17, 1.3149628048888219e-16, 8.1641639956286359e-16, 4.8056898389707300e-15, 2.6831763736632487e-14, 1.4216321504480736e-13, 7.1508314522575616e-13, 3.4161417919950439e-12, 1.5505876032631646e-11, 6.6896188793649314e-11, 2.7441476023994389e-10, 1.0706905991113023e-09, 3.9747846429602356e-09, 1.4044052119190546e-08, 4.7242215798796869e-08, 1.5133894631903387e-07, 4.6181858824280925e-07, 1.3427778873836719e-06, 3.7209613424878082e-06, 9.8293533546629111e-06, 2.4757612288389546e-05, 5.9469805842774389e-05, 1.3626145195379436e-04, 2.9786395909886146e-04, 6.2130683688573309e-04, 1.2368227283931328e-03, 2.3501040099770882e-03, 4.2629032262842719e-03, 7.3827553287034008e-03, 1.2208924001688722e-02, 1.9280976823883154e-02, 2.9081432020399377e-02, 4.1896299298471870e-02, 5.7655710815363609e-02, 7.5795804675644604e-02, 9.5193937891141694e-02, 1.1422353375366404e-01, 1.3094856577352781e-01, 1.4343569727181574e-01, 1.5011822522474477e-01, 1.5011822522474477e-01, 1.4343569727181574e-01, 1.3094856577352781e-01, 1.1422353375366404e-01, 9.5193937891141694e-02, 7.5795804675644604e-02, 5.7655710815363609e-02, 4.1896299298471870e-02, 2.9081432020399377e-02, 1.9280976823883154e-02, 1.2208924001688722e-02, 7.3827553287034008e-03, 4.2629032262842719e-03, 2.3501040099770882e-03, 1.2368227283931328e-03, 6.2130683688573309e-04, 2.9786395909886146e-04, 1.3626145195379436e-04, 5.9469805842774389e-05, 2.4757612288389546e-05, 9.8293533546629111e-06, 3.7209613424878082e-06, 1.3427778873836719e-06, 4.6181858824280925e-07, 1.5133894631903387e-07, 4.7242215798796869e-08, 1.4044052119190546e-08, 3.9747846429602356e-09, 1.0706905991113023e-09, 2.7441476023994389e-10, 6.6896188793649314e-11, 1.5505876032631646e-11, 3.4161417919950439e-12, 7.1508314522575616e-13, 1.4216321504480736e-13, 2.6831763736632487e-14, 4.8056898389707300e-15, 8.1641639956286359e-16, 1.3149628048888219e-16, 2.0070043240260125e-17, 2.9013105636885269e-18, 3.9702645520078747e-19, 5.1402243977739270e-20, 6.2925924422563063e-21, 7.2794477168595113e-22, 7.9526775811935095e-23, 8.1994951837475763e-24, 7.9729602997232079e-25, 7.3062988441733997e-26, 6.3051173258996659e-27, 5.1199371899987404e-28, 3.9088957466494064e-29, 2.8034152482012231e-30, 1.8870059773886237e-31, 1.1909731529300876e-32, 7.0411654624671892e-34, 3.8953956971431042e-35, 2.0144288376257676e-36, 9.7263842188046952e-38, 4.3795689659428445e-39, 1.8367370768736730e-40, 7.1651564650842932e-42, 2.5963610791198993e-43, 8.7263192332605962e-45, 2.7161609526051418e-46, 7.8168818968667932e-48, 2.0764486091263794e-49, 5.0819691921164956e-51, 1.1437576644069702e-52, 2.3623580471674404e-54, 4.4681959655564470e-56, 7.7214787759599970e-58, 1.2161701083247541e-59, 1.7413601437152754e-61, 2.2603869398967457e-63, 2.6521234350652613e-65, 2.8038024736345674e-67, 2.6617645198762597e-69, 2.2608688324572314e-71, 1.7114200608857651e-73, 1.1496573365594917e-75, 6.8220148646876484e-78, 3.5581101139323407e-80, 1.6222763835321407e-82, 6.4275556938243753e-85, 2.1986159587286647e-87, 6.4463886647737192e-90, 1.6073077596553874e-92, 3.3780606107607827e-95, 5.9257988910096090e-98, 8.5810245129266594e-101, 1.0130358260780602e-103, 9.6125997143450870e-107, 7.2131362796894811e-110, 4.2005766103289114e-113, 1.8572077169453742e-116, 6.0746030482858092e-120, 1.4249650100034198e-123, 2.3085411036710099e-127, 2.4650950171742754e-131, 1.6353340891378212e-135, 6.2404773612052171e-140, 1.2347606047124676e-144, 1.0940903755394791e-149, 3.4828172461418377e-155, 2.7698274929964049e-161, 2.7466189949527236e-168, 5.7186844211118222e-177}, + }, + { + n: 217, + x: []float64{-2.0180280152078982e+01, -1.9671145428267970e+01, -1.9252396116029669e+01, -1.8880837640701767e+01, -1.8539959593913657e+01, -1.8221250688860252e+01, -1.7919604408706316e+01, -1.7631655968298805e+01, -1.7355041415469405e+01, -1.7088020370809854e+01, -1.6829264937408070e+01, -1.6577732962488266e+01, -1.6332587652172350e+01, -1.6093144292573264e+01, -1.5858833637952957e+01, -1.5629175980464554e+01, -1.5403762307923412e+01, -1.5182240306661464e+01, -1.4964303762199654e+01, -1.4749684396618285e+01, -1.4538145488075983e+01, -1.4329476816694543e+01, -1.4123490613100632e+01, -1.3920018275613611e+01, -1.3718907684195138e+01, -1.3520020983073742e+01, -1.3323232735334253e+01, -1.3128428375570619e+01, -1.2935502903505391e+01, -1.2744359774012816e+01, -1.2554909948437734e+01, -1.2367071079310476e+01, -1.2180766806106346e+01, -1.1995926144008331e+01, -1.1812482951007951e+01, -1.1630375461345015e+01, -1.1449545875407471e+01, -1.1269939997911081e+01, -1.1091506917547994e+01, -1.0914198722404091e+01, -1.0737970246351363e+01, -1.0562778842365235e+01, -1.0388584179329960e+01, -1.0215348059403579e+01, -1.0043034253437085e+01, -9.8716083522966080e+00, -9.7010376322345699e+00, -9.5312909327068294e+00, -9.3623385452449437e+00, -9.1941521121732386e+00, -9.0267045341142556e+00, -8.8599698853577831e+00, -8.6939233362816957e+00, -8.5285410821102356e+00, -8.3638002773794167e+00, -8.1996789755519419e+00, -8.0361560732874953e+00, -7.8732112589291026e+00, -7.7108249648145373e+00, -7.5489783230637100e+00, -7.3876531245300106e+00, -7.2268317806359086e+00, -7.0664972878418659e+00, -6.9066331945227768e+00, -6.7472235700485381e+00, -6.5882529758852613e+00, -6.4297064385510465e+00, -6.2715694242761426e+00, -6.1138278152311072e+00, -5.9564678871991967e+00, -5.7994762885802258e+00, -5.6428400206233480e+00, -5.4865464187949282e+00, -5.3305831351959538e+00, -5.1749381219506319e+00, -5.0195996154942355e+00, -4.8645561216944264e+00, -4.7097964017452645e+00, -4.5553094587783480e+00, -4.4010845251394572e+00, -4.2471110502834843e+00, -4.0933786892435746e+00, -3.9398772916341032e+00, -3.7865968911497059e+00, -3.6335276955255318e+00, -3.4806600769262501e+00, -3.3279845627335654e+00, -3.1754918267040755e+00, -3.0231726804711898e+00, -2.8710180653663722e+00, -2.7190190445367941e+00, -2.5671667953376018e+00, -2.4154526019785036e+00, -2.2638678484054164e+00, -2.1124040113990956e+00, -1.9610526538735082e+00, -1.8098054183577674e+00, -1.6586540206460576e+00, -1.5075902436008417e+00, -1.3566059310952046e+00, -1.2056929820809235e+00, -1.0548433447690717e+00, -9.0404901091087708e-01, -7.5330201016646747e-01, -6.0259440454997382e-01, -4.5191828293935077e-01, -3.0126575563983427e-01, -1.5062894899007009e-01, 7.9851131193273576e-15, 1.5062894899007009e-01, 3.0126575563983427e-01, 4.5191828293935077e-01, 6.0259440454997382e-01, 7.5330201016646747e-01, 9.0404901091087708e-01, 1.0548433447690717e+00, 1.2056929820809235e+00, 1.3566059310952046e+00, 1.5075902436008417e+00, 1.6586540206460576e+00, 1.8098054183577674e+00, 1.9610526538735082e+00, 2.1124040113990956e+00, 2.2638678484054164e+00, 2.4154526019785036e+00, 2.5671667953376018e+00, 2.7190190445367941e+00, 2.8710180653663722e+00, 3.0231726804711898e+00, 3.1754918267040755e+00, 3.3279845627335654e+00, 3.4806600769262501e+00, 3.6335276955255318e+00, 3.7865968911497059e+00, 3.9398772916341032e+00, 4.0933786892435746e+00, 4.2471110502834843e+00, 4.4010845251394572e+00, 4.5553094587783480e+00, 4.7097964017452645e+00, 4.8645561216944264e+00, 5.0195996154942355e+00, 5.1749381219506319e+00, 5.3305831351959538e+00, 5.4865464187949282e+00, 5.6428400206233480e+00, 5.7994762885802258e+00, 5.9564678871991967e+00, 6.1138278152311072e+00, 6.2715694242761426e+00, 6.4297064385510465e+00, 6.5882529758852613e+00, 6.7472235700485381e+00, 6.9066331945227768e+00, 7.0664972878418659e+00, 7.2268317806359086e+00, 7.3876531245300106e+00, 7.5489783230637100e+00, 7.7108249648145373e+00, 7.8732112589291026e+00, 8.0361560732874953e+00, 8.1996789755519419e+00, 8.3638002773794167e+00, 8.5285410821102356e+00, 8.6939233362816957e+00, 8.8599698853577831e+00, 9.0267045341142556e+00, 9.1941521121732386e+00, 9.3623385452449437e+00, 9.5312909327068294e+00, 9.7010376322345699e+00, 9.8716083522966080e+00, 1.0043034253437085e+01, 1.0215348059403579e+01, 1.0388584179329960e+01, 1.0562778842365235e+01, 1.0737970246351363e+01, 1.0914198722404091e+01, 1.1091506917547994e+01, 1.1269939997911081e+01, 1.1449545875407471e+01, 1.1630375461345015e+01, 1.1812482951007951e+01, 1.1995926144008331e+01, 1.2180766806106346e+01, 1.2367071079310476e+01, 1.2554909948437734e+01, 1.2744359774012816e+01, 1.2935502903505391e+01, 1.3128428375570619e+01, 1.3323232735334253e+01, 1.3520020983073742e+01, 1.3718907684195138e+01, 1.3920018275613611e+01, 1.4123490613100632e+01, 1.4329476816694543e+01, 1.4538145488075983e+01, 1.4749684396618285e+01, 1.4964303762199654e+01, 1.5182240306661464e+01, 1.5403762307923412e+01, 1.5629175980464554e+01, 1.5858833637952957e+01, 1.6093144292573264e+01, 1.6332587652172350e+01, 1.6577732962488266e+01, 1.6829264937408070e+01, 1.7088020370809854e+01, 1.7355041415469405e+01, 1.7631655968298805e+01, 1.7919604408706316e+01, 1.8221250688860252e+01, 1.8539959593913657e+01, 1.8880837640701767e+01, 1.9252396116029669e+01, 1.9671145428267970e+01, 2.0180280152078982e+01}, + w: []float64{8.0790134837724204e-178, 4.0123708332001955e-169, 4.1608342695810454e-162, 5.3647010323313458e-156, 1.7249035730335862e-150, 1.9898962894711550e-145, 1.0270178951244021e-140, 2.7462859803070011e-136, 4.2216443703754674e-132, 4.0296773344706320e-128, 2.5341526783446447e-124, 1.1002243777181162e-120, 3.4246772430261828e-117, 7.8839348684832184e-114, 1.3776135348531781e-110, 1.8677560466742519e-107, 2.0021556471031417e-104, 1.7247770196475562e-101, 1.2111464936797437e-98, 7.0196501028640057e-96, 3.3954234881610162e-93, 1.3842435843570204e-90, 4.7985036069815231e-88, 1.4256947701704702e-85, 3.6567711491235357e-83, 8.1499750643585127e-81, 1.5877740343548737e-78, 2.7187040652791320e-76, 4.1119602314337377e-74, 5.5188731969772834e-72, 6.6010643664052121e-70, 7.0639875689587789e-68, 6.7880577161215916e-66, 5.8772891020073188e-64, 4.5996045356018730e-62, 3.2633290432137694e-60, 2.1047497049395128e-58, 1.2372745780617511e-56, 6.6453150452727337e-55, 3.2684621263244055e-53, 1.4753196845067616e-51, 6.1238771021510087e-50, 2.3420591906941631e-48, 8.2677634302135741e-47, 2.6986236644096577e-45, 8.1576808396884509e-44, 2.2873393442828659e-42, 5.9575720207549899e-41, 1.4433986536815081e-39, 3.2572816931648467e-38, 6.8552334632687487e-37, 1.3471217671214917e-35, 2.4745963539025701e-34, 4.2538970187949130e-33, 6.8502295544213803e-32, 1.0344007225282243e-30, 1.4660497224001333e-29, 1.9519881038552925e-28, 2.4437079996027598e-27, 2.8788818637419581e-26, 3.1940663724110344e-25, 3.3399348780894923e-24, 3.2939758359327470e-23, 3.0661414593245886e-22, 2.6955142404467904e-21, 2.2394681775190790e-20, 1.7594079537257698e-19, 1.3078564789171130e-18, 9.2038260248200122e-18, 6.1351365453804107e-17, 3.8757039748543155e-16, 2.3214598330581677e-15, 1.3190482037051148e-14, 7.1128747627508331e-14, 3.6416855631427732e-13, 1.7709744825377116e-12, 8.1836457113383607e-12, 3.5947660428421198e-11, 1.5015547963310099e-10, 5.9663534866912190e-10, 2.2558892777245505e-09, 8.1190427548544262e-09, 2.7822813440253852e-08, 9.0809483027322313e-08, 2.8236711509871372e-07, 8.3668655155751835e-07, 2.3631134387385760e-06, 6.3632839492173400e-06, 1.6339902252008705e-05, 4.0020290652701539e-05, 9.3510362001206373e-05, 2.0848221478522648e-04, 4.4359250162546185e-04, 9.0090002804434576e-04, 1.7466777765574378e-03, 3.2333646918818863e-03, 5.7155709629331409e-03, 9.6489576482962046e-03, 1.5558416546311961e-02, 2.3963959563684092e-02, 3.5261402555428784e-02, 4.9570551047913969e-02, 6.6582815385485522e-02, 8.5455825791019971e-02, 1.0480572103134121e-01, 1.2283174514792664e-01, 1.3757292020567533e-01, 1.4725235676872742e-01, 1.5062763955757250e-01, 1.4725235676872742e-01, 1.3757292020567533e-01, 1.2283174514792664e-01, 1.0480572103134121e-01, 8.5455825791019971e-02, 6.6582815385485522e-02, 4.9570551047913969e-02, 3.5261402555428784e-02, 2.3963959563684092e-02, 1.5558416546311961e-02, 9.6489576482962046e-03, 5.7155709629331409e-03, 3.2333646918818863e-03, 1.7466777765574378e-03, 9.0090002804434576e-04, 4.4359250162546185e-04, 2.0848221478522648e-04, 9.3510362001206373e-05, 4.0020290652701539e-05, 1.6339902252008705e-05, 6.3632839492173400e-06, 2.3631134387385760e-06, 8.3668655155751835e-07, 2.8236711509871372e-07, 9.0809483027322313e-08, 2.7822813440253852e-08, 8.1190427548544262e-09, 2.2558892777245505e-09, 5.9663534866912190e-10, 1.5015547963310099e-10, 3.5947660428421198e-11, 8.1836457113383607e-12, 1.7709744825377116e-12, 3.6416855631427732e-13, 7.1128747627508331e-14, 1.3190482037051148e-14, 2.3214598330581677e-15, 3.8757039748543155e-16, 6.1351365453804107e-17, 9.2038260248200122e-18, 1.3078564789171130e-18, 1.7594079537257698e-19, 2.2394681775190790e-20, 2.6955142404467904e-21, 3.0661414593245886e-22, 3.2939758359327470e-23, 3.3399348780894923e-24, 3.1940663724110344e-25, 2.8788818637419581e-26, 2.4437079996027598e-27, 1.9519881038552925e-28, 1.4660497224001333e-29, 1.0344007225282243e-30, 6.8502295544213803e-32, 4.2538970187949130e-33, 2.4745963539025701e-34, 1.3471217671214917e-35, 6.8552334632687487e-37, 3.2572816931648467e-38, 1.4433986536815081e-39, 5.9575720207549899e-41, 2.2873393442828659e-42, 8.1576808396884509e-44, 2.6986236644096577e-45, 8.2677634302135741e-47, 2.3420591906941631e-48, 6.1238771021510087e-50, 1.4753196845067616e-51, 3.2684621263244055e-53, 6.6453150452727337e-55, 1.2372745780617511e-56, 2.1047497049395128e-58, 3.2633290432137694e-60, 4.5996045356018730e-62, 5.8772891020073188e-64, 6.7880577161215916e-66, 7.0639875689587789e-68, 6.6010643664052121e-70, 5.5188731969772834e-72, 4.1119602314337377e-74, 2.7187040652791320e-76, 1.5877740343548737e-78, 8.1499750643585127e-81, 3.6567711491235357e-83, 1.4256947701704702e-85, 4.7985036069815231e-88, 1.3842435843570204e-90, 3.3954234881610162e-93, 7.0196501028640057e-96, 1.2111464936797437e-98, 1.7247770196475562e-101, 2.0021556471031417e-104, 1.8677560466742519e-107, 1.3776135348531781e-110, 7.8839348684832184e-114, 3.4246772430261828e-117, 1.1002243777181162e-120, 2.5341526783446447e-124, 4.0296773344706320e-128, 4.2216443703754674e-132, 2.7462859803070011e-136, 1.0270178951244021e-140, 1.9898962894711550e-145, 1.7249035730335862e-150, 5.3647010323313458e-156, 4.1608342695810454e-162, 4.0123708332001955e-169, 8.0790134837724204e-178}, + }, + + { + n: 218, + x: []float64{-2.0228695170577915e+01, -1.9719963830858333e+01, -1.9301552400253843e+01, -1.8930298474919816e+01, -1.8589703851801165e+01, -1.8271263496827501e+01, -1.7969874624529179e+01, -1.7682174897106314e+01, -1.7405802075069708e+01, -1.7139017035820078e+01, -1.6880492838899503e+01, -1.6629188080724916e+01, -1.6384266568226192e+01, -1.6145044078855118e+01, -1.5910951775414047e+01, -1.5681510294638914e+01, -1.5456310918627016e+01, -1.5235001587812036e+01, -1.5017276309282583e+01, -1.4802867000027815e+01, -1.4591537111039028e+01, -1.4383076576817141e+01, -1.4177297766812716e+01, -1.3974032204957940e+01, -1.3773127885530926e+01, -1.3574447057358521e+01, -1.3377864379717227e+01, -1.3183265376084384e+01, -1.2990545128683925e+01, -1.2799607169295788e+01, -1.2610362531246457e+01, -1.2422728934700823e+01, -1.2236630082919943e+01, -1.2051995051456386e+01, -1.1868757755632400e+01, -1.1686856484310367e+01, -1.1506233490083723e+01, -1.1326834627713886e+01, -1.1148609034007171e+01, -1.0971508843435563e+01, -1.0795488934711024e+01, -1.0620506704266159e+01, -1.0446521863206758e+01, -1.0273496254809785e+01, -1.0101393690063306e+01, -9.9301797990985268e+00, -9.7598218966614141e+00, -9.5902888600219054e+00, -9.4215510179308293e+00, -9.2535800494152092e+00, -9.0863488913560904e+00, -8.9198316539249092e+00, -8.7540035430671104e+00, -8.5888407893192067e+00, -8.4243205823293916e+00, -8.2604210105245137e+00, -8.0971210054295799e+00, -7.9344002902008972e+00, -7.7722393319820444e+00, -7.6106192977338623e+00, -7.4495220132267015e+00, -7.2889299249154647e+00, -7.1288260644465895e+00, -6.9691940155714960e+00, -6.8100178832631793e+00, -6.6512822648525844e+00, -6.4929722230189020e+00, -6.3350732604836884e+00, -6.1775712962725331e+00, -6.0204526434206276e+00, -5.8637039880096422e+00, -5.7073123694332661e+00, -5.5512651617979705e+00, -5.3955500563732679e+00, -5.2401550450133421e+00, -5.0850684044781733e+00, -4.9302786815884012e+00, -4.7757746791533817e+00, -4.6215454426166902e+00, -4.4675802473678914e+00, -4.3138685866729931e+00, -4.1604001601800418e+00, -4.0071648629591818e+00, -3.8541527750397258e+00, -3.7013541514093888e+00, -3.5487594124432715e+00, -3.3963591347324886e+00, -3.2441440422843915e+00, -3.0921049980680149e+00, -2.9402329958803848e+00, -2.7885191525106028e+00, -2.6369547001801932e+00, -2.4855309792393636e+00, -2.3342394311001944e+00, -2.1830715913886820e+00, -2.0320190832985223e+00, -1.8810736111306099e+00, -1.7302269540027844e+00, -1.5794709597152470e+00, -1.4287975387577758e+00, -1.2781986584451195e+00, -1.1276663371680935e+00, -9.7719263874768358e-01, -8.2676966688043974e-01, -6.7638955966349490e-01, -5.2604448418800387e-01, -3.7572663118998539e-01, -2.2542820974780486e-01, -7.5141442015907556e-02, 7.5141442015907556e-02, 2.2542820974780486e-01, 3.7572663118998539e-01, 5.2604448418800387e-01, 6.7638955966349490e-01, 8.2676966688043974e-01, 9.7719263874768358e-01, 1.1276663371680935e+00, 1.2781986584451195e+00, 1.4287975387577758e+00, 1.5794709597152470e+00, 1.7302269540027844e+00, 1.8810736111306099e+00, 2.0320190832985223e+00, 2.1830715913886820e+00, 2.3342394311001944e+00, 2.4855309792393636e+00, 2.6369547001801932e+00, 2.7885191525106028e+00, 2.9402329958803848e+00, 3.0921049980680149e+00, 3.2441440422843915e+00, 3.3963591347324886e+00, 3.5487594124432715e+00, 3.7013541514093888e+00, 3.8541527750397258e+00, 4.0071648629591818e+00, 4.1604001601800418e+00, 4.3138685866729931e+00, 4.4675802473678914e+00, 4.6215454426166902e+00, 4.7757746791533817e+00, 4.9302786815884012e+00, 5.0850684044781733e+00, 5.2401550450133421e+00, 5.3955500563732679e+00, 5.5512651617979705e+00, 5.7073123694332661e+00, 5.8637039880096422e+00, 6.0204526434206276e+00, 6.1775712962725331e+00, 6.3350732604836884e+00, 6.4929722230189020e+00, 6.6512822648525844e+00, 6.8100178832631793e+00, 6.9691940155714960e+00, 7.1288260644465895e+00, 7.2889299249154647e+00, 7.4495220132267015e+00, 7.6106192977338623e+00, 7.7722393319820444e+00, 7.9344002902008972e+00, 8.0971210054295799e+00, 8.2604210105245137e+00, 8.4243205823293916e+00, 8.5888407893192067e+00, 8.7540035430671104e+00, 8.9198316539249092e+00, 9.0863488913560904e+00, 9.2535800494152092e+00, 9.4215510179308293e+00, 9.5902888600219054e+00, 9.7598218966614141e+00, 9.9301797990985268e+00, 1.0101393690063306e+01, 1.0273496254809785e+01, 1.0446521863206758e+01, 1.0620506704266159e+01, 1.0795488934711024e+01, 1.0971508843435563e+01, 1.1148609034007171e+01, 1.1326834627713886e+01, 1.1506233490083723e+01, 1.1686856484310367e+01, 1.1868757755632400e+01, 1.2051995051456386e+01, 1.2236630082919943e+01, 1.2422728934700823e+01, 1.2610362531246457e+01, 1.2799607169295788e+01, 1.2990545128683925e+01, 1.3183265376084384e+01, 1.3377864379717227e+01, 1.3574447057358521e+01, 1.3773127885530926e+01, 1.3974032204957940e+01, 1.4177297766812716e+01, 1.4383076576817141e+01, 1.4591537111039028e+01, 1.4802867000027815e+01, 1.5017276309282583e+01, 1.5235001587812036e+01, 1.5456310918627016e+01, 1.5681510294638914e+01, 1.5910951775414047e+01, 1.6145044078855118e+01, 1.6384266568226192e+01, 1.6629188080724916e+01, 1.6880492838899503e+01, 1.7139017035820078e+01, 1.7405802075069708e+01, 1.7682174897106314e+01, 1.7969874624529179e+01, 1.8271263496827501e+01, 1.8589703851801165e+01, 1.8930298474919816e+01, 1.9301552400253843e+01, 1.9719963830858333e+01, 2.0228695170577915e+01}, + w: []float64{1.1412038714903467e-178, 5.8600364276414301e-170, 6.2483530291970031e-163, 8.2600389517381484e-157, 2.7180946943728827e-151, 3.2050447674896954e-146, 1.6891299829881347e-141, 4.6087117363873922e-137, 7.2242769320344098e-133, 7.0281073750791237e-129, 4.5026465211632589e-125, 1.9907761957745900e-121, 6.3085296819235091e-118, 1.4780807064034936e-114, 2.6279883692096037e-111, 3.6246331337631131e-108, 3.9519127727199950e-105, 3.4620642776922925e-102, 2.4718758245223020e-99, 1.4565168188237643e-96, 7.1616419809360768e-94, 2.9675903948483656e-91, 1.0455125036940855e-88, 3.1567897170935801e-86, 8.2277370866559977e-84, 1.8632623782187992e-81, 3.6882177983197069e-79, 6.4162031293430147e-77, 9.8590364210588088e-75, 1.3442782637610740e-72, 1.6333988316711487e-70, 1.7756459769101764e-68, 1.7332892347041021e-66, 1.5244548820160086e-64, 1.2118948225793116e-62, 8.7339153184655864e-61, 5.7220382749093667e-59, 3.4167937984322514e-57, 1.8641137908561576e-55, 9.3133897167275065e-54, 4.2703424814876432e-52, 1.8006175119892686e-50, 6.9955013175656585e-49, 2.5086717527911961e-47, 8.3184624948029151e-46, 2.5546048751257637e-44, 7.2770684318833216e-43, 1.9256515369002052e-41, 4.7401499620934791e-40, 1.0868621062998897e-38, 2.3241907456347607e-37, 4.6409284690005433e-36, 8.6630347696542139e-35, 1.5133539937177412e-33, 2.4766678429636503e-32, 3.8008678166597364e-31, 5.4751646602962371e-30, 7.4097643192715769e-29, 9.4293221065635326e-28, 1.1292370018541933e-26, 1.2736861289852883e-25, 1.3540721404735189e-24, 1.3578087095789605e-23, 1.2851527881373697e-22, 1.1488929806753338e-21, 9.7071144039920359e-21, 7.7562537574525747e-20, 5.8643464026904450e-19, 4.1979458289914584e-18, 2.8466716026161652e-17, 1.8295539696950399e-16, 1.1150004956688747e-15, 6.4466274804790879e-15, 3.5376499268729578e-14, 1.8433622668090456e-13, 9.1243282637242511e-13, 4.2919888935314847e-12, 1.9193290587578772e-11, 8.1626646177788407e-11, 3.3026130822100178e-10, 1.2716614885102940e-09, 4.6613505196508951e-09, 1.6270858113762294e-08, 5.4099533071374670e-08, 1.7138819219313466e-07, 5.1747190361086424e-07, 1.4894285947831174e-06, 4.0877345728852175e-06, 1.0699746166171350e-05, 2.6716804837681635e-05, 6.3650699225936851e-05, 1.4471442394637491e-04, 3.1404212609163355e-04, 6.5058509971884274e-04, 1.2868513657693481e-03, 2.4306591608453860e-03, 4.3848013160776717e-03, 7.5554485133504786e-03, 1.2436693679604333e-02, 1.9558227968032915e-02, 2.9388347600235249e-02, 4.2196739277833864e-02, 5.7899315166709715e-02, 7.5925444911783990e-02, 9.5157950558542009e-02, 1.1399005091049424e-01, 1.3051762867943345e-01, 1.4284462872400217e-01, 1.4943738595687683e-01, 1.4943738595687683e-01, 1.4284462872400217e-01, 1.3051762867943345e-01, 1.1399005091049424e-01, 9.5157950558542009e-02, 7.5925444911783990e-02, 5.7899315166709715e-02, 4.2196739277833864e-02, 2.9388347600235249e-02, 1.9558227968032915e-02, 1.2436693679604333e-02, 7.5554485133504786e-03, 4.3848013160776717e-03, 2.4306591608453860e-03, 1.2868513657693481e-03, 6.5058509971884274e-04, 3.1404212609163355e-04, 1.4471442394637491e-04, 6.3650699225936851e-05, 2.6716804837681635e-05, 1.0699746166171350e-05, 4.0877345728852175e-06, 1.4894285947831174e-06, 5.1747190361086424e-07, 1.7138819219313466e-07, 5.4099533071374670e-08, 1.6270858113762294e-08, 4.6613505196508951e-09, 1.2716614885102940e-09, 3.3026130822100178e-10, 8.1626646177788407e-11, 1.9193290587578772e-11, 4.2919888935314847e-12, 9.1243282637242511e-13, 1.8433622668090456e-13, 3.5376499268729578e-14, 6.4466274804790879e-15, 1.1150004956688747e-15, 1.8295539696950399e-16, 2.8466716026161652e-17, 4.1979458289914584e-18, 5.8643464026904450e-19, 7.7562537574525747e-20, 9.7071144039920359e-21, 1.1488929806753338e-21, 1.2851527881373697e-22, 1.3578087095789605e-23, 1.3540721404735189e-24, 1.2736861289852883e-25, 1.1292370018541933e-26, 9.4293221065635326e-28, 7.4097643192715769e-29, 5.4751646602962371e-30, 3.8008678166597364e-31, 2.4766678429636503e-32, 1.5133539937177412e-33, 8.6630347696542139e-35, 4.6409284690005433e-36, 2.3241907456347607e-37, 1.0868621062998897e-38, 4.7401499620934791e-40, 1.9256515369002052e-41, 7.2770684318833216e-43, 2.5546048751257637e-44, 8.3184624948029151e-46, 2.5086717527911961e-47, 6.9955013175656585e-49, 1.8006175119892686e-50, 4.2703424814876432e-52, 9.3133897167275065e-54, 1.8641137908561576e-55, 3.4167937984322514e-57, 5.7220382749093667e-59, 8.7339153184655864e-61, 1.2118948225793116e-62, 1.5244548820160086e-64, 1.7332892347041021e-66, 1.7756459769101764e-68, 1.6333988316711487e-70, 1.3442782637610740e-72, 9.8590364210588088e-75, 6.4162031293430147e-77, 3.6882177983197069e-79, 1.8632623782187992e-81, 8.2277370866559977e-84, 3.1567897170935801e-86, 1.0455125036940855e-88, 2.9675903948483656e-91, 7.1616419809360768e-94, 1.4565168188237643e-96, 2.4718758245223020e-99, 3.4620642776922925e-102, 3.9519127727199950e-105, 3.6246331337631131e-108, 2.6279883692096037e-111, 1.4780807064034936e-114, 6.3085296819235091e-118, 1.9907761957745900e-121, 4.5026465211632589e-125, 7.0281073750791237e-129, 7.2242769320344098e-133, 4.6087117363873922e-137, 1.6891299829881347e-141, 3.2050447674896954e-146, 2.7180946943728827e-151, 8.2600389517381484e-157, 6.2483530291970031e-163, 5.8600364276414301e-170, 1.1412038714903467e-178}, + }, + { + n: 219, + x: []float64{-2.0276997908046905e+01, -1.9768667748260523e+01, -1.9350592328749663e+01, -1.8979641248255188e+01, -1.8639328445512675e+01, -1.8321155106754730e+01, -1.8020022158568153e+01, -1.7732569697856896e+01, -1.7456437188959409e+01, -1.7189886759582706e+01, -1.6931592420762687e+01, -1.6680513514209245e+01, -1.6435814444517028e+01, -1.6196811477889465e+01, -1.5962936183500821e+01, -1.5733709540823362e+01, -1.5508723124641774e+01, -1.5287625128097030e+01, -1.5070109778611977e+01, -1.4855909186982135e+01, -1.4644786976036578e+01, -1.4436533233749541e+01, -1.4230960467563948e+01, -1.4027900326255610e+01, -1.3827200917702472e+01, -1.3628724594657513e+01, -1.3432346111954516e+01, -1.3237951081351927e+01, -1.3045434667000123e+01, -1.2854700477033081e+01, -1.2665659616227074e+01, -1.2478229871866438e+01, -1.2292335010497055e+01, -1.2107904167551959e+01, -1.1924871315204850e+01, -1.1743174796469416e+01, -1.1562756915679721e+01, -1.1383563577182978e+01, -1.1205543965443459e+01, -1.1028650260865531e+01, -1.0852837386548828e+01, -1.0678062781931233e+01, -1.0504286199887655e+01, -1.0331469524360219e+01, -1.0159576606018058e+01, -9.9885731137985694e+00, -9.8184264004786943e+00, -9.6491053806754916e+00, -9.4805804198871506e+00, -9.3128232333657657e+00, -9.1458067937670240e+00, -8.9795052466532344e+00, -8.8138938330391774e+00, -8.6489488182673355e+00, -8.4846474265831215e+00, -8.3209677808533336e+00, -8.1578888469343305e+00, -7.9953903822513528e+00, -7.8334528881984324e+00, -7.6720575660104693e+00, -7.5111862757957555e+00, -7.3508214984498235e+00, -7.1909463001999656e+00, -7.0315442995549828e+00, -6.8725996364571813e+00, -6.7140969434532645e+00, -6.5560213187184688e+00, -6.3983583007839497e+00, -6.2410938448312283e+00, -6.0842143004302391e+00, -5.9277063906083614e+00, -5.7715571921480873e+00, -5.6157541170197165e+00, -5.4602848948636904e+00, -5.3051375564443513e+00, -5.1503004180034342e+00, -4.9957620664475568e+00, -4.8415113453092564e+00, -4.6875373414259709e+00, -4.5338293722856466e+00, -4.3803769739918419e+00, -4.2271698898044328e+00, -4.0741980592156279e+00, -3.9214516075238026e+00, -3.7689208358703388e+00, -3.6165962117072561e+00, -3.4644683596654966e+00, -3.3125280527959076e+00, -3.1607662041567641e+00, -3.0091738587233952e+00, -2.8577421855969432e+00, -2.7064624704909552e+00, -2.5553261084754681e+00, -2.4043245969596510e+00, -2.2534495288951528e+00, -2.1026925861830650e+00, -1.9520455332686681e+00, -1.8015002109084974e+00, -1.6510485300954487e+00, -1.5006824661279821e+00, -1.3503940528101779e+00, -1.2001753767700742e+00, -1.0500185718839765e+00, -8.9991581379505270e-01, -7.4985931451474896e-01, -5.9984131709602384e-01, -4.4985409036765389e-01, -2.9988992371893503e-01, -1.4994112192465620e-01, 8.0217422708380516e-15, 1.4994112192465620e-01, 2.9988992371893503e-01, 4.4985409036765389e-01, 5.9984131709602384e-01, 7.4985931451474896e-01, 8.9991581379505270e-01, 1.0500185718839765e+00, 1.2001753767700742e+00, 1.3503940528101779e+00, 1.5006824661279821e+00, 1.6510485300954487e+00, 1.8015002109084974e+00, 1.9520455332686681e+00, 2.1026925861830650e+00, 2.2534495288951528e+00, 2.4043245969596510e+00, 2.5553261084754681e+00, 2.7064624704909552e+00, 2.8577421855969432e+00, 3.0091738587233952e+00, 3.1607662041567641e+00, 3.3125280527959076e+00, 3.4644683596654966e+00, 3.6165962117072561e+00, 3.7689208358703388e+00, 3.9214516075238026e+00, 4.0741980592156279e+00, 4.2271698898044328e+00, 4.3803769739918419e+00, 4.5338293722856466e+00, 4.6875373414259709e+00, 4.8415113453092564e+00, 4.9957620664475568e+00, 5.1503004180034342e+00, 5.3051375564443513e+00, 5.4602848948636904e+00, 5.6157541170197165e+00, 5.7715571921480873e+00, 5.9277063906083614e+00, 6.0842143004302391e+00, 6.2410938448312283e+00, 6.3983583007839497e+00, 6.5560213187184688e+00, 6.7140969434532645e+00, 6.8725996364571813e+00, 7.0315442995549828e+00, 7.1909463001999656e+00, 7.3508214984498235e+00, 7.5111862757957555e+00, 7.6720575660104693e+00, 7.8334528881984324e+00, 7.9953903822513528e+00, 8.1578888469343305e+00, 8.3209677808533336e+00, 8.4846474265831215e+00, 8.6489488182673355e+00, 8.8138938330391774e+00, 8.9795052466532344e+00, 9.1458067937670240e+00, 9.3128232333657657e+00, 9.4805804198871506e+00, 9.6491053806754916e+00, 9.8184264004786943e+00, 9.9885731137985694e+00, 1.0159576606018058e+01, 1.0331469524360219e+01, 1.0504286199887655e+01, 1.0678062781931233e+01, 1.0852837386548828e+01, 1.1028650260865531e+01, 1.1205543965443459e+01, 1.1383563577182978e+01, 1.1562756915679721e+01, 1.1743174796469416e+01, 1.1924871315204850e+01, 1.2107904167551959e+01, 1.2292335010497055e+01, 1.2478229871866438e+01, 1.2665659616227074e+01, 1.2854700477033081e+01, 1.3045434667000123e+01, 1.3237951081351927e+01, 1.3432346111954516e+01, 1.3628724594657513e+01, 1.3827200917702472e+01, 1.4027900326255610e+01, 1.4230960467563948e+01, 1.4436533233749541e+01, 1.4644786976036578e+01, 1.4855909186982135e+01, 1.5070109778611977e+01, 1.5287625128097030e+01, 1.5508723124641774e+01, 1.5733709540823362e+01, 1.5962936183500821e+01, 1.6196811477889465e+01, 1.6435814444517028e+01, 1.6680513514209245e+01, 1.6931592420762687e+01, 1.7189886759582706e+01, 1.7456437188959409e+01, 1.7732569697856896e+01, 1.8020022158568153e+01, 1.8321155106754730e+01, 1.8639328445512675e+01, 1.8979641248255188e+01, 1.9350592328749663e+01, 1.9768667748260523e+01, 2.0276997908046905e+01}, + w: []float64{1.6118004761490936e-179, 8.5565157993831952e-171, 9.3801386072360495e-164, 1.2712817065467470e-157, 4.2810879764792902e-152, 5.1593581306426363e-147, 2.7763562197121041e-142, 7.7287684331971630e-138, 1.2353061004428027e-133, 1.2247428452374434e-129, 7.9930519467022852e-126, 3.5986937020445443e-122, 1.1608863141459933e-118, 2.7680773700442792e-115, 5.0074481042562811e-112, 7.0254966797767812e-109, 7.7903695739499256e-106, 6.9398586398625168e-103, 5.0378132240927281e-100, 3.0176790544586562e-97, 1.5082063803644767e-94, 6.3518001539538009e-92, 2.2741855202923794e-89, 6.9776584966048747e-87, 1.8479046829051634e-84, 4.2518674704681371e-82, 8.5507393331426323e-80, 1.5112093165489227e-77, 2.3589639789454550e-75, 3.2673822149378061e-73, 4.0328590535463278e-71, 4.4532356700297110e-69, 4.4154958570004513e-67, 3.9446173154369991e-65, 3.1851636643508064e-63, 2.3315719656364080e-61, 1.5515360955581329e-59, 9.4102483913550526e-58, 5.2146771930312127e-56, 2.6462964683019027e-54, 1.2324622103285675e-52, 5.2785960684684324e-51, 2.0830950016909702e-49, 7.5881492915547110e-48, 2.5559164938518617e-46, 7.9735166177827294e-45, 2.3073707359625722e-43, 6.2027848314701266e-42, 1.5511852212359039e-40, 3.6134675099711877e-39, 7.8508422681776689e-38, 1.5928021832222874e-36, 3.0210523716429586e-35, 5.3626533220153980e-34, 8.9182314112122594e-33, 1.3908724042317442e-31, 2.0361886950192076e-30, 2.8006915544325587e-29, 3.6224809761826824e-28, 4.4096199762595120e-27, 5.0558656605721755e-26, 5.4641111784906703e-25, 5.5704394297442813e-24, 5.3605363007899914e-23, 4.8726597293407410e-22, 4.1864031729275524e-21, 3.4017282707064429e-20, 2.6157557992877646e-19, 1.9044895750724533e-18, 1.3136464708861073e-17, 8.5885898614439566e-17, 5.3250576372585674e-16, 3.1325104388327040e-15, 1.7491400171437906e-14, 9.2749216025525341e-14, 4.6723068181067832e-13, 2.2369795792044991e-12, 1.0182840690359900e-11, 4.4087115371635113e-11, 1.8161128736541464e-10, 7.1204644180465281e-10, 2.6579545759517285e-09, 9.4491700732305002e-09, 3.2001745961210195e-08, 1.0327820095258369e-07, 3.1769761704760471e-07, 9.3174969312259845e-07, 2.6059663547935113e-06, 6.9521878670475772e-06, 1.7695019387908094e-05, 4.2977984770344540e-05, 9.9630005120895210e-05, 2.2047640877838706e-04, 4.6583912781443418e-04, 9.3989854709223869e-04, 1.8111811218635974e-03, 3.3337948402502641e-03, 5.8622951858897081e-03, 9.8491710526776490e-03, 1.5811821288832947e-02, 2.4258117817844916e-02, 3.5568359860607475e-02, 4.9846708381161745e-02, 6.6773674520725357e-02, 8.5505952447471292e-02, 1.0467230074567024e-01, 1.2249815849737687e-01, 1.3705778627617005e-01, 1.4661020932556390e-01, 1.4993984211667696e-01, 1.4661020932556390e-01, 1.3705778627617005e-01, 1.2249815849737687e-01, 1.0467230074567024e-01, 8.5505952447471292e-02, 6.6773674520725357e-02, 4.9846708381161745e-02, 3.5568359860607475e-02, 2.4258117817844916e-02, 1.5811821288832947e-02, 9.8491710526776490e-03, 5.8622951858897081e-03, 3.3337948402502641e-03, 1.8111811218635974e-03, 9.3989854709223869e-04, 4.6583912781443418e-04, 2.2047640877838706e-04, 9.9630005120895210e-05, 4.2977984770344540e-05, 1.7695019387908094e-05, 6.9521878670475772e-06, 2.6059663547935113e-06, 9.3174969312259845e-07, 3.1769761704760471e-07, 1.0327820095258369e-07, 3.2001745961210195e-08, 9.4491700732305002e-09, 2.6579545759517285e-09, 7.1204644180465281e-10, 1.8161128736541464e-10, 4.4087115371635113e-11, 1.0182840690359900e-11, 2.2369795792044991e-12, 4.6723068181067832e-13, 9.2749216025525341e-14, 1.7491400171437906e-14, 3.1325104388327040e-15, 5.3250576372585674e-16, 8.5885898614439566e-17, 1.3136464708861073e-17, 1.9044895750724533e-18, 2.6157557992877646e-19, 3.4017282707064429e-20, 4.1864031729275524e-21, 4.8726597293407410e-22, 5.3605363007899914e-23, 5.5704394297442813e-24, 5.4641111784906703e-25, 5.0558656605721755e-26, 4.4096199762595120e-27, 3.6224809761826824e-28, 2.8006915544325587e-29, 2.0361886950192076e-30, 1.3908724042317442e-31, 8.9182314112122594e-33, 5.3626533220153980e-34, 3.0210523716429586e-35, 1.5928021832222874e-36, 7.8508422681776689e-38, 3.6134675099711877e-39, 1.5511852212359039e-40, 6.2027848314701266e-42, 2.3073707359625722e-43, 7.9735166177827294e-45, 2.5559164938518617e-46, 7.5881492915547110e-48, 2.0830950016909702e-49, 5.2785960684684324e-51, 1.2324622103285675e-52, 2.6462964683019027e-54, 5.2146771930312127e-56, 9.4102483913550526e-58, 1.5515360955581329e-59, 2.3315719656364080e-61, 3.1851636643508064e-63, 3.9446173154369991e-65, 4.4154958570004513e-67, 4.4532356700297110e-69, 4.0328590535463278e-71, 3.2673822149378061e-73, 2.3589639789454550e-75, 1.5112093165489227e-77, 8.5507393331426323e-80, 4.2518674704681371e-82, 1.8479046829051634e-84, 6.9776584966048747e-87, 2.2741855202923794e-89, 6.3518001539538009e-92, 1.5082063803644767e-94, 3.0176790544586562e-97, 5.0378132240927281e-100, 6.9398586398625168e-103, 7.7903695739499256e-106, 7.0254966797767812e-109, 5.0074481042562811e-112, 2.7680773700442792e-115, 1.1608863141459933e-118, 3.5986937020445443e-122, 7.9930519467022852e-126, 1.2247428452374434e-129, 1.2353061004428027e-133, 7.7287684331971630e-138, 2.7763562197121041e-142, 5.1593581306426363e-147, 4.2810879764792902e-152, 1.2712817065467470e-157, 9.3801386072360495e-164, 8.5565157993831952e-171, 1.6118004761490936e-179}, + }, + { + n: 220, + x: []float64{-2.0325189139629405e+01, -1.9817257977795947e+01, -1.9399516717870224e+01, -1.9028866794578029e+01, -1.8688834225534919e+01, -1.8370926385157830e+01, -1.8070047892967271e+01, -1.7782841268044042e+01, -1.7506947669788651e+01, -1.7240630469775191e+01, -1.6982564625621777e+01, -1.6731710220470223e+01, -1.6487232253468321e+01, -1.6248447477010238e+01, -1.6014787864496149e+01, -1.5785774736307584e+01, -1.5560999958339213e+01, -1.5340111975060188e+01, -1.5122805233008011e+01, -1.4908812035694833e+01, -1.4697896176804390e+01, -1.4489847896889446e+01, -1.4284479840564213e+01, -1.4081623780688842e+01, -1.3881127938034011e+01, -1.3682854768615876e+01, -1.3486679122200039e+01, -1.3292486698232523e+01, -1.3100172742223814e+01, -1.2909640938118768e+01, -1.2720802461619986e+01, -1.2533575166624548e+01, -1.2347882882470566e+01, -1.2163654803990811e+01, -1.1980824959739557e+01, -1.1799331746419007e+01, -1.1619117519647554e+01, -1.1440128232906956e+01, -1.1262313117871999e+01, -1.1085624400434606e+01, -1.0910017047638791e+01, -1.0735448541485018e+01, -1.0561878676174262e+01, -1.0389269375869560e+01, -1.0217584530474927e+01, -1.0046789847284987e+01, -9.8768527166552929e+00, -9.7077420900935678e+00, -9.5394283693840993e+00, -9.3718833055374660e+00, -9.2050799065113704e+00, -9.0389923527798217e+00, -8.8735959199405876e+00, -8.7088669076480283e+00, -8.5447825742424133e+00, -8.3813210765192689e+00, -8.2184614141456525e+00, -8.0561833782850805e+00, -7.8944675040409047e+00, -7.7332950263697580e+00, -7.5726478391539116e+00, -7.4125084571532707e+00, -7.2528599805868588e+00, -7.0936860621182607e+00, -6.9349708760424020e+00, -6.7766990894903305e+00, -6.6188558354865279e+00, -6.4614266877089035e+00, -6.3043976368153372e+00, -6.1477550682134519e+00, -5.9914857411611600e+00, -5.8355767690955807e+00, -5.6800156010969900e+00, -5.5247900044023472e+00, -5.3698880478903845e+00, -5.2152980864665599e+00, -5.0610087462822682e+00, -4.9070089107279511e+00, -4.7532877071444766e+00, -4.5998344942017342e+00, -4.4466388498971172e+00, -4.2936905601303739e+00, -4.1409796078143595e+00, -3.9884961624844180e+00, -3.8362305703715940e+00, -3.6841733449075362e+00, -3.5323151576310980e+00, -3.3806468294686467e+00, -3.2291593223621100e+00, -3.0778437312202702e+00, -2.9266912761707076e+00, -2.7756932950907438e+00, -2.6248412363975424e+00, -2.4741266520783536e+00, -2.3235411909430654e+00, -2.1730765920823036e+00, -2.0227246785151167e+00, -1.8724773510110999e+00, -1.7223265820726865e+00, -1.5722644100637477e+00, -1.4222829334715719e+00, -1.2723743052896335e+00, -1.1225307275089995e+00, -9.7274444570696528e-01, -8.2300774372149477e-01, -6.7331293840074014e-01, -5.2365237441695056e-01, -3.7401841913451778e-01, -2.2440345752197671e-01, -7.4799887098051757e-02, 7.4799887098051757e-02, 2.2440345752197671e-01, 3.7401841913451778e-01, 5.2365237441695056e-01, 6.7331293840074014e-01, 8.2300774372149477e-01, 9.7274444570696528e-01, 1.1225307275089995e+00, 1.2723743052896335e+00, 1.4222829334715719e+00, 1.5722644100637477e+00, 1.7223265820726865e+00, 1.8724773510110999e+00, 2.0227246785151167e+00, 2.1730765920823036e+00, 2.3235411909430654e+00, 2.4741266520783536e+00, 2.6248412363975424e+00, 2.7756932950907438e+00, 2.9266912761707076e+00, 3.0778437312202702e+00, 3.2291593223621100e+00, 3.3806468294686467e+00, 3.5323151576310980e+00, 3.6841733449075362e+00, 3.8362305703715940e+00, 3.9884961624844180e+00, 4.1409796078143595e+00, 4.2936905601303739e+00, 4.4466388498971172e+00, 4.5998344942017342e+00, 4.7532877071444766e+00, 4.9070089107279511e+00, 5.0610087462822682e+00, 5.2152980864665599e+00, 5.3698880478903845e+00, 5.5247900044023472e+00, 5.6800156010969900e+00, 5.8355767690955807e+00, 5.9914857411611600e+00, 6.1477550682134519e+00, 6.3043976368153372e+00, 6.4614266877089035e+00, 6.6188558354865279e+00, 6.7766990894903305e+00, 6.9349708760424020e+00, 7.0936860621182607e+00, 7.2528599805868588e+00, 7.4125084571532707e+00, 7.5726478391539116e+00, 7.7332950263697580e+00, 7.8944675040409047e+00, 8.0561833782850805e+00, 8.2184614141456525e+00, 8.3813210765192689e+00, 8.5447825742424133e+00, 8.7088669076480283e+00, 8.8735959199405876e+00, 9.0389923527798217e+00, 9.2050799065113704e+00, 9.3718833055374660e+00, 9.5394283693840993e+00, 9.7077420900935678e+00, 9.8768527166552929e+00, 1.0046789847284987e+01, 1.0217584530474927e+01, 1.0389269375869560e+01, 1.0561878676174262e+01, 1.0735448541485018e+01, 1.0910017047638791e+01, 1.1085624400434606e+01, 1.1262313117871999e+01, 1.1440128232906956e+01, 1.1619117519647554e+01, 1.1799331746419007e+01, 1.1980824959739557e+01, 1.2163654803990811e+01, 1.2347882882470566e+01, 1.2533575166624548e+01, 1.2720802461619986e+01, 1.2909640938118768e+01, 1.3100172742223814e+01, 1.3292486698232523e+01, 1.3486679122200039e+01, 1.3682854768615876e+01, 1.3881127938034011e+01, 1.4081623780688842e+01, 1.4284479840564213e+01, 1.4489847896889446e+01, 1.4697896176804390e+01, 1.4908812035694833e+01, 1.5122805233008011e+01, 1.5340111975060188e+01, 1.5560999958339213e+01, 1.5785774736307584e+01, 1.6014787864496149e+01, 1.6248447477010238e+01, 1.6487232253468321e+01, 1.6731710220470223e+01, 1.6982564625621777e+01, 1.7240630469775191e+01, 1.7506947669788651e+01, 1.7782841268044042e+01, 1.8070047892967271e+01, 1.8370926385157830e+01, 1.8688834225534919e+01, 1.9028866794578029e+01, 1.9399516717870224e+01, 1.9817257977795947e+01, 2.0325189139629405e+01}, + w: []float64{2.2761605731502931e-180, 1.2490844229282551e-171, 1.4077080884426324e-164, 1.9558070725961945e-158, 6.7396164617778564e-153, 8.3007451278928549e-148, 4.5605427168506885e-143, 1.2952107195320918e-138, 2.1106922482765282e-134, 2.1325182525295938e-130, 1.4176541142180510e-126, 6.4990818384221324e-123, 2.1340663816447175e-119, 5.1782994410611593e-116, 9.5303885471678039e-113, 1.3600769560707746e-109, 1.5337501625076215e-106, 1.3892626373123839e-103, 1.0252931948997944e-100, 6.2430026550428978e-98, 3.1713496923820005e-95, 1.3573663268548106e-92, 4.9385791079870452e-90, 1.5396613562557895e-87, 4.1428768007295419e-85, 9.6845718261332366e-83, 1.9785969337019459e-80, 3.5522955000635345e-78, 5.6327088700629997e-76, 7.9248469784581938e-74, 9.9353884108905009e-72, 1.1143371044053519e-69, 1.1222249771693660e-67, 1.0182568638449594e-65, 8.3508496445242703e-64, 6.2085535684767686e-62, 4.1960840622737107e-60, 2.5847807937901128e-58, 1.4547608917709417e-56, 7.4980265458380947e-55, 3.5467498009174184e-53, 1.5428702374218767e-51, 6.1841637682672203e-50, 2.2881100073201874e-48, 7.8282784948541621e-47, 2.4806114249059706e-45, 7.2916745732054914e-44, 1.9911806078855746e-42, 5.0584298583405264e-41, 1.1970700137586669e-39, 2.6422337190194530e-38, 5.4462015155980312e-37, 1.0495069994748297e-35, 1.8928725655710039e-34, 3.1985659419085236e-33, 5.0689745622498271e-32, 7.5410079936029980e-31, 1.0540919389712685e-29, 1.3856239612378123e-28, 1.7143191474654609e-27, 1.9978524188114189e-26, 2.1947842513043781e-25, 2.2745432296820405e-24, 2.2252271383645215e-23, 2.0564749726923156e-22, 1.7964719327802204e-21, 1.4843379300503135e-20, 1.1606915413845120e-19, 8.5944540731309027e-19, 6.0293824390549243e-18, 4.0096487904356170e-17, 2.5289217277543671e-16, 1.5134484435681475e-15, 8.5980922774659504e-15, 4.6390554602844329e-14, 2.3781148094626393e-13, 1.1587426167580950e-12, 5.3685841373417416e-12, 2.3659835874748833e-11, 9.9219381603477156e-11, 3.9606009206879336e-10, 1.5053791970450186e-09, 5.4498580894419877e-09, 1.8797800781026250e-08, 6.1792198822459984e-08, 1.9363392840773747e-07, 5.7857719375034532e-07, 1.6488403637671232e-06, 4.4826356596959815e-06, 1.1628419918195159e-05, 2.8789242845201347e-05, 6.8037279449589797e-05, 1.5351500720814013e-04, 3.3076323494923371e-04, 6.8063888690970183e-04, 1.3378748383672085e-03, 2.5123201954271616e-03, 4.5076732111920138e-03, 7.7285957578851656e-03, 1.2663915587278220e-02, 1.9833481075447929e-02, 2.9691593353631068e-02, 4.2492045448586743e-02, 5.8137078835965875e-02, 7.6049788530935164e-02, 9.5118681388506904e-02, 1.1375654825578213e-01, 1.3009049092173738e-01, 1.4226074789149157e-01, 1.4876572633109977e-01, 1.4876572633109977e-01, 1.4226074789149157e-01, 1.3009049092173738e-01, 1.1375654825578213e-01, 9.5118681388506904e-02, 7.6049788530935164e-02, 5.8137078835965875e-02, 4.2492045448586743e-02, 2.9691593353631068e-02, 1.9833481075447929e-02, 1.2663915587278220e-02, 7.7285957578851656e-03, 4.5076732111920138e-03, 2.5123201954271616e-03, 1.3378748383672085e-03, 6.8063888690970183e-04, 3.3076323494923371e-04, 1.5351500720814013e-04, 6.8037279449589797e-05, 2.8789242845201347e-05, 1.1628419918195159e-05, 4.4826356596959815e-06, 1.6488403637671232e-06, 5.7857719375034532e-07, 1.9363392840773747e-07, 6.1792198822459984e-08, 1.8797800781026250e-08, 5.4498580894419877e-09, 1.5053791970450186e-09, 3.9606009206879336e-10, 9.9219381603477156e-11, 2.3659835874748833e-11, 5.3685841373417416e-12, 1.1587426167580950e-12, 2.3781148094626393e-13, 4.6390554602844329e-14, 8.5980922774659504e-15, 1.5134484435681475e-15, 2.5289217277543671e-16, 4.0096487904356170e-17, 6.0293824390549243e-18, 8.5944540731309027e-19, 1.1606915413845120e-19, 1.4843379300503135e-20, 1.7964719327802204e-21, 2.0564749726923156e-22, 2.2252271383645215e-23, 2.2745432296820405e-24, 2.1947842513043781e-25, 1.9978524188114189e-26, 1.7143191474654609e-27, 1.3856239612378123e-28, 1.0540919389712685e-29, 7.5410079936029980e-31, 5.0689745622498271e-32, 3.1985659419085236e-33, 1.8928725655710039e-34, 1.0495069994748297e-35, 5.4462015155980312e-37, 2.6422337190194530e-38, 1.1970700137586669e-39, 5.0584298583405264e-41, 1.9911806078855746e-42, 7.2916745732054914e-44, 2.4806114249059706e-45, 7.8282784948541621e-47, 2.2881100073201874e-48, 6.1841637682672203e-50, 1.5428702374218767e-51, 3.5467498009174184e-53, 7.4980265458380947e-55, 1.4547608917709417e-56, 2.5847807937901128e-58, 4.1960840622737107e-60, 6.2085535684767686e-62, 8.3508496445242703e-64, 1.0182568638449594e-65, 1.1222249771693660e-67, 1.1143371044053519e-69, 9.9353884108905009e-72, 7.9248469784581938e-74, 5.6327088700629997e-76, 3.5522955000635345e-78, 1.9785969337019459e-80, 9.6845718261332366e-83, 4.1428768007295419e-85, 1.5396613562557895e-87, 4.9385791079870452e-90, 1.3573663268548106e-92, 3.1713496923820005e-95, 6.2430026550428978e-98, 1.0252931948997944e-100, 1.3892626373123839e-103, 1.5337501625076215e-106, 1.3600769560707746e-109, 9.5303885471678039e-113, 5.1782994410611593e-116, 2.1340663816447175e-119, 6.4990818384221324e-123, 1.4176541142180510e-126, 2.1325182525295938e-130, 2.1106922482765282e-134, 1.2952107195320918e-138, 4.5605427168506885e-143, 8.3007451278928549e-148, 6.7396164617778564e-153, 1.9558070725961945e-158, 1.4077080884426324e-164, 1.2490844229282551e-171, 2.2761605731502931e-180}, + }, + } { + h := Hermite{} + x := make([]float64, test.n) + weight := make([]float64, test.n) + h.FixedLocations(x, weight, math.Inf(-1), math.Inf(1)) + if !floats.EqualApprox(x, test.x, 1e-14) { + t.Errorf("n = %v, x mismatch", test.n) + fmt.Println(x) + fmt.Println() + fmt.Println(test.x) + //t.Errorf("x mismatch. \nWant %v\ngot %v", test.x, x) + } + if !floats.EqualApprox(weight, test.w, 1e-14) { + t.Errorf("n = %v, w mismatch", test.n) + //t.Errorf("w mismatch. Want %v, got %v", test.w, weight) + } + } +} + +func TestHermiteInitialGuesses(t *testing.T) { + for _, test := range []struct { + n int + want []float64 + }{ + // Evaluated from Chebfun. + { + n: 215, + want: []float64{0, 0.151326329763712, 0.302660700793398, 0.454011159911720, 0.605385765065948, 0.756792590918330, 0.908239734470234, 1.059735320731617, 1.211287508447394, 1.362904495892717, 1.514594526749157, 1.666365896074552, 1.818226956379164, 1.970186123821706, 2.122251884538916, 2.274432801123240, 2.426737519263548, 2.579174774564779, 2.731753399562905, 2.884482330952826, 3.037370617047366, 3.190427425487010, 3.343662051220745, 3.497083924780193, 3.650702620869949, 3.804527867299248, 3.958569554281313, 4.112837744128784, 4.267342681375636, 4.422094803358200, 4.577104751290402, 4.732383381871004, 4.887941779463563, 5.043791268893151, 5.199943428907478, 5.356410106353889, 5.513203431128299, 5.670335831956713, 5.827820053075521, 5.985669171882509, 6.143896617637219, 6.302516191296349, 6.461542086578262, 6.620988912359293, 6.780871716514890, 6.941206011329554, 7.102007800612191, 7.263293608667420, 7.425080511288993, 7.587386168959320, 7.750228862458692, 7.913627531110426, 8.077601813913194, 8.242172093840729, 8.407359545621334, 8.573186187346858, 8.739674936302684, 8.906849669458699, 9.074735289116129, 9.243357794268617, 9.412744358308792, 9.582923413795772, 9.753924745096450, 9.925779589826769, 10.098520750150884, 10.272182715150265, 10.446801795655594, 10.622416273146731, 10.799066564577450, 10.976795405279171, 11.155648052452676, 11.335672512180423, 11.516919793401330, 11.699444192903831, 11.883303616137852, 12.068559939553955, 12.255279421290370, 12.443533168399910, 12.633397670509774, 12.824955411930718, 13.018295576901773, 13.213514866037960, 13.410718446364541, 13.610021062878001, 13.811548346792373, 14.015438365098394, 14.221843468615116, 14.430932512542578, 14.642893546366283, 14.857937101386424, 15.076300248006383, 15.298251657131900, 15.524097989861344, 15.754192071913305, 15.988943508292977, 16.228832700713156, 16.474429717130270, 16.726420259572109, 16.985642328947012, 17.253139580754688, 17.530241825363181, 17.818691945179868, 18.120857274390474, 18.440107345774539, 18.781555607447057, 19.153723464992801, 19.573128956064245, 20.082675660407357}, + }, + { + n: 216, + want: []float64{7.5487718957947841e-02, 2.2646713089416223e-01, 3.7745846761172613e-01, 5.2846968803819716e-01, 6.7950876473020116e-01, 8.3058368936317251e-01, 9.8170247825952706e-01, 1.1328731779663146e+00, 1.2841038708939367e+00, 1.4354026810274640e+00, 1.5867777797225648e+00, 1.7382373915984026e+00, 1.8897898005400910e+00, 2.0414433558240375e+00, 2.1932064783796412e+00, 2.3450876672018457e+00, 2.4970955059292010e+00, 2.6492386696032790e+00, 2.8015259316256671e+00, 2.9539661709299665e+00, 3.1065683793869288e+00, 3.2593416694621893e+00, 3.4122952821469283e+00, 3.5654385951833136e+00, 3.7187811316079062e+00, 3.8723325686377130e+00, 4.0261027469252912e+00, 4.1801016802112088e+00, 4.3343395654041350e+00, 4.4888267931211692e+00, 4.6435739587232687e+00, 4.7985918738836766e+00, 4.9538915787298405e+00, 5.1094843546028494e+00, 5.2653817374818566e+00, 5.4215955321250595e+00, 5.5781378269829656e+00, 5.7350210099447425e+00, 5.8922577849835758e+00, 6.0498611897730488e+00, 6.2078446143528714e+00, 6.3662218209298418e+00, 6.5250069649076838e+00, 6.6842146172486627e+00, 6.8438597882796577e+00, 7.0039579530666876e+00, 7.1645250784943162e+00, 7.3255776522003675e+00, 7.4871327135320032e+00, 7.6492078867069049e+00, 7.8118214163831334e+00, 7.9749922058635363e+00, 8.1387398581859554e+00, 8.3030847203790454e+00, 8.4680479311960379e+00, 8.6336514726757141e+00, 8.7999182259219690e+00, 8.9668720315415094e+00, 9.1345377552342626e+00, 9.3029413590944845e+00, 9.4721099792532808e+00, 9.6420720105775217e+00, 9.8128571992374614e+00, 9.9844967440684584e+00, 1.0157023407784097e+01, 1.0330471639251822e+01, 1.0504877708222864e+01, 1.0680279854120787e+01, 1.0856718450743809e+01, 1.1034236189033734e+01, 1.1212878280418622e+01, 1.1392692683659751e+01, 1.1573730358642214e+01, 1.1756045551162156e+01, 1.1939696113507749e+01, 1.2124743866538131e+01, 1.2311255010076101e+01, 1.2499300589800702e+01, 1.2688957030525529e+01, 1.2880306747870632e+01, 1.3073438853003600e+01, 1.3268449968504161e+01, 1.3465445177719724e+01, 1.3664539135531767e+01, 1.3865857375666192e+01, 1.4069537859142688e+01, 1.4275732821001174e+01, 1.4484610989259913e+01, 1.4696360272885402e+01, 1.4911191046953165e+01, 1.5129340207007946e+01, 1.5351076226802732e+01, 1.5576705543358910e+01, 1.5806580725457744e+01, 1.6041111080581306e+01, 1.6280776662107755e+01, 1.6526147125048691e+01, 1.6777907674840002e+01, 1.7036895705202610e+01, 1.7304154114531990e+01, 1.7581011746684457e+01, 1.7869210214084568e+01, 1.8171115120332015e+01, 1.8490093525334313e+01, 1.8831255107137672e+01, 1.9203114954794152e+01, 1.9622178785373663e+01, 2.0131752068311702e+01}, + }, + } { + got := make([]float64, test.n/2+test.n%2) + for i := range got { + got[i] = Hermite{}.hermiteInitialGuess(i, test.n) + } + if !floats.EqualApprox(got, test.want, 1e-14) { + t.Errorf("n = %v, hermite initial guesses mismatch", test.n) + } + } +} + +func TestHermiteLocationsAsy0(t *testing.T) { + for _, test := range []struct { + n int + x []float64 + w []float64 + }{ + // Evaluated from Chebfun. + { + n: 215, + x: []float64{-7.9483151672010196e-15, 1.5132632976672361e-01, 3.0266070079942864e-01, 4.5401115992078167e-01, 6.0538576507805808e-01, 7.5679259093351370e-01, 9.0823973448851325e-01, 1.0597353207530273e+00, 1.2112875084719879e+00, 1.3629044959205205e+00, 1.5145945267802365e+00, 1.6663658961089640e+00, 1.8182269564169717e+00, 1.9701861238629792e+00, 2.1222518845837395e+00, 2.2744328011717010e+00, 2.4267375193157439e+00, 2.5791747746208049e+00, 2.7317533996228827e+00, 2.8844823310168755e+00, 3.0373706171156218e+00, 3.1904274255596032e+00, 3.3436620512978501e+00, 3.4970839248619634e+00, 3.6507026209565665e+00, 3.8045278673909002e+00, 3.9585695543782120e+00, 4.1128377442311503e+00, 4.2673426814837114e+00, 4.4220948034722349e+00, 4.5771047514106780e+00, 4.7323833819978187e+00, 4.8879417795972326e+00, 5.0437912690340267e+00, 5.1999434290559226e+00, 5.3564101065103049e+00, 5.5132034312931157e+00, 5.6703358321303936e+00, 5.8278200532585673e+00, 5.9856691720754620e+00, 6.1438966178406549e+00, 6.3025161915109100e+00, 6.4615420868046280e+00, 6.6209889125982082e+00, 6.7808717167671544e+00, 6.9412060115960434e+00, 7.1020078008938672e+00, 7.2632936089653120e+00, 7.4250805116042331e+00, 7.5873861692931381e+00, 7.7502288628124383e+00, 7.9136275314855800e+00, 8.0776018143113824e+00, 8.2421720942637187e+00, 8.4073595460710955e+00, 8.5731861878255415e+00, 8.7396749368126798e+00, 8.9068496700026394e+00, 9.0747352896969389e+00, 9.2433577948895387e+00, 9.4127443589734394e+00, 9.5829234145081710e+00, 9.7539247458611111e+00, 9.9257795906487338e+00, 1.0098520751035824e+01, 1.0272182716104577e+01, 1.0446801796686490e+01, 1.0622416274262394e+01, 1.0799066565787168e+01, 1.0976795406593546e+01, 1.1155648053883823e+01, 1.1335672513742256e+01, 1.1516919795109878e+01, 1.1699444194777641e+01, 1.1883303618198463e+01, 1.2068559941826503e+01, 1.2255279423804318e+01, 1.2443533171189967e+01, 1.2633397673617059e+01, 1.2824955415404188e+01, 1.3018295580800100e+01, 1.3213514870431910e+01, 1.3410718451340038e+01, 1.3610021068540190e+01, 1.3811548353270942e+01, 1.4015438372554696e+01, 1.4221843477251845e+01, 1.4430932522616979e+01, 1.4642893558208563e+01, 1.4857937115425768e+01, 1.5076300264808333e+01, 1.5298251677453143e+01, 1.5524098014731747e+01, 1.5754192102761674e+01, 1.5988943547145137e+01, 1.6228832750513551e+01, 1.6474429782282726e+01, 1.6726420346886542e+01, 1.6985642449377284e+01, 1.7253139752773148e+01, 1.7530242081974308e+01, 1.7818692349773503e+01, 1.8120857960601569e+01, 1.8440108632764016e+01, 1.8781558404513735e+01, 1.9153731166695263e+01, 1.9573161931385755e+01, 2.0083110126223993e+01}, + w: []float64{5.8004562850365771e-04, 5.6692877486338696e-04, 5.2932867305102921e-04, 4.7211368597165944e-04, 4.0223648470876573e-04, 3.2735218319190782e-04, 2.5446548811048362e-04, 1.8892919855999243e-04, 1.3396711152850057e-04, 9.0718165504482523e-05, 5.8661199606591556e-05, 3.6218251240150691e-05, 2.1349054444552587e-05, 1.2013089019084848e-05, 6.4521031002773646e-06, 3.3071925113778075e-06, 1.6175791039359969e-06, 7.5483313427524376e-07, 3.3600239642860852e-07, 1.4264659961771696e-07, 5.7746366478382785e-08, 2.2286582090203475e-08, 8.1983021699506761e-09, 2.8738670556378732e-09, 9.5976924324201262e-10, 3.0529085215378481e-10, 9.2467927287192434e-11, 2.6660996519674056e-11, 7.3154481204350507e-12, 1.9096325566425540e-12, 4.7409073505752031e-13, 1.1189936218333804e-13, 2.5101111888653927e-14, 5.3492761412487281e-15, 1.0825895304391782e-15, 2.0798005039728529e-16, 3.7912539356931888e-17, 6.5547084049896133e-18, 1.0743122119399353e-18, 1.6684093877262400e-19, 2.4538539136228336e-20, 3.4161583900178126e-21, 4.4991409209589655e-22, 5.6023724685401444e-23, 6.5917775903350454e-24, 7.3239791710744789e-25, 7.6792588730186891e-26, 7.5931172671070367e-27, 7.0751732949679160e-28, 6.2078867832748634e-29, 5.1250608797215456e-30, 3.9778286806416675e-31, 2.9000923323091595e-32, 1.9842934651116758e-33, 1.2729744163019100e-34, 7.6493618655638258e-36, 4.3010461850159373e-37, 2.2604572504006732e-38, 1.1091714341886240e-39, 5.0753225126752125e-41, 2.1629552371814077e-42, 8.5739087326714758e-44, 3.1568681170134092e-45, 1.0780709245918455e-46, 3.4094518277810594e-48, 9.9692987408874913e-50, 2.6905726285477170e-51, 6.6902112757430557e-53, 1.5297458011420645e-54, 3.2099851519180199e-56, 6.1681886704578063e-58, 1.0829083084555836e-59, 1.7328083889009238e-61, 2.5206396804555329e-63, 3.3240965181095399e-65, 3.9623955222122382e-67, 4.2558991248868728e-69, 4.1048947183601511e-71, 3.5424776999043975e-73, 2.7245890408644923e-75, 1.8596929038788086e-77, 1.1213274238978696e-79, 5.9430256314002078e-82, 2.7536336403486887e-84, 1.1087876280230634e-86, 3.8548279808836764e-89, 1.1488445098745636e-91, 2.9118805234147757e-94, 6.2218187764965726e-97, 1.1097458975689325e-99, 1.6341809683598844e-102, 1.9621625424695376e-105, 1.8939702898325753e-108, 1.4459753551186440e-111, 8.5692594596311645e-115, 3.8565449589488849e-118, 1.2843410590864927e-121, 3.0685300780965873e-125, 5.0651104293759753e-129, 5.5131423653412833e-133, 3.7300165435945031e-137, 1.4525522232777015e-141, 2.9352196847507026e-146, 2.6587623615117695e-151, 8.6633861029598960e-157, 7.0653364942986233e-163, 7.2051505413036788e-170, 1.5514139491189097e-178}, + }, + { + n: 216, + x: []float64{7.5487718959414210e-02, 2.2646713089859094e-01, 3.7745846761911317e-01, 5.2846968804856509e-01, 6.7950876474356448e-01, 8.3058368937955573e-01, 9.8170247827895785e-01, 1.1328731779888348e+00, 1.2841038709195900e+00, 1.4354026810562848e+00, 1.5867777797546210e+00, 1.7382373916337388e+00, 1.8897898005787916e+00, 2.0414433558661624e+00, 2.1932064784252856e+00, 2.3450876672510903e+00, 2.4970955059821409e+00, 2.6492386696600243e+00, 2.8015259316863266e+00, 2.9539661709946619e+00, 3.1065683794558021e+00, 3.2593416695353823e+00, 3.4122952822245907e+00, 3.5654385952656149e+00, 3.7187811316950210e+00, 3.8723325687298416e+00, 4.0261027470226392e+00, 4.1801016803139959e+00, 4.3343395655126109e+00, 4.4888267932355790e+00, 4.6435739588438905e+00, 4.7985918740108131e+00, 4.9538915788638089e+00, 5.1094843547439881e+00, 5.2653817376305465e+00, 5.4215955322816969e+00, 5.5781378271479722e+00, 5.7350210101185848e+00, 5.8922577851667635e+00, 6.0498611899661094e+00, 6.2078446145563948e+00, 6.3662218211444577e+00, 6.5250069651340752e+00, 6.6842146174875827e+00, 6.8438597885318986e+00, 7.0039579533331269e+00, 7.1645250787759087e+00, 7.3255776524981444e+00, 7.4871327138470951e+00, 7.6492078870405447e+00, 7.8118214167366684e+00, 7.9749922062384426e+00, 8.1387398585838486e+00, 8.3030847208017082e+00, 8.4680479316454296e+00, 8.6336514731539875e+00, 8.7999182264315081e+00, 8.9668720320849413e+00, 9.1345377558145096e+00, 9.3029413597147883e+00, 9.4721099799172528e+00, 9.6420720112891818e+00, 9.8128572000013108e+00, 9.9844967448895385e+00, 1.0157023408668081e+01, 1.0330471640205081e+01, 1.0504877709252620e+01, 1.0680279855235202e+01, 1.0856718451952171e+01, 1.1034236190346626e+01, 1.1212878281848150e+01, 1.1392692685219812e+01, 1.1573730360348824e+01, 1.1756045553033841e+01, 1.1939696115566026e+01, 1.2124743868808109e+01, 1.2311255012587219e+01, 1.2499300592587632e+01, 1.2688957033629340e+01, 1.2880306751340244e+01, 1.3073438856897617e+01, 1.3268449972893279e+01, 1.3465445182689793e+01, 1.3664539141187824e+01, 1.3865857382137794e+01, 1.4069537866591046e+01, 1.4275732829628778e+01, 1.4484610999323769e+01, 1.4696360284715409e+01, 1.4911191060978103e+01, 1.5129340223792830e+01, 1.5351076247103551e+01, 1.5576705568204593e+01, 1.5806580756275796e+01, 1.6041111119395726e+01, 1.6280776711860355e+01, 1.6526147190139376e+01, 1.6777907762072694e+01, 1.7036895825521608e+01, 1.7304154286393636e+01, 1.7581012003064874e+01, 1.7869210618319627e+01, 1.8171115805943941e+01, 1.8490094811217439e+01, 1.8831257901839155e+01, 1.9203122650098184e+01, 1.9622211733828486e+01, 2.0131752068397390e+01}, + w: []float64{5.7408951238509774e-04, 5.4853385977693967e-04, 5.0077995633045094e-04, 4.3681926493182888e-04, 3.6404534695321319e-04, 2.8986205027358900e-04, 2.2048980967270541e-04, 1.6022189177224014e-04, 1.1121464501100074e-04, 7.3735261435177744e-05, 4.6689968632275442e-05, 2.8233496634858870e-05, 1.6302404527221912e-05, 8.9873835313609794e-06, 4.7299184092204348e-06, 2.3760322139117827e-06, 1.1391060264678187e-06, 5.2109775739704647e-07, 2.2742736124678848e-07, 9.4679280581569520e-08, 3.7589897335857270e-08, 1.4229883676778969e-08, 5.1351173480468011e-09, 1.7661093963625318e-09, 5.7875785413194057e-10, 1.8066600901602130e-10, 5.3707955985666741e-11, 1.5200567246892033e-11, 4.0945877360252466e-12, 1.0494304449814065e-12, 2.5582770078364328e-13, 5.9298335011290506e-14, 1.3064177735039720e-14, 2.7346561920969734e-15, 5.4366757055637182e-16, 1.0261135273171614e-16, 1.8378155831501011e-17, 3.1221798154524404e-18, 5.0287455392773255e-19, 7.6752848097550855e-20, 1.1095334788910946e-20, 1.5183281292392555e-21, 1.9657499371912346e-22, 2.4064442018314010e-23, 2.7838422576260478e-24, 3.0413021389695441e-25, 3.1356913424697775e-26, 3.0490587561112177e-27, 2.7941107980138270e-28, 2.4112340295373517e-29, 1.9579916032501855e-30, 1.4948591683644822e-31, 1.0720958700672810e-32, 7.2163812209007653e-34, 4.5545782039839515e-35, 2.6927171840186886e-36, 1.4896964129251313e-37, 7.7036780004272946e-39, 3.7196117693798106e-40, 1.6748563396289038e-41, 7.0241404150854973e-43, 2.7401344340734534e-44, 9.9291319468776600e-46, 3.3371619908503302e-47, 1.0387276524925886e-48, 2.9893704843803614e-50, 7.9408570659652511e-52, 1.9434716944530867e-53, 4.3740144067322860e-55, 9.0342460240718143e-57, 1.7087495134365174e-58, 2.9528859528856670e-60, 4.6509376421165100e-62, 6.6593952486160953e-64, 8.6442830921042970e-66, 1.0142381095581560e-67, 1.0722439547251424e-69, 1.0179251007077803e-71, 8.6461259693742430e-74, 6.5448969088799971e-76, 4.3965762236216239e-78, 2.6089085327841006e-80, 1.3607099985773063e-82, 6.2039892663366641e-85, 2.4580575133840935e-87, 8.4080554628125066e-90, 2.4652597109139967e-92, 6.1467455174872763e-95, 1.2918545805718045e-97, 2.2661732049781124e-100, 3.2815976681148591e-103, 3.8741015126651295e-106, 3.6760977386321105e-109, 2.7584831111443303e-112, 1.6064052012003602e-115, 7.1024252453209961e-119, 2.3230796238780657e-122, 5.4494213912665180e-126, 8.8284366174946482e-130, 9.4271378060446301e-134, 6.2539251873936211e-138, 2.3865140957941506e-142, 4.7220323342515999e-147, 4.1840743138172546e-152, 1.3319161291512504e-157, 1.0592510752538756e-163, 1.0503755670967946e-170, 2.1869674690632971e-179}, + }, + } { + n := test.n + x := make([]float64, n/2+n%2) + w := make([]float64, n/2+n%2) + for i := range x { + x[i], w[i] = Hermite{}.locationsAsy0(i, n) + } + if !floats.EqualApprox(x, test.x, 1e-13) { + t.Errorf("n = %v, x mismatch", n) + fmt.Println(x[107]) + fmt.Println(test.x[107]) + } + if !floats.EqualApprox(w, test.w, 1e-13) { + t.Errorf("n = %v, w mismatch", n) + } + } +} + +func TestHermiteAsyAiry(t *testing.T) { + for _, test := range []struct { + n int + theta []float64 + val []float64 + dval []float64 + }{ + { + n: 215, + theta: []float64{1.5707963267948966e+00, 1.5635071294267224e+00, 1.5562171573546757e+00, 1.5489256352159648e+00, 1.5416317863284521e+00, 1.5343348320272066e+00, 1.5270339909965103e+00, 1.5197284785957685e+00, 1.5124175061777518e+00, 1.5051002803975593e+00, 1.4977760025106577e+00, 1.4904438676582881e+00, 1.4831030641384946e+00, 1.4757527726609410e+00, 1.4683921655836265e+00, 1.4610204061295120e+00, 1.4536366475809854e+00, 1.4462400324499760e+00, 1.4388296916214274e+00, 1.4314047434676882e+00, 1.4239642929312548e+00, 1.4165074305731233e+00, 1.4090332315838545e+00, 1.4015407547542300e+00, 1.3940290414022056e+00, 1.3864971142525955e+00, 1.3789439762656834e+00, 1.3713686094106747e+00, 1.3637699733795743e+00, 1.3561470042367485e+00, 1.3484986129990375e+00, 1.3408236841408716e+00, 1.3331210740183812e+00, 1.3253896092059803e+00, 1.3176280847383373e+00, 1.3098352622500289e+00, 1.3020098680044709e+00, 1.2941505908029671e+00, 1.2862560797638511e+00, 1.2783249419607658e+00, 1.2703557399080556e+00, 1.2623469888800907e+00, 1.2542971540500127e+00, 1.2462046474319508e+00, 1.2380678246090893e+00, 1.2298849812281600e+00, 1.2216543492388388e+00, 1.2133740928542220e+00, 1.2050423042059359e+00, 1.1966569986644591e+00, 1.1882161097919153e+00, 1.1797174838907749e+00, 1.1711588741076131e+00, 1.1625379340461441e+00, 1.1538522108381697e+00, 1.1450991376146524e+00, 1.1362760253118058e+00, 1.1273800537386238e+00, 1.1184082618225748e+00, 1.1093575369389341e+00, 1.1002246032162142e+00, 1.0910060086950395e+00, 1.0816981112001869e+00, 1.0722970627649082e+00, 1.0627987924225111e+00, 1.0531989871517369e+00, 1.0434930707289145e+00, 1.0336761802000907e+00, 1.0237431396389916e+00, 1.0136884308001370e+00, 1.0035061602085740e+00, 9.9319002214595331e-01, 9.8273325689369295e-01, 9.7212860347355579e-01, 9.6136824597870241e-01, 9.5044375240720391e-01, 9.3934600468605900e-01, 9.2806511829511895e-01, 9.1659034955139063e-01, 9.0490998817422319e-01, 8.9301123219309975e-01, 8.8088004154453947e-01, 8.6850096578161351e-01, 8.5585694011780433e-01, 8.4292904244735056e-01, 8.2969620188675874e-01, 8.1613484656631152e-01, 8.0221847457494289e-01, 7.8791712669745728e-01, 7.7319673223616503e-01, 7.5801828879746735e-01, 7.4233682191908168e-01, 7.2610004838413222e-01, 7.0924663405346811e-01, 6.9170388642137270e-01, 6.7338464244284535e-01, 6.5418298314185364e-01, 6.3396819041411068e-01, 6.1257598542667102e-01, 5.8979540387821172e-01, 5.6534835113739590e-01, 5.3885619819698471e-01, 5.0978185232293227e-01, 4.7732127920035572e-01, 4.4017830784988765e-01, 3.9602307074600884e-01, 3.3985069280702440e-01, 2.5624520569356829e-01}, + val: []float64{-2.7524590607067879e-13, -1.2484792737707130e-10, 2.5043777255407545e-10, -3.7621487726711831e-10, 5.0266571286479591e-10, -6.3022107051014496e-10, 7.5847898514904004e-10, -8.8850597267422281e-10, 1.0201287099545048e-09, -1.1532700149758681e-09, 1.2885402426941860e-09, -1.4262514564750722e-09, 1.5667774694950304e-09, -1.7098460348004283e-09, 1.8563663242006209e-09, -2.0060430373954962e-09, 2.1597272205910619e-09, -2.3174687646872261e-09, 2.4795270439737100e-09, -2.6462815453642877e-09, 2.8188431716836157e-09, -2.9962948915230151e-09, 3.1805879826447352e-09, -3.3709772507788239e-09, 3.5681573894354513e-09, -3.7732681484183285e-09, 3.9863813736176932e-09, -4.2080297462347532e-09, 4.4391671460302399e-09, -4.6802436355831232e-09, 4.9322546933533433e-09, -5.1957881449299223e-09, 5.4715433664057677e-09, -5.7608265327475837e-09, 6.0644153161437157e-09, -6.3835515563504339e-09, 6.7192819880764795e-09, -7.0729371214636086e-09, 7.4458702579674617e-09, -7.8396410076078555e-09, 8.2556088536449877e-09, -8.6960989460562939e-09, 9.1626310723815202e-09, -9.6575986146054327e-09, 1.0182896152806950e-08, -1.0741758184989815e-08, 1.1337214303287172e-08, -1.1971481080324528e-08, 1.2648762056240369e-08, -1.3372488830525768e-08, 1.4147041859097387e-08, -1.4977276046958432e-08, 1.5868475891599271e-08, -1.6825823997480545e-08, 1.7856900524878266e-08, -1.8967833880184117e-08, 2.0167708166421882e-08, -2.1465280681285451e-08, 2.2870631970634630e-08, -2.4395881051717265e-08, 2.6054060647767539e-08, -2.7859818527100110e-08, 2.9830454146699167e-08, -3.1984835487787522e-08, 3.4345470368342559e-08, -3.6937900081988413e-08, 3.9790883510012329e-08, -4.2938418365980210e-08, 4.6419377177480922e-08, -5.0279213559974237e-08, 5.4570799296449321e-08, -5.9356303125081130e-08, 6.4708755363671345e-08, -7.0714511032393380e-08, 7.7475892426711618e-08, -8.5115456468135130e-08, 9.3779863576446978e-08, -1.0364644483987255e-07, 1.1493006182865740e-07, -1.2789317815470753e-07, 1.4285900893044798e-07, -1.6022759919461249e-07, 1.8049814080062288e-07, -2.0429953256541455e-07, 2.3243044535889061e-07, -2.6591504027157263e-07, 3.0608147425737922e-07, -3.5467098673335754e-07, 4.1399606056878556e-07, -4.8716979156405424e-07, 5.7844824292016844e-07, -6.9374768843585542e-07, 8.4144962449118331e-07, -1.0336795693201387e-06, 1.2884020459910342e-06, -1.6329629222918408e-06, 2.1103031286712709e-06, -2.7903321871954755e-06, 3.7918023218017778e-06, -5.3269144947324421e-06, 7.7989206456257246e-06, -1.2034979469568085e-05, 1.9905658561076196e-05, -3.6224899321604820e-05, 7.5828952282754516e-05, -1.9870421394114517e-04, 7.9136577883937422e-04, -9.1266148556594703e-03}, + dval: []float64{-2.9359856130945122e+01, 2.9359466144908318e+01, -2.9358296010652477e+01, 2.9356345199427643e+01, -2.9353612829040124e+01, 2.9350097662433203e+01, -2.9345798105693621e+01, 2.9340712205476308e+01, -2.9334837645838910e+01, 2.9328171744474840e+01, -2.9320711448331572e+01, 2.9312453328598885e+01, -2.9303393575049100e+01, 2.9293527989709109e+01, -2.9282851979841201e+01, 2.9271360550207458e+01, -2.9259048294588819e+01, 2.9245909386527540e+01, -2.9231937569258221e+01, 2.9217126144788914e+01, -2.9201467962090302e+01, 2.9184955404346876e+01, -2.9167580375219231e+01, 2.9149334284062498e+01, -2.9130208030040425e+01, 2.9110191985068752e+01, -2.9089275975516287e+01, 2.9067449262584436e+01, -2.9044700521279459e+01, 2.9021017817883425e+01, -2.8996388585821325e+01, 2.8970799599811933e+01, -2.8944236948180023e+01, 2.8916686003195348e+01, -2.8888131389291605e+01, 2.8858556949003951e+01, -2.8827945706448649e+01, 2.8796279828150279e+01, -2.8763540581003511e+01, 2.8729708287134507e+01, -2.8694762275403512e+01, 2.8658680829263385e+01, -2.8621441130659093e+01, 2.8583019199620328e+01, -2.8543389829161509e+01, 2.8502526515061927e+01, -2.8460401380051497e+01, 2.8416985091874277e+01, -2.8372246774642264e+01, 2.8326153912823031e+01, -2.8278672247129006e+01, 2.8229765661486788e+01, -2.8179396060166667e+01, 2.8127523234037287e+01, -2.8074104714780372e+01, 2.8019095615750665e+01, -2.7962448457994284e+01, 2.7904112979739956e+01, -2.7844035927448619e+01, 2.7782160826241125e+01, -2.7718427727214667e+01, 2.7652772928798932e+01, -2.7585128668881747e+01, 2.7515422783940370e+01, -2.7443578330833645e+01, 2.7369513166223737e+01, -2.7293139477783004e+01, 2.7214363260373997e+01, -2.7133083729234610e+01, 2.7049192660814331e+01, -2.6962573650237655e+01, 2.6873101272350414e+01, -2.6780640130847800e+01, 2.6685043776981303e+01, -2.6586153475654008e+01, 2.6483796792158788e+01, -2.6377785967154090e+01, 2.6267916040395331e+01, -2.6153962674834343e+01, 2.6035679621411951e+01, -2.5912795750458177e+01, 2.5785011557068390e+01, -2.5651995023754676e+01, 2.5513376692151432e+01, -2.5368743753874771e+01, 2.5217632914945654e+01, -2.5059521712941240e+01, 2.4893817863127197e+01, -2.4719846067215368e+01, 2.4536831517922174e+01, -2.4343879046260469e+01, 2.4139946442705973e+01, -2.3923809867871942e+01, 2.3694018337866666e+01, -2.3448832829666316e+01, 2.3186143264519330e+01, -2.2903352884396824e+01, 2.2597213200674400e+01, -2.2263581543467414e+01, 2.1897052703993687e+01, -2.1490376258364485e+01, 2.1033488463000687e+01, -2.0511802124454178e+01, 1.9902938182242686e+01, -1.9169784832381577e+01, 1.8243381598901596e+01, -1.6969663168974311e+01, 1.4853826851969115e+01}, + }, + { + n: 215, + theta: []float64{1.5707963267948968e+00, 1.5635071294265777e+00, 1.5562171573543850e+00, 1.5489256352155283e+00, 1.5416317863278686e+00, 1.5343348320264747e+00, 1.5270339909956292e+00, 1.5197284785947358e+00, 1.5124175061765655e+00, 1.5051002803962170e+00, 1.4977760025091569e+00, 1.4904438676566254e+00, 1.4831030641366665e+00, 1.4757527726589439e+00, 1.4683921655814560e+00, 1.4610204061271637e+00, 1.4536366475784539e+00, 1.4462400324472560e+00, 1.4388296916185130e+00, 1.4314047434645731e+00, 1.4239642929279313e+00, 1.4165074305695844e+00, 1.4090332315800913e+00, 1.4015407547502341e+00, 1.3940290413979675e+00, 1.3864971142481046e+00, 1.3789439762609286e+00, 1.3713686094056443e+00, 1.3637699733742550e+00, 1.3561470042311266e+00, 1.3484986129930978e+00, 1.3408236841345980e+00, 1.3331210740117563e+00, 1.3253896091989852e+00, 1.3176280847309516e+00, 1.3098352622422307e+00, 1.3020098679962364e+00, 1.2941505907942705e+00, 1.2862560797546647e+00, 1.2783249419510594e+00, 1.2703557398977969e+00, 1.2623469888692436e+00, 1.2542971540385390e+00, 1.2462046474198085e+00, 1.2380678245962331e+00, 1.2298849812145400e+00, 1.2216543492243996e+00, 1.2133740928389052e+00, 1.2050423041896758e+00, 1.1966569986471847e+00, 1.1882161097735480e+00, 1.1797174838712285e+00, 1.1711588740867924e+00, 1.1625379340239450e+00, 1.1538522108144755e+00, 1.1450991375893356e+00, 1.1362760252847235e+00, 1.1273800537096179e+00, 1.1184082617914692e+00, 1.1093575369055320e+00, 1.1002246031802951e+00, 1.0910060086563567e+00, 1.0816981111584625e+00, 1.0722970627198296e+00, 1.0627987923737243e+00, 1.0531989870988405e+00, 1.0434930706714527e+00, 1.0336761801375436e+00, 1.0237431395707643e+00, 1.0136884307255469e+00, 1.0035061601268345e+00, 9.9319002205615470e-01, 9.8273325679477930e-01, 9.7212860336429585e-01, 9.6136824585765468e-01, 9.5044375227267230e-01, 9.3934600453603823e-01, 9.2806511812722514e-01, 9.1659034936277473e-01, 9.0490998796145916e-01, 8.9301123195204113e-01, 8.8088004127013353e-01, 8.6850096546765831e-01, 8.5585693975662547e-01, 8.4292904202937069e-01, 8.2969620139991496e-01, 8.1613484599525510e-01, 8.0221847389992995e-01, 7.8791712589278218e-01, 7.7319673126791522e-01, 7.5801828762024448e-01, 7.4233682047111893e-01, 7.2610004657985505e-01, 7.0924663177187774e-01, 6.9170388348738876e-01, 6.7338463859636577e-01, 6.5418297798453895e-01, 6.3396818331389482e-01, 6.1257597533770680e-01, 5.8979538898074346e-01, 5.6534832806423485e-01, 5.3885616021897675e-01, 5.0978178458826806e-01, 4.7732114425935024e-01, 4.4017799165717791e-01, 3.9602210904603868e-01, 3.3984592789666196e-01, 2.5616263514373872e-01}, + val: []float64{-2.7524577037687927e-13, -1.3157296144588393e-13, -1.4217705189589319e-13, -9.3051784272423659e-14, 6.2263913433904649e-14, -7.2338165854311426e-14, 1.6489823942055246e-13, 8.2086154015730068e-14, 1.7030857773598118e-13, 1.9200825273544764e-13, 3.4144423192398587e-13, -1.3350292964848512e-13, 7.7406393378692183e-16, 3.0802286839980475e-15, 1.0626665274130983e-13, 9.7508116816654928e-14, -1.2286283979350783e-13, 1.6602061523803380e-13, 1.2145800400612989e-14, -2.0125760394077007e-13, 1.1752853222876857e-13, 1.5246361311903834e-13, -1.7100196342840500e-13, -9.0852635256292980e-14, -7.8101776477326909e-14, -8.6215405399587178e-14, -1.8424041061507494e-13, -1.7748959370373156e-13, 1.6659488983250428e-14, -2.3029664495695825e-14, 4.9882044749360307e-14, -1.6935708059066857e-13, -1.6889419531778083e-14, -1.5488691966202885e-13, 4.7496471682336465e-15, -6.0236075531674274e-14, -4.7790439973748918e-14, 1.0528243973915236e-14, -1.4481370116381506e-13, 4.8870674172048881e-14, 5.9145722182844837e-14, -3.6252017525118028e-14, -1.4799821290649442e-13, 7.8483748114372226e-14, -3.1698431394015554e-14, -2.1250000650523357e-13, -1.2207160366356720e-13, -4.4799710774576449e-14, -6.6076225108040054e-14, 4.9432907671096125e-14, 1.1714372287574581e-13, 7.1071624668919607e-14, -1.4699620399669987e-13, 4.9028118279404591e-14, 5.6995970859340297e-15, 1.8655926516135062e-14, 3.2409175615798361e-14, 7.1510069979380908e-14, -7.2558225742592175e-14, 4.1294505314113302e-14, -1.8304081875904709e-14, 1.3492357431194347e-13, -2.0526864648283952e-13, 1.1949578558177085e-14, 5.3441698191945163e-14, 4.9207462229933007e-14, -1.9962117626180037e-13, 8.2375100050737861e-15, 5.8811770905000782e-14, -3.8856969371752553e-15, 4.8345877891596704e-14, -1.2020353849039574e-13, 1.0795889278969854e-14, 2.7165003590955340e-14, 7.9664181703224841e-15, -3.1357633506603503e-14, 3.0114465704049404e-14, 5.4841545026050259e-14, 8.3356466046602926e-14, 3.4875109219720919e-14, 5.3887688890067731e-14, -8.5090430827758076e-15, 1.4753806570541977e-14, 4.1314792687095403e-15, 2.8114340045724569e-14, -8.9380771455156681e-15, -3.2451925819727029e-14, 5.0739464388639648e-14, 5.2751575373088884e-14, 3.8348847777085630e-14, -3.1825724566756715e-14, 6.6426259272244758e-14, -6.4295491511138863e-14, 8.9401622475124014e-15, 2.5866873030708164e-14, 9.6302605421508054e-14, 4.6623114840341440e-14, -1.7497072577375209e-14, 3.3453526916664849e-14, -5.5592329550244261e-14, 1.4115683421722400e-13, -3.9306913138151204e-13, 1.2007938611150981e-12, -4.7530501604406474e-12, 2.5399685303214922e-11, -2.2827587443604869e-10, 5.3187001008179367e-09, -1.4222383864770318e-06}, + dval: []float64{-2.9359856130945126e+01, 2.9359466144908307e+01, -2.9358296010652474e+01, 2.9356345199427643e+01, -2.9353612829040117e+01, 2.9350097662433203e+01, -2.9345798105693628e+01, 2.9340712205476311e+01, -2.9334837645838906e+01, 2.9328171744474847e+01, -2.9320711448331569e+01, 2.9312453328598881e+01, -2.9303393575049114e+01, 2.9293527989709105e+01, -2.9282851979841208e+01, 2.9271360550207465e+01, -2.9259048294588812e+01, 2.9245909386527540e+01, -2.9231937569258211e+01, 2.9217126144788910e+01, -2.9201467962090309e+01, 2.9184955404346905e+01, -2.9167580375219234e+01, 2.9149334284062515e+01, -2.9130208030040418e+01, 2.9110191985068738e+01, -2.9089275975516284e+01, 2.9067449262584432e+01, -2.9044700521279456e+01, 2.9021017817883422e+01, -2.8996388585821315e+01, 2.8970799599811926e+01, -2.8944236948180027e+01, 2.8916686003195355e+01, -2.8888131389291594e+01, 2.8858556949003940e+01, -2.8827945706448645e+01, 2.8796279828150276e+01, -2.8763540581003515e+01, 2.8729708287134510e+01, -2.8694762275403530e+01, 2.8658680829263389e+01, -2.8621441130659079e+01, 2.8583019199620328e+01, -2.8543389829161509e+01, 2.8502526515061930e+01, -2.8460401380051490e+01, 2.8416985091874288e+01, -2.8372246774642264e+01, 2.8326153912823038e+01, -2.8278672247129016e+01, 2.8229765661486780e+01, -2.8179396060166667e+01, 2.8127523234037294e+01, -2.8074104714780368e+01, 2.8019095615750661e+01, -2.7962448457994284e+01, 2.7904112979739949e+01, -2.7844035927448619e+01, 2.7782160826241114e+01, -2.7718427727214678e+01, 2.7652772928798946e+01, -2.7585128668881751e+01, 2.7515422783940377e+01, -2.7443578330833653e+01, 2.7369513166223744e+01, -2.7293139477783015e+01, 2.7214363260374000e+01, -2.7133083729234624e+01, 2.7049192660814349e+01, -2.6962573650237655e+01, 2.6873101272350418e+01, -2.6780640130847814e+01, 2.6685043776981328e+01, -2.6586153475654026e+01, 2.6483796792158806e+01, -2.6377785967154097e+01, 2.6267916040395356e+01, -2.6153962674834389e+01, 2.6035679621411997e+01, -2.5912795750458240e+01, 2.5785011557068451e+01, -2.5651995023754750e+01, 2.5513376692151542e+01, -2.5368743753874902e+01, 2.5217632914945817e+01, -2.5059521712941454e+01, 2.4893817863127474e+01, -2.4719846067215741e+01, 2.4536831517922678e+01, -2.4343879046261161e+01, 2.4139946442706947e+01, -2.3923809867873366e+01, 2.3694018337868730e+01, -2.3448832829669414e+01, 2.3186143264524166e+01, -2.2903352884404576e+01, 2.2597213200687420e+01, -2.2263581543490410e+01, 2.1897052704036881e+01, -2.1490376258452002e+01, 2.1033488463196051e+01, -2.0511802124949831e+01, 1.9902938183741984e+01, -1.9169784838249630e+01, 1.8243381633602635e+01, -1.6969663610835688e+01, 1.4853865657323199e+01}, + }, + { + n: 215, + theta: []float64{1.5707963267948970e+00, 1.5635071294265774e+00, 1.5562171573543853e+00, 1.5489256352155283e+00, 1.5416317863278686e+00, 1.5343348320264747e+00, 1.5270339909956290e+00, 1.5197284785947358e+00, 1.5124175061765652e+00, 1.5051002803962172e+00, 1.4977760025091564e+00, 1.4904438676566252e+00, 1.4831030641366665e+00, 1.4757527726589439e+00, 1.4683921655814558e+00, 1.4610204061271639e+00, 1.4536366475784541e+00, 1.4462400324472562e+00, 1.4388296916185130e+00, 1.4314047434645729e+00, 1.4239642929279310e+00, 1.4165074305695846e+00, 1.4090332315800915e+00, 1.4015407547502341e+00, 1.3940290413979675e+00, 1.3864971142481046e+00, 1.3789439762609288e+00, 1.3713686094056441e+00, 1.3637699733742550e+00, 1.3561470042311266e+00, 1.3484986129930978e+00, 1.3408236841345977e+00, 1.3331210740117563e+00, 1.3253896091989850e+00, 1.3176280847309516e+00, 1.3098352622422307e+00, 1.3020098679962364e+00, 1.2941505907942705e+00, 1.2862560797546649e+00, 1.2783249419510594e+00, 1.2703557398977969e+00, 1.2623469888692436e+00, 1.2542971540385393e+00, 1.2462046474198085e+00, 1.2380678245962331e+00, 1.2298849812145398e+00, 1.2216543492243999e+00, 1.2133740928389052e+00, 1.2050423041896758e+00, 1.1966569986471847e+00, 1.1882161097735477e+00, 1.1797174838712285e+00, 1.1711588740867926e+00, 1.1625379340239450e+00, 1.1538522108144755e+00, 1.1450991375893356e+00, 1.1362760252847235e+00, 1.1273800537096179e+00, 1.1184082617914692e+00, 1.1093575369055320e+00, 1.1002246031802951e+00, 1.0910060086563569e+00, 1.0816981111584627e+00, 1.0722970627198296e+00, 1.0627987923737243e+00, 1.0531989870988405e+00, 1.0434930706714529e+00, 1.0336761801375436e+00, 1.0237431395707643e+00, 1.0136884307255469e+00, 1.0035061601268345e+00, 9.9319002205615448e-01, 9.8273325679477930e-01, 9.7212860336429585e-01, 9.6136824585765468e-01, 9.5044375227267230e-01, 9.3934600453603823e-01, 9.2806511812722525e-01, 9.1659034936277461e-01, 9.0490998796145927e-01, 8.9301123195204102e-01, 8.8088004127013353e-01, 8.6850096546765831e-01, 8.5585693975662547e-01, 8.4292904202937069e-01, 8.2969620139991496e-01, 8.1613484599525521e-01, 8.0221847389993006e-01, 7.8791712589278207e-01, 7.7319673126791533e-01, 7.5801828762024459e-01, 7.4233682047111904e-01, 7.2610004657985516e-01, 7.0924663177187774e-01, 6.9170388348738865e-01, 6.7338463859636599e-01, 6.5418297798453884e-01, 6.3396818331389482e-01, 6.1257597533770669e-01, 5.8979538898074335e-01, 5.6534832806423441e-01, 5.3885616021897553e-01, 5.0978178458826395e-01, 4.7732114425933253e-01, 4.4017799165707200e-01, 3.9602210904493385e-01, 3.3984592786463697e-01, 2.5616262227240338e-01}, + val: []float64{-4.8194502666337268e-14, -1.8219292956257052e-14, 8.5393034645390052e-14, -9.3051784272423659e-14, 6.2263913433904649e-14, -7.2338165854311426e-14, -6.2580913476718581e-14, 8.2086154015730068e-14, -5.7165830534287467e-14, -3.5936383892293965e-14, -1.1380084519138131e-13, 9.4176333524136458e-14, 7.7406393378692183e-16, 3.0802286839980475e-15, -2.3573275472589349e-13, -1.3018327378045775e-13, 1.0520206501483371e-13, -6.2213644291038904e-14, 1.2145800400612989e-14, 2.7271297683652584e-14, -2.2535922871268711e-13, -7.6298928186738198e-14, 1.7255690675064885e-13, -9.0852635256292980e-14, -7.8101776477326909e-14, -8.6215405399587178e-14, 4.5189259409156241e-14, 1.6773935900994068e-13, 1.6659488983250428e-14, -2.3029664495695825e-14, 4.9882044749360307e-14, 1.1850055135335312e-13, -1.6889419531778083e-14, 7.5802404690310745e-14, 4.7496471682336465e-15, -6.0236075531674274e-14, -4.7790439973748918e-14, 1.0528243973915236e-14, 2.0302122716337677e-13, 4.8870674172048881e-14, 5.9145722182844837e-14, -3.6252017525118028e-14, 2.6839385139099395e-14, 7.8483748114372226e-14, -3.1698431394015554e-14, -3.7141479062747567e-14, 1.1275835568784933e-13, -4.4799710774576449e-14, -6.6076225108040054e-14, 4.9432907671096125e-14, -1.1915508175098585e-13, 7.1071624668919607e-14, 1.4874359999295257e-13, 4.9028118279404591e-14, 5.6995970859340297e-15, 1.8655926516135062e-14, 3.2409175615798361e-14, 7.1510069979380908e-14, -7.2558225742592175e-14, 4.1294505314113302e-14, -1.8304081875904709e-14, -4.6448090671875563e-14, 9.6949756857760571e-14, 1.1949578558177085e-14, 5.3441698191945163e-14, 4.9207462229933007e-14, -1.6005168277506475e-14, 8.2375100050737861e-15, 5.8811770905000782e-14, -3.8856969371752553e-15, 4.8345877891596704e-14, 9.6875037765842389e-14, 1.0795889278969854e-14, 2.7165003590955340e-14, 7.9664181703224841e-15, -3.1357633506603503e-14, 3.0114465704049404e-14, 5.4841606599486569e-14, 1.9665914005907120e-14, -2.8849555274550242e-14, -4.2752529356173103e-14, -8.5090430827758076e-15, 1.4753806570541977e-14, 4.1314792687095403e-15, 2.8114340045724569e-14, -8.9380771455156681e-15, 3.6308713608736668e-16, -4.9851972317585696e-14, -9.9115770904832069e-14, -1.2903366624947848e-14, 5.3938844852967152e-14, -3.7521135648997941e-14, 4.0086325460559029e-14, 8.9401622475124014e-15, -9.8967441436620103e-14, -6.5207531930586132e-14, 4.6622484011593159e-14, -1.7497072577375209e-14, 3.3453526916664849e-14, 4.8715471045751314e-14, 3.3943255654417215e-14, 5.7122398702729805e-15, -9.4574045519538209e-16, 7.2999684957756045e-15, 2.7503783126358897e-14, -7.8728766754343666e-15, 3.5695346037194369e-14, -6.2144904069338325e-14}, + dval: []float64{-2.9359856130945122e+01, 2.9359466144908321e+01, -2.9358296010652467e+01, 2.9356345199427643e+01, -2.9353612829040117e+01, 2.9350097662433203e+01, -2.9345798105693628e+01, 2.9340712205476311e+01, -2.9334837645838913e+01, 2.9328171744474844e+01, -2.9320711448331572e+01, 2.9312453328598878e+01, -2.9303393575049114e+01, 2.9293527989709105e+01, -2.9282851979841219e+01, 2.9271360550207469e+01, -2.9259048294588819e+01, 2.9245909386527547e+01, -2.9231937569258211e+01, 2.9217126144788914e+01, -2.9201467962090305e+01, 2.9184955404346880e+01, -2.9167580375219234e+01, 2.9149334284062515e+01, -2.9130208030040418e+01, 2.9110191985068738e+01, -2.9089275975516287e+01, 2.9067449262584439e+01, -2.9044700521279456e+01, 2.9021017817883422e+01, -2.8996388585821315e+01, 2.8970799599811929e+01, -2.8944236948180027e+01, 2.8916686003195352e+01, -2.8888131389291594e+01, 2.8858556949003940e+01, -2.8827945706448645e+01, 2.8796279828150276e+01, -2.8763540581003500e+01, 2.8729708287134510e+01, -2.8694762275403530e+01, 2.8658680829263389e+01, -2.8621441130659086e+01, 2.8583019199620328e+01, -2.8543389829161509e+01, 2.8502526515061934e+01, -2.8460401380051490e+01, 2.8416985091874288e+01, -2.8372246774642264e+01, 2.8326153912823038e+01, -2.8278672247129023e+01, 2.8229765661486780e+01, -2.8179396060166667e+01, 2.8127523234037294e+01, -2.8074104714780368e+01, 2.8019095615750661e+01, -2.7962448457994284e+01, 2.7904112979739949e+01, -2.7844035927448619e+01, 2.7782160826241114e+01, -2.7718427727214678e+01, 2.7652772928798939e+01, -2.7585128668881751e+01, 2.7515422783940377e+01, -2.7443578330833653e+01, 2.7369513166223744e+01, -2.7293139477783015e+01, 2.7214363260374000e+01, -2.7133083729234624e+01, 2.7049192660814349e+01, -2.6962573650237655e+01, 2.6873101272350418e+01, -2.6780640130847814e+01, 2.6685043776981328e+01, -2.6586153475654026e+01, 2.6483796792158806e+01, -2.6377785967154097e+01, 2.6267916040395356e+01, -2.6153962674834375e+01, 2.6035679621411987e+01, -2.5912795750458244e+01, 2.5785011557068451e+01, -2.5651995023754750e+01, 2.5513376692151542e+01, -2.5368743753874902e+01, 2.5217632914945817e+01, -2.5059521712941446e+01, 2.4893817863127481e+01, -2.4719846067215748e+01, 2.4536831517922678e+01, -2.4343879046261172e+01, 2.4139946442706954e+01, -2.3923809867873342e+01, 2.3694018337868730e+01, -2.3448832829669424e+01, 2.3186143264524159e+01, -2.2903352884404576e+01, 2.2597213200687420e+01, -2.2263581543490410e+01, 2.1897052704036888e+01, -2.1490376258451999e+01, 2.1033488463196083e+01, -2.0511802124949803e+01, 1.9902938183742044e+01, -1.9169784838249644e+01, 1.8243381633602628e+01, -1.6969663610835667e+01, 1.4853865657324123e+01}, + }, + { + n: 216, + theta: []float64{1.5671686105755729e+00, 1.5599127961686350e+00, 1.5526558355349958e+00, 1.5453969634500344e+00, 1.5381354130763418e+00, 1.5308704153134880e+00, 1.5236011981426352e+00, 1.5163269859644990e+00, 1.5090469989291080e+00, 1.5017604522557937e+00, 1.4944665555417909e+00, 1.4871645120577743e+00, 1.4798535180286077e+00, 1.4725327618975033e+00, 1.4652014235717277e+00, 1.4578586736478822e+00, 1.4505036726147191e+00, 1.4431355700313173e+00, 1.4357535036783504e+00, 1.4283565986800277e+00, 1.4209439665941588e+00, 1.4135147044676193e+00, 1.4060678938543345e+00, 1.3986025997926903e+00, 1.3911178697390723e+00, 1.3836127324540022e+00, 1.3760861968370792e+00, 1.3685372507066480e+00, 1.3609648595198076e+00, 1.3533679650280226e+00, 1.3457454838632317e+00, 1.3380963060489126e+00, 1.3304192934301153e+00, 1.3227132780159603e+00, 1.3149770602275335e+00, 1.3072094070434859e+00, 1.2994090500349611e+00, 1.2915746832807011e+00, 1.2837049611523335e+00, 1.2757984959588993e+00, 1.2678538554386305e+00, 1.2598695600848058e+00, 1.2518440802912205e+00, 1.2437758333013242e+00, 1.2356631799434625e+00, 1.2275044211328083e+00, 1.2192977941185159e+00, 1.2110414684522999e+00, 1.2027335416520410e+00, 1.1943720345310531e+00, 1.1859548861603062e+00, 1.1774799484271210e+00, 1.1689449801495315e+00, 1.1603476407006212e+00, 1.1516854830915373e+00, 1.1429559464555037e+00, 1.1341563478678038e+00, 1.1252838734282915e+00, 1.1163355685232694e+00, 1.1073083271723616e+00, 1.0981988803530085e+00, 1.0890037831801158e+00, 1.0797194008007944e+00, 1.0703418928435628e+00, 1.0608671962372638e+00, 1.0512910061865695e+00, 1.0416087550574320e+00, 1.0318155888861182e+00, 1.0219063411782010e+00, 1.0118755036074250e+00, 1.0017171931566209e+00, 9.9142511516121901e-01, 9.8099252161709072e-01, 9.7041216399420693e-01, 9.5967623965057169e-01, 9.4877633076008561e-01, 9.3770333444439402e-01, 9.2644738252057113e-01, 9.1499774892808761e-01, 9.0334274245922008e-01, 8.9146958185913860e-01, 8.7936424964779292e-01, 8.6701132009412707e-01, 8.5439375557323693e-01, 8.4149266395991695e-01, 8.2828700761781482e-01, 8.1475325173188318e-01, 8.0086493591225205e-01, 7.8659214774134534e-01, 7.7190086960046345e-01, 7.5675215971653753e-01, 7.4110111338801099e-01, 7.2489552835323978e-01, 7.0807416530075917e-01, 6.9056444397251160e-01, 6.7227933577676646e-01, 6.5311308498739518e-01, 6.3293517484306561e-01, 6.1158157942775537e-01, 5.8884165912926645e-01, 5.6443774724725360e-01, 5.3799179737419422e-01, 5.0896754324534177e-01, 4.7656218794974137e-01, 4.3948155571863207e-01, 3.9539936631707273e-01, 3.3931845258954985e-01, 2.5576413756997579e-01}, + val: []float64{6.1063360924047490e-11, -1.8435203658490556e-10, 3.0743162265786900e-10, -4.3161999307057153e-10, 5.5600184481941261e-10, -6.8154103751235407e-10, 8.0806640731641332e-10, -9.3648670703302450e-10, 1.0665511846836497e-09, -1.1984227187029326e-09, 1.3320294714997634e-09, -1.4683350272554789e-09, 1.6073141540400390e-09, -1.7488108299475996e-09, 1.8942373170611600e-09, -2.0425637634202854e-09, 2.1952560444756934e-09, -2.3517907718469464e-09, 2.5131243047743498e-09, -2.6788312866718815e-09, 2.8501736508238295e-09, -3.0272882762354559e-09, 3.2101466593235099e-09, -3.3995591281295402e-09, 3.5962230906180571e-09, -3.8005765479605162e-09, 4.0130477356611703e-09, -4.2339156669326267e-09, 4.4646349512119503e-09, -4.7049927091960580e-09, 4.9561002253847192e-09, -5.2191334055490069e-09, 5.4945583626542044e-09, -5.7832433193687254e-09, 6.0863314853460021e-09, -6.4051174909280434e-09, 6.7403553891566650e-09, -7.0933989938263408e-09, 7.4659234299589640e-09, -7.8591408458401506e-09, 8.2751055799843569e-09, -8.7148794606644850e-09, 9.1813301061361439e-09, -9.6760514978089342e-09, 1.0201632305616356e-08, -1.0760129925294149e-08, 1.1355163586751651e-08, -1.1989527720947381e-08, 1.2666360398983932e-08, -1.3390280463762196e-08, 1.4164961106968852e-08, -1.4995012747245716e-08, 1.5885976564229918e-08, -1.6843921766929025e-08, 1.7874947115661739e-08, -1.8986267082409428e-08, 2.0186191955347422e-08, -2.1484132370733845e-08, 2.2890126360750540e-08, -2.4415809556224372e-08, 2.6074391376958674e-08, -2.7880720950296676e-08, 2.9852038341333996e-08, -3.2007470796983141e-08, 3.4369209413828328e-08, -3.6962720963996261e-08, 3.9816961736227733e-08, -4.2965941232291533e-08, 4.6448638367911141e-08, -5.0310249303133202e-08, 5.4604204622873211e-08, -5.9392177920227513e-08, 6.4747522871256546e-08, -7.0756457006013807e-08, 7.7521575966439530e-08, -8.5165469547851754e-08, 9.3834858505459719e-08, -1.0370708662191418e-07, 1.1499734508496046e-07, -1.2796816261852297e-07, 1.4294288769073078e-07, -1.6032201969864769e-07, 1.8060502833216690e-07, -2.0442120587020166e-07, 2.3256958638562142e-07, -2.6607532013847684e-07, 3.0626738095928866e-07, -3.5488829260119791e-07, 4.1425182777935264e-07, -4.8747349724306658e-07, 5.7881217418665015e-07, -6.9418829303134906e-07, 8.4198941248161877e-07, -1.0343491900465793e-06, 1.2892453275257475e-06, -1.6340426463170451e-06, 2.1117130712431397e-06, -2.7922162634453614e-06, 3.7943899196860205e-06, -5.3305886421188924e-06, 7.8043580879824044e-06, -1.2043461755474721e-05, 1.9919842840142057e-05, -3.6251001189673213e-05, 7.5884216611786810e-05, -1.9885074842226311e-04, 7.9195669340038259e-04, -1.8028552886227383e-09}, + dval: []float64{-2.9427800603424885e+01, 2.9427025985916121e+01, -2.9425476404186753e+01, 2.9423151164251298e+01, -2.9420049223750460e+01, 2.9416169190288226e+01, -2.9411509319206207e+01, 2.9406067510787029e+01, -2.9399841306877359e+01, 2.9392827886918830e+01, -2.9385024063373031e+01, 2.9376426276524445e+01, -2.9367030588643040e+01, 2.9356832677485638e+01, -2.9345827829112856e+01, 2.9334010929995458e+01, -2.9321376458381245e+01, 2.9307918474890496e+01, -2.9293630612304742e+01, 2.9278506064510260e+01, -2.9262537574553473e+01, 2.9245717421762187e+01, -2.9228037407881232e+01, 2.9209488842167364e+01, -2.9190062525382210e+01, 2.9169748732617208e+01, -2.9148537194877900e+01, 2.9126417079348521e+01, -2.9103376968250728e+01, 2.9079404836201942e+01, -2.9054488025970496e+01, 2.9028613222515041e+01, -2.9001766425185139e+01, 2.8973932917948382e+01, -2.8945097237496739e+01, 2.8915243139070405e+01, -2.8884353559822184e+01, 2.8852410579527451e+01, -2.8819395378426641e+01, 2.8785288191964121e+01, -2.8750068262165129e+01, 2.8713713785364632e+01, -2.8676201855972838e+01, 2.8637508405928582e+01, -2.8597608139454216e+01, 2.8556474462684317e+01, -2.8514079407692357e+01, 2.8470393550387154e+01, -2.8425385921689980e+01, 2.8379023911335469e+01, -2.8331273163562241e+01, 2.8282097463870919e+01, -2.8231458615927721e+01, 2.8179316307577007e+01, -2.8125627964795978e+01, 2.8070348592274335e+01, -2.8013430599129791e+01, 2.7954823608071283e+01, -2.7894474246092045e+01, 2.7832325914509102e+01, -2.7768318535855649e+01, 2.7702388274772812e+01, -2.7634467229625290e+01, 2.7564483091071313e+01, -2.7492358763234872e+01, 2.7418011942441147e+01, -2.7341354647661582e+01, 2.7262292695845463e+01, -2.7180725114157759e+01, 2.7096543479754125e+01, -2.7009631176051933e+01, 2.6919862552432274e+01, -2.6827101971847423e+01, 2.6731202727801637e+01, -2.6632005808479860e+01, 2.6529338481236699e+01, -2.6423012664989045e+01, 2.6312823050968596e+01, -2.6198544923370154e+01, 2.6079931620126878e+01, -2.5956711559610614e+01, 2.5828584740479602e+01, -2.5695218597789456e+01, 2.5556243066913400e+01, -2.5411244665072719e+01, 2.5259759344501671e+01, -2.5101263795907457e+01, 2.4935164777812641e+01, -2.4760785904535670e+01, 2.4577351124781824e+01, -2.4383963836126313e+01, 2.4179580164227872e+01, -2.3962974319140965e+01, 2.3732693009179656e+01, -2.3486994450692443e+01, 2.3223765221215142e+01, -2.2940404454619134e+01, 2.2633658531147908e+01, -2.2299378247064869e+01, 2.1932149880547183e+01, -2.1524711604262862e+01, 2.1066983867982440e+01, -2.0544356598262947e+01, 1.9934415682618429e+01, -1.9199991275984207e+01, 1.8272015227078569e+01, -1.6996182114611788e+01, 1.4876958810870860e+01}, + }, + { + n: 216, + theta: []float64{1.5671686105755023e+00, 1.5599127961684220e+00, 1.5526558355346407e+00, 1.5453969634495357e+00, 1.5381354130756992e+00, 1.5308704153127000e+00, 1.5236011981417006e+00, 1.5163269859634152e+00, 1.5090469989278730e+00, 1.5017604522544048e+00, 1.4944665555402459e+00, 1.4871645120560699e+00, 1.4798535180267400e+00, 1.4725327618954691e+00, 1.4652014235695219e+00, 1.4578586736455008e+00, 1.4505036726121565e+00, 1.4431355700285682e+00, 1.4357535036754083e+00, 1.4283565986768869e+00, 1.4209439665908115e+00, 1.4135147044640579e+00, 1.4060678938505511e+00, 1.3986025997886760e+00, 1.3911178697348172e+00, 1.3836127324494960e+00, 1.3760861968323106e+00, 1.3685372507016056e+00, 1.3609648595144777e+00, 1.3533679650223920e+00, 1.3457454838572851e+00, 1.3380963060426339e+00, 1.3304192934234869e+00, 1.3227132780089634e+00, 1.3149770602201478e+00, 1.3072094070356892e+00, 1.2994090500267301e+00, 1.2915746832720101e+00, 1.2837049611431546e+00, 1.2757984959492026e+00, 1.2678538554283829e+00, 1.2598695600739727e+00, 1.2518440802797628e+00, 1.2437758332892002e+00, 1.2356631799306261e+00, 1.2275044211192108e+00, 1.2192977941041021e+00, 1.2110414684370108e+00, 1.2027335416358120e+00, 1.1943720345138122e+00, 1.1859548861419755e+00, 1.1774799484076148e+00, 1.1689449801287550e+00, 1.1603476406784692e+00, 1.1516854830678944e+00, 1.1429559464302423e+00, 1.1341563478407819e+00, 1.1252838733993509e+00, 1.1163355684922343e+00, 1.1073083271390356e+00, 1.0981988803171721e+00, 1.0890037831415225e+00, 1.0797194007591668e+00, 1.0703418927985888e+00, 1.0608671961885900e+00, 1.0512910061337959e+00, 1.0416087550001036e+00, 1.0318155888237164e+00, 1.0219063411101317e+00, 1.0118755035330074e+00, 1.0017171930750695e+00, 9.9142511507162645e-01, 9.8099252151840288e-01, 9.7041216388519547e-01, 9.5967623952979786e-01, 9.4877633062585665e-01, 9.3770333429470865e-01, 9.2644738235305046e-01, 9.1499774873988793e-01, 9.0334274224692235e-01, 8.9146958161860457e-01, 8.7936424937397950e-01, 8.6701131978084423e-01, 8.5439375521282512e-01, 8.4149266354281749e-01, 8.2828700713198744e-01, 8.1475325116200825e-01, 8.0086493523862246e-01, 7.8659214693830359e-01, 7.7190086863415974e-01, 7.5675215854165734e-01, 7.4110111194290051e-01, 7.2489552655247935e-01, 7.0807416302356885e-01, 6.9056444104412407e-01, 6.7227933193754241e-01, 6.5311307983969791e-01, 6.3293516775593595e-01, 6.1158156935716357e-01, 5.8884164425859431e-01, 5.6443772421506910e-01, 5.3799175946275157e-01, 5.0896747562778555e-01, 4.7656205323872197e-01, 4.3948124005672007e-01, 3.9539840620540745e-01, 3.3931369540774287e-01, 2.5576413755369809e-01}, + val: []float64{-2.1420664007171084e-13, 5.3170379037842784e-14, -3.4734236933038639e-15, 2.3242110868118431e-13, 3.7943143720204046e-14, -5.7160511614569708e-14, 2.1177269961331864e-13, -3.4948583926844979e-14, 1.7369271883827313e-13, 3.5623756291990570e-13, 6.5520118362261941e-14, 1.1255590127344777e-13, 9.4867994932892441e-14, -6.1601712969494469e-14, 4.7023788875015558e-14, -1.4272998866826663e-13, -2.6605445153274162e-14, -2.5223571223200907e-13, -1.3724084095111965e-13, -7.0111736669803626e-14, 5.7347666545680944e-14, -5.0924962889888544e-14, -5.2683776576685045e-15, -2.1544335394504838e-13, 4.0230445264824984e-15, 6.9175538975130938e-15, -1.1339463388095042e-13, -3.9896959286779273e-14, -8.8360560296236634e-14, -1.0474371284611670e-13, 1.2687327963040444e-14, -1.7782734520430910e-13, 2.0086781777635686e-13, -7.5400883703521135e-14, 1.2278140016266356e-13, -1.1244970732922019e-13, 1.6072100253117342e-14, 5.2340169298568757e-15, 1.1013085876614924e-13, -9.6621831158318670e-15, -1.8366177977891496e-13, 1.0601073284832238e-14, -1.3784763212103856e-13, -1.5863525424166753e-13, -1.6638681463670250e-13, 8.6360908147481066e-14, -7.8672683965135368e-14, 6.8378486764803313e-14, 9.0534733729868808e-14, 6.6505185887739604e-15, 3.3141885340142080e-15, -2.0537396911778824e-13, 7.3393589371575821e-14, 9.8483281662822096e-14, -2.3812738806298458e-13, 6.5975425886450090e-15, 8.7013139463913052e-14, 7.5278742714453987e-14, -1.0708940266003440e-13, 2.0958580081069137e-13, -1.5480716019053119e-14, 4.8469624575186930e-15, -6.1362291991375536e-14, -3.5942923464396180e-14, -7.6176865685553763e-14, 1.0095757892256693e-13, -4.2683956504767779e-14, -4.8938621882647329e-14, 1.6489272569372713e-15, -1.1390338364880240e-13, 2.1513601964632049e-14, -1.0152923724696736e-14, -3.9597826958407387e-14, -8.5123156147931521e-14, -6.5276802085245163e-14, 6.3966825794140229e-14, -2.8207572680644779e-14, -5.9767990455898208e-15, -1.1189271498293956e-13, -4.5600777141900301e-14, 1.5226732724861721e-14, 3.9473540473700922e-14, -5.6017378761616795e-15, -2.4079255903843183e-14, -3.1139558336514997e-14, -5.6034014603771978e-14, 6.9309294575728887e-14, -3.7871955014469560e-14, 4.2988763678275364e-14, 1.0661412180664073e-14, 6.2069599395465107e-14, -4.8913422170368503e-14, 3.3884911719768557e-14, 2.8191908465098299e-15, 2.1228960171536080e-14, -5.6191478942893769e-14, -1.4786950368470112e-14, -2.1665036441200809e-14, 1.4936420829725019e-14, -1.1615745673091571e-13, 1.4661728300981146e-13, -3.6088669931521093e-13, 1.1825080499589470e-12, -4.7300739521811106e-12, 2.5459387908526307e-11, -2.2842779135337983e-10, 5.3230524570865730e-09, 1.8504694403187737e-14}, + dval: []float64{-2.9427800603424888e+01, 2.9427025985916128e+01, -2.9425476404186732e+01, 2.9423151164251305e+01, -2.9420049223750453e+01, 2.9416169190288219e+01, -2.9411509319206210e+01, 2.9406067510787015e+01, -2.9399841306877356e+01, 2.9392827886918813e+01, -2.9385024063373031e+01, 2.9376426276524445e+01, -2.9367030588643043e+01, 2.9356832677485624e+01, -2.9345827829112846e+01, 2.9334010929995465e+01, -2.9321376458381234e+01, 2.9307918474890485e+01, -2.9293630612304742e+01, 2.9278506064510257e+01, -2.9262537574553480e+01, 2.9245717421762187e+01, -2.9228037407881235e+01, 2.9209488842167364e+01, -2.9190062525382206e+01, 2.9169748732617215e+01, -2.9148537194877896e+01, 2.9126417079348521e+01, -2.9103376968250736e+01, 2.9079404836201938e+01, -2.9054488025970500e+01, 2.9028613222515034e+01, -2.9001766425185131e+01, 2.8973932917948375e+01, -2.8945097237496743e+01, 2.8915243139070423e+01, -2.8884353559822181e+01, 2.8852410579527444e+01, -2.8819395378426645e+01, 2.8785288191964142e+01, -2.8750068262165122e+01, 2.8713713785364636e+01, -2.8676201855972852e+01, 2.8637508405928578e+01, -2.8597608139454227e+01, 2.8556474462684314e+01, -2.8514079407692350e+01, 2.8470393550387161e+01, -2.8425385921689987e+01, 2.8379023911335462e+01, -2.8331273163562233e+01, 2.8282097463870926e+01, -2.8231458615927728e+01, 2.8179316307577018e+01, -2.8125627964795974e+01, 2.8070348592274335e+01, -2.8013430599129794e+01, 2.7954823608071287e+01, -2.7894474246092045e+01, 2.7832325914509109e+01, -2.7768318535855656e+01, 2.7702388274772812e+01, -2.7634467229625294e+01, 2.7564483091071331e+01, -2.7492358763234883e+01, 2.7418011942441158e+01, -2.7341354647661582e+01, 2.7262292695845463e+01, -2.7180725114157763e+01, 2.7096543479754128e+01, -2.7009631176051940e+01, 2.6919862552432292e+01, -2.6827101971847430e+01, 2.6731202727801641e+01, -2.6632005808479885e+01, 2.6529338481236724e+01, -2.6423012664989066e+01, 2.6312823050968632e+01, -2.6198544923370196e+01, 2.6079931620126928e+01, -2.5956711559610671e+01, 2.5828584740479652e+01, -2.5695218597789530e+01, 2.5556243066913513e+01, -2.5411244665072843e+01, 2.5259759344501834e+01, -2.5101263795907666e+01, 2.4935164777812918e+01, -2.4760785904536036e+01, 2.4577351124782325e+01, -2.4383963836127013e+01, 2.4179580164228856e+01, -2.3962974319142369e+01, 2.3732693009181720e+01, -2.3486994450695558e+01, 2.3223765221219963e+01, -2.2940404454626893e+01, 2.2633658531160954e+01, -2.2299378247087898e+01, 2.1932149880590437e+01, -2.1524711604350518e+01, 2.1066983868178077e+01, -2.0544356598759389e+01, 1.9934415684120079e+01, -1.9199991281861426e+01, 1.8272015261833435e+01, -1.6996182557157578e+01, 1.4876958810870862e+01}, + }, + } { + got := make([]float64, len(test.theta)) + gotD := make([]float64, len(test.theta)) + for i := range got { + got[i], gotD[i] = Hermite{}.hermpolyAsyAiry(i, test.n, test.theta[i]) + } + if !floats.EqualApprox(test.val, got, 1e-12) { + t.Errorf("n = %v, hermpolyAsyAiry mismatch", test.n) + } + if !floats.EqualApprox(test.dval, gotD, 1e-12) { + t.Errorf("n = %v, hermpolyAsyAiry deriv mismatch", test.n) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/internal/PrintGoSlice.m b/vendor/gonum.org/v1/gonum/integrate/quad/internal/PrintGoSlice.m new file mode 100644 index 00000000..d3a51b28 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/internal/PrintGoSlice.m @@ -0,0 +1,11 @@ +% Copyright 2016 The gonum Authors. All rights reserved. +% Use of this source code is governed by a BSD-style +% license that can be found in the LICENSE file. + +function PrintGoSlice(a) + fprintf('[]float64{') + for i = 1:length(a) + fprintf('%1.16e, ',a(i)) + end + fprintf('}\n') +end \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/internal/genherm.m b/vendor/gonum.org/v1/gonum/integrate/quad/internal/genherm.m new file mode 100644 index 00000000..f673f97d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/internal/genherm.m @@ -0,0 +1,32 @@ +% Copyright 2016 The gonum Authors. All rights reserved. +% Use of this source code is governed by a BSD-style +% license that can be found in the LICENSE file. + +clc +clear all +close all + +% Generate herm points +min = 216; +max = 216; +fprintf('xCache = [][]float64{\n') +for i = min:max + [x,w] = hermpts(i); + fprintf('{') + for j = 1:i-1 + fprintf('%1.16e, ',x(j)) + end + fprintf('%1.16e},\n',x(i)) +end +fprintf('}\n') + +fprintf('wCache = [][]float64{\n') +for i = min:max + [x,w] = hermpts(i); + fprintf('{') + for j = 1:i-1 + fprintf('%1.16e, ',w(j)) + end + fprintf('%1.16e},\n',w(i)) +end +fprintf('}\n') diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/internal/hermpts.m b/vendor/gonum.org/v1/gonum/integrate/quad/internal/hermpts.m new file mode 100644 index 00000000..9306ad60 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/internal/hermpts.m @@ -0,0 +1,609 @@ +% Copyright (c) 2015, The Chancellor, Masters and Scholars of the University +% of Oxford, and the Chebfun Developers. +% Copyright (c) 2016 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 University of Oxford nor the names of its +% 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. + + +function [x, w, v] = hermpts(n, varargin) +%HERMPTS Hermite points and Gauss-Hermite Quadrature Weights. +% HERMPTS(N) returns N Hermite points X in (-inf, inf). By default these are +% roots of the 'physicist'-type Hermite polynomials, which are orthogonal with +% respect to the weight exp(-x.^2). +% +% HERMPTS(N, 'PROB') normalises instead by the probablist's definition (with +% weight exp(-x.^2/2)), which gives rise to monomials. +% +% [X, W] = HERMPTS(N) returns also a row vector W of weights for Gauss-Hermite +% quadrature. [X,W,V] = HERMPTS(N) returns in addition a column vector V of +% the barycentric weights corresponding to X. +% +% [X, W] = HERMPTS(N, METHOD) where METHOD is one of 'GW', 'REC', 'GLR', or +% 'ASY' allows the user to select which method is used. 'GW' will use the +% traditional Golub-Welsch eigenvalue method [1], best when n<=20. 'REC' +% uses Newton's method with polynomial evaluation via the 3-term +% recurrence for Hermite polynomials. 'GLR' uses Glaser-Liu-Rokhlin +% fast algorithm which is much faster for large N [2]. 'ASY' uses Newton's +% method with polynomial evaluation via asymptotic formula. 'ASY' is the +% fastest for N>=200, 'GLR' is the most accurate for nodes close to 0. +% By default HERMPTS uses 'GW' when N <= 20, 'REC' for 21<=N<200, and +% 'ASY' when N>=200. +% +% References: +% [1] G. H. Golub and J. A. Welsch, "Calculation of Gauss quadrature +% rules", Math. Comp. 23:221-230, 1969, +% [2] A. Glaser, X. Liu and V. Rokhlin, "A fast algorithm for the +% calculation of the roots of special functions", SIAM Journal +% on Scientific Computing", 29(4):1420-1438:, 2007. +% [3] A. Townsend, T. Trogdon and S. Olver, Fast computation of Gauss +% nodes and weights on the whole real line, submitted, 2014. +% +% See also CHEBPTS, LEGPTS, LAGPTS, and JACPTS. + +% Copyright 2015 by The University of Oxford and The Chebfun Developers. +% See http://www.chebfun.org/ for Chebfun information. +% +% 'GW' by Nick Trefethen, March 2009 - algorithm adapted from [1]. +% 'GLR' by Nick Hale, March 2010 - algorithm adapted from [2]. + +% Defaults: +method = 'default'; +type = 'phys'; + +if ( n < 0 ) + error('CHEBFUN:hermpts:n', 'First input should be a positive integer.'); +end + +% Return empty vector if n = 0. +if ( n == 0 ) + [x, w, v] = deal([]); + return +end + +% Check the inputs +while ( ~isempty(varargin) ) + s = varargin{1}; + varargin(1) = []; + if ( strcmpi(s, 'GW') ) + method = 'GW'; + elseif ( strcmpi(s,'glr') ) + method = 'GLR'; + elseif ( strcmpi(s,'rec') ) + method = 'REC'; + elseif ( strcmpi(s,'asy') ) + method = 'ASY'; + elseif ( strncmpi(s, 'phys', 3) ) + type = 'phys'; + elseif ( strncmpi(s, 'prob', 3) ) + type = 'prob'; + else + error('CHEBFUN:hermpts:input', 'Unrecognised input string; %s.', s); + end +end + +% Three cases: +% +% N <= 20: Use GW +% 21<=N<200: Use REC +% N>=200: Use ASY +if ( n == 1 ) + % n = 1 case is trivial + x = 0; + w = sqrt(pi); + v = 1; + +elseif ( (n < 21 && strcmpi(method,'default')) || strcmpi(method,'GW') ) + % GW, see [1] + + beta = sqrt(.5*(1:n-1)); % 3-term recurrence coeffs + T = diag(beta, 1) + diag(beta, -1); % Jacobi matrix + [V, D] = eig(T); % Eigenvalue decomposition + [x, indx] = sort(diag(D)); % Hermite points + w = sqrt(pi)*V(1, indx).^2; % weights + v = abs(V(1, indx)).'; % Barycentric weights + v = v./max(v); % Normalize + v(2:2:n) = -v(2:2:n); + + % Enforce symmetry: + ii = 1:floor(n/2); + x = x(ii); + w = w(ii); + vmid = v(floor(n/2)+1); + v = v(ii); + if ( mod(n, 2) ) + x = [x ; 0 ; -x(end:-1:1)]; + w = [w, sqrt(pi) - sum(2*w), w(end:-1:1)]; + v = [v ; vmid ; v(end:-1:1)]; + else + x = [x ; -x(end:-1:1)]; + w = [w, w(end:-1:1)]; + v = [v ; -v(end:-1:1)]; + end + +elseif ( strcmpi(method,'GLR') ) + % Fast, see [2] + + [x, ders] = alg0_Herm(n); % Nodes and H_n'(x) + w = (2*exp(-x.^2)./ders.^2)'; % Quadrature weights + v = exp(-x.^2/2)./ders; % Barycentric weights + v = v./max(abs(v)); % Normalize + if ( ~mod(n, 2) ) + ii = (n/2+1):n; + v(ii) = -v(ii); + end + +elseif ( (n < 200 && strcmpi(method,'default')) || strcmpi(method,'REC') ) + + [x, w, v] = hermpts_rec( n ); + +else + + [x, w, v] = hermpts_asy( n ); + +end + +% Normalise so that sum(w) = sqrt(pi) +w = (sqrt(pi)/sum(w))*w; + +if ( strcmpi(type, 'prob') ) + x = x*sqrt(2); + w = w*sqrt(2); +end + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %%%%%%%%%%%%%%%%%%%%%%% Routines for GLR algorithm %%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Driver for 'GLR'. +function [roots, ders] = alg0_Herm(n) +% Compute coefficients of H_m(0), H_m'(0), m = 0,..,N. + +Hm2 = 0; +Hm1 = pi^(-1/4); +Hpm2 = 0; +Hpm1 = 0; +for k = 0:n-1 + H = -sqrt(k/(k+1))*Hm2; + Hp = sqrt(2/(k+1))*Hm1-sqrt(k/(k+1))*Hpm2; + Hm2 = Hm1; + Hm1 = H; + Hpm2 = Hpm1; + Hpm1 = Hp; +end + +% allocate storage +roots = zeros(n, 1); +ders = zeros(n, 1); +if ( mod(n,2) ) + % zero is a root: + roots((n-1)/2) = 0; + ders((n+1)/2) = Hp; +else + % find first root: + [roots(n/2+1), ders(n/2+1)] = alg2_Herm(H,n); +end + +% compute roots and derivatives: +[roots, ders] = alg1_Herm(roots, ders); + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Main algorithm for 'GLR' +function [roots, ders] = alg1_Herm(roots, ders) + +n = length(roots); +s = mod(n, 2); +N = (n - s) / 2; + +% number of terms in Taylor expansion +m = 30; + +% initialise +hh1 = ones(m + 1, 1); +u = zeros(1, m + 1); +up = zeros(1, m + 1); + +for j = (N + 1):(n - 1) + + % previous root + x = roots(j); + + % initial approx + h = rk2_Herm(pi/2,-pi/2,x,n) - x; + + % scaling + M = 1/h; + + % recurrence relation for Hermite polynomials + c1 = -(2*n+1-x^2)/M^2; + c2 = 2*x./M^3; + c3 = 1./M^4; + u(1) = 0; + u(2) = ders(j)/M; + u(3) = .5*c1*u(1); + u(4) = (c1*u(2) + c2*u(1))/6; + up(1) = u(2); + up(2) = 2*u(3)*M; + up(3) = 3*u(4)*M; + up(m+1) = 0; + + for k = 2:m-2 + u(k+3) = (c1*u(k+1) + c2*u(k) + c3*u(k-1))/((k+1)*(k+2)); + up(k+2) = (k+2)*u(k+3)*M; + end + + % flip for more accuracy in inner product calculation + u = u(m+1:-1:1); + up = up(m+1:-1:1); + + % Newton iteration + hh = hh1; + hh(end) = M; + step = inf; + l = 0; + z = zeros(m, 1); + while ( (abs(step) > eps) && (l < 10) ) + l = l + 1; + step = (u*hh)/(up*hh); + h = h - step; + % powers of h (This is the fastest way!) + hh = [M ; cumprod(M*h + z)]; + % flip for more accuracy in inner product calculation + hh = hh(end:-1:1); + end + + % update + roots(j+1) = x + h; + ders(j+1) = up*hh; +end + +% nodes are symmetric +roots(1:N+s) = -roots(n:-1:N+1); +ders(1:N+s) = ders(n:-1:N+1); + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% find the first root (note H_n'(0) = 0) +function [x1, d1] = alg2_Herm(Hn0, n) + +% advance ODE via Runge-Kutta for initial approx +x1 = rk2_Herm(0, -pi/2, 0, n); + +% number of terms in Taylor expansion +m = 30; + +% scaling +M = 1/x1; +% c = log10(n); +% M = 1./x1.^(1-1.25/(c)); + +% initialise +u = zeros(1,m+1); +up = zeros(1,m+1); + +% recurrence relation for Legendre polynomials +u(1) = Hn0; +u(3) = -.5*(2*n+1)*u(1)/M^2; +up(1) = 0; +up(2) = 2*u(3)*M; +for k = 2:2:m-2 + u(k+3) = (-(2*n+1)*u(k+1)/M^2 + u(k-1)/M^4)/((k+1)*(k+2)); + up(k+2) = (k+2)*u(k+3)*M; +end + +% flip for more accuracy in inner product calculation +u = u(m+1:-1:1); +up = up(m+1:-1:1); + +z = zeros(m, 1); +x1k = [M ; cumprod(M*x1 + z)]; +step = inf; +l = 0; +% Newton iteration +while ( (abs(step) > eps) && (l < 10) ) + l = l + 1; + step = (u*x1k)/(up*x1k); + x1 = x1 - step; + % powers of h (This is the fastest way!) + x1k = [1 ; cumprod(M*x1 + z)]; + x1k = x1k(end:-1:1); +end + +% Update derivative +d1 = up*x1k; + +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Runge-Kutta for Hermite Equation +function x = rk2_Herm(t, tn, x, n) +m = 10; +h = (tn-t)/m; +for j = 1:m + k1 = -h/(sqrt(2*n+1-x^2) - .5*x*sin(2*t)/(2*n+1-x^2)); + t = t + h; + k2 = -h/(sqrt(2*n+1-(x+k1)^2) - .5*x*sin(2*t)/(2*n+1-(x+k1)^2)); + x = x + .5*(k1 + k2); +end +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %%%%%%%%%%%%%%%%%%%%%%% Routines for ASY algorithm %%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function [x, w, v] = hermpts_asy(n) +% HERMPTS_ASY, fast algorithm for computing Gauss-Hermite nodes and weights +% using Newton's method with polynomial evaluation via asymptotic expansions. +% +% x = Gauss-Hermite nodes, w = quad weights, v = bary weights. +% +% See [3]. + +[x, w, v] = hermpts_asy0( n ); + +if mod(n,2) == 1 % fold out + x = [-x(end:-1:1);x(2:end)]; + w = [w(end:-1:1) w(2:end)]; w = (sqrt(pi)/sum(w))*w; + v = [v(end:-1:1);v(2:end)]; v = v./max(abs(v)); +else + x = [-x(end:-1:1);x]; + w = [w(end:-1:1) w]; w = (sqrt(pi)/sum(w))*w; + v = [v(end:-1:1);-v]; v = v./max(abs(v)); +end + +% debug +%tic, exact = hermpts(n); toc +%semilogy(abs(exact-x)) +end + +function [x, w, v] = hermpts_asy0(n) +% Compute Hermite nodes and weights using asymptotic formula + +x0 = HermiteInitialGuesses(n); % get initial guesses +t0 = x0./sqrt(2*n+1); +theta0 = acos(t0); % convert to theta-variable +for k = 1:20 + [val, dval] = hermpoly_asy_airy(n, theta0); + dt = -val./(sqrt(2)*sqrt(2*n+1)*dval.*sin(theta0)); + theta0 = theta0 - dt; % Newton update + if norm(dt,inf) < sqrt(eps)/10, break; end +end +t0 = cos(theta0); +x = sqrt(2*n+1)*t0; % back to x-variable + +ders = x.*val + sqrt(2)*dval; +%ders = dval; +w = (exp(-x.^2)./ders.^2)'; % quadrature weights + +v = exp(-x.^2/2)./ders; % Barycentric weights +end + +function [val, dval] = hermpoly_asy_airy(n, theta) +% HERMPOLY_ASY evaluation hermite poly using Airy asymptotic formula in +% theta-space. + +musq = 2*n+1; +cosT = cos(theta); sinT = sin(theta); +sin2T = 2*cosT.*sinT; +eta = .5*theta - .25*sin2T; +chi = -(3*eta/2).^(2/3); +phi = (-chi./sinT.^2).^(1/4); +const = 2*sqrt(pi)*musq^(1/6)*phi; +Airy0 = real(airy(musq.^(2/3)*chi)); +Airy1 = real(airy(1,musq.^(2/3)*chi)); + +% Terms in (12.10.43): +a0 = 1; b0 = 1; +a1 = 15/144; b1 = -7/5*a1; +a2 = 5*7*9*11/2/144^2; b2 = -13/11*a2; +a3 = 7*9*11*13*15*17/6/144^3; +b3 = -19/17*a3; + +% u polynomials in (12.10.9) +u0 = 1; u1 = (cosT.^3-6*cosT)/24; +u2 = (-9*cosT.^4 + 249*cosT.^2 + 145)/1152; +u3 = (-4042*cosT.^9+18189*cosT.^7-28287*cosT.^5-151995*cosT.^3-259290*cosT)/414720; + +%first term +A0 = 1; +val = A0*Airy0; + +%second term +B0 = -(a0*phi.^6.*u1+a1*u0)./chi.^2; +val = val + B0.*Airy1./musq.^(4/3); + +%third term +A1 = (b0*phi.^12.*u2 + b1*phi.^6.*u1 + b2*u0)./chi.^3; +val = val + A1.*Airy0/musq.^2; + +%fourth term +B1 = -(phi.^18.*u3 + a1*phi.^12.*u2 + a2*phi.^6.*u1 + a3*u0)./chi.^5; +val = val + B1.*Airy1./musq.^(4/3+2); + +val = const.*val; + +%% Derivative + +eta = .5*theta - .25*sin2T; +chi = -(3*eta/2).^(2/3); +phi = (-chi./sinT.^2).^(1/4); +const = sqrt(2*pi)*musq^(1/3)./phi; + +% v polynomials in (12.10.10) +v0 = 1; v1 = (cosT.^3+6*cosT)/24; +v2 = (15*cosT.^4-327*cosT.^2-143)/1152; +v3 = (259290*cosT + 238425*cosT.^3 - 36387*cosT.^5 + 18189*cosT.^7 -... + 4042*cosT.^9)/414720; + +%first term +C0 = -(b0*phi.^6.*v1 + b1.*v0)./chi; +dval = C0.*Airy0/musq.^(2/3); + +% %second term +D0 = a0*v0; +dval = dval + D0*Airy1; + +% %third term +C1 = -(phi.^18.*v3 + b1*phi.^12.*v2 + b2*phi.^6.*v1 + b3*v0)./chi.^4; +dval = dval + C1.*Airy0/musq.^(2/3+2); + +%fourth term +D1 = (a0*phi.^12.*v2 + a1*phi.^6.*v1 + a2*v0)./chi.^3; +dval = dval + D1.*Airy1/musq.^2; + +dval = const.*dval; + +end + +function x_init = HermiteInitialGuesses(n) +%HERMITEINTITIALGUESSES(N), Initial guesses for Hermite zeros. +% +% [1] L. Gatteschi, Asymptotics and bounds for the zeros of Laguerre +% polynomials: a survey, J. Comput. Appl. Math., 144 (2002), pp. 7-27. +% +% [2] F. G. Tricomi, Sugli zeri delle funzioni di cui si conosce una +% rappresentazione asintotica, Ann. Mat. Pura Appl. 26 (1947), pp. 283-300. + +% Gatteschi formula involving airy roots [1]. +% These initial guess are good near x = sqrt(n+1/2); +if mod(n,2) == 1 + m = (n-1)/2; bess = (1:m)'*pi; a = .5; +else + m = n/2; bess = ((0:m-1)'+.5)*pi; a = -.5; +end +nu = 4*m + 2*a + 2; +T = @(t) t.^(2/3).*(1+5/48*t.^(-2)-5/36*t.^(-4)+(77125/82944)*t.^(-6) -... + 108056875/6967296*t.^(-8)+162375596875/334430208*t.^(-10)); +airyrts = -T(3/8*pi*(4*(1:m)'-1)); + +airyrts_exact = [ -2.338107410459762 % Exact Airy roots. + -4.087949444130970 + -5.520559828095555 + -6.786708090071765 + -7.944133587120863 + -9.022650853340979 + -10.040174341558084 + -11.008524303733260 + -11.936015563236262 + -12.828776752865757]; +airyrts(1:10) = airyrts_exact; % correct first 10. + +x_init = sqrt(nu + 2^(2/3)*airyrts*nu^(1/3) +... + 1/5*2^(4/3)*airyrts.^2*nu^(-1/3) +... + (11/35-a^2-12/175*airyrts.^3)/nu +... + (16/1575*airyrts+92/7875*airyrts.^4)*2^(2/3)*nu^(-5/3) -... + (15152/3031875*airyrts.^5+1088/121275*airyrts.^2)*2^(1/3)*nu^(-7/3)); +x_init_airy = real(x_init(end:-1:1)); + +% Tricomi initial guesses. Equation (2.1) in [1]. Originally in [2]. +% These initial guesses are good near x = 0 . Note: zeros of besselj(+/-.5,x) +% are integer and half-integer multiples of pi. +% x_init_bess = bess/sqrt(nu).*sqrt((1+ (bess.^2+2*(a^2-1))/3/nu^2) ); +Tnk0 = pi/2*ones(m,1); +nu = (4*m+2*a+2); +rhs = (4*m-4*(1:m)'+3)./nu*pi; + +for k = 1:7 + val = Tnk0 - sin(Tnk0) - rhs; + dval = 1 - cos(Tnk0); + dTnk0 = val./dval; + Tnk0 = Tnk0 - dTnk0; +end + +tnk = cos(Tnk0/2).^2; +x_init_sin = sqrt(nu*tnk - (5./(4*(1-tnk).^2) - 1./(1-tnk)-1+3*a^2)/3/nu); + +% Patch together +p = 0.4985+eps; +x_init = [x_init_sin(1:floor(p*n));x_init_airy(ceil(p*n):end)]; + + +if mod(n,2) == 1 + x_init = [0;x_init]; + x_init = x_init(1:m+1); +else + x_init = x_init(1:m); +end + +% debug: +%y = hermpts(n); +%semilogy(abs(y - x_init)); +%yhalf = -y(m:-1:1); +%semilogy(abs(yhalf - x_init)); +end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% %%%%%%%%%%%%%%%%%%%%%%% Routines for REC algorithm %%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function [x, w, v] = hermpts_rec(n) +% Compute Hermite nodes and weights using recurrence relation. + +x0 = HermiteInitialGuesses(n); +x0 = x0.*sqrt(2); + +for kk = 1:10 + [val, dval] = hermpoly_rec(n, x0); + dx = val./dval; + dx(isnan(dx)) = 0; + x0 = x0 - dx; + if norm(dx, inf)= max { + panic("legendre: min >= max") + } + if math.IsInf(min, 0) || math.IsInf(max, 0) { + panic("legendre: infinite bound") + } + for i := range x { + x[i], weight[i] = l.boundedLocation(len(x), i, min, max) + } +} + +func (l Legendre) FixedLocationSingle(n, k int, min, max float64) (x, weight float64) { + if min >= max { + panic("legendre: min >= max") + } + if math.IsInf(min, 0) || math.IsInf(max, 0) { + panic("legendre: infinite bound") + } + return l.boundedLocation(n, k, min, max) +} + +func (l Legendre) boundedLocation(n, k int, min, max float64) (x, weight float64) { + x, weight = l.location(n, k) + return (x+1)/2*(max-min) + min, weight * (max - min) / 2 +} + +// Algorithm adapted from http://sourceforge.net/projects/fastgausslegendrequadrature. + +// Original Copyright Notice: +//******************************************* +// Copyright (C) 2014 by Ignace Bogaert * +//******************************************* + +// This software package is based on the paper +// I. Bogaert, "Iteration-Free Computation of Gauss-Legendre Quadrature Nodes and Weights", +// to be published in the SIAM Journal of Scientific Computing. + +// The main features of this software are: +// - Speed: due to the simple formulas and the O(1) complexity computation of individual Gauss-Legendre +// quadrature nodes and weights. This makes it compatible with parallel computing paradigms. +// - Accuracy: the error on the nodes and weights is within a few ulps (see the paper for details). + +// Disclaimer: +// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED 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 REGENTS 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. + +// location finds the location and weight for location k given n total samples. +func (l Legendre) location(n, k int) (x, weight float64) { + // Note: k is 1-indexed in the original algorithm. It has been translated to + // zero-indexed here. + if n < 101 { + theta, weight := l.tabulated(n, k) + return math.Cos(theta), weight + } + if 2*k+1 > n { + theta, weight := l.computed(n, n-k) + return math.Cos(math.Pi - theta), weight + } + theta, weight := l.computed(n, k+1) + return math.Cos(theta), weight +} + +// Returns tabulated theta and weight values: valid for l <= 100 +func (l Legendre) tabulated(n, k int) (theta, weight float64) { + if n%2 == 1 { + n2 := (n - 1) / 2 + if k == n2 { + return math.Pi / 2, 2.0 / (cl[n] * cl[n]) + } + if k < n2 { + return oddThetaZeros[n2-1][n2-k-1], oddWeights[n2-1][n2-k-1] + } + return math.Pi - oddThetaZeros[n2-1][k-n2-1], oddWeights[n2-1][k-n2-1] + } + n2 := n / 2 + if k < n2 { + return evenThetaZeros[n2-1][n2-k-1], evenWeights[n2-1][n2-k-1] + } + return math.Pi - evenThetaZeros[n2-1][k-n2], evenWeights[n2-1][k-n2] +} + +func (l Legendre) computed(n, k int) (theta, weight float64) { + // First, get the bessel zero + w := 1.0 / (float64(n) + 0.5) + nu := besselJZero(k) + theta = w * nu + x := theta * theta + + // Get the asymptotic BesselJ(1, nu) squared + b := besselJ1Squared(k) + + // Get the Chebyshev interpolants for the nodes. + sf1t := (((((-1.29052996274280508473467968379e-12*x+2.40724685864330121825976175184e-10)*x-3.13148654635992041468855740012e-8)*x+0.275573168962061235623801563453e-5)*x-0.148809523713909147898955880165e-3)*x+0.416666666665193394525296923981e-2)*x - 0.416666666666662959639712457549e-1 + sf2t := (((((+2.20639421781871003734786884322e-9*x-7.53036771373769326811030753538e-8)*x+0.161969259453836261731700382098e-5)*x-0.253300326008232025914059965302e-4)*x+0.282116886057560434805998583817e-3)*x-0.209022248387852902722635654229e-2)*x + 0.815972221772932265640401128517e-2 + sf3t := (((((-2.97058225375526229899781956673e-8*x+5.55845330223796209655886325712e-7)*x-0.567797841356833081642185432056e-5)*x+0.418498100329504574443885193835e-4)*x-0.251395293283965914823026348764e-3)*x+0.128654198542845137196151147483e-2)*x - 0.416012165620204364833694266818e-2 + + // and the weights + wsf1t := ((((((((-2.20902861044616638398573427475e-14*x+2.30365726860377376873232578871e-12)*x-1.75257700735423807659851042318e-10)*x+1.03756066927916795821098009353e-8)*x-4.63968647553221331251529631098e-7)*x+0.149644593625028648361395938176e-4)*x-0.326278659594412170300449074873e-3)*x+0.436507936507598105249726413120e-2)*x-0.305555555555553028279487898503e-1)*x + 0.833333333333333302184063103900e-1 + wsf2t := (((((((+3.63117412152654783455929483029e-12*x+7.67643545069893130779501844323e-11)*x-7.12912857233642220650643150625e-9)*x+2.11483880685947151466370130277e-7)*x-0.381817918680045468483009307090e-5)*x+0.465969530694968391417927388162e-4)*x-0.407297185611335764191683161117e-3)*x+0.268959435694729660779984493795e-2)*x - 0.111111111111214923138249347172e-1 + wsf3t := (((((((+2.01826791256703301806643264922e-9*x-4.38647122520206649251063212545e-8)*x+5.08898347288671653137451093208e-7)*x-0.397933316519135275712977531366e-5)*x+0.200559326396458326778521795392e-4)*x-0.422888059282921161626339411388e-4)*x-0.105646050254076140548678457002e-3)*x-0.947969308958577323145923317955e-4)*x + 0.656966489926484797412985260842e-2 + + // Then refine with the paper expansions + nuSin := nu / math.Sin(theta) + bNuSin := b * nuSin + wInvSinc := w * w * nuSin + wIS2 := wInvSinc * wInvSinc + + // Finally, compute the node and the weight + theta = w * (nu + theta*wInvSinc*(sf1t+wIS2*(sf2t+wIS2*sf3t))) + deno := bNuSin + bNuSin*wIS2*(wsf1t+wIS2*(wsf2t+wIS2*wsf3t)) + weight = 2.0 * w / deno + return theta, weight +} + +func besselJZero(k int) float64 { + if k < 20 { + return jz[k-1] + } + z := math.Pi * (float64(k) - 0.25) + r := 1.0 / z + r2 := r * r + z += r * (0.125 + r2*(-0.807291666666666666666666666667e-1+r2*(0.246028645833333333333333333333+r2*(-1.82443876720610119047619047619+r2*(25.3364147973439050099206349206+r2*(-567.644412135183381139802038240+r2*(18690.4765282320653831636345064+r2*(-8.49353580299148769921876983660e5+5.09225462402226769498681286758e7*r2)))))))) + return z +} + +func besselJ1Squared(k int) float64 { + if k < 21 { + return j1[k-1] + } + x := 1.0 / (float64(k) - 0.25) + x2 := x * x + return x * (0.202642367284675542887758926420 + x2*x2*(-0.303380429711290253026202643516e-3+x2*(0.198924364245969295201137972743e-3+x2*(-0.228969902772111653038747229723e-3+x2*(0.433710719130746277915572905025e-3+x2*(-0.123632349727175414724737657367e-2+x2*(0.496101423268883102872271417616e-2+x2*(-0.266837393702323757700998557826e-1+.185395398206345628711318848386*x2)))))))) +} + +// Tabulated values +var jz = [20]float64{2.40482555769577276862163187933, 5.52007811028631064959660411281, 8.65372791291101221695419871266, 11.7915344390142816137430449119, 14.9309177084877859477625939974, 18.0710639679109225431478829756, 21.2116366298792589590783933505, 24.3524715307493027370579447632, 27.4934791320402547958772882346, 30.6346064684319751175495789269, 33.7758202135735686842385463467, 36.9170983536640439797694930633, 40.0584257646282392947993073740, 43.1997917131767303575240727287, 46.3411883716618140186857888791, 49.4826098973978171736027615332, 52.6240518411149960292512853804, 55.7655107550199793116834927735, 58.9069839260809421328344066346, 62.0484691902271698828525002646} +var j1 = [21]float64{0.269514123941916926139021992911, 0.115780138582203695807812836182, 0.0736863511364082151406476811985, 0.0540375731981162820417749182758, 0.0426614290172430912655106063495, 0.0352421034909961013587473033648, 0.0300210701030546726750888157688, 0.0261473914953080885904584675399, 0.0231591218246913922652676382178, 0.0207838291222678576039808057297, 0.0188504506693176678161056800214, 0.0172461575696650082995240053542, 0.0158935181059235978027065594287, 0.0147376260964721895895742982592, 0.0137384651453871179182880484134, 0.0128661817376151328791406637228, 0.0120980515486267975471075438497, 0.0114164712244916085168627222986, 0.0108075927911802040115547286830, 0.0102603729262807628110423992790, 0.00976589713979105054059846736696} + +// Tabulated nodes and weights +// The required theta values for the Legendre nodes for l <= 100 +var evenThetaZeros = [][]float64{ + {0.9553166181245092781638573e0}, + {0.1223899586470372591854100e1, 0.5332956802491269896325121e0}, + {0.1329852612388110166006182e1, 0.8483666264874876548310910e0, 0.3696066519448289481138796e0}, + {0.1386317078892131346282665e1, 0.1017455539490153431016397e1, 0.6490365804607796100719162e0, 0.2827570635937967783987981e0}, + {0.1421366498439524924081833e1, 0.1122539327631709474018620e1, 0.8238386589997556048023640e0, 0.5255196555285001171749362e0, 0.2289442988470260178701589e0}, + {0.1445233238471440081118261e1, 0.1194120375947706635968399e1, 0.9430552870605735796668951e0, 0.6921076988818410126677201e0, 0.4414870814893317611922530e0, 0.1923346793046672033050762e0}, + {0.1462529992921481833498746e1, 0.1246003586776677662375070e1, 0.1029498592525136749641068e1, 0.8130407055389454598609888e0, 0.5966877608172733931509619e0, 0.3806189306666775272453522e0, 0.1658171411523664030454318e0}, + {0.1475640280808194256470687e1, 0.1285331444322965257106517e1, 0.1095033401803444343034890e1, 0.9047575323895165085030778e0, 0.7145252532340252146626998e0, 0.5243866409035941583262629e0, 0.3344986386876292124968005e0, 0.1457246820036738335698855e0}, + {0.1485919440392653014379727e1, 0.1316167494718022699851110e1, 0.1146421481056642228295923e1, 0.9766871104439832694094465e0, 0.8069738930788195349918620e0, 0.6373005058706191519531139e0, 0.4677113145328286263205134e0, 0.2983460782092324727528346e0, 0.1299747364196768405406564e0}, + {0.1494194914310399553510039e1, 0.1340993178589955138305166e1, 0.1187794926634098887711586e1, 0.1034603297590104231043189e1, 0.8814230742890135843662021e0, 0.7282625848696072912405713e0, 0.5751385026314284688366450e0, 0.4220907301111166004529037e0, 0.2692452880289302424376614e0, 0.1172969277059561308491253e0}, + {0.1501000399130816063282492e1, 0.1361409225664372117193308e1, 0.1221820208990359866348145e1, 0.1082235198111836788818162e1, 0.9426568273796608630446470e0, 0.8030892957063359443650460e0, 0.6635400754448062852164288e0, 0.5240242709487281141128643e0, 0.3845781703583910933413978e0, 0.2453165389983612942439953e0, 0.1068723357985259945018899e0}, + {0.1506695545558101030878728e1, 0.1378494427506219143960887e1, 0.1250294703417272987066314e1, 0.1122097523267250692925104e1, 0.9939044422989454674968570e0, 0.8657177770401081355080608e0, 0.7375413075437535618804594e0, 0.6093818382449565759195927e0, 0.4812531951313686873528891e0, 0.3531886675690780704072227e0, 0.2252936226353075734690198e0, 0.9814932949793685067733311e-1}, + {0.1511531546703289231944719e1, 0.1393002286179807923400254e1, 0.1274473959424494104852958e1, 0.1155947313793812040125722e1, 0.1037423319077439147088755e1, 0.9189033445598992550553862e0, 0.8003894803353296871788647e0, 0.6818851814129298518332401e0, 0.5633967073169293284500428e0, 0.4449368152119130526034289e0, 0.3265362611165358134766736e0, 0.2082924425598466358987549e0, 0.9074274842993199730441784e-1}, + {0.1515689149557281132993364e1, 0.1405475003062348722192382e1, 0.1295261501292316172835393e1, 0.1185049147889021579229406e1, 0.1074838574917869281769567e1, 0.9646306371285440922680794e0, 0.8544265718392254369377945e0, 0.7442282945111358297916378e0, 0.6340389954584301734412433e0, 0.5238644768825679339859620e0, 0.4137165857369637683488098e0, 0.3036239070914333637971179e0, 0.1936769929947376175341314e0, 0.8437551461511597225722252e-1}, + {0.1519301729274526620713294e1, 0.1416312682230741743401738e1, 0.1313324092045794720169874e1, 0.1210336308624476413072722e1, 0.1107349759228459143499061e1, 0.1004365001539081003659288e1, 0.9013828087667156388167226e0, 0.7984043170121235411718744e0, 0.6954313000299367256853883e0, 0.5924667257887385542924194e0, 0.4895160050896970092628705e0, 0.3865901987860504829542802e0, 0.2837160095793466884313556e0, 0.1809780449917272162574031e0, 0.7884320726554945051322849e-1}, + {0.1522469852641529230282387e1, 0.1425817011963825344615095e1, 0.1329164502391080681347666e1, 0.1232512573416362994802398e1, 0.1135861522840293704616614e1, 0.1039211728068951568003361e1, 0.9425636940046777101926515e0, 0.8459181315837993237739032e0, 0.7492760951181414487254243e0, 0.6526392394594561548023681e0, 0.5560103418005302722406995e0, 0.4593944730762095704649700e0, 0.3628020075350028174968692e0, 0.2662579994723859636910796e0, 0.1698418454282150179319973e0, 0.7399171309970959768773072e-1}, + {0.1525270780617194430047563e1, 0.1434219768045409606267345e1, 0.1343169000217435981125683e1, 0.1252118659062444379491066e1, 0.1161068957629157748792749e1, 0.1070020159291475075961444e1, 0.9789726059789103169325141e0, 0.8879267623988119819560021e0, 0.7968832893748414870413015e0, 0.7058431727509840105946884e0, 0.6148079652926100198490992e0, 0.5237802779694730663856110e0, 0.4327648832448234459097574e0, 0.3417715500266717765568488e0, 0.2508238767288223767569849e0, 0.1599966542668327644694431e0, 0.6970264809814094464033170e-1}, + {0.1527764849261740485876940e1, 0.1441701954349064743573367e1, 0.1355639243522655042028688e1, 0.1269576852063768424508476e1, 0.1183514935851550608323947e1, 0.1097453683555812711123880e1, 0.1011393333949027021740881e1, 0.9253342019812867059380523e0, 0.8392767201322475821509486e0, 0.7532215073977623159515351e0, 0.6671694908788198522546767e0, 0.5811221342350705406265672e0, 0.4950819018993074588093747e0, 0.4090533017972007314666814e0, 0.3230455648729987995657071e0, 0.2370809940997936908335290e0, 0.1512302802537625099602687e0, 0.6588357082399222649528476e-1}, + {0.1529999863223206659623262e1, 0.1448406982124841835685420e1, 0.1366814241651488684482888e1, 0.1285221744143731581870833e1, 0.1203629605904952775544878e1, 0.1122037965173751996510051e1, 0.1040446993107623345153211e1, 0.9588569097730895525404200e0, 0.8772680085516152329147030e0, 0.7956806951062012653043722e0, 0.7140955526031660805347356e0, 0.6325134568448222221560326e0, 0.5509357927460004487348532e0, 0.4693648943475422765864580e0, 0.3878050333015201414955289e0, 0.3062649591511896679168503e0, 0.2247658146033686460963295e0, 0.1433746167818849555570557e0, 0.6246124541276674097388211e-1}, + {0.1532014188279762793560699e1, 0.1454449946977268522285131e1, 0.1376885814601482670609845e1, 0.1299321869764876494939757e1, 0.1221758200747475205847413e1, 0.1144194910846247537582396e1, 0.1066632125552939823863593e1, 0.9890700026972186303565530e0, 0.9115087474225932692070479e0, 0.8339486352158799520695092e0, 0.7563900488174808348719219e0, 0.6788335401193977027577509e0, 0.6012799395312684623216685e0, 0.5237305617022755897200291e0, 0.4461876237541810478131970e0, 0.3686551849119556335824055e0, 0.2911415613085158758589405e0, 0.2136668503694680525340165e0, 0.1362947587312224822844743e0, 0.5937690028966411906487257e-1}, + {0.1533838971193864306068338e1, 0.1459924288056445029654271e1, 0.1386009690354996919044862e1, 0.1312095239305276612560739e1, 0.1238181002944535867235042e1, 0.1164267059803796726229370e1, 0.1090353503721897748980095e1, 0.1016440450472067349837507e1, 0.9425280472651469176638349e0, 0.8686164868955467866176243e0, 0.7947060295895204342519786e0, 0.7207970381018823842440224e0, 0.6468900366403721167107352e0, 0.5729858150363658839291287e0, 0.4990856247464946058899833e0, 0.4251915773724379089467945e0, 0.3513075400485981451355368e0, 0.2774414365914335857735201e0, 0.2036124177925793565507033e0, 0.1298811916061515892914930e0, 0.5658282534660210272754152e-1}, + {0.1535499761264077326499892e1, 0.1464906652494521470377318e1, 0.1394313611500109323616335e1, 0.1323720686538524176057236e1, 0.1253127930763390908996314e1, 0.1182535404796980113294400e1, 0.1111943180033868679273393e1, 0.1041351343083674290731439e1, 0.9707600019805773720746280e0, 0.9001692951667510715040632e0, 0.8295794049297955988640329e0, 0.7589905782114329186155957e0, 0.6884031600807736268672129e0, 0.6178176499732537480601935e0, 0.5472348011493452159473826e0, 0.4766558078624760377875119e0, 0.4060826859477620301047824e0, 0.3355191279517093844978473e0, 0.2649727008485465487101933e0, 0.1944616940738156405895778e0, 0.1240440866043499301839465e0, 0.5403988657613871827831605e-1}, + {0.1537017713608809830855653e1, 0.1469460505124226636602925e1, 0.1401903350962364703169699e1, 0.1334346289590505369693957e1, 0.1266789363044399933941254e1, 0.1199232618763735058848455e1, 0.1131676111906105521856066e1, 0.1064119908394702657537061e1, 0.9965640890815034701957497e0, 0.9290087556203499065939494e0, 0.8614540390091103102510609e0, 0.7939001124053586164046432e0, 0.7263472110048245091518914e0, 0.6587956640463586742461796e0, 0.5912459486086227271608064e0, 0.5236987847717837556177452e0, 0.4561553147193391989386660e0, 0.3886174669444433167860783e0, 0.3210887745896478259115420e0, 0.2535764786314617292100029e0, 0.1860980813776342452540915e0, 0.1187090676924131329841811e0, 0.5171568198966901682810573e-1}, + {0.1538410494858190444190279e1, 0.1473638845472165977392911e1, 0.1408867240039222913928858e1, 0.1344095709533508756473909e1, 0.1279324287566779722061664e1, 0.1214553011719528935181709e1, 0.1149781925191718586091000e1, 0.1085011078936665906275419e1, 0.1020240534516704208782618e1, 0.9554703680422404498752066e0, 0.8907006757608306209160649e0, 0.8259315822134856671969566e0, 0.7611632524946588128425351e0, 0.6963959112887657683892237e0, 0.6316298735371143844913976e0, 0.5668655960010826255149266e0, 0.5021037684870694065589284e0, 0.4373454855522296089897130e0, 0.3725925956833896735786860e0, 0.3078484858841616878136371e0, 0.2431200981264999375962973e0, 0.1784242126043536701754986e0, 0.1138140258514833068653307e0, 0.4958315373802413441075340e-1}, + {0.1539692973716708504412697e1, 0.1477486279394502338589519e1, 0.1415279620944410339318226e1, 0.1353073023537942666830874e1, 0.1290866514321280958405103e1, 0.1228660123395079609266898e1, 0.1166453885011658611362850e1, 0.1104247839096738022319035e1, 0.1042042033248543055386770e1, 0.9798365254403234947595400e0, 0.9176313877712591840677176e0, 0.8554267118081827231209625e0, 0.7932226163976800550406599e0, 0.7310192594231560707888939e0, 0.6688168560730805146438886e0, 0.6066157082814543103941755e0, 0.5444162542389049922529553e0, 0.4822191559963931133878621e0, 0.4200254643636986308379697e0, 0.3578369542536859435571624e0, 0.2956568781922605524959448e0, 0.2334919029083292837123583e0, 0.1713581437497397360313735e0, 0.1093066902335822942650053e0, 0.4761952998197036029817629e-1}, + {0.1540877753740080417345045e1, 0.1481040617373741365390254e1, 0.1421203510518656600018143e1, 0.1361366453804322852131292e1, 0.1301529469356044341206877e1, 0.1241692581525935716830402e1, 0.1181855817774264617619371e1, 0.1122019209772750368801179e1, 0.1062182794829879659341536e1, 0.1002346617783007482854908e1, 0.9425107335729934538419206e0, 0.8826752108319277463183701e0, 0.8228401370047382776784725e0, 0.7630056258499810562932058e0, 0.7031718287376427885875898e0, 0.6433389522119553277924537e0, 0.5835072863023426715977658e0, 0.5236772521416453354847559e0, 0.4638494862268433259444639e0, 0.4040249990308909882616381e0, 0.3442054975680110060507306e0, 0.2843941101955779333389742e0, 0.2245972494281051799602510e0, 0.1648304164747050021714385e0, 0.1051427544146599992432949e0, 0.4580550859172367960799915e-1}, + {0.1541975588842621898865181e1, 0.1484334121018556567335167e1, 0.1426692677652358867201800e1, 0.1369051275783071487471360e1, 0.1311409933595114953831618e1, 0.1253768670970438091691833e1, 0.1196127510146226323327062e1, 0.1138486476526912406867032e1, 0.1080845599717322003702293e1, 0.1023204914871722785830020e1, 0.9655644644970043364617272e0, 0.9079243009168822510582606e0, 0.8502844897148263889326479e0, 0.7926451146568312828354346e0, 0.7350062849078710810840430e0, 0.6773681459074923011631400e0, 0.6197308962817025162722438e0, 0.5620948151095422609589585e0, 0.5044603077892199488064657e0, 0.4468279872027509013135997e0, 0.3891988265038338944044115e0, 0.3315744698431505326770711e0, 0.2739579305700525818998611e0, 0.2163553856859193758294342e0, 0.1587817673749480300092784e0, 0.1012844151694839452028589e0, 0.4412462056235422293371300e-1}, + {0.1542995710582548837472073e1, 0.1487394484904746766220933e1, 0.1431793279635669382208875e1, 0.1376192108950239363921811e1, 0.1320590987909222553912422e1, 0.1264989932881031519687125e1, 0.1209388962038683919740547e1, 0.1153788095965648154683658e1, 0.1098187358416032947576489e1, 0.1042586777292402877200408e1, 0.9869863859317282394719449e0, 0.9313862248321055503829503e0, 0.8757863440192765677772914e0, 0.8201868063589761051746975e0, 0.7645876922981545448147078e0, 0.7089891068198449136125464e0, 0.6533911899285832425290628e0, 0.5977941329592257586198087e0, 0.5421982048745539015834188e0, 0.4866037965045890355211229e0, 0.4310114988353693539492225e0, 0.3754222503860499120445385e0, 0.3198376369331602148544626e0, 0.2642605649958747239907310e0, 0.2086969927688100977274751e0, 0.1531613237261629042774314e0, 0.9769922156300582041279299e-1, 0.4256272861907242306694832e-1}, + {0.1543946088331101630230404e1, 0.1490245617072432741470241e1, 0.1436545162952171175361532e1, 0.1382844737841275627385236e1, 0.1329144354302189376680665e1, 0.1275444025914442882448630e1, 0.1221743767654456436125309e1, 0.1168043596353244531685999e1, 0.1114343531263457295536939e1, 0.1060643594778787047442989e1, 0.1006943813366184678568021e1, 0.9532442187977767941200107e0, 0.8995448498101763729640445e0, 0.8458457543830885615091264e0, 0.7921469929325243736682034e0, 0.7384486428849507503612470e0, 0.6847508053901545384892447e0, 0.6310536154445759741044291e0, 0.5773572576394624029563656e0, 0.5236619915567428835581025e0, 0.4699681944935857341529219e0, 0.4162764370726533962791279e0, 0.3625876255789859906927245e0, 0.3089032914359211154562848e0, 0.2552262416643531728802047e0, 0.2015622306384971766058615e0, 0.1479251692966707827334002e0, 0.9435916010280739398532997e-1, 0.4110762866287674188292735e-1}, + {0.1544833637851665335244669e1, 0.1492908264756388370493025e1, 0.1440982906138650837480037e1, 0.1389057572001580364167786e1, 0.1337132272892735072773304e1, 0.1285207020157876647295968e1, 0.1233281826234298389291217e1, 0.1181356705000596722238457e1, 0.1129431672204958843918638e1, 0.1077506746001711267258715e1, 0.1025581947637229234301640e1, 0.9736573023432582093437126e0, 0.9217328405213548692702866e0, 0.8698085993416727107979968e0, 0.8178846249414537373941032e0, 0.7659609755086193214466010e0, 0.7140377257012462393241274e0, 0.6621149731355525426273686e0, 0.6101928481720243483360470e0, 0.5582715291407654489802101e0, 0.5063512668959282414914789e0, 0.4544324261262307197237056e0, 0.4025155584642650335664553e0, 0.3506015401168133792671488e0, 0.2986918517703509333332016e0, 0.2467892075469457255751440e0, 0.1948991714956708008247732e0, 0.1430351946011564171352354e0, 0.9123992133264713232350199e-1, 0.3974873026126591246235829e-1}, + {0.1545664389841685834178882e1, 0.1495400520006868605194165e1, 0.1445136662469633349524466e1, 0.1394872825707861196682996e1, 0.1344609018631531661347402e1, 0.1294345250782284139500904e1, 0.1244081532562166402923175e1, 0.1193817875503760392032898e1, 0.1143554292597402872188167e1, 0.1093290798696377946301336e1, 0.1043027411028491785799717e1, 0.9927641498535133311947588e0, 0.9425010393224361375194941e0, 0.8922381086194002226900769e0, 0.8419753935054036625982058e0, 0.7917129384431112475049142e0, 0.7414507995789214800057706e0, 0.6911890490185720721582180e0, 0.6409277811053987947460976e0, 0.5906671218914768219060599e0, 0.5404072438741681591850965e0, 0.4901483897634232956856935e0, 0.4398909124691513811974471e0, 0.3896353458699818240468259e0, 0.3393825380385224469051922e0, 0.2891339221891949677776928e0, 0.2388921255071779766209942e0, 0.1886625339124777570188312e0, 0.1384581678870181657476050e0, 0.8832030722827102577102185e-1, 0.3847679847963676404657822e-1}, + {0.1546443627125265521960044e1, 0.1497738231263909315513507e1, 0.1449032845902631477147772e1, 0.1400327478265391242178337e1, 0.1351622135921668846451224e1, 0.1302916826944702448727527e1, 0.1254211560091483702838765e1, 0.1205506345013417018443405e1, 0.1156801192508980685500292e1, 0.1108096114833249453312212e1, 0.1059391126084216587933501e1, 0.1010686242693213908544820e1, 0.9619814840575052973573711e0, 0.9132768733691264344256970e0, 0.8645724387181842642305406e0, 0.8158682145859558652971026e0, 0.7671642439014559105969752e0, 0.7184605809290069459742089e0, 0.6697572954095121564500879e0, 0.6210544786425143220264938e0, 0.5723522526623283741373995e0, 0.5236507845164779831804685e0, 0.4749503092950064087413842e0, 0.4262511688770346357064771e0, 0.3775538805043668894422883e0, 0.3288592658750793954850446e0, 0.2801687136893753887834348e0, 0.2314847695998852605184853e0, 0.1828126524563463299986617e0, 0.1341649789468091132459783e0, 0.8558174883654483804697753e-1, 0.3728374374031613183399036e-1}, + {0.1547175997094614757138430e1, 0.1499935340679181525271649e1, 0.1452694693272706215568985e1, 0.1405454061061768876728643e1, 0.1358213450511184239883293e1, 0.1310972868490444296079765e1, 0.1263732322416537730871712e1, 0.1216491820419724046503073e1, 0.1169251371540540180758674e1, 0.1122010985968754004469355e1, 0.1074770675338453464761893e1, 0.1027530453098431393666936e1, 0.9802903349842005856557204e0, 0.9330503396284544173873149e0, 0.8858104893623263267477775e0, 0.8385708112832335506864354e0, 0.7913313387011139500976360e0, 0.7440921131314510897906335e0, 0.6968531870945337206139839e0, 0.6496146281309018959581539e0, 0.6023765246993705639765525e0, 0.5551389950762090311242875e0, 0.5079022012032895030848024e0, 0.4606663710240282967569630e0, 0.4134318360639670775957014e0, 0.3661990979414348851212686e0, 0.3189689535781378596191439e0, 0.2717427498485401725509746e0, 0.2245229557871702595200694e0, 0.1773146332323969343091350e0, 0.1301300193754780766338959e0, 0.8300791095077070533235660e-1, 0.3616244959900389221395842e-1}, + {0.1547865604457777747119921e1, 0.1502004162357357213441384e1, 0.1456142728021903760325049e1, 0.1410281306774684706589738e1, 0.1364419904164498130803254e1, 0.1318558526067441138200403e1, 0.1272697178801115154796514e1, 0.1226835869256177571730448e1, 0.1180974605051351016009903e1, 0.1135113394719709026888693e1, 0.1089252247936466574864114e1, 0.1043391175801911243726755e1, 0.9975301911979639874925565e0, 0.9516693092438447484954432e0, 0.9058085478865097428655118e0, 0.8599479286766250282572181e0, 0.8140874778035996603018790e0, 0.7682272274981820559251592e0, 0.7223672179660643783333797e0, 0.6765075001043380283085699e0, 0.6306481393987597674748178e0, 0.5847892216487432573582268e0, 0.5389308616059791284685642e0, 0.4930732164176132508179420e0, 0.4472165073094733435432890e0, 0.4013610560689043520551232e0, 0.3555073496130768130758891e0, 0.3096561615434305328219637e0, 0.2638087993597793691714182e0, 0.2179676599607749036552390e0, 0.1721376573496165890967450e0, 0.1263306713881449555499955e0, 0.8058436603519718986295825e-1, 0.3510663068970053260227480e-1}, + {0.1548516088202564202943238e1, 0.1503955613246577879586994e1, 0.1459395145012190281751360e1, 0.1414834688100222735099866e1, 0.1370274247295441414922756e1, 0.1325713827649021532002630e1, 0.1281153434570536124285912e1, 0.1236593073933169034954499e1, 0.1192032752196710979323473e1, 0.1147472476554108430135576e1, 0.1102912255109027578275434e1, 0.1058352097094263144928973e1, 0.1013792013144153206047048e1, 0.9692320156388929821870602e0, 0.9246721191454417746654622e0, 0.8801123409896300773149632e0, 0.8355527020087518049947413e0, 0.7909932275560464363973909e0, 0.7464339488624693592395086e0, 0.7018749049145358048463504e0, 0.6573161450929179933243905e0, 0.6127577329584494909986789e0, 0.5681997518140860838771656e0, 0.5236423130979094957496400e0, 0.4790855694444512920982626e0, 0.4345297357523596151738496e0, 0.3899751246318782591316393e0, 0.3454222091410984787772492e0, 0.3008717408917773811461237e0, 0.2563249902500918978614004e0, 0.2117842860782107775954396e0, 0.1672544029381415755198150e0, 0.1227468836419337342946123e0, 0.7829832364814667171382217e-1, 0.3411071484766340151578357e-1}, + {0.1549130685823945998342524e1, 0.1505799405819664254557106e1, 0.1462468131657470292685966e1, 0.1419136867330461353369368e1, 0.1375805616982638895139986e1, 0.1332474384976155365522566e1, 0.1289143175965912901391449e1, 0.1245811994984327181800398e1, 0.1202480847539690438616688e1, 0.1159149739732435788417226e1, 0.1115818678394807971862305e1, 0.1072487671261111519215409e1, 0.1029156727178025494814510e1, 0.9858258563677261466814511e0, 0.9424950707611702085500992e0, 0.8991643844255133860018485e0, 0.8558338141192845596532563e0, 0.8125033800232146117493243e0, 0.7691731067161328174004981e0, 0.7258430244984030733808537e0, 0.6825131712172895509836733e0, 0.6391835948321685576634513e0, 0.5958543570955633038336902e0, 0.5525255389612023677479152e0, 0.5091972487450747080139606e0, 0.4658696348260689008126722e0, 0.4225429061321313393543928e0, 0.3792173666095906812269559e0, 0.3358934762285008809293807e0, 0.2925719658301625547639832e0, 0.2492540707015179370724365e0, 0.2059420554273186332219697e0, 0.1626405628266886976038507e0, 0.1193608172622853851645011e0, 0.7613840464754681957544313e-1, 0.3316974474186058622824911e-1}, + {0.1549712287207882890839045e1, 0.1507544209724862511636878e1, 0.1465376137339015815734558e1, 0.1423208073529702865859582e1, 0.1381040021900765225468989e1, 0.1338871986235691269778498e1, 0.1296703970558498635765633e1, 0.1254535979202491212629656e1, 0.1212368016889500927716256e1, 0.1170200088822853513468851e1, 0.1128032200798161849314963e1, 0.1085864359337236600941540e1, 0.1043696571852037437540940e1, 0.1001528846847853898635169e1, 0.9593611941780778060127795e0, 0.9171936253674231737318512e0, 0.8750261540268988114426643e0, 0.8328587963932301252176965e0, 0.7906915720393251716472997e0, 0.7485245048233193695739358e0, 0.7063576241759074809548715e0, 0.6641909668761970070284373e0, 0.6220245795476036586681135e0, 0.5798585222396645710869275e0, 0.5376928736905555113005422e0, 0.4955277392687366749125653e0, 0.4533632633323484070376718e0, 0.4111996491651493998151895e0, 0.3690371925202636251212886e0, 0.3268763409876008462653069e0, 0.2847178057580674399826003e0, 0.2425627889274157106498810e0, 0.2004134942584602007834507e0, 0.1582744399049656648660257e0, 0.1161565488818554609430574e0, 0.7409445176394481360104851e-1, 0.3227929535095246410912398e-1}, + {0.1550263480064160377720298e1, 0.1509197788083808185665328e1, 0.1468132100566875710992083e1, 0.1427066420556418463513913e1, 0.1386000751198712817289420e1, 0.1344935095788765217267069e1, 0.1303869457820298477498722e1, 0.1262803841041882838326682e1, 0.1221738249521212843639205e1, 0.1180672687719991159061894e1, 0.1139607160582508034089119e1, 0.1098541673641858946868449e1, 0.1057476233148907719560749e1, 0.1016410846230700992453501e1, 0.9753455210872527645472818e0, 0.9342802672387126698703291e0, 0.8932150958393123732306518e0, 0.8521500200807685012223049e0, 0.8110850557169691024167180e0, 0.7700202217553081279468270e0, 0.7289555413804262510029339e0, 0.6878910432074509889956044e0, 0.6468267630110350344178276e0, 0.6057627461556542068727688e0, 0.5646990510834698732732127e0, 0.5236357544389875315454201e0, 0.4825729588028297682338108e0, 0.4415108047277878179738561e0, 0.4004494901533595099830119e0, 0.3593893030723592157150581e0, 0.3183306793460978083354355e0, 0.2772743115465352362860883e0, 0.2362213703174823832436869e0, 0.1951740017836102296584907e0, 0.1541366059551230775894261e0, 0.1131198202589878992052369e0, 0.7215736988593890187079586e-1, 0.3143540438351454384152236e-1}, + {0.1550786588415152297375587e1, 0.1510767112957397367780716e1, 0.1470747641421582916022579e1, 0.1430728176478592843861361e1, 0.1390708720885325111445925e1, 0.1350689277522434511387126e1, 0.1310669849435604714836514e1, 0.1270650439881648370588402e1, 0.1230631052380981613091250e1, 0.1190611690778358944744052e1, 0.1150592359314214516523625e1, 0.1110573062709576809284752e1, 0.1070553806268363352417161e1, 0.1030534596002003296175373e1, 0.9905154387828984834423913e0, 0.9504963425353941517573974e0, 0.9104773164759498161192732e0, 0.8704583714184727086854142e0, 0.8304395201669023270865304e0, 0.7904207780260519973626051e0, 0.7504021634749074983118715e0, 0.7103836990664583264642972e0, 0.6703654126486745769832673e0, 0.6303473390491956215820085e0, 0.5903295224434431765765323e0, 0.5503120197533818815098408e0, 0.5102949056413983084126817e0, 0.4702782800468414863285692e0, 0.4302622799152491769326599e0, 0.3902470981180917254123191e0, 0.3502330152869736207185960e0, 0.3102204561556976356809728e0, 0.2702100956292792195263915e0, 0.2302030745053307298726703e0, 0.1902014842102915167005070e0, 0.1502096126336221315300686e0, 0.1102378261690820867329259e0, 0.7031899075931525095025389e-1, 0.3063451333411226493032265e-1}, + {0.1551283705347968314195100e1, 0.1512258463601911009913297e1, 0.1473233225313284690780287e1, 0.1434207992834186122366616e1, 0.1395182768588723275108301e1, 0.1356157555104474252423723e1, 0.1317132355046745793679891e1, 0.1278107171256650000336432e1, 0.1239082006794203284097135e1, 0.1200056864987904389011051e1, 0.1161031749492588664002624e1, 0.1122006664357811755961100e1, 0.1082981614109627397900573e1, 0.1043956603849447575483550e1, 0.1004931639374790125389322e1, 0.9659067273282460489273148e0, 0.9268818753831082867718635e0, 0.8878570924770502938457708e0, 0.8488323891094102606331406e0, 0.8098077777236123075833052e0, 0.7707832732049530424809748e0, 0.7317588935368492604710264e0, 0.6927346606780251833003950e0, 0.6537106017528970872810663e0, 0.6146867506941756306797580e0, 0.5756631505519364744300804e0, 0.5366398568077528417370132e0, 0.4976169422443344500752625e0, 0.4585945042946725387136724e0, 0.4195726764797194195007418e0, 0.3805516468579533335376469e0, 0.3415316890685593880011997e0, 0.3025132172735989410463832e0, 0.2634968895917008761291809e0, 0.2244838184598823563259898e0, 0.1854760433267094750424413e0, 0.1464777455344068532549101e0, 0.1074990339130794792907032e0, 0.6857195785426972961368108e-1, 0.2987341732561906608807860e-1}, + {0.1551756721003315464043007e1, 0.1513677510435354867644006e1, 0.1475598302924814895692182e1, 0.1437519100549654116408972e1, 0.1399439905448387106945081e1, 0.1361360719846430407096351e1, 0.1323281546084682430842605e1, 0.1285202386651141609385598e1, 0.1247123244216506877361870e1, 0.1209044121674894401873626e1, 0.1170965022191058363946285e1, 0.1132885949255841486220662e1, 0.1094806906752030657845562e1, 0.1056727899033393535018723e1, 0.1018648931020478788570327e1, 0.9805700083178549567966928e0, 0.9424911373589552049711100e0, 0.9044123255867553868253384e0, 0.8663335816813894348633149e0, 0.8282549158498738099497389e0, 0.7901763401989443875774432e0, 0.7520978692204962458482329e0, 0.7140195204316730003387055e0, 0.6759413152305656820841666e0, 0.6378632800575392064866756e0, 0.5997854479978337579981629e0, 0.5617078610344953281799357e0, 0.5236305732820186728652802e0, 0.4855536557378012985520074e0, 0.4474772034530068342865487e0, 0.4094013466928584958758982e0, 0.3713262689388439070717808e0, 0.3332522371792479009733062e0, 0.2951796555193184134657530e0, 0.2571091661074227554417865e0, 0.2190418543971735546480404e0, 0.1809797103814301725822348e0, 0.1429268140230164119614409e0, 0.1048930290780323497410212e0, 0.6690962797843649866645769e-1, 0.2914922224685900914817542e-1}, + {0.1552207346590136182648920e1, 0.1515029387081184115266415e1, 0.1477851430283927973458023e1, 0.1440673478039699629370259e1, 0.1403495532240969264030648e1, 0.1366317594853508812224152e1, 0.1329139667940348087929429e1, 0.1291961753688162615428688e1, 0.1254783854436838464182091e1, 0.1217605972713102930414639e1, 0.1180428111269300876868432e1, 0.1143250273128649048802100e1, 0.1106072461638634327789036e1, 0.1068894680534663975270023e1, 0.1031716934016664760314029e1, 0.9945392268421176498894610e0, 0.9573615644400829018748874e0, 0.9201839530522288586731642e0, 0.8830063999088902711516820e0, 0.8458289134509915302518266e0, 0.8086515036126424512848147e0, 0.7714741821849085841225787e0, 0.7342969632895448309937051e0, 0.6971198640037406540069491e0, 0.6599429051953912854163132e0, 0.6227661126567800124770610e0, 0.5855895186691062254659102e0, 0.5484131642019636734351025e0, 0.5112371020703309674589504e0, 0.4740614015734592960802666e0, 0.4368861554959151187817336e0, 0.3997114910036376358365916e0, 0.3625375872199777754435892e0, 0.3253647047992267079974806e0, 0.2881932382678453273830096e0, 0.2510238145617968753500674e0, 0.2138574934303919974438356e0, 0.1766962177535783269128215e0, 0.1395439709154010255199071e0, 0.1024103832005221866954023e0, 0.6532598686141261097119747e-1, 0.2845930797694291389393445e-1}, + {0.1552637135069155811491072e1, 0.1516318752418798211357541e1, 0.1480000372180291690418989e1, 0.1443681995989991700140976e1, 0.1407363625527612735973164e1, 0.1371045262534953065860219e1, 0.1334726908836065747097909e1, 0.1298408566359386697763653e1, 0.1262090237162411913706886e1, 0.1225771923459625279363960e1, 0.1189453627654523146514386e1, 0.1153135352376772077918208e1, 0.1116817100525785826106551e1, 0.1080498875322336017099434e1, 0.1044180680370244915946738e1, 0.1007862519730785566833872e1, 0.9715443980131875264637689e0, 0.9352263204856910439167915e0, 0.8989082932130182550456316e0, 0.8625903232280967802521182e0, 0.8262724187486163930514201e0, 0.7899545894528804342126058e0, 0.7536368468349768085155075e0, 0.7173192046673890278545072e0, 0.6810016796111441673128480e0, 0.6446842920316340773745262e0, 0.6083670671059611518530899e0, 0.5720500363511797523369558e0, 0.5357332397728172506411618e0, 0.4994167289487775362163415e0, 0.4631005715608865274454686e0, 0.4267848582339839676363509e0, 0.3904697131799790288672503e0, 0.3541553113674441557740819e0, 0.3178419074113077198829473e0, 0.2815298867038369044519273e0, 0.2452198616736214006194288e0, 0.2089128675558041239775998e0, 0.1726108022974787183994402e0, 0.1363175571713249458600521e0, 0.1000425397881322914313825e0, 0.6381557644960651200944222e-1, 0.2780129671121636039734655e-1}, + {0.1553047499032218401181962e1, 0.1517549844221432542461907e1, 0.1482052191561582448658478e1, 0.1446554542510861055782865e1, 0.1411056898564365493121105e1, 0.1375559261269981001734724e1, 0.1340061632245437638964436e1, 0.1304564013196950335363525e1, 0.1269066405939915513649123e1, 0.1233568812422221364483924e1, 0.1198071234750839346739124e1, 0.1162573675222508872274463e1, 0.1127076136359515473862368e1, 0.1091578620951808778363231e1, 0.1056081132107029235444226e1, 0.1020583673310438024843461e1, 0.9850862484973095869616622e0, 0.9495888621411026369897815e0, 0.9140915193617473526041913e0, 0.8785942260597805964360395e0, 0.8430969890839839780181254e0, 0.8075998164428632814935249e0, 0.7721027175741014967901450e0, 0.7366057036915554827257553e0, 0.7011087882372792641869964e0, 0.6656119874777629720186974e0, 0.6301153213012084608241887e0, 0.5946188142997514629085459e0, 0.5591224972630766104664894e0, 0.5236264092783024624074546e0, 0.4881306007441175888503326e0, 0.4526351377998500905914452e0, 0.4171401090099414677462070e0, 0.3816456357674021470057899e0, 0.3461518890753412856675063e0, 0.3106591177837409768492156e0, 0.2751676985649013361686770e0, 0.2396782299970584002479842e0, 0.2041917239104339765549482e0, 0.1687100353513348647833163e0, 0.1332369676454340307348264e0, 0.9778171579501174586520881e-1, 0.6237343205901608270979365e-1, 0.2717302558182235133513210e-1}, + {0.1553439726211153891540573e1, 0.1518726525682668668950427e1, 0.1484013327077361052080319e1, 0.1449300131698066374929113e1, 0.1414586940879145218883617e1, 0.1379873756000009717714844e1, 0.1345160578499605494109603e1, 0.1310447409892181029407508e1, 0.1275734251784724823396464e1, 0.1241021105896515467487132e1, 0.1206307974081314658309029e1, 0.1171594858352843571506531e1, 0.1136881760914326165420300e1, 0.1102168684193068774494217e1, 0.1067455630881287279906518e1, 0.1032742603984709761582283e1, 0.9980296068808995413713835e0, 0.9633166433897968474836258e0, 0.9286037178597176902839922e0, 0.8938908352730483454962679e0, 0.8591780013772376740585140e0, 0.8244652228485703565016715e0, 0.7897525074988288740747291e0, 0.7550398645386622329842600e0, 0.7203273049167972965433221e0, 0.6856148417619669061621766e0, 0.6509024909658764678789680e0, 0.6161902719627732109904446e0, 0.5814782087876726421060849e0, 0.5467663315368932859708410e0, 0.5120546784214694424751802e0, 0.4773432987146161851453875e0, 0.4426322570828636775769209e0, 0.4079216401227574252826633e0, 0.3732115665343573673240355e0, 0.3385022035318641142927744e0, 0.3037937944563405612019789e0, 0.2690867076466992914990193e0, 0.2343815284441088285495466e0, 0.1996792463094099012688324e0, 0.1649816752853099621072722e0, 0.1302925346385956500837770e0, 0.9562081616094948269905207e-1, 0.6099502786102040135198395e-1, 0.2657252290854776665952679e-1}, + {0.1553814992974904767594241e1, 0.1519852325907741898557817e1, 0.1485889660564341242674032e1, 0.1451926998111647785152899e1, 0.1417964339743630985906479e1, 0.1384001686692845945859686e1, 0.1350039040242776872946770e1, 0.1316076401741232369348729e1, 0.1282113772615099921371445e1, 0.1248151154386817288949698e1, 0.1214188548692984168143550e1, 0.1180225957305622474388020e1, 0.1146263382156703179022046e1, 0.1112300825366698998613230e1, 0.1078338289278105103916832e1, 0.1044375776495107627552926e1, 0.1010413289930890288650173e1, 0.9764508328644780886953041e0, 0.9424884090095589354132202e0, 0.9085260225984488659490189e0, 0.8745636784853451215455853e0, 0.8406013822743460048537475e0, 0.8066391404795569177534715e0, 0.7726769607271702244889884e0, 0.7387148520130367387469271e0, 0.7047528250344497011443004e0, 0.6707908926224332706815892e0, 0.6368290703120276715090693e0, 0.6028673771049329733376093e0, 0.5689058365047911420524623e0, 0.5349444779460832748774921e0, 0.5009833388030907720537138e0, 0.4670224672735823328060142e0, 0.4330619266162571710985599e0, 0.3991018015460700850326972e0, 0.3651422081877256344485503e0, 0.3311833101314466311103548e0, 0.2972253454486352538763297e0, 0.2632686745061683534910424e0, 0.2293138699815081215985284e0, 0.1953618999343470689252174e0, 0.1614145391777897730914718e0, 0.1274754265555317105245073e0, 0.9355335943686297111639257e-1, 0.5967622944002585907962555e-1, 0.2599798753052849047032580e-1}, + {0.1554174376112911655131098e1, 0.1520930475263640362170511e1, 0.1487686575963027013435604e1, 0.1454442679258803180913942e1, 0.1421198786221944168258440e1, 0.1387954897956585365296993e1, 0.1354711015610581847809736e1, 0.1321467140386931222410853e1, 0.1288223273556309404505081e1, 0.1254979416471008337267759e1, 0.1221735570580615776412743e1, 0.1188491737449843097435062e1, 0.1155247918778991542491874e1, 0.1122004116427655660730083e1, 0.1088760332442401967089102e1, 0.1055516569089340593777585e1, 0.1022272828892740925095715e1, 0.9890291146811467076264609e0, 0.9557854296428465678959260e0, 0.9225417773930866874628226e0, 0.8892981620561221868061383e0, 0.8560545883661619186153440e0, 0.8228110617925680415850631e0, 0.7895675886964734656602191e0, 0.7563241765284943282959446e0, 0.7230808340807681383862155e0, 0.6898375718116413059811978e0, 0.6565944022687408111136058e0, 0.6233513406471279431598408e0, 0.5901084055357449335782332e0, 0.5568656199307345199294838e0, 0.5236230126340485109018232e0, 0.4903806202198476810807501e0, 0.4571384898571183050552302e0, 0.4238966834573972483152713e0, 0.3906552839347125500730013e0, 0.3574144049483910279156003e0, 0.3241742066189948531421192e0, 0.2909349219721993995636414e0, 0.2576969037411283384416169e0, 0.2244607124763750082606152e0, 0.1912272957431274569912962e0, 0.1579983907861406744991899e0, 0.1247775594308675650267811e0, 0.9157341285433675818728635e-1, 0.5841325237532701385812948e-1, 0.2544777076240816313972829e-1}, + {0.1554518863153354618809409e1, 0.1521963936333782670214978e1, 0.1489409010908686292228052e1, 0.1456854087820918568482631e1, 0.1424299168033388494075931e1, 0.1391744252537595165009714e1, 0.1359189342362693116905575e1, 0.1326634438585269225516707e1, 0.1294079542340034988016159e1, 0.1261524654831668904330407e1, 0.1228969777348083696352705e1, 0.1196414911275444418157033e1, 0.1163860058115329026827193e1, 0.1131305219504506571098859e1, 0.1098750397237914982841550e1, 0.1066195593295557461150055e1, 0.1033640809874212986016967e1, 0.1001086049425085324651032e1, 0.9685313146988134601280153e0, 0.9359766087996588330547245e0, 0.9034219352512048766203636e0, 0.8708672980765996496647291e0, 0.8383127018973108640833295e0, 0.8057581520556423644789438e0, 0.7732036547680256450048242e0, 0.7406492173185620802637676e0, 0.7080948483057714882525616e0, 0.6755405579604902654406567e0, 0.6429863585601198571817691e0, 0.6104322649751623629236805e0, 0.5778782954001507969801437e0, 0.5453244723459250134170285e0, 0.5127708240092147734858477e0, 0.4802173861982495342372455e0, 0.4476642050968422792532389e0, 0.4151113413261211455132671e0, 0.3825588760747025757978563e0, 0.3500069206395502661556462e0, 0.3174556318161704671189642e0, 0.2849052377944113082878058e0, 0.2523560839907875626097181e0, 0.2198087193323827316322426e0, 0.1872640717400572601243546e0, 0.1547238424480887172335593e0, 0.1221915194567498709631299e0, 0.8967553546914315204781840e-1, 0.5720262597323678474637133e-1, 0.2492036059421555107245208e-1}, + {0.1554849361424470843090118e1, 0.1522955431101933730645303e1, 0.1491061502037751976297424e1, 0.1459167575082261894770634e1, 0.1427273651103158170602525e1, 0.1395379730992862183093282e1, 0.1363485815676330697886480e1, 0.1331591906119453530640248e1, 0.1299698003338207337770238e1, 0.1267804108408757103237650e1, 0.1235910222478728395590872e1, 0.1204016346779913703159712e1, 0.1172122482642727288439229e1, 0.1140228631512787910483320e1, 0.1108334794970091261912531e1, 0.1076440974751339138680154e1, 0.1044547172776127017814204e1, 0.1012653391177865049408482e1, 0.9807596323405319627306720e0, 0.9488658989426541583823449e0, 0.9169721940102869797082899e0, 0.8850785209812848825432963e0, 0.8531848837838285971960304e0, 0.8212912869330969580404013e0, 0.7893977356512249782795147e0, 0.7575042360174185552669765e0, 0.7256107951575083863622461e0, 0.6937174214856350398887716e0, 0.6618241250156435481462849e0, 0.6299309177668761147121611e0, 0.5980378142995696297245189e0, 0.5661448324309071185385071e0, 0.5342519942071113461815355e0, 0.5023593272451872220760104e0, 0.4704668666194035162003700e0, 0.4385746575692260390945883e0, 0.4066827594785525726660483e0, 0.3747912518813925812276922e0, 0.3429002438089823350625543e0, 0.3110098888674705209106637e0, 0.2791204106078991711912441e0, 0.2472321474279120600810915e0, 0.2153456371036966567922014e0, 0.1834617887100953140198272e0, 0.1515822689338083535939382e0, 0.1197104949484175660714864e0, 0.8785472823121690639967810e-1, 0.5604116141749524467628553e-1, 0.2441436781606819510490200e-1}, + {0.1555166706034023842787706e1, 0.1523907464890582273398300e1, 0.1492648224885016483409279e1, 0.1461388986785839210767990e1, 0.1430129751376631035251350e1, 0.1398870519462421720845393e1, 0.1367611291876438076975682e1, 0.1336352069487341263827064e1, 0.1305092853207091240256110e1, 0.1273833643999595441027728e1, 0.1242574442890323705495464e1, 0.1211315250977103200801981e1, 0.1180056069442347222927677e1, 0.1148796899567022469820701e1, 0.1117537742746723499546780e1, 0.1086278600510304367969825e1, 0.1055019474541620880304106e1, 0.1023760366705069175705639e1, 0.9925012790757765081567637e0, 0.9612422139755203374385844e0, 0.9299831740157389822411293e0, 0.8987241621493743180375722e0, 0.8674651817337867269827651e0, 0.8362062366076504452859926e0, 0.8049473311856388413561914e0, 0.7736884705759381993127359e0, 0.7424296607273230664538510e0, 0.7111709086148904840060001e0, 0.6799122224768919982385331e0, 0.6486536121198915829209739e0, 0.6173950893164463798129595e0, 0.5861366683298159921278400e0, 0.5548783666157332634604655e0, 0.5236202057751242467455922e0, 0.4923622128691229579358494e0, 0.4611044222679868504944176e0, 0.4298468783051183048132298e0, 0.3985896391770900735176252e0, 0.3673327828297899556279530e0, 0.3360764161195064368209114e0, 0.3048206895905456571224703e0, 0.2735658223403245791263072e0, 0.2423121460275046288225596e0, 0.2110601877217048587999889e0, 0.1798108384023314561549010e0, 0.1485657315840060835766576e0, 0.1173282164330337207824850e0, 0.8610639001623934211634967e-1, 0.5492592372249737419414775e-1, 0.2392851379957687254895331e-1}, +} + +var oddThetaZeros = [][]float64{ + {0.6847192030022829138880982e0}, + {0.1002176803643121641749915e1, 0.4366349492255221620374655e0}, + {0.1152892953722227341986065e1, 0.7354466143229520469385622e0, 0.3204050902900619825355950e0}, + {0.1240573923404363422789550e1, 0.9104740292261473250358755e0, 0.5807869795060065580284919e0, 0.2530224166119306882187233e0}, + {0.1297877729331450368298142e1, 0.1025003226369574843297844e1, 0.7522519395990821317003373e0, 0.4798534223256743217333579e0, 0.2090492874137409414071522e0}, + {0.1338247676100454369194835e1, 0.1105718066248490075175419e1, 0.8732366099401630367220948e0, 0.6408663264733867770811230e0, 0.4088002373420211722955679e0, 0.1780944581262765470585931e0}, + {0.1368219536992351783359098e1, 0.1165652065603030148723847e1, 0.9631067821301481995711685e0, 0.7606069572889918619145483e0, 0.5582062109125313357140248e0, 0.3560718303314725022788878e0, 0.1551231069747375098418591e0}, + {0.1391350647015287461874435e1, 0.1211909966211469688151240e1, 0.1032480728417239563449772e1, 0.8530732514258505686069670e0, 0.6737074594242522259878462e0, 0.4944303818194983217354808e0, 0.3153898594929282395996014e0, 0.1373998952992547671039022e0}, + {0.1409742336767428999667236e1, 0.1248691224331339221187704e1, 0.1087646521650454938943641e1, 0.9266134127998189551499083e0, 0.7656007620508340547558669e0, 0.6046261769405451549818494e0, 0.4437316659960951760051408e0, 0.2830497588453068048261493e0, 0.1233108673082312764916251e0}, + {0.1424715475176742734932665e1, 0.1278636375242898727771561e1, 0.1132561101012537613667002e1, 0.9864925055883793730483278e0, 0.8404350520135058972624775e0, 0.6943966110110701016065380e0, 0.5483930281810389839680525e0, 0.4024623099018152227701990e0, 0.2567245837448891192759858e0, 0.1118422651428890834760883e0}, + {0.1437141935303526306632113e1, 0.1303488659735581140681362e1, 0.1169837785762829821262819e1, 0.1036190996404462300207004e1, 0.9025507517347875930425807e0, 0.7689210263823624893974324e0, 0.6353089402976822861185532e0, 0.5017289283414202278167583e0, 0.3682157131008289798868520e0, 0.2348791589702580223688923e0, 0.1023252788872632487579640e0}, + {0.1447620393135667144403507e1, 0.1324445197736386798102445e1, 0.1201271573324181312770120e1, 0.1078100568411879956441542e1, 0.9549336362382321811515336e0, 0.8317729718814276781352878e0, 0.7086221837538611370849622e0, 0.5854877911108011727748238e0, 0.4623830630132757357909198e0, 0.3393399712563371486343129e0, 0.2164597408964339264361902e0, 0.9430083986305519349231898e-1}, + {0.1456575541704195839944967e1, 0.1342355260834552126304154e1, 0.1228136043468909663499174e1, 0.1113918572282611841378549e1, 0.9997037539874953933323299e0, 0.8854928869950799998575862e0, 0.7712879690777516856072467e0, 0.6570923167092416238233585e0, 0.5429119513798658239789812e0, 0.4287591577660783587509129e0, 0.3146635662674373982102762e0, 0.2007190266590380629766487e0, 0.8744338280630300217927750e-1}, + {0.1464317002991565219979113e1, 0.1357838033080061766980173e1, 0.1251359804334884770836945e1, 0.1144882777708662655968171e1, 0.1038407544520296695714932e1, 0.9319349156915986836657782e0, 0.8254660749671546663859351e0, 0.7190028636037068047812305e0, 0.6125483562383020473196681e0, 0.5061081521562999836102547e0, 0.3996936914666951732317457e0, 0.2933325857619472952507468e0, 0.1871123137498061864373407e0, 0.8151560650977882057817999e-1}, + {0.1471075823713997440657641e1, 0.1371355574944658989649887e1, 0.1271635855736122280723838e1, 0.1171916986981363820797100e1, 0.1072199368669106404814915e1, 0.9724835301003496870596165e0, 0.8727702114891848603047954e0, 0.7730605060747958359120755e0, 0.6733561257504194406005404e0, 0.5736599396529727772420934e0, 0.4739771829190733570809765e0, 0.3743185619229329461021810e0, 0.2747099287638327553949437e0, 0.1752332025619508475799133e0, 0.7634046205384429302353073e-1}, + {0.1477027911291552393547878e1, 0.1383259682348271685979143e1, 0.1289491840051302622319481e1, 0.1195724613675799550484673e1, 0.1101958282220461402990667e1, 0.1008193204014774090964219e1, 0.9144298626454031699590564e0, 0.8206689427646120483710056e0, 0.7269114630504563073034288e0, 0.6331590254855162126233733e0, 0.5394143214244183829842424e0, 0.4456822679082866369288652e0, 0.3519729273095236644049666e0, 0.2583106041071417718760275e0, 0.1647723231643112502628240e0, 0.7178317184275122449502857e-1}, + {0.1482309554825692463999299e1, 0.1393822922226542123661077e1, 0.1305336577335833571381699e1, 0.1216850687682353365944624e1, 0.1128365453024608460982204e1, 0.1039881123511957522668140e1, 0.9513980267579228357946521e0, 0.8629166105524045911461307e0, 0.7744375139383604902604254e0, 0.6859616923374368587817328e0, 0.5974906525247623278123711e0, 0.5090269299866796725116786e0, 0.4205751610647263669405267e0, 0.3321448379994943116084719e0, 0.2437588931448048912587688e0, 0.1554900095178924564386865e0, 0.6773932498157585698088354e-1}, + {0.1487027983239550912222135e1, 0.1403259745496922270264564e1, 0.1319491725464661433609663e1, 0.1235724047968681189212364e1, 0.1151956859289811446164825e1, 0.1068190338689553494802072e1, 0.9844247150109837231349622e0, 0.9006602918737365182850484e0, 0.8168974877846821404275069e0, 0.7331369031796229223580227e0, 0.6493794386888650054486281e0, 0.5656265174356596757139537e0, 0.4818805368222631487731579e0, 0.3981458834052590173509113e0, 0.3144315409387123154212535e0, 0.2307592167302372059759857e0, 0.1471977156945989772472748e0, 0.6412678117309944052403703e-1}, + {0.1491268718102344688271411e1, 0.1411741190914640487505771e1, 0.1332213830951015404441941e1, 0.1252686732830809999680267e1, 0.1173160005794509313174730e1, 0.1093633781237958896879965e1, 0.1014108223243148393065201e1, 0.9345835440325075907377330e0, 0.8550600276575269107773349e0, 0.7755380679025248517258532e0, 0.6960182317959841585145109e0, 0.6165013717819833504477346e0, 0.5369888366794912945318079e0, 0.4574829005269902932408889e0, 0.3779877260196973978940863e0, 0.2985118404618624984946326e0, 0.2190758506462427957069113e0, 0.1397450765119767349146353e0, 0.6088003363863534825005464e-1}, + {0.1495100801651051409999732e1, 0.1419405340110198552778393e1, 0.1343710008748627892724810e1, 0.1268014880389353000310414e1, 0.1192320038028903827079750e1, 0.1116625579891689469044026e1, 0.1040931626310454794079799e1, 0.9652383295306942866661884e0, 0.8895458882533946571137358e0, 0.8138545700535261740447950e0, 0.7381647473570304814395029e0, 0.6624769578126105498149624e0, 0.5867920109947446493391737e0, 0.5111111891461744489290992e0, 0.4354366553151050147918632e0, 0.3597723703299625354660452e0, 0.2841264494060559943920389e0, 0.2085185052177154996230005e0, 0.1330107089065635461375419e0, 0.5794620170990797798650123e-1}, + {0.1498580583401444174317386e1, 0.1426364890228584522673414e1, 0.1354149299629923281192036e1, 0.1281933868420423988034246e1, 0.1209718660626713399048551e1, 0.1137503750956414845248481e1, 0.1065289229411733880607916e1, 0.9930752076949068878557126e0, 0.9208618284397049456535757e0, 0.8486492789905562098591586e0, 0.7764378127156926158031943e0, 0.7042277832708635930867344e0, 0.6320197021480767602848178e0, 0.5598143404345395912377042e0, 0.4876129202946139420188428e0, 0.4154175043169533365541148e0, 0.3432318703096418027524597e0, 0.2710637595435203246492797e0, 0.1989318822110657561806962e0, 0.1268955503926593166308254e0, 0.5528212871240371048241379e-1}, + {0.1501754508594837337089856e1, 0.1432712730475143340404518e1, 0.1363671034069754274950592e1, 0.1294629464249430679064317e1, 0.1225588071083248538559259e1, 0.1156546912269029268686830e1, 0.1087506056298747798071893e1, 0.1018465586752840651469411e1, 0.9494256083335850798964741e0, 0.8803862556198167553278643e0, 0.8113477061841624760598814e0, 0.7423102009244498727845341e0, 0.6732740767851639064676858e0, 0.6042398217472142478598295e0, 0.5352081720899522889584566e0, 0.4661802954366277026594659e0, 0.3971581629712621730826920e0, 0.3281453857685808451825081e0, 0.2591493642052661979197670e0, 0.1901879854885491785792565e0, 0.1213179541186130699071317e0, 0.5285224511635143601147552e-1}, + {0.1504661202517196460191540e1, 0.1438526110541037227495230e1, 0.1372391084315255737540026e1, 0.1306256159670931796771616e1, 0.1240121376243315949825014e1, 0.1173986779205849344923421e1, 0.1107852421486856229076325e1, 0.1041718366715156747157745e1, 0.9755846932657442605621389e0, 0.9094514999854931965227238e0, 0.8433189145364798253029042e0, 0.7771871059265138564989363e0, 0.7110563039566125173946002e0, 0.6449268305419475123120585e0, 0.5787991523675322133651034e0, 0.5126739740395088296453592e0, 0.4465524134105889084933393e0, 0.3804363581140941600870992e0, 0.3143292666717729726674543e0, 0.2482382273986418438740754e0, 0.1821803739336923550363257e0, 0.1162100228791666307841708e0, 0.5062697144246344520692308e-1}, + {0.1507333049739684406957329e1, 0.1443869798951040686809862e1, 0.1380406601553595646811530e1, 0.1316943486448336467960940e1, 0.1253480485358734060913055e1, 0.1190017634088428795118215e1, 0.1126554974102287077081806e1, 0.1063092554588577221978254e1, 0.9996304352342330000643921e0, 0.9361686900661624628632729e0, 0.8727074129127595264965883e0, 0.8092467253835331800652228e0, 0.7457867888716805068068402e0, 0.6823278231980088937854296e0, 0.6188701366516795329577182e0, 0.5554141765061554178407906e0, 0.4919606183965743300387332e0, 0.4285105345527885639657014e0, 0.3650657359209552112046854e0, 0.3016295408979540017854803e0, 0.2382087510453128743250072e0, 0.1748198074104535338147956e0, 0.1115148317291502081079519e0, 0.4858150828905663931389750e-1}, + {0.1509797405521643600800862e1, 0.1448798505784201776188819e1, 0.1387799649767640868379247e1, 0.1326800860997572277878513e1, 0.1265802165120213614545418e1, 0.1204803590828283748583827e1, 0.1143805171007496028164312e1, 0.1082806944206958485218487e1, 0.1021808956582037259849130e1, 0.9608112645303606832220554e0, 0.8998139383584991342974664e0, 0.8388170675106567024157190e0, 0.7778207682214244793380700e0, 0.7168251950382156442798800e0, 0.6558305587295081487906238e0, 0.5948371551492265376377962e0, 0.5338454137827292925154468e0, 0.4728559836463229599006206e0, 0.4118698949811841042358258e0, 0.3508888880839026413717319e0, 0.2899161521835467942607342e0, 0.2289582244272697168835150e0, 0.1680309071251709912058722e0, 0.1071842976730454709494914e0, 0.4669490825917857848258897e-1}, + {0.1512077535592702651885542e1, 0.1453358762182399391553360e1, 0.1394640024852448295479492e1, 0.1335921342914185177270306e1, 0.1277202737290683500323248e1, 0.1218484231207691826029908e1, 0.1159765851037557179133987e1, 0.1101047627365156083369632e1, 0.1042329596373083545617043e1, 0.9836118016874520301049009e0, 0.9248942968954766185908511e0, 0.8661771490588063053774554e0, 0.8074604437333368789787031e0, 0.7487442923247565105494255e0, 0.6900288431709550365296138e0, 0.6313142987730108226833704e0, 0.5726009435739572428629866e0, 0.5138891906843943809444838e0, 0.4551796645660731149033106e0, 0.3964733566771858874923011e0, 0.3377719420068963817561906e0, 0.2790784903284342592940125e0, 0.2203992941938221111139898e0, 0.1617495649772923108686624e0, 0.1031775271253784724197264e0, 0.4494935602951385601335598e-1}, + {0.1514193352804819997509006e1, 0.1457590393617468793209691e1, 0.1400987464419153080392546e1, 0.1344384581184662080889348e1, 0.1287781761126833878758488e1, 0.1231179023218584237510462e1, 0.1174576388822640925688125e1, 0.1117973882475943676285829e1, 0.1061371532893653466992815e1, 0.1004769374285310770780417e1, 0.9481674481184788854172919e0, 0.8915658055327279211293483e0, 0.8349645107156934027761499e0, 0.7783636457331086848148917e0, 0.7217633176118399859733190e0, 0.6651636690166557413471029e0, 0.6085648948549621671933311e0, 0.5519672690500084950513985e0, 0.4953711895788266953367288e0, 0.4387772581729219934583483e0, 0.3821864303519236078766179e0, 0.3256003205491779498477363e0, 0.2690218877324958059454348e0, 0.2124571975249336244841297e0, 0.1559209129891515317090843e0, 0.9945952063842375053227931e-1, 0.4332960406341033436157524e-1}, + {0.1516162000094549207021851e1, 0.1461527685790782385188426e1, 0.1406893396579229558427657e1, 0.1352259145769086826235918e1, 0.1297624947629923059740243e1, 0.1242990817790597917328601e1, 0.1188356773715062198539162e1, 0.1133722835287525783953663e1, 0.1079089025551156002698850e1, 0.1024455371662101389801169e1, 0.9698219061474760364582928e0, 0.9151886685974009713577537e0, 0.8605557079864861100238346e0, 0.8059230859253162466918892e0, 0.7512908813164713594661588e0, 0.6966591971861112012613682e0, 0.6420281709850565965229799e0, 0.5873979906122764301937499e0, 0.5327689202536826556885353e0, 0.4781413438508069051295597e0, 0.4235158420269503798571552e0, 0.3688933369002844229314675e0, 0.3142753865947702189467806e0, 0.2596648470121556361200229e0, 0.2050675726616484232653526e0, 0.1504977164639767777858359e0, 0.9600014792058154736462106e-1, 0.4182252607645932321862773e-1}, + {0.1517998315905975681819213e1, 0.1465200315462026532129551e1, 0.1412402336143180968579639e1, 0.1359604389111228213837104e1, 0.1306806486279734731351497e1, 0.1254008640622089183072742e1, 0.1201210866535131048800458e1, 0.1148413180281179970113571e1, 0.1095615600538999408768381e1, 0.1042818149105710558651372e1, 0.9900208518088600875617620e0, 0.9372237397138955502862203e0, 0.8844268507524555199840381e0, 0.8316302319600398731649744e0, 0.7788339426133210890795576e0, 0.7260380587255163256281298e0, 0.6732426796448045921910045e0, 0.6204479380061240544867289e0, 0.5676540152134466427854705e0, 0.5148611664077887834613451e0, 0.4620697624728053757183766e0, 0.4092803643735033357684553e0, 0.3564938631002461237979451e0, 0.3037117642790043703921396e0, 0.2509368276982060978106092e0, 0.1981747109679032915697317e0, 0.1454390911823840643137232e0, 0.9277332955453467429763451e-1, 0.4041676055113025684436480e-1}, + {0.1519715208823086817411929e1, 0.1468634099702062550682430e1, 0.1417553008469014674939490e1, 0.1366471944542347269659860e1, 0.1315390917933946912760115e1, 0.1264309939489363760018555e1, 0.1213229021168654147755139e1, 0.1162148176384137345494752e1, 0.1111067420416500738111992e1, 0.1059986770938296676746064e1, 0.1008906248685091746434581e1, 0.9578258783312407255956784e0, 0.9067456896525242756445150e0, 0.8556657190967860708153477e0, 0.8045860119448479090873824e0, 0.7535066253423996943740445e0, 0.7024276326462752642452137e0, 0.6513491298057893513225544e0, 0.6002712449887427739045163e0, 0.5491941535583390603837715e0, 0.4981181022276018128369963e0, 0.4470434496975185070560821e0, 0.3959707385770101868486847e0, 0.3449008307748737032772825e0, 0.2938351828535981363494671e0, 0.2427764647581323719392653e0, 0.1917301500230701193408602e0, 0.1407094708800750523796875e0, 0.8975637836633630394302762e-1, 0.3910242380354419363081899e-1}, + {0.1521323961422700444944464e1, 0.1471851603590422118622546e1, 0.1422379260986849454727777e1, 0.1372906941604798453293218e1, 0.1323434653909307929892118e1, 0.1273962407026590487708892e1, 0.1224490210963055761921526e1, 0.1175018076866133593082748e1, 0.1125546017342156230227131e1, 0.1076074046851682267877939e1, 0.1026602182210094558879809e1, 0.9771304432322302018639612e0, 0.9276588535760335871906045e0, 0.8781874418647315968408864e0, 0.8287162432047307488040550e0, 0.7792453012756761070555010e0, 0.7297746712644485550469075e0, 0.6803044240724808212528033e0, 0.6308346524943159683026367e0, 0.5813654805388740483542438e0, 0.5318970779332963132260134e0, 0.4824296835154055410257004e0, 0.4329636445908698102350729e0, 0.3834994865870752458854056e0, 0.3340380441799942088370002e0, 0.2845807279748544733570760e0, 0.2351301237470960623526672e0, 0.1856915325646991222655151e0, 0.1362777698319134965765757e0, 0.8692946525012054120187353e-1, 0.3787087726949234365520114e-1}, + {0.1522834478472358672931947e1, 0.1474872636605138418026177e1, 0.1426910807768284322082436e1, 0.1378948998781055367310047e1, 0.1330987216841224680164684e1, 0.1283025469674968454386883e1, 0.1235063765709222885799986e1, 0.1187102114275073728898860e1, 0.1139140525853183114841234e1, 0.1091179012375759666645271e1, 0.1043217587604604879578741e1, 0.9952562676120370548458597e0, 0.9472950714021223337048082e0, 0.8993340217254078241758816e0, 0.8513731461641338285808219e0, 0.8034124786014693431693904e0, 0.7554520612457602368887930e0, 0.7074919474732165281510693e0, 0.6595322059052657580628641e0, 0.6115729263971504325174172e0, 0.5636142290734363894767612e0, 0.5156562783879918167717991e0, 0.4676993058012953469089537e0, 0.4197436479350834076514896e0, 0.3717898140987174444032373e0, 0.3238386134116156886828960e0, 0.2758914133405791810724762e0, 0.2279507206431424610498769e0, 0.1800216744637006612298520e0, 0.1321166988439841543825694e0, 0.8427518284958235696897899e-1, 0.3671453742186897322954009e-1}, + {0.1524255491013576804195881e1, 0.1477714660784952783237945e1, 0.1431173841758652772349485e1, 0.1384633039781787069436630e1, 0.1338092261006965672253841e1, 0.1291551512012124788593875e1, 0.1245010799937299944123195e1, 0.1198470132644670409416924e1, 0.1151929518909907204916554e1, 0.1105388968655282680015213e1, 0.1058848493238442193822372e1, 0.1012308105815651361079674e1, 0.9657678218054126734684090e0, 0.9192276594886802366068293e0, 0.8726876407972167893294764e0, 0.8261477923647281669131478e0, 0.7796081469509049827753598e0, 0.7330687454042532567721262e0, 0.6865296394193009886613469e0, 0.6399908954920466591029822e0, 0.5934526007301573325059582e0, 0.5469148716199143611697357e0, 0.5003778676688561814362271e0, 0.4538418134105091550464446e0, 0.4073070354279485829740435e0, 0.3607740278788822846227453e0, 0.3142435758510728338330843e0, 0.2677170062389944640113953e0, 0.2211967514739567668334169e0, 0.1746877983807874325844051e0, 0.1282022028383479964348629e0, 0.8177818680168764430245080e-1, 0.3562671947817428176226631e-1}, + {0.1525594725214770881206476e1, 0.1480393128432045740356817e1, 0.1435191541323085582529217e1, 0.1389989968924959812091252e1, 0.1344788416522907866060817e1, 0.1299586889746827997174554e1, 0.1254385394680661996389736e1, 0.1209183937989395175829969e1, 0.1163982527069600127515982e1, 0.1118781170231154762473596e1, 0.1073579876920155012130433e1, 0.1028378657996412636748477e1, 0.9831775260837211038023103e0, 0.9379764960179657076015136e0, 0.8927755854282048597997986e0, 0.8475748155007347757967789e0, 0.8023742119985848209905761e0, 0.7571738066433708695662393e0, 0.7119736390205872251796930e0, 0.6667737592565460745639184e0, 0.6215742318591892056934095e0, 0.5763751413603713322640298e0, 0.5311766008298875656047892e0, 0.4859787651249621588538330e0, 0.4407818522612533891543536e0, 0.3955861793705505114602136e0, 0.3503922263398633798966312e0, 0.3052007556167344348049303e0, 0.2600130558662051177480644e0, 0.2148314894784555841956251e0, 0.1696608997322034095150907e0, 0.1245129955389270002683579e0, 0.7942489891978153749097006e-1, 0.3460150809198016850782325e-1}, + {0.1526859042890589526378487e1, 0.1482921763148403842276533e1, 0.1438984491795164536567108e1, 0.1395047233189252525231459e1, 0.1351109991891878034957302e1, 0.1307172772745304669260382e1, 0.1263235580960968906699379e1, 0.1219298422221050703835127e1, 0.1175361302797916700875697e1, 0.1131424229697065895207730e1, 0.1087487210830887883186060e1, 0.1043550255232887174273672e1, 0.9996133733253190253881393e0, 0.9556765772578535710715874e0, 0.9117398813415957196221754e0, 0.8678033026125661948850687e0, 0.8238668615732247310812836e0, 0.7799305831824293601507400e0, 0.7359944981977457886183921e0, 0.6920586450266629333858465e0, 0.6481230723279649663476697e0, 0.6041878427445000852182582e0, 0.5602530383870993537615272e0, 0.5163187691099712879003757e0, 0.4723851853891499571797438e0, 0.4284524990953311047063058e0, 0.3845210184454249891341793e0, 0.3405912098612419399584605e0, 0.2966638144233703899038032e0, 0.2527400847124078576715667e0, 0.2088223170017057788708674e0, 0.1649152190599722827308055e0, 0.1210301722471160155498167e0, 0.7720326018898817828206987e-1, 0.3363364974516995102167462e-1}, + {0.1528054559083405137047563e1, 0.1485312794997097705446883e1, 0.1442571038214470776579613e1, 0.1399829292522320013570493e1, 0.1357087561874166765548658e1, 0.1314345850454078759228779e1, 0.1271604162748143389685638e1, 0.1228862503626296926524085e1, 0.1186120878437839368895715e1, 0.1143379293124832099340074e1, 0.1100637754358770795248912e1, 0.1057896269707576280860569e1, 0.1015154847842238156769126e1, 0.9724134987956584339974640e0, 0.9296722342907946818431047e0, 0.8869310681617368097575324e0, 0.8441900169008687429295884e0, 0.8014491003793523040286325e0, 0.7587083428093935362576859e0, 0.7159677740493625646700975e0, 0.6732274314040501413860867e0, 0.6304873621547357085895928e0, 0.5877476271899241333221832e0, 0.5450083063396327078463020e0, 0.5022695064252395155059223e0, 0.4595313737871711838065652e0, 0.4167941144922007176438387e0, 0.3740580283336802289311736e0, 0.3313235690067746553700419e0, 0.2885914573933480330041531e0, 0.2458629119584249278750153e0, 0.2031401664615301668533461e0, 0.1604278005405711652039491e0, 0.1177368858339244458607172e0, 0.7510252408650086658441596e-1, 0.3271846270775478856070884e-1}, + {0.1529186740959505109653289e1, 0.1487577158293388707508111e1, 0.1445967582009979387718202e1, 0.1404358015412336440816745e1, 0.1362748461941311565399969e1, 0.1321138925227929972823825e1, 0.1279529409151733277951100e1, 0.1237919917907156982173977e1, 0.1196310456080472987418488e1, 0.1154701028740456700905269e1, 0.1113091641546798022997704e1, 0.1071482300881451340842721e1, 0.1029873014009735917989475e1, 0.9882637892802373569245916e0, 0.9466546363756944528310758e0, 0.9050455666314926033869497e0, 0.8634365934447506520344540e0, 0.8218277328062565148449433e0, 0.7802190040012226850703573e0, 0.7386104305454957746359112e0, 0.6970020414556031913861513e0, 0.6553938730008771105113861e0, 0.6137859711661063914322283e0, 0.5721783951857430999179669e0, 0.5305712227365694155165922e0, 0.4889645577740232855661796e0, 0.4473585427277744403333139e0, 0.4057533781735039172217875e0, 0.3641493559322687127223795e0, 0.3225469176515179389138545e0, 0.2809467650889194227770571e0, 0.2393500844055270891104500e0, 0.1977590501629603151642330e0, 0.1561781206604067112364815e0, 0.1146180742271483316267615e0, 0.7311308274978660184520447e-1, 0.3185176130791400787169333e-1}, + {0.1530260491394766313570510e1, 0.1489724658775115137266557e1, 0.1449188831753177403184250e1, 0.1408653013220734918131897e1, 0.1368117206184034069757975e1, 0.1327581413807020172726043e1, 0.1287045639459248683416470e1, 0.1246509886770075360771330e1, 0.1205974159691064843702080e1, 0.1165438462569017837684371e1, 0.1124902800232641860108690e1, 0.1084367178096737546333982e1, 0.1043831602288925654461738e1, 0.1003296079805520648394589e1, 0.9627606187053432591598275e0, 0.9222252283533212928777294e0, 0.8816899197300536544215117e0, 0.8411547058297167490229198e0, 0.8006196021777239861105672e0, 0.7600846275129127849719743e0, 0.7195498046991648764002008e0, 0.6790151619622966197448464e0, 0.6384807345966275863946969e0, 0.5979465673637771458800754e0, 0.5574127179353942966481713e0, 0.5168792619515766918187819e0, 0.4763463006547495614450433e0, 0.4358139727703203523144583e0, 0.3952824736706231680817472e0, 0.3547520876199503791717895e0, 0.3142232448436673832093046e0, 0.2736966289659020439688229e0, 0.2331733955144496369946707e0, 0.1926556629116315949109922e0, 0.1521477743835989472840536e0, 0.1116602300918232453371161e0, 0.7122632005925390425640031e-1, 0.3102979192734513847869512e-1}, + {0.1531280219945530918862887e1, 0.1491764115543711582608611e1, 0.1452248016067723206269747e1, 0.1412731924058150689920340e1, 0.1373215842151127100608219e1, 0.1333699773114208203180680e1, 0.1294183719885939986844436e1, 0.1254667685620366764206205e1, 0.1215151673737978313041594e1, 0.1175635687984935008823566e1, 0.1136119732502868295328130e1, 0.1096603811912170337964094e1, 0.1057087931412518476253055e1, 0.1017572096905509113863513e1, 0.9780563151458206514020694e0, 0.9385405939294598498464432e0, 0.8990249423306286659734381e0, 0.8595093710029676968794279e0, 0.8199938925669823205931282e0, 0.7804785221142635001130339e0, 0.7409632778721439753645470e0, 0.7014481820920565808095373e0, 0.6619332622550151160558599e0, 0.6224185527349885679868616e0, 0.5829040971371158016902326e0, 0.5433899516536147244946347e0, 0.5038761899947552937603140e0, 0.4643629108305196256509391e0, 0.4248502493722176391609139e0, 0.3853383960541810555628366e0, 0.3458276279674767760058527e0, 0.3063183644932167228808922e0, 0.2668112720373341483108662e0, 0.2273074770384765519559169e0, 0.1878090446069578429818381e0, 0.1483202086882449059764783e0, 0.1088512052741322662621244e0, 0.6943448689600673838300180e-1, 0.3024917865720923179577363e-1}, + {0.1532249903371281818085917e1, 0.1493703482108998740614827e1, 0.1455157065195200346809599e1, 0.1416610654869340270223431e1, 0.1378064253450997606022340e1, 0.1339517863369794055919890e1, 0.1300971487198245305453001e1, 0.1262425127688525048786896e1, 0.1223878787814308166546501e1, 0.1185332470819113339105535e1, 0.1146786180272904774996439e1, 0.1108239920139165765487189e1, 0.1069693694855262920629379e1, 0.1031147509429735196850587e1, 0.9926013695612463310882198e0, 0.9540552817854489715123326e0, 0.9155092536580933534978986e0, 0.8769632939856246206308699e0, 0.8384174131186299393233148e0, 0.7998716233293992826192237e0, 0.7613259393034545837300323e0, 0.7227803787876118667749166e0, 0.6842349634562860931661901e0, 0.6456897200871628101751519e0, 0.6071446821835496233813653e0, 0.5685998922550279415939221e0, 0.5300554050908430047380815e0, 0.4915112925697217767572364e0, 0.4529676509187802579380104e0, 0.4144246120108054286121629e0, 0.3758823615873930314093573e0, 0.3373411699211847213003570e0, 0.2988014460838619282843952e0, 0.2602638401106843145315994e0, 0.2217294507811754336425535e0, 0.1832002925124018168986342e0, 0.1446804953347050655563166e0, 0.1061800440374660771048480e0, 0.6773059476567831336488402e-1, 0.2950687695527422224851832e-1}, + {0.1533173137460634461235066e1, 0.1495549950040734249895393e1, 0.1457926766471340970762709e1, 0.1420303588732694442267846e1, 0.1382680418872520759663065e1, 0.1345057259031099988676433e1, 0.1307434111468678960501903e1, 0.1269810978596001635506341e1, 0.1232187863008871596257323e1, 0.1194564767527851916244615e1, 0.1156941695244461089553108e1, 0.1119318649575559636172662e1, 0.1081695634328067979412755e1, 0.1044072653776750930510111e1, 0.1006449712758602402124214e1, 0.9688268167884441336521039e0, 0.9312039722018274751677424e0, 0.8935811863333633591901354e0, 0.8559584677414483220357356e0, 0.8183358264943738874932307e0, 0.7807132745385688213392421e0, 0.7430908261781095392995681e0, 0.7054684987070400358784448e0, 0.6678463132547297820965882e0, 0.6302242959332082940279826e0, 0.5926024794204980683238426e0, 0.5549809051864955237054951e0, 0.5173596266878257139037738e0, 0.4797387140623364241772428e0, 0.4421182612140318859822955e0, 0.4044983968396638104610711e0, 0.3668793022152994411560368e0, 0.3292612411240570212440856e0, 0.2916446128242035199998930e0, 0.2540300517665934607689814e0, 0.2164186303985620085027010e0, 0.1788123148742007754778852e0, 0.1412151362884411752920148e0, 0.1036368402634645114775150e0, 0.6610832470916409695729856e-1, 0.2880013396280840229218334e-1}, + {0.1534053181584449084854269e1, 0.1497310038074501005766978e1, 0.1460566897984002644464183e1, 0.1423823763069232867789940e1, 0.1387080635143547965139117e1, 0.1350337516098480646600889e1, 0.1313594407926723776707731e1, 0.1276851312747612578778902e1, 0.1240108232835827171448969e1, 0.1203365170654181674634873e1, 0.1166622128891556900019450e1, 0.1129879110507284864268762e1, 0.1093136118783624474731954e1, 0.1056393157388405786003046e1, 0.1019650230450503114577901e1, 0.9829073426515786199715451e0, 0.9461644993385942743541994e0, 0.9094217066630320811486021e0, 0.8726789717547518480094350e0, 0.8359363029411928866147184e0, 0.7991937100265521402467844e0, 0.7624512046511992388808212e0, 0.7257088007597790982554974e0, 0.6889665152185689899094400e0, 0.6522243686409073299342467e0, 0.6154823865075504175164916e0, 0.5787406007128420496638175e0, 0.5419990517384125648087865e0, 0.5052577917731960988645056e0, 0.4685168892980173635234519e0, 0.4317764360047099160222576e0, 0.3950365575646972937604113e0, 0.3582974309994310205507555e0, 0.3215593139080007759227897e0, 0.2848225961961619069649047e0, 0.2480878974611689122432227e0, 0.2113562650517154915467591e0, 0.1746296191183898065201571e0, 0.1379118964507339113271975e0, 0.1012126146941469342401701e0, 0.6456194899726137278760257e-1, 0.2812645439079299219187419e-1}, + {0.1534892997139557227614279e1, 0.1498989668998897501276994e1, 0.1463086343903285773505644e1, 0.1427183023414814244376429e1, 0.1391279709144040438287602e1, 0.1355376402767821814937864e1, 0.1319473106048673173924451e1, 0.1283569820856137399848247e1, 0.1247666549190742942502495e1, 0.1211763293211231530413995e1, 0.1175860055265884319525693e1, 0.1139956837928964066704190e1, 0.1104053644043538840797350e1, 0.1068150476772278342447444e1, 0.1032247339658243608912598e1, 0.9963442366982618328585493e0, 0.9604411724322426430586723e0, 0.9245381520528253319358567e0, 0.8886351815411563067305273e0, 0.8527322678365406966379400e0, 0.8168294190504262166761188e0, 0.7809266447390142664026016e0, 0.7450239562542930157586944e0, 0.7091213672012904985883029e0, 0.6732188940411854039055226e0, 0.6373165568977466866717861e0, 0.6014143806519714388063208e0, 0.5655123964528129857845238e0, 0.5296106438411039715966193e0, 0.4937091737981756577948229e0, 0.4578080532255782153525438e0, 0.4219073717059785387344039e0, 0.3860072520255396095683859e0, 0.3501078671472635990145335e0, 0.3142094687704932495909488e0, 0.2783124378775218384923333e0, 0.2424173798924625361874772e0, 0.2065253182141071551836492e0, 0.1706381290938671641708352e0, 0.1347596593282315198612592e0, 0.9889920900871122533586553e-1, 0.6308626356388784057588631e-1, 0.2748357108440508277394892e-1}, + {0.1535695280838629983064694e1, 0.1500594236235067817656313e1, 0.1465493194350303789230585e1, 0.1430392156577492526495371e1, 0.1395291124351096810858349e1, 0.1360190099162024176252063e1, 0.1325089082574000089379322e1, 0.1289988076241572027256558e1, 0.1254887081930202663795858e1, 0.1219786101538994920367859e1, 0.1184685137126702182946916e1, 0.1149584190941820846004092e1, 0.1114483265457749469332035e1, 0.1079382363414242848588494e1, 0.1044281487866708939888712e1, 0.1009180642245317812316634e1, 0.9740798304264509422659935e0, 0.9389790568197674899837757e0, 0.9038783264751749171405213e0, 0.8687776452153701566068907e0, 0.8336770198015192229270720e0, 0.7985764581422970742698971e0, 0.7634759695602610192254430e0, 0.7283755651349081311799055e0, 0.6932752581495918103871962e0, 0.6581750646810479477537782e0, 0.6230750043877162525265513e0, 0.5879751015798285374141491e0, 0.5528753866962970290878822e0, 0.5177758983811020490994086e0, 0.4826766864637186565865902e0, 0.4475778163386701445336738e0, 0.4124793755752883735361361e0, 0.3773814842049053432591527e0, 0.3422843113148581639684411e0, 0.3071881029697497767338606e0, 0.2720932316284942932084102e0, 0.2370002891767127567222407e0, 0.2019102761348421810146637e0, 0.1668250268181992892198073e0, 0.1317483020532982541977987e0, 0.9668919410176593344830717e-1, 0.6167652949817792358742135e-1, 0.2686941953400762687915995e-1}, + {0.1536462493634653558154673e1, 0.1502128661685489464262068e1, 0.1467794832169950298839286e1, 0.1433461006333747476463744e1, 0.1399127185457927306909792e1, 0.1364793370871767472755746e1, 0.1330459563966682507229700e1, 0.1296125766211456950047804e1, 0.1261791979169174443914592e1, 0.1227458204516276373551266e1, 0.1193124444064268679881601e1, 0.1158790699784705540565424e1, 0.1124456973838220917338613e1, 0.1090123268608563332983681e1, 0.1055789586742829027889885e1, 0.1021455931199402224481903e1, 0.9871223053055240306873772e0, 0.9527887128269590857605072e0, 0.9184551580529615732874848e0, 0.8841216459007313197085517e0, 0.8497881820448998068986446e0, 0.8154547730794463756650640e0, 0.7811214267220410983907210e0, 0.7467881520744805288579630e0, 0.7124549599581423848996086e0, 0.6781218633510390484774053e0, 0.6437888779643722276961833e0, 0.6094560230135452763170614e0, 0.5751233222647905281576305e0, 0.5407908054797110156395425e0, 0.5064585104462232763044121e0, 0.4721264858937837018545325e0, 0.4377947957771643018072936e0, 0.4034635257416918872885646e0, 0.3691327931855416440777167e0, 0.3348027634909946151567752e0, 0.3004736773353657517478163e0, 0.2661458990278703974149616e0, 0.2318200075085118064771005e0, 0.1974969814205034596217949e0, 0.1631786149772797106698111e0, 0.1288685867945150272796250e0, 0.9457579039019365184018477e-1, 0.6032842220945916819748797e-1, 0.2628211572883546008386342e-1}, + {0.1537196885933572311910085e1, 0.1503597446159129663218426e1, 0.1469998008568304160871417e1, 0.1436398574277729377094190e1, 0.1402799144434368418084898e1, 0.1369199720226542342210552e1, 0.1335600302895785666466344e1, 0.1302000893749787833197270e1, 0.1268401494176718217187838e1, 0.1234802105661283063077015e1, 0.1201202729802928570677208e1, 0.1167603368336689119731474e1, 0.1134004023157288628212183e1, 0.1100404696347243386055709e1, 0.1066805390209896030700280e1, 0.1033206107308545748870827e1, 0.9996068505131472996246808e0, 0.9660076230564559666956844e0, 0.9324084286020318648375284e0, 0.8988092713272342656758064e0, 0.8652101560253048754543914e0, 0.8316110882319595313175680e0, 0.7980120743837286767240920e0, 0.7644131220178278512956878e0, 0.7308142400269308414762795e0, 0.6972154389873656296775555e0, 0.6636167315867435235683334e0, 0.6300181331881122315700717e0, 0.5964196625844131090385918e0, 0.5628213430226633060114218e0, 0.5292232036175455988770345e0, 0.4956252813388603291268380e0, 0.4620276238643496856689332e0, 0.4284302937718012609061760e0, 0.3948333748659561479104270e0, 0.3612369820255324850503899e0, 0.3276412770872600895283016e0, 0.2940464955725917238672137e0, 0.2604529939906062681054034e0, 0.2268613388903867245835696e0, 0.1932724879746856807613294e0, 0.1596881970714452359218090e0, 0.1261120661032951679792394e0, 0.9255279834764232165670211e-1, 0.5903798711627596210077655e-1, 0.2571993685288741305807485e-1}, + {0.1537900519639177351485509e1, 0.1505004713461118831562885e1, 0.1472108909246876714959093e1, 0.1439213107999753788389740e1, 0.1406317310749171844429399e1, 0.1373421518560135827011261e1, 0.1340525732543378926238078e1, 0.1307629953866399941713193e1, 0.1274734183765634621652739e1, 0.1241838423560042429086765e1, 0.1208942674666441461574345e1, 0.1176046938616989970936899e1, 0.1143151217079296988032361e1, 0.1110255511879752164142939e1, 0.1077359825030803093319347e1, 0.1044464158763086533573607e1, 0.1011568515563550961534623e1, 0.9786728982210094134846821e0, 0.9457773098809579873452675e0, 0.9128817541120207886160886e0, 0.8799862349870845994262022e0, 0.8470907571831347751008168e0, 0.8141953261050969543263697e0, 0.7812999480407721032432037e0, 0.7484046303564402266425896e0, 0.7155093817462244075628281e0, 0.6826142125533466396520346e0, 0.6497191351887403950357432e0, 0.6168241646833332909207560e0, 0.5839293194266532352434130e0, 0.5510346221695150324949297e0, 0.5181401014079633610544426e0, 0.4852457933290632607369490e0, 0.4523517446039431388003505e0, 0.4194580164920722423612656e0, 0.3865646910356375140534892e0, 0.3536718807003189971969294e0, 0.3207797439266498255416416e0, 0.2878885112969848452450724e0, 0.2549985318477515756044100e0, 0.2221103602568508117102717e0, 0.1892249341643785313168465e0, 0.1563439726212394862316010e0, 0.1234710001537068179882843e0, 0.9061453776736619019094845e-1, 0.5780160090309369034797044e-1, 0.2518130440638251656980999e-1}, + {0.1538575287485045780713568e1, 0.1506354249056545799167351e1, 0.1474133212398093554231315e1, 0.1441912178413208451704314e1, 0.1409691148027973881079186e1, 0.1377470122199186272616473e1, 0.1345249101923067139210221e1, 0.1313028088244711409410919e1, 0.1280807082268469343020428e1, 0.1248586085169490583375238e1, 0.1216365098206699074213627e1, 0.1184144122737518830558069e1, 0.1151923160234735793613503e1, 0.1119702212305964062886069e1, 0.1087481280716290811591462e1, 0.1055260367414810028339009e1, 0.1023039474565930165787482e1, 0.9908186045865674272211987e0, 0.9585977601906320722299056e0, 0.9263769444426036830464570e0, 0.8941561608225061952846411e0, 0.8619354133052817812042663e0, 0.8297147064584916186566054e0, 0.7974940455635382827549679e0, 0.7652734367673509855003551e0, 0.7330528872739117793257283e0, 0.7008324055884451343305450e0, 0.6686120018320298047193041e0, 0.6363916881515750209117372e0, 0.6041714792607289968809847e0, 0.5719513931632926368357825e0, 0.5397314521353000325496229e0, 0.5075116840805377280486923e0, 0.4752921244363891783961832e0, 0.4430728189095547215892704e0, 0.4108538274961112658763390e0, 0.3786352305487998074788803e0, 0.3464171382200184643128623e0, 0.3141997056941599156198233e0, 0.2819831588178046655599196e0, 0.2497678394619649260592757e0, 0.2175542909210219972765731e0, 0.1853434315961135904158300e0, 0.1531369452704970394027659e0, 0.1209382841678252589048669e0, 0.8875579450016283173293810e-1, 0.5661593754525190873771522e-1, 0.2466476940450737058975552e-1}, + {0.1539222930035210331902410e1, 0.1507649534071729882214386e1, 0.1476076139707032453353232e1, 0.1444502747756546556830706e1, 0.1412929359055252480197337e1, 0.1381355974464721552102928e1, 0.1349782594880622732927647e1, 0.1318209221240839295255046e1, 0.1286635854534357387243172e1, 0.1255062495811112994872428e1, 0.1223489146193015470717893e1, 0.1191915806886406014313715e1, 0.1160342479196260434661502e1, 0.1128769164542510055952304e1, 0.1097195864478936528824546e1, 0.1065622580715200621234508e1, 0.1034049315142698534418744e1, 0.1002476069865111021377467e1, 0.9709028472347329448081481e0, 0.9393296498959608456620406e0, 0.9077564808376970380335442e0, 0.8761833434569334264096395e0, 0.8446102416364528348063321e0, 0.8130371798404960344077378e0, 0.7814641632334840064334645e0, 0.7498911978285964532098456e0, 0.7183182906753955596314298e0, 0.6867454500990591398232408e0, 0.6551726860086246453663390e0, 0.6236000102986843027011345e0, 0.5920274373793840619034224e0, 0.5604549848852622707385612e0, 0.5288826746375584896948472e0, 0.4973105339724571989307663e0, 0.4657385976085971045914307e0, 0.4341669103277770901346174e0, 0.4025955309141879357899857e0, 0.3710245380997234377015025e0, 0.3394540398171456073906403e0, 0.3078841881262277508367562e0, 0.2763152043287541015913350e0, 0.2447474234189502677044064e0, 0.2131813777658572006989977e0, 0.1816179673056091210434906e0, 0.1500588419721174291665790e0, 0.1185073845935281602210493e0, 0.8697177361567243680812898e-1, 0.5547793843128156580348541e-1, 0.2416899936118312040170588e-1}, +} + +// The weights of these nodes +var evenWeights = [][]float64{ + {1.0}, + {0.6521451548625461426269364e0, 0.3478548451374538573730642e0}, + {0.4679139345726910473898704e0, 0.3607615730481386075698336e0, 0.1713244923791703450402969e0}, + {0.3626837833783619829651504e0, 0.3137066458778872873379622e0, 0.2223810344533744705443556e0, 0.1012285362903762591525320e0}, + {0.2955242247147528701738930e0, 0.2692667193099963550912268e0, 0.2190863625159820439955350e0, 0.1494513491505805931457764e0, 0.6667134430868813759356850e-1}, + {0.2491470458134027850005624e0, 0.2334925365383548087608498e0, 0.2031674267230659217490644e0, 0.1600783285433462263346522e0, 0.1069393259953184309602552e0, 0.4717533638651182719461626e-1}, + {0.2152638534631577901958766e0, 0.2051984637212956039659240e0, 0.1855383974779378137417164e0, 0.1572031671581935345696019e0, 0.1215185706879031846894145e0, 0.8015808715976020980563266e-1, 0.3511946033175186303183410e-1}, + {0.1894506104550684962853967e0, 0.1826034150449235888667636e0, 0.1691565193950025381893119e0, 0.1495959888165767320815019e0, 0.1246289712555338720524763e0, 0.9515851168249278480992520e-1, 0.6225352393864789286284360e-1, 0.2715245941175409485178166e-1}, + {0.1691423829631435918406565e0, 0.1642764837458327229860538e0, 0.1546846751262652449254180e0, 0.1406429146706506512047311e0, 0.1225552067114784601845192e0, 0.1009420441062871655628144e0, 0.7642573025488905652912984e-1, 0.4971454889496979645333512e-1, 0.2161601352648331031334248e-1}, + {0.1527533871307258506980843e0, 0.1491729864726037467878288e0, 0.1420961093183820513292985e0, 0.1316886384491766268984948e0, 0.1181945319615184173123774e0, 0.1019301198172404350367504e0, 0.8327674157670474872475850e-1, 0.6267204833410906356950596e-1, 0.4060142980038694133103928e-1, 0.1761400713915211831186249e-1}, + {0.1392518728556319933754102e0, 0.1365414983460151713525738e0, 0.1311735047870623707329649e0, 0.1232523768105124242855609e0, 0.1129322960805392183934005e0, 0.1004141444428809649320786e0, 0.8594160621706772741444398e-1, 0.6979646842452048809496104e-1, 0.5229333515268328594031142e-1, 0.3377490158481415479330258e-1, 0.1462799529827220068498987e-1}, + {0.1279381953467521569740562e0, 0.1258374563468282961213754e0, 0.1216704729278033912044631e0, 0.1155056680537256013533445e0, 0.1074442701159656347825772e0, 0.9761865210411388826988072e-1, 0.8619016153195327591718514e-1, 0.7334648141108030573403386e-1, 0.5929858491543678074636724e-1, 0.4427743881741980616860272e-1, 0.2853138862893366318130802e-1, 0.1234122979998719954680507e-1}, + {0.1183214152792622765163711e0, 0.1166604434852965820446624e0, 0.1133618165463196665494407e0, 0.1084718405285765906565795e0, 0.1020591610944254232384142e0, 0.9421380035591414846366474e-1, 0.8504589431348523921044770e-1, 0.7468414976565974588707538e-1, 0.6327404632957483553945402e-1, 0.5097582529714781199831990e-1, 0.3796238329436276395030342e-1, 0.2441785109263190878961718e-1, 0, .1055137261734300715565387e-1}, + {0.1100470130164751962823763e0, 0.1087111922582941352535716e0, 0.1060557659228464179104165e0, 0.1021129675780607698142166e0, 0.9693065799792991585048880e-1, 0.9057174439303284094218612e-1, 0.8311341722890121839039666e-1, 0.7464621423456877902393178e-1, 0.6527292396699959579339794e-1, 0.5510734567571674543148330e-1, 0.4427293475900422783958756e-1, 0.3290142778230437997763004e-1, 0.2113211259277125975149896e-1, 0.9124282593094517738816778e-2}, + {0.1028526528935588403412856e0, 0.1017623897484055045964290e0, 0.9959342058679526706278018e-1, 0.9636873717464425963946864e-1, 0.9212252223778612871763266e-1, 0.8689978720108297980238752e-1, 0.8075589522942021535469516e-1, 0.7375597473770520626824384e-1, 0.6597422988218049512812820e-1, 0.5749315621761906648172152e-1, 0.4840267283059405290293858e-1, 0.3879919256962704959680230e-1, 0.2878470788332336934971862e-1, 0.1846646831109095914230276e-1, 0.7968192496166605615469690e-2}, + {0.9654008851472780056676488e-1, 0.9563872007927485941908208e-1, 0.9384439908080456563918026e-1, 0.9117387869576388471286854e-1, 0.8765209300440381114277140e-1, 0.8331192422694675522219922e-1, 0.7819389578707030647174106e-1, 0.7234579410884850622539954e-1, 0.6582222277636184683765034e-1, 0.5868409347853554714528360e-1, 0.5099805926237617619616316e-1, 0.4283589802222668065687810e-1, 0.3427386291302143310268716e-1, 0.2539206530926205945575196e-1, 0.1627439473090567060516896e-1, 0.7018610009470096600404748e-2}, + {0.9095674033025987361533764e-1, 0.9020304437064072957394216e-1, 0.8870189783569386928707642e-1, 0.8646573974703574978424688e-1, 0.8351309969984565518702044e-1, 0.7986844433977184473881888e-1, 0.7556197466003193127083398e-1, 0.7062937581425572499903896e-1, 0.6511152155407641137854442e-1, 0.5905413582752449319396124e-1, 0.5250741457267810616824590e-1, 0.4552561152335327245382266e-1, 0.3816659379638751632176606e-1, 0.3049138063844613180944194e-1, 0.2256372198549497008409476e-1, 0.1445016274859503541520101e-1, 0.6229140555908684718603220e-2}, + {0.8598327567039474749008516e-1, 0.8534668573933862749185052e-1, 0.8407821897966193493345756e-1, 0.8218726670433970951722338e-1, 0.7968782891207160190872470e-1, 0.7659841064587067452875784e-1, 0.7294188500565306135387342e-1, 0.6874532383573644261368974e-1, 0.6403979735501548955638454e-1, 0.5886014424532481730967550e-1, 0.5324471397775991909202590e-1, 0.4723508349026597841661708e-1, 0.4087575092364489547411412e-1, 0.3421381077030722992124474e-1, 0.2729862149856877909441690e-1, 0.2018151529773547153209770e-1, 0.1291594728406557440450307e-1, 0.5565719664245045361251818e-2}, + {0.8152502928038578669921876e-1, 0.8098249377059710062326952e-1, 0.7990103324352782158602774e-1, 0.7828784465821094807537540e-1, 0.7615366354844639606599344e-1, 0.7351269258474345714520658e-1, 0.7038250706689895473928292e-1, 0.6678393797914041193504612e-1, 0.6274093339213305405296984e-1, 0.5828039914699720602230556e-1, 0.5343201991033231997375704e-1, 0.4822806186075868337435238e-1, 0.4270315850467443423587832e-1, 0.3689408159402473816493978e-1, 0.3083950054517505465873166e-1, 0.2457973973823237589520214e-1, 0.1815657770961323689887502e-1, 0.1161344471646867417766868e-1, 0.5002880749639345675901886e-2}, + {0.7750594797842481126372404e-1, 0.7703981816424796558830758e-1, 0.7611036190062624237155810e-1, 0.7472316905796826420018930e-1, 0.7288658239580405906051074e-1, 0.7061164739128677969548346e-1, 0.6791204581523390382569024e-1, 0.6480401345660103807455446e-1, 0.6130624249292893916653822e-1, 0.5743976909939155136661768e-1, 0.5322784698393682435499678e-1, 0.4869580763507223206143380e-1, 0.4387090818567327199167442e-1, 0.3878216797447201763997196e-1, 0.3346019528254784739267780e-1, 0.2793700698002340109848970e-1, 0.2224584919416695726150432e-1, 0.1642105838190788871286396e-1, 0.1049828453115281361474434e-1, 0.4521277098533191258471490e-2}, + {0.7386423423217287999638556e-1, 0.7346081345346752826402828e-1, 0.7265617524380410488790570e-1, 0.7145471426517098292181042e-1, 0.6986299249259415976615480e-1, 0.6788970337652194485536350e-1, 0.6554562436490897892700504e-1, 0.6284355804500257640931846e-1, 0.5979826222758665431283142e-1, 0.5642636935801838164642686e-1, 0.5274629569917407034394234e-1, 0.4877814079280324502744954e-1, 0.4454357777196587787431674e-1, 0.4006573518069226176059618e-1, 0.3536907109759211083266214e-1, 0.3047924069960346836290502e-1, 0.2542295952611304788674188e-1, 0.2022786956905264475705664e-1, 0.1492244369735749414467869e-1, 0.9536220301748502411822340e-2, 0.4105998604649084610599928e-2}, + {0.7054915778935406881133824e-1, 0.7019768547355821258714200e-1, 0.6949649186157257803708402e-1, 0.6844907026936666098545864e-1, 0.6706063890629365239570506e-1, 0.6533811487918143498424096e-1, 0.6329007973320385495013890e-1, 0.6092673670156196803855800e-1, 0.5825985987759549533421064e-1, 0.5530273556372805254874660e-1, 0.5207009609170446188123162e-1, 0.4857804644835203752763920e-1, 0.4484398408197003144624282e-1, 0.4088651231034621890844686e-1, 0.3672534781380887364290888e-1, 0.3238122281206982088084682e-1, 0.2787578282128101008111450e-1, 0.2323148190201921062895910e-1, 0.1847148173681474917204335e-1, 0.1361958675557998552020491e-1, 0.8700481367524844122565470e-2, 0.3745404803112777515171456e-2}, + {0.6751868584903645882021418e-1, 0.6721061360067817586237416e-1, 0.6659587476845488737576196e-1, 0.6567727426778120737875756e-1, 0.6445900346713906958827948e-1, 0.6294662106439450817895206e-1, 0.6114702772465048101535670e-1, 0.5906843459554631480755080e-1, 0.5672032584399123581687444e-1, 0.5411341538585675449163752e-1, 0.5125959800714302133536554e-1, 0.4817189510171220053046892e-1, 0.4486439527731812676709458e-1, 0.4135219010967872970421980e-1, 0.3765130535738607132766076e-1, 0.3377862799910689652060416e-1, 0.2975182955220275579905234e-1, 0.2558928639713001063470016e-1, 0.2130999875413650105447862e-1, 0.1693351400783623804623151e-1, 0.1247988377098868420673525e-1, 0.7969898229724622451610710e-2, 0.3430300868107048286016700e-2}, + {0.6473769681268392250302496e-1, 0.6446616443595008220650418e-1, 0.6392423858464818662390622e-1, 0.6311419228625402565712596e-1, 0.6203942315989266390419786e-1, 0.6070443916589388005296916e-1, 0.5911483969839563574647484e-1, 0.5727729210040321570515042e-1, 0.5519950369998416286820356e-1, 0.5289018948519366709550490e-1, 0.5035903555385447495780746e-1, 0.4761665849249047482590674e-1, 0.4467456085669428041944838e-1, 0.4154508294346474921405856e-1, 0.3824135106583070631721688e-1, 0.3477722256477043889254814e-1, 0.3116722783279808890206628e-1, 0.2742650970835694820007336e-1, 0.2357076083932437914051962e-1, 0.1961616045735552781446139e-1, 0.1557931572294384872817736e-1, 0.1147723457923453948959265e-1, 0.7327553901276262102386656e-2, 0.3153346052305838632678320e-2}, + {0.6217661665534726232103316e-1, 0.6193606742068324338408750e-1, 0.6145589959031666375640678e-1, 0.6073797084177021603175000e-1, 0.5978505870426545750957640e-1, 0.5860084981322244583512250e-1, 0.5718992564772838372302946e-1, 0.5555774480621251762356746e-1, 0.5371062188899624652345868e-1, 0.5165570306958113848990528e-1, 0.4940093844946631492124360e-1, 0.4695505130394843296563322e-1, 0.4432750433880327549202254e-1, 0.4152846309014769742241230e-1, 0.3856875661258767524477018e-1, 0.3545983561514615416073452e-1, 0.3221372822357801664816538e-1, 0.2884299358053519802990658e-1, 0.2536067357001239044019428e-1, 0.2178024317012479298159128e-1, 0.1811556071348939035125903e-1, 0.1438082276148557441937880e-1, 0.1059054838365096926356876e-1, 0.6759799195745401502778824e-2, 0.2908622553155140958394976e-2}, + {0.5981036574529186024778538e-1, 0.5959626017124815825831088e-1, 0.5916881546604297036933200e-1, 0.5852956177181386855029062e-1, 0.5768078745252682765393200e-1, 0.5662553090236859719080832e-1, 0.5536756966930265254904124e-1, 0.5391140693275726475083694e-1, 0.5226225538390699303439404e-1, 0.5042601856634237721821144e-1, 0.4840926974407489685396032e-1, 0.4621922837278479350764582e-1, 0.4386373425900040799512978e-1, 0.4135121950056027167904044e-1, 0.3869067831042397898510146e-1, 0.3589163483509723294194276e-1, 0.3296410908971879791501014e-1, 0.2991858114714394664128188e-1, 0.2676595374650401344949324e-1, 0.2351751355398446159032286e-1, 0.2018489150798079220298930e-1, 0.1678002339630073567792252e-1, 0.1331511498234096065660116e-1, 0.9802634579462752061952706e-2, 0.6255523962973276899717754e-2, 0.2691316950047111118946698e-2}, + {0.5761753670714702467237616e-1, 0.5742613705411211485929010e-1, 0.5704397355879459856782852e-1, 0.5647231573062596503104434e-1, 0.5571306256058998768336982e-1, 0.5476873621305798630622270e-1, 0.5364247364755361127210060e-1, 0.5233801619829874466558872e-1, 0.5085969714618814431970910e-1, 0.4921242732452888606879048e-1, 0.4740167880644499105857626e-1, 0.4543346672827671397485208e-1, 0.4331432930959701544192564e-1, 0.4105130613664497422171834e-1, 0.3865191478210251683685736e-1, 0.3612412584038355258288694e-1, 0.3347633646437264571604038e-1, 0.3071734249787067605400450e-1, 0.2785630931059587028700164e-1, 0.2490274146720877305005456e-1, 0.2186645142285308594551102e-1, 0.1875752762146937791200757e-1, 0.1558630303592413170296832e-1, 0.1236332812884764416646861e-1, 0.9099369455509396948032734e-2, 0.5805611015239984878826112e-2, 0.2497481835761585775945054e-2}, + {0.5557974630651439584627342e-1, 0.5540795250324512321779340e-1, 0.5506489590176242579630464e-1, 0.5455163687088942106175058e-1, 0.5386976186571448570895448e-1, 0.5302137852401076396799152e-1, 0.5200910915174139984305222e-1, 0.5083608261779848056012412e-1, 0.4950592468304757891996610e-1, 0.4802274679360025812073550e-1, 0.4639113337300189676219012e-1, 0.4461612765269228321341510e-1, 0.4270321608466708651103858e-1, 0.4065831138474451788012514e-1, 0.3848773425924766248682568e-1, 0.3619819387231518603588452e-1, 0.3379676711561176129542654e-1, 0.3129087674731044786783572e-1, 0.2868826847382274172988602e-1, 0.2599698705839195219181960e-1, 0.2322535156256531693725830e-1, 0.2038192988240257263480560e-1, 0.1747551291140094650495930e-1, 0.1451508927802147180777130e-1, 0.1150982434038338217377419e-1, 0.8469063163307887661628584e-2, 0.5402522246015337761313780e-2, 0.2323855375773215501098716e-2}, + {0.5368111986333484886390600e-1, 0.5352634330405825210061082e-1, 0.5321723644657901410348096e-1, 0.5275469052637083342964580e-1, 0.5214003918366981897126058e-1, 0.5137505461828572547451486e-1, 0.5046194247995312529765992e-1, 0.4940333550896239286651076e-1, 0.4820228594541774840657052e-1, 0.4686225672902634691841818e-1, 0.4538711151481980250398048e-1, 0.4378110353364025103902560e-1, 0.4204886332958212599457020e-1, 0.4019538540986779688807676e-1, 0.3822601384585843322945902e-1, 0.3614642686708727054078062e-1, 0.3396262049341601079772722e-1, 0.3168089125380932732029244e-1, 0.2930781804416049071839382e-1, 0.2685024318198186847590714e-1, 0.2431525272496395254025850e-1, 0.2171015614014623576691612e-1, 0.1904246546189340865578709e-1, 0.1631987423497096505212063e-1, 0.1355023711298881214517933e-1, 0.1074155353287877411685532e-1, 0.7901973849998674754018608e-2, 0.5039981612650243085015810e-2, 0.2167723249627449943047768e-2}, + {0.5190787763122063973286496e-1, 0.5176794317491018754380368e-1, 0.5148845150098093399504444e-1, 0.5107015606985562740454910e-1, 0.5051418453250937459823872e-1, 0.4982203569055018101115930e-1, 0.4899557545575683538947578e-1, 0.4803703181997118096366674e-1, 0.4694898884891220484701330e-1, 0.4573437971611448664719662e-1, 0.4439647879578711332778398e-1, 0.4293889283593564195423128e-1, 0.4136555123558475561316394e-1, 0.3968069545238079947012286e-1, 0.3788886756924344403094056e-1, 0.3599489805108450306657888e-1, 0.3400389272494642283491466e-1, 0.3192121901929632894945890e-1, 0.2975249150078894524083642e-1, 0.2750355674992479163522324e-1, 0.2518047762152124837957096e-1, 0.2278951694399781986378308e-1, 0.2033712072945728677503268e-1, 0.1782990101420772026039605e-1, 0.1527461859678479930672510e-1, 0.1267816647681596013149540e-1, 0.1004755718228798435788578e-1, 0.7389931163345455531517530e-2, 0.4712729926953568640893942e-2, 0.2026811968873758496433874e-2}, + {0.5024800037525628168840300e-1, 0.5012106956904328807480410e-1, 0.4986752859495239424476130e-1, 0.4948801791969929252786578e-1, 0.4898349622051783710485112e-1, 0.4835523796347767283480314e-1, 0.4760483018410123227045008e-1, 0.4673416847841552480220700e-1, 0.4574545221457018077723242e-1, 0.4464117897712441429364478e-1, 0.4342413825804741958006920e-1, 0.4209740441038509664302268e-1, 0.4066432888241744096828524e-1, 0.3912853175196308412331100e-1, 0.3749389258228002998561838e-1, 0.3576454062276814128558760e-1, 0.3394484437941054509111762e-1, 0.3203940058162467810633926e-1, 0.3005302257398987007700934e-1, 0.2799072816331463754123820e-1, 0.2585772695402469802709536e-1, 0.2365940720868279257451652e-1, 0.2140132227766996884117906e-1, 0.1908917665857319873250324e-1, 0.1672881179017731628855027e-1, 0.1432619182380651776740340e-1, 0.1188739011701050194481938e-1, 0.9418579428420387637936636e-2, 0.6926041901830960871704530e-2, 0.4416333456930904813271960e-2, 0.1899205679513690480402948e-2}, + {0.4869095700913972038336538e-1, 0.4857546744150342693479908e-1, 0.4834476223480295716976954e-1, 0.4799938859645830772812614e-1, 0.4754016571483030866228214e-1, 0.4696818281621001732532634e-1, 0.4628479658131441729595326e-1, 0.4549162792741814447977098e-1, 0.4459055816375656306013478e-1, 0.4358372452932345337682780e-1, 0.4247351512365358900733972e-1, 0.4126256324262352861015628e-1, 0.3995374113272034138665686e-1, 0.3855015317861562912896262e-1, 0.3705512854024004604041492e-1, 0.3547221325688238381069330e-1, 0.3380516183714160939156536e-1, 0.3205792835485155358546770e-1, 0.3023465707240247886797386e-1, 0.2833967261425948322751098e-1, 0.2637746971505465867169136e-1, 0.2435270256871087333817770e-1, 0.2227017380838325415929788e-1, 0.2013482315353020937234076e-1, 0.1795171577569734308504602e-1, 0.1572603047602471932196614e-1, 0.1346304789671864259806029e-1, 0.1116813946013112881859029e-1, 0.8846759826363947723030856e-2, 0.6504457968978362856118112e-2, 0.4147033260562467635287472e-2, 0.1783280721696432947292054e-2}, + {0.4722748126299855484563332e-1, 0.4712209828764473218544518e-1, 0.4691156748762082774625404e-1, 0.4659635863958410362582412e-1, 0.4617717509791597547166640e-1, 0.4565495222527305612043888e-1, 0.4503085530544150021519278e-1, 0.4430627694315316190460328e-1, 0.4348283395666747864757528e-1, 0.4256236377005571631890662e-1, 0.4154692031324188131773448e-1, 0.4043876943895497912586836e-1, 0.3924038386682833018781280e-1, 0.3795443766594162094913028e-1, 0.3658380028813909441368980e-1, 0.3513153016547255590064132e-1, 0.3360086788611223267034862e-1, 0.3199522896404688727128174e-1, 0.3031819621886851919364104e-1, 0.2857351178293187118282268e-1, 0.2676506875425000190879332e-1, 0.2489690251475737263773110e-1, 0.2297318173532665591809836e-1, 0.2099819909186462577733052e-1, 0.1897636172277132593486659e-1, 0.1691218147224521718035102e-1, 0.1481026500273396017364296e-1, 0.1267530398126168187644599e-1, 0.1051206598770575465737803e-1, 0.8325388765990901416725080e-2, 0.6120192018447936365568516e-2, 0.3901625641744248259228942e-2, 0.1677653744007238599334225e-2}, + {0.4584938738725097468656398e-1, 0.4575296541606795051900614e-1, 0.4556032425064828598070770e-1, 0.4527186901844377786941174e-1, 0.4488820634542666782635216e-1, 0.4441014308035275590934876e-1, 0.4383868459795605201060492e-1, 0.4317503268464422322584344e-1, 0.4242058301114249930061428e-1, 0.4157692219740291648457550e-1, 0.4064582447595407614088174e-1, 0.3962924796071230802540652e-1, 0.3852933052910671449325372e-1, 0.3734838532618666771607896e-1, 0.3608889590017987071497568e-1, 0.3475351097975151316679320e-1, 0.3334503890398068790314300e-1, 0.3186644171682106493934736e-1, 0.3032082893855398034157906e-1, 0.2871145102748499071080394e-1, 0.2704169254590396155797848e-1, 0.2531506504517639832390244e-1, 0.2353519968587633336129308e-1, 0.2170583961037807980146532e-1, 0.1983083208795549829102926e-1, 0.1791412045792315248940600e-1, 0.1595973590961380007213420e-1, 0.1397178917445765581596455e-1, 0.1195446231976944210322336e-1, 0.9912001251585937209131520e-2, 0.7848711393177167415052160e-2, 0.5768969918729952021468320e-2, 0.3677366595011730633570254e-2, 0.1581140256372912939103728e-2}, + {0.4454941715975466720216750e-1, 0.4446096841724637082355728e-1, 0.4428424653905540677579966e-1, 0.4401960239018345875735580e-1, 0.4366756139720144025254848e-1, 0.4322882250506869978939520e-1, 0.4270425678944977776996576e-1, 0.4209490572728440602098398e-1, 0.4140197912904520863822652e-1, 0.4062685273678961635122600e-1, 0.3977106549277656747784952e-1, 0.3883631648407340397900292e-1, 0.3782446156922281719727230e-1, 0.3673750969367269534804046e-1, 0.3557761890129238053276980e-1, 0.3434709204990653756854510e-1, 0.3304837223937242047087430e-1, 0.3168403796130848173465310e-1, 0.3025679798015423781653688e-1, 0.2876948595580828066131070e-1, 0.2722505481866441715910742e-1, 0.2562657090846848279898494e-1, 0.2397720788910029227868640e-1, 0.2228024045225659583389064e-1, 0.2053903782432645338449270e-1, 0.1875705709313342341545081e-1, 0.1693783637630293253183738e-1, 0.1508498786544312768229492e-1, 0.1320219081467674762507440e-1, 0.1129318464993153764963015e-1, 0.9361762769699026811498692e-2, 0.7411769363190210362109460e-2, 0.5447111874217218312821680e-2, 0.3471894893078143254999524e-2, 0.1492721288844515731042666e-2}, + {0.4332111216548653707639384e-1, 0.4323978130522261748526514e-1, 0.4307727227491369974525036e-1, 0.4283389016833881366683982e-1, 0.4251009191005772007780078e-1, 0.4210648539758646414658732e-1, 0.4162382836013859820760788e-1, 0.4106302693607506110193610e-1, 0.4042513397173397004332898e-1, 0.3971134704483490178239872e-1, 0.3892300621616966379996300e-1, 0.3806159151380216383437540e-1, 0.3712872015450289946055536e-1, 0.3612614350763799298563092e-1, 0.3505574380721787043413848e-1, 0.3391953061828605949719618e-1, 0.3271963706429384670431246e-1, 0.3145831582256181397777608e-1, 0.3013793489537547929298290e-1, 0.2876097316470176109512506e-1, 0.2733001573895093443379638e-1, 0.2584774910065589028389804e-1, 0.2431695606441916432634724e-1, 0.2274051055503575445593134e-1, 0.2112137221644055350981986e-1, 0.1946258086329427804301667e-1, 0.1776725078920065359435915e-1, 0.1603856495028515521816122e-1, 0.1427976905455419326655572e-1, 0.1249416561987375776778277e-1, 0.1068510816535189715895734e-1, 0.8855996073706153383956510e-2, 0.7010272321861863296081600e-2, 0.5151436018790886908248502e-2, 0.3283169774667495801897558e-2, 0.1411516393973434135715864e-2}, + {0.4215870660994342212223066e-1, 0.4208374996915697247489576e-1, 0.4193396995777702146995522e-1, 0.4170963287924075437870998e-1, 0.4141113759675351082006810e-1, 0.4103901482412726684741876e-1, 0.4059392618219472805807676e-1, 0.4007666302247696675915112e-1, 0.3948814502019646832363280e-1, 0.3882941853913770775808220e-1, 0.3810165477126324889635168e-1, 0.3730614765439415573370658e-1, 0.3644431157165856448181076e-1, 0.3551767883680095992585374e-1, 0.3452789696982646100333388e-1, 0.3347672576782876626372244e-1, 0.3236603417621699952527994e-1, 0.3119779696591542603337254e-1, 0.2997409122246118733996502e-1, 0.2869709265326987534209508e-1, 0.2736907171967935230243778e-1, 0.2599238960072378786677346e-1, 0.2456949399594276724564910e-1, 0.2310291477491582303093246e-1, 0.2159525948167588896969968e-1, 0.2004920870279494425273506e-1, 0.1846751130897987978285368e-1, 0.1685297958202485358484807e-1, 0.1520848424340123480887426e-1, 0.1353694941178749434105245e-1, 0.1184134754749966732316814e-1, 0.1012469453828730542112095e-1, 0.8390045433971397064089364e-2, 0.6640492909114357634760192e-2, 0.4879179758594144584288316e-2, 0.3109420149896754678673688e-2, 0.1336761650069883550325931e-2}, + {0.4105703691622942259325972e-1, 0.4098780546479395154130842e-1, 0.4084945930182849228039176e-1, 0.4064223171029473877745496e-1, 0.4036647212284402315409558e-1, 0.4002264553259682611646172e-1, 0.3961133170906205842314674e-1, 0.3913322422051844076750754e-1, 0.3858912926450673834292118e-1, 0.3797996430840528319523540e-1, 0.3730675654238160982756716e-1, 0.3657064114732961700724404e-1, 0.3577285938071394752777924e-1, 0.3491475648355076744412550e-1, 0.3399777941205638084674262e-1, 0.3302347439779174100654158e-1, 0.3199348434042160006853510e-1, 0.3090954603749159538993714e-1, 0.2977348725590504095670750e-1, 0.2858722365005400377397500e-1, 0.2735275553182752167415270e-1, 0.2607216449798598352427480e-1, 0.2474760992065967164326474e-1, 0.2338132530701118662247962e-1, 0.2197561453441624916801320e-1, 0.2053284796790802109297466e-1, 0.1905545846719058280680223e-1, 0.1754593729147423095419928e-1, 0.1600682991224857088850986e-1, 0.1444073174827667993988980e-1, 0.1285028384751014494492467e-1, 0.1123816856966768723967455e-1, 0.9607105414713754082404616e-2, 0.7959847477239734621118374e-2, 0.6299180497328445866575096e-2, 0.4627935228037421326126844e-2, 0.2949102953642474900394994e-2, 0.1267791634085359663272804e-2}, + {0.4001146511842048298877858e-1, 0.3994739036908802487930490e-1, 0.3981934348036408922503176e-1, 0.3962752950781054295639346e-1, 0.3937225562423312193722022e-1, 0.3905393062777341314731136e-1, 0.3867306428725767400389548e-1, 0.3823026652585098764962036e-1, 0.3772624644432424786429014e-1, 0.3716181118549838685067108e-1, 0.3653786464168470064819248e-1, 0.3585540600719169544500572e-1, 0.3511552817821718947488010e-1, 0.3431941600268909029029166e-1, 0.3346834438285897797298150e-1, 0.3256367623368904440805548e-1, 0.3160686030030479773888294e-1, 0.3059942883801304528943330e-1, 0.2954299515860694641162030e-1, 0.2843925104689751626239046e-1, 0.2728996405162436486456432e-1, 0.2609697465510883502983394e-1, 0.2486219332622245076144308e-1, 0.2358759746145747209645146e-1, 0.2227522821911388676305032e-1, 0.2092718725187772678537816e-1, 0.1954563334339992337791787e-1, 0.1813277895498232864440684e-1, 0.1669088668934389186621294e-1, 0.1522226568017845169331591e-1, 0.1372926792014414839372596e-1, 0.1221428454978988639768250e-1, 0.1067974215748111335351669e-1, 0.9128099227255087276943326e-2, 0.7561843189439718826977318e-2, 0.5983489944440407989648850e-2, 0.4395596039460346742737866e-2, 0.2800868811838630411609396e-2, 0.1204024566067353280336448e-2}, + {0.3901781365630665481128044e-1, 0.3895839596276953119862554e-1, 0.3883965105905196893177418e-1, 0.3866175977407646332707712e-1, 0.3842499300695942318521238e-1, 0.3812971131447763834420674e-1, 0.3777636436200139748977496e-1, 0.3736549023873049002670538e-1, 0.3689771463827600883915092e-1, 0.3637374990583597804396502e-1, 0.3579439395341605460286146e-1, 0.3516052904474759349552658e-1, 0.3447312045175392879436434e-1, 0.3373321498461152281667534e-1, 0.3294193939764540138283636e-1, 0.3210049867348777314805654e-1, 0.3121017418811470164244288e-1, 0.3027232175955798066122008e-1, 0.2928836958326784769276746e-1, 0.2825981605727686239675312e-1, 0.2718822750048638067441898e-1, 0.2607523576756511790296854e-1, 0.2492253576411549110511808e-1, 0.2373188286593010129319242e-1, 0.2250509024633246192622164e-1, 0.2124402611578200638871032e-1, 0.1995061087814199892889169e-1, 0.1862681420829903142873492e-1, 0.1727465205626930635858456e-1, 0.1589618358372568804490352e-1, 0.1449350804050907611696272e-1, 0.1306876159240133929378674e-1, 0.1162411412079782691646643e-1, 0.1016176604110306452083288e-1, 0.8683945269260858426408640e-2, 0.7192904768117312752674654e-2, 0.5690922451403198649270494e-2, 0.4180313124694895236739096e-2, 0.2663533589512681669292770e-2, 0.1144950003186941534544369e-2}, + {0.3807230964014187120769602e-1, 0.3801710843143526990530278e-1, 0.3790678605050578477946422e-1, 0.3774150245427586967153708e-1, 0.3752149728818502087157412e-1, 0.3724708953872766418784006e-1, 0.3691867707095445699853162e-1, 0.3653673605160765284219780e-1, 0.3610182025872702307569544e-1, 0.3561456027872747268049598e-1, 0.3507566259211269038478042e-1, 0.3448590854915070550737888e-1, 0.3384615323699685874463648e-1, 0.3315732423990721132775848e-1, 0.3242042029434060507783656e-1, 0.3163650984090024553762352e-1, 0.3080672947521562981366802e-1, 0.2993228230001272463508596e-1, 0.2901443618076440396145302e-1, 0.2805452190745423047171398e-1, 0.2705393126512477151978662e-1, 0.2601411501601702375386842e-1, 0.2493658079624075515577230e-1, 0.2382289093004782634222678e-1, 0.2267466016491410310244200e-1, 0.2149355333077484404348958e-1, 0.2028128292691215890157032e-1, 0.1903960664017892507303976e-1, 0.1777032479849840714698234e-1, 0.1647527776398370889101217e-1, 0.1515634327076256178846848e-1, 0.1381543371412645938772740e-1, 0.1245449340114210467973318e-1, 0.1107549578175989632022419e-1, 0.9680440704371073736965104e-2, 0.8271351818383685604431294e-2, 0.6850274534183526184325356e-2, 0.5419276232446765090703842e-2, 0.3980457937856074619030326e-2, 0.2536054696856106109823094e-2, 0.1090118595275830866109234e-2}, + {0.3717153701903406760328362e-1, 0.3712016261260209427372758e-1, 0.3701748480379452058524442e-1, 0.3686364550259030771845208e-1, 0.3665885732875907563657692e-1, 0.3640340331800212248862624e-1, 0.3609763653077256670175260e-1, 0.3574197956431530727788894e-1, 0.3533692396860127616038866e-1, 0.3488302956696330845641672e-1, 0.3438092368237270062133504e-1, 0.3383130027042598480372494e-1, 0.3323491896024044407471552e-1, 0.3259260400458425718361322e-1, 0.3190524314069272748402282e-1, 0.3117378636334566129196750e-1, 0.3039924461190246977311372e-1, 0.2958268837311084528960516e-1, 0.2872524620162180221266452e-1, 0.2782810316025840603576668e-1, 0.2689249918219763751581640e-1, 0.2591972735733464772516052e-1, 0.2491113214520642888439108e-1, 0.2386810751695823938471552e-1, 0.2279209502894212933888898e-1, 0.2168458183064482298924430e-1, 0.2054709860975627861152400e-1, 0.1938121747731880864780669e-1, 0.1818854979605654992760044e-1, 0.1697074395521161134308213e-1, 0.1572948309558359820159970e-1, 0.1446648278916118624227443e-1, 0.1318348867918234598679997e-1, 0.1188227408980122349505120e-1, 0.1056463762300824526484878e-1, 0.9232400784190247014382770e-2, 0.7887405752648146382107148e-2, 0.6531513687713654601121566e-2, 0.5166605182746808329881136e-2, 0.3794591650452349696393000e-2, 0.2417511265443122855238466e-2, 0.1039133516451971889197062e-2}, + {0.3631239537581333828231516e-1, 0.3626450208420238743149194e-1, 0.3616877866860063758274494e-1, 0.3602535138093525771008956e-1, 0.3583440939092405578977942e-1, 0.3559620453657549559069116e-1, 0.3531105099203420508058466e-1, 0.3497932485321009937141316e-1, 0.3460146364173769225993442e-1, 0.3417796572791990463423808e-1, 0.3370938967341755486497158e-1, 0.3319635349455159712009034e-1, 0.3263953384718992195609868e-1, 0.3203966513429401611022852e-1, 0.3139753853730286555853332e-1, 0.3071400097263205318303994e-1, 0.2998995397466493249133840e-1, 0.2922635250670994458366154e-1, 0.2842420370149349475731242e-1, 0.2758456553285124838738412e-1, 0.2670854542037220957530654e-1, 0.2579729876883953540777106e-1, 0.2485202744439983591832606e-1, 0.2387397818947900497321768e-1, 0.2286444097854800644577274e-1, 0.2182474731692762780068420e-1, 0.2075626848490914279058154e-1, 0.1966041372956217980740210e-1, 0.1853862840670985920631482e-1, 0.1739239207569054238672012e-1, 0.1622321654972902258808405e-1, 0.1503264390508137868494523e-1, 0.1382224445276667086664874e-1, 0.1259361467806969781040954e-1, 0.1134837515617770397716730e-1, 0.1008816846038610565467284e-1, 0.8814657101954815703782366e-2, 0.7529521612194562606844596e-2, 0.6234459139140123463885784e-2, 0.4931184096960103696423408e-2, 0.3621439249610901437553882e-2, 0.2307087488809902925963262e-2, 0.9916432666203635255681510e-3}, + {0.3549206430171454529606746e-1, 0.3544734460447076970614316e-1, 0.3535796155642384379366902e-1, 0.3522402777945910853287866e-1, 0.3504571202900426139658624e-1, 0.3482323898139935499312912e-1, 0.3455688895080708413486530e-1, 0.3424699753602007873736958e-1, 0.3389395519761025923989258e-1, 0.3349820676595309252806520e-1, 0.3306025088074670014528066e-1, 0.3258063936273210868623942e-1, 0.3205997651840638806926700e-1, 0.3149891837860489232004182e-1, 0.3089817187191219763370292e-1, 0.3025849393394352533513752e-1, 0.2958069055361934911335230e-1, 0.2886561575763542924647688e-1, 0.2811417053440861349157908e-1, 0.2732730169885533083562360e-1, 0.2650600069943473772140906e-1, 0.2565130236896194788477952e-1, 0.2476428362076873302532156e-1, 0.2384606209185966126357838e-1, 0.2289779473478114232724788e-1, 0.2192067635998985359563460e-1, 0.2091593813057662423225406e-1, 0.1988484601127411324360109e-1, 0.1882869917375545139470985e-1, 0.1774882836032407455649534e-1, 0.1664659420821765604511323e-1, 0.1552338553693355384016474e-1, 0.1438061760129994423593466e-1, 0.1321973031362791170818164e-1, 0.1204218643958121230973900e-1, 0.1084946977542927125940107e-1, 0.9643083322053204400769368e-2, 0.8424547492702473015098308e-2, 0.7195398459796372059759572e-2, 0.5957186996138046583131162e-2, 0.4711479279598661743021848e-2, 0.3459867667862796423976646e-2, 0.2204058563143696628535344e-2, 0.9473355981619272667700360e-3}, + {0.3470797248895005792046014e-1, 0.3466615208568824018827232e-1, 0.3458256166949689141805380e-1, 0.3445730196032425617459566e-1, 0.3429052388637504193169728e-1, 0.3408242840225399546360508e-1, 0.3383326624683168725792750e-1, 0.3354333764112427668293316e-1, 0.3321299192655131651404080e-1, 0.3284262714400750457863018e-1, 0.3243268955425561691178950e-1, 0.3198367310021857603945600e-1, 0.3149611881181863607695780e-1, 0.3097061415408092094593650e-1, 0.3040779231928695269039426e-1, 0.2980833146403127548714788e-1, 0.2917295389210074248655798e-1, 0.2850242518416141631875546e-1, 0.2779755327530227515803874e-1, 0.2705918748154795852161408e-1, 0.2628821747651458736159580e-1, 0.2548557221944322848446706e-1, 0.2465221883590485293596628e-1, 0.2378916145252872321010090e-1, 0.2289743998716318463498862e-1, 0.2197812889593413383869188e-1, 0.2103233587872256311706242e-1, 0.2006120054463959596453232e-1, 0.1906589303913731842532399e-1, 0.1804761263446023616404962e-1, 0.1700758628522267570939747e-1, 0.1594706715100663901320649e-1, 0.1486733308804332405038481e-1, 0.1376968511233709343075118e-1, 0.1265544583716812886887583e-1, 0.1152595788914805885059348e-1, 0.1038258230989321461380844e-1, 0.9226696957741990940319884e-2, 0.8059694944620015658670990e-2, 0.6882983208463284314729370e-2, 0.5697981560747352600849438e-2, 0.4506123613674977864136850e-2, 0.3308867243336018195431340e-2, 0.2107778774526329891473788e-2, 0.9059323712148330937360098e-3}, + {0.3395777082810234796700260e-1, 0.3391860442372254949502722e-1, 0.3384031678893360189141840e-1, 0.3372299821957387169380074e-1, 0.3356678402920367631007550e-1, 0.3337185439303681030780114e-1, 0.3313843414012938182262046e-1, 0.3286679249406566032646806e-1, 0.3255724276244004524316198e-1, 0.3221014197549332953574452e-1, 0.3182589047432008582597260e-1, 0.3140493144912217791614030e-1, 0.3094775042804103166804096e-1, 0.3045487471715832098063528e-1, 0.2992687279231107330786762e-1, 0.2936435364342281261274650e-1, 0.2876796607210717582237958e-1, 0.2813839794335440451445112e-1, 0.2747637539216417339517938e-1, 0.2678266198604032330048838e-1, 0.2605805784431417922245786e-1, 0.2530339871531322569754810e-1, 0.2451955501244097425717108e-1, 0.2370743081028191239353720e-1, 0.2286796280189254240434106e-1, 0.2200211921848585739874382e-1, 0.2111089871276246180997612e-1, 0.2019532920718748374956428e-1, 0.1925646670855947471237209e-1, 0.1829539409026755729118717e-1, 0.1731321984368977636114053e-1, 0.1631107680025595800481463e-1, 0.1529012082579650150690625e-1, 0.1425152948895392526580707e-1, 0.1319650070571113802911160e-1, 0.1212625136263771052929676e-1, 0.1104201592263539422398575e-1, 0.9945045019726082041770092e-2, 0.8836604056467877374547944e-2, 0.7717971837373568504533128e-2, 0.6590439334214895223179124e-2, 0.5455308908000870987158870e-2, 0.4313895331861700472339122e-2, 0.3167535943396097874261610e-2, 0.2017671366262838591883234e-2, 0.8671851787671421353540866e-3}, + {0.3323930891781532080070524e-1, 0.3320257661860686379876634e-1, 0.3312915261254696321600516e-1, 0.3301911803949165507667076e-1, 0.3287259449712959072614770e-1, 0.3268974390660630715252838e-1, 0.3247076833358767948450850e-1, 0.3221590976496030711281812e-1, 0.3192544984141561392584074e-1, 0.3159970954621320046477392e-1, 0.3123904885046741788219108e-1, 0.3084386631534918741110674e-1, 0.3041459865164271220328128e-1, 0.2995172023714386920008800e-1, 0.2945574259243367639719146e-1, 0.2892721381560625584227516e-1, 0.2836671797657610681272962e-1, 0.2777487447163422062065088e-1, 0.2715233733896656472388262e-1, 0.2649979453589169919669406e-1, 0.2581796717861672816440260e-1, 0.2510760874535240512858038e-1, 0.2436950424366898830634656e-1, 0.2360446934301438228050796e-1, 0.2281334947335523641001192e-1, 0.2199701889094007717339700e-1, 0.2115637971222138981504522e-1, 0.2029236091701113217988866e-1, 0.1940591732198200488605189e-1, 0.1849802852566591095380957e-1, 0.1756969782614325199872555e-1, 0.1662195111266549663832874e-1, 0.1565583573251555786002188e-1, 0.1467241933449946420426407e-1, 0.1367278869060687850644038e-1, 0.1265804849763899444482439e-1, 0.1162932016112241459607371e-1, 0.1058774056495412223672440e-1, 0.9534460832865158250063918e-2, 0.8470645094534635999910406e-2, 0.7397469288142356200862272e-2, 0.6316120091036448223107804e-2, 0.5227794289507767545307002e-2, 0.4133699875407776483295790e-2, 0.3035065891038628027389626e-2, 0.1933219888725418943121000e-2, 0.8308716126821624946495838e-3}, + {0.3255061449236316624196142e-1, 0.3251611871386883598720548e-1, 0.3244716371406426936401278e-1, 0.3234382256857592842877486e-1, 0.3220620479403025066866710e-1, 0.3203445623199266321813896e-1, 0.3182875889441100653475374e-1, 0.3158933077072716855802074e-1, 0.3131642559686135581278434e-1, 0.3101033258631383742324982e-1, 0.3067137612366914901422878e-1, 0.3029991542082759379408878e-1, 0.2989634413632838598438796e-1, 0.2946108995816790597043632e-1, 0.2899461415055523654267862e-1, 0.2849741106508538564559948e-1, 0.2797000761684833443981840e-1, 0.2741296272602924282342110e-1, 0.2682686672559176219805676e-1, 0.2621234073567241391345816e-1, 0.2557003600534936149879724e-1, 0.2490063322248361028838244e-1, 0.2420484179236469128226730e-1, 0.2348339908592621984223612e-1, 0.2273706965832937400134754e-1, 0.2196664443874434919475618e-1, 0.2117293989219129898767356e-1, 0.2035679715433332459524556e-1, 0.1951908114014502241008485e-1, 0.1866067962741146738515655e-1, 0.1778250231604526083761406e-1, 0.1688547986424517245047785e-1, 0.1597056290256229138061685e-1, 0.1503872102699493800587588e-1, 0.1409094177231486091586166e-1, 0.1312822956696157263706415e-1, 0.1215160467108831963518178e-1, 0.1116210209983849859121361e-1, 0.1016077053500841575758671e-1, 0.9148671230783386632584044e-2, 0.8126876925698759217383246e-2, 0.7096470791153865269143206e-2, 0.6058545504235961683315686e-2, 0.5014202742927517692471308e-2, 0.3964554338444686673733524e-2, 0.2910731817934946408411678e-2, 0.1853960788946921732331620e-2, 0.7967920655520124294367096e-3}, + {0.3188987535287646727794502e-1, 0.3185743815812401071309920e-1, 0.3179259676252863019831786e-1, 0.3169541712034925160907410e-1, 0.3156599807910805290145092e-1, 0.3140447127904656151748860e-1, 0.3121100101922626441684056e-1, 0.3098578409040993463104290e-1, 0.3072904957489366992001356e-1, 0.3044105861349325839490764e-1, 0.3012210413992189884853100e-1, 0.2977251058282947626617570e-1, 0.2939263353580649216776328e-1, 0.2898285939568834204744914e-1, 0.2854360496952788570349054e-1, 0.2807531705063613875324586e-1, 0.2757847196412239390009986e-1, 0.2705357508239612827767608e-1, 0.2650116031112363935248738e-1, 0.2592178954616244891846836e-1, 0.2531605210202609734314644e-1, 0.2468456411246099618197954e-1, 0.2402796790374549880324124e-1, 0.2334693134134927471268304e-1, 0.2264214715061843311126274e-1, 0.2191433221217865041901888e-1, 0.2116422683277485691127980e-1, 0.2039259399229191457948346e-1, 0.1960021856772633077323700e-1, 0.1878790653490468656148738e-1, 0.1795648414877062812244296e-1, 0.1710679710308990026235402e-1, 0.1623970967045369565272614e-1, 0.1535610382349775576849818e-1, 0.1445687833830440197756895e-1, 0.1354294788102946514364726e-1, 0.1261524207892195285778215e-1, 0.1167470457713812428742924e-1, 0.1072229208322431712024324e-1, 0.9758973402174096835348026e-2, 0.8785728467392263202699392e-2, 0.7803547379100754890979542e-2, 0.6813429479165215998771186e-2, 0.5816382546439639112764538e-2, 0.4813422398586770918478190e-2, 0.3805574085352359565512666e-2, 0.2793881135722130870629084e-2, 0.1779477041014528741695358e-2, 0.7647669822743134580383448e-3}, + {0.3125542345386335694764248e-1, 0.3122488425484935773237650e-1, 0.3116383569620990678381832e-1, 0.3107233742756651658781016e-1, 0.3095047885049098823406346e-1, 0.3079837903115259042771392e-1, 0.3061618658398044849645950e-1, 0.3040407952645482001650792e-1, 0.3016226510516914491906862e-1, 0.2989097959333283091683684e-1, 0.2959048805991264251175454e-1, 0.2926108411063827662011896e-1, 0.2890308960112520313487610e-1, 0.2851685432239509799093676e-1, 0.2810275565910117331764820e-1, 0.2766119822079238829420408e-1, 0.2719261344657688013649158e-1, 0.2669745918357096266038448e-1, 0.2617621923954567634230892e-1, 0.2562940291020811607564182e-1, 0.2505754448157958970376402e-1, 0.2446120270795705271997480e-1, 0.2384096026596820596256040e-1, 0.2319742318525412162248878e-1, 0.2253122025633627270179672e-1, 0.2184300241624738631395360e-1, 0.2113344211252764154267220e-1, 0.2040323264620943276683910e-1, 0.1965308749443530586538157e-1, 0.1888373961337490455294131e-1, 0.1809594072212811666439111e-1, 0.1729046056832358243934388e-1, 0.1646808617614521264310506e-1, 0.1562962107754600272393719e-1, 0.1477588452744130176887969e-1, 0.1390771070371877268795387e-1, 0.1302594789297154228555807e-1, 0.1213145766297949740774437e-1, 0.1122511402318597711722209e-1, 0.1030780257486896958578198e-1, 0.9380419653694457951417628e-2, 0.8443871469668971402620252e-2, 0.7499073255464711578829804e-2, 0.6546948450845322764152444e-2, 0.5588428003865515157213478e-2, 0.4624450063422119351093868e-2, 0.3655961201326375182342828e-2, 0.2683925371553482419437272e-2, 0.1709392653518105239533969e-2, 0.7346344905056717304142370e-3}, +} + +var oddWeights = [][]float64{ + {0.5555555555555555555555555}, + {0.4786286704993664680412916e0, 0.2369268850561890875142644e0}, + {0.3818300505051189449503698e0, 0.2797053914892766679014680e0, 0.1294849661688696932706118e0}, + {0.3123470770400028400686304e0, 0.2606106964029354623187428e0, 0.1806481606948574040584721e0, 0.8127438836157441197189206e-1}, + {0.2628045445102466621806890e0, 0.2331937645919904799185238e0, 0.1862902109277342514260979e0, 0.1255803694649046246346947e0, 0.5566856711617366648275374e-1}, + {0.2262831802628972384120902e0, 0.2078160475368885023125234e0, 0.1781459807619457382800468e0, 0.1388735102197872384636019e0, 0.9212149983772844791442126e-1, 0.4048400476531587952001996e-1}, + {0.1984314853271115764561182e0, 0.1861610000155622110268006e0, 0.1662692058169939335532006e0, 0.1395706779261543144478051e0, 0.1071592204671719350118693e0, 0.7036604748810812470926662e-1, 0.3075324199611726835462762e-1}, + {0.1765627053669926463252710e0, 0.1680041021564500445099705e0, 0.1540457610768102880814317e0, 0.1351363684685254732863199e0, 0.1118838471934039710947887e0, 0.8503614831717918088353538e-1, 0.5545952937398720112944102e-1, 0.2414830286854793196010920e-1}, + {0.1589688433939543476499565e0, 0.1527660420658596667788553e0, 0.1426067021736066117757460e0, 0.1287539625393362276755159e0, 0.1115666455473339947160242e0, 0.9149002162244999946446222e-1, 0.6904454273764122658070790e-1, 0.4481422676569960033283728e-1, 0.1946178822972647703631351e-1}, + {0.1445244039899700590638271e0, 0.1398873947910731547221335e0, 0.1322689386333374617810526e0, 0.1218314160537285341953671e0, 0.1087972991671483776634747e0, 0.9344442345603386155329010e-1, 0.7610011362837930201705132e-1, 0.5713442542685720828363528e-1, 0.3695378977085249379995034e-1, 0.1601722825777433332422273e-1}, + {0.1324620394046966173716425e0, 0.1289057221880821499785954e0, 0.1230490843067295304675784e0, 0.1149966402224113649416434e0, 0.1048920914645414100740861e0, 0.9291576606003514747701876e-1, 0.7928141177671895492289248e-1, 0.6423242140852585212716980e-1, 0.4803767173108466857164124e-1, 0.3098800585697944431069484e-1, 0.1341185948714177208130864e-1}, + {0.1222424429903100416889594e0, 0.1194557635357847722281782e0, 0.1148582591457116483393255e0, 0.1085196244742636531160939e0, 0.1005359490670506442022068e0, 0.9102826198296364981149704e-1, 0.8014070033500101801323524e-1, 0.6803833381235691720718712e-1, 0.5490469597583519192593686e-1, 0.4093915670130631265562402e-1, 0.2635498661503213726190216e-1, 0.1139379850102628794789998e-1}, + {0.1134763461089651486203700e0, 0.1112524883568451926721632e0, 0.1075782857885331872121629e0, 0.1025016378177457986712478e0, 0.9608872737002850756565252e-1, 0.8842315854375695019432262e-1, 0.7960486777305777126307488e-1, 0.6974882376624559298432254e-1, 0.5898353685983359911030058e-1, 0.4744941252061506270409646e-1, 0.3529705375741971102257772e-1, 0.2268623159618062319603554e-1, 0.9798996051294360261149438e-2}, + {0.1058761550973209414065914e0, 0.1040733100777293739133284e0, 0.1010912737599149661218204e0, 0.9696383409440860630190016e-1, 0.9173775713925876334796636e-1, 0.8547225736617252754534480e-1, 0.7823832713576378382814484e-1, 0.7011793325505127856958160e-1, 0.6120309065707913854210970e-1, 0.5159482690249792391259412e-1, 0.4140206251868283610482948e-1, 0.3074049220209362264440778e-1, 0.1973208505612270598385931e-1, 0.8516903878746409654261436e-2}, + {0.9922501122667230787487546e-1, 0.9774333538632872509347402e-1, 0.9529024291231951280720412e-1, 0.9189011389364147821536290e-1, 0.8757674060847787612619794e-1, 0.8239299176158926390382334e-1, 0.7639038659877661642635764e-1, 0.6962858323541036616775632e-1, 0.6217478656102842691034334e-1, 0.5410308242491685371166596e-1, 0.4549370752720110290231576e-1, 0.3643227391238546402439264e-1, 0.2700901918497942180060860e-1, 0.1731862079031058246315918e-1, 0.7470831579248775858700554e-2}, + {0.9335642606559611616099912e-1, 0.9212398664331684621324104e-1, 0.9008195866063857723974370e-1, 0.8724828761884433760728158e-1, 0.8364787606703870761392808e-1, 0.7931236479488673836390848e-1, 0.7427985484395414934247216e-1, 0.6859457281865671280595482e-1, 0.6230648253031748003162750e-1, 0.5547084663166356128494468e-1, 0.4814774281871169567014706e-1, 0.4040154133166959156340938e-1, 0.3230035863232895328156104e-1, 0.2391554810174948035053310e-1, 0.1532170151293467612794584e-1, 0.6606227847587378058647800e-2}, + {0.8814053043027546297073886e-1, 0.8710444699718353424332214e-1, 0.8538665339209912522594402e-1, 0.8300059372885658837992644e-1, 0.7996494224232426293266204e-1, 0.7630345715544205353865872e-1, 0.7204479477256006466546180e-1, 0.6722228526908690396430546e-1, 0.6187367196608018888701398e-1, 0.5604081621237012857832772e-1, 0.4976937040135352980519956e-1, 0.4310842232617021878230592e-1, 0.3611011586346338053271748e-1, 0.2882926010889425404871630e-1, 0.2132297991148358088343844e-1, 0.1365082834836149226640441e-1, 0.5883433420443084975750336e-2}, + {0.8347457362586278725225302e-1, 0.8259527223643725089123018e-1, 0.8113662450846503050987774e-1, 0.7910886183752938076721222e-1, 0.7652620757052923788588804e-1, 0.7340677724848817272462668e-1, 0.6977245155570034488508154e-1, 0.6564872287275124948402376e-1, 0.6106451652322598613098804e-1, 0.5605198799827491780853916e-1, 0.5064629765482460160387558e-1, 0.4488536466243716665741054e-1, 0.3880960250193454448896226e-1, 0.3246163984752148106723444e-1, 0.2588603699055893352275954e-1, 0.1912904448908396604350259e-1, 0.1223878010030755652630649e-1, 0.5273057279497939351724544e-2}, + {0.7927622256836847101015574e-1, 0.7852361328737117672506330e-1, 0.7727455254468201672851160e-1, 0.7553693732283605770478448e-1, 0.7332175341426861738115402e-1, 0.7064300597060876077011486e-1, 0.6751763096623126536302120e-1, 0.6396538813868238898670650e-1, 0.6000873608859614957494160e-1, 0.5567269034091629990739094e-1, 0.5098466529212940521402098e-1, 0.4597430110891663188417682e-1, 0.4067327684793384393905618e-1, 0.3511511149813133076106530e-1, 0.2933495598390337859215654e-1, 0.2336938483217816459471240e-1, 0.1725622909372491904080491e-1, 0.1103478893916459424267603e-1, 0.4752944691635101370775866e-2}, + {0.7547874709271582402724706e-1, 0.7482962317622155189130518e-1, 0.7375188202722346993928094e-1, 0.7225169686102307339634646e-1, 0.7033766062081749748165896e-1, 0.6802073676087676673553342e-1, 0.6531419645352741043616384e-1, 0.6223354258096631647157330e-1, 0.5879642094987194499118590e-1, 0.5502251924257874188014710e-1, 0.5093345429461749478117008e-1, 0.4655264836901434206075674e-1, 0.4190519519590968942934048e-1, 0.3701771670350798843526154e-1, 0.3191821173169928178706676e-1, 0.2663589920711044546754900e-1, 0.2120106336877955307569710e-1, 0.1564493840781858853082666e-1, 0.9999938773905945338496546e-2, 0.4306140358164887684003630e-2}, + {0.7202750197142197434530754e-1, 0.7146373425251414129758106e-1, 0.7052738776508502812628636e-1, 0.6922334419365668428229950e-1, 0.6755840222936516919240796e-1, 0.6554124212632279749123378e-1, 0.6318238044939611232562970e-1, 0.6049411524999129451967862e-1, 0.5749046195691051942760910e-1, 0.5418708031888178686337342e-1, 0.5060119278439015652385048e-1, 0.4675149475434658001064704e-1, 0.4265805719798208376380686e-1, 0.3834222219413265757212856e-1, 0.3382649208686029234496834e-1, 0.2913441326149849491594084e-1, 0.2429045661383881590201850e-1, 0.1931990142368390039612543e-1, 0.1424875643157648610854214e-1, 0.9103996637401403318866628e-2, 0.3919490253844127282968528e-2}, + {0.6887731697766132288200278e-1, 0.6838457737866967453169206e-1, 0.6756595416360753627091012e-1, 0.6642534844984252808291474e-1, 0.6496819575072343085382664e-1, 0.6320144007381993774996374e-1, 0.6113350083106652250188634e-1, 0.5877423271884173857436156e-1, 0.5613487875978647664392382e-1, 0.5322801673126895194590376e-1, 0.5006749923795202979913194e-1, 0.4666838771837336526776814e-1, 0.4304688070916497115169120e-1, 0.3922023672930244756418756e-1, 0.3520669220160901624770010e-1, 0.3102537493451546716250854e-1, 0.2669621396757766480567536e-1, 0.2223984755057873239395080e-1, 0.1767753525793759061709347e-1, 0.1303110499158278432063191e-1, 0.8323189296218241645734836e-2, 0.3582663155283558931145652e-2}, + {0.6599053358881047453357062e-1, 0.6555737776654974025114294e-1, 0.6483755623894572670260402e-1, 0.6383421660571703063129384e-1, 0.6255174622092166264056434e-1, 0.6099575300873964533071060e-1, 0.5917304094233887597615438e-1, 0.5709158029323154022201646e-1, 0.5476047278153022595712512e-1, 0.5218991178005714487221170e-1, 0.4939113774736116960457022e-1, 0.4637638908650591120440168e-1, 0.4315884864847953826830162e-1, 0.3975258612253100378090162e-1, 0.3617249658417495161345948e-1, 0.3243423551518475676761786e-1, 0.2855415070064338650473990e-1, 0.2454921165965881853783378e-1, 0.2043693814766842764203432e-1, 0.1623533314643305967072624e-1, 0.1196284846431232096394232e-1, 0.7638616295848833614105174e-2, 0.3287453842528014883248206e-2}, + {0.6333550929649174859083696e-1, 0.6295270746519569947439960e-1, 0.6231641732005726740107682e-1, 0.6142920097919293629682652e-1, 0.6029463095315201730310616e-1, 0.5891727576002726602452756e-1, 0.5730268153018747548516450e-1, 0.5545734967480358869043158e-1, 0.5338871070825896852794302e-1, 0.5110509433014459067462262e-1, 0.4861569588782824027765094e-1, 0.4593053935559585354249958e-1, 0.4306043698125959798834538e-1, 0.4001694576637302136860494e-1, 0.3681232096300068981946734e-1, 0.3345946679162217434248744e-1, 0.2997188462058382535069014e-1, 0.2636361892706601696094518e-1, 0.2264920158744667649877160e-1, 0.1884359585308945844445106e-1, 0.1496214493562465102958377e-1, 0.1102055103159358049750846e-1, 0.7035099590086451473452956e-2, 0.3027278988922905077484090e-2}, + {0.6088546484485634388119860e-1, 0.6054550693473779513812526e-1, 0.5998031577750325209006396e-1, 0.5919199392296154378353896e-1, 0.5818347398259214059843780e-1, 0.5695850772025866210007778e-1, 0.5552165209573869301673704e-1, 0.5387825231304556143409938e-1, 0.5203442193669708756413650e-1, 0.4999702015005740977954886e-1, 0.4777362624062310199999514e-1, 0.4537251140765006874816670e-1, 0.4280260799788008665360980e-1, 0.4007347628549645318680892e-1, 0.3719526892326029284290846e-1, 0.3417869320418833623620910e-1, 0.3103497129016000845442504e-1, 0.2777579859416247719599602e-1, 0.2441330057378143427314164e-1, 0.2095998840170321057979252e-1, 0.1742871472340105225950284e-1, 0.1383263400647782229668883e-1, 0.1018519129782172993923731e-1, 0.6500337783252600292109494e-2, 0.2796807171089895575547228e-2}, + {0.5861758623272026331807196e-1, 0.5831431136225600755627570e-1, 0.5781001499171319631968304e-1, 0.5710643553626719177338328e-1, 0.5620599838173970980865512e-1, 0.5511180752393359900234954e-1, 0.5382763486873102904208140e-1, 0.5235790722987271819970160e-1, 0.5070769106929271529648556e-1, 0.4888267503269914042044844e-1, 0.4688915034075031402187278e-1, 0.4473398910367281021276570e-1, 0.4242462063452001359228150e-1, 0.3996900584354038212709364e-1, 0.3737560980348291567417214e-1, 0.3465337258353423795838740e-1, 0.3181167845901932306323576e-1, 0.2886032361782373626279970e-1, 0.2580948251075751771396152e-1, 0.2266967305707020839878928e-1, 0.1945172110763689538804750e-1, 0.1616672525668746392806095e-1, 0.1282602614424037917915135e-1, 0.9441202284940344386662890e-2, 0.6024276226948673281242120e-2, 0.2591683720567031811603734e-2}, + {0.5651231824977200140065834e-1, 0.5624063407108436802827906e-1, 0.5578879419528408710293598e-1, 0.5515824600250868759665114e-1, 0.5435100932991110207032224e-1, 0.5336967000160547272357054e-1, 0.5221737154563208456439348e-1, 0.5089780512449397922477522e-1, 0.4941519771155173948075862e-1, 0.4777429855120069555003682e-1, 0.4598036394628383810390480e-1, 0.4403914042160658989516800e-1, 0.4195684631771876239520718e-1, 0.3974015187433717960946388e-1, 0.3739615786796554528291572e-1, 0.3493237287358988740726862e-1, 0.3235668922618583168470572e-1, 0.2967735776516104122129630e-1, 0.2690296145639627066711996e-1, 0.2404238800972562200779126e-1, 0.2110480166801645412020978e-1, 0.1809961452072906240796732e-1, 0.1503645833351178821315019e-1, 0.1192516071984861217075236e-1, 0.8775746107058528177390204e-2, 0.5598632266560767354082364e-2, 0.2408323619979788819164582e-2}, + {0.5455280360476188648013898e-1, 0.5430847145249864313874678e-1, 0.5390206148329857464280950e-1, 0.5333478658481915842657698e-1, 0.5260833972917743244023134e-1, 0.5172488892051782472062386e-1, 0.5068707072492740865664050e-1, 0.4949798240201967899383808e-1, 0.4816117266168775126885110e-1, 0.4668063107364150378384082e-1, 0.4506077616138115779721374e-1, 0.4330644221621519659643210e-1, 0.4142286487080111036319668e-1, 0.3941566547548011408995280e-1, 0.3729083432441731735473546e-1, 0.3505471278231261750575064e-1, 0.3271397436637156854248994e-1, 0.3027560484269399945849064e-1, 0.2774688140218019232125814e-1, 0.2513535099091812264727322e-1, 0.2244880789077643807968978e-1, 0.1969527069948852038242318e-1, 0.1688295902344154903500062e-1, 0.1402027079075355617024753e-1, 0.1111576373233599014567619e-1, 0.8178160067821232626211086e-2, 0.5216533474718779390504886e-2, 0.2243753872250662909727492e-2}, + {0.5272443385912793196130422e-1, 0.5250390264782873905094128e-1, 0.5213703364837539138398724e-1, 0.5162484939089148214644000e-1, 0.5096877742539391685024800e-1, 0.5017064634299690281072034e-1, 0.4923268067936198577969374e-1, 0.4815749471460644038814684e-1, 0.4694808518696201919315986e-1, 0.4560782294050976983186828e-1, 0.4414044353029738069079808e-1, 0.4255003681106763866730838e-1, 0.4084103553868670766020196e-1, 0.3901820301616000950303072e-1, 0.3708661981887092269183778e-1, 0.3505166963640010878371850e-1, 0.3291902427104527775751116e-1, 0.3069462783611168323975056e-1, 0.2838468020053479790515332e-1, 0.2599561973129850018665014e-1, 0.2353410539371336342527500e-1, 0.2100699828843718735046168e-1, 0.1842134275361002936061624e-1, 0.1578434731308146614732024e-1, 0.1310336630634519101831859e-1, 0.1038588550099586219379846e-1, 0.7639529453487575142699186e-2, 0.4872239168265284768580414e-2, 0.2095492284541223402697724e-2}, + {0.5101448703869726354373512e-1, 0.5081476366881834320770052e-1, 0.5048247038679740464814450e-1, 0.5001847410817825342505160e-1, 0.4942398534673558993996884e-1, 0.4870055505641152608753004e-1, 0.4785007058509560716183348e-1, 0.4687475075080906597642932e-1, 0.4577714005314595937133982e-1, 0.4456010203508348827154136e-1, 0.4322681181249609790104358e-1, 0.4178074779088849206667564e-1, 0.4022568259099824736764020e-1, 0.3856567320700817274615216e-1, 0.3680505042315481738432126e-1, 0.3494840751653335109085198e-1, 0.3300058827590741063272390e-1, 0.3096667436839739482469792e-1, 0.2885197208818340150434184e-1, 0.2666199852415088966281066e-1, 0.2440246718754420291534050e-1, 0.2207927314831904400247522e-1, 0.1969847774610118133051782e-1, 0.1726629298761374359443389e-1, 0.1478906588493791454617878e-1, 0.1227326350781210462927897e-1, 0.9725461830356133736135366e-2, 0.7152354991749089585834616e-2, 0.4560924006012417184541648e-2, 0.1961453361670282671779431e-2}, + {0.4941183303991817896703964e-1, 0.4923038042374756078504314e-1, 0.4892845282051198994470936e-1, 0.4850678909788384786409014e-1, 0.4796642113799513141105276e-1, 0.4730867131226891908060508e-1, 0.4653514924538369651039536e-1, 0.4564774787629260868588592e-1, 0.4464863882594139537033256e-1, 0.4354026708302759079896428e-1, 0.4232534502081582298250554e-1, 0.4100684575966639863511004e-1, 0.3958799589154409398480778e-1, 0.3807226758434955676363856e-1, 0.3646337008545728963045232e-1, 0.3476524064535587769718026e-1, 0.3298203488377934176568344e-1, 0.3111811662221981750821608e-1, 0.2917804720828052694555162e-1, 0.2716657435909793322519012e-1, 0.2508862055334498661862972e-1, 0.2294927100488993314894282e-1, 0.2075376125803909077534152e-1, 0.1850746446016127040926083e-1, 0.1621587841033833888228333e-1, 0.1388461261611561082486681e-1, 0.1151937607688004175075116e-1, 0.9125968676326656354058462e-2, 0.6710291765960136251908410e-2, 0.4278508346863761866081200e-2, 0.1839874595577084117085868e-2}, + {0.4790669250049586203134730e-1, 0.4774134868124062155903898e-1, 0.4746619823288550315264446e-1, 0.4708187401045452224600686e-1, 0.4658925997223349830225508e-1, 0.4598948914665169696389334e-1, 0.4528394102630023065712822e-1, 0.4447423839508297442732352e-1, 0.4356224359580048653228480e-1, 0.4255005424675580271921714e-1, 0.4143999841724029302268646e-1, 0.4023462927300553381544642e-1, 0.3893671920405119761667398e-1, 0.3754925344825770980977246e-1, 0.3607542322556527393216642e-1, 0.3451861839854905862522142e-1, 0.3288241967636857498404946e-1, 0.3117059038018914246443218e-1, 0.2938706778931066806264472e-1, 0.2753595408845034394249940e-1, 0.2562150693803775821408458e-1, 0.2364812969128723669878144e-1, 0.2162036128493406284165378e-1, 0.1954286583675006282683714e-1, 0.1742042199767024849536596e-1, 0.1525791214644831034926464e-1, 0.1306031163999484633616732e-1, 0.1083267878959796862151440e-1, 0.8580148266881459893636434e-2, 0.6307942578971754550189764e-2, 0.4021524172003736347075858e-2, 0.1729258251300250898337759e-2}, + {0.4649043816026462820831466e-1, 0.4633935168241562110844706e-1, 0.4608790448976157619721740e-1, 0.4573664116106369093689412e-1, 0.4528632245466953156805004e-1, 0.4473792366088982547214182e-1, 0.4409263248975101830783160e-1, 0.4335184649869951735915584e-1, 0.4251717006583049147154770e-1, 0.4159041091519924309854838e-1, 0.4057357620174452522725164e-1, 0.3946886816430888264288692e-1, 0.3827867935617948064763712e-1, 0.3700558746349258202313488e-1, 0.3565234972274500666133270e-1, 0.3422189694953664673983902e-1, 0.3271732719153120542712204e-1, 0.3114189901947282393742616e-1, 0.2949902447094566969584718e-1, 0.2779226166243676998720012e-1, 0.2602530708621323880370460e-1, 0.2420198760967316472069180e-1, 0.2232625219645207692279754e-1, 0.2040216337134354044925720e-1, 0.1843388845680457387216616e-1, 0.1642569062253087920472674e-1, 0.1438191982720055093097663e-1, 0.1230700384928815052195302e-1, 0.1020544003410244098666155e-1, 0.8081790299023136215346300e-2, 0.5940693177582235216514606e-2, 0.3787008301825508445960626e-2, 0.1628325035240012866460003e-2}, + {0.4515543023614546051651704e-1, 0.4501700814039980219871620e-1, 0.4478661887831255754213528e-1, 0.4446473312204713809623108e-1, 0.4405200846590928438098588e-1, 0.4354928808292674103357578e-1, 0.4295759900230521387841984e-1, 0.4227815001128051285158270e-1, 0.4151232918565450208287406e-1, 0.4066170105406160053752604e-1, 0.3972800340176164120645862e-1, 0.3871314372049251393273936e-1, 0.3761919531164090650815840e-1, 0.3644839305070051405664348e-1, 0.3520312882168348614775456e-1, 0.3388594663083228949780964e-1, 0.3249953740964611124473418e-1, 0.3104673351789053903268552e-1, 0.2953050295790671177981110e-1, 0.2795394331218770599086132e-1, 0.2632027541686948379176090e-1, 0.2463283678454245536433616e-1, 0.2289507479074078565552120e-1, 0.2111053963987189462789068e-1, 0.1928287712884940278924393e-1, 0.1741582123196982913207401e-1, 0.1551318654340616473976910e-1, 0.1357886064907567099981112e-1, 0.1161679661067196554873961e-1, 0.9631006150415575588660562e-2, 0.7625555931201510611459992e-2, 0.5604579927870594828535346e-2, 0.3572416739397372609702552e-2, 0.1535976952792084075135094e-2}, + {0.4389487921178858632125256e-1, 0.4376774491340214497230982e-1, 0.4355612710410853337113396e-1, 0.4326043426324126659885626e-1, 0.4288123715758043502060704e-1, 0.4241926773962459303533940e-1, 0.4187541773473300618954268e-1, 0.4125073691986602424910896e-1, 0.4054643109724689643492514e-1, 0.3976385976685758167433708e-1, 0.3890453350226294749240264e-1, 0.3797011103483115621441804e-1, 0.3696239605198203185608278e-1, 0.3588333371564891077796844e-1, 0.3473500690768218837536532e-1, 0.3351963220945403083440624e-1, 0.3223955562344352694190700e-1, 0.3089724804509072169860608e-1, 0.2949530049370881246493644e-1, 0.2803641911174149061798030e-1, 0.2652341994215790800810512e-1, 0.2495922349431387305527612e-1, 0.2334684910922325263171504e-1, 0.2168940913598536796183230e-1, 0.1999010293235011128748561e-1, 0.1825221070467867050232934e-1, 0.1647908720746239655059230e-1, 0.1467415533461152920040808e-1, 0.1284089966808780607041846e-1, 0.1098286015429855170627475e-1, 0.9103626461992005851317578e-2, 0.7206835281831493387342912e-2, 0.5296182844025892632677844e-2, 0.3375555496730675865126842e-2, 0.1451267330029397268489446e-2}, + {0.4270273086485722207660098e-1, 0.4258568982601838702576300e-1, 0.4239085899223159440537396e-1, 0.4211859425425563626894556e-1, 0.4176939294869285375410172e-1, 0.4134389294952549452688336e-1, 0.4084287150293886154936056e-1, 0.4026724380756003336494178e-1, 0.3961806134270614331650800e-1, 0.3889650994769673952047552e-1, 0.3810390765573980059550798e-1, 0.3724170228634977315689404e-1, 0.3631146880069778469034650e-1, 0.3531490642472828750906318e-1, 0.3425383554530221541412972e-1, 0.3313019438504384067706900e-1, 0.3194603546197670648650132e-1, 0.3070352184043350493812614e-1, 0.2940492318011656010545704e-1, 0.2805261159057206032380240e-1, 0.2664905729872748295223048e-1, 0.2519682413753831281333190e-1, 0.2369856486421897462660896e-1, 0.2215701631704007205676952e-1, 0.2057499442036116916601972e-1, 0.1895538904867002168973610e-1, 0.1730115876248908300560664e-1, 0.1561532543359142299553300e-1, 0.1390096878831465086752053e-1, 0.1216122092928111272776412e-1, 0.1039926099500053220130511e-1, 0.8618310479532247613912182e-2, 0.6821631349174792362208078e-2, 0.5012538571606190263812266e-2, 0.3194524377289034522078870e-2, 0.1373376462759619223985654e-2}, + {0.4157356944178127878299940e-1, 0.4146558103261909213524834e-1, 0.4128580808246718908346088e-1, 0.4103456181139210667622250e-1, 0.4071227717293733029875788e-1, 0.4031951210114157755817430e-1, 0.3985694654465635257596536e-1, 0.3932538128963516252076754e-1, 0.3872573657343257584146640e-1, 0.3805905049151360313563098e-1, 0.3732647720033209016730652e-1, 0.3652928491929033900685118e-1, 0.3566885373524045308911856e-1, 0.3474667321333040653509838e-1, 0.3376433981833409264695562e-1, 0.3272355415093422052152286e-1, 0.3162611800374964805603220e-1, 0.3047393124221453920313760e-1, 0.2926898851572598680503318e-1, 0.2801337580478054082525924e-1, 0.2670926681012085177235442e-1, 0.2535891919021637909420806e-1, 0.2396467065371695917476570e-1, 0.2252893491386577645054636e-1, 0.2105419751228284223644546e-1, 0.1954301152012788937957076e-1, 0.1799799312564505063794604e-1, 0.1642181711902464004359937e-1, 0.1481721228981446852013731e-1, 0.1318695676282480211961300e-1, 0.1153387332830449596681366e-1, 0.9860824916114018392051822e-2, 0.8170710707327826403717118e-2, 0.6466464907037538401963982e-2, 0.4751069185015273965898868e-2, 0.3027671014606041291230134e-2, 0.1301591717375855993899257e-2}, + {0.4050253572678803195524960e-1, 0.4040269003221775617032620e-1, 0.4023646282485108419526524e-1, 0.4000412721559123741035150e-1, 0.3970606493128931068103760e-1, 0.3934276568757015193713232e-1, 0.3891482638423378562103292e-1, 0.3842295012455452367368120e-1, 0.3786794506008932026166678e-1, 0.3725072306289371887876038e-1, 0.3657229822732745453345840e-1, 0.3583378520391196260264276e-1, 0.3503639736797827845487748e-1, 0.3418144482611567926531782e-1, 0.3327033226369854530283962e-1, 0.3230455663703097559357210e-1, 0.3128570471390543339395640e-1, 0.3021545046662299869139892e-1, 0.2909555232176876134870268e-1, 0.2792785027127696854150716e-1, 0.2671426284955789083200264e-1, 0.2545678398169440375263742e-1, 0.2415747970795584494059388e-1, 0.2281848479012952051290956e-1, 0.2144199920545613550512462e-1, 0.2003028453431617639624646e-1, 0.1858566024834148550917969e-1, 0.1711049990653110417623953e-1, 0.1560722726874913129508073e-1, 0.1407831234002700405016720e-1, 0.1252626736922736518735940e-1, 0.1095364285391135423859170e-1, 0.9363023692386430769260798e-2, 0.7757025950083070731841176e-2, 0.6138296159756341839268696e-2, 0.4509523600205835333238688e-2, 0.2873553083652691657275240e-2, 0.1235291177139409614163874e-2}, + {0.3948525740129116475372166e-1, 0.3939275600474300393426418e-1, 0.3923874749659464355491890e-1, 0.3902347234287979602650502e-1, 0.3874726667023996706818530e-1, 0.3841056174110417740541666e-1, 0.3801388328032604954551756e-1, 0.3755785065432977047790708e-1, 0.3704317590404678415983790e-1, 0.3647066263315342752925638e-1, 0.3584120475334575228920704e-1, 0.3515578508861113112825058e-1, 0.3441547384067660088259166e-1, 0.3362142691803093004992252e-1, 0.3277488413113081785342150e-1, 0.3187716725661117036051890e-1, 0.3092967797352483528829388e-1, 0.2993389567483836289564858e-1, 0.2889137515760726678163634e-1, 0.2780374419544705894443552e-1, 0.2667270099710555653788310e-1, 0.2550001155512877394733978e-1, 0.2428750688879949263942200e-1, 0.2303708018571902627697914e-1, 0.2175068384660807976864198e-1, 0.2043032643814085987844290e-1, 0.1907806955893748858478357e-1, 0.1769602462431041786466318e-1, 0.1628634957619168209183741e-1, 0.1485124552635006931857919e-1, 0.1339295334482567619730830e-1, 0.1191375021511699869960077e-1, 0.1041594620451338257918368e-1, 0.8901880982652486253740074e-2, 0.7373921131330176830391914e-2, 0.5834459868763465589211910e-2, 0.4285929113126531218219446e-2, 0.2730907065754855918535274e-2, 0.1173930129956613021207112e-2}, + {0.3851778959688469523783810e-1, 0.3843192958037517210025656e-1, 0.3828897129558352443032002e-1, 0.3808912713547560183102332e-1, 0.3783269400830055924757518e-1, 0.3752005289647583785923924e-1, 0.3715166829056371214474266e-1, 0.3672808749918043951690600e-1, 0.3624993983586341279832570e-1, 0.3571793568410456853072614e-1, 0.3513286544193937941597898e-1, 0.3449559834765979589474544e-1, 0.3380708118839624555119598e-1, 0.3306833689348800442087536e-1, 0.3228046301473268887240310e-1, 0.3144463009577406641803652e-1, 0.3056207993305266189565968e-1, 0.2963412373090559765847516e-1, 0.2866214015356067622579182e-1, 0.2764757327692492691108618e-1, 0.2659193044321992109092004e-1, 0.2549678002166567706947970e-1, 0.2436374907856309733249090e-1, 0.2319452096027391988145570e-1, 0.2199083279275163277050144e-1, 0.2075447290144560853952252e-1, 0.1948727815560191821592671e-1, 0.1819113124125576115176324e-1, 0.1686795786763513947433495e-1, 0.1551972391246436293824549e-1, 0.1414843251323606554825229e-1, 0.1275612111513442100025550e-1, 0.1134485849541625576200880e-1, 0.9916741809595875499750926e-2, 0.8473893785345565449616918e-2, 0.7018460484931625511609624e-2, 0.5552611370256278902273182e-2, 0.4078551113421395586018386e-2, 0.2598622299928953013499446e-2, 0.1117029847124606606122469e-2}, + {0.3759656394395517759196934e-1, 0.3751672450373727271505762e-1, 0.3738378433575740441091762e-1, 0.3719793160197673054400130e-1, 0.3695942935618497107975802e-1, 0.3666861517167809004390068e-1, 0.3632590066346228889989584e-1, 0.3593177090566064734733082e-1, 0.3548678374494710264584324e-1, 0.3499156901097965473152462e-1, 0.3444682762495051683252180e-1, 0.3385333060751519869931002e-1, 0.3321191798750501518117324e-1, 0.3252349761296806599129116e-1, 0.3178904386622215064354856e-1, 0.3100959628473919484306724e-1, 0.3018625808981441705410184e-1, 0.2932019462510452791804122e-1, 0.2841263170724764156375054e-1, 0.2746485389090326123892810e-1, 0.2647820265067376248510830e-1, 0.2545407448248949675081806e-1, 0.2439391892715855749743432e-1, 0.2329923651890054937016126e-1, 0.2217157666180362262199056e-1, 0.2101253543726991787400918e-1, 0.1982375334565493904931242e-1, 0.1860691298547847284166721e-1, 0.1736373667382462235016547e-1, 0.1609598401193537091543832e-1, 0.1480544940071787768084914e-1, 0.1349395951237523498069998e-1, 0.1216337072779861206303406e-1, 0.1081556655803715872036043e-1, 0.9452455092479699888244178e-2, 0.8075966593123452283593892e-2, 0.6688051635243685741358420e-2, 0.5290681445859865555240374e-2, 0.3885859435353202192003776e-2, 0.2475719322545939743331242e-2, 0.1064168219666567756385077e-2}, + {0.3671834473341961622215226e-1, 0.3664397593378570248640692e-1, 0.3652013948874488485747660e-1, 0.3634700257169520376675674e-1, 0.3612479890936246037475190e-1, 0.3585382846628081255691520e-1, 0.3553445703985569908199156e-1, 0.3516711576655578824981280e-1, 0.3475230053990063752924744e-1, 0.3429057134102984670822224e-1, 0.3378255148275753033131186e-1, 0.3322892676813276976252854e-1, 0.3263044456464217818903764e-1, 0.3198791279530467445976990e-1, 0.3130219884802087044839684e-1, 0.3057422840464999572392432e-1, 0.2980498419139588737561256e-1, 0.2899550465219015208986610e-1, 0.2814688254686507584638292e-1, 0.2726026347601116478577010e-1, 0.2633684433451435982173160e-1, 0.2537787169586608847736972e-1, 0.2438464012943568314241580e-1, 0.2335849045298989189769872e-1, 0.2230080792283937418945736e-1, 0.2121302036408937967241628e-1, 0.2009659624357542174179408e-1, 0.1895304268818284044680496e-1, 0.1778390345139817090774314e-1, 0.1659075683115467007520452e-1, 0.1537521354238962687440865e-1, 0.1413891454840083293055609e-1, 0.1288352885649808429050626e-1, 0.1161075128670389800962475e-1, 0.1032230023052424589381722e-1, 0.9019915439993631278967098e-2, 0.7705355960382757079897960e-2, 0.6380398587897515098686098e-2, 0.5046838426924442725450432e-2, 0.3706500125759316706868292e-2, 0.2361331704285020896763904e-2, 0.1014971908967743695374167e-2}, + {0.3588019106018701587773518e-1, 0.3581080434383374175662560e-1, 0.3569525919440943377647946e-1, 0.3553370454416059391133478e-1, 0.3532634862941021369843054e-1, 0.3507345872215153655662536e-1, 0.3477536078554782924871120e-1, 0.3443243905378224376593820e-1, 0.3404513553679937345518354e-1, 0.3361394945057693558422230e-1, 0.3313943657366202353628890e-1, 0.3262220853080144392580048e-1, 0.3206293200458966777765818e-1, 0.3146232787615076393796228e-1, 0.3082117029596223415371898e-1, 0.3014028568601882474395096e-1, 0.2942055167462304824922484e-1, 0.2866289596517621838858744e-1, 0.2786829514042920598963448e-1, 0.2703777340373580728397710e-1, 0.2617240125893355894972542e-1, 0.2527329413055707316411874e-1, 0.2434161092616763233921348e-1, 0.2337855254266017225782364e-1, 0.2238536031848547821419758e-1, 0.2136331443380253159361604e-1, 0.2031373226065556952656956e-1, 0.1923796666535655878505047e-1, 0.1813740426535425205021816e-1, 0.1701346364300153443364516e-1, 0.1586759351882631900292224e-1, 0.1470127088723984222989451e-1, 0.1351599911824565808188095e-1, 0.1231330603004803654228712e-1, 0.1109474194056071927972064e-1, 0.9861877713701826716584494e-2, 0.8616302838488951832949878e-2, 0.7359623648818063660769462e-2, 0.6093462047634872130101964e-2, 0.4819456238501885899307624e-2, 0.3539271655388628540179688e-2, 0.2254690753752853092482060e-2, 0.9691097381770753376096654e-3}, + {0.3507942401790202531716760e-1, 0.3501458416619644336915306e-1, 0.3490660650856070989101148e-1, 0.3475562407298142092081152e-1, 0.3456182286913780813643384e-1, 0.3432544165923908781796544e-1, 0.3404677166387108716735582e-1, 0.3372615620321457070630952e-1, 0.3336399027407732093971928e-1, 0.3296072006326111707429234e-1, 0.3251684239786320696758578e-1, 0.3203290413318958550703170e-1, 0.3150950147903428365879858e-1, 0.3094727926515484478947892e-1, 0.3034693014684912934340756e-1, 0.2970919375161245962730194e-1, 0.2903485576792681183001942e-1, 0.2832474697730520722803496e-1, 0.2757974223078458253347716e-1, 0.2680075937112917771256550e-1, 0.2598875810207383625148160e-1, 0.2514473880600256862281534e-1, 0.2426974131152233927366188e-1, 0.2336484361245544582716880e-1, 0.2243116053983636712835892e-1, 0.2146984238856114084341254e-1, 0.2048207350040027021224486e-1, 0.1946907080515187313867415e-1, 0.1843208232178411567584622e-1, 0.1737238562150240166964102e-1, 0.1629128625479238457754130e-1, 0.1519011614466612339747308e-1, 0.1407023194864448281388687e-1, 0.1293301339260267729158710e-1, 0.1177986158087489217661933e-1, 0.1061219728997218803268093e-1, 0.9431459260797890539711922e-2, 0.8239102525389078730572362e-2, 0.7036596870989114137389446e-2, 0.5825425788770107459644064e-2, 0.4607087343463241433054622e-2, 0.3383104792407455132632698e-2, 0.2155112582219113764637582e-2, 0.9262871051934728155239026e-3}, + {0.3431359817623139857242020e-1, 0.3425291647165106006719224e-1, 0.3415185977541012618567448e-1, 0.3401054720622907866548866e-1, 0.3382914533369793579365620e-1, 0.3360786798193575310982430e-1, 0.3334697597754983863697838e-1, 0.3304677684219179120016898e-1, 0.3270762443007278294842040e-1, 0.3232991851086539448409380e-1, 0.3191410429848369728859888e-1, 0.3146067192629708854519032e-1, 0.3097015586939654421561894e-1, 0.3044313431459439490344712e-1, 0.2988022847890037493277136e-1, 0.2928210187727747971826382e-1, 0.2864945954054102439649608e-1, 0.2798304718432316638118606e-1, 0.2728365033008298027898986e-1, 0.2655209337919890810307922e-1, 0.2578923864123601618879028e-1, 0.2499598531753495743256148e-1, 0.2417326844132287942221788e-1, 0.2332205777559880283599600e-1, 0.2244335667009737337332098e-1, 0.2153820087868566629622426e-1, 0.2060765733859846074045938e-1, 0.1965282291296914660474199e-1, 0.1867482309816812542178599e-1, 0.1767481069752190506037194e-1, 0.1665396446306124017225753e-1, 0.1561348770705005975095101e-1, 0.1455460688520869608484063e-1, 0.1347857015383097919431856e-1, 0.1238664590355674305453526e-1, 0.1128012127376968298340906e-1, 0.1016030065441547672889225e-1, 0.9028504189234487748913298e-2, 0.7886066314628901599629988e-2, 0.6734334432268884665261132e-2, 0.5574668047479788997832340e-2, 0.4408439747302676819065170e-2, 0.3237045507972104977098260e-2, 0.2061987122032229660677942e-2, 0.8862412406694141765769646e-3}, + {0.3358047670273290820423322e-1, 0.3352360509236689973246714e-1, 0.3342889041048296629425518e-1, 0.3329643957561578934524218e-1, 0.3312640210470322597293962e-1, 0.3291896994430459113247722e-1, 0.3267437725392241575486392e-1, 0.3239290014167229270630344e-1, 0.3207485635259921958171598e-1, 0.3172060490999230883258760e-1, 0.3133054571010280192591498e-1, 0.3090511907072293590876800e-1, 0.3044480523413530949647580e-1, 0.2995012382499392416587776e-1, 0.2942163326374897748551588e-1, 0.2885993013627770636290672e-1, 0.2826564852043306435742870e-1, 0.2763945927027071971311622e-1, 0.2698206925876273304878794e-1, 0.2629422057985327475229788e-1, 0.2557668971075783892217594e-1, 0.2483028663545258189183534e-1, 0.2405585393034465615306556e-1, 0.2325426581315775168991978e-1, 0.2242642715610957188910656e-1, 0.2157327246449981801505782e-1, 0.2069576482186873448858912e-1, 0.1979489480292792866805571e-1, 0.1887167935550803461442971e-1, 0.1792716065281371317885285e-1, 0.1696240491732901090122756e-1, 0.1597850121778211678831695e-1, 0.1497656024067188095391932e-1, 0.1395771303800797072406999e-1, 0.1292310975318535045602668e-1, 0.1187391832744712509861298e-1, 0.1081132319054248938202577e-1, 0.9736523941887687826947068e-2, 0.8650734035428648314139846e-2, 0.7555179500769820751618632e-2, 0.6451097794311275889059324e-2, 0.5339737098169214613757504e-2, 0.4222357382406607998634106e-2, 0.3100240403099316775464478e-2, 0.1974768768686808388940061e-2, 0.8487371680679110048896640e-3}, + {0.3287800959763194823557646e-1, 0.3282463569369918669308888e-1, 0.3273574336068393226919658e-1, 0.3261142878598215425670652e-1, 0.3245182648620325926685946e-1, 0.3225710916161441434734840e-1, 0.3202748750926769529295728e-1, 0.3176320999501228029097900e-1, 0.3146456258463840201321734e-1, 0.3113186843444399825682258e-1, 0.3076548754155891475295788e-1, 0.3036581635440506677724356e-1, 0.2993328734371411225240016e-1, 0.2946836853456688237515152e-1, 0.2897156299996101153484194e-1, 0.2844340831645486261311894e-1, 0.2788447598247691424309350e-1, 0.2729537079993022266578380e-1, 0.2667673021976135431896846e-1, 0.2602922365220227153290076e-1, 0.2535355174243201293660006e-1, 0.2465044561244261997612948e-1, 0.2392066606993061007707546e-1, 0.2316500278507139174920030e-1, 0.2238427343606939184041926e-1, 0.2157932282441140120676856e-1, 0.2075102196078490181790884e-1, 0.1990026712265721124487174e-1, 0.1902797888454570639306994e-1, 0.1813510112204514410759734e-1, 0.1722259999071698441334003e-1, 0.1629146288099104326591566e-1, 0.1534269735028835663459242e-1, 0.1437733003365908208357459e-1, 0.1339640553436828544136536e-1, 0.1240098529611606104018197e-1, 0.1139214645908584403924275e-1, 0.1037098070311609684083942e-1, 0.9338593083876397086740596e-2, 0.8296100874530990238145090e-2, 0.7244632443933199672626606e-2, 0.6185326261033323769312750e-2, 0.5119330329927718280032034e-2, 0.4047803316371759906879922e-2, 0.2971924240818190718436604e-2, 0.1892968377922935762776147e-2, 0.8135642494541165010544716e-3}, + {0.3220431459661350533475748e-1, 0.3215415737958550153577998e-1, 0.3207061987527279934927952e-1, 0.3195378880670864194528382e-1, 0.3180378546007149044495368e-1, 0.3162076555877401604294910e-1, 0.3140491910180172362457798e-1, 0.3115647016646904145775102e-1, 0.3087567667579765382432642e-1, 0.3056283013075858386135104e-1, 0.3021825530765601453452082e-1, 0.2984230992096702903457814e-1, 0.2943538425198732086424294e-1, 0.2899790074366843187205222e-1, 0.2853031356206718751823808e-1, 0.2803310812486267752680532e-1, 0.2750680059743034256009616e-1, 0.2695193735699644067363378e-1, 0.2636909442542934975707846e-1, 0.2575887687125678489535242e-1, 0.2512191818153004673565192e-1, 0.2445887960418784729059960e-1, 0.2377044946160306882104198e-1, 0.2305734243602599579639616e-1, 0.2232029882766713237862322e-1, 0.2156008378619171827843500e-1, 0.2077748651642656849799008e-1, 0.1997331945910804688818908e-1, 0.1914841744752812933525703e-1, 0.1830363684096414082229124e-1, 0.1743985463580780463940516e-1, 0.1655796755534245662902801e-1, 0.1565889111915692052020687e-1, 0.1474355869323695017635984e-1, 0.1381292052185304327114855e-1, 0.1286794274249338667571135e-1, 0.1190960638533075683273654e-1, 0.1093890635919594895396767e-1, 0.9956850427084044948237490e-2, 0.8964458176697999432566250e-2, 0.7962759997865495595598110e-2, 0.6952796096469405526464256e-2, 0.5935615630788222954183688e-2, 0.4912276262166028130833504e-2, 0.3883845329489294421733034e-2, 0.2851409243213055771419126e-2, 0.1816146398210039609502983e-2, 0.7805332219425612457264822e-3}, + {0.3155766036791122885809208e-1, 0.3151046648162834771323796e-1, 0.3143186227722154616152128e-1, 0.3132192610907518012817474e-1, 0.3118076756395815837033438e-1, 0.3100852735178559535833486e-1, 0.3080537716535627949917920e-1, 0.3057151950920577999218210e-1, 0.3030718749774580397961262e-1, 0.3001264462289103447190280e-1, 0.2968818449140509844801766e-1, 0.2933413053222750347643324e-1, 0.2895083567407331040373860e-1, 0.2853868199362694972663692e-1, 0.2809808033468091126593440e-1, 0.2762946989859901232207604e-1, 0.2713331780651255092639320e-1, 0.2661011863368585130179228e-1, 0.2606039391651548254092866e-1, 0.2548469163265475465058230e-1, 0.2488358565478194644598738e-1, 0.2425767517855707823164026e-1, 0.2360758412533789404661778e-1, 0.2293396052025105528408320e-1, 0.2223747584623937158435550e-1, 0.2151882437473022381824646e-1, 0.2077872247359421120742490e-1, 0.2001790789308656620794778e-1, 0.1923713903048718479867380e-1, 0.1843719417417849927098560e-1, 0.1761887072792438050675710e-1, 0.1678298441613870708950299e-1, 0.1593036847096084971103802e-1, 0.1506187280199023331295260e-1, 0.1417836314957944606614279e-1, 0.1328072022265728347995425e-1, 0.1236983882217516210343368e-1, 0.1144662695149825376113323e-1, 0.1051200491552474540574917e-1, 0.9566904411326136356898158e-2, 0.8612267615478888991732218e-2, 0.7649046279335257935390770e-2, 0.6678200860575098165183170e-2, 0.5700699773395926875152328e-2, 0.4717519037520830079689318e-2, 0.3729643487243034749198276e-2, 0.2738075873626878091327392e-2, 0.1743906958219244938639563e-2, 0.7494736467374053633626714e-3}, +} + +// The factor in front of the direct product representation +var cl = [...]float64{1.0, 1.0, -0.5000000000000000000000000e0, -0.1500000000000000000000000e1, 0.3750000000000000000000000e0, 0.1875000000000000000000000e1, -0.3125000000000000000000000e0, -0.2187500000000000000000000e1, 0.2734375000000000000000000e0, 0.2460937500000000000000000e1, -0.2460937500000000000000000e0, -0.2707031250000000000000000e1, 0.2255859375000000000000000e0, 0.2932617187500000000000000e1, -0.2094726562500000000000000e0, -0.3142089843750000000000000e1, 0.1963806152343750000000000e0, 0.3338470458984375000000000e1, -0.1854705810546875000000000e0, -0.3523941040039062500000000e1, 0.1761970520019531250000000e0, 0.3700138092041015625000000e1, -0.1681880950927734375000000e0, -0.3868326187133789062500000e1, 0.1611802577972412109375000e0, 0.4029506444931030273437500e1, -0.1549810171127319335937500e0, -0.4184487462043762207031250e1, 0.1494459807872772216796875e0, 0.4333933442831039428710938e1, -0.1444644480943679809570312e0, -0.4478397890925407409667969e1, 0.1399499340914189815521240e0, 0.4618347825016826391220093e1, -0.1358337595593184232711792e0, -0.4754181584576144814491272e1, 0.1320605995715595781803131e0, 0.4886242184147704392671585e1, -0.1285853206354659050703049e0, -0.5014827504783170297741890e1, 0.1253706876195792574435472e0, 0.5140198192402749555185437e1, -0.1223856712476845132187009e0, -0.5262583863650434068404138e1, 0.1196041787193280470091850e0, 0.5382188042369762115413323e1, -0.1170040878776035242481157e0, -0.5499192130247365639661439e1, 0.1145665027134867841596133e0, 0.5613758632960852423821052e1, -0.1122751726592170484764210e0, -0.5726033805620069472297473e1, 0.1101160347234628744672591e0, 0.5836149840343532346764732e1, -0.1080768488952505990141617e0, -0.5944226689238782945778894e1, 0.1061469051649782668889088e0, 0.6050373594403761212667803e1, -0.1043167861104096760804794e0, -0.6154690380514170888748282e1, 0.1025781730085695148124714e0, 0.6257268553522740403560753e1, -0.1009236863471409742509799e0, -0.6358192239869881377811733e1, 0.9934675374796689652830833e-1, 0.6457538993617848274340042e1, -0.9784149990330073142939457e-1, -0.6555380493521149005769436e1, 0.9640265431648748537896230e-1, 0.6651783147837636491148399e1, -0.9502547354053766415926284e-1, -0.6746808621378174155307661e1, 0.9370567529691908549038419e-1, 0.6840514296675093240798046e1, -0.9243938238750126001078440e-1, -0.6932953679062594500808830e1, 0.9122307472450782237906355e-1, 0.7024176753787102323187894e1, -0.9005354812547567081010120e-1, -0.7114230301912577993997995e1, 0.8892787877390722492497493e-1, 0.7203158180686485218922970e1, -0.8784339244739616120637768e-1, -0.7291001573133881380129347e1, 0.8679763777540334976344461e-1, 0.7377799210909284729892792e1, -0.8578836291754982244061386e-1, -0.7463587573826834552333406e1, 0.8481349515712311991287961e-1, 0.7548401068983957672246285e1, -0.8387112298871064080273650e-1, -0.7632272191972668313049022e1, 0.8295948034752900340270676e-1, 0.7715231672320197316451729e1, -0.8207693268425741826012477e-1, -0.7797308605004454734711853e1, 0.8122196463546307015324847e-1, 0.7878530569639917804865102e1, -0.8039316907795834494760308e-1, -0.7958923738717876149812705e1, 0.7958923738717876149812705e-1} diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/legendre_test.go b/vendor/gonum.org/v1/gonum/integrate/quad/legendre_test.go new file mode 100644 index 00000000..7fb5bb09 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/legendre_test.go @@ -0,0 +1,84 @@ +// 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 quad + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestLegendre(t *testing.T) { + for i, test := range []struct { + f func(float64) float64 + min, max float64 + n []int + tol []float64 + ans float64 + }{ + // Tolerances determined from intuition and a bit of post-hoc tweaking. + { + f: func(x float64) float64 { return math.Exp(x) }, + min: -3, + max: 5, + n: []int{3, 4, 6, 7, 15, 16, 300, 301}, + tol: []float64{5e-2, 5e-3, 5e-6, 1e-7, 1e-14, 1e-14, 1e-14, 1e-14}, + ans: math.Exp(5) - math.Exp(-3), + }, + } { + for j, n := range test.n { + ans := Fixed(test.f, test.min, test.max, n, Legendre{}, 0) + if !floats.EqualWithinAbsOrRel(ans, test.ans, test.tol[j], test.tol[j]) { + t.Errorf("Mismatch. Case = %d, n = %d. Want %v, got %v", i, n, test.ans, ans) + } + ans2 := Fixed(test.f, test.min, test.max, n, Legendre{}, 3) + if !floats.EqualWithinAbsOrRel(ans2, test.ans, test.tol[j], test.tol[j]) { + t.Errorf("Mismatch concurrent. Case = %d, n = %d. Want %v, got %v", i, n, test.ans, ans) + } + } + } +} + +func TestLegendreSingle(t *testing.T) { + for c, test := range []struct { + n int + min, max float64 + }{ + { + n: 100, + min: -1, + max: 1, + }, + { + n: 50, + min: -3, + max: -1, + }, + { + n: 1000, + min: 2, + max: 7, + }, + } { + l := Legendre{} + n := test.n + xs := make([]float64, n) + weights := make([]float64, n) + l.FixedLocations(xs, weights, test.min, test.max) + + xsSingle := make([]float64, n) + weightsSingle := make([]float64, n) + for i := range xsSingle { + xsSingle[i], weightsSingle[i] = l.FixedLocationSingle(n, i, test.min, test.max) + } + if !floats.Equal(xs, xsSingle) { + t.Errorf("Case %d: xs mismatch batch and single", c) + } + if !floats.Equal(weights, weightsSingle) { + t.Errorf("Case %d: weights mismatch batch and single", c) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/quad.go b/vendor/gonum.org/v1/gonum/integrate/quad/quad.go new file mode 100644 index 00000000..d222641c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/quad.go @@ -0,0 +1,157 @@ +// 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 quad + +import ( + "math" + "sync" +) + +// FixedLocationer computes a set of quadrature locations and weights and stores +// them in-place into x and weight respectively. The number of points generated is equal to +// the len(x). The weights and locations should be chosen such that +// int_min^max f(x) dx ≈ \sum_i w_i f(x_i) +type FixedLocationer interface { + FixedLocations(x, weight []float64, min, max float64) +} + +// FixedLocationSingle returns the location and weight for element k in a +// fixed quadrature rule with n total samples and integral bounds from min to max. +type FixedLocationSingler interface { + FixedLocationSingle(n, k int, min, max float64) (x, weight float64) +} + +// Fixed approximates the integral of the function f from min to max using a fixed +// n-point quadrature rule. During evaluation, f will be evaluated n times using +// the weights and locations specified by rule. That is, Fixed estimates +// int_min^max f(x) dx ≈ \sum_i w_i f(x_i) +// If rule is nil, an acceptable default is chosen, otherwise it is +// assumed that the properties of the integral match the assumptions of rule. +// For example, Legendre assumes that the integration bounds are finite. If +// rule is also a FixedLocationSingler, the quadrature points are computed +// individually rather than as a unit. +// +// If concurrent <= 0, f is evaluated serially, while if concurrent > 0, f +// may be evaluated with at most concurrent simultaneous evaluations. +// +// min must be less than or equal to max, and n must be positive, otherwise +// Fixed will panic. +func Fixed(f func(float64) float64, min, max float64, n int, rule FixedLocationer, concurrent int) float64 { + // TODO(btracey): When there are Hermite polynomial quadrature, add an additional + // example to the documentation comment that talks about weight functions. + if n <= 0 { + panic("quad: non-positive number of locations") + } + if min > max { + panic("quad: min > max") + } + if min == max { + return 0 + } + intfunc := f + // If rule is non-nil it is assumed that the function and the constraints + // of rule are aligned. If it is nil, wrap the function and do something + // reasonable. + // TODO(btracey): Replace wrapping with other quadrature rules when + // we have rules that support infinite-bound integrals. + if rule == nil { + // int_a^b f(x)dx = int_u^-1(a)^u^-1(b) f(u(t))u'(t)dt + switch { + case math.IsInf(max, 1) && math.IsInf(min, -1): + // u(t) = (t/(1-t^2)) + min = -1 + max = 1 + intfunc = func(x float64) float64 { + v := 1 - x*x + return f(x/v) * (1 + x*x) / (v * v) + } + case math.IsInf(max, 1): + // u(t) = a + t / (1-t) + a := min + min = 0 + max = 1 + intfunc = func(x float64) float64 { + v := 1 - x + return f(a+x/v) / (v * v) + } + case math.IsInf(min, -1): + // u(t) = a - (1-t)/t + a := max + min = 0 + max = 1 + intfunc = func(x float64) float64 { + return f(a-(1-x)/x) / (x * x) + } + } + rule = Legendre{} + } + singler, isSingler := rule.(FixedLocationSingler) + + var xs, weights []float64 + if !isSingler { + xs = make([]float64, n) + weights = make([]float64, n) + rule.FixedLocations(xs, weights, min, max) + } + + if concurrent > n { + concurrent = n + } + + if concurrent <= 0 { + var integral float64 + // Evaluate in serial. + if isSingler { + for k := 0; k < n; k++ { + x, weight := singler.FixedLocationSingle(n, k, min, max) + integral += weight * intfunc(x) + } + return integral + } + for i, x := range xs { + integral += weights[i] * intfunc(x) + } + return integral + } + + // Evaluate concurrently + tasks := make(chan int) + + // Launch distributor + go func() { + for i := 0; i < n; i++ { + tasks <- i + } + close(tasks) + }() + + var mux sync.Mutex + var integral float64 + var wg sync.WaitGroup + wg.Add(concurrent) + for i := 0; i < concurrent; i++ { + // Launch workers + go func() { + defer wg.Done() + var subIntegral float64 + for k := range tasks { + var x, weight float64 + if isSingler { + x, weight = singler.FixedLocationSingle(n, k, min, max) + } else { + x = xs[k] + weight = weights[k] + } + f := intfunc(x) + subIntegral += f * weight + } + mux.Lock() + integral += subIntegral + mux.Unlock() + }() + } + wg.Wait() + return integral +} diff --git a/vendor/gonum.org/v1/gonum/integrate/quad/quad_test.go b/vendor/gonum.org/v1/gonum/integrate/quad/quad_test.go new file mode 100644 index 00000000..5e25ffdd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/quad/quad_test.go @@ -0,0 +1,126 @@ +// 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 quad + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/stat/distuv" +) + +func TestFixed(t *testing.T) { + for i, test := range []struct { + f func(float64) float64 + min, max float64 + n []int + tol []float64 + ans float64 + }{ + // Tolerances determined from intuition and a bit of post-hoc tweaking. + { + f: func(x float64) float64 { return math.Exp(x) }, + min: -3, + max: 5, + n: []int{3, 4, 6, 7, 15, 16, 300, 301}, + tol: []float64{5e-2, 5e-3, 5e-6, 1e-7, 1e-14, 1e-14, 1e-14, 1e-14}, + ans: math.Exp(5) - math.Exp(-3), + }, + { + f: distuv.UnitNormal.Prob, + min: math.Inf(-1), + max: math.Inf(1), + n: []int{15, 16, 50, 51, 300, 301}, + tol: []float64{5e-3, 1e-3, 1e-7, 1e-7, 1e-14, 1e-14}, + ans: 1, + }, + { + f: func(x float64) float64 { return math.Exp(-x) }, + min: 5, + max: math.Inf(1), + n: []int{15, 16, 50, 51, 300, 301}, + tol: []float64{5e-3, 1e-3, 1e-7, 1e-7, 1e-14, 1e-14}, + ans: math.Exp(-5), + }, + { + f: func(x float64) float64 { return math.Exp(x) }, + min: math.Inf(-1), + max: -5, + n: []int{15, 16, 50, 51, 300, 301}, + tol: []float64{5e-3, 1e-3, 1e-7, 1e-7, 1e-14, 1e-14}, + ans: math.Exp(-5), + }, + { + f: func(x float64) float64 { return math.Exp(x) }, + min: 3, + max: 3, + n: []int{15, 16, 50, 51, 300, 301}, + tol: []float64{0, 0, 0, 0, 0, 0}, + ans: 0, + }, + } { + for j, n := range test.n { + ans := Fixed(test.f, test.min, test.max, n, nil, 0) + if !floats.EqualWithinAbsOrRel(ans, test.ans, test.tol[j], test.tol[j]) { + t.Errorf("Case %d, n = %d: Mismatch. Want %v, got %v", i, n, test.ans, ans) + } + ans2 := Fixed(test.f, test.min, test.max, n, nil, 3) + if !floats.EqualWithinAbsOrRel(ans2, test.ans, test.tol[j], test.tol[j]) { + t.Errorf("Case %d, n = %d: Mismatch concurrent. Want %v, got %v", i, n, test.ans, ans) + } + } + } +} + +// legendreNonSingle wraps Legendre but does not implement FixedLocationSingle. +type legendreNonSingle struct { + Legendre Legendre +} + +func (l legendreNonSingle) FixedLocations(x, weight []float64, min, max float64) { + l.Legendre.FixedLocations(x, weight, min, max) +} + +func TestFixedNonSingle(t *testing.T) { + // TODO(btracey): Add tests with infinite bounds when we have native support + // for indefinite integrals. + for i, test := range []struct { + f func(float64) float64 + min, max float64 + n []int + tol []float64 + ans float64 + }{ + // Tolerances determined from intuition and a bit of post-hoc tweaking. + { + f: func(x float64) float64 { return math.Exp(x) }, + min: -3, + max: 5, + n: []int{3, 4, 6, 7, 15, 16, 300, 301}, + tol: []float64{5e-2, 5e-3, 5e-6, 1e-7, 1e-14, 1e-14, 1e-14, 1e-14}, + ans: math.Exp(5) - math.Exp(-3), + }, + { + f: func(x float64) float64 { return math.Exp(x) }, + min: 3, + max: 3, + n: []int{3, 4, 6, 7, 15, 16, 300, 301}, + tol: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + ans: 0, + }, + } { + for j, n := range test.n { + ans := Fixed(test.f, test.min, test.max, n, legendreNonSingle{}, 0) + if !floats.EqualWithinAbsOrRel(ans, test.ans, test.tol[j], test.tol[j]) { + t.Errorf("Case = %d, n = %d: Mismatch. Want %v, got %v", i, n, test.ans, ans) + } + ans2 := Fixed(test.f, test.min, test.max, n, legendreNonSingle{}, 3) + if !floats.EqualWithinAbsOrRel(ans2, test.ans, test.tol[j], test.tol[j]) { + t.Errorf("Case = %d, n = %d: Mismatch concurrent. Want %v, got %v", i, n, test.ans, ans) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/integrate/trapezoidal.go b/vendor/gonum.org/v1/gonum/integrate/trapezoidal.go new file mode 100644 index 00000000..3f402ac3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/trapezoidal.go @@ -0,0 +1,40 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package integrate + +import "sort" + +// Trapezoidal estimates the integral of a function f +// \int_a^b f(x) dx +// from a set of evaluations of the function using the trapezoidal rule. +// The trapezoidal rule makes piecewise linear approximations to the function, +// and estimates +// \int_x[i]^x[i+1] f(x) dx +// as +// (x[i+1] - x[i]) * (f[i] + f[i+1])/2 +// where f[i] is the value of the function at x[i]. +// More details on the trapezoidal rule can be found at: +// https://en.wikipedia.org/wiki/Trapezoidal_rule +// +// The (x,f) input data points must be sorted along x. +// One can use github.com/gonum/stat.SortWeighted to do that. +// The x and f slices must be of equal length and have length > 1. +func Trapezoidal(x, f []float64) float64 { + switch { + case len(x) != len(f): + panic("integrate: slice length mismatch") + case len(x) < 2: + panic("integrate: input data too small") + case !sort.Float64sAreSorted(x): + panic("integrate: input must be sorted") + } + + integral := 0.0 + for i := 0; i < len(x)-1; i++ { + integral += 0.5 * (x[i+1] - x[i]) * (f[i+1] + f[i]) + } + + return integral +} diff --git a/vendor/gonum.org/v1/gonum/integrate/trapezoidal_test.go b/vendor/gonum.org/v1/gonum/integrate/trapezoidal_test.go new file mode 100644 index 00000000..c52ee0e6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/integrate/trapezoidal_test.go @@ -0,0 +1,82 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package integrate + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestTrapezoidal(t *testing.T) { + const N = 1e6 + x := floats.Span(make([]float64, N), 0, 1) + for i, test := range []struct { + x []float64 + f func(x float64) float64 + want float64 + }{ + { + x: x, + f: func(x float64) float64 { return x }, + want: 0.5, + }, + { + x: floats.Span(make([]float64, N), -1, 1), + f: func(x float64) float64 { return x }, + want: 0, + }, + { + x: x, + f: func(x float64) float64 { return x + 10 }, + want: 10.5, + }, + { + x: x, + f: func(x float64) float64 { return 3*x*x + 10 }, + want: 11, + }, + { + x: x, + f: func(x float64) float64 { return math.Exp(x) }, + want: 1.7182818284591876, + }, + { + x: floats.Span(make([]float64, N), 0, math.Pi), + f: func(x float64) float64 { return math.Cos(x) }, + want: 0, + }, + { + x: floats.Span(make([]float64, N), 0, 2*math.Pi), + f: func(x float64) float64 { return math.Cos(x) }, + want: 0, + }, + { + x: floats.Span(make([]float64, N*10), 0, math.Pi), + f: func(x float64) float64 { return math.Sin(x) }, + want: 2, + }, + { + x: floats.Span(make([]float64, N*10), 0, 0.5*math.Pi), + f: func(x float64) float64 { return math.Sin(x) }, + want: 1, + }, + { + x: floats.Span(make([]float64, N), 0, 2*math.Pi), + f: func(x float64) float64 { return math.Sin(x) }, + want: 0, + }, + } { + y := make([]float64, len(test.x)) + for i, v := range test.x { + y[i] = test.f(v) + } + v := Trapezoidal(test.x, y) + if !floats.EqualWithinAbs(v, test.want, 1e-12) { + t.Errorf("test #%d: got=%v want=%v\n", i, v, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/README.md b/vendor/gonum.org/v1/gonum/internal/README.md new file mode 100644 index 00000000..dd28a1f7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/README.md @@ -0,0 +1,3 @@ +# Gonum internal [![GoDoc](https://godoc.org/gonum.org/v1/gonum/internal?status.svg)](https://godoc.org/gonum.org/v1/gonum/internal) + +This is the set of internal packages for the Gonum project. diff --git a/vendor/gonum.org/v1/gonum/internal/asm/bench_gen.sh b/vendor/gonum.org/v1/gonum/internal/asm/bench_gen.sh new file mode 100755 index 00000000..e7115c07 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/bench_gen.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# Copyright ©2016 The gonum Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +cat c64/bench_test.go \ + | gofmt -r 'complex(float32(n), float32(n)) -> float32(n)' \ + | gofmt -r 'complex64 -> float32' \ + | gofmt -r '1 + 1i -> 1' \ + | gofmt -r '2 + 2i -> 2' \ + | sed 's/C64/F32/g' \ + | sed 's/c64/f32/g' \ + > f32/bench_test.go + +cat c64/bench_test.go \ + | gofmt -r 'complex(float32(n), float32(n)) -> float64(n)' \ + | gofmt -r 'complex64 -> float64' \ + | gofmt -r '1 + 1i -> 1' \ + | gofmt -r '2 + 2i -> 2' \ + | sed 's/C64/F64/g' \ + | sed 's/c64/f64/g' \ + > f64/bench_test.go + +cat c64/bench_test.go \ + | gofmt -r 'float32 -> float64' \ + | gofmt -r 'complex64 -> complex128' \ + | sed 's/C64/C128/g' \ + | sed 's/c64/c128/g' \ + > c128/bench_test.go diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyinc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyinc_amd64.s new file mode 100644 index 00000000..c66a667b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyinc_amd64.s @@ -0,0 +1,134 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVDDUP X2, X3 +#define MOVDDUP_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xDA +// MOVDDUP X4, X5 +#define MOVDDUP_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xEC +// MOVDDUP X6, X7 +#define MOVDDUP_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xFE +// MOVDDUP X8, X9 +#define MOVDDUP_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC8 + +// ADDSUBPD X2, X3 +#define ADDSUBPD_X2_X3 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA +// ADDSUBPD X4, X5 +#define ADDSUBPD_X4_X5 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC +// ADDSUBPD X6, X7 +#define ADDSUBPD_X6_X7 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE +// ADDSUBPD X8, X9 +#define ADDSUBPD_X8_X9 BYTE $0x66; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyInc(alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyInc(SB), NOSPLIT, $0 + MOVQ x_base+16(FP), SI // SI = &x + MOVQ y_base+40(FP), DI // DI = &y + MOVQ n+64(FP), CX // CX = n + CMPQ CX, $0 // if n==0 { return } + JE axpyi_end + MOVQ ix+88(FP), R8 // R8 = ix // Load the first index + SHLQ $4, R8 // R8 *= sizeof(complex128) + MOVQ iy+96(FP), R9 // R9 = iy + SHLQ $4, R9 // R9 *= sizeof(complex128) + LEAQ (SI)(R8*1), SI // SI = &(x[ix]) + LEAQ (DI)(R9*1), DI // DI = &(y[iy]) + MOVQ DI, DX // DX = DI // Separate Read/Write pointers + MOVQ incX+72(FP), R8 // R8 = incX + SHLQ $4, R8 // R8 *= sizeof(complex128) + MOVQ incY+80(FP), R9 // R9 = iy + SHLQ $4, R9 // R9 *= sizeof(complex128) + MOVUPS alpha+0(FP), X0 // X0 = { imag(a), real(a) } + MOVAPS X0, X1 + SHUFPD $0x1, X1, X1 // X1 = { real(a), imag(a) } + MOVAPS X0, X10 // Copy X0 and X1 for pipelining + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $3, CX // CX = n % 4 + SHRQ $2, BX // BX = floor( n / 4 ) + JZ axpyi_tail // if BX == 0 { goto axpyi_tail } + +axpyi_loop: // do { + MOVUPS (SI), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVUPS (SI)(R8*1), X4 + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + MOVUPS (SI), X6 + MOVUPS (SI)(R8*1), X8 + + // X_(i+1) = { real(x[i], real(x[i]) } + MOVDDUP_X2_X3 + MOVDDUP_X4_X5 + MOVDDUP_X6_X7 + MOVDDUP_X8_X9 + + // X_i = { imag(x[i]), imag(x[i]) } + SHUFPD $0x3, X2, X2 + SHUFPD $0x3, X4, X4 + SHUFPD $0x3, X6, X6 + SHUFPD $0x3, X8, X8 + + // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + MULPD X1, X2 + MULPD X0, X3 + MULPD X11, X4 + MULPD X10, X5 + MULPD X1, X6 + MULPD X0, X7 + MULPD X11, X8 + MULPD X10, X9 + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + ADDSUBPD_X4_X5 + ADDSUBPD_X6_X7 + ADDSUBPD_X8_X9 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DX), X3 + ADDPD (DX)(R9*1), X5 + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + ADDPD (DX), X7 + ADDPD (DX)(R9*1), X9 + MOVUPS X3, (DI) // dst[i] = X_(i+1) + MOVUPS X5, (DI)(R9*1) + LEAQ (DI)(R9*2), DI + MOVUPS X7, (DI) + MOVUPS X9, (DI)(R9*1) + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + LEAQ (DI)(R9*2), DI // DI = &(DI[incY*2]) + DECQ BX + JNZ axpyi_loop // } while --BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE axpyi_end + +axpyi_tail: // do { + MOVUPS (SI), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVDDUP_X2_X3 // X_(i+1) = { real(x[i], real(x[i]) } + SHUFPD $0x3, X2, X2 // X_i = { imag(x[i]), imag(x[i]) } + MULPD X1, X2 // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPD X0, X3 // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DI), X3 + MOVUPS X3, (DI) // y[i] = X_i + ADDQ R8, SI // SI = &(SI[incX]) + ADDQ R9, DI // DI = &(DI[incY]) + LOOP axpyi_tail // } while --CX > 0 + +axpyi_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyincto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyincto_amd64.s new file mode 100644 index 00000000..edc0957c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyincto_amd64.s @@ -0,0 +1,141 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVDDUP X2, X3 +#define MOVDDUP_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xDA +// MOVDDUP X4, X5 +#define MOVDDUP_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xEC +// MOVDDUP X6, X7 +#define MOVDDUP_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xFE +// MOVDDUP X8, X9 +#define MOVDDUP_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC8 + +// ADDSUBPD X2, X3 +#define ADDSUBPD_X2_X3 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA +// ADDSUBPD X4, X5 +#define ADDSUBPD_X4_X5 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC +// ADDSUBPD X6, X7 +#define ADDSUBPD_X6_X7 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE +// ADDSUBPD X8, X9 +#define ADDSUBPD_X8_X9 BYTE $0x66; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyIncTo(dst []complex128, incDst, idst uintptr, alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyIncTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ x_base+56(FP), SI // SI = &x + MOVQ y_base+80(FP), DX // DX = &y + MOVQ n+104(FP), CX // CX = n + CMPQ CX, $0 // if n==0 { return } + JE axpyi_end + MOVQ ix+128(FP), R8 // R8 = ix // Load the first index + SHLQ $4, R8 // R8 *= sizeof(complex128) + MOVQ iy+136(FP), R9 // R9 = iy + SHLQ $4, R9 // R9 *= sizeof(complex128) + MOVQ idst+32(FP), R10 // R10 = idst + SHLQ $4, R10 // R10 *= sizeof(complex128) + LEAQ (SI)(R8*1), SI // SI = &(x[ix]) + LEAQ (DX)(R9*1), DX // DX = &(y[iy]) + LEAQ (DI)(R10*1), DI // DI = &(dst[idst]) + MOVQ incX+112(FP), R8 // R8 = incX + SHLQ $4, R8 // R8 *= sizeof(complex128) + MOVQ incY+120(FP), R9 // R9 = incY + SHLQ $4, R9 // R9 *= sizeof(complex128) + MOVQ incDst+24(FP), R10 // R10 = incDst + SHLQ $4, R10 // R10 *= sizeof(complex128) + MOVUPS alpha+40(FP), X0 // X0 = { imag(a), real(a) } + MOVAPS X0, X1 + SHUFPD $0x1, X1, X1 // X1 = { real(a), imag(a) } + MOVAPS X0, X10 // Copy X0 and X1 for pipelining + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $3, CX // CX = n % 4 + SHRQ $2, BX // BX = floor( n / 4 ) + JZ axpyi_tail // if BX == 0 { goto axpyi_tail } + +axpyi_loop: // do { + MOVUPS (SI), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVUPS (SI)(R8*1), X4 + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + + MOVUPS (SI), X6 + MOVUPS (SI)(R8*1), X8 + + // X_(i+1) = { real(x[i], real(x[i]) } + MOVDDUP_X2_X3 + MOVDDUP_X4_X5 + MOVDDUP_X6_X7 + MOVDDUP_X8_X9 + + // X_i = { imag(x[i]), imag(x[i]) } + SHUFPD $0x3, X2, X2 + SHUFPD $0x3, X4, X4 + SHUFPD $0x3, X6, X6 + SHUFPD $0x3, X8, X8 + + // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + MULPD X1, X2 + MULPD X0, X3 + MULPD X11, X4 + MULPD X10, X5 + MULPD X1, X6 + MULPD X0, X7 + MULPD X11, X8 + MULPD X10, X9 + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + ADDSUBPD_X4_X5 + ADDSUBPD_X6_X7 + ADDSUBPD_X8_X9 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DX), X3 + ADDPD (DX)(R9*1), X5 + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + ADDPD (DX), X7 + ADDPD (DX)(R9*1), X9 + MOVUPS X3, (DI) // dst[i] = X_(i+1) + MOVUPS X5, (DI)(R10*1) + LEAQ (DI)(R10*2), DI + MOVUPS X7, (DI) + MOVUPS X9, (DI)(R10*1) + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + LEAQ (DI)(R10*2), DI // DI = &(DI[incDst*2]) + DECQ BX + JNZ axpyi_loop // } while --BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE axpyi_end + +axpyi_tail: // do { + MOVUPS (SI), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVDDUP_X2_X3 // X_(i+1) = { real(x[i], real(x[i]) } + SHUFPD $0x3, X2, X2 // X_i = { imag(x[i]), imag(x[i]) } + MULPD X1, X2 // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPD X0, X3 // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DX), X3 + MOVUPS X3, (DI) // y[i] X_(i+1) + ADDQ R8, SI // SI += incX + ADDQ R9, DX // DX += incY + ADDQ R10, DI // DI += incDst + LOOP axpyi_tail // } while --CX > 0 + +axpyi_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyunitary_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyunitary_amd64.s new file mode 100644 index 00000000..c9e119d3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyunitary_amd64.s @@ -0,0 +1,122 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVDDUP X2, X3 +#define MOVDDUP_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xDA +// MOVDDUP X4, X5 +#define MOVDDUP_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xEC +// MOVDDUP X6, X7 +#define MOVDDUP_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xFE +// MOVDDUP X8, X9 +#define MOVDDUP_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC8 + +// ADDSUBPD X2, X3 +#define ADDSUBPD_X2_X3 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA +// ADDSUBPD X4, X5 +#define ADDSUBPD_X4_X5 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC +// ADDSUBPD X6, X7 +#define ADDSUBPD_X6_X7 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE +// ADDSUBPD X8, X9 +#define ADDSUBPD_X8_X9 BYTE $0x66; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyUnitary(alpha complex128, x, y []complex128) +TEXT ·AxpyUnitary(SB), NOSPLIT, $0 + MOVQ x_base+16(FP), SI // SI = &x + MOVQ y_base+40(FP), DI // DI = &y + MOVQ x_len+24(FP), CX // CX = min( len(x), len(y) ) + CMPQ y_len+48(FP), CX + CMOVQLE y_len+48(FP), CX + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + PXOR X0, X0 // Clear work registers and cache-align loop + PXOR X1, X1 + MOVUPS alpha+0(FP), X0 // X0 = { imag(a), real(a) } + MOVAPS X0, X1 + SHUFPD $0x1, X1, X1 // X1 = { real(a), imag(a) } + XORQ AX, AX // i = 0 + MOVAPS X0, X10 // Copy X0 and X1 for pipelining + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $3, CX // CX = n % 4 + SHRQ $2, BX // BX = floor( n / 4 ) + JZ caxy_tail // if BX == 0 { goto caxy_tail } + +caxy_loop: // do { + MOVUPS (SI)(AX*8), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVUPS 16(SI)(AX*8), X4 + MOVUPS 32(SI)(AX*8), X6 + MOVUPS 48(SI)(AX*8), X8 + + // X_(i+1) = { real(x[i], real(x[i]) } + MOVDDUP_X2_X3 + MOVDDUP_X4_X5 + MOVDDUP_X6_X7 + MOVDDUP_X8_X9 + + // X_i = { imag(x[i]), imag(x[i]) } + SHUFPD $0x3, X2, X2 + SHUFPD $0x3, X4, X4 + SHUFPD $0x3, X6, X6 + SHUFPD $0x3, X8, X8 + + // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + MULPD X1, X2 + MULPD X0, X3 + MULPD X11, X4 + MULPD X10, X5 + MULPD X1, X6 + MULPD X0, X7 + MULPD X11, X8 + MULPD X10, X9 + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + ADDSUBPD_X4_X5 + ADDSUBPD_X6_X7 + ADDSUBPD_X8_X9 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DI)(AX*8), X3 + ADDPD 16(DI)(AX*8), X5 + ADDPD 32(DI)(AX*8), X7 + ADDPD 48(DI)(AX*8), X9 + MOVUPS X3, (DI)(AX*8) // y[i] = X_(i+1) + MOVUPS X5, 16(DI)(AX*8) + MOVUPS X7, 32(DI)(AX*8) + MOVUPS X9, 48(DI)(AX*8) + ADDQ $8, AX // i += 8 + DECQ BX + JNZ caxy_loop // } while --BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + +caxy_tail: // do { + MOVUPS (SI)(AX*8), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVDDUP_X2_X3 // X_(i+1) = { real(x[i], real(x[i]) } + SHUFPD $0x3, X2, X2 // X_i = { imag(x[i]), imag(x[i]) } + MULPD X1, X2 // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPD X0, X3 // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DI)(AX*8), X3 + MOVUPS X3, (DI)(AX*8) // y[i] = X_(i+1) + ADDQ $2, AX // i += 2 + LOOP caxy_tail // } while --CX > 0 + +caxy_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyunitaryto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyunitaryto_amd64.s new file mode 100644 index 00000000..9dcfc67e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/axpyunitaryto_amd64.s @@ -0,0 +1,123 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVDDUP X2, X3 +#define MOVDDUP_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xDA +// MOVDDUP X4, X5 +#define MOVDDUP_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xEC +// MOVDDUP X6, X7 +#define MOVDDUP_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0x12; BYTE $0xFE +// MOVDDUP X8, X9 +#define MOVDDUP_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC8 + +// ADDSUBPD X2, X3 +#define ADDSUBPD_X2_X3 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA +// ADDSUBPD X4, X5 +#define ADDSUBPD_X4_X5 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC +// ADDSUBPD X6, X7 +#define ADDSUBPD_X6_X7 BYTE $0x66; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE +// ADDSUBPD X8, X9 +#define ADDSUBPD_X8_X9 BYTE $0x66; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyUnitaryTo(dst []complex128, alpha complex64, x, y []complex128) +TEXT ·AxpyUnitaryTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ x_base+40(FP), SI // SI = &x + MOVQ y_base+64(FP), DX // DX = &y + MOVQ x_len+48(FP), CX // CX = min( len(x), len(y), len(dst) ) + CMPQ y_len+72(FP), CX + CMOVQLE y_len+72(FP), CX + CMPQ dst_len+8(FP), CX + CMOVQLE dst_len+8(FP), CX + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + MOVUPS alpha+24(FP), X0 // X0 = { imag(a), real(a) } + MOVAPS X0, X1 + SHUFPD $0x1, X1, X1 // X1 = { real(a), imag(a) } + XORQ AX, AX // i = 0 + MOVAPS X0, X10 // Copy X0 and X1 for pipelining + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $3, CX // CX = n % 4 + SHRQ $2, BX // BX = floor( n / 4 ) + JZ caxy_tail // if BX == 0 { goto caxy_tail } + +caxy_loop: // do { + MOVUPS (SI)(AX*8), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVUPS 16(SI)(AX*8), X4 + MOVUPS 32(SI)(AX*8), X6 + MOVUPS 48(SI)(AX*8), X8 + + // X_(i+1) = { real(x[i], real(x[i]) } + MOVDDUP_X2_X3 // Load and duplicate imag elements (xi, xi) + MOVDDUP_X4_X5 + MOVDDUP_X6_X7 + MOVDDUP_X8_X9 + + // X_i = { imag(x[i]), imag(x[i]) } + SHUFPD $0x3, X2, X2 // duplicate real elements (xr, xr) + SHUFPD $0x3, X4, X4 + SHUFPD $0x3, X6, X6 + SHUFPD $0x3, X8, X8 + + // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + MULPD X1, X2 + MULPD X0, X3 + MULPD X11, X4 + MULPD X10, X5 + MULPD X1, X6 + MULPD X0, X7 + MULPD X11, X8 + MULPD X10, X9 + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + ADDSUBPD_X4_X5 + ADDSUBPD_X6_X7 + ADDSUBPD_X8_X9 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DX)(AX*8), X3 + ADDPD 16(DX)(AX*8), X5 + ADDPD 32(DX)(AX*8), X7 + ADDPD 48(DX)(AX*8), X9 + MOVUPS X3, (DI)(AX*8) // y[i] = X_(i+1) + MOVUPS X5, 16(DI)(AX*8) + MOVUPS X7, 32(DI)(AX*8) + MOVUPS X9, 48(DI)(AX*8) + ADDQ $8, AX // i += 8 + DECQ BX + JNZ caxy_loop // } while --BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + +caxy_tail: // Same calculation, but read in values to avoid trampling memory + MOVUPS (SI)(AX*8), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVDDUP_X2_X3 // X_(i+1) = { real(x[i], real(x[i]) } + SHUFPD $0x3, X2, X2 // X_i = { imag(x[i]), imag(x[i]) } + MULPD X1, X2 // X_i = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPD X0, X3 // X_(i+1) = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X_(i+1) = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + + // X_(i+1) = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + ADDPD (DX)(AX*8), X3 + MOVUPS X3, (DI)(AX*8) // y[i] = X_(i+1) + ADDQ $2, AX // i += 2 + LOOP caxy_tail // } while --CX > 0 + +caxy_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/bench_test.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/bench_test.go new file mode 100644 index 00000000..61049beb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/bench_test.go @@ -0,0 +1,284 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c128 + +import "testing" + +var ( + a = complex128(2 + 2i) + x = make([]complex128, 1000000) + y = make([]complex128, 1000000) + z = make([]complex128, 1000000) +) + +func init() { + for n := range x { + x[n] = complex(float64(n), float64(n)) + y[n] = complex(float64(n), float64(n)) + } +} + +func benchaxpyu(t *testing.B, n int, f func(a complex128, x, y []complex128)) { + x, y := x[:n], y[:n] + for i := 0; i < t.N; i++ { + f(a, x, y) + } +} + +func naiveaxpyu(a complex128, x, y []complex128) { + for i, v := range x { + y[i] += a * v + } +} + +func BenchmarkC128AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, AxpyUnitary) } +func BenchmarkC128AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, AxpyUnitary) } +func BenchmarkC128AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, AxpyUnitary) } +func BenchmarkC128AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, AxpyUnitary) } +func BenchmarkC128AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, AxpyUnitary) } +func BenchmarkC128AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, AxpyUnitary) } +func BenchmarkC128AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, AxpyUnitary) } +func BenchmarkC128AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, AxpyUnitary) } +func BenchmarkC128AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, AxpyUnitary) } +func BenchmarkC128AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, AxpyUnitary) } +func BenchmarkC128AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, AxpyUnitary) } + +func BenchmarkLC128AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, naiveaxpyu) } +func BenchmarkLC128AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, naiveaxpyu) } + +func benchaxpyut(t *testing.B, n int, f func(d []complex128, a complex128, x, y []complex128)) { + x, y, z := x[:n], y[:n], z[:n] + for i := 0; i < t.N; i++ { + f(z, a, x, y) + } +} + +func naiveaxpyut(d []complex128, a complex128, x, y []complex128) { + for i, v := range x { + d[i] = y[i] + a*v + } +} + +func BenchmarkC128AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, AxpyUnitaryTo) } +func BenchmarkC128AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, AxpyUnitaryTo) } + +func BenchmarkLC128AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, naiveaxpyut) } +func BenchmarkLC128AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, naiveaxpyut) } + +func benchaxpyinc(t *testing.B, ln, t_inc int, f func(alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + for i := 0; i < t.N; i++ { + f(1+1i, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyinc(alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +func BenchmarkC128AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, AxpyInc) } + +func BenchmarkC128AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, AxpyInc) } +func BenchmarkC128AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, AxpyInc) } +func BenchmarkC128AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, AxpyInc) } +func BenchmarkC128AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, AxpyInc) } + +func BenchmarkC128AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, AxpyInc) } +func BenchmarkC128AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, AxpyInc) } +func BenchmarkC128AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, AxpyInc) } +func BenchmarkC128AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, AxpyInc) } + +func BenchmarkC128AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, AxpyInc) } +func BenchmarkC128AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, AxpyInc) } +func BenchmarkC128AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, AxpyInc) } +func BenchmarkC128AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, AxpyInc) } + +func BenchmarkC128AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, AxpyInc) } +func BenchmarkC128AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, AxpyInc) } +func BenchmarkC128AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, AxpyInc) } +func BenchmarkC128AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, AxpyInc) } + +func BenchmarkC128AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, AxpyInc) } +func BenchmarkC128AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, AxpyInc) } +func BenchmarkC128AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, AxpyInc) } +func BenchmarkC128AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, AxpyInc) } + +func BenchmarkC128AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, AxpyInc) } +func BenchmarkC128AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, AxpyInc) } +func BenchmarkC128AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, AxpyInc) } +func BenchmarkC128AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, AxpyInc) } + +func BenchmarkC128AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, AxpyInc) } +func BenchmarkC128AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, AxpyInc) } +func BenchmarkC128AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, AxpyInc) } +func BenchmarkC128AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, AxpyInc) } + +func BenchmarkLC128AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, naiveaxpyinc) } + +func BenchmarkLC128AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, naiveaxpyinc) } + +func BenchmarkLC128AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, naiveaxpyinc) } + +func BenchmarkLC128AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, naiveaxpyinc) } + +func BenchmarkLC128AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, naiveaxpyinc) } + +func BenchmarkLC128AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, naiveaxpyinc) } + +func BenchmarkLC128AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, naiveaxpyinc) } + +func BenchmarkLC128AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, naiveaxpyinc) } +func BenchmarkLC128AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, naiveaxpyinc) } + +func benchaxpyincto(t *testing.B, ln, t_inc int, f func(dst []complex128, incDst, idst uintptr, alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + for i := 0; i < t.N; i++ { + f(z, inc, uintptr(idx), 1+1i, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyincto(dst []complex128, incDst, idst uintptr, alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} + +func BenchmarkC128AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, AxpyIncTo) } + +func BenchmarkC128AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, AxpyIncTo) } +func BenchmarkC128AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, AxpyIncTo) } +func BenchmarkC128AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, AxpyIncTo) } +func BenchmarkC128AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, AxpyIncTo) } + +func BenchmarkC128AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, AxpyIncTo) } +func BenchmarkC128AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, AxpyIncTo) } +func BenchmarkC128AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, AxpyIncTo) } +func BenchmarkC128AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, AxpyIncTo) } + +func BenchmarkC128AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, AxpyIncTo) } +func BenchmarkC128AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, AxpyIncTo) } +func BenchmarkC128AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, AxpyIncTo) } +func BenchmarkC128AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, AxpyIncTo) } + +func BenchmarkC128AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, AxpyIncTo) } +func BenchmarkC128AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, AxpyIncTo) } +func BenchmarkC128AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, AxpyIncTo) } +func BenchmarkC128AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, AxpyIncTo) } + +func BenchmarkC128AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, AxpyIncTo) } +func BenchmarkC128AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, AxpyIncTo) } +func BenchmarkC128AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, AxpyIncTo) } +func BenchmarkC128AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, AxpyIncTo) } + +func BenchmarkC128AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, AxpyIncTo) } +func BenchmarkC128AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, AxpyIncTo) } +func BenchmarkC128AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, AxpyIncTo) } +func BenchmarkC128AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, AxpyIncTo) } + +func BenchmarkC128AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, AxpyIncTo) } +func BenchmarkC128AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, AxpyIncTo) } +func BenchmarkC128AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, AxpyIncTo) } +func BenchmarkC128AxpyIncToN100000IncM10(b *testing.B) { benchaxpyincto(b, 100000, -10, AxpyIncTo) } + +func BenchmarkLC128AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, naiveaxpyincto) } + +func BenchmarkLC128AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, naiveaxpyincto) } + +func BenchmarkLC128AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, naiveaxpyincto) } + +func BenchmarkLC128AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, naiveaxpyincto) } + +func BenchmarkLC128AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, naiveaxpyincto) } + +func BenchmarkLC128AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, naiveaxpyincto) } + +func BenchmarkLC128AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, naiveaxpyincto) } + +func BenchmarkLC128AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, naiveaxpyincto) } +func BenchmarkLC128AxpyIncToN100000IncM10(b *testing.B) { + benchaxpyincto(b, 100000, -10, naiveaxpyincto) +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/doc.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/doc.go new file mode 100644 index 00000000..3a77db39 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package c128 provides complex128 vector primitives. +package c128 // import "gonum.org/v1/gonum/internal/asm/c128" diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/dotc.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/dotc.go new file mode 100644 index 00000000..a852f0d2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/dotc.go @@ -0,0 +1,35 @@ +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c128 + +import "math/cmplx" + +// DotcUnitary is +// for i, v := range x { +// sum += y[i] * cmplx.Conj(v) +// } +// return sum +func DotcUnitary(x, y []complex128) (sum complex128) { + for i, v := range x { + sum += y[i] * cmplx.Conj(v) + } + return sum +} + +// DotcInc is +// for i := 0; i < int(n); i++ { +// sum += y[iy] * cmplx.Conj(x[ix]) +// ix += incX +// iy += incY +// } +// return sum +func DotcInc(x, y []complex128, n, incX, incY, ix, iy uintptr) (sum complex128) { + for i := 0; i < int(n); i++ { + sum += y[iy] * cmplx.Conj(x[ix]) + ix += incX + iy += incY + } + return sum +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/dotu.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/dotu.go new file mode 100644 index 00000000..d82dc467 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/dotu.go @@ -0,0 +1,33 @@ +// 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 c128 + +// DotuUnitary is +// for i, v := range x { +// sum += y[i] * v +// } +// return sum +func DotuUnitary(x, y []complex128) (sum complex128) { + for i, v := range x { + sum += y[i] * v + } + return sum +} + +// DotuInc is +// for i := 0; i < int(n); i++ { +// sum += y[iy] * x[ix] +// ix += incX +// iy += incY +// } +// return sum +func DotuInc(x, y []complex128, n, incX, incY, ix, iy uintptr) (sum complex128) { + for i := 0; i < int(n); i++ { + sum += y[iy] * x[ix] + ix += incX + iy += incY + } + return sum +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/dscalinc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/dscalinc_amd64.s new file mode 100644 index 00000000..778e2fab --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/dscalinc_amd64.s @@ -0,0 +1,69 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define SRC SI +#define DST SI +#define LEN CX +#define TAIL BX +#define INC R9 +#define INC3 R10 +#define ALPHA X0 +#define ALPHA_2 X1 + +#define MOVDDUP_ALPHA LONG $0x44120FF2; WORD $0x0824 // MOVDDUP 8(SP), X0 + +// func DscalInc(alpha float64, x []complex128, n, inc uintptr) +TEXT ·DscalInc(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), SRC // SRC = &x + MOVQ n+32(FP), LEN // LEN = n + CMPQ LEN, $0 // if LEN == 0 { return } + JE dscal_end + + MOVDDUP_ALPHA // ALPHA = alpha + MOVQ inc+40(FP), INC // INC = inc + SHLQ $4, INC // INC = INC * sizeof(complex128) + LEAQ (INC)(INC*2), INC3 // INC3 = 3 * INC + MOVUPS ALPHA, ALPHA_2 // Copy ALPHA and ALPHA_2 for pipelining + MOVQ LEN, TAIL // TAIL = LEN + SHRQ $2, LEN // LEN = floor( n / 4 ) + JZ dscal_tail // if LEN == 0 { goto dscal_tail } + +dscal_loop: // do { + MOVUPS (SRC), X2 // X_i = x[i] + MOVUPS (SRC)(INC*1), X3 + MOVUPS (SRC)(INC*2), X4 + MOVUPS (SRC)(INC3*1), X5 + + MULPD ALPHA, X2 // X_i *= ALPHA + MULPD ALPHA_2, X3 + MULPD ALPHA, X4 + MULPD ALPHA_2, X5 + + MOVUPS X2, (DST) // x[i] = X_i + MOVUPS X3, (DST)(INC*1) + MOVUPS X4, (DST)(INC*2) + MOVUPS X5, (DST)(INC3*1) + + LEAQ (SRC)(INC*4), SRC // SRC += INC*4 + DECQ LEN + JNZ dscal_loop // } while --LEN > 0 + +dscal_tail: + ANDQ $3, TAIL // TAIL = TAIL % 4 + JE dscal_end // if TAIL == 0 { return } + +dscal_tail_loop: // do { + MOVUPS (SRC), X2 // X_i = x[i] + MULPD ALPHA, X2 // X_i *= ALPHA + MOVUPS X2, (DST) // x[i] = X_i + ADDQ INC, SRC // SRC += INC + DECQ TAIL + JNZ dscal_tail_loop // } while --TAIL > 0 + +dscal_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/dscalunitary_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/dscalunitary_amd64.s new file mode 100644 index 00000000..32ef1546 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/dscalunitary_amd64.s @@ -0,0 +1,66 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define SRC SI +#define DST SI +#define LEN CX +#define IDX AX +#define TAIL BX +#define ALPHA X0 +#define ALPHA_2 X1 + +#define MOVDDUP_ALPHA LONG $0x44120FF2; WORD $0x0824 // MOVDDUP 8(SP), X0 + +// func DscalUnitary(alpha float64, x []complex128) +TEXT ·DscalUnitary(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), SRC // SRC = &x + MOVQ x_len+16(FP), LEN // LEN = len(x) + CMPQ LEN, $0 // if LEN == 0 { return } + JE dscal_end + + MOVDDUP_ALPHA // ALPHA = alpha + XORQ IDX, IDX // IDX = 0 + MOVUPS ALPHA, ALPHA_2 // Copy ALPHA to ALPHA_2 for pipelining + MOVQ LEN, TAIL // TAIL = LEN + SHRQ $2, LEN // LEN = floor( n / 4 ) + JZ dscal_tail // if LEN == 0 { goto dscal_tail } + +dscal_loop: // do { + MOVUPS (SRC)(IDX*8), X2 // X_i = x[i] + MOVUPS 16(SRC)(IDX*8), X3 + MOVUPS 32(SRC)(IDX*8), X4 + MOVUPS 48(SRC)(IDX*8), X5 + + MULPD ALPHA, X2 // X_i *= ALPHA + MULPD ALPHA_2, X3 + MULPD ALPHA, X4 + MULPD ALPHA_2, X5 + + MOVUPS X2, (DST)(IDX*8) // x[i] = X_i + MOVUPS X3, 16(DST)(IDX*8) + MOVUPS X4, 32(DST)(IDX*8) + MOVUPS X5, 48(DST)(IDX*8) + + ADDQ $8, IDX // IDX += 8 + DECQ LEN + JNZ dscal_loop // } while --LEN > 0 + +dscal_tail: + ANDQ $3, TAIL // TAIL = TAIL % 4 + JZ dscal_end // if TAIL == 0 { return } + +dscal_tail_loop: // do { + MOVUPS (SRC)(IDX*8), X2 // X_i = x[i] + MULPD ALPHA, X2 // X_i *= ALPHA + MOVUPS X2, (DST)(IDX*8) // x[i] = X_i + ADDQ $2, IDX // IDX += 2 + DECQ TAIL + JNZ dscal_tail_loop // } while --TAIL > 0 + +dscal_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/scal.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/scal.go new file mode 100644 index 00000000..580b4d8d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/scal.go @@ -0,0 +1,31 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c128 + +// ScalUnitaryTo is +// for i, v := range x { +// dst[i] = alpha * v +// } +func ScalUnitaryTo(dst []complex128, alpha complex128, x []complex128) { + for i, v := range x { + dst[i] = alpha * v + } +} + +// ScalIncTo is +// var idst, ix uintptr +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha * x[ix] +// ix += incX +// idst += incDst +// } +func ScalIncTo(dst []complex128, incDst uintptr, alpha complex128, x []complex128, n, incX uintptr) { + var idst, ix uintptr + for i := 0; i < int(n); i++ { + dst[idst] = alpha * x[ix] + ix += incX + idst += incDst + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/scalUnitary_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/scalUnitary_amd64.s new file mode 100644 index 00000000..22152a0e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/scalUnitary_amd64.s @@ -0,0 +1,116 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define SRC SI +#define DST SI +#define LEN CX +#define IDX AX +#define TAIL BX +#define ALPHA X0 +#define ALPHA_C X1 +#define ALPHA2 X10 +#define ALPHA_C2 X11 + +#define MOVDDUP_X2_X3 LONG $0xDA120FF2 // MOVDDUP X2, X3 +#define MOVDDUP_X4_X5 LONG $0xEC120FF2 // MOVDDUP X4, X5 +#define MOVDDUP_X6_X7 LONG $0xFE120FF2 // MOVDDUP X6, X7 +#define MOVDDUP_X8_X9 LONG $0x120F45F2; BYTE $0xC8 // MOVDDUP X8, X9 + +#define ADDSUBPD_X2_X3 LONG $0xDAD00F66 // ADDSUBPD X2, X3 +#define ADDSUBPD_X4_X5 LONG $0xECD00F66 // ADDSUBPD X4, X5 +#define ADDSUBPD_X6_X7 LONG $0xFED00F66 // ADDSUBPD X6, X7 +#define ADDSUBPD_X8_X9 LONG $0xD00F4566; BYTE $0xC8 // ADDSUBPD X8, X9 + +// func ScalUnitary(alpha complex128, x []complex128) +TEXT ·ScalUnitary(SB), NOSPLIT, $0 + MOVQ x_base+16(FP), SRC // SRC = &x + MOVQ x_len+24(FP), LEN // LEN = len(x) + CMPQ LEN, $0 // if LEN == 0 { return } + JE scal_end + + MOVUPS alpha+0(FP), ALPHA // ALPHA = { imag(alpha), real(alpha) } + MOVAPS ALPHA, ALPHA_C + SHUFPD $0x1, ALPHA_C, ALPHA_C // ALPHA_C = { real(alpha), imag(alpha) } + + XORQ IDX, IDX // IDX = 0 + MOVAPS ALPHA, ALPHA2 // Copy ALPHA and ALPHA_C for pipelining + MOVAPS ALPHA_C, ALPHA_C2 + MOVQ LEN, TAIL + SHRQ $2, LEN // LEN = floor( n / 4 ) + JZ scal_tail // if BX == 0 { goto scal_tail } + +scal_loop: // do { + MOVUPS (SRC)(IDX*8), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVUPS 16(SRC)(IDX*8), X4 + MOVUPS 32(SRC)(IDX*8), X6 + MOVUPS 48(SRC)(IDX*8), X8 + + // X_(i+1) = { real(x[i], real(x[i]) } + MOVDDUP_X2_X3 + MOVDDUP_X4_X5 + MOVDDUP_X6_X7 + MOVDDUP_X8_X9 + + // X_i = { imag(x[i]), imag(x[i]) } + SHUFPD $0x3, X2, X2 + SHUFPD $0x3, X4, X4 + SHUFPD $0x3, X6, X6 + SHUFPD $0x3, X8, X8 + + // X_i = { real(ALPHA) * imag(x[i]), imag(ALPHA) * imag(x[i]) } + // X_(i+1) = { imag(ALPHA) * real(x[i]), real(ALPHA) * real(x[i]) } + MULPD ALPHA_C, X2 + MULPD ALPHA, X3 + MULPD ALPHA_C2, X4 + MULPD ALPHA2, X5 + MULPD ALPHA_C, X6 + MULPD ALPHA, X7 + MULPD ALPHA_C2, X8 + MULPD ALPHA2, X9 + + // X_(i+1) = { + // imag(result[i]): imag(ALPHA)*real(x[i]) + real(ALPHA)*imag(x[i]), + // real(result[i]): real(ALPHA)*real(x[i]) - imag(ALPHA)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + ADDSUBPD_X4_X5 + ADDSUBPD_X6_X7 + ADDSUBPD_X8_X9 + + MOVUPS X3, (DST)(IDX*8) // x[i] = X_(i+1) + MOVUPS X5, 16(DST)(IDX*8) + MOVUPS X7, 32(DST)(IDX*8) + MOVUPS X9, 48(DST)(IDX*8) + ADDQ $8, IDX // IDX += 8 + DECQ LEN + JNZ scal_loop // } while --LEN > 0 + +scal_tail: + ANDQ $3, TAIL // TAIL = TAIL % 4 + JZ scal_end // if TAIL == 0 { return } + +scal_tail_loop: // do { + MOVUPS (SRC)(IDX*8), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVDDUP_X2_X3 // X_(i+1) = { real(x[i], real(x[i]) } + SHUFPD $0x3, X2, X2 // X_i = { imag(x[i]), imag(x[i]) } + MULPD ALPHA_C, X2 // X_i = { real(ALPHA) * imag(x[i]), imag(ALPHA) * imag(x[i]) } + MULPD ALPHA, X3 // X_(i+1) = { imag(ALPHA) * real(x[i]), real(ALPHA) * real(x[i]) } + + // X_(i+1) = { + // imag(result[i]): imag(ALPHA)*real(x[i]) + real(ALPHA)*imag(x[i]), + // real(result[i]): real(ALPHA)*real(x[i]) - imag(ALPHA)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + + MOVUPS X3, (DST)(IDX*8) // x[i] = X_(i+1) + ADDQ $2, IDX // IDX += 2 + DECQ TAIL + JNZ scal_tail_loop // } while --LEN > 0 + +scal_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/scalinc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c128/scalinc_amd64.s new file mode 100644 index 00000000..ec0f1528 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/scalinc_amd64.s @@ -0,0 +1,121 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define SRC SI +#define DST SI +#define LEN CX +#define TAIL BX +#define INC R9 +#define INC3 R10 +#define ALPHA X0 +#define ALPHA_C X1 +#define ALPHA2 X10 +#define ALPHA_C2 X11 + +#define MOVDDUP_X2_X3 LONG $0xDA120FF2 // MOVDDUP X2, X3 +#define MOVDDUP_X4_X5 LONG $0xEC120FF2 // MOVDDUP X4, X5 +#define MOVDDUP_X6_X7 LONG $0xFE120FF2 // MOVDDUP X6, X7 +#define MOVDDUP_X8_X9 LONG $0x120F45F2; BYTE $0xC8 // MOVDDUP X8, X9 + +#define ADDSUBPD_X2_X3 LONG $0xDAD00F66 // ADDSUBPD X2, X3 +#define ADDSUBPD_X4_X5 LONG $0xECD00F66 // ADDSUBPD X4, X5 +#define ADDSUBPD_X6_X7 LONG $0xFED00F66 // ADDSUBPD X6, X7 +#define ADDSUBPD_X8_X9 LONG $0xD00F4566; BYTE $0xC8 // ADDSUBPD X8, X9 + +// func ScalInc(alpha complex128, x []complex128, n, inc uintptr) +TEXT ·ScalInc(SB), NOSPLIT, $0 + MOVQ x_base+16(FP), SRC // SRC = &x + MOVQ n+40(FP), LEN // LEN = len(x) + CMPQ LEN, $0 + JE scal_end // if LEN == 0 { return } + + MOVQ inc+48(FP), INC // INC = inc + SHLQ $4, INC // INC = INC * sizeof(complex128) + LEAQ (INC)(INC*2), INC3 // INC3 = 3 * INC + + MOVUPS alpha+0(FP), ALPHA // ALPHA = { imag(alpha), real(alpha) } + MOVAPS ALPHA, ALPHA_C + SHUFPD $0x1, ALPHA_C, ALPHA_C // ALPHA_C = { real(alpha), imag(alpha) } + + MOVAPS ALPHA, ALPHA2 // Copy ALPHA and ALPHA_C for pipelining + MOVAPS ALPHA_C, ALPHA_C2 + MOVQ LEN, TAIL + SHRQ $2, LEN // LEN = floor( n / 4 ) + JZ scal_tail // if BX == 0 { goto scal_tail } + +scal_loop: // do { + MOVUPS (SRC), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVUPS (SRC)(INC*1), X4 + MOVUPS (SRC)(INC*2), X6 + MOVUPS (SRC)(INC3*1), X8 + + // X_(i+1) = { real(x[i], real(x[i]) } + MOVDDUP_X2_X3 + MOVDDUP_X4_X5 + MOVDDUP_X6_X7 + MOVDDUP_X8_X9 + + // X_i = { imag(x[i]), imag(x[i]) } + SHUFPD $0x3, X2, X2 + SHUFPD $0x3, X4, X4 + SHUFPD $0x3, X6, X6 + SHUFPD $0x3, X8, X8 + + // X_i = { real(ALPHA) * imag(x[i]), imag(ALPHA) * imag(x[i]) } + // X_(i+1) = { imag(ALPHA) * real(x[i]), real(ALPHA) * real(x[i]) } + MULPD ALPHA_C, X2 + MULPD ALPHA, X3 + MULPD ALPHA_C2, X4 + MULPD ALPHA2, X5 + MULPD ALPHA_C, X6 + MULPD ALPHA, X7 + MULPD ALPHA_C2, X8 + MULPD ALPHA2, X9 + + // X_(i+1) = { + // imag(result[i]): imag(ALPHA)*real(x[i]) + real(ALPHA)*imag(x[i]), + // real(result[i]): real(ALPHA)*real(x[i]) - imag(ALPHA)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + ADDSUBPD_X4_X5 + ADDSUBPD_X6_X7 + ADDSUBPD_X8_X9 + + MOVUPS X3, (DST) // x[i] = X_(i+1) + MOVUPS X5, (DST)(INC*1) + MOVUPS X7, (DST)(INC*2) + MOVUPS X9, (DST)(INC3*1) + + LEAQ (SRC)(INC*4), SRC // SRC = &(SRC[inc*4]) + DECQ LEN + JNZ scal_loop // } while --BX > 0 + +scal_tail: + ANDQ $3, TAIL // TAIL = TAIL % 4 + JE scal_end // if TAIL == 0 { return } + +scal_tail_loop: // do { + MOVUPS (SRC), X2 // X_i = { imag(x[i]), real(x[i]) } + MOVDDUP_X2_X3 // X_(i+1) = { real(x[i], real(x[i]) } + SHUFPD $0x3, X2, X2 // X_i = { imag(x[i]), imag(x[i]) } + MULPD ALPHA_C, X2 // X_i = { real(ALPHA) * imag(x[i]), imag(ALPHA) * imag(x[i]) } + MULPD ALPHA, X3 // X_(i+1) = { imag(ALPHA) * real(x[i]), real(ALPHA) * real(x[i]) } + + // X_(i+1) = { + // imag(result[i]): imag(ALPHA)*real(x[i]) + real(ALPHA)*imag(x[i]), + // real(result[i]): real(ALPHA)*real(x[i]) - imag(ALPHA)*imag(x[i]) + // } + ADDSUBPD_X2_X3 + + MOVUPS X3, (DST) // x[i] = X_i + ADDQ INC, SRC // SRC = &(SRC[incX]) + DECQ TAIL + JNZ scal_tail_loop // } while --TAIL > 0 + +scal_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_amd64.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_amd64.go new file mode 100644 index 00000000..f3494a78 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_amd64.go @@ -0,0 +1,64 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +package c128 + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha complex128, x, y []complex128) + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []complex128, alpha complex128, x, y []complex128) + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []complex128, incDst, idst uintptr, alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) + +// DscalUnitary is +// for i, v := range x { +// x[i] = complex(real(v)*alpha, imag(v)*alpha) +// } +func DscalUnitary(alpha float64, x []complex128) + +// DscalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] = complex(real(x[ix])*alpha, imag(x[ix])*alpha) +// ix += inc +// } +func DscalInc(alpha float64, x []complex128, n, inc uintptr) + +// ScalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] *= alpha +// ix += incX +// } +func ScalInc(alpha complex128, x []complex128, n, inc uintptr) + +// ScalUnitary is +// for i := range x { +// x[i] *= alpha +// } +func ScalUnitary(alpha complex128, x []complex128) diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_noasm.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_noasm.go new file mode 100644 index 00000000..008a1e6a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_noasm.go @@ -0,0 +1,105 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !amd64 noasm appengine + +package c128 + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha complex128, x, y []complex128) { + for i, v := range x { + y[i] += alpha * v + } +} + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []complex128, alpha complex128, x, y []complex128) { + for i, v := range x { + dst[i] = alpha*v + y[i] + } +} + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []complex128, incDst, idst uintptr, alpha complex128, x, y []complex128, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} + +// DscalUnitary is +// for i, v := range x { +// x[i] = complex(real(v)*alpha, imag(v)*alpha) +// } +func DscalUnitary(alpha float64, x []complex128) { + for i, v := range x { + x[i] = complex(real(v)*alpha, imag(v)*alpha) + } +} + +// DscalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] = complex(real(x[ix])*alpha, imag(x[ix])*alpha) +// ix += inc +// } +func DscalInc(alpha float64, x []complex128, n, inc uintptr) { + var ix uintptr + for i := 0; i < int(n); i++ { + x[ix] = complex(real(x[ix])*alpha, imag(x[ix])*alpha) + ix += inc + } +} + +// ScalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] *= alpha +// ix += incX +// } +func ScalInc(alpha complex128, x []complex128, n, inc uintptr) { + var ix uintptr + for i := 0; i < int(n); i++ { + x[ix] *= alpha + ix += inc + } +} + +// ScalUnitary is +// for i := range x { +// x[i] *= alpha +// } +func ScalUnitary(alpha complex128, x []complex128) { + for i := range x { + x[i] *= alpha + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_test.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_test.go new file mode 100644 index 00000000..6af21e11 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/stubs_test.go @@ -0,0 +1,335 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c128 + +import ( + "fmt" + "testing" +) + +var tests = []struct { + incX, incY, incDst int + ix, iy, idst uintptr + a complex128 + dst, x, y []complex128 + ex []complex128 +}{ + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 1i, + dst: []complex128{5}, + x: []complex128{1}, + y: []complex128{1i}, + ex: []complex128{1 + 2i}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 2i, + dst: []complex128{0, 0, 0}, + x: []complex128{0, 0, 0}, + y: []complex128{1, 1, 1}, + ex: []complex128{1, 1, 1}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 2i, + dst: []complex128{0, 0, 0}, + x: []complex128{0, 0}, + y: []complex128{1, 1, 1}, + ex: []complex128{1, 1}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 2i, + dst: []complex128{1i, 1i, 1i}, + x: []complex128{1i, 1i, 1i}, + y: []complex128{1, 2, 1}, + ex: []complex128{-1 + 1i, 1i, -1 + 1i}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -1i, + dst: []complex128{1i, 1i, 1i}, + x: []complex128{1i, 1i, 1i}, + y: []complex128{1, 2, 1}, + ex: []complex128{2, 3, 2}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -1i, + dst: []complex128{1i, 1i, 1i}, + x: []complex128{1i, 1i, 1i, 1i, 1i}[1:4], + y: []complex128{1, 1, 2, 1, 1}[1:4], + ex: []complex128{2, 3, 2}}, + {incX: 2, incY: 4, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -2, + dst: []complex128{1i, 1i, 1i, 1i, 1i}, + x: []complex128{2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i}, + y: []complex128{1, 1, 2, 1, 1}, + ex: []complex128{-3 - 2i, -3 - 2i, -2 - 2i, -3 - 2i, -3 - 2i}}, + // Run big test twice, once aligned once unaligned. + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 - 1i, + dst: make([]complex128, 10), + x: []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 - 1i, + dst: make([]complex128, 10), + x: []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, + {incX: -2, incY: -2, incDst: -3, ix: 18, iy: 18, idst: 27, + a: 1 - 1i, + dst: make([]complex128, 10), + x: []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, + {incX: -2, incY: 2, incDst: -3, ix: 18, iy: 0, idst: 27, + a: 1 - 1i, + dst: make([]complex128, 10), + x: []complex128{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex128{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex128{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, +} + +func TestAxpyUnitary(t *testing.T) { + const xGdVal, yGdVal = 1, 1 + for cas, test := range tests { + xgLn, ygLn := 4+cas%2, 4+cas%3 + test.x, test.y = guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) + x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn] + AxpyUnitary(test.a, x, y) + for i := range test.ex { + if y[i] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i], test.ex[i]) + } + } + if !isValidGuard(test.x, xGdVal, xgLn) { + t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xgLn], test.x[len(test.x)-xgLn:]) + } + if !isValidGuard(test.y, yGdVal, ygLn) { + t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:ygLn], test.y[len(test.y)-ygLn:]) + } + } +} + +func TestAxpyUnitaryTo(t *testing.T) { + const xGdVal, yGdVal, dstGdVal = 1, 1, 0 + for cas, test := range tests { + xgLn, ygLn := 4+cas%2, 4+cas%3 + test.x, test.y = guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) + test.dst = guardVector(test.dst, dstGdVal, xgLn) + x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn] + dst := test.dst[xgLn : len(test.dst)-xgLn] + AxpyUnitaryTo(dst, test.a, x, y) + for i := range test.ex { + if dst[i] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i], test.ex[i]) + } + } + if !isValidGuard(test.x, xGdVal, xgLn) { + t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xgLn], test.x[len(test.x)-xgLn:]) + } + if !isValidGuard(test.y, yGdVal, ygLn) { + t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:ygLn], test.y[len(test.y)-ygLn:]) + } + if !isValidGuard(test.dst, dstGdVal, xgLn) { + t.Errorf("Test %d Guard violated in dst vector %v %v", cas, test.dst[:xgLn], test.dst[len(test.dst)-xgLn:]) + } + + } +} + +func TestAxpyInc(t *testing.T) { + const xGdVal, yGdVal = 1, 1 + for cas, test := range tests { + xgLn, ygLn := 4+cas%2, 4+cas%3 + test.x, test.y = guardIncVector(test.x, xGdVal, test.incX, xgLn), guardIncVector(test.y, yGdVal, test.incY, ygLn) + x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn] + AxpyInc(test.a, x, y, uintptr(len(test.ex)), uintptr(test.incX), uintptr(test.incY), test.ix, test.iy) + for i := range test.ex { + if y[int(test.iy)+i*int(test.incY)] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i*int(test.incY)], test.ex[i]) + } + } + checkValidIncGuard(t, test.x, xGdVal, test.incX, xgLn) + checkValidIncGuard(t, test.y, yGdVal, test.incY, ygLn) + } +} + +func TestAxpyIncTo(t *testing.T) { + const xGdVal, yGdVal, dstGdVal = 1, 1, 0 + for cas, test := range tests { + xgLn, ygLn := 4+cas%2, 4+cas%3 + test.x, test.y = guardIncVector(test.x, xGdVal, test.incX, xgLn), guardIncVector(test.y, yGdVal, test.incY, ygLn) + test.dst = guardIncVector(test.dst, dstGdVal, test.incDst, xgLn) + x, y := test.x[xgLn:len(test.x)-xgLn], test.y[ygLn:len(test.y)-ygLn] + dst := test.dst[xgLn : len(test.dst)-xgLn] + AxpyIncTo(dst, uintptr(test.incDst), test.idst, test.a, x, y, uintptr(len(test.ex)), uintptr(test.incX), uintptr(test.incY), test.ix, test.iy) + for i := range test.ex { + if dst[int(test.idst)+i*int(test.incDst)] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i*int(test.incDst)], test.ex[i]) + } + } + checkValidIncGuard(t, test.x, xGdVal, test.incX, xgLn) + checkValidIncGuard(t, test.y, yGdVal, test.incY, ygLn) + checkValidIncGuard(t, test.dst, dstGdVal, test.incDst, xgLn) + } +} + +var dscalTests = []struct { + alpha float64 + x []complex128 + want []complex128 +}{ + { + alpha: 0, + x: []complex128{}, + want: []complex128{}, + }, + { + alpha: 1, + x: []complex128{1 + 2i}, + want: []complex128{1 + 2i}, + }, + { + alpha: 2, + x: []complex128{1 + 2i}, + want: []complex128{2 + 4i}, + }, + { + alpha: 2, + x: []complex128{1 + 2i, 3 + 5i, 6 + 11i, 12 - 23i}, + want: []complex128{2 + 4i, 6 + 10i, 12 + 22i, 24 - 46i}, + }, + { + alpha: 3, + x: []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i}, + want: []complex128{3 + 6i, 15 + 12i, 9 + 18i, 24 + 36i, -9 - 6i, -15 + 15i}, + }, + { + alpha: 5, + x: []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i, 1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i}, + want: []complex128{5 + 10i, 25 + 20i, 15 + 30i, 40 + 60i, -15 - 10i, -25 + 25i, 5 + 10i, 25 + 20i, 15 + 30i, 40 + 60i, -15 - 10i, -25 + 25i}, + }, +} + +func TestDscalUnitary(t *testing.T) { + const xGdVal = -0.5 + for i, test := range dscalTests { + for _, align := range align1 { + prefix := fmt.Sprintf("Test %v (x:%v)", i, align) + xgLn := 4 + align + xg := guardVector(test.x, xGdVal, xgLn) + x := xg[xgLn : len(xg)-xgLn] + + DscalUnitary(test.alpha, x) + + for i := range test.want { + if !same(x[i], test.want[i]) { + t.Errorf(msgVal, prefix, i, x[i], test.want[i]) + } + } + if !isValidGuard(xg, xGdVal, xgLn) { + t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) + } + } + } +} + +func TestDscalInc(t *testing.T) { + const xGdVal = -0.5 + gdLn := 4 + for i, test := range dscalTests { + n := len(test.x) + for _, incX := range []int{1, 2, 3, 4, 7, 10} { + prefix := fmt.Sprintf("Test %v (x:%v)", i, incX) + xg := guardIncVector(test.x, xGdVal, incX, gdLn) + x := xg[gdLn : len(xg)-gdLn] + + DscalInc(test.alpha, x, uintptr(n), uintptr(incX)) + + for i := range test.want { + if !same(x[i*incX], test.want[i]) { + t.Errorf(msgVal, prefix, i, x[i*incX], test.want[i]) + } + } + checkValidIncGuard(t, xg, xGdVal, incX, gdLn) + } + } +} + +var scalTests = []struct { + alpha complex128 + x []complex128 + want []complex128 +}{ + { + alpha: 0, + x: []complex128{}, + want: []complex128{}, + }, + { + alpha: 1 + 1i, + x: []complex128{1 + 2i}, + want: []complex128{-1 + 3i}, + }, + { + alpha: 2 + 3i, + x: []complex128{1 + 2i}, + want: []complex128{-4 + 7i}, + }, + { + alpha: 2 - 4i, + x: []complex128{1 + 2i}, + want: []complex128{10}, + }, + { + alpha: 2 + 8i, + x: []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i}, + want: []complex128{-14 + 12i, -22 + 48i, -42 + 36i, -80 + 88i, 10 - 28i, -50 - 30i}, + }, + { + alpha: 5 - 10i, + x: []complex128{1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i, 1 + 2i, 5 + 4i, 3 + 6i, 8 + 12i, -3 - 2i, -5 + 5i}, + want: []complex128{25, 65 - 30i, 75, 160 - 20i, -35 + 20i, 25 + 75i, 25, 65 - 30i, 75, 160 - 20i, -35 + 20i, 25 + 75i}, + }, +} + +func TestScalUnitary(t *testing.T) { + const xGdVal = -0.5 + for i, test := range scalTests { + for _, align := range align1 { + prefix := fmt.Sprintf("Test %v (x:%v)", i, align) + xgLn := 4 + align + xg := guardVector(test.x, xGdVal, xgLn) + x := xg[xgLn : len(xg)-xgLn] + + ScalUnitary(test.alpha, x) + + for i := range test.want { + if !same(x[i], test.want[i]) { + t.Errorf(msgVal, prefix, i, x[i], test.want[i]) + } + } + if !isValidGuard(xg, xGdVal, xgLn) { + t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) + } + } + } +} + +func TestScalInc(t *testing.T) { + const xGdVal = -0.5 + gdLn := 4 + for i, test := range scalTests { + n := len(test.x) + for _, inc := range []int{1, 2, 3, 4, 7, 10} { + prefix := fmt.Sprintf("Test %v (x:%v)", i, inc) + xg := guardIncVector(test.x, xGdVal, inc, gdLn) + x := xg[gdLn : len(xg)-gdLn] + + ScalInc(test.alpha, x, uintptr(n), uintptr(inc)) + + for i := range test.want { + if !same(x[i*inc], test.want[i]) { + t.Errorf(msgVal, prefix, i, x[i*inc], test.want[i]) + } + } + checkValidIncGuard(t, xg, xGdVal, inc, gdLn) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c128/util_test.go b/vendor/gonum.org/v1/gonum/internal/asm/c128/util_test.go new file mode 100644 index 00000000..e07470d9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c128/util_test.go @@ -0,0 +1,123 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c128 + +import ( + "math" + "testing" +) + +const ( + msgVal = "%v: unexpected value at %v Got: %v Expected: %v" + msgGuard = "%v: Guard violated in %s vector %v %v" +) + +func same(x, y complex128) bool { + return (x == y || + math.IsNaN(real(x)) && math.IsNaN(real(y)) && imag(x) == imag(y) || + math.IsNaN(imag(y)) && math.IsNaN(imag(x)) && real(y) == real(x) || + math.IsNaN(real(x)) && math.IsNaN(real(y)) && math.IsNaN(imag(y)) && math.IsNaN(imag(x))) +} + +func guardVector(vec []complex128, guard_val complex128, guard_len int) (guarded []complex128) { + guarded = make([]complex128, len(vec)+guard_len*2) + copy(guarded[guard_len:], vec) + for i := 0; i < guard_len; i++ { + guarded[i] = guard_val + guarded[len(guarded)-1-i] = guard_val + } + return guarded +} + +func isValidGuard(vec []complex128, guard_val complex128, guard_len int) bool { + for i := 0; i < guard_len; i++ { + if vec[i] != guard_val || vec[len(vec)-1-i] != guard_val { + return false + } + } + return true +} + +func guardIncVector(vec []complex128, guard_val complex128, inc, guard_len int) (guarded []complex128) { + s_ln := len(vec) * inc + if inc < 0 { + s_ln = len(vec) * -inc + } + guarded = make([]complex128, s_ln+guard_len*2) + for i, cas := 0, 0; i < len(guarded); i++ { + switch { + case i < guard_len, i > guard_len+s_ln: + guarded[i] = guard_val + case (i-guard_len)%(inc) == 0 && cas < len(vec): + guarded[i] = vec[cas] + cas++ + default: + guarded[i] = guard_val + } + } + return guarded +} + +func checkValidIncGuard(t *testing.T, vec []complex128, guard_val complex128, inc, guard_len int) { + s_ln := len(vec) - 2*guard_len + if inc < 0 { + s_ln = len(vec) * -inc + } + + for i := range vec { + switch { + case vec[i] == guard_val: + // Correct value + case i < guard_len: + t.Errorf("Front guard violated at %d %v", i, vec[:guard_len]) + case i > guard_len+s_ln: + t.Errorf("Back guard violated at %d %v", i-guard_len-s_ln, vec[guard_len+s_ln:]) + case (i-guard_len)%inc == 0 && (i-guard_len)/inc < len(vec): + // Ignore input values + default: + t.Errorf("Internal guard violated at %d %v", i-guard_len, vec[guard_len:guard_len+s_ln]) + } + } +} + +var ( // Offset sets for testing alignment handling in Unitary assembly functions. + align1 = []int{0, 1} + align2 = newIncSet(0, 1) + align3 = newIncToSet(0, 1) +) + +type incSet struct { + x, y int +} + +// genInc will generate all (x,y) combinations of the input increment set. +func newIncSet(inc ...int) []incSet { + n := len(inc) + is := make([]incSet, n*n) + for x := range inc { + for y := range inc { + is[x*n+y] = incSet{inc[x], inc[y]} + } + } + return is +} + +type incToSet struct { + dst, x, y int +} + +// genIncTo will generate all (dst,x,y) combinations of the input increment set. +func newIncToSet(inc ...int) []incToSet { + n := len(inc) + is := make([]incToSet, n*n*n) + for i, dst := range inc { + for x := range inc { + for y := range inc { + is[i*n*n+x*n+y] = incToSet{dst, inc[x], inc[y]} + } + } + } + return is +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyinc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyinc_amd64.s new file mode 100644 index 00000000..82c28862 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyinc_amd64.s @@ -0,0 +1,151 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVSHDUP X3, X2 +#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3 +// MOVSLDUP X3, X3 +#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB +// ADDSUBPS X2, X3 +#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA + +// MOVSHDUP X5, X4 +#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5 +// MOVSLDUP X5, X5 +#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED +// ADDSUBPS X4, X5 +#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC + +// MOVSHDUP X7, X6 +#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7 +// MOVSLDUP X7, X7 +#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF +// ADDSUBPS X6, X7 +#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE + +// MOVSHDUP X9, X8 +#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1 +// MOVSLDUP X9, X9 +#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9 +// ADDSUBPS X8, X9 +#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyInc(alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyInc(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), SI // SI = &x + MOVQ y_base+32(FP), DI // DI = &y + MOVQ n+56(FP), CX // CX = n + CMPQ CX, $0 // if n==0 { return } + JE axpyi_end + MOVQ ix+80(FP), R8 // R8 = ix + MOVQ iy+88(FP), R9 // R9 = iy + LEAQ (SI)(R8*8), SI // SI = &(x[ix]) + LEAQ (DI)(R9*8), DI // DI = &(y[iy]) + MOVQ DI, DX // DX = DI // Read/Write pointers + MOVQ incX+64(FP), R8 // R8 = incX + SHLQ $3, R8 // R8 *= sizeof(complex64) + MOVQ incY+72(FP), R9 // R9 = incY + SHLQ $3, R9 // R9 *= sizeof(complex64) + MOVSD alpha+0(FP), X0 // X0 = { 0, 0, imag(a), real(a) } + MOVAPS X0, X1 + SHUFPS $0x11, X1, X1 // X1 = { 0, 0, real(a), imag(a) } + MOVAPS X0, X10 // Copy X0 and X1 for pipelining + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $3, CX // CX = n % 4 + SHRQ $2, BX // BX = floor( n / 4 ) + JZ axpyi_tail // if BX == 0 { goto axpyi_tail } + +axpyi_loop: // do { + MOVSD (SI), X3 // X_i = { imag(x[i+1]), real(x[i+1]) } + MOVSD (SI)(R8*1), X5 + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + MOVSD (SI), X7 + MOVSD (SI)(R8*1), X9 + + // X_(i-1) = { imag(x[i]), imag(x[i]) } + MOVSHDUP_X3_X2 + MOVSHDUP_X5_X4 + MOVSHDUP_X7_X6 + MOVSHDUP_X9_X8 + + // X_i = { real(x[i]), real(x[i]) } + MOVSLDUP_X3_X3 + MOVSLDUP_X5_X5 + MOVSLDUP_X7_X7 + MOVSLDUP_X9_X9 + + // X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + // X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) } + MULPS X1, X2 + MULPS X0, X3 + MULPS X11, X4 + MULPS X10, X5 + MULPS X1, X6 + MULPS X0, X7 + MULPS X11, X8 + MULPS X10, X9 + + // X_i = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]), + // } + ADDSUBPS_X2_X3 + ADDSUBPS_X4_X5 + ADDSUBPS_X6_X7 + ADDSUBPS_X8_X9 + + // X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + MOVSD (DX), X2 + MOVSD (DX)(R9*1), X4 + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + MOVSD (DX), X6 + MOVSD (DX)(R9*1), X8 + ADDPS X2, X3 + ADDPS X4, X5 + ADDPS X6, X7 + ADDPS X8, X9 + + MOVSD X3, (DI) // y[i] = X_i + MOVSD X5, (DI)(R9*1) + LEAQ (DI)(R9*2), DI // DI = &(DI[incDst]) + MOVSD X7, (DI) + MOVSD X9, (DI)(R9*1) + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + LEAQ (DI)(R9*2), DI // DI = &(DI[incDst]) + DECQ BX + JNZ axpyi_loop // } while --BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE axpyi_end + +axpyi_tail: // do { + MOVSD (SI), X3 // X_i = { imag(x[i+1]), real(x[i+1]) } + MOVSHDUP_X3_X2 // X_(i-1) = { real(x[i]), real(x[i]) } + MOVSLDUP_X3_X3 // X_i = { imag(x[i]), imag(x[i]) } + + // X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) } + // X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPS X1, X2 + MULPS X0, X3 + + // X_i = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]), + // } + ADDSUBPS_X2_X3 // (ai*x1r+ar*x1i, ar*x1r-ai*x1i) + + // X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + MOVSD (DI), X4 + ADDPS X4, X3 + MOVSD X3, (DI) // y[i] = X_i + ADDQ R8, SI // SI += incX + ADDQ R9, DI // DI += incY + LOOP axpyi_tail // } while --CX > 0 + +axpyi_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyincto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyincto_amd64.s new file mode 100644 index 00000000..9fdc3ef3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyincto_amd64.s @@ -0,0 +1,156 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVSHDUP X3, X2 +#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3 +// MOVSLDUP X3, X3 +#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB +// ADDSUBPS X2, X3 +#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA + +// MOVSHDUP X5, X4 +#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5 +// MOVSLDUP X5, X5 +#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED +// ADDSUBPS X4, X5 +#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC + +// MOVSHDUP X7, X6 +#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7 +// MOVSLDUP X7, X7 +#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF +// ADDSUBPS X6, X7 +#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE + +// MOVSHDUP X9, X8 +#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1 +// MOVSLDUP X9, X9 +#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9 +// ADDSUBPS X8, X9 +#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyIncTo(dst []complex64, incDst, idst uintptr, alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyIncTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ x_base+48(FP), SI // SI = &x + MOVQ y_base+72(FP), DX // DX = &y + MOVQ n+96(FP), CX // CX = n + CMPQ CX, $0 // if n==0 { return } + JE axpyi_end + MOVQ ix+120(FP), R8 // Load the first index + MOVQ iy+128(FP), R9 + MOVQ idst+32(FP), R10 + LEAQ (SI)(R8*8), SI // SI = &(x[ix]) + LEAQ (DX)(R9*8), DX // DX = &(y[iy]) + LEAQ (DI)(R10*8), DI // DI = &(dst[idst]) + MOVQ incX+104(FP), R8 // Incrementors*8 for easy iteration (ADDQ) + SHLQ $3, R8 + MOVQ incY+112(FP), R9 + SHLQ $3, R9 + MOVQ incDst+24(FP), R10 + SHLQ $3, R10 + MOVSD alpha+40(FP), X0 // X0 = { 0, 0, imag(a), real(a) } + MOVAPS X0, X1 + SHUFPS $0x11, X1, X1 // X1 = { 0, 0, real(a), imag(a) } + MOVAPS X0, X10 // Copy X0 and X1 for pipelining + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $3, CX // CX = n % 4 + SHRQ $2, BX // BX = floor( n / 4 ) + JZ axpyi_tail // if BX == 0 { goto axpyi_tail } + +axpyi_loop: // do { + MOVSD (SI), X3 // X_i = { imag(x[i]), real(x[i]) } + MOVSD (SI)(R8*1), X5 + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + MOVSD (SI), X7 + MOVSD (SI)(R8*1), X9 + + // X_(i-1) = { imag(x[i]), imag(x[i]) } + MOVSHDUP_X3_X2 + MOVSHDUP_X5_X4 + MOVSHDUP_X7_X6 + MOVSHDUP_X9_X8 + + // X_i = { real(x[i]), real(x[i]) } + MOVSLDUP_X3_X3 + MOVSLDUP_X5_X5 + MOVSLDUP_X7_X7 + MOVSLDUP_X9_X9 + + // X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + // X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) } + MULPS X1, X2 + MULPS X0, X3 + MULPS X11, X4 + MULPS X10, X5 + MULPS X1, X6 + MULPS X0, X7 + MULPS X11, X8 + MULPS X10, X9 + + // X_i = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]), + // } + ADDSUBPS_X2_X3 + ADDSUBPS_X4_X5 + ADDSUBPS_X6_X7 + ADDSUBPS_X8_X9 + + // X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + MOVSD (DX), X2 + MOVSD (DX)(R9*1), X4 + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + MOVSD (DX), X6 + MOVSD (DX)(R9*1), X8 + ADDPS X2, X3 + ADDPS X4, X5 + ADDPS X6, X7 + ADDPS X8, X9 + + MOVSD X3, (DI) // y[i] = X_i + MOVSD X5, (DI)(R10*1) + LEAQ (DI)(R10*2), DI // DI = &(DI[incDst]) + MOVSD X7, (DI) + MOVSD X9, (DI)(R10*1) + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + LEAQ (DI)(R10*2), DI // DI = &(DI[incDst]) + DECQ BX + JNZ axpyi_loop // } while --BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE axpyi_end + +axpyi_tail: + MOVSD (SI), X3 // X_i = { imag(x[i]), real(x[i]) } + MOVSHDUP_X3_X2 // X_(i-1) = { imag(x[i]), imag(x[i]) } + MOVSLDUP_X3_X3 // X_i = { real(x[i]), real(x[i]) } + + // X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) } + // X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPS X1, X2 + MULPS X0, X3 + + // X_i = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]), + // } + ADDSUBPS_X2_X3 + + // X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) } + MOVSD (DX), X4 + ADDPS X4, X3 + MOVSD X3, (DI) // y[i] = X_i + ADDQ R8, SI // SI += incX + ADDQ R9, DX // DX += incY + ADDQ R10, DI // DI += incDst + LOOP axpyi_tail // } while --CX > 0 + +axpyi_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitary_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitary_amd64.s new file mode 100644 index 00000000..807a1c42 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitary_amd64.s @@ -0,0 +1,160 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVSHDUP X3, X2 +#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3 +// MOVSLDUP X3, X3 +#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB +// ADDSUBPS X2, X3 +#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA + +// MOVSHDUP X5, X4 +#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5 +// MOVSLDUP X5, X5 +#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED +// ADDSUBPS X4, X5 +#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC + +// MOVSHDUP X7, X6 +#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7 +// MOVSLDUP X7, X7 +#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF +// ADDSUBPS X6, X7 +#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE + +// MOVSHDUP X9, X8 +#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1 +// MOVSLDUP X9, X9 +#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9 +// ADDSUBPS X8, X9 +#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyUnitary(alpha complex64, x, y []complex64) +TEXT ·AxpyUnitary(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), SI // SI = &x + MOVQ y_base+32(FP), DI // DI = &y + MOVQ x_len+16(FP), CX // CX = min( len(x), len(y) ) + CMPQ y_len+40(FP), CX + CMOVQLE y_len+40(FP), CX + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + PXOR X0, X0 // Clear work registers and cache-align loop + PXOR X1, X1 + MOVSD alpha+0(FP), X0 // X0 = { 0, 0, imag(a), real(a) } + SHUFPD $0, X0, X0 // X0 = { imag(a), real(a), imag(a), real(a) } + MOVAPS X0, X1 + SHUFPS $0x11, X1, X1 // X1 = { real(a), imag(a), real(a), imag(a) } + XORQ AX, AX // i = 0 + MOVQ DI, BX // Align on 16-byte boundary for ADDPS + ANDQ $15, BX // BX = &y & 15 + JZ caxy_no_trim // if BX == 0 { goto caxy_no_trim } + + // Trim first value in unaligned buffer + XORPS X2, X2 // Clear work registers and cache-align loop + XORPS X3, X3 + XORPS X4, X4 + MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) } + MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) } + MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) } + MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]), real(a)*real(x[i]) - imag(a)*imag(x[i]) } + ADDSUBPS_X2_X3 + MOVSD (DI)(AX*8), X4 // X3 += y[i] + ADDPS X4, X3 + MOVSD X3, (DI)(AX*8) // y[i] = X3 + INCQ AX // i++ + DECQ CX // --CX + JZ caxy_end // if CX == 0 { return } + +caxy_no_trim: + MOVAPS X0, X10 // Copy X0 and X1 for pipelineing + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $7, CX // CX = n % 8 + SHRQ $3, BX // BX = floor( n / 8 ) + JZ caxy_tail // if BX == 0 { goto caxy_tail } + +caxy_loop: // do { + // X_i = { imag(x[i]), real(x[i]), imag(x[i+1]), real(x[i+1]) } + MOVUPS (SI)(AX*8), X3 + MOVUPS 16(SI)(AX*8), X5 + MOVUPS 32(SI)(AX*8), X7 + MOVUPS 48(SI)(AX*8), X9 + + // X_(i-1) = { imag(x[i]), imag(x[i]), imag(x[i]+1), imag(x[i]+1) } + MOVSHDUP_X3_X2 + MOVSHDUP_X5_X4 + MOVSHDUP_X7_X6 + MOVSHDUP_X9_X8 + + // X_i = { real(x[i]), real(x[i]), real(x[i+1]), real(x[i+1]) } + MOVSLDUP_X3_X3 + MOVSLDUP_X5_X5 + MOVSLDUP_X7_X7 + MOVSLDUP_X9_X9 + + // X_i = { imag(a) * real(x[i]), real(a) * real(x[i]), + // imag(a) * real(x[i+1]), real(a) * real(x[i+1]) } + // X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]), + // real(a) * imag(x[i+1]), imag(a) * imag(x[i+1]) } + MULPS X1, X2 + MULPS X0, X3 + MULPS X11, X4 + MULPS X10, X5 + MULPS X1, X6 + MULPS X0, X7 + MULPS X11, X8 + MULPS X10, X9 + + // X_i = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]), + // imag(result[i+1]): imag(a)*real(x[i+1]) + real(a)*imag(x[i+1]), + // real(result[i+1]): real(a)*real(x[i+1]) - imag(a)*imag(x[i+1]), + // } + ADDSUBPS_X2_X3 + ADDSUBPS_X4_X5 + ADDSUBPS_X6_X7 + ADDSUBPS_X8_X9 + + // X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]), + // imag(result[i+1]) + imag(y[i+1]), real(result[i+1]) + real(y[i+1]) } + ADDPS (DI)(AX*8), X3 + ADDPS 16(DI)(AX*8), X5 + ADDPS 32(DI)(AX*8), X7 + ADDPS 48(DI)(AX*8), X9 + MOVUPS X3, (DI)(AX*8) // y[i:i+1] = X_i + MOVUPS X5, 16(DI)(AX*8) + MOVUPS X7, 32(DI)(AX*8) + MOVUPS X9, 48(DI)(AX*8) + ADDQ $8, AX // i += 8 + DECQ BX // --BX + JNZ caxy_loop // } while BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + +caxy_tail: // do { + MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) } + MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) } + MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) } + MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(a)*real(x[i]) - imag(a)*imag(x[i]) } + ADDSUBPS_X2_X3 + MOVSD (DI)(AX*8), X4 // X3 += y[i] + ADDPS X4, X3 + MOVSD X3, (DI)(AX*8) // y[i] = X3 + INCQ AX // ++i + LOOP caxy_tail // } while --CX > 0 + +caxy_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitaryto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitaryto_amd64.s new file mode 100644 index 00000000..ed5a8c93 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitaryto_amd64.s @@ -0,0 +1,157 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// MOVSHDUP X3, X2 +#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3 +// MOVSLDUP X3, X3 +#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB +// ADDSUBPS X2, X3 +#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA + +// MOVSHDUP X5, X4 +#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5 +// MOVSLDUP X5, X5 +#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED +// ADDSUBPS X4, X5 +#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC + +// MOVSHDUP X7, X6 +#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7 +// MOVSLDUP X7, X7 +#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF +// ADDSUBPS X6, X7 +#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE + +// MOVSHDUP X9, X8 +#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1 +// MOVSLDUP X9, X9 +#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9 +// ADDSUBPS X8, X9 +#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8 + +// func AxpyUnitaryTo(dst []complex64, alpha complex64, x, y []complex64) +TEXT ·AxpyUnitaryTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ x_base+32(FP), SI // SI = &x + MOVQ y_base+56(FP), DX // DX = &y + MOVQ x_len+40(FP), CX + CMPQ y_len+64(FP), CX // CX = min( len(x), len(y), len(dst) ) + CMOVQLE y_len+64(FP), CX + CMPQ dst_len+8(FP), CX + CMOVQLE dst_len+8(FP), CX + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + MOVSD alpha+24(FP), X0 // X0 = { 0, 0, imag(a), real(a) } + SHUFPD $0, X0, X0 // X0 = { imag(a), real(a), imag(a), real(a) } + MOVAPS X0, X1 + SHUFPS $0x11, X1, X1 // X1 = { real(a), imag(a), real(a), imag(a) } + XORQ AX, AX // i = 0 + MOVQ DX, BX // Align on 16-byte boundary for ADDPS + ANDQ $15, BX // BX = &y & 15 + JZ caxy_no_trim // if BX == 0 { goto caxy_no_trim } + + MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) } + MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) } + MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) } + MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]), real(a)*real(x[i]) - imag(a)*imag(x[i]) } + ADDSUBPS_X2_X3 + MOVSD (DX)(AX*8), X4 // X3 += y[i] + ADDPS X4, X3 + MOVSD X3, (DI)(AX*8) // dst[i] = X3 + INCQ AX // i++ + DECQ CX // --CX + JZ caxy_tail // if BX == 0 { goto caxy_tail } + +caxy_no_trim: + MOVAPS X0, X10 // Copy X0 and X1 for pipelineing + MOVAPS X1, X11 + MOVQ CX, BX + ANDQ $7, CX // CX = n % 8 + SHRQ $3, BX // BX = floor( n / 8 ) + JZ caxy_tail // if BX == 0 { goto caxy_tail } + +caxy_loop: + // X_i = { imag(x[i]), real(x[i]), imag(x[i+1]), real(x[i+1]) } + MOVUPS (SI)(AX*8), X3 + MOVUPS 16(SI)(AX*8), X5 + MOVUPS 32(SI)(AX*8), X7 + MOVUPS 48(SI)(AX*8), X9 + + // X_(i-1) = { imag(x[i]), imag(x[i]), imag(x[i]+1), imag(x[i]+1) } + MOVSHDUP_X3_X2 + MOVSHDUP_X5_X4 + MOVSHDUP_X7_X6 + MOVSHDUP_X9_X8 + + // X_i = { real(x[i]), real(x[i]), real(x[i+1]), real(x[i+1]) } + MOVSLDUP_X3_X3 + MOVSLDUP_X5_X5 + MOVSLDUP_X7_X7 + MOVSLDUP_X9_X9 + + // X_i = { imag(a) * real(x[i]), real(a) * real(x[i]), + // imag(a) * real(x[i+1]), real(a) * real(x[i+1]) } + // X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]), + // real(a) * imag(x[i+1]), imag(a) * imag(x[i+1]) } + MULPS X1, X2 + MULPS X0, X3 + MULPS X11, X4 + MULPS X10, X5 + MULPS X1, X6 + MULPS X0, X7 + MULPS X11, X8 + MULPS X10, X9 + + // X_i = { + // imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]), + // imag(result[i+1]): imag(a)*real(x[i+1]) + real(a)*imag(x[i+1]), + // real(result[i+1]): real(a)*real(x[i+1]) - imag(a)*imag(x[i+1]), + // } + ADDSUBPS_X2_X3 + ADDSUBPS_X4_X5 + ADDSUBPS_X6_X7 + ADDSUBPS_X8_X9 + + // X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]), + // imag(result[i+1]) + imag(y[i+1]), real(result[i+1]) + real(y[i+1]) } + ADDPS (DX)(AX*8), X3 + ADDPS 16(DX)(AX*8), X5 + ADDPS 32(DX)(AX*8), X7 + ADDPS 48(DX)(AX*8), X9 + MOVUPS X3, (DI)(AX*8) // y[i:i+1] = X_i + MOVUPS X5, 16(DI)(AX*8) + MOVUPS X7, 32(DI)(AX*8) + MOVUPS X9, 48(DI)(AX*8) + ADDQ $8, AX // i += 8 + DECQ BX // --BX + JNZ caxy_loop // } while BX > 0 + CMPQ CX, $0 // if CX == 0 { return } + JE caxy_end + +caxy_tail: // do { + MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) } + MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) } + MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) } + MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) } + MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) } + + // X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]), + // real(a)*real(x[i]) - imag(a)*imag(x[i]) } + ADDSUBPS_X2_X3 + MOVSD (DX)(AX*8), X4 // X3 += y[i] + ADDPS X4, X3 + MOVSD X3, (DI)(AX*8) // y[i] = X3 + INCQ AX // ++i + LOOP caxy_tail // } while --CX > 0 + +caxy_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/bench_test.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/bench_test.go new file mode 100644 index 00000000..0b7b5b83 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/bench_test.go @@ -0,0 +1,282 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c64 + +import "testing" + +var ( + a = complex64(2 + 2i) + x = make([]complex64, 1000000) + y = make([]complex64, 1000000) + z = make([]complex64, 1000000) +) + +func init() { + for n := range x { + x[n] = complex(float32(n), float32(n)) + y[n] = complex(float32(n), float32(n)) + } +} + +func benchaxpyu(t *testing.B, n int, f func(a complex64, x, y []complex64)) { + x, y := x[:n], y[:n] + for i := 0; i < t.N; i++ { + f(a, x, y) + } +} + +func naiveaxpyu(a complex64, x, y []complex64) { + for i, v := range x { + y[i] += a * v + } +} + +func BenchmarkC64AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, AxpyUnitary) } +func BenchmarkC64AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, AxpyUnitary) } +func BenchmarkC64AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, AxpyUnitary) } +func BenchmarkC64AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, AxpyUnitary) } +func BenchmarkC64AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, AxpyUnitary) } +func BenchmarkC64AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, AxpyUnitary) } +func BenchmarkC64AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, AxpyUnitary) } +func BenchmarkC64AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, AxpyUnitary) } +func BenchmarkC64AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, AxpyUnitary) } +func BenchmarkC64AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, AxpyUnitary) } +func BenchmarkC64AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, AxpyUnitary) } + +func BenchmarkLC64AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, naiveaxpyu) } +func BenchmarkLC64AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, naiveaxpyu) } + +func benchaxpyut(t *testing.B, n int, f func(d []complex64, a complex64, x, y []complex64)) { + x, y, z := x[:n], y[:n], z[:n] + for i := 0; i < t.N; i++ { + f(z, a, x, y) + } +} + +func naiveaxpyut(d []complex64, a complex64, x, y []complex64) { + for i, v := range x { + d[i] = y[i] + a*v + } +} + +func BenchmarkC64AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, AxpyUnitaryTo) } +func BenchmarkC64AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, AxpyUnitaryTo) } + +func BenchmarkLC64AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, naiveaxpyut) } +func BenchmarkLC64AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, naiveaxpyut) } + +func benchaxpyinc(t *testing.B, ln, t_inc int, f func(alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + for i := 0; i < t.N; i++ { + f(1+1i, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyinc(alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +func BenchmarkC64AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, AxpyInc) } + +func BenchmarkC64AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, AxpyInc) } +func BenchmarkC64AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, AxpyInc) } +func BenchmarkC64AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, AxpyInc) } +func BenchmarkC64AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, AxpyInc) } + +func BenchmarkC64AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, AxpyInc) } +func BenchmarkC64AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, AxpyInc) } +func BenchmarkC64AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, AxpyInc) } +func BenchmarkC64AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, AxpyInc) } + +func BenchmarkC64AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, AxpyInc) } +func BenchmarkC64AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, AxpyInc) } +func BenchmarkC64AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, AxpyInc) } +func BenchmarkC64AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, AxpyInc) } + +func BenchmarkC64AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, AxpyInc) } +func BenchmarkC64AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, AxpyInc) } +func BenchmarkC64AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, AxpyInc) } +func BenchmarkC64AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, AxpyInc) } + +func BenchmarkC64AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, AxpyInc) } +func BenchmarkC64AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, AxpyInc) } +func BenchmarkC64AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, AxpyInc) } +func BenchmarkC64AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, AxpyInc) } + +func BenchmarkC64AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, AxpyInc) } +func BenchmarkC64AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, AxpyInc) } +func BenchmarkC64AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, AxpyInc) } +func BenchmarkC64AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, AxpyInc) } + +func BenchmarkC64AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, AxpyInc) } +func BenchmarkC64AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, AxpyInc) } +func BenchmarkC64AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, AxpyInc) } +func BenchmarkC64AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, AxpyInc) } + +func BenchmarkLC64AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, naiveaxpyinc) } + +func BenchmarkLC64AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, naiveaxpyinc) } + +func BenchmarkLC64AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, naiveaxpyinc) } + +func BenchmarkLC64AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, naiveaxpyinc) } + +func BenchmarkLC64AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, naiveaxpyinc) } + +func BenchmarkLC64AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, naiveaxpyinc) } + +func BenchmarkLC64AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, naiveaxpyinc) } + +func BenchmarkLC64AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, naiveaxpyinc) } +func BenchmarkLC64AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, naiveaxpyinc) } + +func benchaxpyincto(t *testing.B, ln, t_inc int, f func(dst []complex64, incDst, idst uintptr, alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + for i := 0; i < t.N; i++ { + f(z, inc, uintptr(idx), 1+1i, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyincto(dst []complex64, incDst, idst uintptr, alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} + +func BenchmarkC64AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, AxpyIncTo) } + +func BenchmarkC64AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, AxpyIncTo) } +func BenchmarkC64AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, AxpyIncTo) } +func BenchmarkC64AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, AxpyIncTo) } +func BenchmarkC64AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, AxpyIncTo) } + +func BenchmarkC64AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, AxpyIncTo) } +func BenchmarkC64AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, AxpyIncTo) } +func BenchmarkC64AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, AxpyIncTo) } +func BenchmarkC64AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, AxpyIncTo) } + +func BenchmarkC64AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, AxpyIncTo) } +func BenchmarkC64AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, AxpyIncTo) } +func BenchmarkC64AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, AxpyIncTo) } +func BenchmarkC64AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, AxpyIncTo) } + +func BenchmarkC64AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, AxpyIncTo) } +func BenchmarkC64AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, AxpyIncTo) } +func BenchmarkC64AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, AxpyIncTo) } +func BenchmarkC64AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, AxpyIncTo) } + +func BenchmarkC64AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, AxpyIncTo) } +func BenchmarkC64AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, AxpyIncTo) } +func BenchmarkC64AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, AxpyIncTo) } +func BenchmarkC64AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, AxpyIncTo) } + +func BenchmarkC64AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, AxpyIncTo) } +func BenchmarkC64AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, AxpyIncTo) } +func BenchmarkC64AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, AxpyIncTo) } +func BenchmarkC64AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, AxpyIncTo) } + +func BenchmarkC64AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, AxpyIncTo) } +func BenchmarkC64AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, AxpyIncTo) } +func BenchmarkC64AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, AxpyIncTo) } +func BenchmarkC64AxpyIncToN100000IncM10(b *testing.B) { benchaxpyincto(b, 100000, -10, AxpyIncTo) } + +func BenchmarkLC64AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, naiveaxpyincto) } + +func BenchmarkLC64AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, naiveaxpyincto) } + +func BenchmarkLC64AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, naiveaxpyincto) } + +func BenchmarkLC64AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, naiveaxpyincto) } + +func BenchmarkLC64AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, naiveaxpyincto) } + +func BenchmarkLC64AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, naiveaxpyincto) } + +func BenchmarkLC64AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, naiveaxpyincto) } + +func BenchmarkLC64AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, naiveaxpyincto) } +func BenchmarkLC64AxpyIncToN100000IncM10(b *testing.B) { benchaxpyincto(b, 100000, -10, naiveaxpyincto) } diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/conj.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/conj.go new file mode 100644 index 00000000..932be953 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/conj.go @@ -0,0 +1,7 @@ +// 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 c64 + +func conj(c complex64) complex64 { return complex(real(c), -imag(c)) } diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/doc.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/doc.go new file mode 100644 index 00000000..a0b8862b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package c64 provides complex64 vector primitives. +package c64 // import "gonum.org/v1/gonum/internal/asm/c64" diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/dotc.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/dotc.go new file mode 100644 index 00000000..cd5b862b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/dotc.go @@ -0,0 +1,33 @@ +// 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 c64 + +// DotcUnitary is +// for i, v := range x { +// sum += y[i] * conj(v) +// } +// return sum +func DotcUnitary(x, y []complex64) (sum complex64) { + for i, v := range x { + sum += y[i] * conj(v) + } + return sum +} + +// DotcInc is +// for i := 0; i < int(n); i++ { +// sum += y[iy] * conj(x[ix]) +// ix += incX +// iy += incY +// } +// return sum +func DotcInc(x, y []complex64, n, incX, incY, ix, iy uintptr) (sum complex64) { + for i := 0; i < int(n); i++ { + sum += y[iy] * conj(x[ix]) + ix += incX + iy += incY + } + return sum +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/dotu.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/dotu.go new file mode 100644 index 00000000..ff15d659 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/dotu.go @@ -0,0 +1,33 @@ +// 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 c64 + +// DotuUnitary is +// for i, v := range x { +// sum += y[i] * v +// } +// return sum +func DotuUnitary(x, y []complex64) (sum complex64) { + for i, v := range x { + sum += y[i] * v + } + return sum +} + +// DotuInc is +// for i := 0; i < int(n); i++ { +// sum += y[iy] * x[ix] +// ix += incX +// iy += incY +// } +// return sum +func DotuInc(x, y []complex64, n, incX, incY, ix, iy uintptr) (sum complex64) { + for i := 0; i < int(n); i++ { + sum += y[iy] * x[ix] + ix += incX + iy += incY + } + return sum +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/scal.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/scal.go new file mode 100644 index 00000000..11212813 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/scal.go @@ -0,0 +1,55 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c64 + +// ScalUnitary is +// for i := range x { +// x[i] *= alpha +// } +func ScalUnitary(alpha complex64, x []complex64) { + for i := range x { + x[i] *= alpha + } +} + +// ScalUnitaryTo is +// for i, v := range x { +// dst[i] = alpha * v +// } +func ScalUnitaryTo(dst []complex64, alpha complex64, x []complex64) { + for i, v := range x { + dst[i] = alpha * v + } +} + +// ScalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] *= alpha +// ix += incX +// } +func ScalInc(alpha complex64, x []complex64, n, incX uintptr) { + var ix uintptr + for i := 0; i < int(n); i++ { + x[ix] *= alpha + ix += incX + } +} + +// ScalIncTo is +// var idst, ix uintptr +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha * x[ix] +// ix += incX +// idst += incDst +// } +func ScalIncTo(dst []complex64, incDst uintptr, alpha complex64, x []complex64, n, incX uintptr) { + var idst, ix uintptr + for i := 0; i < int(n); i++ { + dst[idst] = alpha * x[ix] + ix += incX + idst += incDst + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_amd64.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_amd64.go new file mode 100644 index 00000000..bd6486c3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_amd64.go @@ -0,0 +1,36 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +package c64 + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha complex64, x, y []complex64) + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []complex64, alpha complex64, x, y []complex64) + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []complex64, incDst, idst uintptr, alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_noasm.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_noasm.go new file mode 100644 index 00000000..78aebbd6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_noasm.go @@ -0,0 +1,57 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !amd64 noasm appengine + +package c64 + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha complex64, x, y []complex64) { + for i, v := range x { + y[i] += alpha * v + } +} + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []complex64, alpha complex64, x, y []complex64) { + for i, v := range x { + dst[i] = alpha*v + y[i] + } +} + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []complex64, incDst, idst uintptr, alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_test.go b/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_test.go new file mode 100644 index 00000000..8049a763 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/c64/stubs_test.go @@ -0,0 +1,231 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package c64 + +import "testing" + +var tests = []struct { + incX, incY, incDst int + ix, iy, idst uintptr + a complex64 + dst, x, y []complex64 + ex []complex64 +}{ + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 1i, + dst: []complex64{5}, + x: []complex64{1}, + y: []complex64{1i}, + ex: []complex64{1 + 2i}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 2i, + dst: []complex64{0, 0, 0}, + x: []complex64{0, 0, 0}, + y: []complex64{1, 1, 1}, + ex: []complex64{1, 1, 1}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 2i, + dst: []complex64{0, 0, 0}, + x: []complex64{0, 0}, + y: []complex64{1, 1, 1}, + ex: []complex64{1, 1}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 + 2i, + dst: []complex64{1i, 1i, 1i}, + x: []complex64{1i, 1i, 1i}, + y: []complex64{1, 2, 1}, + ex: []complex64{-1 + 1i, 1i, -1 + 1i}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -1i, + dst: []complex64{1i, 1i, 1i}, + x: []complex64{1i, 1i, 1i}, + y: []complex64{1, 2, 1}, + ex: []complex64{2, 3, 2}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -1i, + dst: []complex64{1i, 1i, 1i}, + x: []complex64{1i, 1i, 1i, 1i, 1i}[1:4], + y: []complex64{1, 1, 2, 1, 1}[1:4], + ex: []complex64{2, 3, 2}}, + {incX: 2, incY: 4, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -2, + dst: []complex64{1i, 1i, 1i, 1i, 1i}, + x: []complex64{2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i}, + y: []complex64{1, 1, 2, 1, 1}, + ex: []complex64{-3 - 2i, -3 - 2i, -2 - 2i, -3 - 2i, -3 - 2i}}, + // Run big test twice, once aligned once unaligned. + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 - 1i, + dst: make([]complex64, 10), + x: []complex64{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex64{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex64{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 1 - 1i, + dst: make([]complex64, 10), + x: []complex64{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex64{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex64{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, + {incX: -2, incY: -2, incDst: -3, ix: 18, iy: 18, idst: 27, + a: 1 - 1i, + dst: make([]complex64, 10), + x: []complex64{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex64{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex64{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, + {incX: -2, incY: 2, incDst: -3, ix: 18, iy: 0, idst: 27, + a: 1 - 1i, + dst: make([]complex64, 10), + x: []complex64{1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i, 1i}, + y: []complex64{1, 1, 2, 1, 1, 1, 1, 2, 1, 1}, + ex: []complex64{2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 2 + 1i, 3 + 1i, 2 + 1i, 2 + 1i}}, +} + +func guardVector(vec []complex64, guard_val complex64, guard_len int) (guarded []complex64) { + guarded = make([]complex64, len(vec)+guard_len*2) + copy(guarded[guard_len:], vec) + for i := 0; i < guard_len; i++ { + guarded[i] = guard_val + guarded[len(guarded)-1-i] = guard_val + } + return guarded +} + +func isValidGuard(vec []complex64, guard_val complex64, guard_len int) bool { + for i := 0; i < guard_len; i++ { + if vec[i] != guard_val || vec[len(vec)-1-i] != guard_val { + return false + } + } + return true +} + +func TestAxpyUnitary(t *testing.T) { + var x_gd, y_gd complex64 = 1, 1 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardVector(test.x, x_gd, xg_ln), guardVector(test.y, y_gd, yg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + AxpyUnitary(test.a, x, y) + for i := range test.ex { + if y[i] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i], test.ex[i]) + } + } + if !isValidGuard(test.x, x_gd, xg_ln) { + t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xg_ln], test.x[len(test.x)-xg_ln:]) + } + if !isValidGuard(test.y, y_gd, yg_ln) { + t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:yg_ln], test.y[len(test.y)-yg_ln:]) + } + } +} + +func TestAxpyUnitaryTo(t *testing.T) { + var x_gd, y_gd, dst_gd complex64 = 1, 1, 0 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardVector(test.x, x_gd, xg_ln), guardVector(test.y, y_gd, yg_ln) + test.dst = guardVector(test.dst, dst_gd, xg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + dst := test.dst[xg_ln : len(test.dst)-xg_ln] + AxpyUnitaryTo(dst, test.a, x, y) + for i := range test.ex { + if dst[i] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i], test.ex[i]) + } + } + if !isValidGuard(test.x, x_gd, xg_ln) { + t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xg_ln], test.x[len(test.x)-xg_ln:]) + } + if !isValidGuard(test.y, y_gd, yg_ln) { + t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:yg_ln], test.y[len(test.y)-yg_ln:]) + } + if !isValidGuard(test.dst, dst_gd, xg_ln) { + t.Errorf("Test %d Guard violated in dst vector %v %v", cas, test.dst[:xg_ln], test.dst[len(test.dst)-xg_ln:]) + } + + } +} + +func guardIncVector(vec []complex64, guard_val complex64, incV uintptr, guard_len int) (guarded []complex64) { + inc := int(incV) + s_ln := len(vec) * inc + if inc < 0 { + s_ln = len(vec) * -inc + } + guarded = make([]complex64, s_ln+guard_len*2) + for i, cas := 0, 0; i < len(guarded); i++ { + switch { + case i < guard_len, i > guard_len+s_ln: + guarded[i] = guard_val + case (i-guard_len)%(inc) == 0 && cas < len(vec): + guarded[i] = vec[cas] + cas++ + default: + guarded[i] = guard_val + } + } + return guarded +} + +func checkValidIncGuard(t *testing.T, vec []complex64, guard_val complex64, incV uintptr, guard_len int) { + inc := int(incV) + s_ln := len(vec) - 2*guard_len + if inc < 0 { + s_ln = len(vec) * -inc + } + + for i := range vec { + switch { + case vec[i] == guard_val: + // Correct value + case i < guard_len: + t.Errorf("Front guard violated at %d %v", i, vec[:guard_len]) + case i > guard_len+s_ln: + t.Errorf("Back guard violated at %d %v", i-guard_len-s_ln, vec[guard_len+s_ln:]) + case (i-guard_len)%inc == 0 && (i-guard_len)/inc < len(vec): + // Ignore input values + default: + t.Errorf("Internal guard violated at %d %v", i-guard_len, vec[guard_len:guard_len+s_ln]) + } + } +} + +func TestAxpyInc(t *testing.T) { + var x_gd, y_gd complex64 = 1, 1 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardIncVector(test.x, x_gd, uintptr(test.incX), xg_ln), guardIncVector(test.y, y_gd, uintptr(test.incY), yg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + AxpyInc(test.a, x, y, uintptr(len(test.ex)), uintptr(test.incX), uintptr(test.incY), test.ix, test.iy) + for i := range test.ex { + if y[int(test.iy)+i*int(test.incY)] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i*int(test.incY)], test.ex[i]) + } + } + checkValidIncGuard(t, test.x, x_gd, uintptr(test.incX), xg_ln) + checkValidIncGuard(t, test.y, y_gd, uintptr(test.incY), yg_ln) + } +} + +func TestAxpyIncTo(t *testing.T) { + var x_gd, y_gd, dst_gd complex64 = 1, 1, 0 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardIncVector(test.x, x_gd, uintptr(test.incX), xg_ln), guardIncVector(test.y, y_gd, uintptr(test.incY), yg_ln) + test.dst = guardIncVector(test.dst, dst_gd, uintptr(test.incDst), xg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + dst := test.dst[xg_ln : len(test.dst)-xg_ln] + AxpyIncTo(dst, uintptr(test.incDst), test.idst, test.a, x, y, uintptr(len(test.ex)), uintptr(test.incX), uintptr(test.incY), test.ix, test.iy) + for i := range test.ex { + if dst[int(test.idst)+i*int(test.incDst)] != test.ex[i] { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i*int(test.incDst)], test.ex[i]) + } + } + checkValidIncGuard(t, test.x, x_gd, uintptr(test.incX), xg_ln) + checkValidIncGuard(t, test.y, y_gd, uintptr(test.incY), yg_ln) + checkValidIncGuard(t, test.dst, dst_gd, uintptr(test.incDst), xg_ln) + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyinc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyinc_amd64.s new file mode 100644 index 00000000..a6462f0e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyinc_amd64.s @@ -0,0 +1,73 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// func AxpyInc(alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyInc(SB), NOSPLIT, $0 + MOVQ n+56(FP), CX // CX = n + CMPQ CX, $0 // if n==0 { return } + JLE axpyi_end + MOVQ x_base+8(FP), SI // SI = &x + MOVQ y_base+32(FP), DI // DI = &y + MOVQ ix+80(FP), R8 // R8 = ix + MOVQ iy+88(FP), R9 // R9 = iy + LEAQ (SI)(R8*4), SI // SI = &(x[ix]) + LEAQ (DI)(R9*4), DI // DI = &(y[iy]) + MOVQ DI, DX // DX = DI Read Pointer for y + MOVQ incX+64(FP), R8 // R8 = incX + SHLQ $2, R8 // R8 *= sizeof(float32) + MOVQ incY+72(FP), R9 // R9 = incY + SHLQ $2, R9 // R9 *= sizeof(float32) + MOVSS alpha+0(FP), X0 // X0 = alpha + MOVSS X0, X1 // X1 = X0 // for pipelining + MOVQ CX, BX + ANDQ $3, BX // BX = n % 4 + SHRQ $2, CX // CX = floor( n / 4 ) + JZ axpyi_tail_start // if CX == 0 { goto axpyi_tail_start } + +axpyi_loop: // Loop unrolled 4x do { + MOVSS (SI), X2 // X_i = x[i] + MOVSS (SI)(R8*1), X3 + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + MOVSS (SI), X4 + MOVSS (SI)(R8*1), X5 + MULSS X1, X2 // X_i *= a + MULSS X0, X3 + MULSS X1, X4 + MULSS X0, X5 + ADDSS (DX), X2 // X_i += y[i] + ADDSS (DX)(R9*1), X3 + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + ADDSS (DX), X4 + ADDSS (DX)(R9*1), X5 + MOVSS X2, (DI) // y[i] = X_i + MOVSS X3, (DI)(R9*1) + LEAQ (DI)(R9*2), DI // DI = &(DI[incY*2]) + MOVSS X4, (DI) + MOVSS X5, (DI)(R9*1) + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) // Increment addresses + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + LEAQ (DI)(R9*2), DI // DI = &(DI[incY*2]) + LOOP axpyi_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE axpyi_end + +axpyi_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + +axpyi_tail: // do { + MOVSS (SI), X2 // X2 = x[i] + MULSS X1, X2 // X2 *= a + ADDSS (DI), X2 // X2 += y[i] + MOVSS X2, (DI) // y[i] = X2 + ADDQ R8, SI // SI = &(SI[incX]) + ADDQ R9, DI // DI = &(DI[incY]) + LOOP axpyi_tail // } while --CX > 0 + +axpyi_end: + RET + diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyincto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyincto_amd64.s new file mode 100644 index 00000000..e1c39e90 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyincto_amd64.s @@ -0,0 +1,78 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// func AxpyIncTo(dst []float32, incDst, idst uintptr, alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyIncTo(SB), NOSPLIT, $0 + MOVQ n+96(FP), CX // CX = n + CMPQ CX, $0 // if n==0 { return } + JLE axpyi_end + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ x_base+48(FP), SI // SI = &x + MOVQ y_base+72(FP), DX // DX = &y + MOVQ ix+120(FP), R8 // R8 = ix // Load the first index + MOVQ iy+128(FP), R9 // R9 = iy + MOVQ idst+32(FP), R10 // R10 = idst + LEAQ (SI)(R8*4), SI // SI = &(x[ix]) + LEAQ (DX)(R9*4), DX // DX = &(y[iy]) + LEAQ (DI)(R10*4), DI // DI = &(dst[idst]) + MOVQ incX+104(FP), R8 // R8 = incX + SHLQ $2, R8 // R8 *= sizeof(float32) + MOVQ incY+112(FP), R9 // R9 = incY + SHLQ $2, R9 // R9 *= sizeof(float32) + MOVQ incDst+24(FP), R10 // R10 = incDst + SHLQ $2, R10 // R10 *= sizeof(float32) + MOVSS alpha+40(FP), X0 // X0 = alpha + MOVSS X0, X1 // X1 = X0 // for pipelining + MOVQ CX, BX + ANDQ $3, BX // BX = n % 4 + SHRQ $2, CX // CX = floor( n / 4 ) + JZ axpyi_tail_start // if CX == 0 { goto axpyi_tail_start } + +axpyi_loop: // Loop unrolled 4x do { + MOVSS (SI), X2 // X_i = x[i] + MOVSS (SI)(R8*1), X3 + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) + MOVSS (SI), X4 + MOVSS (SI)(R8*1), X5 + MULSS X1, X2 // X_i *= a + MULSS X0, X3 + MULSS X1, X4 + MULSS X0, X5 + ADDSS (DX), X2 // X_i += y[i] + ADDSS (DX)(R9*1), X3 + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + ADDSS (DX), X4 + ADDSS (DX)(R9*1), X5 + MOVSS X2, (DI) // dst[i] = X_i + MOVSS X3, (DI)(R10*1) + LEAQ (DI)(R10*2), DI // DI = &(DI[incDst*2]) + MOVSS X4, (DI) + MOVSS X5, (DI)(R10*1) + LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2]) // Increment addresses + LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2]) + LEAQ (DI)(R10*2), DI // DI = &(DI[incDst*2]) + LOOP axpyi_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE axpyi_end + +axpyi_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + +axpyi_tail: // do { + MOVSS (SI), X2 // X2 = x[i] + MULSS X1, X2 // X2 *= a + ADDSS (DX), X2 // X2 += y[i] + MOVSS X2, (DI) // dst[i] = X2 + ADDQ R8, SI // SI = &(SI[incX]) + ADDQ R9, DX // DX = &(DX[incY]) + ADDQ R10, DI // DI = &(DI[incY]) + LOOP axpyi_tail // } while --CX > 0 + +axpyi_end: + RET + diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyunitary_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyunitary_amd64.s new file mode 100644 index 00000000..a5bfaac9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyunitary_amd64.s @@ -0,0 +1,97 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// func AxpyUnitary(alpha float32, x, y []float32) +TEXT ·AxpyUnitary(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), SI // SI = &x + MOVQ y_base+32(FP), DI // DI = &y + MOVQ x_len+16(FP), BX // BX = min( len(x), len(y) ) + CMPQ y_len+40(FP), BX + CMOVQLE y_len+40(FP), BX + CMPQ BX, $0 // if BX == 0 { return } + JE axpy_end + MOVSS alpha+0(FP), X0 + SHUFPS $0, X0, X0 // X0 = { a, a, a, a } + XORQ AX, AX // i = 0 + PXOR X2, X2 // 2 NOP instructions (PXOR) to align + PXOR X3, X3 // loop to cache line + MOVQ DI, CX + ANDQ $0xF, CX // Align on 16-byte boundary for ADDPS + JZ axpy_no_trim // if CX == 0 { goto axpy_no_trim } + + XORQ $0xF, CX // CX = 4 - floor( BX % 16 / 4 ) + INCQ CX + SHRQ $2, CX + +axpy_align: // Trim first value(s) in unaligned buffer do { + MOVSS (SI)(AX*4), X2 // X2 = x[i] + MULSS X0, X2 // X2 *= a + ADDSS (DI)(AX*4), X2 // X2 += y[i] + MOVSS X2, (DI)(AX*4) // y[i] = X2 + INCQ AX // i++ + DECQ BX + JZ axpy_end // if --BX == 0 { return } + LOOP axpy_align // } while --CX > 0 + +axpy_no_trim: + MOVUPS X0, X1 // Copy X0 to X1 for pipelining + MOVQ BX, CX + ANDQ $0xF, BX // BX = len % 16 + SHRQ $4, CX // CX = int( len / 16 ) + JZ axpy_tail4_start // if CX == 0 { return } + +axpy_loop: // Loop unrolled 16x do { + MOVUPS (SI)(AX*4), X2 // X2 = x[i:i+4] + MOVUPS 16(SI)(AX*4), X3 + MOVUPS 32(SI)(AX*4), X4 + MOVUPS 48(SI)(AX*4), X5 + MULPS X0, X2 // X2 *= a + MULPS X1, X3 + MULPS X0, X4 + MULPS X1, X5 + ADDPS (DI)(AX*4), X2 // X2 += y[i:i+4] + ADDPS 16(DI)(AX*4), X3 + ADDPS 32(DI)(AX*4), X4 + ADDPS 48(DI)(AX*4), X5 + MOVUPS X2, (DI)(AX*4) // dst[i:i+4] = X2 + MOVUPS X3, 16(DI)(AX*4) + MOVUPS X4, 32(DI)(AX*4) + MOVUPS X5, 48(DI)(AX*4) + ADDQ $16, AX // i += 16 + LOOP axpy_loop // while (--CX) > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE axpy_end + +axpy_tail4_start: // Reset loop counter for 4-wide tail loop + MOVQ BX, CX // CX = floor( BX / 4 ) + SHRQ $2, CX + JZ axpy_tail_start // if CX == 0 { goto axpy_tail_start } + +axpy_tail4: // Loop unrolled 4x do { + MOVUPS (SI)(AX*4), X2 // X2 = x[i] + MULPS X0, X2 // X2 *= a + ADDPS (DI)(AX*4), X2 // X2 += y[i] + MOVUPS X2, (DI)(AX*4) // y[i] = X2 + ADDQ $4, AX // i += 4 + LOOP axpy_tail4 // } while --CX > 0 + +axpy_tail_start: // Reset loop counter for 1-wide tail loop + MOVQ BX, CX // CX = BX % 4 + ANDQ $3, CX + JZ axpy_end // if CX == 0 { return } + +axpy_tail: + MOVSS (SI)(AX*4), X1 // X1 = x[i] + MULSS X0, X1 // X1 *= a + ADDSS (DI)(AX*4), X1 // X1 += y[i] + MOVSS X1, (DI)(AX*4) // y[i] = X1 + INCQ AX // i++ + LOOP axpy_tail // } while --CX > 0 + +axpy_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyunitaryto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyunitaryto_amd64.s new file mode 100644 index 00000000..9a8289f8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/axpyunitaryto_amd64.s @@ -0,0 +1,98 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +#include "textflag.h" + +// func AxpyUnitaryTo(dst []float32, alpha float32, x, y []float32) +TEXT ·AxpyUnitaryTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ x_base+32(FP), SI // SI = &x + MOVQ y_base+56(FP), DX // DX = &y + MOVQ x_len+40(FP), BX // BX = min( len(x), len(y), len(dst) ) + CMPQ y_len+64(FP), BX + CMOVQLE y_len+64(FP), BX + CMPQ dst_len+8(FP), BX + CMOVQLE dst_len+8(FP), BX + CMPQ BX, $0 // if BX == 0 { return } + JE axpy_end + MOVSS alpha+24(FP), X0 + SHUFPS $0, X0, X0 // X0 = { a, a, a, a, } + XORQ AX, AX // i = 0 + MOVQ DX, CX + ANDQ $0xF, CX // Align on 16-byte boundary for ADDPS + JZ axpy_no_trim // if CX == 0 { goto axpy_no_trim } + + XORQ $0xF, CX // CX = 4 - floor ( B % 16 / 4 ) + INCQ CX + SHRQ $2, CX + +axpy_align: // Trim first value(s) in unaligned buffer do { + MOVSS (SI)(AX*4), X2 // X2 = x[i] + MULSS X0, X2 // X2 *= a + ADDSS (DX)(AX*4), X2 // X2 += y[i] + MOVSS X2, (DI)(AX*4) // y[i] = X2 + INCQ AX // i++ + DECQ BX + JZ axpy_end // if --BX == 0 { return } + LOOP axpy_align // } while --CX > 0 + +axpy_no_trim: + MOVUPS X0, X1 // Copy X0 to X1 for pipelining + MOVQ BX, CX + ANDQ $0xF, BX // BX = len % 16 + SHRQ $4, CX // CX = floor( len / 16 ) + JZ axpy_tail4_start // if CX == 0 { return } + +axpy_loop: // Loop unrolled 16x do { + MOVUPS (SI)(AX*4), X2 // X2 = x[i:i+4] + MOVUPS 16(SI)(AX*4), X3 + MOVUPS 32(SI)(AX*4), X4 + MOVUPS 48(SI)(AX*4), X5 + MULPS X0, X2 // X2 *= a + MULPS X1, X3 + MULPS X0, X4 + MULPS X1, X5 + ADDPS (DX)(AX*4), X2 // X2 += y[i:i+4] + ADDPS 16(DX)(AX*4), X3 + ADDPS 32(DX)(AX*4), X4 + ADDPS 48(DX)(AX*4), X5 + MOVUPS X2, (DI)(AX*4) // dst[i:i+4] = X2 + MOVUPS X3, 16(DI)(AX*4) + MOVUPS X4, 32(DI)(AX*4) + MOVUPS X5, 48(DI)(AX*4) + ADDQ $16, AX // i += 16 + LOOP axpy_loop // while (--CX) > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE axpy_end + +axpy_tail4_start: // Reset loop counter for 4-wide tail loop + MOVQ BX, CX // CX = floor( BX / 4 ) + SHRQ $2, CX + JZ axpy_tail_start // if CX == 0 { goto axpy_tail_start } + +axpy_tail4: // Loop unrolled 4x do { + MOVUPS (SI)(AX*4), X2 // X2 = x[i] + MULPS X0, X2 // X2 *= a + ADDPS (DX)(AX*4), X2 // X2 += y[i] + MOVUPS X2, (DI)(AX*4) // y[i] = X2 + ADDQ $4, AX // i += 4 + LOOP axpy_tail4 // } while --CX > 0 + +axpy_tail_start: // Reset loop counter for 1-wide tail loop + MOVQ BX, CX // CX = BX % 4 + ANDQ $3, CX + JZ axpy_end // if CX == 0 { return } + +axpy_tail: + MOVSS (SI)(AX*4), X1 // X1 = x[i] + MULSS X0, X1 // X1 *= a + ADDSS (DX)(AX*4), X1 // X1 += y[i] + MOVSS X1, (DI)(AX*4) // y[i] = X1 + INCQ AX // i++ + LOOP axpy_tail // } while --CX > 0 + +axpy_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/bench_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/bench_test.go new file mode 100644 index 00000000..a1c415ce --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/bench_test.go @@ -0,0 +1,282 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package f32 + +import "testing" + +var ( + a = float32(2) + x = make([]float32, 1000000) + y = make([]float32, 1000000) + z = make([]float32, 1000000) +) + +func init() { + for n := range x { + x[n] = float32(n) + y[n] = float32(n) + } +} + +func benchaxpyu(t *testing.B, n int, f func(a float32, x, y []float32)) { + x, y := x[:n], y[:n] + for i := 0; i < t.N; i++ { + f(a, x, y) + } +} + +func naiveaxpyu(a float32, x, y []float32) { + for i, v := range x { + y[i] += a * v + } +} + +func BenchmarkF32AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, AxpyUnitary) } +func BenchmarkF32AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, AxpyUnitary) } +func BenchmarkF32AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, AxpyUnitary) } +func BenchmarkF32AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, AxpyUnitary) } +func BenchmarkF32AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, AxpyUnitary) } +func BenchmarkF32AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, AxpyUnitary) } +func BenchmarkF32AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, AxpyUnitary) } +func BenchmarkF32AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, AxpyUnitary) } +func BenchmarkF32AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, AxpyUnitary) } +func BenchmarkF32AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, AxpyUnitary) } +func BenchmarkF32AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, AxpyUnitary) } + +func BenchmarkLF32AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, naiveaxpyu) } +func BenchmarkLF32AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, naiveaxpyu) } + +func benchaxpyut(t *testing.B, n int, f func(d []float32, a float32, x, y []float32)) { + x, y, z := x[:n], y[:n], z[:n] + for i := 0; i < t.N; i++ { + f(z, a, x, y) + } +} + +func naiveaxpyut(d []float32, a float32, x, y []float32) { + for i, v := range x { + d[i] = y[i] + a*v + } +} + +func BenchmarkF32AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, AxpyUnitaryTo) } +func BenchmarkF32AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, AxpyUnitaryTo) } + +func BenchmarkLF32AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, naiveaxpyut) } +func BenchmarkLF32AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, naiveaxpyut) } + +func benchaxpyinc(t *testing.B, ln, t_inc int, f func(alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + for i := 0; i < t.N; i++ { + f(1, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyinc(alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +func BenchmarkF32AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, AxpyInc) } + +func BenchmarkF32AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, AxpyInc) } +func BenchmarkF32AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, AxpyInc) } +func BenchmarkF32AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, AxpyInc) } +func BenchmarkF32AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, AxpyInc) } + +func BenchmarkF32AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, AxpyInc) } +func BenchmarkF32AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, AxpyInc) } +func BenchmarkF32AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, AxpyInc) } +func BenchmarkF32AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, AxpyInc) } + +func BenchmarkF32AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, AxpyInc) } +func BenchmarkF32AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, AxpyInc) } +func BenchmarkF32AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, AxpyInc) } +func BenchmarkF32AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, AxpyInc) } + +func BenchmarkF32AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, AxpyInc) } +func BenchmarkF32AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, AxpyInc) } +func BenchmarkF32AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, AxpyInc) } +func BenchmarkF32AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, AxpyInc) } + +func BenchmarkF32AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, AxpyInc) } +func BenchmarkF32AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, AxpyInc) } +func BenchmarkF32AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, AxpyInc) } +func BenchmarkF32AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, AxpyInc) } + +func BenchmarkF32AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, AxpyInc) } +func BenchmarkF32AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, AxpyInc) } +func BenchmarkF32AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, AxpyInc) } +func BenchmarkF32AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, AxpyInc) } + +func BenchmarkF32AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, AxpyInc) } +func BenchmarkF32AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, AxpyInc) } +func BenchmarkF32AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, AxpyInc) } +func BenchmarkF32AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, AxpyInc) } + +func BenchmarkLF32AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, naiveaxpyinc) } + +func BenchmarkLF32AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, naiveaxpyinc) } + +func BenchmarkLF32AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, naiveaxpyinc) } + +func BenchmarkLF32AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, naiveaxpyinc) } + +func BenchmarkLF32AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, naiveaxpyinc) } + +func BenchmarkLF32AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, naiveaxpyinc) } + +func BenchmarkLF32AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, naiveaxpyinc) } + +func BenchmarkLF32AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, naiveaxpyinc) } +func BenchmarkLF32AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, naiveaxpyinc) } + +func benchaxpyincto(t *testing.B, ln, t_inc int, f func(dst []float32, incDst, idst uintptr, alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + for i := 0; i < t.N; i++ { + f(z, inc, uintptr(idx), 1, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyincto(dst []float32, incDst, idst uintptr, alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} + +func BenchmarkF32AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, AxpyIncTo) } + +func BenchmarkF32AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, AxpyIncTo) } +func BenchmarkF32AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, AxpyIncTo) } +func BenchmarkF32AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, AxpyIncTo) } +func BenchmarkF32AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, AxpyIncTo) } + +func BenchmarkF32AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, AxpyIncTo) } +func BenchmarkF32AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, AxpyIncTo) } +func BenchmarkF32AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, AxpyIncTo) } +func BenchmarkF32AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, AxpyIncTo) } + +func BenchmarkF32AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, AxpyIncTo) } +func BenchmarkF32AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, AxpyIncTo) } +func BenchmarkF32AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, AxpyIncTo) } +func BenchmarkF32AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, AxpyIncTo) } + +func BenchmarkF32AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, AxpyIncTo) } +func BenchmarkF32AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, AxpyIncTo) } +func BenchmarkF32AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, AxpyIncTo) } +func BenchmarkF32AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, AxpyIncTo) } + +func BenchmarkF32AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, AxpyIncTo) } +func BenchmarkF32AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, AxpyIncTo) } +func BenchmarkF32AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, AxpyIncTo) } +func BenchmarkF32AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, AxpyIncTo) } + +func BenchmarkF32AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, AxpyIncTo) } +func BenchmarkF32AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, AxpyIncTo) } +func BenchmarkF32AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, AxpyIncTo) } +func BenchmarkF32AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, AxpyIncTo) } + +func BenchmarkF32AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, AxpyIncTo) } +func BenchmarkF32AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, AxpyIncTo) } +func BenchmarkF32AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, AxpyIncTo) } +func BenchmarkF32AxpyIncToN100000IncM10(b *testing.B) { benchaxpyincto(b, 100000, -10, AxpyIncTo) } + +func BenchmarkLF32AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, naiveaxpyincto) } + +func BenchmarkLF32AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, naiveaxpyincto) } + +func BenchmarkLF32AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, naiveaxpyincto) } + +func BenchmarkLF32AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, naiveaxpyincto) } + +func BenchmarkLF32AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, naiveaxpyincto) } + +func BenchmarkLF32AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, naiveaxpyincto) } + +func BenchmarkLF32AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, naiveaxpyincto) } + +func BenchmarkLF32AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, naiveaxpyincto) } +func BenchmarkLF32AxpyIncToN100000IncM10(b *testing.B) { benchaxpyincto(b, 100000, -10, naiveaxpyincto) } diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/ddot.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/ddot.go new file mode 100644 index 00000000..6920f659 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/ddot.go @@ -0,0 +1,33 @@ +// 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 f32 + +// DdotUnitary is +// for i, v := range x { +// sum += float64(y[i]) * float64(v) +// } +// return +func DdotUnitary(x, y []float32) (sum float64) { + for i, v := range x { + sum += float64(y[i]) * float64(v) + } + return +} + +// DdotInc is +// for i := 0; i < int(n); i++ { +// sum += float64(y[iy]) * float64(x[ix]) +// ix += incX +// iy += incY +// } +// return +func DdotInc(x, y []float32, n, incX, incY, ix, iy uintptr) (sum float64) { + for i := 0; i < int(n); i++ { + sum += float64(y[iy]) * float64(x[ix]) + ix += incX + iy += incY + } + return +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/doc.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/doc.go new file mode 100644 index 00000000..89e9c224 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package f32 provides float32 vector primitives. +package f32 // import "gonum.org/v1/gonum/internal/asm/f32" diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/dot.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/dot.go new file mode 100644 index 00000000..7a27d35e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/dot.go @@ -0,0 +1,33 @@ +// 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 f32 + +// DotUnitary is +// for i, v := range x { +// sum += y[i] * v +// } +// return sum +func DotUnitary(x, y []float32) (sum float32) { + for i, v := range x { + sum += y[i] * v + } + return sum +} + +// DotInc is +// for i := 0; i < int(n); i++ { +// sum += y[iy] * x[ix] +// ix += incX +// iy += incY +// } +// return sum +func DotInc(x, y []float32, n, incX, incY, ix, iy uintptr) (sum float32) { + for i := 0; i < int(n); i++ { + sum += y[iy] * x[ix] + ix += incX + iy += incY + } + return sum +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/scal.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/scal.go new file mode 100644 index 00000000..c4f61e87 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/scal.go @@ -0,0 +1,55 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package f32 + +// ScalUnitary is +// for i := range x { +// x[i] *= alpha +// } +func ScalUnitary(alpha float32, x []float32) { + for i := range x { + x[i] *= alpha + } +} + +// ScalUnitaryTo is +// for i, v := range x { +// dst[i] = alpha * v +// } +func ScalUnitaryTo(dst []float32, alpha float32, x []float32) { + for i, v := range x { + dst[i] = alpha * v + } +} + +// ScalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] *= alpha +// ix += incX +// } +func ScalInc(alpha float32, x []float32, n, incX uintptr) { + var ix uintptr + for i := 0; i < int(n); i++ { + x[ix] *= alpha + ix += incX + } +} + +// ScalIncTo is +// var idst, ix uintptr +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha * x[ix] +// ix += incX +// idst += incDst +// } +func ScalIncTo(dst []float32, incDst uintptr, alpha float32, x []float32, n, incX uintptr) { + var idst, ix uintptr + for i := 0; i < int(n); i++ { + dst[idst] = alpha * x[ix] + ix += incX + idst += incDst + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_amd64.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_amd64.go new file mode 100644 index 00000000..00ad520a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_amd64.go @@ -0,0 +1,36 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !noasm,!appengine + +package f32 + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha float32, x, y []float32) + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []float32, alpha float32, x, y []float32) + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []float32, incDst, idst uintptr, alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_noasm.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_noasm.go new file mode 100644 index 00000000..a6272ea5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_noasm.go @@ -0,0 +1,57 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !amd64 noasm appengine + +package f32 + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha float32, x, y []float32) { + for i, v := range x { + y[i] += alpha * v + } +} + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []float32, alpha float32, x, y []float32) { + for i, v := range x { + dst[i] = alpha*v + y[i] + } +} + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []float32, incDst, idst uintptr, alpha float32, x, y []float32, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_test.go new file mode 100644 index 00000000..df7a1421 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f32/stubs_test.go @@ -0,0 +1,217 @@ +// 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 f32 + +import ( + "math" + "testing" +) + +var ( + nan = float32(math.NaN()) + inf = float32(math.Inf(1)) +) + +var tests = []struct { + incX, incY, incDst uintptr + ix, iy, idst uintptr + a float32 + dst, x, y []float32 + ex []float32 +}{ + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 3, + dst: []float32{5}, + x: []float32{2}, + y: []float32{1}, + ex: []float32{7}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 5, + dst: []float32{0, 0, 0}, + x: []float32{0, 0, 0}, + y: []float32{1, 1, 1}, + ex: []float32{1, 1, 1}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 5, + dst: []float32{0, 0, 0}, + x: []float32{0, 0}, + y: []float32{1, 1, 1}, + ex: []float32{1, 1}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -1, + dst: []float32{-1, -1, -1}, + x: []float32{1, 1, 1}, + y: []float32{1, 2, 1}, + ex: []float32{0, 1, 0}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: -1, + dst: []float32{1, 1, 1}, + x: []float32{1, 2, 1}, + y: []float32{-1, -2, -1}, + ex: []float32{-2, -4, -2}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 2.5, + dst: []float32{1, 1, 1, 1, 1}, + x: []float32{1, 2, 3, 2, 1}, + y: []float32{0, 0, 0, 0, 0}, + ex: []float32{2.5, 5, 7.5, 5, 2.5}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, // Run big test twice, once aligned once unaligned. + a: 16.5, + dst: make([]float32, 20), + x: []float32{.5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5, .5}, + y: []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + ex: []float32{9.25, 10.25, 11.25, 12.25, 13.25, 14.25, 15.25, 16.25, 17.25, 18.25, 9.25, 10.25, 11.25, 12.25, 13.25, 14.25, 15.25, 16.25, 17.25, 18.25}}, + {incX: 2, incY: 2, incDst: 3, ix: 0, iy: 0, idst: 0, + a: 16.5, + dst: make([]float32, 10), + x: []float32{.5, .5, .5, .5, .5, .5, .5, .5, .5, .5}, + y: []float32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + ex: []float32{9.25, 10.25, 11.25, 12.25, 13.25, 14.25, 15.25, 16.25, 17.25, 18.25}}, +} + +func guardVector(vec []float32, guard_val float32, guard_len int) (guarded []float32) { + guarded = make([]float32, len(vec)+guard_len*2) + copy(guarded[guard_len:], vec) + for i := 0; i < guard_len; i++ { + guarded[i] = guard_val + guarded[len(guarded)-1-i] = guard_val + } + return guarded +} + +func isValidGuard(vec []float32, guard_val float32, guard_len int) bool { + for i := 0; i < guard_len; i++ { + if vec[i] != guard_val || vec[len(vec)-1-i] != guard_val { + return false + } + } + return true +} + +func same(x, y float32) bool { + a, b := float64(x), float64(y) + return a == b || (math.IsNaN(a) && math.IsNaN(b)) +} + +func TestAxpyUnitary(t *testing.T) { + var x_gd, y_gd float32 = 1, 1 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardVector(test.x, x_gd, xg_ln), guardVector(test.y, y_gd, yg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + AxpyUnitary(test.a, x, y) + for i := range test.ex { + if !same(y[i], test.ex[i]) { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i], test.ex[i]) + } + } + if !isValidGuard(test.x, x_gd, xg_ln) { + t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xg_ln], test.x[len(test.x)-xg_ln:]) + } + if !isValidGuard(test.y, y_gd, yg_ln) { + t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:yg_ln], test.y[len(test.y)-yg_ln:]) + } + } +} + +func TestAxpyUnitaryTo(t *testing.T) { + var x_gd, y_gd, dst_gd float32 = 1, 1, 0 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardVector(test.x, x_gd, xg_ln), guardVector(test.y, y_gd, yg_ln) + test.dst = guardVector(test.dst, dst_gd, xg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + dst := test.dst[xg_ln : len(test.dst)-xg_ln] + AxpyUnitaryTo(dst, test.a, x, y) + for i := range test.ex { + if !same(test.ex[i], dst[i]) { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i], test.ex[i]) + } + } + if !isValidGuard(test.x, x_gd, xg_ln) { + t.Errorf("Test %d Guard violated in x vector %v %v", cas, test.x[:xg_ln], test.x[len(test.x)-xg_ln:]) + } + if !isValidGuard(test.y, y_gd, yg_ln) { + t.Errorf("Test %d Guard violated in y vector %v %v", cas, test.y[:yg_ln], test.y[len(test.y)-yg_ln:]) + } + if !isValidGuard(test.dst, dst_gd, xg_ln) { + t.Errorf("Test %d Guard violated in dst vector %v %v", cas, test.dst[:xg_ln], test.dst[len(test.dst)-xg_ln:]) + } + } +} + +func guardIncVector(vec []float32, guard_val float32, incV uintptr, guard_len int) (guarded []float32) { + inc := int(incV) + s_ln := len(vec) * (inc) + guarded = make([]float32, s_ln+guard_len*2) + for i, j := 0, 0; i < len(guarded); i++ { + switch { + case i < guard_len, i > guard_len+s_ln: + guarded[i] = guard_val + case (i-guard_len)%(inc) == 0 && j < len(vec): + guarded[i] = vec[j] + j++ + default: + guarded[i] = guard_val + } + } + return guarded +} + +func checkValidIncGuard(t *testing.T, vec []float32, guard_val float32, incV uintptr, guard_len int) { + inc := int(incV) + s_ln := len(vec) - 2*guard_len + for i := range vec { + switch { + case same(vec[i], guard_val): + // Correct value + case i < guard_len: + t.Errorf("Front guard violated at %d %v", i, vec[:guard_len]) + case i > guard_len+s_ln: + t.Errorf("Back guard violated at %d %v", i-guard_len-s_ln, vec[guard_len+s_ln:]) + case (i-guard_len)%inc == 0 && (i-guard_len)/inc < len(vec): + // Ignore input values + default: + t.Errorf("Internal guard violated at %d %v", i-guard_len, vec[guard_len:guard_len+s_ln]) + } + } +} + +func TestAxpyInc(t *testing.T) { + var x_gd, y_gd float32 = 1, 1 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardIncVector(test.x, x_gd, uintptr(test.incX), xg_ln), guardIncVector(test.y, y_gd, uintptr(test.incY), yg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + AxpyInc(test.a, x, y, uintptr(len(test.ex)), test.incX, test.incY, test.ix, test.iy) + for i := range test.ex { + if !same(y[i*int(test.incY)], test.ex[i]) { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, y[i*int(test.incY)], test.ex[i]) + } + } + checkValidIncGuard(t, test.x, x_gd, uintptr(test.incX), xg_ln) + checkValidIncGuard(t, test.y, y_gd, uintptr(test.incY), yg_ln) + } +} + +func TestAxpyIncTo(t *testing.T) { + var x_gd, y_gd, dst_gd float32 = 1, 1, 0 + for cas, test := range tests { + xg_ln, yg_ln := 4+cas%2, 4+cas%3 + test.x, test.y = guardIncVector(test.x, x_gd, uintptr(test.incX), xg_ln), guardIncVector(test.y, y_gd, uintptr(test.incY), yg_ln) + test.dst = guardIncVector(test.dst, dst_gd, uintptr(test.incDst), xg_ln) + x, y := test.x[xg_ln:len(test.x)-xg_ln], test.y[yg_ln:len(test.y)-yg_ln] + dst := test.dst[xg_ln : len(test.dst)-xg_ln] + AxpyIncTo(dst, test.incDst, test.idst, test.a, x, y, uintptr(len(test.ex)), test.incX, test.incY, test.ix, test.iy) + for i := range test.ex { + if !same(dst[i*int(test.incDst)], test.ex[i]) { + t.Errorf("Test %d Unexpected result at %d Got: %v Expected: %v", cas, i, dst[i*int(test.incDst)], test.ex[i]) + } + } + checkValidIncGuard(t, test.x, x_gd, uintptr(test.incX), xg_ln) + checkValidIncGuard(t, test.y, y_gd, uintptr(test.incY), yg_ln) + checkValidIncGuard(t, test.dst, dst_gd, uintptr(test.incDst), xg_ln) + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/abssum_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/abssum_amd64.s new file mode 100644 index 00000000..7e7e5d07 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/abssum_amd64.s @@ -0,0 +1,82 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func L1Norm(x []float64) float64 +TEXT ·L1Norm(SB), NOSPLIT, $0 + MOVQ x_base+0(FP), SI // SI = &x + MOVQ x_len+8(FP), CX // CX = len(x) + XORQ AX, AX // i = 0 + PXOR X0, X0 // p_sum_i = 0 + PXOR X1, X1 + PXOR X2, X2 + PXOR X3, X3 + PXOR X4, X4 + PXOR X5, X5 + PXOR X6, X6 + PXOR X7, X7 + CMPQ CX, $0 // if CX == 0 { return 0 } + JE absum_end + MOVQ CX, BX + ANDQ $7, BX // BX = len(x) % 8 + SHRQ $3, CX // CX = floor( len(x) / 8 ) + JZ absum_tail_start // if CX == 0 { goto absum_tail_start } + +absum_loop: // do { + // p_sum += max( p_sum + x[i], p_sum - x[i] ) + MOVUPS (SI)(AX*8), X8 // X_i = x[i:i+1] + MOVUPS 16(SI)(AX*8), X9 + MOVUPS 32(SI)(AX*8), X10 + MOVUPS 48(SI)(AX*8), X11 + ADDPD X8, X0 // p_sum_i += X_i ( positive values ) + ADDPD X9, X2 + ADDPD X10, X4 + ADDPD X11, X6 + SUBPD X8, X1 // p_sum_(i+1) -= X_i ( negative values ) + SUBPD X9, X3 + SUBPD X10, X5 + SUBPD X11, X7 + MAXPD X1, X0 // p_sum_i = max( p_sum_i, p_sum_(i+1) ) + MAXPD X3, X2 + MAXPD X5, X4 + MAXPD X7, X6 + MOVAPS X0, X1 // p_sum_(i+1) = p_sum_i + MOVAPS X2, X3 + MOVAPS X4, X5 + MOVAPS X6, X7 + ADDQ $8, AX // i += 8 + LOOP absum_loop // } while --CX > 0 + + // p_sum_0 = \sum_{i=1}^{3}( p_sum_(i*2) ) + ADDPD X3, X0 + ADDPD X5, X7 + ADDPD X7, X0 + + // p_sum_0[0] = p_sum_0[0] + p_sum_0[1] + MOVAPS X0, X1 + SHUFPD $0x3, X0, X0 // lower( p_sum_0 ) = upper( p_sum_0 ) + ADDSD X1, X0 + CMPQ BX, $0 + JE absum_end // if BX == 0 { goto absum_end } + +absum_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + XORPS X8, X8 // X_8 = 0 + +absum_tail: // do { + // p_sum += max( p_sum + x[i], p_sum - x[i] ) + MOVSD (SI)(AX*8), X8 // X_8 = x[i] + MOVSD X0, X1 // p_sum_1 = p_sum_0 + ADDSD X8, X0 // p_sum_0 += X_8 + SUBSD X8, X1 // p_sum_1 -= X_8 + MAXSD X1, X0 // p_sum_0 = max( p_sum_0, p_sum_1 ) + INCQ AX // i++ + LOOP absum_tail // } while --CX > 0 + +absum_end: // return p_sum_0 + MOVSD X0, sum+24(FP) + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/abssuminc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/abssuminc_amd64.s new file mode 100644 index 00000000..f4db05bd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/abssuminc_amd64.s @@ -0,0 +1,90 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func L1NormInc(x []float64, n, incX int) (sum float64) +TEXT ·L1NormInc(SB), NOSPLIT, $0 + MOVQ x_base+0(FP), SI // SI = &x + MOVQ n+24(FP), CX // CX = n + MOVQ incX+32(FP), AX // AX = increment * sizeof( float64 ) + SHLQ $3, AX + MOVQ AX, DX // DX = AX * 3 + IMULQ $3, DX + PXOR X0, X0 // p_sum_i = 0 + PXOR X1, X1 + PXOR X2, X2 + PXOR X3, X3 + PXOR X4, X4 + PXOR X5, X5 + PXOR X6, X6 + PXOR X7, X7 + CMPQ CX, $0 // if CX == 0 { return 0 } + JE absum_end + MOVQ CX, BX + ANDQ $7, BX // BX = n % 8 + SHRQ $3, CX // CX = floor( n / 8 ) + JZ absum_tail_start // if CX == 0 { goto absum_tail_start } + +absum_loop: // do { + // p_sum = max( p_sum + x[i], p_sum - x[i] ) + MOVSD (SI), X8 // X_i[0] = x[i] + MOVSD (SI)(AX*1), X9 + MOVSD (SI)(AX*2), X10 + MOVSD (SI)(DX*1), X11 + LEAQ (SI)(AX*4), SI // SI = SI + 4 + MOVHPD (SI), X8 // X_i[1] = x[i+4] + MOVHPD (SI)(AX*1), X9 + MOVHPD (SI)(AX*2), X10 + MOVHPD (SI)(DX*1), X11 + ADDPD X8, X0 // p_sum_i += X_i ( positive values ) + ADDPD X9, X2 + ADDPD X10, X4 + ADDPD X11, X6 + SUBPD X8, X1 // p_sum_(i+1) -= X_i ( negative values ) + SUBPD X9, X3 + SUBPD X10, X5 + SUBPD X11, X7 + MAXPD X1, X0 // p_sum_i = max( p_sum_i, p_sum_(i+1) ) + MAXPD X3, X2 + MAXPD X5, X4 + MAXPD X7, X6 + MOVAPS X0, X1 // p_sum_(i+1) = p_sum_i + MOVAPS X2, X3 + MOVAPS X4, X5 + MOVAPS X6, X7 + LEAQ (SI)(AX*4), SI // SI = SI + 4 + LOOP absum_loop // } while --CX > 0 + + // p_sum_0 = \sum_{i=1}^{3}( p_sum_(i*2) ) + ADDPD X3, X0 + ADDPD X5, X7 + ADDPD X7, X0 + + // p_sum_0[0] = p_sum_0[0] + p_sum_0[1] + MOVAPS X0, X1 + SHUFPD $0x3, X0, X0 // lower( p_sum_0 ) = upper( p_sum_0 ) + ADDSD X1, X0 + CMPQ BX, $0 + JE absum_end // if BX == 0 { goto absum_end } + +absum_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + XORPS X8, X8 // X_8 = 0 + +absum_tail: // do { + // p_sum += max( p_sum + x[i], p_sum - x[i] ) + MOVSD (SI), X8 // X_8 = x[i] + MOVSD X0, X1 // p_sum_1 = p_sum_0 + ADDSD X8, X0 // p_sum_0 += X_8 + SUBSD X8, X1 // p_sum_1 -= X_8 + MAXSD X1, X0 // p_sum_0 = max( p_sum_0, p_sum_1 ) + ADDQ AX, SI // i++ + LOOP absum_tail // } while --CX > 0 + +absum_end: // return p_sum_0 + MOVSD X0, sum+40(FP) + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/add_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/add_amd64.s new file mode 100644 index 00000000..27329699 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/add_amd64.s @@ -0,0 +1,66 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func Add(dst, s []float64) +TEXT ·Add(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ dst_len+8(FP), CX // CX = len(dst) + MOVQ s_base+24(FP), SI // SI = &s + CMPQ s_len+32(FP), CX // CX = max( CX, len(s) ) + CMOVQLE s_len+32(FP), CX + CMPQ CX, $0 // if CX == 0 { return } + JE add_end + XORQ AX, AX + MOVQ DI, BX + ANDQ $0x0F, BX // BX = &dst & 15 + JZ add_no_trim // if BX == 0 { goto add_no_trim } + + // Align on 16-bit boundary + MOVSD (SI)(AX*8), X0 // X0 = s[i] + ADDSD (DI)(AX*8), X0 // X0 += dst[i] + MOVSD X0, (DI)(AX*8) // dst[i] = X0 + INCQ AX // i++ + DECQ CX // --CX + JE add_end // if CX == 0 { return } + +add_no_trim: + MOVQ CX, BX + ANDQ $7, BX // BX = len(dst) % 8 + SHRQ $3, CX // CX = floor( len(dst) / 8 ) + JZ add_tail_start // if CX == 0 { goto add_tail_start } + +add_loop: // Loop unrolled 8x do { + MOVUPS (SI)(AX*8), X0 // X_i = s[i:i+1] + MOVUPS 16(SI)(AX*8), X1 + MOVUPS 32(SI)(AX*8), X2 + MOVUPS 48(SI)(AX*8), X3 + ADDPD (DI)(AX*8), X0 // X_i += dst[i:i+1] + ADDPD 16(DI)(AX*8), X1 + ADDPD 32(DI)(AX*8), X2 + ADDPD 48(DI)(AX*8), X3 + MOVUPS X0, (DI)(AX*8) // dst[i:i+1] = X_i + MOVUPS X1, 16(DI)(AX*8) + MOVUPS X2, 32(DI)(AX*8) + MOVUPS X3, 48(DI)(AX*8) + ADDQ $8, AX // i += 8 + LOOP add_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE add_end + +add_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + +add_tail: // do { + MOVSD (SI)(AX*8), X0 // X0 = s[i] + ADDSD (DI)(AX*8), X0 // X0 += dst[i] + MOVSD X0, (DI)(AX*8) // dst[i] = X0 + INCQ AX // ++i + LOOP add_tail // } while --CX > 0 + +add_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/addconst_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/addconst_amd64.s new file mode 100644 index 00000000..88fed071 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/addconst_amd64.s @@ -0,0 +1,53 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func Addconst(alpha float64, x []float64) +TEXT ·AddConst(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), SI // SI = &x + MOVQ x_len+16(FP), CX // CX = len(x) + CMPQ CX, $0 // if len(x) == 0 { return } + JE ac_end + MOVSD alpha+0(FP), X4 // X4 = { a, a } + SHUFPD $0, X4, X4 + MOVUPS X4, X5 // X5 = X4 + XORQ AX, AX // i = 0 + MOVQ CX, BX + ANDQ $7, BX // BX = len(x) % 8 + SHRQ $3, CX // CX = floor( len(x) / 8 ) + JZ ac_tail_start // if CX == 0 { goto ac_tail_start } + +ac_loop: // Loop unrolled 8x do { + MOVUPS (SI)(AX*8), X0 // X_i = s[i:i+1] + MOVUPS 16(SI)(AX*8), X1 + MOVUPS 32(SI)(AX*8), X2 + MOVUPS 48(SI)(AX*8), X3 + ADDPD X4, X0 // X_i += a + ADDPD X5, X1 + ADDPD X4, X2 + ADDPD X5, X3 + MOVUPS X0, (SI)(AX*8) // s[i:i+1] = X_i + MOVUPS X1, 16(SI)(AX*8) + MOVUPS X2, 32(SI)(AX*8) + MOVUPS X3, 48(SI)(AX*8) + ADDQ $8, AX // i += 8 + LOOP ac_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE ac_end + +ac_tail_start: // Reset loop counters + MOVQ BX, CX // Loop counter: CX = BX + +ac_tail: // do { + MOVSD (SI)(AX*8), X0 // X0 = s[i] + ADDSD X4, X0 // X0 += a + MOVSD X0, (SI)(AX*8) // s[i] = X0 + INCQ AX // ++i + LOOP ac_tail // } while --CX > 0 + +ac_end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/asm_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/asm_test.go new file mode 100644 index 00000000..cca86e84 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/asm_test.go @@ -0,0 +1,204 @@ +// 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 f64 + +import ( + "math" + "math/rand" + "testing" +) + +var ( + nan = math.NaN() + inf = math.Inf(1) +) + +// newGuardedVector allocates a new slice and returns it as three subslices. +// v is a strided vector that contains elements of data at indices i*inc and +// NaN elsewhere. frontGuard and backGuard are filled with NaN values, and +// their backing arrays are directly adjacent to v in memory. The three slices +// can be used to detect invalid memory reads and writes. +func newGuardedVector(data []float64, inc int) (v, frontGuard, backGuard []float64) { + if inc < 0 { + inc = -inc + } + guard := 2 * inc + size := (len(data)-1)*inc + 1 + whole := make([]float64, size+2*guard) + v = whole[guard : len(whole)-guard] + for i := range whole { + whole[i] = math.NaN() + } + for i, d := range data { + v[i*inc] = d + } + return v, whole[:guard], whole[len(whole)-guard:] +} + +// allNaN returns true if x contains only NaN values, and false otherwise. +func allNaN(x []float64) bool { + for _, v := range x { + if !math.IsNaN(v) { + return false + } + } + return true +} + +// equalStrided returns true if the strided vector x contains elements of the +// dense vector ref at indices i*inc, false otherwise. +func equalStrided(ref, x []float64, inc int) bool { + if inc < 0 { + inc = -inc + } + for i, v := range ref { + if !same(x[i*inc], v) { + return false + } + } + return true +} + +// nonStridedWrite returns false if all elements of x at non-stride indices are +// equal to NaN, true otherwise. +func nonStridedWrite(x []float64, inc int) bool { + if inc < 0 { + inc = -inc + } + for i, v := range x { + if i%inc != 0 && !math.IsNaN(v) { + return true + } + } + return false +} + +// guardVector copies the source vector (vec) into a new slice with guards. +// Guards guarded[:gdLn] and guarded[len-gdLn:] will be filled with sigil value gdVal. +func guardVector(vec []float64, gdVal float64, gdLn int) (guarded []float64) { + guarded = make([]float64, len(vec)+gdLn*2) + copy(guarded[gdLn:], vec) + for i := 0; i < gdLn; i++ { + guarded[i] = gdVal + guarded[len(guarded)-1-i] = gdVal + } + return guarded +} + +// isValidGuard will test for violated guards, generated by guardVector. +func isValidGuard(vec []float64, gdVal float64, gdLn int) bool { + for i := 0; i < gdLn; i++ { + if !same(vec[i], gdVal) || !same(vec[len(vec)-1-i], gdVal) { + return false + } + } + return true +} + +// guardIncVector copies the source vector (vec) into a new incremented slice with guards. +// End guards will be length gdLen. +// Internal and end guards will be filled with sigil value gdVal. +func guardIncVector(vec []float64, gdVal float64, inc, gdLen int) (guarded []float64) { + if inc < 0 { + inc = -inc + } + inrLen := len(vec) * inc + guarded = make([]float64, inrLen+gdLen*2) + for i := range guarded { + guarded[i] = gdVal + } + for i, v := range vec { + guarded[gdLen+i*inc] = v + } + return guarded +} + +// checkValidIncGuard will test for violated guards, generated by guardIncVector +func checkValidIncGuard(t *testing.T, vec []float64, gdVal float64, inc, gdLen int) { + srcLn := len(vec) - 2*gdLen + for i := range vec { + switch { + case same(vec[i], gdVal): + // Correct value + case (i-gdLen)%inc == 0 && (i-gdLen)/inc < len(vec): + // Ignore input values + case i < gdLen: + t.Errorf("Front guard violated at %d %v", i, vec[:gdLen]) + case i > gdLen+srcLn: + t.Errorf("Back guard violated at %d %v", i-gdLen-srcLn, vec[gdLen+srcLn:]) + default: + t.Errorf("Internal guard violated at %d %v", i-gdLen, vec[gdLen:gdLen+srcLn]) + } + } +} + +// same tests for nan-aware equality. +func same(a, b float64) bool { + return a == b || (math.IsNaN(a) && math.IsNaN(b)) +} + +var ( // Offset sets for testing alignment handling in Unitary assembly functions. + align1 = []int{0, 1} + align2 = newIncSet(0, 1) + align3 = newIncToSet(0, 1) +) + +type incSet struct { + x, y int +} + +// genInc will generate all (x,y) combinations of the input increment set. +func newIncSet(inc ...int) []incSet { + n := len(inc) + is := make([]incSet, n*n) + for x := range inc { + for y := range inc { + is[x*n+y] = incSet{inc[x], inc[y]} + } + } + return is +} + +type incToSet struct { + dst, x, y int +} + +// genIncTo will generate all (dst,x,y) combinations of the input increment set. +func newIncToSet(inc ...int) []incToSet { + n := len(inc) + is := make([]incToSet, n*n*n) + for i, dst := range inc { + for x := range inc { + for y := range inc { + is[i*n*n+x*n+y] = incToSet{dst, inc[x], inc[y]} + } + } + } + return is +} + +var benchSink []float64 + +func randomSlice(n, inc int) []float64 { + if inc < 0 { + inc = -inc + } + x := make([]float64, (n-1)*inc+1) + for i := range x { + x[i] = rand.Float64() + } + return x +} + +func randSlice(n, inc int, r *rand.Rand) []float64 { + if inc < 0 { + inc = -inc + } + x := make([]float64, (n-1)*inc+1) + for i := range x { + x[i] = r.Float64() + } + return x +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/axpy.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpy.go new file mode 100644 index 00000000..455a5d7e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpy.go @@ -0,0 +1,57 @@ +// 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. + +//+build !amd64 noasm appengine + +package f64 + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha float64, x, y []float64) { + for i, v := range x { + y[i] += alpha * v + } +} + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []float64, alpha float64, x, y []float64) { + for i, v := range x { + dst[i] = alpha*v + y[i] + } +} + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/axpy_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpy_test.go new file mode 100644 index 00000000..2f096aaf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpy_test.go @@ -0,0 +1,274 @@ +// 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 f64 + +import ( + "fmt" + "testing" +) + +const ( + msgVal = "%v: unexpected value at %v Got: %v Expected: %v" + msgGuard = "%v: Guard violated in %s vector %v %v" +) + +var axpyTests = []struct { + alpha float64 + x []float64 + y []float64 + want []float64 + wantRev []float64 // Result when x is traversed in reverse direction. +}{ + { + alpha: 0, + x: []float64{}, + y: []float64{}, + want: []float64{}, + wantRev: []float64{}, + }, + { + alpha: 0, + x: []float64{2}, + y: []float64{-3}, + want: []float64{-3}, + wantRev: []float64{-3}, + }, + { + alpha: 1, + x: []float64{2}, + y: []float64{-3}, + want: []float64{-1}, + wantRev: []float64{-1}, + }, + { + alpha: 3, + x: []float64{2}, + y: []float64{-3}, + want: []float64{3}, + wantRev: []float64{3}, + }, + { + alpha: -3, + x: []float64{2}, + y: []float64{-3}, + want: []float64{-9}, + wantRev: []float64{-9}, + }, + { + alpha: 1, + x: []float64{1, 5}, + y: []float64{2, -3}, + want: []float64{3, 2}, + wantRev: []float64{7, -2}, + }, + { + alpha: 1, + x: []float64{2, 3, 4}, + y: []float64{-3, -2, -1}, + want: []float64{-1, 1, 3}, + wantRev: []float64{1, 1, 1}, + }, + { + alpha: 0, + x: []float64{0, 0, 1, 1, 2, -3, -4}, + y: []float64{0, 1, 0, 3, -4, 5, -6}, + want: []float64{0, 1, 0, 3, -4, 5, -6}, + wantRev: []float64{0, 1, 0, 3, -4, 5, -6}, + }, + { + alpha: 1, + x: []float64{0, 0, 1, 1, 2, -3, -4}, + y: []float64{0, 1, 0, 3, -4, 5, -6}, + want: []float64{0, 1, 1, 4, -2, 2, -10}, + wantRev: []float64{-4, -2, 2, 4, -3, 5, -6}, + }, + { + alpha: 3, + x: []float64{0, 0, 1, 1, 2, -3, -4}, + y: []float64{0, 1, 0, 3, -4, 5, -6}, + want: []float64{0, 1, 3, 6, 2, -4, -18}, + wantRev: []float64{-12, -8, 6, 6, -1, 5, -6}, + }, + { + alpha: -3, + x: []float64{0, 0, 1, 1, 2, -3, -4, 0, 0, 1, 1, 2, -3, -4}, + y: []float64{0, 1, 0, 3, -4, 5, -6, 0, 1, 0, 3, -4, 5, -6}, + want: []float64{0, 1, -3, 0, -10, 14, 6, 0, 1, -3, 0, -10, 14, 6}, + wantRev: []float64{12, 10, -6, 0, -7, 5, -6, 12, 10, -6, 0, -7, 5, -6}, + }, + { + alpha: -5, + x: []float64{0, 0, 1, 1, 2, -3, -4, 5, 1, 2, -3, -4, 5}, + y: []float64{0, 1, 0, 3, -4, 5, -6, 7, 3, -4, 5, -6, 7}, + want: []float64{0, 1, -5, -2, -14, 20, 14, -18, -2, -14, 20, 14, -18}, + wantRev: []float64{-25, 21, 15, -7, -9, -20, 14, 22, -7, -9, 0, -6, 7}, + }, +} + +func TestAxpyUnitary(t *testing.T) { + const xGdVal, yGdVal = -1, 0.5 + for i, test := range axpyTests { + for _, align := range align2 { + prefix := fmt.Sprintf("Test %v (x:%v y:%v)", i, align.x, align.y) + xgLn, ygLn := 4+align.x, 4+align.y + xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) + x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn] + AxpyUnitary(test.alpha, x, y) + for i := range test.want { + if !same(y[i], test.want[i]) { + t.Errorf(msgVal, prefix, i, y[i], test.want[i]) + } + } + if !isValidGuard(xg, xGdVal, xgLn) { + t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) + } + if !isValidGuard(yg, yGdVal, ygLn) { + t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:]) + } + if !equalStrided(test.x, x, 1) { + t.Errorf("%v: modified read-only x argument", prefix) + } + } + } +} + +func TestAxpyUnitaryTo(t *testing.T) { + const dstGdVal, xGdVal, yGdVal = 1, -1, 0.5 + for i, test := range axpyTests { + for _, align := range align3 { + prefix := fmt.Sprintf("Test %v (x:%v y:%v dst:%v)", i, align.x, align.y, align.dst) + + dgLn, xgLn, ygLn := 4+align.dst, 4+align.x, 4+align.y + dstOrig := make([]float64, len(test.x)) + xg, yg := guardVector(test.x, xGdVal, xgLn), guardVector(test.y, yGdVal, ygLn) + dstg := guardVector(dstOrig, dstGdVal, dgLn) + x, y := xg[xgLn:len(xg)-xgLn], yg[ygLn:len(yg)-ygLn] + dst := dstg[dgLn : len(dstg)-dgLn] + + AxpyUnitaryTo(dst, test.alpha, x, y) + for i := range test.want { + if !same(dst[i], test.want[i]) { + t.Errorf(msgVal, prefix, i, dst[i], test.want[i]) + } + } + if !isValidGuard(xg, xGdVal, xgLn) { + t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) + } + if !isValidGuard(yg, yGdVal, ygLn) { + t.Errorf(msgGuard, prefix, "y", yg[:ygLn], yg[len(yg)-ygLn:]) + } + if !isValidGuard(dstg, dstGdVal, dgLn) { + t.Errorf(msgGuard, prefix, "dst", dstg[:dgLn], dstg[len(dstg)-dgLn:]) + } + if !equalStrided(test.x, x, 1) { + t.Errorf("%v: modified read-only x argument", prefix) + } + if !equalStrided(test.y, y, 1) { + t.Errorf("%v: modified read-only y argument", prefix) + } + } + } +} + +func TestAxpyInc(t *testing.T) { + const xGdVal, yGdVal = -1, 0.5 + gdLn := 4 + for i, test := range axpyTests { + n := len(test.x) + for _, inc := range newIncSet(-7, -4, -3, -2, -1, 1, 2, 3, 4, 7) { + var ix, iy int + if inc.x < 0 { + ix = (-n + 1) * inc.x + } + if inc.y < 0 { + iy = (-n + 1) * inc.y + } + prefix := fmt.Sprintf("test %v, inc.x = %v, inc.y = %v", i, inc.x, inc.y) + xg := guardIncVector(test.x, xGdVal, inc.x, gdLn) + yg := guardIncVector(test.y, yGdVal, inc.y, gdLn) + x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn] + + AxpyInc(test.alpha, x, y, uintptr(n), + uintptr(inc.x), uintptr(inc.y), uintptr(ix), uintptr(iy)) + + want := test.want + if inc.x*inc.y < 0 { + want = test.wantRev + } + if inc.y < 0 { + inc.y = -inc.y + } + for i := range want { + if !same(y[i*inc.y], want[i]) { + t.Errorf(msgVal, prefix, i, y[iy+i*inc.y], want[i]) + } + } + if !equalStrided(test.x, x, inc.x) { + t.Errorf("%v: modified read-only x argument", prefix) + } + checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn) + checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn) + } + } +} + +func TestAxpyIncTo(t *testing.T) { + const dstGdVal, xGdVal, yGdVal = 1, -1, 0.5 + var want []float64 + gdLn := 4 + for i, test := range axpyTests { + n := len(test.x) + for _, inc := range newIncToSet(-7, -4, -3, -2, -1, 1, 2, 3, 4, 7) { + var ix, iy, idst uintptr + if inc.x < 0 { + ix = uintptr((-n + 1) * inc.x) + } + if inc.y < 0 { + iy = uintptr((-n + 1) * inc.y) + } + if inc.dst < 0 { + idst = uintptr((-n + 1) * inc.dst) + } + + prefix := fmt.Sprintf("Test %v: (x: %v, y: %v, dst:%v)", i, inc.x, inc.y, inc.dst) + dstOrig := make([]float64, len(test.want)) + xg := guardIncVector(test.x, xGdVal, inc.x, gdLn) + yg := guardIncVector(test.y, yGdVal, inc.y, gdLn) + dstg := guardIncVector(dstOrig, dstGdVal, inc.dst, gdLn) + x, y := xg[gdLn:len(xg)-gdLn], yg[gdLn:len(yg)-gdLn] + dst := dstg[gdLn : len(dstg)-gdLn] + + AxpyIncTo(dst, uintptr(inc.dst), idst, + test.alpha, x, y, uintptr(n), + uintptr(inc.x), uintptr(inc.y), ix, iy) + want = test.want + if inc.x*inc.y < 0 { + want = test.wantRev + } + var iW, incW int = 0, 1 + if inc.y*inc.dst < 0 { + iW, incW = len(want)-1, -1 + } + if inc.dst < 0 { + inc.dst = -inc.dst + } + for i := range want { + if !same(dst[i*inc.dst], want[iW+i*incW]) { + t.Errorf(msgVal, prefix, i, dst[i*inc.dst], want[iW+i*incW]) + } + } + + checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn) + checkValidIncGuard(t, yg, yGdVal, inc.y, gdLn) + checkValidIncGuard(t, dstg, dstGdVal, inc.dst, gdLn) + if !equalStrided(test.x, x, inc.x) { + t.Errorf("%v: modified read-only x argument", prefix) + } + if !equalStrided(test.y, y, inc.y) { + t.Errorf("%v: modified read-only y argument", prefix) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyinc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyinc_amd64.s new file mode 100644 index 00000000..214f9704 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyinc_amd64.s @@ -0,0 +1,142 @@ +// 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. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define X_PTR SI +#define Y_PTR DI +#define DST_PTR DI +#define IDX AX +#define LEN CX +#define TAIL BX +#define INC_X R8 +#define INCx3_X R11 +#define INC_Y R9 +#define INCx3_Y R12 +#define INC_DST R9 +#define INCx3_DST R12 +#define ALPHA X0 +#define ALPHA_2 X1 + +// func AxpyInc(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyInc(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), X_PTR // X_PTR = &x + MOVQ y_base+32(FP), Y_PTR // Y_PTR = &y + MOVQ n+56(FP), LEN // LEN = n + CMPQ LEN, $0 // if LEN == 0 { return } + JE end + + MOVQ ix+80(FP), INC_X + MOVQ iy+88(FP), INC_Y + LEAQ (X_PTR)(INC_X*8), X_PTR // X_PTR = &(x[ix]) + LEAQ (Y_PTR)(INC_Y*8), Y_PTR // Y_PTR = &(y[iy]) + MOVQ Y_PTR, DST_PTR // DST_PTR = Y_PTR // Write pointer + + MOVQ incX+64(FP), INC_X // INC_X = incX * sizeof(float64) + SHLQ $3, INC_X + MOVQ incY+72(FP), INC_Y // INC_Y = incY * sizeof(float64) + SHLQ $3, INC_Y + + MOVSD alpha+0(FP), ALPHA // ALPHA = alpha + MOVQ LEN, TAIL + ANDQ $3, TAIL // TAIL = n % 4 + SHRQ $2, LEN // LEN = floor( n / 4 ) + JZ tail_start // if LEN == 0 { goto tail_start } + + MOVAPS ALPHA, ALPHA_2 // ALPHA_2 = ALPHA for pipelining + LEAQ (INC_X)(INC_X*2), INCx3_X // INCx3_X = INC_X * 3 + LEAQ (INC_Y)(INC_Y*2), INCx3_Y // INCx3_Y = INC_Y * 3 + +loop: // do { // y[i] += alpha * x[i] unrolled 4x. + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MOVSD (X_PTR)(INC_X*2), X4 + MOVSD (X_PTR)(INCx3_X*1), X5 + + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA_2, X3 + MULSD ALPHA, X4 + MULSD ALPHA_2, X5 + + ADDSD (Y_PTR), X2 // X_i += y[i] + ADDSD (Y_PTR)(INC_Y*1), X3 + ADDSD (Y_PTR)(INC_Y*2), X4 + ADDSD (Y_PTR)(INCx3_Y*1), X5 + + MOVSD X2, (DST_PTR) // y[i] = X_i + MOVSD X3, (DST_PTR)(INC_DST*1) + MOVSD X4, (DST_PTR)(INC_DST*2) + MOVSD X5, (DST_PTR)(INCx3_DST*1) + + LEAQ (X_PTR)(INC_X*4), X_PTR // X_PTR = &(X_PTR[incX*4]) + LEAQ (Y_PTR)(INC_Y*4), Y_PTR // Y_PTR = &(Y_PTR[incY*4]) + DECQ LEN + JNZ loop // } while --LEN > 0 + CMPQ TAIL, $0 // if TAIL == 0 { return } + JE end + +tail_start: // Reset Loop registers + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( LEN / 2 ) + JZ tail_one + +tail_two: + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA, X3 + ADDSD (Y_PTR), X2 // X_i += y[i] + ADDSD (Y_PTR)(INC_Y*1), X3 + MOVSD X2, (DST_PTR) // y[i] = X_i + MOVSD X3, (DST_PTR)(INC_DST*1) + + LEAQ (X_PTR)(INC_X*2), X_PTR // X_PTR = &(X_PTR[incX*2]) + LEAQ (Y_PTR)(INC_Y*2), Y_PTR // Y_PTR = &(Y_PTR[incY*2]) + + ANDQ $1, TAIL + JZ end // if TAIL == 0 { goto end } + +tail_one: + // y[i] += alpha * x[i] for the last n % 4 iterations. + MOVSD (X_PTR), X2 // X2 = x[i] + MULSD ALPHA, X2 // X2 *= a + ADDSD (Y_PTR), X2 // X2 += y[i] + MOVSD X2, (DST_PTR) // y[i] = X2 + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyincto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyincto_amd64.s new file mode 100644 index 00000000..a873b1c9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyincto_amd64.s @@ -0,0 +1,148 @@ +// 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. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define X_PTR SI +#define Y_PTR DI +#define DST_PTR DX +#define IDX AX +#define LEN CX +#define TAIL BX +#define INC_X R8 +#define INCx3_X R11 +#define INC_Y R9 +#define INCx3_Y R12 +#define INC_DST R10 +#define INCx3_DST R13 +#define ALPHA X0 +#define ALPHA_2 X1 + +// func AxpyIncTo(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) +TEXT ·AxpyIncTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DST_PTR // DST_PTR := &dst + MOVQ x_base+48(FP), X_PTR // X_PTR := &x + MOVQ y_base+72(FP), Y_PTR // Y_PTR := &y + MOVQ n+96(FP), LEN // LEN := n + CMPQ LEN, $0 // if LEN == 0 { return } + JE end + + MOVQ ix+120(FP), INC_X + LEAQ (X_PTR)(INC_X*8), X_PTR // X_PTR = &(x[ix]) + MOVQ iy+128(FP), INC_Y + LEAQ (Y_PTR)(INC_Y*8), Y_PTR // Y_PTR = &(dst[idst]) + MOVQ idst+32(FP), INC_DST + LEAQ (DST_PTR)(INC_DST*8), DST_PTR // DST_PTR = &(y[iy]) + + MOVQ incX+104(FP), INC_X // INC_X = incX * sizeof(float64) + SHLQ $3, INC_X + MOVQ incY+112(FP), INC_Y // INC_Y = incY * sizeof(float64) + SHLQ $3, INC_Y + MOVQ incDst+24(FP), INC_DST // INC_DST = incDst * sizeof(float64) + SHLQ $3, INC_DST + MOVSD alpha+40(FP), ALPHA + + MOVQ LEN, TAIL + ANDQ $3, TAIL // TAIL = n % 4 + SHRQ $2, LEN // LEN = floor( n / 4 ) + JZ tail_start // if LEN == 0 { goto tail_start } + + MOVSD ALPHA, ALPHA_2 // ALPHA_2 = ALPHA for pipelining + LEAQ (INC_X)(INC_X*2), INCx3_X // INCx3_X = INC_X * 3 + LEAQ (INC_Y)(INC_Y*2), INCx3_Y // INCx3_Y = INC_Y * 3 + LEAQ (INC_DST)(INC_DST*2), INCx3_DST // INCx3_DST = INC_DST * 3 + +loop: // do { // y[i] += alpha * x[i] unrolled 2x. + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MOVSD (X_PTR)(INC_X*2), X4 + MOVSD (X_PTR)(INCx3_X*1), X5 + + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA_2, X3 + MULSD ALPHA, X4 + MULSD ALPHA_2, X5 + + ADDSD (Y_PTR), X2 // X_i += y[i] + ADDSD (Y_PTR)(INC_Y*1), X3 + ADDSD (Y_PTR)(INC_Y*2), X4 + ADDSD (Y_PTR)(INCx3_Y*1), X5 + + MOVSD X2, (DST_PTR) // y[i] = X_i + MOVSD X3, (DST_PTR)(INC_DST*1) + MOVSD X4, (DST_PTR)(INC_DST*2) + MOVSD X5, (DST_PTR)(INCx3_DST*1) + + LEAQ (X_PTR)(INC_X*4), X_PTR // X_PTR = &(X_PTR[incX*4]) + LEAQ (Y_PTR)(INC_Y*4), Y_PTR // Y_PTR = &(Y_PTR[incY*4]) + LEAQ (DST_PTR)(INC_DST*4), DST_PTR // DST_PTR = &(DST_PTR[incDst*4] + DECQ LEN + JNZ loop // } while --LEN > 0 + CMPQ TAIL, $0 // if TAIL == 0 { return } + JE end + +tail_start: // Reset Loop registers + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( LEN / 2 ) + JZ tail_one + +tail_two: + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA, X3 + ADDSD (Y_PTR), X2 // X_i += y[i] + ADDSD (Y_PTR)(INC_Y*1), X3 + MOVSD X2, (DST_PTR) // y[i] = X_i + MOVSD X3, (DST_PTR)(INC_DST*1) + + LEAQ (X_PTR)(INC_X*2), X_PTR // X_PTR = &(X_PTR[incX*2]) + LEAQ (Y_PTR)(INC_Y*2), Y_PTR // Y_PTR = &(Y_PTR[incY*2]) + LEAQ (DST_PTR)(INC_DST*2), DST_PTR // DST_PTR = &(DST_PTR[incY*2] + + ANDQ $1, TAIL + JZ end // if TAIL == 0 { goto end } + +tail_one: + MOVSD (X_PTR), X2 // X2 = x[i] + MULSD ALPHA, X2 // X2 *= a + ADDSD (Y_PTR), X2 // X2 += y[i] + MOVSD X2, (DST_PTR) // y[i] = X2 + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyunitary_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyunitary_amd64.s new file mode 100644 index 00000000..668f091e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyunitary_amd64.s @@ -0,0 +1,134 @@ +// 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. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define X_PTR SI +#define Y_PTR DI +#define DST_PTR DI +#define IDX AX +#define LEN CX +#define TAIL BX +#define ALPHA X0 +#define ALPHA_2 X1 + +// func AxpyUnitary(alpha float64, x, y []float64) +TEXT ·AxpyUnitary(SB), NOSPLIT, $0 + MOVQ x_base+8(FP), X_PTR // X_PTR := &x + MOVQ y_base+32(FP), Y_PTR // Y_PTR := &y + MOVQ x_len+16(FP), LEN // LEN = min( len(x), len(y) ) + CMPQ y_len+40(FP), LEN + CMOVQLE y_len+40(FP), LEN + CMPQ LEN, $0 // if LEN == 0 { return } + JE end + XORQ IDX, IDX + MOVSD alpha+0(FP), ALPHA // ALPHA := { alpha, alpha } + SHUFPD $0, ALPHA, ALPHA + MOVUPS ALPHA, ALPHA_2 // ALPHA_2 := ALPHA for pipelining + MOVQ Y_PTR, TAIL // Check memory alignment + ANDQ $15, TAIL // TAIL = &y % 16 + JZ no_trim // if TAIL == 0 { goto no_trim } + + // Align on 16-byte boundary + MOVSD (X_PTR), X2 // X2 := x[0] + MULSD ALPHA, X2 // X2 *= a + ADDSD (Y_PTR), X2 // X2 += y[0] + MOVSD X2, (DST_PTR) // y[0] = X2 + INCQ IDX // i++ + DECQ LEN // LEN-- + JZ end // if LEN == 0 { return } + +no_trim: + MOVQ LEN, TAIL + ANDQ $7, TAIL // TAIL := n % 8 + SHRQ $3, LEN // LEN = floor( n / 8 ) + JZ tail_start // if LEN == 0 { goto tail2_start } + +loop: // do { + // y[i] += alpha * x[i] unrolled 8x. + MOVUPS (X_PTR)(IDX*8), X2 // X_i = x[i] + MOVUPS 16(X_PTR)(IDX*8), X3 + MOVUPS 32(X_PTR)(IDX*8), X4 + MOVUPS 48(X_PTR)(IDX*8), X5 + + MULPD ALPHA, X2 // X_i *= a + MULPD ALPHA_2, X3 + MULPD ALPHA, X4 + MULPD ALPHA_2, X5 + + ADDPD (Y_PTR)(IDX*8), X2 // X_i += y[i] + ADDPD 16(Y_PTR)(IDX*8), X3 + ADDPD 32(Y_PTR)(IDX*8), X4 + ADDPD 48(Y_PTR)(IDX*8), X5 + + MOVUPS X2, (DST_PTR)(IDX*8) // y[i] = X_i + MOVUPS X3, 16(DST_PTR)(IDX*8) + MOVUPS X4, 32(DST_PTR)(IDX*8) + MOVUPS X5, 48(DST_PTR)(IDX*8) + + ADDQ $8, IDX // i += 8 + DECQ LEN + JNZ loop // } while --LEN > 0 + CMPQ TAIL, $0 // if TAIL == 0 { return } + JE end + +tail_start: // Reset loop registers + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( TAIL / 2 ) + JZ tail_one // if TAIL == 0 { goto tail } + +tail_two: // do { + MOVUPS (X_PTR)(IDX*8), X2 // X2 = x[i] + MULPD ALPHA, X2 // X2 *= a + ADDPD (Y_PTR)(IDX*8), X2 // X2 += y[i] + MOVUPS X2, (DST_PTR)(IDX*8) // y[i] = X2 + ADDQ $2, IDX // i += 2 + DECQ LEN + JNZ tail_two // } while --LEN > 0 + + ANDQ $1, TAIL + JZ end // if TAIL == 0 { goto end } + +tail_one: + MOVSD (X_PTR)(IDX*8), X2 // X2 = x[i] + MULSD ALPHA, X2 // X2 *= a + ADDSD (Y_PTR)(IDX*8), X2 // X2 += y[i] + MOVSD X2, (DST_PTR)(IDX*8) // y[i] = X2 + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyunitaryto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyunitaryto_amd64.s new file mode 100644 index 00000000..03132e9d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/axpyunitaryto_amd64.s @@ -0,0 +1,140 @@ +// 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. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define X_PTR SI +#define Y_PTR DX +#define DST_PTR DI +#define IDX AX +#define LEN CX +#define TAIL BX +#define ALPHA X0 +#define ALPHA_2 X1 + +// func AxpyUnitaryTo(dst []float64, alpha float64, x, y []float64) +TEXT ·AxpyUnitaryTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DST_PTR // DST_PTR := &dst + MOVQ x_base+32(FP), X_PTR // X_PTR := &x + MOVQ y_base+56(FP), Y_PTR // Y_PTR := &y + MOVQ x_len+40(FP), LEN // LEN = min( len(x), len(y), len(dst) ) + CMPQ y_len+64(FP), LEN + CMOVQLE y_len+64(FP), LEN + CMPQ dst_len+8(FP), LEN + CMOVQLE dst_len+8(FP), LEN + + CMPQ LEN, $0 + JE end // if LEN == 0 { return } + + XORQ IDX, IDX // IDX = 0 + MOVSD alpha+24(FP), ALPHA + SHUFPD $0, ALPHA, ALPHA // ALPHA := { alpha, alpha } + MOVQ Y_PTR, TAIL // Check memory alignment + ANDQ $15, TAIL // TAIL = &y % 16 + JZ no_trim // if TAIL == 0 { goto no_trim } + + // Align on 16-byte boundary + MOVSD (X_PTR), X2 // X2 := x[0] + MULSD ALPHA, X2 // X2 *= a + ADDSD (Y_PTR), X2 // X2 += y[0] + MOVSD X2, (DST_PTR) // y[0] = X2 + INCQ IDX // i++ + DECQ LEN // LEN-- + JZ end // if LEN == 0 { return } + +no_trim: + MOVQ LEN, TAIL + ANDQ $7, TAIL // TAIL := n % 8 + SHRQ $3, LEN // LEN = floor( n / 8 ) + JZ tail_start // if LEN == 0 { goto tail_start } + + MOVUPS ALPHA, ALPHA_2 // ALPHA_2 := ALPHA for pipelining + +loop: // do { + // y[i] += alpha * x[i] unrolled 8x. + MOVUPS (X_PTR)(IDX*8), X2 // X_i = x[i] + MOVUPS 16(X_PTR)(IDX*8), X3 + MOVUPS 32(X_PTR)(IDX*8), X4 + MOVUPS 48(X_PTR)(IDX*8), X5 + + MULPD ALPHA, X2 // X_i *= alpha + MULPD ALPHA_2, X3 + MULPD ALPHA, X4 + MULPD ALPHA_2, X5 + + ADDPD (Y_PTR)(IDX*8), X2 // X_i += y[i] + ADDPD 16(Y_PTR)(IDX*8), X3 + ADDPD 32(Y_PTR)(IDX*8), X4 + ADDPD 48(Y_PTR)(IDX*8), X5 + + MOVUPS X2, (DST_PTR)(IDX*8) // y[i] = X_i + MOVUPS X3, 16(DST_PTR)(IDX*8) + MOVUPS X4, 32(DST_PTR)(IDX*8) + MOVUPS X5, 48(DST_PTR)(IDX*8) + + ADDQ $8, IDX // i += 8 + DECQ LEN + JNZ loop // } while --LEN > 0 + CMPQ TAIL, $0 // if TAIL == 0 { return } + JE end + +tail_start: // Reset loop registers + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( TAIL / 2 ) + JZ tail_one // if LEN == 0 { goto tail } + +tail_two: // do { + MOVUPS (X_PTR)(IDX*8), X2 // X2 = x[i] + MULPD ALPHA, X2 // X2 *= alpha + ADDPD (Y_PTR)(IDX*8), X2 // X2 += y[i] + MOVUPS X2, (DST_PTR)(IDX*8) // y[i] = X2 + ADDQ $2, IDX // i += 2 + DECQ LEN + JNZ tail_two // } while --LEN > 0 + + ANDQ $1, TAIL + JZ end // if TAIL == 0 { goto end } + +tail_one: + MOVSD (X_PTR)(IDX*8), X2 // X2 = x[i] + MULSD ALPHA, X2 // X2 *= a + ADDSD (Y_PTR)(IDX*8), X2 // X2 += y[i] + MOVSD X2, (DST_PTR)(IDX*8) // y[i] = X2 + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/benchAxpy_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/benchAxpy_test.go new file mode 100644 index 00000000..7bd3dca7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/benchAxpy_test.go @@ -0,0 +1,167 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package f64 + +import ( + "fmt" + "testing" +) + +const ( + testLen = 1e5 +) + +var ( + a = 2.0 + x = make([]float64, testLen) + y = make([]float64, testLen) + z = make([]float64, testLen) +) + +func init() { + for n := range x { + x[n] = float64(n) + y[n] = float64(n) + } +} + +func BenchmarkAxpyUnitary(t *testing.B) { + naiveaxpyu := func(a float64, x, y []float64) { + for i, v := range x { + y[i] += a * v + } + } + tests := []struct { + name string + f func(a float64, x, y []float64) + }{ + {"AxpyUnitary", AxpyUnitary}, + {"NaiveAxpyUnitary", naiveaxpyu}, + } + for _, test := range tests { + for _, ln := range []uintptr{1, 3, 10, 30, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 1e5} { + t.Run(fmt.Sprintf("%s-%d", test.name, ln), func(b *testing.B) { + b.SetBytes(int64(64 * ln)) + x, y := x[:ln], y[:ln] + b.ResetTimer() + for i := 0; i < b.N; i++ { + test.f(a, x, y) + } + }) + } + } +} + +func BenchmarkAxpyUnitaryTo(t *testing.B) { + naiveaxpyut := func(d []float64, a float64, x, y []float64) { + for i, v := range x { + d[i] = y[i] + a*v + } + } + tests := []struct { + name string + f func(z []float64, a float64, x, y []float64) + }{ + {"AxpyUnitaryTo", AxpyUnitaryTo}, + {"NaiveAxpyUnitaryTo", naiveaxpyut}, + } + for _, test := range tests { + for _, ln := range []uintptr{1, 3, 10, 30, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 1e5} { + t.Run(fmt.Sprintf("%s-%d", test.name, ln), func(b *testing.B) { + b.SetBytes(int64(64 * ln)) + x, y, z := x[:ln], y[:ln], z[:ln] + b.ResetTimer() + for i := 0; i < b.N; i++ { + test.f(z, a, x, y) + } + }) + } + } +} + +var incsAxpy = []struct { + len uintptr + inc []int +}{ + {1, []int{1}}, + {2, []int{1, 2, 4, 10}}, + {3, []int{1, 2, 4, 10}}, + {4, []int{1, 2, 4, 10}}, + {5, []int{1, 2, 4, 10}}, + {10, []int{1, 2, 4, 10}}, + {500, []int{1, 2, 4, 10}}, + {1e3, []int{1, 2, 4, 10}}, + {1e4, []int{1, 2, 4, 10, -1, -2, -4, -10}}, +} + +func BenchmarkAxpyInc(t *testing.B) { + naiveaxpyinc := func(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } + } + tests := []struct { + name string + f func(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) + }{ + {"AxpyInc", AxpyInc}, + {"NaiveAxpyInc", naiveaxpyinc}, + } + for _, test := range tests { + for _, tt := range incsAxpy { + for _, inc := range tt.inc { + t.Run(fmt.Sprintf("%s-%d-inc(%d)", test.name, tt.len, inc), func(b *testing.B) { + b.SetBytes(int64(64 * tt.len)) + var idx, tstInc uintptr = 0, uintptr(inc) + if inc < 0 { + idx = uintptr((-int(tt.len) + 1) * inc) + } + for i := 0; i < b.N; i++ { + test.f(a, x, y, uintptr(tt.len), tstInc, tstInc, idx, idx) + } + }) + } + } + } +} + +func BenchmarkAxpyIncTo(t *testing.B) { + naiveaxpyincto := func(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } + } + tests := []struct { + name string + f func(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) + }{ + {"AxpyIncTo", AxpyIncTo}, + {"NaiveAxpyIncTo", naiveaxpyincto}, + } + for _, test := range tests { + for _, tt := range incsAxpy { + for _, inc := range tt.inc { + t.Run(fmt.Sprintf("%s-%d-inc(%d)", test.name, tt.len, inc), func(b *testing.B) { + b.SetBytes(int64(64 * tt.len)) + var idx, tstInc uintptr = 0, uintptr(inc) + if inc < 0 { + idx = uintptr((-int(tt.len) + 1) * inc) + } + for i := 0; i < b.N; i++ { + test.f(z, tstInc, idx, a, x, y, uintptr(tt.len), + tstInc, tstInc, idx, idx) + } + }) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/benchScal_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/benchScal_test.go new file mode 100644 index 00000000..b4fb19ad --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/benchScal_test.go @@ -0,0 +1,87 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package f64 + +import ( + "fmt" + "testing" +) + +var uniScal = []int64{1, 3, 10, 30, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4} + +func BenchmarkScalUnitary(t *testing.B) { + tstName := "ScalUnitary" + for _, ln := range uniScal { + t.Run(fmt.Sprintf("%s-%d", tstName, ln), func(b *testing.B) { + b.SetBytes(64 * ln) + x := x[:ln] + b.ResetTimer() + for i := 0; i < b.N; i++ { + ScalUnitary(a, x) + } + }) + } +} + +func BenchmarkScalUnitaryTo(t *testing.B) { + tstName := "ScalUnitaryTo" + for _, ln := range uniScal { + t.Run(fmt.Sprintf("%s-%d", tstName, ln), func(b *testing.B) { + b.SetBytes(int64(64 * ln)) + x, y := x[:ln], y[:ln] + b.ResetTimer() + for i := 0; i < b.N; i++ { + ScalUnitaryTo(y, a, x) + } + }) + } +} + +var incScal = []struct { + len uintptr + inc []int +}{ + {1, []int{1}}, + {3, []int{1, 2, 4, 10}}, + {10, []int{1, 2, 4, 10}}, + {30, []int{1, 2, 4, 10}}, + {1e2, []int{1, 2, 4, 10}}, + {3e2, []int{1, 2, 4, 10}}, + {1e3, []int{1, 2, 4, 10}}, + {3e3, []int{1, 2, 4, 10}}, + {1e4, []int{1, 2, 4, 10}}, +} + +func BenchmarkScalInc(t *testing.B) { + tstName := "ScalInc" + for _, tt := range incScal { + for _, inc := range tt.inc { + t.Run(fmt.Sprintf("%s-%d-inc(%d)", tstName, tt.len, inc), func(b *testing.B) { + b.SetBytes(int64(64 * tt.len)) + tstInc := uintptr(inc) + for i := 0; i < b.N; i++ { + ScalInc(a, x, uintptr(tt.len), tstInc) + } + }) + } + } +} + +func BenchmarkScalIncTo(t *testing.B) { + tstName := "ScalIncTo" + for _, tt := range incScal { + for _, inc := range tt.inc { + t.Run(fmt.Sprintf("%s-%d-inc(%d)", tstName, tt.len, inc), func(b *testing.B) { + b.SetBytes(int64(64 * tt.len)) + tstInc := uintptr(inc) + for i := 0; i < b.N; i++ { + ScalIncTo(z, tstInc, a, x, uintptr(tt.len), tstInc) + } + }) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/bench_other_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/bench_other_test.go new file mode 100644 index 00000000..851252ba --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/bench_other_test.go @@ -0,0 +1,443 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package f64 + +import ( + "math" + "testing" +) + +func benchL1Norm(f func(x []float64) float64, sz int, t *testing.B) { + dst := y[:sz] + for i := 0; i < t.N; i++ { + f(dst) + } +} + +var naiveL1Norm = func(x []float64) (sum float64) { + for _, v := range x { + sum += math.Abs(v) + } + return sum +} + +func BenchmarkL1Norm1(t *testing.B) { benchL1Norm(L1Norm, 1, t) } +func BenchmarkL1Norm2(t *testing.B) { benchL1Norm(L1Norm, 2, t) } +func BenchmarkL1Norm3(t *testing.B) { benchL1Norm(L1Norm, 3, t) } +func BenchmarkL1Norm4(t *testing.B) { benchL1Norm(L1Norm, 4, t) } +func BenchmarkL1Norm5(t *testing.B) { benchL1Norm(L1Norm, 5, t) } +func BenchmarkL1Norm10(t *testing.B) { benchL1Norm(L1Norm, 10, t) } +func BenchmarkL1Norm100(t *testing.B) { benchL1Norm(L1Norm, 100, t) } +func BenchmarkL1Norm1000(t *testing.B) { benchL1Norm(L1Norm, 1000, t) } +func BenchmarkL1Norm10000(t *testing.B) { benchL1Norm(L1Norm, 10000, t) } +func BenchmarkL1Norm100000(t *testing.B) { benchL1Norm(L1Norm, 100000, t) } +func BenchmarkL1Norm500000(t *testing.B) { benchL1Norm(L1Norm, 500000, t) } + +func BenchmarkLL1Norm1(t *testing.B) { benchL1Norm(naiveL1Norm, 1, t) } +func BenchmarkLL1Norm2(t *testing.B) { benchL1Norm(naiveL1Norm, 2, t) } +func BenchmarkLL1Norm3(t *testing.B) { benchL1Norm(naiveL1Norm, 3, t) } +func BenchmarkLL1Norm4(t *testing.B) { benchL1Norm(naiveL1Norm, 4, t) } +func BenchmarkLL1Norm5(t *testing.B) { benchL1Norm(naiveL1Norm, 5, t) } +func BenchmarkLL1Norm10(t *testing.B) { benchL1Norm(naiveL1Norm, 10, t) } +func BenchmarkLL1Norm100(t *testing.B) { benchL1Norm(naiveL1Norm, 100, t) } +func BenchmarkLL1Norm1000(t *testing.B) { benchL1Norm(naiveL1Norm, 1000, t) } +func BenchmarkLL1Norm10000(t *testing.B) { benchL1Norm(naiveL1Norm, 10000, t) } +func BenchmarkLL1Norm100000(t *testing.B) { benchL1Norm(naiveL1Norm, 100000, t) } +func BenchmarkLL1Norm500000(t *testing.B) { benchL1Norm(naiveL1Norm, 500000, t) } + +func benchL1NormInc(t *testing.B, ln, inc int, f func(x []float64, n, incX int) float64) { + for i := 0; i < t.N; i++ { + f(x, ln, inc) + } +} + +var naiveL1NormInc = func(x []float64, n, incX int) (sum float64) { + for i := 0; i < n*incX; i += incX { + sum += math.Abs(x[i]) + } + return sum +} + +func BenchmarkF64L1NormIncN1Inc1(b *testing.B) { benchL1NormInc(b, 1, 1, L1NormInc) } + +func BenchmarkF64L1NormIncN2Inc1(b *testing.B) { benchL1NormInc(b, 2, 1, L1NormInc) } +func BenchmarkF64L1NormIncN2Inc2(b *testing.B) { benchL1NormInc(b, 2, 2, L1NormInc) } +func BenchmarkF64L1NormIncN2Inc4(b *testing.B) { benchL1NormInc(b, 2, 4, L1NormInc) } +func BenchmarkF64L1NormIncN2Inc10(b *testing.B) { benchL1NormInc(b, 2, 10, L1NormInc) } + +func BenchmarkF64L1NormIncN3Inc1(b *testing.B) { benchL1NormInc(b, 3, 1, L1NormInc) } +func BenchmarkF64L1NormIncN3Inc2(b *testing.B) { benchL1NormInc(b, 3, 2, L1NormInc) } +func BenchmarkF64L1NormIncN3Inc4(b *testing.B) { benchL1NormInc(b, 3, 4, L1NormInc) } +func BenchmarkF64L1NormIncN3Inc10(b *testing.B) { benchL1NormInc(b, 3, 10, L1NormInc) } + +func BenchmarkF64L1NormIncN4Inc1(b *testing.B) { benchL1NormInc(b, 4, 1, L1NormInc) } +func BenchmarkF64L1NormIncN4Inc2(b *testing.B) { benchL1NormInc(b, 4, 2, L1NormInc) } +func BenchmarkF64L1NormIncN4Inc4(b *testing.B) { benchL1NormInc(b, 4, 4, L1NormInc) } +func BenchmarkF64L1NormIncN4Inc10(b *testing.B) { benchL1NormInc(b, 4, 10, L1NormInc) } + +func BenchmarkF64L1NormIncN10Inc1(b *testing.B) { benchL1NormInc(b, 10, 1, L1NormInc) } +func BenchmarkF64L1NormIncN10Inc2(b *testing.B) { benchL1NormInc(b, 10, 2, L1NormInc) } +func BenchmarkF64L1NormIncN10Inc4(b *testing.B) { benchL1NormInc(b, 10, 4, L1NormInc) } +func BenchmarkF64L1NormIncN10Inc10(b *testing.B) { benchL1NormInc(b, 10, 10, L1NormInc) } + +func BenchmarkF64L1NormIncN1000Inc1(b *testing.B) { benchL1NormInc(b, 1000, 1, L1NormInc) } +func BenchmarkF64L1NormIncN1000Inc2(b *testing.B) { benchL1NormInc(b, 1000, 2, L1NormInc) } +func BenchmarkF64L1NormIncN1000Inc4(b *testing.B) { benchL1NormInc(b, 1000, 4, L1NormInc) } +func BenchmarkF64L1NormIncN1000Inc10(b *testing.B) { benchL1NormInc(b, 1000, 10, L1NormInc) } + +func BenchmarkF64L1NormIncN100000Inc1(b *testing.B) { benchL1NormInc(b, 100000, 1, L1NormInc) } +func BenchmarkF64L1NormIncN100000Inc2(b *testing.B) { benchL1NormInc(b, 100000, 2, L1NormInc) } +func BenchmarkF64L1NormIncN100000Inc4(b *testing.B) { benchL1NormInc(b, 100000, 4, L1NormInc) } +func BenchmarkF64L1NormIncN100000Inc10(b *testing.B) { benchL1NormInc(b, 100000, 10, L1NormInc) } + +func BenchmarkLF64L1NormIncN1Inc1(b *testing.B) { benchL1NormInc(b, 1, 1, naiveL1NormInc) } + +func BenchmarkLF64L1NormIncN2Inc1(b *testing.B) { benchL1NormInc(b, 2, 1, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN2Inc2(b *testing.B) { benchL1NormInc(b, 2, 2, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN2Inc4(b *testing.B) { benchL1NormInc(b, 2, 4, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN2Inc10(b *testing.B) { benchL1NormInc(b, 2, 10, naiveL1NormInc) } + +func BenchmarkLF64L1NormIncN3Inc1(b *testing.B) { benchL1NormInc(b, 3, 1, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN3Inc2(b *testing.B) { benchL1NormInc(b, 3, 2, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN3Inc4(b *testing.B) { benchL1NormInc(b, 3, 4, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN3Inc10(b *testing.B) { benchL1NormInc(b, 3, 10, naiveL1NormInc) } + +func BenchmarkLF64L1NormIncN4Inc1(b *testing.B) { benchL1NormInc(b, 4, 1, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN4Inc2(b *testing.B) { benchL1NormInc(b, 4, 2, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN4Inc4(b *testing.B) { benchL1NormInc(b, 4, 4, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN4Inc10(b *testing.B) { benchL1NormInc(b, 4, 10, naiveL1NormInc) } + +func BenchmarkLF64L1NormIncN10Inc1(b *testing.B) { benchL1NormInc(b, 10, 1, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN10Inc2(b *testing.B) { benchL1NormInc(b, 10, 2, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN10Inc4(b *testing.B) { benchL1NormInc(b, 10, 4, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN10Inc10(b *testing.B) { benchL1NormInc(b, 10, 10, naiveL1NormInc) } + +func BenchmarkLF64L1NormIncN1000Inc1(b *testing.B) { benchL1NormInc(b, 1000, 1, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN1000Inc2(b *testing.B) { benchL1NormInc(b, 1000, 2, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN1000Inc4(b *testing.B) { benchL1NormInc(b, 1000, 4, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN1000Inc10(b *testing.B) { benchL1NormInc(b, 1000, 10, naiveL1NormInc) } + +func BenchmarkLF64L1NormIncN100000Inc1(b *testing.B) { benchL1NormInc(b, 100000, 1, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN100000Inc2(b *testing.B) { benchL1NormInc(b, 100000, 2, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN100000Inc4(b *testing.B) { benchL1NormInc(b, 100000, 4, naiveL1NormInc) } +func BenchmarkLF64L1NormIncN100000Inc10(b *testing.B) { benchL1NormInc(b, 100000, 10, naiveL1NormInc) } + +func benchAdd(f func(dst, s []float64), sz int, t *testing.B) { + dst, s := y[:sz], x[:sz] + for i := 0; i < t.N; i++ { + f(dst, s) + } +} + +var naiveAdd = func(dst, s []float64) { + for i, v := range s { + dst[i] += v + } +} + +func BenchmarkAdd1(t *testing.B) { benchAdd(Add, 1, t) } +func BenchmarkAdd2(t *testing.B) { benchAdd(Add, 2, t) } +func BenchmarkAdd3(t *testing.B) { benchAdd(Add, 3, t) } +func BenchmarkAdd4(t *testing.B) { benchAdd(Add, 4, t) } +func BenchmarkAdd5(t *testing.B) { benchAdd(Add, 5, t) } +func BenchmarkAdd10(t *testing.B) { benchAdd(Add, 10, t) } +func BenchmarkAdd100(t *testing.B) { benchAdd(Add, 100, t) } +func BenchmarkAdd1000(t *testing.B) { benchAdd(Add, 1000, t) } +func BenchmarkAdd10000(t *testing.B) { benchAdd(Add, 10000, t) } +func BenchmarkAdd100000(t *testing.B) { benchAdd(Add, 100000, t) } +func BenchmarkAdd500000(t *testing.B) { benchAdd(Add, 500000, t) } + +func BenchmarkLAdd1(t *testing.B) { benchAdd(naiveAdd, 1, t) } +func BenchmarkLAdd2(t *testing.B) { benchAdd(naiveAdd, 2, t) } +func BenchmarkLAdd3(t *testing.B) { benchAdd(naiveAdd, 3, t) } +func BenchmarkLAdd4(t *testing.B) { benchAdd(naiveAdd, 4, t) } +func BenchmarkLAdd5(t *testing.B) { benchAdd(naiveAdd, 5, t) } +func BenchmarkLAdd10(t *testing.B) { benchAdd(naiveAdd, 10, t) } +func BenchmarkLAdd100(t *testing.B) { benchAdd(naiveAdd, 100, t) } +func BenchmarkLAdd1000(t *testing.B) { benchAdd(naiveAdd, 1000, t) } +func BenchmarkLAdd10000(t *testing.B) { benchAdd(naiveAdd, 10000, t) } +func BenchmarkLAdd100000(t *testing.B) { benchAdd(naiveAdd, 100000, t) } +func BenchmarkLAdd500000(t *testing.B) { benchAdd(naiveAdd, 500000, t) } + +func benchAddConst(f func(a float64, x []float64), sz int, t *testing.B) { + a, x := 1., x[:sz] + for i := 0; i < t.N; i++ { + f(a, x) + } +} + +var naiveAddConst = func(a float64, x []float64) { + for i := range x { + x[i] += a + } +} + +func BenchmarkAddConst1(t *testing.B) { benchAddConst(AddConst, 1, t) } +func BenchmarkAddConst2(t *testing.B) { benchAddConst(AddConst, 2, t) } +func BenchmarkAddConst3(t *testing.B) { benchAddConst(AddConst, 3, t) } +func BenchmarkAddConst4(t *testing.B) { benchAddConst(AddConst, 4, t) } +func BenchmarkAddConst5(t *testing.B) { benchAddConst(AddConst, 5, t) } +func BenchmarkAddConst10(t *testing.B) { benchAddConst(AddConst, 10, t) } +func BenchmarkAddConst100(t *testing.B) { benchAddConst(AddConst, 100, t) } +func BenchmarkAddConst1000(t *testing.B) { benchAddConst(AddConst, 1000, t) } +func BenchmarkAddConst10000(t *testing.B) { benchAddConst(AddConst, 10000, t) } +func BenchmarkAddConst100000(t *testing.B) { benchAddConst(AddConst, 100000, t) } +func BenchmarkAddConst500000(t *testing.B) { benchAddConst(AddConst, 500000, t) } + +func BenchmarkLAddConst1(t *testing.B) { benchAddConst(naiveAddConst, 1, t) } +func BenchmarkLAddConst2(t *testing.B) { benchAddConst(naiveAddConst, 2, t) } +func BenchmarkLAddConst3(t *testing.B) { benchAddConst(naiveAddConst, 3, t) } +func BenchmarkLAddConst4(t *testing.B) { benchAddConst(naiveAddConst, 4, t) } +func BenchmarkLAddConst5(t *testing.B) { benchAddConst(naiveAddConst, 5, t) } +func BenchmarkLAddConst10(t *testing.B) { benchAddConst(naiveAddConst, 10, t) } +func BenchmarkLAddConst100(t *testing.B) { benchAddConst(naiveAddConst, 100, t) } +func BenchmarkLAddConst1000(t *testing.B) { benchAddConst(naiveAddConst, 1000, t) } +func BenchmarkLAddConst10000(t *testing.B) { benchAddConst(naiveAddConst, 10000, t) } +func BenchmarkLAddConst100000(t *testing.B) { benchAddConst(naiveAddConst, 100000, t) } +func BenchmarkLAddConst500000(t *testing.B) { benchAddConst(naiveAddConst, 500000, t) } + +func benchCumSum(f func(a, b []float64) []float64, sz int, t *testing.B) { + a, b := x[:sz], y[:sz] + for i := 0; i < t.N; i++ { + f(a, b) + } +} + +var naiveCumSum = func(dst, s []float64) []float64 { + if len(s) == 0 { + return dst + } + dst[0] = s[0] + for i, v := range s[1:] { + dst[i+1] = dst[i] + v + } + return dst +} + +func BenchmarkCumSum1(t *testing.B) { benchCumSum(CumSum, 1, t) } +func BenchmarkCumSum2(t *testing.B) { benchCumSum(CumSum, 2, t) } +func BenchmarkCumSum3(t *testing.B) { benchCumSum(CumSum, 3, t) } +func BenchmarkCumSum4(t *testing.B) { benchCumSum(CumSum, 4, t) } +func BenchmarkCumSum5(t *testing.B) { benchCumSum(CumSum, 5, t) } +func BenchmarkCumSum10(t *testing.B) { benchCumSum(CumSum, 10, t) } +func BenchmarkCumSum100(t *testing.B) { benchCumSum(CumSum, 100, t) } +func BenchmarkCumSum1000(t *testing.B) { benchCumSum(CumSum, 1000, t) } +func BenchmarkCumSum10000(t *testing.B) { benchCumSum(CumSum, 10000, t) } +func BenchmarkCumSum100000(t *testing.B) { benchCumSum(CumSum, 100000, t) } +func BenchmarkCumSum500000(t *testing.B) { benchCumSum(CumSum, 500000, t) } + +func BenchmarkLCumSum1(t *testing.B) { benchCumSum(naiveCumSum, 1, t) } +func BenchmarkLCumSum2(t *testing.B) { benchCumSum(naiveCumSum, 2, t) } +func BenchmarkLCumSum3(t *testing.B) { benchCumSum(naiveCumSum, 3, t) } +func BenchmarkLCumSum4(t *testing.B) { benchCumSum(naiveCumSum, 4, t) } +func BenchmarkLCumSum5(t *testing.B) { benchCumSum(naiveCumSum, 5, t) } +func BenchmarkLCumSum10(t *testing.B) { benchCumSum(naiveCumSum, 10, t) } +func BenchmarkLCumSum100(t *testing.B) { benchCumSum(naiveCumSum, 100, t) } +func BenchmarkLCumSum1000(t *testing.B) { benchCumSum(naiveCumSum, 1000, t) } +func BenchmarkLCumSum10000(t *testing.B) { benchCumSum(naiveCumSum, 10000, t) } +func BenchmarkLCumSum100000(t *testing.B) { benchCumSum(naiveCumSum, 100000, t) } +func BenchmarkLCumSum500000(t *testing.B) { benchCumSum(naiveCumSum, 500000, t) } + +func benchCumProd(f func(a, b []float64) []float64, sz int, t *testing.B) { + a, b := x[:sz], y[:sz] + for i := 0; i < t.N; i++ { + f(a, b) + } +} + +var naiveCumProd = func(dst, s []float64) []float64 { + if len(s) == 0 { + return dst + } + dst[0] = s[0] + for i, v := range s[1:] { + dst[i+1] = dst[i] + v + } + return dst +} + +func BenchmarkCumProd1(t *testing.B) { benchCumProd(CumProd, 1, t) } +func BenchmarkCumProd2(t *testing.B) { benchCumProd(CumProd, 2, t) } +func BenchmarkCumProd3(t *testing.B) { benchCumProd(CumProd, 3, t) } +func BenchmarkCumProd4(t *testing.B) { benchCumProd(CumProd, 4, t) } +func BenchmarkCumProd5(t *testing.B) { benchCumProd(CumProd, 5, t) } +func BenchmarkCumProd10(t *testing.B) { benchCumProd(CumProd, 10, t) } +func BenchmarkCumProd100(t *testing.B) { benchCumProd(CumProd, 100, t) } +func BenchmarkCumProd1000(t *testing.B) { benchCumProd(CumProd, 1000, t) } +func BenchmarkCumProd10000(t *testing.B) { benchCumProd(CumProd, 10000, t) } +func BenchmarkCumProd100000(t *testing.B) { benchCumProd(CumProd, 100000, t) } +func BenchmarkCumProd500000(t *testing.B) { benchCumProd(CumProd, 500000, t) } + +func BenchmarkLCumProd1(t *testing.B) { benchCumProd(naiveCumProd, 1, t) } +func BenchmarkLCumProd2(t *testing.B) { benchCumProd(naiveCumProd, 2, t) } +func BenchmarkLCumProd3(t *testing.B) { benchCumProd(naiveCumProd, 3, t) } +func BenchmarkLCumProd4(t *testing.B) { benchCumProd(naiveCumProd, 4, t) } +func BenchmarkLCumProd5(t *testing.B) { benchCumProd(naiveCumProd, 5, t) } +func BenchmarkLCumProd10(t *testing.B) { benchCumProd(naiveCumProd, 10, t) } +func BenchmarkLCumProd100(t *testing.B) { benchCumProd(naiveCumProd, 100, t) } +func BenchmarkLCumProd1000(t *testing.B) { benchCumProd(naiveCumProd, 1000, t) } +func BenchmarkLCumProd10000(t *testing.B) { benchCumProd(naiveCumProd, 10000, t) } +func BenchmarkLCumProd100000(t *testing.B) { benchCumProd(naiveCumProd, 100000, t) } +func BenchmarkLCumProd500000(t *testing.B) { benchCumProd(naiveCumProd, 500000, t) } + +func benchDiv(f func(a, b []float64), sz int, t *testing.B) { + a, b := x[:sz], y[:sz] + for i := 0; i < t.N; i++ { + f(a, b) + } +} + +var naiveDiv = func(a, b []float64) { + for i, v := range b { + a[i] /= v + } +} + +func BenchmarkDiv1(t *testing.B) { benchDiv(Div, 1, t) } +func BenchmarkDiv2(t *testing.B) { benchDiv(Div, 2, t) } +func BenchmarkDiv3(t *testing.B) { benchDiv(Div, 3, t) } +func BenchmarkDiv4(t *testing.B) { benchDiv(Div, 4, t) } +func BenchmarkDiv5(t *testing.B) { benchDiv(Div, 5, t) } +func BenchmarkDiv10(t *testing.B) { benchDiv(Div, 10, t) } +func BenchmarkDiv100(t *testing.B) { benchDiv(Div, 100, t) } +func BenchmarkDiv1000(t *testing.B) { benchDiv(Div, 1000, t) } +func BenchmarkDiv10000(t *testing.B) { benchDiv(Div, 10000, t) } +func BenchmarkDiv100000(t *testing.B) { benchDiv(Div, 100000, t) } +func BenchmarkDiv500000(t *testing.B) { benchDiv(Div, 500000, t) } + +func BenchmarkLDiv1(t *testing.B) { benchDiv(naiveDiv, 1, t) } +func BenchmarkLDiv2(t *testing.B) { benchDiv(naiveDiv, 2, t) } +func BenchmarkLDiv3(t *testing.B) { benchDiv(naiveDiv, 3, t) } +func BenchmarkLDiv4(t *testing.B) { benchDiv(naiveDiv, 4, t) } +func BenchmarkLDiv5(t *testing.B) { benchDiv(naiveDiv, 5, t) } +func BenchmarkLDiv10(t *testing.B) { benchDiv(naiveDiv, 10, t) } +func BenchmarkLDiv100(t *testing.B) { benchDiv(naiveDiv, 100, t) } +func BenchmarkLDiv1000(t *testing.B) { benchDiv(naiveDiv, 1000, t) } +func BenchmarkLDiv10000(t *testing.B) { benchDiv(naiveDiv, 10000, t) } +func BenchmarkLDiv100000(t *testing.B) { benchDiv(naiveDiv, 100000, t) } +func BenchmarkLDiv500000(t *testing.B) { benchDiv(naiveDiv, 500000, t) } + +func benchDivTo(f func(dst, a, b []float64) []float64, sz int, t *testing.B) { + dst, a, b := z[:sz], x[:sz], y[:sz] + for i := 0; i < t.N; i++ { + f(dst, a, b) + } +} + +var naiveDivTo = func(dst, s, t []float64) []float64 { + for i, v := range s { + dst[i] = v / t[i] + } + return dst +} + +func BenchmarkDivTo1(t *testing.B) { benchDivTo(DivTo, 1, t) } +func BenchmarkDivTo2(t *testing.B) { benchDivTo(DivTo, 2, t) } +func BenchmarkDivTo3(t *testing.B) { benchDivTo(DivTo, 3, t) } +func BenchmarkDivTo4(t *testing.B) { benchDivTo(DivTo, 4, t) } +func BenchmarkDivTo5(t *testing.B) { benchDivTo(DivTo, 5, t) } +func BenchmarkDivTo10(t *testing.B) { benchDivTo(DivTo, 10, t) } +func BenchmarkDivTo100(t *testing.B) { benchDivTo(DivTo, 100, t) } +func BenchmarkDivTo1000(t *testing.B) { benchDivTo(DivTo, 1000, t) } +func BenchmarkDivTo10000(t *testing.B) { benchDivTo(DivTo, 10000, t) } +func BenchmarkDivTo100000(t *testing.B) { benchDivTo(DivTo, 100000, t) } +func BenchmarkDivTo500000(t *testing.B) { benchDivTo(DivTo, 500000, t) } + +func BenchmarkLDivTo1(t *testing.B) { benchDivTo(naiveDivTo, 1, t) } +func BenchmarkLDivTo2(t *testing.B) { benchDivTo(naiveDivTo, 2, t) } +func BenchmarkLDivTo3(t *testing.B) { benchDivTo(naiveDivTo, 3, t) } +func BenchmarkLDivTo4(t *testing.B) { benchDivTo(naiveDivTo, 4, t) } +func BenchmarkLDivTo5(t *testing.B) { benchDivTo(naiveDivTo, 5, t) } +func BenchmarkLDivTo10(t *testing.B) { benchDivTo(naiveDivTo, 10, t) } +func BenchmarkLDivTo100(t *testing.B) { benchDivTo(naiveDivTo, 100, t) } +func BenchmarkLDivTo1000(t *testing.B) { benchDivTo(naiveDivTo, 1000, t) } +func BenchmarkLDivTo10000(t *testing.B) { benchDivTo(naiveDivTo, 10000, t) } +func BenchmarkLDivTo100000(t *testing.B) { benchDivTo(naiveDivTo, 100000, t) } +func BenchmarkLDivTo500000(t *testing.B) { benchDivTo(naiveDivTo, 500000, t) } + +func benchL1Dist(f func(a, b []float64) float64, sz int, t *testing.B) { + a, b := x[:sz], y[:sz] + for i := 0; i < t.N; i++ { + f(a, b) + } +} + +var naiveL1Dist = func(s, t []float64) float64 { + var norm float64 + for i, v := range s { + norm += math.Abs(t[i] - v) + } + return norm +} + +func BenchmarkL1Dist1(t *testing.B) { benchL1Dist(L1Dist, 1, t) } +func BenchmarkL1Dist2(t *testing.B) { benchL1Dist(L1Dist, 2, t) } +func BenchmarkL1Dist3(t *testing.B) { benchL1Dist(L1Dist, 3, t) } +func BenchmarkL1Dist4(t *testing.B) { benchL1Dist(L1Dist, 4, t) } +func BenchmarkL1Dist5(t *testing.B) { benchL1Dist(L1Dist, 5, t) } +func BenchmarkL1Dist10(t *testing.B) { benchL1Dist(L1Dist, 10, t) } +func BenchmarkL1Dist100(t *testing.B) { benchL1Dist(L1Dist, 100, t) } +func BenchmarkL1Dist1000(t *testing.B) { benchL1Dist(L1Dist, 1000, t) } +func BenchmarkL1Dist10000(t *testing.B) { benchL1Dist(L1Dist, 10000, t) } +func BenchmarkL1Dist100000(t *testing.B) { benchL1Dist(L1Dist, 100000, t) } +func BenchmarkL1Dist500000(t *testing.B) { benchL1Dist(L1Dist, 500000, t) } + +func BenchmarkLL1Dist1(t *testing.B) { benchL1Dist(naiveL1Dist, 1, t) } +func BenchmarkLL1Dist2(t *testing.B) { benchL1Dist(naiveL1Dist, 2, t) } +func BenchmarkLL1Dist3(t *testing.B) { benchL1Dist(naiveL1Dist, 3, t) } +func BenchmarkLL1Dist4(t *testing.B) { benchL1Dist(naiveL1Dist, 4, t) } +func BenchmarkLL1Dist5(t *testing.B) { benchL1Dist(naiveL1Dist, 5, t) } +func BenchmarkLL1Dist10(t *testing.B) { benchL1Dist(naiveL1Dist, 10, t) } +func BenchmarkLL1Dist100(t *testing.B) { benchL1Dist(naiveL1Dist, 100, t) } +func BenchmarkLL1Dist1000(t *testing.B) { benchL1Dist(naiveL1Dist, 1000, t) } +func BenchmarkLL1Dist10000(t *testing.B) { benchL1Dist(naiveL1Dist, 10000, t) } +func BenchmarkLL1Dist100000(t *testing.B) { benchL1Dist(naiveL1Dist, 100000, t) } +func BenchmarkLL1Dist500000(t *testing.B) { benchL1Dist(naiveL1Dist, 500000, t) } + +func benchLinfDist(f func(a, b []float64) float64, sz int, t *testing.B) { + a, b := x[:sz], y[:sz] + for i := 0; i < t.N; i++ { + f(a, b) + } +} + +var naiveLinfDist = func(s, t []float64) float64 { + var norm float64 + if len(s) == 0 { + return 0 + } + norm = math.Abs(t[0] - s[0]) + for i, v := range s[1:] { + absDiff := math.Abs(t[i+1] - v) + if absDiff > norm || math.IsNaN(norm) { + norm = absDiff + } + } + return norm +} + +func BenchmarkLinfDist1(t *testing.B) { benchLinfDist(LinfDist, 1, t) } +func BenchmarkLinfDist2(t *testing.B) { benchLinfDist(LinfDist, 2, t) } +func BenchmarkLinfDist3(t *testing.B) { benchLinfDist(LinfDist, 3, t) } +func BenchmarkLinfDist4(t *testing.B) { benchLinfDist(LinfDist, 4, t) } +func BenchmarkLinfDist5(t *testing.B) { benchLinfDist(LinfDist, 5, t) } +func BenchmarkLinfDist10(t *testing.B) { benchLinfDist(LinfDist, 10, t) } +func BenchmarkLinfDist100(t *testing.B) { benchLinfDist(LinfDist, 100, t) } +func BenchmarkLinfDist1000(t *testing.B) { benchLinfDist(LinfDist, 1000, t) } +func BenchmarkLinfDist10000(t *testing.B) { benchLinfDist(LinfDist, 10000, t) } +func BenchmarkLinfDist100000(t *testing.B) { benchLinfDist(LinfDist, 100000, t) } +func BenchmarkLinfDist500000(t *testing.B) { benchLinfDist(LinfDist, 500000, t) } + +func BenchmarkLLinfDist1(t *testing.B) { benchLinfDist(naiveLinfDist, 1, t) } +func BenchmarkLLinfDist2(t *testing.B) { benchLinfDist(naiveLinfDist, 2, t) } +func BenchmarkLLinfDist3(t *testing.B) { benchLinfDist(naiveLinfDist, 3, t) } +func BenchmarkLLinfDist4(t *testing.B) { benchLinfDist(naiveLinfDist, 4, t) } +func BenchmarkLLinfDist5(t *testing.B) { benchLinfDist(naiveLinfDist, 5, t) } +func BenchmarkLLinfDist10(t *testing.B) { benchLinfDist(naiveLinfDist, 10, t) } +func BenchmarkLLinfDist100(t *testing.B) { benchLinfDist(naiveLinfDist, 100, t) } +func BenchmarkLLinfDist1000(t *testing.B) { benchLinfDist(naiveLinfDist, 1000, t) } +func BenchmarkLLinfDist10000(t *testing.B) { benchLinfDist(naiveLinfDist, 10000, t) } +func BenchmarkLLinfDist100000(t *testing.B) { benchLinfDist(naiveLinfDist, 100000, t) } +func BenchmarkLLinfDist500000(t *testing.B) { benchLinfDist(naiveLinfDist, 500000, t) } diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/bench_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/bench_test.go new file mode 100644 index 00000000..78d26d77 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/bench_test.go @@ -0,0 +1,438 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.7 + +package f64 + +import ( + "math/rand" + "testing" +) + +var ( + a = float64(2) + x = make([]float64, 1000000) + y = make([]float64, 1000000) + z = make([]float64, 1000000) +) + +func init() { + for n := range x { + x[n] = float64(n) + y[n] = float64(n) + } +} + +func benchaxpyu(t *testing.B, n int, f func(a float64, x, y []float64)) { + x, y := x[:n], y[:n] + + for i := 0; i < t.N; i++ { + f(a, x, y) + } +} + +func naiveaxpyu(a float64, x, y []float64) { + for i, v := range x { + y[i] += a * v + } +} + +func BenchmarkF64AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, AxpyUnitary) } +func BenchmarkF64AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, AxpyUnitary) } +func BenchmarkF64AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, AxpyUnitary) } +func BenchmarkF64AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, AxpyUnitary) } +func BenchmarkF64AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, AxpyUnitary) } +func BenchmarkF64AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, AxpyUnitary) } +func BenchmarkF64AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, AxpyUnitary) } +func BenchmarkF64AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, AxpyUnitary) } +func BenchmarkF64AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, AxpyUnitary) } +func BenchmarkF64AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, AxpyUnitary) } +func BenchmarkF64AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, AxpyUnitary) } + +func BenchmarkLF64AxpyUnitary1(t *testing.B) { benchaxpyu(t, 1, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary2(t *testing.B) { benchaxpyu(t, 2, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary3(t *testing.B) { benchaxpyu(t, 3, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary4(t *testing.B) { benchaxpyu(t, 4, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary5(t *testing.B) { benchaxpyu(t, 5, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary10(t *testing.B) { benchaxpyu(t, 10, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary100(t *testing.B) { benchaxpyu(t, 100, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary1000(t *testing.B) { benchaxpyu(t, 1000, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary5000(t *testing.B) { benchaxpyu(t, 5000, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary10000(t *testing.B) { benchaxpyu(t, 10000, naiveaxpyu) } +func BenchmarkLF64AxpyUnitary50000(t *testing.B) { benchaxpyu(t, 50000, naiveaxpyu) } + +func benchaxpyut(t *testing.B, n int, f func(d []float64, a float64, x, y []float64)) { + x, y, z := x[:n], y[:n], z[:n] + + for i := 0; i < t.N; i++ { + f(z, a, x, y) + } +} + +func naiveaxpyut(d []float64, a float64, x, y []float64) { + for i, v := range x { + d[i] = y[i] + a*v + } +} + +func BenchmarkF64AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, AxpyUnitaryTo) } +func BenchmarkF64AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, AxpyUnitaryTo) } + +func BenchmarkLF64AxpyUnitaryTo1(t *testing.B) { benchaxpyut(t, 1, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo2(t *testing.B) { benchaxpyut(t, 2, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo3(t *testing.B) { benchaxpyut(t, 3, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo4(t *testing.B) { benchaxpyut(t, 4, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo5(t *testing.B) { benchaxpyut(t, 5, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo10(t *testing.B) { benchaxpyut(t, 10, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo100(t *testing.B) { benchaxpyut(t, 100, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo1000(t *testing.B) { benchaxpyut(t, 1000, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo5000(t *testing.B) { benchaxpyut(t, 5000, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo10000(t *testing.B) { benchaxpyut(t, 10000, naiveaxpyut) } +func BenchmarkLF64AxpyUnitaryTo50000(t *testing.B) { benchaxpyut(t, 50000, naiveaxpyut) } + +func benchaxpyinc(t *testing.B, ln, t_inc int, f func(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + + for i := 0; i < t.N; i++ { + f(1, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyinc(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + y[iy] += alpha * x[ix] + ix += incX + iy += incY + } +} + +func BenchmarkF64AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, AxpyInc) } + +func BenchmarkF64AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, AxpyInc) } +func BenchmarkF64AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, AxpyInc) } +func BenchmarkF64AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, AxpyInc) } +func BenchmarkF64AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, AxpyInc) } + +func BenchmarkF64AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, AxpyInc) } +func BenchmarkF64AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, AxpyInc) } +func BenchmarkF64AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, AxpyInc) } +func BenchmarkF64AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, AxpyInc) } + +func BenchmarkF64AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, AxpyInc) } +func BenchmarkF64AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, AxpyInc) } +func BenchmarkF64AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, AxpyInc) } +func BenchmarkF64AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, AxpyInc) } + +func BenchmarkF64AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, AxpyInc) } +func BenchmarkF64AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, AxpyInc) } +func BenchmarkF64AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, AxpyInc) } +func BenchmarkF64AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, AxpyInc) } + +func BenchmarkF64AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, AxpyInc) } +func BenchmarkF64AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, AxpyInc) } +func BenchmarkF64AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, AxpyInc) } +func BenchmarkF64AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, AxpyInc) } + +func BenchmarkF64AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, AxpyInc) } +func BenchmarkF64AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, AxpyInc) } +func BenchmarkF64AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, AxpyInc) } +func BenchmarkF64AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, AxpyInc) } + +func BenchmarkF64AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, AxpyInc) } +func BenchmarkF64AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, AxpyInc) } +func BenchmarkF64AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, AxpyInc) } +func BenchmarkF64AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, AxpyInc) } + +func BenchmarkLF64AxpyIncN1Inc1(b *testing.B) { benchaxpyinc(b, 1, 1, naiveaxpyinc) } + +func BenchmarkLF64AxpyIncN2Inc1(b *testing.B) { benchaxpyinc(b, 2, 1, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN2Inc2(b *testing.B) { benchaxpyinc(b, 2, 2, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN2Inc4(b *testing.B) { benchaxpyinc(b, 2, 4, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN2Inc10(b *testing.B) { benchaxpyinc(b, 2, 10, naiveaxpyinc) } + +func BenchmarkLF64AxpyIncN3Inc1(b *testing.B) { benchaxpyinc(b, 3, 1, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN3Inc2(b *testing.B) { benchaxpyinc(b, 3, 2, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN3Inc4(b *testing.B) { benchaxpyinc(b, 3, 4, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN3Inc10(b *testing.B) { benchaxpyinc(b, 3, 10, naiveaxpyinc) } + +func BenchmarkLF64AxpyIncN4Inc1(b *testing.B) { benchaxpyinc(b, 4, 1, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN4Inc2(b *testing.B) { benchaxpyinc(b, 4, 2, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN4Inc4(b *testing.B) { benchaxpyinc(b, 4, 4, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN4Inc10(b *testing.B) { benchaxpyinc(b, 4, 10, naiveaxpyinc) } + +func BenchmarkLF64AxpyIncN10Inc1(b *testing.B) { benchaxpyinc(b, 10, 1, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN10Inc2(b *testing.B) { benchaxpyinc(b, 10, 2, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN10Inc4(b *testing.B) { benchaxpyinc(b, 10, 4, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN10Inc10(b *testing.B) { benchaxpyinc(b, 10, 10, naiveaxpyinc) } + +func BenchmarkLF64AxpyIncN1000Inc1(b *testing.B) { benchaxpyinc(b, 1000, 1, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN1000Inc2(b *testing.B) { benchaxpyinc(b, 1000, 2, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN1000Inc4(b *testing.B) { benchaxpyinc(b, 1000, 4, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN1000Inc10(b *testing.B) { benchaxpyinc(b, 1000, 10, naiveaxpyinc) } + +func BenchmarkLF64AxpyIncN100000Inc1(b *testing.B) { benchaxpyinc(b, 100000, 1, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN100000Inc2(b *testing.B) { benchaxpyinc(b, 100000, 2, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN100000Inc4(b *testing.B) { benchaxpyinc(b, 100000, 4, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN100000Inc10(b *testing.B) { benchaxpyinc(b, 100000, 10, naiveaxpyinc) } + +func BenchmarkLF64AxpyIncN100000IncM1(b *testing.B) { benchaxpyinc(b, 100000, -1, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN100000IncM2(b *testing.B) { benchaxpyinc(b, 100000, -2, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN100000IncM4(b *testing.B) { benchaxpyinc(b, 100000, -4, naiveaxpyinc) } +func BenchmarkLF64AxpyIncN100000IncM10(b *testing.B) { benchaxpyinc(b, 100000, -10, naiveaxpyinc) } + +func benchaxpyincto(t *testing.B, ln, t_inc int, f func(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr)) { + n, inc := uintptr(ln), uintptr(t_inc) + var idx int + if t_inc < 0 { + idx = (-ln + 1) * t_inc + } + + for i := 0; i < t.N; i++ { + f(z, inc, uintptr(idx), 1, x, y, n, inc, inc, uintptr(idx), uintptr(idx)) + } +} + +func naiveaxpyincto(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) { + for i := 0; i < int(n); i++ { + dst[idst] = alpha*x[ix] + y[iy] + ix += incX + iy += incY + idst += incDst + } +} + +func BenchmarkF64AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, AxpyIncTo) } + +func BenchmarkF64AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, AxpyIncTo) } +func BenchmarkF64AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, AxpyIncTo) } +func BenchmarkF64AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, AxpyIncTo) } +func BenchmarkF64AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, AxpyIncTo) } + +func BenchmarkF64AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, AxpyIncTo) } +func BenchmarkF64AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, AxpyIncTo) } +func BenchmarkF64AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, AxpyIncTo) } +func BenchmarkF64AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, AxpyIncTo) } + +func BenchmarkF64AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, AxpyIncTo) } +func BenchmarkF64AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, AxpyIncTo) } +func BenchmarkF64AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, AxpyIncTo) } +func BenchmarkF64AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, AxpyIncTo) } + +func BenchmarkF64AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, AxpyIncTo) } +func BenchmarkF64AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, AxpyIncTo) } +func BenchmarkF64AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, AxpyIncTo) } +func BenchmarkF64AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, AxpyIncTo) } + +func BenchmarkF64AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, AxpyIncTo) } +func BenchmarkF64AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, AxpyIncTo) } +func BenchmarkF64AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, AxpyIncTo) } +func BenchmarkF64AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, AxpyIncTo) } + +func BenchmarkF64AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, AxpyIncTo) } +func BenchmarkF64AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, AxpyIncTo) } +func BenchmarkF64AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, AxpyIncTo) } +func BenchmarkF64AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, AxpyIncTo) } + +func BenchmarkF64AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, AxpyIncTo) } +func BenchmarkF64AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, AxpyIncTo) } +func BenchmarkF64AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, AxpyIncTo) } +func BenchmarkF64AxpyIncToN100000IncM10(b *testing.B) { benchaxpyincto(b, 100000, -10, AxpyIncTo) } + +func BenchmarkLF64AxpyIncToN1Inc1(b *testing.B) { benchaxpyincto(b, 1, 1, naiveaxpyincto) } + +func BenchmarkLF64AxpyIncToN2Inc1(b *testing.B) { benchaxpyincto(b, 2, 1, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN2Inc2(b *testing.B) { benchaxpyincto(b, 2, 2, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN2Inc4(b *testing.B) { benchaxpyincto(b, 2, 4, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN2Inc10(b *testing.B) { benchaxpyincto(b, 2, 10, naiveaxpyincto) } + +func BenchmarkLF64AxpyIncToN3Inc1(b *testing.B) { benchaxpyincto(b, 3, 1, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN3Inc2(b *testing.B) { benchaxpyincto(b, 3, 2, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN3Inc4(b *testing.B) { benchaxpyincto(b, 3, 4, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN3Inc10(b *testing.B) { benchaxpyincto(b, 3, 10, naiveaxpyincto) } + +func BenchmarkLF64AxpyIncToN4Inc1(b *testing.B) { benchaxpyincto(b, 4, 1, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN4Inc2(b *testing.B) { benchaxpyincto(b, 4, 2, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN4Inc4(b *testing.B) { benchaxpyincto(b, 4, 4, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN4Inc10(b *testing.B) { benchaxpyincto(b, 4, 10, naiveaxpyincto) } + +func BenchmarkLF64AxpyIncToN10Inc1(b *testing.B) { benchaxpyincto(b, 10, 1, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN10Inc2(b *testing.B) { benchaxpyincto(b, 10, 2, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN10Inc4(b *testing.B) { benchaxpyincto(b, 10, 4, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN10Inc10(b *testing.B) { benchaxpyincto(b, 10, 10, naiveaxpyincto) } + +func BenchmarkLF64AxpyIncToN1000Inc1(b *testing.B) { benchaxpyincto(b, 1000, 1, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN1000Inc2(b *testing.B) { benchaxpyincto(b, 1000, 2, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN1000Inc4(b *testing.B) { benchaxpyincto(b, 1000, 4, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN1000Inc10(b *testing.B) { benchaxpyincto(b, 1000, 10, naiveaxpyincto) } + +func BenchmarkLF64AxpyIncToN100000Inc1(b *testing.B) { benchaxpyincto(b, 100000, 1, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN100000Inc2(b *testing.B) { benchaxpyincto(b, 100000, 2, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN100000Inc4(b *testing.B) { benchaxpyincto(b, 100000, 4, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN100000Inc10(b *testing.B) { benchaxpyincto(b, 100000, 10, naiveaxpyincto) } + +func BenchmarkLF64AxpyIncToN100000IncM1(b *testing.B) { benchaxpyincto(b, 100000, -1, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN100000IncM2(b *testing.B) { benchaxpyincto(b, 100000, -2, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN100000IncM4(b *testing.B) { benchaxpyincto(b, 100000, -4, naiveaxpyincto) } +func BenchmarkLF64AxpyIncToN100000IncM10(b *testing.B) { benchaxpyincto(b, 100000, -10, naiveaxpyincto) } + +// Scal* benchmarks +func BenchmarkDscalUnitaryN1(b *testing.B) { benchmarkDscalUnitary(b, 1) } +func BenchmarkDscalUnitaryN2(b *testing.B) { benchmarkDscalUnitary(b, 2) } +func BenchmarkDscalUnitaryN3(b *testing.B) { benchmarkDscalUnitary(b, 3) } +func BenchmarkDscalUnitaryN4(b *testing.B) { benchmarkDscalUnitary(b, 4) } +func BenchmarkDscalUnitaryN10(b *testing.B) { benchmarkDscalUnitary(b, 10) } +func BenchmarkDscalUnitaryN100(b *testing.B) { benchmarkDscalUnitary(b, 100) } +func BenchmarkDscalUnitaryN1000(b *testing.B) { benchmarkDscalUnitary(b, 1000) } +func BenchmarkDscalUnitaryN10000(b *testing.B) { benchmarkDscalUnitary(b, 10000) } +func BenchmarkDscalUnitaryN100000(b *testing.B) { benchmarkDscalUnitary(b, 100000) } + +func benchmarkDscalUnitary(b *testing.B, n int) { + x := randomSlice(n, 1) + b.ResetTimer() + for i := 0; i < b.N; i += 2 { + ScalUnitary(2, x) + ScalUnitary(0.5, x) + } + benchSink = x +} + +func BenchmarkDscalUnitaryToN1(b *testing.B) { benchmarkDscalUnitaryTo(b, 1) } +func BenchmarkDscalUnitaryToN2(b *testing.B) { benchmarkDscalUnitaryTo(b, 2) } +func BenchmarkDscalUnitaryToN3(b *testing.B) { benchmarkDscalUnitaryTo(b, 3) } +func BenchmarkDscalUnitaryToN4(b *testing.B) { benchmarkDscalUnitaryTo(b, 4) } +func BenchmarkDscalUnitaryToN10(b *testing.B) { benchmarkDscalUnitaryTo(b, 10) } +func BenchmarkDscalUnitaryToN100(b *testing.B) { benchmarkDscalUnitaryTo(b, 100) } +func BenchmarkDscalUnitaryToN1000(b *testing.B) { benchmarkDscalUnitaryTo(b, 1000) } +func BenchmarkDscalUnitaryToN10000(b *testing.B) { benchmarkDscalUnitaryTo(b, 10000) } +func BenchmarkDscalUnitaryToN100000(b *testing.B) { benchmarkDscalUnitaryTo(b, 100000) } + +func benchmarkDscalUnitaryTo(b *testing.B, n int) { + x := randomSlice(n, 1) + dst := randomSlice(n, 1) + a := rand.Float64() + b.ResetTimer() + for i := 0; i < b.N; i++ { + ScalUnitaryTo(dst, a, x) + } + benchSink = dst +} + +func BenchmarkDscalUnitaryToXN1(b *testing.B) { benchmarkDscalUnitaryToX(b, 1) } +func BenchmarkDscalUnitaryToXN2(b *testing.B) { benchmarkDscalUnitaryToX(b, 2) } +func BenchmarkDscalUnitaryToXN3(b *testing.B) { benchmarkDscalUnitaryToX(b, 3) } +func BenchmarkDscalUnitaryToXN4(b *testing.B) { benchmarkDscalUnitaryToX(b, 4) } +func BenchmarkDscalUnitaryToXN10(b *testing.B) { benchmarkDscalUnitaryToX(b, 10) } +func BenchmarkDscalUnitaryToXN100(b *testing.B) { benchmarkDscalUnitaryToX(b, 100) } +func BenchmarkDscalUnitaryToXN1000(b *testing.B) { benchmarkDscalUnitaryToX(b, 1000) } +func BenchmarkDscalUnitaryToXN10000(b *testing.B) { benchmarkDscalUnitaryToX(b, 10000) } +func BenchmarkDscalUnitaryToXN100000(b *testing.B) { benchmarkDscalUnitaryToX(b, 100000) } + +func benchmarkDscalUnitaryToX(b *testing.B, n int) { + x := randomSlice(n, 1) + b.ResetTimer() + for i := 0; i < b.N; i += 2 { + ScalUnitaryTo(x, 2, x) + ScalUnitaryTo(x, 0.5, x) + } + benchSink = x +} + +func BenchmarkDscalIncN1Inc1(b *testing.B) { benchmarkDscalInc(b, 1, 1) } + +func BenchmarkDscalIncN2Inc1(b *testing.B) { benchmarkDscalInc(b, 2, 1) } +func BenchmarkDscalIncN2Inc2(b *testing.B) { benchmarkDscalInc(b, 2, 2) } +func BenchmarkDscalIncN2Inc4(b *testing.B) { benchmarkDscalInc(b, 2, 4) } +func BenchmarkDscalIncN2Inc10(b *testing.B) { benchmarkDscalInc(b, 2, 10) } + +func BenchmarkDscalIncN3Inc1(b *testing.B) { benchmarkDscalInc(b, 3, 1) } +func BenchmarkDscalIncN3Inc2(b *testing.B) { benchmarkDscalInc(b, 3, 2) } +func BenchmarkDscalIncN3Inc4(b *testing.B) { benchmarkDscalInc(b, 3, 4) } +func BenchmarkDscalIncN3Inc10(b *testing.B) { benchmarkDscalInc(b, 3, 10) } + +func BenchmarkDscalIncN4Inc1(b *testing.B) { benchmarkDscalInc(b, 4, 1) } +func BenchmarkDscalIncN4Inc2(b *testing.B) { benchmarkDscalInc(b, 4, 2) } +func BenchmarkDscalIncN4Inc4(b *testing.B) { benchmarkDscalInc(b, 4, 4) } +func BenchmarkDscalIncN4Inc10(b *testing.B) { benchmarkDscalInc(b, 4, 10) } + +func BenchmarkDscalIncN10Inc1(b *testing.B) { benchmarkDscalInc(b, 10, 1) } +func BenchmarkDscalIncN10Inc2(b *testing.B) { benchmarkDscalInc(b, 10, 2) } +func BenchmarkDscalIncN10Inc4(b *testing.B) { benchmarkDscalInc(b, 10, 4) } +func BenchmarkDscalIncN10Inc10(b *testing.B) { benchmarkDscalInc(b, 10, 10) } + +func BenchmarkDscalIncN1000Inc1(b *testing.B) { benchmarkDscalInc(b, 1000, 1) } +func BenchmarkDscalIncN1000Inc2(b *testing.B) { benchmarkDscalInc(b, 1000, 2) } +func BenchmarkDscalIncN1000Inc4(b *testing.B) { benchmarkDscalInc(b, 1000, 4) } +func BenchmarkDscalIncN1000Inc10(b *testing.B) { benchmarkDscalInc(b, 1000, 10) } + +func BenchmarkDscalIncN100000Inc1(b *testing.B) { benchmarkDscalInc(b, 100000, 1) } +func BenchmarkDscalIncN100000Inc2(b *testing.B) { benchmarkDscalInc(b, 100000, 2) } +func BenchmarkDscalIncN100000Inc4(b *testing.B) { benchmarkDscalInc(b, 100000, 4) } +func BenchmarkDscalIncN100000Inc10(b *testing.B) { benchmarkDscalInc(b, 100000, 10) } + +func benchmarkDscalInc(b *testing.B, n, inc int) { + x := randomSlice(n, inc) + b.ResetTimer() + for i := 0; i < b.N; i += 2 { + ScalInc(2, x, uintptr(n), uintptr(inc)) + ScalInc(0.5, x, uintptr(n), uintptr(inc)) + } + benchSink = x +} + +func BenchmarkDscalIncToN1Inc1(b *testing.B) { benchmarkDscalIncTo(b, 1, 1) } + +func BenchmarkDscalIncToN2Inc1(b *testing.B) { benchmarkDscalIncTo(b, 2, 1) } +func BenchmarkDscalIncToN2Inc2(b *testing.B) { benchmarkDscalIncTo(b, 2, 2) } +func BenchmarkDscalIncToN2Inc4(b *testing.B) { benchmarkDscalIncTo(b, 2, 4) } +func BenchmarkDscalIncToN2Inc10(b *testing.B) { benchmarkDscalIncTo(b, 2, 10) } + +func BenchmarkDscalIncToN3Inc1(b *testing.B) { benchmarkDscalIncTo(b, 3, 1) } +func BenchmarkDscalIncToN3Inc2(b *testing.B) { benchmarkDscalIncTo(b, 3, 2) } +func BenchmarkDscalIncToN3Inc4(b *testing.B) { benchmarkDscalIncTo(b, 3, 4) } +func BenchmarkDscalIncToN3Inc10(b *testing.B) { benchmarkDscalIncTo(b, 3, 10) } + +func BenchmarkDscalIncToN4Inc1(b *testing.B) { benchmarkDscalIncTo(b, 4, 1) } +func BenchmarkDscalIncToN4Inc2(b *testing.B) { benchmarkDscalIncTo(b, 4, 2) } +func BenchmarkDscalIncToN4Inc4(b *testing.B) { benchmarkDscalIncTo(b, 4, 4) } +func BenchmarkDscalIncToN4Inc10(b *testing.B) { benchmarkDscalIncTo(b, 4, 10) } + +func BenchmarkDscalIncToN10Inc1(b *testing.B) { benchmarkDscalIncTo(b, 10, 1) } +func BenchmarkDscalIncToN10Inc2(b *testing.B) { benchmarkDscalIncTo(b, 10, 2) } +func BenchmarkDscalIncToN10Inc4(b *testing.B) { benchmarkDscalIncTo(b, 10, 4) } +func BenchmarkDscalIncToN10Inc10(b *testing.B) { benchmarkDscalIncTo(b, 10, 10) } + +func BenchmarkDscalIncToN1000Inc1(b *testing.B) { benchmarkDscalIncTo(b, 1000, 1) } +func BenchmarkDscalIncToN1000Inc2(b *testing.B) { benchmarkDscalIncTo(b, 1000, 2) } +func BenchmarkDscalIncToN1000Inc4(b *testing.B) { benchmarkDscalIncTo(b, 1000, 4) } +func BenchmarkDscalIncToN1000Inc10(b *testing.B) { benchmarkDscalIncTo(b, 1000, 10) } + +func BenchmarkDscalIncToN100000Inc1(b *testing.B) { benchmarkDscalIncTo(b, 100000, 1) } +func BenchmarkDscalIncToN100000Inc2(b *testing.B) { benchmarkDscalIncTo(b, 100000, 2) } +func BenchmarkDscalIncToN100000Inc4(b *testing.B) { benchmarkDscalIncTo(b, 100000, 4) } +func BenchmarkDscalIncToN100000Inc10(b *testing.B) { benchmarkDscalIncTo(b, 100000, 10) } + +func benchmarkDscalIncTo(b *testing.B, n, inc int) { + x := randomSlice(n, inc) + dst := randomSlice(n, inc) + a := rand.Float64() + b.ResetTimer() + for i := 0; i < b.N; i++ { + ScalIncTo(dst, uintptr(inc), a, x, uintptr(n), uintptr(inc)) + } + benchSink = dst +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/cumprod_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/cumprod_amd64.s new file mode 100644 index 00000000..3d438093 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/cumprod_amd64.s @@ -0,0 +1,71 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +TEXT ·CumProd(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ dst_len+8(FP), CX // CX = len(dst) + MOVQ s_base+24(FP), SI // SI = &s + CMPQ s_len+32(FP), CX // CX = max( CX, len(s) ) + CMOVQLE s_len+32(FP), CX + MOVQ CX, ret_len+56(FP) // len(ret) = CX + CMPQ CX, $0 // if CX == 0 { return } + JE cp_end + XORQ AX, AX // i = 0 + + MOVSD (SI), X5 // p_prod = { s[0], s[0] } + SHUFPD $0, X5, X5 + MOVSD X5, (DI) // dst[0] = s[0] + INCQ AX // ++i + DECQ CX // -- CX + JZ cp_end // if CX == 0 { return } + + MOVQ CX, BX + ANDQ $3, BX // BX = CX % 4 + SHRQ $2, CX // CX = floor( CX / 4 ) + JZ cp_tail_start // if CX == 0 { goto cp_tail_start } + +cp_loop: // Loop unrolled 4x do { + MOVUPS (SI)(AX*8), X0 // X0 = s[i:i+1] + MOVUPS 16(SI)(AX*8), X2 + MOVAPS X0, X1 // X1 = X0 + MOVAPS X2, X3 + SHUFPD $1, X1, X1 // { X1[0], X1[1] } = { X1[1], X1[0] } + SHUFPD $1, X3, X3 + MULPD X0, X1 // X1 *= X0 + MULPD X2, X3 + SHUFPD $2, X1, X0 // { X0[0], X0[1] } = { X0[0], X1[1] } + SHUFPD $3, X1, X1 // { X1[0], X1[1] } = { X1[1], X1[1] } + SHUFPD $2, X3, X2 + SHUFPD $3, X3, X3 + MULPD X5, X0 // X0 *= p_prod + MULPD X1, X5 // p_prod *= X1 + MULPD X5, X2 + MOVUPS X0, (DI)(AX*8) // dst[i] = X0 + MOVUPS X2, 16(DI)(AX*8) + MULPD X3, X5 + ADDQ $4, AX // i += 4 + LOOP cp_loop // } while --CX > 0 + + // if BX == 0 { return } + CMPQ BX, $0 + JE cp_end + +cp_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + +cp_tail: // do { + MULSD (SI)(AX*8), X5 // p_prod *= s[i] + MOVSD X5, (DI)(AX*8) // dst[i] = p_prod + INCQ AX // ++i + LOOP cp_tail // } while --CX > 0 + +cp_end: + MOVQ DI, ret_base+48(FP) // &ret = &dst + MOVQ dst_cap+16(FP), SI // cap(ret) = cap(dst) + MOVQ SI, ret_cap+64(FP) + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/cumsum_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/cumsum_amd64.s new file mode 100644 index 00000000..eecfbbe1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/cumsum_amd64.s @@ -0,0 +1,64 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +TEXT ·CumSum(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ dst_len+8(FP), CX // CX = len(dst) + MOVQ s_base+24(FP), SI // SI = &s + CMPQ s_len+32(FP), CX // CX = max( CX, len(s) ) + CMOVQLE s_len+32(FP), CX + MOVQ CX, ret_len+56(FP) // len(ret) = CX + CMPQ CX, $0 // if CX == 0 { return } + JE cs_end + XORQ AX, AX // i = 0 + PXOR X5, X5 // p_sum = 0 + MOVQ CX, BX + ANDQ $3, BX // BX = CX % 4 + SHRQ $2, CX // CX = floor( CX / 4 ) + JZ cs_tail_start // if CX == 0 { goto cs_tail_start } + +cs_loop: // Loop unrolled 4x do { + MOVUPS (SI)(AX*8), X0 // X0 = s[i:i+1] + MOVUPS 16(SI)(AX*8), X2 + MOVAPS X0, X1 // X1 = X0 + MOVAPS X2, X3 + SHUFPD $1, X1, X1 // { X1[0], X1[1] } = { X1[1], X1[0] } + SHUFPD $1, X3, X3 + ADDPD X0, X1 // X1 += X0 + ADDPD X2, X3 + SHUFPD $2, X1, X0 // { X0[0], X0[1] } = { X0[0], X1[1] } + SHUFPD $3, X1, X1 // { X1[0], X1[1] } = { X1[1], X1[1] } + SHUFPD $2, X3, X2 + SHUFPD $3, X3, X3 + ADDPD X5, X0 // X0 += p_sum + ADDPD X1, X5 // p_sum += X1 + ADDPD X5, X2 + MOVUPS X0, (DI)(AX*8) // dst[i] = X0 + MOVUPS X2, 16(DI)(AX*8) + ADDPD X3, X5 + ADDQ $4, AX // i += 4 + LOOP cs_loop // } while --CX > 0 + + // if BX == 0 { return } + CMPQ BX, $0 + JE cs_end + +cs_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + +cs_tail: // do { + ADDSD (SI)(AX*8), X5 // p_sum *= s[i] + MOVSD X5, (DI)(AX*8) // dst[i] = p_sum + INCQ AX // ++i + LOOP cs_tail // } while --CX > 0 + +cs_end: + MOVQ DI, ret_base+48(FP) // &ret = &dst + MOVQ dst_cap+16(FP), SI // cap(ret) = cap(dst) + MOVQ SI, ret_cap+64(FP) + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/div_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/div_amd64.s new file mode 100644 index 00000000..da417708 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/div_amd64.s @@ -0,0 +1,67 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func Div(dst, s []float64) +TEXT ·Div(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ dst_len+8(FP), CX // CX = len(dst) + MOVQ s_base+24(FP), SI // SI = &s + CMPQ s_len+32(FP), CX // CX = max( CX, len(s) ) + CMOVQLE s_len+32(FP), CX + CMPQ CX, $0 // if CX == 0 { return } + JE div_end + XORQ AX, AX // i = 0 + MOVQ SI, BX + ANDQ $15, BX // BX = &s & 15 + JZ div_no_trim // if BX == 0 { goto div_no_trim } + + // Align on 16-bit boundary + MOVSD (DI)(AX*8), X0 // X0 = dst[i] + DIVSD (SI)(AX*8), X0 // X0 /= s[i] + MOVSD X0, (DI)(AX*8) // dst[i] = X0 + INCQ AX // ++i + DECQ CX // --CX + JZ div_end // if CX == 0 { return } + +div_no_trim: + MOVQ CX, BX + ANDQ $7, BX // BX = len(dst) % 8 + SHRQ $3, CX // CX = floor( len(dst) / 8 ) + JZ div_tail_start // if CX == 0 { goto div_tail_start } + +div_loop: // Loop unrolled 8x do { + MOVUPS (DI)(AX*8), X0 // X0 = dst[i:i+1] + MOVUPS 16(DI)(AX*8), X1 + MOVUPS 32(DI)(AX*8), X2 + MOVUPS 48(DI)(AX*8), X3 + DIVPD (SI)(AX*8), X0 // X0 /= s[i:i+1] + DIVPD 16(SI)(AX*8), X1 + DIVPD 32(SI)(AX*8), X2 + DIVPD 48(SI)(AX*8), X3 + MOVUPS X0, (DI)(AX*8) // dst[i] = X0 + MOVUPS X1, 16(DI)(AX*8) + MOVUPS X2, 32(DI)(AX*8) + MOVUPS X3, 48(DI)(AX*8) + ADDQ $8, AX // i += 8 + LOOP div_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE div_end + +div_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + +div_tail: // do { + MOVSD (DI)(AX*8), X0 // X0 = dst[i] + DIVSD (SI)(AX*8), X0 // X0 /= s[i] + MOVSD X0, (DI)(AX*8) // dst[i] = X0 + INCQ AX // ++i + LOOP div_tail // } while --CX > 0 + +div_end: + RET + diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/divto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/divto_amd64.s new file mode 100644 index 00000000..6280aab4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/divto_amd64.s @@ -0,0 +1,73 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func DivTo(dst, x, y []float64) +TEXT ·DivTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DI // DI = &dst + MOVQ dst_len+8(FP), CX // CX = len(dst) + MOVQ x_base+24(FP), SI // SI = &x + MOVQ y_base+48(FP), DX // DX = &y + CMPQ x_len+32(FP), CX // CX = max( len(dst), len(x), len(y) ) + CMOVQLE x_len+32(FP), CX + CMPQ y_len+56(FP), CX + CMOVQLE y_len+56(FP), CX + MOVQ CX, ret_len+80(FP) // len(ret) = CX + CMPQ CX, $0 // if CX == 0 { return } + JE div_end + XORQ AX, AX // i = 0 + MOVQ DX, BX + ANDQ $15, BX // BX = &y & OxF + JZ div_no_trim // if BX == 0 { goto div_no_trim } + + // Align on 16-bit boundary + MOVSD (SI)(AX*8), X0 // X0 = s[i] + DIVSD (DX)(AX*8), X0 // X0 /= t[i] + MOVSD X0, (DI)(AX*8) // dst[i] = X0 + INCQ AX // ++i + DECQ CX // --CX + JZ div_end // if CX == 0 { return } + +div_no_trim: + MOVQ CX, BX + ANDQ $7, BX // BX = len(dst) % 8 + SHRQ $3, CX // CX = floor( len(dst) / 8 ) + JZ div_tail_start // if CX == 0 { goto div_tail_start } + +div_loop: // Loop unrolled 8x do { + MOVUPS (SI)(AX*8), X0 // X0 = x[i:i+1] + MOVUPS 16(SI)(AX*8), X1 + MOVUPS 32(SI)(AX*8), X2 + MOVUPS 48(SI)(AX*8), X3 + DIVPD (DX)(AX*8), X0 // X0 /= y[i:i+1] + DIVPD 16(DX)(AX*8), X1 + DIVPD 32(DX)(AX*8), X2 + DIVPD 48(DX)(AX*8), X3 + MOVUPS X0, (DI)(AX*8) // dst[i:i+1] = X0 + MOVUPS X1, 16(DI)(AX*8) + MOVUPS X2, 32(DI)(AX*8) + MOVUPS X3, 48(DI)(AX*8) + ADDQ $8, AX // i += 8 + LOOP div_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE div_end + +div_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + +div_tail: // do { + MOVSD (SI)(AX*8), X0 // X0 = x[i] + DIVSD (DX)(AX*8), X0 // X0 /= y[i] + MOVSD X0, (DI)(AX*8) + INCQ AX // ++i + LOOP div_tail // } while --CX > 0 + +div_end: + MOVQ DI, ret_base+72(FP) // &ret = &dst + MOVQ dst_cap+16(FP), DI // cap(ret) = cap(dst) + MOVQ DI, ret_cap+88(FP) + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/doc.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/doc.go new file mode 100644 index 00000000..5b562b57 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package f64 provides float64 vector primitives. +package f64 // import "gonum.org/v1/gonum/internal/asm/f64" diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/dot.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/dot.go new file mode 100644 index 00000000..7b86b5b4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/dot.go @@ -0,0 +1,35 @@ +// Copyright ©2015 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !amd64 noasm appengine + +package f64 + +// DotUnitary is +// for i, v := range x { +// sum += y[i] * v +// } +// return sum +func DotUnitary(x, y []float64) (sum float64) { + for i, v := range x { + sum += y[i] * v + } + return sum +} + +// DotInc is +// for i := 0; i < int(n); i++ { +// sum += y[iy] * x[ix] +// ix += incX +// iy += incY +// } +// return sum +func DotInc(x, y []float64, n, incX, incY, ix, iy uintptr) (sum float64) { + for i := 0; i < int(n); i++ { + sum += y[iy] * x[ix] + ix += incX + iy += incY + } + return sum +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/dot_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/dot_amd64.s new file mode 100644 index 00000000..02e654d5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/dot_amd64.s @@ -0,0 +1,145 @@ +// 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. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +// func DdotUnitary(x, y []float64) (sum float64) +// This function assumes len(y) >= len(x). +TEXT ·DotUnitary(SB), NOSPLIT, $0 + MOVQ x+0(FP), R8 + MOVQ x_len+8(FP), DI // n = len(x) + MOVQ y+24(FP), R9 + + MOVSD $(0.0), X7 // sum = 0 + MOVSD $(0.0), X8 // sum = 0 + + MOVQ $0, SI // i = 0 + SUBQ $4, DI // n -= 4 + JL tail_uni // if n < 0 goto tail_uni + +loop_uni: + // sum += x[i] * y[i] unrolled 4x. + MOVUPD 0(R8)(SI*8), X0 + MOVUPD 0(R9)(SI*8), X1 + MOVUPD 16(R8)(SI*8), X2 + MOVUPD 16(R9)(SI*8), X3 + MULPD X1, X0 + MULPD X3, X2 + ADDPD X0, X7 + ADDPD X2, X8 + + ADDQ $4, SI // i += 4 + SUBQ $4, DI // n -= 4 + JGE loop_uni // if n >= 0 goto loop_uni + +tail_uni: + ADDQ $4, DI // n += 4 + JLE end_uni // if n <= 0 goto end_uni + +onemore_uni: + // sum += x[i] * y[i] for the remaining 1-3 elements. + MOVSD 0(R8)(SI*8), X0 + MOVSD 0(R9)(SI*8), X1 + MULSD X1, X0 + ADDSD X0, X7 + + ADDQ $1, SI // i++ + SUBQ $1, DI // n-- + JNZ onemore_uni // if n != 0 goto onemore_uni + +end_uni: + // Add the four sums together. + ADDPD X8, X7 + MOVSD X7, X0 + UNPCKHPD X7, X7 + ADDSD X0, X7 + MOVSD X7, sum+48(FP) // Return final sum. + RET + +// func DdotInc(x, y []float64, n, incX, incY, ix, iy uintptr) (sum float64) +TEXT ·DotInc(SB), NOSPLIT, $0 + MOVQ x+0(FP), R8 + MOVQ y+24(FP), R9 + MOVQ n+48(FP), CX + MOVQ incX+56(FP), R11 + MOVQ incY+64(FP), R12 + MOVQ ix+72(FP), R13 + MOVQ iy+80(FP), R14 + + MOVSD $(0.0), X7 // sum = 0 + LEAQ (R8)(R13*8), SI // p = &x[ix] + LEAQ (R9)(R14*8), DI // q = &y[ix] + SHLQ $3, R11 // incX *= sizeof(float64) + SHLQ $3, R12 // indY *= sizeof(float64) + + SUBQ $2, CX // n -= 2 + JL tail_inc // if n < 0 goto tail_inc + +loop_inc: + // sum += *p * *q unrolled 2x. + MOVHPD (SI), X0 + MOVHPD (DI), X1 + ADDQ R11, SI // p += incX + ADDQ R12, DI // q += incY + MOVLPD (SI), X0 + MOVLPD (DI), X1 + ADDQ R11, SI // p += incX + ADDQ R12, DI // q += incY + + MULPD X1, X0 + ADDPD X0, X7 + + SUBQ $2, CX // n -= 2 + JGE loop_inc // if n >= 0 goto loop_inc + +tail_inc: + ADDQ $2, CX // n += 2 + JLE end_inc // if n <= 0 goto end_inc + + // sum += *p * *q for the last iteration if n is odd. + MOVSD (SI), X0 + MULSD (DI), X0 + ADDSD X0, X7 + +end_inc: + // Add the two sums together. + MOVSD X7, X0 + UNPCKHPD X7, X7 + ADDSD X0, X7 + MOVSD X7, sum+88(FP) // Return final sum. + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/dot_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/dot_test.go new file mode 100644 index 00000000..5ca88b8b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/dot_test.go @@ -0,0 +1,280 @@ +// 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 f64 + +import ( + "fmt" + "math" + "math/rand" + "testing" +) + +func TestDotUnitary(t *testing.T) { + for i, test := range []struct { + xData []float64 + yData []float64 + + want float64 + }{ + { + xData: []float64{2}, + yData: []float64{-3}, + want: -6, + }, + { + xData: []float64{2, 3}, + yData: []float64{-3, 4}, + want: 6, + }, + { + xData: []float64{2, 3, -4}, + yData: []float64{-3, 4, 5}, + want: -14, + }, + { + xData: []float64{2, 3, -4, -5}, + yData: []float64{-3, 4, 5, -6}, + want: 16, + }, + { + xData: []float64{0, 2, 3, -4, -5}, + yData: []float64{0, -3, 4, 5, -6}, + want: 16, + }, + { + xData: []float64{0, 0, 2, 3, -4, -5}, + yData: []float64{0, 1, -3, 4, 5, -6}, + want: 16, + }, + { + xData: []float64{0, 0, 1, 1, 2, -3, -4}, + yData: []float64{0, 1, 0, 3, -4, 5, -6}, + want: 4, + }, + { + xData: []float64{0, 0, 1, 1, 2, -3, -4, 5}, + yData: []float64{0, 1, 0, 3, -4, 5, -6, 7}, + want: 39, + }, + } { + const msgGuard = "test %v: out-of-bounds write to %v argument\nfront guard: %v\nback guard: %v" + + x, xFront, xBack := newGuardedVector(test.xData, 1) + y, yFront, yBack := newGuardedVector(test.yData, 1) + got := DotUnitary(x, y) + + if !allNaN(xFront) || !allNaN(xBack) { + t.Errorf(msgGuard, i, "x", xFront, xBack) + } + if !allNaN(yFront) || !allNaN(yBack) { + t.Errorf(msgGuard, i, "y", yFront, yBack) + } + if !equalStrided(test.xData, x, 1) { + t.Errorf("test %v: modified read-only x argument", i) + } + if !equalStrided(test.yData, y, 1) { + t.Errorf("test %v: modified read-only y argument", i) + } + if math.IsNaN(got) { + t.Errorf("test %v: invalid memory read", i) + continue + } + + if got != test.want { + t.Errorf("test %v: unexpected result. want %v, got %v", i, test.want, got) + } + } +} + +func TestDotInc(t *testing.T) { + for i, test := range []struct { + xData []float64 + yData []float64 + + want float64 + wantRev float64 // Result when one of the vectors is reversed. + }{ + { + xData: []float64{2}, + yData: []float64{-3}, + want: -6, + wantRev: -6, + }, + { + xData: []float64{2, 3}, + yData: []float64{-3, 4}, + want: 6, + wantRev: -1, + }, + { + xData: []float64{2, 3, -4}, + yData: []float64{-3, 4, 5}, + want: -14, + wantRev: 34, + }, + { + xData: []float64{2, 3, -4, -5}, + yData: []float64{-3, 4, 5, -6}, + want: 16, + wantRev: 2, + }, + { + xData: []float64{0, 2, 3, -4, -5}, + yData: []float64{0, -3, 4, 5, -6}, + want: 16, + wantRev: 34, + }, + { + xData: []float64{0, 0, 2, 3, -4, -5}, + yData: []float64{0, 1, -3, 4, 5, -6}, + want: 16, + wantRev: -5, + }, + { + xData: []float64{0, 0, 1, 1, 2, -3, -4}, + yData: []float64{0, 1, 0, 3, -4, 5, -6}, + want: 4, + wantRev: -4, + }, + { + xData: []float64{0, 0, 1, 1, 2, -3, -4, 5}, + yData: []float64{0, 1, 0, 3, -4, 5, -6, 7}, + want: 39, + wantRev: 3, + }, + } { + const msgGuard = "%v: out-of-bounds write to %v argument\nfront guard: %v\nback guard: %v" + + for _, incX := range []int{-7, -3, -2, -1, 1, 2, 3, 7} { + for _, incY := range []int{-7, -3, -2, -1, 1, 2, 3, 7} { + n := len(test.xData) + x, xFront, xBack := newGuardedVector(test.xData, incX) + y, yFront, yBack := newGuardedVector(test.yData, incY) + + var ix, iy int + if incX < 0 { + ix = (-n + 1) * incX + } + if incY < 0 { + iy = (-n + 1) * incY + } + got := DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy)) + + prefix := fmt.Sprintf("test %v, incX = %v, incY = %v", i, incX, incY) + if !allNaN(xFront) || !allNaN(xBack) { + t.Errorf(msgGuard, prefix, "x", xFront, xBack) + } + if !allNaN(yFront) || !allNaN(yBack) { + t.Errorf(msgGuard, prefix, "y", yFront, yBack) + } + if nonStridedWrite(x, incX) || !equalStrided(test.xData, x, incX) { + t.Errorf("%v: modified read-only x argument", prefix) + } + if nonStridedWrite(y, incY) || !equalStrided(test.yData, y, incY) { + t.Errorf("%v: modified read-only y argument", prefix) + } + if math.IsNaN(got) { + t.Errorf("%v: invalid memory read", prefix) + continue + } + + want := test.want + if incX*incY < 0 { + want = test.wantRev + } + if got != want { + t.Errorf("%v: unexpected result. want %v, got %v", prefix, want, got) + } + } + } + } +} + +func BenchmarkDotUnitaryN1(b *testing.B) { dotUnitaryBenchmark(b, 1) } +func BenchmarkDotUnitaryN2(b *testing.B) { dotUnitaryBenchmark(b, 2) } +func BenchmarkDotUnitaryN3(b *testing.B) { dotUnitaryBenchmark(b, 3) } +func BenchmarkDotUnitaryN4(b *testing.B) { dotUnitaryBenchmark(b, 4) } +func BenchmarkDotUnitaryN10(b *testing.B) { dotUnitaryBenchmark(b, 10) } +func BenchmarkDotUnitaryN100(b *testing.B) { dotUnitaryBenchmark(b, 100) } +func BenchmarkDotUnitaryN1000(b *testing.B) { dotUnitaryBenchmark(b, 1000) } +func BenchmarkDotUnitaryN10000(b *testing.B) { dotUnitaryBenchmark(b, 10000) } +func BenchmarkDotUnitaryN100000(b *testing.B) { dotUnitaryBenchmark(b, 100000) } + +var r float64 + +func dotUnitaryBenchmark(b *testing.B, n int) { + x := make([]float64, n) + for i := range x { + x[i] = rand.Float64() + } + y := make([]float64, n) + for i := range y { + y[i] = rand.Float64() + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + r = DotUnitary(x, y) + } +} + +func BenchmarkDotIncN1Inc1(b *testing.B) { dotIncBenchmark(b, 1, 1) } + +func BenchmarkDotIncN2Inc1(b *testing.B) { dotIncBenchmark(b, 2, 1) } +func BenchmarkDotIncN2Inc2(b *testing.B) { dotIncBenchmark(b, 2, 2) } +func BenchmarkDotIncN2Inc4(b *testing.B) { dotIncBenchmark(b, 2, 4) } +func BenchmarkDotIncN2Inc10(b *testing.B) { dotIncBenchmark(b, 2, 10) } + +func BenchmarkDotIncN3Inc1(b *testing.B) { dotIncBenchmark(b, 3, 1) } +func BenchmarkDotIncN3Inc2(b *testing.B) { dotIncBenchmark(b, 3, 2) } +func BenchmarkDotIncN3Inc4(b *testing.B) { dotIncBenchmark(b, 3, 4) } +func BenchmarkDotIncN3Inc10(b *testing.B) { dotIncBenchmark(b, 3, 10) } + +func BenchmarkDotIncN4Inc1(b *testing.B) { dotIncBenchmark(b, 4, 1) } +func BenchmarkDotIncN4Inc2(b *testing.B) { dotIncBenchmark(b, 4, 2) } +func BenchmarkDotIncN4Inc4(b *testing.B) { dotIncBenchmark(b, 4, 4) } +func BenchmarkDotIncN4Inc10(b *testing.B) { dotIncBenchmark(b, 4, 10) } + +func BenchmarkDotIncN10Inc1(b *testing.B) { dotIncBenchmark(b, 10, 1) } +func BenchmarkDotIncN10Inc2(b *testing.B) { dotIncBenchmark(b, 10, 2) } +func BenchmarkDotIncN10Inc4(b *testing.B) { dotIncBenchmark(b, 10, 4) } +func BenchmarkDotIncN10Inc10(b *testing.B) { dotIncBenchmark(b, 10, 10) } + +func BenchmarkDotIncN1000Inc1(b *testing.B) { dotIncBenchmark(b, 1000, 1) } +func BenchmarkDotIncN1000Inc2(b *testing.B) { dotIncBenchmark(b, 1000, 2) } +func BenchmarkDotIncN1000Inc4(b *testing.B) { dotIncBenchmark(b, 1000, 4) } +func BenchmarkDotIncN1000Inc10(b *testing.B) { dotIncBenchmark(b, 1000, 10) } + +func BenchmarkDotIncN100000Inc1(b *testing.B) { dotIncBenchmark(b, 100000, 1) } +func BenchmarkDotIncN100000Inc2(b *testing.B) { dotIncBenchmark(b, 100000, 2) } +func BenchmarkDotIncN100000Inc4(b *testing.B) { dotIncBenchmark(b, 100000, 4) } +func BenchmarkDotIncN100000Inc10(b *testing.B) { dotIncBenchmark(b, 100000, 10) } + +func BenchmarkDotIncN100000IncM1(b *testing.B) { dotIncBenchmark(b, 100000, -1) } +func BenchmarkDotIncN100000IncM2(b *testing.B) { dotIncBenchmark(b, 100000, -2) } +func BenchmarkDotIncN100000IncM4(b *testing.B) { dotIncBenchmark(b, 100000, -4) } +func BenchmarkDotIncN100000IncM10(b *testing.B) { dotIncBenchmark(b, 100000, -10) } + +func dotIncBenchmark(b *testing.B, n, inc int) { + absInc := inc + if inc < 0 { + absInc = -inc + } + x := make([]float64, (n-1)*absInc+1) + for i := range x { + x[i] = rand.Float64() + } + y := make([]float64, (n-1)*absInc+1) + for i := range y { + y[i] = rand.Float64() + } + var ini int + if inc < 0 { + ini = (-n + 1) * inc + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + r = DotInc(x, y, uintptr(n), uintptr(inc), uintptr(inc), uintptr(ini), uintptr(ini)) + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/l1norm_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/l1norm_amd64.s new file mode 100644 index 00000000..2a8c5a38 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/l1norm_amd64.s @@ -0,0 +1,58 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func L1Dist(s, t []float64) float64 +TEXT ·L1Dist(SB), NOSPLIT, $0 + MOVQ s_base+0(FP), DI // DI = &s + MOVQ t_base+24(FP), SI // SI = &t + MOVQ s_len+8(FP), CX // CX = len(s) + CMPQ t_len+32(FP), CX // CX = max( CX, len(t) ) + CMOVQLE t_len+32(FP), CX + PXOR X3, X3 // norm = 0 + CMPQ CX, $0 // if CX == 0 { return 0 } + JE l1_end + XORQ AX, AX // i = 0 + MOVQ CX, BX + ANDQ $1, BX // BX = CX % 2 + SHRQ $1, CX // CX = floor( CX / 2 ) + JZ l1_tail_start // if CX == 0 { return 0 } + +l1_loop: // Loop unrolled 2x do { + MOVUPS (SI)(AX*8), X0 // X0 = t[i:i+1] + MOVUPS (DI)(AX*8), X1 // X1 = s[i:i+1] + MOVAPS X0, X2 + SUBPD X1, X0 + SUBPD X2, X1 + MAXPD X1, X0 // X0 = max( X0 - X1, X1 - X0 ) + ADDPD X0, X3 // norm += X0 + ADDQ $2, AX // i += 2 + LOOP l1_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE l1_end + +l1_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + PXOR X0, X0 // reset X0, X1 to break dependencies + PXOR X1, X1 + +l1_tail: + MOVSD (SI)(AX*8), X0 // X0 = t[i] + MOVSD (DI)(AX*8), X1 // x1 = s[i] + MOVAPD X0, X2 + SUBSD X1, X0 + SUBSD X2, X1 + MAXSD X1, X0 // X0 = max( X0 - X1, X1 - X0 ) + ADDSD X0, X3 // norm += X0 + +l1_end: + MOVAPS X3, X2 + SHUFPD $1, X2, X2 + ADDSD X3, X2 // X2 = X3[1] + X3[0] + MOVSD X2, ret+48(FP) // return X2 + RET + diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/linfnorm_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/linfnorm_amd64.s new file mode 100644 index 00000000..fb6ef8d2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/linfnorm_amd64.s @@ -0,0 +1,57 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !noasm,!appengine + +#include "textflag.h" + +// func LinfDist(s, t []float64) float64 +TEXT ·LinfDist(SB), NOSPLIT, $0 + MOVQ s_base+0(FP), DI // DI = &s + MOVQ t_base+24(FP), SI // SI = &t + MOVQ s_len+8(FP), CX // CX = len(s) + CMPQ t_len+32(FP), CX // CX = max( CX, len(t) ) + CMOVQLE t_len+32(FP), CX + PXOR X3, X3 // norm = 0 + CMPQ CX, $0 // if CX == 0 { return 0 } + JE l1_end + XORQ AX, AX // i = 0 + MOVQ CX, BX + ANDQ $1, BX // BX = CX % 2 + SHRQ $1, CX // CX = floor( CX / 2 ) + JZ l1_tail_start // if CX == 0 { return 0 } + +l1_loop: // Loop unrolled 2x do { + MOVUPS (SI)(AX*8), X0 // X0 = t[i:i+1] + MOVUPS (DI)(AX*8), X1 // X1 = s[i:i+1] + MOVAPS X0, X2 + SUBPD X1, X0 + SUBPD X2, X1 + MAXPD X1, X0 // X0 = max( X0 - X1, X1 - X0 ) + MAXPD X0, X3 // norm = max( norm, X0 ) + ADDQ $2, AX // i += 2 + LOOP l1_loop // } while --CX > 0 + CMPQ BX, $0 // if BX == 0 { return } + JE l1_end + +l1_tail_start: // Reset loop registers + MOVQ BX, CX // Loop counter: CX = BX + PXOR X0, X0 // reset X0, X1 to break dependencies + PXOR X1, X1 + +l1_tail: + MOVSD (SI)(AX*8), X0 // X0 = t[i] + MOVSD (DI)(AX*8), X1 // X1 = s[i] + MOVAPD X0, X2 + SUBSD X1, X0 + SUBSD X2, X1 + MAXSD X1, X0 // X0 = max( X0 - X1, X1 - X0 ) + MAXSD X0, X3 // norm = max( norm, X0 ) + +l1_end: + MOVAPS X3, X2 + SHUFPD $1, X2, X2 + MAXSD X3, X2 // X2 = max( X3[1], X3[0] ) + MOVSD X2, ret+48(FP) // return X2 + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/scal.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/scal.go new file mode 100644 index 00000000..357e6c4a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/scal.go @@ -0,0 +1,57 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !amd64 noasm appengine + +package f64 + +// ScalUnitary is +// for i := range x { +// x[i] *= alpha +// } +func ScalUnitary(alpha float64, x []float64) { + for i := range x { + x[i] *= alpha + } +} + +// ScalUnitaryTo is +// for i, v := range x { +// dst[i] = alpha * v +// } +func ScalUnitaryTo(dst []float64, alpha float64, x []float64) { + for i, v := range x { + dst[i] = alpha * v + } +} + +// ScalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] *= alpha +// ix += incX +// } +func ScalInc(alpha float64, x []float64, n, incX uintptr) { + var ix uintptr + for i := 0; i < int(n); i++ { + x[ix] *= alpha + ix += incX + } +} + +// ScalIncTo is +// var idst, ix uintptr +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha * x[ix] +// ix += incX +// idst += incDst +// } +func ScalIncTo(dst []float64, incDst uintptr, alpha float64, x []float64, n, incX uintptr) { + var idst, ix uintptr + for i := 0; i < int(n); i++ { + dst[idst] = alpha * x[ix] + ix += incX + idst += incDst + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/scal_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/scal_test.go new file mode 100644 index 00000000..d88b7d10 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/scal_test.go @@ -0,0 +1,179 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package f64 + +import ( + "fmt" + "math/rand" + "testing" +) + +var scalTests = []struct { + alpha float64 + x []float64 + want []float64 +}{ + { + alpha: 0, + x: []float64{}, + want: []float64{}, + }, + { + alpha: 0, + x: []float64{1}, + want: []float64{0}, + }, + { + alpha: 1, + x: []float64{1}, + want: []float64{1}, + }, + { + alpha: 2, + x: []float64{1, -2}, + want: []float64{2, -4}, + }, + { + alpha: 2, + x: []float64{1, -2, 3}, + want: []float64{2, -4, 6}, + }, + { + alpha: 2, + x: []float64{1, -2, 3, 4}, + want: []float64{2, -4, 6, 8}, + }, + { + alpha: 2, + x: []float64{1, -2, 3, 4, -5}, + want: []float64{2, -4, 6, 8, -10}, + }, + { + alpha: 2, + x: []float64{0, 1, -2, 3, 4, -5, 6, -7}, + want: []float64{0, 2, -4, 6, 8, -10, 12, -14}, + }, + { + alpha: 2, + x: []float64{0, 1, -2, 3, 4, -5, 6, -7, 8}, + want: []float64{0, 2, -4, 6, 8, -10, 12, -14, 16}, + }, + { + alpha: 2, + x: []float64{0, 1, -2, 3, 4, -5, 6, -7, 8, 9}, + want: []float64{0, 2, -4, 6, 8, -10, 12, -14, 16, 18}, + }, + { + alpha: 3, + x: []float64{0, 1, -2, 3, 4, -5, 6, -7, 8, 9, 12}, + want: []float64{0, 3, -6, 9, 12, -15, 18, -21, 24, 27, 36}, + }, +} + +func TestScalUnitary(t *testing.T) { + const xGdVal = -0.5 + for i, test := range scalTests { + for _, align := range align1 { + prefix := fmt.Sprintf("Test %v (x:%v)", i, align) + xgLn := 4 + align + xg := guardVector(test.x, xGdVal, xgLn) + x := xg[xgLn : len(xg)-xgLn] + + ScalUnitary(test.alpha, x) + + for i := range test.want { + if !same(x[i], test.want[i]) { + t.Errorf(msgVal, prefix, i, x[i], test.want[i]) + } + } + if !isValidGuard(xg, xGdVal, xgLn) { + t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) + } + } + } +} + +func TestScalUnitaryTo(t *testing.T) { + const xGdVal, dstGdVal = -1, 0.5 + rng := rand.New(rand.NewSource(42)) + for i, test := range scalTests { + n := len(test.x) + for _, align := range align2 { + prefix := fmt.Sprintf("Test %v (x:%v dst:%v)", i, align.x, align.y) + xgLn, dgLn := 4+align.x, 4+align.y + xg := guardVector(test.x, xGdVal, xgLn) + dg := guardVector(randSlice(n, 1, rng), dstGdVal, dgLn) + x, dst := xg[xgLn:len(xg)-xgLn], dg[dgLn:len(dg)-dgLn] + + ScalUnitaryTo(dst, test.alpha, x) + + for i := range test.want { + if !same(dst[i], test.want[i]) { + t.Errorf(msgVal, prefix, i, dst[i], test.want[i]) + } + } + if !isValidGuard(xg, xGdVal, xgLn) { + t.Errorf(msgGuard, prefix, "x", xg[:xgLn], xg[len(xg)-xgLn:]) + } + if !isValidGuard(dg, dstGdVal, dgLn) { + t.Errorf(msgGuard, prefix, "y", dg[:dgLn], dg[len(dg)-dgLn:]) + } + if !equalStrided(test.x, x, 1) { + t.Errorf("%v: modified read-only x argument", prefix) + } + } + } +} + +func TestScalInc(t *testing.T) { + const xGdVal = -0.5 + gdLn := 4 + for i, test := range scalTests { + n := len(test.x) + for _, incX := range []int{1, 2, 3, 4, 7, 10} { + prefix := fmt.Sprintf("Test %v (x:%v)", i, incX) + xg := guardIncVector(test.x, xGdVal, incX, gdLn) + x := xg[gdLn : len(xg)-gdLn] + + ScalInc(test.alpha, x, uintptr(n), uintptr(incX)) + + for i := range test.want { + if !same(x[i*incX], test.want[i]) { + t.Errorf(msgVal, prefix, i, x[i*incX], test.want[i]) + } + } + checkValidIncGuard(t, xg, xGdVal, incX, gdLn) + } + } +} + +func TestScalIncTo(t *testing.T) { + const xGdVal, dstGdVal = -1, 0.5 + gdLn := 4 + rng := rand.New(rand.NewSource(42)) + for i, test := range scalTests { + n := len(test.x) + for _, inc := range newIncSet(1, 2, 3, 4, 7, 10) { + prefix := fmt.Sprintf("test %v (x:%v dst:%v)", i, inc.x, inc.y) + xg := guardIncVector(test.x, xGdVal, inc.x, gdLn) + dg := guardIncVector(randSlice(n, 1, rng), dstGdVal, inc.y, gdLn) + x, dst := xg[gdLn:len(xg)-gdLn], dg[gdLn:len(dg)-gdLn] + + ScalIncTo(dst, uintptr(inc.y), test.alpha, x, uintptr(n), uintptr(inc.x)) + + for i := range test.want { + if !same(dst[i*inc.y], test.want[i]) { + t.Errorf(msgVal, prefix, i, dst[i*inc.y], test.want[i]) + } + } + checkValidIncGuard(t, xg, xGdVal, inc.x, gdLn) + checkValidIncGuard(t, dg, dstGdVal, inc.y, gdLn) + if !equalStrided(test.x, x, inc.x) { + t.Errorf("%v: modified read-only x argument", prefix) + } + + } + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/scalinc_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalinc_amd64.s new file mode 100644 index 00000000..55a5758e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalinc_amd64.s @@ -0,0 +1,113 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define X_PTR SI +#define LEN CX +#define TAIL BX +#define INC_X R8 +#define INCx3_X R9 +#define ALPHA X0 +#define ALPHA_2 X1 + +// func ScalInc(alpha float64, x []float64, n, incX uintptr) +TEXT ·ScalInc(SB), NOSPLIT, $0 + MOVSD alpha+0(FP), ALPHA // ALPHA = alpha + MOVQ x_base+8(FP), X_PTR // X_PTR = &x + MOVQ incX+40(FP), INC_X // INC_X = incX + SHLQ $3, INC_X // INC_X *= sizeof(float64) + MOVQ n+32(FP), LEN // LEN = n + CMPQ LEN, $0 + JE end // if LEN == 0 { return } + + MOVQ LEN, TAIL + ANDQ $3, TAIL // TAIL = LEN % 4 + SHRQ $2, LEN // LEN = floor( LEN / 4 ) + JZ tail_start // if LEN == 0 { goto tail_start } + + MOVUPS ALPHA, ALPHA_2 // ALPHA_2 = ALPHA for pipelining + LEAQ (INC_X)(INC_X*2), INCx3_X // INCx3_X = INC_X * 3 + +loop: // do { // x[i] *= alpha unrolled 4x. + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MOVSD (X_PTR)(INC_X*2), X4 + MOVSD (X_PTR)(INCx3_X*1), X5 + + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA_2, X3 + MULSD ALPHA, X4 + MULSD ALPHA_2, X5 + + MOVSD X2, (X_PTR) // x[i] = X_i + MOVSD X3, (X_PTR)(INC_X*1) + MOVSD X4, (X_PTR)(INC_X*2) + MOVSD X5, (X_PTR)(INCx3_X*1) + + LEAQ (X_PTR)(INC_X*4), X_PTR // X_PTR = &(X_PTR[incX*4]) + DECQ LEN + JNZ loop // } while --LEN > 0 + CMPQ TAIL, $0 + JE end // if TAIL == 0 { return } + +tail_start: // Reset loop registers + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( LEN / 2 ) + JZ tail_one + +tail_two: // do { + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA, X3 + MOVSD X2, (X_PTR) // x[i] = X_i + MOVSD X3, (X_PTR)(INC_X*1) + + LEAQ (X_PTR)(INC_X*2), X_PTR // X_PTR = &(X_PTR[incX*2]) + + ANDQ $1, TAIL + JZ end + +tail_one: + MOVSD (X_PTR), X2 // X_i = x[i] + MULSD ALPHA, X2 // X_i *= ALPHA + MOVSD X2, (X_PTR) // x[i] = X_i + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/scalincto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalincto_amd64.s new file mode 100644 index 00000000..57c90a2a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalincto_amd64.s @@ -0,0 +1,122 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define X_PTR SI +#define DST_PTR DI +#define LEN CX +#define TAIL BX +#define INC_X R8 +#define INCx3_X R9 +#define INC_DST R10 +#define INCx3_DST R11 +#define ALPHA X0 +#define ALPHA_2 X1 + +// func ScalIncTo(dst []float64, incDst uintptr, alpha float64, x []float64, n, incX uintptr) +TEXT ·ScalIncTo(SB), NOSPLIT, $0 + MOVQ dst_base+0(FP), DST_PTR // DST_PTR = &dst + MOVQ incDst+24(FP), INC_DST // INC_DST = incDst + SHLQ $3, INC_DST // INC_DST *= sizeof(float64) + MOVSD alpha+32(FP), ALPHA // ALPHA = alpha + MOVQ x_base+40(FP), X_PTR // X_PTR = &x + MOVQ n+64(FP), LEN // LEN = n + MOVQ incX+72(FP), INC_X // INC_X = incX + SHLQ $3, INC_X // INC_X *= sizeof(float64) + CMPQ LEN, $0 + JE end // if LEN == 0 { return } + + MOVQ LEN, TAIL + ANDQ $3, TAIL // TAIL = LEN % 4 + SHRQ $2, LEN // LEN = floor( LEN / 4 ) + JZ tail_start // if LEN == 0 { goto tail_start } + + MOVUPS ALPHA, ALPHA_2 // ALPHA_2 = ALPHA for pipelining + LEAQ (INC_X)(INC_X*2), INCx3_X // INCx3_X = INC_X * 3 + LEAQ (INC_DST)(INC_DST*2), INCx3_DST // INCx3_DST = INC_DST * 3 + +loop: // do { // x[i] *= alpha unrolled 4x. + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MOVSD (X_PTR)(INC_X*2), X4 + MOVSD (X_PTR)(INCx3_X*1), X5 + + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA_2, X3 + MULSD ALPHA, X4 + MULSD ALPHA_2, X5 + + MOVSD X2, (DST_PTR) // dst[i] = X_i + MOVSD X3, (DST_PTR)(INC_DST*1) + MOVSD X4, (DST_PTR)(INC_DST*2) + MOVSD X5, (DST_PTR)(INCx3_DST*1) + + LEAQ (X_PTR)(INC_X*4), X_PTR // X_PTR = &(X_PTR[incX*4]) + LEAQ (DST_PTR)(INC_DST*4), DST_PTR // DST_PTR = &(DST_PTR[incDst*4]) + DECQ LEN + JNZ loop // } while --LEN > 0 + CMPQ TAIL, $0 + JE end // if TAIL == 0 { return } + +tail_start: // Reset loop registers + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( LEN / 2 ) + JZ tail_one + +tail_two: + MOVSD (X_PTR), X2 // X_i = x[i] + MOVSD (X_PTR)(INC_X*1), X3 + MULSD ALPHA, X2 // X_i *= a + MULSD ALPHA, X3 + MOVSD X2, (DST_PTR) // dst[i] = X_i + MOVSD X3, (DST_PTR)(INC_DST*1) + + LEAQ (X_PTR)(INC_X*2), X_PTR // X_PTR = &(X_PTR[incX*2]) + LEAQ (DST_PTR)(INC_DST*2), DST_PTR // DST_PTR = &(DST_PTR[incDst*2]) + + ANDQ $1, TAIL + JZ end + +tail_one: + MOVSD (X_PTR), X2 // X_i = x[i] + MULSD ALPHA, X2 // X_i *= ALPHA + MOVSD X2, (DST_PTR) // x[i] = X_i + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/scalunitary_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalunitary_amd64.s new file mode 100644 index 00000000..da23af77 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalunitary_amd64.s @@ -0,0 +1,112 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define MOVDDUP_ALPHA LONG $0x44120FF2; WORD $0x0824 // @ MOVDDUP XMM0, 8[RSP] + +#define X_PTR SI +#define DST_PTR DI +#define IDX AX +#define LEN CX +#define TAIL BX +#define ALPHA X0 +#define ALPHA_2 X1 + +// func ScalUnitary(alpha float64, x []float64) +TEXT ·ScalUnitary(SB), NOSPLIT, $0 + MOVDDUP_ALPHA // ALPHA = { alpha, alpha } + MOVQ x_base+8(FP), X_PTR // X_PTR = &x + MOVQ x_len+16(FP), LEN // LEN = len(x) + CMPQ LEN, $0 + JE end // if LEN == 0 { return } + XORQ IDX, IDX // IDX = 0 + + MOVQ LEN, TAIL + ANDQ $7, TAIL // TAIL = LEN % 8 + SHRQ $3, LEN // LEN = floor( LEN / 8 ) + JZ tail_start // if LEN == 0 { goto tail_start } + + MOVUPS ALPHA, ALPHA_2 + +loop: // do { // x[i] *= alpha unrolled 8x. + MOVUPS (X_PTR)(IDX*8), X2 // X_i = x[i] + MOVUPS 16(X_PTR)(IDX*8), X3 + MOVUPS 32(X_PTR)(IDX*8), X4 + MOVUPS 48(X_PTR)(IDX*8), X5 + + MULPD ALPHA, X2 // X_i *= ALPHA + MULPD ALPHA_2, X3 + MULPD ALPHA, X4 + MULPD ALPHA_2, X5 + + MOVUPS X2, (X_PTR)(IDX*8) // x[i] = X_i + MOVUPS X3, 16(X_PTR)(IDX*8) + MOVUPS X4, 32(X_PTR)(IDX*8) + MOVUPS X5, 48(X_PTR)(IDX*8) + + ADDQ $8, IDX // i += 8 + DECQ LEN + JNZ loop // while --LEN > 0 + CMPQ TAIL, $0 + JE end // if TAIL == 0 { return } + +tail_start: // Reset loop registers + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( TAIL / 2 ) + JZ tail_one // if n == 0 goto end + +tail_two: // do { + MOVUPS (X_PTR)(IDX*8), X2 // X_i = x[i] + MULPD ALPHA, X2 // X_i *= ALPHA + MOVUPS X2, (X_PTR)(IDX*8) // x[i] = X_i + ADDQ $2, IDX // i += 2 + DECQ LEN + JNZ tail_two // while --LEN > 0 + + ANDQ $1, TAIL + JZ end // if TAIL == 0 { return } + +tail_one: + // x[i] *= alpha for the remaining element. + MOVSD (X_PTR)(IDX*8), X2 + MULSD ALPHA, X2 + MOVSD X2, (X_PTR)(IDX*8) + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/scalunitaryto_amd64.s b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalunitaryto_amd64.s new file mode 100644 index 00000000..3685d5b5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/scalunitaryto_amd64.s @@ -0,0 +1,113 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// Some of the loop unrolling code is copied from: +// http://golang.org/src/math/big/arith_amd64.s +// which is distributed under these terms: +// +// Copyright (c) 2012 The Go 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 Google Inc. nor the names of its +// 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 +// OWNER 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. + +//+build !noasm,!appengine + +#include "textflag.h" + +#define MOVDDUP_ALPHA LONG $0x44120FF2; WORD $0x2024 // @ MOVDDUP 32(SP), X0 /*XMM0, 32[RSP]*/ + +#define X_PTR SI +#define DST_PTR DI +#define IDX AX +#define LEN CX +#define TAIL BX +#define ALPHA X0 +#define ALPHA_2 X1 + +// func ScalUnitaryTo(dst []float64, alpha float64, x []float64) +// This function assumes len(dst) >= len(x). +TEXT ·ScalUnitaryTo(SB), NOSPLIT, $0 + MOVQ x_base+32(FP), X_PTR // X_PTR = &x + MOVQ dst_base+0(FP), DST_PTR // DST_PTR = &dst + MOVDDUP_ALPHA // ALPHA = { alpha, alpha } + MOVQ x_len+40(FP), LEN // LEN = len(x) + CMPQ LEN, $0 + JE end // if LEN == 0 { return } + + XORQ IDX, IDX // IDX = 0 + MOVQ LEN, TAIL + ANDQ $7, TAIL // TAIL = LEN % 8 + SHRQ $3, LEN // LEN = floor( LEN / 8 ) + JZ tail_start // if LEN == 0 { goto tail_start } + + MOVUPS ALPHA, ALPHA_2 // ALPHA_2 = ALPHA for pipelining + +loop: // do { // dst[i] = alpha * x[i] unrolled 8x. + MOVUPS (X_PTR)(IDX*8), X2 // X_i = x[i] + MOVUPS 16(X_PTR)(IDX*8), X3 + MOVUPS 32(X_PTR)(IDX*8), X4 + MOVUPS 48(X_PTR)(IDX*8), X5 + + MULPD ALPHA, X2 // X_i *= ALPHA + MULPD ALPHA_2, X3 + MULPD ALPHA, X4 + MULPD ALPHA_2, X5 + + MOVUPS X2, (DST_PTR)(IDX*8) // dst[i] = X_i + MOVUPS X3, 16(DST_PTR)(IDX*8) + MOVUPS X4, 32(DST_PTR)(IDX*8) + MOVUPS X5, 48(DST_PTR)(IDX*8) + + ADDQ $8, IDX // i += 8 + DECQ LEN + JNZ loop // while --LEN > 0 + CMPQ TAIL, $0 + JE end // if TAIL == 0 { return } + +tail_start: // Reset loop counters + MOVQ TAIL, LEN // Loop counter: LEN = TAIL + SHRQ $1, LEN // LEN = floor( TAIL / 2 ) + JZ tail_one // if LEN == 0 { goto tail_one } + +tail_two: // do { + MOVUPS (X_PTR)(IDX*8), X2 // X_i = x[i] + MULPD ALPHA, X2 // X_i *= ALPHA + MOVUPS X2, (DST_PTR)(IDX*8) // dst[i] = X_i + ADDQ $2, IDX // i += 2 + DECQ LEN + JNZ tail_two // while --LEN > 0 + + ANDQ $1, TAIL + JZ end // if TAIL == 0 { return } + +tail_one: + MOVSD (X_PTR)(IDX*8), X2 // X_i = x[i] + MULSD ALPHA, X2 // X_i *= ALPHA + MOVSD X2, (DST_PTR)(IDX*8) // dst[i] = X_i + +end: + RET diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_amd64.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_amd64.go new file mode 100644 index 00000000..d4de1919 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_amd64.go @@ -0,0 +1,165 @@ +// 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. + +//+build !noasm,!appengine + +package f64 + +// L1Norm is +// for _, v := range x { +// sum += math.Abs(v) +// } +// return sum +func L1Norm(x []float64) (sum float64) + +// L1NormInc is +// for i := 0; i < n*incX; i += incX { +// sum += math.Abs(x[i]) +// } +// return sum +func L1NormInc(x []float64, n, incX int) (sum float64) + +// AddConst is +// for i := range x { +// x[i] += alpha +// } +func AddConst(alpha float64, x []float64) + +// Add is +// for i, v := range s { +// dst[i] += v +// } +func Add(dst, s []float64) + +// AxpyUnitary is +// for i, v := range x { +// y[i] += alpha * v +// } +func AxpyUnitary(alpha float64, x, y []float64) + +// AxpyUnitaryTo is +// for i, v := range x { +// dst[i] = alpha*v + y[i] +// } +func AxpyUnitaryTo(dst []float64, alpha float64, x, y []float64) + +// AxpyInc is +// for i := 0; i < int(n); i++ { +// y[iy] += alpha * x[ix] +// ix += incX +// iy += incY +// } +func AxpyInc(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) + +// AxpyIncTo is +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha*x[ix] + y[iy] +// ix += incX +// iy += incY +// idst += incDst +// } +func AxpyIncTo(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) + +// CumSum is +// if len(s) == 0 { +// return dst +// } +// dst[0] = s[0] +// for i, v := range s[1:] { +// dst[i+1] = dst[i] + v +// } +// return dst +func CumSum(dst, s []float64) []float64 + +// CumProd is +// if len(s) == 0 { +// return dst +// } +// dst[0] = s[0] +// for i, v := range s[1:] { +// dst[i+1] = dst[i] * v +// } +// return dst +func CumProd(dst, s []float64) []float64 + +// Div is +// for i, v := range s { +// dst[i] /= v +// } +func Div(dst, s []float64) + +// DivTo is +// for i, v := range s { +// dst[i] = v / t[i] +// } +// return dst +func DivTo(dst, x, y []float64) []float64 + +// DotUnitary is +// for i, v := range x { +// sum += y[i] * v +// } +// return sum +func DotUnitary(x, y []float64) (sum float64) + +// DotInc is +// for i := 0; i < int(n); i++ { +// sum += y[iy] * x[ix] +// ix += incX +// iy += incY +// } +// return sum +func DotInc(x, y []float64, n, incX, incY, ix, iy uintptr) (sum float64) + +// L1Dist is +// var norm float64 +// for i, v := range s { +// norm += math.Abs(t[i] - v) +// } +// return norm +func L1Dist(s, t []float64) float64 + +// LinfDist is +// var norm float64 +// if len(s) == 0 { +// return 0 +// } +// norm = math.Abs(t[0] - s[0]) +// for i, v := range s[1:] { +// absDiff := math.Abs(t[i+1] - v) +// if absDiff > norm || math.IsNaN(norm) { +// norm = absDiff +// } +// } +// return norm +func LinfDist(s, t []float64) float64 + +// ScalUnitary is +// for i := range x { +// x[i] *= alpha +// } +func ScalUnitary(alpha float64, x []float64) + +// ScalUnitaryTo is +// for i, v := range x { +// dst[i] = alpha * v +// } +func ScalUnitaryTo(dst []float64, alpha float64, x []float64) + +// ScalInc is +// var ix uintptr +// for i := 0; i < int(n); i++ { +// x[ix] *= alpha +// ix += incX +// } +func ScalInc(alpha float64, x []float64, n, incX uintptr) + +// ScalIncTo is +// var idst, ix uintptr +// for i := 0; i < int(n); i++ { +// dst[idst] = alpha * x[ix] +// ix += incX +// idst += incDst +// } +func ScalIncTo(dst []float64, incDst uintptr, alpha float64, x []float64, n, incX uintptr) diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_noasm.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_noasm.go new file mode 100644 index 00000000..5e4ae69c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_noasm.go @@ -0,0 +1,157 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//+build !amd64 noasm appengine + +package f64 + +import "math" + +// L1Norm is +// for _, v := range x { +// sum += math.Abs(v) +// } +// return sum +func L1Norm(x []float64) (sum float64) { + for _, v := range x { + sum += math.Abs(v) + } + return sum +} + +// L1NormInc is +// for i := 0; i < n*incX; i += incX { +// sum += math.Abs(x[i]) +// } +// return sum +func L1NormInc(x []float64, n, incX int) (sum float64) { + for i := 0; i < n*incX; i += incX { + sum += math.Abs(x[i]) + } + return sum +} + +// Add is +// for i, v := range s { +// dst[i] += v +// } +func Add(dst, s []float64) { + for i, v := range s { + dst[i] += v + } +} + +// AddConst is +// for i := range x { +// x[i] += alpha +// } +func AddConst(alpha float64, x []float64) { + for i := range x { + x[i] += alpha + } +} + +// CumSum is +// if len(s) == 0 { +// return dst +// } +// dst[0] = s[0] +// for i, v := range s[1:] { +// dst[i+1] = dst[i] + v +// } +// return dst +func CumSum(dst, s []float64) []float64 { + if len(s) == 0 { + return dst + } + dst[0] = s[0] + for i, v := range s[1:] { + dst[i+1] = dst[i] + v + } + return dst +} + +// CumProd is +// if len(s) == 0 { +// return dst +// } +// dst[0] = s[0] +// for i, v := range s[1:] { +// dst[i+1] = dst[i] * v +// } +// return dst +func CumProd(dst, s []float64) []float64 { + if len(s) == 0 { + return dst + } + dst[0] = s[0] + for i, v := range s[1:] { + dst[i+1] = dst[i] * v + } + return dst +} + +// Div is +// for i, v := range s { +// dst[i] /= v +// } +func Div(dst, s []float64) { + for i, v := range s { + dst[i] /= v + } +} + +// DivTo is +// for i, v := range s { +// dst[i] = v / t[i] +// } +// return dst +func DivTo(dst, s, t []float64) []float64 { + for i, v := range s { + dst[i] = v / t[i] + } + return dst +} + +// L1Dist is +// var norm float64 +// for i, v := range s { +// norm += math.Abs(t[i] - v) +// } +// return norm +func L1Dist(s, t []float64) float64 { + var norm float64 + for i, v := range s { + norm += math.Abs(t[i] - v) + } + return norm +} + +// LinfDist is +// var norm float64 +// if len(s) == 0 { +// return 0 +// } +// norm = math.Abs(t[0] - s[0]) +// for i, v := range s[1:] { +// absDiff := math.Abs(t[i+1] - v) +// if absDiff > norm || math.IsNaN(norm) { +// norm = absDiff +// } +// } +// return norm +func LinfDist(s, t []float64) float64 { + var norm float64 + if len(s) == 0 { + return 0 + } + norm = math.Abs(t[0] - s[0]) + for i, v := range s[1:] { + absDiff := math.Abs(t[i+1] - v) + if absDiff > norm || math.IsNaN(norm) { + norm = absDiff + } + } + return norm +} diff --git a/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_test.go b/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_test.go new file mode 100644 index 00000000..6dd949fc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/asm/f64/stubs_test.go @@ -0,0 +1,574 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package f64 + +import "testing" + +func TestL1Norm(t *testing.T) { + var src_gd float64 = 1 + for j, v := range []struct { + want float64 + x []float64 + }{ + {want: 0, x: []float64{}}, + {want: 2, x: []float64{2}}, + {want: 6, x: []float64{1, 2, 3}}, + {want: 6, x: []float64{-1, -2, -3}}, + {want: nan, x: []float64{nan}}, + {want: 40, x: []float64{8, -8, 8, -8, 8}}, + {want: 5, x: []float64{0, 1, 0, -1, 0, 1, 0, -1, 0, 1}}, + } { + g_ln := 4 + j%2 + v.x = guardVector(v.x, src_gd, g_ln) + src := v.x[g_ln : len(v.x)-g_ln] + ret := L1Norm(src) + if !same(ret, v.want) { + t.Errorf("Test %d L1Norm error Got: %f Expected: %f", j, ret, v.want) + } + if !isValidGuard(v.x, src_gd, g_ln) { + t.Errorf("Test %d Guard violated in src vector %v %v", j, v.x[:g_ln], v.x[len(v.x)-g_ln:]) + } + } +} + +func TestL1NormInc(t *testing.T) { + var src_gd float64 = 1 + for j, v := range []struct { + inc int + want float64 + x []float64 + }{ + {inc: 2, want: 0, x: []float64{}}, + {inc: 3, want: 2, x: []float64{2}}, + {inc: 10, want: 6, x: []float64{1, 2, 3}}, + {inc: 5, want: 6, x: []float64{-1, -2, -3}}, + {inc: 3, want: nan, x: []float64{nan}}, + {inc: 15, want: 40, x: []float64{8, -8, 8, -8, 8}}, + {inc: 1, want: 5, x: []float64{0, 1, 0, -1, 0, 1, 0, -1, 0, 1}}, + } { + g_ln, ln := 4+j%2, len(v.x) + v.x = guardIncVector(v.x, src_gd, v.inc, g_ln) + src := v.x[g_ln : len(v.x)-g_ln] + ret := L1NormInc(src, ln, v.inc) + if !same(ret, v.want) { + t.Errorf("Test %d L1NormInc error Got: %f Expected: %f", j, ret, v.want) + } + checkValidIncGuard(t, v.x, src_gd, v.inc, g_ln) + } +} + +func TestAdd(t *testing.T) { + var src_gd, dst_gd float64 = 1, 0 + for j, v := range []struct { + dst, src, expect []float64 + }{ + { + dst: []float64{1}, + src: []float64{0}, + expect: []float64{1}, + }, + { + dst: []float64{1, 2, 3}, + src: []float64{1}, + expect: []float64{2, 2, 3}, + }, + { + dst: []float64{}, + src: []float64{}, + expect: []float64{}, + }, + { + dst: []float64{1}, + src: []float64{nan}, + expect: []float64{nan}, + }, + { + dst: []float64{8, 8, 8, 8, 8}, + src: []float64{2, 4, nan, 8, 9}, + expect: []float64{10, 12, nan, 16, 17}, + }, + { + dst: []float64{0, 1, 2, 3, 4}, + src: []float64{-inf, 4, nan, 8, 9}, + expect: []float64{-inf, 5, nan, 11, 13}, + }, + { + dst: make([]float64, 50)[1:49], + src: make([]float64, 50)[1:49], + expect: make([]float64, 50)[1:49], + }, + } { + sg_ln, dg_ln := 4+j%2, 4+j%3 + v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln) + src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln] + Add(dst, src) + for i := range v.expect { + if !same(dst[i], v.expect[i]) { + t.Errorf("Test %d Add error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i]) + } + } + if !isValidGuard(v.src, src_gd, sg_ln) { + t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:]) + } + if !isValidGuard(v.dst, dst_gd, dg_ln) { + t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:]) + } + } +} + +func TestAddConst(t *testing.T) { + var src_gd float64 = 0 + for j, v := range []struct { + alpha float64 + src, expect []float64 + }{ + { + alpha: 1, + src: []float64{0}, + expect: []float64{1}, + }, + { + alpha: 5, + src: []float64{}, + expect: []float64{}, + }, + { + alpha: 1, + src: []float64{nan}, + expect: []float64{nan}, + }, + { + alpha: 8, + src: []float64{2, 4, nan, 8, 9}, + expect: []float64{10, 12, nan, 16, 17}, + }, + { + alpha: inf, + src: []float64{-inf, 4, nan, 8, 9}, + expect: []float64{nan, inf, nan, inf, inf}, + }, + } { + g_ln := 4 + j%2 + v.src = guardVector(v.src, src_gd, g_ln) + src := v.src[g_ln : len(v.src)-g_ln] + AddConst(v.alpha, src) + for i := range v.expect { + if !same(src[i], v.expect[i]) { + t.Errorf("Test %d AddConst error at %d Got: %v Expected: %v", j, i, src[i], v.expect[i]) + } + } + if !isValidGuard(v.src, src_gd, g_ln) { + t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:g_ln], v.src[len(v.src)-g_ln:]) + } + } +} + +func TestCumSum(t *testing.T) { + var src_gd, dst_gd float64 = -1, 0 + for j, v := range []struct { + dst, src, expect []float64 + }{ + { + dst: []float64{}, + src: []float64{}, + expect: []float64{}, + }, + { + dst: []float64{0}, + src: []float64{1}, + expect: []float64{1}, + }, + { + dst: []float64{nan}, + src: []float64{nan}, + expect: []float64{nan}, + }, + { + dst: []float64{0, 0, 0}, + src: []float64{1, 2, 3}, + expect: []float64{1, 3, 6}, + }, + { + dst: []float64{0, 0, 0, 0}, + src: []float64{1, 2, 3}, + expect: []float64{1, 3, 6}, + }, + { + dst: []float64{0, 0, 0, 0}, + src: []float64{1, 2, 3, 4}, + expect: []float64{1, 3, 6, 10}, + }, + { + dst: []float64{1, nan, nan, 1, 1}, + src: []float64{1, 1, nan, 1, 1}, + expect: []float64{1, 2, nan, nan, nan}, + }, + { + dst: []float64{nan, 4, inf, -inf, 9}, + src: []float64{inf, 4, nan, -inf, 9}, + expect: []float64{inf, inf, nan, nan, nan}, + }, + { + dst: make([]float64, 16), + src: []float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + expect: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + }, + } { + g_ln := 4 + j%2 + v.src, v.dst = guardVector(v.src, src_gd, g_ln), guardVector(v.dst, dst_gd, g_ln) + src, dst := v.src[g_ln:len(v.src)-g_ln], v.dst[g_ln:len(v.dst)-g_ln] + ret := CumSum(dst, src) + for i := range v.expect { + if !same(ret[i], v.expect[i]) { + t.Errorf("Test %d CumSum error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i]) + } + if !same(ret[i], dst[i]) { + t.Errorf("Test %d CumSum ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i]) + } + } + if !isValidGuard(v.src, src_gd, g_ln) { + t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:g_ln], v.src[len(v.src)-g_ln:]) + } + if !isValidGuard(v.dst, dst_gd, g_ln) { + t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:g_ln], v.dst[len(v.dst)-g_ln:]) + } + } +} + +func TestCumProd(t *testing.T) { + var src_gd, dst_gd float64 = -1, 1 + for j, v := range []struct { + dst, src, expect []float64 + }{ + { + dst: []float64{}, + src: []float64{}, + expect: []float64{}, + }, + { + dst: []float64{1}, + src: []float64{1}, + expect: []float64{1}, + }, + { + dst: []float64{nan}, + src: []float64{nan}, + expect: []float64{nan}, + }, + { + dst: []float64{0, 0, 0, 0}, + src: []float64{1, 2, 3, 4}, + expect: []float64{1, 2, 6, 24}, + }, + { + dst: []float64{0, 0, 0}, + src: []float64{1, 2, 3}, + expect: []float64{1, 2, 6}, + }, + { + dst: []float64{0, 0, 0, 0}, + src: []float64{1, 2, 3}, + expect: []float64{1, 2, 6}, + }, + { + dst: []float64{nan, 1, nan, 1, 0}, + src: []float64{1, 1, nan, 1, 1}, + expect: []float64{1, 1, nan, nan, nan}, + }, + { + dst: []float64{nan, 4, nan, -inf, 9}, + src: []float64{inf, 4, nan, -inf, 9}, + expect: []float64{inf, inf, nan, nan, nan}, + }, + { + dst: make([]float64, 18), + src: []float64{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}, + expect: []float64{2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}, + }, + } { + sg_ln, dg_ln := 4+j%2, 4+j%3 + v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln) + src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln] + ret := CumProd(dst, src) + for i := range v.expect { + if !same(ret[i], v.expect[i]) { + t.Errorf("Test %d CumProd error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i]) + } + if !same(ret[i], dst[i]) { + t.Errorf("Test %d CumProd ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i]) + } + } + if !isValidGuard(v.src, src_gd, sg_ln) { + t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:]) + } + if !isValidGuard(v.dst, dst_gd, dg_ln) { + t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:]) + } + } +} + +func TestDiv(t *testing.T) { + var src_gd, dst_gd float64 = -1, 0.5 + for j, v := range []struct { + dst, src, expect []float64 + }{ + { + dst: []float64{1}, + src: []float64{1}, + expect: []float64{1}, + }, + { + dst: []float64{nan}, + src: []float64{nan}, + expect: []float64{nan}, + }, + { + dst: []float64{1, 2, 3, 4}, + src: []float64{1, 2, 3, 4}, + expect: []float64{1, 1, 1, 1}, + }, + { + dst: []float64{1, 2, 3, 4, 2, 4, 6, 8}, + src: []float64{1, 2, 3, 4, 1, 2, 3, 4}, + expect: []float64{1, 1, 1, 1, 2, 2, 2, 2}, + }, + { + dst: []float64{2, 4, 6}, + src: []float64{1, 2, 3}, + expect: []float64{2, 2, 2}, + }, + { + dst: []float64{0, 0, 0, 0}, + src: []float64{1, 2, 3}, + expect: []float64{0, 0, 0}, + }, + { + dst: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0}, + src: []float64{1, 1, nan, 1, 1, 1, 1, nan, 1, 1}, + expect: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0}, + }, + { + dst: []float64{inf, 4, nan, -inf, 9, inf, 4, nan, -inf, 9}, + src: []float64{inf, 4, nan, -inf, 3, inf, 4, nan, -inf, 3}, + expect: []float64{nan, 1, nan, nan, 3, nan, 1, nan, nan, 3}, + }, + } { + sg_ln, dg_ln := 4+j%2, 4+j%3 + v.src, v.dst = guardVector(v.src, src_gd, sg_ln), guardVector(v.dst, dst_gd, dg_ln) + src, dst := v.src[sg_ln:len(v.src)-sg_ln], v.dst[dg_ln:len(v.dst)-dg_ln] + Div(dst, src) + for i := range v.expect { + if !same(dst[i], v.expect[i]) { + t.Errorf("Test %d Div error at %d Got: %v Expected: %v", j, i, dst[i], v.expect[i]) + } + } + if !isValidGuard(v.src, src_gd, sg_ln) { + t.Errorf("Test %d Guard violated in src vector %v %v", j, v.src[:sg_ln], v.src[len(v.src)-sg_ln:]) + } + if !isValidGuard(v.dst, dst_gd, dg_ln) { + t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:dg_ln], v.dst[len(v.dst)-dg_ln:]) + } + } +} + +func TestDivTo(t *testing.T) { + var dst_gd, x_gd, y_gd float64 = -1, 0.5, 0.25 + for j, v := range []struct { + dst, x, y, expect []float64 + }{ + { + dst: []float64{1}, + x: []float64{1}, + y: []float64{1}, + expect: []float64{1}, + }, + { + dst: []float64{1}, + x: []float64{nan}, + y: []float64{nan}, + expect: []float64{nan}, + }, + { + dst: []float64{-2, -2, -2}, + x: []float64{1, 2, 3}, + y: []float64{1, 2, 3}, + expect: []float64{1, 1, 1}, + }, + { + dst: []float64{0, 0, 0}, + x: []float64{2, 4, 6}, + y: []float64{1, 2, 3, 4}, + expect: []float64{2, 2, 2}, + }, + { + dst: []float64{-1, -1, -1}, + x: []float64{0, 0, 0}, + y: []float64{1, 2, 3}, + expect: []float64{0, 0, 0}, + }, + { + dst: []float64{inf, inf, inf, inf, inf, inf, inf, inf, inf, inf}, + x: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0}, + y: []float64{1, 1, nan, 1, 1, 1, 1, nan, 1, 1}, + expect: []float64{nan, 1, nan, 1, 0, nan, 1, nan, 1, 0}, + }, + { + dst: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + x: []float64{inf, 4, nan, -inf, 9, inf, 4, nan, -inf, 9}, + y: []float64{inf, 4, nan, -inf, 3, inf, 4, nan, -inf, 3}, + expect: []float64{nan, 1, nan, nan, 3, nan, 1, nan, nan, 3}, + }, + } { + xg_ln, yg_ln := 4+j%2, 4+j%3 + v.y, v.x = guardVector(v.y, y_gd, yg_ln), guardVector(v.x, x_gd, xg_ln) + y, x := v.y[yg_ln:len(v.y)-yg_ln], v.x[xg_ln:len(v.x)-xg_ln] + v.dst = guardVector(v.dst, dst_gd, xg_ln) + dst := v.dst[xg_ln : len(v.dst)-xg_ln] + ret := DivTo(dst, x, y) + for i := range v.expect { + if !same(ret[i], v.expect[i]) { + t.Errorf("Test %d DivTo error at %d Got: %v Expected: %v", j, i, ret[i], v.expect[i]) + } + if !same(ret[i], dst[i]) { + t.Errorf("Test %d DivTo ret/dst mismatch %d Ret: %v Dst: %v", j, i, ret[i], dst[i]) + } + } + if !isValidGuard(v.y, y_gd, yg_ln) { + t.Errorf("Test %d Guard violated in y vector %v %v", j, v.y[:yg_ln], v.y[len(v.y)-yg_ln:]) + } + if !isValidGuard(v.x, x_gd, xg_ln) { + t.Errorf("Test %d Guard violated in x vector %v %v", j, v.x[:xg_ln], v.x[len(v.x)-xg_ln:]) + } + if !isValidGuard(v.dst, dst_gd, xg_ln) { + t.Errorf("Test %d Guard violated in dst vector %v %v", j, v.dst[:xg_ln], v.dst[len(v.dst)-xg_ln:]) + } + } +} + +func TestL1Dist(t *testing.T) { + var t_gd, s_gd float64 = -inf, inf + for j, v := range []struct { + s, t []float64 + expect float64 + }{ + { + s: []float64{1}, + t: []float64{1}, + expect: 0, + }, + { + s: []float64{nan}, + t: []float64{nan}, + expect: nan, + }, + { + s: []float64{1, 2, 3, 4}, + t: []float64{1, 2, 3, 4}, + expect: 0, + }, + { + s: []float64{2, 4, 6}, + t: []float64{1, 2, 3, 4}, + expect: 6, + }, + { + s: []float64{0, 0, 0}, + t: []float64{1, 2, 3}, + expect: 6, + }, + { + s: []float64{0, -4, -10}, + t: []float64{1, 2, 3}, + expect: 20, + }, + { + s: []float64{0, 1, 0, 1, 0}, + t: []float64{1, 1, inf, 1, 1}, + expect: inf, + }, + { + s: []float64{inf, 4, nan, -inf, 9}, + t: []float64{inf, 4, nan, -inf, 3}, + expect: nan, + }, + } { + sg_ln, tg_ln := 4+j%2, 4+j%3 + v.s, v.t = guardVector(v.s, s_gd, sg_ln), guardVector(v.t, t_gd, tg_ln) + s_lc, t_lc := v.s[sg_ln:len(v.s)-sg_ln], v.t[tg_ln:len(v.t)-tg_ln] + ret := L1Dist(s_lc, t_lc) + if !same(ret, v.expect) { + t.Errorf("Test %d L1Dist error Got: %f Expected: %f", j, ret, v.expect) + } + if !isValidGuard(v.s, s_gd, sg_ln) { + t.Errorf("Test %d Guard violated in s vector %v %v", j, v.s[:sg_ln], v.s[len(v.s)-sg_ln:]) + } + if !isValidGuard(v.t, t_gd, tg_ln) { + t.Errorf("Test %d Guard violated in t vector %v %v", j, v.t[:tg_ln], v.t[len(v.t)-tg_ln:]) + } + } +} + +func TestLinfDist(t *testing.T) { + var t_gd, s_gd float64 = 0, inf + for j, v := range []struct { + s, t []float64 + expect float64 + }{ + { + s: []float64{}, + t: []float64{}, + expect: 0, + }, + { + s: []float64{1}, + t: []float64{1}, + expect: 0, + }, + { + s: []float64{nan}, + t: []float64{nan}, + expect: nan, + }, + { + s: []float64{1, 2, 3, 4}, + t: []float64{1, 2, 3, 4}, + expect: 0, + }, + { + s: []float64{2, 4, 6}, + t: []float64{1, 2, 3, 4}, + expect: 3, + }, + { + s: []float64{0, 0, 0}, + t: []float64{1, 2, 3}, + expect: 3, + }, + { + s: []float64{0, 1, 0, 1, 0}, + t: []float64{1, 1, inf, 1, 1}, + expect: inf, + }, + { + s: []float64{inf, 4, nan, -inf, 9}, + t: []float64{inf, 4, nan, -inf, 3}, + expect: 6, + }, + } { + sg_ln, tg_ln := 4+j%2, 4+j%3 + v.s, v.t = guardVector(v.s, s_gd, sg_ln), guardVector(v.t, t_gd, tg_ln) + s_lc, t_lc := v.s[sg_ln:len(v.s)-sg_ln], v.t[tg_ln:len(v.t)-tg_ln] + ret := LinfDist(s_lc, t_lc) + if !same(ret, v.expect) { + t.Errorf("Test %d LinfDist error Got: %f Expected: %f", j, ret, v.expect) + } + if !isValidGuard(v.s, s_gd, sg_ln) { + t.Errorf("Test %d Guard violated in s vector %v %v", j, v.s[:sg_ln], v.s[len(v.s)-sg_ln:]) + } + if !isValidGuard(v.t, t_gd, tg_ln) { + t.Errorf("Test %d Guard violated in t vector %v %v", j, v.t[:tg_ln], v.t[len(v.t)-tg_ln:]) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/cmplx64/abs.go b/vendor/gonum.org/v1/gonum/internal/cmplx64/abs.go new file mode 100644 index 00000000..65b8c985 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/cmplx64/abs.go @@ -0,0 +1,14 @@ +// Copyright 2010 The Go 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 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 cmplx64 + +import math "gonum.org/v1/gonum/internal/math32" + +// Abs returns the absolute value (also called the modulus) of x. +func Abs(x complex64) float32 { return math.Hypot(real(x), imag(x)) } diff --git a/vendor/gonum.org/v1/gonum/internal/cmplx64/cmath_test.go b/vendor/gonum.org/v1/gonum/internal/cmplx64/cmath_test.go new file mode 100644 index 00000000..39cd5d1e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/cmplx64/cmath_test.go @@ -0,0 +1,240 @@ +// Copyright 2010 The Go 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 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 cmplx64 + +import ( + "testing" + + math "gonum.org/v1/gonum/internal/math32" +) + +// The higher-precision values in vc26 were used to derive the +// input arguments vc (see also comment below). For reference +// only (do not delete). +var vc26 = []complex64{ + (4.97901192488367350108546816 + 7.73887247457810456552351752i), + (7.73887247457810456552351752 - 0.27688005719200159404635997i), + (-0.27688005719200159404635997 - 5.01060361827107492160848778i), + (-5.01060361827107492160848778 + 9.63629370719841737980004837i), + (9.63629370719841737980004837 + 2.92637723924396464525443662i), + (2.92637723924396464525443662 + 5.22908343145930665230025625i), + (5.22908343145930665230025625 + 2.72793991043601025126008608i), + (2.72793991043601025126008608 + 1.82530809168085506044576505i), + (1.82530809168085506044576505 - 8.68592476857560136238589621i), + (-8.68592476857560136238589621 + 4.97901192488367350108546816i), +} + +var vc = []complex64{ + (4.9790119248836735e+00 + 7.7388724745781045e+00i), + (7.7388724745781045e+00 - 2.7688005719200159e-01i), + (-2.7688005719200159e-01 - 5.0106036182710749e+00i), + (-5.0106036182710749e+00 + 9.6362937071984173e+00i), + (9.6362937071984173e+00 + 2.9263772392439646e+00i), + (2.9263772392439646e+00 + 5.2290834314593066e+00i), + (5.2290834314593066e+00 + 2.7279399104360102e+00i), + (2.7279399104360102e+00 + 1.8253080916808550e+00i), + (1.8253080916808550e+00 - 8.6859247685756013e+00i), + (-8.6859247685756013e+00 + 4.9790119248836735e+00i), +} + +// The expected results below were computed by the high precision calculators +// at http://keisan.casio.com/. More exact input values (array vc[], above) +// were obtained by printing them with "%.26f". The answers were calculated +// to 26 digits (by using the "Digit number" drop-down control of each +// calculator). + +var abs = []float32{ + 9.2022120669932650313380972e+00, + 7.7438239742296106616261394e+00, + 5.0182478202557746902556648e+00, + 1.0861137372799545160704002e+01, + 1.0070841084922199607011905e+01, + 5.9922447613166942183705192e+00, + 5.8978784056736762299945176e+00, + 3.2822866700678709020367184e+00, + 8.8756430028990417290744307e+00, + 1.0011785496777731986390856e+01, +} + +var conj = []complex64{ + (4.9790119248836735e+00 - 7.7388724745781045e+00i), + (7.7388724745781045e+00 + 2.7688005719200159e-01i), + (-2.7688005719200159e-01 + 5.0106036182710749e+00i), + (-5.0106036182710749e+00 - 9.6362937071984173e+00i), + (9.6362937071984173e+00 - 2.9263772392439646e+00i), + (2.9263772392439646e+00 - 5.2290834314593066e+00i), + (5.2290834314593066e+00 - 2.7279399104360102e+00i), + (2.7279399104360102e+00 - 1.8253080916808550e+00i), + (1.8253080916808550e+00 + 8.6859247685756013e+00i), + (-8.6859247685756013e+00 - 4.9790119248836735e+00i), +} + +var sqrt = []complex64{ + (2.6628203086086130543813948e+00 + 1.4531345674282185229796902e+00i), + (2.7823278427251986247149295e+00 - 4.9756907317005224529115567e-02i), + (1.5397025302089642757361015e+00 - 1.6271336573016637535695727e+00i), + (1.7103411581506875260277898e+00 + 2.8170677122737589676157029e+00i), + (3.1390392472953103383607947e+00 + 4.6612625849858653248980849e-01i), + (2.1117080764822417640789287e+00 + 1.2381170223514273234967850e+00i), + (2.3587032281672256703926939e+00 + 5.7827111903257349935720172e-01i), + (1.7335262588873410476661577e+00 + 5.2647258220721269141550382e-01i), + (2.3131094974708716531499282e+00 - 1.8775429304303785570775490e+00i), + (8.1420535745048086240947359e-01 + 3.0575897587277248522656113e+00i), +} + +// special cases +var vcAbsSC = []complex64{ + NaN(), +} +var absSC = []float32{ + math.NaN(), +} +var vcConjSC = []complex64{ + NaN(), +} +var conjSC = []complex64{ + NaN(), +} +var vcIsNaNSC = []complex64{ + complex(math.Inf(-1), math.Inf(-1)), + complex(math.Inf(-1), math.NaN()), + complex(math.NaN(), math.Inf(-1)), + complex(0, math.NaN()), + complex(math.NaN(), 0), + complex(math.Inf(1), math.Inf(1)), + complex(math.Inf(1), math.NaN()), + complex(math.NaN(), math.Inf(1)), + complex(math.NaN(), math.NaN()), +} +var isNaNSC = []bool{ + false, + false, + false, + true, + true, + false, + false, + false, + true, +} +var vcSqrtSC = []complex64{ + NaN(), +} +var sqrtSC = []complex64{ + NaN(), +} + +// functions borrowed from pkg/math/all_test.go +func tolerance(a, b, e float32) bool { + d := a - b + if d < 0 { + d = -d + } + + // note: b is correct (expected) value, a is actual value. + // make error tolerance a fraction of b, not a. + if b != 0 { + e = e * b + if e < 0 { + e = -e + } + } + return d < e +} +func veryclose(a, b float32) bool { return tolerance(a, b, 1e-7) } +func alike(a, b float32) bool { + switch { + case a != a && b != b: // math.IsNaN(a) && math.IsNaN(b): + return true + case a == b: + return math.Signbit(a) == math.Signbit(b) + } + return false +} + +func cTolerance(a, b complex64, e float32) bool { + d := Abs(a - b) + if b != 0 { + e = e * Abs(b) + if e < 0 { + e = -e + } + } + return d < e +} +func cVeryclose(a, b complex64) bool { return cTolerance(a, b, 1e-7) } +func cAlike(a, b complex64) bool { + switch { + case IsNaN(a) && IsNaN(b): + return true + case a == b: + return math.Signbit(real(a)) == math.Signbit(real(b)) && math.Signbit(imag(a)) == math.Signbit(imag(b)) + } + return false +} + +func TestAbs(t *testing.T) { + for i := 0; i < len(vc); i++ { + if f := Abs(vc[i]); !veryclose(abs[i], f) { + t.Errorf("Abs(%g) = %g, want %g", vc[i], f, abs[i]) + } + } + for i := 0; i < len(vcAbsSC); i++ { + if f := Abs(vcAbsSC[i]); !alike(absSC[i], f) { + t.Errorf("Abs(%g) = %g, want %g", vcAbsSC[i], f, absSC[i]) + } + } +} +func TestConj(t *testing.T) { + for i := 0; i < len(vc); i++ { + if f := Conj(vc[i]); !cVeryclose(conj[i], f) { + t.Errorf("Conj(%g) = %g, want %g", vc[i], f, conj[i]) + } + } + for i := 0; i < len(vcConjSC); i++ { + if f := Conj(vcConjSC[i]); !cAlike(conjSC[i], f) { + t.Errorf("Conj(%g) = %g, want %g", vcConjSC[i], f, conjSC[i]) + } + } +} +func TestIsNaN(t *testing.T) { + for i := 0; i < len(vcIsNaNSC); i++ { + if f := IsNaN(vcIsNaNSC[i]); isNaNSC[i] != f { + t.Errorf("IsNaN(%v) = %v, want %v", vcIsNaNSC[i], f, isNaNSC[i]) + } + } +} +func TestSqrt(t *testing.T) { + for i := 0; i < len(vc); i++ { + if f := Sqrt(vc[i]); !cVeryclose(sqrt[i], f) { + t.Errorf("Sqrt(%g) = %g, want %g", vc[i], f, sqrt[i]) + } + } + for i := 0; i < len(vcSqrtSC); i++ { + if f := Sqrt(vcSqrtSC[i]); !cAlike(sqrtSC[i], f) { + t.Errorf("Sqrt(%g) = %g, want %g", vcSqrtSC[i], f, sqrtSC[i]) + } + } +} + +func BenchmarkAbs(b *testing.B) { + for i := 0; i < b.N; i++ { + Abs(complex(2.5, 3.5)) + } +} +func BenchmarkConj(b *testing.B) { + for i := 0; i < b.N; i++ { + Conj(complex(2.5, 3.5)) + } +} +func BenchmarkSqrt(b *testing.B) { + for i := 0; i < b.N; i++ { + Sqrt(complex(2.5, 3.5)) + } +} diff --git a/vendor/gonum.org/v1/gonum/internal/cmplx64/conj.go b/vendor/gonum.org/v1/gonum/internal/cmplx64/conj.go new file mode 100644 index 00000000..84b7b556 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/cmplx64/conj.go @@ -0,0 +1,12 @@ +// Copyright 2010 The Go 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 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 cmplx64 + +// Conj returns the complex conjugate of x. +func Conj(x complex64) complex64 { return complex(real(x), -imag(x)) } diff --git a/vendor/gonum.org/v1/gonum/internal/cmplx64/doc.go b/vendor/gonum.org/v1/gonum/internal/cmplx64/doc.go new file mode 100644 index 00000000..40f808a9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/cmplx64/doc.go @@ -0,0 +1,7 @@ +// 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 cmplx64 provides complex64 versions of standard library math/cmplx +// package routines used by gonum/blas. +package cmplx64 // import "gonum.org/v1/gonum/internal/cmplx64" diff --git a/vendor/gonum.org/v1/gonum/internal/cmplx64/isinf.go b/vendor/gonum.org/v1/gonum/internal/cmplx64/isinf.go new file mode 100644 index 00000000..e674e52b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/cmplx64/isinf.go @@ -0,0 +1,25 @@ +// Copyright 2010 The Go 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 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 cmplx64 + +import math "gonum.org/v1/gonum/internal/math32" + +// IsInf returns true if either real(x) or imag(x) is an infinity. +func IsInf(x complex64) bool { + if math.IsInf(real(x), 0) || math.IsInf(imag(x), 0) { + return true + } + return false +} + +// Inf returns a complex infinity, complex(+Inf, +Inf). +func Inf() complex64 { + inf := math.Inf(1) + return complex(inf, inf) +} diff --git a/vendor/gonum.org/v1/gonum/internal/cmplx64/isnan.go b/vendor/gonum.org/v1/gonum/internal/cmplx64/isnan.go new file mode 100644 index 00000000..2630ef86 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/cmplx64/isnan.go @@ -0,0 +1,29 @@ +// Copyright 2010 The Go 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 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 cmplx64 + +import math "gonum.org/v1/gonum/internal/math32" + +// IsNaN returns true if either real(x) or imag(x) is NaN +// and neither is an infinity. +func IsNaN(x complex64) bool { + switch { + case math.IsInf(real(x), 0) || math.IsInf(imag(x), 0): + return false + case math.IsNaN(real(x)) || math.IsNaN(imag(x)): + return true + } + return false +} + +// NaN returns a complex ``not-a-number'' value. +func NaN() complex64 { + nan := math.NaN() + return complex(nan, nan) +} diff --git a/vendor/gonum.org/v1/gonum/internal/cmplx64/sqrt.go b/vendor/gonum.org/v1/gonum/internal/cmplx64/sqrt.go new file mode 100644 index 00000000..313fd11f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/cmplx64/sqrt.go @@ -0,0 +1,108 @@ +// Copyright 2010 The Go 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 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 cmplx64 + +import math "gonum.org/v1/gonum/internal/math32" + +// The original C code, the long comment, and the constants +// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c. +// The go code is a simplified version of the original C. +// +// Cephes Math Library Release 2.8: June, 2000 +// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier +// +// The readme file at http://netlib.sandia.gov/cephes/ says: +// Some software in this archive may be from the book _Methods and +// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster +// International, 1989) or from the Cephes Mathematical Library, a +// commercial product. In either event, it is copyrighted by the author. +// What you see here may be used freely but it comes with no support or +// guarantee. +// +// The two known misprints in the book are repaired here in the +// source listings for the gamma function and the incomplete beta +// integral. +// +// Stephen L. Moshier +// moshier@na-net.ornl.gov + +// Complex square root +// +// DESCRIPTION: +// +// If z = x + iy, r = |z|, then +// +// 1/2 +// Re w = [ (r + x)/2 ] , +// +// 1/2 +// Im w = [ (r - x)/2 ] . +// +// Cancelation error in r-x or r+x is avoided by using the +// identity 2 Re w Im w = y. +// +// Note that -w is also a square root of z. The root chosen +// is always in the right half plane and Im w has the same sign as y. +// +// ACCURACY: +// +// Relative error: +// arithmetic domain # trials peak rms +// DEC -10,+10 25000 3.2e-17 9.6e-18 +// IEEE -10,+10 1,000,000 2.9e-16 6.1e-17 + +// Sqrt returns the square root of x. +// The result r is chosen so that real(r) ≥ 0 and imag(r) has the same sign as imag(x). +func Sqrt(x complex64) complex64 { + if imag(x) == 0 { + if real(x) == 0 { + return complex(0, 0) + } + if real(x) < 0 { + return complex(0, math.Sqrt(-real(x))) + } + return complex(math.Sqrt(real(x)), 0) + } + if real(x) == 0 { + if imag(x) < 0 { + r := math.Sqrt(-0.5 * imag(x)) + return complex(r, -r) + } + r := math.Sqrt(0.5 * imag(x)) + return complex(r, r) + } + a := real(x) + b := imag(x) + var scale float32 + // Rescale to avoid internal overflow or underflow. + if math.Abs(a) > 4 || math.Abs(b) > 4 { + a *= 0.25 + b *= 0.25 + scale = 2 + } else { + a *= 1.8014398509481984e16 // 2**54 + b *= 1.8014398509481984e16 + scale = 7.450580596923828125e-9 // 2**-27 + } + r := math.Hypot(a, b) + var t float32 + if a > 0 { + t = math.Sqrt(0.5*r + 0.5*a) + r = scale * math.Abs((0.5*b)/t) + t *= scale + } else { + r = math.Sqrt(0.5*r - 0.5*a) + t = scale * math.Abs((0.5*b)/r) + r *= scale + } + if b < 0 { + return complex(t, -r) + } + return complex(t, r) +} diff --git a/vendor/gonum.org/v1/gonum/internal/math32/doc.go b/vendor/gonum.org/v1/gonum/internal/math32/doc.go new file mode 100644 index 00000000..2368fcd9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/math32/doc.go @@ -0,0 +1,7 @@ +// 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 math32 provides float32 versions of standard library math package +// routines used by gonum/blas/native. +package math32 // import "gonum.org/v1/gonum/internal/math32" diff --git a/vendor/gonum.org/v1/gonum/internal/math32/math.go b/vendor/gonum.org/v1/gonum/internal/math32/math.go new file mode 100644 index 00000000..3e466611 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/math32/math.go @@ -0,0 +1,111 @@ +// Copyright 2009 The Go 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 ©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 math32 + +import ( + "math" +) + +const ( + unan = 0x7fc00000 + uinf = 0x7f800000 + uneginf = 0xff800000 + mask = 0x7f8 >> 3 + shift = 32 - 8 - 1 + bias = 127 +) + +// Abs returns the absolute value of x. +// +// Special cases are: +// Abs(±Inf) = +Inf +// Abs(NaN) = NaN +func Abs(x float32) float32 { + switch { + case x < 0: + return -x + case x == 0: + return 0 // return correctly abs(-0) + } + return x +} + +// Copysign returns a value with the magnitude +// of x and the sign of y. +func Copysign(x, y float32) float32 { + const sign = 1 << 31 + return math.Float32frombits(math.Float32bits(x)&^sign | math.Float32bits(y)&sign) +} + +// Hypot returns Sqrt(p*p + q*q), taking care to avoid +// unnecessary overflow and underflow. +// +// Special cases are: +// Hypot(±Inf, q) = +Inf +// Hypot(p, ±Inf) = +Inf +// Hypot(NaN, q) = NaN +// Hypot(p, NaN) = NaN +func Hypot(p, q float32) float32 { + // special cases + switch { + case IsInf(p, 0) || IsInf(q, 0): + return Inf(1) + case IsNaN(p) || IsNaN(q): + return NaN() + } + if p < 0 { + p = -p + } + if q < 0 { + q = -q + } + if p < q { + p, q = q, p + } + if p == 0 { + return 0 + } + q = q / p + return p * Sqrt(1+q*q) +} + +// Inf returns positive infinity if sign >= 0, negative infinity if sign < 0. +func Inf(sign int) float32 { + var v uint32 + if sign >= 0 { + v = uinf + } else { + v = uneginf + } + return math.Float32frombits(v) +} + +// IsInf reports whether f is an infinity, according to sign. +// If sign > 0, IsInf reports whether f is positive infinity. +// If sign < 0, IsInf reports whether f is negative infinity. +// If sign == 0, IsInf reports whether f is either infinity. +func IsInf(f float32, sign int) bool { + // Test for infinity by comparing against maximum float. + // To avoid the floating-point hardware, could use: + // x := math.Float32bits(f); + // return sign >= 0 && x == uinf || sign <= 0 && x == uneginf; + return sign >= 0 && f > math.MaxFloat32 || sign <= 0 && f < -math.MaxFloat32 +} + +// IsNaN reports whether f is an IEEE 754 ``not-a-number'' value. +func IsNaN(f float32) (is bool) { + // IEEE 754 says that only NaNs satisfy f != f. + // To avoid the floating-point hardware, could use: + // x := math.Float32bits(f); + // return uint32(x>>shift)&mask == mask && x != uinf && x != uneginf + return f != f +} + +// NaN returns an IEEE 754 ``not-a-number'' value. +func NaN() float32 { return math.Float32frombits(unan) } diff --git a/vendor/gonum.org/v1/gonum/internal/math32/math_test.go b/vendor/gonum.org/v1/gonum/internal/math32/math_test.go new file mode 100644 index 00000000..aa29ea37 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/internal/math32/math_test.go @@ -0,0 +1,238 @@ +// 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 math32 + +import ( + "math" + "testing" + "testing/quick" + + "gonum.org/v1/gonum/floats" +) + +const tol = 1e-7 + +func TestAbs(t *testing.T) { + f := func(x float32) bool { + y := Abs(x) + return y == float32(math.Abs(float64(x))) + } + if err := quick.Check(f, nil); err != nil { + t.Error(err) + } +} + +func TestCopySign(t *testing.T) { + f := func(x struct{ X, Y float32 }) bool { + y := Copysign(x.X, x.Y) + return y == float32(math.Copysign(float64(x.X), float64(x.Y))) + } + if err := quick.Check(f, nil); err != nil { + t.Error(err) + } +} + +func TestHypot(t *testing.T) { + // tol is increased for Hypot to avoid failures + // related to https://github.com/gonum/gonum/issues/110. + const tol = 1e-6 + f := func(x struct{ X, Y float32 }) bool { + y := Hypot(x.X, x.Y) + if math.Hypot(float64(x.X), float64(x.Y)) > math.MaxFloat32 { + return true + } + return floats.EqualWithinRel(float64(y), math.Hypot(float64(x.X), float64(x.Y)), tol) + } + if err := quick.Check(f, nil); err != nil { + t.Error(err) + } +} + +func TestInf(t *testing.T) { + if float64(Inf(1)) != math.Inf(1) || float64(Inf(-1)) != math.Inf(-1) { + t.Error("float32(inf) not infinite") + } +} + +func TestIsInf(t *testing.T) { + posInf := float32(math.Inf(1)) + negInf := float32(math.Inf(-1)) + if !IsInf(posInf, 0) || !IsInf(negInf, 0) || !IsInf(posInf, 1) || !IsInf(negInf, -1) || IsInf(posInf, -1) || IsInf(negInf, 1) { + t.Error("unexpected isInf value") + } + f := func(x struct { + F float32 + Sign int + }) bool { + y := IsInf(x.F, x.Sign) + return y == math.IsInf(float64(x.F), x.Sign) + } + if err := quick.Check(f, nil); err != nil { + t.Error(err) + } +} + +func TestIsNaN(t *testing.T) { + f := func(x float32) bool { + y := IsNaN(x) + return y == math.IsNaN(float64(x)) + } + if err := quick.Check(f, nil); err != nil { + t.Error(err) + } +} + +func TestNaN(t *testing.T) { + if !math.IsNaN(float64(NaN())) { + t.Errorf("float32(nan) is a number: %f", NaN()) + } +} + +func TestSignbit(t *testing.T) { + f := func(x float32) bool { + return Signbit(x) == math.Signbit(float64(x)) + } + if err := quick.Check(f, nil); err != nil { + t.Error(err) + } +} + +func TestSqrt(t *testing.T) { + f := func(x float32) bool { + y := Sqrt(x) + if IsNaN(y) && IsNaN(sqrt(x)) { + return true + } + return floats.EqualWithinRel(float64(y), float64(sqrt(x)), tol) + } + if err := quick.Check(f, nil); err != nil { + t.Error(err) + } +} + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The original C code and the long comment below are +// from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and +// came with this notice. The go code is a simplified +// version of the original C. +// +// ==================================================== +// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +// +// Developed at SunPro, a Sun Microsystems, Inc. business. +// Permission to use, copy, modify, and distribute this +// software is freely granted, provided that this notice +// is preserved. +// ==================================================== +// +// __ieee754_sqrt(x) +// Return correctly rounded sqrt. +// ----------------------------------------- +// | Use the hardware sqrt if you have one | +// ----------------------------------------- +// Method: +// Bit by bit method using integer arithmetic. (Slow, but portable) +// 1. Normalization +// Scale x to y in [1,4) with even powers of 2: +// find an integer k such that 1 <= (y=x*2**(2k)) < 4, then +// sqrt(x) = 2**k * sqrt(y) +// 2. Bit by bit computation +// Let q = sqrt(y) truncated to i bit after binary point (q = 1), +// i 0 +// i+1 2 +// s = 2*q , and y = 2 * ( y - q ). (1) +// i i i i +// +// To compute q from q , one checks whether +// i+1 i +// +// -(i+1) 2 +// (q + 2 ) <= y. (2) +// i +// -(i+1) +// If (2) is false, then q = q ; otherwise q = q + 2 . +// i+1 i i+1 i +// +// With some algebraic manipulation, it is not difficult to see +// that (2) is equivalent to +// -(i+1) +// s + 2 <= y (3) +// i i +// +// The advantage of (3) is that s and y can be computed by +// i i +// the following recurrence formula: +// if (3) is false +// +// s = s , y = y ; (4) +// i+1 i i+1 i +// +// otherwise, +// -i -(i+1) +// s = s + 2 , y = y - s - 2 (5) +// i+1 i i+1 i i +// +// One may easily use induction to prove (4) and (5). +// Note. Since the left hand side of (3) contain only i+2 bits, +// it does not necessary to do a full (53-bit) comparison +// in (3). +// 3. Final rounding +// After generating the 53 bits result, we compute one more bit. +// Together with the remainder, we can decide whether the +// result is exact, bigger than 1/2ulp, or less than 1/2ulp +// (it will never equal to 1/2ulp). +// The rounding mode can be detected by checking whether +// huge + tiny is equal to huge, and whether huge - tiny is +// equal to huge for some floating point number "huge" and "tiny". +// +func sqrt(x float32) float32 { + // special cases + switch { + case x == 0 || IsNaN(x) || IsInf(x, 1): + return x + case x < 0: + return NaN() + } + ix := math.Float32bits(x) + // normalize x + exp := int((ix >> shift) & mask) + if exp == 0 { // subnormal x + for ix&1<>= 1 // exp = exp/2, exponent of square root + // generate sqrt(x) bit by bit + ix <<= 1 + var q, s uint32 // q = sqrt(x) + r := uint32(1 << (shift + 1)) // r = moving bit from MSB to LSB + for r != 0 { + t := s + r + if t <= ix { + s = t + r + ix -= t + q += r + } + ix <<= 1 + r >>= 1 + } + // final rounding + if ix != 0 { // remainder, result not exact + q += q & 1 // round according to extra bit + } + ix = q>>1 + uint32(exp-1+bias)< 0 || nru > 0 || ncc > 0) { + info = impl.Dlasq1(n, d, e, work) + // If info is 2 dqds didn't finish, and so try to. + if info != 2 { + return info == 0 + } + info = 0 + } + nm1 := n - 1 + nm12 := nm1 + nm1 + nm13 := nm12 + nm1 + idir := 0 + + eps := dlamchE + unfl := dlamchS + lower := uplo == blas.Lower + var cs, sn, r float64 + if lower { + for i := 0; i < n-1; i++ { + cs, sn, r = impl.Dlartg(d[i], e[i]) + d[i] = r + e[i] = sn * d[i+1] + d[i+1] *= cs + work[i] = cs + work[nm1+i] = sn + } + if nru > 0 { + impl.Dlasr(blas.Right, lapack.Variable, lapack.Forward, nru, n, work, work[n-1:], u, ldu) + } + if ncc > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Forward, n, ncc, work, work[n-1:], c, ldc) + } + } + // Compute singular values to a relative accuracy of tol. If tol is negative + // the values will be computed to an absolute accuracy of math.Abs(tol) * norm(b) + tolmul := math.Max(10, math.Min(100, math.Pow(eps, -1.0/8))) + tol := tolmul * eps + var smax float64 + for i := 0; i < n; i++ { + smax = math.Max(smax, math.Abs(d[i])) + } + for i := 0; i < n-1; i++ { + smax = math.Max(smax, math.Abs(e[i])) + } + + var sminl float64 + var thresh float64 + if tol >= 0 { + sminoa := math.Abs(d[0]) + if sminoa != 0 { + mu := sminoa + for i := 1; i < n; i++ { + mu = math.Abs(d[i]) * (mu / (mu + math.Abs(e[i-1]))) + sminoa = math.Min(sminoa, mu) + if sminoa == 0 { + break + } + } + } + sminoa = sminoa / math.Sqrt(float64(n)) + thresh = math.Max(tol*sminoa, float64(maxIter*n*n)*unfl) + } else { + thresh = math.Max(math.Abs(tol)*smax, float64(maxIter*n*n)*unfl) + } + // Prepare for the main iteration loop for the singular values. + maxIt := maxIter * n * n + iter := 0 + oldl2 := -1 + oldm := -1 + // m points to the last element of unconverged part of matrix. + m := n + + Outer: + for m > 1 { + if iter > maxIt { + info = 0 + for i := 0; i < n-1; i++ { + if e[i] != 0 { + info++ + } + } + return info == 0 + } + // Find diagonal block of matrix to work on. + if tol < 0 && math.Abs(d[m-1]) <= thresh { + d[m-1] = 0 + } + smax = math.Abs(d[m-1]) + smin := smax + var l2 int + var broke bool + for l3 := 0; l3 < m-1; l3++ { + l2 = m - l3 - 2 + abss := math.Abs(d[l2]) + abse := math.Abs(e[l2]) + if tol < 0 && abss <= thresh { + d[l2] = 0 + } + if abse <= thresh { + broke = true + break + } + smin = math.Min(smin, abss) + smax = math.Max(math.Max(smax, abss), abse) + } + if broke { + e[l2] = 0 + if l2 == m-2 { + // Convergence of bottom singular value, return to top. + m-- + continue + } + l2++ + } else { + l2 = 0 + } + // e[ll] through e[m-2] are nonzero, e[ll-1] is zero + if l2 == m-2 { + // Handle 2×2 block separately. + var sinr, cosr, sinl, cosl float64 + d[m-1], d[m-2], sinr, cosr, sinl, cosl = impl.Dlasv2(d[m-2], e[m-2], d[m-1]) + e[m-2] = 0 + if ncvt > 0 { + bi.Drot(ncvt, vt[(m-2)*ldvt:], 1, vt[(m-1)*ldvt:], 1, cosr, sinr) + } + if nru > 0 { + bi.Drot(nru, u[m-2:], ldu, u[m-1:], ldu, cosl, sinl) + } + if ncc > 0 { + bi.Drot(ncc, c[(m-2)*ldc:], 1, c[(m-1)*ldc:], 1, cosl, sinl) + } + m -= 2 + continue + } + // If working on a new submatrix, choose shift direction from larger end + // diagonal element toward smaller. + if l2 > oldm-1 || m-1 < oldl2 { + if math.Abs(d[l2]) >= math.Abs(d[m-1]) { + idir = 1 + } else { + idir = 2 + } + } + // Apply convergence tests. + // TODO(btracey): There is a lot of similar looking code here. See + // if there is a better way to de-duplicate. + if idir == 1 { + // Run convergence test in forward direction. + // First apply standard test to bottom of matrix. + if math.Abs(e[m-2]) <= math.Abs(tol)*math.Abs(d[m-1]) || (tol < 0 && math.Abs(e[m-2]) <= thresh) { + e[m-2] = 0 + continue + } + if tol >= 0 { + // If relative accuracy desired, apply convergence criterion forward. + mu := math.Abs(d[l2]) + sminl = mu + for l3 := l2; l3 < m-1; l3++ { + if math.Abs(e[l3]) <= tol*mu { + e[l3] = 0 + continue Outer + } + mu = math.Abs(d[l3+1]) * (mu / (mu + math.Abs(e[l3]))) + sminl = math.Min(sminl, mu) + } + } + } else { + // Run convergence test in backward direction. + // First apply standard test to top of matrix. + if math.Abs(e[l2]) <= math.Abs(tol)*math.Abs(d[l2]) || (tol < 0 && math.Abs(e[l2]) <= thresh) { + e[l2] = 0 + continue + } + if tol >= 0 { + // If relative accuracy desired, apply convergence criterion backward. + mu := math.Abs(d[m-1]) + sminl = mu + for l3 := m - 2; l3 >= l2; l3-- { + if math.Abs(e[l3]) <= tol*mu { + e[l3] = 0 + continue Outer + } + mu = math.Abs(d[l3]) * (mu / (mu + math.Abs(e[l3]))) + sminl = math.Min(sminl, mu) + } + } + } + oldl2 = l2 + oldm = m + // Compute shift. First, test if shifting would ruin relative accuracy, + // and if so set the shift to zero. + var shift float64 + if tol >= 0 && float64(n)*tol*(sminl/smax) <= math.Max(eps, (1.0/100)*tol) { + shift = 0 + } else { + var sl2 float64 + if idir == 1 { + sl2 = math.Abs(d[l2]) + shift, _ = impl.Dlas2(d[m-2], e[m-2], d[m-1]) + } else { + sl2 = math.Abs(d[m-1]) + shift, _ = impl.Dlas2(d[l2], e[l2], d[l2+1]) + } + // Test if shift is negligible + if sl2 > 0 { + if (shift/sl2)*(shift/sl2) < eps { + shift = 0 + } + } + } + iter += m - l2 + 1 + // If no shift, do simplified QR iteration. + if shift == 0 { + if idir == 1 { + cs := 1.0 + oldcs := 1.0 + var sn, r, oldsn float64 + for i := l2; i < m-1; i++ { + cs, sn, r = impl.Dlartg(d[i]*cs, e[i]) + if i > l2 { + e[i-1] = oldsn * r + } + oldcs, oldsn, d[i] = impl.Dlartg(oldcs*r, d[i+1]*sn) + work[i-l2] = cs + work[i-l2+nm1] = sn + work[i-l2+nm12] = oldcs + work[i-l2+nm13] = oldsn + } + h := d[m-1] * cs + d[m-1] = h * oldcs + e[m-2] = h * oldsn + if ncvt > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Forward, m-l2, ncvt, work, work[n-1:], vt[l2*ldvt:], ldvt) + } + if nru > 0 { + impl.Dlasr(blas.Right, lapack.Variable, lapack.Forward, nru, m-l2, work[nm12:], work[nm13:], u[l2:], ldu) + } + if ncc > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Forward, m-l2, ncc, work[nm12:], work[nm13:], c[l2*ldc:], ldc) + } + if math.Abs(e[m-2]) < thresh { + e[m-2] = 0 + } + } else { + cs := 1.0 + oldcs := 1.0 + var sn, r, oldsn float64 + for i := m - 1; i >= l2+1; i-- { + cs, sn, r = impl.Dlartg(d[i]*cs, e[i-1]) + if i < m-1 { + e[i] = oldsn * r + } + oldcs, oldsn, d[i] = impl.Dlartg(oldcs*r, d[i-1]*sn) + work[i-l2-1] = cs + work[i-l2+nm1-1] = -sn + work[i-l2+nm12-1] = oldcs + work[i-l2+nm13-1] = -oldsn + } + h := d[l2] * cs + d[l2] = h * oldcs + e[l2] = h * oldsn + if ncvt > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Backward, m-l2, ncvt, work[nm12:], work[nm13:], vt[l2*ldvt:], ldvt) + } + if nru > 0 { + impl.Dlasr(blas.Right, lapack.Variable, lapack.Backward, nru, m-l2, work, work[n-1:], u[l2:], ldu) + } + if ncc > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Backward, m-l2, ncc, work, work[n-1:], c[l2*ldc:], ldc) + } + if math.Abs(e[l2]) <= thresh { + e[l2] = 0 + } + } + } else { + // Use nonzero shift. + if idir == 1 { + // Chase bulge from top to bottom. Save cosines and sines for + // later singular vector updates. + f := (math.Abs(d[l2]) - shift) * (math.Copysign(1, d[l2]) + shift/d[l2]) + g := e[l2] + var cosl, sinl float64 + for i := l2; i < m-1; i++ { + cosr, sinr, r := impl.Dlartg(f, g) + if i > l2 { + e[i-1] = r + } + f = cosr*d[i] + sinr*e[i] + e[i] = cosr*e[i] - sinr*d[i] + g = sinr * d[i+1] + d[i+1] *= cosr + cosl, sinl, r = impl.Dlartg(f, g) + d[i] = r + f = cosl*e[i] + sinl*d[i+1] + d[i+1] = cosl*d[i+1] - sinl*e[i] + if i < m-2 { + g = sinl * e[i+1] + e[i+1] = cosl * e[i+1] + } + work[i-l2] = cosr + work[i-l2+nm1] = sinr + work[i-l2+nm12] = cosl + work[i-l2+nm13] = sinl + } + e[m-2] = f + if ncvt > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Forward, m-l2, ncvt, work, work[n-1:], vt[l2*ldvt:], ldvt) + } + if nru > 0 { + impl.Dlasr(blas.Right, lapack.Variable, lapack.Forward, nru, m-l2, work[nm12:], work[nm13:], u[l2:], ldu) + } + if ncc > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Forward, m-l2, ncc, work[nm12:], work[nm13:], c[l2*ldc:], ldc) + } + if math.Abs(e[m-2]) <= thresh { + e[m-2] = 0 + } + } else { + // Chase bulge from top to bottom. Save cosines and sines for + // later singular vector updates. + f := (math.Abs(d[m-1]) - shift) * (math.Copysign(1, d[m-1]) + shift/d[m-1]) + g := e[m-2] + for i := m - 1; i > l2; i-- { + cosr, sinr, r := impl.Dlartg(f, g) + if i < m-1 { + e[i] = r + } + f = cosr*d[i] + sinr*e[i-1] + e[i-1] = cosr*e[i-1] - sinr*d[i] + g = sinr * d[i-1] + d[i-1] *= cosr + cosl, sinl, r := impl.Dlartg(f, g) + d[i] = r + f = cosl*e[i-1] + sinl*d[i-1] + d[i-1] = cosl*d[i-1] - sinl*e[i-1] + if i > l2+1 { + g = sinl * e[i-2] + e[i-2] *= cosl + } + work[i-l2-1] = cosr + work[i-l2+nm1-1] = -sinr + work[i-l2+nm12-1] = cosl + work[i-l2+nm13-1] = -sinl + } + e[l2] = f + if math.Abs(e[l2]) <= thresh { + e[l2] = 0 + } + if ncvt > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Backward, m-l2, ncvt, work[nm12:], work[nm13:], vt[l2*ldvt:], ldvt) + } + if nru > 0 { + impl.Dlasr(blas.Right, lapack.Variable, lapack.Backward, nru, m-l2, work, work[n-1:], u[l2:], ldu) + } + if ncc > 0 { + impl.Dlasr(blas.Left, lapack.Variable, lapack.Backward, m-l2, ncc, work, work[n-1:], c[l2*ldc:], ldc) + } + } + } + } + } + + // All singular values converged, make them positive. + for i := 0; i < n; i++ { + if d[i] < 0 { + d[i] *= -1 + if ncvt > 0 { + bi.Dscal(ncvt, -1, vt[i*ldvt:], 1) + } + } + } + + // Sort the singular values in decreasing order. + for i := 0; i < n-1; i++ { + isub := 0 + smin := d[0] + for j := 1; j < n-i; j++ { + if d[j] <= smin { + isub = j + smin = d[j] + } + } + if isub != n-i { + // Swap singular values and vectors. + d[isub] = d[n-i-1] + d[n-i-1] = smin + if ncvt > 0 { + bi.Dswap(ncvt, vt[isub*ldvt:], 1, vt[(n-i-1)*ldvt:], 1) + } + if nru > 0 { + bi.Dswap(nru, u[isub:], ldu, u[n-i-1:], ldu) + } + if ncc > 0 { + bi.Dswap(ncc, c[isub*ldc:], 1, c[(n-i-1)*ldc:], 1) + } + } + } + info = 0 + for i := 0; i < n-1; i++ { + if e[i] != 0 { + info++ + } + } + return info == 0 +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgebak.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebak.go new file mode 100644 index 00000000..e271c99d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebak.go @@ -0,0 +1,78 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dgebak updates an n×m matrix V as +// V = P D V, if side == lapack.RightEV, +// V = P D^{-1} V, if side == lapack.LeftEV, +// where P and D are n×n permutation and scaling matrices, respectively, +// implicitly represented by job, scale, ilo and ihi as returned by Dgebal. +// +// Typically, columns of the matrix V contain the right or left (determined by +// side) eigenvectors of the balanced matrix output by Dgebal, and Dgebak forms +// the eigenvectors of the original matrix. +// +// Dgebak is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgebak(job lapack.Job, side lapack.EVSide, n, ilo, ihi int, scale []float64, m int, v []float64, ldv int) { + switch job { + default: + panic(badJob) + case lapack.None, lapack.Permute, lapack.Scale, lapack.PermuteScale: + } + switch side { + default: + panic(badEVSide) + case lapack.LeftEV, lapack.RightEV: + } + checkMatrix(n, m, v, ldv) + switch { + case ilo < 0 || max(0, n-1) < ilo: + panic(badIlo) + case ihi < min(ilo, n-1) || n <= ihi: + panic(badIhi) + } + + // Quick return if possible. + if n == 0 || m == 0 || job == lapack.None { + return + } + + bi := blas64.Implementation() + if ilo != ihi && job != lapack.Permute { + // Backward balance. + if side == lapack.RightEV { + for i := ilo; i <= ihi; i++ { + bi.Dscal(m, scale[i], v[i*ldv:], 1) + } + } else { + for i := ilo; i <= ihi; i++ { + bi.Dscal(m, 1/scale[i], v[i*ldv:], 1) + } + } + } + if job == lapack.Scale { + return + } + // Backward permutation. + for i := ilo - 1; i >= 0; i-- { + k := int(scale[i]) + if k == i { + continue + } + bi.Dswap(m, v[i*ldv:], 1, v[k*ldv:], 1) + } + for i := ihi + 1; i < n; i++ { + k := int(scale[i]) + if k == i { + continue + } + bi.Dswap(m, v[i*ldv:], 1, v[k*ldv:], 1) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgebal.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebal.go new file mode 100644 index 00000000..ee57ead1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebal.go @@ -0,0 +1,228 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dgebal balances an n×n matrix A. Balancing consists of two stages, permuting +// and scaling. Both steps are optional and depend on the value of job. +// +// Permuting consists of applying a permutation matrix P such that the matrix +// that results from P^T*A*P takes the upper block triangular form +// [ T1 X Y ] +// P^T A P = [ 0 B Z ], +// [ 0 0 T2 ] +// where T1 and T2 are upper triangular matrices and B contains at least one +// nonzero off-diagonal element in each row and column. The indices ilo and ihi +// mark the starting and ending columns of the submatrix B. The eigenvalues of A +// isolated in the first 0 to ilo-1 and last ihi+1 to n-1 elements on the +// diagonal can be read off without any roundoff error. +// +// Scaling consists of applying a diagonal similarity transformation D such that +// D^{-1}*B*D has the 1-norm of each row and its corresponding column nearly +// equal. The output matrix is +// [ T1 X*D Y ] +// [ 0 inv(D)*B*D inv(D)*Z ]. +// [ 0 0 T2 ] +// Scaling may reduce the 1-norm of the matrix, and improve the accuracy of +// the computed eigenvalues and/or eigenvectors. +// +// job specifies the operations that will be performed on A. +// If job is lapack.None, Dgebal sets scale[i] = 1 for all i and returns ilo=0, ihi=n-1. +// If job is lapack.Permute, only permuting will be done. +// If job is lapack.Scale, only scaling will be done. +// If job is lapack.PermuteScale, both permuting and scaling will be done. +// +// On return, if job is lapack.Permute or lapack.PermuteScale, it will hold that +// A[i,j] == 0, for i > j and j ∈ {0, ..., ilo-1, ihi+1, ..., n-1}. +// If job is lapack.None or lapack.Scale, or if n == 0, it will hold that +// ilo == 0 and ihi == n-1. +// +// On return, scale will contain information about the permutations and scaling +// factors applied to A. If π(j) denotes the index of the column interchanged +// with column j, and D[j,j] denotes the scaling factor applied to column j, +// then +// scale[j] == π(j), for j ∈ {0, ..., ilo-1, ihi+1, ..., n-1}, +// == D[j,j], for j ∈ {ilo, ..., ihi}. +// scale must have length equal to n, otherwise Dgebal will panic. +// +// Dgebal is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgebal(job lapack.Job, n int, a []float64, lda int, scale []float64) (ilo, ihi int) { + switch job { + default: + panic(badJob) + case lapack.None, lapack.Permute, lapack.Scale, lapack.PermuteScale: + } + checkMatrix(n, n, a, lda) + if len(scale) != n { + panic("lapack: bad length of scale") + } + + ilo = 0 + ihi = n - 1 + + if n == 0 || job == lapack.None { + for i := range scale { + scale[i] = 1 + } + return ilo, ihi + } + + bi := blas64.Implementation() + swapped := true + + if job == lapack.Scale { + goto scaling + } + + // Permutation to isolate eigenvalues if possible. + // + // Search for rows isolating an eigenvalue and push them down. + for swapped { + swapped = false + rows: + for i := ihi; i >= 0; i-- { + for j := 0; j <= ihi; j++ { + if i == j { + continue + } + if a[i*lda+j] != 0 { + continue rows + } + } + // Row i has only zero off-diagonal elements in the + // block A[ilo:ihi+1,ilo:ihi+1]. + scale[ihi] = float64(i) + if i != ihi { + bi.Dswap(ihi+1, a[i:], lda, a[ihi:], lda) + bi.Dswap(n, a[i*lda:], 1, a[ihi*lda:], 1) + } + if ihi == 0 { + scale[0] = 1 + return ilo, ihi + } + ihi-- + swapped = true + break + } + } + // Search for columns isolating an eigenvalue and push them left. + swapped = true + for swapped { + swapped = false + columns: + for j := ilo; j <= ihi; j++ { + for i := ilo; i <= ihi; i++ { + if i == j { + continue + } + if a[i*lda+j] != 0 { + continue columns + } + } + // Column j has only zero off-diagonal elements in the + // block A[ilo:ihi+1,ilo:ihi+1]. + scale[ilo] = float64(j) + if j != ilo { + bi.Dswap(ihi+1, a[j:], lda, a[ilo:], lda) + bi.Dswap(n-ilo, a[j*lda+ilo:], 1, a[ilo*lda+ilo:], 1) + } + swapped = true + ilo++ + break + } + } + +scaling: + for i := ilo; i <= ihi; i++ { + scale[i] = 1 + } + + if job == lapack.Permute { + return ilo, ihi + } + + // Balance the submatrix in rows ilo to ihi. + + const ( + // sclfac should be a power of 2 to avoid roundoff errors. + // Elements of scale are restricted to powers of sclfac, + // therefore the matrix will be only nearly balanced. + sclfac = 2 + // factor determines the minimum reduction of the row and column + // norms that is considered non-negligible. It must be less than 1. + factor = 0.95 + ) + sfmin1 := dlamchS / dlamchP + sfmax1 := 1 / sfmin1 + sfmin2 := sfmin1 * sclfac + sfmax2 := 1 / sfmin2 + + // Iterative loop for norm reduction. + var conv bool + for !conv { + conv = true + for i := ilo; i <= ihi; i++ { + c := bi.Dnrm2(ihi-ilo+1, a[ilo*lda+i:], lda) + r := bi.Dnrm2(ihi-ilo+1, a[i*lda+ilo:], 1) + ica := bi.Idamax(ihi+1, a[i:], lda) + ca := math.Abs(a[ica*lda+i]) + ira := bi.Idamax(n-ilo, a[i*lda+ilo:], 1) + ra := math.Abs(a[i*lda+ilo+ira]) + + // Guard against zero c or r due to underflow. + if c == 0 || r == 0 { + continue + } + g := r / sclfac + f := 1.0 + s := c + r + for c < g && math.Max(f, math.Max(c, ca)) < sfmax2 && math.Min(r, math.Min(g, ra)) > sfmin2 { + if math.IsNaN(c + f + ca + r + g + ra) { + // Panic if NaN to avoid infinite loop. + panic("lapack: NaN") + } + f *= sclfac + c *= sclfac + ca *= sclfac + g /= sclfac + r /= sclfac + ra /= sclfac + } + g = c / sclfac + for r <= g && math.Max(r, ra) < sfmax2 && math.Min(math.Min(f, c), math.Min(g, ca)) > sfmin2 { + f /= sclfac + c /= sclfac + ca /= sclfac + g /= sclfac + r *= sclfac + ra *= sclfac + } + + if c+r >= factor*s { + // Reduction would be negligible. + continue + } + if f < 1 && scale[i] < 1 && f*scale[i] <= sfmin1 { + continue + } + if f > 1 && scale[i] > 1 && scale[i] >= sfmax1/f { + continue + } + + // Now balance. + scale[i] *= f + bi.Dscal(n-ilo, 1/f, a[i*lda+ilo:], 1) + bi.Dscal(ihi+1, f, a[i:], lda) + conv = false + } + } + return ilo, ihi +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgebd2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebd2.go new file mode 100644 index 00000000..7f7f61c1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebd2.go @@ -0,0 +1,74 @@ +// 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/blas" + +// Dgebd2 reduces an m×n matrix A to upper or lower bidiagonal form by an orthogonal +// transformation. +// Q^T * A * P = B +// if m >= n, B is upper diagonal, otherwise B is lower bidiagonal. +// d is the diagonal, len = min(m,n) +// e is the off-diagonal len = min(m,n)-1 +// +// Dgebd2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgebd2(m, n int, a []float64, lda int, d, e, tauQ, tauP, work []float64) { + checkMatrix(m, n, a, lda) + if len(d) < min(m, n) { + panic(badD) + } + if len(e) < min(m, n)-1 { + panic(badE) + } + if len(tauQ) < min(m, n) { + panic(badTauQ) + } + if len(tauP) < min(m, n) { + panic(badTauP) + } + if len(work) < max(m, n) { + panic(badWork) + } + if m >= n { + for i := 0; i < n; i++ { + a[i*lda+i], tauQ[i] = impl.Dlarfg(m-i, a[i*lda+i], a[min(i+1, m-1)*lda+i:], lda) + d[i] = a[i*lda+i] + a[i*lda+i] = 1 + // Apply H_i to A[i:m, i+1:n] from the left. + if i < n-1 { + impl.Dlarf(blas.Left, m-i, n-i-1, a[i*lda+i:], lda, tauQ[i], a[i*lda+i+1:], lda, work) + } + a[i*lda+i] = d[i] + if i < n-1 { + a[i*lda+i+1], tauP[i] = impl.Dlarfg(n-i-1, a[i*lda+i+1], a[i*lda+min(i+2, n-1):], 1) + e[i] = a[i*lda+i+1] + a[i*lda+i+1] = 1 + impl.Dlarf(blas.Right, m-i-1, n-i-1, a[i*lda+i+1:], 1, tauP[i], a[(i+1)*lda+i+1:], lda, work) + a[i*lda+i+1] = e[i] + } else { + tauP[i] = 0 + } + } + return + } + for i := 0; i < m; i++ { + a[i*lda+i], tauP[i] = impl.Dlarfg(n-i, a[i*lda+i], a[i*lda+min(i+1, n-1):], 1) + d[i] = a[i*lda+i] + a[i*lda+i] = 1 + if i < m-1 { + impl.Dlarf(blas.Right, m-i-1, n-i, a[i*lda+i:], 1, tauP[i], a[(i+1)*lda+i:], lda, work) + } + a[i*lda+i] = d[i] + if i < m-1 { + a[(i+1)*lda+i], tauQ[i] = impl.Dlarfg(m-i-1, a[(i+1)*lda+i], a[min(i+2, m-1)*lda+i:], lda) + e[i] = a[(i+1)*lda+i] + a[(i+1)*lda+i] = 1 + impl.Dlarf(blas.Left, m-i-1, n-i-1, a[(i+1)*lda+i:], lda, tauQ[i], a[(i+1)*lda+i+1:], lda, work) + a[(i+1)*lda+i] = e[i] + } else { + tauQ[i] = 0 + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgebrd.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebrd.go new file mode 100644 index 00000000..f0c041cc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgebrd.go @@ -0,0 +1,150 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dgebrd reduces a general m×n matrix A to upper or lower bidiagonal form B by +// an orthogonal transformation: +// Q^T * A * P = B. +// The diagonal elements of B are stored in d and the off-diagonal elements are stored +// in e. These are additionally stored along the diagonal of A and the off-diagonal +// of A. If m >= n B is an upper-bidiagonal matrix, and if m < n B is a +// lower-bidiagonal matrix. +// +// The remaining elements of A store the data needed to construct Q and P. +// The matrices Q and P are products of elementary reflectors +// if m >= n, Q = H_0 * H_1 * ... * H_{n-1}, +// P = G_0 * G_1 * ... * G_{n-2}, +// if m < n, Q = H_0 * H_1 * ... * H_{m-2}, +// P = G_0 * G_1 * ... * G_{m-1}, +// where +// H_i = I - tauQ[i] * v_i * v_i^T, +// G_i = I - tauP[i] * u_i * u_i^T. +// +// As an example, on exit the entries of A when m = 6, and n = 5 +// [ d e u1 u1 u1] +// [v1 d e u2 u2] +// [v1 v2 d e u3] +// [v1 v2 v3 d e] +// [v1 v2 v3 v4 d] +// [v1 v2 v3 v4 v5] +// and when m = 5, n = 6 +// [ d u1 u1 u1 u1 u1] +// [ e d u2 u2 u2 u2] +// [v1 e d u3 u3 u3] +// [v1 v2 e d u4 u4] +// [v1 v2 v3 e d u5] +// +// d, tauQ, and tauP must all have length at least min(m,n), and e must have +// length min(m,n) - 1, unless lwork is -1 when there is no check except for +// work which must have a length of at least one. +// +// work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= max(1,m,n) or be -1 and this function will panic otherwise. +// Dgebrd is blocked decomposition, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Dgebrd, +// the optimal work length will be stored into work[0]. +// +// Dgebrd is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgebrd(m, n int, a []float64, lda int, d, e, tauQ, tauP, work []float64, lwork int) { + checkMatrix(m, n, a, lda) + // Calculate optimal work. + nb := impl.Ilaenv(1, "DGEBRD", " ", m, n, -1, -1) + var lworkOpt int + if lwork == -1 { + if len(work) < 1 { + panic(badWork) + } + lworkOpt = ((m + n) * nb) + work[0] = float64(max(1, lworkOpt)) + return + } + minmn := min(m, n) + if len(d) < minmn { + panic(badD) + } + if len(e) < minmn-1 { + panic(badE) + } + if len(tauQ) < minmn { + panic(badTauQ) + } + if len(tauP) < minmn { + panic(badTauP) + } + ws := max(m, n) + if lwork < max(1, ws) { + panic(badWork) + } + if len(work) < lwork { + panic(badWork) + } + var nx int + if nb > 1 && nb < minmn { + nx = max(nb, impl.Ilaenv(3, "DGEBRD", " ", m, n, -1, -1)) + if nx < minmn { + ws = (m + n) * nb + if lwork < ws { + nbmin := impl.Ilaenv(2, "DGEBRD", " ", m, n, -1, -1) + if lwork >= (m+n)*nbmin { + nb = lwork / (m + n) + } else { + nb = minmn + nx = minmn + } + } + } + } else { + nx = minmn + } + bi := blas64.Implementation() + ldworkx := nb + ldworky := nb + var i int + // Netlib lapack has minmn - nx, but this makes the last nx rows (which by + // default is large) be unblocked. As written here, the blocking is more + // consistent. + for i = 0; i < minmn-nb; i += nb { + // Reduce rows and columns i:i+nb to bidiagonal form and return + // the matrices X and Y which are needed to update the unreduced + // part of the matrix. + // X is stored in the first m rows of work, y in the next rows. + x := work[:m*ldworkx] + y := work[m*ldworkx:] + impl.Dlabrd(m-i, n-i, nb, a[i*lda+i:], lda, + d[i:], e[i:], tauQ[i:], tauP[i:], + x, ldworkx, y, ldworky) + + // Update the trailing submatrix A[i+nb:m,i+nb:n], using an update + // of the form A := A - V*Y**T - X*U**T + bi.Dgemm(blas.NoTrans, blas.Trans, m-i-nb, n-i-nb, nb, + -1, a[(i+nb)*lda+i:], lda, y[nb*ldworky:], ldworky, + 1, a[(i+nb)*lda+i+nb:], lda) + + bi.Dgemm(blas.NoTrans, blas.NoTrans, m-i-nb, n-i-nb, nb, + -1, x[nb*ldworkx:], ldworkx, a[i*lda+i+nb:], lda, + 1, a[(i+nb)*lda+i+nb:], lda) + + // Copy diagonal and off-diagonal elements of B back into A. + if m >= n { + for j := i; j < i+nb; j++ { + a[j*lda+j] = d[j] + a[j*lda+j+1] = e[j] + } + } else { + for j := i; j < i+nb; j++ { + a[j*lda+j] = d[j] + a[(j+1)*lda+j] = e[j] + } + } + } + // Use unblocked code to reduce the remainder of the matrix. + impl.Dgebd2(m-i, n-i, a[i*lda+i:], lda, d[i:], e[i:], tauQ[i:], tauP[i:], work) + work[0] = float64(lworkOpt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgecon.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgecon.go new file mode 100644 index 00000000..20bafce4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgecon.go @@ -0,0 +1,81 @@ +// 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/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dgecon estimates the reciprocal of the condition number of the n×n matrix A +// given the LU decomposition of the matrix. The condition number computed may +// be based on the 1-norm or the ∞-norm. +// +// The slice a contains the result of the LU decomposition of A as computed by Dgetrf. +// +// anorm is the corresponding 1-norm or ∞-norm of the original matrix A. +// +// work is a temporary data slice of length at least 4*n and Dgecon will panic otherwise. +// +// iwork is a temporary data slice of length at least n and Dgecon will panic otherwise. +func (impl Implementation) Dgecon(norm lapack.MatrixNorm, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 { + checkMatrix(n, n, a, lda) + if norm != lapack.MaxColumnSum && norm != lapack.MaxRowSum { + panic(badNorm) + } + if len(work) < 4*n { + panic(badWork) + } + if len(iwork) < n { + panic(badWork) + } + + if n == 0 { + return 1 + } else if anorm == 0 { + return 0 + } + + bi := blas64.Implementation() + var rcond, ainvnm float64 + var kase int + var normin bool + isave := new([3]int) + onenrm := norm == lapack.MaxColumnSum + smlnum := dlamchS + kase1 := 2 + if onenrm { + kase1 = 1 + } + for { + ainvnm, kase = impl.Dlacn2(n, work[n:], work, iwork, ainvnm, kase, isave) + if kase == 0 { + if ainvnm != 0 { + rcond = (1 / ainvnm) / anorm + } + return rcond + } + var sl, su float64 + if kase == kase1 { + sl = impl.Dlatrs(blas.Lower, blas.NoTrans, blas.Unit, normin, n, a, lda, work, work[2*n:]) + su = impl.Dlatrs(blas.Upper, blas.NoTrans, blas.NonUnit, normin, n, a, lda, work, work[3*n:]) + } else { + su = impl.Dlatrs(blas.Upper, blas.Trans, blas.NonUnit, normin, n, a, lda, work, work[3*n:]) + sl = impl.Dlatrs(blas.Lower, blas.Trans, blas.Unit, normin, n, a, lda, work, work[2*n:]) + } + scale := sl * su + normin = true + if scale != 1 { + ix := bi.Idamax(n, work, 1) + if scale == 0 || scale < math.Abs(work[ix])*smlnum { + return rcond + } + impl.Drscl(n, scale, work, 1) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgeev.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeev.go new file mode 100644 index 00000000..7c2d9a29 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeev.go @@ -0,0 +1,284 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dgeev computes the eigenvalues and, optionally, the left and/or right +// eigenvectors for an n×n real nonsymmetric matrix A. +// +// The right eigenvector v_j of A corresponding to an eigenvalue λ_j +// is defined by +// A v_j = λ_j v_j, +// and the left eigenvector u_j corresponding to an eigenvalue λ_j is defined by +// u_j^H A = λ_j u_j^H, +// where u_j^H is the conjugate transpose of u_j. +// +// On return, A will be overwritten and the left and right eigenvectors will be +// stored, respectively, in the columns of the n×n matrices VL and VR in the +// same order as their eigenvalues. If the j-th eigenvalue is real, then +// u_j = VL[:,j], +// v_j = VR[:,j], +// and if it is not real, then j and j+1 form a complex conjugate pair and the +// eigenvectors can be recovered as +// u_j = VL[:,j] + i*VL[:,j+1], +// u_{j+1} = VL[:,j] - i*VL[:,j+1], +// v_j = VR[:,j] + i*VR[:,j+1], +// v_{j+1} = VR[:,j] - i*VR[:,j+1], +// where i is the imaginary unit. The computed eigenvectors are normalized to +// have Euclidean norm equal to 1 and largest component real. +// +// Left eigenvectors will be computed only if jobvl == lapack.ComputeLeftEV, +// otherwise jobvl must be lapack.None. Right eigenvectors will be computed +// only if jobvr == lapack.ComputeRightEV, otherwise jobvr must be lapack.None. +// For other values of jobvl and jobvr Dgeev will panic. +// +// wr and wi contain the real and imaginary parts, respectively, of the computed +// eigenvalues. Complex conjugate pairs of eigenvalues appear consecutively with +// the eigenvalue having the positive imaginary part first. +// wr and wi must have length n, and Dgeev will panic otherwise. +// +// work must have length at least lwork and lwork must be at least max(1,4*n) if +// the left or right eigenvectors are computed, and at least max(1,3*n) if no +// eigenvectors are computed. For good performance, lwork must generally be +// larger. On return, optimal value of lwork will be stored in work[0]. +// +// If lwork == -1, instead of performing Dgeev, the function only calculates the +// optimal vaule of lwork and stores it into work[0]. +// +// On return, first is the index of the first valid eigenvalue. If first == 0, +// all eigenvalues and eigenvectors have been computed. If first is positive, +// Dgeev failed to compute all the eigenvalues, no eigenvectors have been +// computed and wr[first:] and wi[first:] contain those eigenvalues which have +// converged. +func (impl Implementation) Dgeev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob, n int, a []float64, lda int, wr, wi []float64, vl []float64, ldvl int, vr []float64, ldvr int, work []float64, lwork int) (first int) { + var wantvl bool + switch jobvl { + default: + panic("lapack: invalid LeftEVJob") + case lapack.ComputeLeftEV: + wantvl = true + case lapack.None: + } + var wantvr bool + switch jobvr { + default: + panic("lapack: invalid RightEVJob") + case lapack.ComputeRightEV: + wantvr = true + case lapack.None: + } + switch { + case n < 0: + panic(nLT0) + case len(work) < lwork: + panic(shortWork) + } + var minwrk int + if wantvl || wantvr { + minwrk = max(1, 4*n) + } else { + minwrk = max(1, 3*n) + } + if lwork != -1 { + checkMatrix(n, n, a, lda) + if wantvl { + checkMatrix(n, n, vl, ldvl) + } + if wantvr { + checkMatrix(n, n, vr, ldvr) + } + switch { + case len(wr) != n: + panic("lapack: bad length of wr") + case len(wi) != n: + panic("lapack: bad length of wi") + case lwork < minwrk: + panic(badWork) + } + } + + // Quick return if possible. + if n == 0 { + work[0] = 1 + return 0 + } + + maxwrk := 2*n + n*impl.Ilaenv(1, "DGEHRD", " ", n, 1, n, 0) + if wantvl || wantvr { + maxwrk = max(maxwrk, 2*n+(n-1)*impl.Ilaenv(1, "DORGHR", " ", n, 1, n, -1)) + impl.Dhseqr(lapack.EigenvaluesAndSchur, lapack.OriginalEV, n, 0, n-1, + nil, 1, nil, nil, nil, 1, work, -1) + maxwrk = max(maxwrk, max(n+1, n+int(work[0]))) + side := lapack.LeftEV + if wantvr { + side = lapack.RightEV + } + impl.Dtrevc3(side, lapack.AllEVMulQ, nil, n, nil, 1, nil, 1, nil, 1, + n, work, -1) + maxwrk = max(maxwrk, n+int(work[0])) + maxwrk = max(maxwrk, 4*n) + } else { + impl.Dhseqr(lapack.EigenvaluesOnly, lapack.None, n, 0, n-1, + nil, 1, nil, nil, nil, 1, work, -1) + maxwrk = max(maxwrk, max(n+1, n+int(work[0]))) + } + maxwrk = max(maxwrk, minwrk) + + if lwork == -1 { + work[0] = float64(maxwrk) + return 0 + } + + // Get machine constants. + smlnum := math.Sqrt(dlamchS) / dlamchP + bignum := 1 / smlnum + + // Scale A if max element outside range [smlnum,bignum]. + anrm := impl.Dlange(lapack.MaxAbs, n, n, a, lda, nil) + var scalea bool + var cscale float64 + if 0 < anrm && anrm < smlnum { + scalea = true + cscale = smlnum + } else if anrm > bignum { + scalea = true + cscale = bignum + } + if scalea { + impl.Dlascl(lapack.General, 0, 0, anrm, cscale, n, n, a, lda) + } + + // Balance the matrix. + workbal := work[:n] + ilo, ihi := impl.Dgebal(lapack.PermuteScale, n, a, lda, workbal) + + // Reduce to upper Hessenberg form. + iwrk := 2 * n + tau := work[n : iwrk-1] + impl.Dgehrd(n, ilo, ihi, a, lda, tau, work[iwrk:], lwork-iwrk) + + var side lapack.EVSide + if wantvl { + side = lapack.LeftEV + // Copy Householder vectors to VL. + impl.Dlacpy(blas.Lower, n, n, a, lda, vl, ldvl) + // Generate orthogonal matrix in VL. + impl.Dorghr(n, ilo, ihi, vl, ldvl, tau, work[iwrk:], lwork-iwrk) + // Perform QR iteration, accumulating Schur vectors in VL. + iwrk = n + first = impl.Dhseqr(lapack.EigenvaluesAndSchur, lapack.OriginalEV, n, ilo, ihi, + a, lda, wr, wi, vl, ldvl, work[iwrk:], lwork-iwrk) + if wantvr { + // Want left and right eigenvectors. + // Copy Schur vectors to VR. + side = lapack.RightLeftEV + impl.Dlacpy(blas.All, n, n, vl, ldvl, vr, ldvr) + } + } else if wantvr { + side = lapack.RightEV + // Copy Householder vectors to VR. + impl.Dlacpy(blas.Lower, n, n, a, lda, vr, ldvr) + // Generate orthogonal matrix in VR. + impl.Dorghr(n, ilo, ihi, vr, ldvr, tau, work[iwrk:], lwork-iwrk) + // Perform QR iteration, accumulating Schur vectors in VR. + iwrk = n + first = impl.Dhseqr(lapack.EigenvaluesAndSchur, lapack.OriginalEV, n, ilo, ihi, + a, lda, wr, wi, vr, ldvr, work[iwrk:], lwork-iwrk) + } else { + // Compute eigenvalues only. + iwrk = n + first = impl.Dhseqr(lapack.EigenvaluesOnly, lapack.None, n, ilo, ihi, + a, lda, wr, wi, nil, 1, work[iwrk:], lwork-iwrk) + } + + if first > 0 { + if scalea { + // Undo scaling. + impl.Dlascl(lapack.General, 0, 0, cscale, anrm, n-first, 1, wr[first:], 1) + impl.Dlascl(lapack.General, 0, 0, cscale, anrm, n-first, 1, wi[first:], 1) + impl.Dlascl(lapack.General, 0, 0, cscale, anrm, ilo, 1, wr, 1) + impl.Dlascl(lapack.General, 0, 0, cscale, anrm, ilo, 1, wi, 1) + } + work[0] = float64(maxwrk) + return first + } + + if wantvl || wantvr { + // Compute left and/or right eigenvectors. + impl.Dtrevc3(side, lapack.AllEVMulQ, nil, n, + a, lda, vl, ldvl, vr, ldvr, n, work[iwrk:], lwork-iwrk) + } + bi := blas64.Implementation() + if wantvl { + // Undo balancing of left eigenvectors. + impl.Dgebak(lapack.PermuteScale, lapack.LeftEV, n, ilo, ihi, workbal, n, vl, ldvl) + // Normalize left eigenvectors and make largest component real. + for i, wii := range wi { + if wii < 0 { + continue + } + if wii == 0 { + scl := 1 / bi.Dnrm2(n, vl[i:], ldvl) + bi.Dscal(n, scl, vl[i:], ldvl) + continue + } + scl := 1 / impl.Dlapy2(bi.Dnrm2(n, vl[i:], ldvl), bi.Dnrm2(n, vl[i+1:], ldvl)) + bi.Dscal(n, scl, vl[i:], ldvl) + bi.Dscal(n, scl, vl[i+1:], ldvl) + for k := 0; k < n; k++ { + vi := vl[k*ldvl+i] + vi1 := vl[k*ldvl+i+1] + work[iwrk+k] = vi*vi + vi1*vi1 + } + k := bi.Idamax(n, work[iwrk:iwrk+n], 1) + cs, sn, _ := impl.Dlartg(vl[k*ldvl+i], vl[k*ldvl+i+1]) + bi.Drot(n, vl[i:], ldvl, vl[i+1:], ldvl, cs, sn) + vl[k*ldvl+i+1] = 0 + } + } + if wantvr { + // Undo balancing of right eigenvectors. + impl.Dgebak(lapack.PermuteScale, lapack.RightEV, n, ilo, ihi, workbal, n, vr, ldvr) + // Normalize right eigenvectors and make largest component real. + for i, wii := range wi { + if wii < 0 { + continue + } + if wii == 0 { + scl := 1 / bi.Dnrm2(n, vr[i:], ldvr) + bi.Dscal(n, scl, vr[i:], ldvr) + continue + } + scl := 1 / impl.Dlapy2(bi.Dnrm2(n, vr[i:], ldvr), bi.Dnrm2(n, vr[i+1:], ldvr)) + bi.Dscal(n, scl, vr[i:], ldvr) + bi.Dscal(n, scl, vr[i+1:], ldvr) + for k := 0; k < n; k++ { + vi := vr[k*ldvr+i] + vi1 := vr[k*ldvr+i+1] + work[iwrk+k] = vi*vi + vi1*vi1 + } + k := bi.Idamax(n, work[iwrk:iwrk+n], 1) + cs, sn, _ := impl.Dlartg(vr[k*ldvr+i], vr[k*ldvr+i+1]) + bi.Drot(n, vr[i:], ldvr, vr[i+1:], ldvr, cs, sn) + vr[k*ldvr+i+1] = 0 + } + } + + if scalea { + // Undo scaling. + impl.Dlascl(lapack.General, 0, 0, cscale, anrm, n-first, 1, wr[first:], 1) + impl.Dlascl(lapack.General, 0, 0, cscale, anrm, n-first, 1, wi[first:], 1) + } + + work[0] = float64(maxwrk) + return first +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgehd2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgehd2.go new file mode 100644 index 00000000..776f8421 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgehd2.go @@ -0,0 +1,84 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas" + +// Dgehd2 reduces a block of a general n×n matrix A to upper Hessenberg form H +// by an orthogonal similarity transformation Q^T * A * Q = H. +// +// The matrix Q is represented as a product of (ihi-ilo) elementary +// reflectors +// Q = H_{ilo} H_{ilo+1} ... H_{ihi-1}. +// Each H_i has the form +// H_i = I - tau[i] * v * v^T +// where v is a real vector with v[0:i+1] = 0, v[i+1] = 1 and v[ihi+1:n] = 0. +// v[i+2:ihi+1] is stored on exit in A[i+2:ihi+1,i]. +// +// On entry, a contains the n×n general matrix to be reduced. On return, the +// upper triangle and the first subdiagonal of A are overwritten with the upper +// Hessenberg matrix H, and the elements below the first subdiagonal, with the +// slice tau, represent the orthogonal matrix Q as a product of elementary +// reflectors. +// +// The contents of A are illustrated by the following example, with n = 7, ilo = +// 1 and ihi = 5. +// On entry, +// [ a a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a ] +// on return, +// [ a a h h h h a ] +// [ a h h h h a ] +// [ h h h h h h ] +// [ v1 h h h h h ] +// [ v1 v2 h h h h ] +// [ v1 v2 v3 h h h ] +// [ a ] +// where a denotes an element of the original matrix A, h denotes a +// modified element of the upper Hessenberg matrix H, and vi denotes an +// element of the vector defining H_i. +// +// ilo and ihi determine the block of A that will be reduced to upper Hessenberg +// form. It must hold that 0 <= ilo <= ihi <= max(0, n-1), otherwise Dgehd2 will +// panic. +// +// On return, tau will contain the scalar factors of the elementary reflectors. +// It must have length equal to n-1, otherwise Dgehd2 will panic. +// +// work must have length at least n, otherwise Dgehd2 will panic. +// +// Dgehd2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgehd2(n, ilo, ihi int, a []float64, lda int, tau, work []float64) { + checkMatrix(n, n, a, lda) + switch { + case ilo < 0 || ilo > max(0, n-1): + panic(badIlo) + case ihi < min(ilo, n-1) || ihi >= n: + panic(badIhi) + case len(tau) != n-1: + panic(badTau) + case len(work) < n: + panic(badWork) + } + + for i := ilo; i < ihi; i++ { + // Compute elementary reflector H_i to annihilate A[i+2:ihi+1,i]. + var aii float64 + aii, tau[i] = impl.Dlarfg(ihi-i, a[(i+1)*lda+i], a[min(i+2, n-1)*lda+i:], lda) + a[(i+1)*lda+i] = 1 + + // Apply H_i to A[0:ihi+1,i+1:ihi+1] from the right. + impl.Dlarf(blas.Right, ihi+1, ihi-i, a[(i+1)*lda+i:], lda, tau[i], a[i+1:], lda, work) + + // Apply H_i to A[i+1:ihi+1,i+1:n] from the left. + impl.Dlarf(blas.Left, ihi-i, n-i-1, a[(i+1)*lda+i:], lda, tau[i], a[(i+1)*lda+i+1:], lda, work) + a[(i+1)*lda+i] = aii + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgehrd.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgehrd.go new file mode 100644 index 00000000..0dd90fa5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgehrd.go @@ -0,0 +1,183 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dgehrd reduces a block of a real n×n general matrix A to upper Hessenberg +// form H by an orthogonal similarity transformation Q^T * A * Q = H. +// +// The matrix Q is represented as a product of (ihi-ilo) elementary +// reflectors +// Q = H_{ilo} H_{ilo+1} ... H_{ihi-1}. +// Each H_i has the form +// H_i = I - tau[i] * v * v^T +// where v is a real vector with v[0:i+1] = 0, v[i+1] = 1 and v[ihi+1:n] = 0. +// v[i+2:ihi+1] is stored on exit in A[i+2:ihi+1,i]. +// +// On entry, a contains the n×n general matrix to be reduced. On return, the +// upper triangle and the first subdiagonal of A will be overwritten with the +// upper Hessenberg matrix H, and the elements below the first subdiagonal, with +// the slice tau, represent the orthogonal matrix Q as a product of elementary +// reflectors. +// +// The contents of a are illustrated by the following example, with n = 7, ilo = +// 1 and ihi = 5. +// On entry, +// [ a a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a a a a a a ] +// [ a ] +// on return, +// [ a a h h h h a ] +// [ a h h h h a ] +// [ h h h h h h ] +// [ v1 h h h h h ] +// [ v1 v2 h h h h ] +// [ v1 v2 v3 h h h ] +// [ a ] +// where a denotes an element of the original matrix A, h denotes a +// modified element of the upper Hessenberg matrix H, and vi denotes an +// element of the vector defining H_i. +// +// ilo and ihi determine the block of A that will be reduced to upper Hessenberg +// form. It must hold that 0 <= ilo <= ihi < n if n > 0, and ilo == 0 and ihi == +// -1 if n == 0, otherwise Dgehrd will panic. +// +// On return, tau will contain the scalar factors of the elementary reflectors. +// Elements tau[:ilo] and tau[ihi:] will be set to zero. tau must have length +// equal to n-1 if n > 0, otherwise Dgehrd will panic. +// +// work must have length at least lwork and lwork must be at least max(1,n), +// otherwise Dgehrd will panic. On return, work[0] contains the optimal value of +// lwork. +// +// If lwork == -1, instead of performing Dgehrd, only the optimal value of lwork +// will be stored in work[0]. +// +// Dgehrd is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgehrd(n, ilo, ihi int, a []float64, lda int, tau, work []float64, lwork int) { + switch { + case ilo < 0 || max(0, n-1) < ilo: + panic(badIlo) + case ihi < min(ilo, n-1) || n <= ihi: + panic(badIhi) + case lwork < max(1, n) && lwork != -1: + panic(badWork) + case len(work) < lwork: + panic(shortWork) + } + if lwork != -1 { + checkMatrix(n, n, a, lda) + if len(tau) != n-1 && n > 0 { + panic(badTau) + } + } + + const ( + nbmax = 64 + ldt = nbmax + 1 + tsize = ldt * nbmax + ) + // Compute the workspace requirements. + nb := min(nbmax, impl.Ilaenv(1, "DGEHRD", " ", n, ilo, ihi, -1)) + lwkopt := n*nb + tsize + if lwork == -1 { + work[0] = float64(lwkopt) + return + } + + // Set tau[:ilo] and tau[ihi:] to zero. + for i := 0; i < ilo; i++ { + tau[i] = 0 + } + for i := ihi; i < n-1; i++ { + tau[i] = 0 + } + + // Quick return if possible. + nh := ihi - ilo + 1 + if nh <= 1 { + work[0] = 1 + return + } + + // Determine the block size. + nbmin := 2 + var nx int + if 1 < nb && nb < nh { + // Determine when to cross over from blocked to unblocked code + // (last block is always handled by unblocked code). + nx = max(nb, impl.Ilaenv(3, "DGEHRD", " ", n, ilo, ihi, -1)) + if nx < nh { + // Determine if workspace is large enough for blocked code. + if lwork < n*nb+tsize { + // Not enough workspace to use optimal nb: + // determine the minimum value of nb, and reduce + // nb or force use of unblocked code. + nbmin = max(2, impl.Ilaenv(2, "DGEHRD", " ", n, ilo, ihi, -1)) + if lwork >= n*nbmin+tsize { + nb = (lwork - tsize) / n + } else { + nb = 1 + } + } + } + } + ldwork := nb // work is used as an n×nb matrix. + + var i int + if nb < nbmin || nh <= nb { + // Use unblocked code below. + i = ilo + } else { + // Use blocked code. + bi := blas64.Implementation() + iwt := n * nb // Size of the matrix Y and index where the matrix T starts in work. + for i = ilo; i < ihi-nx; i += nb { + ib := min(nb, ihi-i) + + // Reduce columns [i:i+ib] to Hessenberg form, returning the + // matrices V and T of the block reflector H = I - V*T*V^T + // which performs the reduction, and also the matrix Y = A*V*T. + impl.Dlahr2(ihi+1, i+1, ib, a[i:], lda, tau[i:], work[iwt:], ldt, work, ldwork) + + // Apply the block reflector H to A[:ihi+1,i+ib:ihi+1] from the + // right, computing A := A - Y * V^T. V[i+ib,i+ib-1] must be set + // to 1. + ei := a[(i+ib)*lda+i+ib-1] + a[(i+ib)*lda+i+ib-1] = 1 + bi.Dgemm(blas.NoTrans, blas.Trans, ihi+1, ihi-i-ib+1, ib, + -1, work, ldwork, + a[(i+ib)*lda+i:], lda, + 1, a[i+ib:], lda) + a[(i+ib)*lda+i+ib-1] = ei + + // Apply the block reflector H to A[0:i+1,i+1:i+ib-1] from the + // right. + bi.Dtrmm(blas.Right, blas.Lower, blas.Trans, blas.Unit, i+1, ib-1, + 1, a[(i+1)*lda+i:], lda, work, ldwork) + for j := 0; j <= ib-2; j++ { + bi.Daxpy(i+1, -1, work[j:], ldwork, a[i+j+1:], lda) + } + + // Apply the block reflector H to A[i+1:ihi+1,i+ib:n] from the + // left. + impl.Dlarfb(blas.Left, blas.Trans, lapack.Forward, lapack.ColumnWise, + ihi-i, n-i-ib, ib, + a[(i+1)*lda+i:], lda, work[iwt:], ldt, a[(i+1)*lda+i+ib:], lda, work, ldwork) + } + } + // Use unblocked code to reduce the rest of the matrix. + impl.Dgehd2(n, i, ihi, a, lda, tau, work) + work[0] = float64(lwkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgelq2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgelq2.go new file mode 100644 index 00000000..2e4fd692 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgelq2.go @@ -0,0 +1,49 @@ +// 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/blas" + +// Dgelq2 computes the LQ factorization of the m×n matrix A. +// +// In an LQ factorization, L is a lower triangular m×n matrix, and Q is an n×n +// orthonormal matrix. +// +// a is modified to contain the information to construct L and Q. +// The lower triangle of a contains the matrix L. The upper triangular elements +// (not including the diagonal) contain the elementary reflectors. tau is modified +// to contain the reflector scales. tau must have length of at least k = min(m,n) +// and this function will panic otherwise. +// +// See Dgeqr2 for a description of the elementary reflectors and orthonormal +// matrix Q. Q is constructed as a product of these elementary reflectors, +// Q = H_{k-1} * ... * H_1 * H_0. +// +// work is temporary storage of length at least m and this function will panic otherwise. +// +// Dgelq2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgelq2(m, n int, a []float64, lda int, tau, work []float64) { + checkMatrix(m, n, a, lda) + k := min(m, n) + if len(tau) < k { + panic(badTau) + } + if len(work) < m { + panic(badWork) + } + for i := 0; i < k; i++ { + a[i*lda+i], tau[i] = impl.Dlarfg(n-i, a[i*lda+i], a[i*lda+min(i+1, n-1):], 1) + if i < m-1 { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(blas.Right, m-i-1, n-i, + a[i*lda+i:], 1, + tau[i], + a[(i+1)*lda+i:], lda, + work) + a[i*lda+i] = aii + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgelqf.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgelqf.go new file mode 100644 index 00000000..13485012 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgelqf.go @@ -0,0 +1,84 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dgelqf computes the LQ factorization of the m×n matrix A using a blocked +// algorithm. See the documentation for Dgelq2 for a description of the +// parameters at entry and exit. +// +// work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= m, and this function will panic otherwise. +// Dgelqf is a blocked LQ factorization, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Dgelqf, +// the optimal work length will be stored into work[0]. +// +// tau must have length at least min(m,n), and this function will panic otherwise. +func (impl Implementation) Dgelqf(m, n int, a []float64, lda int, tau, work []float64, lwork int) { + nb := impl.Ilaenv(1, "DGELQF", " ", m, n, -1, -1) + lworkopt := m * max(nb, 1) + if lwork == -1 { + work[0] = float64(lworkopt) + return + } + checkMatrix(m, n, a, lda) + if len(work) < lwork { + panic(shortWork) + } + if lwork < m { + panic(badWork) + } + k := min(m, n) + if len(tau) < k { + panic(badTau) + } + if k == 0 { + return + } + // Find the optimal blocking size based on the size of available memory + // and optimal machine parameters. + nbmin := 2 + var nx int + iws := m + ldwork := nb + if nb > 1 && k > nb { + nx = max(0, impl.Ilaenv(3, "DGELQF", " ", m, n, -1, -1)) + if nx < k { + iws = m * nb + if lwork < iws { + nb = lwork / m + nbmin = max(2, impl.Ilaenv(2, "DGELQF", " ", m, n, -1, -1)) + } + } + } + // Computed blocked LQ factorization. + var i int + if nb >= nbmin && nb < k && nx < k { + for i = 0; i < k-nx; i += nb { + ib := min(k-i, nb) + impl.Dgelq2(ib, n-i, a[i*lda+i:], lda, tau[i:], work) + if i+ib < m { + impl.Dlarft(lapack.Forward, lapack.RowWise, n-i, ib, + a[i*lda+i:], lda, + tau[i:], + work, ldwork) + impl.Dlarfb(blas.Right, blas.NoTrans, lapack.Forward, lapack.RowWise, + m-i-ib, n-i, ib, + a[i*lda+i:], lda, + work, ldwork, + a[(i+ib)*lda+i:], lda, + work[ib*ldwork:], ldwork) + } + } + } + // Perform unblocked LQ factorization on the remainder. + if i < k { + impl.Dgelq2(m-i, n-i, a[i*lda+i:], lda, tau[i:], work) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgels.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgels.go new file mode 100644 index 00000000..b1d71823 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgels.go @@ -0,0 +1,200 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dgels finds a minimum-norm solution based on the matrices A and B using the +// QR or LQ factorization. Dgels returns false if the matrix +// A is singular, and true if this solution was successfully found. +// +// The minimization problem solved depends on the input parameters. +// +// 1. If m >= n and trans == blas.NoTrans, Dgels finds X such that || A*X - B||_2 +// is minimized. +// 2. If m < n and trans == blas.NoTrans, Dgels finds the minimum norm solution of +// A * X = B. +// 3. If m >= n and trans == blas.Trans, Dgels finds the minimum norm solution of +// A^T * X = B. +// 4. If m < n and trans == blas.Trans, Dgels finds X such that || A*X - B||_2 +// is minimized. +// Note that the least-squares solutions (cases 1 and 3) perform the minimization +// per column of B. This is not the same as finding the minimum-norm matrix. +// +// The matrix A is a general matrix of size m×n and is modified during this call. +// The input matrix B is of size max(m,n)×nrhs, and serves two purposes. On entry, +// the elements of b specify the input matrix B. B has size m×nrhs if +// trans == blas.NoTrans, and n×nrhs if trans == blas.Trans. On exit, the +// leading submatrix of b contains the solution vectors X. If trans == blas.NoTrans, +// this submatrix is of size n×nrhs, and of size m×nrhs otherwise. +// +// work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= max(m,n) + max(m,n,nrhs), and this function will panic +// otherwise. A longer work will enable blocked algorithms to be called. +// In the special case that lwork == -1, work[0] will be set to the optimal working +// length. +func (impl Implementation) Dgels(trans blas.Transpose, m, n, nrhs int, a []float64, lda int, b []float64, ldb int, work []float64, lwork int) bool { + notran := trans == blas.NoTrans + checkMatrix(m, n, a, lda) + mn := min(m, n) + checkMatrix(max(m, n), nrhs, b, ldb) + + // Find optimal block size. + tpsd := true + if notran { + tpsd = false + } + var nb int + if m >= n { + nb = impl.Ilaenv(1, "DGEQRF", " ", m, n, -1, -1) + if tpsd { + nb = max(nb, impl.Ilaenv(1, "DORMQR", "LN", m, nrhs, n, -1)) + } else { + nb = max(nb, impl.Ilaenv(1, "DORMQR", "LT", m, nrhs, n, -1)) + } + } else { + nb = impl.Ilaenv(1, "DGELQF", " ", m, n, -1, -1) + if tpsd { + nb = max(nb, impl.Ilaenv(1, "DORMLQ", "LT", n, nrhs, m, -1)) + } else { + nb = max(nb, impl.Ilaenv(1, "DORMLQ", "LN", n, nrhs, m, -1)) + } + } + if lwork == -1 { + work[0] = float64(max(1, mn+max(mn, nrhs)*nb)) + return true + } + + if len(work) < lwork { + panic(shortWork) + } + if lwork < mn+max(mn, nrhs) { + panic(badWork) + } + if m == 0 || n == 0 || nrhs == 0 { + impl.Dlaset(blas.All, max(m, n), nrhs, 0, 0, b, ldb) + return true + } + + // Scale the input matrices if they contain extreme values. + smlnum := dlamchS / dlamchP + bignum := 1 / smlnum + anrm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, nil) + var iascl int + if anrm > 0 && anrm < smlnum { + impl.Dlascl(lapack.General, 0, 0, anrm, smlnum, m, n, a, lda) + iascl = 1 + } else if anrm > bignum { + impl.Dlascl(lapack.General, 0, 0, anrm, bignum, m, n, a, lda) + } else if anrm == 0 { + // Matrix is all zeros. + impl.Dlaset(blas.All, max(m, n), nrhs, 0, 0, b, ldb) + return true + } + brow := m + if tpsd { + brow = n + } + bnrm := impl.Dlange(lapack.MaxAbs, brow, nrhs, b, ldb, nil) + ibscl := 0 + if bnrm > 0 && bnrm < smlnum { + impl.Dlascl(lapack.General, 0, 0, bnrm, smlnum, brow, nrhs, b, ldb) + ibscl = 1 + } else if bnrm > bignum { + impl.Dlascl(lapack.General, 0, 0, bnrm, bignum, brow, nrhs, b, ldb) + ibscl = 2 + } + + // Solve the minimization problem using a QR or an LQ decomposition. + var scllen int + if m >= n { + impl.Dgeqrf(m, n, a, lda, work, work[mn:], lwork-mn) + if !tpsd { + impl.Dormqr(blas.Left, blas.Trans, m, nrhs, n, + a, lda, + work[:n], + b, ldb, + work[mn:], lwork-mn) + ok := impl.Dtrtrs(blas.Upper, blas.NoTrans, blas.NonUnit, n, nrhs, + a, lda, + b, ldb) + if !ok { + return false + } + scllen = n + } else { + ok := impl.Dtrtrs(blas.Upper, blas.Trans, blas.NonUnit, n, nrhs, + a, lda, + b, ldb) + if !ok { + return false + } + for i := n; i < m; i++ { + for j := 0; j < nrhs; j++ { + b[i*ldb+j] = 0 + } + } + impl.Dormqr(blas.Left, blas.NoTrans, m, nrhs, n, + a, lda, + work[:n], + b, ldb, + work[mn:], lwork-mn) + scllen = m + } + } else { + impl.Dgelqf(m, n, a, lda, work, work[mn:], lwork-mn) + if !tpsd { + ok := impl.Dtrtrs(blas.Lower, blas.NoTrans, blas.NonUnit, + m, nrhs, + a, lda, + b, ldb) + if !ok { + return false + } + for i := m; i < n; i++ { + for j := 0; j < nrhs; j++ { + b[i*ldb+j] = 0 + } + } + impl.Dormlq(blas.Left, blas.Trans, n, nrhs, m, + a, lda, + work, + b, ldb, + work[mn:], lwork-mn) + scllen = n + } else { + impl.Dormlq(blas.Left, blas.NoTrans, n, nrhs, m, + a, lda, + work, + b, ldb, + work[mn:], lwork-mn) + ok := impl.Dtrtrs(blas.Lower, blas.Trans, blas.NonUnit, + m, nrhs, + a, lda, + b, ldb) + if !ok { + return false + } + } + } + + // Adjust answer vector based on scaling. + if iascl == 1 { + impl.Dlascl(lapack.General, 0, 0, anrm, smlnum, scllen, nrhs, b, ldb) + } + if iascl == 2 { + impl.Dlascl(lapack.General, 0, 0, anrm, bignum, scllen, nrhs, b, ldb) + } + if ibscl == 1 { + impl.Dlascl(lapack.General, 0, 0, smlnum, bnrm, scllen, nrhs, b, ldb) + } + if ibscl == 2 { + impl.Dlascl(lapack.General, 0, 0, bignum, bnrm, scllen, nrhs, b, ldb) + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgeql2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeql2.go new file mode 100644 index 00000000..19040cfa --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeql2.go @@ -0,0 +1,45 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas" + +// Dgeql2 computes the QL factorization of the m×n matrix A. That is, Dgeql2 +// computes Q and L such that +// A = Q * L +// where Q is an m×m orthonormal matrix and L is a lower trapezoidal matrix. +// +// Q is represented as a product of elementary reflectors, +// Q = H_{k-1} * ... * H_1 * H_0 +// where k = min(m,n) and each H_i has the form +// H_i = I - tau[i] * v_i * v_i^T +// Vector v_i has v[m-k+i+1:m] = 0, v[m-k+i] = 1, and v[:m-k+i+1] is stored on +// exit in A[0:m-k+i-1, n-k+i]. +// +// tau must have length at least min(m,n), and Dgeql2 will panic otherwise. +// +// work is temporary memory storage and must have length at least n. +// +// Dgeql2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgeql2(m, n int, a []float64, lda int, tau, work []float64) { + checkMatrix(m, n, a, lda) + if len(tau) < min(m, n) { + panic(badTau) + } + if len(work) < n { + panic(badWork) + } + k := min(m, n) + var aii float64 + for i := k - 1; i >= 0; i-- { + // Generate elementary reflector H_i to annihilate A[0:m-k+i-1, n-k+i]. + aii, tau[i] = impl.Dlarfg(m-k+i+1, a[(m-k+i)*lda+n-k+i], a[n-k+i:], lda) + + // Apply H_i to A[0:m-k+i, 0:n-k+i-1] from the left. + a[(m-k+i)*lda+n-k+i] = 1 + impl.Dlarf(blas.Left, m-k+i+1, n-k+i, a[n-k+i:], lda, tau[i], a, lda, work) + a[(m-k+i)*lda+n-k+i] = aii + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqp3.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqp3.go new file mode 100644 index 00000000..50529cac --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqp3.go @@ -0,0 +1,174 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dgeqp3 computes a QR factorization with column pivoting of the +// m×n matrix A: A*P = Q*R using Level 3 BLAS. +// +// The matrix Q is represented as a product of elementary reflectors +// Q = H_0 H_1 . . . H_{k-1}, where k = min(m,n). +// Each H_i has the form +// H_i = I - tau * v * v^T +// where tau and v are real vectors with v[0:i-1] = 0 and v[i] = 1; +// v[i:m] is stored on exit in A[i:m, i], and tau in tau[i]. +// +// jpvt specifies a column pivot to be applied to A. If +// jpvt[j] is at least zero, the jth column of A is permuted +// to the front of A*P (a leading column), if jpvt[j] is -1 +// the jth column of A is a free column. If jpvt[j] < -1, Dgeqp3 +// will panic. On return, jpvt holds the permutation that was +// applied; the jth column of A*P was the jpvt[j] column of A. +// jpvt must have length n or Dgeqp3 will panic. +// +// tau holds the scalar factors of the elementary reflectors. +// It must have length min(m, n), otherwise Dgeqp3 will panic. +// +// work must have length at least max(1,lwork), and lwork must be at least +// 3*n+1, otherwise Dgeqp3 will panic. For optimal performance lwork must +// be at least 2*n+(n+1)*nb, where nb is the optimal blocksize. On return, +// work[0] will contain the optimal value of lwork. +// +// If lwork == -1, instead of performing Dgeqp3, only the optimal value of lwork +// will be stored in work[0]. +// +// Dgeqp3 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgeqp3(m, n int, a []float64, lda int, jpvt []int, tau, work []float64, lwork int) { + const ( + inb = 1 + inbmin = 2 + ixover = 3 + ) + checkMatrix(m, n, a, lda) + + if len(jpvt) != n { + panic(badIpiv) + } + for _, v := range jpvt { + if v < -1 || n <= v { + panic("lapack: jpvt element out of range") + } + } + minmn := min(m, n) + if len(work) < max(1, lwork) { + panic(badWork) + } + + var iws, lwkopt, nb int + if minmn == 0 { + iws = 1 + lwkopt = 1 + } else { + iws = 3*n + 1 + nb = impl.Ilaenv(inb, "DGEQRF", " ", m, n, -1, -1) + lwkopt = 2*n + (n+1)*nb + } + work[0] = float64(lwkopt) + + if lwork == -1 { + return + } + + if len(tau) < minmn { + panic(badTau) + } + + bi := blas64.Implementation() + + // Move initial columns up front. + var nfxd int + for j := 0; j < n; j++ { + if jpvt[j] == -1 { + jpvt[j] = j + continue + } + if j != nfxd { + bi.Dswap(m, a[j:], lda, a[nfxd:], lda) + jpvt[j], jpvt[nfxd] = jpvt[nfxd], j + } else { + jpvt[j] = j + } + nfxd++ + } + + // Factorize nfxd columns. + // + // Compute the QR factorization of nfxd columns and update remaining columns. + if nfxd > 0 { + na := min(m, nfxd) + impl.Dgeqrf(m, na, a, lda, tau, work, lwork) + iws = max(iws, int(work[0])) + if na < n { + impl.Dormqr(blas.Left, blas.Trans, m, n-na, na, a, lda, tau[:na], a[na:], lda, + work, lwork) + iws = max(iws, int(work[0])) + } + } + + if nfxd >= minmn { + work[0] = float64(iws) + return + } + + // Factorize free columns. + sm := m - nfxd + sn := n - nfxd + sminmn := minmn - nfxd + + // Determine the block size. + nb = impl.Ilaenv(inb, "DGEQRF", " ", sm, sn, -1, -1) + nbmin := 2 + nx := 0 + + if 1 < nb && nb < sminmn { + // Determine when to cross over from blocked to unblocked code. + nx = max(0, impl.Ilaenv(ixover, "DGEQRF", " ", sm, sn, -1, -1)) + + if nx < sminmn { + // Determine if workspace is large enough for blocked code. + minws := 2*sn + (sn+1)*nb + iws = max(iws, minws) + if lwork < minws { + // Not enough workspace to use optimal nb. Reduce + // nb and determine the minimum value of nb. + nb = (lwork - 2*sn) / (sn + 1) + nbmin = max(2, impl.Ilaenv(inbmin, "DGEQRF", " ", sm, sn, -1, -1)) + } + } + } + + // Initialize partial column norms. + // The first n elements of work store the exact column norms. + for j := nfxd; j < n; j++ { + work[j] = bi.Dnrm2(sm, a[nfxd*lda+j:], lda) + work[n+j] = work[j] + } + j := nfxd + if nbmin <= nb && nb < sminmn && nx < sminmn { + // Use blocked code initially. + + // Compute factorization. + var fjb int + for topbmn := minmn - nx; j < topbmn; j += fjb { + jb := min(nb, topbmn-j) + + // Factorize jb columns among columns j:n. + fjb = impl.Dlaqps(m, n-j, j, jb, a[j:], lda, jpvt[j:], tau[j:], + work[j:n], work[j+n:2*n], work[2*n:2*n+jb], work[2*n+jb:], jb) + } + } + + // Use unblocked code to factor the last or only block. + if j < minmn { + impl.Dlaqp2(m, n-j, j, a[j:], lda, jpvt[j:], tau[j:], + work[j:n], work[j+n:2*n], work[2*n:]) + } + + work[0] = float64(iws) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqr2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqr2.go new file mode 100644 index 00000000..6b032063 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqr2.go @@ -0,0 +1,59 @@ +// 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/blas" + +// Dgeqr2 computes a QR factorization of the m×n matrix A. +// +// In a QR factorization, Q is an m×m orthonormal matrix, and R is an +// upper triangular m×n matrix. +// +// A is modified to contain the information to construct Q and R. +// The upper triangle of a contains the matrix R. The lower triangular elements +// (not including the diagonal) contain the elementary reflectors. tau is modified +// to contain the reflector scales. tau must have length at least min(m,n), and +// this function will panic otherwise. +// +// The ith elementary reflector can be explicitly constructed by first extracting +// the +// v[j] = 0 j < i +// v[j] = 1 j == i +// v[j] = a[j*lda+i] j > i +// and computing H_i = I - tau[i] * v * v^T. +// +// The orthonormal matrix Q can be constructed from a product of these elementary +// reflectors, Q = H_0 * H_1 * ... * H_{k-1}, where k = min(m,n). +// +// work is temporary storage of length at least n and this function will panic otherwise. +// +// Dgeqr2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgeqr2(m, n int, a []float64, lda int, tau, work []float64) { + // TODO(btracey): This is oriented such that columns of a are eliminated. + // This likely could be re-arranged to take better advantage of row-major + // storage. + checkMatrix(m, n, a, lda) + if len(work) < n { + panic(badWork) + } + k := min(m, n) + if len(tau) < k { + panic(badTau) + } + for i := 0; i < k; i++ { + // Generate elementary reflector H_i. + a[i*lda+i], tau[i] = impl.Dlarfg(m-i, a[i*lda+i], a[min((i+1), m-1)*lda+i:], lda) + if i < n-1 { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(blas.Left, m-i, n-i-1, + a[i*lda+i:], lda, + tau[i], + a[i*lda+i+1:], lda, + work) + a[i*lda+i] = aii + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqrf.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqrf.go new file mode 100644 index 00000000..c5662c91 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgeqrf.go @@ -0,0 +1,99 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dgeqrf computes the QR factorization of the m×n matrix A using a blocked +// algorithm. See the documentation for Dgeqr2 for a description of the +// parameters at entry and exit. +// +// work is temporary storage, and lwork specifies the usable memory length. +// The length of work must be at least max(1, lwork) and lwork must be -1 +// or at least n, otherwise this function will panic. +// Dgeqrf is a blocked QR factorization, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Dgeqrf, +// the optimal work length will be stored into work[0]. +// +// tau must have length at least min(m,n), and this function will panic otherwise. +func (impl Implementation) Dgeqrf(m, n int, a []float64, lda int, tau, work []float64, lwork int) { + if len(work) < max(1, lwork) { + panic(shortWork) + } + // nb is the optimal blocksize, i.e. the number of columns transformed at a time. + nb := impl.Ilaenv(1, "DGEQRF", " ", m, n, -1, -1) + lworkopt := n * max(nb, 1) + lworkopt = max(n, lworkopt) + if lwork == -1 { + work[0] = float64(lworkopt) + return + } + checkMatrix(m, n, a, lda) + if lwork < n { + panic(badWork) + } + k := min(m, n) + if len(tau) < k { + panic(badTau) + } + if k == 0 { + work[0] = float64(lworkopt) + return + } + nbmin := 2 // Minimal block size. + var nx int // Use unblocked (unless changed in the next for loop) + iws := n + ldwork := nb + // Only consider blocked if the suggested block size is > 1 and the + // number of rows or columns is sufficiently large. + if 1 < nb && nb < k { + // nx is the block size at which the code switches from blocked + // to unblocked. + nx = max(0, impl.Ilaenv(3, "DGEQRF", " ", m, n, -1, -1)) + if k > nx { + iws = ldwork * n + if lwork < iws { + // Not enough workspace to use the optimal block + // size. Get the minimum block size instead. + nb = lwork / n + nbmin = max(2, impl.Ilaenv(2, "DGEQRF", " ", m, n, -1, -1)) + } + } + } + for i := range work { + work[i] = 0 + } + // Compute QR using a blocked algorithm. + var i int + if nbmin <= nb && nb < k && nx < k { + for i = 0; i < k-nx; i += nb { + ib := min(k-i, nb) + // Compute the QR factorization of the current block. + impl.Dgeqr2(m-i, ib, a[i*lda+i:], lda, tau[i:], work) + if i+ib < n { + // Form the triangular factor of the block reflector and apply H^T + // In Dlarft, work becomes the T matrix. + impl.Dlarft(lapack.Forward, lapack.ColumnWise, m-i, ib, + a[i*lda+i:], lda, + tau[i:], + work, ldwork) + impl.Dlarfb(blas.Left, blas.Trans, lapack.Forward, lapack.ColumnWise, + m-i, n-i-ib, ib, + a[i*lda+i:], lda, + work, ldwork, + a[i*lda+i+ib:], lda, + work[ib*ldwork:], ldwork) + } + } + } + // Call unblocked code on the remaining columns. + if i < k { + impl.Dgeqr2(m-i, n-i, a[i*lda+i:], lda, tau[i:], work) + } + work[0] = float64(lworkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgerq2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgerq2.go new file mode 100644 index 00000000..ef20a022 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgerq2.go @@ -0,0 +1,53 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas" + +// Dgerq2 computes an RQ factorization of the m×n matrix A, +// A = R * Q. +// On exit, if m <= n, the upper triangle of the subarray +// A[0:m, n-m:n] contains the m×m upper triangular matrix R. +// If m >= n, the elements on and above the (m-n)-th subdiagonal +// contain the m×n upper trapezoidal matrix R. +// The remaining elements, with tau, represent the +// orthogonal matrix Q as a product of min(m,n) elementary +// reflectors. +// +// The matrix Q is represented as a product of elementary reflectors +// Q = H_0 H_1 . . . H_{min(m,n)-1}. +// Each H(i) has the form +// H_i = I - tau_i * v * v^T +// where v is a vector with v[0:n-k+i-1] stored in A[m-k+i, 0:n-k+i-1], +// v[n-k+i:n] = 0 and v[n-k+i] = 1. +// +// tau must have length min(m,n) and work must have length m, otherwise +// Dgerq2 will panic. +// +// Dgerq2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgerq2(m, n int, a []float64, lda int, tau, work []float64) { + checkMatrix(m, n, a, lda) + k := min(m, n) + if len(tau) < k { + panic(badTau) + } + if len(work) < m { + panic(badWork) + } + + for i := k - 1; i >= 0; i-- { + // Generate elementary reflector H[i] to annihilate + // A[m-k+i, 0:n-k+i-1]. + mki := m - k + i + nki := n - k + i + var aii float64 + aii, tau[i] = impl.Dlarfg(nki+1, a[mki*lda+nki], a[mki*lda:], 1) + + // Apply H[i] to A[0:m-k+i-1, 0:n-k+i] from the right. + a[mki*lda+nki] = 1 + impl.Dlarf(blas.Right, mki, nki+1, a[mki*lda:], 1, tau[i], a, lda, work) + a[mki*lda+nki] = aii + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgerqf.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgerqf.go new file mode 100644 index 00000000..daf8f0d0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgerqf.go @@ -0,0 +1,128 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dgerqf computes an RQ factorization of the m×n matrix A, +// A = R * Q. +// On exit, if m <= n, the upper triangle of the subarray +// A[0:m, n-m:n] contains the m×m upper triangular matrix R. +// If m >= n, the elements on and above the (m-n)-th subdiagonal +// contain the m×n upper trapezoidal matrix R. +// The remaining elements, with tau, represent the +// orthogonal matrix Q as a product of min(m,n) elementary +// reflectors. +// +// The matrix Q is represented as a product of elementary reflectors +// Q = H_0 H_1 . . . H_{min(m,n)-1}. +// Each H(i) has the form +// H_i = I - tau_i * v * v^T +// where v is a vector with v[0:n-k+i-1] stored in A[m-k+i, 0:n-k+i-1], +// v[n-k+i:n] = 0 and v[n-k+i] = 1. +// +// tau must have length min(m,n), work must have length max(1, lwork), +// and lwork must be -1 or at least max(1, m), otherwise Dgerqf will panic. +// On exit, work[0] will contain the optimal length for work. +// +// Dgerqf is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dgerqf(m, n int, a []float64, lda int, tau, work []float64, lwork int) { + checkMatrix(m, n, a, lda) + + if len(work) < max(1, lwork) { + panic(shortWork) + } + if lwork != -1 && lwork < max(1, m) { + panic(badWork) + } + + k := min(m, n) + if len(tau) != k { + panic(badTau) + } + + var nb, lwkopt int + if k == 0 { + lwkopt = 1 + } else { + nb = impl.Ilaenv(1, "DGERQF", " ", m, n, -1, -1) + lwkopt = m * nb + } + work[0] = float64(lwkopt) + + if lwork == -1 { + return + } + + // Return quickly if possible. + if k == 0 { + return + } + + nbmin := 2 + nx := 1 + iws := m + var ldwork int + if 1 < nb && nb < k { + // Determine when to cross over from blocked to unblocked code. + nx = max(0, impl.Ilaenv(3, "DGERQF", " ", m, n, -1, -1)) + if nx < k { + // Determine whether workspace is large enough for blocked code. + iws = m * nb + if lwork < iws { + // Not enough workspace to use optimal nb. Reduce + // nb and determine the minimum value of nb. + nb = lwork / m + nbmin = max(2, impl.Ilaenv(2, "DGERQF", " ", m, n, -1, -1)) + } + ldwork = nb + } + } + + var mu, nu int + if nbmin <= nb && nb < k && nx < k { + // Use blocked code initially. + // The last kk rows are handled by the block method. + ki := ((k - nx - 1) / nb) * nb + kk := min(k, ki+nb) + + var i int + for i = k - kk + ki; i >= k-kk; i -= nb { + ib := min(k-i, nb) + + // Compute the RQ factorization of the current block + // A[m-k+i:m-k+i+ib-1, 0:n-k+i+ib-1]. + impl.Dgerq2(ib, n-k+i+ib, a[(m-k+i)*lda:], lda, tau[i:], work) + if m-k+i > 0 { + // Form the triangular factor of the block reflector + // H = H_{i+ib-1} . . . H_{i+1} H_i. + impl.Dlarft(lapack.Backward, lapack.RowWise, + n-k+i+ib, ib, a[(m-k+i)*lda:], lda, tau[i:], + work, ldwork) + + // Apply H to A[0:m-k+i-1, 0:n-k+i+ib-1] from the right. + impl.Dlarfb(blas.Right, blas.NoTrans, lapack.Backward, lapack.RowWise, + m-k+i, n-k+i+ib, ib, a[(m-k+i)*lda:], lda, + work, ldwork, + a, lda, + work[ib*ldwork:], ldwork) + } + } + mu = m - k + i + nb + nu = n - k + i + nb + } else { + mu = m + nu = n + } + + // Use unblocked code to factor the last or only block. + if mu > 0 && nu > 0 { + impl.Dgerq2(mu, nu, a, lda, tau, work) + } + work[0] = float64(iws) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgesvd.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgesvd.go new file mode 100644 index 00000000..82a151c7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgesvd.go @@ -0,0 +1,1356 @@ +// 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/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +const noSVDO = "dgesvd: not coded for overwrite" + +// Dgesvd computes the singular value decomposition of the input matrix A. +// +// The singular value decomposition is +// A = U * Sigma * V^T +// where Sigma is an m×n diagonal matrix containing the singular values of A, +// U is an m×m orthogonal matrix and V is an n×n orthogonal matrix. The first +// min(m,n) columns of U and V are the left and right singular vectors of A +// respectively. +// +// jobU and jobVT are options for computing the singular vectors. The behavior +// is as follows +// jobU == lapack.SVDAll All m columns of U are returned in u +// jobU == lapack.SVDInPlace The first min(m,n) columns are returned in u +// jobU == lapack.SVDOverwrite The first min(m,n) columns of U are written into a +// jobU == lapack.SVDNone The columns of U are not computed. +// The behavior is the same for jobVT and the rows of V^T. At most one of jobU +// and jobVT can equal lapack.SVDOverwrite, and Dgesvd will panic otherwise. +// +// On entry, a contains the data for the m×n matrix A. During the call to Dgesvd +// the data is overwritten. On exit, A contains the appropriate singular vectors +// if either job is lapack.SVDOverwrite. +// +// s is a slice of length at least min(m,n) and on exit contains the singular +// values in decreasing order. +// +// u contains the left singular vectors on exit, stored column-wise. If +// jobU == lapack.SVDAll, u is of size m×m. If jobU == lapack.SVDInPlace u is +// of size m×min(m,n). If jobU == lapack.SVDOverwrite or lapack.SVDNone, u is +// not used. +// +// vt contains the left singular vectors on exit, stored row-wise. If +// jobV == lapack.SVDAll, vt is of size n×m. If jobVT == lapack.SVDInPlace vt is +// of size min(m,n)×n. If jobVT == lapack.SVDOverwrite or lapack.SVDNone, vt is +// not used. +// +// work is a slice for storing temporary memory, and lwork is the usable size of +// the slice. lwork must be at least max(5*min(m,n), 3*min(m,n)+max(m,n)). +// If lwork == -1, instead of performing Dgesvd, the optimal work length will be +// stored into work[0]. Dgesvd will panic if the working memory has insufficient +// storage. +// +// Dgesvd returns whether the decomposition successfully completed. +func (impl Implementation) Dgesvd(jobU, jobVT lapack.SVDJob, m, n int, a []float64, lda int, s, u []float64, ldu int, vt []float64, ldvt int, work []float64, lwork int) (ok bool) { + minmn := min(m, n) + checkMatrix(m, n, a, lda) + if jobU == lapack.SVDAll { + checkMatrix(m, m, u, ldu) + } else if jobU == lapack.SVDInPlace { + checkMatrix(m, minmn, u, ldu) + } + if jobVT == lapack.SVDAll { + checkMatrix(n, n, vt, ldvt) + } else if jobVT == lapack.SVDInPlace { + checkMatrix(minmn, n, vt, ldvt) + } + if jobU == lapack.SVDOverwrite && jobVT == lapack.SVDOverwrite { + panic("lapack: both jobU and jobVT are lapack.SVDOverwrite") + } + if len(s) < minmn { + panic(badS) + } + if jobU == lapack.SVDOverwrite || jobVT == lapack.SVDOverwrite { + panic(noSVDO) + } + if m == 0 || n == 0 { + return true + } + + wantua := jobU == lapack.SVDAll + wantus := jobU == lapack.SVDInPlace + wantuas := wantua || wantus + wantuo := jobU == lapack.SVDOverwrite + wantun := jobU == lapack.None + + wantva := jobVT == lapack.SVDAll + wantvs := jobVT == lapack.SVDInPlace + wantvas := wantva || wantvs + wantvo := jobVT == lapack.SVDOverwrite + wantvn := jobVT == lapack.None + + bi := blas64.Implementation() + var mnthr int + + // Compute optimal space for subroutines. + maxwrk := 1 + opts := string(jobU) + string(jobVT) + var wrkbl, bdspac int + if m >= n { + mnthr = impl.Ilaenv(6, "DGESVD", opts, m, n, 0, 0) + bdspac = 5 * n + impl.Dgeqrf(m, n, a, lda, nil, work, -1) + lwork_dgeqrf := int(work[0]) + impl.Dorgqr(m, n, n, a, lda, nil, work, -1) + lwork_dorgqr_n := int(work[0]) + impl.Dorgqr(m, m, n, a, lda, nil, work, -1) + lwork_dorgqr_m := int(work[0]) + impl.Dgebrd(n, n, a, lda, s, nil, nil, nil, work, -1) + lwork_dgebrd := int(work[0]) + impl.Dorgbr(lapack.ApplyP, n, n, n, a, lda, nil, work, -1) + lwork_dorgbr_p := int(work[0]) + impl.Dorgbr(lapack.ApplyQ, n, n, n, a, lda, nil, work, -1) + lwork_dorgbr_q := int(work[0]) + + if m >= mnthr { + // m >> n + if wantun { + // Path 1 + maxwrk = n + lwork_dgeqrf + maxwrk = max(maxwrk, 3*n+lwork_dgebrd) + if wantvo || wantvas { + maxwrk = max(maxwrk, 3*n+lwork_dorgbr_p) + } + maxwrk = max(maxwrk, bdspac) + } else if wantuo && wantvn { + // Path 2 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_n) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = max(n*n+wrkbl, n*n+m*n+n) + } else if wantuo && wantvs { + // Path 3 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_n) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = max(n*n+wrkbl, n*n+m*n+n) + } else if wantus && wantvn { + // Path 4 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_n) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = n*n + wrkbl + } else if wantus && wantvo { + // Path 5 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_n) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = 2*n*n + wrkbl + } else if wantus && wantvas { + // Path 6 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_n) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = n*n + wrkbl + } else if wantua && wantvn { + // Path 7 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_m) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = n*n + wrkbl + } else if wantua && wantvo { + // Path 8 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_m) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = 2*n*n + wrkbl + } else if wantua && wantvas { + // Path 9 + wrkbl = n + lwork_dgeqrf + wrkbl = max(wrkbl, n+lwork_dorgqr_m) + wrkbl = max(wrkbl, 3*n+lwork_dgebrd) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_q) + wrkbl = max(wrkbl, 3*n+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = n*n + wrkbl + } + } else { + // Path 10: m > n + impl.Dgebrd(m, n, a, lda, s, nil, nil, nil, work, -1) + lwork_dgebrd := int(work[0]) + maxwrk = 3*n + lwork_dgebrd + if wantus || wantuo { + impl.Dorgbr(lapack.ApplyQ, m, n, n, a, lda, nil, work, -1) + lwork_dorgbr_q = int(work[0]) + maxwrk = max(maxwrk, 3*n+lwork_dorgbr_q) + } + if wantua { + impl.Dorgbr(lapack.ApplyQ, m, m, n, a, lda, nil, work, -1) + lwork_dorgbr_q := int(work[0]) + maxwrk = max(maxwrk, 3*n+lwork_dorgbr_q) + } + if !wantvn { + maxwrk = max(maxwrk, 3*n+lwork_dorgbr_p) + } + maxwrk = max(maxwrk, bdspac) + } + } else { + mnthr = impl.Ilaenv(6, "DGESVD", opts, m, n, 0, 0) + + bdspac = 5 * m + impl.Dgelqf(m, n, a, lda, nil, work, -1) + lwork_dgelqf := int(work[0]) + impl.Dorglq(n, n, m, nil, n, nil, work, -1) + lwork_dorglq_n := int(work[0]) + impl.Dorglq(m, n, m, a, lda, nil, work, -1) + lwork_dorglq_m := int(work[0]) + impl.Dgebrd(m, m, a, lda, s, nil, nil, nil, work, -1) + lwork_dgebrd := int(work[0]) + impl.Dorgbr(lapack.ApplyP, m, m, m, a, n, nil, work, -1) + lwork_dorgbr_p := int(work[0]) + impl.Dorgbr(lapack.ApplyQ, m, m, m, a, n, nil, work, -1) + lwork_dorgbr_q := int(work[0]) + if n >= mnthr { + // n >> m + if wantvn { + // Path 1t + maxwrk = m + lwork_dgelqf + maxwrk = max(maxwrk, 3*m+lwork_dgebrd) + if wantuo || wantuas { + maxwrk = max(maxwrk, 3*m+lwork_dorgbr_q) + } + maxwrk = max(maxwrk, bdspac) + } else if wantvo && wantun { + // Path 2t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_m) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = max(m*m+wrkbl, m*m+m*n+m) + } else if wantvo && wantuas { + // Path 3t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_m) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = max(m*m+wrkbl, m*m+m*n+m) + } else if wantvs && wantun { + // Path 4t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_m) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = m*m + wrkbl + } else if wantvs && wantuo { + // Path 5t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_m) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = 2*m*m + wrkbl + } else if wantvs && wantuas { + // Path 6t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_m) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = m*m + wrkbl + } else if wantva && wantun { + // Path 7t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_n) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, bdspac) + maxwrk = m*m + wrkbl + } else if wantva && wantuo { + // Path 8t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_n) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = 2*m*m + wrkbl + } else if wantva && wantuas { + // Path 9t + wrkbl = m + lwork_dgelqf + wrkbl = max(wrkbl, m+lwork_dorglq_n) + wrkbl = max(wrkbl, 3*m+lwork_dgebrd) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_p) + wrkbl = max(wrkbl, 3*m+lwork_dorgbr_q) + wrkbl = max(wrkbl, bdspac) + maxwrk = m*m + wrkbl + } + } else { + // Path 10t, n > m + impl.Dgebrd(m, n, a, lda, s, nil, nil, nil, work, -1) + lwork_dgebrd = int(work[0]) + maxwrk = 3*m + lwork_dgebrd + if wantvs || wantvo { + impl.Dorgbr(lapack.ApplyP, m, n, m, a, n, nil, work, -1) + lwork_dorgbr_p = int(work[0]) + maxwrk = max(maxwrk, 3*m+lwork_dorgbr_p) + } + if wantva { + impl.Dorgbr(lapack.ApplyP, n, n, m, a, n, nil, work, -1) + lwork_dorgbr_p = int(work[0]) + maxwrk = max(maxwrk, 3*m+lwork_dorgbr_p) + } + if !wantun { + maxwrk = max(maxwrk, 3*m+lwork_dorgbr_q) + } + maxwrk = max(maxwrk, bdspac) + } + } + + minWork := max(1, 5*minmn) + if !((wantun && m >= mnthr) || (wantvn && n >= mnthr)) { + minWork = max(minWork, 3*minmn+max(m, n)) + } + + if lwork != -1 { + if len(work) < lwork { + panic(badWork) + } + if lwork < minWork { + panic(badWork) + } + } + if m == 0 || n == 0 { + return true + } + + maxwrk = max(maxwrk, minWork) + work[0] = float64(maxwrk) + if lwork == -1 { + return true + } + + // Perform decomposition. + eps := dlamchE + smlnum := math.Sqrt(dlamchS) / eps + bignum := 1 / smlnum + + // Scale A if max element outside range [smlnum, bignum]. + anrm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, nil) + var iscl bool + if anrm > 0 && anrm < smlnum { + iscl = true + impl.Dlascl(lapack.General, 0, 0, anrm, smlnum, m, n, a, lda) + } else if anrm > bignum { + iscl = true + impl.Dlascl(lapack.General, 0, 0, anrm, bignum, m, n, a, lda) + } + + var ie int + if m >= n { + // If A has sufficiently more rows than columns, use the QR decomposition. + if m >= mnthr { + // m >> n + if wantun { + // Path 1. + itau := 0 + iwork := itau + n + + // Compute A = Q * R. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + + // Zero out below R. + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, a[lda:], lda) + ie = 0 + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + // Bidiagonalize R in A. + impl.Dgebrd(n, n, a, lda, s, work[ie:], work[itauq:], + work[itaup:], work[iwork:], lwork-iwork) + ncvt := 0 + if wantvo || wantvas { + // Generate P^T. + impl.Dorgbr(lapack.ApplyP, n, n, n, a, lda, work[itaup:], + work[iwork:], lwork-iwork) + ncvt = n + } + iwork = ie + n + + // Perform bidiagonal QR iteration computing right singular vectors + // of A in A if desired. + ok = impl.Dbdsqr(blas.Upper, n, ncvt, 0, 0, s, work[ie:], + a, lda, work, 1, work, 1, work[iwork:]) + + // If right singular vectors desired in VT, copy them there. + if wantvas { + impl.Dlacpy(blas.All, n, n, a, lda, vt, ldvt) + } + } else if wantuo && wantvn { + // Path 2 + panic(noSVDO) + } else if wantuo && wantvas { + // Path 3 + panic(noSVDO) + } else if wantus { + if wantvn { + // Path 4 + if lwork >= n*n+max(4*n, bdspac) { + // Sufficient workspace for a fast algorithm. + ir := 0 + var ldworkr int + if lwork >= wrkbl+lda*n { + ldworkr = lda + } else { + ldworkr = n + } + itau := ir + ldworkr*n + iwork := itau + n + // Compute A = Q * R. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + + // Copy R to work[ir:], zeroing out below it. + impl.Dlacpy(blas.Upper, n, n, a, lda, work[ir:], ldworkr) + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, work[ir+ldworkr:], ldworkr) + + // Generate Q in A. + impl.Dorgqr(m, n, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + ie := itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Bidiagonalize R in work[ir:]. + impl.Dgebrd(n, n, work[ir:], ldworkr, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Generate left vectors bidiagonalizing R in work[ir:]. + impl.Dorgbr(lapack.ApplyQ, n, n, n, work[ir:], ldworkr, + work[itauq:], work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, compuing left singular + // vectors of R in work[ir:]. + ok = impl.Dbdsqr(blas.Upper, n, 0, n, 0, s, work[ie:], work, 1, + work[ir:], ldworkr, work, 1, work[iwork:]) + + // Multiply Q in A by left singular vectors of R in + // work[ir:], storing result in U. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, n, 1, a, lda, + work[ir:], ldworkr, 0, u, ldu) + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + n + + // Compute A = Q*R, copying result to U. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, n, a, lda, u, ldu) + + // Generate Q in U. + impl.Dorgqr(m, n, n, u, ldu, work[itau:], work[iwork:], lwork-iwork) + ie := itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Zero out below R in A. + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, a[lda:], lda) + + // Bidiagonalize R in A. + impl.Dgebrd(n, n, a, lda, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Multiply Q in U by left vectors bidiagonalizing R. + impl.Dormbr(lapack.ApplyQ, blas.Right, blas.NoTrans, m, n, n, + a, lda, work[itauq:], u, ldu, work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left + // singular vectors of A in U. + ok = impl.Dbdsqr(blas.Upper, n, 0, m, 0, s, work[ie:], work, 1, + u, ldu, work, 1, work[iwork:]) + } + } else if wantvo { + // Path 5 + panic(noSVDO) + } else if wantvas { + // Path 6 + if lwork >= n*n+max(4*n, bdspac) { + // Sufficient workspace for a fast algorithm. + iu := 0 + var ldworku int + if lwork >= wrkbl+lda*n { + ldworku = lda + } else { + ldworku = n + } + itau := iu + ldworku*n + iwork := itau + n + + // Compute A = Q * R. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + // Copy R to work[iu:], zeroing out below it. + impl.Dlacpy(blas.Upper, n, n, a, lda, work[iu:], ldworku) + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, work[iu+ldworku:], ldworku) + + // Generate Q in A. + impl.Dorgqr(m, n, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + + ie := itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Bidiagonalize R in work[iu:], copying result to VT. + impl.Dgebrd(n, n, work[iu:], ldworku, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Upper, n, n, work[iu:], ldworku, vt, ldvt) + + // Generate left bidiagonalizing vectors in work[iu:]. + impl.Dorgbr(lapack.ApplyQ, n, n, n, work[iu:], ldworku, + work[itauq:], work[iwork:], lwork-iwork) + + // Generate right bidiagonalizing vectors in VT. + impl.Dorgbr(lapack.ApplyP, n, n, n, vt, ldvt, + work[itaup:], work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left singular + // vectors of R in work[iu:], and computing right singular + // vectors of R in VT. + ok = impl.Dbdsqr(blas.Upper, n, n, n, 0, s, work[ie:], + vt, ldvt, work[iu:], ldworku, work, 1, work[iwork:]) + + // Multiply Q in A by left singular vectors of R in + // work[iu:], storing result in U. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, n, 1, a, lda, + work[iu:], ldworku, 0, u, ldu) + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + n + + // Compute A = Q * R, copying result to U. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, n, a, lda, u, ldu) + + // Generate Q in U. + impl.Dorgqr(m, n, n, u, ldu, work[itau:], work[iwork:], lwork-iwork) + + // Copy R to VT, zeroing out below it. + impl.Dlacpy(blas.Upper, n, n, a, lda, vt, ldvt) + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, vt[ldvt:], ldvt) + + ie := itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Bidiagonalize R in VT. + impl.Dgebrd(n, n, vt, ldvt, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Multiply Q in U by left bidiagonalizing vectors in VT. + impl.Dormbr(lapack.ApplyQ, blas.Right, blas.NoTrans, m, n, n, + vt, ldvt, work[itauq:], u, ldu, work[iwork:], lwork-iwork) + + // Generate right bidiagonalizing vectors in VT. + impl.Dorgbr(lapack.ApplyP, n, n, n, vt, ldvt, + work[itaup:], work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left singular + // vectors of A in U and computing right singular vectors + // of A in VT. + ok = impl.Dbdsqr(blas.Upper, n, n, m, 0, s, work[ie:], + vt, ldvt, u, ldu, work, 1, work[iwork:]) + } + } + } else if wantua { + if wantvn { + // Path 7 + if lwork >= n*n+max(max(n+m, 4*n), bdspac) { + // Sufficient workspace for a fast algorithm. + ir := 0 + var ldworkr int + if lwork >= wrkbl+lda*n { + ldworkr = lda + } else { + ldworkr = n + } + itau := ir + ldworkr*n + iwork := itau + n + + // Compute A = Q*R, copying result to U. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, n, a, lda, u, ldu) + + // Copy R to work[ir:], zeroing out below it. + impl.Dlacpy(blas.Upper, n, n, a, lda, work[ir:], ldworkr) + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, work[ir+ldworkr:], ldworkr) + + // Generate Q in U. + impl.Dorgqr(m, m, n, u, ldu, work[itau:], work[iwork:], lwork-iwork) + ie := itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Bidiagonalize R in work[ir:]. + impl.Dgebrd(n, n, work[ir:], ldworkr, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Generate left bidiagonalizing vectors in work[ir:]. + impl.Dorgbr(lapack.ApplyQ, n, n, n, work[ir:], ldworkr, + work[itauq:], work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left singular + // vectors of R in work[ir:]. + ok = impl.Dbdsqr(blas.Upper, n, 0, n, 0, s, work[ie:], work, 1, + work[ir:], ldworkr, work, 1, work[iwork:]) + + // Multiply Q in U by left singular vectors of R in + // work[ir:], storing result in A. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, n, 1, u, ldu, + work[ir:], ldworkr, 0, a, lda) + + // Copy left singular vectors of A from A to U. + impl.Dlacpy(blas.All, m, n, a, lda, u, ldu) + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + n + + // Compute A = Q*R, copying result to U. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, n, a, lda, u, ldu) + + // Generate Q in U. + impl.Dorgqr(m, m, n, u, ldu, work[itau:], work[iwork:], lwork-iwork) + ie := itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Zero out below R in A. + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, a[lda:], lda) + + // Bidiagonalize R in A. + impl.Dgebrd(n, n, a, lda, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Multiply Q in U by left bidiagonalizing vectors in A. + impl.Dormbr(lapack.ApplyQ, blas.Right, blas.NoTrans, m, n, n, + a, lda, work[itauq:], u, ldu, work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left + // singular vectors of A in U. + ok = impl.Dbdsqr(blas.Upper, n, 0, m, 0, s, work[ie:], + work, 1, u, ldu, work, 1, work[iwork:]) + } + } else if wantvo { + // Path 8. + panic(noSVDO) + } else if wantvas { + // Path 9. + if lwork >= n*n+max(max(n+m, 4*n), bdspac) { + // Sufficient workspace for a fast algorithm. + iu := 0 + var ldworku int + if lwork >= wrkbl+lda*n { + ldworku = lda + } else { + ldworku = n + } + itau := iu + ldworku*n + iwork := itau + n + + // Compute A = Q * R, copying result to U. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, n, a, lda, u, ldu) + + // Generate Q in U. + impl.Dorgqr(m, m, n, u, ldu, work[itau:], work[iwork:], lwork-iwork) + + // Copy R to work[iu:], zeroing out below it. + impl.Dlacpy(blas.Upper, n, n, a, lda, work[iu:], ldworku) + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, work[iu+ldworku:], ldworku) + + ie = itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Bidiagonalize R in work[iu:], copying result to VT. + impl.Dgebrd(n, n, work[iu:], ldworku, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Upper, n, n, work[iu:], ldworku, vt, ldvt) + + // Generate left bidiagonalizing vectors in work[iu:]. + impl.Dorgbr(lapack.ApplyQ, n, n, n, work[iu:], ldworku, + work[itauq:], work[iwork:], lwork-iwork) + + // Generate right bidiagonalizing vectors in VT. + impl.Dorgbr(lapack.ApplyP, n, n, n, vt, ldvt, + work[itaup:], work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left singular + // vectors of R in work[iu:] and computing right + // singular vectors of R in VT. + ok = impl.Dbdsqr(blas.Upper, n, n, n, 0, s, work[ie:], + vt, ldvt, work[iu:], ldworku, work, 1, work[iwork:]) + + // Multiply Q in U by left singular vectors of R in + // work[iu:], storing result in A. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, n, 1, + u, ldu, work[iu:], ldworku, 0, a, lda) + + // Copy left singular vectors of A from A to U. + impl.Dlacpy(blas.All, m, n, a, lda, u, ldu) + + /* + // Bidiagonalize R in VT. + impl.Dgebrd(n, n, vt, ldvt, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Multiply Q in U by left bidiagonalizing vectors in VT. + impl.Dormbr(lapack.ApplyQ, blas.Right, blas.NoTrans, + m, n, n, vt, ldvt, work[itauq:], u, ldu, work[iwork:], lwork-iwork) + + // Generate right bidiagonalizing vectors in VT. + impl.Dorgbr(lapack.ApplyP, n, n, n, vt, ldvt, + work[itaup:], work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left singular + // vectors of A in U and computing right singular vectors + // of A in VT. + ok = impl.Dbdsqr(blas.Upper, n, n, m, 0, s, work[ie:], + vt, ldvt, u, ldu, work, 1, work[iwork:]) + */ + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + n + + // Compute A = Q*R, copying result to U. + impl.Dgeqrf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, n, a, lda, u, ldu) + + // Generate Q in U. + impl.Dorgqr(m, m, n, u, ldu, work[itau:], work[iwork:], lwork-iwork) + + // Copy R from A to VT, zeroing out below it. + impl.Dlacpy(blas.Upper, n, n, a, lda, vt, ldvt) + impl.Dlaset(blas.Lower, n-1, n-1, 0, 0, vt[ldvt:], ldvt) + + ie := itau + itauq := ie + n + itaup := itauq + n + iwork = itaup + n + + // Bidiagonalize R in VT. + impl.Dgebrd(n, n, vt, ldvt, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Multiply Q in U by left bidiagonalizing vectors in VT. + impl.Dormbr(lapack.ApplyQ, blas.Right, blas.NoTrans, + m, n, n, vt, ldvt, work[itauq:], u, ldu, work[iwork:], lwork-iwork) + + // Generate right bidiagonizing vectors in VT. + impl.Dorgbr(lapack.ApplyP, n, n, n, vt, ldvt, + work[itaup:], work[iwork:], lwork-iwork) + iwork = ie + n + + // Perform bidiagonal QR iteration, computing left singular + // vectors of A in U and computing right singular vectors + // of A in VT. + impl.Dbdsqr(blas.Upper, n, n, m, 0, s, work[ie:], + vt, ldvt, u, ldu, work, 1, work[iwork:]) + } + } + } + } else { + // Path 10. + // M at least N, but not much larger. + ie = 0 + itauq := ie + n + itaup := itauq + n + iwork := itaup + n + + // Bidiagonalize A. + impl.Dgebrd(m, n, a, lda, s, work[ie:], work[itauq:], + work[itaup:], work[iwork:], lwork-iwork) + if wantuas { + // Left singular vectors are desired in U. Copy result to U and + // generate left biadiagonalizing vectors in U. + impl.Dlacpy(blas.Lower, m, n, a, lda, u, ldu) + var ncu int + if wantus { + ncu = n + } + if wantua { + ncu = m + } + impl.Dorgbr(lapack.ApplyQ, m, ncu, n, u, ldu, work[itauq:], work[iwork:], lwork-iwork) + } + if wantvas { + // Right singular vectors are desired in VT. Copy result to VT and + // generate left biadiagonalizing vectors in VT. + impl.Dlacpy(blas.Upper, n, n, a, lda, vt, ldvt) + impl.Dorgbr(lapack.ApplyP, n, n, n, vt, ldvt, work[itaup:], work[iwork:], lwork-iwork) + } + if wantuo { + panic(noSVDO) + } + if wantvo { + panic(noSVDO) + } + iwork = ie + n + var nru, ncvt int + if wantuas || wantuo { + nru = m + } + if wantun { + nru = 0 + } + if wantvas || wantvo { + ncvt = n + } + if wantvn { + ncvt = 0 + } + if !wantuo && !wantvo { + // Perform bidiagonal QR iteration, if desired, computing left + // singular vectors in U and right singular vectors in VT. + ok = impl.Dbdsqr(blas.Upper, n, ncvt, nru, 0, s, work[ie:], + vt, ldvt, u, ldu, work, 1, work[iwork:]) + } else { + // There will be two branches when the implementation is complete. + panic(noSVDO) + } + } + } else { + // A has more columns than rows. If A has sufficiently more columns than + // rows, first reduce using the LQ decomposition. + if n >= mnthr { + // n >> m. + if wantvn { + // Path 1t. + itau := 0 + iwork := itau + m + + // Compute A = L*Q. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + + // Zero out above L. + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, a[1:], lda) + ie := 0 + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Bidiagonalize L in A. + impl.Dgebrd(m, m, a, lda, s, work[ie:itauq], + work[itauq:itaup], work[itaup:iwork], work[iwork:], lwork-iwork) + if wantuo || wantuas { + impl.Dorgbr(lapack.ApplyQ, m, m, m, a, lda, + work[itauq:], work[iwork:], lwork-iwork) + } + iwork = ie + m + nru := 0 + if wantuo || wantuas { + nru = m + } + + // Perform bidiagonal QR iteration, computing left singular vectors + // of A in A if desired. + ok = impl.Dbdsqr(blas.Upper, m, 0, nru, 0, s, work[ie:], + work, 1, a, lda, work, 1, work[iwork:]) + + // If left singular vectors desired in U, copy them there. + if wantuas { + impl.Dlacpy(blas.All, m, m, a, lda, u, ldu) + } + } else if wantvo && wantun { + // Path 2t. + panic(noSVDO) + } else if wantvo && wantuas { + // Path 3t. + panic(noSVDO) + } else if wantvs { + if wantun { + // Path 4t. + if lwork >= m*m+max(4*m, bdspac) { + // Sufficient workspace for a fast algorithm. + ir := 0 + var ldworkr int + if lwork >= wrkbl+lda*m { + ldworkr = lda + } else { + ldworkr = m + } + itau := ir + ldworkr*m + iwork := itau + m + + // Compute A = L*Q. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + + // Copy L to work[ir:], zeroing out above it. + impl.Dlacpy(blas.Lower, m, m, a, lda, work[ir:], ldworkr) + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, work[ir+1:], ldworkr) + + // Generate Q in A. + impl.Dorglq(m, n, m, a, lda, work[itau:], work[iwork:], lwork-iwork) + ie := itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Bidiagonalize L in work[ir:]. + impl.Dgebrd(m, m, work[ir:], ldworkr, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Generate right vectors bidiagonalizing L in work[ir:]. + impl.Dorgbr(lapack.ApplyP, m, m, m, work[ir:], ldworkr, + work[itaup:], work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing right singular + // vectors of L in work[ir:]. + ok = impl.Dbdsqr(blas.Upper, m, m, 0, 0, s, work[ie:], + work[ir:], ldworkr, work, 1, work, 1, work[iwork:]) + + // Multiply right singular vectors of L in work[ir:] by + // Q in A, storing result in VT. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, m, 1, + work[ir:], ldworkr, a, lda, 0, vt, ldvt) + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + m + + // Compute A = L*Q. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + + // Copy result to VT. + impl.Dlacpy(blas.Upper, m, n, a, lda, vt, ldvt) + + // Generate Q in VT. + impl.Dorglq(m, n, m, vt, ldvt, work[itau:], work[iwork:], lwork-iwork) + ie := itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Zero out above L in A. + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, a[1:], lda) + + // Bidiagonalize L in A. + impl.Dgebrd(m, m, a, lda, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Multiply right vectors bidiagonalizing L by Q in VT. + impl.Dormbr(lapack.ApplyP, blas.Left, blas.Trans, m, n, m, + a, lda, work[itaup:], vt, ldvt, work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing right + // singular vectors of A in VT. + ok = impl.Dbdsqr(blas.Upper, m, n, 0, 0, s, work[ie:], + vt, ldvt, work, 1, work, 1, work[iwork:]) + } + } else if wantuo { + // Path 5t. + panic(noSVDO) + } else if wantuas { + // Path 6t. + if lwork >= m*m+max(4*m, bdspac) { + // Sufficient workspace for a fast algorithm. + iu := 0 + var ldworku int + if lwork >= wrkbl+lda*m { + ldworku = lda + } else { + ldworku = m + } + itau := iu + ldworku*m + iwork := itau + m + + // Compute A = L*Q. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + + // Copy L to work[iu:], zeroing out above it. + impl.Dlacpy(blas.Lower, m, m, a, lda, work[iu:], ldworku) + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, work[iu+1:], ldworku) + + // Generate Q in A. + impl.Dorglq(m, n, m, a, lda, work[itau:], work[iwork:], lwork-iwork) + ie := itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Bidiagonalize L in work[iu:], copying result to U. + impl.Dgebrd(m, m, work[iu:], ldworku, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, m, work[iu:], ldworku, u, ldu) + + // Generate right bidiagionalizing vectors in work[iu:]. + impl.Dorgbr(lapack.ApplyP, m, m, m, work[iu:], ldworku, + work[itaup:], work[iwork:], lwork-iwork) + + // Generate left bidiagonalizing vectors in U. + impl.Dorgbr(lapack.ApplyQ, m, m, m, u, ldu, work[itauq:], work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing left singular + // vectors of L in U and computing right singular vectors of + // L in work[iu:]. + ok = impl.Dbdsqr(blas.Upper, m, m, m, 0, s, work[ie:], + work[iu:], ldworku, u, ldu, work, 1, work[iwork:]) + + // Multiply right singular vectors of L in work[iu:] by + // Q in A, storing result in VT. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, m, 1, + work[iu:], ldworku, a, lda, 0, vt, ldvt) + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + m + + // Compute A = L*Q, copying result to VT. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Upper, m, n, a, lda, vt, ldvt) + + // Generate Q in VT. + impl.Dorglq(m, n, m, vt, ldvt, work[itau:], work[iwork:], lwork-iwork) + + // Copy L to U, zeroing out above it. + impl.Dlacpy(blas.Lower, m, m, a, lda, u, ldu) + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, u[1:], ldu) + + ie := itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Bidiagonalize L in U. + impl.Dgebrd(m, m, u, ldu, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Multiply right bidiagonalizing vectors in U by Q in VT. + impl.Dormbr(lapack.ApplyP, blas.Left, blas.Trans, m, n, m, + u, ldu, work[itaup:], vt, ldvt, work[iwork:], lwork-iwork) + + // Generate left bidiagonalizing vectors in U. + impl.Dorgbr(lapack.ApplyQ, m, m, m, u, ldu, work[itauq:], work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing left singular + // vectors of A in U and computing right singular vectors + // of A in VT. + impl.Dbdsqr(blas.Upper, m, n, m, 0, s, work[ie:], vt, ldvt, + u, ldu, work, 1, work[iwork:]) + } + } + } else if wantva { + if wantun { + // Path 7t. + if lwork >= m*m+max(max(n+m, 4*m), bdspac) { + // Sufficient workspace for a fast algorithm. + ir := 0 + var ldworkr int + if lwork >= wrkbl+lda*m { + ldworkr = lda + } else { + ldworkr = m + } + itau := ir + ldworkr*m + iwork := itau + m + + // Compute A = L*Q, copying result to VT. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Upper, m, n, a, lda, vt, ldvt) + + // Copy L to work[ir:], zeroing out above it. + impl.Dlacpy(blas.Lower, m, m, a, lda, work[ir:], ldworkr) + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, work[ir+1:], ldworkr) + + // Generate Q in VT. + impl.Dorglq(n, n, m, vt, ldvt, work[itau:], work[iwork:], lwork-iwork) + + ie := itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Bidiagonalize L in work[ir:]. + impl.Dgebrd(m, m, work[ir:], ldworkr, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + + // Generate right bidiagonalizing vectors in work[ir:]. + impl.Dorgbr(lapack.ApplyP, m, m, m, work[ir:], ldworkr, + work[itaup:], work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing right + // singular vectors of L in work[ir:]. + ok = impl.Dbdsqr(blas.Upper, m, m, 0, 0, s, work[ie:], + work[ir:], ldworkr, work, 1, work, 1, work[iwork:]) + + // Multiply right singular vectors of L in work[ir:] by + // Q in VT, storing result in A. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, m, 1, + work[ir:], ldworkr, vt, ldvt, 0, a, lda) + + // Copy right singular vectors of A from A to VT. + impl.Dlacpy(blas.All, m, n, a, lda, vt, ldvt) + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + m + // Compute A = L * Q, copying result to VT. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Upper, m, n, a, lda, vt, ldvt) + + // Generate Q in VT. + impl.Dorglq(n, n, m, vt, ldvt, work[itau:], work[iwork:], lwork-iwork) + + ie := itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Zero out above L in A. + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, a[1:], lda) + + // Bidiagonalize L in A. + impl.Dgebrd(m, m, a, lda, s, work[ie:], work[itauq:], + work[itaup:], work[iwork:], lwork-iwork) + + // Multiply right bidiagonalizing vectors in A by Q in VT. + impl.Dormbr(lapack.ApplyP, blas.Left, blas.Trans, m, n, m, + a, lda, work[itaup:], vt, ldvt, work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing right singular + // vectors of A in VT. + ok = impl.Dbdsqr(blas.Upper, m, n, 0, 0, s, work[ie:], + vt, ldvt, work, 1, work, 1, work[iwork:]) + } + } else if wantuo { + panic(noSVDO) + } else if wantuas { + // Path 9t. + if lwork >= m*m+max(max(m+n, 4*m), bdspac) { + // Sufficient workspace for a fast algorithm. + iu := 0 + + var ldworku int + if lwork >= wrkbl+lda*m { + ldworku = lda + } else { + ldworku = m + } + itau := iu + ldworku*m + iwork := itau + m + + // Generate A = L * Q copying result to VT. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Upper, m, n, a, lda, vt, ldvt) + + // Generate Q in VT. + impl.Dorglq(n, n, m, vt, ldvt, work[itau:], work[iwork:], lwork-iwork) + + // Copy L to work[iu:], zeroing out above it. + impl.Dlacpy(blas.Lower, m, m, a, lda, work[iu:], ldworku) + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, work[iu+1:], ldworku) + ie = itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Bidiagonalize L in work[iu:], copying result to U. + impl.Dgebrd(m, m, work[iu:], ldworku, s, work[ie:], + work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Lower, m, m, work[iu:], ldworku, u, ldu) + + // Generate right bidiagonalizing vectors in work[iu:]. + impl.Dorgbr(lapack.ApplyP, m, m, m, work[iu:], ldworku, + work[itaup:], work[iwork:], lwork-iwork) + + // Generate left bidiagonalizing vectors in U. + impl.Dorgbr(lapack.ApplyQ, m, m, m, u, ldu, work[itauq:], work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing left singular + // vectors of L in U and computing right singular vectors + // of L in work[iu:]. + ok = impl.Dbdsqr(blas.Upper, m, m, m, 0, s, work[ie:], + work[iu:], ldworku, u, ldu, work, 1, work[iwork:]) + + // Multiply right singular vectors of L in work[iu:] + // Q in VT, storing result in A. + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n, m, 1, + work[iu:], ldworku, vt, ldvt, 0, a, lda) + + // Copy right singular vectors of A from A to VT. + impl.Dlacpy(blas.All, m, n, a, lda, vt, ldvt) + } else { + // Insufficient workspace for a fast algorithm. + itau := 0 + iwork := itau + m + + // Compute A = L * Q, copying result to VT. + impl.Dgelqf(m, n, a, lda, work[itau:], work[iwork:], lwork-iwork) + impl.Dlacpy(blas.Upper, m, n, a, lda, vt, ldvt) + + // Generate Q in VT. + impl.Dorglq(n, n, m, vt, ldvt, work[itau:], work[iwork:], lwork-iwork) + + // Copy L to U, zeroing out above it. + impl.Dlacpy(blas.Lower, m, m, a, lda, u, ldu) + impl.Dlaset(blas.Upper, m-1, m-1, 0, 0, u[1:], ldu) + + ie = itau + itauq := ie + m + itaup := itauq + m + iwork = itaup + m + + // Bidiagonalize L in U. + impl.Dgebrd(m, m, u, ldu, s, work[ie:], work[itauq:], + work[itaup:], work[iwork:], lwork-iwork) + + // Multiply right bidiagonalizing vectors in U by Q in VT. + impl.Dormbr(lapack.ApplyP, blas.Left, blas.Trans, m, n, m, + u, ldu, work[itaup:], vt, ldvt, work[iwork:], lwork-iwork) + + // Generate left bidiagonalizing vectors in U. + impl.Dorgbr(lapack.ApplyQ, m, m, m, u, ldu, work[itauq:], work[iwork:], lwork-iwork) + iwork = ie + m + + // Perform bidiagonal QR iteration, computing left singular + // vectors of A in U and computing right singular vectors + // of A in VT. + ok = impl.Dbdsqr(blas.Upper, m, n, m, 0, s, work[ie:], + vt, ldvt, u, ldu, work, 1, work[iwork:]) + } + } + } + } else { + // Path 10t. + // N at least M, but not much larger. + ie = 0 + itauq := ie + m + itaup := itauq + m + iwork := itaup + m + + // Bidiagonalize A. + impl.Dgebrd(m, n, a, lda, s, work[ie:], work[itauq:], work[itaup:], work[iwork:], lwork-iwork) + if wantuas { + // If left singular vectors desired in U, copy result to U and + // generate left bidiagonalizing vectors in U. + impl.Dlacpy(blas.Lower, m, m, a, lda, u, ldu) + impl.Dorgbr(lapack.ApplyQ, m, m, n, u, ldu, work[itauq:], work[iwork:], lwork-iwork) + } + if wantvas { + // If right singular vectors desired in VT, copy result to VT + // and generate right bidiagonalizing vectors in VT. + impl.Dlacpy(blas.Upper, m, n, a, lda, vt, ldvt) + var nrvt int + if wantva { + nrvt = n + } else { + nrvt = m + } + impl.Dorgbr(lapack.ApplyP, nrvt, n, m, vt, ldvt, work[itaup:], work[iwork:], lwork-iwork) + } + if wantuo { + panic(noSVDO) + } + if wantvo { + panic(noSVDO) + } + iwork = ie + m + var nru, ncvt int + if wantuas || wantuo { + nru = m + } + if wantvas || wantvo { + ncvt = n + } + if !wantuo && !wantvo { + // Perform bidiagonal QR iteration, if desired, computing left + // singular vectors in U and computing right singular vectors in + // VT. + ok = impl.Dbdsqr(blas.Lower, m, ncvt, nru, 0, s, work[ie:], + vt, ldvt, u, ldu, work, 1, work[iwork:]) + } else { + // There will be two branches when the implementation is complete. + panic(noSVDO) + } + } + } + if !ok { + if ie > 1 { + for i := 0; i < minmn-1; i++ { + work[i+1] = work[i+ie] + } + } + if ie < 1 { + for i := minmn - 2; i >= 0; i-- { + work[i+1] = work[i+ie] + } + } + } + // Undo scaling if necessary. + if iscl { + if anrm > bignum { + impl.Dlascl(lapack.General, 0, 0, bignum, anrm, minmn, 1, s, minmn) + } + if !ok && anrm > bignum { + impl.Dlascl(lapack.General, 0, 0, bignum, anrm, minmn-1, 1, work[minmn:], minmn) + } + if anrm < smlnum { + impl.Dlascl(lapack.General, 0, 0, smlnum, anrm, minmn, 1, s, minmn) + } + if !ok && anrm < smlnum { + impl.Dlascl(lapack.General, 0, 0, smlnum, anrm, minmn-1, 1, work[minmn:], minmn) + } + } + work[0] = float64(maxwrk) + return ok +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgetf2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetf2.go new file mode 100644 index 00000000..3167d160 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetf2.go @@ -0,0 +1,69 @@ +// 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/blas64" +) + +// Dgetf2 computes the LU decomposition of the m×n matrix A. +// The LU decomposition is a factorization of a into +// A = P * L * U +// where P is a permutation matrix, L is a unit lower triangular matrix, and +// U is a (usually) non-unit upper triangular matrix. On exit, L and U are stored +// in place into a. +// +// ipiv is a permutation vector. It indicates that row i of the matrix was +// changed with ipiv[i]. ipiv must have length at least min(m,n), and will panic +// otherwise. ipiv is zero-indexed. +// +// Dgetf2 returns whether the matrix A is singular. The LU decomposition will +// be computed regardless of the singularity of A, but division by zero +// will occur if the false is returned and the result is used to solve a +// system of equations. +// +// Dgetf2 is an internal routine. It is exported for testing purposes. +func (Implementation) Dgetf2(m, n int, a []float64, lda int, ipiv []int) (ok bool) { + mn := min(m, n) + checkMatrix(m, n, a, lda) + if len(ipiv) < mn { + panic(badIpiv) + } + if m == 0 || n == 0 { + return true + } + bi := blas64.Implementation() + sfmin := dlamchS + ok = true + for j := 0; j < mn; j++ { + // Find a pivot and test for singularity. + jp := j + bi.Idamax(m-j, a[j*lda+j:], lda) + ipiv[j] = jp + if a[jp*lda+j] == 0 { + ok = false + } else { + // Swap the rows if necessary. + if jp != j { + bi.Dswap(n, a[j*lda:], 1, a[jp*lda:], 1) + } + if j < m-1 { + aj := a[j*lda+j] + if math.Abs(aj) >= sfmin { + bi.Dscal(m-j-1, 1/aj, a[(j+1)*lda+j:], lda) + } else { + for i := 0; i < m-j-1; i++ { + a[(j+1)*lda+j] = a[(j+1)*lda+j] / a[lda*j+j] + } + } + } + } + if j < mn-1 { + bi.Dger(m-j-1, n-j-1, -1, a[(j+1)*lda+j:], lda, a[j*lda+j+1:], 1, a[(j+1)*lda+j+1:], lda) + } + } + return ok +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgetrf.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetrf.go new file mode 100644 index 00000000..2b95668c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetrf.go @@ -0,0 +1,70 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dgetrf computes the LU decomposition of the m×n matrix A. +// The LU decomposition is a factorization of A into +// A = P * L * U +// where P is a permutation matrix, L is a unit lower triangular matrix, and +// U is a (usually) non-unit upper triangular matrix. On exit, L and U are stored +// in place into a. +// +// ipiv is a permutation vector. It indicates that row i of the matrix was +// changed with ipiv[i]. ipiv must have length at least min(m,n), and will panic +// otherwise. ipiv is zero-indexed. +// +// Dgetrf is the blocked version of the algorithm. +// +// Dgetrf returns whether the matrix A is singular. The LU decomposition will +// be computed regardless of the singularity of A, but division by zero +// will occur if the false is returned and the result is used to solve a +// system of equations. +func (impl Implementation) Dgetrf(m, n int, a []float64, lda int, ipiv []int) (ok bool) { + mn := min(m, n) + checkMatrix(m, n, a, lda) + if len(ipiv) < mn { + panic(badIpiv) + } + if m == 0 || n == 0 { + return false + } + bi := blas64.Implementation() + nb := impl.Ilaenv(1, "DGETRF", " ", m, n, -1, -1) + if nb <= 1 || nb >= min(m, n) { + // Use the unblocked algorithm. + return impl.Dgetf2(m, n, a, lda, ipiv) + } + ok = true + for j := 0; j < mn; j += nb { + jb := min(mn-j, nb) + blockOk := impl.Dgetf2(m-j, jb, a[j*lda+j:], lda, ipiv[j:]) + if !blockOk { + ok = false + } + for i := j; i <= min(m-1, j+jb-1); i++ { + ipiv[i] = j + ipiv[i] + } + impl.Dlaswp(j, a, lda, j, j+jb-1, ipiv[:j+jb], 1) + if j+jb < n { + impl.Dlaswp(n-j-jb, a[j+jb:], lda, j, j+jb-1, ipiv[:j+jb], 1) + bi.Dtrsm(blas.Left, blas.Lower, blas.NoTrans, blas.Unit, + jb, n-j-jb, 1, + a[j*lda+j:], lda, + a[j*lda+j+jb:], lda) + if j+jb < m { + bi.Dgemm(blas.NoTrans, blas.NoTrans, m-j-jb, n-j-jb, jb, -1, + a[(j+jb)*lda+j:], lda, + a[j*lda+j+jb:], lda, + 1, a[(j+jb)*lda+j+jb:], lda) + } + } + } + return ok +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgetri.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetri.go new file mode 100644 index 00000000..993d6c02 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetri.go @@ -0,0 +1,92 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dgetri computes the inverse of the matrix A using the LU factorization computed +// by Dgetrf. On entry, a contains the PLU decomposition of A as computed by +// Dgetrf and on exit contains the reciprocal of the original matrix. +// +// Dgetri will not perform the inversion if the matrix is singular, and returns +// a boolean indicating whether the inversion was successful. +// +// work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= n and this function will panic otherwise. +// Dgetri is a blocked inversion, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Dgetri, +// the optimal work length will be stored into work[0]. +func (impl Implementation) Dgetri(n int, a []float64, lda int, ipiv []int, work []float64, lwork int) (ok bool) { + checkMatrix(n, n, a, lda) + if len(ipiv) < n { + panic(badIpiv) + } + nb := impl.Ilaenv(1, "DGETRI", " ", n, -1, -1, -1) + if lwork == -1 { + work[0] = float64(n * nb) + return true + } + if lwork < n { + panic(badWork) + } + if len(work) < lwork { + panic(badWork) + } + if n == 0 { + return true + } + ok = impl.Dtrtri(blas.Upper, blas.NonUnit, n, a, lda) + if !ok { + return false + } + nbmin := 2 + ldwork := nb + if nb > 1 && nb < n { + iws := max(ldwork*n, 1) + if lwork < iws { + nb = lwork / ldwork + nbmin = max(2, impl.Ilaenv(2, "DGETRI", " ", n, -1, -1, -1)) + } + } + bi := blas64.Implementation() + // TODO(btracey): Replace this with a more row-major oriented algorithm. + if nb < nbmin || nb >= n { + // Unblocked code. + for j := n - 1; j >= 0; j-- { + for i := j + 1; i < n; i++ { + work[i*ldwork] = a[i*lda+j] + a[i*lda+j] = 0 + } + if j < n { + bi.Dgemv(blas.NoTrans, n, n-j-1, -1, a[(j+1):], lda, work[(j+1)*ldwork:], ldwork, 1, a[j:], lda) + } + } + } else { + nn := ((n - 1) / nb) * nb + for j := nn; j >= 0; j -= nb { + jb := min(nb, n-j) + for jj := j; jj < j+jb-1; jj++ { + for i := jj + 1; i < n; i++ { + work[i*ldwork+(jj-j)] = a[i*lda+jj] + a[i*lda+jj] = 0 + } + } + if j+jb < n { + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, jb, n-j-jb, -1, a[(j+jb):], lda, work[(j+jb)*ldwork:], ldwork, 1, a[j:], lda) + bi.Dtrsm(blas.Right, blas.Lower, blas.NoTrans, blas.Unit, n, jb, 1, work[j*ldwork:], ldwork, a[j:], lda) + } + } + } + for j := n - 2; j >= 0; j-- { + jp := ipiv[j] + if jp != j { + bi.Dswap(n, a[j:], lda, a[jp:], lda) + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dgetrs.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetrs.go new file mode 100644 index 00000000..ca5a9b2a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dgetrs.go @@ -0,0 +1,55 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dgetrs solves a system of equations using an LU factorization. +// The system of equations solved is +// A * X = B if trans == blas.Trans +// A^T * X = B if trans == blas.NoTrans +// A is a general n×n matrix with stride lda. B is a general matrix of size n×nrhs. +// +// On entry b contains the elements of the matrix B. On exit, b contains the +// elements of X, the solution to the system of equations. +// +// a and ipiv contain the LU factorization of A and the permutation indices as +// computed by Dgetrf. ipiv is zero-indexed. +func (impl Implementation) Dgetrs(trans blas.Transpose, n, nrhs int, a []float64, lda int, ipiv []int, b []float64, ldb int) { + checkMatrix(n, n, a, lda) + checkMatrix(n, nrhs, b, ldb) + if len(ipiv) < n { + panic(badIpiv) + } + if n == 0 || nrhs == 0 { + return + } + if trans != blas.Trans && trans != blas.NoTrans { + panic(badTrans) + } + bi := blas64.Implementation() + if trans == blas.NoTrans { + // Solve A * X = B. + impl.Dlaswp(nrhs, b, ldb, 0, n-1, ipiv, 1) + // Solve L * X = B, updating b. + bi.Dtrsm(blas.Left, blas.Lower, blas.NoTrans, blas.Unit, + n, nrhs, 1, a, lda, b, ldb) + // Solve U * X = B, updating b. + bi.Dtrsm(blas.Left, blas.Upper, blas.NoTrans, blas.NonUnit, + n, nrhs, 1, a, lda, b, ldb) + return + } + // Solve A^T * X = B. + // Solve U^T * X = B, updating b. + bi.Dtrsm(blas.Left, blas.Upper, blas.Trans, blas.NonUnit, + n, nrhs, 1, a, lda, b, ldb) + // Solve L^T * X = B, updating b. + bi.Dtrsm(blas.Left, blas.Lower, blas.Trans, blas.Unit, + n, nrhs, 1, a, lda, b, ldb) + impl.Dlaswp(nrhs, b, ldb, 0, n-1, ipiv, -1) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dggsvd3.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dggsvd3.go new file mode 100644 index 00000000..cf3635d9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dggsvd3.go @@ -0,0 +1,230 @@ +// 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/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dggsvd3 computes the generalized singular value decomposition (GSVD) +// of an m×n matrix A and p×n matrix B: +// U^T*A*Q = D1*[ 0 R ] +// +// V^T*B*Q = D2*[ 0 R ] +// where U, V and Q are orthogonal matrices. +// +// Dggsvd3 returns k and l, the dimensions of the sub-blocks. k+l +// is the effective numerical rank of the (m+p)×n matrix [ A^T B^T ]^T. +// R is a (k+l)×(k+l) nonsingular upper triangular matrix, D1 and +// D2 are m×(k+l) and p×(k+l) diagonal matrices and of the following +// structures, respectively: +// +// If m-k-l >= 0, +// +// k l +// D1 = k [ I 0 ] +// l [ 0 C ] +// m-k-l [ 0 0 ] +// +// k l +// D2 = l [ 0 S ] +// p-l [ 0 0 ] +// +// n-k-l k l +// [ 0 R ] = k [ 0 R11 R12 ] k +// l [ 0 0 R22 ] l +// +// where +// +// C = diag( alpha_k, ... , alpha_{k+l} ), +// S = diag( beta_k, ... , beta_{k+l} ), +// C^2 + S^2 = I. +// +// R is stored in +// A[0:k+l, n-k-l:n] +// on exit. +// +// If m-k-l < 0, +// +// k m-k k+l-m +// D1 = k [ I 0 0 ] +// m-k [ 0 C 0 ] +// +// k m-k k+l-m +// D2 = m-k [ 0 S 0 ] +// k+l-m [ 0 0 I ] +// p-l [ 0 0 0 ] +// +// n-k-l k m-k k+l-m +// [ 0 R ] = k [ 0 R11 R12 R13 ] +// m-k [ 0 0 R22 R23 ] +// k+l-m [ 0 0 0 R33 ] +// +// where +// C = diag( alpha_k, ... , alpha_m ), +// S = diag( beta_k, ... , beta_m ), +// C^2 + S^2 = I. +// +// R = [ R11 R12 R13 ] is stored in A[1:m, n-k-l+1:n] +// [ 0 R22 R23 ] +// and R33 is stored in +// B[m-k:l, n+m-k-l:n] on exit. +// +// Dggsvd3 computes C, S, R, and optionally the orthogonal transformation +// matrices U, V and Q. +// +// jobU, jobV and jobQ are options for computing the orthogonal matrices. The behavior +// is as follows +// jobU == lapack.GSVDU Compute orthogonal matrix U +// jobU == lapack.GSVDNone Do not compute orthogonal matrix. +// The behavior is the same for jobV and jobQ with the exception that instead of +// lapack.GSVDU these accept lapack.GSVDV and lapack.GSVDQ respectively. +// The matrices U, V and Q must be m×m, p×p and n×n respectively unless the +// relevant job parameter is lapack.GSVDNone. +// +// alpha and beta must have length n or Dggsvd3 will panic. On exit, alpha and +// beta contain the generalized singular value pairs of A and B +// alpha[0:k] = 1, +// beta[0:k] = 0, +// if m-k-l >= 0, +// alpha[k:k+l] = diag(C), +// beta[k:k+l] = diag(S), +// if m-k-l < 0, +// alpha[k:m]= C, alpha[m:k+l]= 0 +// beta[k:m] = S, beta[m:k+l] = 1. +// if k+l < n, +// alpha[k+l:n] = 0 and +// beta[k+l:n] = 0. +// +// On exit, iwork contains the permutation required to sort alpha descending. +// +// iwork must have length n, work must have length at least max(1, lwork), and +// lwork must be -1 or greater than n, otherwise Dggsvd3 will panic. If +// lwork is -1, work[0] holds the optimal lwork on return, but Dggsvd3 does +// not perform the GSVD. +func (impl Implementation) Dggsvd3(jobU, jobV, jobQ lapack.GSVDJob, m, n, p int, a []float64, lda int, b []float64, ldb int, alpha, beta, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, work []float64, lwork int, iwork []int) (k, l int, ok bool) { + checkMatrix(m, n, a, lda) + checkMatrix(p, n, b, ldb) + + wantu := jobU == lapack.GSVDU + if wantu { + checkMatrix(m, m, u, ldu) + } else if jobU != lapack.GSVDNone { + panic(badGSVDJob + "U") + } + wantv := jobV == lapack.GSVDV + if wantv { + checkMatrix(p, p, v, ldv) + } else if jobV != lapack.GSVDNone { + panic(badGSVDJob + "V") + } + wantq := jobQ == lapack.GSVDQ + if wantq { + checkMatrix(n, n, q, ldq) + } else if jobQ != lapack.GSVDNone { + panic(badGSVDJob + "Q") + } + + if len(alpha) != n { + panic(badAlpha) + } + if len(beta) != n { + panic(badBeta) + } + + if lwork != -1 && lwork <= n { + panic(badWork) + } + if len(work) < max(1, lwork) { + panic(shortWork) + } + if len(iwork) < n { + panic(badWork) + } + + // Determine optimal work length. + impl.Dggsvp3(jobU, jobV, jobQ, + m, p, n, + a, lda, + b, ldb, + 0, 0, + u, ldu, + v, ldv, + q, ldq, + iwork, + work, work, -1) + lwkopt := n + int(work[0]) + lwkopt = max(lwkopt, 2*n) + lwkopt = max(lwkopt, 1) + work[0] = float64(lwkopt) + if lwork == -1 { + return 0, 0, true + } + + // Compute the Frobenius norm of matrices A and B. + anorm := impl.Dlange(lapack.NormFrob, m, n, a, lda, nil) + bnorm := impl.Dlange(lapack.NormFrob, p, n, b, ldb, nil) + + // Get machine precision and set up threshold for determining + // the effective numerical rank of the matrices A and B. + tola := float64(max(m, n)) * math.Max(anorm, dlamchS) * dlamchP + tolb := float64(max(p, n)) * math.Max(bnorm, dlamchS) * dlamchP + + // Preprocessing. + k, l = impl.Dggsvp3(jobU, jobV, jobQ, + m, p, n, + a, lda, + b, ldb, + tola, tolb, + u, ldu, + v, ldv, + q, ldq, + iwork, + work[:n], work[n:], lwork-n) + + // Compute the GSVD of two upper "triangular" matrices. + _, ok = impl.Dtgsja(jobU, jobV, jobQ, + m, p, n, + k, l, + a, lda, + b, ldb, + tola, tolb, + alpha, beta, + u, ldu, + v, ldv, + q, ldq, + work) + + // Sort the singular values and store the pivot indices in iwork + // Copy alpha to work, then sort alpha in work. + bi := blas64.Implementation() + bi.Dcopy(n, alpha, 1, work[:n], 1) + ibnd := min(l, m-k) + for i := 0; i < ibnd; i++ { + // Scan for largest alpha_{k+i}. + isub := i + smax := work[k+i] + for j := i + 1; j < ibnd; j++ { + if v := work[k+j]; v > smax { + isub = j + smax = v + } + } + if isub != i { + work[k+isub] = work[k+i] + work[k+i] = smax + iwork[k+i] = k + isub + } else { + iwork[k+i] = k + i + } + } + + work[0] = float64(lwkopt) + + return k, l, ok +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dggsvp3.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dggsvp3.go new file mode 100644 index 00000000..bd068ff1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dggsvp3.go @@ -0,0 +1,273 @@ +// 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/lapack" +) + +// Dggsvp3 computes orthogonal matrices U, V and Q such that +// +// n-k-l k l +// U^T*A*Q = k [ 0 A12 A13 ] if m-k-l >= 0; +// l [ 0 0 A23 ] +// m-k-l [ 0 0 0 ] +// +// n-k-l k l +// U^T*A*Q = k [ 0 A12 A13 ] if m-k-l < 0; +// m-k [ 0 0 A23 ] +// +// n-k-l k l +// V^T*B*Q = l [ 0 0 B13 ] +// p-l [ 0 0 0 ] +// +// where the k×k matrix A12 and l×l matrix B13 are non-singular +// upper triangular. A23 is l×l upper triangular if m-k-l >= 0, +// otherwise A23 is (m-k)×l upper trapezoidal. +// +// Dggsvp3 returns k and l, the dimensions of the sub-blocks. k+l +// is the effective numerical rank of the (m+p)×n matrix [ A^T B^T ]^T. +// +// jobU, jobV and jobQ are options for computing the orthogonal matrices. The behavior +// is as follows +// jobU == lapack.GSVDU Compute orthogonal matrix U +// jobU == lapack.GSVDNone Do not compute orthogonal matrix. +// The behavior is the same for jobV and jobQ with the exception that instead of +// lapack.GSVDU these accept lapack.GSVDV and lapack.GSVDQ respectively. +// The matrices U, V and Q must be m×m, p×p and n×n respectively unless the +// relevant job parameter is lapack.GSVDNone. +// +// tola and tolb are the convergence criteria for the Jacobi-Kogbetliantz +// iteration procedure. Generally, they are the same as used in the preprocessing +// step, for example, +// tola = max(m, n)*norm(A)*eps, +// tolb = max(p, n)*norm(B)*eps. +// Where eps is the machine epsilon. +// +// iwork must have length n, work must have length at least max(1, lwork), and +// lwork must be -1 or greater than zero, otherwise Dggsvp3 will panic. +// +// Dggsvp3 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dggsvp3(jobU, jobV, jobQ lapack.GSVDJob, m, p, n int, a []float64, lda int, b []float64, ldb int, tola, tolb float64, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, iwork []int, tau, work []float64, lwork int) (k, l int) { + const forward = true + + checkMatrix(m, n, a, lda) + checkMatrix(p, n, b, ldb) + + wantu := jobU == lapack.GSVDU + if !wantu && jobU != lapack.GSVDNone { + panic(badGSVDJob + "U") + } + if jobU != lapack.GSVDNone { + checkMatrix(m, m, u, ldu) + } + + wantv := jobV == lapack.GSVDV + if !wantv && jobV != lapack.GSVDNone { + panic(badGSVDJob + "V") + } + if jobV != lapack.GSVDNone { + checkMatrix(p, p, v, ldv) + } + + wantq := jobQ == lapack.GSVDQ + if !wantq && jobQ != lapack.GSVDNone { + panic(badGSVDJob + "Q") + } + if jobQ != lapack.GSVDNone { + checkMatrix(n, n, q, ldq) + } + + if len(iwork) != n { + panic(badWork) + } + if lwork != -1 && lwork < 1 { + panic(badWork) + } + if len(work) < max(1, lwork) { + panic(badWork) + } + + var lwkopt int + impl.Dgeqp3(p, n, b, ldb, iwork, tau, work, -1) + lwkopt = int(work[0]) + if wantv { + lwkopt = max(lwkopt, p) + } + lwkopt = max(lwkopt, min(n, p)) + lwkopt = max(lwkopt, m) + if wantq { + lwkopt = max(lwkopt, n) + } + impl.Dgeqp3(m, n, a, lda, iwork, tau, work, -1) + lwkopt = max(lwkopt, int(work[0])) + lwkopt = max(1, lwkopt) + if lwork == -1 { + work[0] = float64(lwkopt) + return 0, 0 + } + + // tau check must come after lwkopt query since + // the Dggsvd3 call for lwkopt query may have + // lwork == -1, and tau is provided by work. + if len(tau) < n { + panic(badTau) + } + + // QR with column pivoting of B: B*P = V*[ S11 S12 ]. + // [ 0 0 ] + for i := range iwork[:n] { + iwork[i] = 0 + } + impl.Dgeqp3(p, n, b, ldb, iwork, tau, work, lwork) + + // Update A := A*P. + impl.Dlapmt(forward, m, n, a, lda, iwork) + + // Determine the effective rank of matrix B. + for i := 0; i < min(p, n); i++ { + if math.Abs(b[i*ldb+i]) > tolb { + l++ + } + } + + if wantv { + // Copy the details of V, and form V. + impl.Dlaset(blas.All, p, p, 0, 0, v, ldv) + if p > 1 { + impl.Dlacpy(blas.Lower, p-1, min(p, n), b[ldb:], ldb, v[ldv:], ldv) + } + impl.Dorg2r(p, p, min(p, n), v, ldv, tau, work) + } + + // Clean up B. + for i := 1; i < l; i++ { + r := b[i*ldb : i*ldb+i] + for j := range r { + r[j] = 0 + } + } + if p > l { + impl.Dlaset(blas.All, p-l, n, 0, 0, b[l*ldb:], ldb) + } + + if wantq { + // Set Q = I and update Q := Q*P. + impl.Dlaset(blas.All, n, n, 0, 1, q, ldq) + impl.Dlapmt(forward, n, n, q, ldq, iwork) + } + + if p >= l && n != l { + // RQ factorization of [ S11 S12 ]: [ S11 S12 ] = [ 0 S12 ]*Z. + impl.Dgerq2(l, n, b, ldb, tau, work) + + // Update A := A*Z^T. + impl.Dormr2(blas.Right, blas.Trans, m, n, l, b, ldb, tau, a, lda, work) + + if wantq { + // Update Q := Q*Z^T. + impl.Dormr2(blas.Right, blas.Trans, n, n, l, b, ldb, tau, q, ldq, work) + } + + // Clean up B. + impl.Dlaset(blas.All, l, n-l, 0, 0, b, ldb) + for i := 1; i < l; i++ { + r := b[i*ldb+n-l : i*ldb+i+n-l] + for j := range r { + r[j] = 0 + } + } + } + + // Let N-L L + // A = [ A11 A12 ] M, + // + // then the following does the complete QR decomposition of A11: + // + // A11 = U*[ 0 T12 ]*P1^T. + // [ 0 0 ] + for i := range iwork[:n-l] { + iwork[i] = 0 + } + impl.Dgeqp3(m, n-l, a, lda, iwork[:n-l], tau, work, lwork) + + // Determine the effective rank of A11. + for i := 0; i < min(m, n-l); i++ { + if math.Abs(a[i*lda+i]) > tola { + k++ + } + } + + // Update A12 := U^T*A12, where A12 = A[0:m, n-l:n]. + impl.Dorm2r(blas.Left, blas.Trans, m, l, min(m, n-l), a, lda, tau, a[n-l:], lda, work) + + if wantu { + // Copy the details of U, and form U. + impl.Dlaset(blas.All, m, m, 0, 0, u, ldu) + if m > 1 { + impl.Dlacpy(blas.Lower, m-1, min(m, n-l), a[lda:], lda, u[ldu:], ldu) + } + impl.Dorg2r(m, m, min(m, n-l), u, ldu, tau, work) + } + + if wantq { + // Update Q[0:n, 0:n-l] := Q[0:n, 0:n-l]*P1. + impl.Dlapmt(forward, n, n-l, q, ldq, iwork[:n-l]) + } + + // Clean up A: set the strictly lower triangular part of + // A[0:k, 0:k] = 0, and A[k:m, 0:n-l] = 0. + for i := 1; i < k; i++ { + r := a[i*lda : i*lda+i] + for j := range r { + r[j] = 0 + } + } + if m > k { + impl.Dlaset(blas.All, m-k, n-l, 0, 0, a[k*lda:], lda) + } + + if n-l > k { + // RQ factorization of [ T11 T12 ] = [ 0 T12 ]*Z1. + impl.Dgerq2(k, n-l, a, lda, tau, work) + + if wantq { + // Update Q[0:n, 0:n-l] := Q[0:n, 0:n-l]*Z1^T. + impl.Dorm2r(blas.Right, blas.Trans, n, n-l, k, a, lda, tau, q, ldq, work) + } + + // Clean up A. + impl.Dlaset(blas.All, k, n-l-k, 0, 0, a, lda) + for i := 1; i < k; i++ { + r := a[i*lda+n-k-l : i*lda+i+n-k-l] + for j := range r { + a[j] = 0 + } + } + } + + if m > k { + // QR factorization of A[k:m, n-l:n]. + impl.Dgeqr2(m-k, l, a[k*lda+n-l:], lda, tau, work) + if wantu { + // Update U[:, k:m) := U[:, k:m]*U1. + impl.Dorm2r(blas.Right, blas.NoTrans, m, m-k, min(m-k, l), a[k*lda+n-l:], lda, tau, u[k:], ldu, work) + } + + // Clean up A. + for i := k + 1; i < m; i++ { + r := a[i*lda+n-l : i*lda+min(n-l+i-k, n)] + for j := range r { + r[j] = 0 + } + } + } + + work[0] = float64(lwkopt) + return k, l +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dhseqr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dhseqr.go new file mode 100644 index 00000000..a8c81888 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dhseqr.go @@ -0,0 +1,257 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dhseqr computes the eigenvalues of an n×n Hessenberg matrix H and, +// optionally, the matrices T and Z from the Schur decomposition +// H = Z T Z^T, +// where T is an n×n upper quasi-triangular matrix (the Schur form), and Z is +// the n×n orthogonal matrix of Schur vectors. +// +// Optionally Z may be postmultiplied into an input orthogonal matrix Q so that +// this routine can give the Schur factorization of a matrix A which has been +// reduced to the Hessenberg form H by the orthogonal matrix Q: +// A = Q H Q^T = (QZ) T (QZ)^T. +// +// If job == lapack.EigenvaluesOnly, only the eigenvalues will be computed. +// If job == lapack.EigenvaluesAndSchur, the eigenvalues and the Schur form T will +// be computed. +// For other values of job Dhseqr will panic. +// +// If compz == lapack.None, no Schur vectors will be computed and Z will not be +// referenced. +// If compz == lapack.HessEV, on return Z will contain the matrix of Schur +// vectors of H. +// If compz == lapack.OriginalEV, on entry z is assumed to contain the orthogonal +// matrix Q that is the identity except for the submatrix +// Q[ilo:ihi+1,ilo:ihi+1]. On return z will be updated to the product Q*Z. +// +// ilo and ihi determine the block of H on which Dhseqr operates. It is assumed +// that H is already upper triangular in rows and columns [0:ilo] and [ihi+1:n], +// although it will be only checked that the block is isolated, that is, +// ilo == 0 or H[ilo,ilo-1] == 0, +// ihi == n-1 or H[ihi+1,ihi] == 0, +// and Dhseqr will panic otherwise. ilo and ihi are typically set by a previous +// call to Dgebal, otherwise they should be set to 0 and n-1, respectively. It +// must hold that +// 0 <= ilo <= ihi < n, if n > 0, +// ilo == 0 and ihi == -1, if n == 0. +// +// wr and wi must have length n. +// +// work must have length at least lwork and lwork must be at least max(1,n) +// otherwise Dhseqr will panic. The minimum lwork delivers very good and +// sometimes optimal performance, although lwork as large as 11*n may be +// required. On return, work[0] will contain the optimal value of lwork. +// +// If lwork is -1, instead of performing Dhseqr, the function only estimates the +// optimal workspace size and stores it into work[0]. Neither h nor z are +// accessed. +// +// unconverged indicates whether Dhseqr computed all the eigenvalues. +// +// If unconverged == 0, all the eigenvalues have been computed and their real +// and imaginary parts will be stored on return in wr and wi, respectively. If +// two eigenvalues are computed as a complex conjugate pair, they are stored in +// consecutive elements of wr and wi, say the i-th and (i+1)th, with wi[i] > 0 +// and wi[i+1] < 0. +// +// If unconverged == 0 and job == lapack.EigenvaluesAndSchur, on return H will +// contain the upper quasi-triangular matrix T from the Schur decomposition (the +// Schur form). 2×2 diagonal blocks (corresponding to complex conjugate pairs of +// eigenvalues) will be returned in standard form, with +// H[i,i] == H[i+1,i+1], +// and +// H[i+1,i]*H[i,i+1] < 0. +// The eigenvalues will be stored in wr and wi in the same order as on the +// diagonal of the Schur form returned in H, with +// wr[i] = H[i,i], +// and, if H[i:i+2,i:i+2] is a 2×2 diagonal block, +// wi[i] = sqrt(-H[i+1,i]*H[i,i+1]), +// wi[i+1] = -wi[i]. +// +// If unconverged == 0 and job == lapack.EigenvaluesOnly, the contents of h +// on return is unspecified. +// +// If unconverged > 0, some eigenvalues have not converged, and the blocks +// [0:ilo] and [unconverged:n] of wr and wi will contain those eigenvalues which +// have been successfully computed. Failures are rare. +// +// If unconverged > 0 and job == lapack.EigenvaluesOnly, on return the +// remaining unconverged eigenvalues are the eigenvalues of the upper Hessenberg +// matrix H[ilo:unconverged,ilo:unconverged]. +// +// If unconverged > 0 and job == lapack.EigenvaluesAndSchur, then on +// return +// (initial H) U = U (final H), (*) +// where U is an orthogonal matrix. The final H is upper Hessenberg and +// H[unconverged:ihi+1,unconverged:ihi+1] is upper quasi-triangular. +// +// If unconverged > 0 and compz == lapack.OriginalEV, then on return +// (final Z) = (initial Z) U, +// where U is the orthogonal matrix in (*) regardless of the value of job. +// +// If unconverged > 0 and compz == lapack.HessEV, then on return +// (final Z) = U, +// where U is the orthogonal matrix in (*) regardless of the value of job. +// +// References: +// [1] R. Byers. LAPACK 3.1 xHSEQR: Tuning and Implementation Notes on the +// Small Bulge Multi-Shift QR Algorithm with Aggressive Early Deflation. +// LAPACK Working Note 187 (2007) +// URL: http://www.netlib.org/lapack/lawnspdf/lawn187.pdf +// [2] K. Braman, R. Byers, R. Mathias. The Multishift QR Algorithm. Part I: +// Maintaining Well-Focused Shifts and Level 3 Performance. SIAM J. Matrix +// Anal. Appl. 23(4) (2002), pp. 929—947 +// URL: http://dx.doi.org/10.1137/S0895479801384573 +// [3] K. Braman, R. Byers, R. Mathias. The Multishift QR Algorithm. Part II: +// Aggressive Early Deflation. SIAM J. Matrix Anal. Appl. 23(4) (2002), pp. 948—973 +// URL: http://dx.doi.org/10.1137/S0895479801384585 +// +// Dhseqr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dhseqr(job lapack.EVJob, compz lapack.EVComp, n, ilo, ihi int, h []float64, ldh int, wr, wi []float64, z []float64, ldz int, work []float64, lwork int) (unconverged int) { + var wantt bool + switch job { + default: + panic(badEVJob) + case lapack.EigenvaluesOnly: + case lapack.EigenvaluesAndSchur: + wantt = true + } + var wantz bool + switch compz { + default: + panic(badEVComp) + case lapack.None: + case lapack.HessEV, lapack.OriginalEV: + wantz = true + } + switch { + case n < 0: + panic(nLT0) + case ilo < 0 || max(0, n-1) < ilo: + panic(badIlo) + case ihi < min(ilo, n-1) || n <= ihi: + panic(badIhi) + case len(work) < lwork: + panic(shortWork) + case lwork < max(1, n) && lwork != -1: + panic(badWork) + } + if lwork != -1 { + checkMatrix(n, n, h, ldh) + switch { + case wantz: + checkMatrix(n, n, z, ldz) + case len(wr) < n: + panic("lapack: wr has insufficient length") + case len(wi) < n: + panic("lapack: wi has insufficient length") + } + } + + const ( + // Matrices of order ntiny or smaller must be processed by + // Dlahqr because of insufficient subdiagonal scratch space. + // This is a hard limit. + ntiny = 11 + + // nl is the size of a local workspace to help small matrices + // through a rare Dlahqr failure. nl > ntiny is required and + // nl <= nmin = Ilaenv(ispec=12,...) is recommended (the default + // value of nmin is 75). Using nl = 49 allows up to six + // simultaneous shifts and a 16×16 deflation window. + nl = 49 + ) + + // Quick return if possible. + if n == 0 { + work[0] = 1 + return 0 + } + + // Quick return in case of a workspace query. + if lwork == -1 { + impl.Dlaqr04(wantt, wantz, n, ilo, ihi, nil, 0, nil, nil, ilo, ihi, nil, 0, work, -1, 1) + work[0] = math.Max(float64(n), work[0]) + return 0 + } + + // Copy eigenvalues isolated by Dgebal. + for i := 0; i < ilo; i++ { + wr[i] = h[i*ldh+i] + wi[i] = 0 + } + for i := ihi + 1; i < n; i++ { + wr[i] = h[i*ldh+i] + wi[i] = 0 + } + + // Initialize Z to identity matrix if requested. + if compz == lapack.HessEV { + impl.Dlaset(blas.All, n, n, 0, 1, z, ldz) + } + + // Quick return if possible. + if ilo == ihi { + wr[ilo] = h[ilo*ldh+ilo] + wi[ilo] = 0 + return 0 + } + + // Dlahqr/Dlaqr04 crossover point. + nmin := impl.Ilaenv(12, "DHSEQR", string(job)+string(compz), n, ilo, ihi, lwork) + nmin = max(ntiny, nmin) + + if n > nmin { + // Dlaqr0 for big matrices. + unconverged = impl.Dlaqr04(wantt, wantz, n, ilo, ihi, h, ldh, wr[:ihi+1], wi[:ihi+1], + ilo, ihi, z, ldz, work, lwork, 1) + } else { + // Dlahqr for small matrices. + unconverged = impl.Dlahqr(wantt, wantz, n, ilo, ihi, h, ldh, wr[:ihi+1], wi[:ihi+1], + ilo, ihi, z, ldz) + if unconverged > 0 { + // A rare Dlahqr failure! Dlaqr04 sometimes succeeds + // when Dlahqr fails. + kbot := unconverged + if n >= nl { + // Larger matrices have enough subdiagonal + // scratch space to call Dlaqr04 directly. + unconverged = impl.Dlaqr04(wantt, wantz, n, ilo, kbot, h, ldh, + wr[:ihi+1], wi[:ihi+1], ilo, ihi, z, ldz, work, lwork, 1) + } else { + // Tiny matrices don't have enough subdiagonal + // scratch space to benefit from Dlaqr04. Hence, + // tiny matrices must be copied into a larger + // array before calling Dlaqr04. + var hl [nl * nl]float64 + impl.Dlacpy(blas.All, n, n, h, ldh, hl[:], nl) + impl.Dlaset(blas.All, nl, nl-n, 0, 0, hl[n:], nl) + var workl [nl]float64 + unconverged = impl.Dlaqr04(wantt, wantz, nl, ilo, kbot, hl[:], nl, + wr[:ihi+1], wi[:ihi+1], ilo, ihi, z, ldz, workl[:], nl, 1) + work[0] = workl[0] + if wantt || unconverged > 0 { + impl.Dlacpy(blas.All, n, n, hl[:], nl, h, ldh) + } + } + } + } + // Zero out under the first subdiagonal, if necessary. + if (wantt || unconverged > 0) && n > 2 { + impl.Dlaset(blas.Lower, n-2, n-2, 0, 0, h[2*ldh:], ldh) + } + + work[0] = math.Max(float64(n), work[0]) + return unconverged +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlabrd.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlabrd.go new file mode 100644 index 00000000..abe5dae0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlabrd.go @@ -0,0 +1,150 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlabrd reduces the first NB rows and columns of a real general m×n matrix +// A to upper or lower bidiagonal form by an orthogonal transformation +// Q**T * A * P +// If m >= n, A is reduced to upper bidiagonal form and upon exit the elements +// on and below the diagonal in the first nb columns represent the elementary +// reflectors, and the elements above the diagonal in the first nb rows represent +// the matrix P. If m < n, A is reduced to lower bidiagonal form and the elements +// P is instead stored above the diagonal. +// +// The reduction to bidiagonal form is stored in d and e, where d are the diagonal +// elements, and e are the off-diagonal elements. +// +// The matrices Q and P are products of elementary reflectors +// Q = H_0 * H_1 * ... * H_{nb-1} +// P = G_0 * G_1 * ... * G_{nb-1} +// where +// H_i = I - tauQ[i] * v_i * v_i^T +// G_i = I - tauP[i] * u_i * u_i^T +// +// As an example, on exit the entries of A when m = 6, n = 5, and nb = 2 +// [ 1 1 u1 u1 u1] +// [v1 1 1 u2 u2] +// [v1 v2 a a a] +// [v1 v2 a a a] +// [v1 v2 a a a] +// [v1 v2 a a a] +// and when m = 5, n = 6, and nb = 2 +// [ 1 u1 u1 u1 u1 u1] +// [ 1 1 u2 u2 u2 u2] +// [v1 1 a a a a] +// [v1 v2 a a a a] +// [v1 v2 a a a a] +// +// Dlabrd also returns the matrices X and Y which are used with U and V to +// apply the transformation to the unreduced part of the matrix +// A := A - V*Y^T - X*U^T +// and returns the matrices X and Y which are needed to apply the +// transformation to the unreduced part of A. +// +// X is an m×nb matrix, Y is an n×nb matrix. d, e, taup, and tauq must all have +// length at least nb. Dlabrd will panic if these size constraints are violated. +// +// Dlabrd is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlabrd(m, n, nb int, a []float64, lda int, d, e, tauQ, tauP, x []float64, ldx int, y []float64, ldy int) { + checkMatrix(m, n, a, lda) + checkMatrix(m, nb, x, ldx) + checkMatrix(n, nb, y, ldy) + if len(d) < nb { + panic(badD) + } + if len(e) < nb { + panic(badE) + } + if len(tauQ) < nb { + panic(badTauQ) + } + if len(tauP) < nb { + panic(badTauP) + } + if m <= 0 || n <= 0 { + return + } + bi := blas64.Implementation() + if m >= n { + // Reduce to upper bidiagonal form. + for i := 0; i < nb; i++ { + bi.Dgemv(blas.NoTrans, m-i, i, -1, a[i*lda:], lda, y[i*ldy:], 1, 1, a[i*lda+i:], lda) + bi.Dgemv(blas.NoTrans, m-i, i, -1, x[i*ldx:], ldx, a[i:], lda, 1, a[i*lda+i:], lda) + + a[i*lda+i], tauQ[i] = impl.Dlarfg(m-i, a[i*lda+i], a[min(i+1, m-1)*lda+i:], lda) + d[i] = a[i*lda+i] + if i < n-1 { + // Compute Y[i+1:n, i]. + a[i*lda+i] = 1 + bi.Dgemv(blas.Trans, m-i, n-i-1, 1, a[i*lda+i+1:], lda, a[i*lda+i:], lda, 0, y[(i+1)*ldy+i:], ldy) + bi.Dgemv(blas.Trans, m-i, i, 1, a[i*lda:], lda, a[i*lda+i:], lda, 0, y[i:], ldy) + bi.Dgemv(blas.NoTrans, n-i-1, i, -1, y[(i+1)*ldy:], ldy, y[i:], ldy, 1, y[(i+1)*ldy+i:], ldy) + bi.Dgemv(blas.Trans, m-i, i, 1, x[i*ldx:], ldx, a[i*lda+i:], lda, 0, y[i:], ldy) + bi.Dgemv(blas.Trans, i, n-i-1, -1, a[i+1:], lda, y[i:], ldy, 1, y[(i+1)*ldy+i:], ldy) + bi.Dscal(n-i-1, tauQ[i], y[(i+1)*ldy+i:], ldy) + + // Update A[i, i+1:n]. + bi.Dgemv(blas.NoTrans, n-i-1, i+1, -1, y[(i+1)*ldy:], ldy, a[i*lda:], 1, 1, a[i*lda+i+1:], 1) + bi.Dgemv(blas.Trans, i, n-i-1, -1, a[i+1:], lda, x[i*ldx:], 1, 1, a[i*lda+i+1:], 1) + + // Generate reflection P[i] to annihilate A[i, i+2:n]. + a[i*lda+i+1], tauP[i] = impl.Dlarfg(n-i-1, a[i*lda+i+1], a[i*lda+min(i+2, n-1):], 1) + e[i] = a[i*lda+i+1] + a[i*lda+i+1] = 1 + + // Compute X[i+1:m, i]. + bi.Dgemv(blas.NoTrans, m-i-1, n-i-1, 1, a[(i+1)*lda+i+1:], lda, a[i*lda+i+1:], 1, 0, x[(i+1)*ldx+i:], ldx) + bi.Dgemv(blas.Trans, n-i-1, i+1, 1, y[(i+1)*ldy:], ldy, a[i*lda+i+1:], 1, 0, x[i:], ldx) + bi.Dgemv(blas.NoTrans, m-i-1, i+1, -1, a[(i+1)*lda:], lda, x[i:], ldx, 1, x[(i+1)*ldx+i:], ldx) + bi.Dgemv(blas.NoTrans, i, n-i-1, 1, a[i+1:], lda, a[i*lda+i+1:], 1, 0, x[i:], ldx) + bi.Dgemv(blas.NoTrans, m-i-1, i, -1, x[(i+1)*ldx:], ldx, x[i:], ldx, 1, x[(i+1)*ldx+i:], ldx) + bi.Dscal(m-i-1, tauP[i], x[(i+1)*ldx+i:], ldx) + } + } + return + } + // Reduce to lower bidiagonal form. + for i := 0; i < nb; i++ { + // Update A[i,i:n] + bi.Dgemv(blas.NoTrans, n-i, i, -1, y[i*ldy:], ldy, a[i*lda:], 1, 1, a[i*lda+i:], 1) + bi.Dgemv(blas.Trans, i, n-i, -1, a[i:], lda, x[i*ldx:], 1, 1, a[i*lda+i:], 1) + + // Generate reflection P[i] to annihilate A[i, i+1:n] + a[i*lda+i], tauP[i] = impl.Dlarfg(n-i, a[i*lda+i], a[i*lda+min(i+1, n-1):], 1) + d[i] = a[i*lda+i] + if i < m-1 { + a[i*lda+i] = 1 + // Compute X[i+1:m, i]. + bi.Dgemv(blas.NoTrans, m-i-1, n-i, 1, a[(i+1)*lda+i:], lda, a[i*lda+i:], 1, 0, x[(i+1)*ldx+i:], ldx) + bi.Dgemv(blas.Trans, n-i, i, 1, y[i*ldy:], ldy, a[i*lda+i:], 1, 0, x[i:], ldx) + bi.Dgemv(blas.NoTrans, m-i-1, i, -1, a[(i+1)*lda:], lda, x[i:], ldx, 1, x[(i+1)*ldx+i:], ldx) + bi.Dgemv(blas.NoTrans, i, n-i, 1, a[i:], lda, a[i*lda+i:], 1, 0, x[i:], ldx) + bi.Dgemv(blas.NoTrans, m-i-1, i, -1, x[(i+1)*ldx:], ldx, x[i:], ldx, 1, x[(i+1)*ldx+i:], ldx) + bi.Dscal(m-i-1, tauP[i], x[(i+1)*ldx+i:], ldx) + + // Update A[i+1:m, i]. + bi.Dgemv(blas.NoTrans, m-i-1, i, -1, a[(i+1)*lda:], lda, y[i*ldy:], 1, 1, a[(i+1)*lda+i:], lda) + bi.Dgemv(blas.NoTrans, m-i-1, i+1, -1, x[(i+1)*ldx:], ldx, a[i:], lda, 1, a[(i+1)*lda+i:], lda) + + // Generate reflection Q[i] to annihilate A[i+2:m, i]. + a[(i+1)*lda+i], tauQ[i] = impl.Dlarfg(m-i-1, a[(i+1)*lda+i], a[min(i+2, m-1)*lda+i:], lda) + e[i] = a[(i+1)*lda+i] + a[(i+1)*lda+i] = 1 + + // Compute Y[i+1:n, i]. + bi.Dgemv(blas.Trans, m-i-1, n-i-1, 1, a[(i+1)*lda+i+1:], lda, a[(i+1)*lda+i:], lda, 0, y[(i+1)*ldy+i:], ldy) + bi.Dgemv(blas.Trans, m-i-1, i, 1, a[(i+1)*lda:], lda, a[(i+1)*lda+i:], lda, 0, y[i:], ldy) + bi.Dgemv(blas.NoTrans, n-i-1, i, -1, y[(i+1)*ldy:], ldy, y[i:], ldy, 1, y[(i+1)*ldy+i:], ldy) + bi.Dgemv(blas.Trans, m-i-1, i+1, 1, x[(i+1)*ldx:], ldx, a[(i+1)*lda+i:], lda, 0, y[i:], ldy) + bi.Dgemv(blas.Trans, i+1, n-i-1, -1, a[i+1:], lda, y[i:], ldy, 1, y[(i+1)*ldy+i:], ldy) + bi.Dscal(n-i-1, tauQ[i], y[(i+1)*ldy+i:], ldy) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlacn2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlacn2.go new file mode 100644 index 00000000..0f38ac1d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlacn2.go @@ -0,0 +1,134 @@ +// 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/blas64" +) + +// Dlacn2 estimates the 1-norm of an n×n matrix A using sequential updates with +// matrix-vector products provided externally. +// +// Dlacn2 is called sequentially and it returns the value of est and kase to be +// used on the next call. +// On the initial call, kase must be 0. +// In between calls, x must be overwritten by +// A * X if kase was returned as 1, +// A^T * X if kase was returned as 2, +// and all other parameters must not be changed. +// On the final return, kase is returned as 0, v contains A*W where W is a +// vector, and est = norm(V)/norm(W) is a lower bound for 1-norm of A. +// +// v, x, and isgn must all have length n and n must be at least 1, otherwise +// Dlacn2 will panic. isave is used for temporary storage. +// +// Dlacn2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlacn2(n int, v, x []float64, isgn []int, est float64, kase int, isave *[3]int) (float64, int) { + if n < 1 { + panic("lapack: non-positive n") + } + checkVector(n, x, 1) + checkVector(n, v, 1) + if len(isgn) < n { + panic("lapack: insufficient isgn length") + } + if isave[0] < 0 || isave[0] > 5 { + panic("lapack: bad isave value") + } + if isave[0] == 0 && kase != 0 { + panic("lapack: bad isave value") + } + itmax := 5 + bi := blas64.Implementation() + if kase == 0 { + for i := 0; i < n; i++ { + x[i] = 1 / float64(n) + } + kase = 1 + isave[0] = 1 + return est, kase + } + switch isave[0] { + default: + panic("unreachable") + case 1: + if n == 1 { + v[0] = x[0] + est = math.Abs(v[0]) + kase = 0 + return est, kase + } + est = bi.Dasum(n, x, 1) + for i := 0; i < n; i++ { + x[i] = math.Copysign(1, x[i]) + isgn[i] = int(x[i]) + } + kase = 2 + isave[0] = 2 + return est, kase + case 2: + isave[1] = bi.Idamax(n, x, 1) + isave[2] = 2 + for i := 0; i < n; i++ { + x[i] = 0 + } + x[isave[1]] = 1 + kase = 1 + isave[0] = 3 + return est, kase + case 3: + bi.Dcopy(n, x, 1, v, 1) + estold := est + est = bi.Dasum(n, v, 1) + sameSigns := true + for i := 0; i < n; i++ { + if int(math.Copysign(1, x[i])) != isgn[i] { + sameSigns = false + break + } + } + if !sameSigns && est > estold { + for i := 0; i < n; i++ { + x[i] = math.Copysign(1, x[i]) + isgn[i] = int(x[i]) + } + kase = 2 + isave[0] = 4 + return est, kase + } + case 4: + jlast := isave[1] + isave[1] = bi.Idamax(n, x, 1) + if x[jlast] != math.Abs(x[isave[1]]) && isave[2] < itmax { + isave[2] += 1 + for i := 0; i < n; i++ { + x[i] = 0 + } + x[isave[1]] = 1 + kase = 1 + isave[0] = 3 + return est, kase + } + case 5: + tmp := 2 * (bi.Dasum(n, x, 1)) / float64(3*n) + if tmp > est { + bi.Dcopy(n, x, 1, v, 1) + est = tmp + } + kase = 0 + return est, kase + } + // Iteration complete. Final stage + altsgn := 1.0 + for i := 0; i < n; i++ { + x[i] = altsgn * (1 + float64(i)/float64(n-1)) + altsgn *= -1 + } + kase = 1 + isave[0] = 5 + return est, kase +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlacpy.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlacpy.go new file mode 100644 index 00000000..f5b90e17 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlacpy.go @@ -0,0 +1,40 @@ +// 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/blas" + +// Dlacpy copies the elements of A specified by uplo into B. Uplo can specify +// a triangular portion with blas.Upper or blas.Lower, or can specify all of the +// elemest with blas.All. +// +// Dlacpy is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlacpy(uplo blas.Uplo, m, n int, a []float64, lda int, b []float64, ldb int) { + checkMatrix(m, n, a, lda) + checkMatrix(m, n, b, ldb) + switch uplo { + default: + panic(badUplo) + case blas.Upper: + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + b[i*ldb+j] = a[i*lda+j] + } + } + + case blas.Lower: + for i := 0; i < m; i++ { + for j := 0; j < min(i+1, n); j++ { + b[i*ldb+j] = a[i*lda+j] + } + } + case blas.All: + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + b[i*ldb+j] = a[i*lda+j] + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlae2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlae2.go new file mode 100644 index 00000000..17f356e8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlae2.go @@ -0,0 +1,49 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "math" + +// Dlae2 computes the eigenvalues of a 2×2 symmetric matrix +// [a b] +// [b c] +// and returns the eigenvalue with the larger absolute value as rt1 and the +// smaller as rt2. +// +// Dlae2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlae2(a, b, c float64) (rt1, rt2 float64) { + sm := a + c + df := a - c + adf := math.Abs(df) + tb := b + b + ab := math.Abs(tb) + acmx := c + acmn := a + if math.Abs(a) > math.Abs(c) { + acmx = a + acmn = c + } + var rt float64 + if adf > ab { + rt = adf * math.Sqrt(1+(ab/adf)*(ab/adf)) + } else if adf < ab { + rt = ab * math.Sqrt(1+(adf/ab)*(adf/ab)) + } else { + rt = ab * math.Sqrt2 + } + if sm < 0 { + rt1 = 0.5 * (sm - rt) + rt2 = (acmx/rt1)*acmn - (b/rt1)*b + return rt1, rt2 + } + if sm > 0 { + rt1 = 0.5 * (sm + rt) + rt2 = (acmx/rt1)*acmn - (b/rt1)*b + return rt1, rt2 + } + rt1 = 0.5 * rt + rt2 = -0.5 * rt + return rt1, rt2 +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaev2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaev2.go new file mode 100644 index 00000000..50fd7d0b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaev2.go @@ -0,0 +1,82 @@ +// 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" + +// Dlaev2 computes the Eigen decomposition of a symmetric 2×2 matrix. +// The matrix is given by +// [a b] +// [b c] +// Dlaev2 returns rt1 and rt2, the eigenvalues of the matrix where |RT1| > |RT2|, +// and [cs1, sn1] which is the unit right eigenvalue for RT1. +// [ cs1 sn1] [a b] [cs1 -sn1] = [rt1 0] +// [-sn1 cs1] [b c] [sn1 cs1] [ 0 rt2] +// +// Dlaev2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaev2(a, b, c float64) (rt1, rt2, cs1, sn1 float64) { + sm := a + c + df := a - c + adf := math.Abs(df) + tb := b + b + ab := math.Abs(tb) + acmx := c + acmn := a + if math.Abs(a) > math.Abs(c) { + acmx = a + acmn = c + } + var rt float64 + if adf > ab { + rt = adf * math.Sqrt(1+(ab/adf)*(ab/adf)) + } else if adf < ab { + rt = ab * math.Sqrt(1+(adf/ab)*(adf/ab)) + } else { + rt = ab * math.Sqrt(2) + } + var sgn1 float64 + if sm < 0 { + rt1 = 0.5 * (sm - rt) + sgn1 = -1 + rt2 = (acmx/rt1)*acmn - (b/rt1)*b + } else if sm > 0 { + rt1 = 0.5 * (sm + rt) + sgn1 = 1 + rt2 = (acmx/rt1)*acmn - (b/rt1)*b + } else { + rt1 = 0.5 * rt + rt2 = -0.5 * rt + sgn1 = 1 + } + var cs, sgn2 float64 + if df >= 0 { + cs = df + rt + sgn2 = 1 + } else { + cs = df - rt + sgn2 = -1 + } + acs := math.Abs(cs) + if acs > ab { + ct := -tb / cs + sn1 = 1 / math.Sqrt(1+ct*ct) + cs1 = ct * sn1 + } else { + if ab == 0 { + cs1 = 1 + sn1 = 0 + } else { + tn := -cs / tb + cs1 = 1 / math.Sqrt(1+tn*tn) + sn1 = tn * cs1 + } + } + if sgn1 == sgn2 { + tn := cs1 + cs1 = -sn1 + sn1 = tn + } + return rt1, rt2, cs1, sn1 +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaexc.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaexc.go new file mode 100644 index 00000000..470b63a4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaexc.go @@ -0,0 +1,261 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dlaexc swaps two adjacent diagonal blocks of order 1 or 2 in an n×n upper +// quasi-triangular matrix T by an orthogonal similarity transformation. +// +// T must be in Schur canonical form, that is, block upper triangular with 1×1 +// and 2×2 diagonal blocks; each 2×2 diagonal block has its diagonal elements +// equal and its off-diagonal elements of opposite sign. On return, T will +// contain the updated matrix again in Schur canonical form. +// +// If wantq is true, the transformation is accumulated in the n×n matrix Q, +// otherwise Q is not referenced. +// +// j1 is the index of the first row of the first block. n1 and n2 are the order +// of the first and second block, respectively. +// +// work must have length at least n, otherwise Dlaexc will panic. +// +// If ok is false, the transformed matrix T would be too far from Schur form. +// The blocks are not swapped, and T and Q are not modified. +// +// If n1 and n2 are both equal to 1, Dlaexc will always return true. +// +// Dlaexc is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaexc(wantq bool, n int, t []float64, ldt int, q []float64, ldq int, j1, n1, n2 int, work []float64) (ok bool) { + checkMatrix(n, n, t, ldt) + if wantq { + checkMatrix(n, n, q, ldq) + } + if j1 < 0 || n <= j1 { + panic("lapack: index j1 out of range") + } + if len(work) < n { + panic(badWork) + } + if n1 < 0 || 2 < n1 { + panic("lapack: invalid value of n1") + } + if n2 < 0 || 2 < n2 { + panic("lapack: invalid value of n2") + } + + if n == 0 || n1 == 0 || n2 == 0 { + return true + } + if j1+n1 >= n { + // TODO(vladimir-ch): Reference LAPACK does this check whether + // the start of the second block is in the matrix T. It returns + // true if it is not and moreover it does not check whether the + // whole second block fits into T. This does not feel + // satisfactory. The only caller of Dlaexc is Dtrexc, so if the + // caller makes sure that this does not happen, we could be + // stricter here. + return true + } + + j2 := j1 + 1 + j3 := j1 + 2 + + bi := blas64.Implementation() + + if n1 == 1 && n2 == 1 { + // Swap two 1×1 blocks. + t11 := t[j1*ldt+j1] + t22 := t[j2*ldt+j2] + + // Determine the transformation to perform the interchange. + cs, sn, _ := impl.Dlartg(t[j1*ldt+j2], t22-t11) + + // Apply transformation to the matrix T. + if n-j3 > 0 { + bi.Drot(n-j3, t[j1*ldt+j3:], 1, t[j2*ldt+j3:], 1, cs, sn) + } + if j1 > 0 { + bi.Drot(j1, t[j1:], ldt, t[j2:], ldt, cs, sn) + } + + t[j1*ldt+j1] = t22 + t[j2*ldt+j2] = t11 + + if wantq { + // Accumulate transformation in the matrix Q. + bi.Drot(n, q[j1:], ldq, q[j2:], ldq, cs, sn) + } + + return true + } + + // Swapping involves at least one 2×2 block. + // + // Copy the diagonal block of order n1+n2 to the local array d and + // compute its norm. + nd := n1 + n2 + var d [16]float64 + const ldd = 4 + impl.Dlacpy(blas.All, nd, nd, t[j1*ldt+j1:], ldt, d[:], ldd) + dnorm := impl.Dlange(lapack.MaxAbs, nd, nd, d[:], ldd, work) + + // Compute machine-dependent threshold for test for accepting swap. + eps := dlamchP + thresh := math.Max(10*eps*dnorm, dlamchS/eps) + + // Solve T11*X - X*T22 = scale*T12 for X. + var x [4]float64 + const ldx = 2 + scale, _, _ := impl.Dlasy2(false, false, -1, n1, n2, d[:], ldd, d[n1*ldd+n1:], ldd, d[n1:], ldd, x[:], ldx) + + // Swap the adjacent diagonal blocks. + switch { + case n1 == 1 && n2 == 2: + // Generate elementary reflector H so that + // ( scale, X11, X12 ) H = ( 0, 0, * ) + u := [3]float64{scale, x[0], 1} + _, tau := impl.Dlarfg(3, x[1], u[:2], 1) + t11 := t[j1*ldt+j1] + + // Perform swap provisionally on diagonal block in d. + impl.Dlarfx(blas.Left, 3, 3, u[:], tau, d[:], ldd, work) + impl.Dlarfx(blas.Right, 3, 3, u[:], tau, d[:], ldd, work) + + // Test whether to reject swap. + if math.Max(math.Abs(d[2*ldd]), math.Max(math.Abs(d[2*ldd+1]), math.Abs(d[2*ldd+2]-t11))) > thresh { + return false + } + + // Accept swap: apply transformation to the entire matrix T. + impl.Dlarfx(blas.Left, 3, n-j1, u[:], tau, t[j1*ldt+j1:], ldt, work) + impl.Dlarfx(blas.Right, j2+1, 3, u[:], tau, t[j1:], ldt, work) + + t[j3*ldt+j1] = 0 + t[j3*ldt+j2] = 0 + t[j3*ldt+j3] = t11 + + if wantq { + // Accumulate transformation in the matrix Q. + impl.Dlarfx(blas.Right, n, 3, u[:], tau, q[j1:], ldq, work) + } + + case n1 == 2 && n2 == 1: + // Generate elementary reflector H so that: + // H ( -X11 ) = ( * ) + // ( -X21 ) = ( 0 ) + // ( scale ) = ( 0 ) + u := [3]float64{1, -x[ldx], scale} + _, tau := impl.Dlarfg(3, -x[0], u[1:], 1) + t33 := t[j3*ldt+j3] + + // Perform swap provisionally on diagonal block in D. + impl.Dlarfx(blas.Left, 3, 3, u[:], tau, d[:], ldd, work) + impl.Dlarfx(blas.Right, 3, 3, u[:], tau, d[:], ldd, work) + + // Test whether to reject swap. + if math.Max(math.Abs(d[ldd]), math.Max(math.Abs(d[2*ldd]), math.Abs(d[0]-t33))) > thresh { + return false + } + + // Accept swap: apply transformation to the entire matrix T. + impl.Dlarfx(blas.Right, j3+1, 3, u[:], tau, t[j1:], ldt, work) + impl.Dlarfx(blas.Left, 3, n-j1-1, u[:], tau, t[j1*ldt+j2:], ldt, work) + + t[j1*ldt+j1] = t33 + t[j2*ldt+j1] = 0 + t[j3*ldt+j1] = 0 + + if wantq { + // Accumulate transformation in the matrix Q. + impl.Dlarfx(blas.Right, n, 3, u[:], tau, q[j1:], ldq, work) + } + + default: // n1 == 2 && n2 == 2 + // Generate elementary reflectors H_1 and H_2 so that: + // H_2 H_1 ( -X11 -X12 ) = ( * * ) + // ( -X21 -X22 ) ( 0 * ) + // ( scale 0 ) ( 0 0 ) + // ( 0 scale ) ( 0 0 ) + u1 := [3]float64{1, -x[ldx], scale} + _, tau1 := impl.Dlarfg(3, -x[0], u1[1:], 1) + + temp := -tau1 * (x[1] + u1[1]*x[ldx+1]) + u2 := [3]float64{1, -temp * u1[2], scale} + _, tau2 := impl.Dlarfg(3, -temp*u1[1]-x[ldx+1], u2[1:], 1) + + // Perform swap provisionally on diagonal block in D. + impl.Dlarfx(blas.Left, 3, 4, u1[:], tau1, d[:], ldd, work) + impl.Dlarfx(blas.Right, 4, 3, u1[:], tau1, d[:], ldd, work) + impl.Dlarfx(blas.Left, 3, 4, u2[:], tau2, d[ldd:], ldd, work) + impl.Dlarfx(blas.Right, 4, 3, u2[:], tau2, d[1:], ldd, work) + + // Test whether to reject swap. + m1 := math.Max(math.Abs(d[2*ldd]), math.Abs(d[2*ldd+1])) + m2 := math.Max(math.Abs(d[3*ldd]), math.Abs(d[3*ldd+1])) + if math.Max(m1, m2) > thresh { + return false + } + + // Accept swap: apply transformation to the entire matrix T. + j4 := j1 + 3 + impl.Dlarfx(blas.Left, 3, n-j1, u1[:], tau1, t[j1*ldt+j1:], ldt, work) + impl.Dlarfx(blas.Right, j4+1, 3, u1[:], tau1, t[j1:], ldt, work) + impl.Dlarfx(blas.Left, 3, n-j1, u2[:], tau2, t[j2*ldt+j1:], ldt, work) + impl.Dlarfx(blas.Right, j4+1, 3, u2[:], tau2, t[j2:], ldt, work) + + t[j3*ldt+j1] = 0 + t[j3*ldt+j2] = 0 + t[j4*ldt+j1] = 0 + t[j4*ldt+j2] = 0 + + if wantq { + // Accumulate transformation in the matrix Q. + impl.Dlarfx(blas.Right, n, 3, u1[:], tau1, q[j1:], ldq, work) + impl.Dlarfx(blas.Right, n, 3, u2[:], tau2, q[j2:], ldq, work) + } + } + + if n2 == 2 { + // Standardize new 2×2 block T11. + a, b := t[j1*ldt+j1], t[j1*ldt+j2] + c, d := t[j2*ldt+j1], t[j2*ldt+j2] + var cs, sn float64 + t[j1*ldt+j1], t[j1*ldt+j2], t[j2*ldt+j1], t[j2*ldt+j2], _, _, _, _, cs, sn = impl.Dlanv2(a, b, c, d) + if n-j1-2 > 0 { + bi.Drot(n-j1-2, t[j1*ldt+j1+2:], 1, t[j2*ldt+j1+2:], 1, cs, sn) + } + if j1 > 0 { + bi.Drot(j1, t[j1:], ldt, t[j2:], ldt, cs, sn) + } + if wantq { + bi.Drot(n, q[j1:], ldq, q[j2:], ldq, cs, sn) + } + } + if n1 == 2 { + // Standardize new 2×2 block T22. + j3 := j1 + n2 + j4 := j3 + 1 + a, b := t[j3*ldt+j3], t[j3*ldt+j4] + c, d := t[j4*ldt+j3], t[j4*ldt+j4] + var cs, sn float64 + t[j3*ldt+j3], t[j3*ldt+j4], t[j4*ldt+j3], t[j4*ldt+j4], _, _, _, _, cs, sn = impl.Dlanv2(a, b, c, d) + if n-j3-2 > 0 { + bi.Drot(n-j3-2, t[j3*ldt+j3+2:], 1, t[j4*ldt+j3+2:], 1, cs, sn) + } + bi.Drot(j3, t[j3:], ldt, t[j4:], ldt, cs, sn) + if wantq { + bi.Drot(n, q[j3:], ldq, q[j4:], ldq, cs, sn) + } + } + + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlags2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlags2.go new file mode 100644 index 00000000..3b73384f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlags2.go @@ -0,0 +1,182 @@ +// 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" + +// Dlags2 computes 2-by-2 orthogonal matrices U, V and Q with the +// triangles of A and B specified by upper. +// +// If upper is true +// +// U^T*A*Q = U^T*[ a1 a2 ]*Q = [ x 0 ] +// [ 0 a3 ] [ x x ] +// and +// V^T*B*Q = V^T*[ b1 b2 ]*Q = [ x 0 ] +// [ 0 b3 ] [ x x ] +// +// otherwise +// +// U^T*A*Q = U^T*[ a1 0 ]*Q = [ x x ] +// [ a2 a3 ] [ 0 x ] +// and +// V^T*B*Q = V^T*[ b1 0 ]*Q = [ x x ] +// [ b2 b3 ] [ 0 x ]. +// +// The rows of the transformed A and B are parallel, where +// +// U = [ csu snu ], V = [ csv snv ], Q = [ csq snq ] +// [ -snu csu ] [ -snv csv ] [ -snq csq ] +// +// Dlags2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlags2(upper bool, a1, a2, a3, b1, b2, b3 float64) (csu, snu, csv, snv, csq, snq float64) { + if upper { + // Input matrices A and B are upper triangular matrices. + // + // Form matrix C = A*adj(B) = [ a b ] + // [ 0 d ] + a := a1 * b3 + d := a3 * b1 + b := a2*b1 - a1*b2 + + // The SVD of real 2-by-2 triangular C. + // + // [ csl -snl ]*[ a b ]*[ csr snr ] = [ r 0 ] + // [ snl csl ] [ 0 d ] [ -snr csr ] [ 0 t ] + _, _, snr, csr, snl, csl := impl.Dlasv2(a, b, d) + + if math.Abs(csl) >= math.Abs(snl) || math.Abs(csr) >= math.Abs(snr) { + // Compute the [0, 0] and [0, 1] elements of U^T*A and V^T*B, + // and [0, 1] element of |U|^T*|A| and |V|^T*|B|. + + ua11r := csl * a1 + ua12 := csl*a2 + snl*a3 + + vb11r := csr * b1 + vb12 := csr*b2 + snr*b3 + + aua12 := math.Abs(csl)*math.Abs(a2) + math.Abs(snl)*math.Abs(a3) + avb12 := math.Abs(csr)*math.Abs(b2) + math.Abs(snr)*math.Abs(b3) + + // Zero [0, 1] elements of U^T*A and V^T*B. + if math.Abs(ua11r)+math.Abs(ua12) != 0 { + if aua12/(math.Abs(ua11r)+math.Abs(ua12)) <= avb12/(math.Abs(vb11r)+math.Abs(vb12)) { + csq, snq, _ = impl.Dlartg(-ua11r, ua12) + } else { + csq, snq, _ = impl.Dlartg(-vb11r, vb12) + } + } else { + csq, snq, _ = impl.Dlartg(-vb11r, vb12) + } + + csu = csl + snu = -snl + csv = csr + snv = -snr + } else { + // Compute the [1, 0] and [1, 1] elements of U^T*A and V^T*B, + // and [1, 1] element of |U|^T*|A| and |V|^T*|B|. + + ua21 := -snl * a1 + ua22 := -snl*a2 + csl*a3 + + vb21 := -snr * b1 + vb22 := -snr*b2 + csr*b3 + + aua22 := math.Abs(snl)*math.Abs(a2) + math.Abs(csl)*math.Abs(a3) + avb22 := math.Abs(snr)*math.Abs(b2) + math.Abs(csr)*math.Abs(b3) + + // Zero [1, 1] elements of U^T*A and V^T*B, and then swap. + if math.Abs(ua21)+math.Abs(ua22) != 0 { + if aua22/(math.Abs(ua21)+math.Abs(ua22)) <= avb22/(math.Abs(vb21)+math.Abs(vb22)) { + csq, snq, _ = impl.Dlartg(-ua21, ua22) + } else { + csq, snq, _ = impl.Dlartg(-vb21, vb22) + } + } else { + csq, snq, _ = impl.Dlartg(-vb21, vb22) + } + + csu = snl + snu = csl + csv = snr + snv = csr + } + } else { + // Input matrices A and B are lower triangular matrices + // + // Form matrix C = A*adj(B) = [ a 0 ] + // [ c d ] + a := a1 * b3 + d := a3 * b1 + c := a2*b3 - a3*b2 + + // The SVD of real 2-by-2 triangular C + // + // [ csl -snl ]*[ a 0 ]*[ csr snr ] = [ r 0 ] + // [ snl csl ] [ c d ] [ -snr csr ] [ 0 t ] + _, _, snr, csr, snl, csl := impl.Dlasv2(a, c, d) + + if math.Abs(csr) >= math.Abs(snr) || math.Abs(csl) >= math.Abs(snl) { + // Compute the [1, 0] and [1, 1] elements of U^T*A and V^T*B, + // and [1, 0] element of |U|^T*|A| and |V|^T*|B|. + + ua21 := -snr*a1 + csr*a2 + ua22r := csr * a3 + + vb21 := -snl*b1 + csl*b2 + vb22r := csl * b3 + + aua21 := math.Abs(snr)*math.Abs(a1) + math.Abs(csr)*math.Abs(a2) + avb21 := math.Abs(snl)*math.Abs(b1) + math.Abs(csl)*math.Abs(b2) + + // Zero [1, 0] elements of U^T*A and V^T*B. + if (math.Abs(ua21) + math.Abs(ua22r)) != 0 { + if aua21/(math.Abs(ua21)+math.Abs(ua22r)) <= avb21/(math.Abs(vb21)+math.Abs(vb22r)) { + csq, snq, _ = impl.Dlartg(ua22r, ua21) + } else { + csq, snq, _ = impl.Dlartg(vb22r, vb21) + } + } else { + csq, snq, _ = impl.Dlartg(vb22r, vb21) + } + + csu = csr + snu = -snr + csv = csl + snv = -snl + } else { + // Compute the [0, 0] and [0, 1] elements of U^T *A and V^T *B, + // and [0, 0] element of |U|^T*|A| and |V|^T*|B|. + + ua11 := csr*a1 + snr*a2 + ua12 := snr * a3 + + vb11 := csl*b1 + snl*b2 + vb12 := snl * b3 + + aua11 := math.Abs(csr)*math.Abs(a1) + math.Abs(snr)*math.Abs(a2) + avb11 := math.Abs(csl)*math.Abs(b1) + math.Abs(snl)*math.Abs(b2) + + // Zero [0, 0] elements of U^T*A and V^T*B, and then swap. + if (math.Abs(ua11) + math.Abs(ua12)) != 0 { + if aua11/(math.Abs(ua11)+math.Abs(ua12)) <= avb11/(math.Abs(vb11)+math.Abs(vb12)) { + csq, snq, _ = impl.Dlartg(ua12, ua11) + } else { + csq, snq, _ = impl.Dlartg(vb12, vb11) + } + } else { + csq, snq, _ = impl.Dlartg(vb12, vb11) + } + + csu = snr + snu = csr + csv = snl + snv = csl + } + } + + return csu, snu, csv, snv, csq, snq +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlahqr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlahqr.go new file mode 100644 index 00000000..bf14a036 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlahqr.go @@ -0,0 +1,423 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlahqr computes the eigenvalues and Schur factorization of a block of an n×n +// upper Hessenberg matrix H, using the double-shift/single-shift QR algorithm. +// +// h and ldh represent the matrix H. Dlahqr works primarily with the Hessenberg +// submatrix H[ilo:ihi+1,ilo:ihi+1], but applies transformations to all of H if +// wantt is true. It is assumed that H[ihi+1:n,ihi+1:n] is already upper +// quasi-triangular, although this is not checked. +// +// It must hold that +// 0 <= ilo <= max(0,ihi), and ihi < n, +// and that +// H[ilo,ilo-1] == 0, if ilo > 0, +// otherwise Dlahqr will panic. +// +// If unconverged is zero on return, wr[ilo:ihi+1] and wi[ilo:ihi+1] will contain +// respectively the real and imaginary parts of the computed eigenvalues ilo +// to ihi. If two eigenvalues are computed as a complex conjugate pair, they are +// stored in consecutive elements of wr and wi, say the i-th and (i+1)th, with +// wi[i] > 0 and wi[i+1] < 0. If wantt is true, the eigenvalues are stored in +// the same order as on the diagonal of the Schur form returned in H, with +// wr[i] = H[i,i], and, if H[i:i+2,i:i+2] is a 2×2 diagonal block, +// wi[i] = sqrt(abs(H[i+1,i]*H[i,i+1])) and wi[i+1] = -wi[i]. +// +// wr and wi must have length ihi+1. +// +// z and ldz represent an n×n matrix Z. If wantz is true, the transformations +// will be applied to the submatrix Z[iloz:ihiz+1,ilo:ihi+1] and it must hold that +// 0 <= iloz <= ilo, and ihi <= ihiz < n. +// If wantz is false, z is not referenced. +// +// unconverged indicates whether Dlahqr computed all the eigenvalues ilo to ihi +// in a total of 30 iterations per eigenvalue. +// +// If unconverged is zero, all the eigenvalues ilo to ihi have been computed and +// will be stored on return in wr[ilo:ihi+1] and wi[ilo:ihi+1]. +// +// If unconverged is zero and wantt is true, H[ilo:ihi+1,ilo:ihi+1] will be +// overwritten on return by upper quasi-triangular full Schur form with any +// 2×2 diagonal blocks in standard form. +// +// If unconverged is zero and if wantt is false, the contents of h on return is +// unspecified. +// +// If unconverged is positive, some eigenvalues have not converged, and +// wr[unconverged:ihi+1] and wi[unconverged:ihi+1] contain those eigenvalues +// which have been successfully computed. +// +// If unconverged is positive and wantt is true, then on return +// (initial H)*U = U*(final H), (*) +// where U is an orthogonal matrix. The final H is upper Hessenberg and +// H[unconverged:ihi+1,unconverged:ihi+1] is upper quasi-triangular. +// +// If unconverged is positive and wantt is false, on return the remaining +// unconverged eigenvalues are the eigenvalues of the upper Hessenberg matrix +// H[ilo:unconverged,ilo:unconverged]. +// +// If unconverged is positive and wantz is true, then on return +// (final Z) = (initial Z)*U, +// where U is the orthogonal matrix in (*) regardless of the value of wantt. +// +// Dlahqr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlahqr(wantt, wantz bool, n, ilo, ihi int, h []float64, ldh int, wr, wi []float64, iloz, ihiz int, z []float64, ldz int) (unconverged int) { + checkMatrix(n, n, h, ldh) + switch { + case ilo < 0 || max(0, ihi) < ilo: + panic(badIlo) + case n <= ihi: + panic(badIhi) + case len(wr) != ihi+1: + panic("lapack: bad length of wr") + case len(wi) != ihi+1: + panic("lapack: bad length of wi") + case ilo > 0 && h[ilo*ldh+ilo-1] != 0: + panic("lapack: block is not isolated") + } + if wantz { + checkMatrix(n, n, z, ldz) + switch { + case iloz < 0 || ilo < iloz: + panic("lapack: iloz out of range") + case ihiz < ihi || n <= ihiz: + panic("lapack: ihiz out of range") + } + } + + // Quick return if possible. + if n == 0 { + return 0 + } + if ilo == ihi { + wr[ilo] = h[ilo*ldh+ilo] + wi[ilo] = 0 + return 0 + } + + // Clear out the trash. + for j := ilo; j < ihi-2; j++ { + h[(j+2)*ldh+j] = 0 + h[(j+3)*ldh+j] = 0 + } + if ilo <= ihi-2 { + h[ihi*ldh+ihi-2] = 0 + } + + nh := ihi - ilo + 1 + nz := ihiz - iloz + 1 + + // Set machine-dependent constants for the stopping criterion. + ulp := dlamchP + smlnum := float64(nh) / ulp * dlamchS + + // i1 and i2 are the indices of the first row and last column of H to + // which transformations must be applied. If eigenvalues only are being + // computed, i1 and i2 are set inside the main loop. + var i1, i2 int + if wantt { + i1 = 0 + i2 = n - 1 + } + + itmax := 30 * max(10, nh) // Total number of QR iterations allowed. + + // The main loop begins here. i is the loop index and decreases from ihi + // to ilo in steps of 1 or 2. Each iteration of the loop works with the + // active submatrix in rows and columns l to i. Eigenvalues i+1 to ihi + // have already converged. Either l = ilo or H[l,l-1] is negligible so + // that the matrix splits. + bi := blas64.Implementation() + i := ihi + for i >= ilo { + l := ilo + + // Perform QR iterations on rows and columns ilo to i until a + // submatrix of order 1 or 2 splits off at the bottom because a + // subdiagonal element has become negligible. + converged := false + for its := 0; its <= itmax; its++ { + // Look for a single small subdiagonal element. + var k int + for k = i; k > l; k-- { + if math.Abs(h[k*ldh+k-1]) <= smlnum { + break + } + tst := math.Abs(h[(k-1)*ldh+k-1]) + math.Abs(h[k*ldh+k]) + if tst == 0 { + if k-2 >= ilo { + tst += math.Abs(h[(k-1)*ldh+k-2]) + } + if k+1 <= ihi { + tst += math.Abs(h[(k+1)*ldh+k]) + } + } + // The following is a conservative small + // subdiagonal deflation criterion due to Ahues + // & Tisseur (LAWN 122, 1997). It has better + // mathematical foundation and improves accuracy + // in some cases. + if math.Abs(h[k*ldh+k-1]) <= ulp*tst { + ab := math.Max(math.Abs(h[k*ldh+k-1]), math.Abs(h[(k-1)*ldh+k])) + ba := math.Min(math.Abs(h[k*ldh+k-1]), math.Abs(h[(k-1)*ldh+k])) + aa := math.Max(math.Abs(h[k*ldh+k]), math.Abs(h[(k-1)*ldh+k-1]-h[k*ldh+k])) + bb := math.Min(math.Abs(h[k*ldh+k]), math.Abs(h[(k-1)*ldh+k-1]-h[k*ldh+k])) + s := aa + ab + if ab/s*ba <= math.Max(smlnum, aa/s*bb*ulp) { + break + } + } + } + l = k + if l > ilo { + // H[l,l-1] is negligible. + h[l*ldh+l-1] = 0 + } + if l >= i-1 { + // Break the loop because a submatrix of order 1 + // or 2 has split off. + converged = true + break + } + + // Now the active submatrix is in rows and columns l to + // i. If eigenvalues only are being computed, only the + // active submatrix need be transformed. + if !wantt { + i1 = l + i2 = i + } + + const ( + dat1 = 3.0 + dat2 = -0.4375 + ) + var h11, h21, h12, h22 float64 + switch its { + case 10: // Exceptional shift. + s := math.Abs(h[(l+1)*ldh+l]) + math.Abs(h[(l+2)*ldh+l+1]) + h11 = dat1*s + h[l*ldh+l] + h12 = dat2 * s + h21 = s + h22 = h11 + case 20: // Exceptional shift. + s := math.Abs(h[i*ldh+i-1]) + math.Abs(h[(i-1)*ldh+i-2]) + h11 = dat1*s + h[i*ldh+i] + h12 = dat2 * s + h21 = s + h22 = h11 + default: // Prepare to use Francis' double shift (i.e., + // 2nd degree generalized Rayleigh quotient). + h11 = h[(i-1)*ldh+i-1] + h21 = h[i*ldh+i-1] + h12 = h[(i-1)*ldh+i] + h22 = h[i*ldh+i] + } + s := math.Abs(h11) + math.Abs(h12) + math.Abs(h21) + math.Abs(h22) + var ( + rt1r, rt1i float64 + rt2r, rt2i float64 + ) + if s != 0 { + h11 /= s + h21 /= s + h12 /= s + h22 /= s + tr := (h11 + h22) / 2 + det := (h11-tr)*(h22-tr) - h12*h21 + rtdisc := math.Sqrt(math.Abs(det)) + if det >= 0 { + // Complex conjugate shifts. + rt1r = tr * s + rt2r = rt1r + rt1i = rtdisc * s + rt2i = -rt1i + } else { + // Real shifts (use only one of them). + rt1r = tr + rtdisc + rt2r = tr - rtdisc + if math.Abs(rt1r-h22) <= math.Abs(rt2r-h22) { + rt1r *= s + rt2r = rt1r + } else { + rt2r *= s + rt1r = rt2r + } + rt1i = 0 + rt2i = 0 + } + } + + // Look for two consecutive small subdiagonal elements. + var m int + var v [3]float64 + for m = i - 2; m >= l; m-- { + // Determine the effect of starting the + // double-shift QR iteration at row m, and see + // if this would make H[m,m-1] negligible. The + // following uses scaling to avoid overflows and + // most underflows. + h21s := h[(m+1)*ldh+m] + s := math.Abs(h[m*ldh+m]-rt2r) + math.Abs(rt2i) + math.Abs(h21s) + h21s /= s + v[0] = h21s*h[m*ldh+m+1] + (h[m*ldh+m]-rt1r)*((h[m*ldh+m]-rt2r)/s) - rt2i/s*rt1i + v[1] = h21s * (h[m*ldh+m] + h[(m+1)*ldh+m+1] - rt1r - rt2r) + v[2] = h21s * h[(m+2)*ldh+m+1] + s = math.Abs(v[0]) + math.Abs(v[1]) + math.Abs(v[2]) + v[0] /= s + v[1] /= s + v[2] /= s + if m == l { + break + } + dsum := math.Abs(h[(m-1)*ldh+m-1]) + math.Abs(h[m*ldh+m]) + math.Abs(h[(m+1)*ldh+m+1]) + if math.Abs(h[m*ldh+m-1])*(math.Abs(v[1])+math.Abs(v[2])) <= ulp*math.Abs(v[0])*dsum { + break + } + } + + // Double-shift QR step. + for k := m; k < i; k++ { + // The first iteration of this loop determines a + // reflection G from the vector V and applies it + // from left and right to H, thus creating a + // non-zero bulge below the subdiagonal. + // + // Each subsequent iteration determines a + // reflection G to restore the Hessenberg form + // in the (k-1)th column, and thus chases the + // bulge one step toward the bottom of the + // active submatrix. nr is the order of G. + + nr := min(3, i-k+1) + if k > m { + bi.Dcopy(nr, h[k*ldh+k-1:], ldh, v[:], 1) + } + var t0 float64 + v[0], t0 = impl.Dlarfg(nr, v[0], v[1:], 1) + if k > m { + h[k*ldh+k-1] = v[0] + h[(k+1)*ldh+k-1] = 0 + if k < i-1 { + h[(k+2)*ldh+k-1] = 0 + } + } else if m > l { + // Use the following instead of H[k,k-1] = -H[k,k-1] + // to avoid a bug when v[1] and v[2] underflow. + h[k*ldh+k-1] *= 1 - t0 + } + t1 := t0 * v[1] + if nr == 3 { + t2 := t0 * v[2] + + // Apply G from the left to transform + // the rows of the matrix in columns k + // to i2. + for j := k; j <= i2; j++ { + sum := h[k*ldh+j] + v[1]*h[(k+1)*ldh+j] + v[2]*h[(k+2)*ldh+j] + h[k*ldh+j] -= sum * t0 + h[(k+1)*ldh+j] -= sum * t1 + h[(k+2)*ldh+j] -= sum * t2 + } + + // Apply G from the right to transform + // the columns of the matrix in rows i1 + // to min(k+3,i). + for j := i1; j <= min(k+3, i); j++ { + sum := h[j*ldh+k] + v[1]*h[j*ldh+k+1] + v[2]*h[j*ldh+k+2] + h[j*ldh+k] -= sum * t0 + h[j*ldh+k+1] -= sum * t1 + h[j*ldh+k+2] -= sum * t2 + } + + if wantz { + // Accumulate transformations in the matrix Z. + for j := iloz; j <= ihiz; j++ { + sum := z[j*ldz+k] + v[1]*z[j*ldz+k+1] + v[2]*z[j*ldz+k+2] + z[j*ldz+k] -= sum * t0 + z[j*ldz+k+1] -= sum * t1 + z[j*ldz+k+2] -= sum * t2 + } + } + } else if nr == 2 { + // Apply G from the left to transform + // the rows of the matrix in columns k + // to i2. + for j := k; j <= i2; j++ { + sum := h[k*ldh+j] + v[1]*h[(k+1)*ldh+j] + h[k*ldh+j] -= sum * t0 + h[(k+1)*ldh+j] -= sum * t1 + } + + // Apply G from the right to transform + // the columns of the matrix in rows i1 + // to min(k+3,i). + for j := i1; j <= i; j++ { + sum := h[j*ldh+k] + v[1]*h[j*ldh+k+1] + h[j*ldh+k] -= sum * t0 + h[j*ldh+k+1] -= sum * t1 + } + + if wantz { + // Accumulate transformations in the matrix Z. + for j := iloz; j <= ihiz; j++ { + sum := z[j*ldz+k] + v[1]*z[j*ldz+k+1] + z[j*ldz+k] -= sum * t0 + z[j*ldz+k+1] -= sum * t1 + } + } + } + } + } + + if !converged { + // The QR iteration finished without splitting off a + // submatrix of order 1 or 2. + return i + 1 + } + + if l == i { + // H[i,i-1] is negligible: one eigenvalue has converged. + wr[i] = h[i*ldh+i] + wi[i] = 0 + } else if l == i-1 { + // H[i-1,i-2] is negligible: a pair of eigenvalues have converged. + + // Transform the 2×2 submatrix to standard Schur form, + // and compute and store the eigenvalues. + var cs, sn float64 + a, b := h[(i-1)*ldh+i-1], h[(i-1)*ldh+i] + c, d := h[i*ldh+i-1], h[i*ldh+i] + a, b, c, d, wr[i-1], wi[i-1], wr[i], wi[i], cs, sn = impl.Dlanv2(a, b, c, d) + h[(i-1)*ldh+i-1], h[(i-1)*ldh+i] = a, b + h[i*ldh+i-1], h[i*ldh+i] = c, d + + if wantt { + // Apply the transformation to the rest of H. + if i2 > i { + bi.Drot(i2-i, h[(i-1)*ldh+i+1:], 1, h[i*ldh+i+1:], 1, cs, sn) + } + bi.Drot(i-i1-1, h[i1*ldh+i-1:], ldh, h[i1*ldh+i:], ldh, cs, sn) + } + + if wantz { + // Apply the transformation to Z. + bi.Drot(nz, z[iloz*ldz+i-1:], ldz, z[iloz*ldz+i:], ldz, cs, sn) + } + } + + // Return to start of the main loop with new value of i. + i = l - 1 + } + return 0 +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlahr2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlahr2.go new file mode 100644 index 00000000..607810f0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlahr2.go @@ -0,0 +1,169 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlahr2 reduces the first nb columns of a real general n×(n-k+1) matrix A so +// that elements below the k-th subdiagonal are zero. The reduction is performed +// by an orthogonal similarity transformation Q^T * A * Q. Dlahr2 returns the +// matrices V and T which determine Q as a block reflector I - V*T*V^T, and +// also the matrix Y = A * V * T. +// +// The matrix Q is represented as a product of nb elementary reflectors +// Q = H_0 * H_1 * ... * H_{nb-1}. +// Each H_i has the form +// H_i = I - tau[i] * v * v^T, +// where v is a real vector with v[0:i+k-1] = 0 and v[i+k-1] = 1. v[i+k:n] is +// stored on exit in A[i+k+1:n,i]. +// +// The elements of the vectors v together form the (n-k+1)×nb matrix +// V which is needed, with T and Y, to apply the transformation to the +// unreduced part of the matrix, using an update of the form +// A = (I - V*T*V^T) * (A - Y*V^T). +// +// On entry, a contains the n×(n-k+1) general matrix A. On return, the elements +// on and above the k-th subdiagonal in the first nb columns are overwritten +// with the corresponding elements of the reduced matrix; the elements below the +// k-th subdiagonal, with the slice tau, represent the matrix Q as a product of +// elementary reflectors. The other columns of A are unchanged. +// +// The contents of A on exit are illustrated by the following example +// with n = 7, k = 3 and nb = 2: +// [ a a a a a ] +// [ a a a a a ] +// [ a a a a a ] +// [ h h a a a ] +// [ v0 h a a a ] +// [ v0 v1 a a a ] +// [ v0 v1 a a a ] +// where a denotes an element of the original matrix A, h denotes a +// modified element of the upper Hessenberg matrix H, and vi denotes an +// element of the vector defining H_i. +// +// k is the offset for the reduction. Elements below the k-th subdiagonal in the +// first nb columns are reduced to zero. +// +// nb is the number of columns to be reduced. +// +// On entry, a represents the n×(n-k+1) matrix A. On return, the elements on and +// above the k-th subdiagonal in the first nb columns are overwritten with the +// corresponding elements of the reduced matrix. The elements below the k-th +// subdiagonal, with the slice tau, represent the matrix Q as a product of +// elementary reflectors. The other columns of A are unchanged. +// +// tau will contain the scalar factors of the elementary reflectors. It must +// have length at least nb. +// +// t and ldt represent the nb×nb upper triangular matrix T, and y and ldy +// represent the n×nb matrix Y. +// +// Dlahr2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlahr2(n, k, nb int, a []float64, lda int, tau, t []float64, ldt int, y []float64, ldy int) { + checkMatrix(n, n-k+1, a, lda) + if len(tau) < nb { + panic(badTau) + } + checkMatrix(nb, nb, t, ldt) + checkMatrix(n, nb, y, ldy) + + // Quick return if possible. + if n <= 1 { + return + } + + bi := blas64.Implementation() + var ei float64 + for i := 0; i < nb; i++ { + if i > 0 { + // Update A[k:n,i]. + + // Update i-th column of A - Y * V^T. + bi.Dgemv(blas.NoTrans, n-k, i, + -1, y[k*ldy:], ldy, + a[(k+i-1)*lda:], 1, + 1, a[k*lda+i:], lda) + + // Apply I - V * T^T * V^T to this column (call it b) + // from the left, using the last column of T as + // workspace. + // Let V = [ V1 ] and b = [ b1 ] (first i rows) + // [ V2 ] [ b2 ] + // where V1 is unit lower triangular. + // + // w := V1^T * b1. + bi.Dcopy(i, a[k*lda+i:], lda, t[nb-1:], ldt) + bi.Dtrmv(blas.Lower, blas.Trans, blas.Unit, i, + a[k*lda:], lda, t[nb-1:], ldt) + + // w := w + V2^T * b2. + bi.Dgemv(blas.Trans, n-k-i, i, + 1, a[(k+i)*lda:], lda, + a[(k+i)*lda+i:], lda, + 1, t[nb-1:], ldt) + + // w := T^T * w. + bi.Dtrmv(blas.Upper, blas.Trans, blas.NonUnit, i, + t, ldt, t[nb-1:], ldt) + + // b2 := b2 - V2*w. + bi.Dgemv(blas.NoTrans, n-k-i, i, + -1, a[(k+i)*lda:], lda, + t[nb-1:], ldt, + 1, a[(k+i)*lda+i:], lda) + + // b1 := b1 - V1*w. + bi.Dtrmv(blas.Lower, blas.NoTrans, blas.Unit, i, + a[k*lda:], lda, t[nb-1:], ldt) + bi.Daxpy(i, -1, t[nb-1:], ldt, a[k*lda+i:], lda) + + a[(k+i-1)*lda+i-1] = ei + } + + // Generate the elementary reflector H_i to annihilate + // A[k+i+1:n,i]. + ei, tau[i] = impl.Dlarfg(n-k-i, a[(k+i)*lda+i], a[min(k+i+1, n-1)*lda+i:], lda) + a[(k+i)*lda+i] = 1 + + // Compute Y[k:n,i]. + bi.Dgemv(blas.NoTrans, n-k, n-k-i, + 1, a[k*lda+i+1:], lda, + a[(k+i)*lda+i:], lda, + 0, y[k*ldy+i:], ldy) + bi.Dgemv(blas.Trans, n-k-i, i, + 1, a[(k+i)*lda:], lda, + a[(k+i)*lda+i:], lda, + 0, t[i:], ldt) + bi.Dgemv(blas.NoTrans, n-k, i, + -1, y[k*ldy:], ldy, + t[i:], ldt, + 1, y[k*ldy+i:], ldy) + bi.Dscal(n-k, tau[i], y[k*ldy+i:], ldy) + + // Compute T[0:i,i]. + bi.Dscal(i, -tau[i], t[i:], ldt) + bi.Dtrmv(blas.Upper, blas.NoTrans, blas.NonUnit, i, + t, ldt, t[i:], ldt) + + t[i*ldt+i] = tau[i] + } + a[(k+nb-1)*lda+nb-1] = ei + + // Compute Y[0:k,0:nb]. + impl.Dlacpy(blas.All, k, nb, a[1:], lda, y, ldy) + bi.Dtrmm(blas.Right, blas.Lower, blas.NoTrans, blas.Unit, k, nb, + 1, a[k*lda:], lda, y, ldy) + if n > k+nb { + bi.Dgemm(blas.NoTrans, blas.NoTrans, k, nb, n-k-nb, + 1, a[1+nb:], lda, + a[(k+nb)*lda:], lda, + 1, y, ldy) + } + bi.Dtrmm(blas.Right, blas.Upper, blas.NoTrans, blas.NonUnit, k, nb, + 1, t, ldt, y, ldy) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaln2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaln2.go new file mode 100644 index 00000000..fb1873f7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaln2.go @@ -0,0 +1,396 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "math" + +// Dlaln2 solves a linear equation or a system of 2 linear equations of the form +// (ca A - w D) X = scale B, if trans == false, +// (ca A^T - w D) X = scale B, if trans == true, +// where A is a na×na real matrix, ca is a real scalar, D is a na×na diagonal +// real matrix, w is a scalar, real if nw == 1, complex if nw == 2, and X and B +// are na×1 matrices, real if w is real, complex if w is complex. +// +// If w is complex, X and B are represented as na×2 matrices, the first column +// of each being the real part and the second being the imaginary part. +// +// na and nw must be 1 or 2, otherwise Dlaln2 will panic. +// +// d1 and d2 are the diagonal elements of D. d2 is not used if na == 1. +// +// wr and wi represent the real and imaginary part, respectively, of the scalar +// w. wi is not used if nw == 1. +// +// smin is the desired lower bound on the singular values of A. This should be +// a safe distance away from underflow or overflow, say, between +// (underflow/machine precision) and (overflow*machine precision). +// +// If both singular values of (ca A - w D) are less than smin, smin*identity +// will be used instead of (ca A - w D). If only one singular value is less than +// smin, one element of (ca A - w D) will be perturbed enough to make the +// smallest singular value roughly smin. If both singular values are at least +// smin, (ca A - w D) will not be perturbed. In any case, the perturbation will +// be at most some small multiple of max(smin, ulp*norm(ca A - w D)). The +// singular values are computed by infinity-norm approximations, and thus will +// only be correct to a factor of 2 or so. +// +// All input quantities are assumed to be smaller than overflow by a reasonable +// factor. +// +// scale is a scaling factor less than or equal to 1 which is chosen so that X +// can be computed without overflow. X is further scaled if necessary to assure +// that norm(ca A - w D)*norm(X) is less than overflow. +// +// xnorm contains the infinity-norm of X when X is regarded as a na×nw real +// matrix. +// +// ok will be false if (ca A - w D) had to be perturbed to make its smallest +// singular value greater than smin, otherwise ok will be true. +// +// Dlaln2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaln2(trans bool, na, nw int, smin, ca float64, a []float64, lda int, d1, d2 float64, b []float64, ldb int, wr, wi float64, x []float64, ldx int) (scale, xnorm float64, ok bool) { + // TODO(vladimir-ch): Consider splitting this function into two, one + // handling the real case (nw == 1) and the other handling the complex + // case (nw == 2). Given that Go has complex types, their signatures + // would be simpler and more natural, and the implementation not as + // convoluted. + + if na != 1 && na != 2 { + panic("lapack: invalid value of na") + } + if nw != 1 && nw != 2 { + panic("lapack: invalid value of nw") + } + checkMatrix(na, na, a, lda) + checkMatrix(na, nw, b, ldb) + checkMatrix(na, nw, x, ldx) + + smlnum := 2 * dlamchS + bignum := 1 / smlnum + smini := math.Max(smin, smlnum) + + ok = true + scale = 1 + + if na == 1 { + // 1×1 (i.e., scalar) system C X = B. + + if nw == 1 { + // Real 1×1 system. + + // C = ca A - w D. + csr := ca*a[0] - wr*d1 + cnorm := math.Abs(csr) + + // If |C| < smini, use C = smini. + if cnorm < smini { + csr = smini + cnorm = smini + ok = false + } + + // Check scaling for X = B / C. + bnorm := math.Abs(b[0]) + if cnorm < 1 && bnorm > math.Max(1, bignum*cnorm) { + scale = 1 / bnorm + } + + // Compute X. + x[0] = b[0] * scale / csr + xnorm = math.Abs(x[0]) + + return scale, xnorm, ok + } + + // Complex 1×1 system (w is complex). + + // C = ca A - w D. + csr := ca*a[0] - wr*d1 + csi := -wi * d1 + cnorm := math.Abs(csr) + math.Abs(csi) + + // If |C| < smini, use C = smini. + if cnorm < smini { + csr = smini + csi = 0 + cnorm = smini + ok = false + } + + // Check scaling for X = B / C. + bnorm := math.Abs(b[0]) + math.Abs(b[1]) + if cnorm < 1 && bnorm > math.Max(1, bignum*cnorm) { + scale = 1 / bnorm + } + + // Compute X. + cx := complex(scale*b[0], scale*b[1]) / complex(csr, csi) + x[0], x[1] = real(cx), imag(cx) + xnorm = math.Abs(x[0]) + math.Abs(x[1]) + + return scale, xnorm, ok + } + + // 2×2 system. + + // Compute the real part of + // C = ca A - w D + // or + // C = ca A^T - w D. + crv := [4]float64{ + ca*a[0] - wr*d1, + ca * a[1], + ca * a[lda], + ca*a[lda+1] - wr*d2, + } + if trans { + crv[1] = ca * a[lda] + crv[2] = ca * a[1] + } + + pivot := [4][4]int{ + {0, 1, 2, 3}, + {1, 0, 3, 2}, + {2, 3, 0, 1}, + {3, 2, 1, 0}, + } + + if nw == 1 { + // Real 2×2 system (w is real). + + // Find the largest element in C. + var cmax float64 + var icmax int + for j, v := range crv { + v = math.Abs(v) + if v > cmax { + cmax = v + icmax = j + } + } + + // If norm(C) < smini, use smini*identity. + if cmax < smini { + bnorm := math.Max(math.Abs(b[0]), math.Abs(b[ldb])) + if smini < 1 && bnorm > math.Max(1, bignum*smini) { + scale = 1 / bnorm + } + temp := scale / smini + x[0] = temp * b[0] + x[ldx] = temp * b[ldb] + xnorm = temp * bnorm + ok = false + + return scale, xnorm, ok + } + + // Gaussian elimination with complete pivoting. + // Form upper triangular matrix + // [ur11 ur12] + // [ 0 ur22] + ur11 := crv[icmax] + ur12 := crv[pivot[icmax][1]] + cr21 := crv[pivot[icmax][2]] + cr22 := crv[pivot[icmax][3]] + ur11r := 1 / ur11 + lr21 := ur11r * cr21 + ur22 := cr22 - ur12*lr21 + + // If smaller pivot < smini, use smini. + if math.Abs(ur22) < smini { + ur22 = smini + ok = false + } + + var br1, br2 float64 + if icmax > 1 { + // If the pivot lies in the second row, swap the rows. + br1 = b[ldb] + br2 = b[0] + } else { + br1 = b[0] + br2 = b[ldb] + } + br2 -= lr21 * br1 // Apply the Gaussian elimination step to the right-hand side. + + bbnd := math.Max(math.Abs(ur22*ur11r*br1), math.Abs(br2)) + if bbnd > 1 && math.Abs(ur22) < 1 && bbnd >= bignum*math.Abs(ur22) { + scale = 1 / bbnd + } + + // Solve the linear system ur*xr=br. + xr2 := br2 * scale / ur22 + xr1 := scale*br1*ur11r - ur11r*ur12*xr2 + if icmax&0x1 != 0 { + // If the pivot lies in the second column, swap the components of the solution. + x[0] = xr2 + x[ldx] = xr1 + } else { + x[0] = xr1 + x[ldx] = xr2 + } + xnorm = math.Max(math.Abs(xr1), math.Abs(xr2)) + + // Further scaling if norm(A)*norm(X) > overflow. + if xnorm > 1 && cmax > 1 && xnorm > bignum/cmax { + temp := cmax / bignum + x[0] *= temp + x[ldx] *= temp + xnorm *= temp + scale *= temp + } + + return scale, xnorm, ok + } + + // Complex 2×2 system (w is complex). + + // Find the largest element in C. + civ := [4]float64{ + -wi * d1, + 0, + 0, + -wi * d2, + } + var cmax float64 + var icmax int + for j, v := range crv { + v := math.Abs(v) + if v+math.Abs(civ[j]) > cmax { + cmax = v + math.Abs(civ[j]) + icmax = j + } + } + + // If norm(C) < smini, use smini*identity. + if cmax < smini { + br1 := math.Abs(b[0]) + math.Abs(b[1]) + br2 := math.Abs(b[ldb]) + math.Abs(b[ldb+1]) + bnorm := math.Max(br1, br2) + if smini < 1 && bnorm > 1 && bnorm > bignum*smini { + scale = 1 / bnorm + } + temp := scale / smini + x[0] = temp * b[0] + x[1] = temp * b[1] + x[ldb] = temp * b[ldb] + x[ldb+1] = temp * b[ldb+1] + xnorm = temp * bnorm + ok = false + + return scale, xnorm, ok + } + + // Gaussian elimination with complete pivoting. + ur11 := crv[icmax] + ui11 := civ[icmax] + ur12 := crv[pivot[icmax][1]] + ui12 := civ[pivot[icmax][1]] + cr21 := crv[pivot[icmax][2]] + ci21 := civ[pivot[icmax][2]] + cr22 := crv[pivot[icmax][3]] + ci22 := civ[pivot[icmax][3]] + var ( + ur11r, ui11r float64 + lr21, li21 float64 + ur12s, ui12s float64 + ur22, ui22 float64 + ) + if icmax == 0 || icmax == 3 { + // Off-diagonals of pivoted C are real. + if math.Abs(ur11) > math.Abs(ui11) { + temp := ui11 / ur11 + ur11r = 1 / (ur11 * (1 + temp*temp)) + ui11r = -temp * ur11r + } else { + temp := ur11 / ui11 + ui11r = -1 / (ui11 * (1 + temp*temp)) + ur11r = -temp * ui11r + } + lr21 = cr21 * ur11r + li21 = cr21 * ui11r + ur12s = ur12 * ur11r + ui12s = ur12 * ui11r + ur22 = cr22 - ur12*lr21 + ui22 = ci22 - ur12*li21 + } else { + // Diagonals of pivoted C are real. + ur11r = 1 / ur11 + // ui11r is already 0. + lr21 = cr21 * ur11r + li21 = ci21 * ur11r + ur12s = ur12 * ur11r + ui12s = ui12 * ur11r + ur22 = cr22 - ur12*lr21 + ui12*li21 + ui22 = -ur12*li21 - ui12*lr21 + } + u22abs := math.Abs(ur22) + math.Abs(ui22) + + // If smaller pivot < smini, use smini. + if u22abs < smini { + ur22 = smini + ui22 = 0 + ok = false + } + + var br1, bi1 float64 + var br2, bi2 float64 + if icmax > 1 { + // If the pivot lies in the second row, swap the rows. + br1 = b[ldb] + bi1 = b[ldb+1] + br2 = b[0] + bi2 = b[1] + } else { + br1 = b[0] + bi1 = b[1] + br2 = b[ldb] + bi2 = b[ldb+1] + } + br2 += -lr21*br1 + li21*bi1 + bi2 += -li21*br1 - lr21*bi1 + + bbnd1 := u22abs * (math.Abs(ur11r) + math.Abs(ui11r)) * (math.Abs(br1) + math.Abs(bi1)) + bbnd2 := math.Abs(br2) + math.Abs(bi2) + bbnd := math.Max(bbnd1, bbnd2) + if bbnd > 1 && u22abs < 1 && bbnd >= bignum*u22abs { + scale = 1 / bbnd + br1 *= scale + bi1 *= scale + br2 *= scale + bi2 *= scale + } + + cx2 := complex(br2, bi2) / complex(ur22, ui22) + xr2, xi2 := real(cx2), imag(cx2) + xr1 := ur11r*br1 - ui11r*bi1 - ur12s*xr2 + ui12s*xi2 + xi1 := ui11r*br1 + ur11r*bi1 - ui12s*xr2 - ur12s*xi2 + if icmax&0x1 != 0 { + // If the pivot lies in the second column, swap the components of the solution. + x[0] = xr2 + x[1] = xi2 + x[ldx] = xr1 + x[ldx+1] = xi1 + } else { + x[0] = xr1 + x[1] = xi1 + x[ldx] = xr2 + x[ldx+1] = xi2 + } + xnorm = math.Max(math.Abs(xr1)+math.Abs(xi1), math.Abs(xr2)+math.Abs(xi2)) + + // Further scaling if norm(A)*norm(X) > overflow. + if xnorm > 1 && cmax > 1 && xnorm > bignum/cmax { + temp := cmax / bignum + x[0] *= temp + x[1] *= temp + x[ldx] *= temp + x[ldx+1] *= temp + xnorm *= temp + scale *= temp + } + + return scale, xnorm, ok +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlange.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlange.go new file mode 100644 index 00000000..66b46aab --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlange.go @@ -0,0 +1,84 @@ +// 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/lapack" +) + +// Dlange computes the matrix norm of the general m×n matrix a. The input norm +// specifies the norm computed. +// lapack.MaxAbs: the maximum absolute value of an element. +// lapack.MaxColumnSum: the maximum column sum of the absolute values of the entries. +// lapack.MaxRowSum: the maximum row sum of the absolute values of the entries. +// lapack.NormFrob: the square root of the sum of the squares of the entries. +// If norm == lapack.MaxColumnSum, work must be of length n, and this function will panic otherwise. +// There are no restrictions on work for the other matrix norms. +func (impl Implementation) Dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int, work []float64) float64 { + // TODO(btracey): These should probably be refactored to use BLAS calls. + checkMatrix(m, n, a, lda) + switch norm { + case lapack.MaxRowSum, lapack.MaxColumnSum, lapack.NormFrob, lapack.MaxAbs: + default: + panic(badNorm) + } + if norm == lapack.MaxColumnSum && len(work) < n { + panic(badWork) + } + if m == 0 && n == 0 { + return 0 + } + if norm == lapack.MaxAbs { + var value float64 + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + value = math.Max(value, math.Abs(a[i*lda+j])) + } + } + return value + } + if norm == lapack.MaxColumnSum { + if len(work) < n { + panic(badWork) + } + for i := 0; i < n; i++ { + work[i] = 0 + } + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + work[j] += math.Abs(a[i*lda+j]) + } + } + var value float64 + for i := 0; i < n; i++ { + value = math.Max(value, work[i]) + } + return value + } + if norm == lapack.MaxRowSum { + var value float64 + for i := 0; i < m; i++ { + var sum float64 + for j := 0; j < n; j++ { + sum += math.Abs(a[i*lda+j]) + } + value = math.Max(value, sum) + } + return value + } + if norm == lapack.NormFrob { + var value float64 + scale := 0.0 + sum := 1.0 + for i := 0; i < m; i++ { + scale, sum = impl.Dlassq(n, a[i*lda:], 1, scale, sum) + } + value = scale * math.Sqrt(sum) + return value + } + panic("lapack: bad matrix norm") +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlanst.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlanst.go new file mode 100644 index 00000000..7adb7aad --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlanst.go @@ -0,0 +1,68 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/lapack" +) + +// Dlanst computes the specified norm of a symmetric tridiagonal matrix A. +// The diagonal elements of A are stored in d and the off-diagonal elements +// are stored in e. +func (impl Implementation) Dlanst(norm lapack.MatrixNorm, n int, d, e []float64) float64 { + if len(d) < n { + panic(badD) + } + if len(e) < n-1 { + panic(badE) + } + if n <= 0 { + return 0 + } + switch norm { + default: + panic(badNorm) + case lapack.MaxAbs: + anorm := math.Abs(d[n-1]) + for i := 0; i < n-1; i++ { + sum := math.Abs(d[i]) + if anorm < sum || math.IsNaN(sum) { + anorm = sum + } + sum = math.Abs(e[i]) + if anorm < sum || math.IsNaN(sum) { + anorm = sum + } + } + return anorm + case lapack.MaxColumnSum, lapack.MaxRowSum: + if n == 1 { + return math.Abs(d[0]) + } + anorm := math.Abs(d[0]) + math.Abs(e[0]) + sum := math.Abs(e[n-2]) + math.Abs(d[n-1]) + if anorm < sum || math.IsNaN(sum) { + anorm = sum + } + for i := 1; i < n-1; i++ { + sum := math.Abs(d[i]) + math.Abs(e[i]) + math.Abs(e[i-1]) + if anorm < sum || math.IsNaN(sum) { + anorm = sum + } + } + return anorm + case lapack.NormFrob: + var scale float64 + sum := 1.0 + if n > 1 { + scale, sum = impl.Dlassq(n-1, e, 1, scale, sum) + sum = 2 * sum + } + scale, sum = impl.Dlassq(n, d, 1, scale, sum) + return scale * math.Sqrt(sum) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlansy.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlansy.go new file mode 100644 index 00000000..03a7585b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlansy.go @@ -0,0 +1,125 @@ +// 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/lapack" +) + +// Dlansy computes the specified norm of an n×n symmetric matrix. If +// norm == lapack.MaxColumnSum or norm == lapackMaxRowSum work must have length +// at least n, otherwise work is unused. +func (impl Implementation) Dlansy(norm lapack.MatrixNorm, uplo blas.Uplo, n int, a []float64, lda int, work []float64) float64 { + checkMatrix(n, n, a, lda) + switch norm { + case lapack.MaxRowSum, lapack.MaxColumnSum, lapack.NormFrob, lapack.MaxAbs: + default: + panic(badNorm) + } + if (norm == lapack.MaxColumnSum || norm == lapack.MaxRowSum) && len(work) < n { + panic(badWork) + } + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + + if n == 0 { + return 0 + } + switch norm { + default: + panic("unreachable") + case lapack.MaxAbs: + if uplo == blas.Upper { + var max float64 + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := math.Abs(a[i*lda+j]) + if math.IsNaN(v) { + return math.NaN() + } + if v > max { + max = v + } + } + } + return max + } + var max float64 + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + v := math.Abs(a[i*lda+j]) + if math.IsNaN(v) { + return math.NaN() + } + if v > max { + max = v + } + } + } + return max + case lapack.MaxRowSum, lapack.MaxColumnSum: + // A symmetric matrix has the same 1-norm and ∞-norm. + for i := 0; i < n; i++ { + work[i] = 0 + } + if uplo == blas.Upper { + for i := 0; i < n; i++ { + work[i] += math.Abs(a[i*lda+i]) + for j := i + 1; j < n; j++ { + v := math.Abs(a[i*lda+j]) + work[i] += v + work[j] += v + } + } + } else { + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + v := math.Abs(a[i*lda+j]) + work[i] += v + work[j] += v + } + work[i] += math.Abs(a[i*lda+i]) + } + } + var max float64 + for i := 0; i < n; i++ { + v := work[i] + if math.IsNaN(v) { + return math.NaN() + } + if v > max { + max = v + } + } + return max + case lapack.NormFrob: + if uplo == blas.Upper { + var sum float64 + for i := 0; i < n; i++ { + v := a[i*lda+i] + sum += v * v + for j := i + 1; j < n; j++ { + v := a[i*lda+j] + sum += 2 * v * v + } + } + return math.Sqrt(sum) + } + var sum float64 + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + v := a[i*lda+j] + sum += 2 * v * v + } + v := a[i*lda+i] + sum += v * v + } + return math.Sqrt(sum) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlantr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlantr.go new file mode 100644 index 00000000..43cf6fd2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlantr.go @@ -0,0 +1,252 @@ +// 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/lapack" +) + +// Dlantr computes the specified norm of an m×n trapezoidal matrix A. If +// norm == lapack.MaxColumnSum work must have length at least n, otherwise work +// is unused. +func (impl Implementation) Dlantr(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, m, n int, a []float64, lda int, work []float64) float64 { + checkMatrix(m, n, a, lda) + switch norm { + case lapack.MaxRowSum, lapack.MaxColumnSum, lapack.NormFrob, lapack.MaxAbs: + default: + panic(badNorm) + } + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + if diag != blas.Unit && diag != blas.NonUnit { + panic(badDiag) + } + if norm == lapack.MaxColumnSum && len(work) < n { + panic(badWork) + } + if min(m, n) == 0 { + return 0 + } + switch norm { + default: + panic("unreachable") + case lapack.MaxAbs: + if diag == blas.Unit { + value := 1.0 + if uplo == blas.Upper { + for i := 0; i < m; i++ { + for j := i + 1; j < n; j++ { + tmp := math.Abs(a[i*lda+j]) + if math.IsNaN(tmp) { + return tmp + } + if tmp > value { + value = tmp + } + } + } + return value + } + for i := 1; i < m; i++ { + for j := 0; j < min(i, n); j++ { + tmp := math.Abs(a[i*lda+j]) + if math.IsNaN(tmp) { + return tmp + } + if tmp > value { + value = tmp + } + } + } + return value + } + var value float64 + if uplo == blas.Upper { + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + tmp := math.Abs(a[i*lda+j]) + if math.IsNaN(tmp) { + return tmp + } + if tmp > value { + value = tmp + } + } + } + return value + } + for i := 0; i < m; i++ { + for j := 0; j <= min(i, n-1); j++ { + tmp := math.Abs(a[i*lda+j]) + if math.IsNaN(tmp) { + return tmp + } + if tmp > value { + value = tmp + } + } + } + return value + case lapack.MaxColumnSum: + if diag == blas.Unit { + for i := 0; i < min(m, n); i++ { + work[i] = 1 + } + for i := min(m, n); i < n; i++ { + work[i] = 0 + } + if uplo == blas.Upper { + for i := 0; i < m; i++ { + for j := i + 1; j < n; j++ { + work[j] += math.Abs(a[i*lda+j]) + } + } + } else { + for i := 1; i < m; i++ { + for j := 0; j < min(i, n); j++ { + work[j] += math.Abs(a[i*lda+j]) + } + } + } + } else { + for i := 0; i < n; i++ { + work[i] = 0 + } + if uplo == blas.Upper { + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + work[j] += math.Abs(a[i*lda+j]) + } + } + } else { + for i := 0; i < m; i++ { + for j := 0; j <= min(i, n-1); j++ { + work[j] += math.Abs(a[i*lda+j]) + } + } + } + } + var max float64 + for _, v := range work[:n] { + if math.IsNaN(v) { + return math.NaN() + } + if v > max { + max = v + } + } + return max + case lapack.MaxRowSum: + var maxsum float64 + if diag == blas.Unit { + if uplo == blas.Upper { + for i := 0; i < m; i++ { + var sum float64 + if i < min(m, n) { + sum = 1 + } + for j := i + 1; j < n; j++ { + sum += math.Abs(a[i*lda+j]) + } + if math.IsNaN(sum) { + return math.NaN() + } + if sum > maxsum { + maxsum = sum + } + } + return maxsum + } else { + for i := 1; i < m; i++ { + var sum float64 + if i < min(m, n) { + sum = 1 + } + for j := 0; j < min(i, n); j++ { + sum += math.Abs(a[i*lda+j]) + } + if math.IsNaN(sum) { + return math.NaN() + } + if sum > maxsum { + maxsum = sum + } + } + return maxsum + } + } else { + if uplo == blas.Upper { + for i := 0; i < m; i++ { + var sum float64 + for j := i; j < n; j++ { + sum += math.Abs(a[i*lda+j]) + } + if math.IsNaN(sum) { + return sum + } + if sum > maxsum { + maxsum = sum + } + } + return maxsum + } else { + for i := 0; i < m; i++ { + var sum float64 + for j := 0; j <= min(i, n-1); j++ { + sum += math.Abs(a[i*lda+j]) + } + if math.IsNaN(sum) { + return sum + } + if sum > maxsum { + maxsum = sum + } + } + return maxsum + } + } + case lapack.NormFrob: + var nrm float64 + if diag == blas.Unit { + if uplo == blas.Upper { + for i := 0; i < m; i++ { + for j := i + 1; j < n; j++ { + tmp := a[i*lda+j] + nrm += tmp * tmp + } + } + } else { + for i := 1; i < m; i++ { + for j := 0; j < min(i, n); j++ { + tmp := a[i*lda+j] + nrm += tmp * tmp + } + } + } + nrm += float64(min(m, n)) + } else { + if uplo == blas.Upper { + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + tmp := math.Abs(a[i*lda+j]) + nrm += tmp * tmp + } + } + } else { + for i := 0; i < m; i++ { + for j := 0; j <= min(i, n-1); j++ { + tmp := math.Abs(a[i*lda+j]) + nrm += tmp * tmp + } + } + } + } + return math.Sqrt(nrm) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlanv2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlanv2.go new file mode 100644 index 00000000..1faeba32 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlanv2.go @@ -0,0 +1,132 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "math" + +// Dlanv2 computes the Schur factorization of a real 2×2 matrix: +// [ a b ] = [ cs -sn ] * [ aa bb ] * [ cs sn ] +// [ c d ] [ sn cs ] [ cc dd ] * [-sn cs ] +// If cc is zero, aa and dd are real eigenvalues of the matrix. Otherwise it +// holds that aa = dd and bb*cc < 0, and aa ± sqrt(bb*cc) are complex conjugate +// eigenvalues. The real and imaginary parts of the eigenvalues are returned in +// (rt1r,rt1i) and (rt2r,rt2i). +func (impl Implementation) Dlanv2(a, b, c, d float64) (aa, bb, cc, dd float64, rt1r, rt1i, rt2r, rt2i float64, cs, sn float64) { + switch { + case c == 0: // Matrix is already upper triangular. + aa = a + bb = b + cc = 0 + dd = d + cs = 1 + sn = 0 + case b == 0: // Matrix is lower triangular, swap rows and columns. + aa = d + bb = -c + cc = 0 + dd = a + cs = 0 + sn = 1 + case a == d && math.Signbit(b) != math.Signbit(c): // Matrix is already in the standard Schur form. + aa = a + bb = b + cc = c + dd = d + cs = 1 + sn = 0 + default: + temp := a - d + p := temp / 2 + bcmax := math.Max(math.Abs(b), math.Abs(c)) + bcmis := math.Min(math.Abs(b), math.Abs(c)) + if b*c < 0 { + bcmis *= -1 + } + scale := math.Max(math.Abs(p), bcmax) + z := p/scale*p + bcmax/scale*bcmis + eps := dlamchP + + if z >= 4*eps { + // Real eigenvalues. Compute aa and dd. + if p > 0 { + z = p + math.Sqrt(scale)*math.Sqrt(z) + } else { + z = p - math.Sqrt(scale)*math.Sqrt(z) + } + aa = d + z + dd = d - bcmax/z*bcmis + // Compute bb and the rotation matrix. + tau := impl.Dlapy2(c, z) + cs = z / tau + sn = c / tau + bb = b - c + cc = 0 + } else { + // Complex eigenvalues, or real (almost) equal eigenvalues. + // Make diagonal elements equal. + sigma := b + c + tau := impl.Dlapy2(sigma, temp) + cs = math.Sqrt((1 + math.Abs(sigma)/tau) / 2) + sn = -p / (tau * cs) + if sigma < 0 { + sn *= -1 + } + // Compute [ aa bb ] = [ a b ] [ cs -sn ] + // [ cc dd ] [ c d ] [ sn cs ] + aa = a*cs + b*sn + bb = -a*sn + b*cs + cc = c*cs + d*sn + dd = -c*sn + d*cs + // Compute [ a b ] = [ cs sn ] [ aa bb ] + // [ c d ] [-sn cs ] [ cc dd ] + a = aa*cs + cc*sn + b = bb*cs + dd*sn + c = -aa*sn + cc*cs + d = -bb*sn + dd*cs + + temp = (a + d) / 2 + aa = temp + bb = b + cc = c + dd = temp + + if cc != 0 { + if bb != 0 { + if math.Signbit(bb) == math.Signbit(cc) { + // Real eigenvalues, reduce to + // upper triangular form. + sab := math.Sqrt(math.Abs(bb)) + sac := math.Sqrt(math.Abs(cc)) + p = sab * sac + if cc < 0 { + p *= -1 + } + tau = 1 / math.Sqrt(math.Abs(bb+cc)) + aa = temp + p + bb = bb - cc + cc = 0 + dd = temp - p + cs1 := sab * tau + sn1 := sac * tau + cs, sn = cs*cs1-sn*sn1, cs*sn1+sn+cs1 + } + } else { + bb = -cc + cc = 0 + cs, sn = -sn, cs + } + } + } + } + + // Store eigenvalues in (rt1r,rt1i) and (rt2r,rt2i). + rt1r = aa + rt2r = dd + if cc != 0 { + rt1i = math.Sqrt(math.Abs(bb)) * math.Sqrt(math.Abs(cc)) + rt2i = -rt1i + } + return +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlapll.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlapll.go new file mode 100644 index 00000000..990e90d2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlapll.go @@ -0,0 +1,36 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas/blas64" + +// Dlapll returns the smallest singular value of the n×2 matrix A = [ x y ]. +// The function first computes the QR factorization of A = Q*R, and then computes +// the SVD of the 2-by-2 upper triangular matrix r. +// +// The contents of x and y are overwritten during the call. +// +// Dlapll is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlapll(n int, x []float64, incX int, y []float64, incY int) float64 { + checkVector(n, x, incX) + checkVector(n, y, incY) + + if n <= 1 { + return 0 + } + + // Compute the QR factorization of the N-by-2 matrix [ X Y ]. + a00, tau := impl.Dlarfg(n, x[0], x[incX:], incX) + x[0] = 1 + + bi := blas64.Implementation() + c := -tau * bi.Ddot(n, x, incX, y, incY) + bi.Daxpy(n, c, x, incX, y, incY) + a11, _ := impl.Dlarfg(n-1, y[incY], y[2*incY:], incY) + + // Compute the SVD of 2-by-2 upper triangular matrix. + ssmin, _ := impl.Dlas2(a00, y[0], a11) + return ssmin +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlapmt.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlapmt.go new file mode 100644 index 00000000..98331f5b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlapmt.go @@ -0,0 +1,72 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas/blas64" + +// Dlapmt rearranges the columns of the m×n matrix X as specified by the +// permutation k_0, k_1, ..., k_n-1 of the integers 0, ..., n-1. +// +// If forward is true a forward permutation is performed: +// +// X[0:m, k[j]] is moved to X[0:m, j] for j = 0, 1, ..., n-1. +// +// otherwise a backward permutation is performed: +// +// X[0:m, j] is moved to X[0:m, k[j]] for j = 0, 1, ..., n-1. +// +// k must have length n, otherwise Dlapmt will panic. k is zero-indexed. +func (impl Implementation) Dlapmt(forward bool, m, n int, x []float64, ldx int, k []int) { + checkMatrix(m, n, x, ldx) + if len(k) != n { + panic(badKperm) + } + + if n <= 1 { + return + } + + for i, v := range k { + v++ + k[i] = -v + } + + bi := blas64.Implementation() + + if forward { + for j, v := range k { + if v >= 0 { + continue + } + k[j] = -v + i := -v - 1 + for k[i] < 0 { + bi.Dswap(m, x[j:], ldx, x[i:], ldx) + + k[i] = -k[i] + j = i + i = k[i] - 1 + } + } + } else { + for i, v := range k { + if v >= 0 { + continue + } + k[i] = -v + j := -v - 1 + for j != i { + bi.Dswap(m, x[j:], ldx, x[i:], ldx) + + k[j] = -k[j] + j = k[j] - 1 + } + } + } + + for i := range k { + k[i]-- + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlapy2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlapy2.go new file mode 100644 index 00000000..cbc63210 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlapy2.go @@ -0,0 +1,14 @@ +// 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" + +// Dlapy2 is the LAPACK version of math.Hypot. +// +// Dlapy2 is an internal routine. It is exported for testing purposes. +func (Implementation) Dlapy2(x, y float64) float64 { + return math.Hypot(x, y) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqp2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqp2.go new file mode 100644 index 00000000..8b2118b1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqp2.go @@ -0,0 +1,111 @@ +// 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/blas/blas64" +) + +// Dlaqp2 computes a QR factorization with column pivoting of the block A[offset:m, 0:n] +// of the m×n matrix A. The block A[0:offset, 0:n] is accordingly pivoted, but not factorized. +// +// On exit, the upper triangle of block A[offset:m, 0:n] is the triangular factor obtained. +// The elements in block A[offset:m, 0:n] below the diagonal, together with tau, represent +// the orthogonal matrix Q as a product of elementary reflectors. +// +// offset is number of rows of the matrix A that must be pivoted but not factorized. +// offset must not be negative otherwise Dlaqp2 will panic. +// +// On exit, jpvt holds the permutation that was applied; the jth column of A*P was the +// jpvt[j] column of A. jpvt must have length n, otherwise Dlaqp2 will panic. +// +// On exit tau holds the scalar factors of the elementary reflectors. It must have length +// at least min(m-offset, n) otherwise Dlaqp2 will panic. +// +// vn1 and vn2 hold the partial and complete column norms respectively. They must have length n, +// otherwise Dlaqp2 will panic. +// +// work must have length n, otherwise Dlaqp2 will panic. +// +// Dlaqp2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaqp2(m, n, offset int, a []float64, lda int, jpvt []int, tau, vn1, vn2, work []float64) { + checkMatrix(m, n, a, lda) + if len(jpvt) != n { + panic(badIpiv) + } + mn := min(m-offset, n) + if len(tau) < mn { + panic(badTau) + } + if len(vn1) < n { + panic(badVn1) + } + if len(vn2) < n { + panic(badVn2) + } + if len(work) < n { + panic(badWork) + } + + tol3z := math.Sqrt(dlamchE) + + bi := blas64.Implementation() + + // Compute factorization. + for i := 0; i < mn; i++ { + offpi := offset + i + + // Determine ith pivot column and swap if necessary. + p := i + bi.Idamax(n-i, vn1[i:], 1) + if p != i { + bi.Dswap(m, a[p:], lda, a[i:], lda) + jpvt[p], jpvt[i] = jpvt[i], jpvt[p] + vn1[p] = vn1[i] + vn2[p] = vn2[i] + } + + // Generate elementary reflector H_i. + if offpi < m-1 { + a[offpi*lda+i], tau[i] = impl.Dlarfg(m-offpi, a[offpi*lda+i], a[(offpi+1)*lda+i:], lda) + } else { + tau[i] = 0 + } + + if i < n-1 { + // Apply H_i^T to A[offset+i:m, i:n] from the left. + aii := a[offpi*lda+i] + a[offpi*lda+i] = 1 + impl.Dlarf(blas.Left, m-offpi, n-i-1, a[offpi*lda+i:], lda, tau[i], a[offpi*lda+i+1:], lda, work) + a[offpi*lda+i] = aii + } + + // Update partial column norms. + for j := i + 1; j < n; j++ { + if vn1[j] == 0 { + continue + } + + // The following marked lines follow from the + // analysis in Lapack Working Note 176. + r := math.Abs(a[offpi*lda+j]) / vn1[j] // * + temp := math.Max(0, 1-r*r) // * + r = vn1[j] / vn2[j] // * + temp2 := temp * r * r // * + if temp2 < tol3z { + var v float64 + if offpi < m-1 { + v = bi.Dnrm2(m-offpi-1, a[(offpi+1)*lda+j:], lda) + } + vn1[j] = v + vn2[j] = v + } else { + vn1[j] *= math.Sqrt(temp) // * + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqps.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqps.go new file mode 100644 index 00000000..d5883c5c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqps.go @@ -0,0 +1,217 @@ +// 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/blas/blas64" +) + +// Dlaqps computes a step of QR factorization with column pivoting +// of an m×n matrix A by using Blas-3. It tries to factorize nb +// columns from A starting from the row offset, and updates all +// of the matrix with Dgemm. +// +// In some cases, due to catastrophic cancellations, it cannot +// factorize nb columns. Hence, the actual number of factorized +// columns is returned in kb. +// +// Dlaqps computes a QR factorization with column pivoting of the +// block A[offset:m, 0:nb] of the m×n matrix A. The block +// A[0:offset, 0:n] is accordingly pivoted, but not factorized. +// +// On exit, the upper triangle of block A[offset:m, 0:kb] is the +// triangular factor obtained. The elements in block A[offset:m, 0:n] +// below the diagonal, together with tau, represent the orthogonal +// matrix Q as a product of elementary reflectors. +// +// offset is number of rows of the matrix A that must be pivoted but +// not factorized. offset must not be negative otherwise Dlaqps will panic. +// +// On exit, jpvt holds the permutation that was applied; the jth column +// of A*P was the jpvt[j] column of A. jpvt must have length n, +// otherwise Dlapqs will panic. +// +// On exit tau holds the scalar factors of the elementary reflectors. +// It must have length nb, otherwise Dlapqs will panic. +// +// vn1 and vn2 hold the partial and complete column norms respectively. +// They must have length n, otherwise Dlapqs will panic. +// +// auxv must have length nb, otherwise Dlaqps will panic. +// +// f and ldf represent an n×nb matrix F that is overwritten during the +// call. +// +// Dlaqps is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaqps(m, n, offset, nb int, a []float64, lda int, jpvt []int, tau, vn1, vn2, auxv, f []float64, ldf int) (kb int) { + checkMatrix(m, n, a, lda) + checkMatrix(n, nb, f, ldf) + if offset > m { + panic(offsetGTM) + } + if n < 0 || nb > n { + panic(badNb) + } + if len(jpvt) != n { + panic(badIpiv) + } + if len(tau) < nb { + panic(badTau) + } + if len(vn1) < n { + panic(badVn1) + } + if len(vn2) < n { + panic(badVn2) + } + if len(auxv) < nb { + panic(badAuxv) + } + + lastrk := min(m, n+offset) + lsticc := -1 + tol3z := math.Sqrt(dlamchE) + + bi := blas64.Implementation() + + var k, rk int + for ; k < nb && lsticc == -1; k++ { + rk = offset + k + + // Determine kth pivot column and swap if necessary. + p := k + bi.Idamax(n-k, vn1[k:], 1) + if p != k { + bi.Dswap(m, a[p:], lda, a[k:], lda) + bi.Dswap(k, f[p*ldf:], 1, f[k*ldf:], 1) + jpvt[p], jpvt[k] = jpvt[k], jpvt[p] + vn1[p] = vn1[k] + vn2[p] = vn2[k] + } + + // Apply previous Householder reflectors to column K: + // + // A[rk:m, k] = A[rk:m, k] - A[rk:m, 0:k-1]*F[k, 0:k-1]^T. + if k > 0 { + bi.Dgemv(blas.NoTrans, m-rk, k, -1, + a[rk*lda:], lda, + f[k*ldf:], 1, + 1, + a[rk*lda+k:], lda) + } + + // Generate elementary reflector H_k. + if rk < m-1 { + a[rk*lda+k], tau[k] = impl.Dlarfg(m-rk, a[rk*lda+k], a[(rk+1)*lda+k:], lda) + } else { + tau[k] = 0 + } + + akk := a[rk*lda+k] + a[rk*lda+k] = 1 + + // Compute kth column of F: + // + // Compute F[k+1:n, k] = tau[k]*A[rk:m, k+1:n]^T*A[rk:m, k]. + if k < n-1 { + bi.Dgemv(blas.Trans, m-rk, n-k-1, tau[k], + a[rk*lda+k+1:], lda, + a[rk*lda+k:], lda, + 0, + f[(k+1)*ldf+k:], ldf) + } + + // Padding F[0:k, k] with zeros. + for j := 0; j < k; j++ { + f[j*ldf+k] = 0 + } + + // Incremental updating of F: + // + // F[0:n, k] := F[0:n, k] - tau[k]*F[0:n, 0:k-1]*A[rk:m, 0:k-1]^T*A[rk:m,k]. + if k > 0 { + bi.Dgemv(blas.Trans, m-rk, k, -tau[k], + a[rk*lda:], lda, + a[rk*lda+k:], lda, + 0, + auxv, 1) + bi.Dgemv(blas.NoTrans, n, k, 1, + f, ldf, + auxv, 1, + 1, + f[k:], ldf) + } + + // Update the current row of A: + // + // A[rk, k+1:n] = A[rk, k+1:n] - A[rk, 0:k]*F[k+1:n, 0:k]^T. + if k < n-1 { + bi.Dgemv(blas.NoTrans, n-k-1, k+1, -1, + f[(k+1)*ldf:], ldf, + a[rk*lda:], 1, + 1, + a[rk*lda+k+1:], 1) + } + + // Update partial column norms. + if rk < lastrk-1 { + for j := k + 1; j < n; j++ { + if vn1[j] == 0 { + continue + } + + // The following marked lines follow from the + // analysis in Lapack Working Note 176. + r := math.Abs(a[rk*lda+j]) / vn1[j] // * + temp := math.Max(0, 1-r*r) // * + r = vn1[j] / vn2[j] // * + temp2 := temp * r * r // * + if temp2 < tol3z { + // vn2 is used here as a collection of + // indices into vn2 and also a collection + // of column norms. + vn2[j] = float64(lsticc) + lsticc = j + } else { + vn1[j] *= math.Sqrt(temp) // * + } + } + } + + a[rk*lda+k] = akk + } + kb = k + rk = offset + kb + + // Apply the block reflector to the rest of the matrix: + // + // A[offset+kb+1:m, kb+1:n] := A[offset+kb+1:m, kb+1:n] - A[offset+kb+1:m, 1:kb]*F[kb+1:n, 1:kb]^T. + if kb < min(n, m-offset) { + bi.Dgemm(blas.NoTrans, blas.Trans, + m-rk, n-kb, kb, -1, + a[rk*lda:], lda, + f[kb*ldf:], ldf, + 1, + a[rk*lda+kb:], lda) + } + + // Recomputation of difficult columns. + for lsticc >= 0 { + itemp := int(vn2[lsticc]) + + // NOTE: The computation of vn1[lsticc] relies on the fact that + // Dnrm2 does not fail on vectors with norm below the value of + // sqrt(dlamchS) + v := bi.Dnrm2(m-rk, a[rk*lda+lsticc:], lda) + vn1[lsticc] = v + vn2[lsticc] = v + + lsticc = itemp + } + + return kb +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr04.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr04.go new file mode 100644 index 00000000..6db4d98d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr04.go @@ -0,0 +1,475 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" +) + +// Dlaqr04 computes the eigenvalues of a block of an n×n upper Hessenberg matrix +// H, and optionally the matrices T and Z from the Schur decomposition +// H = Z T Z^T +// where T is an upper quasi-triangular matrix (the Schur form), and Z is the +// orthogonal matrix of Schur vectors. +// +// wantt indicates whether the full Schur form T is required. If wantt is false, +// then only enough of H will be updated to preserve the eigenvalues. +// +// wantz indicates whether the n×n matrix of Schur vectors Z is required. If it +// is true, the orthogonal similarity transformation will be accumulated into +// Z[iloz:ihiz+1,ilo:ihi+1], otherwise Z will not be referenced. +// +// ilo and ihi determine the block of H on which Dlaqr04 operates. It must hold that +// 0 <= ilo <= ihi < n, if n > 0, +// ilo == 0 and ihi == -1, if n == 0, +// and the block must be isolated, that is, +// ilo == 0 or H[ilo,ilo-1] == 0, +// ihi == n-1 or H[ihi+1,ihi] == 0, +// otherwise Dlaqr04 will panic. +// +// wr and wi must have length ihi+1. +// +// iloz and ihiz specify the rows of Z to which transformations will be applied +// if wantz is true. It must hold that +// 0 <= iloz <= ilo, and ihi <= ihiz < n, +// otherwise Dlaqr04 will panic. +// +// work must have length at least lwork and lwork must be +// lwork >= 1, if n <= 11, +// lwork >= n, if n > 11, +// otherwise Dlaqr04 will panic. lwork as large as 6*n may be required for +// optimal performance. On return, work[0] will contain the optimal value of +// lwork. +// +// If lwork is -1, instead of performing Dlaqr04, the function only estimates the +// optimal workspace size and stores it into work[0]. Neither h nor z are +// accessed. +// +// recur is the non-negative recursion depth. For recur > 0, Dlaqr04 behaves +// as DLAQR0, for recur == 0 it behaves as DLAQR4. +// +// unconverged indicates whether Dlaqr04 computed all the eigenvalues of H[ilo:ihi+1,ilo:ihi+1]. +// +// If unconverged is zero and wantt is true, H will contain on return the upper +// quasi-triangular matrix T from the Schur decomposition. 2×2 diagonal blocks +// (corresponding to complex conjugate pairs of eigenvalues) will be returned in +// standard form, with H[i,i] == H[i+1,i+1] and H[i+1,i]*H[i,i+1] < 0. +// +// If unconverged is zero and if wantt is false, the contents of h on return is +// unspecified. +// +// If unconverged is zero, all the eigenvalues have been computed and their real +// and imaginary parts will be stored on return in wr[ilo:ihi+1] and +// wi[ilo:ihi+1], respectively. If two eigenvalues are computed as a complex +// conjugate pair, they are stored in consecutive elements of wr and wi, say the +// i-th and (i+1)th, with wi[i] > 0 and wi[i+1] < 0. If wantt is true, then the +// eigenvalues are stored in the same order as on the diagonal of the Schur form +// returned in H, with wr[i] = H[i,i] and, if H[i:i+2,i:i+2] is a 2×2 diagonal +// block, wi[i] = sqrt(-H[i+1,i]*H[i,i+1]) and wi[i+1] = -wi[i]. +// +// If unconverged is positive, some eigenvalues have not converged, and +// wr[unconverged:ihi+1] and wi[unconverged:ihi+1] will contain those +// eigenvalues which have been successfully computed. Failures are rare. +// +// If unconverged is positive and wantt is true, then on return +// (initial H)*U = U*(final H), (*) +// where U is an orthogonal matrix. The final H is upper Hessenberg and +// H[unconverged:ihi+1,unconverged:ihi+1] is upper quasi-triangular. +// +// If unconverged is positive and wantt is false, on return the remaining +// unconverged eigenvalues are the eigenvalues of the upper Hessenberg matrix +// H[ilo:unconverged,ilo:unconverged]. +// +// If unconverged is positive and wantz is true, then on return +// (final Z) = (initial Z)*U, +// where U is the orthogonal matrix in (*) regardless of the value of wantt. +// +// References: +// [1] K. Braman, R. Byers, R. Mathias. The Multishift QR Algorithm. Part I: +// Maintaining Well-Focused Shifts and Level 3 Performance. SIAM J. Matrix +// Anal. Appl. 23(4) (2002), pp. 929—947 +// URL: http://dx.doi.org/10.1137/S0895479801384573 +// [2] K. Braman, R. Byers, R. Mathias. The Multishift QR Algorithm. Part II: +// Aggressive Early Deflation. SIAM J. Matrix Anal. Appl. 23(4) (2002), pp. 948—973 +// URL: http://dx.doi.org/10.1137/S0895479801384585 +// +// Dlaqr04 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaqr04(wantt, wantz bool, n, ilo, ihi int, h []float64, ldh int, wr, wi []float64, iloz, ihiz int, z []float64, ldz int, work []float64, lwork int, recur int) (unconverged int) { + const ( + // Matrices of order ntiny or smaller must be processed by + // Dlahqr because of insufficient subdiagonal scratch space. + // This is a hard limit. + ntiny = 11 + // Exceptional deflation windows: try to cure rare slow + // convergence by varying the size of the deflation window after + // kexnw iterations. + kexnw = 5 + // Exceptional shifts: try to cure rare slow convergence with + // ad-hoc exceptional shifts every kexsh iterations. + kexsh = 6 + + // See https://github.com/gonum/lapack/pull/151#discussion_r68162802 + // and the surrounding discussion for an explanation where these + // constants come from. + // TODO(vladimir-ch): Similar constants for exceptional shifts + // are used also in dlahqr.go. The first constant is different + // there, it is equal to 3. Why? And does it matter? + wilk1 = 0.75 + wilk2 = -0.4375 + ) + + switch { + case ilo < 0 || max(0, n-1) < ilo: + panic(badIlo) + case ihi < min(ilo, n-1) || n <= ihi: + panic(badIhi) + case lwork < 1 && n <= ntiny && lwork != -1: + panic(badWork) + // TODO(vladimir-ch): Enable if and when we figure out what the minimum + // necessary lwork value is. Dlaqr04 says that the minimum is n which + // clashes with Dlaqr23's opinion about optimal work when nw <= 2 + // (independent of n). + // case lwork < n && n > ntiny && lwork != -1: + // panic(badWork) + case len(work) < lwork: + panic(shortWork) + case recur < 0: + panic("lapack: recur is negative") + } + if wantz { + if iloz < 0 || ilo < iloz { + panic("lapack: invalid value of iloz") + } + if ihiz < ihi || n <= ihiz { + panic("lapack: invalid value of ihiz") + } + } + if lwork != -1 { + checkMatrix(n, n, h, ldh) + if wantz { + checkMatrix(n, n, z, ldz) + } + switch { + case ilo > 0 && h[ilo*ldh+ilo-1] != 0: + panic("lapack: block not isolated") + case ihi+1 < n && h[(ihi+1)*ldh+ihi] != 0: + panic("lapack: block not isolated") + case len(wr) != ihi+1: + panic("lapack: bad length of wr") + case len(wi) != ihi+1: + panic("lapack: bad length of wi") + } + } + + // Quick return. + if n == 0 { + work[0] = 1 + return 0 + } + + if n <= ntiny { + // Tiny matrices must use Dlahqr. + work[0] = 1 + if lwork == -1 { + return 0 + } + return impl.Dlahqr(wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, iloz, ihiz, z, ldz) + } + + // Use small bulge multi-shift QR with aggressive early deflation on + // larger-than-tiny matrices. + var jbcmpz string + if wantt { + jbcmpz = "S" + } else { + jbcmpz = "E" + } + if wantz { + jbcmpz += "V" + } else { + jbcmpz += "N" + } + + var fname string + if recur > 0 { + fname = "DLAQR0" + } else { + fname = "DLAQR4" + } + // nwr is the recommended deflation window size. n is greater than 11, + // so there is enough subdiagonal workspace for nwr >= 2 as required. + // (In fact, there is enough subdiagonal space for nwr >= 3.) + // TODO(vladimir-ch): If there is enough space for nwr >= 3, should we + // use it? + nwr := impl.Ilaenv(13, fname, jbcmpz, n, ilo, ihi, lwork) + nwr = max(2, nwr) + nwr = min(ihi-ilo+1, min((n-1)/3, nwr)) + + // nsr is the recommended number of simultaneous shifts. n is greater + // than 11, so there is enough subdiagonal workspace for nsr to be even + // and greater than or equal to two as required. + nsr := impl.Ilaenv(15, fname, jbcmpz, n, ilo, ihi, lwork) + nsr = min(nsr, min((n+6)/9, ihi-ilo)) + nsr = max(2, nsr&^1) + + // Workspace query call to Dlaqr23. + impl.Dlaqr23(wantt, wantz, n, ilo, ihi, nwr+1, nil, 0, iloz, ihiz, nil, 0, + nil, nil, nil, 0, n, nil, 0, n, nil, 0, work, -1, recur) + // Optimal workspace is max(Dlaqr5, Dlaqr23). + lwkopt := max(3*nsr/2, int(work[0])) + // Quick return in case of workspace query. + if lwork == -1 { + work[0] = float64(lwkopt) + return 0 + } + + // Dlahqr/Dlaqr04 crossover point. + nmin := impl.Ilaenv(12, fname, jbcmpz, n, ilo, ihi, lwork) + nmin = max(ntiny, nmin) + + // Nibble determines when to skip a multi-shift QR sweep (Dlaqr5). + nibble := impl.Ilaenv(14, fname, jbcmpz, n, ilo, ihi, lwork) + nibble = max(0, nibble) + + // Computation mode of far-from-diagonal orthogonal updates in Dlaqr5. + kacc22 := impl.Ilaenv(16, fname, jbcmpz, n, ilo, ihi, lwork) + kacc22 = max(0, min(kacc22, 2)) + + // nwmax is the largest possible deflation window for which there is + // sufficient workspace. + nwmax := min((n-1)/3, lwork/2) + nw := nwmax // Start with maximum deflation window size. + + // nsmax is the largest number of simultaneous shifts for which there is + // sufficient workspace. + nsmax := min((n+6)/9, 2*lwork/3) &^ 1 + + ndfl := 1 // Number of iterations since last deflation. + ndec := 0 // Deflation window size decrement. + + // Main loop. + var ( + itmax = max(30, 2*kexsh) * max(10, (ihi-ilo+1)) + it = 0 + ) + for kbot := ihi; kbot >= ilo; { + if it == itmax { + unconverged = kbot + 1 + break + } + it++ + + // Locate active block. + ktop := ilo + for k := kbot; k >= ilo+1; k-- { + if h[k*ldh+k-1] == 0 { + ktop = k + break + } + } + + // Select deflation window size nw. + // + // Typical Case: + // If possible and advisable, nibble the entire active block. + // If not, use size min(nwr,nwmax) or min(nwr+1,nwmax) + // depending upon which has the smaller corresponding + // subdiagonal entry (a heuristic). + // + // Exceptional Case: + // If there have been no deflations in kexnw or more + // iterations, then vary the deflation window size. At first, + // because larger windows are, in general, more powerful than + // smaller ones, rapidly increase the window to the maximum + // possible. Then, gradually reduce the window size. + nh := kbot - ktop + 1 + nwupbd := min(nh, nwmax) + if ndfl < kexnw { + nw = min(nwupbd, nwr) + } else { + nw = min(nwupbd, 2*nw) + } + if nw < nwmax { + if nw >= nh-1 { + nw = nh + } else { + kwtop := kbot - nw + 1 + if math.Abs(h[kwtop*ldh+kwtop-1]) > math.Abs(h[(kwtop-1)*ldh+kwtop-2]) { + nw++ + } + } + } + if ndfl < kexnw { + ndec = -1 + } else if ndec >= 0 || nw >= nwupbd { + ndec++ + if nw-ndec < 2 { + ndec = 0 + } + nw -= ndec + } + + // Split workspace under the subdiagonal of H into: + // - an nw×nw work array V in the lower left-hand corner, + // - an nw×nhv horizontal work array along the bottom edge (nhv + // must be at least nw but more is better), + // - an nve×nw vertical work array along the left-hand-edge + // (nhv can be any positive integer but more is better). + kv := n - nw + kt := nw + kwv := nw + 1 + nhv := n - kwv - kt + // Aggressive early deflation. + ls, ld := impl.Dlaqr23(wantt, wantz, n, ktop, kbot, nw, + h, ldh, iloz, ihiz, z, ldz, wr[:kbot+1], wi[:kbot+1], + h[kv*ldh:], ldh, nhv, h[kv*ldh+kt:], ldh, nhv, h[kwv*ldh:], ldh, work, lwork, recur) + + // Adjust kbot accounting for new deflations. + kbot -= ld + // ks points to the shifts. + ks := kbot - ls + 1 + + // Skip an expensive QR sweep if there is a (partly heuristic) + // reason to expect that many eigenvalues will deflate without + // it. Here, the QR sweep is skipped if many eigenvalues have + // just been deflated or if the remaining active block is small. + if ld > 0 && (100*ld > nw*nibble || kbot-ktop+1 <= min(nmin, nwmax)) { + // ld is positive, note progress. + ndfl = 1 + continue + } + + // ns is the nominal number of simultaneous shifts. This may be + // lowered (slightly) if Dlaqr23 did not provide that many + // shifts. + ns := min(min(nsmax, nsr), max(2, kbot-ktop)) &^ 1 + + // If there have been no deflations in a multiple of kexsh + // iterations, then try exceptional shifts. Otherwise use shifts + // provided by Dlaqr23 above or from the eigenvalues of a + // trailing principal submatrix. + if ndfl%kexsh == 0 { + ks = kbot - ns + 1 + for i := kbot; i > max(ks, ktop+1); i -= 2 { + ss := math.Abs(h[i*ldh+i-1]) + math.Abs(h[(i-1)*ldh+i-2]) + aa := wilk1*ss + h[i*ldh+i] + _, _, _, _, wr[i-1], wi[i-1], wr[i], wi[i], _, _ = + impl.Dlanv2(aa, ss, wilk2*ss, aa) + } + if ks == ktop { + wr[ks+1] = h[(ks+1)*ldh+ks+1] + wi[ks+1] = 0 + wr[ks] = wr[ks+1] + wi[ks] = wi[ks+1] + } + } else { + // If we got ns/2 or fewer shifts, use Dlahqr or recur + // into Dlaqr04 on a trailing principal submatrix to get + // more. Since ns <= nsmax <=(n+6)/9, there is enough + // space below the subdiagonal to fit an ns×ns scratch + // array. + if kbot-ks+1 <= ns/2 { + ks = kbot - ns + 1 + kt = n - ns + impl.Dlacpy(blas.All, ns, ns, h[ks*ldh+ks:], ldh, h[kt*ldh:], ldh) + if ns > nmin && recur > 0 { + ks += impl.Dlaqr04(false, false, ns, 1, ns-1, h[kt*ldh:], ldh, + wr[ks:ks+ns], wi[ks:ks+ns], 0, 0, nil, 0, work, lwork, recur-1) + } else { + ks += impl.Dlahqr(false, false, ns, 0, ns-1, h[kt*ldh:], ldh, + wr[ks:ks+ns], wi[ks:ks+ns], 0, 0, nil, 0) + } + // In case of a rare QR failure use eigenvalues + // of the trailing 2×2 principal submatrix. + if ks >= kbot { + aa := h[(kbot-1)*ldh+kbot-1] + bb := h[(kbot-1)*ldh+kbot] + cc := h[kbot*ldh+kbot-1] + dd := h[kbot*ldh+kbot] + _, _, _, _, wr[kbot-1], wi[kbot-1], wr[kbot], wi[kbot], _, _ = + impl.Dlanv2(aa, bb, cc, dd) + ks = kbot - 1 + } + } + + if kbot-ks+1 > ns { + // Sorting the shifts helps a little. Bubble + // sort keeps complex conjugate pairs together. + sorted := false + for k := kbot; k > ks; k-- { + if sorted { + break + } + sorted = true + for i := ks; i < k; i++ { + if math.Abs(wr[i])+math.Abs(wi[i]) >= math.Abs(wr[i+1])+math.Abs(wi[i+1]) { + continue + } + sorted = false + wr[i], wr[i+1] = wr[i+1], wr[i] + wi[i], wi[i+1] = wi[i+1], wi[i] + } + } + } + + // Shuffle shifts into pairs of real shifts and pairs of + // complex conjugate shifts using the fact that complex + // conjugate shifts are already adjacent to one another. + // TODO(vladimir-ch): The shuffling here could probably + // be removed but I'm not sure right now and it's safer + // to leave it. + for i := kbot; i > ks+1; i -= 2 { + if wi[i] == -wi[i-1] { + continue + } + wr[i], wr[i-1], wr[i-2] = wr[i-1], wr[i-2], wr[i] + wi[i], wi[i-1], wi[i-2] = wi[i-1], wi[i-2], wi[i] + } + } + + // If there are only two shifts and both are real, then use only one. + if kbot-ks+1 == 2 && wi[kbot] == 0 { + if math.Abs(wr[kbot]-h[kbot*ldh+kbot]) < math.Abs(wr[kbot-1]-h[kbot*ldh+kbot]) { + wr[kbot-1] = wr[kbot] + } else { + wr[kbot] = wr[kbot-1] + } + } + + // Use up to ns of the the smallest magnitude shifts. If there + // aren't ns shifts available, then use them all, possibly + // dropping one to make the number of shifts even. + ns = min(ns, kbot-ks+1) &^ 1 + ks = kbot - ns + 1 + + // Split workspace under the subdiagonal into: + // - a kdu×kdu work array U in the lower left-hand-corner, + // - a kdu×nhv horizontal work array WH along the bottom edge + // (nhv must be at least kdu but more is better), + // - an nhv×kdu vertical work array WV along the left-hand-edge + // (nhv must be at least kdu but more is better). + kdu := 3*ns - 3 + ku := n - kdu + kwh := kdu + kwv = kdu + 3 + nhv = n - kwv - kdu + // Small-bulge multi-shift QR sweep. + impl.Dlaqr5(wantt, wantz, kacc22, n, ktop, kbot, ns, + wr[ks:ks+ns], wi[ks:ks+ns], h, ldh, iloz, ihiz, z, ldz, + work, 3, h[ku*ldh:], ldh, nhv, h[kwv*ldh:], ldh, nhv, h[ku*ldh+kwh:], ldh) + + // Note progress (or the lack of it). + if ld > 0 { + ndfl = 1 + } else { + ndfl++ + } + } + + work[0] = float64(lwkopt) + return unconverged +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr1.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr1.go new file mode 100644 index 00000000..9efd774a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr1.go @@ -0,0 +1,57 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "math" + +// Dlaqr1 sets v to a scalar multiple of the first column of the product +// (H - (sr1 + i*si1)*I)*(H - (sr2 + i*si2)*I) +// where H is a 2×2 or 3×3 matrix, I is the identity matrix of the same size, +// and i is the imaginary unit. Scaling is done to avoid overflows and most +// underflows. +// +// n is the order of H and must be either 2 or 3. It must hold that either sr1 = +// sr2 and si1 = -si2, or si1 = si2 = 0. The length of v must be equal to n. If +// any of these conditions is not met, Dlaqr1 will panic. +// +// Dlaqr1 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaqr1(n int, h []float64, ldh int, sr1, si1, sr2, si2 float64, v []float64) { + if n != 2 && n != 3 { + panic(badDims) + } + checkMatrix(n, n, h, ldh) + if len(v) != n { + panic(badSlice) + } + if !((sr1 == sr2 && si1 == -si2) || (si1 == 0 && si2 == 0)) { + panic(badShifts) + } + + if n == 2 { + s := math.Abs(h[0]-sr2) + math.Abs(si2) + math.Abs(h[ldh]) + if s == 0 { + v[0] = 0 + v[1] = 0 + } else { + h21s := h[ldh] / s + v[0] = h21s*h[1] + (h[0]-sr1)*((h[0]-sr2)/s) - si1*(si2/s) + v[1] = h21s * (h[0] + h[ldh+1] - sr1 - sr2) + } + return + } + + s := math.Abs(h[0]-sr2) + math.Abs(si2) + math.Abs(h[ldh]) + math.Abs(h[2*ldh]) + if s == 0 { + v[0] = 0 + v[1] = 0 + v[2] = 0 + } else { + h21s := h[ldh] / s + h31s := h[2*ldh] / s + v[0] = (h[0]-sr1)*((h[0]-sr2)/s) - si1*(si2/s) + h[1]*h21s + h[2]*h31s + v[1] = h21s*(h[0]+h[ldh+1]-sr1-sr2) + h[ldh+2]*h31s + v[2] = h31s*(h[0]+h[2*ldh+2]-sr1-sr2) + h21s*h[2*ldh+1] + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr23.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr23.go new file mode 100644 index 00000000..1a59e4b9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr23.go @@ -0,0 +1,403 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dlaqr23 performs the orthogonal similarity transformation of an n×n upper +// Hessenberg matrix to detect and deflate fully converged eigenvalues from a +// trailing principal submatrix using aggressive early deflation [1]. +// +// On return, H will be overwritten by a new Hessenberg matrix that is a +// perturbation of an orthogonal similarity transformation of H. It is hoped +// that on output H will have many zero subdiagonal entries. +// +// If wantt is true, the matrix H will be fully updated so that the +// quasi-triangular Schur factor can be computed. If wantt is false, then only +// enough of H will be updated to preserve the eigenvalues. +// +// If wantz is true, the orthogonal similarity transformation will be +// accumulated into Z[iloz:ihiz+1,ktop:kbot+1], otherwise Z is not referenced. +// +// ktop and kbot determine a block [ktop:kbot+1,ktop:kbot+1] along the diagonal +// of H. It must hold that +// 0 <= ilo <= ihi < n, if n > 0, +// ilo == 0 and ihi == -1, if n == 0, +// and the block must be isolated, that is, it must hold that +// ktop == 0 or H[ktop,ktop-1] == 0, +// kbot == n-1 or H[kbot+1,kbot] == 0, +// otherwise Dlaqr23 will panic. +// +// nw is the deflation window size. It must hold that +// 0 <= nw <= kbot-ktop+1, +// otherwise Dlaqr23 will panic. +// +// iloz and ihiz specify the rows of the n×n matrix Z to which transformations +// will be applied if wantz is true. It must hold that +// 0 <= iloz <= ktop, and kbot <= ihiz < n, +// otherwise Dlaqr23 will panic. +// +// sr and si must have length kbot+1, otherwise Dlaqr23 will panic. +// +// v and ldv represent an nw×nw work matrix. +// t and ldt represent an nw×nh work matrix, and nh must be at least nw. +// wv and ldwv represent an nv×nw work matrix. +// +// work must have length at least lwork and lwork must be at least max(1,2*nw), +// otherwise Dlaqr23 will panic. Larger values of lwork may result in greater +// efficiency. On return, work[0] will contain the optimal value of lwork. +// +// If lwork is -1, instead of performing Dlaqr23, the function only estimates the +// optimal workspace size and stores it into work[0]. Neither h nor z are +// accessed. +// +// recur is the non-negative recursion depth. For recur > 0, Dlaqr23 behaves +// as DLAQR3, for recur == 0 it behaves as DLAQR2. +// +// On return, ns and nd will contain respectively the number of unconverged +// (i.e., approximate) eigenvalues and converged eigenvalues that are stored in +// sr and si. +// +// On return, the real and imaginary parts of approximate eigenvalues that may +// be used for shifts will be stored respectively in sr[kbot-nd-ns+1:kbot-nd+1] +// and si[kbot-nd-ns+1:kbot-nd+1]. +// +// On return, the real and imaginary parts of converged eigenvalues will be +// stored respectively in sr[kbot-nd+1:kbot+1] and si[kbot-nd+1:kbot+1]. +// +// References: +// [1] K. Braman, R. Byers, R. Mathias. The Multishift QR Algorithm. Part II: +// Aggressive Early Deflation. SIAM J. Matrix Anal. Appl 23(4) (2002), pp. 948—973 +// URL: http://dx.doi.org/10.1137/S0895479801384585 +// +func (impl Implementation) Dlaqr23(wantt, wantz bool, n, ktop, kbot, nw int, h []float64, ldh int, iloz, ihiz int, z []float64, ldz int, sr, si []float64, v []float64, ldv int, nh int, t []float64, ldt int, nv int, wv []float64, ldwv int, work []float64, lwork int, recur int) (ns, nd int) { + switch { + case ktop < 0 || max(0, n-1) < ktop: + panic("lapack: invalid value of ktop") + case kbot < min(ktop, n-1) || n <= kbot: + panic("lapack: invalid value of kbot") + case (nw < 0 || kbot-ktop+1 < nw) && lwork != -1: + panic("lapack: invalid value of nw") + case nh < nw: + panic("lapack: invalid value of nh") + case lwork < max(1, 2*nw) && lwork != -1: + panic(badWork) + case len(work) < lwork: + panic(shortWork) + case recur < 0: + panic("lapack: recur is negative") + } + if wantz { + switch { + case iloz < 0 || ktop < iloz: + panic("lapack: invalid value of iloz") + case ihiz < kbot || n <= ihiz: + panic("lapack: invalid value of ihiz") + } + } + if lwork != -1 { + // Check input slices only if not doing workspace query. + checkMatrix(n, n, h, ldh) + checkMatrix(nw, nw, v, ldv) + checkMatrix(nw, nh, t, ldt) + checkMatrix(nv, nw, wv, ldwv) + if wantz { + checkMatrix(n, n, z, ldz) + } + switch { + case ktop > 0 && h[ktop*ldh+ktop-1] != 0: + panic("lapack: block not isolated") + case kbot+1 < n && h[(kbot+1)*ldh+kbot] != 0: + panic("lapack: block not isolated") + case len(sr) != kbot+1: + panic("lapack: bad length of sr") + case len(si) != kbot+1: + panic("lapack: bad length of si") + } + } + + // Quick return for zero window size. + if nw == 0 { + work[0] = 1 + return 0, 0 + } + + // LAPACK code does not enforce the documented behavior + // nw <= kbot-ktop+1 + // but we do (we panic above). + jw := nw + lwkopt := max(1, 2*nw) + if jw > 2 { + // Workspace query call to Dgehrd. + impl.Dgehrd(jw, 0, jw-2, nil, 0, nil, work, -1) + lwk1 := int(work[0]) + // Workspace query call to Dormhr. + impl.Dormhr(blas.Right, blas.NoTrans, jw, jw, 0, jw-2, nil, 0, nil, nil, 0, work, -1) + lwk2 := int(work[0]) + if recur > 0 { + // Workspace query call to Dlaqr04. + impl.Dlaqr04(true, true, jw, 0, jw-1, nil, 0, nil, nil, 0, jw-1, nil, 0, work, -1, recur-1) + lwk3 := int(work[0]) + // Optimal workspace. + lwkopt = max(jw+max(lwk1, lwk2), lwk3) + } else { + // Optimal workspace. + lwkopt = jw + max(lwk1, lwk2) + } + } + // Quick return in case of workspace query. + if lwork == -1 { + work[0] = float64(lwkopt) + return 0, 0 + } + + // Machine constants. + ulp := dlamchP + smlnum := float64(n) / ulp * dlamchS + + // Setup deflation window. + var s float64 + kwtop := kbot - jw + 1 + if kwtop != ktop { + s = h[kwtop*ldh+kwtop-1] + } + if kwtop == kbot { + // 1×1 deflation window. + sr[kwtop] = h[kwtop*ldh+kwtop] + si[kwtop] = 0 + ns = 1 + nd = 0 + if math.Abs(s) <= math.Max(smlnum, ulp*math.Abs(h[kwtop*ldh+kwtop])) { + ns = 0 + nd = 1 + if kwtop > ktop { + h[kwtop*ldh+kwtop-1] = 0 + } + } + work[0] = 1 + return ns, nd + } + + // Convert to spike-triangular form. In case of a rare QR failure, this + // routine continues to do aggressive early deflation using that part of + // the deflation window that converged using infqr here and there to + // keep track. + impl.Dlacpy(blas.Upper, jw, jw, h[kwtop*ldh+kwtop:], ldh, t, ldt) + bi := blas64.Implementation() + bi.Dcopy(jw-1, h[(kwtop+1)*ldh+kwtop:], ldh+1, t[ldt:], ldt+1) + impl.Dlaset(blas.All, jw, jw, 0, 1, v, ldv) + nmin := impl.Ilaenv(12, "DLAQR3", "SV", jw, 0, jw-1, lwork) + var infqr int + if recur > 0 && jw > nmin { + infqr = impl.Dlaqr04(true, true, jw, 0, jw-1, t, ldt, sr[kwtop:], si[kwtop:], 0, jw-1, v, ldv, work, lwork, recur-1) + } else { + infqr = impl.Dlahqr(true, true, jw, 0, jw-1, t, ldt, sr[kwtop:], si[kwtop:], 0, jw-1, v, ldv) + } + // Note that ilo == 0 which conveniently coincides with the success + // value of infqr, that is, infqr as an index always points to the first + // converged eigenvalue. + + // Dtrexc needs a clean margin near the diagonal. + for j := 0; j < jw-3; j++ { + t[(j+2)*ldt+j] = 0 + t[(j+3)*ldt+j] = 0 + } + if jw >= 3 { + t[(jw-1)*ldt+jw-3] = 0 + } + + ns = jw + ilst := infqr + // Deflation detection loop. + for ilst < ns { + bulge := false + if ns >= 2 { + bulge = t[(ns-1)*ldt+ns-2] != 0 + } + if !bulge { + // Real eigenvalue. + abst := math.Abs(t[(ns-1)*ldt+ns-1]) + if abst == 0 { + abst = math.Abs(s) + } + if math.Abs(s*v[ns-1]) <= math.Max(smlnum, ulp*abst) { + // Deflatable. + ns-- + } else { + // Undeflatable, move it up out of the way. + // Dtrexc can not fail in this case. + _, ilst, _ = impl.Dtrexc(lapack.UpdateSchur, jw, t, ldt, v, ldv, ns-1, ilst, work) + ilst++ + } + continue + } + // Complex conjugate pair. + abst := math.Abs(t[(ns-1)*ldt+ns-1]) + math.Sqrt(math.Abs(t[(ns-1)*ldt+ns-2]))*math.Sqrt(math.Abs(t[(ns-2)*ldt+ns-1])) + if abst == 0 { + abst = math.Abs(s) + } + if math.Max(math.Abs(s*v[ns-1]), math.Abs(s*v[ns-2])) <= math.Max(smlnum, ulp*abst) { + // Deflatable. + ns -= 2 + } else { + // Undeflatable, move them up out of the way. + // Dtrexc does the right thing with ilst in case of a + // rare exchange failure. + _, ilst, _ = impl.Dtrexc(lapack.UpdateSchur, jw, t, ldt, v, ldv, ns-1, ilst, work) + ilst += 2 + } + } + + // Return to Hessenberg form. + if ns == 0 { + s = 0 + } + if ns < jw { + // Sorting diagonal blocks of T improves accuracy for graded + // matrices. Bubble sort deals well with exchange failures. + sorted := false + i := ns + for !sorted { + sorted = true + kend := i - 1 + i = infqr + var k int + if i == ns-1 || t[(i+1)*ldt+i] == 0 { + k = i + 1 + } else { + k = i + 2 + } + for k <= kend { + var evi float64 + if k == i+1 { + evi = math.Abs(t[i*ldt+i]) + } else { + evi = math.Abs(t[i*ldt+i]) + math.Sqrt(math.Abs(t[(i+1)*ldt+i]))*math.Sqrt(math.Abs(t[i*ldt+i+1])) + } + + var evk float64 + if k == kend || t[(k+1)*ldt+k] == 0 { + evk = math.Abs(t[k*ldt+k]) + } else { + evk = math.Abs(t[k*ldt+k]) + math.Sqrt(math.Abs(t[(k+1)*ldt+k]))*math.Sqrt(math.Abs(t[k*ldt+k+1])) + } + + if evi >= evk { + i = k + } else { + sorted = false + _, ilst, ok := impl.Dtrexc(lapack.UpdateSchur, jw, t, ldt, v, ldv, i, k, work) + if ok { + i = ilst + } else { + i = k + } + } + if i == kend || t[(i+1)*ldt+i] == 0 { + k = i + 1 + } else { + k = i + 2 + } + } + } + } + + // Restore shift/eigenvalue array from T. + for i := jw - 1; i >= infqr; { + if i == infqr || t[i*ldt+i-1] == 0 { + sr[kwtop+i] = t[i*ldt+i] + si[kwtop+i] = 0 + i-- + continue + } + aa := t[(i-1)*ldt+i-1] + bb := t[(i-1)*ldt+i] + cc := t[i*ldt+i-1] + dd := t[i*ldt+i] + _, _, _, _, sr[kwtop+i-1], si[kwtop+i-1], sr[kwtop+i], si[kwtop+i], _, _ = impl.Dlanv2(aa, bb, cc, dd) + i -= 2 + } + + if ns < jw || s == 0 { + if ns > 1 && s != 0 { + // Reflect spike back into lower triangle. + bi.Dcopy(ns, v[:ns], 1, work[:ns], 1) + _, tau := impl.Dlarfg(ns, work[0], work[1:ns], 1) + work[0] = 1 + impl.Dlaset(blas.Lower, jw-2, jw-2, 0, 0, t[2*ldt:], ldt) + impl.Dlarf(blas.Left, ns, jw, work[:ns], 1, tau, t, ldt, work[jw:]) + impl.Dlarf(blas.Right, ns, ns, work[:ns], 1, tau, t, ldt, work[jw:]) + impl.Dlarf(blas.Right, jw, ns, work[:ns], 1, tau, v, ldv, work[jw:]) + impl.Dgehrd(jw, 0, ns-1, t, ldt, work[:jw-1], work[jw:], lwork-jw) + } + + // Copy updated reduced window into place. + if kwtop > 0 { + h[kwtop*ldh+kwtop-1] = s * v[0] + } + impl.Dlacpy(blas.Upper, jw, jw, t, ldt, h[kwtop*ldh+kwtop:], ldh) + bi.Dcopy(jw-1, t[ldt:], ldt+1, h[(kwtop+1)*ldh+kwtop:], ldh+1) + + // Accumulate orthogonal matrix in order to update H and Z, if + // requested. + if ns > 1 && s != 0 { + // work[:ns-1] contains the elementary reflectors stored + // by a call to Dgehrd above. + impl.Dormhr(blas.Right, blas.NoTrans, jw, ns, 0, ns-1, + t, ldt, work[:ns-1], v, ldv, work[jw:], lwork-jw) + } + + // Update vertical slab in H. + var ltop int + if !wantt { + ltop = ktop + } + for krow := ltop; krow < kwtop; krow += nv { + kln := min(nv, kwtop-krow) + bi.Dgemm(blas.NoTrans, blas.NoTrans, kln, jw, jw, + 1, h[krow*ldh+kwtop:], ldh, v, ldv, + 0, wv, ldwv) + impl.Dlacpy(blas.All, kln, jw, wv, ldwv, h[krow*ldh+kwtop:], ldh) + } + + // Update horizontal slab in H. + if wantt { + for kcol := kbot + 1; kcol < n; kcol += nh { + kln := min(nh, n-kcol) + bi.Dgemm(blas.Trans, blas.NoTrans, jw, kln, jw, + 1, v, ldv, h[kwtop*ldh+kcol:], ldh, + 0, t, ldt) + impl.Dlacpy(blas.All, jw, kln, t, ldt, h[kwtop*ldh+kcol:], ldh) + } + } + + // Update vertical slab in Z. + if wantz { + for krow := iloz; krow <= ihiz; krow += nv { + kln := min(nv, ihiz-krow+1) + bi.Dgemm(blas.NoTrans, blas.NoTrans, kln, jw, jw, + 1, z[krow*ldz+kwtop:], ldz, v, ldv, + 0, wv, ldwv) + impl.Dlacpy(blas.All, kln, jw, wv, ldwv, z[krow*ldz+kwtop:], ldz) + } + } + } + + // The number of deflations. + nd = jw - ns + // Shifts are converged eigenvalues that could not be deflated. + // Subtracting infqr from the spike length takes care of the case of a + // rare QR failure while calculating eigenvalues of the deflation + // window. + ns -= infqr + work[0] = float64(lwkopt) + return ns, nd +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr5.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr5.go new file mode 100644 index 00000000..0b6959dd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaqr5.go @@ -0,0 +1,616 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlaqr5 performs a single small-bulge multi-shift QR sweep on an isolated +// block of a Hessenberg matrix. +// +// wantt and wantz determine whether the quasi-triangular Schur factor and the +// orthogonal Schur factor, respectively, will be computed. +// +// kacc22 specifies the computation mode of far-from-diagonal orthogonal +// updates. Permitted values are: +// 0: Dlaqr5 will not accumulate reflections and will not use matrix-matrix +// multiply to update far-from-diagonal matrix entries. +// 1: Dlaqr5 will accumulate reflections and use matrix-matrix multiply to +// update far-from-diagonal matrix entries. +// 2: Dlaqr5 will accumulate reflections, use matrix-matrix multiply to update +// far-from-diagonal matrix entries, and take advantage of 2×2 block +// structure during matrix multiplies. +// For other values of kacc2 Dlaqr5 will panic. +// +// n is the order of the Hessenberg matrix H. +// +// ktop and kbot are indices of the first and last row and column of an isolated +// diagonal block upon which the QR sweep will be applied. It must hold that +// ktop == 0, or 0 < ktop <= n-1 and H[ktop, ktop-1] == 0, and +// kbot == n-1, or 0 <= kbot < n-1 and H[kbot+1, kbot] == 0, +// otherwise Dlaqr5 will panic. +// +// nshfts is the number of simultaneous shifts. It must be positive and even, +// otherwise Dlaqr5 will panic. +// +// sr and si contain the real and imaginary parts, respectively, of the shifts +// of origin that define the multi-shift QR sweep. On return both slices may be +// reordered by Dlaqr5. Their length must be equal to nshfts, otherwise Dlaqr5 +// will panic. +// +// h and ldh represent the Hessenberg matrix H of size n×n. On return +// multi-shift QR sweep with shifts sr+i*si has been applied to the isolated +// diagonal block in rows and columns ktop through kbot, inclusive. +// +// iloz and ihiz specify the rows of Z to which transformations will be applied +// if wantz is true. It must hold that 0 <= iloz <= ihiz < n, otherwise Dlaqr5 +// will panic. +// +// z and ldz represent the matrix Z of size n×n. If wantz is true, the QR sweep +// orthogonal similarity transformation is accumulated into +// z[iloz:ihiz,iloz:ihiz] from the right, otherwise z not referenced. +// +// v and ldv represent an auxiliary matrix V of size (nshfts/2)×3. Note that V +// is transposed with respect to the reference netlib implementation. +// +// u and ldu represent an auxiliary matrix of size (3*nshfts-3)×(3*nshfts-3). +// +// wh and ldwh represent an auxiliary matrix of size (3*nshfts-3)×nh. +// +// wv and ldwv represent an auxiliary matrix of size nv×(3*nshfts-3). +// +// Dlaqr5 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaqr5(wantt, wantz bool, kacc22 int, n, ktop, kbot, nshfts int, sr, si []float64, h []float64, ldh int, iloz, ihiz int, z []float64, ldz int, v []float64, ldv int, u []float64, ldu int, nv int, wv []float64, ldwv int, nh int, wh []float64, ldwh int) { + checkMatrix(n, n, h, ldh) + if ktop < 0 || n <= ktop { + panic("lapack: invalid value of ktop") + } + if ktop > 0 && h[ktop*ldh+ktop-1] != 0 { + panic("lapack: diagonal block is not isolated") + } + if kbot < 0 || n <= kbot { + panic("lapack: invalid value of kbot") + } + if kbot < n-1 && h[(kbot+1)*ldh+kbot] != 0 { + panic("lapack: diagonal block is not isolated") + } + if nshfts < 0 || nshfts&0x1 != 0 { + panic("lapack: invalid number of shifts") + } + if len(sr) != nshfts || len(si) != nshfts { + panic(badSlice) // TODO(vladimir-ch) Another message? + } + if wantz { + if ihiz >= n { + panic("lapack: invalid value of ihiz") + } + if iloz < 0 || ihiz < iloz { + panic("lapack: invalid value of iloz") + } + checkMatrix(n, n, z, ldz) + } + checkMatrix(nshfts/2, 3, v, ldv) // Transposed w.r.t. lapack. + checkMatrix(3*nshfts-3, 3*nshfts-3, u, ldu) + checkMatrix(nv, 3*nshfts-3, wv, ldwv) + checkMatrix(3*nshfts-3, nh, wh, ldwh) + if kacc22 != 0 && kacc22 != 1 && kacc22 != 2 { + panic("lapack: invalid value of kacc22") + } + + // If there are no shifts, then there is nothing to do. + if nshfts < 2 { + return + } + // If the active block is empty or 1×1, then there is nothing to do. + if ktop >= kbot { + return + } + + // Shuffle shifts into pairs of real shifts and pairs of complex + // conjugate shifts assuming complex conjugate shifts are already + // adjacent to one another. + for i := 0; i < nshfts-2; i += 2 { + if si[i] == -si[i+1] { + continue + } + sr[i], sr[i+1], sr[i+2] = sr[i+1], sr[i+2], sr[i] + si[i], si[i+1], si[i+2] = si[i+1], si[i+2], si[i] + } + + // Note: lapack says that nshfts must be even but allows it to be odd + // anyway. We panic above if nshfts is not even, so reducing it by one + // is unnecessary. The only caller Dlaqr04 uses only even nshfts. + // + // The original comment and code from lapack-3.6.0/SRC/dlaqr5.f:341: + // * ==== NSHFTS is supposed to be even, but if it is odd, + // * . then simply reduce it by one. The shuffle above + // * . ensures that the dropped shift is real and that + // * . the remaining shifts are paired. ==== + // * + // NS = NSHFTS - MOD( NSHFTS, 2 ) + ns := nshfts + + safmin := dlamchS + ulp := dlamchP + smlnum := safmin * float64(n) / ulp + + // Use accumulated reflections to update far-from-diagonal entries? + accum := kacc22 == 1 || kacc22 == 2 + // If so, exploit the 2×2 block structure? + blk22 := ns > 2 && kacc22 == 2 + + // Clear trash. + if ktop+2 <= kbot { + h[(ktop+2)*ldh+ktop] = 0 + } + + // nbmps = number of 2-shift bulges in the chain. + nbmps := ns / 2 + + // kdu = width of slab. + kdu := 6*nbmps - 3 + + // Create and chase chains of nbmps bulges. + for incol := 3*(1-nbmps) + ktop - 1; incol <= kbot-2; incol += 3*nbmps - 2 { + ndcol := incol + kdu + if accum { + impl.Dlaset(blas.All, kdu, kdu, 0, 1, u, ldu) + } + + // Near-the-diagonal bulge chase. The following loop performs + // the near-the-diagonal part of a small bulge multi-shift QR + // sweep. Each 6*nbmps-2 column diagonal chunk extends from + // column incol to column ndcol (including both column incol and + // column ndcol). The following loop chases a 3*nbmps column + // long chain of nbmps bulges 3*nbmps-2 columns to the right. + // (incol may be less than ktop and ndcol may be greater than + // kbot indicating phantom columns from which to chase bulges + // before they are actually introduced or to which to chase + // bulges beyond column kbot.) + for krcol := incol; krcol <= min(incol+3*nbmps-3, kbot-2); krcol++ { + // Bulges number mtop to mbot are active double implicit + // shift bulges. There may or may not also be small 2×2 + // bulge, if there is room. The inactive bulges (if any) + // must wait until the active bulges have moved down the + // diagonal to make room. The phantom matrix paradigm + // described above helps keep track. + + mtop := max(0, ((ktop-1)-krcol+2)/3) + mbot := min(nbmps, (kbot-krcol)/3) - 1 + m22 := mbot + 1 + bmp22 := (mbot < nbmps-1) && (krcol+3*m22 == kbot-2) + + // Generate reflections to chase the chain right one + // column. (The minimum value of k is ktop-1.) + for m := mtop; m <= mbot; m++ { + k := krcol + 3*m + if k == ktop-1 { + impl.Dlaqr1(3, h[ktop*ldh+ktop:], ldh, + sr[2*m], si[2*m], sr[2*m+1], si[2*m+1], + v[m*ldv:m*ldv+3]) + alpha := v[m*ldv] + _, v[m*ldv] = impl.Dlarfg(3, alpha, v[m*ldv+1:m*ldv+3], 1) + continue + } + beta := h[(k+1)*ldh+k] + v[m*ldv+1] = h[(k+2)*ldh+k] + v[m*ldv+2] = h[(k+3)*ldh+k] + beta, v[m*ldv] = impl.Dlarfg(3, beta, v[m*ldv+1:m*ldv+3], 1) + + // A bulge may collapse because of vigilant deflation or + // destructive underflow. In the underflow case, try the + // two-small-subdiagonals trick to try to reinflate the + // bulge. + if h[(k+3)*ldh+k] != 0 || h[(k+3)*ldh+k+1] != 0 || h[(k+3)*ldh+k+2] == 0 { + // Typical case: not collapsed (yet). + h[(k+1)*ldh+k] = beta + h[(k+2)*ldh+k] = 0 + h[(k+3)*ldh+k] = 0 + continue + } + + // Atypical case: collapsed. Attempt to reintroduce + // ignoring H[k+1,k] and H[k+2,k]. If the fill + // resulting from the new reflector is too large, + // then abandon it. Otherwise, use the new one. + var vt [3]float64 + impl.Dlaqr1(3, h[(k+1)*ldh+k+1:], ldh, sr[2*m], + si[2*m], sr[2*m+1], si[2*m+1], vt[:]) + alpha := vt[0] + _, vt[0] = impl.Dlarfg(3, alpha, vt[1:3], 1) + refsum := vt[0] * (h[(k+1)*ldh+k] + vt[1]*h[(k+2)*ldh+k]) + + dsum := math.Abs(h[k*ldh+k]) + math.Abs(h[(k+1)*ldh+k+1]) + math.Abs(h[(k+2)*ldh+k+2]) + if math.Abs(h[(k+2)*ldh+k]-refsum*vt[1])+math.Abs(refsum*vt[2]) > ulp*dsum { + // Starting a new bulge here would create + // non-negligible fill. Use the old one with + // trepidation. + h[(k+1)*ldh+k] = beta + h[(k+2)*ldh+k] = 0 + h[(k+3)*ldh+k] = 0 + continue + } else { + // Starting a new bulge here would create + // only negligible fill. Replace the old + // reflector with the new one. + h[(k+1)*ldh+k] -= refsum + h[(k+2)*ldh+k] = 0 + h[(k+3)*ldh+k] = 0 + v[m*ldv] = vt[0] + v[m*ldv+1] = vt[1] + v[m*ldv+2] = vt[2] + } + } + + // Generate a 2×2 reflection, if needed. + if bmp22 { + k := krcol + 3*m22 + if k == ktop-1 { + impl.Dlaqr1(2, h[(k+1)*ldh+k+1:], ldh, + sr[2*m22], si[2*m22], sr[2*m22+1], si[2*m22+1], + v[m22*ldv:m22*ldv+2]) + beta := v[m22*ldv] + _, v[m22*ldv] = impl.Dlarfg(2, beta, v[m22*ldv+1:m22*ldv+2], 1) + } else { + beta := h[(k+1)*ldh+k] + v[m22*ldv+1] = h[(k+2)*ldh+k] + beta, v[m22*ldv] = impl.Dlarfg(2, beta, v[m22*ldv+1:m22*ldv+2], 1) + h[(k+1)*ldh+k] = beta + h[(k+2)*ldh+k] = 0 + } + } + + // Multiply H by reflections from the left. + var jbot int + switch { + case accum: + jbot = min(ndcol, kbot) + case wantt: + jbot = n - 1 + default: + jbot = kbot + } + for j := max(ktop, krcol); j <= jbot; j++ { + mend := min(mbot+1, (j-krcol+2)/3) - 1 + for m := mtop; m <= mend; m++ { + k := krcol + 3*m + refsum := v[m*ldv] * (h[(k+1)*ldh+j] + + v[m*ldv+1]*h[(k+2)*ldh+j] + v[m*ldv+2]*h[(k+3)*ldh+j]) + h[(k+1)*ldh+j] -= refsum + h[(k+2)*ldh+j] -= refsum * v[m*ldv+1] + h[(k+3)*ldh+j] -= refsum * v[m*ldv+2] + } + } + if bmp22 { + k := krcol + 3*m22 + for j := max(k+1, ktop); j <= jbot; j++ { + refsum := v[m22*ldv] * (h[(k+1)*ldh+j] + v[m22*ldv+1]*h[(k+2)*ldh+j]) + h[(k+1)*ldh+j] -= refsum + h[(k+2)*ldh+j] -= refsum * v[m22*ldv+1] + } + } + + // Multiply H by reflections from the right. Delay filling in the last row + // until the vigilant deflation check is complete. + var jtop int + switch { + case accum: + jtop = max(ktop, incol) + case wantt: + jtop = 0 + default: + jtop = ktop + } + for m := mtop; m <= mbot; m++ { + if v[m*ldv] == 0 { + continue + } + k := krcol + 3*m + for j := jtop; j <= min(kbot, k+3); j++ { + refsum := v[m*ldv] * (h[j*ldh+k+1] + + v[m*ldv+1]*h[j*ldh+k+2] + v[m*ldv+2]*h[j*ldh+k+3]) + h[j*ldh+k+1] -= refsum + h[j*ldh+k+2] -= refsum * v[m*ldv+1] + h[j*ldh+k+3] -= refsum * v[m*ldv+2] + } + if accum { + // Accumulate U. (If necessary, update Z later with with an + // efficient matrix-matrix multiply.) + kms := k - incol + for j := max(0, ktop-incol-1); j < kdu; j++ { + refsum := v[m*ldv] * (u[j*ldu+kms] + + v[m*ldv+1]*u[j*ldu+kms+1] + v[m*ldv+2]*u[j*ldu+kms+2]) + u[j*ldu+kms] -= refsum + u[j*ldu+kms+1] -= refsum * v[m*ldv+1] + u[j*ldu+kms+2] -= refsum * v[m*ldv+2] + } + } else if wantz { + // U is not accumulated, so update Z now by multiplying by + // reflections from the right. + for j := iloz; j <= ihiz; j++ { + refsum := v[m*ldv] * (z[j*ldz+k+1] + + v[m*ldv+1]*z[j*ldz+k+2] + v[m*ldv+2]*z[j*ldz+k+3]) + z[j*ldz+k+1] -= refsum + z[j*ldz+k+2] -= refsum * v[m*ldv+1] + z[j*ldz+k+3] -= refsum * v[m*ldv+2] + } + } + } + + // Special case: 2×2 reflection (if needed). + if bmp22 && v[m22*ldv] != 0 { + k := krcol + 3*m22 + for j := jtop; j <= min(kbot, k+3); j++ { + refsum := v[m22*ldv] * (h[j*ldh+k+1] + v[m22*ldv+1]*h[j*ldh+k+2]) + h[j*ldh+k+1] -= refsum + h[j*ldh+k+2] -= refsum * v[m22*ldv+1] + } + if accum { + kms := k - incol + for j := max(0, ktop-incol-1); j < kdu; j++ { + refsum := v[m22*ldv] * (u[j*ldu+kms] + v[m22*ldv+1]*u[j*ldu+kms+1]) + u[j*ldu+kms] -= refsum + u[j*ldu+kms+1] -= refsum * v[m22*ldv+1] + } + } else if wantz { + for j := iloz; j <= ihiz; j++ { + refsum := v[m22*ldv] * (z[j*ldz+k+1] + v[m22*ldv+1]*z[j*ldz+k+2]) + z[j*ldz+k+1] -= refsum + z[j*ldz+k+2] -= refsum * v[m22*ldv+1] + } + } + } + + // Vigilant deflation check. + mstart := mtop + if krcol+3*mstart < ktop { + mstart++ + } + mend := mbot + if bmp22 { + mend++ + } + if krcol == kbot-2 { + mend++ + } + for m := mstart; m <= mend; m++ { + k := min(kbot-1, krcol+3*m) + + // The following convergence test requires that the tradition + // small-compared-to-nearby-diagonals criterion and the Ahues & + // Tisseur (LAWN 122, 1997) criteria both be satisfied. The latter + // improves accuracy in some examples. Falling back on an alternate + // convergence criterion when tst1 or tst2 is zero (as done here) is + // traditional but probably unnecessary. + + if h[(k+1)*ldh+k] == 0 { + continue + } + tst1 := math.Abs(h[k*ldh+k]) + math.Abs(h[(k+1)*ldh+k+1]) + if tst1 == 0 { + if k >= ktop+1 { + tst1 += math.Abs(h[k*ldh+k-1]) + } + if k >= ktop+2 { + tst1 += math.Abs(h[k*ldh+k-2]) + } + if k >= ktop+3 { + tst1 += math.Abs(h[k*ldh+k-3]) + } + if k <= kbot-2 { + tst1 += math.Abs(h[(k+2)*ldh+k+1]) + } + if k <= kbot-3 { + tst1 += math.Abs(h[(k+3)*ldh+k+1]) + } + if k <= kbot-4 { + tst1 += math.Abs(h[(k+4)*ldh+k+1]) + } + } + if math.Abs(h[(k+1)*ldh+k]) <= math.Max(smlnum, ulp*tst1) { + h12 := math.Max(math.Abs(h[(k+1)*ldh+k]), math.Abs(h[k*ldh+k+1])) + h21 := math.Min(math.Abs(h[(k+1)*ldh+k]), math.Abs(h[k*ldh+k+1])) + h11 := math.Max(math.Abs(h[(k+1)*ldh+k+1]), math.Abs(h[k*ldh+k]-h[(k+1)*ldh+k+1])) + h22 := math.Min(math.Abs(h[(k+1)*ldh+k+1]), math.Abs(h[k*ldh+k]-h[(k+1)*ldh+k+1])) + scl := h11 + h12 + tst2 := h22 * (h11 / scl) + if tst2 == 0 || h21*(h12/scl) <= math.Max(smlnum, ulp*tst2) { + h[(k+1)*ldh+k] = 0 + } + } + } + + // Fill in the last row of each bulge. + mend = min(nbmps, (kbot-krcol-1)/3) - 1 + for m := mtop; m <= mend; m++ { + k := krcol + 3*m + refsum := v[m*ldv] * v[m*ldv+2] * h[(k+4)*ldh+k+3] + h[(k+4)*ldh+k+1] = -refsum + h[(k+4)*ldh+k+2] = -refsum * v[m*ldv+1] + h[(k+4)*ldh+k+3] -= refsum * v[m*ldv+2] + } + } + + // Use U (if accumulated) to update far-from-diagonal entries in H. + // If required, use U to update Z as well. + if !accum { + continue + } + var jtop, jbot int + if wantt { + jtop = 0 + jbot = n - 1 + } else { + jtop = ktop + jbot = kbot + } + bi := blas64.Implementation() + if !blk22 || incol < ktop || kbot < ndcol || ns <= 2 { + // Updates not exploiting the 2×2 block structure of U. k0 and nu keep track + // of the location and size of U in the special cases of introducing bulges + // and chasing bulges off the bottom. In these special cases and in case the + // number of shifts is ns = 2, there is no 2×2 block structure to exploit. + + k0 := max(0, ktop-incol-1) + nu := kdu - max(0, ndcol-kbot) - k0 + + // Horizontal multiply. + for jcol := min(ndcol, kbot) + 1; jcol <= jbot; jcol += nh { + jlen := min(nh, jbot-jcol+1) + bi.Dgemm(blas.Trans, blas.NoTrans, nu, jlen, nu, + 1, u[k0*ldu+k0:], ldu, + h[(incol+k0+1)*ldh+jcol:], ldh, + 0, wh, ldwh) + impl.Dlacpy(blas.All, nu, jlen, wh, ldwh, h[(incol+k0+1)*ldh+jcol:], ldh) + } + + // Vertical multiply. + for jrow := jtop; jrow <= max(ktop, incol)-1; jrow += nv { + jlen := min(nv, max(ktop, incol)-jrow) + bi.Dgemm(blas.NoTrans, blas.NoTrans, jlen, nu, nu, + 1, h[jrow*ldh+incol+k0+1:], ldh, + u[k0*ldu+k0:], ldu, + 0, wv, ldwv) + impl.Dlacpy(blas.All, jlen, nu, wv, ldwv, h[jrow*ldh+incol+k0+1:], ldh) + } + + // Z multiply (also vertical). + if wantz { + for jrow := iloz; jrow <= ihiz; jrow += nv { + jlen := min(nv, ihiz-jrow+1) + bi.Dgemm(blas.NoTrans, blas.NoTrans, jlen, nu, nu, + 1, z[jrow*ldz+incol+k0+1:], ldz, + u[k0*ldu+k0:], ldu, + 0, wv, ldwv) + impl.Dlacpy(blas.All, jlen, nu, wv, ldwv, z[jrow*ldz+incol+k0+1:], ldz) + } + } + + continue + } + + // Updates exploiting U's 2×2 block structure. + + // i2, i4, j2, j4 are the last rows and columns of the blocks. + i2 := (kdu + 1) / 2 + i4 := kdu + j2 := i4 - i2 + j4 := kdu + + // kzs and knz deal with the band of zeros along the diagonal of one of the + // triangular blocks. + kzs := (j4 - j2) - (ns + 1) + knz := ns + 1 + + // Horizontal multiply. + for jcol := min(ndcol, kbot) + 1; jcol <= jbot; jcol += nh { + jlen := min(nh, jbot-jcol+1) + + // Copy bottom of H to top+kzs of scratch (the first kzs + // rows get multiplied by zero). + impl.Dlacpy(blas.All, knz, jlen, h[(incol+1+j2)*ldh+jcol:], ldh, wh[kzs*ldwh:], ldwh) + + // Multiply by U21^T. + impl.Dlaset(blas.All, kzs, jlen, 0, 0, wh, ldwh) + bi.Dtrmm(blas.Left, blas.Upper, blas.Trans, blas.NonUnit, knz, jlen, + 1, u[j2*ldu+kzs:], ldu, wh[kzs*ldwh:], ldwh) + + // Multiply top of H by U11^T. + bi.Dgemm(blas.Trans, blas.NoTrans, i2, jlen, j2, + 1, u, ldu, h[(incol+1)*ldh+jcol:], ldh, + 1, wh, ldwh) + + // Copy top of H to bottom of WH. + impl.Dlacpy(blas.All, j2, jlen, h[(incol+1)*ldh+jcol:], ldh, wh[i2*ldwh:], ldwh) + + // Multiply by U21^T. + bi.Dtrmm(blas.Left, blas.Lower, blas.Trans, blas.NonUnit, j2, jlen, + 1, u[i2:], ldu, wh[i2*ldwh:], ldwh) + + // Multiply by U22. + bi.Dgemm(blas.Trans, blas.NoTrans, i4-i2, jlen, j4-j2, + 1, u[j2*ldu+i2:], ldu, h[(incol+1+j2)*ldh+jcol:], ldh, + 1, wh[i2*ldwh:], ldwh) + + // Copy it back. + impl.Dlacpy(blas.All, kdu, jlen, wh, ldwh, h[(incol+1)*ldh+jcol:], ldh) + } + + // Vertical multiply. + for jrow := jtop; jrow <= max(incol, ktop)-1; jrow += nv { + jlen := min(nv, max(incol, ktop)-jrow) + + // Copy right of H to scratch (the first kzs columns get multiplied + // by zero). + impl.Dlacpy(blas.All, jlen, knz, h[jrow*ldh+incol+1+j2:], ldh, wv[kzs:], ldwv) + + // Multiply by U21. + impl.Dlaset(blas.All, jlen, kzs, 0, 0, wv, ldwv) + bi.Dtrmm(blas.Right, blas.Upper, blas.NoTrans, blas.NonUnit, jlen, knz, + 1, u[j2*ldu+kzs:], ldu, wv[kzs:], ldwv) + + // Multiply by U11. + bi.Dgemm(blas.NoTrans, blas.NoTrans, jlen, i2, j2, + 1, h[jrow*ldh+incol+1:], ldh, u, ldu, + 1, wv, ldwv) + + // Copy left of H to right of scratch. + impl.Dlacpy(blas.All, jlen, j2, h[jrow*ldh+incol+1:], ldh, wv[i2:], ldwv) + + // Multiply by U21. + bi.Dtrmm(blas.Right, blas.Lower, blas.NoTrans, blas.NonUnit, jlen, i4-i2, + 1, u[i2:], ldu, wv[i2:], ldwv) + + // Multiply by U22. + bi.Dgemm(blas.NoTrans, blas.NoTrans, jlen, i4-i2, j4-j2, + 1, h[jrow*ldh+incol+1+j2:], ldh, u[j2*ldu+i2:], ldu, + 1, wv[i2:], ldwv) + + // Copy it back. + impl.Dlacpy(blas.All, jlen, kdu, wv, ldwv, h[jrow*ldh+incol+1:], ldh) + } + + if !wantz { + continue + } + // Multiply Z (also vertical). + for jrow := iloz; jrow <= ihiz; jrow += nv { + jlen := min(nv, ihiz-jrow+1) + + // Copy right of Z to left of scratch (first kzs columns get + // multiplied by zero). + impl.Dlacpy(blas.All, jlen, knz, z[jrow*ldz+incol+1+j2:], ldz, wv[kzs:], ldwv) + + // Multiply by U12. + impl.Dlaset(blas.All, jlen, kzs, 0, 0, wv, ldwv) + bi.Dtrmm(blas.Right, blas.Upper, blas.NoTrans, blas.NonUnit, jlen, knz, + 1, u[j2*ldu+kzs:], ldu, wv[kzs:], ldwv) + + // Multiply by U11. + bi.Dgemm(blas.NoTrans, blas.NoTrans, jlen, i2, j2, + 1, z[jrow*ldz+incol+1:], ldz, u, ldu, + 1, wv, ldwv) + + // Copy left of Z to right of scratch. + impl.Dlacpy(blas.All, jlen, j2, z[jrow*ldz+incol+1:], ldz, wv[i2:], ldwv) + + // Multiply by U21. + bi.Dtrmm(blas.Right, blas.Lower, blas.NoTrans, blas.NonUnit, jlen, i4-i2, + 1, u[i2:], ldu, wv[i2:], ldwv) + + // Multiply by U22. + bi.Dgemm(blas.NoTrans, blas.NoTrans, jlen, i4-i2, j4-j2, + 1, z[jrow*ldz+incol+1+j2:], ldz, u[j2*ldu+i2:], ldu, + 1, wv[i2:], ldwv) + + // Copy the result back to Z. + impl.Dlacpy(blas.All, jlen, kdu, wv, ldwv, z[jrow*ldz+incol+1:], ldz) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlarf.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarf.go new file mode 100644 index 00000000..01f50eae --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarf.go @@ -0,0 +1,83 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlarf applies an elementary reflector to a general rectangular matrix c. +// This computes +// c = h * c if side == Left +// c = c * h if side == right +// where +// h = 1 - tau * v * v^T +// and c is an m * n matrix. +// +// work is temporary storage of length at least m if side == Left and at least +// n if side == Right. This function will panic if this length requirement is not met. +// +// Dlarf is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlarf(side blas.Side, m, n int, v []float64, incv int, tau float64, c []float64, ldc int, work []float64) { + applyleft := side == blas.Left + if (applyleft && len(work) < n) || (!applyleft && len(work) < m) { + panic(badWork) + } + checkMatrix(m, n, c, ldc) + + // v has length m if applyleft and n otherwise. + lenV := n + if applyleft { + lenV = m + } + + checkVector(lenV, v, incv) + + lastv := 0 // last non-zero element of v + lastc := 0 // last non-zero row/column of c + if tau != 0 { + var i int + if applyleft { + lastv = m - 1 + } else { + lastv = n - 1 + } + if incv > 0 { + i = lastv * incv + } + + // Look for the last non-zero row in v. + for lastv >= 0 && v[i] == 0 { + lastv-- + i -= incv + } + if applyleft { + // Scan for the last non-zero column in C[0:lastv, :] + lastc = impl.Iladlc(lastv+1, n, c, ldc) + } else { + // Scan for the last non-zero row in C[:, 0:lastv] + lastc = impl.Iladlr(m, lastv+1, c, ldc) + } + } + if lastv == -1 || lastc == -1 { + return + } + // Sometimes 1-indexing is nicer ... + bi := blas64.Implementation() + if applyleft { + // Form H * C + // w[0:lastc+1] = c[1:lastv+1, 1:lastc+1]^T * v[1:lastv+1,1] + bi.Dgemv(blas.Trans, lastv+1, lastc+1, 1, c, ldc, v, incv, 0, work, 1) + // c[0: lastv, 0: lastc] = c[...] - w[0:lastv, 1] * v[1:lastc, 1]^T + bi.Dger(lastv+1, lastc+1, -tau, v, incv, work, 1, c, ldc) + return + } + // Form C*H + // w[0:lastc+1,1] := c[0:lastc+1,0:lastv+1] * v[0:lastv+1,1] + bi.Dgemv(blas.NoTrans, lastc+1, lastv+1, 1, c, ldc, v, incv, 0, work, 1) + // c[0:lastc+1,0:lastv+1] = c[...] - w[0:lastc+1,0] * v[0:lastv+1,0]^T + bi.Dger(lastc+1, lastv+1, -tau, work, 1, v, incv, c, ldc) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfb.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfb.go new file mode 100644 index 00000000..bfafd360 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfb.go @@ -0,0 +1,431 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dlarfb applies a block reflector to a matrix. +// +// In the call to Dlarfb, the mxn c is multiplied by the implicitly defined matrix h as follows: +// c = h * c if side == Left and trans == NoTrans +// c = c * h if side == Right and trans == NoTrans +// c = h^T * c if side == Left and trans == Trans +// c = c * h^T if side == Right and trans == Trans +// h is a product of elementary reflectors. direct sets the direction of multiplication +// h = h_1 * h_2 * ... * h_k if direct == Forward +// h = h_k * h_k-1 * ... * h_1 if direct == Backward +// The combination of direct and store defines the orientation of the elementary +// reflectors. In all cases the ones on the diagonal are implicitly represented. +// +// If direct == lapack.Forward and store == lapack.ColumnWise +// V = [ 1 ] +// [v1 1 ] +// [v1 v2 1] +// [v1 v2 v3] +// [v1 v2 v3] +// If direct == lapack.Forward and store == lapack.RowWise +// V = [ 1 v1 v1 v1 v1] +// [ 1 v2 v2 v2] +// [ 1 v3 v3] +// If direct == lapack.Backward and store == lapack.ColumnWise +// V = [v1 v2 v3] +// [v1 v2 v3] +// [ 1 v2 v3] +// [ 1 v3] +// [ 1] +// If direct == lapack.Backward and store == lapack.RowWise +// V = [v1 v1 1 ] +// [v2 v2 v2 1 ] +// [v3 v3 v3 v3 1] +// An elementary reflector can be explicitly constructed by extracting the +// corresponding elements of v, placing a 1 where the diagonal would be, and +// placing zeros in the remaining elements. +// +// t is a k×k matrix containing the block reflector, and this function will panic +// if t is not of sufficient size. See Dlarft for more information. +// +// work is a temporary storage matrix with stride ldwork. +// work must be of size at least n×k side == Left and m×k if side == Right, and +// this function will panic if this size is not met. +// +// Dlarfb is an internal routine. It is exported for testing purposes. +func (Implementation) Dlarfb(side blas.Side, trans blas.Transpose, direct lapack.Direct, store lapack.StoreV, m, n, k int, v []float64, ldv int, t []float64, ldt int, c []float64, ldc int, work []float64, ldwork int) { + if side != blas.Left && side != blas.Right { + panic(badSide) + } + if trans != blas.Trans && trans != blas.NoTrans { + panic(badTrans) + } + if direct != lapack.Forward && direct != lapack.Backward { + panic(badDirect) + } + if store != lapack.ColumnWise && store != lapack.RowWise { + panic(badStore) + } + checkMatrix(m, n, c, ldc) + if k < 0 { + panic(kLT0) + } + checkMatrix(k, k, t, ldt) + nv := m + nw := n + if side == blas.Right { + nv = n + nw = m + } + if store == lapack.ColumnWise { + checkMatrix(nv, k, v, ldv) + } else { + checkMatrix(k, nv, v, ldv) + } + checkMatrix(nw, k, work, ldwork) + + if m == 0 || n == 0 { + return + } + + bi := blas64.Implementation() + + transt := blas.Trans + if trans == blas.Trans { + transt = blas.NoTrans + } + // TODO(btracey): This follows the original Lapack code where the + // elements are copied into the columns of the working array. The + // loops should go in the other direction so the data is written + // into the rows of work so the copy is not strided. A bigger change + // would be to replace work with work^T, but benchmarks would be + // needed to see if the change is merited. + if store == lapack.ColumnWise { + if direct == lapack.Forward { + // V1 is the first k rows of C. V2 is the remaining rows. + if side == blas.Left { + // W = C^T V = C1^T V1 + C2^T V2 (stored in work). + + // W = C1. + for j := 0; j < k; j++ { + bi.Dcopy(n, c[j*ldc:], 1, work[j:], ldwork) + } + // W = W * V1. + bi.Dtrmm(blas.Right, blas.Lower, blas.NoTrans, blas.Unit, + n, k, 1, + v, ldv, + work, ldwork) + if m > k { + // W = W + C2^T V2. + bi.Dgemm(blas.Trans, blas.NoTrans, n, k, m-k, + 1, c[k*ldc:], ldc, v[k*ldv:], ldv, + 1, work, ldwork) + } + // W = W * T^T or W * T. + bi.Dtrmm(blas.Right, blas.Upper, transt, blas.NonUnit, n, k, + 1, t, ldt, + work, ldwork) + // C -= V * W^T. + if m > k { + // C2 -= V2 * W^T. + bi.Dgemm(blas.NoTrans, blas.Trans, m-k, n, k, + -1, v[k*ldv:], ldv, work, ldwork, + 1, c[k*ldc:], ldc) + } + // W *= V1^T. + bi.Dtrmm(blas.Right, blas.Lower, blas.Trans, blas.Unit, n, k, + 1, v, ldv, + work, ldwork) + // C1 -= W^T. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < n; i++ { + for j := 0; j < k; j++ { + c[j*ldc+i] -= work[i*ldwork+j] + } + } + return + } + // Form C = C * H or C * H^T, where C = (C1 C2). + + // W = C1. + for i := 0; i < k; i++ { + bi.Dcopy(m, c[i:], ldc, work[i:], ldwork) + } + // W *= V1. + bi.Dtrmm(blas.Right, blas.Lower, blas.NoTrans, blas.Unit, m, k, + 1, v, ldv, + work, ldwork) + if n > k { + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, k, n-k, + 1, c[k:], ldc, v[k*ldv:], ldv, + 1, work, ldwork) + } + // W *= T or T^T. + bi.Dtrmm(blas.Right, blas.Upper, trans, blas.NonUnit, m, k, + 1, t, ldt, + work, ldwork) + if n > k { + bi.Dgemm(blas.NoTrans, blas.Trans, m, n-k, k, + -1, work, ldwork, v[k*ldv:], ldv, + 1, c[k:], ldc) + } + // C -= W * V^T. + bi.Dtrmm(blas.Right, blas.Lower, blas.Trans, blas.Unit, m, k, + 1, v, ldv, + work, ldwork) + // C -= W. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + c[i*ldc+j] -= work[i*ldwork+j] + } + } + return + } + // V = (V1) + // = (V2) (last k rows) + // Where V2 is unit upper triangular. + if side == blas.Left { + // Form H * C or + // W = C^T V. + + // W = C2^T. + for j := 0; j < k; j++ { + bi.Dcopy(n, c[(m-k+j)*ldc:], 1, work[j:], ldwork) + } + // W *= V2. + bi.Dtrmm(blas.Right, blas.Upper, blas.NoTrans, blas.Unit, n, k, + 1, v[(m-k)*ldv:], ldv, + work, ldwork) + if m > k { + // W += C1^T * V1. + bi.Dgemm(blas.Trans, blas.NoTrans, n, k, m-k, + 1, c, ldc, v, ldv, + 1, work, ldwork) + } + // W *= T or T^T. + bi.Dtrmm(blas.Right, blas.Lower, transt, blas.NonUnit, n, k, + 1, t, ldt, + work, ldwork) + // C -= V * W^T. + if m > k { + bi.Dgemm(blas.NoTrans, blas.Trans, m-k, n, k, + -1, v, ldv, work, ldwork, + 1, c, ldc) + } + // W *= V2^T. + bi.Dtrmm(blas.Right, blas.Upper, blas.Trans, blas.Unit, n, k, + 1, v[(m-k)*ldv:], ldv, + work, ldwork) + // C2 -= W^T. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < n; i++ { + for j := 0; j < k; j++ { + c[(m-k+j)*ldc+i] -= work[i*ldwork+j] + } + } + return + } + // Form C * H or C * H^T where C = (C1 C2). + // W = C * V. + + // W = C2. + for j := 0; j < k; j++ { + bi.Dcopy(m, c[n-k+j:], ldc, work[j:], ldwork) + } + + // W = W * V2. + bi.Dtrmm(blas.Right, blas.Upper, blas.NoTrans, blas.Unit, m, k, + 1, v[(n-k)*ldv:], ldv, + work, ldwork) + if n > k { + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, k, n-k, + 1, c, ldc, v, ldv, + 1, work, ldwork) + } + // W *= T or T^T. + bi.Dtrmm(blas.Right, blas.Lower, trans, blas.NonUnit, m, k, + 1, t, ldt, + work, ldwork) + // C -= W * V^T. + if n > k { + // C1 -= W * V1^T. + bi.Dgemm(blas.NoTrans, blas.Trans, m, n-k, k, + -1, work, ldwork, v, ldv, + 1, c, ldc) + } + // W *= V2^T. + bi.Dtrmm(blas.Right, blas.Upper, blas.Trans, blas.Unit, m, k, + 1, v[(n-k)*ldv:], ldv, + work, ldwork) + // C2 -= W. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + c[i*ldc+n-k+j] -= work[i*ldwork+j] + } + } + return + } + // Store = Rowwise. + if direct == lapack.Forward { + // V = (V1 V2) where v1 is unit upper triangular. + if side == blas.Left { + // Form H * C or H^T * C where C = (C1; C2). + // W = C^T * V^T. + + // W = C1^T. + for j := 0; j < k; j++ { + bi.Dcopy(n, c[j*ldc:], 1, work[j:], ldwork) + } + // W *= V1^T. + bi.Dtrmm(blas.Right, blas.Upper, blas.Trans, blas.Unit, n, k, + 1, v, ldv, + work, ldwork) + if m > k { + bi.Dgemm(blas.Trans, blas.Trans, n, k, m-k, + 1, c[k*ldc:], ldc, v[k:], ldv, + 1, work, ldwork) + } + // W *= T or T^T. + bi.Dtrmm(blas.Right, blas.Upper, transt, blas.NonUnit, n, k, + 1, t, ldt, + work, ldwork) + // C -= V^T * W^T. + if m > k { + bi.Dgemm(blas.Trans, blas.Trans, m-k, n, k, + -1, v[k:], ldv, work, ldwork, + 1, c[k*ldc:], ldc) + } + // W *= V1. + bi.Dtrmm(blas.Right, blas.Upper, blas.NoTrans, blas.Unit, n, k, + 1, v, ldv, + work, ldwork) + // C1 -= W^T. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < n; i++ { + for j := 0; j < k; j++ { + c[j*ldc+i] -= work[i*ldwork+j] + } + } + return + } + // Form C * H or C * H^T where C = (C1 C2). + // W = C * V^T. + + // W = C1. + for j := 0; j < k; j++ { + bi.Dcopy(m, c[j:], ldc, work[j:], ldwork) + } + // W *= V1^T. + bi.Dtrmm(blas.Right, blas.Upper, blas.Trans, blas.Unit, m, k, + 1, v, ldv, + work, ldwork) + if n > k { + bi.Dgemm(blas.NoTrans, blas.Trans, m, k, n-k, + 1, c[k:], ldc, v[k:], ldv, + 1, work, ldwork) + } + // W *= T or T^T. + bi.Dtrmm(blas.Right, blas.Upper, trans, blas.NonUnit, m, k, + 1, t, ldt, + work, ldwork) + // C -= W * V. + if n > k { + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n-k, k, + -1, work, ldwork, v[k:], ldv, + 1, c[k:], ldc) + } + // W *= V1. + bi.Dtrmm(blas.Right, blas.Upper, blas.NoTrans, blas.Unit, m, k, + 1, v, ldv, + work, ldwork) + // C1 -= W. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + c[i*ldc+j] -= work[i*ldwork+j] + } + } + return + } + // V = (V1 V2) where V2 is the last k columns and is lower unit triangular. + if side == blas.Left { + // Form H * C or H^T C where C = (C1 ; C2). + // W = C^T * V^T. + + // W = C2^T. + for j := 0; j < k; j++ { + bi.Dcopy(n, c[(m-k+j)*ldc:], 1, work[j:], ldwork) + } + // W *= V2^T. + bi.Dtrmm(blas.Right, blas.Lower, blas.Trans, blas.Unit, n, k, + 1, v[m-k:], ldv, + work, ldwork) + if m > k { + bi.Dgemm(blas.Trans, blas.Trans, n, k, m-k, + 1, c, ldc, v, ldv, + 1, work, ldwork) + } + // W *= T or T^T. + bi.Dtrmm(blas.Right, blas.Lower, transt, blas.NonUnit, n, k, + 1, t, ldt, + work, ldwork) + // C -= V^T * W^T. + if m > k { + bi.Dgemm(blas.Trans, blas.Trans, m-k, n, k, + -1, v, ldv, work, ldwork, + 1, c, ldc) + } + // W *= V2. + bi.Dtrmm(blas.Right, blas.Lower, blas.NoTrans, blas.Unit, n, k, + 1, v[m-k:], ldv, + work, ldwork) + // C2 -= W^T. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < n; i++ { + for j := 0; j < k; j++ { + c[(m-k+j)*ldc+i] -= work[i*ldwork+j] + } + } + return + } + // Form C * H or C * H^T where C = (C1 C2). + // W = C * V^T. + // W = C2. + for j := 0; j < k; j++ { + bi.Dcopy(m, c[n-k+j:], ldc, work[j:], ldwork) + } + // W *= V2^T. + bi.Dtrmm(blas.Right, blas.Lower, blas.Trans, blas.Unit, m, k, + 1, v[n-k:], ldv, + work, ldwork) + if n > k { + bi.Dgemm(blas.NoTrans, blas.Trans, m, k, n-k, + 1, c, ldc, v, ldv, + 1, work, ldwork) + } + // W *= T or T^T. + bi.Dtrmm(blas.Right, blas.Lower, trans, blas.NonUnit, m, k, + 1, t, ldt, + work, ldwork) + // C -= W * V. + if n > k { + bi.Dgemm(blas.NoTrans, blas.NoTrans, m, n-k, k, + -1, work, ldwork, v, ldv, + 1, c, ldc) + } + // W *= V2. + bi.Dtrmm(blas.Right, blas.Lower, blas.NoTrans, blas.Unit, m, k, + 1, v[n-k:], ldv, + work, ldwork) + // C1 -= W. + // TODO(btracey): This should use blas.Axpy. + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + c[i*ldc+n-k+j] -= work[i*ldwork+j] + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfg.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfg.go new file mode 100644 index 00000000..09977e50 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfg.go @@ -0,0 +1,62 @@ +// 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/blas64" +) + +// Dlarfg generates an elementary reflector for a Householder matrix. It creates +// a real elementary reflector of order n such that +// H * (alpha) = (beta) +// ( x) ( 0) +// H^T * H = I +// H is represented in the form +// H = 1 - tau * (1; v) * (1 v^T) +// where tau is a real scalar. +// +// On entry, x contains the vector x, on exit it contains v. +// +// Dlarfg is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlarfg(n int, alpha float64, x []float64, incX int) (beta, tau float64) { + if n < 0 { + panic(nLT0) + } + if n <= 1 { + return alpha, 0 + } + checkVector(n-1, x, incX) + bi := blas64.Implementation() + xnorm := bi.Dnrm2(n-1, x, incX) + if xnorm == 0 { + return alpha, 0 + } + beta = -math.Copysign(impl.Dlapy2(alpha, xnorm), alpha) + safmin := dlamchS / dlamchE + knt := 0 + if math.Abs(beta) < safmin { + // xnorm and beta may be inaccurate, scale x and recompute. + rsafmn := 1 / safmin + for { + knt++ + bi.Dscal(n-1, rsafmn, x, incX) + beta *= rsafmn + alpha *= rsafmn + if math.Abs(beta) >= safmin { + break + } + } + xnorm = bi.Dnrm2(n-1, x, incX) + beta = -math.Copysign(impl.Dlapy2(alpha, xnorm), alpha) + } + tau = (beta - alpha) / beta + bi.Dscal(n-1, 1/(alpha-beta), x, incX) + for j := 0; j < knt; j++ { + beta *= safmin + } + return beta, tau +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlarft.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarft.go new file mode 100644 index 00000000..0a244a48 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarft.go @@ -0,0 +1,150 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dlarft forms the triangular factor T of a block reflector H, storing the answer +// in t. +// H = I - V * T * V^T if store == lapack.ColumnWise +// H = I - V^T * T * V if store == lapack.RowWise +// H is defined by a product of the elementary reflectors where +// H = H_0 * H_1 * ... * H_{k-1} if direct == lapack.Forward +// H = H_{k-1} * ... * H_1 * H_0 if direct == lapack.Backward +// +// t is a k×k triangular matrix. t is upper triangular if direct = lapack.Forward +// and lower triangular otherwise. This function will panic if t is not of +// sufficient size. +// +// store describes the storage of the elementary reflectors in v. Please see +// Dlarfb for a description of layout. +// +// tau contains the scalar factors of the elementary reflectors H_i. +// +// Dlarft is an internal routine. It is exported for testing purposes. +func (Implementation) Dlarft(direct lapack.Direct, store lapack.StoreV, n, k int, + v []float64, ldv int, tau []float64, t []float64, ldt int) { + if n == 0 { + return + } + if n < 0 || k < 0 { + panic(negDimension) + } + if direct != lapack.Forward && direct != lapack.Backward { + panic(badDirect) + } + if store != lapack.RowWise && store != lapack.ColumnWise { + panic(badStore) + } + if len(tau) < k { + panic(badTau) + } + checkMatrix(k, k, t, ldt) + bi := blas64.Implementation() + // TODO(btracey): There are a number of minor obvious loop optimizations here. + // TODO(btracey): It may be possible to rearrange some of the code so that + // index of 1 is more common in the Dgemv. + if direct == lapack.Forward { + prevlastv := n - 1 + for i := 0; i < k; i++ { + prevlastv = max(i, prevlastv) + if tau[i] == 0 { + for j := 0; j <= i; j++ { + t[j*ldt+i] = 0 + } + continue + } + var lastv int + if store == lapack.ColumnWise { + // skip trailing zeros + for lastv = n - 1; lastv >= i+1; lastv-- { + if v[lastv*ldv+i] != 0 { + break + } + } + for j := 0; j < i; j++ { + t[j*ldt+i] = -tau[i] * v[i*ldv+j] + } + j := min(lastv, prevlastv) + bi.Dgemv(blas.Trans, j-i, i, + -tau[i], v[(i+1)*ldv:], ldv, v[(i+1)*ldv+i:], ldv, + 1, t[i:], ldt) + } else { + for lastv = n - 1; lastv >= i+1; lastv-- { + if v[i*ldv+lastv] != 0 { + break + } + } + for j := 0; j < i; j++ { + t[j*ldt+i] = -tau[i] * v[j*ldv+i] + } + j := min(lastv, prevlastv) + bi.Dgemv(blas.NoTrans, i, j-i, + -tau[i], v[i+1:], ldv, v[i*ldv+i+1:], 1, + 1, t[i:], ldt) + } + bi.Dtrmv(blas.Upper, blas.NoTrans, blas.NonUnit, i, t, ldt, t[i:], ldt) + t[i*ldt+i] = tau[i] + if i > 1 { + prevlastv = max(prevlastv, lastv) + } else { + prevlastv = lastv + } + } + return + } + prevlastv := 0 + for i := k - 1; i >= 0; i-- { + if tau[i] == 0 { + for j := i; j < k; j++ { + t[j*ldt+i] = 0 + } + continue + } + var lastv int + if i < k-1 { + if store == lapack.ColumnWise { + for lastv = 0; lastv < i; lastv++ { + if v[lastv*ldv+i] != 0 { + break + } + } + for j := i + 1; j < k; j++ { + t[j*ldt+i] = -tau[i] * v[(n-k+i)*ldv+j] + } + j := max(lastv, prevlastv) + bi.Dgemv(blas.Trans, n-k+i-j, k-i-1, + -tau[i], v[j*ldv+i+1:], ldv, v[j*ldv+i:], ldv, + 1, t[(i+1)*ldt+i:], ldt) + } else { + for lastv = 0; lastv < i; lastv++ { + if v[i*ldv+lastv] != 0 { + break + } + } + for j := i + 1; j < k; j++ { + t[j*ldt+i] = -tau[i] * v[j*ldv+n-k+i] + } + j := max(lastv, prevlastv) + bi.Dgemv(blas.NoTrans, k-i-1, n-k+i-j, + -tau[i], v[(i+1)*ldv+j:], ldv, v[i*ldv+j:], 1, + 1, t[(i+1)*ldt+i:], ldt) + } + bi.Dtrmv(blas.Lower, blas.NoTrans, blas.NonUnit, k-i-1, + t[(i+1)*ldt+i+1:], ldt, + t[(i+1)*ldt+i:], ldt) + if i > 0 { + prevlastv = min(prevlastv, lastv) + } else { + prevlastv = lastv + } + } + t[i*ldt+i] = tau[i] + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfx.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfx.go new file mode 100644 index 00000000..5dc00f03 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlarfx.go @@ -0,0 +1,535 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas" + +// Dlarfx applies an elementary reflector H to a real m×n matrix C, from either +// the left or the right, with loop unrolling when the reflector has order less +// than 11. +// +// H is represented in the form +// H = I - tau * v * v^T, +// where tau is a real scalar and v is a real vector. If tau = 0, then H is +// taken to be the identity matrix. +// +// v must have length equal to m if side == blas.Left, and equal to n if side == +// blas.Right, otherwise Dlarfx will panic. +// +// c and ldc represent the m×n matrix C. On return, C is overwritten by the +// matrix H * C if side == blas.Left, or C * H if side == blas.Right. +// +// work must have length at least n if side == blas.Left, and at least m if side +// == blas.Right, otherwise Dlarfx will panic. work is not referenced if H has +// order < 11. +// +// Dlarfx is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlarfx(side blas.Side, m, n int, v []float64, tau float64, c []float64, ldc int, work []float64) { + checkMatrix(m, n, c, ldc) + switch side { + case blas.Left: + checkVector(m, v, 1) + if m > 10 && len(work) < n { + panic(badWork) + } + case blas.Right: + checkVector(n, v, 1) + if n > 10 && len(work) < m { + panic(badWork) + } + default: + panic(badSide) + } + + if tau == 0 { + return + } + + if side == blas.Left { + // Form H * C, where H has order m. + switch m { + default: // Code for general m. + impl.Dlarf(side, m, n, v, 1, tau, c, ldc, work) + return + + case 0: // No-op for zero size matrix. + return + + case 1: // Special code for 1×1 Householder matrix. + t0 := 1 - tau*v[0]*v[0] + for j := 0; j < n; j++ { + c[j] *= t0 + } + return + + case 2: // Special code for 2×2 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + } + return + + case 3: // Special code for 3×3 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + } + return + + case 4: // Special code for 4×4 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + c[3*ldc+j] -= sum * t3 + } + return + + case 5: // Special code for 5×5 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + c[3*ldc+j] -= sum * t3 + c[4*ldc+j] -= sum * t4 + } + return + + case 6: // Special code for 6×6 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + + v5*c[5*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + c[3*ldc+j] -= sum * t3 + c[4*ldc+j] -= sum * t4 + c[5*ldc+j] -= sum * t5 + } + return + + case 7: // Special code for 7×7 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + + v5*c[5*ldc+j] + v6*c[6*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + c[3*ldc+j] -= sum * t3 + c[4*ldc+j] -= sum * t4 + c[5*ldc+j] -= sum * t5 + c[6*ldc+j] -= sum * t6 + } + return + + case 8: // Special code for 8×8 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + v7 := v[7] + t7 := tau * v7 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + + v5*c[5*ldc+j] + v6*c[6*ldc+j] + v7*c[7*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + c[3*ldc+j] -= sum * t3 + c[4*ldc+j] -= sum * t4 + c[5*ldc+j] -= sum * t5 + c[6*ldc+j] -= sum * t6 + c[7*ldc+j] -= sum * t7 + } + return + + case 9: // Special code for 9×9 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + v7 := v[7] + t7 := tau * v7 + v8 := v[8] + t8 := tau * v8 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + + v5*c[5*ldc+j] + v6*c[6*ldc+j] + v7*c[7*ldc+j] + v8*c[8*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + c[3*ldc+j] -= sum * t3 + c[4*ldc+j] -= sum * t4 + c[5*ldc+j] -= sum * t5 + c[6*ldc+j] -= sum * t6 + c[7*ldc+j] -= sum * t7 + c[8*ldc+j] -= sum * t8 + } + return + + case 10: // Special code for 10×10 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + v7 := v[7] + t7 := tau * v7 + v8 := v[8] + t8 := tau * v8 + v9 := v[9] + t9 := tau * v9 + for j := 0; j < n; j++ { + sum := v0*c[j] + v1*c[ldc+j] + v2*c[2*ldc+j] + v3*c[3*ldc+j] + v4*c[4*ldc+j] + + v5*c[5*ldc+j] + v6*c[6*ldc+j] + v7*c[7*ldc+j] + v8*c[8*ldc+j] + v9*c[9*ldc+j] + c[j] -= sum * t0 + c[ldc+j] -= sum * t1 + c[2*ldc+j] -= sum * t2 + c[3*ldc+j] -= sum * t3 + c[4*ldc+j] -= sum * t4 + c[5*ldc+j] -= sum * t5 + c[6*ldc+j] -= sum * t6 + c[7*ldc+j] -= sum * t7 + c[8*ldc+j] -= sum * t8 + c[9*ldc+j] -= sum * t9 + } + return + } + } + + // Form C * H, where H has order n. + switch n { + default: // Code for general n. + impl.Dlarf(side, m, n, v, 1, tau, c, ldc, work) + return + + case 0: // No-op for zero size matrix. + return + + case 1: // Special code for 1×1 Householder matrix. + t0 := 1 - tau*v[0]*v[0] + for j := 0; j < m; j++ { + c[j*ldc] *= t0 + } + return + + case 2: // Special code for 2×2 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + } + return + + case 3: // Special code for 3×3 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + } + return + + case 4: // Special code for 4×4 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + cs[3] -= sum * t3 + } + return + + case 5: // Special code for 5×5 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + cs[3] -= sum * t3 + cs[4] -= sum * t4 + } + return + + case 6: // Special code for 6×6 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + v5*cs[5] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + cs[3] -= sum * t3 + cs[4] -= sum * t4 + cs[5] -= sum * t5 + } + return + + case 7: // Special code for 7×7 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + + v5*cs[5] + v6*cs[6] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + cs[3] -= sum * t3 + cs[4] -= sum * t4 + cs[5] -= sum * t5 + cs[6] -= sum * t6 + } + return + + case 8: // Special code for 8×8 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + v7 := v[7] + t7 := tau * v7 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + + v5*cs[5] + v6*cs[6] + v7*cs[7] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + cs[3] -= sum * t3 + cs[4] -= sum * t4 + cs[5] -= sum * t5 + cs[6] -= sum * t6 + cs[7] -= sum * t7 + } + return + + case 9: // Special code for 9×9 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + v7 := v[7] + t7 := tau * v7 + v8 := v[8] + t8 := tau * v8 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + + v5*cs[5] + v6*cs[6] + v7*cs[7] + v8*cs[8] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + cs[3] -= sum * t3 + cs[4] -= sum * t4 + cs[5] -= sum * t5 + cs[6] -= sum * t6 + cs[7] -= sum * t7 + cs[8] -= sum * t8 + } + return + + case 10: // Special code for 10×10 Householder matrix. + v0 := v[0] + t0 := tau * v0 + v1 := v[1] + t1 := tau * v1 + v2 := v[2] + t2 := tau * v2 + v3 := v[3] + t3 := tau * v3 + v4 := v[4] + t4 := tau * v4 + v5 := v[5] + t5 := tau * v5 + v6 := v[6] + t6 := tau * v6 + v7 := v[7] + t7 := tau * v7 + v8 := v[8] + t8 := tau * v8 + v9 := v[9] + t9 := tau * v9 + for j := 0; j < m; j++ { + cs := c[j*ldc:] + sum := v0*cs[0] + v1*cs[1] + v2*cs[2] + v3*cs[3] + v4*cs[4] + + v5*cs[5] + v6*cs[6] + v7*cs[7] + v8*cs[8] + v9*cs[9] + cs[0] -= sum * t0 + cs[1] -= sum * t1 + cs[2] -= sum * t2 + cs[3] -= sum * t3 + cs[4] -= sum * t4 + cs[5] -= sum * t5 + cs[6] -= sum * t6 + cs[7] -= sum * t7 + cs[8] -= sum * t8 + cs[9] -= sum * t9 + } + return + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlartg.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlartg.go new file mode 100644 index 00000000..85aa2064 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlartg.go @@ -0,0 +1,80 @@ +// 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" + +// Dlartg generates a plane rotation so that +// [ cs sn] * [f] = [r] +// [-sn cs] [g] = [0] +// This is a more accurate version of BLAS drotg, with the other differences that +// if g = 0, then cs = 1 and sn = 0, and if f = 0 and g != 0, then cs = 0 and sn = 1. +// If abs(f) > abs(g), cs will be positive. +// +// Dlartg is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlartg(f, g float64) (cs, sn, r float64) { + safmn2 := math.Pow(dlamchB, math.Trunc(math.Log(dlamchS/dlamchE)/math.Log(dlamchB)/2)) + safmx2 := 1 / safmn2 + if g == 0 { + cs = 1 + sn = 0 + r = f + return cs, sn, r + } + if f == 0 { + cs = 0 + sn = 1 + r = g + return cs, sn, r + } + f1 := f + g1 := g + scale := math.Max(math.Abs(f1), math.Abs(g1)) + if scale >= safmx2 { + var count int + for { + count++ + f1 *= safmn2 + g1 *= safmn2 + scale = math.Max(math.Abs(f1), math.Abs(g1)) + if scale < safmx2 { + break + } + } + r = math.Sqrt(f1*f1 + g1*g1) + cs = f1 / r + sn = g1 / r + for i := 0; i < count; i++ { + r *= safmx2 + } + } else if scale <= safmn2 { + var count int + for { + count++ + f1 *= safmx2 + g1 *= safmx2 + scale = math.Max(math.Abs(f1), math.Abs(g1)) + if scale >= safmn2 { + break + } + } + r = math.Sqrt(f1*f1 + g1*g1) + cs = f1 / r + sn = g1 / r + for i := 0; i < count; i++ { + r *= safmn2 + } + } else { + r = math.Sqrt(f1*f1 + g1*g1) + cs = f1 / r + sn = g1 / r + } + if math.Abs(f) > math.Abs(g) && cs < 0 { + cs *= -1 + sn *= -1 + r *= -1 + } + return cs, sn, r +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlas2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlas2.go new file mode 100644 index 00000000..40a4b9c3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlas2.go @@ -0,0 +1,43 @@ +// 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" + +// Dlas2 computes the singular values of the 2×2 matrix defined by +// [F G] +// [0 H] +// The smaller and larger singular values are returned in that order. +// +// Dlas2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlas2(f, g, h float64) (ssmin, ssmax float64) { + fa := math.Abs(f) + ga := math.Abs(g) + ha := math.Abs(h) + fhmin := math.Min(fa, ha) + fhmax := math.Max(fa, ha) + if fhmin == 0 { + if fhmax == 0 { + return 0, ga + } + v := math.Min(fhmax, ga) / math.Max(fhmax, ga) + return 0, math.Max(fhmax, ga) * math.Sqrt(1+v*v) + } + if ga < fhmax { + as := 1 + fhmin/fhmax + at := (fhmax - fhmin) / fhmax + au := (ga / fhmax) * (ga / fhmax) + c := 2 / (math.Sqrt(as*as+au) + math.Sqrt(at*at+au)) + return fhmin * c, fhmax / c + } + au := fhmax / ga + if au == 0 { + return fhmin * fhmax / ga, ga + } + as := 1 + fhmin/fhmax + at := (fhmax - fhmin) / fhmax + c := 1 / (math.Sqrt(1+(as*au)*(as*au)) + math.Sqrt(1+(at*au)*(at*au))) + return 2 * (fhmin * c) * au, ga / (c + c) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlascl.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlascl.go new file mode 100644 index 00000000..b25408df --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlascl.go @@ -0,0 +1,89 @@ +// 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/lapack" +) + +// Dlascl multiplies an m×n matrix by the scalar cto/cfrom. +// +// cfrom must not be zero, and cto and cfrom must not be NaN, otherwise Dlascl +// will panic. +// +// Dlascl is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlascl(kind lapack.MatrixType, kl, ku int, cfrom, cto float64, m, n int, a []float64, lda int) { + checkMatrix(m, n, a, lda) + if cfrom == 0 { + panic(zeroDiv) + } + if math.IsNaN(cfrom) || math.IsNaN(cto) { + panic(nanScale) + } + if n == 0 || m == 0 { + return + } + smlnum := dlamchS + bignum := 1 / smlnum + cfromc := cfrom + ctoc := cto + cfrom1 := cfromc * smlnum + for { + var done bool + var mul, ctol float64 + if cfrom1 == cfromc { + // cfromc is inf. + mul = ctoc / cfromc + done = true + ctol = ctoc + } else { + ctol = ctoc / bignum + if ctol == ctoc { + // ctoc is either 0 or inf. + mul = ctoc + done = true + cfromc = 1 + } else if math.Abs(cfrom1) > math.Abs(ctoc) && ctoc != 0 { + mul = smlnum + done = false + cfromc = cfrom1 + } else if math.Abs(ctol) > math.Abs(cfromc) { + mul = bignum + done = false + ctoc = ctol + } else { + mul = ctoc / cfromc + done = true + } + } + switch kind { + default: + panic("lapack: not implemented") + case lapack.General: + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = a[i*lda+j] * mul + } + } + case lapack.UpperTri: + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + a[i*lda+j] = a[i*lda+j] * mul + } + } + case lapack.LowerTri: + for i := 0; i < m; i++ { + for j := 0; j <= min(i, n-1); j++ { + a[i*lda+j] = a[i*lda+j] * mul + } + } + } + if done { + break + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaset.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaset.go new file mode 100644 index 00000000..79d7edfd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaset.go @@ -0,0 +1,40 @@ +// 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/blas" + +// Dlaset sets the off-diagonal elements of A to alpha, and the diagonal +// elements to beta. If uplo == blas.Upper, only the elements in the upper +// triangular part are set. If uplo == blas.Lower, only the elements in the +// lower triangular part are set. If uplo is otherwise, all of the elements of A +// are set. +// +// Dlaset is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaset(uplo blas.Uplo, m, n int, alpha, beta float64, a []float64, lda int) { + checkMatrix(m, n, a, lda) + if uplo == blas.Upper { + for i := 0; i < m; i++ { + for j := i + 1; j < n; j++ { + a[i*lda+j] = alpha + } + } + } else if uplo == blas.Lower { + for i := 0; i < m; i++ { + for j := 0; j < min(i+1, n); j++ { + a[i*lda+j] = alpha + } + } + } else { + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = alpha + } + } + } + for i := 0; i < min(m, n); i++ { + a[i*lda+i] = beta + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq1.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq1.go new file mode 100644 index 00000000..0c91ded4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq1.go @@ -0,0 +1,97 @@ +// 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/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dlasq1 computes the singular values of an n×n bidiagonal matrix with diagonal +// d and off-diagonal e. On exit, d contains the singular values in decreasing +// order, and e is overwritten. d must have length at least n, e must have +// length at least n-1, and the input work must have length at least 4*n. Dlasq1 +// will panic if these conditions are not met. +// +// Dlasq1 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasq1(n int, d, e, work []float64) (info int) { + // TODO(btracey): replace info with an error. + if n < 0 { + panic(nLT0) + } + if len(work) < 4*n { + panic(badWork) + } + if len(d) < n { + panic("lapack: length of d less than n") + } + if len(e) < n-1 { + panic("lapack: length of e less than n-1") + } + if n == 0 { + return info + } + if n == 1 { + d[0] = math.Abs(d[0]) + return info + } + if n == 2 { + d[1], d[0] = impl.Dlas2(d[0], e[0], d[1]) + return info + } + // Estimate the largest singular value. + var sigmx float64 + for i := 0; i < n-1; i++ { + d[i] = math.Abs(d[i]) + sigmx = math.Max(sigmx, math.Abs(e[i])) + } + d[n-1] = math.Abs(d[n-1]) + // Early return if sigmx is zero (matrix is already diagonal). + if sigmx == 0 { + impl.Dlasrt(lapack.SortDecreasing, n, d) + return info + } + + for i := 0; i < n; i++ { + sigmx = math.Max(sigmx, d[i]) + } + + // Copy D and E into WORK (in the Z format) and scale (squaring the + // input data makes scaling by a power of the radix pointless). + + eps := dlamchP + safmin := dlamchS + scale := math.Sqrt(eps / safmin) + bi := blas64.Implementation() + bi.Dcopy(n, d, 1, work, 2) + bi.Dcopy(n-1, e, 1, work[1:], 2) + impl.Dlascl(lapack.General, 0, 0, sigmx, scale, 2*n-1, 1, work, 1) + + // Compute the q's and e's. + for i := 0; i < 2*n-1; i++ { + work[i] *= work[i] + } + work[2*n-1] = 0 + + info = impl.Dlasq2(n, work) + if info == 0 { + for i := 0; i < n; i++ { + d[i] = math.Sqrt(work[i]) + } + impl.Dlascl(lapack.General, 0, 0, scale, sigmx, n, 1, d, 1) + } else if info == 2 { + // Maximum number of iterations exceeded. Move data from work + // into D and E so the calling subroutine can try to finish. + for i := 0; i < n; i++ { + d[i] = math.Sqrt(work[2*i]) + e[i] = math.Sqrt(work[2*i+1]) + } + impl.Dlascl(lapack.General, 0, 0, scale, sigmx, n, 1, d, 1) + impl.Dlascl(lapack.General, 0, 0, scale, sigmx, n, 1, e, 1) + } + return info +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq2.go new file mode 100644 index 00000000..ebf5863a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq2.go @@ -0,0 +1,368 @@ +// 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/lapack" +) + +// Dlasq2 computes all the eigenvalues of the symmetric positive +// definite tridiagonal matrix associated with the qd array Z. Eigevalues +// are computed to high relative accuracy avoiding denormalization, underflow +// and overflow. +// +// To see the relation of Z to the tridiagonal matrix, let L be a +// unit lower bidiagonal matrix with sub-diagonals Z(2,4,6,,..) and +// let U be an upper bidiagonal matrix with 1's above and diagonal +// Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the +// symmetric tridiagonal to which it is similar. +// +// info returns a status error. The return codes mean as follows: +// 0: The algorithm completed successfully. +// 1: A split was marked by a positive value in e. +// 2: Current block of Z not diagonalized after 100*n iterations (in inner +// while loop). On exit Z holds a qd array with the same eigenvalues as +// the given Z. +// 3: Termination criterion of outer while loop not met (program created more +// than N unreduced blocks). +// +// z must have length at least 4*n, and must not contain any negative elements. +// Dlasq2 will panic otherwise. +// +// Dlasq2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasq2(n int, z []float64) (info int) { + // TODO(btracey): make info an error. + if len(z) < 4*n { + panic(badZ) + } + const cbias = 1.5 + + eps := dlamchP + safmin := dlamchS + tol := eps * 100 + tol2 := tol * tol + if n < 0 { + panic(nLT0) + } + if n == 0 { + return info + } + if n == 1 { + if z[0] < 0 { + panic(negZ) + } + return info + } + if n == 2 { + if z[1] < 0 || z[2] < 0 { + panic("lapack: bad z value") + } else if z[2] > z[0] { + z[0], z[2] = z[2], z[0] + } + z[4] = z[0] + z[1] + z[2] + if z[1] > z[2]*tol2 { + t := 0.5 * (z[0] - z[2] + z[1]) + s := z[2] * (z[1] / t) + if s <= t { + s = z[2] * (z[1] / (t * (1 + math.Sqrt(1+s/t)))) + } else { + s = z[2] * (z[1] / (t + math.Sqrt(t)*math.Sqrt(t+s))) + } + t = z[0] + s + z[1] + z[2] *= z[0] / t + z[0] = t + } + z[1] = z[2] + z[5] = z[1] + z[0] + return info + } + // Check for negative data and compute sums of q's and e's. + z[2*n-1] = 0 + emin := z[1] + var d, e, qmax float64 + var i1, n1 int + for k := 0; k < 2*(n-1); k += 2 { + if z[k] < 0 || z[k+1] < 0 { + panic("lapack: bad z value") + } + d += z[k] + e += z[k+1] + qmax = math.Max(qmax, z[k]) + emin = math.Min(emin, z[k+1]) + } + if z[2*(n-1)] < 0 { + panic("lapack: bad z value") + } + d += z[2*(n-1)] + qmax = math.Max(qmax, z[2*(n-1)]) + // Check for diagonality. + if e == 0 { + for k := 1; k < n; k++ { + z[k] = z[2*k] + } + impl.Dlasrt(lapack.SortDecreasing, n, z) + z[2*(n-1)] = d + return info + } + trace := d + e + // Check for zero data. + if trace == 0 { + z[2*(n-1)] = 0 + return info + } + // Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...). + for k := 2 * n; k >= 2; k -= 2 { + z[2*k-1] = 0 + z[2*k-2] = z[k-1] + z[2*k-3] = 0 + z[2*k-4] = z[k-2] + } + i0 := 0 + n0 := n - 1 + + // Reverse the qd-array, if warranted. + // z[4*i0-3] --> z[4*(i0+1)-3-1] --> z[4*i0] + if cbias*z[4*i0] < z[4*n0] { + ipn4Out := 4 * (i0 + n0 + 2) + for i4loop := 4 * (i0 + 1); i4loop <= 2*(i0+n0+1); i4loop += 4 { + i4 := i4loop - 1 + ipn4 := ipn4Out - 1 + z[i4-3], z[ipn4-i4-4] = z[ipn4-i4-4], z[i4-3] + z[i4-1], z[ipn4-i4-6] = z[ipn4-i4-6], z[i4-1] + } + } + + // Initial split checking via dqd and Li's test. + pp := 0 + for k := 0; k < 2; k++ { + d = z[4*n0+pp] + for i4loop := 4*n0 + pp; i4loop >= 4*(i0+1)+pp; i4loop -= 4 { + i4 := i4loop - 1 + if z[i4-1] <= tol2*d { + z[i4-1] = math.Copysign(0, -1) + d = z[i4-3] + } else { + d = z[i4-3] * (d / (d + z[i4-1])) + } + } + // dqd maps Z to ZZ plus Li's test. + emin = z[4*(i0+1)+pp] + d = z[4*i0+pp] + for i4loop := 4*(i0+1) + pp; i4loop <= 4*n0+pp; i4loop += 4 { + i4 := i4loop - 1 + z[i4-2*pp-2] = d + z[i4-1] + if z[i4-1] <= tol2*d { + z[i4-1] = math.Copysign(0, -1) + z[i4-2*pp-2] = d + z[i4-2*pp] = 0 + d = z[i4+1] + } else if safmin*z[i4+1] < z[i4-2*pp-2] && safmin*z[i4-2*pp-2] < z[i4+1] { + tmp := z[i4+1] / z[i4-2*pp-2] + z[i4-2*pp] = z[i4-1] * tmp + d *= tmp + } else { + z[i4-2*pp] = z[i4+1] * (z[i4-1] / z[i4-2*pp-2]) + d = z[i4+1] * (d / z[i4-2*pp-2]) + } + emin = math.Min(emin, z[i4-2*pp]) + } + z[4*(n0+1)-pp-3] = d + + // Now find qmax. + qmax = z[4*(i0+1)-pp-3] + for i4loop := 4*(i0+1) - pp + 2; i4loop <= 4*(n0+1)+pp-2; i4loop += 4 { + i4 := i4loop - 1 + qmax = math.Max(qmax, z[i4]) + } + // Prepare for the next iteration on K. + pp = 1 - pp + } + + // Initialise variables to pass to DLASQ3. + var ttype int + var dmin1, dmin2, dn, dn1, dn2, g, tau float64 + var tempq float64 + iter := 2 + var nFail int + nDiv := 2 * (n0 - i0) + var i4 int +outer: + for iwhila := 1; iwhila <= n+1; iwhila++ { + // Test for completion. + if n0 < 0 { + // Move q's to the front. + for k := 1; k < n; k++ { + z[k] = z[4*k] + } + // Sort and compute sum of eigenvalues. + impl.Dlasrt(lapack.SortDecreasing, n, z) + e = 0 + for k := n - 1; k >= 0; k-- { + e += z[k] + } + // Store trace, sum(eigenvalues) and information on performance. + z[2*n] = trace + z[2*n+1] = e + z[2*n+2] = float64(iter) + z[2*n+3] = float64(nDiv) / float64(n*n) + z[2*n+4] = 100 * float64(nFail) / float64(iter) + return info + } + + // While array unfinished do + // e[n0] holds the value of sigma when submatrix in i0:n0 + // splits from the rest of the array, but is negated. + var desig float64 + var sigma float64 + if n0 != n-1 { + sigma = -z[4*(n0+1)-2] + } + if sigma < 0 { + info = 1 + return info + } + // Find last unreduced submatrix's top index i0, find qmax and + // emin. Find Gershgorin-type bound if Q's much greater than E's. + var emax float64 + if n0 > i0 { + emin = math.Abs(z[4*(n0+1)-6]) + } else { + emin = 0 + } + qmin := z[4*(n0+1)-4] + qmax = qmin + zSmall := false + for i4loop := 4 * (n0 + 1); i4loop >= 8; i4loop -= 4 { + i4 = i4loop - 1 + if z[i4-5] <= 0 { + zSmall = true + break + } + if qmin >= 4*emax { + qmin = math.Min(qmin, z[i4-3]) + emax = math.Max(emax, z[i4-5]) + } + qmax = math.Max(qmax, z[i4-7]+z[i4-5]) + emin = math.Min(emin, z[i4-5]) + } + if !zSmall { + i4 = 3 + } + i0 = (i4+1)/4 - 1 + pp = 0 + if n0-i0 > 1 { + dee := z[4*i0] + deemin := dee + kmin := i0 + for i4loop := 4*(i0+1) + 1; i4loop <= 4*(n0+1)-3; i4loop += 4 { + i4 := i4loop - 1 + dee = z[i4] * (dee / (dee + z[i4-2])) + if dee <= deemin { + deemin = dee + kmin = (i4+4)/4 - 1 + } + } + if (kmin-i0)*2 < n0-kmin && deemin <= 0.5*z[4*n0] { + ipn4Out := 4 * (i0 + n0 + 2) + pp = 2 + for i4loop := 4 * (i0 + 1); i4loop <= 2*(i0+n0+1); i4loop += 4 { + i4 := i4loop - 1 + ipn4 := ipn4Out - 1 + z[i4-3], z[ipn4-i4-4] = z[ipn4-i4-4], z[i4-3] + z[i4-2], z[ipn4-i4-3] = z[ipn4-i4-3], z[i4-2] + z[i4-1], z[ipn4-i4-6] = z[ipn4-i4-6], z[i4-1] + z[i4], z[ipn4-i4-5] = z[ipn4-i4-5], z[i4] + } + } + } + // Put -(initial shift) into DMIN. + dmin := -math.Max(0, qmin-2*math.Sqrt(qmin)*math.Sqrt(emax)) + + // Now i0:n0 is unreduced. + // PP = 0 for ping, PP = 1 for pong. + // PP = 2 indicates that flipping was applied to the Z array and + // and that the tests for deflation upon entry in Dlasq3 + // should not be performed. + nbig := 100 * (n0 - i0 + 1) + for iwhilb := 0; iwhilb < nbig; iwhilb++ { + if i0 > n0 { + continue outer + } + + // While submatrix unfinished take a good dqds step. + i0, n0, pp, dmin, sigma, desig, qmax, nFail, iter, nDiv, ttype, dmin1, dmin2, dn, dn1, dn2, g, tau = + impl.Dlasq3(i0, n0, z, pp, dmin, sigma, desig, qmax, nFail, iter, nDiv, ttype, dmin1, dmin2, dn, dn1, dn2, g, tau) + + pp = 1 - pp + // When emin is very small check for splits. + if pp == 0 && n0-i0 >= 3 { + if z[4*(n0+1)-1] <= tol2*qmax || z[4*(n0+1)-2] <= tol2*sigma { + splt := i0 - 1 + qmax = z[4*i0] + emin = z[4*(i0+1)-2] + oldemn := z[4*(i0+1)-1] + for i4loop := 4 * (i0 + 1); i4loop <= 4*(n0-2); i4loop += 4 { + i4 := i4loop - 1 + if z[i4] <= tol2*z[i4-3] || z[i4-1] <= tol2*sigma { + z[i4-1] = -sigma + splt = i4 / 4 + qmax = 0 + emin = z[i4+3] + oldemn = z[i4+4] + } else { + qmax = math.Max(qmax, z[i4+1]) + emin = math.Min(emin, z[i4-1]) + oldemn = math.Min(oldemn, z[i4]) + } + } + z[4*(n0+1)-2] = emin + z[4*(n0+1)-1] = oldemn + i0 = splt + 1 + } + } + } + // Maximum number of iterations exceeded, restore the shift + // sigma and place the new d's and e's in a qd array. + // This might need to be done for several blocks. + info = 2 + i1 = i0 + n1 = n0 + for { + tempq = z[4*i0] + z[4*i0] += sigma + for k := i0 + 1; k <= n0; k++ { + tempe := z[4*(k+1)-6] + z[4*(k+1)-6] *= tempq / z[4*(k+1)-8] + tempq = z[4*k] + z[4*k] += sigma + tempe - z[4*(k+1)-6] + } + // Prepare to do this on the previous block if there is one. + if i1 <= 0 { + break + } + n1 = i1 - 1 + for i1 >= 1 && z[4*(i1+1)-6] >= 0 { + i1 -= 1 + } + sigma = -z[4*(n1+1)-2] + } + for k := 0; k < n; k++ { + z[2*k] = z[4*k] + // Only the block 1..N0 is unfinished. The rest of the e's + // must be essentially zero, although sometimes other data + // has been stored in them. + if k < n0 { + z[2*(k+1)-1] = z[4*(k+1)-1] + } else { + z[2*(k+1)] = 0 + } + } + return info + } + info = 3 + return info +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq3.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq3.go new file mode 100644 index 00000000..d547acfb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq3.go @@ -0,0 +1,161 @@ +// 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" + +// Dlasq3 checks for deflation, computes a shift (tau) and calls dqds. +// In case of failure it changes shifts, and tries again until output +// is positive. +// +// Dlasq3 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasq3(i0, n0 int, z []float64, pp int, dmin, sigma, desig, qmax float64, nFail, iter, nDiv int, ttype int, dmin1, dmin2, dn, dn1, dn2, g, tau float64) ( + i0Out, n0Out, ppOut int, dminOut, sigmaOut, desigOut, qmaxOut float64, nFailOut, iterOut, nDivOut, ttypeOut int, dmin1Out, dmin2Out, dnOut, dn1Out, dn2Out, gOut, tauOut float64) { + const cbias = 1.5 + + n0in := n0 + eps := dlamchP + tol := eps * 100 + tol2 := tol * tol + var nn int + var t float64 + for { + if n0 < i0 { + return i0, n0, pp, dmin, sigma, desig, qmax, nFail, iter, nDiv, ttype, dmin1, dmin2, dn, dn1, dn2, g, tau + } + if n0 == i0 { + z[4*(n0+1)-4] = z[4*(n0+1)+pp-4] + sigma + n0-- + continue + } + nn = 4*(n0+1) + pp - 1 + if n0 != i0+1 { + // Check whether e[n0-1] is negligible, 1 eigenvalue. + if z[nn-5] > tol2*(sigma+z[nn-3]) && z[nn-2*pp-4] > tol2*z[nn-7] { + // Check whether e[n0-2] is negligible, 2 eigenvalues. + if z[nn-9] > tol2*sigma && z[nn-2*pp-8] > tol2*z[nn-11] { + break + } + } else { + z[4*(n0+1)-4] = z[4*(n0+1)+pp-4] + sigma + n0-- + continue + } + } + if z[nn-3] > z[nn-7] { + z[nn-3], z[nn-7] = z[nn-7], z[nn-3] + } + t = 0.5 * (z[nn-7] - z[nn-3] + z[nn-5]) + if z[nn-5] > z[nn-3]*tol2 && t != 0 { + s := z[nn-3] * (z[nn-5] / t) + if s <= t { + s = z[nn-3] * (z[nn-5] / (t * (1 + math.Sqrt(1+s/t)))) + } else { + s = z[nn-3] * (z[nn-5] / (t + math.Sqrt(t)*math.Sqrt(t+s))) + } + t = z[nn-7] + (s + z[nn-5]) + z[nn-3] *= z[nn-7] / t + z[nn-7] = t + } + z[4*(n0+1)-8] = z[nn-7] + sigma + z[4*(n0+1)-4] = z[nn-3] + sigma + n0 -= 2 + } + if pp == 2 { + pp = 0 + } + + // Reverse the qd-array, if warranted. + if dmin <= 0 || n0 < n0in { + if cbias*z[4*(i0+1)+pp-4] < z[4*(n0+1)+pp-4] { + ipn4Out := 4 * (i0 + n0 + 2) + for j4loop := 4 * (i0 + 1); j4loop <= 2*((i0+1)+(n0+1)-1); j4loop += 4 { + ipn4 := ipn4Out - 1 + j4 := j4loop - 1 + + z[j4-3], z[ipn4-j4-4] = z[ipn4-j4-4], z[j4-3] + z[j4-2], z[ipn4-j4-3] = z[ipn4-j4-3], z[j4-2] + z[j4-1], z[ipn4-j4-6] = z[ipn4-j4-6], z[j4-1] + z[j4], z[ipn4-j4-5] = z[ipn4-j4-5], z[j4] + } + if n0-i0 <= 4 { + z[4*(n0+1)+pp-2] = z[4*(i0+1)+pp-2] + z[4*(n0+1)-pp-1] = z[4*(i0+1)-pp-1] + } + dmin2 = math.Min(dmin2, z[4*(i0+1)-pp-2]) + z[4*(n0+1)+pp-2] = math.Min(math.Min(z[4*(n0+1)+pp-2], z[4*(i0+1)+pp-2]), z[4*(i0+1)+pp+2]) + z[4*(n0+1)-pp-1] = math.Min(math.Min(z[4*(n0+1)-pp-1], z[4*(i0+1)-pp-1]), z[4*(i0+1)-pp+3]) + qmax = math.Max(math.Max(qmax, z[4*(i0+1)+pp-4]), z[4*(i0+1)+pp]) + dmin = math.Copysign(0, -1) // Fortran code has -zero, but -0 in go is 0 + } + } + + // Choose a shift. + tau, ttype, g = impl.Dlasq4(i0, n0, z, pp, n0in, dmin, dmin1, dmin2, dn, dn1, dn2, tau, ttype, g) + + // Call dqds until dmin > 0. +loop: + for { + i0, n0, pp, tau, sigma, dmin, dmin1, dmin2, dn, dn1, dn2 = impl.Dlasq5(i0, n0, z, pp, tau, sigma) + + nDiv += n0 - i0 + 2 + iter++ + switch { + case dmin >= 0 && dmin1 >= 0: + // Success. + goto done + + case dmin < 0 && dmin1 > 0 && z[4*n0-pp-1] < tol*(sigma+dn1) && math.Abs(dn) < tol*sigma: + // Convergence hidden by negative dn. + z[4*n0-pp+1] = 0 + dmin = 0 + goto done + + case dmin < 0: + // Tau too big. Select new Tau and try again. + nFail++ + if ttype < -22 { + // Failed twice. Play it safe. + tau = 0 + } else if dmin1 > 0 { + // Late failure. Gives excellent shift. + tau = (tau + dmin) * (1 - 2*eps) + ttype -= 11 + } else { + // Early failure. Divide by 4. + tau = tau / 4 + ttype -= 12 + } + + case math.IsNaN(dmin): + if tau == 0 { + break loop + } + tau = 0 + + default: + // Possible underflow. Play it safe. + break loop + } + } + + // Risk of underflow. + dmin, dmin1, dmin2, dn, dn1, dn2 = impl.Dlasq6(i0, n0, z, pp) + nDiv += n0 - i0 + 2 + iter++ + tau = 0 + +done: + if tau < sigma { + desig += tau + t = sigma + desig + desig -= t - sigma + } else { + t = sigma + tau + desig += sigma - (t - tau) + } + sigma = t + return i0, n0, pp, dmin, sigma, desig, qmax, nFail, iter, nDiv, ttype, dmin1, dmin2, dn, dn1, dn2, g, tau +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq4.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq4.go new file mode 100644 index 00000000..e09193b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq4.go @@ -0,0 +1,238 @@ +// 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" + +// Dlasq4 computes an approximation to the smallest eigenvalue using values of d +// from the previous transform. +// i0, n0, and n0in are zero-indexed. +// +// Dlasq4 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasq4(i0, n0 int, z []float64, pp int, n0in int, dmin, dmin1, dmin2, dn, dn1, dn2, tau float64, ttype int, g float64) (tauOut float64, ttypeOut int, gOut float64) { + const ( + cnst1 = 0.563 + cnst2 = 1.01 + cnst3 = 1.05 + + cnstthird = 0.333 // TODO(btracey): Fix? + ) + // A negative dmin forces the shift to take that absolute value + // ttype records the type of shift. + if dmin <= 0 { + tau = -dmin + ttype = -1 + return tau, ttype, g + } + nn := 4*(n0+1) + pp - 1 // -1 for zero indexing + s := math.NaN() // Poison s so that failure to take a path below is obvious + if n0in == n0 { + // No eigenvalues deflated. + if dmin == dn || dmin == dn1 { + b1 := math.Sqrt(z[nn-3]) * math.Sqrt(z[nn-5]) + b2 := math.Sqrt(z[nn-7]) * math.Sqrt(z[nn-9]) + a2 := z[nn-7] + z[nn-5] + if dmin == dn && dmin1 == dn1 { + gap2 := dmin2 - a2 - dmin2/4 + var gap1 float64 + if gap2 > 0 && gap2 > b2 { + gap1 = a2 - dn - (b2/gap2)*b2 + } else { + gap1 = a2 - dn - (b1 + b2) + } + if gap1 > 0 && gap1 > b1 { + s = math.Max(dn-(b1/gap1)*b1, 0.5*dmin) + ttype = -2 + } else { + s = 0 + if dn > b1 { + s = dn - b1 + } + if a2 > b1+b2 { + s = math.Min(s, a2-(b1+b2)) + } + s = math.Max(s, cnstthird*dmin) + ttype = -3 + } + } else { + ttype = -4 + s = dmin / 4 + var gam float64 + var np int + if dmin == dn { + gam = dn + a2 = 0 + if z[nn-5] > z[nn-7] { + return tau, ttype, g + } + b2 = z[nn-5] / z[nn-7] + np = nn - 9 + } else { + np = nn - 2*pp + gam = dn1 + if z[np-4] > z[np-2] { + return tau, ttype, g + } + a2 = z[np-4] / z[np-2] + if z[nn-9] > z[nn-11] { + return tau, ttype, g + } + b2 = z[nn-9] / z[nn-11] + np = nn - 13 + } + // Approximate contribution to norm squared from i < nn-1. + a2 += b2 + for i4loop := np + 1; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 { + i4 := i4loop - 1 + if b2 == 0 { + break + } + b1 = b2 + if z[i4] > z[i4-2] { + return tau, ttype, g + } + b2 *= z[i4] / z[i4-2] + a2 += b2 + if 100*math.Max(b2, b1) < a2 || cnst1 < a2 { + break + } + } + a2 *= cnst3 + // Rayleigh quotient residual bound. + if a2 < cnst1 { + s = gam * (1 - math.Sqrt(a2)) / (1 + a2) + } + } + } else if dmin == dn2 { + ttype = -5 + s = dmin / 4 + // Compute contribution to norm squared from i > nn-2. + np := nn - 2*pp + b1 := z[np-2] + b2 := z[np-6] + gam := dn2 + if z[np-8] > b2 || z[np-4] > b1 { + return tau, ttype, g + } + a2 := (z[np-8] / b2) * (1 + z[np-4]/b1) + // Approximate contribution to norm squared from i < nn-2. + if n0-i0 > 2 { + b2 = z[nn-13] / z[nn-15] + a2 += b2 + for i4loop := (nn + 1) - 17; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 { + i4 := i4loop - 1 + if b2 == 0 { + break + } + b1 = b2 + if z[i4] > z[i4-2] { + return tau, ttype, g + } + b2 *= z[i4] / z[i4-2] + a2 += b2 + if 100*math.Max(b2, b1) < a2 || cnst1 < a2 { + break + } + } + a2 *= cnst3 + } + if a2 < cnst1 { + s = gam * (1 - math.Sqrt(a2)) / (1 + a2) + } + } else { + // Case 6, no information to guide us. + if ttype == -6 { + g += cnstthird * (1 - g) + } else if ttype == -18 { + g = cnstthird / 4 + } else { + g = 1.0 / 4 + } + s = g * dmin + ttype = -6 + } + } else if n0in == (n0 + 1) { + // One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN. + if dmin1 == dn1 && dmin2 == dn2 { + ttype = -7 + s = cnstthird * dmin1 + if z[nn-5] > z[nn-7] { + return tau, ttype, g + } + b1 := z[nn-5] / z[nn-7] + b2 := b1 + if b2 != 0 { + for i4loop := 4*(n0+1) - 9 + pp; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 { + i4 := i4loop - 1 + a2 := b1 + if z[i4] > z[i4-2] { + return tau, ttype, g + } + b1 *= z[i4] / z[i4-2] + b2 += b1 + if 100*math.Max(b1, a2) < b2 { + break + } + } + } + b2 = math.Sqrt(cnst3 * b2) + a2 := dmin1 / (1 + b2*b2) + gap2 := 0.5*dmin2 - a2 + if gap2 > 0 && gap2 > b2*a2 { + s = math.Max(s, a2*(1-cnst2*a2*(b2/gap2)*b2)) + } else { + s = math.Max(s, a2*(1-cnst2*b2)) + ttype = -8 + } + } else { + s = dmin1 / 4 + if dmin1 == dn1 { + s = 0.5 * dmin1 + } + ttype = -9 + } + } else if n0in == (n0 + 2) { + // Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN. + if dmin2 == dn2 && 2*z[nn-5] < z[nn-7] { + ttype = -10 + s = cnstthird * dmin2 + if z[nn-5] > z[nn-7] { + return tau, ttype, g + } + b1 := z[nn-5] / z[nn-7] + b2 := b1 + if b2 != 0 { + for i4loop := 4*(n0+1) - 9 + pp; i4loop >= 4*(i0+1)-1+pp; i4loop -= 4 { + i4 := i4loop - 1 + if z[i4] > z[i4-2] { + return tau, ttype, g + } + b1 *= z[i4] / z[i4-2] + b2 += b1 + if 100*b1 < b2 { + break + } + } + } + b2 = math.Sqrt(cnst3 * b2) + a2 := dmin2 / (1 + b2*b2) + gap2 := z[nn-7] + z[nn-9] - math.Sqrt(z[nn-11])*math.Sqrt(z[nn-9]) - a2 + if gap2 > 0 && gap2 > b2*a2 { + s = math.Max(s, a2*(1-cnst2*a2*(b2/gap2)*b2)) + } else { + s = math.Max(s, a2*(1-cnst2*b2)) + } + } else { + s = dmin2 / 4 + ttype = -11 + } + } else if n0in > n0+2 { + // Case 12, more than two eigenvalues deflated. No information. + s = 0 + ttype = -12 + } + tau = s + return tau, ttype, g +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq5.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq5.go new file mode 100644 index 00000000..f94f2fb8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq5.go @@ -0,0 +1,127 @@ +// 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" + +// Dlasq5 computes one dqds transform in ping-pong form. +// i0 and n0 are zero-indexed. +// +// Dlasq5 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasq5(i0, n0 int, z []float64, pp int, tau, sigma float64) (i0Out, n0Out, ppOut int, tauOut, sigmaOut, dmin, dmin1, dmin2, dn, dnm1, dnm2 float64) { + // The lapack function has inputs for ieee and eps, but Go requires ieee so + // these are unnecessary. + if n0-i0-1 <= 0 { + return i0, n0, pp, tau, sigma, dmin, dmin1, dmin2, dn, dnm1, dnm2 + } + eps := dlamchP + dthresh := eps * (sigma + tau) + if tau < dthresh*0.5 { + tau = 0 + } + var j4 int + var emin float64 + if tau != 0 { + j4 = 4*i0 + pp + emin = z[j4+4] + d := z[j4] - tau + dmin = d + // In the reference there are code paths that actually return this value. + // dmin1 = -z[j4] + if pp == 0 { + for j4loop := 4 * (i0 + 1); j4loop <= 4*((n0+1)-3); j4loop += 4 { + j4 := j4loop - 1 + z[j4-2] = d + z[j4-1] + tmp := z[j4+1] / z[j4-2] + d = d*tmp - tau + dmin = math.Min(dmin, d) + z[j4] = z[j4-1] * tmp + emin = math.Min(z[j4], emin) + } + } else { + for j4loop := 4 * (i0 + 1); j4loop <= 4*((n0+1)-3); j4loop += 4 { + j4 := j4loop - 1 + z[j4-3] = d + z[j4] + tmp := z[j4+2] / z[j4-3] + d = d*tmp - tau + dmin = math.Min(dmin, d) + z[j4-1] = z[j4] * tmp + emin = math.Min(z[j4-1], emin) + } + } + // Unroll the last two steps. + dnm2 = d + dmin2 = dmin + j4 = 4*((n0+1)-2) - pp - 1 + j4p2 := j4 + 2*pp - 1 + z[j4-2] = dnm2 + z[j4p2] + z[j4] = z[j4p2+2] * (z[j4p2] / z[j4-2]) + dnm1 = z[j4p2+2]*(dnm2/z[j4-2]) - tau + dmin = math.Min(dmin, dnm1) + + dmin1 = dmin + j4 += 4 + j4p2 = j4 + 2*pp - 1 + z[j4-2] = dnm1 + z[j4p2] + z[j4] = z[j4p2+2] * (z[j4p2] / z[j4-2]) + dn = z[j4p2+2]*(dnm1/z[j4-2]) - tau + dmin = math.Min(dmin, dn) + } else { + // This is the version that sets d's to zero if they are small enough. + j4 = 4*(i0+1) + pp - 4 + emin = z[j4+4] + d := z[j4] - tau + dmin = d + // In the reference there are code paths that actually return this value. + // dmin1 = -z[j4] + if pp == 0 { + for j4loop := 4 * (i0 + 1); j4loop <= 4*((n0+1)-3); j4loop += 4 { + j4 := j4loop - 1 + z[j4-2] = d + z[j4-1] + tmp := z[j4+1] / z[j4-2] + d = d*tmp - tau + if d < dthresh { + d = 0 + } + dmin = math.Min(dmin, d) + z[j4] = z[j4-1] * tmp + emin = math.Min(z[j4], emin) + } + } else { + for j4loop := 4 * (i0 + 1); j4loop <= 4*((n0+1)-3); j4loop += 4 { + j4 := j4loop - 1 + z[j4-3] = d + z[j4] + tmp := z[j4+2] / z[j4-3] + d = d*tmp - tau + if d < dthresh { + d = 0 + } + dmin = math.Min(dmin, d) + z[j4-1] = z[j4] * tmp + emin = math.Min(z[j4-1], emin) + } + } + // Unroll the last two steps. + dnm2 = d + dmin2 = dmin + j4 = 4*((n0+1)-2) - pp - 1 + j4p2 := j4 + 2*pp - 1 + z[j4-2] = dnm2 + z[j4p2] + z[j4] = z[j4p2+2] * (z[j4p2] / z[j4-2]) + dnm1 = z[j4p2+2]*(dnm2/z[j4-2]) - tau + dmin = math.Min(dmin, dnm1) + + dmin1 = dmin + j4 += 4 + j4p2 = j4 + 2*pp - 1 + z[j4-2] = dnm1 + z[j4p2] + z[j4] = z[j4p2+2] * (z[j4p2] / z[j4-2]) + dn = z[j4p2+2]*(dnm1/z[j4-2]) - tau + dmin = math.Min(dmin, dn) + } + z[j4+2] = dn + z[4*(n0+1)-pp-1] = emin + return i0, n0, pp, tau, sigma, dmin, dmin1, dmin2, dn, dnm1, dnm2 +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq6.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq6.go new file mode 100644 index 00000000..94f69395 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasq6.go @@ -0,0 +1,109 @@ +// 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" + +// Dlasq6 computes one dqd transform in ping-pong form with protection against +// overflow and underflow. z has length at least 4*(n0+1) and holds the qd array. +// i0 is the zero-based first index. +// n0 is the zero-based last index. +// +// Dlasq6 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasq6(i0, n0 int, z []float64, pp int) (dmin, dmin1, dmin2, dn, dnm1, dnm2 float64) { + if len(z) < 4*(n0+1) { + panic(badZ) + } + if n0-i0-1 <= 0 { + return dmin, dmin1, dmin2, dn, dnm1, dnm2 + } + safmin := dlamchS + j4 := 4*(i0+1) + pp - 4 // -4 rather than -3 for zero indexing + emin := z[j4+4] + d := z[j4] + dmin = d + if pp == 0 { + for j4loop := 4 * (i0 + 1); j4loop <= 4*((n0+1)-3); j4loop += 4 { + j4 := j4loop - 1 // Translate back to zero-indexed. + z[j4-2] = d + z[j4-1] + if z[j4-2] == 0 { + z[j4] = 0 + d = z[j4+1] + dmin = d + emin = 0 + } else if safmin*z[j4+1] < z[j4-2] && safmin*z[j4-2] < z[j4+1] { + tmp := z[j4+1] / z[j4-2] + z[j4] = z[j4-1] * tmp + d *= tmp + } else { + z[j4] = z[j4+1] * (z[j4-1] / z[j4-2]) + d = z[j4+1] * (d / z[j4-2]) + } + dmin = math.Min(dmin, d) + emin = math.Min(emin, z[j4]) + } + } else { + for j4loop := 4 * (i0 + 1); j4loop <= 4*((n0+1)-3); j4loop += 4 { + j4 := j4loop - 1 + z[j4-3] = d + z[j4] + if z[j4-3] == 0 { + z[j4-1] = 0 + d = z[j4+2] + dmin = d + emin = 0 + } else if safmin*z[j4+2] < z[j4-3] && safmin*z[j4-3] < z[j4+2] { + tmp := z[j4+2] / z[j4-3] + z[j4-1] = z[j4] * tmp + d *= tmp + } else { + z[j4-1] = z[j4+2] * (z[j4] / z[j4-3]) + d = z[j4+2] * (d / z[j4-3]) + } + dmin = math.Min(dmin, d) + emin = math.Min(emin, z[j4-1]) + } + } + // Unroll last two steps. + dnm2 = d + dmin2 = dmin + j4 = 4*(n0-1) - pp - 1 + j4p2 := j4 + 2*pp - 1 + z[j4-2] = dnm2 + z[j4p2] + if z[j4-2] == 0 { + z[j4] = 0 + dnm1 = z[j4p2+2] + dmin = dnm1 + emin = 0 + } else if safmin*z[j4p2+2] < z[j4-2] && safmin*z[j4-2] < z[j4p2+2] { + tmp := z[j4p2+2] / z[j4-2] + z[j4] = z[j4p2] * tmp + dnm1 = dnm2 * tmp + } else { + z[j4] = z[j4p2+2] * (z[j4p2] / z[j4-2]) + dnm1 = z[j4p2+2] * (dnm2 / z[j4-2]) + } + dmin = math.Min(dmin, dnm1) + dmin1 = dmin + j4 += 4 + j4p2 = j4 + 2*pp - 1 + z[j4-2] = dnm1 + z[j4p2] + if z[j4-2] == 0 { + z[j4] = 0 + dn = z[j4p2+2] + dmin = dn + emin = 0 + } else if safmin*z[j4p2+2] < z[j4-2] && safmin*z[j4-2] < z[j4p2+2] { + tmp := z[j4p2+2] / z[j4-2] + z[j4] = z[j4p2] * tmp + dn = dnm1 * tmp + } else { + z[j4] = z[j4p2+2] * (z[j4p2] / z[j4-2]) + dn = z[j4p2+2] * (dnm1 / z[j4-2]) + } + dmin = math.Min(dmin, dn) + z[j4+2] = dn + z[4*(n0+1)-pp-1] = emin + return dmin, dmin1, dmin2, dn, dnm1, dnm2 +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasr.go new file mode 100644 index 00000000..dde44ddb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasr.go @@ -0,0 +1,268 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dlasr applies a sequence of plane rotations to the m×n matrix A. This series +// of plane rotations is implicitly represented by a matrix P. P is multiplied +// by a depending on the value of side -- A = P * A if side == lapack.Left, +// A = A * P^T if side == lapack.Right. +// +//The exact value of P depends on the value of pivot, but in all cases P is +// implicitly represented by a series of 2×2 rotation matrices. The entries of +// rotation matrix k are defined by s[k] and c[k] +// R(k) = [ c[k] s[k]] +// [-s[k] s[k]] +// If direct == lapack.Forward, the rotation matrices are applied as +// P = P(z-1) * ... * P(2) * P(1), while if direct == lapack.Backward they are +// applied as P = P(1) * P(2) * ... * P(n). +// +// pivot defines the mapping of the elements in R(k) to P(k). +// If pivot == lapack.Variable, the rotation is performed for the (k, k+1) plane. +// P(k) = [1 ] +// [ ... ] +// [ 1 ] +// [ c[k] s[k] ] +// [ -s[k] c[k] ] +// [ 1 ] +// [ ... ] +// [ 1] +// if pivot == lapack.Top, the rotation is performed for the (1, k+1) plane, +// P(k) = [c[k] s[k] ] +// [ 1 ] +// [ ... ] +// [ 1 ] +// [-s[k] c[k] ] +// [ 1 ] +// [ ... ] +// [ 1] +// and if pivot == lapack.Bottom, the rotation is performed for the (k, z) plane. +// P(k) = [1 ] +// [ ... ] +// [ 1 ] +// [ c[k] s[k]] +// [ 1 ] +// [ ... ] +// [ 1 ] +// [ -s[k] c[k]] +// s and c have length m - 1 if side == blas.Left, and n - 1 if side == blas.Right. +// +// Dlasr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasr(side blas.Side, pivot lapack.Pivot, direct lapack.Direct, m, n int, c, s, a []float64, lda int) { + checkMatrix(m, n, a, lda) + if side != blas.Left && side != blas.Right { + panic(badSide) + } + if pivot != lapack.Variable && pivot != lapack.Top && pivot != lapack.Bottom { + panic(badPivot) + } + if direct != lapack.Forward && direct != lapack.Backward { + panic(badDirect) + } + if side == blas.Left { + if len(c) < m-1 { + panic(badSlice) + } + if len(s) < m-1 { + panic(badSlice) + } + } else { + if len(c) < n-1 { + panic(badSlice) + } + if len(s) < n-1 { + panic(badSlice) + } + } + if m == 0 || n == 0 { + return + } + if side == blas.Left { + if pivot == lapack.Variable { + if direct == lapack.Forward { + for j := 0; j < m-1; j++ { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < n; i++ { + tmp2 := a[j*lda+i] + tmp := a[(j+1)*lda+i] + a[(j+1)*lda+i] = ctmp*tmp - stmp*tmp2 + a[j*lda+i] = stmp*tmp + ctmp*tmp2 + } + } + } + return + } + for j := m - 2; j >= 0; j-- { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < n; i++ { + tmp2 := a[j*lda+i] + tmp := a[(j+1)*lda+i] + a[(j+1)*lda+i] = ctmp*tmp - stmp*tmp2 + a[j*lda+i] = stmp*tmp + ctmp*tmp2 + } + } + } + return + } else if pivot == lapack.Top { + if direct == lapack.Forward { + for j := 1; j < m; j++ { + ctmp := c[j-1] + stmp := s[j-1] + if ctmp != 1 || stmp != 0 { + for i := 0; i < n; i++ { + tmp := a[j*lda+i] + tmp2 := a[i] + a[j*lda+i] = ctmp*tmp - stmp*tmp2 + a[i] = stmp*tmp + ctmp*tmp2 + } + } + } + return + } + for j := m - 1; j >= 1; j-- { + ctmp := c[j-1] + stmp := s[j-1] + if ctmp != 1 || stmp != 0 { + for i := 0; i < n; i++ { + ctmp := c[j-1] + stmp := s[j-1] + if ctmp != 1 || stmp != 0 { + for i := 0; i < n; i++ { + tmp := a[j*lda+i] + tmp2 := a[i] + a[j*lda+i] = ctmp*tmp - stmp*tmp2 + a[i] = stmp*tmp + ctmp*tmp2 + } + } + } + } + } + return + } + if direct == lapack.Forward { + for j := 0; j < m-1; j++ { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < n; i++ { + tmp := a[j*lda+i] + tmp2 := a[(m-1)*lda+i] + a[j*lda+i] = stmp*tmp2 + ctmp*tmp + a[(m-1)*lda+i] = ctmp*tmp2 - stmp*tmp + } + } + } + return + } + for j := m - 2; j >= 0; j-- { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < n; i++ { + tmp := a[j*lda+i] + tmp2 := a[(m-1)*lda+i] + a[j*lda+i] = stmp*tmp2 + ctmp*tmp + a[(m-1)*lda+i] = ctmp*tmp2 - stmp*tmp + } + } + } + return + } + if pivot == lapack.Variable { + if direct == lapack.Forward { + for j := 0; j < n-1; j++ { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < m; i++ { + tmp := a[i*lda+j+1] + tmp2 := a[i*lda+j] + a[i*lda+j+1] = ctmp*tmp - stmp*tmp2 + a[i*lda+j] = stmp*tmp + ctmp*tmp2 + } + } + } + return + } + for j := n - 2; j >= 0; j-- { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < m; i++ { + tmp := a[i*lda+j+1] + tmp2 := a[i*lda+j] + a[i*lda+j+1] = ctmp*tmp - stmp*tmp2 + a[i*lda+j] = stmp*tmp + ctmp*tmp2 + } + } + } + return + } else if pivot == lapack.Top { + if direct == lapack.Forward { + for j := 1; j < n; j++ { + ctmp := c[j-1] + stmp := s[j-1] + if ctmp != 1 || stmp != 0 { + for i := 0; i < m; i++ { + tmp := a[i*lda+j] + tmp2 := a[i*lda] + a[i*lda+j] = ctmp*tmp - stmp*tmp2 + a[i*lda] = stmp*tmp + ctmp*tmp2 + } + } + } + return + } + for j := n - 1; j >= 1; j-- { + ctmp := c[j-1] + stmp := s[j-1] + if ctmp != 1 || stmp != 0 { + for i := 0; i < m; i++ { + tmp := a[i*lda+j] + tmp2 := a[i*lda] + a[i*lda+j] = ctmp*tmp - stmp*tmp2 + a[i*lda] = stmp*tmp + ctmp*tmp2 + } + } + } + return + } + if direct == lapack.Forward { + for j := 0; j < n-1; j++ { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < m; i++ { + tmp := a[i*lda+j] + tmp2 := a[i*lda+n-1] + a[i*lda+j] = stmp*tmp2 + ctmp*tmp + a[i*lda+n-1] = ctmp*tmp2 - stmp*tmp + } + + } + } + return + } + for j := n - 2; j >= 0; j-- { + ctmp := c[j] + stmp := s[j] + if ctmp != 1 || stmp != 0 { + for i := 0; i < m; i++ { + tmp := a[i*lda+j] + tmp2 := a[i*lda+n-1] + a[i*lda+j] = stmp*tmp2 + ctmp*tmp + a[i*lda+n-1] = ctmp*tmp2 - stmp*tmp + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasrt.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasrt.go new file mode 100644 index 00000000..eb63c63d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasrt.go @@ -0,0 +1,30 @@ +// 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 ( + "sort" + + "gonum.org/v1/gonum/lapack" +) + +// Dlasrt sorts the numbers in the input slice d. If s == lapack.SortIncreasing, +// the elements are sorted in increasing order. If s == lapack.SortDecreasing, +// the elements are sorted in decreasing order. For other values of s Dlasrt +// will panic. +// +// Dlasrt is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasrt(s lapack.Sort, n int, d []float64) { + checkVector(n, d, 1) + d = d[:n] + switch s { + default: + panic(badSort) + case lapack.SortIncreasing: + sort.Float64s(d) + case lapack.SortDecreasing: + sort.Sort(sort.Reverse(sort.Float64Slice(d))) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlassq.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlassq.go new file mode 100644 index 00000000..186b840b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlassq.go @@ -0,0 +1,31 @@ +// 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" + +// Dlassq updates a sum of squares in scaled form. The input parameters scale and +// sumsq represent the current scale and total sum of squares. These values are +// updated with the information in the first n elements of the vector specified +// by x and incX. +// +// Dlassq is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlassq(n int, x []float64, incx int, scale float64, sumsq float64) (scl, smsq float64) { + if n <= 0 { + return scale, sumsq + } + for ix := 0; ix <= (n-1)*incx; ix += incx { + absxi := math.Abs(x[ix]) + if absxi > 0 || math.IsNaN(absxi) { + if scale < absxi { + sumsq = 1 + sumsq*(scale/absxi)*(scale/absxi) + scale = absxi + } else { + sumsq += (absxi / scale) * (absxi / scale) + } + } + } + return scale, sumsq +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasv2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasv2.go new file mode 100644 index 00000000..ba1445c0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasv2.go @@ -0,0 +1,115 @@ +// 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" + +// Dlasv2 computes the singular value decomposition of a 2×2 matrix. +// [ csl snl] [f g] [csr -snr] = [ssmax 0] +// [-snl csl] [0 h] [snr csr] = [ 0 ssmin] +// ssmax is the larger absolute singular value, and ssmin is the smaller absolute +// singular value. [cls, snl] and [csr, snr] are the left and right singular vectors. +// +// Dlasv2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasv2(f, g, h float64) (ssmin, ssmax, snr, csr, snl, csl float64) { + ft := f + fa := math.Abs(ft) + ht := h + ha := math.Abs(h) + // pmax points to the largest element of the matrix in terms of absolute value. + // 1 if F, 2 if G, 3 if H. + pmax := 1 + swap := ha > fa + if swap { + pmax = 3 + ft, ht = ht, ft + fa, ha = ha, fa + } + gt := g + ga := math.Abs(gt) + var clt, crt, slt, srt float64 + if ga == 0 { + ssmin = ha + ssmax = fa + clt = 1 + crt = 1 + slt = 0 + srt = 0 + } else { + gasmall := true + if ga > fa { + pmax = 2 + if (fa / ga) < dlamchE { + gasmall = false + ssmax = ga + if ha > 1 { + ssmin = fa / (ga / ha) + } else { + ssmin = (fa / ga) * ha + } + clt = 1 + slt = ht / gt + srt = 1 + crt = ft / gt + } + } + if gasmall { + d := fa - ha + l := d / fa + if d == fa { // deal with inf + l = 1 + } + m := gt / ft + t := 2 - l + s := math.Hypot(t, m) + var r float64 + if l == 0 { + r = math.Abs(m) + } else { + r = math.Hypot(l, m) + } + a := 0.5 * (s + r) + ssmin = ha / a + ssmax = fa * a + if m == 0 { + if l == 0 { + t = math.Copysign(2, ft) * math.Copysign(1, gt) + } else { + t = gt/math.Copysign(d, ft) + m/t + } + } else { + t = (m/(s+t) + m/(r+l)) * (1 + a) + } + l = math.Hypot(t, 2) + crt = 2 / l + srt = t / l + clt = (crt + srt*m) / a + slt = (ht / ft) * srt / a + } + } + if swap { + csl = srt + snl = crt + csr = slt + snr = clt + } else { + csl = clt + snl = slt + csr = crt + snr = srt + } + var tsign float64 + switch pmax { + case 1: + tsign = math.Copysign(1, csr) * math.Copysign(1, csl) * math.Copysign(1, f) + case 2: + tsign = math.Copysign(1, snr) * math.Copysign(1, csl) * math.Copysign(1, g) + case 3: + tsign = math.Copysign(1, snr) * math.Copysign(1, snl) * math.Copysign(1, h) + } + ssmax = math.Copysign(ssmax, tsign) + ssmin = math.Copysign(ssmin, tsign*math.Copysign(1, f)*math.Copysign(1, h)) + return ssmin, ssmax, snr, csr, snl, csl +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlaswp.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaswp.go new file mode 100644 index 00000000..22ef3533 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlaswp.go @@ -0,0 +1,47 @@ +// 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/blas/blas64" + +// Dlaswp swaps the rows k1 to k2 of a rectangular matrix A according to the +// indices in ipiv so that row k is swapped with ipiv[k]. +// +// n is the number of columns of A and incX is the increment for ipiv. If incX +// is 1, the swaps are applied from k1 to k2. If incX is -1, the swaps are +// applied in reverse order from k2 to k1. For other values of incX Dlaswp will +// panic. ipiv must have length k2+1, otherwise Dlaswp will panic. +// +// The indices k1, k2, and the elements of ipiv are zero-based. +// +// Dlaswp is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlaswp(n int, a []float64, lda int, k1, k2 int, ipiv []int, incX int) { + switch { + case n < 0: + panic(nLT0) + case k2 < 0: + panic(badK2) + case k1 < 0 || k2 < k1: + panic(badK1) + case len(ipiv) != k2+1: + panic(badIpiv) + case incX != 1 && incX != -1: + panic(absIncNotOne) + } + + if n == 0 { + return + } + bi := blas64.Implementation() + if incX == 1 { + for k := k1; k <= k2; k++ { + bi.Dswap(n, a[k*lda:], 1, a[ipiv[k]*lda:], 1) + } + return + } + for k := k2; k >= k1; k-- { + bi.Dswap(n, a[k*lda:], 1, a[ipiv[k]*lda:], 1) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlasy2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasy2.go new file mode 100644 index 00000000..aa983bb9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlasy2.go @@ -0,0 +1,290 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlasy2 solves the Sylvester matrix equation where the matrices are of order 1 +// or 2. It computes the unknown n1×n2 matrix X so that +// TL*X + sgn*X*TR = scale*B, if tranl == false and tranr == false, +// TL^T*X + sgn*X*TR = scale*B, if tranl == true and tranr == false, +// TL*X + sgn*X*TR^T = scale*B, if tranl == false and tranr == true, +// TL^T*X + sgn*X*TR^T = scale*B, if tranl == true and tranr == true, +// where TL is n1×n1, TR is n2×n2, B is n1×n2, and 1 <= n1,n2 <= 2. +// +// isgn must be 1 or -1, and n1 and n2 must be 0, 1, or 2, but these conditions +// are not checked. +// +// Dlasy2 returns three values, a scale factor that is chosen less than or equal +// to 1 to prevent the solution overflowing, the infinity norm of the solution, +// and an indicator of success. If ok is false, TL and TR have eigenvalues that +// are too close, so TL or TR is perturbed to get a non-singular equation. +// +// Dlasy2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlasy2(tranl, tranr bool, isgn, n1, n2 int, tl []float64, ldtl int, tr []float64, ldtr int, b []float64, ldb int, x []float64, ldx int) (scale, xnorm float64, ok bool) { + // TODO(vladimir-ch): Add input validation checks conditionally skipped + // using the build tag mechanism. + + ok = true + // Quick return if possible. + if n1 == 0 || n2 == 0 { + return scale, xnorm, ok + } + + // Set constants to control overflow. + eps := dlamchP + smlnum := dlamchS / eps + sgn := float64(isgn) + + if n1 == 1 && n2 == 1 { + // 1×1 case: TL11*X + sgn*X*TR11 = B11. + tau1 := tl[0] + sgn*tr[0] + bet := math.Abs(tau1) + if bet <= smlnum { + tau1 = smlnum + bet = smlnum + ok = false + } + scale = 1 + gam := math.Abs(b[0]) + if smlnum*gam > bet { + scale = 1 / gam + } + x[0] = b[0] * scale / tau1 + xnorm = math.Abs(x[0]) + return scale, xnorm, ok + } + + if n1+n2 == 3 { + // 1×2 or 2×1 case. + var ( + smin float64 + tmp [4]float64 // tmp is used as a 2×2 row-major matrix. + btmp [2]float64 + ) + if n1 == 1 && n2 == 2 { + // 1×2 case: TL11*[X11 X12] + sgn*[X11 X12]*op[TR11 TR12] = [B11 B12]. + // [TR21 TR22] + smin = math.Abs(tl[0]) + smin = math.Max(smin, math.Max(math.Abs(tr[0]), math.Abs(tr[1]))) + smin = math.Max(smin, math.Max(math.Abs(tr[ldtr]), math.Abs(tr[ldtr+1]))) + smin = math.Max(eps*smin, smlnum) + tmp[0] = tl[0] + sgn*tr[0] + tmp[3] = tl[0] + sgn*tr[ldtr+1] + if tranr { + tmp[1] = sgn * tr[1] + tmp[2] = sgn * tr[ldtr] + } else { + tmp[1] = sgn * tr[ldtr] + tmp[2] = sgn * tr[1] + } + btmp[0] = b[0] + btmp[1] = b[1] + } else { + // 2×1 case: op[TL11 TL12]*[X11] + sgn*[X11]*TR11 = [B11]. + // [TL21 TL22]*[X21] [X21] [B21] + smin = math.Abs(tr[0]) + smin = math.Max(smin, math.Max(math.Abs(tl[0]), math.Abs(tl[1]))) + smin = math.Max(smin, math.Max(math.Abs(tl[ldtl]), math.Abs(tl[ldtl+1]))) + smin = math.Max(eps*smin, smlnum) + tmp[0] = tl[0] + sgn*tr[0] + tmp[3] = tl[ldtl+1] + sgn*tr[0] + if tranl { + tmp[1] = tl[ldtl] + tmp[2] = tl[1] + } else { + tmp[1] = tl[1] + tmp[2] = tl[ldtl] + } + btmp[0] = b[0] + btmp[1] = b[ldb] + } + + // Solve 2×2 system using complete pivoting. + // Set pivots less than smin to smin. + + bi := blas64.Implementation() + ipiv := bi.Idamax(len(tmp), tmp[:], 1) + // Compute the upper triangular matrix [u11 u12]. + // [ 0 u22] + u11 := tmp[ipiv] + if math.Abs(u11) <= smin { + ok = false + u11 = smin + } + locu12 := [4]int{1, 0, 3, 2} // Index in tmp of the element on the same row as the pivot. + u12 := tmp[locu12[ipiv]] + locl21 := [4]int{2, 3, 0, 1} // Index in tmp of the element on the same column as the pivot. + l21 := tmp[locl21[ipiv]] / u11 + locu22 := [4]int{3, 2, 1, 0} // Index in tmp of the remaining element. + u22 := tmp[locu22[ipiv]] - l21*u12 + if math.Abs(u22) <= smin { + ok = false + u22 = smin + } + if ipiv&0x2 != 0 { // true for ipiv equal to 2 and 3. + // The pivot was in the second row, swap the elements of + // the right-hand side. + btmp[0], btmp[1] = btmp[1], btmp[0]-l21*btmp[1] + } else { + btmp[1] -= l21 * btmp[0] + } + scale = 1 + if 2*smlnum*math.Abs(btmp[1]) > math.Abs(u22) || 2*smlnum*math.Abs(btmp[0]) > math.Abs(u11) { + scale = 0.5 / math.Max(math.Abs(btmp[0]), math.Abs(btmp[1])) + btmp[0] *= scale + btmp[1] *= scale + } + // Solve the system [u11 u12] [x21] = [ btmp[0] ]. + // [ 0 u22] [x22] [ btmp[1] ] + x22 := btmp[1] / u22 + x21 := btmp[0]/u11 - (u12/u11)*x22 + if ipiv&0x1 != 0 { // true for ipiv equal to 1 and 3. + // The pivot was in the second column, swap the elements + // of the solution. + x21, x22 = x22, x21 + } + x[0] = x21 + if n1 == 1 { + x[1] = x22 + xnorm = math.Abs(x[0]) + math.Abs(x[1]) + } else { + x[ldx] = x22 + xnorm = math.Max(math.Abs(x[0]), math.Abs(x[ldx])) + } + return scale, xnorm, ok + } + + // 2×2 case: op[TL11 TL12]*[X11 X12] + SGN*[X11 X12]*op[TR11 TR12] = [B11 B12]. + // [TL21 TL22] [X21 X22] [X21 X22] [TR21 TR22] [B21 B22] + // + // Solve equivalent 4×4 system using complete pivoting. + // Set pivots less than smin to smin. + + smin := math.Max(math.Abs(tr[0]), math.Abs(tr[1])) + smin = math.Max(smin, math.Max(math.Abs(tr[ldtr]), math.Abs(tr[ldtr+1]))) + smin = math.Max(smin, math.Max(math.Abs(tl[0]), math.Abs(tl[1]))) + smin = math.Max(smin, math.Max(math.Abs(tl[ldtl]), math.Abs(tl[ldtl+1]))) + smin = math.Max(eps*smin, smlnum) + + var t [4][4]float64 + t[0][0] = tl[0] + sgn*tr[0] + t[1][1] = tl[0] + sgn*tr[ldtr+1] + t[2][2] = tl[ldtl+1] + sgn*tr[0] + t[3][3] = tl[ldtl+1] + sgn*tr[ldtr+1] + if tranl { + t[0][2] = tl[ldtl] + t[1][3] = tl[ldtl] + t[2][0] = tl[1] + t[3][1] = tl[1] + } else { + t[0][2] = tl[1] + t[1][3] = tl[1] + t[2][0] = tl[ldtl] + t[3][1] = tl[ldtl] + } + if tranr { + t[0][1] = sgn * tr[1] + t[1][0] = sgn * tr[ldtr] + t[2][3] = sgn * tr[1] + t[3][2] = sgn * tr[ldtr] + } else { + t[0][1] = sgn * tr[ldtr] + t[1][0] = sgn * tr[1] + t[2][3] = sgn * tr[ldtr] + t[3][2] = sgn * tr[1] + } + + var btmp [4]float64 + btmp[0] = b[0] + btmp[1] = b[1] + btmp[2] = b[ldb] + btmp[3] = b[ldb+1] + + // Perform elimination. + var jpiv [4]int // jpiv records any column swaps for pivoting. + for i := 0; i < 3; i++ { + var ( + xmax float64 + ipsv, jpsv int + ) + for ip := i; ip < 4; ip++ { + for jp := i; jp < 4; jp++ { + if math.Abs(t[ip][jp]) >= xmax { + xmax = math.Abs(t[ip][jp]) + ipsv = ip + jpsv = jp + } + } + } + if ipsv != i { + // The pivot is not in the top row of the unprocessed + // block, swap rows ipsv and i of t and btmp. + t[ipsv], t[i] = t[i], t[ipsv] + btmp[ipsv], btmp[i] = btmp[i], btmp[ipsv] + } + if jpsv != i { + // The pivot is not in the left column of the + // unprocessed block, swap columns jpsv and i of t. + for k := 0; k < 4; k++ { + t[k][jpsv], t[k][i] = t[k][i], t[k][jpsv] + } + } + jpiv[i] = jpsv + if math.Abs(t[i][i]) < smin { + ok = false + t[i][i] = smin + } + for k := i + 1; k < 4; k++ { + t[k][i] /= t[i][i] + btmp[k] -= t[k][i] * btmp[i] + for j := i + 1; j < 4; j++ { + t[k][j] -= t[k][i] * t[i][j] + } + } + } + if math.Abs(t[3][3]) < smin { + ok = false + t[3][3] = smin + } + scale = 1 + if 8*smlnum*math.Abs(btmp[0]) > math.Abs(t[0][0]) || + 8*smlnum*math.Abs(btmp[1]) > math.Abs(t[1][1]) || + 8*smlnum*math.Abs(btmp[2]) > math.Abs(t[2][2]) || + 8*smlnum*math.Abs(btmp[3]) > math.Abs(t[3][3]) { + + maxbtmp := math.Max(math.Abs(btmp[0]), math.Abs(btmp[1])) + maxbtmp = math.Max(maxbtmp, math.Max(math.Abs(btmp[2]), math.Abs(btmp[3]))) + scale = 1 / 8 / maxbtmp + btmp[0] *= scale + btmp[1] *= scale + btmp[2] *= scale + btmp[3] *= scale + } + // Compute the solution of the upper triangular system t * tmp = btmp. + var tmp [4]float64 + for i := 3; i >= 0; i-- { + temp := 1 / t[i][i] + tmp[i] = btmp[i] * temp + for j := i + 1; j < 4; j++ { + tmp[i] -= temp * t[i][j] * tmp[j] + } + } + for i := 2; i >= 0; i-- { + if jpiv[i] != i { + tmp[i], tmp[jpiv[i]] = tmp[jpiv[i]], tmp[i] + } + } + x[0] = tmp[0] + x[1] = tmp[1] + x[ldx] = tmp[2] + x[ldx+1] = tmp[3] + xnorm = math.Max(math.Abs(tmp[0])+math.Abs(tmp[1]), math.Abs(tmp[2])+math.Abs(tmp[3])) + return scale, xnorm, ok +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlatrd.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlatrd.go new file mode 100644 index 00000000..28bc2325 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlatrd.go @@ -0,0 +1,145 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlatrd reduces nb rows and columns of a real n×n symmetric matrix A to symmetric +// tridiagonal form. It computes the orthonormal similarity transformation +// Q^T * A * Q +// and returns the matrices V and W to apply to the unreduced part of A. If +// uplo == blas.Upper, the upper triangle is supplied and the last nb rows are +// reduced. If uplo == blas.Lower, the lower triangle is supplied and the first +// nb rows are reduced. +// +// a contains the symmetric matrix on entry with active triangular half specified +// by uplo. On exit, the nb columns have been reduced to tridiagonal form. The +// diagonal contains the diagonal of the reduced matrix, the off-diagonal is +// set to 1, and the remaining elements contain the data to construct Q. +// +// If uplo == blas.Upper, with n = 5 and nb = 2 on exit a is +// [ a a a v4 v5] +// [ a a v4 v5] +// [ a 1 v5] +// [ d 1] +// [ d] +// +// If uplo == blas.Lower, with n = 5 and nb = 2, on exit a is +// [ d ] +// [ 1 d ] +// [v1 1 a ] +// [v1 v2 a a ] +// [v1 v2 a a a] +// +// e contains the superdiagonal elements of the reduced matrix. If uplo == blas.Upper, +// e[n-nb:n-1] contains the last nb columns of the reduced matrix, while if +// uplo == blas.Lower, e[:nb] contains the first nb columns of the reduced matrix. +// e must have length at least n-1, and Dlatrd will panic otherwise. +// +// tau contains the scalar factors of the elementary reflectors needed to construct Q. +// The reflectors are stored in tau[n-nb:n-1] if uplo == blas.Upper, and in +// tau[:nb] if uplo == blas.Lower. tau must have length n-1, and Dlatrd will panic +// otherwise. +// +// w is an n×nb matrix. On exit it contains the data to update the unreduced part +// of A. +// +// The matrix Q is represented as a product of elementary reflectors. Each reflector +// H has the form +// I - tau * v * v^T +// If uplo == blas.Upper, +// Q = H_{n-1} * H_{n-2} * ... * H_{n-nb} +// where v[:i-1] is stored in A[:i-1,i], v[i-1] = 1, and v[i:n] = 0. +// +// If uplo == blas.Lower, +// Q = H_0 * H_1 * ... * H_{nb-1} +// where v[:i+1] = 0, v[i+1] = 1, and v[i+2:n] is stored in A[i+2:n,i]. +// +// The vectors v form the n×nb matrix V which is used with W to apply a +// symmetric rank-2 update to the unreduced part of A +// A = A - V * W^T - W * V^T +// +// Dlatrd is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlatrd(uplo blas.Uplo, n, nb int, a []float64, lda int, e, tau, w []float64, ldw int) { + checkMatrix(n, n, a, lda) + checkMatrix(n, nb, w, ldw) + if len(e) < n-1 { + panic(badE) + } + if len(tau) < n-1 { + panic(badTau) + } + if n <= 0 { + return + } + bi := blas64.Implementation() + if uplo == blas.Upper { + for i := n - 1; i >= n-nb; i-- { + iw := i - n + nb + if i < n-1 { + // Update A(0:i, i). + bi.Dgemv(blas.NoTrans, i+1, n-i-1, -1, a[i+1:], lda, + w[i*ldw+iw+1:], 1, 1, a[i:], lda) + bi.Dgemv(blas.NoTrans, i+1, n-i-1, -1, w[iw+1:], ldw, + a[i*lda+i+1:], 1, 1, a[i:], lda) + } + if i > 0 { + // Generate elementary reflector H_i to annihilate A(0:i-2,i). + e[i-1], tau[i-1] = impl.Dlarfg(i, a[(i-1)*lda+i], a[i:], lda) + a[(i-1)*lda+i] = 1 + + // Compute W(0:i-1, i). + bi.Dsymv(blas.Upper, i, 1, a, lda, a[i:], lda, 0, w[iw:], ldw) + if i < n-1 { + bi.Dgemv(blas.Trans, i, n-i-1, 1, w[iw+1:], ldw, + a[i:], lda, 0, w[(i+1)*ldw+iw:], ldw) + bi.Dgemv(blas.NoTrans, i, n-i-1, -1, a[i+1:], lda, + w[(i+1)*ldw+iw:], ldw, 1, w[iw:], ldw) + bi.Dgemv(blas.Trans, i, n-i-1, 1, a[i+1:], lda, + a[i:], lda, 0, w[(i+1)*ldw+iw:], ldw) + bi.Dgemv(blas.NoTrans, i, n-i-1, -1, w[iw+1:], ldw, + w[(i+1)*ldw+iw:], ldw, 1, w[iw:], ldw) + } + bi.Dscal(i, tau[i-1], w[iw:], ldw) + alpha := -0.5 * tau[i-1] * bi.Ddot(i, w[iw:], ldw, a[i:], lda) + bi.Daxpy(i, alpha, a[i:], lda, w[iw:], ldw) + } + } + } else { + // Reduce first nb columns of lower triangle. + for i := 0; i < nb; i++ { + // Update A(i:n, i) + bi.Dgemv(blas.NoTrans, n-i, i, -1, a[i*lda:], lda, + w[i*ldw:], 1, 1, a[i*lda+i:], lda) + bi.Dgemv(blas.NoTrans, n-i, i, -1, w[i*ldw:], ldw, + a[i*lda:], 1, 1, a[i*lda+i:], lda) + if i < n-1 { + // Generate elementary reflector H_i to annihilate A(i+2:n,i). + e[i], tau[i] = impl.Dlarfg(n-i-1, a[(i+1)*lda+i], a[min(i+2, n-1)*lda+i:], lda) + a[(i+1)*lda+i] = 1 + + // Compute W(i+1:n,i). + bi.Dsymv(blas.Lower, n-i-1, 1, a[(i+1)*lda+i+1:], lda, + a[(i+1)*lda+i:], lda, 0, w[(i+1)*ldw+i:], ldw) + bi.Dgemv(blas.Trans, n-i-1, i, 1, w[(i+1)*ldw:], ldw, + a[(i+1)*lda+i:], lda, 0, w[i:], ldw) + bi.Dgemv(blas.NoTrans, n-i-1, i, -1, a[(i+1)*lda:], lda, + w[i:], ldw, 1, w[(i+1)*ldw+i:], ldw) + bi.Dgemv(blas.Trans, n-i-1, i, 1, a[(i+1)*lda:], lda, + a[(i+1)*lda+i:], lda, 0, w[i:], ldw) + bi.Dgemv(blas.NoTrans, n-i-1, i, -1, w[(i+1)*ldw:], ldw, + w[i:], ldw, 1, w[(i+1)*ldw+i:], ldw) + bi.Dscal(n-i-1, tau[i], w[(i+1)*ldw+i:], ldw) + alpha := -0.5 * tau[i] * bi.Ddot(n-i-1, w[(i+1)*ldw+i:], ldw, + a[(i+1)*lda+i:], lda) + bi.Daxpy(n-i-1, alpha, a[(i+1)*lda+i:], lda, + w[(i+1)*ldw+i:], ldw) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dlatrs.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dlatrs.go new file mode 100644 index 00000000..64470f59 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dlatrs.go @@ -0,0 +1,350 @@ +// 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/blas/blas64" +) + +// Dlatrs solves a triangular system of equations scaled to prevent overflow. It +// solves +// A * x = scale * b if trans == blas.NoTrans +// A^T * x = scale * b if trans == blas.Trans +// where the scale s is set for numeric stability. +// +// A is an n×n triangular matrix. On entry, the slice x contains the values of +// of b, and on exit it contains the solution vector x. +// +// If normin == true, cnorm is an input and cnorm[j] contains the norm of the off-diagonal +// part of the j^th column of A. If trans == blas.NoTrans, cnorm[j] must be greater +// than or equal to the infinity norm, and greater than or equal to the one-norm +// otherwise. If normin == false, then cnorm is treated as an output, and is set +// to contain the 1-norm of the off-diagonal part of the j^th column of A. +// +// Dlatrs is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dlatrs(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, normin bool, n int, a []float64, lda int, x []float64, cnorm []float64) (scale float64) { + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + if trans != blas.Trans && trans != blas.NoTrans { + panic(badTrans) + } + if diag != blas.Unit && diag != blas.NonUnit { + panic(badDiag) + } + upper := uplo == blas.Upper + noTrans := trans == blas.NoTrans + nonUnit := diag == blas.NonUnit + + if n < 0 { + panic(nLT0) + } + checkMatrix(n, n, a, lda) + checkVector(n, x, 1) + checkVector(n, cnorm, 1) + + if n == 0 { + return 0 + } + smlnum := dlamchS / dlamchP + bignum := 1 / smlnum + scale = 1 + bi := blas64.Implementation() + if !normin { + if upper { + cnorm[0] = 0 + for j := 1; j < n; j++ { + cnorm[j] = bi.Dasum(j, a[j:], lda) + } + } else { + for j := 0; j < n-1; j++ { + cnorm[j] = bi.Dasum(n-j-1, a[(j+1)*lda+j:], lda) + } + cnorm[n-1] = 0 + } + } + // Scale the column norms by tscal if the maximum element in cnorm is greater than bignum. + imax := bi.Idamax(n, cnorm, 1) + tmax := cnorm[imax] + var tscal float64 + if tmax <= bignum { + tscal = 1 + } else { + tscal = 1 / (smlnum * tmax) + bi.Dscal(n, tscal, cnorm, 1) + } + + // Compute a bound on the computed solution vector to see if bi.Dtrsv can be used. + j := bi.Idamax(n, x, 1) + xmax := math.Abs(x[j]) + xbnd := xmax + var grow float64 + var jfirst, jlast, jinc int + if noTrans { + if upper { + jfirst = n - 1 + jlast = -1 + jinc = -1 + } else { + jfirst = 0 + jlast = n + jinc = 1 + } + // Compute the growth in A * x = b. + if tscal != 1 { + grow = 0 + goto Solve + } + if nonUnit { + grow = 1 / math.Max(xbnd, smlnum) + xbnd = grow + for j := jfirst; j != jlast; j += jinc { + if grow <= smlnum { + goto Solve + } + tjj := math.Abs(a[j*lda+j]) + xbnd = math.Min(xbnd, math.Min(1, tjj)*grow) + if tjj+cnorm[j] >= smlnum { + grow *= tjj / (tjj + cnorm[j]) + } else { + grow = 0 + } + } + grow = xbnd + } else { + grow = math.Min(1, 1/math.Max(xbnd, smlnum)) + for j := jfirst; j != jlast; j += jinc { + if grow <= smlnum { + goto Solve + } + grow *= 1 / (1 + cnorm[j]) + } + } + } else { + if upper { + jfirst = 0 + jlast = n + jinc = 1 + } else { + jfirst = n - 1 + jlast = -1 + jinc = -1 + } + if tscal != 1 { + grow = 0 + goto Solve + } + if nonUnit { + grow = 1 / (math.Max(xbnd, smlnum)) + xbnd = grow + for j := jfirst; j != jlast; j += jinc { + if grow <= smlnum { + goto Solve + } + xj := 1 + cnorm[j] + grow = math.Min(grow, xbnd/xj) + tjj := math.Abs(a[j*lda+j]) + if xj > tjj { + xbnd *= tjj / xj + } + } + grow = math.Min(grow, xbnd) + } else { + grow = math.Min(1, 1/math.Max(xbnd, smlnum)) + for j := jfirst; j != jlast; j += jinc { + if grow <= smlnum { + goto Solve + } + xj := 1 + cnorm[j] + grow /= xj + } + } + } + +Solve: + if grow*tscal > smlnum { + // Use the Level 2 BLAS solve if the reciprocal of the bound on + // elements of X is not too small. + bi.Dtrsv(uplo, trans, diag, n, a, lda, x, 1) + if tscal != 1 { + bi.Dscal(n, 1/tscal, cnorm, 1) + } + return scale + } + + // Use a Level 1 BLAS solve, scaling intermediate results. + if xmax > bignum { + scale = bignum / xmax + bi.Dscal(n, scale, x, 1) + xmax = bignum + } + if noTrans { + for j := jfirst; j != jlast; j += jinc { + xj := math.Abs(x[j]) + var tjj, tjjs float64 + if nonUnit { + tjjs = a[j*lda+j] * tscal + } else { + tjjs = tscal + if tscal == 1 { + goto Skip1 + } + } + tjj = math.Abs(tjjs) + if tjj > smlnum { + if tjj < 1 { + if xj > tjj*bignum { + rec := 1 / xj + bi.Dscal(n, rec, x, 1) + scale *= rec + xmax *= rec + } + } + x[j] /= tjjs + xj = math.Abs(x[j]) + } else if tjj > 0 { + if xj > tjj*bignum { + rec := (tjj * bignum) / xj + if cnorm[j] > 1 { + rec /= cnorm[j] + } + bi.Dscal(n, rec, x, 1) + scale *= rec + xmax *= rec + } + x[j] /= tjjs + xj = math.Abs(x[j]) + } else { + for i := 0; i < n; i++ { + x[i] = 0 + } + x[j] = 1 + xj = 1 + scale = 0 + xmax = 0 + } + Skip1: + if xj > 1 { + rec := 1 / xj + if cnorm[j] > (bignum-xmax)*rec { + rec *= 0.5 + bi.Dscal(n, rec, x, 1) + scale *= rec + } + } else if xj*cnorm[j] > bignum-xmax { + bi.Dscal(n, 0.5, x, 1) + scale *= 0.5 + } + if upper { + if j > 0 { + bi.Daxpy(j, -x[j]*tscal, a[j:], lda, x, 1) + i := bi.Idamax(j, x, 1) + xmax = math.Abs(x[i]) + } + } else { + if j < n-1 { + bi.Daxpy(n-j-1, -x[j]*tscal, a[(j+1)*lda+j:], lda, x[j+1:], 1) + i := j + bi.Idamax(n-j-1, x[j+1:], 1) + xmax = math.Abs(x[i]) + } + } + } + } else { + for j := jfirst; j != jlast; j += jinc { + xj := math.Abs(x[j]) + uscal := tscal + rec := 1 / math.Max(xmax, 1) + var tjjs float64 + if cnorm[j] > (bignum-xj)*rec { + rec *= 0.5 + if nonUnit { + tjjs = a[j*lda+j] * tscal + } else { + tjjs = tscal + } + tjj := math.Abs(tjjs) + if tjj > 1 { + rec = math.Min(1, rec*tjj) + uscal /= tjjs + } + if rec < 1 { + bi.Dscal(n, rec, x, 1) + scale *= rec + xmax *= rec + } + } + var sumj float64 + if uscal == 1 { + if upper { + sumj = bi.Ddot(j, a[j:], lda, x, 1) + } else if j < n-1 { + sumj = bi.Ddot(n-j-1, a[(j+1)*lda+j:], lda, x[j+1:], 1) + } + } else { + if upper { + for i := 0; i < j; i++ { + sumj += (a[i*lda+j] * uscal) * x[i] + } + } else if j < n { + for i := j + 1; i < n; i++ { + sumj += (a[i*lda+j] * uscal) * x[i] + } + } + } + if uscal == tscal { + x[j] -= sumj + xj := math.Abs(x[j]) + var tjjs float64 + if nonUnit { + tjjs = a[j*lda+j] * tscal + } else { + tjjs = tscal + if tscal == 1 { + goto Skip2 + } + } + tjj := math.Abs(tjjs) + if tjj > smlnum { + if tjj < 1 { + if xj > tjj*bignum { + rec = 1 / xj + bi.Dscal(n, rec, x, 1) + scale *= rec + xmax *= rec + } + } + x[j] /= tjjs + } else if tjj > 0 { + if xj > tjj*bignum { + rec = (tjj * bignum) / xj + bi.Dscal(n, rec, x, 1) + scale *= rec + xmax *= rec + } + x[j] /= tjjs + } else { + for i := 0; i < n; i++ { + x[i] = 0 + } + x[j] = 1 + scale = 0 + xmax = 0 + } + } else { + x[j] = x[j]/tjjs - sumj + } + Skip2: + xmax = math.Max(xmax, math.Abs(x[j])) + } + } + scale /= tscal + if tscal != 1 { + bi.Dscal(n, 1/tscal, cnorm, 1) + } + return scale +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/doc.go b/vendor/gonum.org/v1/gonum/lapack/gonum/doc.go new file mode 100644 index 00000000..f69b4285 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/doc.go @@ -0,0 +1,28 @@ +// 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 is a pure-go implementation of the LAPACK API. The LAPACK API defines +// a set of algorithms for advanced matrix operations. +// +// The function definitions and implementations follow that of the netlib reference +// implementation. Please see http://www.netlib.org/lapack/explore-html/ for more +// information, and http://www.netlib.org/lapack/explore-html/d4/de1/_l_i_c_e_n_s_e_source.html +// for more license information. +// +// Slice function arguments frequently represent vectors and matrices. The data +// layout is identical to that found in https://godoc.org/gonum.org/v1/gonum/blas/gonum. +// +// Most LAPACK functions are built on top the routines defined in the BLAS API, +// and as such the computation time for many LAPACK functions is +// dominated by BLAS calls. Here, BLAS is accessed through the +// the blas64 package (https://godoc.org/golang.org/v1/gonum/blas/blas64). In particular, +// this implies that an external BLAS library will be used if it is +// registered in blas64. +// +// The full LAPACK capability has not been implemented at present. The full +// API is very large, containing approximately 200 functions for double precision +// alone. Future additions will be focused on supporting the gonum matrix +// package (https://godoc.org/github.com/gonum/matrix/mat64), though pull requests +// with implementations and tests for LAPACK function are encouraged. +package gonum // import "gonum.org/v1/gonum/lapack/gonum" diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorg2l.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorg2l.go new file mode 100644 index 00000000..728924f6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorg2l.go @@ -0,0 +1,65 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dorg2l generates an m×n matrix Q with orthonormal columns which is defined +// as the last n columns of a product of k elementary reflectors of order m. +// Q = H_{k-1} * ... * H_1 * H_0 +// See Dgelqf for more information. It must be that m >= n >= k. +// +// tau contains the scalar reflectors computed by Dgeqlf. tau must have length +// at least k, and Dorg2l will panic otherwise. +// +// work contains temporary memory, and must have length at least n. Dorg2l will +// panic otherwise. +// +// Dorg2l is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorg2l(m, n, k int, a []float64, lda int, tau, work []float64) { + checkMatrix(m, n, a, lda) + if len(tau) < k { + panic(badTau) + } + if len(work) < n { + panic(badWork) + } + if m < n { + panic(mLTN) + } + if k > n { + panic(kGTN) + } + if n == 0 { + return + } + + // Initialize columns 0:n-k to columns of the unit matrix. + for j := 0; j < n-k; j++ { + for l := 0; l < m; l++ { + a[l*lda+j] = 0 + } + a[(m-n+j)*lda+j] = 1 + } + + bi := blas64.Implementation() + for i := 0; i < k; i++ { + ii := n - k + i + + // Apply H_i to A[0:m-k+i, 0:n-k+i] from the left. + a[(m-n+ii)*lda+ii] = 1 + impl.Dlarf(blas.Left, m-n+ii+1, ii, a[ii:], lda, tau[i], a, lda, work) + bi.Dscal(m-n+ii, -tau[i], a[ii:], lda) + a[(m-n+ii)*lda+ii] = 1 - tau[i] + + // Set A[m-k+i:m, n-k+i+1] to zero. + for l := m - n + ii + 1; l < m; l++ { + a[l*lda+ii] = 0 + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorg2r.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorg2r.go new file mode 100644 index 00000000..25f0ee54 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorg2r.go @@ -0,0 +1,65 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dorg2r generates an m×n matrix Q with orthonormal columns defined by the +// product of elementary reflectors as computed by Dgeqrf. +// Q = H_0 * H_1 * ... * H_{k-1} +// len(tau) >= k, 0 <= k <= n, 0 <= n <= m, len(work) >= n. +// Dorg2r will panic if these conditions are not met. +// +// Dorg2r is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorg2r(m, n, k int, a []float64, lda int, tau []float64, work []float64) { + checkMatrix(m, n, a, lda) + if len(tau) < k { + panic(badTau) + } + if len(work) < n { + panic(badWork) + } + if k > n { + panic(kGTN) + } + if n > m { + panic(mLTN) + } + if len(work) < n { + panic(badWork) + } + if n == 0 { + return + } + bi := blas64.Implementation() + // Initialize columns k+1:n to columns of the unit matrix. + for l := 0; l < m; l++ { + for j := k; j < n; j++ { + a[l*lda+j] = 0 + } + } + for j := k; j < n; j++ { + a[j*lda+j] = 1 + } + for i := k - 1; i >= 0; i-- { + for i := range work { + work[i] = 0 + } + if i < n-1 { + a[i*lda+i] = 1 + impl.Dlarf(blas.Left, m-i, n-i-1, a[i*lda+i:], lda, tau[i], a[i*lda+i+1:], lda, work) + } + if i < m-1 { + bi.Dscal(m-i-1, -tau[i], a[(i+1)*lda+i:], lda) + } + a[i*lda+i] = 1 - tau[i] + for l := 0; l < i; l++ { + a[l*lda+i] = 0 + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorgbr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgbr.go new file mode 100644 index 00000000..b8789661 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgbr.go @@ -0,0 +1,124 @@ +// 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/lapack" + +// Dorgbr generates one of the matrices Q or P^T computed by Dgebrd +// computed from the decomposition Dgebrd. See Dgebd2 for the description of +// Q and P^T. +// +// If vect == lapack.ApplyQ, then a is assumed to have been an m×k matrix and +// Q is of order m. If m >= k, then Dorgbr returns the first n columns of Q +// where m >= n >= k. If m < k, then Dorgbr returns Q as an m×m matrix. +// +// If vect == lapack.ApplyP, then A is assumed to have been a k×n matrix, and +// P^T is of order n. If k < n, then Dorgbr returns the first m rows of P^T, +// where n >= m >= k. If k >= n, then Dorgbr returns P^T as an n×n matrix. +// +// Dorgbr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorgbr(vect lapack.DecompUpdate, m, n, k int, a []float64, lda int, tau, work []float64, lwork int) { + mn := min(m, n) + wantq := vect == lapack.ApplyQ + if wantq { + if m < n || n < min(m, k) || m < min(m, k) { + panic(badDims) + } + } else { + if n < m || m < min(n, k) || n < min(n, k) { + panic(badDims) + } + } + if wantq { + if m >= k { + checkMatrix(m, k, a, lda) + } else { + checkMatrix(m, m, a, lda) + } + } else { + if n >= k { + checkMatrix(k, n, a, lda) + } else { + checkMatrix(n, n, a, lda) + } + } + work[0] = 1 + if wantq { + if m >= k { + impl.Dorgqr(m, n, k, a, lda, tau, work, -1) + } else if m > 1 { + impl.Dorgqr(m-1, m-1, m-1, a[lda+1:], lda, tau, work, -1) + } + } else { + if k < n { + impl.Dorglq(m, n, k, a, lda, tau, work, -1) + } else if n > 1 { + impl.Dorglq(n-1, n-1, n-1, a[lda+1:], lda, tau, work, -1) + } + } + lworkopt := int(work[0]) + lworkopt = max(lworkopt, mn) + if lwork == -1 { + work[0] = float64(lworkopt) + return + } + if len(work) < lwork { + panic(badWork) + } + if lwork < mn { + panic(badWork) + } + if m == 0 || n == 0 { + work[0] = 1 + return + } + if wantq { + // Form Q, determined by a call to Dgebrd to reduce an m×k matrix. + if m >= k { + impl.Dorgqr(m, n, k, a, lda, tau, work, lwork) + } else { + // Shift the vectors which define the elementary reflectors one + // column to the right, and set the first row and column of Q to + // those of the unit matrix. + for j := m - 1; j >= 1; j-- { + a[j] = 0 + for i := j + 1; i < m; i++ { + a[i*lda+j] = a[i*lda+j-1] + } + } + a[0] = 1 + for i := 1; i < m; i++ { + a[i*lda] = 0 + } + if m > 1 { + // Form Q[1:m-1, 1:m-1] + impl.Dorgqr(m-1, m-1, m-1, a[lda+1:], lda, tau, work, lwork) + } + } + } else { + // Form P^T, determined by a call to Dgebrd to reduce a k×n matrix. + if k < n { + impl.Dorglq(m, n, k, a, lda, tau, work, lwork) + } else { + // Shift the vectors which define the elementary reflectors one + // row downward, and set the first row and column of P^T to + // those of the unit matrix. + a[0] = 1 + for i := 1; i < n; i++ { + a[i*lda] = 0 + } + for j := 1; j < n; j++ { + for i := j - 1; i >= 1; i-- { + a[i*lda+j] = a[(i-1)*lda+j] + } + a[j] = 0 + } + if n > 1 { + impl.Dorglq(n-1, n-1, n-1, a[lda+1:], lda, tau, work, lwork) + } + } + } + work[0] = float64(lworkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorghr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorghr.go new file mode 100644 index 00000000..dcdc0dec --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorghr.go @@ -0,0 +1,93 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +// Dorghr generates an n×n orthogonal matrix Q which is defined as the product +// of ihi-ilo elementary reflectors: +// Q = H_{ilo} H_{ilo+1} ... H_{ihi-1}. +// +// a and lda represent an n×n matrix that contains the elementary reflectors, as +// returned by Dgehrd. On return, a is overwritten by the n×n orthogonal matrix +// Q. Q will be equal to the identity matrix except in the submatrix +// Q[ilo+1:ihi+1,ilo+1:ihi+1]. +// +// ilo and ihi must have the same values as in the previous call of Dgehrd. It +// must hold that +// 0 <= ilo <= ihi < n, if n > 0, +// ilo = 0, ihi = -1, if n == 0. +// +// tau contains the scalar factors of the elementary reflectors, as returned by +// Dgehrd. tau must have length n-1. +// +// work must have length at least max(1,lwork) and lwork must be at least +// ihi-ilo. For optimum performance lwork must be at least (ihi-ilo)*nb where nb +// is the optimal blocksize. On return, work[0] will contain the optimal value +// of lwork. +// +// If lwork == -1, instead of performing Dorghr, only the optimal value of lwork +// will be stored into work[0]. +// +// If any requirement on input sizes is not met, Dorghr will panic. +// +// Dorghr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorghr(n, ilo, ihi int, a []float64, lda int, tau, work []float64, lwork int) { + checkMatrix(n, n, a, lda) + nh := ihi - ilo + switch { + case ilo < 0 || max(1, n) <= ilo: + panic(badIlo) + case ihi < min(ilo, n-1) || n <= ihi: + panic(badIhi) + case lwork < max(1, nh) && lwork != -1: + panic(badWork) + case len(work) < max(1, lwork): + panic(shortWork) + } + + lwkopt := max(1, nh) * impl.Ilaenv(1, "DORGQR", " ", nh, nh, nh, -1) + if lwork == -1 { + work[0] = float64(lwkopt) + return + } + + // Quick return if possible. + if n == 0 { + work[0] = 1 + return + } + + // Shift the vectors which define the elementary reflectors one column + // to the right. + for i := ilo + 2; i < ihi+1; i++ { + copy(a[i*lda+ilo+1:i*lda+i], a[i*lda+ilo:i*lda+i-1]) + } + // Set the first ilo+1 and the last n-ihi-1 rows and columns to those of + // the identity matrix. + for i := 0; i < ilo+1; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = 0 + } + a[i*lda+i] = 1 + } + for i := ilo + 1; i < ihi+1; i++ { + for j := 0; j <= ilo; j++ { + a[i*lda+j] = 0 + } + for j := i; j < n; j++ { + a[i*lda+j] = 0 + } + } + for i := ihi + 1; i < n; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = 0 + } + a[i*lda+i] = 1 + } + if nh > 0 { + // Generate Q[ilo+1:ihi+1,ilo+1:ihi+1]. + impl.Dorgqr(nh, nh, nh, a[(ilo+1)*lda+ilo+1:], lda, tau[ilo:ihi], work, lwork) + } + work[0] = float64(lwkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorgl2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgl2.go new file mode 100644 index 00000000..3cdc10b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgl2.go @@ -0,0 +1,63 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dorgl2 generates an m×n matrix Q with orthonormal rows defined by the +// first m rows product of elementary reflectors as computed by Dgelqf. +// Q = H_0 * H_1 * ... * H_{k-1} +// len(tau) >= k, 0 <= k <= m, 0 <= m <= n, len(work) >= m. +// Dorgl2 will panic if these conditions are not met. +// +// Dorgl2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorgl2(m, n, k int, a []float64, lda int, tau, work []float64) { + checkMatrix(m, n, a, lda) + if len(tau) < k { + panic(badTau) + } + if k > m { + panic(kGTM) + } + if k > m { + panic(kGTM) + } + if m > n { + panic(nLTM) + } + if len(work) < m { + panic(badWork) + } + if m == 0 { + return + } + bi := blas64.Implementation() + if k < m { + for i := k; i < m; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = 0 + } + } + for j := k; j < m; j++ { + a[j*lda+j] = 1 + } + } + for i := k - 1; i >= 0; i-- { + if i < n-1 { + if i < m-1 { + a[i*lda+i] = 1 + impl.Dlarf(blas.Right, m-i-1, n-i, a[i*lda+i:], 1, tau[i], a[(i+1)*lda+i:], lda, work) + } + bi.Dscal(n-i-1, -tau[i], a[i*lda+i+1:], 1) + } + a[i*lda+i] = 1 - tau[i] + for l := 0; l < i; l++ { + a[i*lda+l] = 0 + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorglq.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorglq.go new file mode 100644 index 00000000..0535027b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorglq.go @@ -0,0 +1,117 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dorglq generates an m×n matrix Q with orthonormal columns defined by the +// product of elementary reflectors as computed by Dgelqf. +// Q = H_0 * H_1 * ... * H_{k-1} +// Dorglq is the blocked version of Dorgl2 that makes greater use of level-3 BLAS +// routines. +// +// len(tau) >= k, 0 <= k <= n, and 0 <= n <= m. +// +// work is temporary storage, and lwork specifies the usable memory length. At minimum, +// lwork >= m, and the amount of blocking is limited by the usable length. +// If lwork == -1, instead of computing Dorglq the optimal work length is stored +// into work[0]. +// +// Dorglq will panic if the conditions on input values are not met. +// +// Dorglq is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorglq(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) { + nb := impl.Ilaenv(1, "DORGLQ", " ", m, n, k, -1) + // work is treated as an n×nb matrix + if lwork == -1 { + work[0] = float64(max(1, m) * nb) + return + } + checkMatrix(m, n, a, lda) + if k < 0 { + panic(kLT0) + } + if k > m { + panic(kGTM) + } + if m > n { + panic(nLTM) + } + if len(tau) < k { + panic(badTau) + } + if len(work) < lwork { + panic(shortWork) + } + if lwork < m { + panic(badWork) + } + if m == 0 { + return + } + nbmin := 2 // Minimum number of blocks + var nx int // Minimum number of rows + iws := m // Length of work needed + var ldwork int + if nb > 1 && nb < k { + nx = max(0, impl.Ilaenv(3, "DORGLQ", " ", m, n, k, -1)) + if nx < k { + ldwork = nb + iws = m * ldwork + if lwork < iws { + nb = lwork / m + ldwork = nb + nbmin = max(2, impl.Ilaenv(2, "DORGLQ", " ", m, n, k, -1)) + } + } + } + var ki, kk int + if nb >= nbmin && nb < k && nx < k { + // The first kk rows are handled by the blocked method. + // Note: lapack has nx here, but this means the last nx rows are handled + // serially which could be quite different than nb. + ki = ((k - nb - 1) / nb) * nb + kk = min(k, ki+nb) + for i := kk; i < m; i++ { + for j := 0; j < kk; j++ { + a[i*lda+j] = 0 + } + } + } + if kk < m { + // Perform the operation on colums kk to the end. + impl.Dorgl2(m-kk, n-kk, k-kk, a[kk*lda+kk:], lda, tau[kk:], work) + } + if kk == 0 { + return + } + // Perform the operation on column-blocks + for i := ki; i >= 0; i -= nb { + ib := min(nb, k-i) + if i+ib < m { + impl.Dlarft(lapack.Forward, lapack.RowWise, + n-i, ib, + a[i*lda+i:], lda, + tau[i:], + work, ldwork) + + impl.Dlarfb(blas.Right, blas.Trans, lapack.Forward, lapack.RowWise, + m-i-ib, n-i, ib, + a[i*lda+i:], lda, + work, ldwork, + a[(i+ib)*lda+i:], lda, + work[ib*ldwork:], ldwork) + } + impl.Dorgl2(ib, n-i, ib, a[i*lda+i:], lda, tau[i:], work) + for l := i; l < i+ib; l++ { + for j := 0; j < i; j++ { + a[l*lda+j] = 0 + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorgql.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgql.go new file mode 100644 index 00000000..f13bf727 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgql.go @@ -0,0 +1,130 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dorgql generates the m×n matrix Q with orthonormal columns defined as the +// last n columns of a product of k elementary reflectors of order m +// Q = H_{k-1} * ... * H_1 * H_0. +// +// It must hold that +// 0 <= k <= n <= m, +// and Dorgql will panic otherwise. +// +// On entry, the (n-k+i)-th column of A must contain the vector which defines +// the elementary reflector H_i, for i=0,...,k-1, and tau[i] must contain its +// scalar factor. On return, a contains the m×n matrix Q. +// +// tau must have length at least k, and Dorgql will panic otherwise. +// +// work must have length at least max(1,lwork), and lwork must be at least +// max(1,n), otherwise Dorgql will panic. For optimum performance lwork must +// be a sufficiently large multiple of n. +// +// If lwork == -1, instead of computing Dorgql the optimal work length is stored +// into work[0]. +// +// Dorgql is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorgql(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) { + switch { + case n < 0: + panic(nLT0) + case m < n: + panic(mLTN) + case k < 0: + panic(kLT0) + case k > n: + panic(kGTN) + case lwork < max(1, n) && lwork != -1: + panic(badWork) + case len(work) < lwork: + panic(shortWork) + } + if lwork != -1 { + checkMatrix(m, n, a, lda) + if len(tau) < k { + panic(badTau) + } + } + + if n == 0 { + work[0] = 1 + return + } + + nb := impl.Ilaenv(1, "DORGQL", " ", m, n, k, -1) + if lwork == -1 { + work[0] = float64(n * nb) + return + } + + nbmin := 2 + var nx, ldwork int + iws := n + if nb > 1 && nb < k { + // Determine when to cross over from blocked to unblocked code. + nx = max(0, impl.Ilaenv(3, "DORGQL", " ", m, n, k, -1)) + if nx < k { + // Determine if workspace is large enough for blocked code. + iws = n * nb + if lwork < iws { + // Not enough workspace to use optimal nb: reduce nb and determine + // the minimum value of nb. + nb = lwork / n + nbmin = max(2, impl.Ilaenv(2, "DORGQL", " ", m, n, k, -1)) + } + ldwork = nb + } + } + + var kk int + if nb >= nbmin && nb < k && nx < k { + // Use blocked code after the first block. The last kk columns are handled + // by the block method. + kk = min(k, ((k-nx+nb-1)/nb)*nb) + + // Set A(m-kk:m, 0:n-kk) to zero. + for i := m - kk; i < m; i++ { + for j := 0; j < n-kk; j++ { + a[i*lda+j] = 0 + } + } + } + + // Use unblocked code for the first or only block. + impl.Dorg2l(m-kk, n-kk, k-kk, a, lda, tau, work) + if kk > 0 { + // Use blocked code. + for i := k - kk; i < k; i += nb { + ib := min(nb, k-i) + if n-k+i > 0 { + // Form the triangular factor of the block reflector + // H = H_{i+ib-1} * ... * H_{i+1} * H_i. + impl.Dlarft(lapack.Backward, lapack.ColumnWise, m-k+i+ib, ib, + a[n-k+i:], lda, tau[i:], work, ldwork) + + // Apply H to A[0:m-k+i+ib, 0:n-k+i] from the left. + impl.Dlarfb(blas.Left, blas.NoTrans, lapack.Backward, lapack.ColumnWise, + m-k+i+ib, n-k+i, ib, a[n-k+i:], lda, work, ldwork, + a, lda, work[ib*ldwork:], ldwork) + } + + // Apply H to rows 0:m-k+i+ib of current block. + impl.Dorg2l(m-k+i+ib, ib, ib, a[n-k+i:], lda, tau[i:], work) + + // Set rows m-k+i+ib:m of current block to zero. + for j := n - k + i; j < n-k+i+ib; j++ { + for l := m - k + i + ib; l < m; l++ { + a[l*lda+j] = 0 + } + } + } + } + work[0] = float64(iws) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorgqr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgqr.go new file mode 100644 index 00000000..0d525d8a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgqr.go @@ -0,0 +1,120 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dorgqr generates an m×n matrix Q with orthonormal columns defined by the +// product of elementary reflectors +// Q = H_0 * H_1 * ... * H_{k-1} +// as computed by Dgeqrf. +// Dorgqr is the blocked version of Dorg2r that makes greater use of level-3 BLAS +// routines. +// +// The length of tau must be at least k, and the length of work must be at least n. +// It also must be that 0 <= k <= n and 0 <= n <= m. +// +// work is temporary storage, and lwork specifies the usable memory length. At +// minimum, lwork >= n, and the amount of blocking is limited by the usable +// length. If lwork == -1, instead of computing Dorgqr the optimal work length +// is stored into work[0]. +// +// Dorgqr will panic if the conditions on input values are not met. +// +// Dorgqr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorgqr(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) { + nb := impl.Ilaenv(1, "DORGQR", " ", m, n, k, -1) + // work is treated as an n×nb matrix + if lwork == -1 { + work[0] = float64(max(1, n) * nb) + return + } + checkMatrix(m, n, a, lda) + if k < 0 { + panic(kLT0) + } + if k > n { + panic(kGTN) + } + if n > m { + panic(mLTN) + } + if len(tau) < k { + panic(badTau) + } + if len(work) < lwork { + panic(shortWork) + } + if lwork < n { + panic(badWork) + } + if n == 0 { + return + } + nbmin := 2 // Minimum number of blocks + var nx int // Minimum number of rows + iws := n // Length of work needed + var ldwork int + if nb > 1 && nb < k { + nx = max(0, impl.Ilaenv(3, "DORGQR", " ", m, n, k, -1)) + if nx < k { + ldwork = nb + iws = n * ldwork + if lwork < iws { + nb = lwork / n + ldwork = nb + nbmin = max(2, impl.Ilaenv(2, "DORGQR", " ", m, n, k, -1)) + } + } + } + var ki, kk int + if nb >= nbmin && nb < k && nx < k { + // The first kk columns are handled by the blocked method. + // Note: lapack has nx here, but this means the last nx rows are handled + // serially which could be quite different than nb. + ki = ((k - nb - 1) / nb) * nb + kk = min(k, ki+nb) + for j := kk; j < n; j++ { + for i := 0; i < kk; i++ { + a[i*lda+j] = 0 + } + } + } + if kk < n { + // Perform the operation on colums kk to the end. + impl.Dorg2r(m-kk, n-kk, k-kk, a[kk*lda+kk:], lda, tau[kk:], work) + } + if kk == 0 { + return + } + // Perform the operation on column-blocks + for i := ki; i >= 0; i -= nb { + ib := min(nb, k-i) + if i+ib < n { + impl.Dlarft(lapack.Forward, lapack.ColumnWise, + m-i, ib, + a[i*lda+i:], lda, + tau[i:], + work, ldwork) + + impl.Dlarfb(blas.Left, blas.NoTrans, lapack.Forward, lapack.ColumnWise, + m-i, n-i-ib, ib, + a[i*lda+i:], lda, + work, ldwork, + a[i*lda+i+ib:], lda, + work[ib*ldwork:], ldwork) + } + impl.Dorg2r(m-i, ib, ib, a[i*lda+i:], lda, tau[i:], work) + // Set rows 0:i-1 of current block to zero + for j := i; j < i+ib; j++ { + for l := 0; l < i; l++ { + a[l*lda+j] = 0 + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorgtr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgtr.go new file mode 100644 index 00000000..39b7df29 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorgtr.go @@ -0,0 +1,99 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas" + +// Dorgtr generates a real orthogonal matrix Q which is defined as the product +// of n-1 elementary reflectors of order n as returned by Dsytrd. +// +// The construction of Q depends on the value of uplo: +// Q = H_{n-1} * ... * H_1 * H_0 if uplo == blas.Upper +// Q = H_0 * H_1 * ... * H_{n-1} if uplo == blas.Lower +// where H_i is constructed from the elementary reflectors as computed by Dsytrd. +// See the documentation for Dsytrd for more information. +// +// tau must have length at least n-1, and Dorgtr will panic otherwise. +// +// work is temporary storage, and lwork specifies the usable memory length. At +// minimum, lwork >= max(1,n-1), and Dorgtr will panic otherwise. The amount of blocking +// is limited by the usable length. +// If lwork == -1, instead of computing Dorgtr the optimal work length is stored +// into work[0]. +// +// Dorgtr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorgtr(uplo blas.Uplo, n int, a []float64, lda int, tau, work []float64, lwork int) { + checkMatrix(n, n, a, lda) + if len(tau) < n-1 { + panic(badTau) + } + if len(work) < lwork { + panic(badWork) + } + if lwork < n-1 && lwork != -1 { + panic(badWork) + } + upper := uplo == blas.Upper + if !upper && uplo != blas.Lower { + panic(badUplo) + } + + if n == 0 { + work[0] = 1 + return + } + + var nb int + if upper { + nb = impl.Ilaenv(1, "DORGQL", " ", n-1, n-1, n-1, -1) + } else { + nb = impl.Ilaenv(1, "DORGQR", " ", n-1, n-1, n-1, -1) + } + lworkopt := max(1, n-1) * nb + if lwork == -1 { + work[0] = float64(lworkopt) + return + } + + if upper { + // Q was determined by a call to Dsytrd with uplo == blas.Upper. + // Shift the vectors which define the elementary reflectors one column + // to the left, and set the last row and column of Q to those of the unit + // matrix. + for j := 0; j < n-1; j++ { + for i := 0; i < j; i++ { + a[i*lda+j] = a[i*lda+j+1] + } + a[(n-1)*lda+j] = 0 + } + for i := 0; i < n-1; i++ { + a[i*lda+n-1] = 0 + } + a[(n-1)*lda+n-1] = 1 + + // Generate Q[0:n-1, 0:n-1]. + impl.Dorgql(n-1, n-1, n-1, a, lda, tau, work, lwork) + } else { + // Q was determined by a call to Dsytrd with uplo == blas.Upper. + // Shift the vectors which define the elementary reflectors one column + // to the right, and set the first row and column of Q to those of the unit + // matrix. + for j := n - 1; j > 0; j-- { + a[j] = 0 + for i := j + 1; i < n; i++ { + a[i*lda+j] = a[i*lda+j-1] + } + } + a[0] = 1 + for i := 1; i < n; i++ { + a[i*lda] = 0 + } + if n > 1 { + // Generate Q[1:n, 1:n]. + impl.Dorgqr(n-1, n-1, n-1, a[lda+1:], lda, tau, work, lwork) + } + } + work[0] = float64(lworkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorm2r.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorm2r.go new file mode 100644 index 00000000..15864fcc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorm2r.go @@ -0,0 +1,88 @@ +// 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/blas" + +// Dorm2r multiplies a general matrix C by an orthogonal matrix from a QR factorization +// determined by Dgeqrf. +// C = Q * C if side == blas.Left and trans == blas.NoTrans +// C = Q^T * C if side == blas.Left and trans == blas.Trans +// C = C * Q if side == blas.Right and trans == blas.NoTrans +// C = C * Q^T if side == blas.Right and trans == blas.Trans +// If side == blas.Left, a is a matrix of size m×k, and if side == blas.Right +// a is of size n×k. +// +// tau contains the Householder factors and is of length at least k and this function +// will panic otherwise. +// +// work is temporary storage of length at least n if side == blas.Left +// and at least m if side == blas.Right and this function will panic otherwise. +// +// Dorm2r is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorm2r(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) { + if side != blas.Left && side != blas.Right { + panic(badSide) + } + if trans != blas.Trans && trans != blas.NoTrans { + panic(badTrans) + } + + left := side == blas.Left + notran := trans == blas.NoTrans + if left { + // Q is m x m + checkMatrix(m, k, a, lda) + if len(work) < n { + panic(badWork) + } + } else { + // Q is n x n + checkMatrix(n, k, a, lda) + if len(work) < m { + panic(badWork) + } + } + checkMatrix(m, n, c, ldc) + if m == 0 || n == 0 || k == 0 { + return + } + if len(tau) < k { + panic(badTau) + } + if left { + if notran { + for i := k - 1; i >= 0; i-- { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m-i, n, a[i*lda+i:], lda, tau[i], c[i*ldc:], ldc, work) + a[i*lda+i] = aii + } + return + } + for i := 0; i < k; i++ { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m-i, n, a[i*lda+i:], lda, tau[i], c[i*ldc:], ldc, work) + a[i*lda+i] = aii + } + return + } + if notran { + for i := 0; i < k; i++ { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m, n-i, a[i*lda+i:], lda, tau[i], c[i:], ldc, work) + a[i*lda+i] = aii + } + return + } + for i := k - 1; i >= 0; i-- { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m, n-i, a[i*lda+i:], lda, tau[i], c[i:], ldc, work) + a[i*lda+i] = aii + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dormbr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dormbr.go new file mode 100644 index 00000000..6518c186 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dormbr.go @@ -0,0 +1,158 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dormbr applies a multiplicative update to the matrix C based on a +// decomposition computed by Dgebrd. +// +// Dormbr overwrites the m×n matrix C with +// Q * C if vect == lapack.ApplyQ, side == blas.Left, and trans == blas.NoTrans +// C * Q if vect == lapack.ApplyQ, side == blas.Right, and trans == blas.NoTrans +// Q^T * C if vect == lapack.ApplyQ, side == blas.Left, and trans == blas.Trans +// C * Q^T if vect == lapack.ApplyQ, side == blas.Right, and trans == blas.Trans +// +// P * C if vect == lapack.ApplyP, side == blas.Left, and trans == blas.NoTrans +// C * P if vect == lapack.ApplyP, side == blas.Right, and trans == blas.NoTrans +// P^T * C if vect == lapack.ApplyP, side == blas.Left, and trans == blas.Trans +// C * P^T if vect == lapack.ApplyP, side == blas.Right, and trans == blas.Trans +// where P and Q are the orthogonal matrices determined by Dgebrd when reducing +// a matrix A to bidiagonal form: A = Q * B * P^T. See Dgebrd for the +// definitions of Q and P. +// +// If vect == lapack.ApplyQ, A is assumed to have been an nq×k matrix, while if +// vect == lapack.ApplyP, A is assumed to have been a k×nq matrix. nq = m if +// side == blas.Left, while nq = n if side == blas.Right. +// +// tau must have length min(nq,k), and Dormbr will panic otherwise. tau contains +// the elementary reflectors to construct Q or P depending on the value of +// vect. +// +// work must have length at least max(1,lwork), and lwork must be either -1 or +// at least max(1,n) if side == blas.Left, and at least max(1,m) if side == +// blas.Right. For optimum performance lwork should be at least n*nb if side == +// blas.Left, and at least m*nb if side == blas.Right, where nb is the optimal +// block size. On return, work[0] will contain the optimal value of lwork. +// +// If lwork == -1, the function only calculates the optimal value of lwork and +// returns it in work[0]. +// +// Dormbr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dormbr(vect lapack.DecompUpdate, side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) { + if side != blas.Left && side != blas.Right { + panic(badSide) + } + if trans != blas.NoTrans && trans != blas.Trans { + panic(badTrans) + } + if vect != lapack.ApplyP && vect != lapack.ApplyQ { + panic(badDecompUpdate) + } + nq := n + nw := m + if side == blas.Left { + nq = m + nw = n + } + if vect == lapack.ApplyQ { + checkMatrix(nq, min(nq, k), a, lda) + } else { + checkMatrix(min(nq, k), nq, a, lda) + } + if len(tau) < min(nq, k) { + panic(badTau) + } + checkMatrix(m, n, c, ldc) + if len(work) < lwork { + panic(shortWork) + } + if lwork < max(1, nw) && lwork != -1 { + panic(badWork) + } + + applyQ := vect == lapack.ApplyQ + left := side == blas.Left + var nb int + + // The current implementation does not use opts, but a future change may + // use these options so construct them. + var opts string + if side == blas.Left { + opts = "L" + } else { + opts = "R" + } + if trans == blas.Trans { + opts += "T" + } else { + opts += "N" + } + if applyQ { + if left { + nb = impl.Ilaenv(1, "DORMQR", opts, m-1, n, m-1, -1) + } else { + nb = impl.Ilaenv(1, "DORMQR", opts, m, n-1, n-1, -1) + } + } else { + if left { + nb = impl.Ilaenv(1, "DORMLQ", opts, m-1, n, m-1, -1) + } else { + nb = impl.Ilaenv(1, "DORMLQ", opts, m, n-1, n-1, -1) + } + } + lworkopt := max(1, nw) * nb + if lwork == -1 { + work[0] = float64(lworkopt) + } + if applyQ { + // Change the operation to get Q depending on the size of the initial + // matrix to Dgebrd. The size matters due to the storage location of + // the off-diagonal elements. + if nq >= k { + impl.Dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork) + } else if nq > 1 { + mi := m + ni := n - 1 + i1 := 0 + i2 := 1 + if left { + mi = m - 1 + ni = n + i1 = 1 + i2 = 0 + } + impl.Dormqr(side, trans, mi, ni, nq-1, a[1*lda:], lda, tau[:nq-1], c[i1*ldc+i2:], ldc, work, lwork) + } + work[0] = float64(lworkopt) + return + } + transt := blas.Trans + if trans == blas.Trans { + transt = blas.NoTrans + } + // Change the operation to get P depending on the size of the initial + // matrix to Dgebrd. The size matters due to the storage location of + // the off-diagonal elements. + if nq > k { + impl.Dormlq(side, transt, m, n, k, a, lda, tau, c, ldc, work, lwork) + } else if nq > 1 { + mi := m + ni := n - 1 + i1 := 0 + i2 := 1 + if left { + mi = m - 1 + ni = n + i1 = 1 + i2 = 0 + } + impl.Dormlq(side, transt, mi, ni, nq-1, a[1:], lda, tau, c[i1*ldc+i2:], ldc, work, lwork) + } + work[0] = float64(lworkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dormhr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dormhr.go new file mode 100644 index 00000000..fccb5738 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dormhr.go @@ -0,0 +1,121 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/blas" + +// Dormhr multiplies an m×n general matrix C with an nq×nq orthogonal matrix Q +// Q * C, if side == blas.Left and trans == blas.NoTrans, +// Q^T * C, if side == blas.Left and trans == blas.Trans, +// C * Q, if side == blas.Right and trans == blas.NoTrans, +// C * Q^T, if side == blas.Right and trans == blas.Trans, +// where nq == m if side == blas.Left and nq == n if side == blas.Right. +// +// Q is defined implicitly as the product of ihi-ilo elementary reflectors, as +// returned by Dgehrd: +// Q = H_{ilo} H_{ilo+1} ... H_{ihi-1}. +// Q is equal to the identity matrix except in the submatrix +// Q[ilo+1:ihi+1,ilo+1:ihi+1]. +// +// ilo and ihi must have the same values as in the previous call of Dgehrd. It +// must hold that +// 0 <= ilo <= ihi < m, if m > 0 and side == blas.Left, +// ilo = 0 and ihi = -1, if m = 0 and side == blas.Left, +// 0 <= ilo <= ihi < n, if n > 0 and side == blas.Right, +// ilo = 0 and ihi = -1, if n = 0 and side == blas.Right. +// +// a and lda represent an m×m matrix if side == blas.Left and an n×n matrix if +// side == blas.Right. The matrix contains vectors which define the elementary +// reflectors, as returned by Dgehrd. +// +// tau contains the scalar factors of the elementary reflectors, as returned by +// Dgehrd. tau must have length m-1 if side == blas.Left and n-1 if side == +// blas.Right. +// +// c and ldc represent the m×n matrix C. On return, c is overwritten by the +// product with Q. +// +// work must have length at least max(1,lwork), and lwork must be at least +// max(1,n), if side == blas.Left, and max(1,m), if side == blas.Right. For +// optimum performance lwork should be at least n*nb if side == blas.Left and +// m*nb if side == blas.Right, where nb is the optimal block size. On return, +// work[0] will contain the optimal value of lwork. +// +// If lwork == -1, instead of performing Dormhr, only the optimal value of lwork +// will be stored in work[0]. +// +// If any requirement on input sizes is not met, Dormhr will panic. +// +// Dormhr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dormhr(side blas.Side, trans blas.Transpose, m, n, ilo, ihi int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) { + var ( + nq int // The order of Q. + nw int // The minimum length of work. + ) + switch side { + case blas.Left: + nq = m + nw = n + case blas.Right: + nq = n + nw = m + default: + panic(badSide) + } + switch { + case trans != blas.NoTrans && trans != blas.Trans: + panic(badTrans) + case ilo < 0 || max(1, nq) <= ilo: + panic(badIlo) + case ihi < min(ilo, nq-1) || nq <= ihi: + panic(badIhi) + case lwork < max(1, nw) && lwork != -1: + panic(badWork) + case len(work) < max(1, lwork): + panic(shortWork) + } + if lwork != -1 { + checkMatrix(m, n, c, ldc) + checkMatrix(nq, nq, a, lda) + if len(tau) != nq-1 && nq > 0 { + panic(badTau) + } + + } + + nh := ihi - ilo + var nb int + if side == blas.Left { + opts := "LN" + if trans == blas.Trans { + opts = "LT" + } + nb = impl.Ilaenv(1, "DORMQR", opts, nh, n, nh, -1) + } else { + opts := "RN" + if trans == blas.Trans { + opts = "RT" + } + nb = impl.Ilaenv(1, "DORMQR", opts, m, nh, nh, -1) + } + lwkopt := max(1, nw) * nb + if lwork == -1 { + work[0] = float64(lwkopt) + return + } + + if m == 0 || n == 0 || nh == 0 { + work[0] = 1 + return + } + if side == blas.Left { + impl.Dormqr(side, trans, nh, n, nh, a[(ilo+1)*lda+ilo:], lda, + tau[ilo:ihi], c[(ilo+1)*ldc:], ldc, work, lwork) + } else { + impl.Dormqr(side, trans, m, nh, nh, a[(ilo+1)*lda+ilo:], lda, + tau[ilo:ihi], c[ilo+1:], ldc, work, lwork) + } + work[0] = float64(lwkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dorml2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dorml2.go new file mode 100644 index 00000000..7c5f1950 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dorml2.go @@ -0,0 +1,83 @@ +// 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/blas" + +// Dorml2 multiplies a general matrix C by an orthogonal matrix from an LQ factorization +// determined by Dgelqf. +// C = Q * C if side == blas.Left and trans == blas.NoTrans +// C = Q^T * C if side == blas.Left and trans == blas.Trans +// C = C * Q if side == blas.Right and trans == blas.NoTrans +// C = C * Q^T if side == blas.Right and trans == blas.Trans +// If side == blas.Left, a is a matrix of side k×m, and if side == blas.Right +// a is of size k×n. +// +// tau contains the Householder factors and is of length at least k and this function will +// panic otherwise. +// +// work is temporary storage of length at least n if side == blas.Left +// and at least m if side == blas.Right and this function will panic otherwise. +// +// Dorml2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dorml2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) { + if side != blas.Left && side != blas.Right { + panic(badSide) + } + if trans != blas.Trans && trans != blas.NoTrans { + panic(badTrans) + } + + left := side == blas.Left + notran := trans == blas.NoTrans + if left { + checkMatrix(k, m, a, lda) + if len(work) < n { + panic(badWork) + } + } else { + checkMatrix(k, n, a, lda) + if len(work) < m { + panic(badWork) + } + } + checkMatrix(m, n, c, ldc) + if m == 0 || n == 0 || k == 0 { + return + } + switch { + case left && notran: + for i := 0; i < k; i++ { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m-i, n, a[i*lda+i:], 1, tau[i], c[i*ldc:], ldc, work) + a[i*lda+i] = aii + } + + case left && !notran: + for i := k - 1; i >= 0; i-- { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m-i, n, a[i*lda+i:], 1, tau[i], c[i*ldc:], ldc, work) + a[i*lda+i] = aii + } + + case !left && notran: + for i := k - 1; i >= 0; i-- { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m, n-i, a[i*lda+i:], 1, tau[i], c[i:], ldc, work) + a[i*lda+i] = aii + } + + case !left && !notran: + for i := 0; i < k; i++ { + aii := a[i*lda+i] + a[i*lda+i] = 1 + impl.Dlarf(side, m, n-i, a[i*lda+i:], 1, tau[i], c[i:], ldc, work) + a[i*lda+i] = aii + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dormlq.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dormlq.go new file mode 100644 index 00000000..12219d20 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dormlq.go @@ -0,0 +1,159 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dormlq multiplies the matrix C by the orthogonal matrix Q defined by the +// slices a and tau. A and tau are as returned from Dgelqf. +// C = Q * C if side == blas.Left and trans == blas.NoTrans +// C = Q^T * C if side == blas.Left and trans == blas.Trans +// C = C * Q if side == blas.Right and trans == blas.NoTrans +// C = C * Q^T if side == blas.Right and trans == blas.Trans +// If side == blas.Left, A is a matrix of side k×m, and if side == blas.Right +// A is of size k×n. This uses a blocked algorithm. +// +// work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= m if side == blas.Left and lwork >= n if side == blas.Right, +// and this function will panic otherwise. +// Dormlq uses a block algorithm, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Dormlq, +// the optimal work length will be stored into work[0]. +// +// tau contains the Householder scales and must have length at least k, and +// this function will panic otherwise. +func (impl Implementation) Dormlq(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) { + if side != blas.Left && side != blas.Right { + panic(badSide) + } + if trans != blas.Trans && trans != blas.NoTrans { + panic(badTrans) + } + left := side == blas.Left + if left { + checkMatrix(k, m, a, lda) + } else { + checkMatrix(k, n, a, lda) + } + checkMatrix(m, n, c, ldc) + if len(tau) < k { + panic(badTau) + } + if len(work) < lwork { + panic(shortWork) + } + nw := m + if left { + nw = n + } + if lwork < max(1, nw) && lwork != -1 { + panic(badWork) + } + + if m == 0 || n == 0 || k == 0 { + work[0] = 1 + return + } + + const ( + nbmax = 64 + ldt = nbmax + tsize = nbmax * ldt + ) + opts := string(side) + string(trans) + nb := min(nbmax, impl.Ilaenv(1, "DORMLQ", opts, m, n, k, -1)) + lworkopt := max(1, nw)*nb + tsize + if lwork == -1 { + work[0] = float64(lworkopt) + return + } + + nbmin := 2 + if 1 < nb && nb < k { + iws := nw*nb + tsize + if lwork < iws { + nb = (lwork - tsize) / nw + nbmin = max(2, impl.Ilaenv(2, "DORMLQ", opts, m, n, k, -1)) + } + } + if nb < nbmin || k <= nb { + // Call unblocked code. + impl.Dorml2(side, trans, m, n, k, a, lda, tau, c, ldc, work) + work[0] = float64(lworkopt) + return + } + + t := work[:tsize] + wrk := work[tsize:] + ldwrk := nb + + notran := trans == blas.NoTrans + transt := blas.NoTrans + if notran { + transt = blas.Trans + } + + switch { + case left && notran: + for i := 0; i < k; i += nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.RowWise, m-i, ib, + a[i*lda+i:], lda, + tau[i:], + t, ldt) + impl.Dlarfb(side, transt, lapack.Forward, lapack.RowWise, m-i, n, ib, + a[i*lda+i:], lda, + t, ldt, + c[i*ldc:], ldc, + wrk, ldwrk) + } + + case left && !notran: + for i := ((k - 1) / nb) * nb; i >= 0; i -= nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.RowWise, m-i, ib, + a[i*lda+i:], lda, + tau[i:], + t, ldt) + impl.Dlarfb(side, transt, lapack.Forward, lapack.RowWise, m-i, n, ib, + a[i*lda+i:], lda, + t, ldt, + c[i*ldc:], ldc, + wrk, ldwrk) + } + + case !left && notran: + for i := ((k - 1) / nb) * nb; i >= 0; i -= nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.RowWise, n-i, ib, + a[i*lda+i:], lda, + tau[i:], + t, ldt) + impl.Dlarfb(side, transt, lapack.Forward, lapack.RowWise, m, n-i, ib, + a[i*lda+i:], lda, + t, ldt, + c[i:], ldc, + wrk, ldwrk) + } + + case !left && !notran: + for i := 0; i < k; i += nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.RowWise, n-i, ib, + a[i*lda+i:], lda, + tau[i:], + t, ldt) + impl.Dlarfb(side, transt, lapack.Forward, lapack.RowWise, m, n-i, ib, + a[i*lda+i:], lda, + t, ldt, + c[i:], ldc, + wrk, ldwrk) + } + } + work[0] = float64(lworkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dormqr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dormqr.go new file mode 100644 index 00000000..9a02b90d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dormqr.go @@ -0,0 +1,167 @@ +// 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/blas" + "gonum.org/v1/gonum/lapack" +) + +// Dormqr multiplies an m×n matrix C by an orthogonal matrix Q as +// C = Q * C, if side == blas.Left and trans == blas.NoTrans, +// C = Q^T * C, if side == blas.Left and trans == blas.Trans, +// C = C * Q, if side == blas.Right and trans == blas.NoTrans, +// C = C * Q^T, if side == blas.Right and trans == blas.Trans, +// where Q is defined as the product of k elementary reflectors +// Q = H_0 * H_1 * ... * H_{k-1}. +// +// If side == blas.Left, A is an m×k matrix and 0 <= k <= m. +// If side == blas.Right, A is an n×k matrix and 0 <= k <= n. +// The ith column of A contains the vector which defines the elementary +// reflector H_i and tau[i] contains its scalar factor. tau must have length k +// and Dormqr will panic otherwise. Dgeqrf returns A and tau in the required +// form. +// +// work must have length at least max(1,lwork), and lwork must be at least n if +// side == blas.Left and at least m if side == blas.Right, otherwise Dormqr will +// panic. +// +// work is temporary storage, and lwork specifies the usable memory length. At +// minimum, lwork >= m if side == blas.Left and lwork >= n if side == +// blas.Right, and this function will panic otherwise. Larger values of lwork +// will generally give better performance. On return, work[0] will contain the +// optimal value of lwork. +// +// If lwork is -1, instead of performing Dormqr, the optimal workspace size will +// be stored into work[0]. +func (impl Implementation) Dormqr(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) { + var nq, nw int + switch side { + default: + panic(badSide) + case blas.Left: + nq = m + nw = n + case blas.Right: + nq = n + nw = m + } + switch { + case trans != blas.NoTrans && trans != blas.Trans: + panic(badTrans) + case m < 0 || n < 0: + panic(negDimension) + case k < 0 || nq < k: + panic("lapack: invalid value of k") + case len(work) < lwork: + panic(shortWork) + case lwork < max(1, nw) && lwork != -1: + panic(badWork) + } + if lwork != -1 { + checkMatrix(nq, k, a, lda) + checkMatrix(m, n, c, ldc) + if len(tau) != k { + panic(badTau) + } + } + + if m == 0 || n == 0 || k == 0 { + work[0] = 1 + return + } + + const ( + nbmax = 64 + ldt = nbmax + tsize = nbmax * ldt + ) + opts := string(side) + string(trans) + nb := min(nbmax, impl.Ilaenv(1, "DORMQR", opts, m, n, k, -1)) + lworkopt := max(1, nw)*nb + tsize + if lwork == -1 { + work[0] = float64(lworkopt) + return + } + + nbmin := 2 + if 1 < nb && nb < k { + if lwork < nw*nb+tsize { + nb = (lwork - tsize) / nw + nbmin = max(2, impl.Ilaenv(2, "DORMQR", opts, m, n, k, -1)) + } + } + + if nb < nbmin || k <= nb { + // Call unblocked code. + impl.Dorm2r(side, trans, m, n, k, a, lda, tau, c, ldc, work) + work[0] = float64(lworkopt) + return + } + + var ( + ldwork = nb + left = side == blas.Left + notran = trans == blas.NoTrans + ) + switch { + case left && notran: + for i := ((k - 1) / nb) * nb; i >= 0; i -= nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.ColumnWise, m-i, ib, + a[i*lda+i:], lda, + tau[i:], + work[:tsize], ldt) + impl.Dlarfb(side, trans, lapack.Forward, lapack.ColumnWise, m-i, n, ib, + a[i*lda+i:], lda, + work[:tsize], ldt, + c[i*ldc:], ldc, + work[tsize:], ldwork) + } + + case left && !notran: + for i := 0; i < k; i += nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.ColumnWise, m-i, ib, + a[i*lda+i:], lda, + tau[i:], + work[:tsize], ldt) + impl.Dlarfb(side, trans, lapack.Forward, lapack.ColumnWise, m-i, n, ib, + a[i*lda+i:], lda, + work[:tsize], ldt, + c[i*ldc:], ldc, + work[tsize:], ldwork) + } + + case !left && notran: + for i := 0; i < k; i += nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.ColumnWise, n-i, ib, + a[i*lda+i:], lda, + tau[i:], + work[:tsize], ldt) + impl.Dlarfb(side, trans, lapack.Forward, lapack.ColumnWise, m, n-i, ib, + a[i*lda+i:], lda, + work[:tsize], ldt, + c[i:], ldc, + work[tsize:], ldwork) + } + + case !left && !notran: + for i := ((k - 1) / nb) * nb; i >= 0; i -= nb { + ib := min(nb, k-i) + impl.Dlarft(lapack.Forward, lapack.ColumnWise, n-i, ib, + a[i*lda+i:], lda, + tau[i:], + work[:tsize], ldt) + impl.Dlarfb(side, trans, lapack.Forward, lapack.ColumnWise, m, n-i, ib, + a[i*lda+i:], lda, + work[:tsize], ldt, + c[i:], ldc, + work[tsize:], ldwork) + } + } + work[0] = float64(lworkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dormr2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dormr2.go new file mode 100644 index 00000000..c867e8e8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dormr2.go @@ -0,0 +1,93 @@ +// 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/blas" + +// Dormr2 multiplies a general matrix C by an orthogonal matrix from a RQ factorization +// determined by Dgerqf. +// C = Q * C if side == blas.Left and trans == blas.NoTrans +// C = Q^T * C if side == blas.Left and trans == blas.Trans +// C = C * Q if side == blas.Right and trans == blas.NoTrans +// C = C * Q^T if side == blas.Right and trans == blas.Trans +// If side == blas.Left, a is a matrix of size k×m, and if side == blas.Right +// a is of size k×n. +// +// tau contains the Householder factors and is of length at least k and this function +// will panic otherwise. +// +// work is temporary storage of length at least n if side == blas.Left +// and at least m if side == blas.Right and this function will panic otherwise. +// +// Dormr2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dormr2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) { + if side != blas.Left && side != blas.Right { + panic(badSide) + } + if trans != blas.Trans && trans != blas.NoTrans { + panic(badTrans) + } + + left := side == blas.Left + notran := trans == blas.NoTrans + if left { + if k > m { + panic(kGTM) + } + checkMatrix(k, m, a, lda) + if len(work) < n { + panic(badWork) + } + } else { + if k > n { + panic(kGTN) + } + checkMatrix(k, n, a, lda) + if len(work) < m { + panic(badWork) + } + } + if len(tau) < k { + panic(badTau) + } + checkMatrix(m, n, c, ldc) + + if m == 0 || n == 0 || k == 0 { + return + } + if left { + if notran { + for i := k - 1; i >= 0; i-- { + aii := a[i*lda+(m-k+i)] + a[i*lda+(m-k+i)] = 1 + impl.Dlarf(side, m-k+i+1, n, a[i*lda:], 1, tau[i], c, ldc, work) + a[i*lda+(m-k+i)] = aii + } + return + } + for i := 0; i < k; i++ { + aii := a[i*lda+(m-k+i)] + a[i*lda+(m-k+i)] = 1 + impl.Dlarf(side, m-k+i+1, n, a[i*lda:], 1, tau[i], c, ldc, work) + a[i*lda+(m-k+i)] = aii + } + return + } + if notran { + for i := 0; i < k; i++ { + aii := a[i*lda+(n-k+i)] + a[i*lda+(n-k+i)] = 1 + impl.Dlarf(side, m, n-k+i+1, a[i*lda:], 1, tau[i], c, ldc, work) + a[i*lda+(n-k+i)] = aii + } + return + } + for i := k - 1; i >= 0; i-- { + aii := a[i*lda+(n-k+i)] + a[i*lda+(n-k+i)] = 1 + impl.Dlarf(side, m, n-k+i+1, a[i*lda:], 1, tau[i], c, ldc, work) + a[i*lda+(n-k+i)] = aii + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dpbtf2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dpbtf2.go new file mode 100644 index 00000000..6cc5f38f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dpbtf2.go @@ -0,0 +1,97 @@ +// 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/blas/blas64" +) + +// Dpbtf2 computes the Cholesky factorization of a symmetric positive banded +// matrix ab. The matrix ab is n×n with kd diagonal bands. The Cholesky +// factorization computed is +// A = U^T * U if ul == blas.Upper +// A = L * L^T if ul == blas.Lower +// ul also specifies the storage of ab. If ul == blas.Upper, then +// ab is stored as an upper-triangular banded matrix with kd super-diagonals, +// and if ul == blas.Lower, ab is stored as a lower-triangular banded matrix +// with kd sub-diagonals. On exit, the banded matrix U or L is stored in-place +// into ab depending on the value of ul. Dpbtf2 returns whether the factorization +// was successfully completed. +// +// The band storage scheme is illustrated below when n = 6, and kd = 2. +// The resulting Cholesky decomposition is stored in the same elements as the +// input band matrix (a11 becomes u11 or l11, etc.). +// +// ul = blas.Upper +// a11 a12 a13 +// a22 a23 a24 +// a33 a34 a35 +// a44 a45 a46 +// a55 a56 * +// a66 * * +// +// ul = blas.Lower +// * * a11 +// * a21 a22 +// a31 a32 a33 +// a42 a43 a44 +// a53 a54 a55 +// a64 a65 a66 +// +// Dpbtf2 is the unblocked version of the algorithm, see Dpbtrf for the blocked +// version. +// +// Dpbtf2 is an internal routine, exported for testing purposes. +func (Implementation) Dpbtf2(ul blas.Uplo, n, kd int, ab []float64, ldab int) (ok bool) { + if ul != blas.Upper && ul != blas.Lower { + panic(badUplo) + } + checkSymBanded(ab, n, kd, ldab) + if n == 0 { + return + } + bi := blas64.Implementation() + kld := max(1, ldab-1) + if ul == blas.Upper { + for j := 0; j < n; j++ { + // Compute U(J,J) and test for non positive-definiteness. + ajj := ab[j*ldab] + if ajj <= 0 { + return false + } + ajj = math.Sqrt(ajj) + ab[j*ldab] = ajj + // Compute elements j+1:j+kn of row J and update the trailing submatrix + // within the band. + kn := min(kd, n-j-1) + if kn > 0 { + bi.Dscal(kn, 1/ajj, ab[j*ldab+1:], 1) + bi.Dsyr(blas.Upper, kn, -1, ab[j*ldab+1:], 1, ab[(j+1)*ldab:], kld) + } + } + return true + } + for j := 0; j < n; j++ { + // Compute L(J,J) and test for non positive-definiteness. + ajj := ab[j*ldab+kd] + if ajj <= 0 { + return false + } + ajj = math.Sqrt(ajj) + ab[j*ldab+kd] = ajj + + // Compute elements J+1:J+KN of column J and update the trailing submatrix + // within the band. + kn := min(kd, n-j-1) + if kn > 0 { + bi.Dscal(kn, 1/ajj, ab[(j+1)*ldab+kd-1:], kld) + bi.Dsyr(blas.Lower, kn, -1, ab[(j+1)*ldab+kd-1:], kld, ab[(j+1)*ldab+kd:], kld) + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dpocon.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dpocon.go new file mode 100644 index 00000000..ce85bd0e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dpocon.go @@ -0,0 +1,76 @@ +// 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/blas/blas64" +) + +// Dpocon estimates the reciprocal of the condition number of a positive-definite +// matrix A given the Cholesky decomposition of A. The condition number computed +// is based on the 1-norm and the ∞-norm. +// +// anorm is the 1-norm and the ∞-norm of the original matrix A. +// +// work is a temporary data slice of length at least 3*n and Dpocon will panic otherwise. +// +// iwork is a temporary data slice of length at least n and Dpocon will panic otherwise. +func (impl Implementation) Dpocon(uplo blas.Uplo, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 { + checkMatrix(n, n, a, lda) + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + if len(work) < 3*n { + panic(badWork) + } + if len(iwork) < n { + panic(badWork) + } + var rcond float64 + if n == 0 { + return 1 + } + if anorm == 0 { + return rcond + } + + bi := blas64.Implementation() + var ainvnm float64 + smlnum := dlamchS + upper := uplo == blas.Upper + var kase int + var normin bool + isave := new([3]int) + var sl, su float64 + for { + ainvnm, kase = impl.Dlacn2(n, work[n:], work, iwork, ainvnm, kase, isave) + if kase == 0 { + if ainvnm != 0 { + rcond = (1 / ainvnm) / anorm + } + return rcond + } + if upper { + sl = impl.Dlatrs(blas.Upper, blas.Trans, blas.NonUnit, normin, n, a, lda, work, work[2*n:]) + normin = true + su = impl.Dlatrs(blas.Upper, blas.NoTrans, blas.NonUnit, normin, n, a, lda, work, work[2*n:]) + } else { + sl = impl.Dlatrs(blas.Lower, blas.NoTrans, blas.NonUnit, normin, n, a, lda, work, work[2*n:]) + normin = true + su = impl.Dlatrs(blas.Lower, blas.Trans, blas.NonUnit, normin, n, a, lda, work, work[2*n:]) + } + scale := sl * su + if scale != 1 { + ix := bi.Idamax(n, work, 1) + if scale == 0 || scale < math.Abs(work[ix])*smlnum { + return rcond + } + impl.Drscl(n, scale, work, 1) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dpotf2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dpotf2.go new file mode 100644 index 00000000..a8891988 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dpotf2.go @@ -0,0 +1,72 @@ +// 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/blas/blas64" +) + +// Dpotf2 computes the Cholesky decomposition of the symmetric positive definite +// matrix a. If ul == blas.Upper, then a is stored as an upper-triangular matrix, +// and a = U^T U is stored in place into a. If ul == blas.Lower, then a = L L^T +// is computed and stored in-place into a. If a is not positive definite, false +// is returned. This is the unblocked version of the algorithm. +// +// Dpotf2 is an internal routine. It is exported for testing purposes. +func (Implementation) Dpotf2(ul blas.Uplo, n int, a []float64, lda int) (ok bool) { + if ul != blas.Upper && ul != blas.Lower { + panic(badUplo) + } + checkMatrix(n, n, a, lda) + + if n == 0 { + return true + } + + bi := blas64.Implementation() + if ul == blas.Upper { + for j := 0; j < n; j++ { + ajj := a[j*lda+j] + if j != 0 { + ajj -= bi.Ddot(j, a[j:], lda, a[j:], lda) + } + if ajj <= 0 || math.IsNaN(ajj) { + a[j*lda+j] = ajj + return false + } + ajj = math.Sqrt(ajj) + a[j*lda+j] = ajj + if j < n-1 { + bi.Dgemv(blas.Trans, j, n-j-1, + -1, a[j+1:], lda, a[j:], lda, + 1, a[j*lda+j+1:], 1) + bi.Dscal(n-j-1, 1/ajj, a[j*lda+j+1:], 1) + } + } + return true + } + for j := 0; j < n; j++ { + ajj := a[j*lda+j] + if j != 0 { + ajj -= bi.Ddot(j, a[j*lda:], 1, a[j*lda:], 1) + } + if ajj <= 0 || math.IsNaN(ajj) { + a[j*lda+j] = ajj + return false + } + ajj = math.Sqrt(ajj) + a[j*lda+j] = ajj + if j < n-1 { + bi.Dgemv(blas.NoTrans, n-j-1, j, + -1, a[(j+1)*lda:], lda, a[j*lda:], 1, + 1, a[(j+1)*lda+j:], lda) + bi.Dscal(n-j-1, 1/ajj, a[(j+1)*lda+j:], lda) + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dpotrf.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dpotrf.go new file mode 100644 index 00000000..a942259a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dpotrf.go @@ -0,0 +1,72 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dpotrf computes the Cholesky decomposition of the symmetric positive definite +// matrix a. If ul == blas.Upper, then a is stored as an upper-triangular matrix, +// and a = U^T U is stored in place into a. If ul == blas.Lower, then a = L L^T +// is computed and stored in-place into a. If a is not positive definite, false +// is returned. This is the blocked version of the algorithm. +func (impl Implementation) Dpotrf(ul blas.Uplo, n int, a []float64, lda int) (ok bool) { + if ul != blas.Upper && ul != blas.Lower { + panic(badUplo) + } + checkMatrix(n, n, a, lda) + + if n == 0 { + return true + } + + nb := impl.Ilaenv(1, "DPOTRF", string(ul), n, -1, -1, -1) + if nb <= 1 || n <= nb { + return impl.Dpotf2(ul, n, a, lda) + } + bi := blas64.Implementation() + if ul == blas.Upper { + for j := 0; j < n; j += nb { + jb := min(nb, n-j) + bi.Dsyrk(blas.Upper, blas.Trans, jb, j, + -1, a[j:], lda, + 1, a[j*lda+j:], lda) + ok = impl.Dpotf2(blas.Upper, jb, a[j*lda+j:], lda) + if !ok { + return ok + } + if j+jb < n { + bi.Dgemm(blas.Trans, blas.NoTrans, jb, n-j-jb, j, + -1, a[j:], lda, a[j+jb:], lda, + 1, a[j*lda+j+jb:], lda) + bi.Dtrsm(blas.Left, blas.Upper, blas.Trans, blas.NonUnit, jb, n-j-jb, + 1, a[j*lda+j:], lda, + a[j*lda+j+jb:], lda) + } + } + return true + } + for j := 0; j < n; j += nb { + jb := min(nb, n-j) + bi.Dsyrk(blas.Lower, blas.NoTrans, jb, j, + -1, a[j*lda:], lda, + 1, a[j*lda+j:], lda) + ok := impl.Dpotf2(blas.Lower, jb, a[j*lda+j:], lda) + if !ok { + return ok + } + if j+jb < n { + bi.Dgemm(blas.NoTrans, blas.Trans, n-j-jb, jb, j, + -1, a[(j+jb)*lda:], lda, a[j*lda:], lda, + 1, a[(j+jb)*lda+j:], lda) + bi.Dtrsm(blas.Right, blas.Lower, blas.Trans, blas.NonUnit, n-j-jb, jb, + 1, a[j*lda+j:], lda, + a[(j+jb)*lda+j:], lda) + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/drscl.go b/vendor/gonum.org/v1/gonum/lapack/gonum/drscl.go new file mode 100644 index 00000000..0ed15214 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/drscl.go @@ -0,0 +1,47 @@ +// 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/blas64" +) + +// Drscl multiplies the vector x by 1/a being careful to avoid overflow or +// underflow where possible. +// +// Drscl is an internal routine. It is exported for testing purposes. +func (impl Implementation) Drscl(n int, a float64, x []float64, incX int) { + checkVector(n, x, incX) + bi := blas64.Implementation() + cden := a + cnum := 1.0 + smlnum := dlamchS + bignum := 1 / smlnum + for { + cden1 := cden * smlnum + cnum1 := cnum / bignum + var mul float64 + var done bool + switch { + case cnum != 0 && math.Abs(cden1) > math.Abs(cnum): + mul = smlnum + done = false + cden = cden1 + case math.Abs(cnum1) > math.Abs(cden): + mul = bignum + done = false + cnum = cnum1 + default: + mul = cnum / cden + done = true + } + bi.Dscal(n, mul, x, incX) + if done { + break + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dsteqr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dsteqr.go new file mode 100644 index 00000000..9a36e1c5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dsteqr.go @@ -0,0 +1,373 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dsteqr computes the eigenvalues and optionally the eigenvectors of a symmetric +// tridiagonal matrix using the implicit QL or QR method. The eigenvectors of a +// full or band symmetric matrix can also be found if Dsytrd, Dsptrd, or Dsbtrd +// have been used to reduce this matrix to tridiagonal form. +// +// d, on entry, contains the diagonal elements of the tridiagonal matrix. On exit, +// d contains the eigenvalues in ascending order. d must have length n and +// Dsteqr will panic otherwise. +// +// e, on entry, contains the off-diagonal elements of the tridiagonal matrix on +// entry, and is overwritten during the call to Dsteqr. e must have length n-1 and +// Dsteqr will panic otherwise. +// +// z, on entry, contains the n×n orthogonal matrix used in the reduction to +// tridiagonal form if compz == lapack.OriginalEV. On exit, if +// compz == lapack.OriginalEV, z contains the orthonormal eigenvectors of the +// original symmetric matrix, and if compz == lapack.TridiagEV, z contains the +// orthonormal eigenvectors of the symmetric tridiagonal matrix. z is not used +// if compz == lapack.None. +// +// work must have length at least max(1, 2*n-2) if the eigenvectors are computed, +// and Dsteqr will panic otherwise. +// +// Dsteqr is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dsteqr(compz lapack.EVComp, n int, d, e, z []float64, ldz int, work []float64) (ok bool) { + if n < 0 { + panic(nLT0) + } + if len(d) < n { + panic(badD) + } + if len(e) < n-1 { + panic(badE) + } + if compz != lapack.None && compz != lapack.TridiagEV && compz != lapack.OriginalEV { + panic(badEVComp) + } + if compz != lapack.None { + if len(work) < max(1, 2*n-2) { + panic(badWork) + } + checkMatrix(n, n, z, ldz) + } + + var icompz int + if compz == lapack.OriginalEV { + icompz = 1 + } else if compz == lapack.TridiagEV { + icompz = 2 + } + + if n == 0 { + return true + } + if n == 1 { + if icompz == 2 { + z[0] = 1 + } + return true + } + + bi := blas64.Implementation() + + eps := dlamchE + eps2 := eps * eps + safmin := dlamchS + safmax := 1 / safmin + ssfmax := math.Sqrt(safmax) / 3 + ssfmin := math.Sqrt(safmin) / eps2 + + // Compute the eigenvalues and eigenvectors of the tridiagonal matrix. + if icompz == 2 { + impl.Dlaset(blas.All, n, n, 0, 1, z, ldz) + } + const maxit = 30 + nmaxit := n * maxit + + jtot := 0 + + // Determine where the matrix splits and choose QL or QR iteration for each + // block, according to whether top or bottom diagonal element is smaller. + l1 := 0 + nm1 := n - 1 + + type scaletype int + const ( + down scaletype = iota + 1 + up + ) + var iscale scaletype + + for { + if l1 > n-1 { + // Order eigenvalues and eigenvectors. + if icompz == 0 { + impl.Dlasrt(lapack.SortIncreasing, n, d) + } else { + // TODO(btracey): Consider replacing this sort with a call to sort.Sort. + for ii := 1; ii < n; ii++ { + i := ii - 1 + k := i + p := d[i] + for j := ii; j < n; j++ { + if d[j] < p { + k = j + p = d[j] + } + } + if k != i { + d[k] = d[i] + d[i] = p + bi.Dswap(n, z[i:], ldz, z[k:], ldz) + } + } + } + return true + } + if l1 > 0 { + e[l1-1] = 0 + } + var m int + if l1 <= nm1 { + for m = l1; m < nm1; m++ { + test := math.Abs(e[m]) + if test == 0 { + break + } + if test <= (math.Sqrt(math.Abs(d[m]))*math.Sqrt(math.Abs(d[m+1])))*eps { + e[m] = 0 + break + } + } + } + l := l1 + lsv := l + lend := m + lendsv := lend + l1 = m + 1 + if lend == l { + continue + } + + // Scale submatrix in rows and columns L to Lend + anorm := impl.Dlanst(lapack.MaxAbs, lend-l+1, d[l:], e[l:]) + switch { + case anorm == 0: + continue + case anorm > ssfmax: + iscale = down + // Pretend that d and e are matrices with 1 column. + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmax, lend-l+1, 1, d[l:], 1) + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmax, lend-l, 1, e[l:], 1) + case anorm < ssfmin: + iscale = up + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmin, lend-l+1, 1, d[l:], 1) + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmin, lend-l, 1, e[l:], 1) + } + + // Choose between QL and QR. + if math.Abs(d[lend]) < math.Abs(d[l]) { + lend = lsv + l = lendsv + } + if lend > l { + // QL Iteration. Look for small subdiagonal element. + for { + if l != lend { + for m = l; m < lend; m++ { + v := math.Abs(e[m]) + if v*v <= (eps2*math.Abs(d[m]))*math.Abs(d[m+1])+safmin { + break + } + } + } else { + m = lend + } + if m < lend { + e[m] = 0 + } + p := d[l] + if m == l { + // Eigenvalue found. + l++ + if l > lend { + break + } + continue + } + + // If remaining matrix is 2×2, use Dlae2 to compute its eigensystem. + if m == l+1 { + if icompz > 0 { + d[l], d[l+1], work[l], work[n-1+l] = impl.Dlaev2(d[l], e[l], d[l+1]) + impl.Dlasr(blas.Right, lapack.Variable, lapack.Backward, + n, 2, work[l:], work[n-1+l:], z[l:], ldz) + } else { + d[l], d[l+1] = impl.Dlae2(d[l], e[l], d[l+1]) + } + e[l] = 0 + l += 2 + if l > lend { + break + } + continue + } + + if jtot == nmaxit { + break + } + jtot++ + + // Form shift + g := (d[l+1] - p) / (2 * e[l]) + r := impl.Dlapy2(g, 1) + g = d[m] - p + e[l]/(g+math.Copysign(r, g)) + s := 1.0 + c := 1.0 + p = 0.0 + + // Inner loop + for i := m - 1; i >= l; i-- { + f := s * e[i] + b := c * e[i] + c, s, r = impl.Dlartg(g, f) + if i != m-1 { + e[i+1] = r + } + g = d[i+1] - p + r = (d[i]-g)*s + 2*c*b + p = s * r + d[i+1] = g + p + g = c*r - b + + // If eigenvectors are desired, then save rotations. + if icompz > 0 { + work[i] = c + work[n-1+i] = -s + } + } + // If eigenvectors are desired, then apply saved rotations. + if icompz > 0 { + mm := m - l + 1 + impl.Dlasr(blas.Right, lapack.Variable, lapack.Backward, + n, mm, work[l:], work[n-1+l:], z[l:], ldz) + } + d[l] -= p + e[l] = g + } + } else { + // QR Iteration. + // Look for small superdiagonal element. + for { + if l != lend { + for m = l; m > lend; m-- { + v := math.Abs(e[m-1]) + if v*v <= (eps2*math.Abs(d[m])*math.Abs(d[m-1]) + safmin) { + break + } + } + } else { + m = lend + } + if m > lend { + e[m-1] = 0 + } + p := d[l] + if m == l { + // Eigenvalue found + l-- + if l < lend { + break + } + continue + } + + // If remaining matrix is 2×2, use Dlae2 to compute its eigenvalues. + if m == l-1 { + if icompz > 0 { + d[l-1], d[l], work[m], work[n-1+m] = impl.Dlaev2(d[l-1], e[l-1], d[l]) + impl.Dlasr(blas.Right, lapack.Variable, lapack.Forward, + n, 2, work[m:], work[n-1+m:], z[l-1:], ldz) + } else { + d[l-1], d[l] = impl.Dlae2(d[l-1], e[l-1], d[l]) + } + e[l-1] = 0 + l -= 2 + if l < lend { + break + } + continue + } + if jtot == nmaxit { + break + } + jtot++ + + // Form shift. + g := (d[l-1] - p) / (2 * e[l-1]) + r := impl.Dlapy2(g, 1) + g = d[m] - p + (e[l-1])/(g+math.Copysign(r, g)) + s := 1.0 + c := 1.0 + p = 0.0 + + // Inner loop. + for i := m; i < l; i++ { + f := s * e[i] + b := c * e[i] + c, s, r = impl.Dlartg(g, f) + if i != m { + e[i-1] = r + } + g = d[i] - p + r = (d[i+1]-g)*s + 2*c*b + p = s * r + d[i] = g + p + g = c*r - b + + // If eigenvectors are desired, then save rotations. + if icompz > 0 { + work[i] = c + work[n-1+i] = s + } + } + + // If eigenvectors are desired, then apply saved rotations. + if icompz > 0 { + mm := l - m + 1 + impl.Dlasr(blas.Right, lapack.Variable, lapack.Forward, + n, mm, work[m:], work[n-1+m:], z[m:], ldz) + } + d[l] -= p + e[l-1] = g + } + } + + // Undo scaling if necessary. + switch iscale { + case down: + // Pretend that d and e are matrices with 1 column. + impl.Dlascl(lapack.General, 0, 0, ssfmax, anorm, lendsv-lsv+1, 1, d[lsv:], 1) + impl.Dlascl(lapack.General, 0, 0, ssfmax, anorm, lendsv-lsv, 1, e[lsv:], 1) + case up: + impl.Dlascl(lapack.General, 0, 0, ssfmin, anorm, lendsv-lsv+1, 1, d[lsv:], 1) + impl.Dlascl(lapack.General, 0, 0, ssfmin, anorm, lendsv-lsv, 1, e[lsv:], 1) + } + + // Check for no convergence to an eigenvalue after a total of n*maxit iterations. + if jtot >= nmaxit { + break + } + } + for i := 0; i < n-1; i++ { + if e[i] != 0 { + return false + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dsterf.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dsterf.go new file mode 100644 index 00000000..1ed59820 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dsterf.go @@ -0,0 +1,278 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/lapack" +) + +// Dsterf computes all eigenvalues of a symmetric tridiagonal matrix using the +// Pal-Walker-Kahan variant of the QL or QR algorithm. +// +// d contains the diagonal elements of the tridiagonal matrix on entry, and +// contains the eigenvalues in ascending order on exit. d must have length at +// least n, or Dsterf will panic. +// +// e contains the off-diagonal elements of the tridiagonal matrix on entry, and is +// overwritten during the call to Dsterf. e must have length of at least n-1 or +// Dsterf will panic. +// +// Dsterf is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dsterf(n int, d, e []float64) (ok bool) { + if n < 0 { + panic(nLT0) + } + if n == 0 { + return true + } + if len(d) < n { + panic(badD) + } + if len(e) < n-1 { + panic(badE) + } + + const ( + none = 0 // The values are not scaled. + down = 1 // The values are scaled below ssfmax threshold. + up = 2 // The values are scaled below ssfmin threshold. + ) + + // Determine the unit roundoff for this environment. + eps := dlamchE + eps2 := eps * eps + safmin := dlamchS + safmax := 1 / safmin + ssfmax := math.Sqrt(safmax) / 3 + ssfmin := math.Sqrt(safmin) / eps2 + + // Compute the eigenvalues of the tridiagonal matrix. + maxit := 30 + nmaxit := n * maxit + jtot := 0 + + l1 := 0 + + for { + if l1 > n-1 { + impl.Dlasrt(lapack.SortIncreasing, n, d) + return true + } + if l1 > 0 { + e[l1-1] = 0 + } + var m int + for m = l1; m < n-1; m++ { + if math.Abs(e[m]) <= math.Sqrt(math.Abs(d[m]))*math.Sqrt(math.Abs(d[m+1]))*eps { + e[m] = 0 + break + } + } + + l := l1 + lsv := l + lend := m + lendsv := lend + l1 = m + 1 + if lend == 0 { + continue + } + + // Scale submatrix in rows and columns l to lend. + anorm := impl.Dlanst(lapack.MaxAbs, lend-l+1, d[l:], e[l:]) + iscale := none + if anorm == 0 { + continue + } + if anorm > ssfmax { + iscale = down + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmax, lend-l+1, 1, d[l:], n) + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmax, lend-l, 1, e[l:], n) + } else if anorm < ssfmin { + iscale = up + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmin, lend-l+1, 1, d[l:], n) + impl.Dlascl(lapack.General, 0, 0, anorm, ssfmin, lend-l, 1, e[l:], n) + } + + el := e[l:lend] + for i, v := range el { + el[i] *= v + } + + // Choose between QL and QR iteration. + if math.Abs(d[lend]) < math.Abs(d[l]) { + lend = lsv + l = lendsv + } + if lend >= l { + // QL Iteration. + // Look for small sub-diagonal element. + for { + if l != lend { + for m = l; m < lend; m++ { + if math.Abs(e[m]) <= eps2*(math.Abs(d[m]*d[m+1])) { + break + } + } + } else { + m = lend + } + if m < lend { + e[m] = 0 + } + p := d[l] + if m == l { + // Eigenvalue found. + l++ + if l > lend { + break + } + continue + } + // If remaining matrix is 2 by 2, use Dlae2 to compute its eigenvalues. + if m == l+1 { + d[l], d[l+1] = impl.Dlae2(d[l], math.Sqrt(e[l]), d[l+1]) + e[l] = 0 + l += 2 + if l > lend { + break + } + continue + } + if jtot == nmaxit { + break + } + jtot++ + + // Form shift. + rte := math.Sqrt(e[l]) + sigma := (d[l+1] - p) / (2 * rte) + r := impl.Dlapy2(sigma, 1) + sigma = p - (rte / (sigma + math.Copysign(r, sigma))) + + c := 1.0 + s := 0.0 + gamma := d[m] - sigma + p = gamma * gamma + + // Inner loop. + for i := m - 1; i >= l; i-- { + bb := e[i] + r := p + bb + if i != m-1 { + e[i+1] = s * r + } + oldc := c + c = p / r + s = bb / r + oldgam := gamma + alpha := d[i] + gamma = c*(alpha-sigma) - s*oldgam + d[i+1] = oldgam + (alpha - gamma) + if c != 0 { + p = (gamma * gamma) / c + } else { + p = oldc * bb + } + } + e[l] = s * p + d[l] = sigma + gamma + } + } else { + for { + // QR Iteration. + // Look for small super-diagonal element. + for m = l; m > lend; m-- { + if math.Abs(e[m-1]) <= eps2*math.Abs(d[m]*d[m-1]) { + break + } + } + if m > lend { + e[m-1] = 0 + } + p := d[l] + if m == l { + // Eigenvalue found. + l-- + if l < lend { + break + } + continue + } + + // If remaining matrix is 2 by 2, use Dlae2 to compute its eigenvalues. + if m == l-1 { + d[l], d[l-1] = impl.Dlae2(d[l], math.Sqrt(e[l-1]), d[l-1]) + e[l-1] = 0 + l -= 2 + if l < lend { + break + } + continue + } + if jtot == nmaxit { + break + } + jtot++ + + // Form shift. + rte := math.Sqrt(e[l-1]) + sigma := (d[l-1] - p) / (2 * rte) + r := impl.Dlapy2(sigma, 1) + sigma = p - (rte / (sigma + math.Copysign(r, sigma))) + + c := 1.0 + s := 0.0 + gamma := d[m] - sigma + p = gamma * gamma + + // Inner loop. + for i := m; i < l; i++ { + bb := e[i] + r := p + bb + if i != m { + e[i-1] = s * r + } + oldc := c + c = p / r + s = bb / r + oldgam := gamma + alpha := d[i+1] + gamma = c*(alpha-sigma) - s*oldgam + d[i] = oldgam + alpha - gamma + if c != 0 { + p = (gamma * gamma) / c + } else { + p = oldc * bb + } + } + e[l-1] = s * p + d[l] = sigma + gamma + } + } + + // Undo scaling if necessary + switch iscale { + case down: + impl.Dlascl(lapack.General, 0, 0, ssfmax, anorm, lendsv-lsv+1, 1, d[lsv:], n) + case up: + impl.Dlascl(lapack.General, 0, 0, ssfmin, anorm, lendsv-lsv+1, 1, d[lsv:], n) + } + + // Check for no convergence to an eigenvalue after a total of n*maxit iterations. + if jtot >= nmaxit { + break + } + } + for _, v := range e[:n-1] { + if v != 0 { + return false + } + } + impl.Dlasrt(lapack.SortIncreasing, n, d) + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dsyev.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dsyev.go new file mode 100644 index 00000000..35241728 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dsyev.go @@ -0,0 +1,113 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dsyev computes all eigenvalues and, optionally, the eigenvectors of a real +// symmetric matrix A. +// +// w contains the eigenvalues in ascending order upon return. w must have length +// at least n, and Dsyev will panic otherwise. +// +// On entry, a contains the elements of the symmetric matrix A in the triangular +// portion specified by uplo. If jobz == lapack.ComputeEV a contains the +// orthonormal eigenvectors of A on exit, otherwise on exit the specified +// triangular region is overwritten. +// +// work is temporary storage, and lwork specifies the usable memory length. At minimum, +// lwork >= 3*n-1, and Dsyev will panic otherwise. The amount of blocking is +// limited by the usable length. If lwork == -1, instead of computing Dsyev the +// optimal work length is stored into work[0]. +func (impl Implementation) Dsyev(jobz lapack.EVJob, uplo blas.Uplo, n int, a []float64, lda int, w, work []float64, lwork int) (ok bool) { + checkMatrix(n, n, a, lda) + upper := uplo == blas.Upper + wantz := jobz == lapack.ComputeEV + var opts string + if upper { + opts = "U" + } else { + opts = "L" + } + nb := impl.Ilaenv(1, "DSYTRD", opts, n, -1, -1, -1) + lworkopt := max(1, (nb+2)*n) + work[0] = float64(lworkopt) + if lwork == -1 { + return + } + if len(work) < lwork { + panic(badWork) + } + if lwork < 3*n-1 { + panic(badWork) + } + if n == 0 { + return true + } + if n == 1 { + w[0] = a[0] + work[0] = 2 + if wantz { + a[0] = 1 + } + return true + } + safmin := dlamchS + eps := dlamchP + smlnum := safmin / eps + bignum := 1 / smlnum + rmin := math.Sqrt(smlnum) + rmax := math.Sqrt(bignum) + + // Scale matrix to allowable range, if necessary. + anrm := impl.Dlansy(lapack.MaxAbs, uplo, n, a, lda, work) + scaled := false + var sigma float64 + if anrm > 0 && anrm < rmin { + scaled = true + sigma = rmin / anrm + } else if anrm > rmax { + scaled = true + sigma = rmax / anrm + } + if scaled { + kind := lapack.LowerTri + if upper { + kind = lapack.UpperTri + } + impl.Dlascl(kind, 0, 0, 1, sigma, n, n, a, lda) + } + var inde int + indtau := inde + n + indwork := indtau + n + llwork := lwork - indwork + impl.Dsytrd(uplo, n, a, lda, w, work[inde:], work[indtau:], work[indwork:], llwork) + + // For eigenvalues only, call Dsterf. For eigenvectors, first call Dorgtr + // to generate the orthogonal matrix, then call Dsteqr. + if !wantz { + ok = impl.Dsterf(n, w, work[inde:]) + } else { + impl.Dorgtr(uplo, n, a, lda, work[indtau:], work[indwork:], llwork) + ok = impl.Dsteqr(lapack.EVComp(jobz), n, w, work[inde:], a, lda, work[indtau:]) + } + if !ok { + return false + } + + // If the matrix was scaled, then rescale eigenvalues appropriately. + if scaled { + bi := blas64.Implementation() + bi.Dscal(n, 1/sigma, w, 1) + } + work[0] = float64(lworkopt) + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dsytd2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dsytd2.go new file mode 100644 index 00000000..a4d69201 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dsytd2.go @@ -0,0 +1,123 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dsytd2 reduces a symmetric n×n matrix A to symmetric tridiagonal form T by an +// orthogonal similarity transformation +// Q^T * A * Q = T +// On entry, the matrix is contained in the specified triangle of a. On exit, +// if uplo == blas.Upper, the diagonal and first super-diagonal of a are +// overwritten with the elements of T. The elements above the first super-diagonal +// are overwritten with the the elementary reflectors that are used with the +// elements written to tau in order to construct Q. If uplo == blas.Lower, the +// elements are written in the lower triangular region. +// +// d must have length at least n. e and tau must have length at least n-1. Dsytd2 +// will panic if these sizes are not met. +// +// Q is represented as a product of elementary reflectors. +// If uplo == blas.Upper +// Q = H_{n-2} * ... * H_1 * H_0 +// and if uplo == blas.Lower +// Q = H_0 * H_1 * ... * H_{n-2} +// where +// H_i = I - tau * v * v^T +// where tau is stored in tau[i], and v is stored in a. +// +// If uplo == blas.Upper, v[0:i-1] is stored in A[0:i-1,i+1], v[i] = 1, and +// v[i+1:] = 0. The elements of a are +// [ d e v2 v3 v4] +// [ d e v3 v4] +// [ d e v4] +// [ d e] +// [ d] +// If uplo == blas.Lower, v[0:i+1] = 0, v[i+1] = 1, and v[i+2:] is stored in +// A[i+2:n,i]. +// The elements of a are +// [ d ] +// [ e d ] +// [v1 e d ] +// [v1 v2 e d ] +// [v1 v2 v3 e d] +// +// Dsytd2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dsytd2(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau []float64) { + checkMatrix(n, n, a, lda) + if len(d) < n { + panic(badD) + } + if len(e) < n-1 { + panic(badE) + } + if len(tau) < n-1 { + panic(badTau) + } + if n <= 0 { + return + } + bi := blas64.Implementation() + if uplo == blas.Upper { + // Reduce the upper triangle of A. + for i := n - 2; i >= 0; i-- { + // Generate elementary reflector H_i = I - tau * v * v^T to + // annihilate A[i:i-1, i+1]. + var taui float64 + a[i*lda+i+1], taui = impl.Dlarfg(i+1, a[i*lda+i+1], a[i+1:], lda) + e[i] = a[i*lda+i+1] + if taui != 0 { + // Apply H_i from both sides to A[0:i,0:i]. + a[i*lda+i+1] = 1 + + // Compute x := tau * A * v storing x in tau[0:i]. + bi.Dsymv(uplo, i+1, taui, a, lda, a[i+1:], lda, 0, tau, 1) + + // Compute w := x - 1/2 * tau * (x^T * v) * v. + alpha := -0.5 * taui * bi.Ddot(i+1, tau, 1, a[i+1:], lda) + bi.Daxpy(i+1, alpha, a[i+1:], lda, tau, 1) + + // Apply the transformation as a rank-2 update + // A = A - v * w^T - w * v^T. + bi.Dsyr2(uplo, i+1, -1, a[i+1:], lda, tau, 1, a, lda) + a[i*lda+i+1] = e[i] + } + d[i+1] = a[(i+1)*lda+i+1] + tau[i] = taui + } + d[0] = a[0] + return + } + // Reduce the lower triangle of A. + for i := 0; i < n-1; i++ { + // Generate elementary reflector H_i = I - tau * v * v^T to + // annihilate A[i+2:n, i]. + var taui float64 + a[(i+1)*lda+i], taui = impl.Dlarfg(n-i-1, a[(i+1)*lda+i], a[min(i+2, n-1)*lda+i:], lda) + e[i] = a[(i+1)*lda+i] + if taui != 0 { + // Apply H_i from both sides to A[i+1:n, i+1:n]. + a[(i+1)*lda+i] = 1 + + // Compute x := tau * A * v, storing y in tau[i:n-1]. + bi.Dsymv(uplo, n-i-1, taui, a[(i+1)*lda+i+1:], lda, a[(i+1)*lda+i:], lda, 0, tau[i:], 1) + + // Compute w := x - 1/2 * tau * (x^T * v) * v. + alpha := -0.5 * taui * bi.Ddot(n-i-1, tau[i:], 1, a[(i+1)*lda+i:], lda) + bi.Daxpy(n-i-1, alpha, a[(i+1)*lda+i:], lda, tau[i:], 1) + + // Apply the transformation as a rank-2 update + // A = A - v * w^T - w * v^T. + bi.Dsyr2(uplo, n-i-1, -1, a[(i+1)*lda+i:], lda, tau[i:], 1, a[(i+1)*lda+i+1:], lda) + a[(i+1)*lda+i] = e[i] + } + d[i] = a[i*lda+i] + tau[i] = taui + } + d[n-1] = a[(n-1)*lda+n-1] +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dsytrd.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dsytrd.go new file mode 100644 index 00000000..f8a4ca95 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dsytrd.go @@ -0,0 +1,178 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dsytrd reduces a symmetric n×n matrix A to symmetric tridiagonal form by an +// orthogonal similarity transformation +// Q^T * A * Q = T +// where Q is an orthonormal matrix and T is symmetric and tridiagonal. +// +// On entry, a contains the elements of the input matrix in the triangle specified +// by uplo. On exit, the diagonal and sub/super-diagonal are overwritten by the +// corresponding elements of the tridiagonal matrix T. The remaining elements in +// the triangle, along with the array tau, contain the data to construct Q as +// the product of elementary reflectors. +// +// If uplo == blas.Upper, Q is constructed with +// Q = H_{n-2} * ... * H_1 * H_0 +// where +// H_i = I - tau_i * v * v^T +// v is constructed as v[i+1:n] = 0, v[i] = 1, v[0:i-1] is stored in A[0:i-1, i+1]. +// The elements of A are +// [ d e v1 v2 v3] +// [ d e v2 v3] +// [ d e v3] +// [ d e] +// [ e] +// +// If uplo == blas.Lower, Q is constructed with +// Q = H_0 * H_1 * ... * H_{n-2} +// where +// H_i = I - tau_i * v * v^T +// v is constructed as v[0:i+1] = 0, v[i+1] = 1, v[i+2:n] is stored in A[i+2:n, i]. +// The elements of A are +// [ d ] +// [ e d ] +// [v0 e d ] +// [v0 v1 e d ] +// [v0 v1 v2 e d] +// +// d must have length n, and e and tau must have length n-1. Dsytrd will panic if +// these conditions are not met. +// +// work is temporary storage, and lwork specifies the usable memory length. At minimum, +// lwork >= 1, and Dsytrd will panic otherwise. The amount of blocking is +// limited by the usable length. +// If lwork == -1, instead of computing Dsytrd the optimal work length is stored +// into work[0]. +// +// Dsytrd is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau, work []float64, lwork int) { + checkMatrix(n, n, a, lda) + if len(d) < n { + panic(badD) + } + if len(e) < n-1 { + panic(badE) + } + if len(tau) < n-1 { + panic(badTau) + } + if len(work) < lwork { + panic(shortWork) + } + if lwork != -1 && lwork < 1 { + panic(badWork) + } + + var upper bool + var opts string + switch uplo { + case blas.Upper: + upper = true + opts = "U" + case blas.Lower: + opts = "L" + default: + panic(badUplo) + } + + if n == 0 { + work[0] = 1 + return + } + + nb := impl.Ilaenv(1, "DSYTRD", opts, n, -1, -1, -1) + lworkopt := n * nb + if lwork == -1 { + work[0] = float64(lworkopt) + return + } + + nx := n + bi := blas64.Implementation() + var ldwork int + if 1 < nb && nb < n { + // Determine when to cross over from blocked to unblocked code. The last + // block is always handled by unblocked code. + opts := "L" + if upper { + opts = "U" + } + nx = max(nb, impl.Ilaenv(3, "DSYTRD", opts, n, -1, -1, -1)) + if nx < n { + // Determine if workspace is large enough for blocked code. + ldwork = nb + iws := n * ldwork + if lwork < iws { + // Not enough workspace to use optimal nb: determine the minimum + // value of nb and reduce nb or force use of unblocked code by + // setting nx = n. + nb = max(lwork/n, 1) + nbmin := impl.Ilaenv(2, "DSYTRD", opts, n, -1, -1, -1) + if nb < nbmin { + nx = n + } + } + } else { + nx = n + } + } else { + nb = 1 + } + ldwork = nb + + if upper { + // Reduce the upper triangle of A. Columns 0:kk are handled by the + // unblocked method. + var i int + kk := n - ((n-nx+nb-1)/nb)*nb + for i = n - nb; i >= kk; i -= nb { + // Reduce columns i:i+nb to tridiagonal form and form the matrix W + // which is needed to update the unreduced part of the matrix. + impl.Dlatrd(uplo, i+nb, nb, a, lda, e, tau, work, ldwork) + + // Update the unreduced submatrix A[0:i-1,0:i-1], using an update + // of the form A = A - V*W^T - W*V^T. + bi.Dsyr2k(uplo, blas.NoTrans, i, nb, -1, a[i:], lda, work, ldwork, 1, a, lda) + + // Copy superdiagonal elements back into A, and diagonal elements into D. + for j := i; j < i+nb; j++ { + a[(j-1)*lda+j] = e[j-1] + d[j] = a[j*lda+j] + } + } + // Use unblocked code to reduce the last or only block + // check that i == kk. + impl.Dsytd2(uplo, kk, a, lda, d, e, tau) + } else { + var i int + // Reduce the lower triangle of A. + for i = 0; i < n-nx; i += nb { + // Reduce columns 0:i+nb to tridiagonal form and form the matrix W + // which is needed to update the unreduced part of the matrix. + impl.Dlatrd(uplo, n-i, nb, a[i*lda+i:], lda, e[i:], tau[i:], work, ldwork) + + // Update the unreduced submatrix A[i+ib:n, i+ib:n], using an update + // of the form A = A + V*W^T - W*V^T. + bi.Dsyr2k(uplo, blas.NoTrans, n-i-nb, nb, -1, a[(i+nb)*lda+i:], lda, + work[nb*ldwork:], ldwork, 1, a[(i+nb)*lda+i+nb:], lda) + + // Copy subdiagonal elements back into A, and diagonal elements into D. + for j := i; j < i+nb; j++ { + a[(j+1)*lda+j] = e[j] + d[j] = a[j*lda+j] + } + } + // Use unblocked code to reduce the last or only block. + impl.Dsytd2(uplo, n-i, a[i*lda+i:], lda, d[i:], e[i:], tau[i:]) + } + work[0] = float64(lworkopt) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dtgsja.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dtgsja.go new file mode 100644 index 00000000..ca0326ef --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dtgsja.go @@ -0,0 +1,357 @@ +// 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/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dtgsja computes the generalized singular value decomposition (GSVD) +// of two real upper triangular or trapezoidal matrices A and B. +// +// A and B have the following forms, which may be obtained by the +// preprocessing subroutine Dggsvp from a general m×n matrix A and p×n +// matrix B: +// +// n-k-l k l +// A = k [ 0 A12 A13 ] if m-k-l >= 0; +// l [ 0 0 A23 ] +// m-k-l [ 0 0 0 ] +// +// n-k-l k l +// A = k [ 0 A12 A13 ] if m-k-l < 0; +// m-k [ 0 0 A23 ] +// +// n-k-l k l +// B = l [ 0 0 B13 ] +// p-l [ 0 0 0 ] +// +// where the k×k matrix A12 and l×l matrix B13 are non-singular +// upper triangular. A23 is l×l upper triangular if m-k-l >= 0, +// otherwise A23 is (m-k)×l upper trapezoidal. +// +// On exit, +// +// U^T*A*Q = D1*[ 0 R ], V^T*B*Q = D2*[ 0 R ], +// +// where U, V and Q are orthogonal matrices. +// R is a non-singular upper triangular matrix, and D1 and D2 are +// diagonal matrices, which are of the following structures: +// +// If m-k-l >= 0, +// +// k l +// D1 = k [ I 0 ] +// l [ 0 C ] +// m-k-l [ 0 0 ] +// +// k l +// D2 = l [ 0 S ] +// p-l [ 0 0 ] +// +// n-k-l k l +// [ 0 R ] = k [ 0 R11 R12 ] k +// l [ 0 0 R22 ] l +// +// where +// +// C = diag( alpha_k, ... , alpha_{k+l} ), +// S = diag( beta_k, ... , beta_{k+l} ), +// C^2 + S^2 = I. +// +// R is stored in +// A[0:k+l, n-k-l:n] +// on exit. +// +// If m-k-l < 0, +// +// k m-k k+l-m +// D1 = k [ I 0 0 ] +// m-k [ 0 C 0 ] +// +// k m-k k+l-m +// D2 = m-k [ 0 S 0 ] +// k+l-m [ 0 0 I ] +// p-l [ 0 0 0 ] +// +// n-k-l k m-k k+l-m +// [ 0 R ] = k [ 0 R11 R12 R13 ] +// m-k [ 0 0 R22 R23 ] +// k+l-m [ 0 0 0 R33 ] +// +// where +// C = diag( alpha_k, ... , alpha_m ), +// S = diag( beta_k, ... , beta_m ), +// C^2 + S^2 = I. +// +// R = [ R11 R12 R13 ] is stored in A[0:m, n-k-l:n] +// [ 0 R22 R23 ] +// and R33 is stored in +// B[m-k:l, n+m-k-l:n] on exit. +// +// The computation of the orthogonal transformation matrices U, V or Q +// is optional. These matrices may either be formed explicitly, or they +// may be post-multiplied into input matrices U1, V1, or Q1. +// +// Dtgsja essentially uses a variant of Kogbetliantz algorithm to reduce +// min(l,m-k)×l triangular or trapezoidal matrix A23 and l×l +// matrix B13 to the form: +// +// U1^T*A13*Q1 = C1*R1; V1^T*B13*Q1 = S1*R1, +// +// where U1, V1 and Q1 are orthogonal matrices. C1 and S1 are diagonal +// matrices satisfying +// +// C1^2 + S1^2 = I, +// +// and R1 is an l×l non-singular upper triangular matrix. +// +// jobU, jobV and jobQ are options for computing the orthogonal matrices. The behavior +// is as follows +// jobU == lapack.GSVDU Compute orthogonal matrix U +// jobU == lapack.GSVDUnit Use unit-initialized matrix +// jobU == lapack.GSVDNone Do not compute orthogonal matrix. +// The behavior is the same for jobV and jobQ with the exception that instead of +// lapack.GSVDU these accept lapack.GSVDV and lapack.GSVDQ respectively. +// The matrices U, V and Q must be m×m, p×p and n×n respectively unless the +// relevant job parameter is lapack.GSVDNone. +// +// k and l specify the sub-blocks in the input matrices A and B: +// A23 = A[k:min(k+l,m), n-l:n) and B13 = B[0:l, n-l:n] +// of A and B, whose GSVD is going to be computed by Dtgsja. +// +// tola and tolb are the convergence criteria for the Jacobi-Kogbetliantz +// iteration procedure. Generally, they are the same as used in the preprocessing +// step, for example, +// tola = max(m, n)*norm(A)*eps, +// tolb = max(p, n)*norm(B)*eps, +// where eps is the machine epsilon. +// +// work must have length at least 2*n, otherwise Dtgsja will panic. +// +// alpha and beta must have length n or Dtgsja will panic. On exit, alpha and +// beta contain the generalized singular value pairs of A and B +// alpha[0:k] = 1, +// beta[0:k] = 0, +// if m-k-l >= 0, +// alpha[k:k+l] = diag(C), +// beta[k:k+l] = diag(S), +// if m-k-l < 0, +// alpha[k:m]= C, alpha[m:k+l]= 0 +// beta[k:m] = S, beta[m:k+l] = 1. +// if k+l < n, +// alpha[k+l:n] = 0 and +// beta[k+l:n] = 0. +// +// On exit, A[n-k:n, 0:min(k+l,m)] contains the triangular matrix R or part of R +// and if necessary, B[m-k:l, n+m-k-l:n] contains a part of R. +// +// Dtgsja returns whether the routine converged and the number of iteration cycles +// that were run. +// +// Dtgsja is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dtgsja(jobU, jobV, jobQ lapack.GSVDJob, m, p, n, k, l int, a []float64, lda int, b []float64, ldb int, tola, tolb float64, alpha, beta, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, work []float64) (cycles int, ok bool) { + const maxit = 40 + + checkMatrix(m, n, a, lda) + checkMatrix(p, n, b, ldb) + + if len(alpha) != n { + panic(badAlpha) + } + if len(beta) != n { + panic(badBeta) + } + + initu := jobU == lapack.GSVDUnit + wantu := initu || jobU == lapack.GSVDU + if !initu && !wantu && jobU != lapack.GSVDNone { + panic(badGSVDJob + "U") + } + if jobU != lapack.GSVDNone { + checkMatrix(m, m, u, ldu) + } + + initv := jobV == lapack.GSVDUnit + wantv := initv || jobV == lapack.GSVDV + if !initv && !wantv && jobV != lapack.GSVDNone { + panic(badGSVDJob + "V") + } + if jobV != lapack.GSVDNone { + checkMatrix(p, p, v, ldv) + } + + initq := jobQ == lapack.GSVDUnit + wantq := initq || jobQ == lapack.GSVDQ + if !initq && !wantq && jobQ != lapack.GSVDNone { + panic(badGSVDJob + "Q") + } + if jobQ != lapack.GSVDNone { + checkMatrix(n, n, q, ldq) + } + + if len(work) < 2*n { + panic(badWork) + } + + // Initialize U, V and Q, if necessary + if initu { + impl.Dlaset(blas.All, m, m, 0, 1, u, ldu) + } + if initv { + impl.Dlaset(blas.All, p, p, 0, 1, v, ldv) + } + if initq { + impl.Dlaset(blas.All, n, n, 0, 1, q, ldq) + } + + bi := blas64.Implementation() + minTol := math.Min(tola, tolb) + + // Loop until convergence. + upper := false + for cycles = 1; cycles <= maxit; cycles++ { + upper = !upper + + for i := 0; i < l-1; i++ { + for j := i + 1; j < l; j++ { + var a1, a2, a3 float64 + if k+i < m { + a1 = a[(k+i)*lda+n-l+i] + } + if k+j < m { + a3 = a[(k+j)*lda+n-l+j] + } + + b1 := b[i*ldb+n-l+i] + b3 := b[j*ldb+n-l+j] + + var b2 float64 + if upper { + if k+i < m { + a2 = a[(k+i)*lda+n-l+j] + } + b2 = b[i*ldb+n-l+j] + } else { + if k+j < m { + a2 = a[(k+j)*lda+n-l+i] + } + b2 = b[j*ldb+n-l+i] + } + + csu, snu, csv, snv, csq, snq := impl.Dlags2(upper, a1, a2, a3, b1, b2, b3) + + // Update (k+i)-th and (k+j)-th rows of matrix A: U^T*A. + if k+j < m { + bi.Drot(l, a[(k+j)*lda+n-l:], 1, a[(k+i)*lda+n-l:], 1, csu, snu) + } + + // Update i-th and j-th rows of matrix B: V^T*B. + bi.Drot(l, b[j*ldb+n-l:], 1, b[i*ldb+n-l:], 1, csv, snv) + + // Update (n-l+i)-th and (n-l+j)-th columns of matrices + // A and B: A*Q and B*Q. + bi.Drot(min(k+l, m), a[n-l+j:], lda, a[n-l+i:], lda, csq, snq) + bi.Drot(l, b[n-l+j:], ldb, b[n-l+i:], ldb, csq, snq) + + if upper { + if k+i < m { + a[(k+i)*lda+n-l+j] = 0 + } + b[i*ldb+n-l+j] = 0 + } else { + if k+j < m { + a[(k+j)*lda+n-l+i] = 0 + } + b[j*ldb+n-l+i] = 0 + } + + // Update orthogonal matrices U, V, Q, if desired. + if wantu && k+j < m { + bi.Drot(m, u[k+j:], ldu, u[k+i:], ldu, csu, snu) + } + if wantv { + bi.Drot(p, v[j:], ldv, v[i:], ldv, csv, snv) + } + if wantq { + bi.Drot(n, q[n-l+j:], ldq, q[n-l+i:], ldq, csq, snq) + } + } + } + + if !upper { + // The matrices A13 and B13 were lower triangular at the start + // of the cycle, and are now upper triangular. + // + // Convergence test: test the parallelism of the corresponding + // rows of A and B. + var error float64 + for i := 0; i < min(l, m-k); i++ { + bi.Dcopy(l-i, a[(k+i)*lda+n-l+i:], 1, work, 1) + bi.Dcopy(l-i, b[i*ldb+n-l+i:], 1, work[l:], 1) + ssmin := impl.Dlapll(l-i, work, 1, work[l:], 1) + error = math.Max(error, ssmin) + } + if math.Abs(error) <= minTol { + // The algorithm has converged. + // Compute the generalized singular value pairs (alpha, beta) + // and set the triangular matrix R to array A. + for i := 0; i < k; i++ { + alpha[i] = 1 + beta[i] = 0 + } + + for i := 0; i < min(l, m-k); i++ { + a1 := a[(k+i)*lda+n-l+i] + b1 := b[i*ldb+n-l+i] + + if a1 != 0 { + gamma := b1 / a1 + + // Change sign if necessary. + if gamma < 0 { + bi.Dscal(l-i, -1, b[i*ldb+n-l+i:], 1) + if wantv { + bi.Dscal(p, -1, v[i:], ldv) + } + } + beta[k+i], alpha[k+i], _ = impl.Dlartg(math.Abs(gamma), 1) + + if alpha[k+i] >= beta[k+i] { + bi.Dscal(l-i, 1/alpha[k+i], a[(k+i)*lda+n-l+i:], 1) + } else { + bi.Dscal(l-i, 1/beta[k+i], b[i*ldb+n-l+i:], 1) + bi.Dcopy(l-i, b[i*ldb+n-l+i:], 1, a[(k+i)*lda+n-l+i:], 1) + } + } else { + alpha[k+i] = 0 + beta[k+i] = 1 + bi.Dcopy(l-i, b[i*ldb+n-l+i:], 1, a[(k+i)*lda+n-l+i:], 1) + } + } + + for i := m; i < k+l; i++ { + alpha[i] = 0 + beta[i] = 1 + } + if k+l < n { + for i := k + l; i < n; i++ { + alpha[i] = 0 + beta[i] = 0 + } + } + + return cycles, true + } + } + } + + // The algorithm has not converged after maxit cycles. + return cycles, false +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dtrcon.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrcon.go new file mode 100644 index 00000000..14101325 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrcon.go @@ -0,0 +1,82 @@ +// 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/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dtrcon estimates the reciprocal of the condition number of a triangular matrix A. +// The condition number computed may be based on the 1-norm or the ∞-norm. +// +// work is a temporary data slice of length at least 3*n and Dtrcon will panic otherwise. +// +// iwork is a temporary data slice of length at least n and Dtrcon will panic otherwise. +func (impl Implementation) Dtrcon(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int, work []float64, iwork []int) float64 { + if norm != lapack.MaxColumnSum && norm != lapack.MaxRowSum { + panic(badNorm) + } + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + if diag != blas.NonUnit && diag != blas.Unit { + panic(badDiag) + } + if len(work) < 3*n { + panic(badWork) + } + if len(iwork) < n { + panic(badWork) + } + if n == 0 { + return 1 + } + bi := blas64.Implementation() + + var rcond float64 + smlnum := dlamchS * float64(n) + + anorm := impl.Dlantr(norm, uplo, diag, n, n, a, lda, work) + + if anorm <= 0 { + return rcond + } + var ainvnm float64 + var normin bool + kase1 := 2 + if norm == lapack.MaxColumnSum { + kase1 = 1 + } + var kase int + isave := new([3]int) + var scale float64 + for { + ainvnm, kase = impl.Dlacn2(n, work[n:], work, iwork, ainvnm, kase, isave) + if kase == 0 { + if ainvnm != 0 { + rcond = (1 / anorm) / ainvnm + } + return rcond + } + if kase == kase1 { + scale = impl.Dlatrs(uplo, blas.NoTrans, diag, normin, n, a, lda, work, work[2*n:]) + } else { + scale = impl.Dlatrs(uplo, blas.Trans, diag, normin, n, a, lda, work, work[2*n:]) + } + normin = true + if scale != 1 { + ix := bi.Idamax(n, work, 1) + xnorm := math.Abs(work[ix]) + if scale == 0 || scale < xnorm*smlnum { + return rcond + } + impl.Drscl(n, scale, work, 1) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dtrevc3.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrevc3.go new file mode 100644 index 00000000..d62d5f05 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrevc3.go @@ -0,0 +1,866 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +// Dtrevc3 computes some or all of the right and/or left eigenvectors of an n×n +// upper quasi-triangular matrix T in Schur canonical form. Matrices of this +// type are produced by the Schur factorization of a real general matrix A +// A = Q T Q^T, +// as computed by Dhseqr. +// +// The right eigenvector x of T corresponding to an +// eigenvalue λ is defined by +// T x = λ x, +// and the left eigenvector is defined by +// y^H T = λ y^H, +// where y^H is the conjugate transpose of y. +// +// The eigenvalues are read directly from the diagonal blocks of T. +// +// This routine returns the matrices X and/or Y of right and left eigenvectors +// of T, or the products Q*X and/or Q*Y, where Q is an input matrix. If Q is the +// orthogonal factor that reduces a matrix A to Schur form T, then Q*X and Q*Y +// are the matrices of right and left eigenvectors of A. +// +// If side == lapack.RightEV, only right eigenvectors will be computed. +// If side == lapack.LeftEV, only left eigenvectors will be computed. +// If side == lapack.RightLeftEV, both right and left eigenvectors will be computed. +// For other values of side, Dtrevc3 will panic. +// +// If howmny == lapack.AllEV, all right and/or left eigenvectors will be +// computed. +// If howmny == lapack.AllEVMulQ, all right and/or left eigenvectors will be +// computed and multiplied from left by the matrices in VR and/or VL. +// If howmny == lapack.SelectedEV, right and/or left eigenvectors will be +// computed as indicated by selected. +// For other values of howmny, Dtrevc3 will panic. +// +// selected specifies which eigenvectors will be computed. It must have length n +// if howmny == lapack.SelectedEV, and it is not referenced otherwise. +// If w_j is a real eigenvalue, the corresponding real eigenvector will be +// computed if selected[j] is true. +// If w_j and w_{j+1} are the real and imaginary parts of a complex eigenvalue, +// the corresponding complex eigenvector is computed if either selected[j] or +// selected[j+1] is true, and on return selected[j] will be set to true and +// selected[j+1] will be set to false. +// +// VL and VR are n×mm matrices. If howmny is lapack.AllEV or +// lapack.AllEVMulQ, mm must be at least n. If howmny == +// lapack.SelectedEV, mm must be large enough to store the selected +// eigenvectors. Each selected real eigenvector occupies one column and each +// selected complex eigenvector occupies two columns. If mm is not sufficiently +// large, Dtrevc3 will panic. +// +// On entry, if howmny == lapack.AllEVMulQ, it is assumed that VL (if side +// is lapack.LeftEV or lapack.RightLeftEV) contains an n×n matrix QL, +// and that VR (if side is lapack.LeftEV or lapack.RightLeftEV) contains +// an n×n matrix QR. QL and QR are typically the orthogonal matrix Q of Schur +// vectors returned by Dhseqr. +// +// On return, if side is lapack.LeftEV or lapack.RightLeftEV, +// VL will contain: +// if howmny == lapack.AllEV, the matrix Y of left eigenvectors of T, +// if howmny == lapack.AllEVMulQ, the matrix Q*Y, +// if howmny == lapack.SelectedEV, the left eigenvectors of T specified by +// selected, stored consecutively in the +// columns of VL, in the same order as their +// eigenvalues. +// VL is not referenced if side == lapack.RightEV. +// +// On return, if side is lapack.RightEV or lapack.RightLeftEV, +// VR will contain: +// if howmny == lapack.AllEV, the matrix X of right eigenvectors of T, +// if howmny == lapack.AllEVMulQ, the matrix Q*X, +// if howmny == lapack.SelectedEV, the left eigenvectors of T specified by +// selected, stored consecutively in the +// columns of VR, in the same order as their +// eigenvalues. +// VR is not referenced if side == lapack.LeftEV. +// +// Complex eigenvectors corresponding to a complex eigenvalue are stored in VL +// and VR in two consecutive columns, the first holding the real part, and the +// second the imaginary part. +// +// Each eigenvector will be normalized so that the element of largest magnitude +// has magnitude 1. Here the magnitude of a complex number (x,y) is taken to be +// |x| + |y|. +// +// work must have length at least lwork and lwork must be at least max(1,3*n), +// otherwise Dtrevc3 will panic. For optimum performance, lwork should be at +// least n+2*n*nb, where nb is the optimal blocksize. +// +// If lwork == -1, instead of performing Dtrevc3, the function only estimates +// the optimal workspace size based on n and stores it into work[0]. +// +// Dtrevc3 returns the number of columns in VL and/or VR actually used to store +// the eigenvectors. +// +// Dtrevc3 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, selected []bool, n int, t []float64, ldt int, vl []float64, ldvl int, vr []float64, ldvr int, mm int, work []float64, lwork int) (m int) { + switch side { + default: + panic(badEVSide) + case lapack.RightEV, lapack.LeftEV, lapack.RightLeftEV: + } + switch howmny { + default: + panic(badHowMany) + case lapack.AllEV, lapack.AllEVMulQ, lapack.SelectedEV: + } + switch { + case n < 0: + panic(nLT0) + case len(work) < lwork: + panic(shortWork) + case lwork < max(1, 3*n) && lwork != -1: + panic(badWork) + } + if lwork != -1 { + if howmny == lapack.SelectedEV { + if len(selected) != n { + panic("lapack: bad selected length") + } + // Set m to the number of columns required to store the + // selected eigenvectors, and standardize the slice + // selected. + for j := 0; j < n; { + if j == n-1 || t[(j+1)*ldt+j] == 0 { + // Diagonal 1×1 block corresponding to a + // real eigenvalue. + if selected[j] { + m++ + } + j++ + } else { + // Diagonal 2×2 block corresponding to a + // complex eigenvalue. + if selected[j] || selected[j+1] { + selected[j] = true + selected[j+1] = false + m += 2 + } + j += 2 + } + } + } else { + m = n + } + if m > mm { + panic("lapack: insufficient number of columns") + } + checkMatrix(n, n, t, ldt) + if (side == lapack.RightEV || side == lapack.RightLeftEV) && m > 0 { + checkMatrix(n, m, vr, ldvr) + } + if (side == lapack.LeftEV || side == lapack.RightLeftEV) && m > 0 { + checkMatrix(n, m, vl, ldvl) + } + } + + // Quick return if possible. + if n == 0 { + work[0] = 1 + return m + } + + const ( + nbmin = 8 + nbmax = 128 + ) + nb := impl.Ilaenv(1, "DTREVC", string(side)+string(howmny), n, -1, -1, -1) + + // Quick return in case of a workspace query. + if lwork == -1 { + work[0] = float64(n + 2*n*nb) + return m + } + + // Use blocked version of back-transformation if sufficient workspace. + // Zero-out the workspace to avoid potential NaN propagation. + if howmny == lapack.AllEVMulQ && lwork >= n+2*n*nbmin { + nb = min((lwork-n)/(2*n), nbmax) + impl.Dlaset(blas.All, n, 1+2*nb, 0, 0, work[:n+2*nb*n], 1+2*nb) + } else { + nb = 1 + } + + // Set the constants to control overflow. + ulp := dlamchP + smlnum := float64(n) / ulp * dlamchS + bignum := (1 - ulp) / smlnum + + // Split work into a vector of column norms and an n×2*nb matrix b. + norms := work[:n] + ldb := 2 * nb + b := work[n : n+n*ldb] + + // Compute 1-norm of each column of strictly upper triangular part of T + // to control overflow in triangular solver. + norms[0] = 0 + for j := 1; j < n; j++ { + var cn float64 + for i := 0; i < j; i++ { + cn += math.Abs(t[i*ldt+j]) + } + norms[j] = cn + } + + bi := blas64.Implementation() + + var ( + x [4]float64 + + iv int // Index of column in current block. + is int + + // ip is used below to specify the real or complex eigenvalue: + // ip == 0, real eigenvalue, + // 1, first of conjugate complex pair (wr,wi), + // -1, second of conjugate complex pair (wr,wi). + ip int + iscomplex [nbmax]int // Stores ip for each column in current block. + ) + + if side == lapack.LeftEV { + goto leftev + } + + // Compute right eigenvectors. + + // For complex right vector, iv-1 is for real part and iv for complex + // part. Non-blocked version always uses iv=1, blocked version starts + // with iv=nb-1 and goes down to 0 or 1. + iv = max(2, nb) - 1 + ip = 0 + is = m - 1 + for ki := n - 1; ki >= 0; ki-- { + if ip == -1 { + // Previous iteration (ki+1) was second of + // conjugate pair, so this ki is first of + // conjugate pair. + ip = 1 + continue + } + + if ki == 0 || t[ki*ldt+ki-1] == 0 { + // Last column or zero on sub-diagonal, so this + // ki must be real eigenvalue. + ip = 0 + } else { + // Non-zero on sub-diagonal, so this ki is + // second of conjugate pair. + ip = -1 + } + + if howmny == lapack.SelectedEV { + if ip == 0 { + if !selected[ki] { + continue + } + } else if !selected[ki-1] { + continue + } + } + + // Compute the ki-th eigenvalue (wr,wi). + wr := t[ki*ldt+ki] + var wi float64 + if ip != 0 { + wi = math.Sqrt(math.Abs(t[ki*ldt+ki-1])) * math.Sqrt(math.Abs(t[(ki-1)*ldt+ki])) + } + smin := math.Max(ulp*(math.Abs(wr)+math.Abs(wi)), smlnum) + + if ip == 0 { + // Real right eigenvector. + + b[ki*ldb+iv] = 1 + // Form right-hand side. + for k := 0; k < ki; k++ { + b[k*ldb+iv] = -t[k*ldt+ki] + } + // Solve upper quasi-triangular system: + // [ T[0:ki,0:ki] - wr ]*X = scale*b. + for j := ki - 1; j >= 0; { + if j == 0 || t[j*ldt+j-1] == 0 { + // 1×1 diagonal block. + scale, xnorm, _ := impl.Dlaln2(false, 1, 1, smin, 1, t[j*ldt+j:], ldt, + 1, 1, b[j*ldb+iv:], ldb, wr, 0, x[:1], 2) + // Scale X[0,0] to avoid overflow when updating the + // right-hand side. + if xnorm > 1 && norms[j] > bignum/xnorm { + x[0] /= xnorm + scale /= xnorm + } + // Scale if necessary. + if scale != 1 { + bi.Dscal(ki+1, scale, b[iv:], ldb) + } + b[j*ldb+iv] = x[0] + // Update right-hand side. + bi.Daxpy(j, -x[0], t[j:], ldt, b[iv:], ldb) + j-- + } else { + // 2×2 diagonal block. + scale, xnorm, _ := impl.Dlaln2(false, 2, 1, smin, 1, t[(j-1)*ldt+j-1:], ldt, + 1, 1, b[(j-1)*ldb+iv:], ldb, wr, 0, x[:3], 2) + // Scale X[0,0] and X[1,0] to avoid overflow + // when updating the right-hand side. + if xnorm > 1 { + beta := math.Max(norms[j-1], norms[j]) + if beta > bignum/xnorm { + x[0] /= xnorm + x[2] /= xnorm + scale /= xnorm + } + } + // Scale if necessary. + if scale != 1 { + bi.Dscal(ki+1, scale, b[iv:], ldb) + } + b[(j-1)*ldb+iv] = x[0] + b[j*ldb+iv] = x[2] + // Update right-hand side. + bi.Daxpy(j-1, -x[0], t[j-1:], ldt, b[iv:], ldb) + bi.Daxpy(j-1, -x[2], t[j:], ldt, b[iv:], ldb) + j -= 2 + } + } + // Copy the vector x or Q*x to VR and normalize. + switch { + case howmny != lapack.AllEVMulQ: + // No back-transform: copy x to VR and normalize. + bi.Dcopy(ki+1, b[iv:], ldb, vr[is:], ldvr) + ii := bi.Idamax(ki+1, vr[is:], ldvr) + remax := 1 / math.Abs(vr[ii*ldvr+is]) + bi.Dscal(ki+1, remax, vr[is:], ldvr) + for k := ki + 1; k < n; k++ { + vr[k*ldvr+is] = 0 + } + case nb == 1: + // Version 1: back-transform each vector with GEMV, Q*x. + if ki > 0 { + bi.Dgemv(blas.NoTrans, n, ki, 1, vr, ldvr, b[iv:], ldb, + b[ki*ldb+iv], vr[ki:], ldvr) + } + ii := bi.Idamax(n, vr[ki:], ldvr) + remax := 1 / math.Abs(vr[ii*ldvr+ki]) + bi.Dscal(n, remax, vr[ki:], ldvr) + default: + // Version 2: back-transform block of vectors with GEMM. + // Zero out below vector. + for k := ki + 1; k < n; k++ { + b[k*ldb+iv] = 0 + } + iscomplex[iv] = ip + // Back-transform and normalization is done below. + } + } else { + // Complex right eigenvector. + + // Initial solve + // [ ( T[ki-1,ki-1] T[ki-1,ki] ) - (wr + i*wi) ]*X = 0. + // [ ( T[ki, ki-1] T[ki, ki] ) ] + if math.Abs(t[(ki-1)*ldt+ki]) >= math.Abs(t[ki*ldt+ki-1]) { + b[(ki-1)*ldb+iv-1] = 1 + b[ki*ldb+iv] = wi / t[(ki-1)*ldt+ki] + } else { + b[(ki-1)*ldb+iv-1] = -wi / t[ki*ldt+ki-1] + b[ki*ldb+iv] = 1 + } + b[ki*ldb+iv-1] = 0 + b[(ki-1)*ldb+iv] = 0 + // Form right-hand side. + for k := 0; k < ki-1; k++ { + b[k*ldb+iv-1] = -b[(ki-1)*ldb+iv-1] * t[k*ldt+ki-1] + b[k*ldb+iv] = -b[ki*ldb+iv] * t[k*ldt+ki] + } + // Solve upper quasi-triangular system: + // [ T[0:ki-1,0:ki-1] - (wr+i*wi) ]*X = scale*(b1+i*b2) + for j := ki - 2; j >= 0; { + if j == 0 || t[j*ldt+j-1] == 0 { + // 1×1 diagonal block. + + scale, xnorm, _ := impl.Dlaln2(false, 1, 2, smin, 1, t[j*ldt+j:], ldt, + 1, 1, b[j*ldb+iv-1:], ldb, wr, wi, x[:2], 2) + // Scale X[0,0] and X[0,1] to avoid + // overflow when updating the right-hand side. + if xnorm > 1 && norms[j] > bignum/xnorm { + x[0] /= xnorm + x[1] /= xnorm + scale /= xnorm + } + // Scale if necessary. + if scale != 1 { + bi.Dscal(ki+1, scale, b[iv-1:], ldb) + bi.Dscal(ki+1, scale, b[iv:], ldb) + } + b[j*ldb+iv-1] = x[0] + b[j*ldb+iv] = x[1] + // Update the right-hand side. + bi.Daxpy(j, -x[0], t[j:], ldt, b[iv-1:], ldb) + bi.Daxpy(j, -x[1], t[j:], ldt, b[iv:], ldb) + j-- + } else { + // 2×2 diagonal block. + + scale, xnorm, _ := impl.Dlaln2(false, 2, 2, smin, 1, t[(j-1)*ldt+j-1:], ldt, + 1, 1, b[(j-1)*ldb+iv-1:], ldb, wr, wi, x[:], 2) + // Scale X to avoid overflow when updating + // the right-hand side. + if xnorm > 1 { + beta := math.Max(norms[j-1], norms[j]) + if beta > bignum/xnorm { + rec := 1 / xnorm + x[0] *= rec + x[1] *= rec + x[2] *= rec + x[3] *= rec + scale *= rec + } + } + // Scale if necessary. + if scale != 1 { + bi.Dscal(ki+1, scale, b[iv-1:], ldb) + bi.Dscal(ki+1, scale, b[iv:], ldb) + } + b[(j-1)*ldb+iv-1] = x[0] + b[(j-1)*ldb+iv] = x[1] + b[j*ldb+iv-1] = x[2] + b[j*ldb+iv] = x[3] + // Update the right-hand side. + bi.Daxpy(j-1, -x[0], t[j-1:], ldt, b[iv-1:], ldb) + bi.Daxpy(j-1, -x[1], t[j-1:], ldt, b[iv:], ldb) + bi.Daxpy(j-1, -x[2], t[j:], ldt, b[iv-1:], ldb) + bi.Daxpy(j-1, -x[3], t[j:], ldt, b[iv:], ldb) + j -= 2 + } + } + + // Copy the vector x or Q*x to VR and normalize. + switch { + case howmny != lapack.AllEVMulQ: + // No back-transform: copy x to VR and normalize. + bi.Dcopy(ki+1, b[iv-1:], ldb, vr[is-1:], ldvr) + bi.Dcopy(ki+1, b[iv:], ldb, vr[is:], ldvr) + emax := 0.0 + for k := 0; k <= ki; k++ { + emax = math.Max(emax, math.Abs(vr[k*ldvr+is-1])+math.Abs(vr[k*ldvr+is])) + } + remax := 1 / emax + bi.Dscal(ki+1, remax, vr[is-1:], ldvr) + bi.Dscal(ki+1, remax, vr[is:], ldvr) + for k := ki + 1; k < n; k++ { + vr[k*ldvr+is-1] = 0 + vr[k*ldvr+is] = 0 + } + case nb == 1: + // Version 1: back-transform each vector with GEMV, Q*x. + if ki-1 > 0 { + bi.Dgemv(blas.NoTrans, n, ki-1, 1, vr, ldvr, b[iv-1:], ldb, + b[(ki-1)*ldb+iv-1], vr[ki-1:], ldvr) + bi.Dgemv(blas.NoTrans, n, ki-1, 1, vr, ldvr, b[iv:], ldb, + b[ki*ldb+iv], vr[ki:], ldvr) + } else { + bi.Dscal(n, b[(ki-1)*ldb+iv-1], vr[ki-1:], ldvr) + bi.Dscal(n, b[ki*ldb+iv], vr[ki:], ldvr) + } + emax := 0.0 + for k := 0; k < n; k++ { + emax = math.Max(emax, math.Abs(vr[k*ldvr+ki-1])+math.Abs(vr[k*ldvr+ki])) + } + remax := 1 / emax + bi.Dscal(n, remax, vr[ki-1:], ldvr) + bi.Dscal(n, remax, vr[ki:], ldvr) + default: + // Version 2: back-transform block of vectors with GEMM. + // Zero out below vector. + for k := ki + 1; k < n; k++ { + b[k*ldb+iv-1] = 0 + b[k*ldb+iv] = 0 + } + iscomplex[iv-1] = -ip + iscomplex[iv] = ip + iv-- + // Back-transform and normalization is done below. + } + } + if nb > 1 { + // Blocked version of back-transform. + + // For complex case, ki2 includes both vectors (ki-1 and ki). + ki2 := ki + if ip != 0 { + ki2-- + } + // Columns iv:nb of b are valid vectors. + // When the number of vectors stored reaches nb-1 or nb, + // or if this was last vector, do the Gemm. + if iv < 2 || ki2 == 0 { + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, nb-iv, ki2+nb-iv, + 1, vr, ldvr, b[iv:], ldb, + 0, b[nb+iv:], ldb) + // Normalize vectors. + var remax float64 + for k := iv; k < nb; k++ { + if iscomplex[k] == 0 { + // Real eigenvector. + ii := bi.Idamax(n, b[nb+k:], ldb) + remax = 1 / math.Abs(b[ii*ldb+nb+k]) + } else if iscomplex[k] == 1 { + // First eigenvector of conjugate pair. + emax := 0.0 + for ii := 0; ii < n; ii++ { + emax = math.Max(emax, math.Abs(b[ii*ldb+nb+k])+math.Abs(b[ii*ldb+nb+k+1])) + } + remax = 1 / emax + // Second eigenvector of conjugate pair + // will reuse this value of remax. + } + bi.Dscal(n, remax, b[nb+k:], ldb) + } + impl.Dlacpy(blas.All, n, nb-iv, b[nb+iv:], ldb, vr[ki2:], ldvr) + iv = nb - 1 + } else { + iv-- + } + } + is-- + if ip != 0 { + is-- + } + } + + if side == lapack.RightEV { + return m + } + +leftev: + // Compute left eigenvectors. + + // For complex left vector, iv is for real part and iv+1 for complex + // part. Non-blocked version always uses iv=0. Blocked version starts + // with iv=0, goes up to nb-2 or nb-1. + iv = 0 + ip = 0 + is = 0 + for ki := 0; ki < n; ki++ { + if ip == 1 { + // Previous iteration ki-1 was first of conjugate pair, + // so this ki is second of conjugate pair. + ip = -1 + continue + } + + if ki == n-1 || t[(ki+1)*ldt+ki] == 0 { + // Last column or zero on sub-diagonal, so this ki must + // be real eigenvalue. + ip = 0 + } else { + // Non-zero on sub-diagonal, so this ki is first of + // conjugate pair. + ip = 1 + } + if howmny == lapack.SelectedEV && !selected[ki] { + continue + } + + // Compute the ki-th eigenvalue (wr,wi). + wr := t[ki*ldt+ki] + var wi float64 + if ip != 0 { + wi = math.Sqrt(math.Abs(t[ki*ldt+ki+1])) * math.Sqrt(math.Abs(t[(ki+1)*ldt+ki])) + } + smin := math.Max(ulp*(math.Abs(wr)+math.Abs(wi)), smlnum) + + if ip == 0 { + // Real left eigenvector. + + b[ki*ldb+iv] = 1 + // Form right-hand side. + for k := ki + 1; k < n; k++ { + b[k*ldb+iv] = -t[ki*ldt+k] + } + // Solve transposed quasi-triangular system: + // [ T[ki+1:n,ki+1:n] - wr ]^T * X = scale*b + vmax := 1.0 + vcrit := bignum + for j := ki + 1; j < n; { + if j == n-1 || t[(j+1)*ldt+j] == 0 { + // 1×1 diagonal block. + + // Scale if necessary to avoid overflow + // when forming the right-hand side. + if norms[j] > vcrit { + rec := 1 / vmax + bi.Dscal(n-ki, rec, b[ki*ldb+iv:], ldb) + vmax = 1 + vcrit = bignum + } + b[j*ldb+iv] -= bi.Ddot(j-ki-1, t[(ki+1)*ldt+j:], ldt, b[(ki+1)*ldb+iv:], ldb) + // Solve [ T[j,j] - wr ]^T * X = b. + scale, _, _ := impl.Dlaln2(false, 1, 1, smin, 1, t[j*ldt+j:], ldt, + 1, 1, b[j*ldb+iv:], ldb, wr, 0, x[:1], 2) + // Scale if necessary. + if scale != 1 { + bi.Dscal(n-ki, scale, b[ki*ldb+iv:], ldb) + } + b[j*ldb+iv] = x[0] + vmax = math.Max(math.Abs(b[j*ldb+iv]), vmax) + vcrit = bignum / vmax + j++ + } else { + // 2×2 diagonal block. + + // Scale if necessary to avoid overflow + // when forming the right-hand side. + beta := math.Max(norms[j], norms[j+1]) + if beta > vcrit { + bi.Dscal(n-ki+1, 1/vmax, b[ki*ldb+iv:], 1) + vmax = 1 + vcrit = bignum + } + b[j*ldb+iv] -= bi.Ddot(j-ki-1, t[(ki+1)*ldt+j:], ldt, b[(ki+1)*ldb+iv:], ldb) + b[(j+1)*ldb+iv] -= bi.Ddot(j-ki-1, t[(ki+1)*ldt+j+1:], ldt, b[(ki+1)*ldb+iv:], ldb) + // Solve + // [ T[j,j]-wr T[j,j+1] ]^T * X = scale*[ b1 ] + // [ T[j+1,j] T[j+1,j+1]-wr ] [ b2 ] + scale, _, _ := impl.Dlaln2(true, 2, 1, smin, 1, t[j*ldt+j:], ldt, + 1, 1, b[j*ldb+iv:], ldb, wr, 0, x[:3], 2) + // Scale if necessary. + if scale != 1 { + bi.Dscal(n-ki, scale, b[ki*ldb+iv:], ldb) + } + b[j*ldb+iv] = x[0] + b[(j+1)*ldb+iv] = x[2] + vmax = math.Max(vmax, math.Max(math.Abs(b[j*ldb+iv]), math.Abs(b[(j+1)*ldb+iv]))) + vcrit = bignum / vmax + j += 2 + } + } + // Copy the vector x or Q*x to VL and normalize. + switch { + case howmny != lapack.AllEVMulQ: + // No back-transform: copy x to VL and normalize. + bi.Dcopy(n-ki, b[ki*ldb+iv:], ldb, vl[ki*ldvl+is:], ldvl) + ii := bi.Idamax(n-ki, vl[ki*ldvl+is:], ldvl) + ki + remax := 1 / math.Abs(vl[ii*ldvl+is]) + bi.Dscal(n-ki, remax, vl[ki*ldvl+is:], ldvl) + for k := 0; k < ki; k++ { + vl[k*ldvl+is] = 0 + } + case nb == 1: + // Version 1: back-transform each vector with Gemv, Q*x. + if n-ki-1 > 0 { + bi.Dgemv(blas.NoTrans, n, n-ki-1, + 1, vl[ki+1:], ldvl, b[(ki+1)*ldb+iv:], ldb, + b[ki*ldb+iv], vl[ki:], ldvl) + } + ii := bi.Idamax(n, vl[ki:], ldvl) + remax := 1 / math.Abs(vl[ii*ldvl+ki]) + bi.Dscal(n, remax, vl[ki:], ldvl) + default: + // Version 2: back-transform block of vectors with Gemm + // zero out above vector. + for k := 0; k < ki; k++ { + b[k*ldb+iv] = 0 + } + iscomplex[iv] = ip + // Back-transform and normalization is done below. + } + } else { + // Complex left eigenvector. + + // Initial solve: + // [ [ T[ki,ki] T[ki,ki+1] ]^T - (wr - i* wi) ]*X = 0. + // [ [ T[ki+1,ki] T[ki+1,ki+1] ] ] + if math.Abs(t[ki*ldt+ki+1]) >= math.Abs(t[(ki+1)*ldt+ki]) { + b[ki*ldb+iv] = wi / t[ki*ldt+ki+1] + b[(ki+1)*ldb+iv+1] = 1 + } else { + b[ki*ldb+iv] = 1 + b[(ki+1)*ldb+iv+1] = -wi / t[(ki+1)*ldt+ki] + } + b[(ki+1)*ldb+iv] = 0 + b[ki*ldb+iv+1] = 0 + // Form right-hand side. + for k := ki + 2; k < n; k++ { + b[k*ldb+iv] = -b[ki*ldb+iv] * t[ki*ldt+k] + b[k*ldb+iv+1] = -b[(ki+1)*ldb+iv+1] * t[(ki+1)*ldt+k] + } + // Solve transposed quasi-triangular system: + // [ T[ki+2:n,ki+2:n]^T - (wr-i*wi) ]*X = b1+i*b2 + vmax := 1.0 + vcrit := bignum + for j := ki + 2; j < n; { + if j == n-1 || t[(j+1)*ldt+j] == 0 { + // 1×1 diagonal block. + + // Scale if necessary to avoid overflow + // when forming the right-hand side elements. + if norms[j] > vcrit { + rec := 1 / vmax + bi.Dscal(n-ki, rec, b[ki*ldb+iv:], ldb) + bi.Dscal(n-ki, rec, b[ki*ldb+iv+1:], ldb) + vmax = 1 + vcrit = bignum + } + b[j*ldb+iv] -= bi.Ddot(j-ki-2, t[(ki+2)*ldt+j:], ldt, b[(ki+2)*ldb+iv:], ldb) + b[j*ldb+iv+1] -= bi.Ddot(j-ki-2, t[(ki+2)*ldt+j:], ldt, b[(ki+2)*ldb+iv+1:], ldb) + // Solve [ T[j,j]-(wr-i*wi) ]*(X11+i*X12) = b1+i*b2. + scale, _, _ := impl.Dlaln2(false, 1, 2, smin, 1, t[j*ldt+j:], ldt, + 1, 1, b[j*ldb+iv:], ldb, wr, -wi, x[:2], 2) + // Scale if necessary. + if scale != 1 { + bi.Dscal(n-ki, scale, b[ki*ldb+iv:], ldb) + bi.Dscal(n-ki, scale, b[ki*ldb+iv+1:], ldb) + } + b[j*ldb+iv] = x[0] + b[j*ldb+iv+1] = x[1] + vmax = math.Max(vmax, math.Max(math.Abs(b[j*ldb+iv]), math.Abs(b[j*ldb+iv+1]))) + vcrit = bignum / vmax + j++ + } else { + // 2×2 diagonal block. + + // Scale if necessary to avoid overflow + // when forming the right-hand side elements. + if math.Max(norms[j], norms[j+1]) > vcrit { + rec := 1 / vmax + bi.Dscal(n-ki, rec, b[ki*ldb+iv:], ldb) + bi.Dscal(n-ki, rec, b[ki*ldb+iv+1:], ldb) + vmax = 1 + vcrit = bignum + } + b[j*ldb+iv] -= bi.Ddot(j-ki-2, t[(ki+2)*ldt+j:], ldt, b[(ki+2)*ldb+iv:], ldb) + b[j*ldb+iv+1] -= bi.Ddot(j-ki-2, t[(ki+2)*ldt+j:], ldt, b[(ki+2)*ldb+iv+1:], ldb) + b[(j+1)*ldb+iv] -= bi.Ddot(j-ki-2, t[(ki+2)*ldt+j+1:], ldt, b[(ki+2)*ldb+iv:], ldb) + b[(j+1)*ldb+iv+1] -= bi.Ddot(j-ki-2, t[(ki+2)*ldt+j+1:], ldt, b[(ki+2)*ldb+iv+1:], ldb) + // Solve 2×2 complex linear equation + // [ [T[j,j] T[j,j+1] ]^T - (wr-i*wi)*I ]*X = scale*b + // [ [T[j+1,j] T[j+1,j+1]] ] + scale, _, _ := impl.Dlaln2(true, 2, 2, smin, 1, t[j*ldt+j:], ldt, + 1, 1, b[j*ldb+iv:], ldb, wr, -wi, x[:], 2) + // Scale if necessary. + if scale != 1 { + bi.Dscal(n-ki, scale, b[ki*ldb+iv:], ldb) + bi.Dscal(n-ki, scale, b[ki*ldb+iv+1:], ldb) + } + b[j*ldb+iv] = x[0] + b[j*ldb+iv+1] = x[1] + b[(j+1)*ldb+iv] = x[2] + b[(j+1)*ldb+iv+1] = x[3] + vmax01 := math.Max(math.Abs(x[0]), math.Abs(x[1])) + vmax23 := math.Max(math.Abs(x[2]), math.Abs(x[3])) + vmax = math.Max(vmax, math.Max(vmax01, vmax23)) + vcrit = bignum / vmax + j += 2 + } + } + // Copy the vector x or Q*x to VL and normalize. + switch { + case howmny != lapack.AllEVMulQ: + // No back-transform: copy x to VL and normalize. + bi.Dcopy(n-ki, b[ki*ldb+iv:], ldb, vl[ki*ldvl+is:], ldvl) + bi.Dcopy(n-ki, b[ki*ldb+iv+1:], ldb, vl[ki*ldvl+is+1:], ldvl) + emax := 0.0 + for k := ki; k < n; k++ { + emax = math.Max(emax, math.Abs(vl[k*ldvl+is])+math.Abs(vl[k*ldvl+is+1])) + } + remax := 1 / emax + bi.Dscal(n-ki, remax, vl[ki*ldvl+is:], ldvl) + bi.Dscal(n-ki, remax, vl[ki*ldvl+is+1:], ldvl) + for k := 0; k < ki; k++ { + vl[k*ldvl+is] = 0 + vl[k*ldvl+is+1] = 0 + } + case nb == 1: + // Version 1: back-transform each vector with GEMV, Q*x. + if n-ki-2 > 0 { + bi.Dgemv(blas.NoTrans, n, n-ki-2, + 1, vl[ki+2:], ldvl, b[(ki+2)*ldb+iv:], ldb, + b[ki*ldb+iv], vl[ki:], ldvl) + bi.Dgemv(blas.NoTrans, n, n-ki-2, + 1, vl[ki+2:], ldvl, b[(ki+2)*ldb+iv+1:], ldb, + b[(ki+1)*ldb+iv+1], vl[ki+1:], ldvl) + } else { + bi.Dscal(n, b[ki*ldb+iv], vl[ki:], ldvl) + bi.Dscal(n, b[(ki+1)*ldb+iv+1], vl[ki+1:], ldvl) + } + emax := 0.0 + for k := 0; k < n; k++ { + emax = math.Max(emax, math.Abs(vl[k*ldvl+ki])+math.Abs(vl[k*ldvl+ki+1])) + } + remax := 1 / emax + bi.Dscal(n, remax, vl[ki:], ldvl) + bi.Dscal(n, remax, vl[ki+1:], ldvl) + default: + // Version 2: back-transform block of vectors with GEMM. + // Zero out above vector. + // Could go from ki-nv+1 to ki-1. + for k := 0; k < ki; k++ { + b[k*ldb+iv] = 0 + b[k*ldb+iv+1] = 0 + } + iscomplex[iv] = ip + iscomplex[iv+1] = -ip + iv++ + // Back-transform and normalization is done below. + } + } + if nb > 1 { + // Blocked version of back-transform. + // For complex case, ki2 includes both vectors ki and ki+1. + ki2 := ki + if ip != 0 { + ki2++ + } + // Columns [0:iv] of work are valid vectors. When the + // number of vectors stored reaches nb-1 or nb, or if + // this was last vector, do the Gemm. + if iv >= nb-2 || ki2 == n-1 { + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, iv+1, n-ki2+iv, + 1, vl[ki2-iv:], ldvl, b[(ki2-iv)*ldb:], ldb, + 0, b[nb:], ldb) + // Normalize vectors. + var remax float64 + for k := 0; k <= iv; k++ { + if iscomplex[k] == 0 { + // Real eigenvector. + ii := bi.Idamax(n, b[nb+k:], ldb) + remax = 1 / math.Abs(b[ii*ldb+nb+k]) + } else if iscomplex[k] == 1 { + // First eigenvector of conjugate pair. + emax := 0.0 + for ii := 0; ii < n; ii++ { + emax = math.Max(emax, math.Abs(b[ii*ldb+nb+k])+math.Abs(b[ii*ldb+nb+k+1])) + } + remax = 1 / emax + // Second eigenvector of conjugate pair + // will reuse this value of remax. + } + bi.Dscal(n, remax, b[nb+k:], ldb) + } + impl.Dlacpy(blas.All, n, iv+1, b[nb:], ldb, vl[ki2-iv:], ldvl) + iv = 0 + } else { + iv++ + } + } + is++ + if ip != 0 { + is++ + } + } + + return m +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dtrexc.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrexc.go new file mode 100644 index 00000000..4a88931f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrexc.go @@ -0,0 +1,221 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "gonum.org/v1/gonum/lapack" + +// Dtrexc reorders the real Schur factorization of a n×n real matrix +// A = Q*T*Q^T +// so that the diagonal block of T with row index ifst is moved to row ilst. +// +// On entry, T must be in Schur canonical form, that is, block upper triangular +// with 1×1 and 2×2 diagonal blocks; each 2×2 diagonal block has its diagonal +// elements equal and its off-diagonal elements of opposite sign. +// +// On return, T will be reordered by an orthogonal similarity transformation Z +// as Z^T*T*Z, and will be again in Schur canonical form. +// +// If compq is lapack.UpdateSchur, on return the matrix Q of Schur vectors will be +// updated by postmultiplying it with Z. +// If compq is lapack.None, the matrix Q is not referenced and will not be +// updated. +// For other values of compq Dtrexc will panic. +// +// ifst and ilst specify the reordering of the diagonal blocks of T. The block +// with row index ifst is moved to row ilst, by a sequence of transpositions +// between adjacent blocks. +// +// If ifst points to the second row of a 2×2 block, ifstOut will point to the +// first row, otherwise it will be equal to ifst. +// +// ilstOut will point to the first row of the block in its final position. If ok +// is true, ilstOut may differ from ilst by +1 or -1. +// +// It must hold that +// 0 <= ifst < n, and 0 <= ilst < n, +// otherwise Dtrexc will panic. +// +// If ok is false, two adjacent blocks were too close to swap because the +// problem is very ill-conditioned. T may have been partially reordered, and +// ilstOut will point to the first row of the block at the position to which it +// has been moved. +// +// work must have length at least n, otherwise Dtrexc will panic. +// +// Dtrexc is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dtrexc(compq lapack.EVComp, n int, t []float64, ldt int, q []float64, ldq int, ifst, ilst int, work []float64) (ifstOut, ilstOut int, ok bool) { + checkMatrix(n, n, t, ldt) + var wantq bool + switch compq { + default: + panic("lapack: bad value of compq") + case lapack.None: + // Nothing to do because wantq is already false. + case lapack.UpdateSchur: + wantq = true + checkMatrix(n, n, q, ldq) + } + if (ifst < 0 || n <= ifst) && n > 0 { + panic("lapack: ifst out of range") + } + if (ilst < 0 || n <= ilst) && n > 0 { + panic("lapack: ilst out of range") + } + if len(work) < n { + panic(badWork) + } + + ok = true + + // Quick return if possible. + if n <= 1 { + return ifst, ilst, true + } + + // Determine the first row of specified block + // and find out it is 1×1 or 2×2. + if ifst > 0 && t[ifst*ldt+ifst-1] != 0 { + ifst-- + } + nbf := 1 // Size of the first block. + if ifst+1 < n && t[(ifst+1)*ldt+ifst] != 0 { + nbf = 2 + } + // Determine the first row of the final block + // and find out it is 1×1 or 2×2. + if ilst > 0 && t[ilst*ldt+ilst-1] != 0 { + ilst-- + } + nbl := 1 // Size of the last block. + if ilst+1 < n && t[(ilst+1)*ldt+ilst] != 0 { + nbl = 2 + } + + switch { + case ifst == ilst: + return ifst, ilst, true + + case ifst < ilst: + // Update ilst. + switch { + case nbf == 2 && nbl == 1: + ilst-- + case nbf == 1 && nbl == 2: + ilst++ + } + here := ifst + for here < ilst { + // Swap block with next one below. + if nbf == 1 || nbf == 2 { + // Current block either 1×1 or 2×2. + nbnext := 1 // Size of the next block. + if here+nbf+1 < n && t[(here+nbf+1)*ldt+here+nbf] != 0 { + nbnext = 2 + } + ok = impl.Dlaexc(wantq, n, t, ldt, q, ldq, here, nbf, nbnext, work) + if !ok { + return ifst, here, false + } + here += nbnext + // Test if 2×2 block breaks into two 1×1 blocks. + if nbf == 2 && t[(here+1)*ldt+here] == 0 { + nbf = 3 + } + continue + } + + // Current block consists of two 1×1 blocks each of + // which must be swapped individually. + nbnext := 1 // Size of the next block. + if here+3 < n && t[(here+3)*ldt+here+2] != 0 { + nbnext = 2 + } + ok = impl.Dlaexc(wantq, n, t, ldt, q, ldq, here+1, 1, nbnext, work) + if !ok { + return ifst, here, false + } + if nbnext == 1 { + // Swap two 1×1 blocks, no problems possible. + impl.Dlaexc(wantq, n, t, ldt, q, ldq, here, 1, nbnext, work) + here++ + continue + } + // Recompute nbnext in case 2×2 split. + if t[(here+2)*ldt+here+1] == 0 { + nbnext = 1 + } + if nbnext == 2 { + // 2×2 block did not split. + ok = impl.Dlaexc(wantq, n, t, ldt, q, ldq, here, 1, nbnext, work) + if !ok { + return ifst, here, false + } + } else { + // 2×2 block did split. + impl.Dlaexc(wantq, n, t, ldt, q, ldq, here, 1, 1, work) + impl.Dlaexc(wantq, n, t, ldt, q, ldq, here+1, 1, 1, work) + } + here += 2 + } + return ifst, here, true + + default: // ifst > ilst + here := ifst + for here > ilst { + // Swap block with next one above. + if nbf == 1 || nbf == 2 { + // Current block either 1×1 or 2×2. + nbnext := 1 + if here-2 >= 0 && t[(here-1)*ldt+here-2] != 0 { + nbnext = 2 + } + ok = impl.Dlaexc(wantq, n, t, ldt, q, ldq, here-nbnext, nbnext, nbf, work) + if !ok { + return ifst, here, false + } + here -= nbnext + // Test if 2×2 block breaks into two 1×1 blocks. + if nbf == 2 && t[(here+1)*ldt+here] == 0 { + nbf = 3 + } + continue + } + + // Current block consists of two 1×1 blocks each of + // which must be swapped individually. + nbnext := 1 + if here-2 >= 0 && t[(here-1)*ldt+here-2] != 0 { + nbnext = 2 + } + ok = impl.Dlaexc(wantq, n, t, ldt, q, ldq, here-nbnext, nbnext, 1, work) + if !ok { + return ifst, here, false + } + if nbnext == 1 { + // Swap two 1×1 blocks, no problems possible. + impl.Dlaexc(wantq, n, t, ldt, q, ldq, here, nbnext, 1, work) + here-- + continue + } + // Recompute nbnext in case 2×2 split. + if t[here*ldt+here-1] == 0 { + nbnext = 1 + } + if nbnext == 2 { + // 2×2 block did not split. + ok = impl.Dlaexc(wantq, n, t, ldt, q, ldq, here-1, 2, 1, work) + if !ok { + return ifst, here, false + } + } else { + // 2×2 block did split. + impl.Dlaexc(wantq, n, t, ldt, q, ldq, here, 1, 1, work) + impl.Dlaexc(wantq, n, t, ldt, q, ldq, here-1, 1, 1, work) + } + here -= 2 + } + return ifst, here, true + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dtrti2.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrti2.go new file mode 100644 index 00000000..8998f5eb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrti2.go @@ -0,0 +1,57 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dtrti2 computes the inverse of a triangular matrix, storing the result in place +// into a. This is the BLAS level 2 version of the algorithm. +// +// Dtrti2 is an internal routine. It is exported for testing purposes. +func (impl Implementation) Dtrti2(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) { + checkMatrix(n, n, a, lda) + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + if diag != blas.NonUnit && diag != blas.Unit { + panic(badDiag) + } + bi := blas64.Implementation() + + nonUnit := diag == blas.NonUnit + // TODO(btracey): Replace this with a row-major ordering. + if uplo == blas.Upper { + for j := 0; j < n; j++ { + var ajj float64 + if nonUnit { + ajj = 1 / a[j*lda+j] + a[j*lda+j] = ajj + ajj *= -1 + } else { + ajj = -1 + } + bi.Dtrmv(blas.Upper, blas.NoTrans, diag, j, a, lda, a[j:], lda) + bi.Dscal(j, ajj, a[j:], lda) + } + return + } + for j := n - 1; j >= 0; j-- { + var ajj float64 + if nonUnit { + ajj = 1 / a[j*lda+j] + a[j*lda+j] = ajj + ajj *= -1 + } else { + ajj = -1 + } + if j < n-1 { + bi.Dtrmv(blas.Lower, blas.NoTrans, diag, n-j-1, a[(j+1)*lda+j+1:], lda, a[(j+1)*lda+j:], lda) + bi.Dscal(n-j-1, ajj, a[(j+1)*lda+j:], lda) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dtrtri.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrtri.go new file mode 100644 index 00000000..25e43ddc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrtri.go @@ -0,0 +1,64 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dtrtri computes the inverse of a triangular matrix, storing the result in place +// into a. This is the BLAS level 3 version of the algorithm which builds upon +// Dtrti2 to operate on matrix blocks instead of only individual columns. +// +// Dtrtri will not perform the inversion if the matrix is singular, and returns +// a boolean indicating whether the inversion was successful. +func (impl Implementation) Dtrtri(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) (ok bool) { + checkMatrix(n, n, a, lda) + if uplo != blas.Upper && uplo != blas.Lower { + panic(badUplo) + } + if diag != blas.NonUnit && diag != blas.Unit { + panic(badDiag) + } + if n == 0 { + return false + } + nonUnit := diag == blas.NonUnit + if nonUnit { + for i := 0; i < n; i++ { + if a[i*lda+i] == 0 { + return false + } + } + } + + bi := blas64.Implementation() + + nb := impl.Ilaenv(1, "DTRTRI", "UD", n, -1, -1, -1) + if nb <= 1 || nb > n { + impl.Dtrti2(uplo, diag, n, a, lda) + return true + } + if uplo == blas.Upper { + for j := 0; j < n; j += nb { + jb := min(nb, n-j) + bi.Dtrmm(blas.Left, blas.Upper, blas.NoTrans, diag, j, jb, 1, a, lda, a[j:], lda) + bi.Dtrsm(blas.Right, blas.Upper, blas.NoTrans, diag, j, jb, -1, a[j*lda+j:], lda, a[j:], lda) + impl.Dtrti2(blas.Upper, diag, jb, a[j*lda+j:], lda) + } + return true + } + nn := ((n - 1) / nb) * nb + for j := nn; j >= 0; j -= nb { + jb := min(nb, n-j) + if j+jb <= n-1 { + bi.Dtrmm(blas.Left, blas.Lower, blas.NoTrans, diag, n-j-jb, jb, 1, a[(j+jb)*lda+j+jb:], lda, a[(j+jb)*lda+j:], lda) + bi.Dtrsm(blas.Right, blas.Lower, blas.NoTrans, diag, n-j-jb, jb, -1, a[j*lda+j:], lda, a[(j+jb)*lda+j:], lda) + } + impl.Dtrti2(blas.Lower, diag, jb, a[j*lda+j:], lda) + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/dtrtrs.go b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrtrs.go new file mode 100644 index 00000000..6760796d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/dtrtrs.go @@ -0,0 +1,30 @@ +// 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/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dtrtrs solves a triangular system of the form A * X = B or A^T * X = B. Dtrtrs +// returns whether the solve completed successfully. If A is singular, no solve is performed. +func (impl Implementation) Dtrtrs(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n, nrhs int, a []float64, lda int, b []float64, ldb int) (ok bool) { + nounit := diag == blas.NonUnit + if n == 0 { + return false + } + // Check for singularity. + if nounit { + for i := 0; i < n; i++ { + if a[i*lda+i] == 0 { + return false + } + } + } + bi := blas64.Implementation() + bi.Dtrsm(blas.Left, uplo, trans, diag, n, nrhs, 1, a, lda, b, ldb) + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/general.go b/vendor/gonum.org/v1/gonum/lapack/gonum/general.go new file mode 100644 index 00000000..4006ea70 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/general.go @@ -0,0 +1,143 @@ +// 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/lapack" +) + +// Implementation is the native Go implementation of LAPACK routines. It +// is built on top of calls to the return of blas64.Implementation(), so while +// this code is in pure Go, the underlying BLAS implementation may not be. +type Implementation struct{} + +var _ lapack.Float64 = Implementation{} + +// This list is duplicated in lapack/cgo. Keep in sync. +const ( + absIncNotOne = "lapack: increment not one or negative one" + badAlpha = "lapack: bad alpha length" + badAuxv = "lapack: auxv has insufficient length" + badBeta = "lapack: bad beta length" + badD = "lapack: d has insufficient length" + badDecompUpdate = "lapack: bad decomp update" + badDiag = "lapack: bad diag" + badDims = "lapack: bad input dimensions" + badDirect = "lapack: bad direct" + badE = "lapack: e has insufficient length" + badEVComp = "lapack: bad EVComp" + badEVJob = "lapack: bad EVJob" + badEVSide = "lapack: bad EVSide" + badGSVDJob = "lapack: bad GSVDJob" + badHowMany = "lapack: bad HowMany" + badIlo = "lapack: ilo out of range" + badIhi = "lapack: ihi out of range" + badIpiv = "lapack: bad permutation length" + badJob = "lapack: bad Job" + badK1 = "lapack: k1 out of range" + badK2 = "lapack: k2 out of range" + badKperm = "lapack: incorrect permutation length" + badLdA = "lapack: index of a out of range" + badNb = "lapack: nb out of range" + badNorm = "lapack: bad norm" + badPivot = "lapack: bad pivot" + badS = "lapack: s has insufficient length" + badShifts = "lapack: bad shifts" + badSide = "lapack: bad side" + badSlice = "lapack: bad input slice length" + badSort = "lapack: bad Sort" + badStore = "lapack: bad store" + badTau = "lapack: tau has insufficient length" + badTauQ = "lapack: tauQ has insufficient length" + badTauP = "lapack: tauP has insufficient length" + badTrans = "lapack: bad trans" + badVn1 = "lapack: vn1 has insufficient length" + badVn2 = "lapack: vn2 has insufficient length" + badUplo = "lapack: illegal triangle" + badWork = "lapack: insufficient working memory" + badZ = "lapack: insufficient z length" + kGTM = "lapack: k > m" + kGTN = "lapack: k > n" + kLT0 = "lapack: k < 0" + mLTN = "lapack: m < n" + nanScale = "lapack: NaN scale factor" + negDimension = "lapack: negative matrix dimension" + negZ = "lapack: negative z value" + nLT0 = "lapack: n < 0" + nLTM = "lapack: n < m" + offsetGTM = "lapack: offset > m" + shortWork = "lapack: working array shorter than declared" + zeroDiv = "lapack: zero divisor" +) + +// checkMatrix verifies the parameters of a matrix input. +func checkMatrix(m, n int, a []float64, lda int) { + if m < 0 { + panic("lapack: has negative number of rows") + } + if n < 0 { + panic("lapack: has negative number of columns") + } + if lda < n { + panic("lapack: stride less than number of columns") + } + if len(a) < (m-1)*lda+n { + panic("lapack: insufficient matrix slice length") + } +} + +func checkVector(n int, v []float64, inc int) { + if n < 0 { + panic("lapack: negative vector length") + } + if (inc > 0 && (n-1)*inc >= len(v)) || (inc < 0 && (1-n)*inc >= len(v)) { + panic("lapack: insufficient vector slice length") + } +} + +func checkSymBanded(ab []float64, n, kd, lda int) { + if n < 0 { + panic("lapack: negative banded length") + } + if kd < 0 { + panic("lapack: negative bandwidth value") + } + if lda < kd+1 { + panic("lapack: stride less than number of bands") + } + if len(ab) < (n-1)*lda+kd { + panic("lapack: insufficient banded vector length") + } +} + +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 +} + +const ( + // dlamchE is the machine epsilon. For IEEE this is 2^{-53}. + dlamchE = 1.0 / (1 << 53) + + // dlamchB is the radix of the machine (the base of the number system). + dlamchB = 2 + + // dlamchP is base * eps. + dlamchP = dlamchB * dlamchE + + // dlamchS is the "safe minimum", that is, the lowest number such that + // 1/dlamchS does not overflow, or also the smallest normal number. + // For IEEE this is 2^{-1022}. + dlamchS = 1.0 / (1 << 256) / (1 << 256) / (1 << 256) / (1 << 254) +) diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/iladlc.go b/vendor/gonum.org/v1/gonum/lapack/gonum/iladlc.go new file mode 100644 index 00000000..126a6f9d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/iladlc.go @@ -0,0 +1,33 @@ +// 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 + +// Iladlc scans a matrix for its last non-zero column. Returns -1 if the matrix +// is all zeros. +// +// Iladlc is an internal routine. It is exported for testing purposes. +func (Implementation) Iladlc(m, n int, a []float64, lda int) int { + if n == 0 || m == 0 { + return n - 1 + } + checkMatrix(m, n, a, lda) + + // Test common case where corner is non-zero. + if a[n-1] != 0 || a[(m-1)*lda+(n-1)] != 0 { + return n - 1 + } + + // Scan each row tracking the highest column seen. + highest := -1 + for i := 0; i < m; i++ { + for j := n - 1; j >= 0; j-- { + if a[i*lda+j] != 0 { + highest = max(highest, j) + break + } + } + } + return highest +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/iladlr.go b/vendor/gonum.org/v1/gonum/lapack/gonum/iladlr.go new file mode 100644 index 00000000..1ec7c523 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/iladlr.go @@ -0,0 +1,30 @@ +// 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 + +// Iladlr scans a matrix for its last non-zero row. Returns -1 if the matrix +// is all zeros. +// +// Iladlr is an internal routine. It is exported for testing purposes. +func (Implementation) Iladlr(m, n int, a []float64, lda int) int { + if m == 0 { + return m - 1 + } + + checkMatrix(m, n, a, lda) + + // Check the common case where the corner is non-zero + if a[(m-1)*lda] != 0 || a[(m-1)*lda+n-1] != 0 { + return m - 1 + } + for i := m - 1; i >= 0; i-- { + for j := 0; j < n; j++ { + if a[i*lda+j] != 0 { + return i + } + } + } + return -1 +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/ilaenv.go b/vendor/gonum.org/v1/gonum/lapack/gonum/ilaenv.go new file mode 100644 index 00000000..750e3c44 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/ilaenv.go @@ -0,0 +1,387 @@ +// 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 + +// Ilaenv returns algorithm tuning parameters for the algorithm given by the +// input string. ispec specifies the parameter to return: +// 1: The optimal block size for a blocked algorithm. +// 2: The minimum block size for a blocked algorithm. +// 3: The block size of unprocessed data at which a blocked algorithm should +// crossover to an unblocked version. +// 4: The number of shifts. +// 5: The minimum column dimension for blocking to be used. +// 6: The crossover point for SVD (to use QR factorization or not). +// 7: The number of processors. +// 8: The crossover point for multi-shift in QR and QZ methods for non-symmetric eigenvalue problems. +// 9: Maximum size of the subproblems in divide-and-conquer algorithms. +// 10: ieee NaN arithmetic can be trusted not to trap. +// 11: infinity arithmetic can be trusted not to trap. +// 12...16: parameters for Dhseqr and related functions. See Iparmq for more +// information. +// +// Ilaenv is an internal routine. It is exported for testing purposes. +func (impl Implementation) Ilaenv(ispec int, s string, opts string, n1, n2, n3, n4 int) int { + // TODO(btracey): Replace this with a constant lookup? A list of constants? + sname := s[0] == 'S' || s[0] == 'D' + cname := s[0] == 'C' || s[0] == 'Z' + if !sname && !cname { + panic("lapack: bad name") + } + c2 := s[1:3] + c3 := s[3:6] + c4 := c3[1:3] + + switch ispec { + default: + panic("lapack: bad ispec") + case 1: + switch c2 { + default: + panic("lapack: bad function name") + case "GE": + switch c3 { + default: + panic("lapack: bad function name") + case "TRF": + if sname { + return 64 + } + return 64 + case "QRF", "RQF", "LQF", "QLF": + if sname { + return 32 + } + return 32 + case "HRD": + if sname { + return 32 + } + return 32 + case "BRD": + if sname { + return 32 + } + return 32 + case "TRI": + if sname { + return 64 + } + return 64 + } + case "PO": + switch c3 { + default: + panic("lapack: bad function name") + case "TRF": + if sname { + return 64 + } + return 64 + } + case "SY": + switch c3 { + default: + panic("lapack: bad function name") + case "TRF": + if sname { + return 64 + } + return 64 + case "TRD": + return 32 + case "GST": + return 64 + } + case "HE": + switch c3 { + default: + panic("lapack: bad function name") + case "TRF": + return 64 + case "TRD": + return 32 + case "GST": + return 64 + } + case "OR": + switch c3[0] { + default: + panic("lapack: bad function name") + case 'G': + switch c3[1:] { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 32 + } + case 'M': + switch c3[1:] { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 32 + } + } + case "UN": + switch c3[0] { + default: + panic("lapack: bad function name") + case 'G': + switch c3[1:] { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 32 + } + case 'M': + switch c3[1:] { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 32 + } + } + case "GB": + switch c3 { + default: + panic("lapack: bad function name") + case "TRF": + if sname { + if n4 <= 64 { + return 1 + } + return 32 + } + if n4 <= 64 { + return 1 + } + return 32 + } + case "PB": + switch c3 { + default: + panic("lapack: bad function name") + case "TRF": + if sname { + if n4 <= 64 { + return 1 + } + return 32 + } + if n4 <= 64 { + return 1 + } + return 32 + } + case "TR": + switch c3 { + default: + panic("lapack: bad function name") + case "TRI": + if sname { + return 64 + } + return 64 + case "EVC": + if sname { + return 64 + } + return 64 + } + case "LA": + switch c3 { + default: + panic("lapack: bad function name") + case "UUM": + if sname { + return 64 + } + return 64 + } + case "ST": + if sname && c3 == "EBZ" { + return 1 + } + panic("lapack: bad function name") + } + case 2: + switch c2 { + default: + panic("lapack: bad function name") + case "GE": + switch c3 { + default: + panic("lapack: bad function name") + case "QRF", "RQF", "LQF", "QLF": + if sname { + return 2 + } + return 2 + case "HRD": + if sname { + return 2 + } + return 2 + case "BRD": + if sname { + return 2 + } + return 2 + case "TRI": + if sname { + return 2 + } + return 2 + } + case "SY": + switch c3 { + default: + panic("lapack: bad function name") + case "TRF": + if sname { + return 8 + } + return 8 + case "TRD": + if sname { + return 2 + } + panic("lapack: bad function name") + } + case "HE": + if c3 == "TRD" { + return 2 + } + panic("lapack: bad function name") + case "OR": + if !sname { + panic("lapack: bad function name") + } + switch c3[0] { + default: + panic("lapack: bad function name") + case 'G': + switch c4 { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 2 + } + case 'M': + switch c4 { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 2 + } + } + case "UN": + switch c3[0] { + default: + panic("lapack: bad function name") + case 'G': + switch c4 { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 2 + } + case 'M': + switch c4 { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 2 + } + } + } + case 3: + switch c2 { + default: + panic("lapack: bad function name") + case "GE": + switch c3 { + default: + panic("lapack: bad function name") + case "QRF", "RQF", "LQF", "QLF": + if sname { + return 128 + } + return 128 + case "HRD": + if sname { + return 128 + } + return 128 + case "BRD": + if sname { + return 128 + } + return 128 + } + case "SY": + if sname && c3 == "TRD" { + return 32 + } + panic("lapack: bad function name") + case "HE": + if c3 == "TRD" { + return 32 + } + panic("lapack: bad function name") + case "OR": + switch c3[0] { + default: + panic("lapack: bad function name") + case 'G': + switch c4 { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 128 + } + } + case "UN": + switch c3[0] { + default: + panic("lapack: bad function name") + case 'G': + switch c4 { + default: + panic("lapack: bad function name") + case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR": + return 128 + } + } + } + case 4: + // Used by xHSEQR + return 6 + case 5: + // Not used + return 2 + case 6: + // Used by xGELSS and xGESVD + return int(float64(min(n1, n2)) * 1.6) + case 7: + // Not used + return 1 + case 8: + // Used by xHSEQR + return 50 + case 9: + // used by xGELSD and xGESDD + return 25 + case 10: + // Go guarantees ieee + return 1 + case 11: + // Go guarantees ieee + return 1 + case 12, 13, 14, 15, 16: + // Dhseqr and related functions for eigenvalue problems. + return impl.Iparmq(ispec, s, opts, n1, n2, n3, n4) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/iparmq.go b/vendor/gonum.org/v1/gonum/lapack/gonum/iparmq.go new file mode 100644 index 00000000..4fc255c5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/iparmq.go @@ -0,0 +1,115 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import "math" + +// Iparmq returns problem and machine dependent parameters useful for Dhseqr and +// related subroutines for eigenvalue problems. +// +// ispec specifies the parameter to return: +// 12: Crossover point between Dlahqr and Dlaqr0. Will be at least 11. +// 13: Deflation window size. +// 14: Nibble crossover point. Determines when to skip a multi-shift QR sweep. +// 15: Number of simultaneous shifts in a multishift QR iteration. +// 16: Select structured matrix multiply. +// For other values of ispec Iparmq will panic. +// +// name is the name of the calling function. name must be in uppercase but this +// is not checked. +// +// opts is not used and exists for future use. +// +// n is the order of the Hessenberg matrix H. +// +// ilo and ihi specify the block [ilo:ihi+1,ilo:ihi+1] that is being processed. +// +// lwork is the amount of workspace available. +// +// Except for ispec input parameters are not checked. +// +// Iparmq is an internal routine. It is exported for testing purposes. +func (Implementation) Iparmq(ispec int, name, opts string, n, ilo, ihi, lwork int) int { + nh := ihi - ilo + 1 + ns := 2 + switch { + case nh >= 30: + ns = 4 + case nh >= 60: + ns = 10 + case nh >= 150: + ns = max(10, nh/int(math.Log(float64(nh))/math.Ln2)) + case nh >= 590: + ns = 64 + case nh >= 3000: + ns = 128 + case nh >= 6000: + ns = 256 + } + ns = max(2, ns-(ns%2)) + + switch ispec { + default: + panic("lapack: bad ispec") + + case 12: + // Matrices of order smaller than nmin get sent to Dlahqr, the + // classic double shift algorithm. This must be at least 11. + const nmin = 75 + return nmin + + case 13: + const knwswp = 500 + if nh <= knwswp { + return ns + } + return 3 * ns / 2 + + case 14: + // Skip a computationally expensive multi-shift QR sweep with + // Dlaqr5 whenever aggressive early deflation finds at least + // nibble*(window size)/100 deflations. The default, small, + // value reflects the expectation that the cost of looking + // through the deflation window with Dlaqr3 will be + // substantially smaller. + const nibble = 14 + return nibble + + case 15: + return ns + + case 16: + if len(name) != 6 { + panic("lapack: bad name") + } + const ( + k22min = 14 + kacmin = 14 + ) + var acc22 int + switch { + case name[1:] == "GGHRD" || name[1:] == "GGHD3": + acc22 = 1 + if nh >= k22min { + acc22 = 2 + } + case name[3:] == "EXC": + if nh >= kacmin { + acc22 = 1 + } + if nh >= k22min { + acc22 = 2 + } + case name[1:] == "HSEQR" || name[1:5] == "LAQR": + if ns >= kacmin { + acc22 = 1 + } + if ns >= k22min { + acc22 = 2 + } + } + return acc22 + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/gonum/lapack_test.go b/vendor/gonum.org/v1/gonum/lapack/gonum/lapack_test.go new file mode 100644 index 00000000..5a34fa85 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/gonum/lapack_test.go @@ -0,0 +1,441 @@ +// 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 ( + "testing" + + "gonum.org/v1/gonum/lapack/testlapack" +) + +var appengine bool + +var impl = Implementation{} + +func TestDbdsqr(t *testing.T) { + testlapack.DbdsqrTest(t, impl) +} + +func TestDhseqr(t *testing.T) { + testlapack.DhseqrTest(t, impl) +} + +func TestDgebak(t *testing.T) { + testlapack.DgebakTest(t, impl) +} + +func TestDgebal(t *testing.T) { + testlapack.DgebalTest(t, impl) +} + +func TestDgebd2(t *testing.T) { + testlapack.Dgebd2Test(t, impl) +} + +func TestDgebrd(t *testing.T) { + if appengine { + t.Skip("non-asm implementation fails test") + } + testlapack.DgebrdTest(t, impl) +} + +func TestDgecon(t *testing.T) { + testlapack.DgeconTest(t, impl) +} + +func TestDgeev(t *testing.T) { + if appengine { + t.Skip("non-asm implementation fails test") + } + testlapack.DgeevTest(t, impl) +} + +func TestDgehd2(t *testing.T) { + testlapack.Dgehd2Test(t, impl) +} + +func TestDgehrd(t *testing.T) { + testlapack.DgehrdTest(t, impl) +} + +func TestDgelqf(t *testing.T) { + testlapack.DgelqfTest(t, impl) +} + +func TestDgelq2(t *testing.T) { + testlapack.Dgelq2Test(t, impl) +} + +func TestDgeql2(t *testing.T) { + testlapack.Dgeql2Test(t, impl) +} + +func TestDgels(t *testing.T) { + testlapack.DgelsTest(t, impl) +} + +func TestDgerq2(t *testing.T) { + testlapack.Dgerq2Test(t, impl) +} + +func TestDgeqp3(t *testing.T) { + testlapack.Dgeqp3Test(t, impl) +} + +func TestDgeqr2(t *testing.T) { + testlapack.Dgeqr2Test(t, impl) +} + +func TestDgeqrf(t *testing.T) { + testlapack.DgeqrfTest(t, impl) +} + +func TestDgerqf(t *testing.T) { + testlapack.DgerqfTest(t, impl) +} + +func TestDgesvd(t *testing.T) { + testlapack.DgesvdTest(t, impl) +} + +func TestDgetri(t *testing.T) { + testlapack.DgetriTest(t, impl) +} + +func TestDgetf2(t *testing.T) { + testlapack.Dgetf2Test(t, impl) +} + +func TestDgetrf(t *testing.T) { + testlapack.DgetrfTest(t, impl) +} + +func TestDgetrs(t *testing.T) { + testlapack.DgetrsTest(t, impl) +} + +func TestDggsvd3(t *testing.T) { + testlapack.Dggsvd3Test(t, impl) +} + +func TestDggsvp3(t *testing.T) { + testlapack.Dggsvp3Test(t, impl) +} + +func TestDlabrd(t *testing.T) { + testlapack.DlabrdTest(t, impl) +} + +func TestDlacn2(t *testing.T) { + testlapack.Dlacn2Test(t, impl) +} + +func TestDlacpy(t *testing.T) { + testlapack.DlacpyTest(t, impl) +} + +func TestDlae2(t *testing.T) { + testlapack.Dlae2Test(t, impl) +} + +func TestDlaev2(t *testing.T) { + testlapack.Dlaev2Test(t, impl) +} + +func TestDlaexc(t *testing.T) { + testlapack.DlaexcTest(t, impl) +} + +func TestDlags2(t *testing.T) { + testlapack.Dlags2Test(t, impl) +} + +func TestDlahqr(t *testing.T) { + testlapack.DlahqrTest(t, impl) +} + +func TestDlahr2(t *testing.T) { + testlapack.Dlahr2Test(t, impl) +} + +func TestDlaln2(t *testing.T) { + testlapack.Dlaln2Test(t, impl) +} + +func TestDlange(t *testing.T) { + testlapack.DlangeTest(t, impl) +} + +func TestDlapy2(t *testing.T) { + testlapack.Dlapy2Test(t, impl) +} + +func TestDlapll(t *testing.T) { + testlapack.DlapllTest(t, impl) +} + +func TestDlapmt(t *testing.T) { + testlapack.DlapmtTest(t, impl) +} + +func TestDlas2(t *testing.T) { + testlapack.Dlas2Test(t, impl) +} + +func TestDlascl(t *testing.T) { + testlapack.DlasclTest(t, impl) +} + +func TestDlaset(t *testing.T) { + testlapack.DlasetTest(t, impl) +} + +func TestDlasrt(t *testing.T) { + testlapack.DlasrtTest(t, impl) +} + +func TestDlaswp(t *testing.T) { + testlapack.DlaswpTest(t, impl) +} + +func TestDlasy2(t *testing.T) { + testlapack.Dlasy2Test(t, impl) +} + +func TestDlanst(t *testing.T) { + testlapack.DlanstTest(t, impl) +} + +func TestDlansy(t *testing.T) { + testlapack.DlansyTest(t, impl) +} + +func TestDlantr(t *testing.T) { + testlapack.DlantrTest(t, impl) +} + +func TestDlanv2(t *testing.T) { + testlapack.Dlanv2Test(t, impl) +} + +func TestDlaqr04(t *testing.T) { + testlapack.Dlaqr04Test(t, impl) +} + +func TestDlaqp2(t *testing.T) { + testlapack.Dlaqp2Test(t, impl) +} + +func TestDlaqps(t *testing.T) { + testlapack.DlaqpsTest(t, impl) +} + +func TestDlaqr1(t *testing.T) { + testlapack.Dlaqr1Test(t, impl) +} + +func TestDlaqr23(t *testing.T) { + testlapack.Dlaqr23Test(t, impl) +} + +func TestDlaqr5(t *testing.T) { + testlapack.Dlaqr5Test(t, impl) +} + +func TestDlarf(t *testing.T) { + testlapack.DlarfTest(t, impl) +} + +func TestDlarfb(t *testing.T) { + testlapack.DlarfbTest(t, impl) +} + +func TestDlarfg(t *testing.T) { + testlapack.DlarfgTest(t, impl) +} + +func TestDlarft(t *testing.T) { + testlapack.DlarftTest(t, impl) +} + +func TestDlarfx(t *testing.T) { + testlapack.DlarfxTest(t, impl) +} + +func TestDlartg(t *testing.T) { + testlapack.DlartgTest(t, impl) +} + +func TestDlasq1(t *testing.T) { + testlapack.Dlasq1Test(t, impl) +} + +func TestDlasq2(t *testing.T) { + testlapack.Dlasq2Test(t, impl) +} + +func TestDlasq3(t *testing.T) { + testlapack.Dlasq3Test(t, impl) +} + +func TestDlasq4(t *testing.T) { + testlapack.Dlasq4Test(t, impl) +} + +func TestDlasq5(t *testing.T) { + testlapack.Dlasq5Test(t, impl) +} + +func TestDlasr(t *testing.T) { + testlapack.DlasrTest(t, impl) +} + +func TestDlasv2(t *testing.T) { + testlapack.Dlasv2Test(t, impl) +} + +func TestDlatrd(t *testing.T) { + testlapack.DlatrdTest(t, impl) +} + +func TestDlatrs(t *testing.T) { + testlapack.DlatrsTest(t, impl) +} + +func TestDorg2r(t *testing.T) { + testlapack.Dorg2rTest(t, impl) +} + +func TestDorgbr(t *testing.T) { + testlapack.DorgbrTest(t, impl) +} + +func TestDorghr(t *testing.T) { + testlapack.DorghrTest(t, impl) +} + +func TestDorg2l(t *testing.T) { + testlapack.Dorg2lTest(t, impl) +} + +func TestDorgl2(t *testing.T) { + testlapack.Dorgl2Test(t, impl) +} + +func TestDorglq(t *testing.T) { + testlapack.DorglqTest(t, impl) +} + +func TestDorgql(t *testing.T) { + testlapack.DorgqlTest(t, impl) +} + +func TestDorgqr(t *testing.T) { + testlapack.DorgqrTest(t, impl) +} + +func TestDorgtr(t *testing.T) { + testlapack.DorgtrTest(t, impl) +} + +func TestDormbr(t *testing.T) { + testlapack.DormbrTest(t, impl) +} + +func TestDormhr(t *testing.T) { + testlapack.DormhrTest(t, impl) +} + +func TestDorml2(t *testing.T) { + testlapack.Dorml2Test(t, impl) +} + +func TestDormlq(t *testing.T) { + testlapack.DormlqTest(t, impl) +} + +func TestDormqr(t *testing.T) { + testlapack.DormqrTest(t, impl) +} + +func TestDormr2(t *testing.T) { + testlapack.Dormr2Test(t, impl) +} + +func TestDorm2r(t *testing.T) { + testlapack.Dorm2rTest(t, impl) +} + +func TestDpbtf2(t *testing.T) { + testlapack.Dpbtf2Test(t, impl) +} + +func TestDpocon(t *testing.T) { + testlapack.DpoconTest(t, impl) +} + +func TestDpotf2(t *testing.T) { + testlapack.Dpotf2Test(t, impl) +} + +func TestDpotrf(t *testing.T) { + testlapack.DpotrfTest(t, impl) +} + +func TestDrscl(t *testing.T) { + testlapack.DrsclTest(t, impl) +} + +func TestDsteqr(t *testing.T) { + testlapack.DsteqrTest(t, impl) +} + +func TestDsterf(t *testing.T) { + testlapack.DsterfTest(t, impl) +} + +func TestDsyev(t *testing.T) { + testlapack.DsyevTest(t, impl) +} + +func TestDsytd2(t *testing.T) { + testlapack.Dsytd2Test(t, impl) +} + +func TestDsytrd(t *testing.T) { + testlapack.DsytrdTest(t, impl) +} + +func TestDtgsja(t *testing.T) { + testlapack.DtgsjaTest(t, impl) +} + +func TestDtrcon(t *testing.T) { + testlapack.DtrconTest(t, impl) +} + +func TestDtrevc3(t *testing.T) { + testlapack.Dtrevc3Test(t, impl) +} + +func TestDtrexc(t *testing.T) { + testlapack.DtrexcTest(t, impl) +} + +func TestDtrti2(t *testing.T) { + testlapack.Dtrti2Test(t, impl) +} + +func TestDtrtri(t *testing.T) { + testlapack.DtrtriTest(t, impl) +} + +func TestIladlc(t *testing.T) { + testlapack.IladlcTest(t, impl) +} + +func TestIladlr(t *testing.T) { + testlapack.IladlrTest(t, impl) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlahr2test/main.go b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlahr2test/main.go new file mode 100644 index 00000000..d2c5b604 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlahr2test/main.go @@ -0,0 +1,101 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// dlahr2test generates test data for Dlahr2. Test cases are stored in +// gzip-compressed JSON file testlapack/testdata/dlahr2data.json.gz which is +// read during testing by testlapack/dlahr2.go. +// +// This program uses cgo to call Fortran version of DLAHR2. Therefore, matrices +// passed to the Fortran routine are in column-major format but are written into +// the output file in row-major format. +package main + +import ( + "compress/gzip" + "encoding/json" + "log" + "math/rand" + "os" + "path/filepath" + + "gonum.org/v1/gonum/lapack/internal/testdata/netlib" +) + +type Dlahr2Test struct { + N, K, NB int + A []float64 + + AWant []float64 + TWant []float64 + YWant []float64 + TauWant []float64 +} + +func main() { + file, err := os.Create(filepath.FromSlash("../../../testlapack/testdata/dlahr2data.json.gz")) + if err != nil { + log.Fatal(err) + } + defer file.Close() + w := gzip.NewWriter(file) + + rnd := rand.New(rand.NewSource(1)) + + var tests []Dlahr2Test + for _, n := range []int{4, 5, 6, 7, 11} { + for k := 0; k <= n/2; k++ { + for nb := 1; nb <= k; nb++ { + ain := genrand(n, n-k+1, rnd) + a := make([]float64, len(ain)) + copy(a, ain) + + t := genrand(nb, nb, rnd) + y := genrand(n, nb, rnd) + tau := genrand(nb, 1, rnd) + + netlib.Dlahr2(n, k, nb, a, n, tau, t, nb, y, n) + + tests = append(tests, Dlahr2Test{ + N: n, + K: k, + NB: nb, + A: rowMajor(n, n-k+1, ain), + AWant: rowMajor(n, n-k+1, a), + TWant: rowMajor(nb, nb, t), + YWant: rowMajor(n, nb, y), + TauWant: tau, + }) + } + } + } + json.NewEncoder(w).Encode(tests) + + err = w.Close() + if err != nil { + log.Fatal(err) + } +} + +// genrand returns a general r×c matrix with random entries. +func genrand(r, c int, rnd *rand.Rand) []float64 { + m := make([]float64, r*c) + for i := range m { + m[i] = rnd.NormFloat64() + } + return m +} + +// rowMajor returns the given r×c column-major matrix a in row-major format. +func rowMajor(r, c int, a []float64) []float64 { + if len(a) != r*c { + panic("testdata: slice length mismatch") + } + m := make([]float64, len(a)) + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + m[i*c+j] = a[i+j*r] + } + } + return m +} diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlaqr5test/main.go b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlaqr5test/main.go new file mode 100644 index 00000000..b3980e93 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlaqr5test/main.go @@ -0,0 +1,185 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This program generates test data for Dlaqr5. Test cases are stored in +// gzip-compressed JSON file testlapack/testdata/dlaqr5data.json.gz which is +// read during testing by testlapack/dlaqr5.go. +// +// This program uses cgo to call Fortran version of DLAQR5. Therefore, matrices +// passed to the Fortran routine are in column-major format but are written into +// the output file in row-major format. +package main + +import ( + "compress/gzip" + "encoding/json" + "log" + "math/rand" + "os" + "path/filepath" + + "gonum.org/v1/gonum/lapack/internal/testdata/netlib" +) + +type Dlaqr5Test struct { + WantT bool + N int + NShifts int + KTop, KBot int + ShiftR, ShiftI []float64 + H []float64 + + HWant []float64 + ZWant []float64 +} + +func main() { + file, err := os.Create(filepath.FromSlash("../../../testlapack/testdata/dlaqr5data.json.gz")) + if err != nil { + log.Fatal(err) + } + defer file.Close() + w := gzip.NewWriter(file) + + rnd := rand.New(rand.NewSource(1)) + + var tests []Dlaqr5Test + for _, wantt := range []bool{true, false} { + for _, n := range []int{2, 3, 4, 5, 6, 7, 11} { + for k := 0; k <= min(5, n); k++ { + npairs := k + if npairs == 0 { + npairs = 2 * n + } + for ktop := 0; ktop < n-1; ktop++ { + for kbot := ktop + 1; kbot < n; kbot++ { + sr, si := shiftpairs(npairs, rnd) + nshfts := len(sr) + + v := genrand(nshfts/2, 3, rnd) + u := genrand(3*nshfts-3, 3*nshfts-3, rnd) + wh := genrand(3*nshfts-3, n, rnd) + nh := n + wv := genrand(n, 3*nshfts-3, rnd) + nv := n + + h := hessrand(n, rnd) + if ktop > 0 { + h[ktop+(ktop-1)*n] = 0 + } + if kbot < n-1 { + h[kbot+1+kbot*n] = 0 + } + hin := make([]float64, len(h)) + copy(hin, h) + z := eye(n) + + netlib.Dlaqr5(wantt, true, 2, + n, ktop+1, kbot+1, + nshfts, sr, si, + h, n, + 1, n, z, n, + v, 3, + u, 3*nshfts-3, + nh, wh, nh, + nv, wv, 3*nshfts-3) + + tests = append(tests, Dlaqr5Test{ + WantT: wantt, + N: n, + NShifts: nshfts, + KTop: ktop, + KBot: kbot, + ShiftR: sr, + ShiftI: si, + H: rowMajor(n, n, hin), + HWant: rowMajor(n, n, h), + ZWant: rowMajor(n, n, z), + }) + } + } + } + } + } + json.NewEncoder(w).Encode(tests) + + err = w.Close() + if err != nil { + log.Fatal(err) + } +} + +// genrand returns a general r×c matrix with random entries. +func genrand(r, c int, rnd *rand.Rand) []float64 { + m := make([]float64, r*c) + for i := range m { + m[i] = rnd.NormFloat64() + } + return m +} + +// eye returns an identity matrix of order n. +func eye(n int) []float64 { + m := make([]float64, n*n) + for i := 0; i < n*n; i += n + 1 { + m[i] = 1 + } + return m +} + +// hessrand returns a Hessenberg matrix of order n with random non-zero entries +// in column-major format. +func hessrand(n int, rnd *rand.Rand) []float64 { + h := make([]float64, n*n) + for j := 0; j < n; j++ { + for i := 0; i <= min(j+1, n-1); i++ { + h[i+j*n] = rnd.NormFloat64() + } + } + return h +} + +// shiftpairs generates k real and complex conjugate shift pairs. That is, the +// length of sr and si is 2*k. +func shiftpairs(k int, rnd *rand.Rand) (sr, si []float64) { + sr = make([]float64, 2*k) + si = make([]float64, 2*k) + for i := 0; i < len(sr); { + if rnd.Float64() < 0.5 || i == len(sr)-1 { + sr[i] = rnd.NormFloat64() + i++ + continue + } + // Generate a complex conjugate pair. + r := rnd.NormFloat64() + c := rnd.NormFloat64() + sr[i] = r + si[i] = c + sr[i+1] = r + si[i+1] = -c + i += 2 + } + return sr, si +} + +// rowMajor returns the given r×c column-major matrix a in row-major format. +func rowMajor(r, c int, a []float64) []float64 { + if len(a) != r*c { + panic("testdata: slice length mismatch") + } + m := make([]float64, len(a)) + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + m[i*c+j] = a[i+j*r] + } + } + return m +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/Makefile b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/Makefile new file mode 100644 index 00000000..f9f94446 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/Makefile @@ -0,0 +1,27 @@ +FC = gfortran +FFLAGS = -O2 + +targets = testdlasq1 testdlasq2 testdlasq3 testdlasq4 +objects = dlamch.o lsame.o xerbla.o ieeeck.o iparmq.o ilaenv.o dlasrt.o \ + dlaisnan.o disnan.o dlasq6.o dlasq5.o dlasq4.o dlasq3.o dlasq2.o + +default : $(targets) +.PHONY : default + +testdlasq1 : testdlasq1.o $(objects) dcopy.o dlas2.o dlascl.o dlasq1.o + +testdlasq2 : testdlasq2.o $(objects) + +testdlasq3 : testdlasq3.o $(objects) + +testdlasq4 : testdlasq4.o $(objects) + +% : %.o + $(FC) $(FFLAGS) $^ -o $@ + +%.o : %.f90 + $(FC) $(FFLAGS) -c -o $@ $< + +clean : + rm -f *.o $(targets) *.txt +.PHONY : clean \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/Readme.md b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/Readme.md new file mode 100644 index 00000000..65c47448 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/Readme.md @@ -0,0 +1,23 @@ +This set of codes generates tests for the dlasq* routines. + +The high level routines are testdlasq*.f90. The testdlasq*.f90 routines are intended in combination with the routines in gonum/lapack/testlapack. +During execution, these high-level routines record the inputs and outputs +to the executed subroutines. For example, testdlasq3, when executed, +generates files gen4tests.txt and gen5tests.txt that record the inputs +and outputs to the evaluation of dlasq4 and dlasq5 respectively. The output +format in gen*tests.txt is the struct literal that matches the respective test +in gonum/lapack/testlapack/dlasq*.go. Thus, these generated tests can be copied +into the testing routine to test the native implementation. + +The testing routines in testlapack have code for generating inputs for these +fortran routines. Typically, one would isolate the particular failing test, +and modify the testlapack routine to print it to the terminal, for example +in testlapack/dlasq3.go one might add + + printDlasq3FortranInput(test) + os.Exit(1) + +This prints variable initialization for dlasq3 routine to the terminal, which +can be copied and pasted into testdlasq3.f90. Please note that this process +is not completely automated. Some of the other initialization may need to +change, particularly the size allocation of the data array(s). \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dcopy.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dcopy.f new file mode 100644 index 00000000..d9d5ac7a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dcopy.f @@ -0,0 +1,115 @@ +*> \brief \b DCOPY +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DCOPY(N,DX,INCX,DY,INCY) +* +* .. Scalar Arguments .. +* INTEGER INCX,INCY,N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION DX(*),DY(*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DCOPY copies a vector, x, to a vector, y. +*> uses unrolled loops for increments equal to one. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup double_blas_level1 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> jack dongarra, linpack, 3/11/78. +*> modified 12/3/93, array(1) declarations changed to array(*) +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DCOPY(N,DX,INCX,DY,INCY) +* +* -- Reference BLAS level1 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + INTEGER INCX,INCY,N +* .. +* .. Array Arguments .. + DOUBLE PRECISION DX(*),DY(*) +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I,IX,IY,M,MP1 +* .. +* .. Intrinsic Functions .. + INTRINSIC MOD +* .. + IF (N.LE.0) RETURN + IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN +* +* code for both increments equal to 1 +* +* +* clean-up loop +* + M = MOD(N,7) + IF (M.NE.0) THEN + DO I = 1,M + DY(I) = DX(I) + END DO + IF (N.LT.7) RETURN + END IF + MP1 = M + 1 + DO I = MP1,N,7 + DY(I) = DX(I) + DY(I+1) = DX(I+1) + DY(I+2) = DX(I+2) + DY(I+3) = DX(I+3) + DY(I+4) = DX(I+4) + DY(I+5) = DX(I+5) + DY(I+6) = DX(I+6) + END DO + ELSE +* +* code for unequal increments or equal increments +* not equal to 1 +* + IX = 1 + IY = 1 + IF (INCX.LT.0) IX = (-N+1)*INCX + 1 + IF (INCY.LT.0) IY = (-N+1)*INCY + 1 + DO I = 1,N + DY(IY) = DX(IX) + IX = IX + INCX + IY = IY + INCY + END DO + END IF + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/disnan.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/disnan.f new file mode 100644 index 00000000..355b8279 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/disnan.f @@ -0,0 +1,80 @@ +*> \brief \b DISNAN tests input for NaN. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DISNAN + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* LOGICAL FUNCTION DISNAN( DIN ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION DIN +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DISNAN returns .TRUE. if its argument is NaN, and .FALSE. +*> otherwise. To be replaced by the Fortran 2003 intrinsic in the +*> future. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] DIN +*> \verbatim +*> DIN is DOUBLE PRECISION +*> Input to test for NaN. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + LOGICAL FUNCTION DISNAN( DIN ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION DIN +* .. +* +* ===================================================================== +* +* .. External Functions .. + LOGICAL DLAISNAN + EXTERNAL DLAISNAN +* .. +* .. Executable Statements .. + DISNAN = DLAISNAN(DIN,DIN) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlaisnan.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlaisnan.f new file mode 100644 index 00000000..58595c5c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlaisnan.f @@ -0,0 +1,91 @@ +*> \brief \b DLAISNAN tests input for NaN by comparing two arguments for inequality. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAISNAN + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION DIN1, DIN2 +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> This routine is not for general use. It exists solely to avoid +*> over-optimization in DISNAN. +*> +*> DLAISNAN checks for NaNs by comparing its two arguments for +*> inequality. NaN is the only floating-point value where NaN != NaN +*> returns .TRUE. To check for NaNs, pass the same variable as both +*> arguments. +*> +*> A compiler must assume that the two arguments are +*> not the same variable, and the test will not be optimized away. +*> Interprocedural or whole-program optimization may delete this +*> test. The ISNAN functions will be replaced by the correct +*> Fortran 03 intrinsic once the intrinsic is widely available. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] DIN1 +*> \verbatim +*> DIN1 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] DIN2 +*> \verbatim +*> DIN2 is DOUBLE PRECISION +*> Two numbers to compare for inequality. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION DIN1, DIN2 +* .. +* +* ===================================================================== +* +* .. Executable Statements .. + DLAISNAN = (DIN1.NE.DIN2) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlamch.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlamch.f new file mode 100644 index 00000000..25c2c8e6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlamch.f @@ -0,0 +1,193 @@ +*> \brief \b DLAMCH +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAMCH determines double precision machine parameters. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] CMACH +*> \verbatim +*> Specifies the value to be returned by DLAMCH: +*> = 'E' or 'e', DLAMCH := eps +*> = 'S' or 's , DLAMCH := sfmin +*> = 'B' or 'b', DLAMCH := base +*> = 'P' or 'p', DLAMCH := eps*base +*> = 'N' or 'n', DLAMCH := t +*> = 'R' or 'r', DLAMCH := rnd +*> = 'M' or 'm', DLAMCH := emin +*> = 'U' or 'u', DLAMCH := rmin +*> = 'L' or 'l', DLAMCH := emax +*> = 'O' or 'o', DLAMCH := rmax +*> where +*> eps = relative machine precision +*> sfmin = safe minimum, such that 1/sfmin does not overflow +*> base = base of the machine +*> prec = eps*base +*> t = number of (base) digits in the mantissa +*> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise +*> emin = minimum exponent before (gradual) underflow +*> rmin = underflow threshold - base**(emin-1) +*> emax = largest exponent before overflow +*> rmax = overflow threshold - (base**emax)*(1-eps) +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER CMACH +* .. +* +* .. Scalar Arguments .. + DOUBLE PRECISION A, B +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION RND, EPS, SFMIN, SMALL, RMACH +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT, + $ MINEXPONENT, RADIX, TINY +* .. +* .. Executable Statements .. +* +* +* Assume rounding, not chopping. Always. +* + RND = ONE +* + IF( ONE.EQ.RND ) THEN + EPS = EPSILON(ZERO) * 0.5 + ELSE + EPS = EPSILON(ZERO) + END IF +* + IF( LSAME( CMACH, 'E' ) ) THEN + RMACH = EPS + ELSE IF( LSAME( CMACH, 'S' ) ) THEN + SFMIN = TINY(ZERO) + SMALL = ONE / HUGE(ZERO) + IF( SMALL.GE.SFMIN ) THEN +* +* Use SMALL plus a bit, to avoid the possibility of rounding +* causing overflow when computing 1/sfmin. +* + SFMIN = SMALL*( ONE+EPS ) + END IF + RMACH = SFMIN + ELSE IF( LSAME( CMACH, 'B' ) ) THEN + RMACH = RADIX(ZERO) + ELSE IF( LSAME( CMACH, 'P' ) ) THEN + RMACH = EPS * RADIX(ZERO) + ELSE IF( LSAME( CMACH, 'N' ) ) THEN + RMACH = DIGITS(ZERO) + ELSE IF( LSAME( CMACH, 'R' ) ) THEN + RMACH = RND + ELSE IF( LSAME( CMACH, 'M' ) ) THEN + RMACH = MINEXPONENT(ZERO) + ELSE IF( LSAME( CMACH, 'U' ) ) THEN + RMACH = tiny(zero) + ELSE IF( LSAME( CMACH, 'L' ) ) THEN + RMACH = MAXEXPONENT(ZERO) + ELSE IF( LSAME( CMACH, 'O' ) ) THEN + RMACH = HUGE(ZERO) + ELSE + RMACH = ZERO + END IF +* + DLAMCH = RMACH + RETURN +* +* End of DLAMCH +* + END +************************************************************************ +*> \brief \b DLAMC3 +*> \details +*> \b Purpose: +*> \verbatim +*> DLAMC3 is intended to force A and B to be stored prior to doing +*> the addition of A and B , for use in situations where optimizers +*> might hold one of these in a register. +*> \endverbatim +*> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd.. +*> \date November 2011 +*> \ingroup auxOTHERauxiliary +*> +*> \param[in] A +*> \verbatim +*> A is a DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is a DOUBLE PRECISION +*> The values A and B. +*> \endverbatim +*> + DOUBLE PRECISION FUNCTION DLAMC3( A, B ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. +* November 2010 +* +* .. Scalar Arguments .. + DOUBLE PRECISION A, B +* .. +* ===================================================================== +* +* .. Executable Statements .. +* + DLAMC3 = A + B +* + RETURN +* +* End of DLAMC3 +* + END +* +************************************************************************ diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlas2.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlas2.f new file mode 100644 index 00000000..81077f94 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlas2.f @@ -0,0 +1,183 @@ +*> \brief \b DLAS2 computes singular values of a 2-by-2 triangular matrix. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAS2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLAS2( F, G, H, SSMIN, SSMAX ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION F, G, H, SSMAX, SSMIN +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAS2 computes the singular values of the 2-by-2 matrix +*> [ F G ] +*> [ 0 H ]. +*> On return, SSMIN is the smaller singular value and SSMAX is the +*> larger singular value. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] F +*> \verbatim +*> F is DOUBLE PRECISION +*> The (1,1) element of the 2-by-2 matrix. +*> \endverbatim +*> +*> \param[in] G +*> \verbatim +*> G is DOUBLE PRECISION +*> The (1,2) element of the 2-by-2 matrix. +*> \endverbatim +*> +*> \param[in] H +*> \verbatim +*> H is DOUBLE PRECISION +*> The (2,2) element of the 2-by-2 matrix. +*> \endverbatim +*> +*> \param[out] SSMIN +*> \verbatim +*> SSMIN is DOUBLE PRECISION +*> The smaller singular value. +*> \endverbatim +*> +*> \param[out] SSMAX +*> \verbatim +*> SSMAX is DOUBLE PRECISION +*> The larger singular value. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Barring over/underflow, all output quantities are correct to within +*> a few units in the last place (ulps), even in the absence of a guard +*> digit in addition/subtraction. +*> +*> In IEEE arithmetic, the code works correctly if one matrix element is +*> infinite. +*> +*> Overflow will not occur unless the largest singular value itself +*> overflows, or is within a few ulps of overflow. (On machines with +*> partial overflow, like the Cray, overflow may occur if the largest +*> singular value is within a factor of 2 of overflow.) +*> +*> Underflow is harmless if underflow is gradual. Otherwise, results +*> may correspond to a matrix modified by perturbations of size near +*> the underflow threshold. +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DLAS2( F, G, H, SSMIN, SSMAX ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION F, G, H, SSMAX, SSMIN +* .. +* +* ==================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) + DOUBLE PRECISION TWO + PARAMETER ( TWO = 2.0D0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION AS, AT, AU, C, FA, FHMN, FHMX, GA, HA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* + FA = ABS( F ) + GA = ABS( G ) + HA = ABS( H ) + FHMN = MIN( FA, HA ) + FHMX = MAX( FA, HA ) + IF( FHMN.EQ.ZERO ) THEN + SSMIN = ZERO + IF( FHMX.EQ.ZERO ) THEN + SSMAX = GA + ELSE + SSMAX = MAX( FHMX, GA )*SQRT( ONE+ + $ ( MIN( FHMX, GA ) / MAX( FHMX, GA ) )**2 ) + END IF + ELSE + IF( GA.LT.FHMX ) THEN + AS = ONE + FHMN / FHMX + AT = ( FHMX-FHMN ) / FHMX + AU = ( GA / FHMX )**2 + C = TWO / ( SQRT( AS*AS+AU )+SQRT( AT*AT+AU ) ) + SSMIN = FHMN*C + SSMAX = FHMX / C + ELSE + AU = FHMX / GA + IF( AU.EQ.ZERO ) THEN +* +* Avoid possible harmful underflow if exponent range +* asymmetric (true SSMIN may not underflow even if +* AU underflows) +* + SSMIN = ( FHMN*FHMX ) / GA + SSMAX = GA + ELSE + AS = ONE + FHMN / FHMX + AT = ( FHMX-FHMN ) / FHMX + C = ONE / ( SQRT( ONE+( AS*AU )**2 )+ + $ SQRT( ONE+( AT*AU )**2 ) ) + SSMIN = ( FHMN*C )*AU + SSMIN = SSMIN + SSMIN + SSMAX = GA / ( C+C ) + END IF + END IF + END IF + RETURN +* +* End of DLAS2 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlascl.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlascl.f new file mode 100644 index 00000000..9b9b33c0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlascl.f @@ -0,0 +1,364 @@ +*> \brief \b DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASCL + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER TYPE +* INTEGER INFO, KL, KU, LDA, M, N +* DOUBLE PRECISION CFROM, CTO +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASCL multiplies the M by N real matrix A by the real scalar +*> CTO/CFROM. This is done without over/underflow as long as the final +*> result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that +*> A may be full, upper triangular, lower triangular, upper Hessenberg, +*> or banded. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] TYPE +*> \verbatim +*> TYPE is CHARACTER*1 +*> TYPE indices the storage type of the input matrix. +*> = 'G': A is a full matrix. +*> = 'L': A is a lower triangular matrix. +*> = 'U': A is an upper triangular matrix. +*> = 'H': A is an upper Hessenberg matrix. +*> = 'B': A is a symmetric band matrix with lower bandwidth KL +*> and upper bandwidth KU and with the only the lower +*> half stored. +*> = 'Q': A is a symmetric band matrix with lower bandwidth KL +*> and upper bandwidth KU and with the only the upper +*> half stored. +*> = 'Z': A is a band matrix with lower bandwidth KL and upper +*> bandwidth KU. See DGBTRF for storage details. +*> \endverbatim +*> +*> \param[in] KL +*> \verbatim +*> KL is INTEGER +*> The lower bandwidth of A. Referenced only if TYPE = 'B', +*> 'Q' or 'Z'. +*> \endverbatim +*> +*> \param[in] KU +*> \verbatim +*> KU is INTEGER +*> The upper bandwidth of A. Referenced only if TYPE = 'B', +*> 'Q' or 'Z'. +*> \endverbatim +*> +*> \param[in] CFROM +*> \verbatim +*> CFROM is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] CTO +*> \verbatim +*> CTO is DOUBLE PRECISION +*> +*> The matrix A is multiplied by CTO/CFROM. A(I,J) is computed +*> without over/underflow if the final result CTO*A(I,J)/CFROM +*> can be represented without over/underflow. CFROM must be +*> nonzero. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix A. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> The matrix to be multiplied by CTO/CFROM. See TYPE for the +*> storage type. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,M). +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> 0 - successful exit +*> <0 - if INFO = -i, the i-th argument had an illegal value. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + CHARACTER TYPE + INTEGER INFO, KL, KU, LDA, M, N + DOUBLE PRECISION CFROM, CTO +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL DONE + INTEGER I, ITYPE, J, K1, K2, K3, K4 + DOUBLE PRECISION BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM +* .. +* .. External Functions .. + LOGICAL LSAME, DISNAN + DOUBLE PRECISION DLAMCH + EXTERNAL LSAME, DLAMCH, DISNAN +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 +* + IF( LSAME( TYPE, 'G' ) ) THEN + ITYPE = 0 + ELSE IF( LSAME( TYPE, 'L' ) ) THEN + ITYPE = 1 + ELSE IF( LSAME( TYPE, 'U' ) ) THEN + ITYPE = 2 + ELSE IF( LSAME( TYPE, 'H' ) ) THEN + ITYPE = 3 + ELSE IF( LSAME( TYPE, 'B' ) ) THEN + ITYPE = 4 + ELSE IF( LSAME( TYPE, 'Q' ) ) THEN + ITYPE = 5 + ELSE IF( LSAME( TYPE, 'Z' ) ) THEN + ITYPE = 6 + ELSE + ITYPE = -1 + END IF +* + IF( ITYPE.EQ.-1 ) THEN + INFO = -1 + ELSE IF( CFROM.EQ.ZERO .OR. DISNAN(CFROM) ) THEN + INFO = -4 + ELSE IF( DISNAN(CTO) ) THEN + INFO = -5 + ELSE IF( M.LT.0 ) THEN + INFO = -6 + ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR. + $ ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN + INFO = -7 + ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN + INFO = -9 + ELSE IF( ITYPE.GE.4 ) THEN + IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN + INFO = -2 + ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR. + $ ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) ) + $ THEN + INFO = -3 + ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR. + $ ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR. + $ ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN + INFO = -9 + END IF + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DLASCL', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 .OR. M.EQ.0 ) + $ RETURN +* +* Get machine parameters +* + SMLNUM = DLAMCH( 'S' ) + BIGNUM = ONE / SMLNUM +* + CFROMC = CFROM + CTOC = CTO +* + 10 CONTINUE + CFROM1 = CFROMC*SMLNUM + IF( CFROM1.EQ.CFROMC ) THEN +! CFROMC is an inf. Multiply by a correctly signed zero for +! finite CTOC, or a NaN if CTOC is infinite. + MUL = CTOC / CFROMC + DONE = .TRUE. + CTO1 = CTOC + ELSE + CTO1 = CTOC / BIGNUM + IF( CTO1.EQ.CTOC ) THEN +! CTOC is either 0 or an inf. In both cases, CTOC itself +! serves as the correct multiplication factor. + MUL = CTOC + DONE = .TRUE. + CFROMC = ONE + ELSE IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN + MUL = SMLNUM + DONE = .FALSE. + CFROMC = CFROM1 + ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN + MUL = BIGNUM + DONE = .FALSE. + CTOC = CTO1 + ELSE + MUL = CTOC / CFROMC + DONE = .TRUE. + END IF + END IF +* + IF( ITYPE.EQ.0 ) THEN +* +* Full matrix +* + DO 30 J = 1, N + DO 20 I = 1, M + A( I, J ) = A( I, J )*MUL + 20 CONTINUE + 30 CONTINUE +* + ELSE IF( ITYPE.EQ.1 ) THEN +* +* Lower triangular matrix +* + DO 50 J = 1, N + DO 40 I = J, M + A( I, J ) = A( I, J )*MUL + 40 CONTINUE + 50 CONTINUE +* + ELSE IF( ITYPE.EQ.2 ) THEN +* +* Upper triangular matrix +* + DO 70 J = 1, N + DO 60 I = 1, MIN( J, M ) + A( I, J ) = A( I, J )*MUL + 60 CONTINUE + 70 CONTINUE +* + ELSE IF( ITYPE.EQ.3 ) THEN +* +* Upper Hessenberg matrix +* + DO 90 J = 1, N + DO 80 I = 1, MIN( J+1, M ) + A( I, J ) = A( I, J )*MUL + 80 CONTINUE + 90 CONTINUE +* + ELSE IF( ITYPE.EQ.4 ) THEN +* +* Lower half of a symmetric band matrix +* + K3 = KL + 1 + K4 = N + 1 + DO 110 J = 1, N + DO 100 I = 1, MIN( K3, K4-J ) + A( I, J ) = A( I, J )*MUL + 100 CONTINUE + 110 CONTINUE +* + ELSE IF( ITYPE.EQ.5 ) THEN +* +* Upper half of a symmetric band matrix +* + K1 = KU + 2 + K3 = KU + 1 + DO 130 J = 1, N + DO 120 I = MAX( K1-J, 1 ), K3 + A( I, J ) = A( I, J )*MUL + 120 CONTINUE + 130 CONTINUE +* + ELSE IF( ITYPE.EQ.6 ) THEN +* +* Band matrix +* + K1 = KL + KU + 2 + K2 = KL + 1 + K3 = 2*KL + KU + 1 + K4 = KL + KU + 1 + M + DO 150 J = 1, N + DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J ) + A( I, J ) = A( I, J )*MUL + 140 CONTINUE + 150 CONTINUE +* + END IF +* + IF( .NOT.DONE ) + $ GO TO 10 +* + RETURN +* +* End of DLASCL +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq1.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq1.f new file mode 100644 index 00000000..f0847781 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq1.f @@ -0,0 +1,226 @@ +*> \brief \b DLASQ1 computes the singular values of a real square bidiagonal matrix. Used by sbdsqr. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASQ1 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASQ1( N, D, E, WORK, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION D( * ), E( * ), WORK( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASQ1 computes the singular values of a real N-by-N bidiagonal +*> matrix with diagonal D and off-diagonal E. The singular values +*> are computed to high relative accuracy, in the absence of +*> denormalization, underflow and overflow. The algorithm was first +*> presented in +*> +*> "Accurate singular values and differential qd algorithms" by K. V. +*> Fernando and B. N. Parlett, Numer. Math., Vol-67, No. 2, pp. 191-230, +*> 1994, +*> +*> and the present implementation is described in "An implementation of +*> the dqds Algorithm (Positive Case)", LAPACK Working Note. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of rows and columns in the matrix. N >= 0. +*> \endverbatim +*> +*> \param[in,out] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> On entry, D contains the diagonal elements of the +*> bidiagonal matrix whose SVD is desired. On normal exit, +*> D contains the singular values in decreasing order. +*> \endverbatim +*> +*> \param[in,out] E +*> \verbatim +*> E is DOUBLE PRECISION array, dimension (N) +*> On entry, elements E(1:N-1) contain the off-diagonal elements +*> of the bidiagonal matrix whose SVD is desired. +*> On exit, E is overwritten. +*> \endverbatim +*> +*> \param[out] WORK +*> \verbatim +*> WORK is DOUBLE PRECISION array, dimension (4*N) +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> > 0: the algorithm failed +*> = 1, a split was marked by a positive value in E +*> = 2, current block of Z not diagonalized after 100*N +*> iterations (in inner while loop) On exit D and E +*> represent a matrix with the same singular values +*> which the calling subroutine could use to finish the +*> computation, or even feed back into DLASQ1 +*> = 3, termination criterion of outer while loop not met +*> (program created more than N unreduced blocks) +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +* ===================================================================== + SUBROUTINE DLASQ1( N, D, E, WORK, INFO ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER INFO, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION D( * ), E( * ), WORK( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) +* .. +* .. Local Scalars .. + INTEGER I, IINFO + DOUBLE PRECISION EPS, SCALE, SAFMIN, SIGMN, SIGMX +* .. +* .. External Subroutines .. + EXTERNAL DCOPY, DLAS2, DLASCL, DLASQ2, DLASRT, XERBLA +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, SQRT +* .. +* .. Executable Statements .. +* + INFO = 0 + IF( N.LT.0 ) THEN + INFO = -2 + CALL XERBLA( 'DLASQ1', -INFO ) + RETURN + ELSE IF( N.EQ.0 ) THEN + RETURN + ELSE IF( N.EQ.1 ) THEN + D( 1 ) = ABS( D( 1 ) ) + RETURN + ELSE IF( N.EQ.2 ) THEN + CALL DLAS2( D( 1 ), E( 1 ), D( 2 ), SIGMN, SIGMX ) + D( 1 ) = SIGMX + D( 2 ) = SIGMN + RETURN + END IF +* +* Estimate the largest singular value. +* + SIGMX = ZERO + DO 10 I = 1, N - 1 + D( I ) = ABS( D( I ) ) + SIGMX = MAX( SIGMX, ABS( E( I ) ) ) + 10 CONTINUE + D( N ) = ABS( D( N ) ) +* +* Early return if SIGMX is zero (matrix is already diagonal). +* + IF( SIGMX.EQ.ZERO ) THEN + CALL DLASRT( 'D', N, D, IINFO ) + RETURN + END IF +* + DO 20 I = 1, N + SIGMX = MAX( SIGMX, D( I ) ) + 20 CONTINUE +* +* Copy D and E into WORK (in the Z format) and scale (squaring the +* input data makes scaling by a power of the radix pointless). +* + EPS = DLAMCH( 'Precision' ) + SAFMIN = DLAMCH( 'Safe minimum' ) + SCALE = SQRT( EPS / SAFMIN ) + + CALL DCOPY( N, D, 1, WORK( 1 ), 2 ) + CALL DCOPY( N-1, E, 1, WORK( 2 ), 2 ) + CALL DLASCL( 'G', 0, 0, SIGMX, SCALE, 2*N-1, 1, WORK, 2*N-1, + $ IINFO ) +* +* Compute the q's and e's. +* + DO 30 I = 1, 2*N - 1 + WORK( I ) = WORK( I )**2 + 30 CONTINUE + WORK( 2*N ) = ZERO +* + + CALL DLASQ2( N, WORK, INFO ) +* + IF( INFO.EQ.0 ) THEN + DO 40 I = 1, N + D( I ) = SQRT( WORK( I ) ) + 40 CONTINUE + CALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO ) + ELSE IF( INFO.EQ.2 ) THEN +* +* Maximum number of iterations exceeded. Move data from WORK +* into D and E so the calling subroutine can try to finish +* + DO I = 1, N + D( I ) = SQRT( WORK( 2*I-1 ) ) + E( I ) = SQRT( WORK( 2*I ) ) + END DO + CALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, D, N, IINFO ) + CALL DLASCL( 'G', 0, 0, SCALE, SIGMX, N, 1, E, N, IINFO ) + END IF +* + RETURN +* +* End of DLASQ1 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq2.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq2.f new file mode 100644 index 00000000..602dffc9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq2.f @@ -0,0 +1,652 @@ +*> \brief \b DLASQ2 computes all the eigenvalues of the symmetric positive definite tridiagonal matrix associated with the qd Array Z to high relative accuracy. Used by sbdsqr and sstegr. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASQ2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASQ2( N, Z, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION Z( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASQ2 computes all the eigenvalues of the symmetric positive +*> definite tridiagonal matrix associated with the qd array Z to high +*> relative accuracy are computed to high relative accuracy, in the +*> absence of denormalization, underflow and overflow. +*> +*> To see the relation of Z to the tridiagonal matrix, let L be a +*> unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and +*> let U be an upper bidiagonal matrix with 1's above and diagonal +*> Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the +*> symmetric tridiagonal to which it is similar. +*> +*> Note : DLASQ2 defines a logical variable, IEEE, which is true +*> on machines which follow ieee-754 floating-point standard in their +*> handling of infinities and NaNs, and false otherwise. This variable +*> is passed to DLASQ3. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of rows and columns in the matrix. N >= 0. +*> \endverbatim +*> +*> \param[in,out] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension ( 4*N ) +*> On entry Z holds the qd array. On exit, entries 1 to N hold +*> the eigenvalues in decreasing order, Z( 2*N+1 ) holds the +*> trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If +*> N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 ) +*> holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of +*> shifts that failed. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if the i-th argument is a scalar and had an illegal +*> value, then INFO = -i, if the i-th argument is an +*> array and the j-entry had an illegal value, then +*> INFO = -(i*100+j) +*> > 0: the algorithm failed +*> = 1, a split was marked by a positive value in E +*> = 2, current block of Z not diagonalized after 100*N +*> iterations (in inner while loop). On exit Z holds +*> a qd array with the same eigenvalues as the given Z. +*> = 3, termination criterion of outer while loop not met +*> (program created more than N unreduced blocks) +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Local Variables: I0:N0 defines a current unreduced segment of Z. +*> The shifts are accumulated in SIGMA. Iteration count is in ITER. +*> Ping-pong is controlled by PP (alternates between 0 and 1). +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DLASQ2( N, Z, INFO ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER INFO, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION Z( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION CBIAS + PARAMETER ( CBIAS = 1.50D0 ) + DOUBLE PRECISION ZERO, HALF, ONE, TWO, FOUR, HUNDRD + PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0, + $ TWO = 2.0D0, FOUR = 4.0D0, HUNDRD = 100.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL IEEE + INTEGER I0, I1, I4, IINFO, IPN4, ITER, IWHILA, IWHILB, + $ K, KMIN, N0, N1, NBIG, NDIV, NFAIL, PP, SPLT, + $ TTYPE + DOUBLE PRECISION D, DEE, DEEMIN, DESIG, DMIN, DMIN1, DMIN2, DN, + $ DN1, DN2, E, EMAX, EMIN, EPS, G, OLDEMN, QMAX, + $ QMIN, S, SAFMIN, SIGMA, T, TAU, TEMP, TOL, + $ TOL2, TRACE, ZMAX, TEMPE, TEMPQ +* .. +* .. External Subroutines .. + EXTERNAL DLASQ3, DLASRT, XERBLA +* .. +* .. External Functions .. + INTEGER ILAENV + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH, ILAENV +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, DBLE, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* +* Test the input arguments. +* (in case DLASQ2 is not called by DLASQ1) +* + INFO = 0 + EPS = DLAMCH( 'Precision' ) + SAFMIN = DLAMCH( 'Safe minimum' ) + TOL = EPS*HUNDRD + TOL2 = TOL**2 +* + IF( N.LT.0 ) THEN + INFO = -1 + CALL XERBLA( 'DLASQ2', 1 ) + RETURN + ELSE IF( N.EQ.0 ) THEN + RETURN + ELSE IF( N.EQ.1 ) THEN +* +* 1-by-1 case. +* + IF( Z( 1 ).LT.ZERO ) THEN + INFO = -201 + CALL XERBLA( 'DLASQ2', 2 ) + END IF + RETURN + ELSE IF( N.EQ.2 ) THEN +* +* 2-by-2 case. +* + IF( Z( 2 ).LT.ZERO .OR. Z( 3 ).LT.ZERO ) THEN + INFO = -2 + CALL XERBLA( 'DLASQ2', 2 ) + RETURN + ELSE IF( Z( 3 ).GT.Z( 1 ) ) THEN + D = Z( 3 ) + Z( 3 ) = Z( 1 ) + Z( 1 ) = D + END IF + Z( 5 ) = Z( 1 ) + Z( 2 ) + Z( 3 ) + IF( Z( 2 ).GT.Z( 3 )*TOL2 ) THEN + T = HALF*( ( Z( 1 )-Z( 3 ) )+Z( 2 ) ) + S = Z( 3 )*( Z( 2 ) / T ) + IF( S.LE.T ) THEN + S = Z( 3 )*( Z( 2 ) / ( T*( ONE+SQRT( ONE+S / T ) ) ) ) + ELSE + S = Z( 3 )*( Z( 2 ) / ( T+SQRT( T )*SQRT( T+S ) ) ) + END IF + T = Z( 1 ) + ( S+Z( 2 ) ) + Z( 3 ) = Z( 3 )*( Z( 1 ) / T ) + Z( 1 ) = T + END IF + Z( 2 ) = Z( 3 ) + Z( 6 ) = Z( 2 ) + Z( 1 ) + RETURN + END IF +* +* Check for negative data and compute sums of q's and e's. +* + Z( 2*N ) = ZERO + EMIN = Z( 2 ) + QMAX = ZERO + ZMAX = ZERO + D = ZERO + E = ZERO +* + DO 10 K = 1, 2*( N-1 ), 2 + IF( Z( K ).LT.ZERO ) THEN + INFO = -( 200+K ) + CALL XERBLA( 'DLASQ2', 2 ) + RETURN + ELSE IF( Z( K+1 ).LT.ZERO ) THEN + INFO = -( 200+K+1 ) + CALL XERBLA( 'DLASQ2', 2 ) + RETURN + END IF + D = D + Z( K ) + E = E + Z( K+1 ) + QMAX = MAX( QMAX, Z( K ) ) + EMIN = MIN( EMIN, Z( K+1 ) ) + ZMAX = MAX( QMAX, ZMAX, Z( K+1 ) ) + 10 CONTINUE + IF( Z( 2*N-1 ).LT.ZERO ) THEN + INFO = -( 200+2*N-1 ) + CALL XERBLA( 'DLASQ2', 2 ) + RETURN + END IF + D = D + Z( 2*N-1 ) + QMAX = MAX( QMAX, Z( 2*N-1 ) ) + ZMAX = MAX( QMAX, ZMAX ) +* +* Check for diagonality. +* + IF( E.EQ.ZERO ) THEN + DO 20 K = 2, N + Z( K ) = Z( 2*K-1 ) + 20 CONTINUE + CALL DLASRT( 'D', N, Z, IINFO ) + Z( 2*N-1 ) = D + RETURN + END IF +* + TRACE = D + E +* +* Check for zero data. +* + IF( TRACE.EQ.ZERO ) THEN + Z( 2*N-1 ) = ZERO + RETURN + END IF +* +* Check whether the machine is IEEE conformable. +* + IEEE = ILAENV( 10, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 .AND. + $ ILAENV( 11, 'DLASQ2', 'N', 1, 2, 3, 4 ).EQ.1 +* +* Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...). +* + DO 30 K = 2*N, 2, -2 + Z( 2*K ) = ZERO + Z( 2*K-1 ) = Z( K ) + Z( 2*K-2 ) = ZERO + Z( 2*K-3 ) = Z( K-1 ) + 30 CONTINUE +* + I0 = 1 + N0 = N +* +* Reverse the qd-array, if warranted. +* + IF( CBIAS*Z( 4*I0-3 ).LT.Z( 4*N0-3 ) ) THEN + IPN4 = 4*( I0+N0 ) + DO 40 I4 = 4*I0, 2*( I0+N0-1 ), 4 + + TEMP = Z( I4-3 ) + Z( I4-3 ) = Z( IPN4-I4-3 ) + Z( IPN4-I4-3 ) = TEMP + TEMP = Z( I4-1 ) + Z( I4-1 ) = Z( IPN4-I4-5 ) + Z( IPN4-I4-5 ) = TEMP + 40 CONTINUE + END IF +* +* Initial split checking via dqd and Li's test. +* + PP = 0 +* + DO 80 K = 1, 2 +* + D = Z( 4*N0+PP-3 ) + DO 50 I4 = 4*( N0-1 ) + PP, 4*I0 + PP, -4 + IF( Z( I4-1 ).LE.TOL2*D ) THEN + Z( I4-1 ) = -ZERO + D = Z( I4-3 ) + ELSE + D = Z( I4-3 )*( D / ( D+Z( I4-1 ) ) ) + END IF + 50 CONTINUE +* +* dqd maps Z to ZZ plus Li's test. +* + EMIN = Z( 4*I0+PP+1 ) + D = Z( 4*I0+PP-3 ) + DO 60 I4 = 4*I0 + PP, 4*( N0-1 ) + PP, 4 + Z( I4-2*PP-2 ) = D + Z( I4-1 ) + IF( Z( I4-1 ).LE.TOL2*D ) THEN + Z( I4-1 ) = -ZERO + Z( I4-2*PP-2 ) = D + Z( I4-2*PP ) = ZERO + D = Z( I4+1 ) + ELSE IF( SAFMIN*Z( I4+1 ).LT.Z( I4-2*PP-2 ) .AND. + $ SAFMIN*Z( I4-2*PP-2 ).LT.Z( I4+1 ) ) THEN + TEMP = Z( I4+1 ) / Z( I4-2*PP-2 ) + Z( I4-2*PP ) = Z( I4-1 )*TEMP + D = D*TEMP + ELSE + Z( I4-2*PP ) = Z( I4+1 )*( Z( I4-1 ) / Z( I4-2*PP-2 ) ) + D = Z( I4+1 )*( D / Z( I4-2*PP-2 ) ) + END IF + EMIN = MIN( EMIN, Z( I4-2*PP ) ) + 60 CONTINUE + Z( 4*N0-PP-2 ) = D +* +* Now find qmax. +* + QMAX = Z( 4*I0-PP-2 ) + DO 70 I4 = 4*I0 - PP + 2, 4*N0 - PP - 2, 4 + QMAX = MAX( QMAX, Z( I4 ) ) + 70 CONTINUE +* +* Prepare for the next iteration on K. +* + PP = 1 - PP + 80 CONTINUE + +* +* Initialise variables to pass to DLASQ3. +* + TTYPE = 0 + DMIN1 = ZERO + DMIN2 = ZERO + DN = ZERO + DN1 = ZERO + DN2 = ZERO + G = ZERO + TAU = ZERO +* + ITER = 2 + NFAIL = 0 + NDIV = 2*( N0-I0 ) +* + DO 160 IWHILA = 1, N + 1 + + IF( N0.LT.1 ) THEN + GO TO 170 + END IF +* +* While array unfinished do +* +* E(N0) holds the value of SIGMA when submatrix in I0:N0 +* splits from the rest of the array, but is negated. +* + DESIG = ZERO + IF( N0.EQ.N ) THEN + SIGMA = ZERO + ELSE + SIGMA = -Z( 4*N0-1 ) + END IF + IF( SIGMA.LT.ZERO ) THEN + INFO = 1 + RETURN + END IF +* +* Find last unreduced submatrix's top index I0, find QMAX and +* EMIN. Find Gershgorin-type bound if Q's much greater than E's. +* + EMAX = ZERO + IF( N0.GT.I0 ) THEN + EMIN = ABS( Z( 4*N0-5 ) ) + ELSE + EMIN = ZERO + END IF + QMIN = Z( 4*N0-3 ) + QMAX = QMIN + DO 90 I4 = 4*N0, 8, -4 + IF( Z( I4-5 ).LE.ZERO ) + $ GO TO 100 + IF( QMIN.GE.FOUR*EMAX ) THEN + QMIN = MIN( QMIN, Z( I4-3 ) ) + EMAX = MAX( EMAX, Z( I4-5 ) ) + END IF + QMAX = MAX( QMAX, Z( I4-7 )+Z( I4-5 ) ) + EMIN = MIN( EMIN, Z( I4-5 ) ) + 90 CONTINUE + I4 = 4 +* + 100 CONTINUE + I0 = I4 / 4 + + PP = 0 +* + IF( N0-I0.GT.1 ) THEN + DEE = Z( 4*I0-3 ) + DEEMIN = DEE + KMIN = I0 + DO 110 I4 = 4*I0+1, 4*N0-3, 4 + DEE = Z( I4 )*( DEE /( DEE+Z( I4-2 ) ) ) + IF( DEE.LE.DEEMIN ) THEN + DEEMIN = DEE + KMIN = ( I4+3 )/4 + END IF + 110 CONTINUE + IF( (KMIN-I0)*2.LT.N0-KMIN .AND. + $ DEEMIN.LE.HALF*Z(4*N0-3) ) THEN + IPN4 = 4*( I0+N0 ) + PP = 2 + DO 120 I4 = 4*I0, 2*( I0+N0-1 ), 4 + TEMP = Z( I4-3 ) + Z( I4-3 ) = Z( IPN4-I4-3 ) + Z( IPN4-I4-3 ) = TEMP + TEMP = Z( I4-2 ) + Z( I4-2 ) = Z( IPN4-I4-2 ) + Z( IPN4-I4-2 ) = TEMP + TEMP = Z( I4-1 ) + Z( I4-1 ) = Z( IPN4-I4-5 ) + Z( IPN4-I4-5 ) = TEMP + TEMP = Z( I4 ) + Z( I4 ) = Z( IPN4-I4-4 ) + Z( IPN4-I4-4 ) = TEMP + 120 CONTINUE + END IF + END IF +* +* Put -(initial shift) into DMIN. +* + DMIN = -MAX( ZERO, QMIN-TWO*SQRT( QMIN )*SQRT( EMAX ) ) +* +* Now I0:N0 is unreduced. +* PP = 0 for ping, PP = 1 for pong. +* PP = 2 indicates that flipping was applied to the Z array and +* and that the tests for deflation upon entry in DLASQ3 +* should not be performed. +* + NBIG = 100*( N0-I0+1 ) + DO 140 IWHILB = 1, NBIG + + IF( I0.GT.N0 ) + $ GO TO 150 +* + + ! Print out test cases + + write(3,*) "{" + write(3,*) "i0: ", I0, "," + write(3,*) "n0: ", N0, "," + write(3,'(9999(g0))',advance="no") "z: []float64{" + do i = 1, 4*n + write (3,'(99999(e24.16,a))',advance="no") z(i), "," + end do + write (3,*) "}," + write (3,*) "pp: ", PP, "," + write (3,*) "dmin: ", DMIN, "," + write (3,*) "desig:", DESIG, "," + write (3,*) "qmax: ", QMAX, "," + write (3,*) "ttype:", TTYPE, "," + write (3,*) "dmin1:", DMIN1, "," + write (3,*) "dmin2:", DMIN2, "," + write (3,*) "dn: ", DN, "," + write (3,*) "dn1: ", DN1, "," + write (3,*) "dn2: ", DN2, "," + write (3,*) "g: ", G, "," + write (3,*) "tau: ", TAU, "," + write (3,*) "nFail:", NFAIL, "," + write (3,*) "iter: ", ITER, "," + write (3,*) "sigma:", SIGMA, "," + write (3,*) "nDiv: ", NDIV, "," + +* While submatrix unfinished take a good dqds step. +* + + + CALL DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL, + $ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1, + $ DN2, G, TAU ) + + + ! Write the outputs + write(3,'(9999(g0))',advance="no") "zOut: []float64{" + do i = 1, 4*n + write (3,'(99999(e24.16,a))',advance="no") z(i), "," + end do + write (3,*) "}," + write (3,*) "i0Out:",I0, "," + write (3,*) "n0Out:", N0, "," + write (3,*) "ppOut:", PP, "," + write (3,*) "dminOut:", DMIN, "," + write (3,*) "desigOut:", DESIG, "," + write (3,*) "sigmaOut:", SIGMA, "," + write (3,*) "qmaxOut:", QMAX, "," + write (3,*) "nFailOut:", NFAIL, "," + write (3,*) "iterOut:", ITER, "," + write (3,*) "nDivOut:", NDIV, "," + write (3,*) "ttypeOut:", TTYPE, "," + write (3,*) "dmin1Out:", DMIN1, "," + write (3,*) "dmin2Out:", DMIN2, "," + write (3,*) "dnOut:", DN, "," + write (3,*) "dn1Out:", DN1, "," + write (3,*) "dn2Out:", DN2, "," + write (3,*) "gOut:", G, "," + write (3,*) "tauOut:", TAU, "," + + write (3,*) "}," + + + PP = 1 - PP +* +* When EMIN is very small check for splits. +* + IF( PP.EQ.0 .AND. N0-I0.GE.3 ) THEN + IF( Z( 4*N0 ).LE.TOL2*QMAX .OR. + $ Z( 4*N0-1 ).LE.TOL2*SIGMA ) THEN + SPLT = I0 - 1 + QMAX = Z( 4*I0-3 ) + EMIN = Z( 4*I0-1 ) + OLDEMN = Z( 4*I0 ) + DO 130 I4 = 4*I0, 4*( N0-3 ), 4 + IF( Z( I4 ).LE.TOL2*Z( I4-3 ) .OR. + $ Z( I4-1 ).LE.TOL2*SIGMA ) THEN + Z( I4-1 ) = -SIGMA + SPLT = I4 / 4 + QMAX = ZERO + EMIN = Z( I4+3 ) + OLDEMN = Z( I4+4 ) + ELSE + QMAX = MAX( QMAX, Z( I4+1 ) ) + EMIN = MIN( EMIN, Z( I4-1 ) ) + OLDEMN = MIN( OLDEMN, Z( I4 ) ) + END IF + 130 CONTINUE + Z( 4*N0-1 ) = EMIN + Z( 4*N0 ) = OLDEMN + I0 = SPLT + 1 + END IF + END IF +* + 140 CONTINUE +* + INFO = 2 +* +* Maximum number of iterations exceeded, restore the shift +* SIGMA and place the new d's and e's in a qd array. +* This might need to be done for several blocks +* + I1 = I0 + N1 = N0 + 145 CONTINUE + + TEMPQ = Z( 4*I0-3 ) + Z( 4*I0-3 ) = Z( 4*I0-3 ) + SIGMA + DO K = I0+1, N0 + TEMPE = Z( 4*K-5 ) + Z( 4*K-5 ) = Z( 4*K-5 ) * (TEMPQ / Z( 4*K-7 )) + TEMPQ = Z( 4*K-3 ) + Z( 4*K-3 ) = Z( 4*K-3 ) + SIGMA + TEMPE - Z( 4*K-5 ) + END DO +* +* Prepare to do this on the previous block if there is one +* + IF( I1.GT.1 ) THEN + N1 = I1-1 + DO WHILE( ( I1.GE.2 ) .AND. ( Z(4*I1-5).GE.ZERO ) ) + I1 = I1 - 1 + END DO + SIGMA = -Z(4*N1-1) + GO TO 145 + END IF + + DO K = 1, N + Z( 2*K-1 ) = Z( 4*K-3 ) +* +* Only the block 1..N0 is unfinished. The rest of the e's +* must be essentially zero, although sometimes other data +* has been stored in them. +* + IF( K.LT.N0 ) THEN + Z( 2*K ) = Z( 4*K-1 ) + ELSE + Z( 2*K ) = 0 + END IF + END DO + RETURN +* +* end IWHILB +* + 150 CONTINUE +* + 160 CONTINUE +* + INFO = 3 + RETURN +* +* end IWHILA +* + 170 CONTINUE +* + +* Move q's to the front. +* + DO 180 K = 2, N + Z( K ) = Z( 4*K-3 ) + 180 CONTINUE +* +* Sort and compute sum of eigenvalues. +* + CALL DLASRT( 'D', N, Z, IINFO ) +* + + E = ZERO + DO 190 K = N, 1, -1 + E = E + Z( K ) + 190 CONTINUE +* +* Store trace, sum(eigenvalues) and information on performance. +* + + Z( 2*N+1 ) = TRACE + Z( 2*N+2 ) = E + Z( 2*N+3 ) = DBLE( ITER ) + Z( 2*N+4 ) = DBLE( NDIV ) / DBLE( N**2 ) + Z( 2*N+5 ) = HUNDRD*NFAIL / DBLE( ITER ) + + RETURN +* +* End of DLASQ2 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq3.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq3.f new file mode 100644 index 00000000..1c4e8ecf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq3.f @@ -0,0 +1,498 @@ +*> \brief \b DLASQ3 checks for deflation, computes a shift and calls dqds. Used by sbdsqr. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASQ3 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL, +* ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1, +* DN2, G, TAU ) +* +* .. Scalar Arguments .. +* LOGICAL IEEE +* INTEGER I0, ITER, N0, NDIV, NFAIL, PP +* DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, +* $ QMAX, SIGMA, TAU +* .. +* .. Array Arguments .. +* DOUBLE PRECISION Z( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds. +*> In case of failure it changes shifts, and tries again until output +*> is positive. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] I0 +*> \verbatim +*> I0 is INTEGER +*> First index. +*> \endverbatim +*> +*> \param[in,out] N0 +*> \verbatim +*> N0 is INTEGER +*> Last index. +*> \endverbatim +*> +*> \param[in] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension ( 4*N ) +*> Z holds the qd array. +*> \endverbatim +*> +*> \param[in,out] PP +*> \verbatim +*> PP is INTEGER +*> PP=0 for ping, PP=1 for pong. +*> PP=2 indicates that flipping was applied to the Z array +*> and that the initial tests for deflation should not be +*> performed. +*> \endverbatim +*> +*> \param[out] DMIN +*> \verbatim +*> DMIN is DOUBLE PRECISION +*> Minimum value of d. +*> \endverbatim +*> +*> \param[out] SIGMA +*> \verbatim +*> SIGMA is DOUBLE PRECISION +*> Sum of shifts used in current segment. +*> \endverbatim +*> +*> \param[in,out] DESIG +*> \verbatim +*> DESIG is DOUBLE PRECISION +*> Lower order part of SIGMA +*> \endverbatim +*> +*> \param[in] QMAX +*> \verbatim +*> QMAX is DOUBLE PRECISION +*> Maximum value of q. +*> \endverbatim +*> +*> \param[out] NFAIL +*> \verbatim +*> NFAIL is INTEGER +*> Number of times shift was too big. +*> \endverbatim +*> +*> \param[out] ITER +*> \verbatim +*> ITER is INTEGER +*> Number of iterations. +*> \endverbatim +*> +*> \param[out] NDIV +*> \verbatim +*> NDIV is INTEGER +*> Number of divisions. +*> \endverbatim +*> +*> \param[in] IEEE +*> \verbatim +*> IEEE is LOGICAL +*> Flag for IEEE or non IEEE arithmetic (passed to DLASQ5). +*> \endverbatim +*> +*> \param[in,out] TTYPE +*> \verbatim +*> TTYPE is INTEGER +*> Shift type. +*> \endverbatim +*> +*> \param[in,out] DMIN1 +*> \verbatim +*> DMIN1 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in,out] DMIN2 +*> \verbatim +*> DMIN2 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in,out] DN +*> \verbatim +*> DN is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in,out] DN1 +*> \verbatim +*> DN1 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in,out] DN2 +*> \verbatim +*> DN2 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in,out] G +*> \verbatim +*> G is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in,out] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION +*> +*> These are passed as arguments in order to save their values +*> between calls to DLASQ3. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +* ===================================================================== + SUBROUTINE DLASQ3( I0, N0, Z, PP, DMIN, SIGMA, DESIG, QMAX, NFAIL, + $ ITER, NDIV, IEEE, TTYPE, DMIN1, DMIN2, DN, DN1, + $ DN2, G, TAU ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + LOGICAL IEEE + INTEGER I0, ITER, N0, NDIV, NFAIL, PP + DOUBLE PRECISION DESIG, DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, + $ QMAX, SIGMA, TAU +* .. +* .. Array Arguments .. + DOUBLE PRECISION Z( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION CBIAS + PARAMETER ( CBIAS = 1.50D0 ) + DOUBLE PRECISION ZERO, QURTR, HALF, ONE, TWO, HUNDRD + PARAMETER ( ZERO = 0.0D0, QURTR = 0.250D0, HALF = 0.5D0, + $ ONE = 1.0D0, TWO = 2.0D0, HUNDRD = 100.0D0 ) +* .. +* .. Local Scalars .. + INTEGER IPN4, J4, N0IN, NN, TTYPE + DOUBLE PRECISION EPS, S, T, TEMP, TOL, TOL2 +* .. +* .. External Subroutines .. + EXTERNAL DLASQ4, DLASQ5, DLASQ6 +* .. +* .. External Function .. + DOUBLE PRECISION DLAMCH + LOGICAL DISNAN + EXTERNAL DISNAN, DLAMCH +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* + + N0IN = N0 + EPS = DLAMCH( 'Precision' ) + TOL = EPS*HUNDRD + TOL2 = TOL**2 +* +* Check for deflation. +* + 10 CONTINUE +* + IF( N0.LT.I0 ) + $ RETURN + IF( N0.EQ.I0 ) + $ GO TO 20 + NN = 4*N0 + PP + IF( N0.EQ.( I0+1 ) ) + $ GO TO 40 +* +* Check whether E(N0-1) is negligible, 1 eigenvalue. +* + IF( Z( NN-5 ).GT.TOL2*( SIGMA+Z( NN-3 ) ) .AND. + $ Z( NN-2*PP-4 ).GT.TOL2*Z( NN-7 ) ) + $ GO TO 30 +* + 20 CONTINUE +* + Z( 4*N0-3 ) = Z( 4*N0+PP-3 ) + SIGMA + N0 = N0 - 1 + GO TO 10 +* +* Check whether E(N0-2) is negligible, 2 eigenvalues. +* + 30 CONTINUE +* + IF( Z( NN-9 ).GT.TOL2*SIGMA .AND. + $ Z( NN-2*PP-8 ).GT.TOL2*Z( NN-11 ) ) + $ GO TO 50 +* + 40 CONTINUE +* + IF( Z( NN-3 ).GT.Z( NN-7 ) ) THEN + S = Z( NN-3 ) + Z( NN-3 ) = Z( NN-7 ) + Z( NN-7 ) = S + END IF + T = HALF*( ( Z( NN-7 )-Z( NN-3 ) )+Z( NN-5 ) ) + IF( Z( NN-5 ).GT.Z( NN-3 )*TOL2.AND.T.NE.ZERO ) THEN + S = Z( NN-3 )*( Z( NN-5 ) / T ) + IF( S.LE.T ) THEN + S = Z( NN-3 )*( Z( NN-5 ) / + $ ( T*( ONE+SQRT( ONE+S / T ) ) ) ) + ELSE + S = Z( NN-3 )*( Z( NN-5 ) / ( T+SQRT( T )*SQRT( T+S ) ) ) + END IF + T = Z( NN-7 ) + ( S+Z( NN-5 ) ) + Z( NN-3 ) = Z( NN-3 )*( Z( NN-7 ) / T ) + Z( NN-7 ) = T + END IF + Z( 4*N0-7 ) = Z( NN-7 ) + SIGMA + Z( 4*N0-3 ) = Z( NN-3 ) + SIGMA + N0 = N0 - 2 + GO TO 10 +* + 50 CONTINUE + IF( PP.EQ.2 ) + $ PP = 0 +* +* Reverse the qd-array, if warranted. +* + + IF( DMIN.LE.ZERO .OR. N0.LT.N0IN ) THEN + IF( CBIAS*Z( 4*I0+PP-3 ).LT.Z( 4*N0+PP-3 ) ) THEN + IPN4 = 4*( I0+N0 ) + DO 60 J4 = 4*I0, 2*( I0+N0-1 ), 4 + TEMP = Z( J4-3 ) + Z( J4-3 ) = Z( IPN4-J4-3 ) + Z( IPN4-J4-3 ) = TEMP + TEMP = Z( J4-2 ) + Z( J4-2 ) = Z( IPN4-J4-2 ) + Z( IPN4-J4-2 ) = TEMP + TEMP = Z( J4-1 ) + Z( J4-1 ) = Z( IPN4-J4-5 ) + Z( IPN4-J4-5 ) = TEMP + TEMP = Z( J4 ) + Z( J4 ) = Z( IPN4-J4-4 ) + Z( IPN4-J4-4 ) = TEMP + 60 CONTINUE + IF( N0-I0.LE.4 ) THEN + Z( 4*N0+PP-1 ) = Z( 4*I0+PP-1 ) + Z( 4*N0-PP ) = Z( 4*I0-PP ) + END IF + DMIN2 = MIN( DMIN2, Z( 4*N0+PP-1 ) ) + Z( 4*N0+PP-1 ) = MIN( Z( 4*N0+PP-1 ), Z( 4*I0+PP-1 ), + $ Z( 4*I0+PP+3 ) ) + Z( 4*N0-PP ) = MIN( Z( 4*N0-PP ), Z( 4*I0-PP ), + $ Z( 4*I0-PP+4 ) ) + QMAX = MAX( QMAX, Z( 4*I0+PP-3 ), Z( 4*I0+PP+1 ) ) + DMIN = -ZERO + END IF + END IF +* +* Choose a shift. +* + ! Print out DLASQ4 test cases + write(4,*) "{" + write(4,'(9999(g0))',advance="no") "z: []float64{" + do i = 1, NN + write (4,'(99999(e24.16,a))',advance="no") z(i), "," + end do + write (4,*) "}," + write (4,*) "i0: ", I0, "," + write (4,*) "n0: ", N0, "," + write (4,*) "pp: ", PP, "," + write (4,*) "n0in: ", N0IN, "," + write (4,*) "dmin: ", DMIN, "," + write (4,*) "dmin1:", DMIN1, "," + write (4,*) "dmin2:", DMIN2, "," + write (4,*) "dn: ", DN, "," + write (4,*) "dn1: ", DN1, "," + write (4,*) "dn2: ", DN2, "," + write (4,*) "tau: ", TAU, "," + write (4,*) "ttype: ", TTYPE, "," + write (4,*) "g: ", G, "," + CALL DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, DN1, + $ DN2, TAU, TTYPE, G ) + + write(4,'(9999(g0))',advance="no") "zOut: []float64{" + do i = 1, NN + write (4,'(99999(e24.16,a))',advance="no") z(i), "," + end do + write (4,*) "}," + write (4,*) "tauOut: ", TAU, "," + write (4,*) "ttypeOut: ", TTYPE, "," + write (4,*) "gOut: ", G, "," + write (4,*) "}," + +* +* Call dqds until DMIN > 0. +* + 70 CONTINUE +* + + write(5,*) "{" + write(5,'(9999(g0))',advance="no") "z: []float64{" + do i = 1, NN + write (5,'(99999(e24.16,a))',advance="no") z(i), "," + end do + write (5,*) "}," + write (5,*) "i0: ", I0, "," + write (5,*) "n0: ", N0, "," + write (5,*) "pp: ", PP, "," + write (5,*) "tau: ", TAU, "," + write (5,*) "sigma: ", SIGMA, "," + write (5,*) "dmin: ", DMIN, "," + write (5,*) "dmin1:", DMIN1, "," + write (5,*) "dmin2:", DMIN2, "," + write (5,*) "dn: ", DN, "," + write (5,*) "dnm1: ", DN1, "," + write (5,*) "dnm2: ", DN2, "," + + + CALL DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2, DN, + $ DN1, DN2, IEEE, EPS ) + + + + write (5,*) "i0Out: ", I0, "," + write (5,*) "n0Out: ", N0, "," + write (5,*) "ppOut: ", PP, "," + write (5,*) "tauOut: ", TAU, "," + write (5,*) "sigmaOut: ", SIGMA, "," + write (5,*) "dminOut: ", DMIN, "," + write (5,*) "dmin1Out:", DMIN1, "," + write (5,*) "dmin2Out:", DMIN2, "," + write (5,*) "dnOut: ", DN, "," + write (5,*) "dnm1Out: ", DN1, "," + write (5,*) "dnm2Out: ", DN2, "," + write (5,*) "}," + +* + NDIV = NDIV + ( N0-I0+2 ) + + ITER = ITER + 1 +* +* Check status. +* + + IF( DMIN.GE.ZERO .AND. DMIN1.GE.ZERO ) THEN +* +* Success. +* + GO TO 90 +* + ELSE IF( DMIN.LT.ZERO .AND. DMIN1.GT.ZERO .AND. + $ Z( 4*( N0-1 )-PP ).LT.TOL*( SIGMA+DN1 ) .AND. + $ ABS( DN ).LT.TOL*SIGMA ) THEN + +* +* Convergence hidden by negative DN. +* + Z( 4*( N0-1 )-PP+2 ) = ZERO + DMIN = ZERO + GO TO 90 + ELSE IF( DMIN.LT.ZERO ) THEN + +* +* TAU too big. Select new TAU and try again. +* + NFAIL = NFAIL + 1 + IF( TTYPE.LT.-22 ) THEN +* +* Failed twice. Play it safe. +* + TAU = ZERO + ELSE IF( DMIN1.GT.ZERO ) THEN +* +* Late failure. Gives excellent shift. +* + TAU = ( TAU+DMIN )*( ONE-TWO*EPS ) + TTYPE = TTYPE - 11 + ELSE +* +* Early failure. Divide by 4. +* + TAU = QURTR*TAU + TTYPE = TTYPE - 12 + END IF + GO TO 70 + ELSE IF( DISNAN( DMIN ) ) THEN +* +* NaN. +* + IF( TAU.EQ.ZERO ) THEN + GO TO 80 + ELSE + TAU = ZERO + GO TO 70 + END IF + ELSE +* +* Possible underflow. Play it safe. +* + GO TO 80 + END IF +* +* Risk of underflow. +* + 80 CONTINUE + + CALL DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, DN1, DN2 ) + + + NDIV = NDIV + ( N0-I0+2 ) + ITER = ITER + 1 + TAU = ZERO +* + 90 CONTINUE + + IF( TAU.LT.SIGMA ) THEN + DESIG = DESIG + TAU + T = SIGMA + DESIG + DESIG = DESIG - ( T-SIGMA ) + ELSE + T = SIGMA + TAU + DESIG = SIGMA - ( T-TAU ) + DESIG + END IF + SIGMA = T +* + RETURN +* +* End of DLASQ3 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq4.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq4.f new file mode 100644 index 00000000..f60f775b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq4.f @@ -0,0 +1,427 @@ +*> \brief \b DLASQ4 computes an approximation to the smallest eigenvalue using values of d from the previous transform. Used by sbdsqr. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASQ4 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, +* DN1, DN2, TAU, TTYPE, G ) +* +* .. Scalar Arguments .. +* INTEGER I0, N0, N0IN, PP, TTYPE +* DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU +* .. +* .. Array Arguments .. +* DOUBLE PRECISION Z( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASQ4 computes an approximation TAU to the smallest eigenvalue +*> using values of d from the previous transform. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] I0 +*> \verbatim +*> I0 is INTEGER +*> First index. +*> \endverbatim +*> +*> \param[in] N0 +*> \verbatim +*> N0 is INTEGER +*> Last index. +*> \endverbatim +*> +*> \param[in] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension ( 4*N ) +*> Z holds the qd array. +*> \endverbatim +*> +*> \param[in] PP +*> \verbatim +*> PP is INTEGER +*> PP=0 for ping, PP=1 for pong. +*> \endverbatim +*> +*> \param[in] N0IN +*> \verbatim +*> N0IN is INTEGER +*> The value of N0 at start of EIGTEST. +*> \endverbatim +*> +*> \param[in] DMIN +*> \verbatim +*> DMIN is DOUBLE PRECISION +*> Minimum value of d. +*> \endverbatim +*> +*> \param[in] DMIN1 +*> \verbatim +*> DMIN1 is DOUBLE PRECISION +*> Minimum value of d, excluding D( N0 ). +*> \endverbatim +*> +*> \param[in] DMIN2 +*> \verbatim +*> DMIN2 is DOUBLE PRECISION +*> Minimum value of d, excluding D( N0 ) and D( N0-1 ). +*> \endverbatim +*> +*> \param[in] DN +*> \verbatim +*> DN is DOUBLE PRECISION +*> d(N) +*> \endverbatim +*> +*> \param[in] DN1 +*> \verbatim +*> DN1 is DOUBLE PRECISION +*> d(N-1) +*> \endverbatim +*> +*> \param[in] DN2 +*> \verbatim +*> DN2 is DOUBLE PRECISION +*> d(N-2) +*> \endverbatim +*> +*> \param[out] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION +*> This is the shift. +*> \endverbatim +*> +*> \param[out] TTYPE +*> \verbatim +*> TTYPE is INTEGER +*> Shift type. +*> \endverbatim +*> +*> \param[in,out] G +*> \verbatim +*> G is REAL +*> G is passed as an argument in order to save its value between +*> calls to DLASQ4. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> CNST1 = 9/16 +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DLASQ4( I0, N0, Z, PP, N0IN, DMIN, DMIN1, DMIN2, DN, + $ DN1, DN2, TAU, TTYPE, G ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER I0, N0, N0IN, PP, TTYPE + DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DN1, DN2, G, TAU +* .. +* .. Array Arguments .. + DOUBLE PRECISION Z( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION CNST1, CNST2, CNST3 + PARAMETER ( CNST1 = 0.5630D0, CNST2 = 1.010D0, + $ CNST3 = 1.050D0 ) + DOUBLE PRECISION QURTR, THIRD, HALF, ZERO, ONE, TWO, HUNDRD + PARAMETER ( QURTR = 0.250D0, THIRD = 0.3330D0, + $ HALF = 0.50D0, ZERO = 0.0D0, ONE = 1.0D0, + $ TWO = 2.0D0, HUNDRD = 100.0D0 ) +* .. +* .. Local Scalars .. + INTEGER I4, NN, NP + DOUBLE PRECISION A2, B1, B2, GAM, GAP1, GAP2, S +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* +* A negative DMIN forces the shift to take that absolute value +* TTYPE records the type of shift. +* + + IF( DMIN.LE.ZERO ) THEN + TAU = -DMIN + TTYPE = -1 + RETURN + END IF +* + NN = 4*N0 + PP + IF( N0IN.EQ.N0 ) THEN +* +* No eigenvalues deflated. +* + IF( DMIN.EQ.DN .OR. DMIN.EQ.DN1 ) THEN +* + B1 = SQRT( Z( NN-3 ) )*SQRT( Z( NN-5 ) ) + B2 = SQRT( Z( NN-7 ) )*SQRT( Z( NN-9 ) ) + A2 = Z( NN-7 ) + Z( NN-5 ) +* +* Cases 2 and 3. +* + IF( DMIN.EQ.DN .AND. DMIN1.EQ.DN1 ) THEN + + GAP2 = DMIN2 - A2 - DMIN2*QURTR + IF( GAP2.GT.ZERO .AND. GAP2.GT.B2 ) THEN + GAP1 = A2 - DN - ( B2 / GAP2 )*B2 + ELSE + GAP1 = A2 - DN - ( B1+B2 ) + END IF + IF( GAP1.GT.ZERO .AND. GAP1.GT.B1 ) THEN + S = MAX( DN-( B1 / GAP1 )*B1, HALF*DMIN ) + TTYPE = -2 + ELSE + S = ZERO + IF( DN.GT.B1 ) + $ S = DN - B1 + IF( A2.GT.( B1+B2 ) ) + $ S = MIN( S, A2-( B1+B2 ) ) + S = MAX( S, THIRD*DMIN ) + TTYPE = -3 + END IF + ELSE +* +* Case 4. +* + TTYPE = -4 + S = QURTR*DMIN + IF( DMIN.EQ.DN ) THEN + GAM = DN + A2 = ZERO + IF( Z( NN-5 ) .GT. Z( NN-7 ) ) + $ RETURN + B2 = Z( NN-5 ) / Z( NN-7 ) + NP = NN - 9 + ELSE + NP = NN - 2*PP + B2 = Z( NP-2 ) + GAM = DN1 + IF( Z( NP-4 ) .GT. Z( NP-2 ) ) + $ RETURN + A2 = Z( NP-4 ) / Z( NP-2 ) + IF( Z( NN-9 ) .GT. Z( NN-11 ) ) + $ RETURN + B2 = Z( NN-9 ) / Z( NN-11 ) + NP = NN - 13 + END IF +* +* Approximate contribution to norm squared from I < NN-1. +* + A2 = A2 + B2 + DO 10 I4 = NP, 4*I0 - 1 + PP, -4 + IF( B2.EQ.ZERO ) + $ GO TO 20 + B1 = B2 + IF( Z( I4 ) .GT. Z( I4-2 ) ) + $ RETURN + B2 = B2*( Z( I4 ) / Z( I4-2 ) ) + A2 = A2 + B2 + IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) + $ GO TO 20 + 10 CONTINUE + 20 CONTINUE + A2 = CNST3*A2 +* +* Rayleigh quotient residual bound. +* + IF( A2.LT.CNST1 ) + $ S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 ) + END IF + ELSE IF( DMIN.EQ.DN2 ) THEN +* +* Case 5. +* + TTYPE = -5 + S = QURTR*DMIN +* +* Compute contribution to norm squared from I > NN-2. +* + NP = NN - 2*PP + B1 = Z( NP-2 ) + B2 = Z( NP-6 ) + GAM = DN2 + IF( Z( NP-8 ).GT.B2 .OR. Z( NP-4 ).GT.B1 ) + $ RETURN + A2 = ( Z( NP-8 ) / B2 )*( ONE+Z( NP-4 ) / B1 ) +* +* Approximate contribution to norm squared from I < NN-2. +* + IF( N0-I0.GT.2 ) THEN + B2 = Z( NN-13 ) / Z( NN-15 ) + A2 = A2 + B2 + DO 30 I4 = NN - 17, 4*I0 - 1 + PP, -4 + IF( B2.EQ.ZERO ) + $ GO TO 40 + B1 = B2 + IF( Z( I4 ) .GT. Z( I4-2 ) ) + $ RETURN + B2 = B2*( Z( I4 ) / Z( I4-2 ) ) + A2 = A2 + B2 + IF( HUNDRD*MAX( B2, B1 ).LT.A2 .OR. CNST1.LT.A2 ) + $ GO TO 40 + 30 CONTINUE + 40 CONTINUE + A2 = CNST3*A2 + END IF +* + IF( A2.LT.CNST1 ) + $ S = GAM*( ONE-SQRT( A2 ) ) / ( ONE+A2 ) + ELSE +* +* Case 6, no information to guide us. +* + IF( TTYPE.EQ.-6 ) THEN + G = G + THIRD*( ONE-G ) + ELSE IF( TTYPE.EQ.-18 ) THEN + G = QURTR*THIRD + ELSE + G = QURTR + END IF + S = G*DMIN + TTYPE = -6 + END IF +* + ELSE IF( N0IN.EQ.( N0+1 ) ) THEN +* +* One eigenvalue just deflated. Use DMIN1, DN1 for DMIN and DN. +* + IF( DMIN1.EQ.DN1 .AND. DMIN2.EQ.DN2 ) THEN +* +* Cases 7 and 8. +* + TTYPE = -7 + S = THIRD*DMIN1 + IF( Z( NN-5 ).GT.Z( NN-7 ) ) + $ RETURN + B1 = Z( NN-5 ) / Z( NN-7 ) + B2 = B1 + IF( B2.EQ.ZERO ) + $ GO TO 60 + DO 50 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4 + A2 = B1 + IF( Z( I4 ).GT.Z( I4-2 ) ) + $ RETURN + B1 = B1*( Z( I4 ) / Z( I4-2 ) ) + B2 = B2 + B1 + IF( HUNDRD*MAX( B1, A2 ).LT.B2 ) + $ GO TO 60 + 50 CONTINUE + 60 CONTINUE + B2 = SQRT( CNST3*B2 ) + A2 = DMIN1 / ( ONE+B2**2 ) + GAP2 = HALF*DMIN2 - A2 + IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN + S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) ) + ELSE + S = MAX( S, A2*( ONE-CNST2*B2 ) ) + TTYPE = -8 + END IF + ELSE +* +* Case 9. +* + S = QURTR*DMIN1 + IF( DMIN1.EQ.DN1 ) + $ S = HALF*DMIN1 + TTYPE = -9 + END IF +* + ELSE IF( N0IN.EQ.( N0+2 ) ) THEN +* +* Two eigenvalues deflated. Use DMIN2, DN2 for DMIN and DN. +* +* Cases 10 and 11. +* + IF( DMIN2.EQ.DN2 .AND. TWO*Z( NN-5 ).LT.Z( NN-7 ) ) THEN + TTYPE = -10 + S = THIRD*DMIN2 + IF( Z( NN-5 ).GT.Z( NN-7 ) ) + $ RETURN + B1 = Z( NN-5 ) / Z( NN-7 ) + B2 = B1 + IF( B2.EQ.ZERO ) + $ GO TO 80 + DO 70 I4 = 4*N0 - 9 + PP, 4*I0 - 1 + PP, -4 + IF( Z( I4 ).GT.Z( I4-2 ) ) + $ RETURN + B1 = B1*( Z( I4 ) / Z( I4-2 ) ) + B2 = B2 + B1 + IF( HUNDRD*B1.LT.B2 ) + $ GO TO 80 + 70 CONTINUE + 80 CONTINUE + B2 = SQRT( CNST3*B2 ) + A2 = DMIN2 / ( ONE+B2**2 ) + GAP2 = Z( NN-7 ) + Z( NN-9 ) - + $ SQRT( Z( NN-11 ) )*SQRT( Z( NN-9 ) ) - A2 + IF( GAP2.GT.ZERO .AND. GAP2.GT.B2*A2 ) THEN + S = MAX( S, A2*( ONE-CNST2*A2*( B2 / GAP2 )*B2 ) ) + ELSE + S = MAX( S, A2*( ONE-CNST2*B2 ) ) + END IF + ELSE + S = QURTR*DMIN2 + TTYPE = -11 + END IF + ELSE IF( N0IN.GT.( N0+2 ) ) THEN +* +* Case 12, more than two eigenvalues deflated. No information. +* + S = ZERO + TTYPE = -12 + END IF +* + TAU = S + RETURN +* +* End of DLASQ4 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq5.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq5.f new file mode 100644 index 00000000..19470447 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq5.f @@ -0,0 +1,413 @@ +*> \brief \b DLASQ5 computes one dqds transform in ping-pong form. Used by sbdsqr and sstegr. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASQ5 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2, DN, +* DNM1, DNM2, IEEE, EPS ) +* +* .. Scalar Arguments .. +* LOGICAL IEEE +* INTEGER I0, N0, PP +* DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2, TAU, SIGMA, EPS +* .. +* .. Array Arguments .. +* DOUBLE PRECISION Z( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASQ5 computes one dqds transform in ping-pong form, one +*> version for IEEE machines another for non IEEE machines. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] I0 +*> \verbatim +*> I0 is INTEGER +*> First index. +*> \endverbatim +*> +*> \param[in] N0 +*> \verbatim +*> N0 is INTEGER +*> Last index. +*> \endverbatim +*> +*> \param[in] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension ( 4*N ) +*> Z holds the qd array. EMIN is stored in Z(4*N0) to avoid +*> an extra argument. +*> \endverbatim +*> +*> \param[in] PP +*> \verbatim +*> PP is INTEGER +*> PP=0 for ping, PP=1 for pong. +*> \endverbatim +*> +*> \param[in] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION +*> This is the shift. +*> \endverbatim +*> +*> \param[in] SIGMA +*> \verbatim +*> SIGMA is DOUBLE PRECISION +*> This is the accumulated shift up to this step. +*> \endverbatim +*> +*> \param[out] DMIN +*> \verbatim +*> DMIN is DOUBLE PRECISION +*> Minimum value of d. +*> \endverbatim +*> +*> \param[out] DMIN1 +*> \verbatim +*> DMIN1 is DOUBLE PRECISION +*> Minimum value of d, excluding D( N0 ). +*> \endverbatim +*> +*> \param[out] DMIN2 +*> \verbatim +*> DMIN2 is DOUBLE PRECISION +*> Minimum value of d, excluding D( N0 ) and D( N0-1 ). +*> \endverbatim +*> +*> \param[out] DN +*> \verbatim +*> DN is DOUBLE PRECISION +*> d(N0), the last value of d. +*> \endverbatim +*> +*> \param[out] DNM1 +*> \verbatim +*> DNM1 is DOUBLE PRECISION +*> d(N0-1). +*> \endverbatim +*> +*> \param[out] DNM2 +*> \verbatim +*> DNM2 is DOUBLE PRECISION +*> d(N0-2). +*> \endverbatim +*> +*> \param[in] IEEE +*> \verbatim +*> IEEE is LOGICAL +*> Flag for IEEE or non IEEE arithmetic. +*> \endverbatim +* +*> \param[in] EPS +*> \verbatim +*> EPS is DOUBLE PRECISION +*> This is the value of epsilon used. +*> \endverbatim +*> +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +* ===================================================================== + SUBROUTINE DLASQ5( I0, N0, Z, PP, TAU, SIGMA, DMIN, DMIN1, DMIN2, + $ DN, DNM1, DNM2, IEEE, EPS ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + LOGICAL IEEE + INTEGER I0, N0, PP + DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2, TAU, + $ SIGMA, EPS +* .. +* .. Array Arguments .. + DOUBLE PRECISION Z( * ) +* .. +* +* ===================================================================== +* +* .. Parameter .. + DOUBLE PRECISION ZERO, HALF + PARAMETER ( ZERO = 0.0D0, HALF = 0.5 ) +* .. +* .. Local Scalars .. + INTEGER J4, J4P2 + DOUBLE PRECISION D, EMIN, TEMP, DTHRESH +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* + + IF( ( N0-I0-1 ).LE.0 ) + $ RETURN +* + DTHRESH = EPS*(SIGMA+TAU) + IF( TAU.LT.DTHRESH*HALF ) TAU = ZERO + IF( TAU.NE.ZERO ) THEN + J4 = 4*I0 + PP - 3 + EMIN = Z( J4+4 ) + D = Z( J4 ) - TAU + DMIN = D + DMIN1 = -Z( J4 ) +* + IF( IEEE ) THEN +* +* Code for IEEE arithmetic. +* + IF( PP.EQ.0 ) THEN + DO 10 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-2 ) = D + Z( J4-1 ) + TEMP = Z( J4+1 ) / Z( J4-2 ) + D = D*TEMP - TAU + DMIN = MIN( DMIN, D ) + Z( J4 ) = Z( J4-1 )*TEMP + EMIN = MIN( Z( J4 ), EMIN ) + 10 CONTINUE + ELSE + DO 20 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-3 ) = D + Z( J4 ) + TEMP = Z( J4+2 ) / Z( J4-3 ) + D = D*TEMP - TAU + DMIN = MIN( DMIN, D ) + Z( J4-1 ) = Z( J4 )*TEMP + EMIN = MIN( Z( J4-1 ), EMIN ) + 20 CONTINUE + END IF + +* +* Unroll last two steps. +* + DNM2 = D + DMIN2 = DMIN + J4 = 4*( N0-2 ) - PP + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM2 + Z( J4P2 ) + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU + DMIN = MIN( DMIN, DNM1 ) +* + DMIN1 = DMIN + J4 = J4 + 4 + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM1 + Z( J4P2 ) + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU + DMIN = MIN( DMIN, DN ) +* + ELSE +* +* Code for non IEEE arithmetic. +* + IF( PP.EQ.0 ) THEN + DO 30 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-2 ) = D + Z( J4-1 ) + IF( D.LT.ZERO ) THEN + RETURN + ELSE + Z( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) ) + D = Z( J4+1 )*( D / Z( J4-2 ) ) - TAU + END IF + DMIN = MIN( DMIN, D ) + EMIN = MIN( EMIN, Z( J4 ) ) + 30 CONTINUE + ELSE + DO 40 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-3 ) = D + Z( J4 ) + IF( D.LT.ZERO ) THEN + RETURN + ELSE + Z( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) ) + D = Z( J4+2 )*( D / Z( J4-3 ) ) - TAU + END IF + DMIN = MIN( DMIN, D ) + EMIN = MIN( EMIN, Z( J4-1 ) ) + 40 CONTINUE + END IF +* +* Unroll last two steps. +* + DNM2 = D + DMIN2 = DMIN + J4 = 4*( N0-2 ) - PP + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM2 + Z( J4P2 ) + IF( DNM2.LT.ZERO ) THEN + RETURN + ELSE + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU + END IF + DMIN = MIN( DMIN, DNM1 ) +* + DMIN1 = DMIN + J4 = J4 + 4 + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM1 + Z( J4P2 ) + IF( DNM1.LT.ZERO ) THEN + RETURN + ELSE + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU + END IF + DMIN = MIN( DMIN, DN ) +* + END IF + ELSE +* This is the version that sets d's to zero if they are small enough + J4 = 4*I0 + PP - 3 + EMIN = Z( J4+4 ) + D = Z( J4 ) - TAU + DMIN = D + DMIN1 = -Z( J4 ) + IF( IEEE ) THEN +* +* Code for IEEE arithmetic. +* + + IF( PP.EQ.0 ) THEN + DO 50 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-2 ) = D + Z( J4-1 ) + TEMP = Z( J4+1 ) / Z( J4-2 ) + D = D*TEMP - TAU + IF( D.LT.DTHRESH ) D = ZERO + DMIN = MIN( DMIN, D ) + Z( J4 ) = Z( J4-1 )*TEMP + EMIN = MIN( Z( J4 ), EMIN ) + 50 CONTINUE + ELSE + DO 60 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-3 ) = D + Z( J4 ) + TEMP = Z( J4+2 ) / Z( J4-3 ) + D = D*TEMP - TAU + IF( D.LT.DTHRESH ) D = ZERO + DMIN = MIN( DMIN, D ) + Z( J4-1 ) = Z( J4 )*TEMP + EMIN = MIN( Z( J4-1 ), EMIN ) + 60 CONTINUE + END IF +* +* Unroll last two steps. +* + DNM2 = D + DMIN2 = DMIN + J4 = 4*( N0-2 ) - PP + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM2 + Z( J4P2 ) + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU + DMIN = MIN( DMIN, DNM1 ) +* + DMIN1 = DMIN + J4 = J4 + 4 + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM1 + Z( J4P2 ) + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU + DMIN = MIN( DMIN, DN ) +* + ELSE +* +* Code for non IEEE arithmetic. +* + IF( PP.EQ.0 ) THEN + DO 70 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-2 ) = D + Z( J4-1 ) + IF( D.LT.ZERO ) THEN + RETURN + ELSE + Z( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) ) + D = Z( J4+1 )*( D / Z( J4-2 ) ) - TAU + END IF + IF( D.LT.DTHRESH) D = ZERO + DMIN = MIN( DMIN, D ) + EMIN = MIN( EMIN, Z( J4 ) ) + 70 CONTINUE + ELSE + DO 80 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-3 ) = D + Z( J4 ) + IF( D.LT.ZERO ) THEN + RETURN + ELSE + Z( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) ) + D = Z( J4+2 )*( D / Z( J4-3 ) ) - TAU + END IF + IF( D.LT.DTHRESH) D = ZERO + DMIN = MIN( DMIN, D ) + EMIN = MIN( EMIN, Z( J4-1 ) ) + 80 CONTINUE + END IF +* +* Unroll last two steps. +* + DNM2 = D + DMIN2 = DMIN + J4 = 4*( N0-2 ) - PP + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM2 + Z( J4P2 ) + IF( DNM2.LT.ZERO ) THEN + RETURN + ELSE + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) - TAU + END IF + DMIN = MIN( DMIN, DNM1 ) +* + DMIN1 = DMIN + J4 = J4 + 4 + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM1 + Z( J4P2 ) + IF( DNM1.LT.ZERO ) THEN + RETURN + ELSE + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) - TAU + END IF + DMIN = MIN( DMIN, DN ) +* + END IF + END IF +* + Z( J4+2 ) = DN + Z( 4*N0-PP ) = EMIN + RETURN +* +* End of DLASQ5 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq6.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq6.f new file mode 100644 index 00000000..bcd61f35 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasq6.f @@ -0,0 +1,258 @@ +*> \brief \b DLASQ6 computes one dqd transform in ping-pong form. Used by sbdsqr and sstegr. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASQ6 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, +* DNM1, DNM2 ) +* +* .. Scalar Arguments .. +* INTEGER I0, N0, PP +* DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2 +* .. +* .. Array Arguments .. +* DOUBLE PRECISION Z( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASQ6 computes one dqd (shift equal to zero) transform in +*> ping-pong form, with protection against underflow and overflow. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] I0 +*> \verbatim +*> I0 is INTEGER +*> First index. +*> \endverbatim +*> +*> \param[in] N0 +*> \verbatim +*> N0 is INTEGER +*> Last index. +*> \endverbatim +*> +*> \param[in] Z +*> \verbatim +*> Z is DOUBLE PRECISION array, dimension ( 4*N ) +*> Z holds the qd array. EMIN is stored in Z(4*N0) to avoid +*> an extra argument. +*> \endverbatim +*> +*> \param[in] PP +*> \verbatim +*> PP is INTEGER +*> PP=0 for ping, PP=1 for pong. +*> \endverbatim +*> +*> \param[out] DMIN +*> \verbatim +*> DMIN is DOUBLE PRECISION +*> Minimum value of d. +*> \endverbatim +*> +*> \param[out] DMIN1 +*> \verbatim +*> DMIN1 is DOUBLE PRECISION +*> Minimum value of d, excluding D( N0 ). +*> \endverbatim +*> +*> \param[out] DMIN2 +*> \verbatim +*> DMIN2 is DOUBLE PRECISION +*> Minimum value of d, excluding D( N0 ) and D( N0-1 ). +*> \endverbatim +*> +*> \param[out] DN +*> \verbatim +*> DN is DOUBLE PRECISION +*> d(N0), the last value of d. +*> \endverbatim +*> +*> \param[out] DNM1 +*> \verbatim +*> DNM1 is DOUBLE PRECISION +*> d(N0-1). +*> \endverbatim +*> +*> \param[out] DNM2 +*> \verbatim +*> DNM2 is DOUBLE PRECISION +*> d(N0-2). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +* ===================================================================== + SUBROUTINE DLASQ6( I0, N0, Z, PP, DMIN, DMIN1, DMIN2, DN, + $ DNM1, DNM2 ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER I0, N0, PP + DOUBLE PRECISION DMIN, DMIN1, DMIN2, DN, DNM1, DNM2 +* .. +* .. Array Arguments .. + DOUBLE PRECISION Z( * ) +* .. +* +* ===================================================================== +* +* .. Parameter .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) +* .. +* .. Local Scalars .. + INTEGER J4, J4P2 + DOUBLE PRECISION D, EMIN, SAFMIN, TEMP +* .. +* .. External Function .. + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* + IF( ( N0-I0-1 ).LE.0 ) + $ RETURN +* + + print *, "In dlasq6" + STOP + + SAFMIN = DLAMCH( 'Safe minimum' ) + J4 = 4*I0 + PP - 3 + EMIN = Z( J4+4 ) + D = Z( J4 ) + DMIN = D +* + IF( PP.EQ.0 ) THEN + DO 10 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-2 ) = D + Z( J4-1 ) + IF( Z( J4-2 ).EQ.ZERO ) THEN + Z( J4 ) = ZERO + D = Z( J4+1 ) + DMIN = D + EMIN = ZERO + ELSE IF( SAFMIN*Z( J4+1 ).LT.Z( J4-2 ) .AND. + $ SAFMIN*Z( J4-2 ).LT.Z( J4+1 ) ) THEN + TEMP = Z( J4+1 ) / Z( J4-2 ) + Z( J4 ) = Z( J4-1 )*TEMP + D = D*TEMP + ELSE + Z( J4 ) = Z( J4+1 )*( Z( J4-1 ) / Z( J4-2 ) ) + D = Z( J4+1 )*( D / Z( J4-2 ) ) + END IF + DMIN = MIN( DMIN, D ) + EMIN = MIN( EMIN, Z( J4 ) ) + 10 CONTINUE + ELSE + DO 20 J4 = 4*I0, 4*( N0-3 ), 4 + Z( J4-3 ) = D + Z( J4 ) + IF( Z( J4-3 ).EQ.ZERO ) THEN + Z( J4-1 ) = ZERO + D = Z( J4+2 ) + DMIN = D + EMIN = ZERO + ELSE IF( SAFMIN*Z( J4+2 ).LT.Z( J4-3 ) .AND. + $ SAFMIN*Z( J4-3 ).LT.Z( J4+2 ) ) THEN + TEMP = Z( J4+2 ) / Z( J4-3 ) + Z( J4-1 ) = Z( J4 )*TEMP + D = D*TEMP + ELSE + Z( J4-1 ) = Z( J4+2 )*( Z( J4 ) / Z( J4-3 ) ) + D = Z( J4+2 )*( D / Z( J4-3 ) ) + END IF + DMIN = MIN( DMIN, D ) + EMIN = MIN( EMIN, Z( J4-1 ) ) + 20 CONTINUE + END IF +* +* Unroll last two steps. +* + DNM2 = D + DMIN2 = DMIN + J4 = 4*( N0-2 ) - PP + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM2 + Z( J4P2 ) + IF( Z( J4-2 ).EQ.ZERO ) THEN + Z( J4 ) = ZERO + DNM1 = Z( J4P2+2 ) + DMIN = DNM1 + EMIN = ZERO + ELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND. + $ SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THEN + TEMP = Z( J4P2+2 ) / Z( J4-2 ) + Z( J4 ) = Z( J4P2 )*TEMP + DNM1 = DNM2*TEMP + ELSE + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DNM1 = Z( J4P2+2 )*( DNM2 / Z( J4-2 ) ) + END IF + DMIN = MIN( DMIN, DNM1 ) +* + DMIN1 = DMIN + J4 = J4 + 4 + J4P2 = J4 + 2*PP - 1 + Z( J4-2 ) = DNM1 + Z( J4P2 ) + IF( Z( J4-2 ).EQ.ZERO ) THEN + Z( J4 ) = ZERO + DN = Z( J4P2+2 ) + DMIN = DN + EMIN = ZERO + ELSE IF( SAFMIN*Z( J4P2+2 ).LT.Z( J4-2 ) .AND. + $ SAFMIN*Z( J4-2 ).LT.Z( J4P2+2 ) ) THEN + TEMP = Z( J4P2+2 ) / Z( J4-2 ) + Z( J4 ) = Z( J4P2 )*TEMP + DN = DNM1*TEMP + ELSE + Z( J4 ) = Z( J4P2+2 )*( Z( J4P2 ) / Z( J4-2 ) ) + DN = Z( J4P2+2 )*( DNM1 / Z( J4-2 ) ) + END IF + DMIN = MIN( DMIN, DN ) +* + Z( J4+2 ) = DN + Z( 4*N0-PP ) = EMIN + RETURN +* +* End of DLASQ6 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasrt.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasrt.f new file mode 100644 index 00000000..f5d0e6cd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/dlasrt.f @@ -0,0 +1,303 @@ +*> \brief \b DLASRT sorts numbers in increasing or decreasing order. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASRT + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASRT( ID, N, D, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER ID +* INTEGER INFO, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION D( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> Sort the numbers in D in increasing order (if ID = 'I') or +*> in decreasing order (if ID = 'D' ). +*> +*> Use Quick Sort, reverting to Insertion sort on arrays of +*> size <= 20. Dimension of STACK limits N to about 2**32. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ID +*> \verbatim +*> ID is CHARACTER*1 +*> = 'I': sort D in increasing order; +*> = 'D': sort D in decreasing order. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The length of the array D. +*> \endverbatim +*> +*> \param[in,out] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> On entry, the array to be sorted. +*> On exit, D has been sorted into increasing order +*> (D(1) <= ... <= D(N) ) or into decreasing order +*> (D(1) >= ... >= D(N) ), depending on ID. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +* ===================================================================== + SUBROUTINE DLASRT( ID, N, D, INFO ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + CHARACTER ID + INTEGER INFO, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION D( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + INTEGER SELECT + PARAMETER ( SELECT = 20 ) +* .. +* .. Local Scalars .. + INTEGER DIR, ENDD, I, J, START, STKPNT + DOUBLE PRECISION D1, D2, D3, DMNMX, TMP +* .. +* .. Local Arrays .. + INTEGER STACK( 2, 32 ) +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input paramters. +* + INFO = 0 + DIR = -1 + IF( LSAME( ID, 'D' ) ) THEN + DIR = 0 + ELSE IF( LSAME( ID, 'I' ) ) THEN + DIR = 1 + END IF + IF( DIR.EQ.-1 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DLASRT', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.1 ) + $ RETURN +* + STKPNT = 1 + STACK( 1, 1 ) = 1 + STACK( 2, 1 ) = N + 10 CONTINUE + START = STACK( 1, STKPNT ) + ENDD = STACK( 2, STKPNT ) + STKPNT = STKPNT - 1 + IF( ENDD-START.LE.SELECT .AND. ENDD-START.GT.0 ) THEN +* +* Do Insertion sort on D( START:ENDD ) +* + IF( DIR.EQ.0 ) THEN +* +* Sort into decreasing order +* + DO 30 I = START + 1, ENDD + DO 20 J = I, START + 1, -1 + IF( D( J ).GT.D( J-1 ) ) THEN + DMNMX = D( J ) + D( J ) = D( J-1 ) + D( J-1 ) = DMNMX + ELSE + GO TO 30 + END IF + 20 CONTINUE + 30 CONTINUE +* + ELSE +* +* Sort into increasing order +* + DO 50 I = START + 1, ENDD + DO 40 J = I, START + 1, -1 + IF( D( J ).LT.D( J-1 ) ) THEN + DMNMX = D( J ) + D( J ) = D( J-1 ) + D( J-1 ) = DMNMX + ELSE + GO TO 50 + END IF + 40 CONTINUE + 50 CONTINUE +* + END IF +* + ELSE IF( ENDD-START.GT.SELECT ) THEN +* +* Partition D( START:ENDD ) and stack parts, largest one first +* +* Choose partition entry as median of 3 +* + D1 = D( START ) + D2 = D( ENDD ) + I = ( START+ENDD ) / 2 + D3 = D( I ) + IF( D1.LT.D2 ) THEN + IF( D3.LT.D1 ) THEN + DMNMX = D1 + ELSE IF( D3.LT.D2 ) THEN + DMNMX = D3 + ELSE + DMNMX = D2 + END IF + ELSE + IF( D3.LT.D2 ) THEN + DMNMX = D2 + ELSE IF( D3.LT.D1 ) THEN + DMNMX = D3 + ELSE + DMNMX = D1 + END IF + END IF +* + IF( DIR.EQ.0 ) THEN +* +* Sort into decreasing order +* + I = START - 1 + J = ENDD + 1 + 60 CONTINUE + 70 CONTINUE + J = J - 1 + IF( D( J ).LT.DMNMX ) + $ GO TO 70 + 80 CONTINUE + I = I + 1 + IF( D( I ).GT.DMNMX ) + $ GO TO 80 + IF( I.LT.J ) THEN + TMP = D( I ) + D( I ) = D( J ) + D( J ) = TMP + GO TO 60 + END IF + IF( J-START.GT.ENDD-J-1 ) THEN + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + ELSE + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + END IF + ELSE +* +* Sort into increasing order +* + I = START - 1 + J = ENDD + 1 + 90 CONTINUE + 100 CONTINUE + J = J - 1 + IF( D( J ).GT.DMNMX ) + $ GO TO 100 + 110 CONTINUE + I = I + 1 + IF( D( I ).LT.DMNMX ) + $ GO TO 110 + IF( I.LT.J ) THEN + TMP = D( I ) + D( I ) = D( J ) + D( J ) = TMP + GO TO 90 + END IF + IF( J-START.GT.ENDD-J-1 ) THEN + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + ELSE + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + END IF + END IF + END IF + IF( STKPNT.GT.0 ) + $ GO TO 10 + RETURN +* +* End of DLASRT +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/ieeeck.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/ieeeck.f new file mode 100644 index 00000000..132e4367 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/ieeeck.f @@ -0,0 +1,203 @@ +*> \brief \b IEEECK +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download IEEECK + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE ) +* +* .. Scalar Arguments .. +* INTEGER ISPEC +* REAL ONE, ZERO +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> IEEECK is called from the ILAENV to verify that Infinity and +*> possibly NaN arithmetic is safe (i.e. will not trap). +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ISPEC +*> \verbatim +*> ISPEC is INTEGER +*> Specifies whether to test just for inifinity arithmetic +*> or whether to test for infinity and NaN arithmetic. +*> = 0: Verify infinity arithmetic only. +*> = 1: Verify infinity and NaN arithmetic. +*> \endverbatim +*> +*> \param[in] ZERO +*> \verbatim +*> ZERO is REAL +*> Must contain the value 0.0 +*> This is passed to prevent the compiler from optimizing +*> away this code. +*> \endverbatim +*> +*> \param[in] ONE +*> \verbatim +*> ONE is REAL +*> Must contain the value 1.0 +*> This is passed to prevent the compiler from optimizing +*> away this code. +*> +*> RETURN VALUE: INTEGER +*> = 0: Arithmetic failed to produce the correct answers +*> = 1: Arithmetic produced the correct answers +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + INTEGER FUNCTION IEEECK( ISPEC, ZERO, ONE ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + INTEGER ISPEC + REAL ONE, ZERO +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + REAL NAN1, NAN2, NAN3, NAN4, NAN5, NAN6, NEGINF, + $ NEGZRO, NEWZRO, POSINF +* .. +* .. Executable Statements .. + IEEECK = 1 +* + POSINF = ONE / ZERO + IF( POSINF.LE.ONE ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGINF = -ONE / ZERO + IF( NEGINF.GE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGZRO = ONE / ( NEGINF+ONE ) + IF( NEGZRO.NE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGINF = ONE / NEGZRO + IF( NEGINF.GE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + NEWZRO = NEGZRO + ZERO + IF( NEWZRO.NE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + POSINF = ONE / NEWZRO + IF( POSINF.LE.ONE ) THEN + IEEECK = 0 + RETURN + END IF +* + NEGINF = NEGINF*POSINF + IF( NEGINF.GE.ZERO ) THEN + IEEECK = 0 + RETURN + END IF +* + POSINF = POSINF*POSINF + IF( POSINF.LE.ONE ) THEN + IEEECK = 0 + RETURN + END IF +* +* +* +* +* Return if we were only asked to check infinity arithmetic +* + IF( ISPEC.EQ.0 ) + $ RETURN +* + NAN1 = POSINF + NEGINF +* + NAN2 = POSINF / NEGINF +* + NAN3 = POSINF / POSINF +* + NAN4 = POSINF*ZERO +* + NAN5 = NEGINF*NEGZRO +* + NAN6 = NAN5*ZERO +* + IF( NAN1.EQ.NAN1 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN2.EQ.NAN2 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN3.EQ.NAN3 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN4.EQ.NAN4 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN5.EQ.NAN5 ) THEN + IEEECK = 0 + RETURN + END IF +* + IF( NAN6.EQ.NAN6 ) THEN + IEEECK = 0 + RETURN + END IF +* + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/ilaenv.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/ilaenv.f new file mode 100644 index 00000000..867464de --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/ilaenv.f @@ -0,0 +1,624 @@ +*> \brief \b ILAENV +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download ILAENV + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 ) +* +* .. Scalar Arguments .. +* CHARACTER*( * ) NAME, OPTS +* INTEGER ISPEC, N1, N2, N3, N4 +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> ILAENV is called from the LAPACK routines to choose problem-dependent +*> parameters for the local environment. See ISPEC for a description of +*> the parameters. +*> +*> ILAENV returns an INTEGER +*> if ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC +*> if ILAENV < 0: if ILAENV = -k, the k-th argument had an illegal value. +*> +*> This version provides a set of parameters which should give good, +*> but not optimal, performance on many of the currently available +*> computers. Users are encouraged to modify this subroutine to set +*> the tuning parameters for their particular machine using the option +*> and problem size information in the arguments. +*> +*> This routine will not function correctly if it is converted to all +*> lower case. Converting it to all upper case is allowed. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ISPEC +*> \verbatim +*> ISPEC is INTEGER +*> Specifies the parameter to be returned as the value of +*> ILAENV. +*> = 1: the optimal blocksize; if this value is 1, an unblocked +*> algorithm will give the best performance. +*> = 2: the minimum block size for which the block routine +*> should be used; if the usable block size is less than +*> this value, an unblocked routine should be used. +*> = 3: the crossover point (in a block routine, for N less +*> than this value, an unblocked routine should be used) +*> = 4: the number of shifts, used in the nonsymmetric +*> eigenvalue routines (DEPRECATED) +*> = 5: the minimum column dimension for blocking to be used; +*> rectangular blocks must have dimension at least k by m, +*> where k is given by ILAENV(2,...) and m by ILAENV(5,...) +*> = 6: the crossover point for the SVD (when reducing an m by n +*> matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds +*> this value, a QR factorization is used first to reduce +*> the matrix to a triangular form.) +*> = 7: the number of processors +*> = 8: the crossover point for the multishift QR method +*> for nonsymmetric eigenvalue problems (DEPRECATED) +*> = 9: maximum size of the subproblems at the bottom of the +*> computation tree in the divide-and-conquer algorithm +*> (used by xGELSD and xGESDD) +*> =10: ieee NaN arithmetic can be trusted not to trap +*> =11: infinity arithmetic can be trusted not to trap +*> 12 <= ISPEC <= 16: +*> xHSEQR or one of its subroutines, +*> see IPARMQ for detailed explanation +*> \endverbatim +*> +*> \param[in] NAME +*> \verbatim +*> NAME is CHARACTER*(*) +*> The name of the calling subroutine, in either upper case or +*> lower case. +*> \endverbatim +*> +*> \param[in] OPTS +*> \verbatim +*> OPTS is CHARACTER*(*) +*> The character options to the subroutine NAME, concatenated +*> into a single character string. For example, UPLO = 'U', +*> TRANS = 'T', and DIAG = 'N' for a triangular routine would +*> be specified as OPTS = 'UTN'. +*> \endverbatim +*> +*> \param[in] N1 +*> \verbatim +*> N1 is INTEGER +*> \endverbatim +*> +*> \param[in] N2 +*> \verbatim +*> N2 is INTEGER +*> \endverbatim +*> +*> \param[in] N3 +*> \verbatim +*> N3 is INTEGER +*> \endverbatim +*> +*> \param[in] N4 +*> \verbatim +*> N4 is INTEGER +*> Problem dimensions for the subroutine NAME; these may not all +*> be required. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> The following conventions have been used when calling ILAENV from the +*> LAPACK routines: +*> 1) OPTS is a concatenation of all of the character options to +*> subroutine NAME, in the same order that they appear in the +*> argument list for NAME, even if they are not used in determining +*> the value of the parameter specified by ISPEC. +*> 2) The problem dimensions N1, N2, N3, N4 are specified in the order +*> that they appear in the argument list for NAME. N1 is used +*> first, N2 second, and so on, and unused problem dimensions are +*> passed a value of -1. +*> 3) The parameter value returned by ILAENV is checked for validity in +*> the calling subroutine. For example, ILAENV is used to retrieve +*> the optimal blocksize for STRTRI as follows: +*> +*> NB = ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 ) +*> IF( NB.LE.1 ) NB = MAX( 1, N ) +*> \endverbatim +*> +* ===================================================================== + INTEGER FUNCTION ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, N4 ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER*( * ) NAME, OPTS + INTEGER ISPEC, N1, N2, N3, N4 +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, IC, IZ, NB, NBMIN, NX + LOGICAL CNAME, SNAME + CHARACTER C1*1, C2*2, C4*2, C3*3, SUBNAM*6 +* .. +* .. Intrinsic Functions .. + INTRINSIC CHAR, ICHAR, INT, MIN, REAL +* .. +* .. External Functions .. + INTEGER IEEECK, IPARMQ + EXTERNAL IEEECK, IPARMQ +* .. +* .. Executable Statements .. +* + GO TO ( 10, 10, 10, 80, 90, 100, 110, 120, + $ 130, 140, 150, 160, 160, 160, 160, 160 )ISPEC +* +* Invalid value for ISPEC +* + ILAENV = -1 + RETURN +* + 10 CONTINUE +* +* Convert NAME to upper case if the first character is lower case. +* + ILAENV = 1 + SUBNAM = NAME + IC = ICHAR( SUBNAM( 1: 1 ) ) + IZ = ICHAR( 'Z' ) + IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN +* +* ASCII character set +* + IF( IC.GE.97 .AND. IC.LE.122 ) THEN + SUBNAM( 1: 1 ) = CHAR( IC-32 ) + DO 20 I = 2, 6 + IC = ICHAR( SUBNAM( I: I ) ) + IF( IC.GE.97 .AND. IC.LE.122 ) + $ SUBNAM( I: I ) = CHAR( IC-32 ) + 20 CONTINUE + END IF +* + ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN +* +* EBCDIC character set +* + IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. + $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. + $ ( IC.GE.162 .AND. IC.LE.169 ) ) THEN + SUBNAM( 1: 1 ) = CHAR( IC+64 ) + DO 30 I = 2, 6 + IC = ICHAR( SUBNAM( I: I ) ) + IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR. + $ ( IC.GE.145 .AND. IC.LE.153 ) .OR. + $ ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I: + $ I ) = CHAR( IC+64 ) + 30 CONTINUE + END IF +* + ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN +* +* Prime machines: ASCII+128 +* + IF( IC.GE.225 .AND. IC.LE.250 ) THEN + SUBNAM( 1: 1 ) = CHAR( IC-32 ) + DO 40 I = 2, 6 + IC = ICHAR( SUBNAM( I: I ) ) + IF( IC.GE.225 .AND. IC.LE.250 ) + $ SUBNAM( I: I ) = CHAR( IC-32 ) + 40 CONTINUE + END IF + END IF +* + C1 = SUBNAM( 1: 1 ) + SNAME = C1.EQ.'S' .OR. C1.EQ.'D' + CNAME = C1.EQ.'C' .OR. C1.EQ.'Z' + IF( .NOT.( CNAME .OR. SNAME ) ) + $ RETURN + C2 = SUBNAM( 2: 3 ) + C3 = SUBNAM( 4: 6 ) + C4 = C3( 2: 3 ) +* + GO TO ( 50, 60, 70 )ISPEC +* + 50 CONTINUE +* +* ISPEC = 1: block size +* +* In these examples, separate code is provided for setting NB for +* real and complex. We assume that NB will take the same value in +* single or double precision. +* + NB = 1 +* + IF( C2.EQ.'GE' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + ELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. + $ C3.EQ.'QLF' ) THEN + IF( SNAME ) THEN + NB = 32 + ELSE + NB = 32 + END IF + ELSE IF( C3.EQ.'HRD' ) THEN + IF( SNAME ) THEN + NB = 32 + ELSE + NB = 32 + END IF + ELSE IF( C3.EQ.'BRD' ) THEN + IF( SNAME ) THEN + NB = 32 + ELSE + NB = 32 + END IF + ELSE IF( C3.EQ.'TRI' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( C2.EQ.'PO' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( C2.EQ.'SY' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN + NB = 32 + ELSE IF( SNAME .AND. C3.EQ.'GST' ) THEN + NB = 64 + END IF + ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN + IF( C3.EQ.'TRF' ) THEN + NB = 64 + ELSE IF( C3.EQ.'TRD' ) THEN + NB = 32 + ELSE IF( C3.EQ.'GST' ) THEN + NB = 64 + END IF + ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN + IF( C3( 1: 1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NB = 32 + END IF + ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NB = 32 + END IF + END IF + ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN + IF( C3( 1: 1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NB = 32 + END IF + ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NB = 32 + END IF + END IF + ELSE IF( C2.EQ.'GB' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + IF( N4.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + ELSE + IF( N4.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + END IF + END IF + ELSE IF( C2.EQ.'PB' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + IF( N2.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + ELSE + IF( N2.LE.64 ) THEN + NB = 1 + ELSE + NB = 32 + END IF + END IF + END IF + ELSE IF( C2.EQ.'TR' ) THEN + IF( C3.EQ.'TRI' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( C2.EQ.'LA' ) THEN + IF( C3.EQ.'UUM' ) THEN + IF( SNAME ) THEN + NB = 64 + ELSE + NB = 64 + END IF + END IF + ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN + IF( C3.EQ.'EBZ' ) THEN + NB = 1 + END IF + END IF + ILAENV = NB + RETURN +* + 60 CONTINUE +* +* ISPEC = 2: minimum block size +* + NBMIN = 2 + IF( C2.EQ.'GE' ) THEN + IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ. + $ 'QLF' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + ELSE IF( C3.EQ.'HRD' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + ELSE IF( C3.EQ.'BRD' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + ELSE IF( C3.EQ.'TRI' ) THEN + IF( SNAME ) THEN + NBMIN = 2 + ELSE + NBMIN = 2 + END IF + END IF + ELSE IF( C2.EQ.'SY' ) THEN + IF( C3.EQ.'TRF' ) THEN + IF( SNAME ) THEN + NBMIN = 8 + ELSE + NBMIN = 8 + END IF + ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN + NBMIN = 2 + END IF + ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN + IF( C3.EQ.'TRD' ) THEN + NBMIN = 2 + END IF + ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN + IF( C3( 1: 1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NBMIN = 2 + END IF + ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NBMIN = 2 + END IF + END IF + ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN + IF( C3( 1: 1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NBMIN = 2 + END IF + ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NBMIN = 2 + END IF + END IF + END IF + ILAENV = NBMIN + RETURN +* + 70 CONTINUE +* +* ISPEC = 3: crossover point +* + NX = 0 + IF( C2.EQ.'GE' ) THEN + IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ. + $ 'QLF' ) THEN + IF( SNAME ) THEN + NX = 128 + ELSE + NX = 128 + END IF + ELSE IF( C3.EQ.'HRD' ) THEN + IF( SNAME ) THEN + NX = 128 + ELSE + NX = 128 + END IF + ELSE IF( C3.EQ.'BRD' ) THEN + IF( SNAME ) THEN + NX = 128 + ELSE + NX = 128 + END IF + END IF + ELSE IF( C2.EQ.'SY' ) THEN + IF( SNAME .AND. C3.EQ.'TRD' ) THEN + NX = 32 + END IF + ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN + IF( C3.EQ.'TRD' ) THEN + NX = 32 + END IF + ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN + IF( C3( 1: 1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NX = 128 + END IF + END IF + ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN + IF( C3( 1: 1 ).EQ.'G' ) THEN + IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ. + $ 'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' ) + $ THEN + NX = 128 + END IF + END IF + END IF + ILAENV = NX + RETURN +* + 80 CONTINUE +* +* ISPEC = 4: number of shifts (used by xHSEQR) +* + ILAENV = 6 + RETURN +* + 90 CONTINUE +* +* ISPEC = 5: minimum column dimension (not used) +* + ILAENV = 2 + RETURN +* + 100 CONTINUE +* +* ISPEC = 6: crossover point for SVD (used by xGELSS and xGESVD) +* + ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 ) + RETURN +* + 110 CONTINUE +* +* ISPEC = 7: number of processors (not used) +* + ILAENV = 1 + RETURN +* + 120 CONTINUE +* +* ISPEC = 8: crossover point for multishift (used by xHSEQR) +* + ILAENV = 50 + RETURN +* + 130 CONTINUE +* +* ISPEC = 9: maximum size of the subproblems at the bottom of the +* computation tree in the divide-and-conquer algorithm +* (used by xGELSD and xGESDD) +* + ILAENV = 25 + RETURN +* + 140 CONTINUE +* +* ISPEC = 10: ieee NaN arithmetic can be trusted not to trap +* +* ILAENV = 0 + ILAENV = 1 + IF( ILAENV.EQ.1 ) THEN + ILAENV = IEEECK( 1, 0.0, 1.0 ) + END IF + RETURN +* + 150 CONTINUE +* +* ISPEC = 11: infinity arithmetic can be trusted not to trap +* +* ILAENV = 0 + ILAENV = 1 + IF( ILAENV.EQ.1 ) THEN + ILAENV = IEEECK( 0, 0.0, 1.0 ) + END IF + RETURN +* + 160 CONTINUE +* +* 12 <= ISPEC <= 16: xHSEQR or one of its subroutines. +* + ILAENV = IPARMQ( ISPEC, NAME, OPTS, N1, N2, N3, N4 ) + RETURN +* +* End of ILAENV +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/iparmq.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/iparmq.f new file mode 100644 index 00000000..bd5bd7a0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/iparmq.f @@ -0,0 +1,322 @@ +*> \brief \b IPARMQ +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download IPARMQ + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, LWORK ) +* +* .. Scalar Arguments .. +* INTEGER IHI, ILO, ISPEC, LWORK, N +* CHARACTER NAME*( * ), OPTS*( * ) +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> This program sets problem and machine dependent parameters +*> useful for xHSEQR and its subroutines. It is called whenever +*> ILAENV is called with 12 <= ISPEC <= 16 +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ISPEC +*> \verbatim +*> ISPEC is integer scalar +*> ISPEC specifies which tunable parameter IPARMQ should +*> return. +*> +*> ISPEC=12: (INMIN) Matrices of order nmin or less +*> are sent directly to xLAHQR, the implicit +*> double shift QR algorithm. NMIN must be +*> at least 11. +*> +*> ISPEC=13: (INWIN) Size of the deflation window. +*> This is best set greater than or equal to +*> the number of simultaneous shifts NS. +*> Larger matrices benefit from larger deflation +*> windows. +*> +*> ISPEC=14: (INIBL) Determines when to stop nibbling and +*> invest in an (expensive) multi-shift QR sweep. +*> If the aggressive early deflation subroutine +*> finds LD converged eigenvalues from an order +*> NW deflation window and LD.GT.(NW*NIBBLE)/100, +*> then the next QR sweep is skipped and early +*> deflation is applied immediately to the +*> remaining active diagonal block. Setting +*> IPARMQ(ISPEC=14) = 0 causes TTQRE to skip a +*> multi-shift QR sweep whenever early deflation +*> finds a converged eigenvalue. Setting +*> IPARMQ(ISPEC=14) greater than or equal to 100 +*> prevents TTQRE from skipping a multi-shift +*> QR sweep. +*> +*> ISPEC=15: (NSHFTS) The number of simultaneous shifts in +*> a multi-shift QR iteration. +*> +*> ISPEC=16: (IACC22) IPARMQ is set to 0, 1 or 2 with the +*> following meanings. +*> 0: During the multi-shift QR sweep, +*> xLAQR5 does not accumulate reflections and +*> does not use matrix-matrix multiply to +*> update the far-from-diagonal matrix +*> entries. +*> 1: During the multi-shift QR sweep, +*> xLAQR5 and/or xLAQRaccumulates reflections and uses +*> matrix-matrix multiply to update the +*> far-from-diagonal matrix entries. +*> 2: During the multi-shift QR sweep. +*> xLAQR5 accumulates reflections and takes +*> advantage of 2-by-2 block structure during +*> matrix-matrix multiplies. +*> (If xTRMM is slower than xGEMM, then +*> IPARMQ(ISPEC=16)=1 may be more efficient than +*> IPARMQ(ISPEC=16)=2 despite the greater level of +*> arithmetic work implied by the latter choice.) +*> \endverbatim +*> +*> \param[in] NAME +*> \verbatim +*> NAME is character string +*> Name of the calling subroutine +*> \endverbatim +*> +*> \param[in] OPTS +*> \verbatim +*> OPTS is character string +*> This is a concatenation of the string arguments to +*> TTQRE. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is integer scalar +*> N is the order of the Hessenberg matrix H. +*> \endverbatim +*> +*> \param[in] ILO +*> \verbatim +*> ILO is INTEGER +*> \endverbatim +*> +*> \param[in] IHI +*> \verbatim +*> IHI is INTEGER +*> It is assumed that H is already upper triangular +*> in rows and columns 1:ILO-1 and IHI+1:N. +*> \endverbatim +*> +*> \param[in] LWORK +*> \verbatim +*> LWORK is integer scalar +*> The amount of workspace available. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Little is known about how best to choose these parameters. +*> It is possible to use different values of the parameters +*> for each of CHSEQR, DHSEQR, SHSEQR and ZHSEQR. +*> +*> It is probably best to choose different parameters for +*> different matrices and different parameters at different +*> times during the iteration, but this has not been +*> implemented --- yet. +*> +*> +*> The best choices of most of the parameters depend +*> in an ill-understood way on the relative execution +*> rate of xLAQR3 and xLAQR5 and on the nature of each +*> particular eigenvalue problem. Experiment may be the +*> only practical way to determine which choices are most +*> effective. +*> +*> Following is a list of default values supplied by IPARMQ. +*> These defaults may be adjusted in order to attain better +*> performance in any particular computational environment. +*> +*> IPARMQ(ISPEC=12) The xLAHQR vs xLAQR0 crossover point. +*> Default: 75. (Must be at least 11.) +*> +*> IPARMQ(ISPEC=13) Recommended deflation window size. +*> This depends on ILO, IHI and NS, the +*> number of simultaneous shifts returned +*> by IPARMQ(ISPEC=15). The default for +*> (IHI-ILO+1).LE.500 is NS. The default +*> for (IHI-ILO+1).GT.500 is 3*NS/2. +*> +*> IPARMQ(ISPEC=14) Nibble crossover point. Default: 14. +*> +*> IPARMQ(ISPEC=15) Number of simultaneous shifts, NS. +*> a multi-shift QR iteration. +*> +*> If IHI-ILO+1 is ... +*> +*> greater than ...but less ... the +*> or equal to ... than default is +*> +*> 0 30 NS = 2+ +*> 30 60 NS = 4+ +*> 60 150 NS = 10 +*> 150 590 NS = ** +*> 590 3000 NS = 64 +*> 3000 6000 NS = 128 +*> 6000 infinity NS = 256 +*> +*> (+) By default matrices of this order are +*> passed to the implicit double shift routine +*> xLAHQR. See IPARMQ(ISPEC=12) above. These +*> values of NS are used only in case of a rare +*> xLAHQR failure. +*> +*> (**) The asterisks (**) indicate an ad-hoc +*> function increasing from 10 to 64. +*> +*> IPARMQ(ISPEC=16) Select structured matrix multiply. +*> (See ISPEC=16 above for details.) +*> Default: 3. +*> \endverbatim +*> +* ===================================================================== + INTEGER FUNCTION IPARMQ( ISPEC, NAME, OPTS, N, ILO, IHI, LWORK ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + INTEGER IHI, ILO, ISPEC, LWORK, N + CHARACTER NAME*( * ), OPTS*( * ) +* +* ================================================================ +* .. Parameters .. + INTEGER INMIN, INWIN, INIBL, ISHFTS, IACC22 + PARAMETER ( INMIN = 12, INWIN = 13, INIBL = 14, + $ ISHFTS = 15, IACC22 = 16 ) + INTEGER NMIN, K22MIN, KACMIN, NIBBLE, KNWSWP + PARAMETER ( NMIN = 75, K22MIN = 14, KACMIN = 14, + $ NIBBLE = 14, KNWSWP = 500 ) + REAL TWO + PARAMETER ( TWO = 2.0 ) +* .. +* .. Local Scalars .. + INTEGER NH, NS +* .. +* .. Intrinsic Functions .. + INTRINSIC LOG, MAX, MOD, NINT, REAL +* .. +* .. Executable Statements .. + IF( ( ISPEC.EQ.ISHFTS ) .OR. ( ISPEC.EQ.INWIN ) .OR. + $ ( ISPEC.EQ.IACC22 ) ) THEN +* +* ==== Set the number simultaneous shifts ==== +* + NH = IHI - ILO + 1 + NS = 2 + IF( NH.GE.30 ) + $ NS = 4 + IF( NH.GE.60 ) + $ NS = 10 + IF( NH.GE.150 ) + $ NS = MAX( 10, NH / NINT( LOG( REAL( NH ) ) / LOG( TWO ) ) ) + IF( NH.GE.590 ) + $ NS = 64 + IF( NH.GE.3000 ) + $ NS = 128 + IF( NH.GE.6000 ) + $ NS = 256 + NS = MAX( 2, NS-MOD( NS, 2 ) ) + END IF +* + IF( ISPEC.EQ.INMIN ) THEN +* +* +* ===== Matrices of order smaller than NMIN get sent +* . to xLAHQR, the classic double shift algorithm. +* . This must be at least 11. ==== +* + IPARMQ = NMIN +* + ELSE IF( ISPEC.EQ.INIBL ) THEN +* +* ==== INIBL: skip a multi-shift qr iteration and +* . whenever aggressive early deflation finds +* . at least (NIBBLE*(window size)/100) deflations. ==== +* + IPARMQ = NIBBLE +* + ELSE IF( ISPEC.EQ.ISHFTS ) THEN +* +* ==== NSHFTS: The number of simultaneous shifts ===== +* + IPARMQ = NS +* + ELSE IF( ISPEC.EQ.INWIN ) THEN +* +* ==== NW: deflation window size. ==== +* + IF( NH.LE.KNWSWP ) THEN + IPARMQ = NS + ELSE + IPARMQ = 3*NS / 2 + END IF +* + ELSE IF( ISPEC.EQ.IACC22 ) THEN +* +* ==== IACC22: Whether to accumulate reflections +* . before updating the far-from-diagonal elements +* . and whether to use 2-by-2 block structure while +* . doing it. A small amount of work could be saved +* . by making this choice dependent also upon the +* . NH=IHI-ILO+1. +* + IPARMQ = 0 + IF( NS.GE.KACMIN ) + $ IPARMQ = 1 + IF( NS.GE.K22MIN ) + $ IPARMQ = 2 +* + ELSE +* ===== invalid value of ispec ===== + IPARMQ = -1 +* + END IF +* +* ==== End of IPARMQ ==== +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/lsame.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/lsame.f new file mode 100644 index 00000000..315304c3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/lsame.f @@ -0,0 +1,125 @@ +*> \brief \b LSAME +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* LOGICAL FUNCTION LSAME( CA, CB ) +* +* .. Scalar Arguments .. +* CHARACTER CA, CB +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> LSAME returns .TRUE. if CA is the same letter as CB regardless of +*> case. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] CA +*> \verbatim +*> \endverbatim +*> +*> \param[in] CB +*> \verbatim +*> CA and CB specify the single characters to be compared. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + LOGICAL FUNCTION LSAME( CA, CB ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER CA, CB +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC ICHAR +* .. +* .. Local Scalars .. + INTEGER INTA, INTB, ZCODE +* .. +* .. Executable Statements .. +* +* Test if the characters are equal +* + LSAME = CA.EQ.CB + IF( LSAME ) + $ RETURN +* +* Now test for equivalence if both characters are alphabetic. +* + ZCODE = ICHAR( 'Z' ) +* +* Use 'Z' rather than 'A' so that ASCII can be detected on Prime +* machines, on which ICHAR returns a value with bit 8 set. +* ICHAR('A') on Prime machines returns 193 which is the same as +* ICHAR('A') on an EBCDIC machine. +* + INTA = ICHAR( CA ) + INTB = ICHAR( CB ) +* + IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN +* +* ASCII is assumed - ZCODE is the ASCII code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32 + IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32 +* + ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN +* +* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.129 .AND. INTA.LE.137 .OR. + $ INTA.GE.145 .AND. INTA.LE.153 .OR. + $ INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64 + IF( INTB.GE.129 .AND. INTB.LE.137 .OR. + $ INTB.GE.145 .AND. INTB.LE.153 .OR. + $ INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64 +* + ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN +* +* ASCII is assumed, on Prime machines - ZCODE is the ASCII code +* plus 128 of either lower or upper case 'Z'. +* + IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32 + IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32 + END IF + LSAME = INTA.EQ.INTB +* +* RETURN +* +* End of LSAME +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq1.f90 b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq1.f90 new file mode 100644 index 00000000..5ee8878d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq1.f90 @@ -0,0 +1,626 @@ +program randomsys1 +implicit none +integer, parameter :: nmax=1000 +real(kind=8), dimension(nmax) :: b, x +real(kind=8), dimension(nmax,nmax) :: a +real(kind=8) :: err +integer :: i, info, lda, ldb, nrhs, n,iter +integer, dimension(nmax) :: ipiv + +real(kind=8), dimension(100) :: d +real(kind=8), dimension(99) :: e +real(kind=8), dimension(400) :: work + +d(1:100) = (/1.8334043365537367D+00, & +1.4451749896846686D+00, & +1.0018566447551758D-01, & +-7.2143260438744417D-01, & +-3.7864653015502087D-01, & +-9.0270111568850808D-01, & +1.2204305489831029D+00, & +-9.7628177811136485D-01, & +8.4199233511256721D-01, & +-2.7938817329922050D-01, & +3.6157779599908046D-01, & +-1.8563411313998144D+00, & +-5.7930081140992240D-01, & +7.4080550463379169D-01, & +1.7021409147402005D+00, & +-5.7992035328196923D-01, & +4.0877426434579855D-01, & +-7.1297236049446144D-01, & +-1.2214095798914903D+00, & +2.9037983248746674D-01, & +7.4685018821608473D-01, & +3.0213735481316539D-01, & +-1.5207207136907624D-01, & +-2.1332671668411556D+00, & +6.8744661834930676D-01, & +-2.0946670404018297D-01, & +-1.5221059713957628D+00, & +1.1117190383859539D+00, & +-6.1175948159744020D-01, & +-4.4149212620857964D-01, & +-5.5702632609947533D-01, & +1.4071858950692646D+00, & +-3.2329881667362437D-01, & +-3.1958092104323499D-01, & +9.0934520529412111D-01, & +9.7881421364746712D-01, & +-5.1202970940327841D-01, & +1.5040024724520102D+00, & +-7.1993831181468571D-01, & +-7.1819661000094503D-01, & +-1.3481185445933910D+00, & +-1.4984426192966893D+00, & +1.1356626654278745D+00, & +1.6427417967661164D+00, & +-1.4184643787388000D+00, & +2.9811560271518989D-01, & +7.8630022575860559D-01, & +-1.8262830018047089D+00, & +6.3058255632564841D-01, & +-2.0692752940382309D-02, & +-7.2726648905906033D-01, & +-1.0461446937034022D+00, & +1.2530345094987356D+00, & +-2.3583665341168443D+00, & +1.9177654334479410D-01, & +-1.3563410975095058D+00, & +-1.0669710425337906D+00, & +1.4840245472507219D+00, & +-6.9185935518981789D-01, & +1.6813910559942205D-01, & +-7.1255209442204559D-01, & +-1.0112797453604008D+00, & +2.8591746998403011D-01, & +-1.9403039239509563D+00, & +-8.1434141084858885D-02, & +1.3873918713367210D+00, & +-8.8212258376548647D-01, & +-1.2253510598547583D+00, & +-3.8677386127356073D-01, & +-1.0262656526479850D+00, & +2.9468734022014376D-01, & +2.3442965677966704D-01, & +1.2219251054024911D+00, & +2.6066505150099868D+00, & +-7.8543147636303856D-01, & +-9.8126277325503253D-01, & +1.1722358680271947D+00, & +-8.1477749181289072D-01, & +1.3437777060446568D-01, & +3.4626341297821356D-01, & +-4.5672026157532375D-01, & +3.0496975959999184D-01, & +3.4636683737604146D-01, & +1.5114807806635011D-01, & +-1.1376177393945328D+00, & +9.3419670621891793D-01, & +7.9186416310239138D-01, & +6.7230421440462595D-01, & +-2.3236847424852280D-01, & +-1.0927137499922757D+00, & +9.8562766620822340D-01, & +-1.1382935431007701D-01, & +-9.2072237463768225D-01, & +6.1142850054965170D-01, & +8.2752057022739134D-03, & +6.7197122515126417D-01, & +-1.1007816668204429D+00, & +-1.2196829073430047D+00, & +-6.1428585523321222D-01, & +6.4599803465517280D-01/) +e(1:99) = (/-9.6393084631802151D-01, & +2.5532567563781607D+00, & +8.2492664240014357D-01, & +8.2628261757058474D-01, & +7.3021658879350859D-01, & +3.4014431785419519D-02, & +3.2121571974900542D-01, & +2.5987166374572213D-02, & +-3.1150206355945814D-01, & +1.3429094629249927D+00, & +8.6246434952180806D-01, & +-8.3756967113851388D-01, & +9.5277237959592009D-01, & +1.1717152179539618D+00, & +2.5980977671460709D-01, & +-6.4468162556415265D-01, & +-1.3751364204170078D+00, & +2.9677172586579936D-01, & +-3.7071376979215720D-01, & +8.2912690407496381D-01, & +-8.6820437618589197D-01, & +5.2500961173269689D-01, & +1.0657701704030644D+00, & +-4.6621502244820201D-03, & +-1.9013997092621748D-01, & +1.5098985741543924D-01, & +1.0102557493909003D+00, & +8.8830298507891103D-01, & +2.0464938169302065D+00, & +4.7910192662606277D-01, & +1.4155288808120892D+00, & +-5.8169388172737679D-01, & +-9.8007278321065916D-01, & +2.4369633027015425D-01, & +1.6173163491335715D-01, & +6.6887624704464499D-01, & +-1.6500999383869115D+00, & +1.4380895281962367D+00, & +4.7508565250807777D-01, & +-3.1332991280327299D-01, & +3.1402552392574451D-01, & +5.6246373170551534D-01, & +2.5944662334710866D-01, & +4.8101648688789655D-01, & +1.7823376751423265D+00, & +3.0160656491545923D-01, & +-8.8915960863742050D-01, & +-4.4783548340444157D-01, & +8.9985836172311440D-01, & +-1.5626460660617920D+00, & +8.9972644535054036D-01, & +2.4456452268563592D-01, & +-3.1377944726557985D+00, & +1.6874136691232020D+00, & +2.4791290942030142D-01, & +1.7055713617986679D+00, & +1.7027580566127303D+00, & +-5.2969836953828042D-01, & +-8.6858804294195124D-01, & +7.6588136514601834D-01, & +8.6161822555855139D-01, & +6.5387844189250555D-01, & +7.0164941351276944D-01, & +4.1171318512873312D-01, & +7.6075070364872455D-01, & +8.5708035578209718D-02, & +-4.3558500874018535D-01, & +-6.2302104134015979D-01, & +8.4912051051824700D-01, & +-1.7120108380813925D-01, & +-9.7880552224113848D-01, & +1.1904436348486702D+00, & +7.0273864977367972D-01, & +-1.0213785672492079D+00, & +4.8392839864322634D-02, & +1.2611184618297511D-01, & +5.3330169134056482D-01, & +1.8070298106837654D+00, & +-2.8022831541922144D-01, & +8.0235047640662738D-01, & +-1.2615220404695868D+00, & +1.1878769364434660D+00, & +-2.1059219864297674D-01, & +3.2897539618854971D-01, & +-5.8928028913554642D-01, & +1.9164347352074701D-02, & +2.8035162764822374D-01, & +-9.6622429734784299D-02, & +3.4216241143907045D-01, & +-2.2358052317750254D+00, & +6.6284070879481805D-01, & +7.4316074303777269D-01, & +1.0280848437626724D+00, & +-2.0939898252763922D-01, & +-1.0268515265064981D+00, & +-1.2648527910628871D-01, & +4.8663846308033204D-01, & +1.2270171407392749D+00, & +-1.6189022502021406D+00/) +work(1:400) = (/6.0466028797961957D-01, & +9.4050908804501243D-01, & +6.6456005321849043D-01, & +4.3771418718698019D-01, & +4.2463749707126569D-01, & +6.8682307286710942D-01, & +6.5637019217476222D-02, & +1.5651925473279124D-01, & +9.6969518914484562D-02, & +3.0091186058528707D-01, & +5.1521262850206540D-01, & +8.1363996099009683D-01, & +2.1426387258237492D-01, & +3.8065718929968601D-01, & +3.1805817433032985D-01, & +4.6888984490242319D-01, & +2.8303415118044517D-01, & +2.9310185733681576D-01, & +6.7908467592021626D-01, & +2.1855305259276428D-01, & +2.0318687664732285D-01, & +3.6087141685690599D-01, & +5.7067327607102258D-01, & +8.6249143744788637D-01, & +2.9311424455385804D-01, & +2.9708256355629153D-01, & +7.5257303555161192D-01, & +2.0658266191369859D-01, & +8.6533501300156102D-01, & +6.9671916574663473D-01, & +5.2382030605000085D-01, & +2.8303083325889995D-02, & +1.5832827774512764D-01, & +6.0725343954551536D-01, & +9.7524161886057836D-01, & +7.9453623373871976D-02, & +5.9480859768306260D-01, & +5.9120651313875290D-02, & +6.9202458735311201D-01, & +3.0152268100655999D-01, & +1.7326623818270528D-01, & +5.4109985500873525D-01, & +5.4415557300088502D-01, & +2.7850762181610883D-01, & +4.2315220157182809D-01, & +5.3058571535070520D-01, & +2.5354050051506050D-01, & +2.8208099496492467D-01, & +7.8860491501934493D-01, & +3.6180548048031691D-01, & +8.8054312274161706D-01, & +2.9711226063977081D-01, & +8.9436172933045366D-01, & +9.7454618399116566D-02, & +9.7691686858626237D-01, & +7.4290998949843021D-02, & +2.2228941700678773D-01, & +6.8107831239257088D-01, & +2.4151508854715265D-01, & +3.1152244431052484D-01, & +9.3284642851843402D-01, & +7.4184895999182299D-01, & +8.0105504265266125D-01, & +7.3023147729480831D-01, & +1.8292491645390843D-01, & +4.2835708180680782D-01, & +8.9699195756187267D-01, & +6.8265348801324377D-01, & +9.7892935557668759D-01, & +9.2221225892172687D-01, & +9.0837275353887081D-02, & +4.9314199770488037D-01, & +9.2698680357441421D-01, & +9.5494544041678175D-01, & +3.4795396362822290D-01, & +6.9083883150567893D-01, & +7.1090719529999513D-01, & +5.6377959581526438D-01, & +6.4948946059294044D-01, & +5.5176504901277490D-01, & +7.5582350749159777D-01, & +4.0380328579570035D-01, & +1.3065111702897217D-01, & +9.8596472934024670D-01, & +8.9634174539621614D-01, & +3.2208397052088172D-01, & +7.2114776519267410D-01, & +6.4453978250932942D-01, & +8.5520507541911234D-02, & +6.6957529769977453D-01, & +6.2272831736370449D-01, & +3.6969284363982191D-01, & +2.3682254680548520D-01, & +5.3528189063440612D-01, & +1.8724610140105305D-01, & +2.3884070280531861D-01, & +6.2809817121836331D-01, & +1.2675292937260130D-01, & +2.8133029380535923D-01, & +4.1032284435628247D-01, & +4.3491247389145765D-01, & +6.2509502830053043D-01, & +5.5014692050772329D-01, & +6.2360882645293014D-01, & +7.2918072673429812D-01, & +8.3053391899480622D-01, & +5.1381551612136129D-04, & +7.3606860149543141D-01, & +3.9998376285699544D-01, & +4.9786811334270198D-01, & +6.0397810228292748D-01, & +4.0961827788499267D-01, & +2.9671281274886468D-02, & +1.9038945142366389D-03, & +2.8430411748625642D-03, & +9.1582131461295702D-01, & +5.8983418500491935D-01, & +5.5939244907101404D-01, & +8.1540517093336062D-01, & +8.7801175865240000D-01, & +4.5844247857565062D-01, & +6.0016559532333080D-01, & +2.6265150609689439D-02, & +8.4583278724804167D-01, & +2.4969320116349378D-01, & +6.4178429079958299D-01, & +2.4746660783662855D-01, & +1.7365584472313275D-01, & +5.9262375321244554D-01, & +8.1439455096702107D-01, & +6.9383813651720949D-01, & +3.0322547833006870D-02, & +5.3921010589094598D-01, & +9.7567481498731645D-01, & +7.5076305647959851D-01, & +2.9400631279501488D-01, & +7.5316127773675856D-01, & +1.5096404497960700D-01, & +3.5576726540923664D-01, & +8.3193085296981628D-01, & +2.3183004193767690D-01, & +6.2783460500002275D-01, & +4.9839430127597562D-01, & +8.9836089260366833D-02, & +2.5193959794895041D-02, & +3.9221618315402479D-01, & +5.8938308640079917D-01, & +9.2961163544903025D-01, & +5.7208680144308399D-01, & +5.8857634514348212D-01, & +4.1176268834501623D-01, & +5.5258038981424384D-01, & +4.9160739613162047D-01, & +9.5795391353751358D-01, & +7.9720854091080284D-01, & +1.0738111282075208D-01, & +7.8303497339600214D-01, & +3.9325099922888668D-01, & +1.3041384617379179D-01, & +1.9003276633920804D-01, & +7.3982578101583363D-01, & +6.5404140923127974D-01, & +9.8383788985732593D-02, & +5.2038028571222783D-01, & +9.9729663719935122D-02, & +1.5184340208190175D-01, & +7.6190262303755044D-02, & +3.1520808532012451D-01, & +1.5965092146489504D-01, & +1.3780406161952607D-01, & +3.2261068286779754D-01, & +5.3907451703947940D-01, & +5.7085162734549566D-01, & +5.1278175811108151D-01, & +6.8417513009745512D-01, & +6.5304020513536076D-01, & +5.2449975954986505D-01, & +6.5427013442414605D-01, & +7.1636837490167116D-01, & +6.3664421403817983D-01, & +1.2825909106361078D-02, & +3.0682195787138565D-02, & +9.8030874806304999D-02, & +3.6911170916434483D-01, & +8.2645412563474197D-01, & +3.4768170859156955D-01, & +3.4431501772636058D-01, & +2.5299982364784412D-01, & +2.1647114665497036D-01, & +5.5500213563479417D-01, & +4.0207084527183062D-01, & +5.0649706367641834D-01, & +1.6867966833433606D-01, & +3.3136826030698385D-01, & +8.2792809615055885D-01, & +7.0028787314581509D-01, & +5.7926259664335768D-02, & +9.9915949022033324D-01, & +4.1154036322047599D-01, & +1.1167463676480495D-01, & +7.8075408455849260D-01, & +9.2117624440742188D-02, & +5.3494624494407637D-02, & +7.1469581589162956D-01, & +2.5076227542918023D-01, & +8.4863292090315690D-01, & +9.7388187407067284D-01, & +2.1256094905031958D-01, & +2.1533783325605065D-02, & +9.4519476038882588D-01, & +9.2970155499924934D-02, & +6.4583337452397671D-01, & +3.1188554282705405D-01, & +4.4846436394045647D-01, & +4.8723924858036949D-01, & +8.2479676511350006D-02, & +6.7182910623463954D-01, & +4.0018828942364343D-01, & +9.0027514726431157D-01, & +9.4988320610125321D-01, & +3.1933126760711733D-01, & +4.9938549375241320D-01, & +4.0043231714181288D-01, & +1.9808670325451940D-02, & +6.4503886601944815D-01, & +4.2868843006993296D-01, & +3.3959675138730994D-01, & +8.8744750085050050D-01, & +2.3632747430436052D-01, & +7.6500821493327975D-01, & +3.5754647436084384D-02, & +7.2757725604152290D-01, & +6.2583662695812525D-01, & +5.1308750608785669D-01, & +7.2448356792351315D-02, & +7.2422905845916841D-01, & +8.7984484630570914D-01, & +9.7776347735771851D-01, & +8.4750026226468134D-01, & +8.3219793814993315D-01, & +2.4784452318699535D-01, & +9.1339906293647088D-01, & +7.5037210134653420D-02, & +8.3510380115435290D-01, & +6.2933169164530067D-01, & +7.5174057889673473D-01, & +6.3200343378879975D-01, & +9.6934213238731665D-02, & +1.4827369494876504D-02, & +5.8383474186253115D-01, & +6.8756195202154743D-02, & +9.9827381100849455D-01, & +6.4918841659842363D-01, & +9.8546557863324791D-01, & +8.3480576021921249D-01, & +3.3205608571906026D-01, & +6.6139318058334262D-01, & +9.5602062659660969D-01, & +3.1051027622482125D-01, & +1.8439069400202679D-01, & +9.6709434137177297D-01, & +8.3324181552815457D-01, & +3.0954845052732810D-01, & +8.0587176753764456D-01, & +4.1732584219038238D-01, & +7.1853044935277477D-01, & +4.0673677545039083D-01, & +8.9580326774414576D-01, & +9.5817636260259365D-01, & +1.8713221139656417D-02, & +7.9167230908208319D-01, & +4.2355315388584103D-01, & +1.5181277223073395D-02, & +4.3269824007906393D-01, & +9.0477623706573340D-01, & +8.5570441457488644D-01, & +4.2921642176334200D-02, & +6.5903053300775438D-01, & +3.4785904313005395D-01, & +5.0348679004869112D-01, & +8.3994742117055976D-01, & +2.3109568410543832D-02, & +1.2436351859954159D-01, & +2.6117561918821841D-01, & +8.3494750649349414D-01, & +3.1480479595597533D-01, & +7.6812064740880894D-03, & +8.9975012571752733D-01, & +3.7026753645051064D-01, & +1.0019940926941497D-01, & +6.4320402657020315D-01, & +7.6988908998308336D-01, & +7.9112533566198451D-01, & +2.6238190747072776D-01, & +3.4686388037925503D-01, & +2.1465371537694145D-01, & +8.2209289717657175D-01, & +3.5113429966521320D-01, & +5.9919425250588099D-01, & +5.7835125693111211D-01, & +4.1358098797631293D-01, & +1.1985050890286310D-01, & +9.1161370679159903D-01, & +5.3785580105748208D-02, & +2.2891758676059876D-01, & +3.2417396306138829D-01, & +3.5076512764716117D-01, & +3.4928874777426255D-01, & +3.0380212985436572D-01, & +9.6874615996581170D-01, & +6.7152655046083776D-01, & +2.0794312837315651D-01, & +9.6313940120247044D-01, & +3.0220237504213365D-01, & +8.0794108095480799D-01, & +1.3408416275024179D-01, & +9.4776028919455635D-01, & +6.4086482116825383D-01, & +9.5325875425035178D-01, & +8.0987422593395209D-01, & +1.8159084675756379D-01, & +9.4275737153737327D-01, & +8.3124103554376771D-01, & +4.9468043578205978D-01, & +8.5531034647693982D-01, & +7.1074391181909824D-01, & +2.7349475629159786D-01, & +4.0763287189198161D-01, & +9.0976128251911847D-01, & +9.4439713870030451D-01, & +4.9863245185560190D-01, & +2.8863831012730923D-01, & +9.7589525649963815D-01, & +4.5258447627808124D-01, & +4.4990698677957075D-02, & +3.1536198151820755D-01, & +9.5190614812037189D-01, & +7.5156308247423609D-01, & +5.3579099898961424D-01, & +6.6971458883510748D-01, & +8.6517499748328641D-01, & +4.5888445390388938D-01, & +5.7855090249582031D-01, & +4.8152982184966137D-01, & +5.5061576198318274D-01, & +9.5062324380815433D-01, & +5.0986542047295536D-01, & +7.4251472966182985D-01, & +4.9079401441435533D-01, & +6.6151414870689360D-02, & +2.6249066264989940D-01, & +9.2546794407799982D-01, & +3.7148665165822231D-01, & +4.0941940003107308D-01, & +4.1575196973399631D-01, & +9.7261599736539445D-02, & +9.0162762447969347D-01, & +4.4446597981328932D-03, & +2.7392454335102678D-01, & +1.0930666111680035D-01, & +8.5544841289295426D-01, & +2.5705535663902546D-01, & +9.8913209203202213D-01, & +9.2641142236812712D-01, & +1.7094603208839290D-01, & +3.0388712489325242D-01, & +5.3345144978115477D-01, & +1.7648961347647024D-01, & +8.1359077477652830D-01, & +7.0513712380125892D-01, & +2.5720755742139950D-01, & +2.5036892046498466D-01, & +3.3509436689927874D-01, & +7.5124063162526056D-01, & +4.8797826077860845D-03, & +8.4099320643626019D-01, & +2.2957358869665739D-01, & +1.3285547727582237D-02, & +9.4993740716879371D-01, & +8.9937146465701423D-01, & +9.6262420114388625D-01, & +4.3000361954927006D-02, & +7.1266261216467264D-01, & +5.1094098258212241D-02, & +4.0753210485857738D-01, & +4.7569737399615403D-01, & +3.4746838606940983D-01, & +4.0719938711096422D-02, & +5.9756620514440806D-01, & +2.6012467360309705D-01, & +8.3285585557738717D-01, & +9.6049750529821787D-01, & +9.3670756890653750D-01, & +2.2932023844733959D-01, & +7.2031310018914962D-01, & +7.5648232426876405D-01, & +4.5015392507594826D-01, & +3.3897738839543617D-01, & +4.7249205225111501D-01, & +9.8599436000817042D-01/) +n = 100 +info = 0 + +open(unit = 4, STATUS='REPLACE', file = "gen4tests.txt") +open(unit = 3, STATUS='REPLACE', file = "gen3tests.txt") +open(unit = 5, STATUS='REPLACE', file = "gen5tests.txt") + +call dlasq1(n, d, e, work, info) + +close(5) +close(3) +close(4) + +end \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq2.f90 b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq2.f90 new file mode 100644 index 00000000..c908f7d6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq2.f90 @@ -0,0 +1,171 @@ +! $CLASSHG/codes/lapack/random/randomsys1.f90 + +program randomsys1 +implicit none +integer, parameter :: nmax=1000 +real(kind=8), dimension(nmax) :: b, x +real(kind=8), dimension(nmax,nmax) :: a +real(kind=8) :: err +integer :: i, info, lda, ldb, nrhs, n,iter +integer, dimension(nmax) :: ipiv + +real(kind=8), dimension(84) :: z + +z(1:84) = (/2.3962280929192509D-01, & +6.4346010490580374D-01, & +5.4886677265274941D-01, & +1.8435046456575191D-01, & +4.2690013698472401D-01, & +6.2760930131666248D-01, & +8.7243363936287288D-02, & +5.3710399529030350D-01, & +8.4474604576675638D-01, & +4.0947669295022632D-01, & +2.0315141244999760D-01, & +8.2714283129979482D-01, & +9.6582843029739029D-01, & +3.7773539690481128D-01, & +6.4713340225873406D-01, & +6.7774351756798612D-01, & +4.4568905572928591D-01, & +1.7208265726837521D-01, & +3.5202074329011412D-01, & +3.2913965083413110D-01, & +7.4682622623737438D-01, & +2.7151044969605542D-01, & +5.6129178633962351D-01, & +1.3244294692867761D-01, & +7.9837660640147112D-01, & +2.0595995860196409D-01, & +2.6555102564257749D-02, & +1.9623902644848701D-01, & +7.8452468963715605D-03, & +8.2177375597112101D-01, & +9.4444982187044924D-01, & +4.6799576958310329D-01, & +1.1359180530395520D-01, & +1.6049482525711320D-01, & +8.4523811016138373D-01, & +8.5370708147160490D-01, & +3.0139325968162661D-01, & +2.5117154067021252D-01, & +2.0086476380364379D-01, & +2.6078975734443288D-01, & +2.5710509100784901D-01, & +6.2861740244633146D-01, & +4.7397018497236110D-01, & +8.6989475348440182D-01, & +6.4860795895959611D-01, & +8.8943219043019872D-01, & +7.9524758401855578D-01, & +8.8016617212154102D-01, & +2.1472721943810300D-01, & +9.5183566464760194D-01, & +7.1911522894148772D-01, & +1.1065249711733080D-01, & +9.5745872307341484D-01, & +6.4694742306793951D-01, & +5.8182607574435841D-01, & +1.2922028370755401D-02, & +2.7617229134380777D-01, & +8.0045359255855852D-01, & +3.2789738555900377D-01, & +5.7940374386642890D-01, & +2.3961554431041750D-02, & +6.6990484757537938D-01, & +1.8144929371280860D-01, & +2.8661849362222419D-01, & +6.5845572125062690D-01, & +5.8896512277754309D-01, & +6.3697665190607378D-02, & +1.3281935295985961D-01, & +7.4166314172628711D-01, & +5.0033182787066932D-01, & +3.1440772963953763D-02, & +9.9073931564031925D-01, & +3.4236965949145941D-03, & +6.9929220728508257D-01, & +7.5905196170645428D-01, & +2.5421825141163590D-01, & +3.3146571845550887D-01, & +5.7286596840196446D-01, & +9.9158547964144228D-01, & +4.8967497301052382D-01, & +5.6113697207961410D-01, & +6.0641422150435165D-01, & +8.5675901647669139D-02, & +2.5817319326781851D-01/) +n = 21 +info = 0 + +open(unit = 2,STATUS='REPLACE', file = "gen2tests.txt") +open(unit = 4, STATUS='REPLACE', file = "gen4tests.txt") +open(unit = 3,STATUS='REPLACE', file = "gen3tests.txt") +open(unit = 5,STATUS='REPLACE', file = "gen5tests.txt") + +write(2,*) "{" +write(2,'(9999(g0))',advance="no") "z: []float64{" +do i = 1, 4*n +write (2,'(99999(e24.16,a))',advance="no") z(i), "," +end do +write (2,*) "}," +write(2,*) "n: " ,n,"," + + +call dlasq2(n, z, info) + +write(2,'(9999(g0))', advance="no") "zOut: []float64{" +do i = 1, 4*n +write (2,'(99999(e24.16,a))', advance="no") z(i), "," +end do +write (2,*) "}," +write(2,*) "info:", info, "," +write(2,*) "}," + +print *, "Done fixed dlasq2" + +close(5) +close(3) +close(4) +close(2) + +! For random tests +n = 21 + +open(unit = 2, STATUS='REPLACE', file = "gen2tests.txt") +open(unit = 4, STATUS='REPLACE', file = "gen4tests.txt") +open(unit = 3, STATUS='REPLACE', file = "gen3tests.txt") +open(unit = 5, STATUS='REPLACE', file = "gen5tests.txt") + +do iter = 1, 2 + +call random_number(z(1:4*n)) + +write(2,*) "{" +write(2,'(9999(g0))', advance="no") "z: []float64{" +do i = 1, 4*n +write (2,'(99999(e24.16,a))', advance="no") z(i), "," +end do +write (2,*) "}," +write(2,*) "n: " ,n,"," + +call dlasq2(n, z, info) + +write(2,'(9999(g0))', advance="no") "zOut: []float64{" +do i = 1, 4*n + write (2,'(99999(e24.16,a))', advance="no") z(i), "," +end do +write (2,*) "}," +write(2,*) "info:", info, "," +write(2,*) "}," + +print *, "Done with dlasq2" + +end do + +close(5) +close(3) +close(4) +close(2) + +end program randomsys1 \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq3.f90 b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq3.f90 new file mode 100644 index 00000000..8cc5cf0f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq3.f90 @@ -0,0 +1,132 @@ +program testdlasq3 +implicit none + +! Dlasq3 tests +integer :: i0, n0, pp,ttype, nFail,iter,nDiv,n +real(kind=8), dimension(84) :: z +real(kind=8) :: dmin,desig,qmax,dmin1,dmin2,dn,dn1,dn2,g,tau,sigma +logical :: ieee + +n = 84 + +ieee = .True. + +z(1:84) = (/1.9143652461808209D+00, & +1.5643842977038900D+00, & +2.4933891621438989D-01, & +3.4998094847693051D-01, & +1.3159965131315450D+00, & +1.3638621124906269D+00, & +9.8984666119707590D-02, & +2.0147331685530781D-01, & +6.0239739795872871D-01, & +6.4655447927417942D-01, & +2.2100334106387809D-03, & +5.4827584804256833D-02, & +9.8618572336789667D-02, & +2.4281908107454921D-02, & +4.7563214844548191D-01, & +7.6546697639973529D-02, & +2.5887481436771148D-01, & +6.1277840695087704D-01, & +1.0786113766900041D-01, & +1.2172855586231640D-01, & +6.4428964922552456D-01, & +2.2938358048981550D-01, & +6.2032304866397048D-01, & +5.2276720640470942D-01, & +3.6956606786075852D-01, & +7.6452331847458654D-01, & +5.3788380542522651D-01, & +2.2536579805014259D-01, & +3.5625331812646233D-01, & +8.8204867223354833D-01, & +2.2221324964361449D-02, & +1.2088451318140349D-02, & +1.2750943030216850D+00, & +6.5487468521633574D-01, & +1.6473243548212180D-01, & +6.4244094276971109D-01, & +1.0075305765438660D+00, & +3.2695517365467008D-01, & +3.4538816017831181D-01, & +8.4530783837131718D-01, & +2.6793917191534039D-01, & +4.1167148387782809D-01, & +7.3286777366837230D-01, & +2.0165584821582411D-01, & +8.3608281383074101D-01, & +9.7375794521953263D-01, & +4.8136607095928219D-01, & +5.9519264227958080D-01, & +6.4953705136764595D-01, & +6.7618762481481709D-01, & +2.3254758802226480D-01, & +4.5471549751211121D-01, & +1.9936248028938069D-01, & +3.3218193673422552D-01, & +3.7823189169112570D-01, & +9.9728131577419957D-02, & +9.8304494035037460D-01, & +7.5610809968448423D-01, & +4.4297338640403672D-01, & +6.0516873235701607D-01, & +1.1732795506024030D+00, & +7.1957244803166864D-01, & +5.0355240691445868D-01, & +8.9668048897477137D-01, & +3.0589803950585209D-01, & +6.5888323539286620D-01, & +3.0146344334154529D-01, & +1.5056721102744461D-01, & +1.2894222375675779D+00, & +6.1246453109936005D-01, & +7.5833643057994404D-01, & +9.7842114980976291D-01, & +4.9778147794615712D-01, & +9.9938135774918690D-01, & +2.8414688478625982D-01, & +2.5673655077691432D-01, & +9.2575397942057647D-01, & +5.5092683856146663D-01, & +5.2313556054509897D-05, & +6.5897402564536967D-01, & +2.1178692213810329D-05, & +7.3492248268320243D-05, & +0.0000000000000000D+00, & +0.0000000000000000D+00/) +i0 = 1 +n0 = 21 +pp = 0 +dmin = -0.0000000000000000D+00 +sigma = 0.0000000000000000D+00 +desig = 0.0000000000000000D+00 +qmax = 2.1637041623952107D+00 +nFail = 0 +iter = 2 +nDiv = 40 +ttype = 0 +dmin1 = 0.0000000000000000D+00 +dmin2 = 0.0000000000000000D+00 +dn = 0.0000000000000000D+00 +dn1 = 0.0000000000000000D+00 +dn2 = 0.0000000000000000D+00 +g = 0.0000000000000000D+00 +tau = 0.0000000000000000D+00 + +print *, "Starting Dlasq3" +open(unit = 4, file = "gen4tests.txt") +open(unit = 5, file = "gen5tests.txt") +call Dlasq3(i0, n0, z, pp, dmin, sigma, desig, qmax, nFail, iter, nDiv, ieee, ttype, dmin1, dmin2, dn, dn1, dn2, g, tau) +close(4) +close(5) + +print *, "Done calling dlasq3" +print *, Z(1:n) + +print *, I0, N0, PP +print *, DMIN, DESIG, SIGMA, QMAX +print *, NFAIL, ITER, NDIV, TTYPE +print *, DMIN1, DMIN2, DN, DN1, DN2, G, TAU + +end \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq4.f90 b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq4.f90 new file mode 100644 index 00000000..3c84983a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/testdlasq4.f90 @@ -0,0 +1,435 @@ +program testdlasq4 +implicit none + +! Dlasq4 tests +integer :: i0, n0, pp, ttype, iter, nDiv, n, n0in +real(kind=8), dimension(401) :: z +real(kind=8) :: dmin, desig, qmax, dmin1, dmin2, dn, dn1, dn2, g, tau, sigma +logical :: ieee + +z(1:401) = (/2.9266499599402414D+02, & +2.9276699640004830D+02, & +2.9210200041216615D+02, & +2.9171973344922628D+02, & +2.9254120660184350D+02, & +2.9246923723528141D+02, & +2.8739845025761718D+02, & +2.8713781898215319D+02, & +2.9216230331620721D+02, & +2.9216609319427272D+02, & +2.9037912623973870D+02, & +2.9019341222762625D+02, & +2.9184732870824223D+02, & +2.9211597271231784D+02, & +2.9133173969911888D+02, & +2.9116703928303986D+02, & +2.9158395177813247D+02, & +2.9142053084921997D+02, & +2.8936184155474774D+02, & +2.9014388604362898D+02, & +2.9216722380092682D+02, & +2.9216917065163557D+02, & +2.9033857172870131D+02, & +2.9017428768626024D+02, & +2.9187084534700494D+02, & +2.9185392666684271D+02, & +2.8851014988393416D+02, & +2.8849290783118727D+02, & +2.9182506564169046D+02, & +2.9184679532940385D+02, & +2.9022222656964715D+02, & +2.9051820223150668D+02, & +2.9219746119018231D+02, & +2.9219997046052623D+02, & +2.9076912988009974D+02, & +2.9110108536012547D+02, & +2.9226281758828725D+02, & +2.9246883105892533D+02, & +2.9221612201279271D+02, & +2.9059157967819368D+02, & +2.9112833071623868D+02, & +2.9210680427275844D+02, & +2.9199887004058536D+02, & +2.9151030826460186D+02, & +2.9154564759046622D+02, & +2.9212462005167004D+02, & +2.9212108612522559D+02, & +2.9225720737270348D+02, & +2.9226471402909704D+02, & +2.9186949422820902D+02, & +2.9179442772569342D+02, & +2.9025839700680774D+02, & +2.9028281327393216D+02, & +2.9168280284451140D+02, & +2.9168036127921908D+02, & +2.9115346030764749D+02, & +2.9115401102000044D+02, & +2.9212282665919003D+02, & +2.9212277159409672D+02, & +2.9212554020600300D+02, & +2.9212559651286460D+02, & +2.9050907549403615D+02, & +2.9050344542208029D+02, & +2.9211004769628386D+02, & +2.9211127836880860D+02, & +2.9159257985266015D+02, & +2.9158027318883302D+02, & +2.9042716308833894D+02, & +2.9043622253245718D+02, & +2.9134221002346220D+02, & +2.9134130414047053D+02, & +2.9193179671375327D+02, & +2.9193426987096007D+02, & +2.9145366956406895D+02, & +2.9145119646828226D+02, & +2.9144876630819033D+02, & +2.9145122608379586D+02, & +2.9058395601500280D+02, & +2.9055935887314877D+02, & +2.9123982459393329D+02, & +2.9125037059550806D+02, & +2.9111624624209884D+02, & +2.9110570030194424D+02, & +2.9250004994137356D+02, & +2.9254994096967755D+02, & +2.9166071282413282D+02, & +2.9116180260251298D+02, & +2.8862845048087325D+02, & +2.8925662460652461D+02, & +2.9012609983518610D+02, & +2.9010672249354360D+02, & +2.9142999275190090D+02, & +2.9150806548221971D+02, & +2.9078477842534176D+02, & +2.8840517363552317D+02, & +2.8946267131307206D+02, & +2.9189614533792309D+02, & +2.9232617409967031D+02, & +2.9223702224333306D+02, & +2.9149978725880743D+02, & +2.9168777367421643D+02, & +2.9213296087125275D+02, & +2.9211416223585388D+02, & +2.9151431726536367D+02, & +2.9159900781717892D+02, & +2.9215362494632291D+02, & +2.9214515589728342D+02, & +2.9229900293632022D+02, & +2.9231644811476662D+02, & +2.9119079594655176D+02, & +2.9016344223508082D+02, & +2.9040052826233938D+02, & +2.9146756071890462D+02, & +2.9216592215429023D+02, & +2.9212317137116514D+02, & +2.9220217331561315D+02, & +2.9227234439098311D+02, & +2.9210931773273273D+02, & +2.9139146663504778D+02, & +2.9047426145779627D+02, & +2.9113243832972501D+02, & +2.9163901100086372D+02, & +2.9155399887833846D+02, & +2.9145039523229758D+02, & +2.9151950918932886D+02, & +2.9116352441156198D+02, & +2.9094410515950784D+02, & +2.9056083843332891D+02, & +2.9097140423254604D+02, & +2.9185385310744653D+02, & +2.9181279658894493D+02, & +2.9031697123096876D+02, & +2.9033298229128292D+02, & +2.9212507489852788D+02, & +2.9212491479406674D+02, & +2.9123248207180859D+02, & +2.9123278004625678D+02, & +2.9210890357464513D+02, & +2.9210887378334229D+02, & +2.9240010366769212D+02, & +2.9240021314868147D+02, & +2.9212046105624000D+02, & +2.9212035158139264D+02, & +2.9215242607939217D+02, & +2.9215256473001551D+02, & +2.9086373488934720D+02, & +2.9084987044121846D+02, & +2.9162085042968522D+02, & +2.9163097873649599D+02, & +2.9113228736441005D+02, & +2.9112215911901944D+02, & +2.9210393504686402D+02, & +2.9211255232953414D+02, & +2.9191445519642213D+02, & +2.9182828243114074D+02, & +2.9127013482394887D+02, & +2.9129823908392501D+02, & +2.9220880435635905D+02, & +2.9220599393650343D+02, & +2.9144676491963560D+02, & +2.9145286023012017D+02, & +2.9148058174349006D+02, & +2.9147448649442555D+02, & +2.9186619188590822D+02, & +2.9187731897876392D+02, & +2.9151148084374620D+02, & +2.9150035381231066D+02, & +2.9224292392669071D+02, & +2.9224832614828313D+02, & +2.9140236136264468D+02, & +2.9134833920814032D+02, & +2.9241531971951883D+02, & +2.9247972954055604D+02, & +2.9164613863843044D+02, & +2.8920404894780614D+02, & +2.8913485112658549D+02, & +2.9142701775363003D+02, & +2.9213449277295280D+02, & +2.9191925854858397D+02, & +2.9217029610406047D+02, & +2.9224915292105180D+02, & +2.9220325626287905D+02, & +2.9212439945202976D+02, & +2.9057154227612733D+02, & +2.9093384291672965D+02, & +2.9183595231931184D+02, & +2.9179972231667176D+02, & +2.9133916987034183D+02, & +2.9135453536038978D+02, & +2.9047085843212886D+02, & +2.9031720414585078D+02, & +2.9113106705127024D+02, & +2.9119455617800747D+02, & +2.9230127009862616D+02, & +2.9229492119209442D+02, & +2.9098170102485551D+02, & +2.9110028345622749D+02, & +2.9215236246918653D+02, & +2.9215215113995436D+02, & +2.9124650182241129D+02, & +2.9124684419934567D+02, & +2.9216244260160767D+02, & +2.9216240837005626D+02, & +2.9314769094184447D+02, & +2.9314772207133655D+02, & +2.9212215646682506D+02, & +2.9212184517804621D+02, & +2.9224739389310008D+02, & +2.9224802593241526D+02, & +2.8978611958992855D+02, & +2.8915408641678846D+02, & +2.9118533307571403D+02, & +2.9194553410039072D+02, & +2.9244688594134544D+02, & +2.9237086584501975D+02, & +2.9189894464487475D+02, & +2.9210832103555418D+02, & +2.9227685116407457D+02, & +2.9225842459914986D+02, & +2.9224821267514392D+02, & +2.9226591109467802D+02, & +2.9158625025645608D+02, & +2.9140926612253548D+02, & +2.9125298964526195D+02, & +2.9136239316241648D+02, & +2.9182040805585694D+02, & +2.9171100460012258D+02, & +2.9126693393315793D+02, & +2.9130800749967943D+02, & +2.9084722625682167D+02, & +2.9043649120580767D+02, & +2.9153791610078673D+02, & +2.9210440912405335D+02, & +2.9188686486416555D+02, & +2.9138068978583891D+02, & +2.9158124399039616D+02, & +2.9213540811751852D+02, & +2.9211624446790427D+02, & +2.9138960755567365D+02, & +2.9060415959100914D+02, & +2.9118025885063923D+02, & +2.9132902926505932D+02, & +2.9120918643494110D+02, & +2.9222955158764825D+02, & +2.9236106160611405D+02, & +2.9219941546106151D+02, & +2.9167905448737707D+02, & +2.8956733560159137D+02, & +2.9016660738228080D+02, & +2.9069372888915495D+02, & +2.9058385568123452D+02, & +2.9219861470697771D+02, & +2.9223599112669444D+02, & +2.9150234673408067D+02, & +2.9112858259833354D+02, & +2.9011809831967531D+02, & +2.9046138673473865D+02, & +2.9176526297220903D+02, & +2.9173093419212285D+02, & +2.9150067445343569D+02, & +2.9152418894132262D+02, & +2.9197021328944544D+02, & +2.9194669886297868D+02, & +2.9168012546172463D+02, & +2.9169701864791432D+02, & +2.9061916960844030D+02, & +2.9045023836074438D+02, & +2.9212529304266053D+02, & +2.9217230349727680D+02, & +2.9156357220873417D+02, & +2.9093467723991887D+02, & +2.9015918793416472D+02, & +2.9095983823965622D+02, & +2.9124303667219704D+02, & +2.9116297170306802D+02, & +2.9162557939634507D+02, & +2.9193291492830070D+02, & +2.9138731414547760D+02, & +2.9079978674942083D+02, & +2.9159254111122891D+02, & +2.9228695093326087D+02, & +2.9225423965335352D+02, & +2.9126542837357596D+02, & +2.9173807466948557D+02, & +2.9270696227984581D+02, & +2.9274075480094893D+02, & +2.9210759999419366D+02, & +2.9091701924155882D+02, & +2.9163130710260498D+02, & +2.9157158980248664D+02, & +2.9031984685457667D+02, & +2.8939239820067894D+02, & +2.9070124438246870D+02, & +2.9196350995833507D+02, & +2.9189730956351508D+02, & +2.9047434516138509D+02, & +2.9050934070611282D+02, & +2.9179387236503283D+02, & +2.9179037287198020D+02, & +2.9197909575321057D+02, & +2.9198343084479546D+02, & +2.9146450345905629D+02, & +2.9146016842889151D+02, & +2.9233889755268928D+02, & +2.9234209014701219D+02, & +2.9032302536354865D+02, & +2.8837665454569191D+02, & +2.8923259893670223D+02, & +2.9119948081590582D+02, & +2.9158422265927129D+02, & +2.9138706789415261D+02, & +2.9131767302238063D+02, & +2.9147948119882238D+02, & +2.9186937598758146D+02, & +2.9170756787255982D+02, & +2.9181460198203825D+02, & +2.9210008868832023D+02, & +2.9132088639794199D+02, & +2.9113460155819826D+02, & +2.9159448593680958D+02, & +2.9214172380575934D+02, & +2.9182660907964311D+02, & +2.8938570202792107D+02, & +2.8829979954353007D+02, & +2.9064250900128923D+02, & +2.9110347860364448D+02, & +2.9039527564479215D+02, & +2.9152783923893156D+02, & +2.9213818222324863D+02, & +2.9211881276563861D+02, & +2.9133414472425187D+02, & +2.9125375097531855D+02, & +2.9190226937530139D+02, & +2.9164903795105636D+02, & +2.8851961249369930D+02, & +2.8835729910731652D+02, & +2.9144629542849515D+02, & +2.9171485796658368D+02, & +2.9126891989861593D+02, & +2.9051052150188838D+02, & +2.9113570969073521D+02, & +2.9141652614094619D+02, & +2.9133186866181995D+02, & +2.8912484642922516D+02, & +2.8915669391948876D+02, & +2.9117142770169869D+02, & +2.9117110928821620D+02, & +2.9183490795481288D+02, & +2.9183646161652371D+02, & +2.9254379194824975D+02, & +2.9254363658822064D+02, & +2.9192127768678108D+02, & +2.9192154096878102D+02, & +2.9151073810022524D+02, & +2.9151047487964541D+02, & +2.9013993357169915D+02, & +2.9014000572685774D+02, & +2.9145714571416084D+02, & +2.9145713856006512D+02, & +2.9196091751473017D+02, & +2.9196093255283131D+02, & +2.9195731369267685D+02, & +2.9195729871599588D+02, & +2.9149460806187619D+02, & +2.9149461579988633D+02, & +2.9034687539457741D+02, & +2.9034679862867739D+02, & +2.9010765498373922D+02, & +2.9010767881379803D+02, & +2.8967492890608241D+02, & +2.8967469674750663D+02, & +2.9215189060671338D+02, & +2.9215194287124120D+02, & +2.8956132995364590D+02, & +2.8950907156783751D+02, & +2.9210783379750950D+02, & +2.9211890340058585D+02, & +2.9139896954309916D+02, & +2.9128827357375536D+02, & +2.9190012628763964D+02, & +2.9212457714005234D+02, & +2.9221336158434212D+02, & +2.9217879707919576D+02, & +2.9127472708852724D+02, & +2.9132783649002283D+02, & +2.9227509889951233D+02, & +2.9226978796550475D+02, & +2.9142078378447616D+02, & +2.9142906715955786D+02, & +2.9017517054475991D+02, & +2.8992337408144391D+02, & +2.8477362931531121D+02, & +2.8514676291150971D+02, & +2.8393423954726200D+02, & +2.8313625395453965D+02, & +2.8449999402409759D+02, & +2.8534282615303522D+02, & +2.8523140662657408D+02, & +2.8739845025761718D+02, & +2.8713781898215319D+02, & +0.0000000000000000D+00/) +i0 = 1 +n0 = 100 +pp = 1 +n0in = 100 +dmin = 7.9798559272231942D+282 +dmin1 = 7.9798559272231942D+282 +dmin2 = 2.3215857579138407D+285 +dn = 2.3140662657409930D+284 +dn1 = 7.9798559272231942D+282 +dn2 = 8.2833136615500372D+288 +g = 2.5000000000000000D-01 +tau = 6.1420124051338430D+283 +ttype = -4 + +ieee = .True. + +print *, "Starting Dlasq4" + +call Dlasq4(i0, n0, z, pp, n0in, dmin, dmin1, dmin2, dn, dn1, dn2, tau, ttype, g) + +print *, "Done calling dlasq4" +print *, "tau = ", tau +print *, tau, ttype, g + +end \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/xerbla.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/xerbla.f new file mode 100644 index 00000000..3e93bc4e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dlasqtest/xerbla.f @@ -0,0 +1,99 @@ +*> \brief \b XERBLA +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download XERBLA + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE XERBLA( SRNAME, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER*(*) SRNAME +* INTEGER INFO +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> XERBLA is an error handler for the LAPACK routines. +*> It is called by an LAPACK routine if an input parameter has an +*> invalid value. A message is printed and execution stops. +*> +*> Installers may consider modifying the STOP statement in order to +*> call system-specific exception-handling facilities. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SRNAME +*> \verbatim +*> SRNAME is CHARACTER*(*) +*> The name of the routine which called XERBLA. +*> \endverbatim +*> +*> \param[in] INFO +*> \verbatim +*> INFO is INTEGER +*> The position of the invalid parameter in the parameter list +*> of the calling routine. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE XERBLA( SRNAME, INFO ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER*(*) SRNAME + INTEGER INFO +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC LEN_TRIM +* .. +* .. Executable Statements .. +* + WRITE( *, FMT = 9999 )SRNAME( 1:LEN_TRIM( SRNAME ) ), INFO +* + STOP +* + 9999 FORMAT( ' ** On entry to ', A, ' parameter number ', I2, ' had ', + $ 'an illegal value' ) +* +* End of XERBLA +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/Makefile b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/Makefile new file mode 100644 index 00000000..7d22727a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/Makefile @@ -0,0 +1,20 @@ +FC = gfortran +FFLAGS = -O2 + +targets = testdsterf +objects = disnan.o dlamch.o dlanst.o dlaisnan.o dlassq.o dlapy2.o lsame.o dlae2.o dlascl.o dlasrt.o dsterf.o xerbla.o + +default : $(targets) +.PHONY : default + +testdsterf : testdsterf.o $(objects) + +% : %.o + $(FC) $(FFLAGS) $^ -o $@ + +%.o : %.f90 + $(FC) $(FFLAGS) -c -o $@ $< + +clean : + rm -f *.o $(targets) *.txt +.PHONY : clean \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/disnan.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/disnan.f new file mode 100644 index 00000000..355b8279 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/disnan.f @@ -0,0 +1,80 @@ +*> \brief \b DISNAN tests input for NaN. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DISNAN + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* LOGICAL FUNCTION DISNAN( DIN ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION DIN +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DISNAN returns .TRUE. if its argument is NaN, and .FALSE. +*> otherwise. To be replaced by the Fortran 2003 intrinsic in the +*> future. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] DIN +*> \verbatim +*> DIN is DOUBLE PRECISION +*> Input to test for NaN. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + LOGICAL FUNCTION DISNAN( DIN ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION DIN +* .. +* +* ===================================================================== +* +* .. External Functions .. + LOGICAL DLAISNAN + EXTERNAL DLAISNAN +* .. +* .. Executable Statements .. + DISNAN = DLAISNAN(DIN,DIN) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlae2.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlae2.f new file mode 100644 index 00000000..302eeaa1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlae2.f @@ -0,0 +1,185 @@ +*> \brief \b DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAE2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLAE2( A, B, C, RT1, RT2 ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION A, B, C, RT1, RT2 +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAE2 computes the eigenvalues of a 2-by-2 symmetric matrix +*> [ A B ] +*> [ B C ]. +*> On return, RT1 is the eigenvalue of larger absolute value, and RT2 +*> is the eigenvalue of smaller absolute value. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION +*> The (1,1) element of the 2-by-2 matrix. +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is DOUBLE PRECISION +*> The (1,2) and (2,1) elements of the 2-by-2 matrix. +*> \endverbatim +*> +*> \param[in] C +*> \verbatim +*> C is DOUBLE PRECISION +*> The (2,2) element of the 2-by-2 matrix. +*> \endverbatim +*> +*> \param[out] RT1 +*> \verbatim +*> RT1 is DOUBLE PRECISION +*> The eigenvalue of larger absolute value. +*> \endverbatim +*> +*> \param[out] RT2 +*> \verbatim +*> RT2 is DOUBLE PRECISION +*> The eigenvalue of smaller absolute value. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> RT1 is accurate to a few ulps barring over/underflow. +*> +*> RT2 may be inaccurate if there is massive cancellation in the +*> determinant A*C-B*B; higher precision or correctly rounded or +*> correctly truncated arithmetic would be needed to compute RT2 +*> accurately in all cases. +*> +*> Overflow is possible only if RT1 is within a factor of 5 of overflow. +*> Underflow is harmless if the input data is 0 or exceeds +*> underflow_threshold / macheps. +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DLAE2( A, B, C, RT1, RT2 ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION A, B, C, RT1, RT2 +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) + DOUBLE PRECISION TWO + PARAMETER ( TWO = 2.0D0 ) + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION HALF + PARAMETER ( HALF = 0.5D0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION AB, ACMN, ACMX, ADF, DF, RT, SM, TB +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, SQRT +* .. +* .. Executable Statements .. +* +* Compute the eigenvalues +* + SM = A + C + DF = A - C + ADF = ABS( DF ) + TB = B + B + AB = ABS( TB ) + IF( ABS( A ).GT.ABS( C ) ) THEN + ACMX = A + ACMN = C + ELSE + ACMX = C + ACMN = A + END IF + IF( ADF.GT.AB ) THEN + RT = ADF*SQRT( ONE+( AB / ADF )**2 ) + ELSE IF( ADF.LT.AB ) THEN + RT = AB*SQRT( ONE+( ADF / AB )**2 ) + ELSE +* +* Includes case AB=ADF=0 +* + RT = AB*SQRT( TWO ) + END IF + IF( SM.LT.ZERO ) THEN + RT1 = HALF*( SM-RT ) +* +* Order of execution important. +* To get fully accurate smaller eigenvalue, +* next line needs to be executed in higher precision. +* + RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B + ELSE IF( SM.GT.ZERO ) THEN + RT1 = HALF*( SM+RT ) +* +* Order of execution important. +* To get fully accurate smaller eigenvalue, +* next line needs to be executed in higher precision. +* + RT2 = ( ACMX / RT1 )*ACMN - ( B / RT1 )*B + ELSE +* +* Includes case RT1 = RT2 = 0 +* + RT1 = HALF*RT + RT2 = -HALF*RT + END IF + RETURN +* +* End of DLAE2 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlaisnan.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlaisnan.f new file mode 100644 index 00000000..58595c5c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlaisnan.f @@ -0,0 +1,91 @@ +*> \brief \b DLAISNAN tests input for NaN by comparing two arguments for inequality. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAISNAN + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION DIN1, DIN2 +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> This routine is not for general use. It exists solely to avoid +*> over-optimization in DISNAN. +*> +*> DLAISNAN checks for NaNs by comparing its two arguments for +*> inequality. NaN is the only floating-point value where NaN != NaN +*> returns .TRUE. To check for NaNs, pass the same variable as both +*> arguments. +*> +*> A compiler must assume that the two arguments are +*> not the same variable, and the test will not be optimized away. +*> Interprocedural or whole-program optimization may delete this +*> test. The ISNAN functions will be replaced by the correct +*> Fortran 03 intrinsic once the intrinsic is widely available. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] DIN1 +*> \verbatim +*> DIN1 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] DIN2 +*> \verbatim +*> DIN2 is DOUBLE PRECISION +*> Two numbers to compare for inequality. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + LOGICAL FUNCTION DLAISNAN( DIN1, DIN2 ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION DIN1, DIN2 +* .. +* +* ===================================================================== +* +* .. Executable Statements .. + DLAISNAN = (DIN1.NE.DIN2) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlamch.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlamch.f new file mode 100644 index 00000000..25c2c8e6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlamch.f @@ -0,0 +1,193 @@ +*> \brief \b DLAMCH +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAMCH determines double precision machine parameters. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] CMACH +*> \verbatim +*> Specifies the value to be returned by DLAMCH: +*> = 'E' or 'e', DLAMCH := eps +*> = 'S' or 's , DLAMCH := sfmin +*> = 'B' or 'b', DLAMCH := base +*> = 'P' or 'p', DLAMCH := eps*base +*> = 'N' or 'n', DLAMCH := t +*> = 'R' or 'r', DLAMCH := rnd +*> = 'M' or 'm', DLAMCH := emin +*> = 'U' or 'u', DLAMCH := rmin +*> = 'L' or 'l', DLAMCH := emax +*> = 'O' or 'o', DLAMCH := rmax +*> where +*> eps = relative machine precision +*> sfmin = safe minimum, such that 1/sfmin does not overflow +*> base = base of the machine +*> prec = eps*base +*> t = number of (base) digits in the mantissa +*> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise +*> emin = minimum exponent before (gradual) underflow +*> rmin = underflow threshold - base**(emin-1) +*> emax = largest exponent before overflow +*> rmax = overflow threshold - (base**emax)*(1-eps) +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER CMACH +* .. +* +* .. Scalar Arguments .. + DOUBLE PRECISION A, B +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION RND, EPS, SFMIN, SMALL, RMACH +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT, + $ MINEXPONENT, RADIX, TINY +* .. +* .. Executable Statements .. +* +* +* Assume rounding, not chopping. Always. +* + RND = ONE +* + IF( ONE.EQ.RND ) THEN + EPS = EPSILON(ZERO) * 0.5 + ELSE + EPS = EPSILON(ZERO) + END IF +* + IF( LSAME( CMACH, 'E' ) ) THEN + RMACH = EPS + ELSE IF( LSAME( CMACH, 'S' ) ) THEN + SFMIN = TINY(ZERO) + SMALL = ONE / HUGE(ZERO) + IF( SMALL.GE.SFMIN ) THEN +* +* Use SMALL plus a bit, to avoid the possibility of rounding +* causing overflow when computing 1/sfmin. +* + SFMIN = SMALL*( ONE+EPS ) + END IF + RMACH = SFMIN + ELSE IF( LSAME( CMACH, 'B' ) ) THEN + RMACH = RADIX(ZERO) + ELSE IF( LSAME( CMACH, 'P' ) ) THEN + RMACH = EPS * RADIX(ZERO) + ELSE IF( LSAME( CMACH, 'N' ) ) THEN + RMACH = DIGITS(ZERO) + ELSE IF( LSAME( CMACH, 'R' ) ) THEN + RMACH = RND + ELSE IF( LSAME( CMACH, 'M' ) ) THEN + RMACH = MINEXPONENT(ZERO) + ELSE IF( LSAME( CMACH, 'U' ) ) THEN + RMACH = tiny(zero) + ELSE IF( LSAME( CMACH, 'L' ) ) THEN + RMACH = MAXEXPONENT(ZERO) + ELSE IF( LSAME( CMACH, 'O' ) ) THEN + RMACH = HUGE(ZERO) + ELSE + RMACH = ZERO + END IF +* + DLAMCH = RMACH + RETURN +* +* End of DLAMCH +* + END +************************************************************************ +*> \brief \b DLAMC3 +*> \details +*> \b Purpose: +*> \verbatim +*> DLAMC3 is intended to force A and B to be stored prior to doing +*> the addition of A and B , for use in situations where optimizers +*> might hold one of these in a register. +*> \endverbatim +*> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd.. +*> \date November 2011 +*> \ingroup auxOTHERauxiliary +*> +*> \param[in] A +*> \verbatim +*> A is a DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is a DOUBLE PRECISION +*> The values A and B. +*> \endverbatim +*> + DOUBLE PRECISION FUNCTION DLAMC3( A, B ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. +* November 2010 +* +* .. Scalar Arguments .. + DOUBLE PRECISION A, B +* .. +* ===================================================================== +* +* .. Executable Statements .. +* + DLAMC3 = A + B +* + RETURN +* +* End of DLAMC3 +* + END +* +************************************************************************ diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlanst.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlanst.f new file mode 100644 index 00000000..213b06ad --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlanst.f @@ -0,0 +1,186 @@ +*> \brief \b DLANST returns the value of the 1-norm, or the Frobenius norm, or the infinity norm, or the element of largest absolute value of a real symmetric tridiagonal matrix. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLANST + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DLANST( NORM, N, D, E ) +* +* .. Scalar Arguments .. +* CHARACTER NORM +* INTEGER N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION D( * ), E( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLANST returns the value of the one norm, or the Frobenius norm, or +*> the infinity norm, or the element of largest absolute value of a +*> real symmetric tridiagonal matrix A. +*> \endverbatim +*> +*> \return DLANST +*> \verbatim +*> +*> DLANST = ( max(abs(A(i,j))), NORM = 'M' or 'm' +*> ( +*> ( norm1(A), NORM = '1', 'O' or 'o' +*> ( +*> ( normI(A), NORM = 'I' or 'i' +*> ( +*> ( normF(A), NORM = 'F', 'f', 'E' or 'e' +*> +*> where norm1 denotes the one norm of a matrix (maximum column sum), +*> normI denotes the infinity norm of a matrix (maximum row sum) and +*> normF denotes the Frobenius norm of a matrix (square root of sum of +*> squares). Note that max(abs(A(i,j))) is not a consistent matrix norm. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] NORM +*> \verbatim +*> NORM is CHARACTER*1 +*> Specifies the value to be returned in DLANST as described +*> above. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. N >= 0. When N = 0, DLANST is +*> set to zero. +*> \endverbatim +*> +*> \param[in] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> The diagonal elements of A. +*> \endverbatim +*> +*> \param[in] E +*> \verbatim +*> E is DOUBLE PRECISION array, dimension (N-1) +*> The (n-1) sub-diagonal or super-diagonal elements of A. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + DOUBLE PRECISION FUNCTION DLANST( NORM, N, D, E ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + CHARACTER NORM + INTEGER N +* .. +* .. Array Arguments .. + DOUBLE PRECISION D( * ), E( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I + DOUBLE PRECISION ANORM, SCALE, SUM +* .. +* .. External Functions .. + LOGICAL LSAME, DISNAN + EXTERNAL LSAME, DISNAN +* .. +* .. External Subroutines .. + EXTERNAL DLASSQ +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, SQRT +* .. +* .. Executable Statements .. +* + IF( N.LE.0 ) THEN + ANORM = ZERO + ELSE IF( LSAME( NORM, 'M' ) ) THEN +* +* Find max(abs(A(i,j))). +* + ANORM = ABS( D( N ) ) + DO 10 I = 1, N - 1 + SUM = ABS( D( I ) ) + IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUM + SUM = ABS( E( I ) ) + IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUM + 10 CONTINUE + ELSE IF( LSAME( NORM, 'O' ) .OR. NORM.EQ.'1' .OR. + $ LSAME( NORM, 'I' ) ) THEN +* +* Find norm1(A). +* + IF( N.EQ.1 ) THEN + ANORM = ABS( D( 1 ) ) + ELSE + ANORM = ABS( D( 1 ) )+ABS( E( 1 ) ) + SUM = ABS( E( N-1 ) )+ABS( D( N ) ) + IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUM + DO 20 I = 2, N - 1 + SUM = ABS( D( I ) )+ABS( E( I ) )+ABS( E( I-1 ) ) + IF( ANORM .LT. SUM .OR. DISNAN( SUM ) ) ANORM = SUM + 20 CONTINUE + END IF + ELSE IF( ( LSAME( NORM, 'F' ) ) .OR. ( LSAME( NORM, 'E' ) ) ) THEN +* +* Find normF(A). +* + SCALE = ZERO + SUM = ONE + IF( N.GT.1 ) THEN + CALL DLASSQ( N-1, E, 1, SCALE, SUM ) + SUM = 2*SUM + END IF + CALL DLASSQ( N, D, 1, SCALE, SUM ) + ANORM = SCALE*SQRT( SUM ) + END IF +* + DLANST = ANORM + RETURN +* +* End of DLANST +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlapy2.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlapy2.f new file mode 100644 index 00000000..d43b0d5d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlapy2.f @@ -0,0 +1,104 @@ +*> \brief \b DLAPY2 returns sqrt(x2+y2). +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAPY2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DLAPY2( X, Y ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION X, Y +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary +*> overflow. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] X +*> \verbatim +*> X is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] Y +*> \verbatim +*> Y is DOUBLE PRECISION +*> X and Y specify the values x and y. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + DOUBLE PRECISION FUNCTION DLAPY2( X, Y ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION X, Y +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION W, XABS, YABS, Z +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* + XABS = ABS( X ) + YABS = ABS( Y ) + W = MAX( XABS, YABS ) + Z = MIN( XABS, YABS ) + IF( Z.EQ.ZERO ) THEN + DLAPY2 = W + ELSE + DLAPY2 = W*SQRT( ONE+( Z / W )**2 ) + END IF + RETURN +* +* End of DLAPY2 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlascl.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlascl.f new file mode 100644 index 00000000..9b9b33c0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlascl.f @@ -0,0 +1,364 @@ +*> \brief \b DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASCL + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER TYPE +* INTEGER INFO, KL, KU, LDA, M, N +* DOUBLE PRECISION CFROM, CTO +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASCL multiplies the M by N real matrix A by the real scalar +*> CTO/CFROM. This is done without over/underflow as long as the final +*> result CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that +*> A may be full, upper triangular, lower triangular, upper Hessenberg, +*> or banded. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] TYPE +*> \verbatim +*> TYPE is CHARACTER*1 +*> TYPE indices the storage type of the input matrix. +*> = 'G': A is a full matrix. +*> = 'L': A is a lower triangular matrix. +*> = 'U': A is an upper triangular matrix. +*> = 'H': A is an upper Hessenberg matrix. +*> = 'B': A is a symmetric band matrix with lower bandwidth KL +*> and upper bandwidth KU and with the only the lower +*> half stored. +*> = 'Q': A is a symmetric band matrix with lower bandwidth KL +*> and upper bandwidth KU and with the only the upper +*> half stored. +*> = 'Z': A is a band matrix with lower bandwidth KL and upper +*> bandwidth KU. See DGBTRF for storage details. +*> \endverbatim +*> +*> \param[in] KL +*> \verbatim +*> KL is INTEGER +*> The lower bandwidth of A. Referenced only if TYPE = 'B', +*> 'Q' or 'Z'. +*> \endverbatim +*> +*> \param[in] KU +*> \verbatim +*> KU is INTEGER +*> The upper bandwidth of A. Referenced only if TYPE = 'B', +*> 'Q' or 'Z'. +*> \endverbatim +*> +*> \param[in] CFROM +*> \verbatim +*> CFROM is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] CTO +*> \verbatim +*> CTO is DOUBLE PRECISION +*> +*> The matrix A is multiplied by CTO/CFROM. A(I,J) is computed +*> without over/underflow if the final result CTO*A(I,J)/CFROM +*> can be represented without over/underflow. CFROM must be +*> nonzero. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix A. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> The matrix to be multiplied by CTO/CFROM. See TYPE for the +*> storage type. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,M). +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> 0 - successful exit +*> <0 - if INFO = -i, the i-th argument had an illegal value. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE DLASCL( TYPE, KL, KU, CFROM, CTO, M, N, A, LDA, INFO ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + CHARACTER TYPE + INTEGER INFO, KL, KU, LDA, M, N + DOUBLE PRECISION CFROM, CTO +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + LOGICAL DONE + INTEGER I, ITYPE, J, K1, K2, K3, K4 + DOUBLE PRECISION BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM +* .. +* .. External Functions .. + LOGICAL LSAME, DISNAN + DOUBLE PRECISION DLAMCH + EXTERNAL LSAME, DLAMCH, DISNAN +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input arguments +* + INFO = 0 +* + IF( LSAME( TYPE, 'G' ) ) THEN + ITYPE = 0 + ELSE IF( LSAME( TYPE, 'L' ) ) THEN + ITYPE = 1 + ELSE IF( LSAME( TYPE, 'U' ) ) THEN + ITYPE = 2 + ELSE IF( LSAME( TYPE, 'H' ) ) THEN + ITYPE = 3 + ELSE IF( LSAME( TYPE, 'B' ) ) THEN + ITYPE = 4 + ELSE IF( LSAME( TYPE, 'Q' ) ) THEN + ITYPE = 5 + ELSE IF( LSAME( TYPE, 'Z' ) ) THEN + ITYPE = 6 + ELSE + ITYPE = -1 + END IF +* + IF( ITYPE.EQ.-1 ) THEN + INFO = -1 + ELSE IF( CFROM.EQ.ZERO .OR. DISNAN(CFROM) ) THEN + INFO = -4 + ELSE IF( DISNAN(CTO) ) THEN + INFO = -5 + ELSE IF( M.LT.0 ) THEN + INFO = -6 + ELSE IF( N.LT.0 .OR. ( ITYPE.EQ.4 .AND. N.NE.M ) .OR. + $ ( ITYPE.EQ.5 .AND. N.NE.M ) ) THEN + INFO = -7 + ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN + INFO = -9 + ELSE IF( ITYPE.GE.4 ) THEN + IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN + INFO = -2 + ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR. + $ ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) ) + $ THEN + INFO = -3 + ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR. + $ ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR. + $ ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN + INFO = -9 + END IF + END IF +* + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DLASCL', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.EQ.0 .OR. M.EQ.0 ) + $ RETURN +* +* Get machine parameters +* + SMLNUM = DLAMCH( 'S' ) + BIGNUM = ONE / SMLNUM +* + CFROMC = CFROM + CTOC = CTO +* + 10 CONTINUE + CFROM1 = CFROMC*SMLNUM + IF( CFROM1.EQ.CFROMC ) THEN +! CFROMC is an inf. Multiply by a correctly signed zero for +! finite CTOC, or a NaN if CTOC is infinite. + MUL = CTOC / CFROMC + DONE = .TRUE. + CTO1 = CTOC + ELSE + CTO1 = CTOC / BIGNUM + IF( CTO1.EQ.CTOC ) THEN +! CTOC is either 0 or an inf. In both cases, CTOC itself +! serves as the correct multiplication factor. + MUL = CTOC + DONE = .TRUE. + CFROMC = ONE + ELSE IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN + MUL = SMLNUM + DONE = .FALSE. + CFROMC = CFROM1 + ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN + MUL = BIGNUM + DONE = .FALSE. + CTOC = CTO1 + ELSE + MUL = CTOC / CFROMC + DONE = .TRUE. + END IF + END IF +* + IF( ITYPE.EQ.0 ) THEN +* +* Full matrix +* + DO 30 J = 1, N + DO 20 I = 1, M + A( I, J ) = A( I, J )*MUL + 20 CONTINUE + 30 CONTINUE +* + ELSE IF( ITYPE.EQ.1 ) THEN +* +* Lower triangular matrix +* + DO 50 J = 1, N + DO 40 I = J, M + A( I, J ) = A( I, J )*MUL + 40 CONTINUE + 50 CONTINUE +* + ELSE IF( ITYPE.EQ.2 ) THEN +* +* Upper triangular matrix +* + DO 70 J = 1, N + DO 60 I = 1, MIN( J, M ) + A( I, J ) = A( I, J )*MUL + 60 CONTINUE + 70 CONTINUE +* + ELSE IF( ITYPE.EQ.3 ) THEN +* +* Upper Hessenberg matrix +* + DO 90 J = 1, N + DO 80 I = 1, MIN( J+1, M ) + A( I, J ) = A( I, J )*MUL + 80 CONTINUE + 90 CONTINUE +* + ELSE IF( ITYPE.EQ.4 ) THEN +* +* Lower half of a symmetric band matrix +* + K3 = KL + 1 + K4 = N + 1 + DO 110 J = 1, N + DO 100 I = 1, MIN( K3, K4-J ) + A( I, J ) = A( I, J )*MUL + 100 CONTINUE + 110 CONTINUE +* + ELSE IF( ITYPE.EQ.5 ) THEN +* +* Upper half of a symmetric band matrix +* + K1 = KU + 2 + K3 = KU + 1 + DO 130 J = 1, N + DO 120 I = MAX( K1-J, 1 ), K3 + A( I, J ) = A( I, J )*MUL + 120 CONTINUE + 130 CONTINUE +* + ELSE IF( ITYPE.EQ.6 ) THEN +* +* Band matrix +* + K1 = KL + KU + 2 + K2 = KL + 1 + K3 = 2*KL + KU + 1 + K4 = KL + KU + 1 + M + DO 150 J = 1, N + DO 140 I = MAX( K1-J, K2 ), MIN( K3, K4-J ) + A( I, J ) = A( I, J )*MUL + 140 CONTINUE + 150 CONTINUE +* + END IF +* + IF( .NOT.DONE ) + $ GO TO 10 +* + RETURN +* +* End of DLASCL +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlasrt.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlasrt.f new file mode 100644 index 00000000..f5d0e6cd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlasrt.f @@ -0,0 +1,303 @@ +*> \brief \b DLASRT sorts numbers in increasing or decreasing order. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASRT + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASRT( ID, N, D, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER ID +* INTEGER INFO, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION D( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> Sort the numbers in D in increasing order (if ID = 'I') or +*> in decreasing order (if ID = 'D' ). +*> +*> Use Quick Sort, reverting to Insertion sort on arrays of +*> size <= 20. Dimension of STACK limits N to about 2**32. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] ID +*> \verbatim +*> ID is CHARACTER*1 +*> = 'I': sort D in increasing order; +*> = 'D': sort D in decreasing order. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The length of the array D. +*> \endverbatim +*> +*> \param[in,out] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> On entry, the array to be sorted. +*> On exit, D has been sorted into increasing order +*> (D(1) <= ... <= D(N) ) or into decreasing order +*> (D(1) >= ... >= D(N) ), depending on ID. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERcomputational +* +* ===================================================================== + SUBROUTINE DLASRT( ID, N, D, INFO ) +* +* -- LAPACK computational routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + CHARACTER ID + INTEGER INFO, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION D( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + INTEGER SELECT + PARAMETER ( SELECT = 20 ) +* .. +* .. Local Scalars .. + INTEGER DIR, ENDD, I, J, START, STKPNT + DOUBLE PRECISION D1, D2, D3, DMNMX, TMP +* .. +* .. Local Arrays .. + INTEGER STACK( 2, 32 ) +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Executable Statements .. +* +* Test the input paramters. +* + INFO = 0 + DIR = -1 + IF( LSAME( ID, 'D' ) ) THEN + DIR = 0 + ELSE IF( LSAME( ID, 'I' ) ) THEN + DIR = 1 + END IF + IF( DIR.EQ.-1 ) THEN + INFO = -1 + ELSE IF( N.LT.0 ) THEN + INFO = -2 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'DLASRT', -INFO ) + RETURN + END IF +* +* Quick return if possible +* + IF( N.LE.1 ) + $ RETURN +* + STKPNT = 1 + STACK( 1, 1 ) = 1 + STACK( 2, 1 ) = N + 10 CONTINUE + START = STACK( 1, STKPNT ) + ENDD = STACK( 2, STKPNT ) + STKPNT = STKPNT - 1 + IF( ENDD-START.LE.SELECT .AND. ENDD-START.GT.0 ) THEN +* +* Do Insertion sort on D( START:ENDD ) +* + IF( DIR.EQ.0 ) THEN +* +* Sort into decreasing order +* + DO 30 I = START + 1, ENDD + DO 20 J = I, START + 1, -1 + IF( D( J ).GT.D( J-1 ) ) THEN + DMNMX = D( J ) + D( J ) = D( J-1 ) + D( J-1 ) = DMNMX + ELSE + GO TO 30 + END IF + 20 CONTINUE + 30 CONTINUE +* + ELSE +* +* Sort into increasing order +* + DO 50 I = START + 1, ENDD + DO 40 J = I, START + 1, -1 + IF( D( J ).LT.D( J-1 ) ) THEN + DMNMX = D( J ) + D( J ) = D( J-1 ) + D( J-1 ) = DMNMX + ELSE + GO TO 50 + END IF + 40 CONTINUE + 50 CONTINUE +* + END IF +* + ELSE IF( ENDD-START.GT.SELECT ) THEN +* +* Partition D( START:ENDD ) and stack parts, largest one first +* +* Choose partition entry as median of 3 +* + D1 = D( START ) + D2 = D( ENDD ) + I = ( START+ENDD ) / 2 + D3 = D( I ) + IF( D1.LT.D2 ) THEN + IF( D3.LT.D1 ) THEN + DMNMX = D1 + ELSE IF( D3.LT.D2 ) THEN + DMNMX = D3 + ELSE + DMNMX = D2 + END IF + ELSE + IF( D3.LT.D2 ) THEN + DMNMX = D2 + ELSE IF( D3.LT.D1 ) THEN + DMNMX = D3 + ELSE + DMNMX = D1 + END IF + END IF +* + IF( DIR.EQ.0 ) THEN +* +* Sort into decreasing order +* + I = START - 1 + J = ENDD + 1 + 60 CONTINUE + 70 CONTINUE + J = J - 1 + IF( D( J ).LT.DMNMX ) + $ GO TO 70 + 80 CONTINUE + I = I + 1 + IF( D( I ).GT.DMNMX ) + $ GO TO 80 + IF( I.LT.J ) THEN + TMP = D( I ) + D( I ) = D( J ) + D( J ) = TMP + GO TO 60 + END IF + IF( J-START.GT.ENDD-J-1 ) THEN + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + ELSE + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + END IF + ELSE +* +* Sort into increasing order +* + I = START - 1 + J = ENDD + 1 + 90 CONTINUE + 100 CONTINUE + J = J - 1 + IF( D( J ).GT.DMNMX ) + $ GO TO 100 + 110 CONTINUE + I = I + 1 + IF( D( I ).LT.DMNMX ) + $ GO TO 110 + IF( I.LT.J ) THEN + TMP = D( I ) + D( I ) = D( J ) + D( J ) = TMP + GO TO 90 + END IF + IF( J-START.GT.ENDD-J-1 ) THEN + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + ELSE + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = J + 1 + STACK( 2, STKPNT ) = ENDD + STKPNT = STKPNT + 1 + STACK( 1, STKPNT ) = START + STACK( 2, STKPNT ) = J + END IF + END IF + END IF + IF( STKPNT.GT.0 ) + $ GO TO 10 + RETURN +* +* End of DLASRT +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlassq.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlassq.f new file mode 100644 index 00000000..c7c4087e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dlassq.f @@ -0,0 +1,155 @@ +*> \brief \b DLASSQ updates a sum of squares represented in scaled form. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASSQ + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASSQ( N, X, INCX, SCALE, SUMSQ ) +* +* .. Scalar Arguments .. +* INTEGER INCX, N +* DOUBLE PRECISION SCALE, SUMSQ +* .. +* .. Array Arguments .. +* DOUBLE PRECISION X( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASSQ returns the values scl and smsq such that +*> +*> ( scl**2 )*smsq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq, +*> +*> where x( i ) = X( 1 + ( i - 1 )*INCX ). The value of sumsq is +*> assumed to be non-negative and scl returns the value +*> +*> scl = max( scale, abs( x( i ) ) ). +*> +*> scale and sumsq must be supplied in SCALE and SUMSQ and +*> scl and smsq are overwritten on SCALE and SUMSQ respectively. +*> +*> The routine makes only one pass through the vector x. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of elements to be used from the vector X. +*> \endverbatim +*> +*> \param[in] X +*> \verbatim +*> X is DOUBLE PRECISION array, dimension (N) +*> The vector for which a scaled sum of squares is computed. +*> x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n. +*> \endverbatim +*> +*> \param[in] INCX +*> \verbatim +*> INCX is INTEGER +*> The increment between successive values of the vector X. +*> INCX > 0. +*> \endverbatim +*> +*> \param[in,out] SCALE +*> \verbatim +*> SCALE is DOUBLE PRECISION +*> On entry, the value scale in the equation above. +*> On exit, SCALE is overwritten with scl , the scaling factor +*> for the sum of squares. +*> \endverbatim +*> +*> \param[in,out] SUMSQ +*> \verbatim +*> SUMSQ is DOUBLE PRECISION +*> On entry, the value sumsq in the equation above. +*> On exit, SUMSQ is overwritten with smsq , the basic sum of +*> squares from which scl has been factored out. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE DLASSQ( N, X, INCX, SCALE, SUMSQ ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER INCX, N + DOUBLE PRECISION SCALE, SUMSQ +* .. +* .. Array Arguments .. + DOUBLE PRECISION X( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER IX + DOUBLE PRECISION ABSXI +* .. +* .. External Functions .. + LOGICAL DISNAN + EXTERNAL DISNAN +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS +* .. +* .. Executable Statements .. +* + IF( N.GT.0 ) THEN + DO 10 IX = 1, 1 + ( N-1 )*INCX, INCX + ABSXI = ABS( X( IX ) ) + IF( ABSXI.GT.ZERO.OR.DISNAN( ABSXI ) ) THEN + IF( SCALE.LT.ABSXI ) THEN + SUMSQ = 1 + SUMSQ*( SCALE / ABSXI )**2 + SCALE = ABSXI + ELSE + SUMSQ = SUMSQ + ( ABSXI / SCALE )**2 + END IF + END IF + 10 CONTINUE + END IF + RETURN +* +* End of DLASSQ +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dsterf.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dsterf.f new file mode 100644 index 00000000..43395cc7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/dsterf.f @@ -0,0 +1,448 @@ +*> \brief \b DSTERF +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DSTERF + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DSTERF( N, D, E, INFO ) +* +* .. Scalar Arguments .. +* INTEGER INFO, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION D( * ), E( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSTERF computes all eigenvalues of a symmetric tridiagonal matrix +*> using the Pal-Walker-Kahan variant of the QL or QR algorithm. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix. N >= 0. +*> \endverbatim +*> +*> \param[in,out] D +*> \verbatim +*> D is DOUBLE PRECISION array, dimension (N) +*> On entry, the n diagonal elements of the tridiagonal matrix. +*> On exit, if INFO = 0, the eigenvalues in ascending order. +*> \endverbatim +*> +*> \param[in,out] E +*> \verbatim +*> E is DOUBLE PRECISION array, dimension (N-1) +*> On entry, the (n-1) subdiagonal elements of the tridiagonal +*> matrix. +*> On exit, E has been destroyed. +*> \endverbatim +*> +*> \param[out] INFO +*> \verbatim +*> INFO is INTEGER +*> = 0: successful exit +*> < 0: if INFO = -i, the i-th argument had an illegal value +*> > 0: the algorithm failed to find all of the eigenvalues in +*> a total of 30*N iterations; if INFO = i, then i +*> elements of E have not converged to zero. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERcomputational +* +* ===================================================================== + SUBROUTINE DSTERF( N, D, E, INFO ) +* +* -- LAPACK computational routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + INTEGER INFO, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION D( * ), E( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE, TWO, THREE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0, + $ THREE = 3.0D0 ) + INTEGER MAXIT + PARAMETER ( MAXIT = 30 ) +* .. +* .. Local Scalars .. + INTEGER I, ISCALE, JTOT, L, L1, LEND, LENDSV, LSV, M, + $ NMAXIT + DOUBLE PRECISION ALPHA, ANORM, BB, C, EPS, EPS2, GAMMA, OLDC, + $ OLDGAM, P, R, RT1, RT2, RTE, S, SAFMAX, SAFMIN, + $ SIGMA, SSFMAX, SSFMIN, RMAX +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH, DLANST, DLAPY2 + EXTERNAL DLAMCH, DLANST, DLAPY2 +* .. +* .. External Subroutines .. + EXTERNAL DLAE2, DLASCL, DLASRT, XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, SIGN, SQRT +* .. +* .. Executable Statements .. +* +* Test the input parameters. +* + INFO = 0 +* +* Quick return if possible +* + IF( N.LT.0 ) THEN + INFO = -1 + CALL XERBLA( 'DSTERF', -INFO ) + RETURN + END IF + IF( N.LE.1 ) + $ RETURN +* +* Determine the unit roundoff for this environment. +* + EPS = DLAMCH( 'E' ) + EPS2 = EPS**2 + SAFMIN = DLAMCH( 'S' ) + SAFMAX = ONE / SAFMIN + SSFMAX = SQRT( SAFMAX ) / THREE + SSFMIN = SQRT( SAFMIN ) / EPS2 + RMAX = DLAMCH( 'O' ) +* +* Compute the eigenvalues of the tridiagonal matrix. +* + NMAXIT = N*MAXIT + SIGMA = ZERO + JTOT = 0 +* +* Determine where the matrix splits and choose QL or QR iteration +* for each block, according to whether top or bottom diagonal +* element is smaller. +* + L1 = 1 +* + 10 CONTINUE + print *, "l1 = ", l1 + IF( L1.GT.N ) THEN + print *, "going to 170" + GO TO 170 + end if + IF( L1.GT.1 ) + $ E( L1-1 ) = ZERO + DO 20 M = L1, N - 1 + IF( ABS( E( M ) ).LE.( SQRT( ABS( D( M ) ) )*SQRT( ABS( D( M+ + $ 1 ) ) ) )*EPS ) THEN + E( M ) = ZERO + GO TO 30 + END IF + 20 CONTINUE + M = N +* + 30 CONTINUE + print *, "30, d" + print *, d(1:n) + L = L1 + LSV = L + LEND = M + LENDSV = LEND + L1 = M + 1 + IF( LEND.EQ.L ) + $ GO TO 10 +* +* Scale submatrix in rows and columns L to LEND +* + ANORM = DLANST( 'M', LEND-L+1, D( L ), E( L ) ) + ISCALE = 0 + IF( ANORM.EQ.ZERO ) + $ GO TO 10 + IF( (ANORM.GT.SSFMAX) ) THEN + ISCALE = 1 + CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L+1, 1, D( L ), N, + $ INFO ) + CALL DLASCL( 'G', 0, 0, ANORM, SSFMAX, LEND-L, 1, E( L ), N, + $ INFO ) + ELSE IF( ANORM.LT.SSFMIN ) THEN + ISCALE = 2 + CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L+1, 1, D( L ), N, + $ INFO ) + CALL DLASCL( 'G', 0, 0, ANORM, SSFMIN, LEND-L, 1, E( L ), N, + $ INFO ) + END IF +* + DO 40 I = L, LEND - 1 + E( I ) = E( I )**2 + 40 CONTINUE +* +* Choose between QL and QR iteration +* + IF( ABS( D( LEND ) ).LT.ABS( D( L ) ) ) THEN + LEND = LSV + L = LENDSV + END IF +* + IF( LEND.GE.L ) THEN + print *, "ql, d" + print *, d(1:n) +* +* QL Iteration +* +* Look for small subdiagonal element. +* + 50 CONTINUE + IF( L.NE.LEND ) THEN + DO 60 M = L, LEND - 1 + IF( ABS( E( M ) ).LE.EPS2*ABS( D( M )*D( M+1 ) ) ) + $ GO TO 70 + 60 CONTINUE + END IF + M = LEND +* + 70 CONTINUE + IF( M.LT.LEND ) + $ E( M ) = ZERO + P = D( L ) + IF( M.EQ.L ) + $ GO TO 90 +* +* If remaining matrix is 2 by 2, use DLAE2 to compute its +* eigenvalues. +* + IF( M.EQ.L+1 ) THEN + RTE = SQRT( E( L ) ) + CALL DLAE2( D( L ), RTE, D( L+1 ), RT1, RT2 ) + D( L ) = RT1 + D( L+1 ) = RT2 + E( L ) = ZERO + L = L + 2 + IF( L.LE.LEND ) + $ GO TO 50 + GO TO 150 + END IF +* + IF( JTOT.EQ.NMAXIT ) + $ GO TO 150 + JTOT = JTOT + 1 +* +* Form shift. +* + RTE = SQRT( E( L ) ) + SIGMA = ( D( L+1 )-P ) / ( TWO*RTE ) + R = DLAPY2( SIGMA, ONE ) + SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) ) +* + C = ONE + S = ZERO + GAMMA = D( M ) - SIGMA + P = GAMMA*GAMMA +* +* Inner loop +* + print *, "inner loop d before" + print *, d(1:n) + + DO 80 I = M - 1, L, -1 + print *, "inner loop" + print *, "ei", e(i) + BB = E( I ) + R = P + BB + print *, "bb,p,r" + print *, bb,p,r + IF( I.NE.M-1 ) THEN + print *, s,r + E( I+1 ) = S*R + end if + OLDC = C + C = P / R + S = BB / R + OLDGAM = GAMMA + print *, "di", d(i) + ALPHA = D( I ) + GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM + print *,"og, a, ga", OLDGAM, ALPHA, GAMMA + D( I+1 ) = OLDGAM + ( ALPHA-GAMMA ) + IF( C.NE.ZERO ) THEN + P = ( GAMMA*GAMMA ) / C + ELSE + P = OLDC*BB + END IF + print *, "p, gamma = ", p,GAMMA + 80 CONTINUE +* + E( L ) = S*P + D( L ) = SIGMA + GAMMA + + print *, "inner loop d after" + print *, d(1:n) + GO TO 50 +* +* Eigenvalue found. +* + 90 CONTINUE + D( L ) = P +* + L = L + 1 + IF( L.LE.LEND ) + $ GO TO 50 + GO TO 150 +* + ELSE +* +* QR Iteration +* +* Look for small superdiagonal element. +* + 100 CONTINUE + DO 110 M = L, LEND + 1, -1 + IF( ABS( E( M-1 ) ).LE.EPS2*ABS( D( M )*D( M-1 ) ) ) + $ GO TO 120 + 110 CONTINUE + M = LEND +* + 120 CONTINUE + IF( M.GT.LEND ) + $ E( M-1 ) = ZERO + P = D( L ) + IF( M.EQ.L ) + $ GO TO 140 +* +* If remaining matrix is 2 by 2, use DLAE2 to compute its +* eigenvalues. +* + IF( M.EQ.L-1 ) THEN + RTE = SQRT( E( L-1 ) ) + CALL DLAE2( D( L ), RTE, D( L-1 ), RT1, RT2 ) + D( L ) = RT1 + D( L-1 ) = RT2 + E( L-1 ) = ZERO + L = L - 2 + IF( L.GE.LEND ) + $ GO TO 100 + GO TO 150 + END IF +* + IF( JTOT.EQ.NMAXIT ) + $ GO TO 150 + JTOT = JTOT + 1 +* +* Form shift. +* + RTE = SQRT( E( L-1 ) ) + SIGMA = ( D( L-1 )-P ) / ( TWO*RTE ) + R = DLAPY2( SIGMA, ONE ) + SIGMA = P - ( RTE / ( SIGMA+SIGN( R, SIGMA ) ) ) +* + C = ONE + S = ZERO + GAMMA = D( M ) - SIGMA + P = GAMMA*GAMMA +* +* Inner loop +* + DO 130 I = M, L - 1 + BB = E( I ) + R = P + BB + IF( I.NE.M ) + $ E( I-1 ) = S*R + OLDC = C + C = P / R + S = BB / R + OLDGAM = GAMMA + ALPHA = D( I+1 ) + GAMMA = C*( ALPHA-SIGMA ) - S*OLDGAM + D( I ) = OLDGAM + ( ALPHA-GAMMA ) + IF( C.NE.ZERO ) THEN + P = ( GAMMA*GAMMA ) / C + ELSE + P = OLDC*BB + END IF + 130 CONTINUE +* + E( L-1 ) = S*P + D( L ) = SIGMA + GAMMA + GO TO 100 +* +* Eigenvalue found. +* + 140 CONTINUE + D( L ) = P +* + L = L - 1 + IF( L.GE.LEND ) + $ GO TO 100 + GO TO 150 +* + END IF +* +* Undo scaling if necessary +* + 150 CONTINUE + IF( ISCALE.EQ.1 ) + $ CALL DLASCL( 'G', 0, 0, SSFMAX, ANORM, LENDSV-LSV+1, 1, + $ D( LSV ), N, INFO ) + IF( ISCALE.EQ.2 ) + $ CALL DLASCL( 'G', 0, 0, SSFMIN, ANORM, LENDSV-LSV+1, 1, + $ D( LSV ), N, INFO ) +* +* Check for no convergence to an eigenvalue after a total +* of N*MAXIT iterations. +* + IF( JTOT.LT.NMAXIT ) + $ GO TO 10 + DO 160 I = 1, N - 1 + IF( E( I ).NE.ZERO ) + $ INFO = INFO + 1 + 160 CONTINUE + GO TO 180 +* +* Sort eigenvalues in increasing order. +* + 170 CONTINUE + CALL DLASRT( 'I', N, D, INFO ) +* + 180 CONTINUE + RETURN +* +* End of DSTERF +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/lsame.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/lsame.f new file mode 100644 index 00000000..315304c3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/lsame.f @@ -0,0 +1,125 @@ +*> \brief \b LSAME +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* LOGICAL FUNCTION LSAME( CA, CB ) +* +* .. Scalar Arguments .. +* CHARACTER CA, CB +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> LSAME returns .TRUE. if CA is the same letter as CB regardless of +*> case. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] CA +*> \verbatim +*> \endverbatim +*> +*> \param[in] CB +*> \verbatim +*> CA and CB specify the single characters to be compared. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + LOGICAL FUNCTION LSAME( CA, CB ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER CA, CB +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC ICHAR +* .. +* .. Local Scalars .. + INTEGER INTA, INTB, ZCODE +* .. +* .. Executable Statements .. +* +* Test if the characters are equal +* + LSAME = CA.EQ.CB + IF( LSAME ) + $ RETURN +* +* Now test for equivalence if both characters are alphabetic. +* + ZCODE = ICHAR( 'Z' ) +* +* Use 'Z' rather than 'A' so that ASCII can be detected on Prime +* machines, on which ICHAR returns a value with bit 8 set. +* ICHAR('A') on Prime machines returns 193 which is the same as +* ICHAR('A') on an EBCDIC machine. +* + INTA = ICHAR( CA ) + INTB = ICHAR( CB ) +* + IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN +* +* ASCII is assumed - ZCODE is the ASCII code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32 + IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32 +* + ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN +* +* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.129 .AND. INTA.LE.137 .OR. + $ INTA.GE.145 .AND. INTA.LE.153 .OR. + $ INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64 + IF( INTB.GE.129 .AND. INTB.LE.137 .OR. + $ INTB.GE.145 .AND. INTB.LE.153 .OR. + $ INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64 +* + ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN +* +* ASCII is assumed, on Prime machines - ZCODE is the ASCII code +* plus 128 of either lower or upper case 'Z'. +* + IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32 + IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32 + END IF + LSAME = INTA.EQ.INTB +* +* RETURN +* +* End of LSAME +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/testdsterf.f90 b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/testdsterf.f90 new file mode 100644 index 00000000..8373f512 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/testdsterf.f90 @@ -0,0 +1,15 @@ +program testdsterf +implicit none +integer, parameter :: n = 4 +real(kind=8), dimension(n) :: d +real(kind=8), dimension(n-1) :: e +integer :: info,i + +d(1:4) = (/1D+00, 3D+00, 4D+00, 6D+00/) +e(1:3) = (/2D+00, 4D+00, 5D+00/) + +call dsterf(n,d,e,info) +DO i = 1, n + print *, d(i) +end do +end \ No newline at end of file diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/xerbla.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/xerbla.f new file mode 100644 index 00000000..3e93bc4e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/dsterftest/xerbla.f @@ -0,0 +1,99 @@ +*> \brief \b XERBLA +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download XERBLA + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE XERBLA( SRNAME, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER*(*) SRNAME +* INTEGER INFO +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> XERBLA is an error handler for the LAPACK routines. +*> It is called by an LAPACK routine if an input parameter has an +*> invalid value. A message is printed and execution stops. +*> +*> Installers may consider modifying the STOP statement in order to +*> call system-specific exception-handling facilities. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SRNAME +*> \verbatim +*> SRNAME is CHARACTER*(*) +*> The name of the routine which called XERBLA. +*> \endverbatim +*> +*> \param[in] INFO +*> \verbatim +*> INFO is INTEGER +*> The position of the invalid parameter in the parameter list +*> of the calling routine. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE XERBLA( SRNAME, INFO ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER*(*) SRNAME + INTEGER INFO +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC LEN_TRIM +* .. +* .. Executable Statements .. +* + WRITE( *, FMT = 9999 )SRNAME( 1:LEN_TRIM( SRNAME ) ), INFO +* + STOP +* + 9999 FORMAT( ' ** On entry to ', A, ' parameter number ', I2, ' had ', + $ 'an illegal value' ) +* +* End of XERBLA +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/daxpy.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/daxpy.f new file mode 100644 index 00000000..64a02d68 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/daxpy.f @@ -0,0 +1,115 @@ +*> \brief \b DAXPY +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION DA +* INTEGER INCX,INCY,N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION DX(*),DY(*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DAXPY constant times a vector plus a vector. +*> uses unrolled loops for increments equal to one. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup double_blas_level1 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> jack dongarra, linpack, 3/11/78. +*> modified 12/3/93, array(1) declarations changed to array(*) +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY) +* +* -- Reference BLAS level1 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + DOUBLE PRECISION DA + INTEGER INCX,INCY,N +* .. +* .. Array Arguments .. + DOUBLE PRECISION DX(*),DY(*) +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I,IX,IY,M,MP1 +* .. +* .. Intrinsic Functions .. + INTRINSIC MOD +* .. + IF (N.LE.0) RETURN + IF (DA.EQ.0.0d0) RETURN + IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN +* +* code for both increments equal to 1 +* +* +* clean-up loop +* + M = MOD(N,4) + IF (M.NE.0) THEN + DO I = 1,M + DY(I) = DY(I) + DA*DX(I) + END DO + END IF + IF (N.LT.4) RETURN + MP1 = M + 1 + DO I = MP1,N,4 + DY(I) = DY(I) + DA*DX(I) + DY(I+1) = DY(I+1) + DA*DX(I+1) + DY(I+2) = DY(I+2) + DA*DX(I+2) + DY(I+3) = DY(I+3) + DA*DX(I+3) + END DO + ELSE +* +* code for unequal increments or equal increments +* not equal to 1 +* + IX = 1 + IY = 1 + IF (INCX.LT.0) IX = (-N+1)*INCX + 1 + IF (INCY.LT.0) IY = (-N+1)*INCY + 1 + DO I = 1,N + DY(IY) = DY(IY) + DA*DX(IX) + IX = IX + INCX + IY = IY + INCY + END DO + END IF + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dcopy.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dcopy.f new file mode 100644 index 00000000..d9d5ac7a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dcopy.f @@ -0,0 +1,115 @@ +*> \brief \b DCOPY +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DCOPY(N,DX,INCX,DY,INCY) +* +* .. Scalar Arguments .. +* INTEGER INCX,INCY,N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION DX(*),DY(*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DCOPY copies a vector, x, to a vector, y. +*> uses unrolled loops for increments equal to one. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup double_blas_level1 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> jack dongarra, linpack, 3/11/78. +*> modified 12/3/93, array(1) declarations changed to array(*) +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DCOPY(N,DX,INCX,DY,INCY) +* +* -- Reference BLAS level1 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + INTEGER INCX,INCY,N +* .. +* .. Array Arguments .. + DOUBLE PRECISION DX(*),DY(*) +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I,IX,IY,M,MP1 +* .. +* .. Intrinsic Functions .. + INTRINSIC MOD +* .. + IF (N.LE.0) RETURN + IF (INCX.EQ.1 .AND. INCY.EQ.1) THEN +* +* code for both increments equal to 1 +* +* +* clean-up loop +* + M = MOD(N,7) + IF (M.NE.0) THEN + DO I = 1,M + DY(I) = DX(I) + END DO + IF (N.LT.7) RETURN + END IF + MP1 = M + 1 + DO I = MP1,N,7 + DY(I) = DX(I) + DY(I+1) = DX(I+1) + DY(I+2) = DX(I+2) + DY(I+3) = DX(I+3) + DY(I+4) = DX(I+4) + DY(I+5) = DX(I+5) + DY(I+6) = DX(I+6) + END DO + ELSE +* +* code for unequal increments or equal increments +* not equal to 1 +* + IX = 1 + IY = 1 + IF (INCX.LT.0) IX = (-N+1)*INCX + 1 + IF (INCY.LT.0) IY = (-N+1)*INCY + 1 + DO I = 1,N + DY(IY) = DX(IX) + IX = IX + INCX + IY = IY + INCY + END DO + END IF + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dgemm.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dgemm.f new file mode 100644 index 00000000..4bae243a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dgemm.f @@ -0,0 +1,384 @@ +*> \brief \b DGEMM +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION ALPHA,BETA +* INTEGER K,LDA,LDB,LDC,M,N +* CHARACTER TRANSA,TRANSB +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DGEMM performs one of the matrix-matrix operations +*> +*> C := alpha*op( A )*op( B ) + beta*C, +*> +*> where op( X ) is one of +*> +*> op( X ) = X or op( X ) = X**T, +*> +*> alpha and beta are scalars, and A, B and C are matrices, with op( A ) +*> an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] TRANSA +*> \verbatim +*> TRANSA is CHARACTER*1 +*> On entry, TRANSA specifies the form of op( A ) to be used in +*> the matrix multiplication as follows: +*> +*> TRANSA = 'N' or 'n', op( A ) = A. +*> +*> TRANSA = 'T' or 't', op( A ) = A**T. +*> +*> TRANSA = 'C' or 'c', op( A ) = A**T. +*> \endverbatim +*> +*> \param[in] TRANSB +*> \verbatim +*> TRANSB is CHARACTER*1 +*> On entry, TRANSB specifies the form of op( B ) to be used in +*> the matrix multiplication as follows: +*> +*> TRANSB = 'N' or 'n', op( B ) = B. +*> +*> TRANSB = 'T' or 't', op( B ) = B**T. +*> +*> TRANSB = 'C' or 'c', op( B ) = B**T. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> On entry, M specifies the number of rows of the matrix +*> op( A ) and of the matrix C. M must be at least zero. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> On entry, N specifies the number of columns of the matrix +*> op( B ) and the number of columns of the matrix C. N must be +*> at least zero. +*> \endverbatim +*> +*> \param[in] K +*> \verbatim +*> K is INTEGER +*> On entry, K specifies the number of columns of the matrix +*> op( A ) and the number of rows of the matrix op( B ). K must +*> be at least zero. +*> \endverbatim +*> +*> \param[in] ALPHA +*> \verbatim +*> ALPHA is DOUBLE PRECISION. +*> On entry, ALPHA specifies the scalar alpha. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array of DIMENSION ( LDA, ka ), where ka is +*> k when TRANSA = 'N' or 'n', and is m otherwise. +*> Before entry with TRANSA = 'N' or 'n', the leading m by k +*> part of the array A must contain the matrix A, otherwise +*> the leading k by m part of the array A must contain the +*> matrix A. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> On entry, LDA specifies the first dimension of A as declared +*> in the calling (sub) program. When TRANSA = 'N' or 'n' then +*> LDA must be at least max( 1, m ), otherwise LDA must be at +*> least max( 1, k ). +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is DOUBLE PRECISION array of DIMENSION ( LDB, kb ), where kb is +*> n when TRANSB = 'N' or 'n', and is k otherwise. +*> Before entry with TRANSB = 'N' or 'n', the leading k by n +*> part of the array B must contain the matrix B, otherwise +*> the leading n by k part of the array B must contain the +*> matrix B. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> On entry, LDB specifies the first dimension of B as declared +*> in the calling (sub) program. When TRANSB = 'N' or 'n' then +*> LDB must be at least max( 1, k ), otherwise LDB must be at +*> least max( 1, n ). +*> \endverbatim +*> +*> \param[in] BETA +*> \verbatim +*> BETA is DOUBLE PRECISION. +*> On entry, BETA specifies the scalar beta. When BETA is +*> supplied as zero then C need not be set on input. +*> \endverbatim +*> +*> \param[in,out] C +*> \verbatim +*> C is DOUBLE PRECISION array of DIMENSION ( LDC, n ). +*> Before entry, the leading m by n part of the array C must +*> contain the matrix C, except when beta is zero, in which +*> case C need not be set on entry. +*> On exit, the array C is overwritten by the m by n matrix +*> ( alpha*op( A )*op( B ) + beta*C ). +*> \endverbatim +*> +*> \param[in] LDC +*> \verbatim +*> LDC is INTEGER +*> On entry, LDC specifies the first dimension of C as declared +*> in the calling (sub) program. LDC must be at least +*> max( 1, m ). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2015 +* +*> \ingroup double_blas_level3 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Level 3 Blas routine. +*> +*> -- Written on 8-February-1989. +*> Jack Dongarra, Argonne National Laboratory. +*> Iain Duff, AERE Harwell. +*> Jeremy Du Croz, Numerical Algorithms Group Ltd. +*> Sven Hammarling, Numerical Algorithms Group Ltd. +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC) +* +* -- Reference BLAS level3 routine (version 3.6.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2015 +* +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA,BETA + INTEGER K,LDA,LDB,LDC,M,N + CHARACTER TRANSA,TRANSB +* .. +* .. Array Arguments .. + DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*) +* .. +* +* ===================================================================== +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I,INFO,J,L,NCOLA,NROWA,NROWB + LOGICAL NOTA,NOTB +* .. +* .. Parameters .. + DOUBLE PRECISION ONE,ZERO + PARAMETER (ONE=1.0D+0,ZERO=0.0D+0) +* .. +* +* Set NOTA and NOTB as true if A and B respectively are not +* transposed and set NROWA, NCOLA and NROWB as the number of rows +* and columns of A and the number of rows of B respectively. +* + NOTA = LSAME(TRANSA,'N') + NOTB = LSAME(TRANSB,'N') + IF (NOTA) THEN + NROWA = M + NCOLA = K + ELSE + NROWA = K + NCOLA = M + END IF + IF (NOTB) THEN + NROWB = K + ELSE + NROWB = N + END IF +* +* Test the input parameters. +* + INFO = 0 + IF ((.NOT.NOTA) .AND. (.NOT.LSAME(TRANSA,'C')) .AND. + + (.NOT.LSAME(TRANSA,'T'))) THEN + INFO = 1 + ELSE IF ((.NOT.NOTB) .AND. (.NOT.LSAME(TRANSB,'C')) .AND. + + (.NOT.LSAME(TRANSB,'T'))) THEN + INFO = 2 + ELSE IF (M.LT.0) THEN + INFO = 3 + ELSE IF (N.LT.0) THEN + INFO = 4 + ELSE IF (K.LT.0) THEN + INFO = 5 + ELSE IF (LDA.LT.MAX(1,NROWA)) THEN + INFO = 8 + ELSE IF (LDB.LT.MAX(1,NROWB)) THEN + INFO = 10 + ELSE IF (LDC.LT.MAX(1,M)) THEN + INFO = 13 + END IF + IF (INFO.NE.0) THEN + CALL XERBLA('DGEMM ',INFO) + RETURN + END IF +* +* Quick return if possible. +* + IF ((M.EQ.0) .OR. (N.EQ.0) .OR. + + (((ALPHA.EQ.ZERO).OR. (K.EQ.0)).AND. (BETA.EQ.ONE))) RETURN +* +* And if alpha.eq.zero. +* + IF (ALPHA.EQ.ZERO) THEN + IF (BETA.EQ.ZERO) THEN + DO 20 J = 1,N + DO 10 I = 1,M + C(I,J) = ZERO + 10 CONTINUE + 20 CONTINUE + ELSE + DO 40 J = 1,N + DO 30 I = 1,M + C(I,J) = BETA*C(I,J) + 30 CONTINUE + 40 CONTINUE + END IF + RETURN + END IF +* +* Start the operations. +* + IF (NOTB) THEN + IF (NOTA) THEN +* +* Form C := alpha*A*B + beta*C. +* + DO 90 J = 1,N + IF (BETA.EQ.ZERO) THEN + DO 50 I = 1,M + C(I,J) = ZERO + 50 CONTINUE + ELSE IF (BETA.NE.ONE) THEN + DO 60 I = 1,M + C(I,J) = BETA*C(I,J) + 60 CONTINUE + END IF + DO 80 L = 1,K + TEMP = ALPHA*B(L,J) + DO 70 I = 1,M + C(I,J) = C(I,J) + TEMP*A(I,L) + 70 CONTINUE + 80 CONTINUE + 90 CONTINUE + ELSE +* +* Form C := alpha*A**T*B + beta*C +* + DO 120 J = 1,N + DO 110 I = 1,M + TEMP = ZERO + DO 100 L = 1,K + TEMP = TEMP + A(L,I)*B(L,J) + 100 CONTINUE + IF (BETA.EQ.ZERO) THEN + C(I,J) = ALPHA*TEMP + ELSE + C(I,J) = ALPHA*TEMP + BETA*C(I,J) + END IF + 110 CONTINUE + 120 CONTINUE + END IF + ELSE + IF (NOTA) THEN +* +* Form C := alpha*A*B**T + beta*C +* + DO 170 J = 1,N + IF (BETA.EQ.ZERO) THEN + DO 130 I = 1,M + C(I,J) = ZERO + 130 CONTINUE + ELSE IF (BETA.NE.ONE) THEN + DO 140 I = 1,M + C(I,J) = BETA*C(I,J) + 140 CONTINUE + END IF + DO 160 L = 1,K + TEMP = ALPHA*B(J,L) + DO 150 I = 1,M + C(I,J) = C(I,J) + TEMP*A(I,L) + 150 CONTINUE + 160 CONTINUE + 170 CONTINUE + ELSE +* +* Form C := alpha*A**T*B**T + beta*C +* + DO 200 J = 1,N + DO 190 I = 1,M + TEMP = ZERO + DO 180 L = 1,K + TEMP = TEMP + A(L,I)*B(J,L) + 180 CONTINUE + IF (BETA.EQ.ZERO) THEN + C(I,J) = ALPHA*TEMP + ELSE + C(I,J) = ALPHA*TEMP + BETA*C(I,J) + END IF + 190 CONTINUE + 200 CONTINUE + END IF + END IF +* + RETURN +* +* End of DGEMM . +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dgemv.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dgemv.f new file mode 100644 index 00000000..e04cc07c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dgemv.f @@ -0,0 +1,330 @@ +*> \brief \b DGEMV +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION ALPHA,BETA +* INTEGER INCX,INCY,LDA,M,N +* CHARACTER TRANS +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A(LDA,*),X(*),Y(*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DGEMV performs one of the matrix-vector operations +*> +*> y := alpha*A*x + beta*y, or y := alpha*A**T*x + beta*y, +*> +*> where alpha and beta are scalars, x and y are vectors and A is an +*> m by n matrix. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] TRANS +*> \verbatim +*> TRANS is CHARACTER*1 +*> On entry, TRANS specifies the operation to be performed as +*> follows: +*> +*> TRANS = 'N' or 'n' y := alpha*A*x + beta*y. +*> +*> TRANS = 'T' or 't' y := alpha*A**T*x + beta*y. +*> +*> TRANS = 'C' or 'c' y := alpha*A**T*x + beta*y. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> On entry, M specifies the number of rows of the matrix A. +*> M must be at least zero. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> On entry, N specifies the number of columns of the matrix A. +*> N must be at least zero. +*> \endverbatim +*> +*> \param[in] ALPHA +*> \verbatim +*> ALPHA is DOUBLE PRECISION. +*> On entry, ALPHA specifies the scalar alpha. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array of DIMENSION ( LDA, n ). +*> Before entry, the leading m by n part of the array A must +*> contain the matrix of coefficients. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> On entry, LDA specifies the first dimension of A as declared +*> in the calling (sub) program. LDA must be at least +*> max( 1, m ). +*> \endverbatim +*> +*> \param[in] X +*> \verbatim +*> X is DOUBLE PRECISION array of DIMENSION at least +*> ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n' +*> and at least +*> ( 1 + ( m - 1 )*abs( INCX ) ) otherwise. +*> Before entry, the incremented array X must contain the +*> vector x. +*> \endverbatim +*> +*> \param[in] INCX +*> \verbatim +*> INCX is INTEGER +*> On entry, INCX specifies the increment for the elements of +*> X. INCX must not be zero. +*> \endverbatim +*> +*> \param[in] BETA +*> \verbatim +*> BETA is DOUBLE PRECISION. +*> On entry, BETA specifies the scalar beta. When BETA is +*> supplied as zero then Y need not be set on input. +*> \endverbatim +*> +*> \param[in,out] Y +*> \verbatim +*> Y is DOUBLE PRECISION array of DIMENSION at least +*> ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n' +*> and at least +*> ( 1 + ( n - 1 )*abs( INCY ) ) otherwise. +*> Before entry with BETA non-zero, the incremented array Y +*> must contain the vector y. On exit, Y is overwritten by the +*> updated vector y. +*> \endverbatim +*> +*> \param[in] INCY +*> \verbatim +*> INCY is INTEGER +*> On entry, INCY specifies the increment for the elements of +*> Y. INCY must not be zero. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2015 +* +*> \ingroup double_blas_level2 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Level 2 Blas routine. +*> The vector and matrix arguments are not referenced when N = 0, or M = 0 +*> +*> -- Written on 22-October-1986. +*> Jack Dongarra, Argonne National Lab. +*> Jeremy Du Croz, Nag Central Office. +*> Sven Hammarling, Nag Central Office. +*> Richard Hanson, Sandia National Labs. +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DGEMV(TRANS,M,N,ALPHA,A,LDA,X,INCX,BETA,Y,INCY) +* +* -- Reference BLAS level2 routine (version 3.6.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2015 +* +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA,BETA + INTEGER INCX,INCY,LDA,M,N + CHARACTER TRANS +* .. +* .. Array Arguments .. + DOUBLE PRECISION A(LDA,*),X(*),Y(*) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE,ZERO + PARAMETER (ONE=1.0D+0,ZERO=0.0D+0) +* .. +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I,INFO,IX,IY,J,JX,JY,KX,KY,LENX,LENY +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* +* Test the input parameters. +* + INFO = 0 + IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND. + + .NOT.LSAME(TRANS,'C')) THEN + INFO = 1 + ELSE IF (M.LT.0) THEN + INFO = 2 + ELSE IF (N.LT.0) THEN + INFO = 3 + ELSE IF (LDA.LT.MAX(1,M)) THEN + INFO = 6 + ELSE IF (INCX.EQ.0) THEN + INFO = 8 + ELSE IF (INCY.EQ.0) THEN + INFO = 11 + END IF + IF (INFO.NE.0) THEN + CALL XERBLA('DGEMV ',INFO) + RETURN + END IF +* +* Quick return if possible. +* + IF ((M.EQ.0) .OR. (N.EQ.0) .OR. + + ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN +* +* Set LENX and LENY, the lengths of the vectors x and y, and set +* up the start points in X and Y. +* + IF (LSAME(TRANS,'N')) THEN + LENX = N + LENY = M + ELSE + LENX = M + LENY = N + END IF + IF (INCX.GT.0) THEN + KX = 1 + ELSE + KX = 1 - (LENX-1)*INCX + END IF + IF (INCY.GT.0) THEN + KY = 1 + ELSE + KY = 1 - (LENY-1)*INCY + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through A. +* +* First form y := beta*y. +* + IF (BETA.NE.ONE) THEN + IF (INCY.EQ.1) THEN + IF (BETA.EQ.ZERO) THEN + DO 10 I = 1,LENY + Y(I) = ZERO + 10 CONTINUE + ELSE + DO 20 I = 1,LENY + Y(I) = BETA*Y(I) + 20 CONTINUE + END IF + ELSE + IY = KY + IF (BETA.EQ.ZERO) THEN + DO 30 I = 1,LENY + Y(IY) = ZERO + IY = IY + INCY + 30 CONTINUE + ELSE + DO 40 I = 1,LENY + Y(IY) = BETA*Y(IY) + IY = IY + INCY + 40 CONTINUE + END IF + END IF + END IF + IF (ALPHA.EQ.ZERO) RETURN + IF (LSAME(TRANS,'N')) THEN +* +* Form y := alpha*A*x + y. +* + JX = KX + IF (INCY.EQ.1) THEN + DO 60 J = 1,N + TEMP = ALPHA*X(JX) + DO 50 I = 1,M + Y(I) = Y(I) + TEMP*A(I,J) + 50 CONTINUE + JX = JX + INCX + 60 CONTINUE + ELSE + DO 80 J = 1,N + TEMP = ALPHA*X(JX) + IY = KY + DO 70 I = 1,M + Y(IY) = Y(IY) + TEMP*A(I,J) + IY = IY + INCY + 70 CONTINUE + JX = JX + INCX + 80 CONTINUE + END IF + ELSE +* +* Form y := alpha*A**T*x + y. +* + JY = KY + IF (INCX.EQ.1) THEN + DO 100 J = 1,N + TEMP = ZERO + DO 90 I = 1,M + TEMP = TEMP + A(I,J)*X(I) + 90 CONTINUE + Y(JY) = Y(JY) + ALPHA*TEMP + JY = JY + INCY + 100 CONTINUE + ELSE + DO 120 J = 1,N + TEMP = ZERO + IX = KX + DO 110 I = 1,M + TEMP = TEMP + A(I,J)*X(IX) + IX = IX + INCX + 110 CONTINUE + Y(JY) = Y(JY) + ALPHA*TEMP + JY = JY + INCY + 120 CONTINUE + END IF + END IF +* + RETURN +* +* End of DGEMV . +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlabad.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlabad.f new file mode 100644 index 00000000..da412633 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlabad.f @@ -0,0 +1,105 @@ +*> \brief \b DLABAD +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLABAD + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLABAD( SMALL, LARGE ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION LARGE, SMALL +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLABAD takes as input the values computed by DLAMCH for underflow and +*> overflow, and returns the square root of each of these values if the +*> log of LARGE is sufficiently large. This subroutine is intended to +*> identify machines with a large exponent range, such as the Crays, and +*> redefine the underflow and overflow limits to be the square roots of +*> the values computed by DLAMCH. This subroutine is needed because +*> DLAMCH does not compensate for poor arithmetic in the upper half of +*> the exponent range, as is found on a Cray. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in,out] SMALL +*> \verbatim +*> SMALL is DOUBLE PRECISION +*> On entry, the underflow threshold as computed by DLAMCH. +*> On exit, if LOG10(LARGE) is sufficiently large, the square +*> root of SMALL, otherwise unchanged. +*> \endverbatim +*> +*> \param[in,out] LARGE +*> \verbatim +*> LARGE is DOUBLE PRECISION +*> On entry, the overflow threshold as computed by DLAMCH. +*> On exit, if LOG10(LARGE) is sufficiently large, the square +*> root of LARGE, otherwise unchanged. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE DLABAD( SMALL, LARGE ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + DOUBLE PRECISION LARGE, SMALL +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC LOG10, SQRT +* .. +* .. Executable Statements .. +* +* If it looks like we're on a Cray, take the square root of +* SMALL and LARGE to avoid overflow and underflow problems. +* +* IF( LOG10( LARGE ).GT.2000.D0 ) THEN +* SMALL = SQRT( SMALL ) +* LARGE = SQRT( LARGE ) +* END IF +* + RETURN +* +* End of DLABAD +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlacpy.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlacpy.f new file mode 100644 index 00000000..a9a23c94 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlacpy.f @@ -0,0 +1,156 @@ +*> \brief \b DLACPY copies all or part of one two-dimensional array to another. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLACPY + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER LDA, LDB, M, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLACPY copies all or part of a two-dimensional matrix A to another +*> matrix B. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> Specifies the part of the matrix A to be copied to B. +*> = 'U': Upper triangular part +*> = 'L': Lower triangular part +*> Otherwise: All of the matrix A +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix A. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> The m by n matrix A. If UPLO = 'U', only the upper triangle +*> or trapezoid is accessed; if UPLO = 'L', only the lower +*> triangle or trapezoid is accessed. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,M). +*> \endverbatim +*> +*> \param[out] B +*> \verbatim +*> B is DOUBLE PRECISION array, dimension (LDB,N) +*> On exit, B = A in the locations specified by UPLO. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> The leading dimension of the array B. LDB >= max(1,M). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE DLACPY( UPLO, M, N, A, LDA, B, LDB ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER LDA, LDB, M, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), B( LDB, * ) +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, J +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* + IF( LSAME( UPLO, 'U' ) ) THEN + DO 20 J = 1, N + DO 10 I = 1, MIN( J, M ) + B( I, J ) = A( I, J ) + 10 CONTINUE + 20 CONTINUE + ELSE IF( LSAME( UPLO, 'L' ) ) THEN + DO 40 J = 1, N + DO 30 I = J, M + B( I, J ) = A( I, J ) + 30 CONTINUE + 40 CONTINUE + ELSE + DO 60 J = 1, N + DO 50 I = 1, M + B( I, J ) = A( I, J ) + 50 CONTINUE + 60 CONTINUE + END IF + RETURN +* +* End of DLACPY +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlahr2.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlahr2.f new file mode 100644 index 00000000..9d15979c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlahr2.f @@ -0,0 +1,326 @@ +*> \brief \b DLAHR2 reduces the specified number of first columns of a general rectangular matrix A so that elements below the specified subdiagonal are zero, and returns auxiliary matrices which are needed to apply the transformation to the unreduced part of A. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAHR2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY ) +* +* .. Scalar Arguments .. +* INTEGER K, LDA, LDT, LDY, N, NB +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ), T( LDT, NB ), TAU( NB ), +* $ Y( LDY, NB ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAHR2 reduces the first NB columns of A real general n-BY-(n-k+1) +*> matrix A so that elements below the k-th subdiagonal are zero. The +*> reduction is performed by an orthogonal similarity transformation +*> Q**T * A * Q. The routine returns the matrices V and T which determine +*> Q as a block reflector I - V*T*V**T, and also the matrix Y = A * V * T. +*> +*> This is an auxiliary routine called by DGEHRD. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the matrix A. +*> \endverbatim +*> +*> \param[in] K +*> \verbatim +*> K is INTEGER +*> The offset for the reduction. Elements below the k-th +*> subdiagonal in the first NB columns are reduced to zero. +*> K < N. +*> \endverbatim +*> +*> \param[in] NB +*> \verbatim +*> NB is INTEGER +*> The number of columns to be reduced. +*> \endverbatim +*> +*> \param[in,out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N-K+1) +*> On entry, the n-by-(n-k+1) general matrix A. +*> On exit, the elements on and above the k-th subdiagonal in +*> the first NB columns are overwritten with the corresponding +*> elements of the reduced matrix; the elements below the k-th +*> subdiagonal, with the array TAU, represent the matrix Q as a +*> product of elementary reflectors. The other columns of A are +*> unchanged. See Further Details. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,N). +*> \endverbatim +*> +*> \param[out] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION array, dimension (NB) +*> The scalar factors of the elementary reflectors. See Further +*> Details. +*> \endverbatim +*> +*> \param[out] T +*> \verbatim +*> T is DOUBLE PRECISION array, dimension (LDT,NB) +*> The upper triangular matrix T. +*> \endverbatim +*> +*> \param[in] LDT +*> \verbatim +*> LDT is INTEGER +*> The leading dimension of the array T. LDT >= NB. +*> \endverbatim +*> +*> \param[out] Y +*> \verbatim +*> Y is DOUBLE PRECISION array, dimension (LDY,NB) +*> The n-by-nb matrix Y. +*> \endverbatim +*> +*> \param[in] LDY +*> \verbatim +*> LDY is INTEGER +*> The leading dimension of the array Y. LDY >= N. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup doubleOTHERauxiliary +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> The matrix Q is represented as a product of nb elementary reflectors +*> +*> Q = H(1) H(2) . . . H(nb). +*> +*> Each H(i) has the form +*> +*> H(i) = I - tau * v * v**T +*> +*> where tau is a real scalar, and v is a real vector with +*> v(1:i+k-1) = 0, v(i+k) = 1; v(i+k+1:n) is stored on exit in +*> A(i+k+1:n,i), and tau in TAU(i). +*> +*> The elements of the vectors v together form the (n-k+1)-by-nb matrix +*> V which is needed, with T and Y, to apply the transformation to the +*> unreduced part of the matrix, using an update of the form: +*> A := (I - V*T*V**T) * (A - Y*V**T). +*> +*> The contents of A on exit are illustrated by the following example +*> with n = 7, k = 3 and nb = 2: +*> +*> ( a a a a a ) +*> ( a a a a a ) +*> ( a a a a a ) +*> ( h h a a a ) +*> ( v1 h a a a ) +*> ( v1 v2 a a a ) +*> ( v1 v2 a a a ) +*> +*> where a denotes an element of the original matrix A, h denotes a +*> modified element of the upper Hessenberg matrix H, and vi denotes an +*> element of the vector defining H(i). +*> +*> This subroutine is a slight modification of LAPACK-3.0's DLAHRD +*> incorporating improvements proposed by Quintana-Orti and Van de +*> Gejin. Note that the entries of A(1:K,2:NB) differ from those +*> returned by the original LAPACK-3.0's DLAHRD routine. (This +*> subroutine is not backward compatible with LAPACK-3.0's DLAHRD.) +*> \endverbatim +* +*> \par References: +* ================ +*> +*> Gregorio Quintana-Orti and Robert van de Geijn, "Improving the +*> performance of reduction to Hessenberg form," ACM Transactions on +*> Mathematical Software, 32(2):180-194, June 2006. +*> +* ===================================================================== + SUBROUTINE DLAHR2( N, K, NB, A, LDA, TAU, T, LDT, Y, LDY ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER K, LDA, LDT, LDY, N, NB +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ), T( LDT, NB ), TAU( NB ), + $ Y( LDY, NB ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, + $ ONE = 1.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER I + DOUBLE PRECISION EI +* .. +* .. External Subroutines .. + EXTERNAL DAXPY, DCOPY, DGEMM, DGEMV, DLACPY, + $ DLARFG, DSCAL, DTRMM, DTRMV +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* +* Quick return if possible +* + IF( N.LE.1 ) + $ RETURN +* + DO 10 I = 1, NB + IF( I.GT.1 ) THEN +* +* Update A(K+1:N,I) +* +* Update I-th column of A - Y * V**T +* + CALL DGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, Y(K+1,1), LDY, + $ A( K+I-1, 1 ), LDA, ONE, A( K+1, I ), 1 ) +* +* Apply I - V * T**T * V**T to this column (call it b) from the +* left, using the last column of T as workspace +* +* Let V = ( V1 ) and b = ( b1 ) (first I-1 rows) +* ( V2 ) ( b2 ) +* +* where V1 is unit lower triangular +* +* w := V1**T * b1 +* + CALL DCOPY( I-1, A( K+1, I ), 1, T( 1, NB ), 1 ) + CALL DTRMV( 'Lower', 'Transpose', 'UNIT', + $ I-1, A( K+1, 1 ), + $ LDA, T( 1, NB ), 1 ) +* +* w := w + V2**T * b2 +* + CALL DGEMV( 'Transpose', N-K-I+1, I-1, + $ ONE, A( K+I, 1 ), + $ LDA, A( K+I, I ), 1, ONE, T( 1, NB ), 1 ) +* +* w := T**T * w +* + CALL DTRMV( 'Upper', 'Transpose', 'NON-UNIT', + $ I-1, T, LDT, + $ T( 1, NB ), 1 ) +* +* b2 := b2 - V2*w +* + CALL DGEMV( 'NO TRANSPOSE', N-K-I+1, I-1, -ONE, + $ A( K+I, 1 ), + $ LDA, T( 1, NB ), 1, ONE, A( K+I, I ), 1 ) +* +* b1 := b1 - V1*w +* + CALL DTRMV( 'Lower', 'NO TRANSPOSE', + $ 'UNIT', I-1, + $ A( K+1, 1 ), LDA, T( 1, NB ), 1 ) + CALL DAXPY( I-1, -ONE, T( 1, NB ), 1, A( K+1, I ), 1 ) +* + A( K+I-1, I-1 ) = EI + END IF +* +* Generate the elementary reflector H(I) to annihilate +* A(K+I+1:N,I) +* + CALL DLARFG( N-K-I+1, A( K+I, I ), A( MIN( K+I+1, N ), I ), 1, + $ TAU( I ) ) + EI = A( K+I, I ) + A( K+I, I ) = ONE +* +* Compute Y(K+1:N,I) +* + CALL DGEMV( 'NO TRANSPOSE', N-K, N-K-I+1, + $ ONE, A( K+1, I+1 ), + $ LDA, A( K+I, I ), 1, ZERO, Y( K+1, I ), 1 ) + CALL DGEMV( 'Transpose', N-K-I+1, I-1, + $ ONE, A( K+I, 1 ), LDA, + $ A( K+I, I ), 1, ZERO, T( 1, I ), 1 ) + CALL DGEMV( 'NO TRANSPOSE', N-K, I-1, -ONE, + $ Y( K+1, 1 ), LDY, + $ T( 1, I ), 1, ONE, Y( K+1, I ), 1 ) + CALL DSCAL( N-K, TAU( I ), Y( K+1, I ), 1 ) +* +* Compute T(1:I,I) +* + CALL DSCAL( I-1, -TAU( I ), T( 1, I ), 1 ) + CALL DTRMV( 'Upper', 'No Transpose', 'NON-UNIT', + $ I-1, T, LDT, + $ T( 1, I ), 1 ) + T( I, I ) = TAU( I ) +* + 10 CONTINUE + A( K+NB, NB ) = EI +* +* Compute Y(1:K,1:NB) +* + CALL DLACPY( 'ALL', K, NB, A( 1, 2 ), LDA, Y, LDY ) + CALL DTRMM( 'RIGHT', 'Lower', 'NO TRANSPOSE', + $ 'UNIT', K, NB, + $ ONE, A( K+1, 1 ), LDA, Y, LDY ) + IF( N.GT.K+NB ) + $ CALL DGEMM( 'NO TRANSPOSE', 'NO TRANSPOSE', K, + $ NB, N-K-NB, ONE, + $ A( 1, 2+NB ), LDA, A( K+1+NB, 1 ), LDA, ONE, Y, + $ LDY ) + CALL DTRMM( 'RIGHT', 'Upper', 'NO TRANSPOSE', + $ 'NON-UNIT', K, NB, + $ ONE, T, LDT, Y, LDY ) +* + RETURN +* +* End of DLAHR2 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlamch.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlamch.f new file mode 100644 index 00000000..22a16218 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlamch.f @@ -0,0 +1,189 @@ +*> \brief \b DLAMCH +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAMCH determines double precision machine parameters. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] CMACH +*> \verbatim +*> Specifies the value to be returned by DLAMCH: +*> = 'E' or 'e', DLAMCH := eps +*> = 'S' or 's , DLAMCH := sfmin +*> = 'B' or 'b', DLAMCH := base +*> = 'P' or 'p', DLAMCH := eps*base +*> = 'N' or 'n', DLAMCH := t +*> = 'R' or 'r', DLAMCH := rnd +*> = 'M' or 'm', DLAMCH := emin +*> = 'U' or 'u', DLAMCH := rmin +*> = 'L' or 'l', DLAMCH := emax +*> = 'O' or 'o', DLAMCH := rmax +*> where +*> eps = relative machine precision +*> sfmin = safe minimum, such that 1/sfmin does not overflow +*> base = base of the machine +*> prec = eps*base +*> t = number of (base) digits in the mantissa +*> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise +*> emin = minimum exponent before (gradual) underflow +*> rmin = underflow threshold - base**(emin-1) +*> emax = largest exponent before overflow +*> rmax = overflow threshold - (base**emax)*(1-eps) +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2015 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + DOUBLE PRECISION FUNCTION DLAMCH( CMACH ) +* +* -- LAPACK auxiliary routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2015 +* +* .. Scalar Arguments .. + CHARACTER CMACH +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION RND, EPS, SFMIN, SMALL, RMACH +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT, + $ MINEXPONENT, RADIX, TINY +* .. +* .. Executable Statements .. +* +* +* Assume rounding, not chopping. Always. +* + RND = ONE +* + IF( ONE.EQ.RND ) THEN + EPS = EPSILON(ZERO) * 0.5 + ELSE + EPS = EPSILON(ZERO) + END IF +* + IF( LSAME( CMACH, 'E' ) ) THEN + RMACH = EPS + ELSE IF( LSAME( CMACH, 'S' ) ) THEN + SFMIN = TINY(ZERO) + SMALL = ONE / HUGE(ZERO) + IF( SMALL.GE.SFMIN ) THEN +* +* Use SMALL plus a bit, to avoid the possibility of rounding +* causing overflow when computing 1/sfmin. +* + SFMIN = SMALL*( ONE+EPS ) + END IF + RMACH = SFMIN + ELSE IF( LSAME( CMACH, 'B' ) ) THEN + RMACH = RADIX(ZERO) + ELSE IF( LSAME( CMACH, 'P' ) ) THEN + RMACH = EPS * RADIX(ZERO) + ELSE IF( LSAME( CMACH, 'N' ) ) THEN + RMACH = DIGITS(ZERO) + ELSE IF( LSAME( CMACH, 'R' ) ) THEN + RMACH = RND + ELSE IF( LSAME( CMACH, 'M' ) ) THEN + RMACH = MINEXPONENT(ZERO) + ELSE IF( LSAME( CMACH, 'U' ) ) THEN + RMACH = tiny(zero) + ELSE IF( LSAME( CMACH, 'L' ) ) THEN + RMACH = MAXEXPONENT(ZERO) + ELSE IF( LSAME( CMACH, 'O' ) ) THEN + RMACH = HUGE(ZERO) + ELSE + RMACH = ZERO + END IF +* + DLAMCH = RMACH + RETURN +* +* End of DLAMCH +* + END +************************************************************************ +*> \brief \b DLAMC3 +*> \details +*> \b Purpose: +*> \verbatim +*> DLAMC3 is intended to force A and B to be stored prior to doing +*> the addition of A and B , for use in situations where optimizers +*> might hold one of these in a register. +*> \endverbatim +*> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd.. +*> \date November 2015 +*> \ingroup auxOTHERauxiliary +*> +*> \param[in] A +*> \verbatim +*> A is a DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] B +*> \verbatim +*> B is a DOUBLE PRECISION +*> The values A and B. +*> \endverbatim +*> + DOUBLE PRECISION FUNCTION DLAMC3( A, B ) +* +* -- LAPACK auxiliary routine (version 3.6.0) -- +* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. +* November 2010 +* +* .. Scalar Arguments .. + DOUBLE PRECISION A, B +* .. +* ===================================================================== +* +* .. Executable Statements .. +* + DLAMC3 = A + B +* + RETURN +* +* End of DLAMC3 +* + END +* +************************************************************************ diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlapy2.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlapy2.f new file mode 100644 index 00000000..d43b0d5d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlapy2.f @@ -0,0 +1,104 @@ +*> \brief \b DLAPY2 returns sqrt(x2+y2). +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAPY2 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DLAPY2( X, Y ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION X, Y +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary +*> overflow. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] X +*> \verbatim +*> X is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] Y +*> \verbatim +*> Y is DOUBLE PRECISION +*> X and Y specify the values x and y. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + DOUBLE PRECISION FUNCTION DLAPY2( X, Y ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION X, Y +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION W, XABS, YABS, Z +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, MAX, MIN, SQRT +* .. +* .. Executable Statements .. +* + XABS = ABS( X ) + YABS = ABS( Y ) + W = MAX( XABS, YABS ) + Z = MIN( XABS, YABS ) + IF( Z.EQ.ZERO ) THEN + DLAPY2 = W + ELSE + DLAPY2 = W*SQRT( ONE+( Z / W )**2 ) + END IF + RETURN +* +* End of DLAPY2 +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaqr1.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaqr1.f new file mode 100644 index 00000000..df4fb68b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaqr1.f @@ -0,0 +1,179 @@ +*> \brief \b DLAQR1 sets a scalar multiple of the first column of the product of 2-by-2 or 3-by-3 matrix H and specified shifts. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAQR1 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLAQR1( N, H, LDH, SR1, SI1, SR2, SI2, V ) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION SI1, SI2, SR1, SR2 +* INTEGER LDH, N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION H( LDH, * ), V( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> Given a 2-by-2 or 3-by-3 matrix H, DLAQR1 sets v to a +*> scalar multiple of the first column of the product +*> +*> (*) K = (H - (sr1 + i*si1)*I)*(H - (sr2 + i*si2)*I) +*> +*> scaling to avoid overflows and most underflows. It +*> is assumed that either +*> +*> 1) sr1 = sr2 and si1 = -si2 +*> or +*> 2) si1 = si2 = 0. +*> +*> This is useful for starting double implicit shift bulges +*> in the QR algorithm. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] N +*> \verbatim +*> N is integer +*> Order of the matrix H. N must be either 2 or 3. +*> \endverbatim +*> +*> \param[in] H +*> \verbatim +*> H is DOUBLE PRECISION array of dimension (LDH,N) +*> The 2-by-2 or 3-by-3 matrix H in (*). +*> \endverbatim +*> +*> \param[in] LDH +*> \verbatim +*> LDH is integer +*> The leading dimension of H as declared in +*> the calling procedure. LDH.GE.N +*> \endverbatim +*> +*> \param[in] SR1 +*> \verbatim +*> SR1 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] SI1 +*> \verbatim +*> SI1 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] SR2 +*> \verbatim +*> SR2 is DOUBLE PRECISION +*> \endverbatim +*> +*> \param[in] SI2 +*> \verbatim +*> SI2 is DOUBLE PRECISION +*> The shifts in (*). +*> \endverbatim +*> +*> \param[out] V +*> \verbatim +*> V is DOUBLE PRECISION array of dimension N +*> A scalar multiple of the first column of the +*> matrix K in (*). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup doubleOTHERauxiliary +* +*> \par Contributors: +* ================== +*> +*> Karen Braman and Ralph Byers, Department of Mathematics, +*> University of Kansas, USA +*> +* ===================================================================== + SUBROUTINE DLAQR1( N, H, LDH, SR1, SI1, SR2, SI2, V ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + DOUBLE PRECISION SI1, SI2, SR1, SR2 + INTEGER LDH, N +* .. +* .. Array Arguments .. + DOUBLE PRECISION H( LDH, * ), V( * ) +* .. +* +* ================================================================ +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0d0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION H21S, H31S, S +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS +* .. +* .. Executable Statements .. + IF( N.EQ.2 ) THEN + S = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) ) + IF( S.EQ.ZERO ) THEN + V( 1 ) = ZERO + V( 2 ) = ZERO + ELSE + H21S = H( 2, 1 ) / S + V( 1 ) = H21S*H( 1, 2 ) + ( H( 1, 1 )-SR1 )* + $ ( ( H( 1, 1 )-SR2 ) / S ) - SI1*( SI2 / S ) + V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 ) + END IF + ELSE + S = ABS( H( 1, 1 )-SR2 ) + ABS( SI2 ) + ABS( H( 2, 1 ) ) + + $ ABS( H( 3, 1 ) ) + IF( S.EQ.ZERO ) THEN + V( 1 ) = ZERO + V( 2 ) = ZERO + V( 3 ) = ZERO + ELSE + H21S = H( 2, 1 ) / S + H31S = H( 3, 1 ) / S + V( 1 ) = ( H( 1, 1 )-SR1 )*( ( H( 1, 1 )-SR2 ) / S ) - + $ SI1*( SI2 / S ) + H( 1, 2 )*H21S + H( 1, 3 )*H31S + V( 2 ) = H21S*( H( 1, 1 )+H( 2, 2 )-SR1-SR2 ) + + $ H( 2, 3 )*H31S + V( 3 ) = H31S*( H( 1, 1 )+H( 3, 3 )-SR1-SR2 ) + + $ H21S*H( 3, 2 ) + END IF + END IF + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaqr5.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaqr5.f new file mode 100644 index 00000000..37ce6f6b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaqr5.f @@ -0,0 +1,921 @@ +*> \brief \b DLAQR5 performs a single small-bulge multi-shift QR sweep. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLAQR5 + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS, +* SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U, +* LDU, NV, WV, LDWV, NH, WH, LDWH ) +* +* .. Scalar Arguments .. +* INTEGER IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV, +* $ LDWH, LDWV, LDZ, N, NH, NSHFTS, NV +* LOGICAL WANTT, WANTZ +* .. +* .. Array Arguments .. +* DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), U( LDU, * ), +* $ V( LDV, * ), WH( LDWH, * ), WV( LDWV, * ), +* $ Z( LDZ, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLAQR5, called by DLAQR0, performs a +*> single small-bulge multi-shift QR sweep. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] WANTT +*> \verbatim +*> WANTT is logical scalar +*> WANTT = .true. if the quasi-triangular Schur factor +*> is being computed. WANTT is set to .false. otherwise. +*> \endverbatim +*> +*> \param[in] WANTZ +*> \verbatim +*> WANTZ is logical scalar +*> WANTZ = .true. if the orthogonal Schur factor is being +*> computed. WANTZ is set to .false. otherwise. +*> \endverbatim +*> +*> \param[in] KACC22 +*> \verbatim +*> KACC22 is integer with value 0, 1, or 2. +*> Specifies the computation mode of far-from-diagonal +*> orthogonal updates. +*> = 0: DLAQR5 does not accumulate reflections and does not +*> use matrix-matrix multiply to update far-from-diagonal +*> matrix entries. +*> = 1: DLAQR5 accumulates reflections and uses matrix-matrix +*> multiply to update the far-from-diagonal matrix entries. +*> = 2: DLAQR5 accumulates reflections, uses matrix-matrix +*> multiply to update the far-from-diagonal matrix entries, +*> and takes advantage of 2-by-2 block structure during +*> matrix multiplies. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is integer scalar +*> N is the order of the Hessenberg matrix H upon which this +*> subroutine operates. +*> \endverbatim +*> +*> \param[in] KTOP +*> \verbatim +*> KTOP is integer scalar +*> \endverbatim +*> +*> \param[in] KBOT +*> \verbatim +*> KBOT is integer scalar +*> These are the first and last rows and columns of an +*> isolated diagonal block upon which the QR sweep is to be +*> applied. It is assumed without a check that +*> either KTOP = 1 or H(KTOP,KTOP-1) = 0 +*> and +*> either KBOT = N or H(KBOT+1,KBOT) = 0. +*> \endverbatim +*> +*> \param[in] NSHFTS +*> \verbatim +*> NSHFTS is integer scalar +*> NSHFTS gives the number of simultaneous shifts. NSHFTS +*> must be positive and even. +*> \endverbatim +*> +*> \param[in,out] SR +*> \verbatim +*> SR is DOUBLE PRECISION array of size (NSHFTS) +*> \endverbatim +*> +*> \param[in,out] SI +*> \verbatim +*> SI is DOUBLE PRECISION array of size (NSHFTS) +*> SR contains the real parts and SI contains the imaginary +*> parts of the NSHFTS shifts of origin that define the +*> multi-shift QR sweep. On output SR and SI may be +*> reordered. +*> \endverbatim +*> +*> \param[in,out] H +*> \verbatim +*> H is DOUBLE PRECISION array of size (LDH,N) +*> On input H contains a Hessenberg matrix. On output a +*> multi-shift QR sweep with shifts SR(J)+i*SI(J) is applied +*> to the isolated diagonal block in rows and columns KTOP +*> through KBOT. +*> \endverbatim +*> +*> \param[in] LDH +*> \verbatim +*> LDH is integer scalar +*> LDH is the leading dimension of H just as declared in the +*> calling procedure. LDH.GE.MAX(1,N). +*> \endverbatim +*> +*> \param[in] ILOZ +*> \verbatim +*> ILOZ is INTEGER +*> \endverbatim +*> +*> \param[in] IHIZ +*> \verbatim +*> IHIZ is INTEGER +*> Specify the rows of Z to which transformations must be +*> applied if WANTZ is .TRUE.. 1 .LE. ILOZ .LE. IHIZ .LE. N +*> \endverbatim +*> +*> \param[in,out] Z +*> \verbatim +*> Z is DOUBLE PRECISION array of size (LDZ,IHI) +*> If WANTZ = .TRUE., then the QR Sweep orthogonal +*> similarity transformation is accumulated into +*> Z(ILOZ:IHIZ,ILO:IHI) from the right. +*> If WANTZ = .FALSE., then Z is unreferenced. +*> \endverbatim +*> +*> \param[in] LDZ +*> \verbatim +*> LDZ is integer scalar +*> LDA is the leading dimension of Z just as declared in +*> the calling procedure. LDZ.GE.N. +*> \endverbatim +*> +*> \param[out] V +*> \verbatim +*> V is DOUBLE PRECISION array of size (LDV,NSHFTS/2) +*> \endverbatim +*> +*> \param[in] LDV +*> \verbatim +*> LDV is integer scalar +*> LDV is the leading dimension of V as declared in the +*> calling procedure. LDV.GE.3. +*> \endverbatim +*> +*> \param[out] U +*> \verbatim +*> U is DOUBLE PRECISION array of size +*> (LDU,3*NSHFTS-3) +*> \endverbatim +*> +*> \param[in] LDU +*> \verbatim +*> LDU is integer scalar +*> LDU is the leading dimension of U just as declared in the +*> in the calling subroutine. LDU.GE.3*NSHFTS-3. +*> \endverbatim +*> +*> \param[in] NH +*> \verbatim +*> NH is integer scalar +*> NH is the number of columns in array WH available for +*> workspace. NH.GE.1. +*> \endverbatim +*> +*> \param[out] WH +*> \verbatim +*> WH is DOUBLE PRECISION array of size (LDWH,NH) +*> \endverbatim +*> +*> \param[in] LDWH +*> \verbatim +*> LDWH is integer scalar +*> Leading dimension of WH just as declared in the +*> calling procedure. LDWH.GE.3*NSHFTS-3. +*> \endverbatim +*> +*> \param[in] NV +*> \verbatim +*> NV is integer scalar +*> NV is the number of rows in WV agailable for workspace. +*> NV.GE.1. +*> \endverbatim +*> +*> \param[out] WV +*> \verbatim +*> WV is DOUBLE PRECISION array of size +*> (LDWV,3*NSHFTS-3) +*> \endverbatim +*> +*> \param[in] LDWV +*> \verbatim +*> LDWV is integer scalar +*> LDWV is the leading dimension of WV as declared in the +*> in the calling subroutine. LDWV.GE.NV. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup doubleOTHERauxiliary +* +*> \par Contributors: +* ================== +*> +*> Karen Braman and Ralph Byers, Department of Mathematics, +*> University of Kansas, USA +* +*> \par References: +* ================ +*> +*> K. Braman, R. Byers and R. Mathias, The Multi-Shift QR +*> Algorithm Part I: Maintaining Well Focused Shifts, and Level 3 +*> Performance, SIAM Journal of Matrix Analysis, volume 23, pages +*> 929--947, 2002. +*> +* ===================================================================== + SUBROUTINE DLAQR5( WANTT, WANTZ, KACC22, N, KTOP, KBOT, NSHFTS, + $ SR, SI, H, LDH, ILOZ, IHIZ, Z, LDZ, V, LDV, U, + $ LDU, NV, WV, LDWV, NH, WH, LDWH ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER IHIZ, ILOZ, KACC22, KBOT, KTOP, LDH, LDU, LDV, + $ LDWH, LDWV, LDZ, N, NH, NSHFTS, NV + LOGICAL WANTT, WANTZ +* .. +* .. Array Arguments .. + DOUBLE PRECISION H( LDH, * ), SI( * ), SR( * ), U( LDU, * ), + $ V( LDV, * ), WH( LDWH, * ), WV( LDWV, * ), + $ Z( LDZ, * ) +* .. +* +* ================================================================ +* .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0d0, ONE = 1.0d0 ) +* .. +* .. Local Scalars .. + DOUBLE PRECISION ALPHA, BETA, H11, H12, H21, H22, REFSUM, + $ SAFMAX, SAFMIN, SCL, SMLNUM, SWAP, TST1, TST2, + $ ULP + INTEGER I, I2, I4, INCOL, J, J2, J4, JBOT, JCOL, JLEN, + $ JROW, JTOP, K, K1, KDU, KMS, KNZ, KRCOL, KZS, + $ M, M22, MBOT, MEND, MSTART, MTOP, NBMPS, NDCOL, + $ NS, NU + LOGICAL ACCUM, BLK22, BMP22 +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH +* .. +* .. Intrinsic Functions .. +* + INTRINSIC ABS, DBLE, MAX, MIN, MOD +* .. +* .. Local Arrays .. + DOUBLE PRECISION VT( 3 ) +* .. +* .. External Subroutines .. + EXTERNAL DGEMM, DLABAD, DLACPY, DLAQR1, DLARFG, DLASET, + $ DTRMM +* .. +* .. Executable Statements .. +* +* ==== If there are no shifts, then there is nothing to do. ==== +* + IF( NSHFTS.LT.2 ) + $ RETURN +* +* ==== If the active block is empty or 1-by-1, then there +* . is nothing to do. ==== +* + IF( KTOP.GE.KBOT ) + $ RETURN +* +* ==== Shuffle shifts into pairs of real shifts and pairs +* . of complex conjugate shifts assuming complex +* . conjugate shifts are already adjacent to one +* . another. ==== +* + DO 10 I = 1, NSHFTS - 2, 2 + IF( SI( I ).NE.-SI( I+1 ) ) THEN +* + SWAP = SR( I ) + SR( I ) = SR( I+1 ) + SR( I+1 ) = SR( I+2 ) + SR( I+2 ) = SWAP +* + SWAP = SI( I ) + SI( I ) = SI( I+1 ) + SI( I+1 ) = SI( I+2 ) + SI( I+2 ) = SWAP + END IF + 10 CONTINUE +* +* ==== NSHFTS is supposed to be even, but if it is odd, +* . then simply reduce it by one. The shuffle above +* . ensures that the dropped shift is real and that +* . the remaining shifts are paired. ==== +* + NS = NSHFTS - MOD( NSHFTS, 2 ) +* +* ==== Machine constants for deflation ==== +* + SAFMIN = DLAMCH( 'SAFE MINIMUM' ) + SAFMAX = ONE / SAFMIN + CALL DLABAD( SAFMIN, SAFMAX ) + ULP = DLAMCH( 'PRECISION' ) + SMLNUM = SAFMIN*( DBLE( N ) / ULP ) +* +* ==== Use accumulated reflections to update far-from-diagonal +* . entries ? ==== +* + ACCUM = ( KACC22.EQ.1 ) .OR. ( KACC22.EQ.2 ) +* +* ==== If so, exploit the 2-by-2 block structure? ==== +* + BLK22 = ( NS.GT.2 ) .AND. ( KACC22.EQ.2 ) +* +* ==== clear trash ==== +* + IF( KTOP+2.LE.KBOT ) + $ H( KTOP+2, KTOP ) = ZERO +* +* ==== NBMPS = number of 2-shift bulges in the chain ==== +* + NBMPS = NS / 2 +* +* ==== KDU = width of slab ==== +* + KDU = 6*NBMPS - 3 +* +* ==== Create and chase chains of NBMPS bulges ==== +* + DO 220 INCOL = 3*( 1-NBMPS ) + KTOP - 1, KBOT - 2, 3*NBMPS - 2 + NDCOL = INCOL + KDU + IF( ACCUM ) + $ CALL DLASET( 'ALL', KDU, KDU, ZERO, ONE, U, LDU ) +* +* ==== Near-the-diagonal bulge chase. The following loop +* . performs the near-the-diagonal part of a small bulge +* . multi-shift QR sweep. Each 6*NBMPS-2 column diagonal +* . chunk extends from column INCOL to column NDCOL +* . (including both column INCOL and column NDCOL). The +* . following loop chases a 3*NBMPS column long chain of +* . NBMPS bulges 3*NBMPS-2 columns to the right. (INCOL +* . may be less than KTOP and and NDCOL may be greater than +* . KBOT indicating phantom columns from which to chase +* . bulges before they are actually introduced or to which +* . to chase bulges beyond column KBOT.) ==== +* + DO 150 KRCOL = INCOL, MIN( INCOL+3*NBMPS-3, KBOT-2 ) +* +* ==== Bulges number MTOP to MBOT are active double implicit +* . shift bulges. There may or may not also be small +* . 2-by-2 bulge, if there is room. The inactive bulges +* . (if any) must wait until the active bulges have moved +* . down the diagonal to make room. The phantom matrix +* . paradigm described above helps keep track. ==== +* + MTOP = MAX( 1, ( ( KTOP-1 )-KRCOL+2 ) / 3+1 ) + MBOT = MIN( NBMPS, ( KBOT-KRCOL ) / 3 ) + M22 = MBOT + 1 + BMP22 = ( MBOT.LT.NBMPS ) .AND. ( KRCOL+3*( M22-1 ) ).EQ. + $ ( KBOT-2 ) +* +* ==== Generate reflections to chase the chain right +* . one column. (The minimum value of K is KTOP-1.) ==== +* + DO 20 M = MTOP, MBOT + K = KRCOL + 3*( M-1 ) + IF( K.EQ.KTOP-1 ) THEN + CALL DLAQR1( 3, H( KTOP, KTOP ), LDH, SR( 2*M-1 ), + $ SI( 2*M-1 ), SR( 2*M ), SI( 2*M ), + $ V( 1, M ) ) + ALPHA = V( 1, M ) + CALL DLARFG( 3, ALPHA, V( 2, M ), 1, V( 1, M ) ) + ELSE + BETA = H( K+1, K ) + V( 2, M ) = H( K+2, K ) + V( 3, M ) = H( K+3, K ) + CALL DLARFG( 3, BETA, V( 2, M ), 1, V( 1, M ) ) +* +* ==== A Bulge may collapse because of vigilant +* . deflation or destructive underflow. In the +* . underflow case, try the two-small-subdiagonals +* . trick to try to reinflate the bulge. ==== +* + IF( H( K+3, K ).NE.ZERO .OR. H( K+3, K+1 ).NE. + $ ZERO .OR. H( K+3, K+2 ).EQ.ZERO ) THEN +* +* ==== Typical case: not collapsed (yet). ==== +* + H( K+1, K ) = BETA + H( K+2, K ) = ZERO + H( K+3, K ) = ZERO + ELSE +* +* ==== Atypical case: collapsed. Attempt to +* . reintroduce ignoring H(K+1,K) and H(K+2,K). +* . If the fill resulting from the new +* . reflector is too large, then abandon it. +* . Otherwise, use the new one. ==== +* + CALL DLAQR1( 3, H( K+1, K+1 ), LDH, SR( 2*M-1 ), + $ SI( 2*M-1 ), SR( 2*M ), SI( 2*M ), + $ VT ) + ALPHA = VT( 1 ) + CALL DLARFG( 3, ALPHA, VT( 2 ), 1, VT( 1 ) ) + REFSUM = VT( 1 )*( H( K+1, K )+VT( 2 )* + $ H( K+2, K ) ) +* + IF( ABS( H( K+2, K )-REFSUM*VT( 2 ) )+ + $ ABS( REFSUM*VT( 3 ) ).GT.ULP* + $ ( ABS( H( K, K ) )+ABS( H( K+1, + $ K+1 ) )+ABS( H( K+2, K+2 ) ) ) ) THEN +* +* ==== Starting a new bulge here would +* . create non-negligible fill. Use +* . the old one with trepidation. ==== +* + H( K+1, K ) = BETA + H( K+2, K ) = ZERO + H( K+3, K ) = ZERO + ELSE +* +* ==== Stating a new bulge here would +* . create only negligible fill. +* . Replace the old reflector with +* . the new one. ==== +* + H( K+1, K ) = H( K+1, K ) - REFSUM + H( K+2, K ) = ZERO + H( K+3, K ) = ZERO + V( 1, M ) = VT( 1 ) + V( 2, M ) = VT( 2 ) + V( 3, M ) = VT( 3 ) + END IF + END IF + END IF + 20 CONTINUE +* +* ==== Generate a 2-by-2 reflection, if needed. ==== +* + K = KRCOL + 3*( M22-1 ) + IF( BMP22 ) THEN + IF( K.EQ.KTOP-1 ) THEN + CALL DLAQR1( 2, H( K+1, K+1 ), LDH, SR( 2*M22-1 ), + $ SI( 2*M22-1 ), SR( 2*M22 ), SI( 2*M22 ), + $ V( 1, M22 ) ) + BETA = V( 1, M22 ) + CALL DLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) ) + ELSE + BETA = H( K+1, K ) + V( 2, M22 ) = H( K+2, K ) + CALL DLARFG( 2, BETA, V( 2, M22 ), 1, V( 1, M22 ) ) + H( K+1, K ) = BETA + H( K+2, K ) = ZERO + END IF + END IF +* +* ==== Multiply H by reflections from the left ==== +* + IF( ACCUM ) THEN + JBOT = MIN( NDCOL, KBOT ) + ELSE IF( WANTT ) THEN + JBOT = N + ELSE + JBOT = KBOT + END IF + DO 40 J = MAX( KTOP, KRCOL ), JBOT + MEND = MIN( MBOT, ( J-KRCOL+2 ) / 3 ) + DO 30 M = MTOP, MEND + K = KRCOL + 3*( M-1 ) + REFSUM = V( 1, M )*( H( K+1, J )+V( 2, M )* + $ H( K+2, J )+V( 3, M )*H( K+3, J ) ) + H( K+1, J ) = H( K+1, J ) - REFSUM + H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M ) + H( K+3, J ) = H( K+3, J ) - REFSUM*V( 3, M ) + 30 CONTINUE + 40 CONTINUE + IF( BMP22 ) THEN + K = KRCOL + 3*( M22-1 ) + DO 50 J = MAX( K+1, KTOP ), JBOT + REFSUM = V( 1, M22 )*( H( K+1, J )+V( 2, M22 )* + $ H( K+2, J ) ) + H( K+1, J ) = H( K+1, J ) - REFSUM + H( K+2, J ) = H( K+2, J ) - REFSUM*V( 2, M22 ) + 50 CONTINUE + END IF +* +* ==== Multiply H by reflections from the right. +* . Delay filling in the last row until the +* . vigilant deflation check is complete. ==== +* + IF( ACCUM ) THEN + JTOP = MAX( KTOP, INCOL ) + ELSE IF( WANTT ) THEN + JTOP = 1 + ELSE + JTOP = KTOP + END IF + DO 90 M = MTOP, MBOT + IF( V( 1, M ).NE.ZERO ) THEN + K = KRCOL + 3*( M-1 ) + DO 60 J = JTOP, MIN( KBOT, K+3 ) + REFSUM = V( 1, M )*( H( J, K+1 )+V( 2, M )* + $ H( J, K+2 )+V( 3, M )*H( J, K+3 ) ) + H( J, K+1 ) = H( J, K+1 ) - REFSUM + H( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M ) + H( J, K+3 ) = H( J, K+3 ) - REFSUM*V( 3, M ) + 60 CONTINUE +* + IF( ACCUM ) THEN +* +* ==== Accumulate U. (If necessary, update Z later +* . with with an efficient matrix-matrix +* . multiply.) ==== +* + KMS = K - INCOL + DO 70 J = MAX( 1, KTOP-INCOL ), KDU + REFSUM = V( 1, M )*( U( J, KMS+1 )+V( 2, M )* + $ U( J, KMS+2 )+V( 3, M )*U( J, KMS+3 ) ) + U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM + U( J, KMS+2 ) = U( J, KMS+2 ) - REFSUM*V( 2, M ) + U( J, KMS+3 ) = U( J, KMS+3 ) - REFSUM*V( 3, M ) + 70 CONTINUE + ELSE IF( WANTZ ) THEN +* +* ==== U is not accumulated, so update Z +* . now by multiplying by reflections +* . from the right. ==== +* + DO 80 J = ILOZ, IHIZ + REFSUM = V( 1, M )*( Z( J, K+1 )+V( 2, M )* + $ Z( J, K+2 )+V( 3, M )*Z( J, K+3 ) ) + Z( J, K+1 ) = Z( J, K+1 ) - REFSUM + Z( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M ) + Z( J, K+3 ) = Z( J, K+3 ) - REFSUM*V( 3, M ) + 80 CONTINUE + END IF + END IF + 90 CONTINUE +* +* ==== Special case: 2-by-2 reflection (if needed) ==== +* + K = KRCOL + 3*( M22-1 ) + IF( BMP22 ) THEN + IF ( V( 1, M22 ).NE.ZERO ) THEN + DO 100 J = JTOP, MIN( KBOT, K+3 ) + REFSUM = V( 1, M22 )*( H( J, K+1 )+V( 2, M22 )* + $ H( J, K+2 ) ) + H( J, K+1 ) = H( J, K+1 ) - REFSUM + H( J, K+2 ) = H( J, K+2 ) - REFSUM*V( 2, M22 ) + 100 CONTINUE +* + IF( ACCUM ) THEN + KMS = K - INCOL + DO 110 J = MAX( 1, KTOP-INCOL ), KDU + REFSUM = V( 1, M22 )*( U( J, KMS+1 )+ + $ V( 2, M22 )*U( J, KMS+2 ) ) + U( J, KMS+1 ) = U( J, KMS+1 ) - REFSUM + U( J, KMS+2 ) = U( J, KMS+2 ) - + $ REFSUM*V( 2, M22 ) + 110 CONTINUE + ELSE IF( WANTZ ) THEN + DO 120 J = ILOZ, IHIZ + REFSUM = V( 1, M22 )*( Z( J, K+1 )+V( 2, M22 )* + $ Z( J, K+2 ) ) + Z( J, K+1 ) = Z( J, K+1 ) - REFSUM + Z( J, K+2 ) = Z( J, K+2 ) - REFSUM*V( 2, M22 ) + 120 CONTINUE + END IF + END IF + END IF +* +* ==== Vigilant deflation check ==== +* + MSTART = MTOP + IF( KRCOL+3*( MSTART-1 ).LT.KTOP ) + $ MSTART = MSTART + 1 + MEND = MBOT + IF( BMP22 ) + $ MEND = MEND + 1 + IF( KRCOL.EQ.KBOT-2 ) + $ MEND = MEND + 1 + DO 130 M = MSTART, MEND + K = MIN( KBOT-1, KRCOL+3*( M-1 ) ) +* +* ==== The following convergence test requires that +* . the tradition small-compared-to-nearby-diagonals +* . criterion and the Ahues & Tisseur (LAWN 122, 1997) +* . criteria both be satisfied. The latter improves +* . accuracy in some examples. Falling back on an +* . alternate convergence criterion when TST1 or TST2 +* . is zero (as done here) is traditional but probably +* . unnecessary. ==== +* + IF( H( K+1, K ).NE.ZERO ) THEN + TST1 = ABS( H( K, K ) ) + ABS( H( K+1, K+1 ) ) + IF( TST1.EQ.ZERO ) THEN + IF( K.GE.KTOP+1 ) + $ TST1 = TST1 + ABS( H( K, K-1 ) ) + IF( K.GE.KTOP+2 ) + $ TST1 = TST1 + ABS( H( K, K-2 ) ) + IF( K.GE.KTOP+3 ) + $ TST1 = TST1 + ABS( H( K, K-3 ) ) + IF( K.LE.KBOT-2 ) + $ TST1 = TST1 + ABS( H( K+2, K+1 ) ) + IF( K.LE.KBOT-3 ) + $ TST1 = TST1 + ABS( H( K+3, K+1 ) ) + IF( K.LE.KBOT-4 ) + $ TST1 = TST1 + ABS( H( K+4, K+1 ) ) + END IF + IF( ABS( H( K+1, K ) ).LE.MAX( SMLNUM, ULP*TST1 ) ) + $ THEN + H12 = MAX( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) ) + H21 = MIN( ABS( H( K+1, K ) ), ABS( H( K, K+1 ) ) ) + H11 = MAX( ABS( H( K+1, K+1 ) ), + $ ABS( H( K, K )-H( K+1, K+1 ) ) ) + H22 = MIN( ABS( H( K+1, K+1 ) ), + $ ABS( H( K, K )-H( K+1, K+1 ) ) ) + SCL = H11 + H12 + TST2 = H22*( H11 / SCL ) +* + IF( TST2.EQ.ZERO .OR. H21*( H12 / SCL ).LE. + $ MAX( SMLNUM, ULP*TST2 ) )H( K+1, K ) = ZERO + END IF + END IF + 130 CONTINUE +* +* ==== Fill in the last row of each bulge. ==== +* + MEND = MIN( NBMPS, ( KBOT-KRCOL-1 ) / 3 ) + DO 140 M = MTOP, MEND + K = KRCOL + 3*( M-1 ) + REFSUM = V( 1, M )*V( 3, M )*H( K+4, K+3 ) + H( K+4, K+1 ) = -REFSUM + H( K+4, K+2 ) = -REFSUM*V( 2, M ) + H( K+4, K+3 ) = H( K+4, K+3 ) - REFSUM*V( 3, M ) + 140 CONTINUE +* +* ==== End of near-the-diagonal bulge chase. ==== +* + 150 CONTINUE +* +* ==== Use U (if accumulated) to update far-from-diagonal +* . entries in H. If required, use U to update Z as +* . well. ==== +* + IF( ACCUM ) THEN + IF( WANTT ) THEN + JTOP = 1 + JBOT = N + ELSE + JTOP = KTOP + JBOT = KBOT + END IF + IF( ( .NOT.BLK22 ) .OR. ( INCOL.LT.KTOP ) .OR. + $ ( NDCOL.GT.KBOT ) .OR. ( NS.LE.2 ) ) THEN +* +* ==== Updates not exploiting the 2-by-2 block +* . structure of U. K1 and NU keep track of +* . the location and size of U in the special +* . cases of introducing bulges and chasing +* . bulges off the bottom. In these special +* . cases and in case the number of shifts +* . is NS = 2, there is no 2-by-2 block +* . structure to exploit. ==== +* + K1 = MAX( 1, KTOP-INCOL ) + NU = ( KDU-MAX( 0, NDCOL-KBOT ) ) - K1 + 1 +* +* ==== Horizontal Multiply ==== +* + DO 160 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH + JLEN = MIN( NH, JBOT-JCOL+1 ) + CALL DGEMM( 'C', 'N', NU, JLEN, NU, ONE, U( K1, K1 ), + $ LDU, H( INCOL+K1, JCOL ), LDH, ZERO, WH, + $ LDWH ) + CALL DLACPY( 'ALL', NU, JLEN, WH, LDWH, + $ H( INCOL+K1, JCOL ), LDH ) + 160 CONTINUE +* +* ==== Vertical multiply ==== +* + DO 170 JROW = JTOP, MAX( KTOP, INCOL ) - 1, NV + JLEN = MIN( NV, MAX( KTOP, INCOL )-JROW ) + CALL DGEMM( 'N', 'N', JLEN, NU, NU, ONE, + $ H( JROW, INCOL+K1 ), LDH, U( K1, K1 ), + $ LDU, ZERO, WV, LDWV ) + CALL DLACPY( 'ALL', JLEN, NU, WV, LDWV, + $ H( JROW, INCOL+K1 ), LDH ) + 170 CONTINUE +* +* ==== Z multiply (also vertical) ==== +* + IF( WANTZ ) THEN + DO 180 JROW = ILOZ, IHIZ, NV + JLEN = MIN( NV, IHIZ-JROW+1 ) + CALL DGEMM( 'N', 'N', JLEN, NU, NU, ONE, + $ Z( JROW, INCOL+K1 ), LDZ, U( K1, K1 ), + $ LDU, ZERO, WV, LDWV ) + CALL DLACPY( 'ALL', JLEN, NU, WV, LDWV, + $ Z( JROW, INCOL+K1 ), LDZ ) + 180 CONTINUE + END IF + ELSE +* +* ==== Updates exploiting U's 2-by-2 block structure. +* . (I2, I4, J2, J4 are the last rows and columns +* . of the blocks.) ==== +* + I2 = ( KDU+1 ) / 2 + I4 = KDU + J2 = I4 - I2 + J4 = KDU +* +* ==== KZS and KNZ deal with the band of zeros +* . along the diagonal of one of the triangular +* . blocks. ==== +* + KZS = ( J4-J2 ) - ( NS+1 ) + KNZ = NS + 1 +* +* ==== Horizontal multiply ==== +* + DO 190 JCOL = MIN( NDCOL, KBOT ) + 1, JBOT, NH + JLEN = MIN( NH, JBOT-JCOL+1 ) +* +* ==== Copy bottom of H to top+KZS of scratch ==== +* (The first KZS rows get multiplied by zero.) ==== +* + CALL DLACPY( 'ALL', KNZ, JLEN, H( INCOL+1+J2, JCOL ), + $ LDH, WH( KZS+1, 1 ), LDWH ) +* +* ==== Multiply by U21**T ==== +* + CALL DLASET( 'ALL', KZS, JLEN, ZERO, ZERO, WH, LDWH ) + CALL DTRMM( 'L', 'U', 'C', 'N', KNZ, JLEN, ONE, + $ U( J2+1, 1+KZS ), LDU, WH( KZS+1, 1 ), + $ LDWH ) +* +* ==== Multiply top of H by U11**T ==== +* + CALL DGEMM( 'C', 'N', I2, JLEN, J2, ONE, U, LDU, + $ H( INCOL+1, JCOL ), LDH, ONE, WH, LDWH ) +* +* ==== Copy top of H to bottom of WH ==== +* + CALL DLACPY( 'ALL', J2, JLEN, H( INCOL+1, JCOL ), LDH, + $ WH( I2+1, 1 ), LDWH ) +* +* ==== Multiply by U21**T ==== +* + CALL DTRMM( 'L', 'L', 'C', 'N', J2, JLEN, ONE, + $ U( 1, I2+1 ), LDU, WH( I2+1, 1 ), LDWH ) +* +* ==== Multiply by U22 ==== +* + CALL DGEMM( 'C', 'N', I4-I2, JLEN, J4-J2, ONE, + $ U( J2+1, I2+1 ), LDU, + $ H( INCOL+1+J2, JCOL ), LDH, ONE, + $ WH( I2+1, 1 ), LDWH ) +* +* ==== Copy it back ==== +* + CALL DLACPY( 'ALL', KDU, JLEN, WH, LDWH, + $ H( INCOL+1, JCOL ), LDH ) + 190 CONTINUE +* +* ==== Vertical multiply ==== +* + DO 200 JROW = JTOP, MAX( INCOL, KTOP ) - 1, NV + JLEN = MIN( NV, MAX( INCOL, KTOP )-JROW ) +* +* ==== Copy right of H to scratch (the first KZS +* . columns get multiplied by zero) ==== +* + CALL DLACPY( 'ALL', JLEN, KNZ, H( JROW, INCOL+1+J2 ), + $ LDH, WV( 1, 1+KZS ), LDWV ) +* +* ==== Multiply by U21 ==== +* + CALL DLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV, LDWV ) + CALL DTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE, + $ U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ), + $ LDWV ) +* +* ==== Multiply by U11 ==== +* + CALL DGEMM( 'N', 'N', JLEN, I2, J2, ONE, + $ H( JROW, INCOL+1 ), LDH, U, LDU, ONE, WV, + $ LDWV ) +* +* ==== Copy left of H to right of scratch ==== +* + CALL DLACPY( 'ALL', JLEN, J2, H( JROW, INCOL+1 ), LDH, + $ WV( 1, 1+I2 ), LDWV ) +* +* ==== Multiply by U21 ==== +* + CALL DTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE, + $ U( 1, I2+1 ), LDU, WV( 1, 1+I2 ), LDWV ) +* +* ==== Multiply by U22 ==== +* + CALL DGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE, + $ H( JROW, INCOL+1+J2 ), LDH, + $ U( J2+1, I2+1 ), LDU, ONE, WV( 1, 1+I2 ), + $ LDWV ) +* +* ==== Copy it back ==== +* + CALL DLACPY( 'ALL', JLEN, KDU, WV, LDWV, + $ H( JROW, INCOL+1 ), LDH ) + 200 CONTINUE +* +* ==== Multiply Z (also vertical) ==== +* + IF( WANTZ ) THEN + DO 210 JROW = ILOZ, IHIZ, NV + JLEN = MIN( NV, IHIZ-JROW+1 ) +* +* ==== Copy right of Z to left of scratch (first +* . KZS columns get multiplied by zero) ==== +* + CALL DLACPY( 'ALL', JLEN, KNZ, + $ Z( JROW, INCOL+1+J2 ), LDZ, + $ WV( 1, 1+KZS ), LDWV ) +* +* ==== Multiply by U12 ==== +* + CALL DLASET( 'ALL', JLEN, KZS, ZERO, ZERO, WV, + $ LDWV ) + CALL DTRMM( 'R', 'U', 'N', 'N', JLEN, KNZ, ONE, + $ U( J2+1, 1+KZS ), LDU, WV( 1, 1+KZS ), + $ LDWV ) +* +* ==== Multiply by U11 ==== +* + CALL DGEMM( 'N', 'N', JLEN, I2, J2, ONE, + $ Z( JROW, INCOL+1 ), LDZ, U, LDU, ONE, + $ WV, LDWV ) +* +* ==== Copy left of Z to right of scratch ==== +* + CALL DLACPY( 'ALL', JLEN, J2, Z( JROW, INCOL+1 ), + $ LDZ, WV( 1, 1+I2 ), LDWV ) +* +* ==== Multiply by U21 ==== +* + CALL DTRMM( 'R', 'L', 'N', 'N', JLEN, I4-I2, ONE, + $ U( 1, I2+1 ), LDU, WV( 1, 1+I2 ), + $ LDWV ) +* +* ==== Multiply by U22 ==== +* + CALL DGEMM( 'N', 'N', JLEN, I4-I2, J4-J2, ONE, + $ Z( JROW, INCOL+1+J2 ), LDZ, + $ U( J2+1, I2+1 ), LDU, ONE, + $ WV( 1, 1+I2 ), LDWV ) +* +* ==== Copy the result back to Z ==== +* + CALL DLACPY( 'ALL', JLEN, KDU, WV, LDWV, + $ Z( JROW, INCOL+1 ), LDZ ) + 210 CONTINUE + END IF + END IF + END IF + 220 CONTINUE +* +* ==== End of DLAQR5 ==== +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlarfg.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlarfg.f new file mode 100644 index 00000000..ce91d33c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlarfg.f @@ -0,0 +1,196 @@ +*> \brief \b DLARFG generates an elementary reflector (Householder matrix). +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLARFG + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU ) +* +* .. Scalar Arguments .. +* INTEGER INCX, N +* DOUBLE PRECISION ALPHA, TAU +* .. +* .. Array Arguments .. +* DOUBLE PRECISION X( * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLARFG generates a real elementary reflector H of order n, such +*> that +*> +*> H * ( alpha ) = ( beta ), H**T * H = I. +*> ( x ) ( 0 ) +*> +*> where alpha and beta are scalars, and x is an (n-1)-element real +*> vector. H is represented in the form +*> +*> H = I - tau * ( 1 ) * ( 1 v**T ) , +*> ( v ) +*> +*> where tau is a real scalar and v is a real (n-1)-element +*> vector. +*> +*> If the elements of x are all zero, then tau = 0 and H is taken to be +*> the unit matrix. +*> +*> Otherwise 1 <= tau <= 2. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The order of the elementary reflector. +*> \endverbatim +*> +*> \param[in,out] ALPHA +*> \verbatim +*> ALPHA is DOUBLE PRECISION +*> On entry, the value alpha. +*> On exit, it is overwritten with the value beta. +*> \endverbatim +*> +*> \param[in,out] X +*> \verbatim +*> X is DOUBLE PRECISION array, dimension +*> (1+(N-2)*abs(INCX)) +*> On entry, the vector x. +*> On exit, it is overwritten with the vector v. +*> \endverbatim +*> +*> \param[in] INCX +*> \verbatim +*> INCX is INTEGER +*> The increment between elements of X. INCX > 0. +*> \endverbatim +*> +*> \param[out] TAU +*> \verbatim +*> TAU is DOUBLE PRECISION +*> The value tau. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date September 2012 +* +*> \ingroup doubleOTHERauxiliary +* +* ===================================================================== + SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU ) +* +* -- LAPACK auxiliary routine (version 3.4.2) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* September 2012 +* +* .. Scalar Arguments .. + INTEGER INCX, N + DOUBLE PRECISION ALPHA, TAU +* .. +* .. Array Arguments .. + DOUBLE PRECISION X( * ) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE, ZERO + PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) +* .. +* .. Local Scalars .. + INTEGER J, KNT + DOUBLE PRECISION BETA, RSAFMN, SAFMIN, XNORM +* .. +* .. External Functions .. + DOUBLE PRECISION DLAMCH, DLAPY2, DNRM2 + EXTERNAL DLAMCH, DLAPY2, DNRM2 +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS, SIGN +* .. +* .. External Subroutines .. + EXTERNAL DSCAL +* .. +* .. Executable Statements .. +* + IF( N.LE.1 ) THEN + TAU = ZERO + RETURN + END IF +* + XNORM = DNRM2( N-1, X, INCX ) +* + IF( XNORM.EQ.ZERO ) THEN +* +* H = I +* + TAU = ZERO + ELSE +* +* general case +* + BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA ) + SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' ) + KNT = 0 + IF( ABS( BETA ).LT.SAFMIN ) THEN +* +* XNORM, BETA may be inaccurate; scale X and recompute them +* + RSAFMN = ONE / SAFMIN + 10 CONTINUE + KNT = KNT + 1 + CALL DSCAL( N-1, RSAFMN, X, INCX ) + BETA = BETA*RSAFMN + ALPHA = ALPHA*RSAFMN + IF( ABS( BETA ).LT.SAFMIN ) + $ GO TO 10 +* +* New BETA is at most 1, at least SAFMIN +* + XNORM = DNRM2( N-1, X, INCX ) + BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA ) + END IF + TAU = ( BETA-ALPHA ) / BETA + CALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX ) +* +* If ALPHA is subnormal, it may lose relative accuracy +* + DO 20 J = 1, KNT + BETA = BETA*SAFMIN + 20 CONTINUE + ALPHA = BETA + END IF +* + RETURN +* +* End of DLARFG +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaset.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaset.f new file mode 100644 index 00000000..d3bb9456 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dlaset.f @@ -0,0 +1,184 @@ +*> \brief \b DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values. +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +*> \htmlonly +*> Download DLASET + dependencies +*> +*> [TGZ] +*> +*> [ZIP] +*> +*> [TXT] +*> \endhtmlonly +* +* Definition: +* =========== +* +* SUBROUTINE DLASET( UPLO, M, N, ALPHA, BETA, A, LDA ) +* +* .. Scalar Arguments .. +* CHARACTER UPLO +* INTEGER LDA, M, N +* DOUBLE PRECISION ALPHA, BETA +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A( LDA, * ) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DLASET initializes an m-by-n matrix A to BETA on the diagonal and +*> ALPHA on the offdiagonals. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> Specifies the part of the matrix A to be set. +*> = 'U': Upper triangular part is set; the strictly lower +*> triangular part of A is not changed. +*> = 'L': Lower triangular part is set; the strictly upper +*> triangular part of A is not changed. +*> Otherwise: All of the matrix A is set. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> The number of rows of the matrix A. M >= 0. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> The number of columns of the matrix A. N >= 0. +*> \endverbatim +*> +*> \param[in] ALPHA +*> \verbatim +*> ALPHA is DOUBLE PRECISION +*> The constant to which the offdiagonal elements are to be set. +*> \endverbatim +*> +*> \param[in] BETA +*> \verbatim +*> BETA is DOUBLE PRECISION +*> The constant to which the diagonal elements are to be set. +*> \endverbatim +*> +*> \param[out] A +*> \verbatim +*> A is DOUBLE PRECISION array, dimension (LDA,N) +*> On exit, the leading m-by-n submatrix of A is set as follows: +*> +*> if UPLO = 'U', A(i,j) = ALPHA, 1<=i<=j-1, 1<=j<=n, +*> if UPLO = 'L', A(i,j) = ALPHA, j+1<=i<=m, 1<=j<=n, +*> otherwise, A(i,j) = ALPHA, 1<=i<=m, 1<=j<=n, i.ne.j, +*> +*> and, for all UPLO, A(i,i) = BETA, 1<=i<=min(m,n). +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> The leading dimension of the array A. LDA >= max(1,M). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2015 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + SUBROUTINE DLASET( UPLO, M, N, ALPHA, BETA, A, LDA ) +* +* -- LAPACK auxiliary routine (version 3.6.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2015 +* +* .. Scalar Arguments .. + CHARACTER UPLO + INTEGER LDA, M, N + DOUBLE PRECISION ALPHA, BETA +* .. +* .. Array Arguments .. + DOUBLE PRECISION A( LDA, * ) +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I, J +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. Intrinsic Functions .. + INTRINSIC MIN +* .. +* .. Executable Statements .. +* + IF( LSAME( UPLO, 'U' ) ) THEN +* +* Set the strictly upper triangular or trapezoidal part of the +* array to ALPHA. +* + DO 20 J = 2, N + DO 10 I = 1, MIN( J-1, M ) + A( I, J ) = ALPHA + 10 CONTINUE + 20 CONTINUE +* + ELSE IF( LSAME( UPLO, 'L' ) ) THEN +* +* Set the strictly lower triangular or trapezoidal part of the +* array to ALPHA. +* + DO 40 J = 1, MIN( M, N ) + DO 30 I = J + 1, M + A( I, J ) = ALPHA + 30 CONTINUE + 40 CONTINUE +* + ELSE +* +* Set the leading m-by-n submatrix to ALPHA. +* + DO 60 J = 1, N + DO 50 I = 1, M + A( I, J ) = ALPHA + 50 CONTINUE + 60 CONTINUE + END IF +* +* Set the first min(M,N) diagonal elements to BETA. +* + DO 70 I = 1, MIN( M, N ) + A( I, I ) = BETA + 70 CONTINUE +* + RETURN +* +* End of DLASET +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dnrm2.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dnrm2.f new file mode 100644 index 00000000..5ea257a2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dnrm2.f @@ -0,0 +1,112 @@ +*> \brief \b DNRM2 +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* DOUBLE PRECISION FUNCTION DNRM2(N,X,INCX) +* +* .. Scalar Arguments .. +* INTEGER INCX,N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION X(*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DNRM2 returns the euclidean norm of a vector via the function +*> name, so that +*> +*> DNRM2 := sqrt( x'*x ) +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup double_blas_level1 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> -- This version written on 25-October-1982. +*> Modified on 14-October-1993 to inline the call to DLASSQ. +*> Sven Hammarling, Nag Ltd. +*> \endverbatim +*> +* ===================================================================== + DOUBLE PRECISION FUNCTION DNRM2(N,X,INCX) +* +* -- Reference BLAS level1 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + INTEGER INCX,N +* .. +* .. Array Arguments .. + DOUBLE PRECISION X(*) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ONE,ZERO + PARAMETER (ONE=1.0D+0,ZERO=0.0D+0) +* .. +* .. Local Scalars .. + DOUBLE PRECISION ABSXI,NORM,SCALE,SSQ + INTEGER IX +* .. +* .. Intrinsic Functions .. + INTRINSIC ABS,SQRT +* .. + IF (N.LT.1 .OR. INCX.LT.1) THEN + NORM = ZERO + ELSE IF (N.EQ.1) THEN + NORM = ABS(X(1)) + ELSE + SCALE = ZERO + SSQ = ONE +* The following loop is equivalent to this call to the LAPACK +* auxiliary routine: +* CALL DLASSQ( N, X, INCX, SCALE, SSQ ) +* + DO 10 IX = 1,1 + (N-1)*INCX,INCX + IF (X(IX).NE.ZERO) THEN + ABSXI = ABS(X(IX)) + IF (SCALE.LT.ABSXI) THEN + SSQ = ONE + SSQ* (SCALE/ABSXI)**2 + SCALE = ABSXI + ELSE + SSQ = SSQ + (ABSXI/SCALE)**2 + END IF + END IF + 10 CONTINUE + NORM = SCALE*SQRT(SSQ) + END IF +* + DNRM2 = NORM + RETURN +* +* End of DNRM2. +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dscal.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dscal.f new file mode 100644 index 00000000..3337de8e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dscal.f @@ -0,0 +1,110 @@ +*> \brief \b DSCAL +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DSCAL(N,DA,DX,INCX) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION DA +* INTEGER INCX,N +* .. +* .. Array Arguments .. +* DOUBLE PRECISION DX(*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DSCAL scales a vector by a constant. +*> uses unrolled loops for increment equal to one. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup double_blas_level1 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> jack dongarra, linpack, 3/11/78. +*> modified 3/93 to return if incx .le. 0. +*> modified 12/3/93, array(1) declarations changed to array(*) +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DSCAL(N,DA,DX,INCX) +* +* -- Reference BLAS level1 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + DOUBLE PRECISION DA + INTEGER INCX,N +* .. +* .. Array Arguments .. + DOUBLE PRECISION DX(*) +* .. +* +* ===================================================================== +* +* .. Local Scalars .. + INTEGER I,M,MP1,NINCX +* .. +* .. Intrinsic Functions .. + INTRINSIC MOD +* .. + IF (N.LE.0 .OR. INCX.LE.0) RETURN + IF (INCX.EQ.1) THEN +* +* code for increment equal to 1 +* +* +* clean-up loop +* + M = MOD(N,5) + IF (M.NE.0) THEN + DO I = 1,M + DX(I) = DA*DX(I) + END DO + IF (N.LT.5) RETURN + END IF + MP1 = M + 1 + DO I = MP1,N,5 + DX(I) = DA*DX(I) + DX(I+1) = DA*DX(I+1) + DX(I+2) = DA*DX(I+2) + DX(I+3) = DA*DX(I+3) + DX(I+4) = DA*DX(I+4) + END DO + ELSE +* +* code for increment not equal to 1 +* + NINCX = N*INCX + DO I = 1,NINCX,INCX + DX(I) = DA*DX(I) + END DO + END IF + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dtrmm.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dtrmm.f new file mode 100644 index 00000000..cbd5ce70 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dtrmm.f @@ -0,0 +1,415 @@ +*> \brief \b DTRMM +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB) +* +* .. Scalar Arguments .. +* DOUBLE PRECISION ALPHA +* INTEGER LDA,LDB,M,N +* CHARACTER DIAG,SIDE,TRANSA,UPLO +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A(LDA,*),B(LDB,*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DTRMM performs one of the matrix-matrix operations +*> +*> B := alpha*op( A )*B, or B := alpha*B*op( A ), +*> +*> where alpha is a scalar, B is an m by n matrix, A is a unit, or +*> non-unit, upper or lower triangular matrix and op( A ) is one of +*> +*> op( A ) = A or op( A ) = A**T. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SIDE +*> \verbatim +*> SIDE is CHARACTER*1 +*> On entry, SIDE specifies whether op( A ) multiplies B from +*> the left or right as follows: +*> +*> SIDE = 'L' or 'l' B := alpha*op( A )*B. +*> +*> SIDE = 'R' or 'r' B := alpha*B*op( A ). +*> \endverbatim +*> +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> On entry, UPLO specifies whether the matrix A is an upper or +*> lower triangular matrix as follows: +*> +*> UPLO = 'U' or 'u' A is an upper triangular matrix. +*> +*> UPLO = 'L' or 'l' A is a lower triangular matrix. +*> \endverbatim +*> +*> \param[in] TRANSA +*> \verbatim +*> TRANSA is CHARACTER*1 +*> On entry, TRANSA specifies the form of op( A ) to be used in +*> the matrix multiplication as follows: +*> +*> TRANSA = 'N' or 'n' op( A ) = A. +*> +*> TRANSA = 'T' or 't' op( A ) = A**T. +*> +*> TRANSA = 'C' or 'c' op( A ) = A**T. +*> \endverbatim +*> +*> \param[in] DIAG +*> \verbatim +*> DIAG is CHARACTER*1 +*> On entry, DIAG specifies whether or not A is unit triangular +*> as follows: +*> +*> DIAG = 'U' or 'u' A is assumed to be unit triangular. +*> +*> DIAG = 'N' or 'n' A is not assumed to be unit +*> triangular. +*> \endverbatim +*> +*> \param[in] M +*> \verbatim +*> M is INTEGER +*> On entry, M specifies the number of rows of B. M must be at +*> least zero. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> On entry, N specifies the number of columns of B. N must be +*> at least zero. +*> \endverbatim +*> +*> \param[in] ALPHA +*> \verbatim +*> ALPHA is DOUBLE PRECISION. +*> On entry, ALPHA specifies the scalar alpha. When alpha is +*> zero then A is not referenced and B need not be set before +*> entry. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array of DIMENSION ( LDA, k ), where k is m +*> when SIDE = 'L' or 'l' and is n when SIDE = 'R' or 'r'. +*> Before entry with UPLO = 'U' or 'u', the leading k by k +*> upper triangular part of the array A must contain the upper +*> triangular matrix and the strictly lower triangular part of +*> A is not referenced. +*> Before entry with UPLO = 'L' or 'l', the leading k by k +*> lower triangular part of the array A must contain the lower +*> triangular matrix and the strictly upper triangular part of +*> A is not referenced. +*> Note that when DIAG = 'U' or 'u', the diagonal elements of +*> A are not referenced either, but are assumed to be unity. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> On entry, LDA specifies the first dimension of A as declared +*> in the calling (sub) program. When SIDE = 'L' or 'l' then +*> LDA must be at least max( 1, m ), when SIDE = 'R' or 'r' +*> then LDA must be at least max( 1, n ). +*> \endverbatim +*> +*> \param[in,out] B +*> \verbatim +*> B is DOUBLE PRECISION array of DIMENSION ( LDB, n ). +*> Before entry, the leading m by n part of the array B must +*> contain the matrix B, and on exit is overwritten by the +*> transformed matrix. +*> \endverbatim +*> +*> \param[in] LDB +*> \verbatim +*> LDB is INTEGER +*> On entry, LDB specifies the first dimension of B as declared +*> in the calling (sub) program. LDB must be at least +*> max( 1, m ). +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup double_blas_level3 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Level 3 Blas routine. +*> +*> -- Written on 8-February-1989. +*> Jack Dongarra, Argonne National Laboratory. +*> Iain Duff, AERE Harwell. +*> Jeremy Du Croz, Numerical Algorithms Group Ltd. +*> Sven Hammarling, Numerical Algorithms Group Ltd. +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DTRMM(SIDE,UPLO,TRANSA,DIAG,M,N,ALPHA,A,LDA,B,LDB) +* +* -- Reference BLAS level3 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + DOUBLE PRECISION ALPHA + INTEGER LDA,LDB,M,N + CHARACTER DIAG,SIDE,TRANSA,UPLO +* .. +* .. Array Arguments .. + DOUBLE PRECISION A(LDA,*),B(LDB,*) +* .. +* +* ===================================================================== +* +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I,INFO,J,K,NROWA + LOGICAL LSIDE,NOUNIT,UPPER +* .. +* .. Parameters .. + DOUBLE PRECISION ONE,ZERO + PARAMETER (ONE=1.0D+0,ZERO=0.0D+0) +* .. +* +* Test the input parameters. +* + LSIDE = LSAME(SIDE,'L') + IF (LSIDE) THEN + NROWA = M + ELSE + NROWA = N + END IF + NOUNIT = LSAME(DIAG,'N') + UPPER = LSAME(UPLO,'U') +* + INFO = 0 + IF ((.NOT.LSIDE) .AND. (.NOT.LSAME(SIDE,'R'))) THEN + INFO = 1 + ELSE IF ((.NOT.UPPER) .AND. (.NOT.LSAME(UPLO,'L'))) THEN + INFO = 2 + ELSE IF ((.NOT.LSAME(TRANSA,'N')) .AND. + + (.NOT.LSAME(TRANSA,'T')) .AND. + + (.NOT.LSAME(TRANSA,'C'))) THEN + INFO = 3 + ELSE IF ((.NOT.LSAME(DIAG,'U')) .AND. (.NOT.LSAME(DIAG,'N'))) THEN + INFO = 4 + ELSE IF (M.LT.0) THEN + INFO = 5 + ELSE IF (N.LT.0) THEN + INFO = 6 + ELSE IF (LDA.LT.MAX(1,NROWA)) THEN + INFO = 9 + ELSE IF (LDB.LT.MAX(1,M)) THEN + INFO = 11 + END IF + IF (INFO.NE.0) THEN + CALL XERBLA('DTRMM ',INFO) + RETURN + END IF +* +* Quick return if possible. +* + IF (M.EQ.0 .OR. N.EQ.0) RETURN +* +* And when alpha.eq.zero. +* + IF (ALPHA.EQ.ZERO) THEN + DO 20 J = 1,N + DO 10 I = 1,M + B(I,J) = ZERO + 10 CONTINUE + 20 CONTINUE + RETURN + END IF +* +* Start the operations. +* + IF (LSIDE) THEN + IF (LSAME(TRANSA,'N')) THEN +* +* Form B := alpha*A*B. +* + IF (UPPER) THEN + DO 50 J = 1,N + DO 40 K = 1,M + IF (B(K,J).NE.ZERO) THEN + TEMP = ALPHA*B(K,J) + DO 30 I = 1,K - 1 + B(I,J) = B(I,J) + TEMP*A(I,K) + 30 CONTINUE + IF (NOUNIT) TEMP = TEMP*A(K,K) + B(K,J) = TEMP + END IF + 40 CONTINUE + 50 CONTINUE + ELSE + DO 80 J = 1,N + DO 70 K = M,1,-1 + IF (B(K,J).NE.ZERO) THEN + TEMP = ALPHA*B(K,J) + B(K,J) = TEMP + IF (NOUNIT) B(K,J) = B(K,J)*A(K,K) + DO 60 I = K + 1,M + B(I,J) = B(I,J) + TEMP*A(I,K) + 60 CONTINUE + END IF + 70 CONTINUE + 80 CONTINUE + END IF + ELSE +* +* Form B := alpha*A**T*B. +* + IF (UPPER) THEN + DO 110 J = 1,N + DO 100 I = M,1,-1 + TEMP = B(I,J) + IF (NOUNIT) TEMP = TEMP*A(I,I) + DO 90 K = 1,I - 1 + TEMP = TEMP + A(K,I)*B(K,J) + 90 CONTINUE + B(I,J) = ALPHA*TEMP + 100 CONTINUE + 110 CONTINUE + ELSE + DO 140 J = 1,N + DO 130 I = 1,M + TEMP = B(I,J) + IF (NOUNIT) TEMP = TEMP*A(I,I) + DO 120 K = I + 1,M + TEMP = TEMP + A(K,I)*B(K,J) + 120 CONTINUE + B(I,J) = ALPHA*TEMP + 130 CONTINUE + 140 CONTINUE + END IF + END IF + ELSE + IF (LSAME(TRANSA,'N')) THEN +* +* Form B := alpha*B*A. +* + IF (UPPER) THEN + DO 180 J = N,1,-1 + TEMP = ALPHA + IF (NOUNIT) TEMP = TEMP*A(J,J) + DO 150 I = 1,M + B(I,J) = TEMP*B(I,J) + 150 CONTINUE + DO 170 K = 1,J - 1 + IF (A(K,J).NE.ZERO) THEN + TEMP = ALPHA*A(K,J) + DO 160 I = 1,M + B(I,J) = B(I,J) + TEMP*B(I,K) + 160 CONTINUE + END IF + 170 CONTINUE + 180 CONTINUE + ELSE + DO 220 J = 1,N + TEMP = ALPHA + IF (NOUNIT) TEMP = TEMP*A(J,J) + DO 190 I = 1,M + B(I,J) = TEMP*B(I,J) + 190 CONTINUE + DO 210 K = J + 1,N + IF (A(K,J).NE.ZERO) THEN + TEMP = ALPHA*A(K,J) + DO 200 I = 1,M + B(I,J) = B(I,J) + TEMP*B(I,K) + 200 CONTINUE + END IF + 210 CONTINUE + 220 CONTINUE + END IF + ELSE +* +* Form B := alpha*B*A**T. +* + IF (UPPER) THEN + DO 260 K = 1,N + DO 240 J = 1,K - 1 + IF (A(J,K).NE.ZERO) THEN + TEMP = ALPHA*A(J,K) + DO 230 I = 1,M + B(I,J) = B(I,J) + TEMP*B(I,K) + 230 CONTINUE + END IF + 240 CONTINUE + TEMP = ALPHA + IF (NOUNIT) TEMP = TEMP*A(K,K) + IF (TEMP.NE.ONE) THEN + DO 250 I = 1,M + B(I,K) = TEMP*B(I,K) + 250 CONTINUE + END IF + 260 CONTINUE + ELSE + DO 300 K = N,1,-1 + DO 280 J = K + 1,N + IF (A(J,K).NE.ZERO) THEN + TEMP = ALPHA*A(J,K) + DO 270 I = 1,M + B(I,J) = B(I,J) + TEMP*B(I,K) + 270 CONTINUE + END IF + 280 CONTINUE + TEMP = ALPHA + IF (NOUNIT) TEMP = TEMP*A(K,K) + IF (TEMP.NE.ONE) THEN + DO 290 I = 1,M + B(I,K) = TEMP*B(I,K) + 290 CONTINUE + END IF + 300 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTRMM . +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dtrmv.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dtrmv.f new file mode 100644 index 00000000..71459fe7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/dtrmv.f @@ -0,0 +1,342 @@ +*> \brief \b DTRMV +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE DTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX) +* +* .. Scalar Arguments .. +* INTEGER INCX,LDA,N +* CHARACTER DIAG,TRANS,UPLO +* .. +* .. Array Arguments .. +* DOUBLE PRECISION A(LDA,*),X(*) +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> DTRMV performs one of the matrix-vector operations +*> +*> x := A*x, or x := A**T*x, +*> +*> where x is an n element vector and A is an n by n unit, or non-unit, +*> upper or lower triangular matrix. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] UPLO +*> \verbatim +*> UPLO is CHARACTER*1 +*> On entry, UPLO specifies whether the matrix is an upper or +*> lower triangular matrix as follows: +*> +*> UPLO = 'U' or 'u' A is an upper triangular matrix. +*> +*> UPLO = 'L' or 'l' A is a lower triangular matrix. +*> \endverbatim +*> +*> \param[in] TRANS +*> \verbatim +*> TRANS is CHARACTER*1 +*> On entry, TRANS specifies the operation to be performed as +*> follows: +*> +*> TRANS = 'N' or 'n' x := A*x. +*> +*> TRANS = 'T' or 't' x := A**T*x. +*> +*> TRANS = 'C' or 'c' x := A**T*x. +*> \endverbatim +*> +*> \param[in] DIAG +*> \verbatim +*> DIAG is CHARACTER*1 +*> On entry, DIAG specifies whether or not A is unit +*> triangular as follows: +*> +*> DIAG = 'U' or 'u' A is assumed to be unit triangular. +*> +*> DIAG = 'N' or 'n' A is not assumed to be unit +*> triangular. +*> \endverbatim +*> +*> \param[in] N +*> \verbatim +*> N is INTEGER +*> On entry, N specifies the order of the matrix A. +*> N must be at least zero. +*> \endverbatim +*> +*> \param[in] A +*> \verbatim +*> A is DOUBLE PRECISION array of DIMENSION ( LDA, n ). +*> Before entry with UPLO = 'U' or 'u', the leading n by n +*> upper triangular part of the array A must contain the upper +*> triangular matrix and the strictly lower triangular part of +*> A is not referenced. +*> Before entry with UPLO = 'L' or 'l', the leading n by n +*> lower triangular part of the array A must contain the lower +*> triangular matrix and the strictly upper triangular part of +*> A is not referenced. +*> Note that when DIAG = 'U' or 'u', the diagonal elements of +*> A are not referenced either, but are assumed to be unity. +*> \endverbatim +*> +*> \param[in] LDA +*> \verbatim +*> LDA is INTEGER +*> On entry, LDA specifies the first dimension of A as declared +*> in the calling (sub) program. LDA must be at least +*> max( 1, n ). +*> \endverbatim +*> +*> \param[in,out] X +*> \verbatim +*> X is DOUBLE PRECISION array of dimension at least +*> ( 1 + ( n - 1 )*abs( INCX ) ). +*> Before entry, the incremented array X must contain the n +*> element vector x. On exit, X is overwritten with the +*> tranformed vector x. +*> \endverbatim +*> +*> \param[in] INCX +*> \verbatim +*> INCX is INTEGER +*> On entry, INCX specifies the increment for the elements of +*> X. INCX must not be zero. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup double_blas_level2 +* +*> \par Further Details: +* ===================== +*> +*> \verbatim +*> +*> Level 2 Blas routine. +*> The vector and matrix arguments are not referenced when N = 0, or M = 0 +*> +*> -- Written on 22-October-1986. +*> Jack Dongarra, Argonne National Lab. +*> Jeremy Du Croz, Nag Central Office. +*> Sven Hammarling, Nag Central Office. +*> Richard Hanson, Sandia National Labs. +*> \endverbatim +*> +* ===================================================================== + SUBROUTINE DTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX) +* +* -- Reference BLAS level2 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + INTEGER INCX,LDA,N + CHARACTER DIAG,TRANS,UPLO +* .. +* .. Array Arguments .. + DOUBLE PRECISION A(LDA,*),X(*) +* .. +* +* ===================================================================== +* +* .. Parameters .. + DOUBLE PRECISION ZERO + PARAMETER (ZERO=0.0D+0) +* .. +* .. Local Scalars .. + DOUBLE PRECISION TEMP + INTEGER I,INFO,IX,J,JX,KX + LOGICAL NOUNIT +* .. +* .. External Functions .. + LOGICAL LSAME + EXTERNAL LSAME +* .. +* .. External Subroutines .. + EXTERNAL XERBLA +* .. +* .. Intrinsic Functions .. + INTRINSIC MAX +* .. +* +* Test the input parameters. +* + INFO = 0 + IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN + INFO = 1 + ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND. + + .NOT.LSAME(TRANS,'C')) THEN + INFO = 2 + ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN + INFO = 3 + ELSE IF (N.LT.0) THEN + INFO = 4 + ELSE IF (LDA.LT.MAX(1,N)) THEN + INFO = 6 + ELSE IF (INCX.EQ.0) THEN + INFO = 8 + END IF + IF (INFO.NE.0) THEN + CALL XERBLA('DTRMV ',INFO) + RETURN + END IF +* +* Quick return if possible. +* + IF (N.EQ.0) RETURN +* + NOUNIT = LSAME(DIAG,'N') +* +* Set up the start point in X if the increment is not unity. This +* will be ( N - 1 )*INCX too small for descending loops. +* + IF (INCX.LE.0) THEN + KX = 1 - (N-1)*INCX + ELSE IF (INCX.NE.1) THEN + KX = 1 + END IF +* +* Start the operations. In this version the elements of A are +* accessed sequentially with one pass through A. +* + IF (LSAME(TRANS,'N')) THEN +* +* Form x := A*x. +* + IF (LSAME(UPLO,'U')) THEN + IF (INCX.EQ.1) THEN + DO 20 J = 1,N + IF (X(J).NE.ZERO) THEN + TEMP = X(J) + DO 10 I = 1,J - 1 + X(I) = X(I) + TEMP*A(I,J) + 10 CONTINUE + IF (NOUNIT) X(J) = X(J)*A(J,J) + END IF + 20 CONTINUE + ELSE + JX = KX + DO 40 J = 1,N + IF (X(JX).NE.ZERO) THEN + TEMP = X(JX) + IX = KX + DO 30 I = 1,J - 1 + X(IX) = X(IX) + TEMP*A(I,J) + IX = IX + INCX + 30 CONTINUE + IF (NOUNIT) X(JX) = X(JX)*A(J,J) + END IF + JX = JX + INCX + 40 CONTINUE + END IF + ELSE + IF (INCX.EQ.1) THEN + DO 60 J = N,1,-1 + IF (X(J).NE.ZERO) THEN + TEMP = X(J) + DO 50 I = N,J + 1,-1 + X(I) = X(I) + TEMP*A(I,J) + 50 CONTINUE + IF (NOUNIT) X(J) = X(J)*A(J,J) + END IF + 60 CONTINUE + ELSE + KX = KX + (N-1)*INCX + JX = KX + DO 80 J = N,1,-1 + IF (X(JX).NE.ZERO) THEN + TEMP = X(JX) + IX = KX + DO 70 I = N,J + 1,-1 + X(IX) = X(IX) + TEMP*A(I,J) + IX = IX - INCX + 70 CONTINUE + IF (NOUNIT) X(JX) = X(JX)*A(J,J) + END IF + JX = JX - INCX + 80 CONTINUE + END IF + END IF + ELSE +* +* Form x := A**T*x. +* + IF (LSAME(UPLO,'U')) THEN + IF (INCX.EQ.1) THEN + DO 100 J = N,1,-1 + TEMP = X(J) + IF (NOUNIT) TEMP = TEMP*A(J,J) + DO 90 I = J - 1,1,-1 + TEMP = TEMP + A(I,J)*X(I) + 90 CONTINUE + X(J) = TEMP + 100 CONTINUE + ELSE + JX = KX + (N-1)*INCX + DO 120 J = N,1,-1 + TEMP = X(JX) + IX = JX + IF (NOUNIT) TEMP = TEMP*A(J,J) + DO 110 I = J - 1,1,-1 + IX = IX - INCX + TEMP = TEMP + A(I,J)*X(IX) + 110 CONTINUE + X(JX) = TEMP + JX = JX - INCX + 120 CONTINUE + END IF + ELSE + IF (INCX.EQ.1) THEN + DO 140 J = 1,N + TEMP = X(J) + IF (NOUNIT) TEMP = TEMP*A(J,J) + DO 130 I = J + 1,N + TEMP = TEMP + A(I,J)*X(I) + 130 CONTINUE + X(J) = TEMP + 140 CONTINUE + ELSE + JX = KX + DO 160 J = 1,N + TEMP = X(JX) + IX = JX + IF (NOUNIT) TEMP = TEMP*A(J,J) + DO 150 I = J + 1,N + IX = IX + INCX + TEMP = TEMP + A(I,J)*X(IX) + 150 CONTINUE + X(JX) = TEMP + JX = JX + INCX + 160 CONTINUE + END IF + END IF + END IF +* + RETURN +* +* End of DTRMV . +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/lsame.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/lsame.f new file mode 100644 index 00000000..315304c3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/lsame.f @@ -0,0 +1,125 @@ +*> \brief \b LSAME +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* LOGICAL FUNCTION LSAME( CA, CB ) +* +* .. Scalar Arguments .. +* CHARACTER CA, CB +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> LSAME returns .TRUE. if CA is the same letter as CB regardless of +*> case. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] CA +*> \verbatim +*> \endverbatim +*> +*> \param[in] CB +*> \verbatim +*> CA and CB specify the single characters to be compared. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup auxOTHERauxiliary +* +* ===================================================================== + LOGICAL FUNCTION LSAME( CA, CB ) +* +* -- LAPACK auxiliary routine (version 3.4.0) -- +* -- LAPACK is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER CA, CB +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC ICHAR +* .. +* .. Local Scalars .. + INTEGER INTA, INTB, ZCODE +* .. +* .. Executable Statements .. +* +* Test if the characters are equal +* + LSAME = CA.EQ.CB + IF( LSAME ) + $ RETURN +* +* Now test for equivalence if both characters are alphabetic. +* + ZCODE = ICHAR( 'Z' ) +* +* Use 'Z' rather than 'A' so that ASCII can be detected on Prime +* machines, on which ICHAR returns a value with bit 8 set. +* ICHAR('A') on Prime machines returns 193 which is the same as +* ICHAR('A') on an EBCDIC machine. +* + INTA = ICHAR( CA ) + INTB = ICHAR( CB ) +* + IF( ZCODE.EQ.90 .OR. ZCODE.EQ.122 ) THEN +* +* ASCII is assumed - ZCODE is the ASCII code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.97 .AND. INTA.LE.122 ) INTA = INTA - 32 + IF( INTB.GE.97 .AND. INTB.LE.122 ) INTB = INTB - 32 +* + ELSE IF( ZCODE.EQ.233 .OR. ZCODE.EQ.169 ) THEN +* +* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or +* upper case 'Z'. +* + IF( INTA.GE.129 .AND. INTA.LE.137 .OR. + $ INTA.GE.145 .AND. INTA.LE.153 .OR. + $ INTA.GE.162 .AND. INTA.LE.169 ) INTA = INTA + 64 + IF( INTB.GE.129 .AND. INTB.LE.137 .OR. + $ INTB.GE.145 .AND. INTB.LE.153 .OR. + $ INTB.GE.162 .AND. INTB.LE.169 ) INTB = INTB + 64 +* + ELSE IF( ZCODE.EQ.218 .OR. ZCODE.EQ.250 ) THEN +* +* ASCII is assumed, on Prime machines - ZCODE is the ASCII code +* plus 128 of either lower or upper case 'Z'. +* + IF( INTA.GE.225 .AND. INTA.LE.250 ) INTA = INTA - 32 + IF( INTB.GE.225 .AND. INTB.LE.250 ) INTB = INTB - 32 + END IF + LSAME = INTA.EQ.INTB +* +* RETURN +* +* End of LSAME +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/netlib.go b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/netlib.go new file mode 100644 index 00000000..182e074a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/netlib.go @@ -0,0 +1,68 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package netlib + +// void dlahr2_(int* n, int* k, int* nb, double* a, int* lda, double* tau, double* t, int* ldt, double* y, int* ldy); +// +// void dlaqr5_(int* wantt, int* wantz, int* kacc22, int* n, int* ktop, int* kbot, int* nshfts, +// double* sr, double* si, double* h, int* ldh, int* iloz, int* ihiz, +// double* z, int* ldz, double* v, int* ldv, double* u, int* ldu, +// int* nv, double* wv, int* ldwv, int* nh, double* wh, int* ldwh); +import "C" + +func Dlahr2(n, k, nb int, a []float64, lda int, tau, t []float64, ldt int, y []float64, ldy int) { + func() { + n := C.int(n) + k := C.int(k) + nb := C.int(nb) + lda := C.int(lda) + ldt := C.int(ldt) + ldy := C.int(ldy) + C.dlahr2_((*C.int)(&n), (*C.int)(&k), (*C.int)(&nb), + (*C.double)(&a[0]), (*C.int)(&lda), + (*C.double)(&tau[0]), + (*C.double)(&t[0]), (*C.int)(&ldt), + (*C.double)(&y[0]), (*C.int)(&ldy)) + }() +} + +func Dlaqr5(wantt, wantz bool, kacc22 int, n, ktop, kbot int, nshfts int, sr, si []float64, h []float64, + ldh int, iloz, ihiz int, z []float64, ldz int, v []float64, ldv int, + u []float64, ldu int, nh int, wh []float64, ldwh int, nv int, wv []float64, ldwv int) { + func() { + wt := C.int(0) + if wantt { + wt = 1 + } + wz := C.int(0) + if wantz { + wz = 1 + } + kacc22 := C.int(kacc22) + n := C.int(n) + ktop := C.int(ktop) + kbot := C.int(kbot) + nshfts := C.int(nshfts) + ldh := C.int(ldh) + iloz := C.int(iloz) + ihiz := C.int(ihiz) + ldz := C.int(ldz) + ldv := C.int(ldv) + ldu := C.int(ldu) + nh := C.int(nh) + ldwh := C.int(ldwh) + nv := C.int(nv) + ldwv := C.int(ldwv) + C.dlaqr5_((*C.int)(&wt), (*C.int)(&wz), (*C.int)(&kacc22), + (*C.int)(&n), (*C.int)(&ktop), (*C.int)(&kbot), + (*C.int)(&nshfts), (*C.double)(&sr[0]), (*C.double)(&si[0]), + (*C.double)(&h[0]), (*C.int)(&ldh), + (*C.int)(&iloz), (*C.int)(&ihiz), (*C.double)(&z[0]), (*C.int)(&ldz), + (*C.double)(&v[0]), (*C.int)(&ldv), + (*C.double)(&u[0]), (*C.int)(&ldu), + (*C.int)(&nh), (*C.double)(&wh[0]), (*C.int)(&ldwh), + (*C.int)(&nv), (*C.double)(&wv[0]), (*C.int)(&ldwv)) + }() +} diff --git a/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/xerbla.f b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/xerbla.f new file mode 100644 index 00000000..eb1c037d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/internal/testdata/netlib/xerbla.f @@ -0,0 +1,89 @@ +*> \brief \b XERBLA +* +* =========== DOCUMENTATION =========== +* +* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +* +* Definition: +* =========== +* +* SUBROUTINE XERBLA( SRNAME, INFO ) +* +* .. Scalar Arguments .. +* CHARACTER*(*) SRNAME +* INTEGER INFO +* .. +* +* +*> \par Purpose: +* ============= +*> +*> \verbatim +*> +*> XERBLA is an error handler for the LAPACK routines. +*> It is called by an LAPACK routine if an input parameter has an +*> invalid value. A message is printed and execution stops. +*> +*> Installers may consider modifying the STOP statement in order to +*> call system-specific exception-handling facilities. +*> \endverbatim +* +* Arguments: +* ========== +* +*> \param[in] SRNAME +*> \verbatim +*> SRNAME is CHARACTER*(*) +*> The name of the routine which called XERBLA. +*> \endverbatim +*> +*> \param[in] INFO +*> \verbatim +*> INFO is INTEGER +*> The position of the invalid parameter in the parameter list +*> of the calling routine. +*> \endverbatim +* +* Authors: +* ======== +* +*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +* +*> \date November 2011 +* +*> \ingroup aux_blas +* +* ===================================================================== + SUBROUTINE XERBLA( SRNAME, INFO ) +* +* -- Reference BLAS level1 routine (version 3.4.0) -- +* -- Reference BLAS is a software package provided by Univ. of Tennessee, -- +* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- +* November 2011 +* +* .. Scalar Arguments .. + CHARACTER*(*) SRNAME + INTEGER INFO +* .. +* +* ===================================================================== +* +* .. Intrinsic Functions .. + INTRINSIC LEN_TRIM +* .. +* .. Executable Statements .. +* + WRITE( *, FMT = 9999 )SRNAME( 1:LEN_TRIM( SRNAME ) ), INFO +* + STOP +* + 9999 FORMAT( ' ** On entry to ', A, ' parameter number ', I2, ' had ', + $ 'an illegal value' ) +* +* End of XERBLA +* + END diff --git a/vendor/gonum.org/v1/gonum/lapack/lapack.go b/vendor/gonum.org/v1/gonum/lapack/lapack.go new file mode 100644 index 00000000..c78d19c8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/lapack.go @@ -0,0 +1,188 @@ +// 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 lapack // import "gonum.org/v1/gonum/lapack" + +import "gonum.org/v1/gonum/blas" + +const None = 'N' + +type Job byte + +type Comp byte + +// Complex128 defines the public complex128 LAPACK API supported by gonum/lapack. +type Complex128 interface{} + +// Float64 defines the public float64 LAPACK API supported by gonum/lapack. +type Float64 interface { + Dgecon(norm MatrixNorm, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 + Dgeev(jobvl LeftEVJob, jobvr RightEVJob, n int, a []float64, lda int, wr, wi []float64, vl []float64, ldvl int, vr []float64, ldvr int, work []float64, lwork int) (first int) + Dgels(trans blas.Transpose, m, n, nrhs int, a []float64, lda int, b []float64, ldb int, work []float64, lwork int) bool + Dgelqf(m, n int, a []float64, lda int, tau, work []float64, lwork int) + Dgeqrf(m, n int, a []float64, lda int, tau, work []float64, lwork int) + Dgesvd(jobU, jobVT SVDJob, m, n int, a []float64, lda int, s, u []float64, ldu int, vt []float64, ldvt int, work []float64, lwork int) (ok bool) + Dgetrf(m, n int, a []float64, lda int, ipiv []int) (ok bool) + Dgetri(n int, a []float64, lda int, ipiv []int, work []float64, lwork int) (ok bool) + Dgetrs(trans blas.Transpose, n, nrhs int, a []float64, lda int, ipiv []int, b []float64, ldb int) + Dggsvd3(jobU, jobV, jobQ GSVDJob, m, n, p int, a []float64, lda int, b []float64, ldb int, alpha, beta, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, work []float64, lwork int, iwork []int) (k, l int, ok bool) + Dlantr(norm MatrixNorm, uplo blas.Uplo, diag blas.Diag, m, n int, a []float64, lda int, work []float64) float64 + Dlange(norm MatrixNorm, m, n int, a []float64, lda int, work []float64) float64 + Dlansy(norm MatrixNorm, uplo blas.Uplo, n int, a []float64, lda int, work []float64) float64 + Dlapmt(forward bool, m, n int, x []float64, ldx int, k []int) + Dormqr(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) + Dormlq(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) + Dpocon(uplo blas.Uplo, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 + Dpotrf(ul blas.Uplo, n int, a []float64, lda int) (ok bool) + Dsyev(jobz EVJob, uplo blas.Uplo, n int, a []float64, lda int, w, work []float64, lwork int) (ok bool) + Dtrcon(norm MatrixNorm, uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int, work []float64, iwork []int) float64 + Dtrtri(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) (ok bool) + Dtrtrs(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n, nrhs int, a []float64, lda int, b []float64, ldb int) (ok bool) +} + +// Direct specifies the direction of the multiplication for the Householder matrix. +type Direct byte + +const ( + Forward Direct = 'F' // Reflectors are right-multiplied, H_0 * H_1 * ... * H_{k-1}. + Backward Direct = 'B' // Reflectors are left-multiplied, H_{k-1} * ... * H_1 * H_0. +) + +// Sort is the sorting order. +type Sort byte + +const ( + SortIncreasing Sort = 'I' + SortDecreasing Sort = 'D' +) + +// StoreV indicates the storage direction of elementary reflectors. +type StoreV byte + +const ( + ColumnWise StoreV = 'C' // Reflector stored in a column of the matrix. + RowWise StoreV = 'R' // Reflector stored in a row of the matrix. +) + +// MatrixNorm represents the kind of matrix norm to compute. +type MatrixNorm byte + +const ( + MaxAbs MatrixNorm = 'M' // max(abs(A(i,j))) ('M') + MaxColumnSum MatrixNorm = 'O' // Maximum column sum (one norm) ('1', 'O') + MaxRowSum MatrixNorm = 'I' // Maximum row sum (infinity norm) ('I', 'i') + NormFrob MatrixNorm = 'F' // Frobenius norm (sqrt of sum of squares) ('F', 'f', E, 'e') +) + +// MatrixType represents the kind of matrix represented in the data. +type MatrixType byte + +const ( + General MatrixType = 'G' // A dense matrix (like blas64.General). + UpperTri MatrixType = 'U' // An upper triangular matrix. + LowerTri MatrixType = 'L' // A lower triangular matrix. +) + +// Pivot specifies the pivot type for plane rotations +type Pivot byte + +const ( + Variable Pivot = 'V' + Top Pivot = 'T' + Bottom Pivot = 'B' +) + +type DecompUpdate byte + +const ( + ApplyP DecompUpdate = 'P' + ApplyQ DecompUpdate = 'Q' +) + +// SVDJob specifies the singular vector computation type for SVD. +type SVDJob byte + +const ( + SVDAll SVDJob = 'A' // Compute all singular vectors + SVDInPlace SVDJob = 'S' // Compute the first singular vectors and store them in provided storage. + SVDOverwrite SVDJob = 'O' // Compute the singular vectors and store them in input matrix + SVDNone SVDJob = 'N' // Do not compute singular vectors +) + +// GSVDJob specifies the singular vector computation type for Generalized SVD. +type GSVDJob byte + +const ( + GSVDU GSVDJob = 'U' // Compute orthogonal matrix U + GSVDV GSVDJob = 'V' // Compute orthogonal matrix V + GSVDQ GSVDJob = 'Q' // Compute orthogonal matrix Q + GSVDUnit GSVDJob = 'I' // Use unit-initialized matrix + GSVDNone GSVDJob = 'N' // Do not compute orthogonal matrix +) + +// EVComp specifies how eigenvectors are computed. +type EVComp byte + +const ( + // OriginalEV specifies to compute the eigenvectors of the original + // matrix. + OriginalEV EVComp = 'V' + // TridiagEV specifies to compute both the eigenvectors of the input + // tridiagonal matrix. + TridiagEV EVComp = 'I' + // HessEV specifies to compute both the eigenvectors of the input upper + // Hessenberg matrix. + HessEV EVComp = 'I' + + // UpdateSchur specifies that the matrix of Schur vectors will be + // updated by Dtrexc. + UpdateSchur EVComp = 'V' +) + +// Job types for computation of eigenvectors. +type ( + EVJob byte + LeftEVJob byte + RightEVJob byte +) + +// Job constants for computation of eigenvectors. +const ( + ComputeEV EVJob = 'V' // Compute eigenvectors in Dsyev. + ComputeLeftEV LeftEVJob = 'V' // Compute left eigenvectors. + ComputeRightEV RightEVJob = 'V' // Compute right eigenvectors. +) + +// Jobs for Dgebal. +const ( + Permute Job = 'P' + Scale Job = 'S' + PermuteScale Job = 'B' +) + +// Job constants for Dhseqr. +const ( + EigenvaluesOnly EVJob = 'E' + EigenvaluesAndSchur EVJob = 'S' +) + +// EVSide specifies what eigenvectors will be computed. +type EVSide byte + +// EVSide constants for Dtrevc3. +const ( + RightEV EVSide = 'R' // Compute right eigenvectors only. + LeftEV EVSide = 'L' // Compute left eigenvectors only. + RightLeftEV EVSide = 'B' // Compute both right and left eigenvectors. +) + +// HowMany specifies which eigenvectors will be computed. +type HowMany byte + +// HowMany constants for Dhseqr. +const ( + AllEV HowMany = 'A' // Compute all right and/or left eigenvectors. + AllEVMulQ HowMany = 'B' // Compute all right and/or left eigenvectors multiplied by an input matrix. + SelectedEV HowMany = 'S' // Compute selected right and/or left eigenvectors. +) diff --git a/vendor/gonum.org/v1/gonum/lapack/lapack64/doc.go b/vendor/gonum.org/v1/gonum/lapack/lapack64/doc.go new file mode 100644 index 00000000..07071df8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/lapack64/doc.go @@ -0,0 +1,20 @@ +// 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 lapack64 provides a set of convenient wrapper functions for LAPACK +// calls, as specified in the netlib standard (www.netlib.org). +// +// The native Go routines are used by default, and the Use function can be used +// to set an alternative implementation. +// +// If the type of matrix (General, Symmetric, etc.) is known and fixed, it is +// used in the wrapper signature. In many cases, however, the type of the matrix +// changes during the call to the routine, for example the matrix is symmetric on +// entry and is triangular on exit. In these cases the correct types should be checked +// in the documentation. +// +// The full set of Lapack functions is very large, and it is not clear that a +// full implementation is desirable, let alone feasible. Please open up an issue +// if there is a specific function you need and/or are willing to implement. +package lapack64 // import "gonum.org/v1/gonum/lapack/lapack64" diff --git a/vendor/gonum.org/v1/gonum/lapack/lapack64/lapack64.go b/vendor/gonum.org/v1/gonum/lapack/lapack64/lapack64.go new file mode 100644 index 00000000..f93e9207 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/lapack64/lapack64.go @@ -0,0 +1,545 @@ +// 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 lapack64 + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/gonum" +) + +var lapack64 lapack.Float64 = gonum.Implementation{} + +// Use sets the LAPACK float64 implementation to be used by subsequent BLAS calls. +// The default implementation is native.Implementation. +func Use(l lapack.Float64) { + lapack64 = l +} + +// Potrf computes the Cholesky factorization of a. +// The factorization has the form +// A = U^T * U if a.Uplo == blas.Upper, or +// A = L * L^T if a.Uplo == blas.Lower, +// where U is an upper triangular matrix and L is lower triangular. +// The triangular matrix is returned in t, and the underlying data between +// a and t is shared. The returned bool indicates whether a is positive +// definite and the factorization could be finished. +func Potrf(a blas64.Symmetric) (t blas64.Triangular, ok bool) { + ok = lapack64.Dpotrf(a.Uplo, a.N, a.Data, a.Stride) + t.Uplo = a.Uplo + t.N = a.N + t.Data = a.Data + t.Stride = a.Stride + t.Diag = blas.NonUnit + return +} + +// Gecon estimates the reciprocal of the condition number of the n×n matrix A +// given the LU decomposition of the matrix. The condition number computed may +// be based on the 1-norm or the ∞-norm. +// +// a contains the result of the LU decomposition of A as computed by Getrf. +// +// anorm is the corresponding 1-norm or ∞-norm of the original matrix A. +// +// work is a temporary data slice of length at least 4*n and Gecon will panic otherwise. +// +// iwork is a temporary data slice of length at least n and Gecon will panic otherwise. +func Gecon(norm lapack.MatrixNorm, a blas64.General, anorm float64, work []float64, iwork []int) float64 { + return lapack64.Dgecon(norm, a.Cols, a.Data, a.Stride, anorm, work, iwork) +} + +// Gels finds a minimum-norm solution based on the matrices A and B using the +// QR or LQ factorization. Gels returns false if the matrix +// A is singular, and true if this solution was successfully found. +// +// The minimization problem solved depends on the input parameters. +// +// 1. If m >= n and trans == blas.NoTrans, Gels finds X such that || A*X - B||_2 +// is minimized. +// 2. If m < n and trans == blas.NoTrans, Gels finds the minimum norm solution of +// A * X = B. +// 3. If m >= n and trans == blas.Trans, Gels finds the minimum norm solution of +// A^T * X = B. +// 4. If m < n and trans == blas.Trans, Gels finds X such that || A*X - B||_2 +// is minimized. +// Note that the least-squares solutions (cases 1 and 3) perform the minimization +// per column of B. This is not the same as finding the minimum-norm matrix. +// +// The matrix A is a general matrix of size m×n and is modified during this call. +// The input matrix B is of size max(m,n)×nrhs, and serves two purposes. On entry, +// the elements of b specify the input matrix B. B has size m×nrhs if +// trans == blas.NoTrans, and n×nrhs if trans == blas.Trans. On exit, the +// leading submatrix of b contains the solution vectors X. If trans == blas.NoTrans, +// this submatrix is of size n×nrhs, and of size m×nrhs otherwise. +// +// Work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= max(m,n) + max(m,n,nrhs), and this function will panic +// otherwise. A longer work will enable blocked algorithms to be called. +// In the special case that lwork == -1, work[0] will be set to the optimal working +// length. +func Gels(trans blas.Transpose, a blas64.General, b blas64.General, work []float64, lwork int) bool { + return lapack64.Dgels(trans, a.Rows, a.Cols, b.Cols, a.Data, a.Stride, b.Data, b.Stride, work, lwork) +} + +// Geqrf computes the QR factorization of the m×n matrix A using a blocked +// algorithm. A is modified to contain the information to construct Q and R. +// The upper triangle of a contains the matrix R. The lower triangular elements +// (not including the diagonal) contain the elementary reflectors. tau is modified +// to contain the reflector scales. tau must have length at least min(m,n), and +// this function will panic otherwise. +// +// The ith elementary reflector can be explicitly constructed by first extracting +// the +// v[j] = 0 j < i +// v[j] = 1 j == i +// v[j] = a[j*lda+i] j > i +// and computing H_i = I - tau[i] * v * v^T. +// +// The orthonormal matrix Q can be constucted from a product of these elementary +// reflectors, Q = H_0 * H_1 * ... * H_{k-1}, where k = min(m,n). +// +// Work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= m and this function will panic otherwise. +// Geqrf is a blocked QR factorization, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Geqrf, +// the optimal work length will be stored into work[0]. +func Geqrf(a blas64.General, tau, work []float64, lwork int) { + lapack64.Dgeqrf(a.Rows, a.Cols, a.Data, a.Stride, tau, work, lwork) +} + +// Gelqf computes the LQ factorization of the m×n matrix A using a blocked +// algorithm. A is modified to contain the information to construct L and Q. The +// lower triangle of a contains the matrix L. The elements above the diagonal +// and the slice tau represent the matrix Q. tau is modified to contain the +// reflector scales. tau must have length at least min(m,n), and this function +// will panic otherwise. +// +// See Geqrf for a description of the elementary reflectors and orthonormal +// matrix Q. Q is constructed as a product of these elementary reflectors, +// Q = H_{k-1} * ... * H_1 * H_0. +// +// Work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= m and this function will panic otherwise. +// Gelqf is a blocked LQ factorization, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Gelqf, +// the optimal work length will be stored into work[0]. +func Gelqf(a blas64.General, tau, work []float64, lwork int) { + lapack64.Dgelqf(a.Rows, a.Cols, a.Data, a.Stride, tau, work, lwork) +} + +// Gesvd computes the singular value decomposition of the input matrix A. +// +// The singular value decomposition is +// A = U * Sigma * V^T +// where Sigma is an m×n diagonal matrix containing the singular values of A, +// U is an m×m orthogonal matrix and V is an n×n orthogonal matrix. The first +// min(m,n) columns of U and V are the left and right singular vectors of A +// respectively. +// +// jobU and jobVT are options for computing the singular vectors. The behavior +// is as follows +// jobU == lapack.SVDAll All m columns of U are returned in u +// jobU == lapack.SVDInPlace The first min(m,n) columns are returned in u +// jobU == lapack.SVDOverwrite The first min(m,n) columns of U are written into a +// jobU == lapack.SVDNone The columns of U are not computed. +// The behavior is the same for jobVT and the rows of V^T. At most one of jobU +// and jobVT can equal lapack.SVDOverwrite, and Gesvd will panic otherwise. +// +// On entry, a contains the data for the m×n matrix A. During the call to Gesvd +// the data is overwritten. On exit, A contains the appropriate singular vectors +// if either job is lapack.SVDOverwrite. +// +// s is a slice of length at least min(m,n) and on exit contains the singular +// values in decreasing order. +// +// u contains the left singular vectors on exit, stored columnwise. If +// jobU == lapack.SVDAll, u is of size m×m. If jobU == lapack.SVDInPlace u is +// of size m×min(m,n). If jobU == lapack.SVDOverwrite or lapack.SVDNone, u is +// not used. +// +// vt contains the left singular vectors on exit, stored rowwise. If +// jobV == lapack.SVDAll, vt is of size n×m. If jobVT == lapack.SVDInPlace vt is +// of size min(m,n)×n. If jobVT == lapack.SVDOverwrite or lapack.SVDNone, vt is +// not used. +// +// work is a slice for storing temporary memory, and lwork is the usable size of +// the slice. lwork must be at least max(5*min(m,n), 3*min(m,n)+max(m,n)). +// If lwork == -1, instead of performing Gesvd, the optimal work length will be +// stored into work[0]. Gesvd will panic if the working memory has insufficient +// storage. +// +// Gesvd returns whether the decomposition successfully completed. +func Gesvd(jobU, jobVT lapack.SVDJob, a, u, vt blas64.General, s, work []float64, lwork int) (ok bool) { + return lapack64.Dgesvd(jobU, jobVT, a.Rows, a.Cols, a.Data, a.Stride, s, u.Data, u.Stride, vt.Data, vt.Stride, work, lwork) +} + +// Getrf computes the LU decomposition of the m×n matrix A. +// The LU decomposition is a factorization of A into +// A = P * L * U +// where P is a permutation matrix, L is a unit lower triangular matrix, and +// U is a (usually) non-unit upper triangular matrix. On exit, L and U are stored +// in place into a. +// +// ipiv is a permutation vector. It indicates that row i of the matrix was +// changed with ipiv[i]. ipiv must have length at least min(m,n), and will panic +// otherwise. ipiv is zero-indexed. +// +// Getrf is the blocked version of the algorithm. +// +// Getrf returns whether the matrix A is singular. The LU decomposition will +// be computed regardless of the singularity of A, but division by zero +// will occur if the false is returned and the result is used to solve a +// system of equations. +func Getrf(a blas64.General, ipiv []int) bool { + return lapack64.Dgetrf(a.Rows, a.Cols, a.Data, a.Stride, ipiv) +} + +// Getri computes the inverse of the matrix A using the LU factorization computed +// by Getrf. On entry, a contains the PLU decomposition of A as computed by +// Getrf and on exit contains the reciprocal of the original matrix. +// +// Getri will not perform the inversion if the matrix is singular, and returns +// a boolean indicating whether the inversion was successful. +// +// Work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= n and this function will panic otherwise. +// Getri is a blocked inversion, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Getri, +// the optimal work length will be stored into work[0]. +func Getri(a blas64.General, ipiv []int, work []float64, lwork int) (ok bool) { + return lapack64.Dgetri(a.Cols, a.Data, a.Stride, ipiv, work, lwork) +} + +// Getrs solves a system of equations using an LU factorization. +// The system of equations solved is +// A * X = B if trans == blas.Trans +// A^T * X = B if trans == blas.NoTrans +// A is a general n×n matrix with stride lda. B is a general matrix of size n×nrhs. +// +// On entry b contains the elements of the matrix B. On exit, b contains the +// elements of X, the solution to the system of equations. +// +// a and ipiv contain the LU factorization of A and the permutation indices as +// computed by Getrf. ipiv is zero-indexed. +func Getrs(trans blas.Transpose, a blas64.General, b blas64.General, ipiv []int) { + lapack64.Dgetrs(trans, a.Cols, b.Cols, a.Data, a.Stride, ipiv, b.Data, b.Stride) +} + +// Ggsvd3 computes the generalized singular value decomposition (GSVD) +// of an m×n matrix A and p×n matrix B: +// U^T*A*Q = D1*[ 0 R ] +// +// V^T*B*Q = D2*[ 0 R ] +// where U, V and Q are orthogonal matrices. +// +// Ggsvd3 returns k and l, the dimensions of the sub-blocks. k+l +// is the effective numerical rank of the (m+p)×n matrix [ A^T B^T ]^T. +// R is a (k+l)×(k+l) nonsingular upper triangular matrix, D1 and +// D2 are m×(k+l) and p×(k+l) diagonal matrices and of the following +// structures, respectively: +// +// If m-k-l >= 0, +// +// k l +// D1 = k [ I 0 ] +// l [ 0 C ] +// m-k-l [ 0 0 ] +// +// k l +// D2 = l [ 0 S ] +// p-l [ 0 0 ] +// +// n-k-l k l +// [ 0 R ] = k [ 0 R11 R12 ] k +// l [ 0 0 R22 ] l +// +// where +// +// C = diag( alpha_k, ... , alpha_{k+l} ), +// S = diag( beta_k, ... , beta_{k+l} ), +// C^2 + S^2 = I. +// +// R is stored in +// A[0:k+l, n-k-l:n] +// on exit. +// +// If m-k-l < 0, +// +// k m-k k+l-m +// D1 = k [ I 0 0 ] +// m-k [ 0 C 0 ] +// +// k m-k k+l-m +// D2 = m-k [ 0 S 0 ] +// k+l-m [ 0 0 I ] +// p-l [ 0 0 0 ] +// +// n-k-l k m-k k+l-m +// [ 0 R ] = k [ 0 R11 R12 R13 ] +// m-k [ 0 0 R22 R23 ] +// k+l-m [ 0 0 0 R33 ] +// +// where +// C = diag( alpha_k, ... , alpha_m ), +// S = diag( beta_k, ... , beta_m ), +// C^2 + S^2 = I. +// +// R = [ R11 R12 R13 ] is stored in A[1:m, n-k-l+1:n] +// [ 0 R22 R23 ] +// and R33 is stored in +// B[m-k:l, n+m-k-l:n] on exit. +// +// Ggsvd3 computes C, S, R, and optionally the orthogonal transformation +// matrices U, V and Q. +// +// jobU, jobV and jobQ are options for computing the orthogonal matrices. The behavior +// is as follows +// jobU == lapack.GSVDU Compute orthogonal matrix U +// jobU == lapack.GSVDNone Do not compute orthogonal matrix. +// The behavior is the same for jobV and jobQ with the exception that instead of +// lapack.GSVDU these accept lapack.GSVDV and lapack.GSVDQ respectively. +// The matrices U, V and Q must be m×m, p×p and n×n respectively unless the +// relevant job parameter is lapack.GSVDNone. +// +// alpha and beta must have length n or Ggsvd3 will panic. On exit, alpha and +// beta contain the generalized singular value pairs of A and B +// alpha[0:k] = 1, +// beta[0:k] = 0, +// if m-k-l >= 0, +// alpha[k:k+l] = diag(C), +// beta[k:k+l] = diag(S), +// if m-k-l < 0, +// alpha[k:m]= C, alpha[m:k+l]= 0 +// beta[k:m] = S, beta[m:k+l] = 1. +// if k+l < n, +// alpha[k+l:n] = 0 and +// beta[k+l:n] = 0. +// +// On exit, iwork contains the permutation required to sort alpha descending. +// +// iwork must have length n, work must have length at least max(1, lwork), and +// lwork must be -1 or greater than n, otherwise Ggsvd3 will panic. If +// lwork is -1, work[0] holds the optimal lwork on return, but Ggsvd3 does +// not perform the GSVD. +func Ggsvd3(jobU, jobV, jobQ lapack.GSVDJob, a, b blas64.General, alpha, beta []float64, u, v, q blas64.General, work []float64, lwork int, iwork []int) (k, l int, ok bool) { + return lapack64.Dggsvd3(jobU, jobV, jobQ, a.Rows, a.Cols, b.Rows, a.Data, a.Stride, b.Data, b.Stride, alpha, beta, u.Data, u.Stride, v.Data, v.Stride, q.Data, q.Stride, work, lwork, iwork) +} + +// Lange computes the matrix norm of the general m×n matrix A. The input norm +// specifies the norm computed. +// lapack.MaxAbs: the maximum absolute value of an element. +// lapack.MaxColumnSum: the maximum column sum of the absolute values of the entries. +// lapack.MaxRowSum: the maximum row sum of the absolute values of the entries. +// lapack.Frobenius: the square root of the sum of the squares of the entries. +// If norm == lapack.MaxColumnSum, work must be of length n, and this function will panic otherwise. +// There are no restrictions on work for the other matrix norms. +func Lange(norm lapack.MatrixNorm, a blas64.General, work []float64) float64 { + return lapack64.Dlange(norm, a.Rows, a.Cols, a.Data, a.Stride, work) +} + +// Lansy computes the specified norm of an n×n symmetric matrix. If +// norm == lapack.MaxColumnSum or norm == lapackMaxRowSum work must have length +// at least n and this function will panic otherwise. +// There are no restrictions on work for the other matrix norms. +func Lansy(norm lapack.MatrixNorm, a blas64.Symmetric, work []float64) float64 { + return lapack64.Dlansy(norm, a.Uplo, a.N, a.Data, a.Stride, work) +} + +// Lantr computes the specified norm of an m×n trapezoidal matrix A. If +// norm == lapack.MaxColumnSum work must have length at least n and this function +// will panic otherwise. There are no restrictions on work for the other matrix norms. +func Lantr(norm lapack.MatrixNorm, a blas64.Triangular, work []float64) float64 { + return lapack64.Dlantr(norm, a.Uplo, a.Diag, a.N, a.N, a.Data, a.Stride, work) +} + +// Lapmt rearranges the columns of the m×n matrix X as specified by the +// permutation k_0, k_1, ..., k_{n-1} of the integers 0, ..., n-1. +// +// If forward is true a forward permutation is performed: +// +// X[0:m, k[j]] is moved to X[0:m, j] for j = 0, 1, ..., n-1. +// +// otherwise a backward permutation is performed: +// +// X[0:m, j] is moved to X[0:m, k[j]] for j = 0, 1, ..., n-1. +// +// k must have length n, otherwise Lapmt will panic. k is zero-indexed. +func Lapmt(forward bool, x blas64.General, k []int) { + lapack64.Dlapmt(forward, x.Rows, x.Cols, x.Data, x.Stride, k) +} + +// Ormlq multiplies the matrix C by the othogonal matrix Q defined by +// A and tau. A and tau are as returned from Gelqf. +// C = Q * C if side == blas.Left and trans == blas.NoTrans +// C = Q^T * C if side == blas.Left and trans == blas.Trans +// C = C * Q if side == blas.Right and trans == blas.NoTrans +// C = C * Q^T if side == blas.Right and trans == blas.Trans +// If side == blas.Left, A is a matrix of side k×m, and if side == blas.Right +// A is of size k×n. This uses a blocked algorithm. +// +// Work is temporary storage, and lwork specifies the usable memory length. +// At minimum, lwork >= m if side == blas.Left and lwork >= n if side == blas.Right, +// and this function will panic otherwise. +// Ormlq uses a block algorithm, but the block size is limited +// by the temporary space available. If lwork == -1, instead of performing Ormlq, +// the optimal work length will be stored into work[0]. +// +// Tau contains the Householder scales and must have length at least k, and +// this function will panic otherwise. +func Ormlq(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { + lapack64.Dormlq(side, trans, c.Rows, c.Cols, a.Rows, a.Data, a.Stride, tau, c.Data, c.Stride, work, lwork) +} + +// Ormqr multiplies an m×n matrix C by an orthogonal matrix Q as +// C = Q * C, if side == blas.Left and trans == blas.NoTrans, +// C = Q^T * C, if side == blas.Left and trans == blas.Trans, +// C = C * Q, if side == blas.Right and trans == blas.NoTrans, +// C = C * Q^T, if side == blas.Right and trans == blas.Trans, +// where Q is defined as the product of k elementary reflectors +// Q = H_0 * H_1 * ... * H_{k-1}. +// +// If side == blas.Left, A is an m×k matrix and 0 <= k <= m. +// If side == blas.Right, A is an n×k matrix and 0 <= k <= n. +// The ith column of A contains the vector which defines the elementary +// reflector H_i and tau[i] contains its scalar factor. tau must have length k +// and Ormqr will panic otherwise. Geqrf returns A and tau in the required +// form. +// +// work must have length at least max(1,lwork), and lwork must be at least n if +// side == blas.Left and at least m if side == blas.Right, otherwise Ormqr will +// panic. +// +// work is temporary storage, and lwork specifies the usable memory length. At +// minimum, lwork >= m if side == blas.Left and lwork >= n if side == +// blas.Right, and this function will panic otherwise. Larger values of lwork +// will generally give better performance. On return, work[0] will contain the +// optimal value of lwork. +// +// If lwork is -1, instead of performing Ormqr, the optimal workspace size will +// be stored into work[0]. +func Ormqr(side blas.Side, trans blas.Transpose, a blas64.General, tau []float64, c blas64.General, work []float64, lwork int) { + lapack64.Dormqr(side, trans, c.Rows, c.Cols, a.Cols, a.Data, a.Stride, tau, c.Data, c.Stride, work, lwork) +} + +// Pocon estimates the reciprocal of the condition number of a positive-definite +// matrix A given the Cholesky decmposition of A. The condition number computed +// is based on the 1-norm and the ∞-norm. +// +// anorm is the 1-norm and the ∞-norm of the original matrix A. +// +// work is a temporary data slice of length at least 3*n and Pocon will panic otherwise. +// +// iwork is a temporary data slice of length at least n and Pocon will panic otherwise. +func Pocon(a blas64.Symmetric, anorm float64, work []float64, iwork []int) float64 { + return lapack64.Dpocon(a.Uplo, a.N, a.Data, a.Stride, anorm, work, iwork) +} + +// Syev computes all eigenvalues and, optionally, the eigenvectors of a real +// symmetric matrix A. +// +// w contains the eigenvalues in ascending order upon return. w must have length +// at least n, and Syev will panic otherwise. +// +// On entry, a contains the elements of the symmetric matrix A in the triangular +// portion specified by uplo. If jobz == lapack.ComputeEV a contains the +// orthonormal eigenvectors of A on exit, otherwise on exit the specified +// triangular region is overwritten. +// +// Work is temporary storage, and lwork specifies the usable memory length. At minimum, +// lwork >= 3*n-1, and Syev will panic otherwise. The amount of blocking is +// limited by the usable length. If lwork == -1, instead of computing Syev the +// optimal work length is stored into work[0]. +func Syev(jobz lapack.EVJob, a blas64.Symmetric, w, work []float64, lwork int) (ok bool) { + return lapack64.Dsyev(jobz, a.Uplo, a.N, a.Data, a.Stride, w, work, lwork) +} + +// Trcon estimates the reciprocal of the condition number of a triangular matrix A. +// The condition number computed may be based on the 1-norm or the ∞-norm. +// +// work is a temporary data slice of length at least 3*n and Trcon will panic otherwise. +// +// iwork is a temporary data slice of length at least n and Trcon will panic otherwise. +func Trcon(norm lapack.MatrixNorm, a blas64.Triangular, work []float64, iwork []int) float64 { + return lapack64.Dtrcon(norm, a.Uplo, a.Diag, a.N, a.Data, a.Stride, work, iwork) +} + +// Trtri computes the inverse of a triangular matrix, storing the result in place +// into a. +// +// Trtri will not perform the inversion if the matrix is singular, and returns +// a boolean indicating whether the inversion was successful. +func Trtri(a blas64.Triangular) (ok bool) { + return lapack64.Dtrtri(a.Uplo, a.Diag, a.N, a.Data, a.Stride) +} + +// Trtrs solves a triangular system of the form A * X = B or A^T * X = B. Trtrs +// returns whether the solve completed successfully. If A is singular, no solve is performed. +func Trtrs(trans blas.Transpose, a blas64.Triangular, b blas64.General) (ok bool) { + return lapack64.Dtrtrs(a.Uplo, trans, a.Diag, a.N, b.Cols, a.Data, a.Stride, b.Data, b.Stride) +} + +// Geev computes the eigenvalues and, optionally, the left and/or right +// eigenvectors for an n×n real nonsymmetric matrix A. +// +// The right eigenvector v_j of A corresponding to an eigenvalue λ_j +// is defined by +// A v_j = λ_j v_j, +// and the left eigenvector u_j corresponding to an eigenvalue λ_j is defined by +// u_j^H A = λ_j u_j^H, +// where u_j^H is the conjugate transpose of u_j. +// +// On return, A will be overwritten and the left and right eigenvectors will be +// stored, respectively, in the columns of the n×n matrices VL and VR in the +// same order as their eigenvalues. If the j-th eigenvalue is real, then +// u_j = VL[:,j], +// v_j = VR[:,j], +// and if it is not real, then j and j+1 form a complex conjugate pair and the +// eigenvectors can be recovered as +// u_j = VL[:,j] + i*VL[:,j+1], +// u_{j+1} = VL[:,j] - i*VL[:,j+1], +// v_j = VR[:,j] + i*VR[:,j+1], +// v_{j+1} = VR[:,j] - i*VR[:,j+1], +// where i is the imaginary unit. The computed eigenvectors are normalized to +// have Euclidean norm equal to 1 and largest component real. +// +// Left eigenvectors will be computed only if jobvl == lapack.ComputeLeftEV, +// otherwise jobvl must be lapack.None. +// Right eigenvectors will be computed only if jobvr == lapack.ComputeRightEV, +// otherwise jobvr must be lapack.None. +// For other values of jobvl and jobvr Geev will panic. +// +// On return, wr and wi will contain the real and imaginary parts, respectively, +// of the computed eigenvalues. Complex conjugate pairs of eigenvalues appear +// consecutively with the eigenvalue having the positive imaginary part first. +// wr and wi must have length n, and Geev will panic otherwise. +// +// work must have length at least lwork and lwork must be at least max(1,4*n) if +// the left or right eigenvectors are computed, and at least max(1,3*n) if no +// eigenvectors are computed. For good performance, lwork must generally be +// larger. On return, optimal value of lwork will be stored in work[0]. +// +// If lwork == -1, instead of performing Geev, the function only calculates the +// optimal vaule of lwork and stores it into work[0]. +// +// On return, first will be the index of the first valid eigenvalue. +// If first == 0, all eigenvalues and eigenvectors have been computed. +// If first is positive, Geev failed to compute all the eigenvalues, no +// eigenvectors have been computed and wr[first:] and wi[first:] contain those +// eigenvalues which have converged. +func Geev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob, a blas64.General, wr, wi []float64, vl, vr blas64.General, work []float64, lwork int) (first int) { + n := a.Rows + if a.Cols != n { + panic("lapack64: matrix not square") + } + if jobvl == lapack.ComputeLeftEV && (vl.Rows != n || vl.Cols != n) { + panic("lapack64: bad size of VL") + } + if jobvr == lapack.ComputeRightEV && (vr.Rows != n || vr.Cols != n) { + panic("lapack64: bad size of VR") + } + return lapack64.Dgeev(jobvl, jobvr, n, a.Data, a.Stride, wr, wi, vl.Data, vl.Stride, vr.Data, vr.Stride, work, lwork) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dbdsqr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dbdsqr.go new file mode 100644 index 00000000..e52fd9dd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dbdsqr.go @@ -0,0 +1,198 @@ +// 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 testlapack + +import ( + "fmt" + "math/rand" + "sort" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dbdsqrer interface { + Dbdsqr(uplo blas.Uplo, n, ncvt, nru, ncc int, d, e, vt []float64, ldvt int, u []float64, ldu int, c []float64, ldc int, work []float64) (ok bool) +} + +func DbdsqrTest(t *testing.T, impl Dbdsqrer) { + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + _ = bi + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, test := range []struct { + n, ncvt, nru, ncc, ldvt, ldu, ldc int + }{ + {5, 5, 5, 5, 0, 0, 0}, + {10, 10, 10, 10, 0, 0, 0}, + {10, 11, 12, 13, 0, 0, 0}, + {20, 13, 12, 11, 0, 0, 0}, + + {5, 5, 5, 5, 6, 7, 8}, + {10, 10, 10, 10, 30, 40, 50}, + {10, 12, 11, 13, 30, 40, 50}, + {20, 12, 13, 11, 30, 40, 50}, + + {130, 130, 130, 500, 900, 900, 500}, + } { + for cas := 0; cas < 10; cas++ { + n := test.n + ncvt := test.ncvt + nru := test.nru + ncc := test.ncc + ldvt := test.ldvt + ldu := test.ldu + ldc := test.ldc + if ldvt == 0 { + ldvt = ncvt + } + if ldu == 0 { + ldu = n + } + if ldc == 0 { + ldc = ncc + } + + d := make([]float64, n) + for i := range d { + d[i] = rnd.NormFloat64() + } + e := make([]float64, n-1) + for i := range e { + e[i] = rnd.NormFloat64() + } + dCopy := make([]float64, len(d)) + copy(dCopy, d) + eCopy := make([]float64, len(e)) + copy(eCopy, e) + work := make([]float64, 4*n) + for i := range work { + work[i] = rnd.NormFloat64() + } + + // First test the decomposition of the bidiagonal matrix. Set + // pt and u equal to I with the correct size. At the result + // of Dbdsqr, p and u will contain the data of P^T and Q, which + // will be used in the next step to test the multiplication + // with Q and VT. + + q := make([]float64, n*n) + ldq := n + pt := make([]float64, n*n) + ldpt := n + for i := 0; i < n; i++ { + q[i*ldq+i] = 1 + } + for i := 0; i < n; i++ { + pt[i*ldpt+i] = 1 + } + + ok := impl.Dbdsqr(uplo, n, n, n, 0, d, e, pt, ldpt, q, ldq, nil, 0, work) + + isUpper := uplo == blas.Upper + errStr := fmt.Sprintf("isUpper = %v, n = %v, ncvt = %v, nru = %v, ncc = %v", isUpper, n, ncvt, nru, ncc) + if !ok { + t.Errorf("Unexpected Dbdsqr failure: %s", errStr) + } + + bMat := constructBidiagonal(uplo, n, dCopy, eCopy) + sMat := constructBidiagonal(uplo, n, d, e) + + tmp := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + ansMat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, n, n, 1, q, ldq, sMat.Data, sMat.Stride, 0, tmp.Data, tmp.Stride) + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, n, n, 1, tmp.Data, tmp.Stride, pt, ldpt, 0, ansMat.Data, ansMat.Stride) + + same := true + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if !floats.EqualWithinAbsOrRel(ansMat.Data[i*ansMat.Stride+j], bMat.Data[i*bMat.Stride+j], 1e-8, 1e-8) { + same = false + } + } + } + if !same { + t.Errorf("Bidiagonal mismatch. %s", errStr) + } + if !sort.IsSorted(sort.Reverse(sort.Float64Slice(d))) { + t.Errorf("D is not sorted. %s", errStr) + } + + // The above computed the real P and Q. Now input data for V^T, + // U, and C to check that the multiplications happen properly. + dAns := make([]float64, len(d)) + copy(dAns, d) + eAns := make([]float64, len(e)) + copy(eAns, e) + + u := make([]float64, nru*ldu) + for i := range u { + u[i] = rnd.NormFloat64() + } + uCopy := make([]float64, len(u)) + copy(uCopy, u) + vt := make([]float64, n*ldvt) + for i := range vt { + vt[i] = rnd.NormFloat64() + } + vtCopy := make([]float64, len(vt)) + copy(vtCopy, vt) + c := make([]float64, n*ldc) + for i := range c { + c[i] = rnd.NormFloat64() + } + cCopy := make([]float64, len(c)) + copy(cCopy, c) + + // Reset input data + copy(d, dCopy) + copy(e, eCopy) + impl.Dbdsqr(uplo, n, ncvt, nru, ncc, d, e, vt, ldvt, u, ldu, c, ldc, work) + + // Check result. + if !floats.EqualApprox(d, dAns, 1e-14) { + t.Errorf("D mismatch second time. %s", errStr) + } + if !floats.EqualApprox(e, eAns, 1e-14) { + t.Errorf("E mismatch second time. %s", errStr) + } + ans := make([]float64, len(vtCopy)) + copy(ans, vtCopy) + ldans := ldvt + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, ncvt, n, 1, pt, ldpt, vtCopy, ldvt, 0, ans, ldans) + if !floats.EqualApprox(ans, vt, 1e-10) { + t.Errorf("Vt result mismatch. %s", errStr) + } + ans = make([]float64, len(uCopy)) + copy(ans, uCopy) + ldans = ldu + bi.Dgemm(blas.NoTrans, blas.NoTrans, nru, n, n, 1, uCopy, ldu, q, ldq, 0, ans, ldans) + if !floats.EqualApprox(ans, u, 1e-10) { + t.Errorf("U result mismatch. %s", errStr) + } + ans = make([]float64, len(cCopy)) + copy(ans, cCopy) + ldans = ldc + bi.Dgemm(blas.Trans, blas.NoTrans, n, ncc, n, 1, q, ldq, cCopy, ldc, 0, ans, ldans) + if !floats.EqualApprox(ans, c, 1e-10) { + t.Errorf("C result mismatch. %s", errStr) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebak.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebak.go new file mode 100644 index 00000000..7d1030a4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebak.go @@ -0,0 +1,110 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +type Dgebaker interface { + Dgebak(job lapack.Job, side lapack.EVSide, n, ilo, ihi int, scale []float64, m int, v []float64, ldv int) +} + +func DgebakTest(t *testing.T, impl Dgebaker) { + rnd := rand.New(rand.NewSource(1)) + + for _, job := range []lapack.Job{lapack.None, lapack.Permute, lapack.Scale, lapack.PermuteScale} { + for _, side := range []lapack.EVSide{lapack.LeftEV, lapack.RightEV} { + for _, n := range []int{0, 1, 2, 3, 4, 5, 6, 10, 18, 31, 53} { + for _, extra := range []int{0, 11} { + for cas := 0; cas < 100; cas++ { + m := rnd.Intn(n + 1) + v := randomGeneral(n, m, m+extra, rnd) + var ilo, ihi int + if v.Rows > 0 { + ihi = rnd.Intn(n) + ilo = rnd.Intn(ihi + 1) + } else { + ihi = -1 + } + testDgebak(t, impl, job, side, ilo, ihi, v, rnd) + } + } + } + } + } +} + +func testDgebak(t *testing.T, impl Dgebaker, job lapack.Job, side lapack.EVSide, ilo, ihi int, v blas64.General, rnd *rand.Rand) { + const tol = 1e-15 + n := v.Rows + m := v.Cols + extra := v.Stride - v.Cols + + // Create D and D^{-1} by generating random scales between ilo and ihi. + d := eye(n, n) + dinv := eye(n, n) + scale := nanSlice(n) + if job == lapack.Scale || job == lapack.PermuteScale { + if ilo == ihi { + scale[ilo] = 1 + } else { + for i := ilo; i <= ihi; i++ { + scale[i] = 2 * rnd.Float64() + d.Data[i*d.Stride+i] = scale[i] + dinv.Data[i*dinv.Stride+i] = 1 / scale[i] + } + } + } + + // Create P by generating random column swaps. + p := eye(n, n) + if job == lapack.Permute || job == lapack.PermuteScale { + // Make up some random permutations. + for i := n - 1; i > ihi; i-- { + scale[i] = float64(rnd.Intn(i + 1)) + blas64.Swap(n, + blas64.Vector{p.Stride, p.Data[i:]}, + blas64.Vector{p.Stride, p.Data[int(scale[i]):]}) + } + for i := 0; i < ilo; i++ { + scale[i] = float64(i + rnd.Intn(ihi-i+1)) + blas64.Swap(n, + blas64.Vector{p.Stride, p.Data[i:]}, + blas64.Vector{p.Stride, p.Data[int(scale[i]):]}) + } + } + + got := cloneGeneral(v) + impl.Dgebak(job, side, n, ilo, ihi, scale, m, got.Data, got.Stride) + + prefix := fmt.Sprintf("Case job=%v, side=%v, n=%v, ilo=%v, ihi=%v, m=%v, extra=%v", + job, side, n, ilo, ihi, m, extra) + + if !generalOutsideAllNaN(got) { + t.Errorf("%v: out-of-range write to V\n%v", prefix, got.Data) + } + + // Compute D*V or D^{-1}*V and store into dv. + dv := zeros(n, m, m) + if side == lapack.RightEV { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, d, v, 0, dv) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, dinv, v, 0, dv) + } + // Compute P*D*V or P*D^{-1}*V and store into want. + want := zeros(n, m, m) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, p, dv, 0, want) + + if !equalApproxGeneral(want, got, tol) { + t.Errorf("%v: unexpected value of V", prefix) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebal.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebal.go new file mode 100644 index 00000000..b07ababf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebal.go @@ -0,0 +1,175 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +type Dgebaler interface { + Dgebal(job lapack.Job, n int, a []float64, lda int, scale []float64) (int, int) +} + +func DgebalTest(t *testing.T, impl Dgebaler) { + rnd := rand.New(rand.NewSource(1)) + + for _, job := range []lapack.Job{lapack.None, lapack.Permute, lapack.Scale, lapack.PermuteScale} { + for _, n := range []int{0, 1, 2, 3, 4, 5, 6, 10, 18, 31, 53, 100} { + for _, extra := range []int{0, 11} { + for cas := 0; cas < 100; cas++ { + a := unbalancedSparseGeneral(n, n, n+extra, 2*n, rnd) + testDgebal(t, impl, job, a) + } + } + } + } +} + +func testDgebal(t *testing.T, impl Dgebaler, job lapack.Job, a blas64.General) { + const tol = 1e-14 + + n := a.Rows + extra := a.Stride - n + + var scale []float64 + if n > 0 { + scale = nanSlice(n) + } + + want := cloneGeneral(a) + + ilo, ihi := impl.Dgebal(job, n, a.Data, a.Stride, scale) + + prefix := fmt.Sprintf("Case job=%v, n=%v, extra=%v", job, n, extra) + + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A\n%v", prefix, a.Data) + } + + if n == 0 { + if ilo != 0 { + t.Errorf("%v: unexpected ilo when n=0. Want 0, got %v", prefix, ilo) + } + if ihi != -1 { + t.Errorf("%v: unexpected ihi when n=0. Want -1, got %v", prefix, ihi) + } + return + } + + if job == lapack.None { + if ilo != 0 { + t.Errorf("%v: unexpected ilo when job=None. Want 0, got %v", prefix, ilo) + } + if ihi != n-1 { + t.Errorf("%v: unexpected ihi when job=None. Want %v, got %v", prefix, n-1, ihi) + } + k := -1 + for i := range scale { + if scale[i] != 1 { + k = i + break + } + } + if k != -1 { + t.Errorf("%v: unexpected scale[%v] when job=None. Want 1, got %v", prefix, k, scale[k]) + } + if !equalApproxGeneral(a, want, 0) { + t.Errorf("%v: unexpected modification of A when job=None", prefix) + } + return + } + + if ilo < 0 || ihi < ilo || n <= ihi { + t.Errorf("%v: invalid ordering of ilo=%v and ihi=%v", prefix, ilo, ihi) + } + + if ilo >= 2 && !isUpperTriangular(blas64.General{ilo - 1, ilo - 1, a.Stride, a.Data}) { + t.Errorf("%v: T1 is not upper triangular", prefix) + } + m := n - ihi - 1 // Order of T2. + k := ihi + 1 + if m >= 2 && !isUpperTriangular(blas64.General{m, m, a.Stride, a.Data[k*a.Stride+k:]}) { + t.Errorf("%v: T2 is not upper triangular", prefix) + } + + if job == lapack.Permute || job == lapack.PermuteScale { + // Check that all rows in [ilo:ihi+1] have at least one nonzero + // off-diagonal element. + zeroRow := -1 + for i := ilo; i <= ihi; i++ { + onlyZeros := true + for j := ilo; j <= ihi; j++ { + if i != j && a.Data[i*a.Stride+j] != 0 { + onlyZeros = false + break + } + } + if onlyZeros { + zeroRow = i + break + } + } + if zeroRow != -1 && ilo != ihi { + t.Errorf("%v: row %v has only zero off-diagonal elements, ilo=%v, ihi=%v", prefix, zeroRow, ilo, ihi) + } + // Check that all columns in [ilo:ihi+1] have at least one nonzero + // off-diagonal element. + zeroCol := -1 + for j := ilo; j <= ihi; j++ { + onlyZeros := true + for i := ilo; i <= ihi; i++ { + if i != j && a.Data[i*a.Stride+j] != 0 { + onlyZeros = false + break + } + } + if onlyZeros { + zeroCol = j + break + } + } + if zeroCol != -1 && ilo != ihi { + t.Errorf("%v: column %v has only zero off-diagonal elements, ilo=%v, ihi=%v", prefix, zeroCol, ilo, ihi) + } + + // Create the permutation matrix P. + p := eye(n, n) + for j := n - 1; j > ihi; j-- { + blas64.Swap(n, + blas64.Vector{p.Stride, p.Data[j:]}, + blas64.Vector{p.Stride, p.Data[int(scale[j]):]}) + } + for j := 0; j < ilo; j++ { + blas64.Swap(n, + blas64.Vector{p.Stride, p.Data[j:]}, + blas64.Vector{p.Stride, p.Data[int(scale[j]):]}) + } + // Compute P^T*A*P and store into want. + ap := zeros(n, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, want, p, 0, ap) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, p, ap, 0, want) + } + if job == lapack.Scale || job == lapack.PermuteScale { + // Modify want by D and D^{-1}. + d := eye(n, n) + dinv := eye(n, n) + for i := ilo; i <= ihi; i++ { + d.Data[i*d.Stride+i] = scale[i] + dinv.Data[i*dinv.Stride+i] = 1 / scale[i] + } + ad := zeros(n, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, want, d, 0, ad) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, dinv, ad, 0, want) + } + if !equalApproxGeneral(want, a, tol) { + t.Errorf("%v: unexpected value of A, ilo=%v, ihi=%v", prefix, ilo, ihi) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebd2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebd2.go new file mode 100644 index 00000000..f122c407 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebd2.go @@ -0,0 +1,54 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" +) + +type Dgebd2er interface { + Dgebd2(m, n int, a []float64, lda int, d, e, tauq, taup, work []float64) +} + +func Dgebd2Test(t *testing.T, impl Dgebd2er) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, lda int + }{ + {3, 4, 0}, + {4, 3, 0}, + {3, 4, 10}, + {4, 3, 10}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + nb := min(m, n) // 'nb' name parallel with Dlabrd code. + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + d := nanSlice(nb) + e := nanSlice(nb - 1) + tauP := nanSlice(nb) + tauQ := nanSlice(nb) + work := nanSlice(max(m, n)) + aCopy := make([]float64, len(a)) + copy(aCopy, a) + impl.Dgebd2(m, n, a, lda, d, e, tauQ, tauP, work) + if m >= n && nb == n { + tauP[n-1] = 0 + } + if m < n && nb == m { + tauQ[m-1] = 0 + } + + checkBidiagonal(t, m, n, nb, a, lda, d, e, tauP, tauQ, aCopy) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebrd.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebrd.go new file mode 100644 index 00000000..0bbba460 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgebrd.go @@ -0,0 +1,151 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dgebrder interface { + Dgebrd(m, n int, a []float64, lda int, d, e, tauQ, tauP, work []float64, lwork int) + Dgebd2er +} + +func DgebrdTest(t *testing.T, impl Dgebrder) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, lda int + }{ + {100, 100, 0}, + {100, 150, 0}, + {150, 100, 0}, + {100, 100, 200}, + {100, 150, 200}, + {150, 100, 200}, + + {300, 300, 0}, + {300, 400, 0}, + {400, 300, 0}, + {300, 300, 500}, + {300, 400, 500}, + {300, 400, 500}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + minmn := min(m, n) + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + + d := make([]float64, minmn) + e := make([]float64, minmn-1) + tauP := make([]float64, minmn) + tauQ := make([]float64, minmn) + work := make([]float64, max(m, n)) + for i := range work { + work[i] = math.NaN() + } + + // Store a. + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + // Compute the true answer with the unblocked algorithm. + impl.Dgebd2(m, n, a, lda, d, e, tauQ, tauP, work) + aAns := make([]float64, len(a)) + copy(aAns, a) + dAns := make([]float64, len(d)) + copy(dAns, d) + eAns := make([]float64, len(e)) + copy(eAns, e) + tauQAns := make([]float64, len(tauQ)) + copy(tauQAns, tauQ) + tauPAns := make([]float64, len(tauP)) + copy(tauPAns, tauP) + + // Test with optimal work. + lwork := -1 + copy(a, aCopy) + impl.Dgebrd(m, n, a, lda, d, e, tauQ, tauP, work, lwork) + work = make([]float64, int(work[0])) + lwork = len(work) + for i := range work { + work[i] = math.NaN() + } + for i := range d { + d[i] = math.NaN() + } + for i := range e { + e[i] = math.NaN() + } + for i := range tauQ { + tauQ[i] = math.NaN() + } + for i := range tauP { + tauP[i] = math.NaN() + } + impl.Dgebrd(m, n, a, lda, d, e, tauQ, tauP, work, lwork) + + // Test answers + if !floats.EqualApprox(a, aAns, 1e-10) { + t.Errorf("a mismatch") + } + if !floats.EqualApprox(d, dAns, 1e-10) { + t.Errorf("d mismatch") + } + if !floats.EqualApprox(e, eAns, 1e-10) { + t.Errorf("e mismatch") + } + if !floats.EqualApprox(tauQ, tauQAns, 1e-10) { + t.Errorf("tauQ mismatch") + } + if !floats.EqualApprox(tauP, tauPAns, 1e-10) { + t.Errorf("tauP mismatch") + } + + // Test with shorter than optimal work. + lwork-- + copy(a, aCopy) + for i := range d { + d[i] = 0 + } + for i := range e { + e[i] = 0 + } + for i := range tauP { + tauP[i] = 0 + } + for i := range tauQ { + tauQ[i] = 0 + } + impl.Dgebrd(m, n, a, lda, d, e, tauQ, tauP, work, lwork) + + // Test answers + if !floats.EqualApprox(a, aAns, 1e-10) { + t.Errorf("a mismatch") + } + if !floats.EqualApprox(d, dAns, 1e-10) { + t.Errorf("d mismatch") + } + if !floats.EqualApprox(e, eAns, 1e-10) { + t.Errorf("e mismatch") + } + if !floats.EqualApprox(tauQ, tauQAns, 1e-10) { + t.Errorf("tauQ mismatch") + } + if !floats.EqualApprox(tauP, tauPAns, 1e-10) { + t.Errorf("tauP mismatch") + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgecon.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgecon.go new file mode 100644 index 00000000..bbb76284 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgecon.go @@ -0,0 +1,97 @@ +// 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 testlapack + +import ( + "log" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dgeconer interface { + Dlanger + Dgetrfer + Dgecon(norm lapack.MatrixNorm, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 +} + +func DgeconTest(t *testing.T, impl Dgeconer) { + for _, test := range []struct { + m int + n int + a []float64 + condOne float64 + condInf float64 + }{ + { + a: []float64{ + 8, 1, 6, + 3, 5, 7, + 4, 9, 2, + }, + m: 3, + n: 3, + condOne: 3.0 / 16, + condInf: 3.0 / 16, + }, + { + a: []float64{ + 2, 9, 3, 2, + 10, 9, 9, 3, + 1, 1, 5, 2, + 8, 4, 10, 2, + }, + m: 4, + n: 4, + condOne: 0.024740155174938, + condInf: 0.012034465570035, + }, + // Dgecon does not match Dpocon for this case. https://github.com/xianyi/OpenBLAS/issues/664. + { + a: []float64{ + 2.9995576045549965, -2.0898894566158663, 3.965560740124006, + -2.0898894566158663, 1.9634729526261008, -2.8681002706874104, + 3.965560740124006, -2.8681002706874104, 5.502416670471008, + }, + m: 3, + n: 3, + condOne: 0.024054837369015203, + condInf: 0.024054837369015203, + }, + } { + m := test.m + n := test.n + lda := n + a := make([]float64, len(test.a)) + copy(a, test.a) + ipiv := make([]int, min(m, n)) + + // Find the norms of the original matrix. + work := make([]float64, 4*n) + oneNorm := impl.Dlange(lapack.MaxColumnSum, m, n, a, lda, work) + infNorm := impl.Dlange(lapack.MaxRowSum, m, n, a, lda, work) + + // Compute LU factorization of a. + impl.Dgetrf(m, n, a, lda, ipiv) + + // Compute the condition number + iwork := make([]int, n) + condOne := impl.Dgecon(lapack.MaxColumnSum, n, a, lda, oneNorm, work, iwork) + condInf := impl.Dgecon(lapack.MaxRowSum, n, a, lda, infNorm, work, iwork) + + // Error if not the same order, otherwise log the difference. + if !floats.EqualWithinAbsOrRel(condOne, test.condOne, 1e0, 1e0) { + t.Errorf("One norm mismatch. Want %v, got %v.", test.condOne, condOne) + } else if !floats.EqualWithinAbsOrRel(condOne, test.condOne, 1e-14, 1e-14) { + log.Printf("Dgecon one norm mismatch. Want %v, got %v.", test.condOne, condOne) + } + if !floats.EqualWithinAbsOrRel(condInf, test.condInf, 1e0, 1e0) { + t.Errorf("One norm mismatch. Want %v, got %v.", test.condInf, condInf) + } else if !floats.EqualWithinAbsOrRel(condInf, test.condInf, 1e-14, 1e-14) { + log.Printf("Dgecon one norm mismatch. Want %v, got %v.", test.condInf, condInf) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeev.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeev.go new file mode 100644 index 00000000..3ad86c1e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeev.go @@ -0,0 +1,735 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/cmplx" + "math/rand" + "strconv" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dgeever interface { + Dgeev(jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob, n int, a []float64, lda int, + wr, wi []float64, vl []float64, ldvl int, vr []float64, ldvr int, work []float64, lwork int) int +} + +type dgeevTest struct { + a blas64.General + evWant []complex128 // If nil, the eigenvalues are not known. + valTol float64 // Tolerance for eigenvalue checks. + vecTol float64 // Tolerance for eigenvector checks. +} + +func DgeevTest(t *testing.T, impl Dgeever) { + rnd := rand.New(rand.NewSource(1)) + + for i, test := range []dgeevTest{ + { + a: A123{}.Matrix(), + evWant: A123{}.Eigenvalues(), + }, + + dgeevTestForAntisymRandom(10, rnd), + dgeevTestForAntisymRandom(11, rnd), + dgeevTestForAntisymRandom(50, rnd), + dgeevTestForAntisymRandom(51, rnd), + dgeevTestForAntisymRandom(100, rnd), + dgeevTestForAntisymRandom(101, rnd), + + { + a: Circulant(2).Matrix(), + evWant: Circulant(2).Eigenvalues(), + }, + { + a: Circulant(3).Matrix(), + evWant: Circulant(3).Eigenvalues(), + }, + { + a: Circulant(4).Matrix(), + evWant: Circulant(4).Eigenvalues(), + }, + { + a: Circulant(5).Matrix(), + evWant: Circulant(5).Eigenvalues(), + }, + { + a: Circulant(10).Matrix(), + evWant: Circulant(10).Eigenvalues(), + }, + { + a: Circulant(15).Matrix(), + evWant: Circulant(15).Eigenvalues(), + valTol: 1e-12, + }, + { + a: Circulant(30).Matrix(), + evWant: Circulant(30).Eigenvalues(), + valTol: 1e-11, + vecTol: 1e-12, + }, + { + a: Circulant(50).Matrix(), + evWant: Circulant(50).Eigenvalues(), + valTol: 1e-11, + vecTol: 1e-12, + }, + { + a: Circulant(101).Matrix(), + evWant: Circulant(101).Eigenvalues(), + valTol: 1e-10, + vecTol: 1e-11, + }, + { + a: Circulant(150).Matrix(), + evWant: Circulant(150).Eigenvalues(), + valTol: 1e-9, + vecTol: 1e-10, + }, + + { + a: Clement(2).Matrix(), + evWant: Clement(2).Eigenvalues(), + }, + { + a: Clement(3).Matrix(), + evWant: Clement(3).Eigenvalues(), + }, + { + a: Clement(4).Matrix(), + evWant: Clement(4).Eigenvalues(), + }, + { + a: Clement(5).Matrix(), + evWant: Clement(5).Eigenvalues(), + }, + { + a: Clement(10).Matrix(), + evWant: Clement(10).Eigenvalues(), + }, + { + a: Clement(15).Matrix(), + evWant: Clement(15).Eigenvalues(), + }, + { + a: Clement(30).Matrix(), + evWant: Clement(30).Eigenvalues(), + valTol: 1e-11, + }, + { + a: Clement(50).Matrix(), + evWant: Clement(50).Eigenvalues(), + valTol: 1e-7, + vecTol: 1e-11, + }, + + { + a: Creation(2).Matrix(), + evWant: Creation(2).Eigenvalues(), + }, + { + a: Creation(3).Matrix(), + evWant: Creation(3).Eigenvalues(), + }, + { + a: Creation(4).Matrix(), + evWant: Creation(4).Eigenvalues(), + }, + { + a: Creation(5).Matrix(), + evWant: Creation(5).Eigenvalues(), + }, + { + a: Creation(10).Matrix(), + evWant: Creation(10).Eigenvalues(), + }, + { + a: Creation(15).Matrix(), + evWant: Creation(15).Eigenvalues(), + }, + { + a: Creation(30).Matrix(), + evWant: Creation(30).Eigenvalues(), + }, + { + a: Creation(50).Matrix(), + evWant: Creation(50).Eigenvalues(), + }, + { + a: Creation(101).Matrix(), + evWant: Creation(101).Eigenvalues(), + }, + { + a: Creation(150).Matrix(), + evWant: Creation(150).Eigenvalues(), + }, + + { + a: Diagonal(0).Matrix(), + evWant: Diagonal(0).Eigenvalues(), + }, + { + a: Diagonal(10).Matrix(), + evWant: Diagonal(10).Eigenvalues(), + }, + { + a: Diagonal(50).Matrix(), + evWant: Diagonal(50).Eigenvalues(), + }, + { + a: Diagonal(151).Matrix(), + evWant: Diagonal(151).Eigenvalues(), + }, + + { + a: Downshift(2).Matrix(), + evWant: Downshift(2).Eigenvalues(), + }, + { + a: Downshift(3).Matrix(), + evWant: Downshift(3).Eigenvalues(), + }, + { + a: Downshift(4).Matrix(), + evWant: Downshift(4).Eigenvalues(), + }, + { + a: Downshift(5).Matrix(), + evWant: Downshift(5).Eigenvalues(), + }, + { + a: Downshift(10).Matrix(), + evWant: Downshift(10).Eigenvalues(), + }, + { + a: Downshift(15).Matrix(), + evWant: Downshift(15).Eigenvalues(), + }, + { + a: Downshift(30).Matrix(), + evWant: Downshift(30).Eigenvalues(), + }, + { + a: Downshift(50).Matrix(), + evWant: Downshift(50).Eigenvalues(), + }, + { + a: Downshift(101).Matrix(), + evWant: Downshift(101).Eigenvalues(), + }, + { + a: Downshift(150).Matrix(), + evWant: Downshift(150).Eigenvalues(), + }, + + { + a: Fibonacci(2).Matrix(), + evWant: Fibonacci(2).Eigenvalues(), + }, + { + a: Fibonacci(3).Matrix(), + evWant: Fibonacci(3).Eigenvalues(), + }, + { + a: Fibonacci(4).Matrix(), + evWant: Fibonacci(4).Eigenvalues(), + }, + { + a: Fibonacci(5).Matrix(), + evWant: Fibonacci(5).Eigenvalues(), + }, + { + a: Fibonacci(10).Matrix(), + evWant: Fibonacci(10).Eigenvalues(), + }, + { + a: Fibonacci(15).Matrix(), + evWant: Fibonacci(15).Eigenvalues(), + }, + { + a: Fibonacci(30).Matrix(), + evWant: Fibonacci(30).Eigenvalues(), + }, + { + a: Fibonacci(50).Matrix(), + evWant: Fibonacci(50).Eigenvalues(), + }, + { + a: Fibonacci(101).Matrix(), + evWant: Fibonacci(101).Eigenvalues(), + }, + { + a: Fibonacci(150).Matrix(), + evWant: Fibonacci(150).Eigenvalues(), + }, + + { + a: Gear(2).Matrix(), + evWant: Gear(2).Eigenvalues(), + }, + { + a: Gear(3).Matrix(), + evWant: Gear(3).Eigenvalues(), + }, + { + a: Gear(4).Matrix(), + evWant: Gear(4).Eigenvalues(), + valTol: 1e-7, + }, + { + a: Gear(5).Matrix(), + evWant: Gear(5).Eigenvalues(), + }, + { + a: Gear(10).Matrix(), + evWant: Gear(10).Eigenvalues(), + valTol: 1e-8, + }, + { + a: Gear(15).Matrix(), + evWant: Gear(15).Eigenvalues(), + }, + { + a: Gear(30).Matrix(), + evWant: Gear(30).Eigenvalues(), + valTol: 1e-8, + }, + { + a: Gear(50).Matrix(), + evWant: Gear(50).Eigenvalues(), + valTol: 1e-8, + }, + { + a: Gear(101).Matrix(), + evWant: Gear(101).Eigenvalues(), + }, + { + a: Gear(150).Matrix(), + evWant: Gear(150).Eigenvalues(), + valTol: 1e-8, + }, + + { + a: Grcar{N: 10, K: 3}.Matrix(), + evWant: Grcar{N: 10, K: 3}.Eigenvalues(), + }, + { + a: Grcar{N: 10, K: 7}.Matrix(), + evWant: Grcar{N: 10, K: 7}.Eigenvalues(), + }, + { + a: Grcar{N: 11, K: 7}.Matrix(), + evWant: Grcar{N: 11, K: 7}.Eigenvalues(), + }, + { + a: Grcar{N: 50, K: 3}.Matrix(), + evWant: Grcar{N: 50, K: 3}.Eigenvalues(), + }, + { + a: Grcar{N: 51, K: 3}.Matrix(), + evWant: Grcar{N: 51, K: 3}.Eigenvalues(), + }, + { + a: Grcar{N: 50, K: 10}.Matrix(), + evWant: Grcar{N: 50, K: 10}.Eigenvalues(), + }, + { + a: Grcar{N: 51, K: 10}.Matrix(), + evWant: Grcar{N: 51, K: 10}.Eigenvalues(), + }, + { + a: Grcar{N: 50, K: 30}.Matrix(), + evWant: Grcar{N: 50, K: 30}.Eigenvalues(), + }, + { + a: Grcar{N: 150, K: 2}.Matrix(), + evWant: Grcar{N: 150, K: 2}.Eigenvalues(), + }, + { + a: Grcar{N: 150, K: 148}.Matrix(), + evWant: Grcar{N: 150, K: 148}.Eigenvalues(), + }, + + { + a: Hanowa{N: 6, Alpha: 17}.Matrix(), + evWant: Hanowa{N: 6, Alpha: 17}.Eigenvalues(), + }, + { + a: Hanowa{N: 50, Alpha: -1}.Matrix(), + evWant: Hanowa{N: 50, Alpha: -1}.Eigenvalues(), + }, + { + a: Hanowa{N: 100, Alpha: -1}.Matrix(), + evWant: Hanowa{N: 100, Alpha: -1}.Eigenvalues(), + }, + + { + a: Lesp(2).Matrix(), + evWant: Lesp(2).Eigenvalues(), + }, + { + a: Lesp(3).Matrix(), + evWant: Lesp(3).Eigenvalues(), + }, + { + a: Lesp(4).Matrix(), + evWant: Lesp(4).Eigenvalues(), + }, + { + a: Lesp(5).Matrix(), + evWant: Lesp(5).Eigenvalues(), + }, + { + a: Lesp(10).Matrix(), + evWant: Lesp(10).Eigenvalues(), + }, + { + a: Lesp(15).Matrix(), + evWant: Lesp(15).Eigenvalues(), + }, + { + a: Lesp(30).Matrix(), + evWant: Lesp(30).Eigenvalues(), + }, + { + a: Lesp(50).Matrix(), + evWant: Lesp(50).Eigenvalues(), + valTol: 1e-12, + vecTol: 1e-12, + }, + { + a: Lesp(101).Matrix(), + evWant: Lesp(101).Eigenvalues(), + valTol: 1e-12, + vecTol: 1e-12, + }, + { + a: Lesp(150).Matrix(), + evWant: Lesp(150).Eigenvalues(), + valTol: 1e-12, + vecTol: 1e-12, + }, + + { + a: Rutis{}.Matrix(), + evWant: Rutis{}.Eigenvalues(), + }, + + { + a: Tris{N: 74, X: 1, Y: -2, Z: 1}.Matrix(), + evWant: Tris{N: 74, X: 1, Y: -2, Z: 1}.Eigenvalues(), + }, + { + a: Tris{N: 74, X: 1, Y: 2, Z: -3}.Matrix(), + evWant: Tris{N: 74, X: 1, Y: 2, Z: -3}.Eigenvalues(), + }, + { + a: Tris{N: 75, X: 1, Y: 2, Z: -3}.Matrix(), + evWant: Tris{N: 75, X: 1, Y: 2, Z: -3}.Eigenvalues(), + }, + + { + a: Wilk4{}.Matrix(), + evWant: Wilk4{}.Eigenvalues(), + }, + { + a: Wilk12{}.Matrix(), + evWant: Wilk12{}.Eigenvalues(), + valTol: 1e-8, + }, + { + a: Wilk20(0).Matrix(), + evWant: Wilk20(0).Eigenvalues(), + }, + { + a: Wilk20(1e-10).Matrix(), + evWant: Wilk20(1e-10).Eigenvalues(), + valTol: 1e-12, + vecTol: 1e-12, + }, + + { + a: Zero(1).Matrix(), + evWant: Zero(1).Eigenvalues(), + }, + { + a: Zero(10).Matrix(), + evWant: Zero(10).Eigenvalues(), + }, + { + a: Zero(50).Matrix(), + evWant: Zero(50).Eigenvalues(), + }, + { + a: Zero(100).Matrix(), + evWant: Zero(100).Eigenvalues(), + }, + } { + for _, jobvl := range []lapack.LeftEVJob{lapack.ComputeLeftEV, lapack.None} { + for _, jobvr := range []lapack.RightEVJob{lapack.ComputeRightEV, lapack.None} { + for _, extra := range []int{0, 11} { + for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { + testDgeev(t, impl, strconv.Itoa(i), test, jobvl, jobvr, extra, wl) + } + } + } + } + } + + for _, n := range []int{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 20, 50, 51, 100, 101} { + for _, jobvl := range []lapack.LeftEVJob{lapack.ComputeLeftEV, lapack.None} { + for _, jobvr := range []lapack.RightEVJob{lapack.ComputeRightEV, lapack.None} { + for cas := 0; cas < 10; cas++ { + // Create a block diagonal matrix with + // random eigenvalues of random multiplicity. + ev := make([]complex128, n) + tmat := zeros(n, n, n) + for i := 0; i < n; { + re := rnd.NormFloat64() + if i == n-1 || rnd.Float64() < 0.5 { + // Real eigenvalue. + nb := rnd.Intn(min(4, n-i)) + 1 + for k := 0; k < nb; k++ { + tmat.Data[i*tmat.Stride+i] = re + ev[i] = complex(re, 0) + i++ + } + continue + } + // Complex eigenvalue. + im := rnd.NormFloat64() + nb := rnd.Intn(min(4, (n-i)/2)) + 1 + for k := 0; k < nb; k++ { + // 2×2 block for the complex eigenvalue. + tmat.Data[i*tmat.Stride+i] = re + tmat.Data[(i+1)*tmat.Stride+i+1] = re + tmat.Data[(i+1)*tmat.Stride+i] = -im + tmat.Data[i*tmat.Stride+i+1] = im + ev[i] = complex(re, im) + ev[i+1] = complex(re, -im) + i += 2 + } + } + + // Compute A = Q T Q^T where Q is an + // orthogonal matrix. + q := randomOrthogonal(n, rnd) + tq := zeros(n, n, n) + blas64.Gemm(blas.NoTrans, blas.Trans, 1, tmat, q, 0, tq) + a := zeros(n, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, tq, 0, a) + + test := dgeevTest{ + a: a, + evWant: ev, + valTol: 1e-12, + vecTol: 1e-8, + } + testDgeev(t, impl, "random", test, jobvl, jobvr, 0, optimumWork) + } + } + } + } +} + +func testDgeev(t *testing.T, impl Dgeever, tc string, test dgeevTest, jobvl lapack.LeftEVJob, jobvr lapack.RightEVJob, extra int, wl worklen) { + const defaultTol = 1e-13 + valTol := test.valTol + if valTol == 0 { + valTol = defaultTol + } + vecTol := test.vecTol + if vecTol == 0 { + vecTol = defaultTol + } + + a := cloneGeneral(test.a) + n := a.Rows + + var vl blas64.General + if jobvl == lapack.ComputeLeftEV { + vl = nanGeneral(n, n, n) + } + + var vr blas64.General + if jobvr == lapack.ComputeRightEV { + vr = nanGeneral(n, n, n) + } + + wr := make([]float64, n) + wi := make([]float64, n) + + var lwork int + switch wl { + case minimumWork: + if jobvl == lapack.ComputeLeftEV || jobvr == lapack.ComputeRightEV { + lwork = max(1, 4*n) + } else { + lwork = max(1, 3*n) + } + case mediumWork: + work := make([]float64, 1) + impl.Dgeev(jobvl, jobvr, n, nil, 1, nil, nil, nil, 1, nil, 1, work, -1) + if jobvl == lapack.ComputeLeftEV || jobvr == lapack.ComputeRightEV { + lwork = (int(work[0]) + 4*n) / 2 + } else { + lwork = (int(work[0]) + 3*n) / 2 + } + lwork = max(1, lwork) + case optimumWork: + work := make([]float64, 1) + impl.Dgeev(jobvl, jobvr, n, nil, 1, nil, nil, nil, 1, nil, 1, work, -1) + lwork = int(work[0]) + } + work := make([]float64, lwork) + + first := impl.Dgeev(jobvl, jobvr, n, a.Data, a.Stride, wr, wi, + vl.Data, vl.Stride, vr.Data, vr.Stride, work, len(work)) + + prefix := fmt.Sprintf("Case #%v: n=%v, jobvl=%v, jobvr=%v, extra=%v, work=%v", + tc, n, jobvl, jobvr, extra, wl) + + if !generalOutsideAllNaN(vl) { + t.Errorf("%v: out-of-range write to VL", prefix) + } + if !generalOutsideAllNaN(vr) { + t.Errorf("%v: out-of-range write to VR", prefix) + } + + if first > 0 { + t.Logf("%v: all eigenvalues haven't been computed, first=%v", prefix, first) + } + + // Check that conjugate pair eigevalues are ordered correctly. + for i := first; i < n; { + if wi[i] == 0 { + i++ + continue + } + if wr[i] != wr[i+1] { + t.Errorf("%v: real parts of %vth conjugate pair not equal", prefix, i) + } + if wi[i] < 0 || wi[i+1] > 0 { + t.Errorf("%v: unexpected ordering of %vth conjugate pair", prefix, i) + } + i += 2 + } + + // Check the computed eigenvalues against provided known eigenvalues. + if test.evWant != nil { + used := make([]bool, n) + for i := first; i < n; i++ { + evGot := complex(wr[i], wi[i]) + idx := -1 + for k, evWant := range test.evWant { + if !used[k] && cmplx.Abs(evWant-evGot) < valTol { + idx = k + used[k] = true + break + } + } + if idx == -1 { + t.Errorf("%v: unexpected eigenvalue %v", prefix, evGot) + } + } + } + + if first > 0 || (jobvl == lapack.None && jobvr == lapack.None) { + // No eigenvectors have been computed. + return + } + + // Check that the columns of VL and VR are eigenvectors that correspond + // to the computed eigenvalues. + for k := 0; k < n; { + if wi[k] == 0 { + if jobvl == lapack.ComputeLeftEV { + ev := columnOf(vl, k) + if !isLeftEigenvectorOf(test.a, ev, nil, complex(wr[k], 0), vecTol) { + t.Errorf("%v: VL[:,%v] is not left real eigenvector", + prefix, k) + } + + norm := floats.Norm(ev, 2) + if math.Abs(norm-1) >= defaultTol { + t.Errorf("%v: norm of left real eigenvector %v not equal to 1: got %v", + prefix, k, norm) + } + } + if jobvr == lapack.ComputeRightEV { + ev := columnOf(vr, k) + if !isRightEigenvectorOf(test.a, ev, nil, complex(wr[k], 0), vecTol) { + t.Errorf("%v: VR[:,%v] is not right real eigenvector", + prefix, k) + } + + norm := floats.Norm(ev, 2) + if math.Abs(norm-1) >= defaultTol { + t.Errorf("%v: norm of right real eigenvector %v not equal to 1: got %v", + prefix, k, norm) + } + } + k++ + } else { + if jobvl == lapack.ComputeLeftEV { + evre := columnOf(vl, k) + evim := columnOf(vl, k+1) + if !isLeftEigenvectorOf(test.a, evre, evim, complex(wr[k], wi[k]), vecTol) { + t.Errorf("%v: VL[:,%v:%v] is not left complex eigenvector", + prefix, k, k+1) + } + floats.Scale(-1, evim) + if !isLeftEigenvectorOf(test.a, evre, evim, complex(wr[k+1], wi[k+1]), vecTol) { + t.Errorf("%v: VL[:,%v:%v] is not left complex eigenvector", + prefix, k, k+1) + } + + norm := math.Hypot(floats.Norm(evre, 2), floats.Norm(evim, 2)) + if math.Abs(norm-1) > defaultTol { + t.Errorf("%v: norm of left complex eigenvector %v not equal to 1: got %v", + prefix, k, norm) + } + } + if jobvr == lapack.ComputeRightEV { + evre := columnOf(vr, k) + evim := columnOf(vr, k+1) + if !isRightEigenvectorOf(test.a, evre, evim, complex(wr[k], wi[k]), vecTol) { + t.Errorf("%v: VR[:,%v:%v] is not right complex eigenvector", + prefix, k, k+1) + } + floats.Scale(-1, evim) + if !isRightEigenvectorOf(test.a, evre, evim, complex(wr[k+1], wi[k+1]), vecTol) { + t.Errorf("%v: VR[:,%v:%v] is not right complex eigenvector", + prefix, k, k+1) + } + + norm := math.Hypot(floats.Norm(evre, 2), floats.Norm(evim, 2)) + if math.Abs(norm-1) > defaultTol { + t.Errorf("%v: norm of right complex eigenvector %v not equal to 1: got %v", + prefix, k, norm) + } + } + // We don't test whether the largest component is real + // because checking it is flaky due to rounding errors. + + k += 2 + } + } +} + +func dgeevTestForAntisymRandom(n int, rnd *rand.Rand) dgeevTest { + a := NewAntisymRandom(n, rnd) + return dgeevTest{ + a: a.Matrix(), + evWant: a.Eigenvalues(), + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeev_bench.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeev_bench.go new file mode 100644 index 00000000..177807de --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeev_bench.go @@ -0,0 +1,63 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.7 + +package testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +var resultGeneral blas64.General + +func DgeevBenchmark(b *testing.B, impl Dgeever) { + rnd := rand.New(rand.NewSource(1)) + benchmarks := []struct { + name string + a blas64.General + }{ + {"AntisymRandom3", NewAntisymRandom(3, rnd).Matrix()}, + {"AntisymRandom4", NewAntisymRandom(4, rnd).Matrix()}, + {"AntisymRandom5", NewAntisymRandom(5, rnd).Matrix()}, + {"AntisymRandom10", NewAntisymRandom(10, rnd).Matrix()}, + {"AntisymRandom50", NewAntisymRandom(50, rnd).Matrix()}, + {"AntisymRandom100", NewAntisymRandom(100, rnd).Matrix()}, + {"AntisymRandom200", NewAntisymRandom(200, rnd).Matrix()}, + {"AntisymRandom500", NewAntisymRandom(500, rnd).Matrix()}, + {"Circulant3", Circulant(3).Matrix()}, + {"Circulant4", Circulant(4).Matrix()}, + {"Circulant5", Circulant(5).Matrix()}, + {"Circulant10", Circulant(10).Matrix()}, + {"Circulant50", Circulant(50).Matrix()}, + {"Circulant100", Circulant(100).Matrix()}, + {"Circulant200", Circulant(200).Matrix()}, + {"Circulant500", Circulant(500).Matrix()}, + } + for _, bm := range benchmarks { + n := bm.a.Rows + a := zeros(n, n, n) + vl := zeros(n, n, n) + vr := zeros(n, n, n) + wr := make([]float64, n) + wi := make([]float64, n) + work := make([]float64, 1) + impl.Dgeev(lapack.ComputeLeftEV, lapack.ComputeRightEV, n, nil, n, nil, nil, nil, n, nil, n, work, -1) + work = make([]float64, int(work[0])) + b.Run(bm.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + b.StopTimer() + copyGeneral(a, bm.a) + b.StartTimer() + impl.Dgeev(lapack.ComputeLeftEV, lapack.ComputeRightEV, n, a.Data, a.Stride, wr, wi, + vl.Data, vl.Stride, vr.Data, vr.Stride, work, len(work)) + } + resultGeneral = a + }) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgehd2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgehd2.go new file mode 100644 index 00000000..5b7e8309 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgehd2.go @@ -0,0 +1,196 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dgehd2er interface { + Dgehd2(n, ilo, ihi int, a []float64, lda int, tau, work []float64) +} + +func Dgehd2Test(t *testing.T, impl Dgehd2er) { + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{1, 2, 3, 4, 5, 7, 10, 30} { + for _, extra := range []int{0, 1, 13} { + for cas := 0; cas < 100; cas++ { + testDgehd2(t, impl, n, extra, rnd) + } + } + } +} + +func testDgehd2(t *testing.T, impl Dgehd2er, n, extra int, rnd *rand.Rand) { + ilo := rnd.Intn(n) + ihi := rnd.Intn(n) + if ilo > ihi { + ilo, ihi = ihi, ilo + } + + tau := nanSlice(n - 1) + work := nanSlice(n) + + a := randomGeneral(n, n, n+extra, rnd) + // NaN out elements under the diagonal except + // for the [ilo:ihi,ilo:ihi] block. + for i := 1; i <= ihi; i++ { + for j := 0; j < min(ilo, i); j++ { + a.Data[i*a.Stride+j] = math.NaN() + } + } + for i := ihi + 1; i < n; i++ { + for j := 0; j < i; j++ { + a.Data[i*a.Stride+j] = math.NaN() + } + } + aCopy := a + aCopy.Data = make([]float64, len(a.Data)) + copy(aCopy.Data, a.Data) + + impl.Dgehd2(n, ilo, ihi, a.Data, a.Stride, tau, work) + + prefix := fmt.Sprintf("Case n=%v, ilo=%v, ihi=%v, extra=%v", n, ilo, ihi, extra) + + // Check any invalid modifications of a. + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A\n%v", prefix, a.Data) + } + for i := ilo; i <= ihi; i++ { + for j := 0; j < min(ilo, i); j++ { + if !math.IsNaN(a.Data[i*a.Stride+j]) { + t.Errorf("%v: expected NaN at A[%v,%v]", prefix, i, j) + } + } + } + for i := ihi + 1; i < n; i++ { + for j := 0; j < i; j++ { + if !math.IsNaN(a.Data[i*a.Stride+j]) { + t.Errorf("%v: expected NaN at A[%v,%v]", prefix, i, j) + } + } + } + for i := 0; i <= ilo; i++ { + for j := i; j < ilo+1; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification at A[%v,%v]", prefix, i, j) + } + } + for j := ihi + 1; j < n; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification at A[%v,%v]", prefix, i, j) + } + } + } + for i := ihi + 1; i < n; i++ { + for j := i; j < n; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification at A[%v,%v]", prefix, i, j) + } + } + } + + // Check that tau has been assigned properly. + for i, v := range tau { + if i < ilo || i >= ihi { + if !math.IsNaN(v) { + t.Errorf("%v: expected NaN at tau[%v]", prefix, i) + } + } else { + if math.IsNaN(v) { + t.Errorf("%v: unexpected NaN at tau[%v]", prefix, i) + } + } + } + + // Extract Q and check that it is orthogonal. + q := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + for i := 0; i < q.Rows; i++ { + q.Data[i*q.Stride+i] = 1 + } + qCopy := q + qCopy.Data = make([]float64, len(q.Data)) + for j := ilo; j < ihi; j++ { + h := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + for i := 0; i < h.Rows; i++ { + h.Data[i*h.Stride+i] = 1 + } + v := blas64.Vector{ + Inc: 1, + Data: make([]float64, n), + } + v.Data[j+1] = 1 + for i := j + 2; i < ihi+1; i++ { + v.Data[i] = a.Data[i*a.Stride+j] + } + blas64.Ger(-tau[j], v, v, h) + copy(qCopy.Data, q.Data) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qCopy, h, 0, q) + } + if !isOrthonormal(q) { + t.Errorf("%v: Q is not orthogonal\nQ=%v", prefix, q) + } + + // Overwrite NaN elements of aCopy with zeros + // (we will multiply with it below). + for i := 1; i <= ihi; i++ { + for j := 0; j < min(ilo, i); j++ { + aCopy.Data[i*aCopy.Stride+j] = 0 + } + } + for i := ihi + 1; i < n; i++ { + for j := 0; j < i; j++ { + aCopy.Data[i*aCopy.Stride+j] = 0 + } + } + + // Construct Q^T * AOrig * Q and check that it is + // equal to A from Dgehd2. + aq := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aCopy, q, 0, aq) + qaq := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, aq, 0, qaq) + for i := ilo; i <= ihi; i++ { + for j := ilo; j <= ihi; j++ { + qaqij := qaq.Data[i*qaq.Stride+j] + if j < i-1 { + if math.Abs(qaqij) > 1e-14 { + t.Errorf("%v: Q^T*A*Q is not upper Hessenberg, [%v,%v]=%v", prefix, i, j, qaqij) + } + continue + } + diff := qaqij - a.Data[i*a.Stride+j] + if math.Abs(diff) > 1e-14 { + t.Errorf("%v: Q^T*AOrig*Q and A are not equal, diff at [%v,%v]=%v", prefix, i, j, diff) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgehrd.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgehrd.go new file mode 100644 index 00000000..012b8707 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgehrd.go @@ -0,0 +1,209 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dgehrder interface { + Dgehrd(n, ilo, ihi int, a []float64, lda int, tau, work []float64, lwork int) + + Dorgqr(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) +} + +func DgehrdTest(t *testing.T, impl Dgehrder) { + rnd := rand.New(rand.NewSource(1)) + + // Randomized tests for small matrix sizes that will most likely + // use the unblocked algorithm. + for _, n := range []int{1, 2, 3, 4, 5, 10, 34} { + for _, extra := range []int{0, 13} { + for _, optwork := range []bool{true, false} { + for cas := 0; cas < 10; cas++ { + ilo := rnd.Intn(n) + ihi := rnd.Intn(n) + if ilo > ihi { + ilo, ihi = ihi, ilo + } + testDgehrd(t, impl, n, ilo, ihi, extra, optwork, rnd) + } + } + } + } + + // These are selected tests for larger matrix sizes to test the blocked + // algorithm. Use sizes around several powers of two because that is + // where the blocked path will most likely start to be taken. For + // example, at present the blocked algorithm is used for sizes larger + // than 129. + for _, test := range []struct { + n, ilo, ihi int + }{ + {0, 0, -1}, + + {68, 0, 63}, + {68, 0, 64}, + {68, 0, 65}, + {68, 0, 66}, + {68, 0, 67}, + + {132, 2, 129}, + {132, 1, 129}, // Size = 129, unblocked. + {132, 0, 129}, // Size = 130, blocked. + {132, 1, 130}, + {132, 0, 130}, + {132, 1, 131}, + {132, 0, 131}, + + {260, 2, 257}, + {260, 1, 257}, + {260, 0, 257}, + {260, 0, 258}, + {260, 0, 259}, + } { + for _, extra := range []int{0, 13} { + for _, optwork := range []bool{true, false} { + testDgehrd(t, impl, test.n, test.ilo, test.ihi, extra, optwork, rnd) + } + } + } +} + +func testDgehrd(t *testing.T, impl Dgehrder, n, ilo, ihi, extra int, optwork bool, rnd *rand.Rand) { + a := randomGeneral(n, n, n+extra, rnd) + aCopy := a + aCopy.Data = make([]float64, len(a.Data)) + copy(aCopy.Data, a.Data) + + var tau []float64 + if n > 1 { + tau = nanSlice(n - 1) + } + + var work []float64 + if optwork { + work = nanSlice(1) + impl.Dgehrd(n, ilo, ihi, nil, a.Stride, nil, work, -1) + work = nanSlice(int(work[0])) + } else { + work = nanSlice(max(1, n)) + } + + impl.Dgehrd(n, ilo, ihi, a.Data, a.Stride, tau, work, len(work)) + + if n == 0 { + // Just make sure there is no panic. + return + } + + prefix := fmt.Sprintf("Case n=%v, ilo=%v, ihi=%v, extra=%v", n, ilo, ihi, extra) + + // Check any invalid modifications of a. + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A\n%v", prefix, a.Data) + } + for i := ilo; i <= ihi; i++ { + for j := 0; j < min(ilo, i); j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification of A[%v,%v]", prefix, i, j) + } + } + } + for i := ihi + 1; i < n; i++ { + for j := 0; j < i; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification of A[%v,%v]", prefix, i, j) + } + } + } + for i := 0; i <= ilo; i++ { + for j := i; j < ilo+1; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification at A[%v,%v]", prefix, i, j) + } + } + for j := ihi + 1; j < n; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification at A[%v,%v]", prefix, i, j) + } + } + } + for i := ihi + 1; i < n; i++ { + for j := i; j < n; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification at A[%v,%v]", prefix, i, j) + } + } + } + + // Check that tau has been assigned properly. + for i, v := range tau { + if math.IsNaN(v) { + t.Errorf("%v: unexpected NaN at tau[%v]", prefix, i) + } + } + + // Extract Q and check that it is orthogonal. + q := eye(n, n) + if ilo != ihi { + for i := ilo + 2; i <= ihi; i++ { + for j := ilo + 1; j < ihi; j++ { + q.Data[i*q.Stride+j] = a.Data[i*a.Stride+j-1] + } + } + nh := ihi - ilo + impl.Dorgqr(nh, nh, nh, q.Data[(ilo+1)*q.Stride+ilo+1:], q.Stride, tau[ilo:ihi], work, len(work)) + } + if !isOrthonormal(q) { + t.Errorf("%v: Q is not orthogonal\nQ=%v", prefix, q) + } + + // Construct Q^T * AOrig * Q and check that it is upper Hessenberg. + aq := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aCopy, q, 0, aq) + qaq := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, aq, 0, qaq) + for i := 0; i <= ilo; i++ { + for j := ilo + 1; j <= ihi; j++ { + qaqij := qaq.Data[i*qaq.Stride+j] + diff := qaqij - a.Data[i*a.Stride+j] + if math.Abs(diff) > 1e-13 { + t.Errorf("%v: Q^T*AOrig*Q and A are not equal, diff at [%v,%v]=%v", prefix, i, j, diff) + } + } + } + for i := ilo + 1; i <= ihi; i++ { + for j := ilo; j < n; j++ { + qaqij := qaq.Data[i*qaq.Stride+j] + if j < i-1 { + if math.Abs(qaqij) > 1e-13 { + t.Errorf("%v: Q^T*AOrig*Q is not upper Hessenberg, [%v,%v]=%v", prefix, i, j, qaqij) + } + continue + } + diff := qaqij - a.Data[i*a.Stride+j] + if math.Abs(diff) > 1e-13 { + t.Errorf("%v: Q^T*AOrig*Q and A are not equal, diff at [%v,%v]=%v", prefix, i, j, diff) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgelq2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgelq2.go new file mode 100644 index 00000000..20f95717 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgelq2.go @@ -0,0 +1,113 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dgelq2er interface { + Dgelq2(m, n int, a []float64, lda int, tau, work []float64) +} + +func Dgelq2Test(t *testing.T, impl Dgelq2er) { + rnd := rand.New(rand.NewSource(1)) + for c, test := range []struct { + m, n, lda int + }{ + {1, 1, 0}, + {2, 2, 0}, + {3, 2, 0}, + {2, 3, 0}, + {1, 12, 0}, + {2, 6, 0}, + {3, 4, 0}, + {4, 3, 0}, + {6, 2, 0}, + {1, 12, 0}, + {1, 1, 20}, + {2, 2, 20}, + {3, 2, 20}, + {2, 3, 20}, + {1, 12, 20}, + {2, 6, 20}, + {3, 4, 20}, + {4, 3, 20}, + {6, 2, 20}, + {1, 12, 20}, + } { + n := test.n + m := test.m + lda := test.lda + if lda == 0 { + lda = test.n + } + k := min(m, n) + tau := make([]float64, k) + for i := range tau { + tau[i] = rnd.Float64() + } + work := make([]float64, m) + for i := range work { + work[i] = rnd.Float64() + } + a := make([]float64, m*lda) + for i := 0; i < m*lda; i++ { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + impl.Dgelq2(m, n, a, lda, tau, work) + + Q := constructQ("LQ", m, n, a, lda, tau) + + // Check that Q is orthonormal + for i := 0; i < Q.Rows; i++ { + nrm := blas64.Nrm2(Q.Cols, blas64.Vector{Inc: 1, Data: Q.Data[i*Q.Stride:]}) + if math.Abs(nrm-1) > 1e-14 { + t.Errorf("Q not normal. Norm is %v", nrm) + } + for j := 0; j < i; j++ { + dot := blas64.Dot(Q.Rows, + blas64.Vector{Inc: 1, Data: Q.Data[i*Q.Stride:]}, + blas64.Vector{Inc: 1, Data: Q.Data[j*Q.Stride:]}, + ) + if math.Abs(dot) > 1e-14 { + t.Errorf("Q not orthogonal. Dot is %v", dot) + } + } + } + + L := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + for i := 0; i < m; i++ { + for j := 0; j <= min(i, n-1); j++ { + L.Data[i*L.Stride+j] = a[i*lda+j] + } + } + + ans := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + copy(ans.Data, aCopy) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, L, Q, 0, ans) + if !floats.EqualApprox(aCopy, ans.Data, 1e-14) { + t.Errorf("Case %v, LQ mismatch. Want %v, got %v.", c, aCopy, ans.Data) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgelqf.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgelqf.go new file mode 100644 index 00000000..5bbe7312 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgelqf.go @@ -0,0 +1,98 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dgelqfer interface { + Dgelq2er + Dgelqf(m, n int, a []float64, lda int, tau, work []float64, lwork int) +} + +func DgelqfTest(t *testing.T, impl Dgelqfer) { + rnd := rand.New(rand.NewSource(1)) + for c, test := range []struct { + m, n, lda int + }{ + {10, 5, 0}, + {5, 10, 0}, + {10, 10, 0}, + {300, 5, 0}, + {3, 500, 0}, + {200, 200, 0}, + {300, 200, 0}, + {204, 300, 0}, + {1, 3000, 0}, + {3000, 1, 0}, + {10, 5, 30}, + {5, 10, 30}, + {10, 10, 30}, + {300, 5, 500}, + {3, 500, 600}, + {200, 200, 300}, + {300, 200, 300}, + {204, 300, 400}, + {1, 3000, 4000}, + {3000, 1, 4000}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = rnd.Float64() + } + } + tau := make([]float64, n) + for i := 0; i < n; i++ { + tau[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + ans := make([]float64, len(a)) + copy(ans, a) + work := make([]float64, m) + for i := range work { + work[i] = rnd.Float64() + } + // Compute unblocked QR. + impl.Dgelq2(m, n, ans, lda, tau, work) + // Compute blocked QR with small work. + impl.Dgelqf(m, n, a, lda, tau, work, len(work)) + if !floats.EqualApprox(ans, a, 1e-12) { + t.Errorf("Case %v, mismatch small work.", c) + } + // Try the full length of work. + impl.Dgelqf(m, n, a, lda, tau, work, -1) + lwork := int(work[0]) + work = make([]float64, lwork) + copy(a, aCopy) + impl.Dgelqf(m, n, a, lda, tau, work, lwork) + if !floats.EqualApprox(ans, a, 1e-12) { + t.Errorf("Case %v, mismatch large work.", c) + } + + // Try a slightly smaller version of work to test blocking code. + if len(work) <= m { + continue + } + work = work[1:] + lwork-- + copy(a, aCopy) + impl.Dgelqf(m, n, a, lda, tau, work, lwork) + if !floats.EqualApprox(ans, a, 1e-12) { + t.Errorf("Case %v, mismatch large work.", c) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgels.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgels.go new file mode 100644 index 00000000..9b49a54c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgels.go @@ -0,0 +1,182 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dgelser interface { + Dgels(trans blas.Transpose, m, n, nrhs int, a []float64, lda int, b []float64, ldb int, work []float64, lwork int) bool +} + +func DgelsTest(t *testing.T, impl Dgelser) { + rnd := rand.New(rand.NewSource(1)) + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, test := range []struct { + m, n, nrhs, lda, ldb int + }{ + {3, 4, 5, 0, 0}, + {3, 5, 4, 0, 0}, + {4, 3, 5, 0, 0}, + {4, 5, 3, 0, 0}, + {5, 3, 4, 0, 0}, + {5, 4, 3, 0, 0}, + {3, 4, 5, 10, 20}, + {3, 5, 4, 10, 20}, + {4, 3, 5, 10, 20}, + {4, 5, 3, 10, 20}, + {5, 3, 4, 10, 20}, + {5, 4, 3, 10, 20}, + {3, 4, 5, 20, 10}, + {3, 5, 4, 20, 10}, + {4, 3, 5, 20, 10}, + {4, 5, 3, 20, 10}, + {5, 3, 4, 20, 10}, + {5, 4, 3, 20, 10}, + {200, 300, 400, 0, 0}, + {200, 400, 300, 0, 0}, + {300, 200, 400, 0, 0}, + {300, 400, 200, 0, 0}, + {400, 200, 300, 0, 0}, + {400, 300, 200, 0, 0}, + {200, 300, 400, 500, 600}, + {200, 400, 300, 500, 600}, + {300, 200, 400, 500, 600}, + {300, 400, 200, 500, 600}, + {400, 200, 300, 500, 600}, + {400, 300, 200, 500, 600}, + {200, 300, 400, 600, 500}, + {200, 400, 300, 600, 500}, + {300, 200, 400, 600, 500}, + {300, 400, 200, 600, 500}, + {400, 200, 300, 600, 500}, + {400, 300, 200, 600, 500}, + } { + m := test.m + n := test.n + nrhs := test.nrhs + + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + // Size of b is the same trans or no trans, because the number of rows + // has to be the max of (m,n). + mb := max(m, n) + nb := nrhs + ldb := test.ldb + if ldb == 0 { + ldb = nb + } + b := make([]float64, mb*ldb) + for i := range b { + b[i] = rnd.Float64() + } + bCopy := make([]float64, len(b)) + copy(bCopy, b) + + // Find optimal work length. + work := make([]float64, 1) + impl.Dgels(trans, m, n, nrhs, a, lda, b, ldb, work, -1) + + // Perform linear solve + work = make([]float64, int(work[0])) + lwork := len(work) + for i := range work { + work[i] = rnd.Float64() + } + impl.Dgels(trans, m, n, nrhs, a, lda, b, ldb, work, lwork) + + // Check that the answer is correct by comparing to the normal equations. + aMat := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, len(aCopy)), + } + copy(aMat.Data, aCopy) + szAta := n + if trans == blas.Trans { + szAta = m + } + aTA := blas64.General{ + Rows: szAta, + Cols: szAta, + Stride: szAta, + Data: make([]float64, szAta*szAta), + } + + // Compute A^T * A if notrans and A * A^T otherwise. + if trans == blas.NoTrans { + blas64.Gemm(blas.Trans, blas.NoTrans, 1, aMat, aMat, 0, aTA) + } else { + blas64.Gemm(blas.NoTrans, blas.Trans, 1, aMat, aMat, 0, aTA) + } + + // Multiply by X. + X := blas64.General{ + Rows: szAta, + Cols: nrhs, + Stride: ldb, + Data: b, + } + ans := blas64.General{ + Rows: aTA.Rows, + Cols: X.Cols, + Stride: X.Cols, + Data: make([]float64, aTA.Rows*X.Cols), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aTA, X, 0, ans) + + B := blas64.General{ + Rows: szAta, + Cols: nrhs, + Stride: ldb, + Data: make([]float64, len(bCopy)), + } + + copy(B.Data, bCopy) + var ans2 blas64.General + if trans == blas.NoTrans { + ans2 = blas64.General{ + Rows: aMat.Cols, + Cols: B.Cols, + Stride: B.Cols, + Data: make([]float64, aMat.Cols*B.Cols), + } + } else { + ans2 = blas64.General{ + Rows: aMat.Rows, + Cols: B.Cols, + Stride: B.Cols, + Data: make([]float64, aMat.Rows*B.Cols), + } + } + + // Compute A^T B if Trans or A * B otherwise + if trans == blas.NoTrans { + blas64.Gemm(blas.Trans, blas.NoTrans, 1, aMat, B, 0, ans2) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aMat, B, 0, ans2) + } + if !floats.EqualApprox(ans.Data, ans2.Data, 1e-12) { + t.Errorf("Normal equations not satisfied") + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeql2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeql2.go new file mode 100644 index 00000000..0ff6a930 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeql2.go @@ -0,0 +1,99 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dgeql2er interface { + Dgeql2(m, n int, a []float64, lda int, tau, work []float64) +} + +func Dgeql2Test(t *testing.T, impl Dgeql2er) { + rnd := rand.New(rand.NewSource(1)) + // TODO(btracey): Add tests for m < n. + for _, test := range []struct { + m, n, lda int + }{ + {5, 5, 0}, + {5, 3, 0}, + {5, 4, 0}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + tau := nanSlice(min(m, n)) + work := nanSlice(n) + + aCopy := make([]float64, len(a)) + copy(aCopy, a) + impl.Dgeql2(m, n, a, lda, tau, work) + + k := min(m, n) + // Construct Q. + q := blas64.General{ + Rows: m, + Cols: m, + Stride: m, + Data: make([]float64, m*m), + } + for i := 0; i < m; i++ { + q.Data[i*q.Stride+i] = 1 + } + for i := 0; i < k; i++ { + h := blas64.General{Rows: m, Cols: m, Stride: m, Data: make([]float64, m*m)} + for j := 0; j < m; j++ { + h.Data[j*h.Stride+j] = 1 + } + v := blas64.Vector{Inc: 1, Data: make([]float64, m)} + v.Data[m-k+i] = 1 + for j := 0; j < m-k+i; j++ { + v.Data[j] = a[j*lda+n-k+i] + } + blas64.Ger(-tau[i], v, v, h) + qTmp := blas64.General{Rows: q.Rows, Cols: q.Cols, Stride: q.Stride, Data: make([]float64, len(q.Data))} + copy(qTmp.Data, q.Data) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, h, qTmp, 0, q) + } + if !isOrthonormal(q) { + t.Errorf("Q is not orthonormal") + } + l := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + if m >= n { + for i := m - n; i < m; i++ { + for j := 0; j <= min(i-(m-n), n-1); j++ { + l.Data[i*l.Stride+j] = a[i*lda+j] + } + } + } else { + panic("untested") + } + ans := blas64.General{Rows: m, Cols: n, Stride: lda, Data: make([]float64, len(a))} + copy(ans.Data, a) + + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, l, 0, ans) + if !floats.EqualApprox(ans.Data, aCopy, 1e-10) { + t.Errorf("Reconstruction mismatch: m = %v, n = %v", m, n) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqp3.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqp3.go new file mode 100644 index 00000000..54e30bf5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqp3.go @@ -0,0 +1,135 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dgeqp3er interface { + Dlapmter + Dgeqp3(m, n int, a []float64, lda int, jpvt []int, tau, work []float64, lwork int) +} + +func Dgeqp3Test(t *testing.T, impl Dgeqp3er) { + rnd := rand.New(rand.NewSource(1)) + for c, test := range []struct { + m, n, lda int + }{ + {1, 1, 0}, + {2, 2, 0}, + {3, 2, 0}, + {2, 3, 0}, + {1, 12, 0}, + {2, 6, 0}, + {3, 4, 0}, + {4, 3, 0}, + {6, 2, 0}, + {12, 1, 0}, + {1, 1, 20}, + {2, 2, 20}, + {3, 2, 20}, + {2, 3, 20}, + {1, 12, 20}, + {2, 6, 20}, + {3, 4, 20}, + {4, 3, 20}, + {6, 2, 20}, + {12, 1, 20}, + {129, 256, 0}, + {256, 129, 0}, + {129, 256, 266}, + {256, 129, 266}, + } { + n := test.n + m := test.m + lda := test.lda + if lda == 0 { + lda = test.n + } + const ( + all = iota + some + none + ) + for _, free := range []int{all, some, none} { + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + jpvt := make([]int, n) + for j := range jpvt { + switch free { + case all: + jpvt[j] = -1 + case some: + jpvt[j] = rnd.Intn(2) - 1 + case none: + jpvt[j] = 0 + default: + panic("bad freedom") + } + } + k := min(m, n) + tau := make([]float64, k) + for i := range tau { + tau[i] = rnd.Float64() + } + work := make([]float64, 1) + impl.Dgeqp3(m, n, a, lda, jpvt, tau, work, -1) + lwork := int(work[0]) + work = make([]float64, lwork) + for i := range work { + work[i] = rnd.Float64() + } + impl.Dgeqp3(m, n, a, lda, jpvt, tau, work, lwork) + + // Test that the QR factorization has completed successfully. Compute + // Q based on the vectors. + q := constructQ("QR", m, n, a, lda, tau) + + // Check that q is orthonormal + for i := 0; i < m; i++ { + nrm := blas64.Nrm2(m, blas64.Vector{Inc: 1, Data: q.Data[i*m:]}) + if math.Abs(nrm-1) > 1e-13 { + t.Errorf("Case %v, q not normal", c) + } + for j := 0; j < i; j++ { + dot := blas64.Dot(m, blas64.Vector{Inc: 1, Data: q.Data[i*m:]}, blas64.Vector{Inc: 1, Data: q.Data[j*m:]}) + if math.Abs(dot) > 1e-14 { + t.Errorf("Case %v, q not orthogonal", c) + } + } + } + // Check that A * P = Q * R + r := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + r.Data[i*n+j] = a[i*lda+j] + } + } + got := nanGeneral(m, n, lda) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, 0, got) + + want := blas64.General{Rows: m, Cols: n, Stride: lda, Data: aCopy} + impl.Dlapmt(true, want.Rows, want.Cols, want.Data, want.Stride, jpvt) + if !equalApproxGeneral(got, want, 1e-13) { + t.Errorf("Case %v, Q*R != A*P\nQ*R=%v\nA*P=%v", c, got, want) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqr2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqr2.go new file mode 100644 index 00000000..f9ebf694 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqr2.go @@ -0,0 +1,111 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dgeqr2er interface { + Dgeqr2(m, n int, a []float64, lda int, tau []float64, work []float64) +} + +func Dgeqr2Test(t *testing.T, impl Dgeqr2er) { + rnd := rand.New(rand.NewSource(1)) + for c, test := range []struct { + m, n, lda int + }{ + {1, 1, 0}, + {2, 2, 0}, + {3, 2, 0}, + {2, 3, 0}, + {1, 12, 0}, + {2, 6, 0}, + {3, 4, 0}, + {4, 3, 0}, + {6, 2, 0}, + {12, 1, 0}, + {1, 1, 20}, + {2, 2, 20}, + {3, 2, 20}, + {2, 3, 20}, + {1, 12, 20}, + {2, 6, 20}, + {3, 4, 20}, + {4, 3, 20}, + {6, 2, 20}, + {12, 1, 20}, + } { + n := test.n + m := test.m + lda := test.lda + if lda == 0 { + lda = test.n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + k := min(m, n) + tau := make([]float64, k) + for i := range tau { + tau[i] = rnd.Float64() + } + work := make([]float64, n) + for i := range work { + work[i] = rnd.Float64() + } + copy(aCopy, a) + impl.Dgeqr2(m, n, a, lda, tau, work) + + // Test that the QR factorization has completed successfully. Compute + // Q based on the vectors. + q := constructQ("QR", m, n, a, lda, tau) + + // Check that q is orthonormal + for i := 0; i < m; i++ { + nrm := blas64.Nrm2(m, blas64.Vector{Inc: 1, Data: q.Data[i*m:]}) + if math.Abs(nrm-1) > 1e-14 { + t.Errorf("Case %v, q not normal", c) + } + for j := 0; j < i; j++ { + dot := blas64.Dot(m, blas64.Vector{Inc: 1, Data: q.Data[i*m:]}, blas64.Vector{Inc: 1, Data: q.Data[j*m:]}) + if math.Abs(dot) > 1e-14 { + t.Errorf("Case %v, q not orthogonal", c) + } + } + } + // Check that A = Q * R + r := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + r.Data[i*n+j] = a[i*lda+j] + } + } + atmp := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + copy(atmp.Data, a) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, 0, atmp) + if !floats.EqualApprox(atmp.Data, aCopy, 1e-14) { + t.Errorf("Q*R != a") + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqrf.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqrf.go new file mode 100644 index 00000000..60386c08 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgeqrf.go @@ -0,0 +1,95 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dgeqrfer interface { + Dgeqr2er + Dgeqrf(m, n int, a []float64, lda int, tau, work []float64, lwork int) +} + +func DgeqrfTest(t *testing.T, impl Dgeqrfer) { + rnd := rand.New(rand.NewSource(1)) + for c, test := range []struct { + m, n, lda int + }{ + {10, 5, 0}, + {5, 10, 0}, + {10, 10, 0}, + {300, 5, 0}, + {3, 500, 0}, + {200, 200, 0}, + {300, 200, 0}, + {204, 300, 0}, + {1, 3000, 0}, + {3000, 1, 0}, + {10, 5, 20}, + {5, 10, 20}, + {10, 10, 20}, + {300, 5, 400}, + {3, 500, 600}, + {200, 200, 300}, + {300, 200, 300}, + {204, 300, 400}, + {1, 3000, 4000}, + {3000, 1, 4000}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = test.n + } + a := make([]float64, m*lda) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = rnd.Float64() + } + } + tau := make([]float64, n) + for i := 0; i < n; i++ { + tau[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + ans := make([]float64, len(a)) + copy(ans, a) + work := make([]float64, n) + // Compute unblocked QR. + impl.Dgeqr2(m, n, ans, lda, tau, work) + // Compute blocked QR with small work. + impl.Dgeqrf(m, n, a, lda, tau, work, len(work)) + if !floats.EqualApprox(ans, a, 1e-12) { + t.Errorf("Case %v, mismatch small work.", c) + } + // Try the full length of work. + impl.Dgeqrf(m, n, a, lda, tau, work, -1) + lwork := int(work[0]) + work = make([]float64, lwork) + copy(a, aCopy) + impl.Dgeqrf(m, n, a, lda, tau, work, lwork) + if !floats.EqualApprox(ans, a, 1e-12) { + t.Errorf("Case %v, mismatch large work.", c) + } + + // Try a slightly smaller version of work to test blocking. + if len(work) <= n { + continue + } + work = work[1:] + lwork-- + copy(a, aCopy) + impl.Dgeqrf(m, n, a, lda, tau, work, lwork) + if !floats.EqualApprox(ans, a, 1e-12) { + t.Errorf("Case %v, mismatch large work.", c) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgerq2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgerq2.go new file mode 100644 index 00000000..ec0dde2a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgerq2.go @@ -0,0 +1,117 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dgerq2er interface { + Dgerq2(m, n int, a []float64, lda int, tau []float64, work []float64) +} + +func Dgerq2Test(t *testing.T, impl Dgerq2er) { + rnd := rand.New(rand.NewSource(1)) + for c, test := range []struct { + m, n, lda int + }{ + {1, 1, 0}, + {2, 2, 0}, + {3, 2, 0}, + {2, 3, 0}, + {1, 12, 0}, + {2, 6, 0}, + {3, 4, 0}, + {4, 3, 0}, + {6, 2, 0}, + {12, 1, 0}, + {1, 1, 20}, + {2, 2, 20}, + {3, 2, 20}, + {2, 3, 20}, + {1, 12, 20}, + {2, 6, 20}, + {3, 4, 20}, + {4, 3, 20}, + {6, 2, 20}, + {12, 1, 20}, + } { + n := test.n + m := test.m + lda := test.lda + if lda == 0 { + lda = test.n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + k := min(m, n) + tau := make([]float64, k) + for i := range tau { + tau[i] = rnd.Float64() + } + work := make([]float64, m) + for i := range work { + work[i] = rnd.Float64() + } + copy(aCopy, a) + impl.Dgerq2(m, n, a, lda, tau, work) + + // Test that the RQ factorization has completed successfully. Compute + // Q based on the vectors. + q := constructQ("RQ", m, n, a, lda, tau) + + // Check that q is orthonormal + for i := 0; i < q.Rows; i++ { + nrm := blas64.Nrm2(q.Cols, blas64.Vector{Inc: 1, Data: q.Data[i*q.Stride:]}) + if math.IsNaN(nrm) || math.Abs(nrm-1) > 1e-14 { + t.Errorf("Case %v, q not normal", c) + } + for j := 0; j < i; j++ { + dot := blas64.Dot(q.Cols, blas64.Vector{Inc: 1, Data: q.Data[i*q.Stride:]}, blas64.Vector{Inc: 1, Data: q.Data[j*q.Stride:]}) + if math.IsNaN(dot) || math.Abs(dot) > 1e-14 { + t.Errorf("Case %v, q not orthogonal", c) + } + } + } + // Check that A = R * Q + r := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + for i := 0; i < m; i++ { + off := m - n + for j := max(0, i-off); j < n; j++ { + r.Data[i*r.Stride+j] = a[i*lda+j] + } + } + + got := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, r, q, 0, got) + want := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: aCopy, + } + if !equalApproxGeneral(got, want, 1e-14) { + t.Errorf("Case %d, R*Q != a\ngot: %+v\nwant:%+v", c, got, want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgerqf.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgerqf.go new file mode 100644 index 00000000..b6e24126 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgerqf.go @@ -0,0 +1,142 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dgerqfer interface { + Dgerqf(m, n int, a []float64, lda int, tau, work []float64, lwork int) +} + +func DgerqfTest(t *testing.T, impl Dgerqfer) { + const tol = 1e-13 + + rnd := rand.New(rand.NewSource(1)) + for c, test := range []struct { + m, n, lda int + }{ + {1, 1, 0}, + {2, 2, 0}, + {3, 2, 0}, + {2, 3, 0}, + {1, 12, 0}, + {2, 6, 0}, + {3, 4, 0}, + {4, 3, 0}, + {6, 2, 0}, + {12, 1, 0}, + {200, 180, 0}, + {180, 200, 0}, + {200, 200, 0}, + {1, 1, 20}, + {2, 2, 20}, + {3, 2, 20}, + {2, 3, 20}, + {1, 12, 20}, + {2, 6, 20}, + {3, 4, 20}, + {4, 3, 20}, + {6, 2, 20}, + {12, 1, 20}, + {200, 180, 220}, + {180, 200, 220}, + {200, 200, 220}, + } { + n := test.n + m := test.m + lda := test.lda + if lda == 0 { + lda = test.n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + k := min(m, n) + tau := make([]float64, k) + for i := range tau { + tau[i] = rnd.Float64() + } + work := []float64{0} + impl.Dgerqf(m, n, a, lda, tau, work, -1) + lwkopt := int(work[0]) + for _, wk := range []struct { + name string + length int + }{ + {name: "short", length: m}, + {name: "medium", length: lwkopt - 1}, + {name: "long", length: lwkopt}, + } { + if wk.length < max(1, m) { + continue + } + lwork := wk.length + work = make([]float64, lwork) + for i := range work { + work[i] = rnd.Float64() + } + copy(a, aCopy) + impl.Dgerqf(m, n, a, lda, tau, work, lwork) + + // Test that the RQ factorization has completed successfully. Compute + // Q based on the vectors. + q := constructQ("RQ", m, n, a, lda, tau) + + // Check that q is orthonormal + for i := 0; i < q.Rows; i++ { + nrm := blas64.Nrm2(q.Cols, blas64.Vector{Inc: 1, Data: q.Data[i*q.Stride:]}) + if math.IsNaN(nrm) || math.Abs(nrm-1) > 1e-14 { + t.Errorf("Case %v, q not normal", c) + } + for j := 0; j < i; j++ { + dot := blas64.Dot(q.Cols, blas64.Vector{Inc: 1, Data: q.Data[i*q.Stride:]}, blas64.Vector{Inc: 1, Data: q.Data[j*q.Stride:]}) + if math.IsNaN(dot) || math.Abs(dot) > 1e-14 { + t.Errorf("Case %v, q not orthogonal", c) + } + } + } + // Check that A = R * Q + r := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + for i := 0; i < m; i++ { + off := m - n + for j := max(0, i-off); j < n; j++ { + r.Data[i*r.Stride+j] = a[i*lda+j] + } + } + + got := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, r, q, 0, got) + want := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: aCopy, + } + if !equalApproxGeneral(got, want, tol) { + t.Errorf("Case %d, R*Q != a %s\ngot: %+v\nwant:%+v", c, wk.name, got, want) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgesvd.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgesvd.go new file mode 100644 index 00000000..8c317993 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgesvd.go @@ -0,0 +1,286 @@ +// 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 testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dgesvder interface { + Dgesvd(jobU, jobVT lapack.SVDJob, m, n int, a []float64, lda int, s, u []float64, ldu int, vt []float64, ldvt int, work []float64, lwork int) (ok bool) +} + +func DgesvdTest(t *testing.T, impl Dgesvder) { + rnd := rand.New(rand.NewSource(1)) + // TODO(btracey): Add tests for all of the cases when the SVD implementation + // is finished. + // TODO(btracey): Add tests for m > mnthr and n > mnthr when other SVD + // conditions are implemented. Right now mnthr is 5,000,000 which is too + // large to create a square matrix of that size. + for _, test := range []struct { + m, n, lda, ldu, ldvt int + }{ + {5, 5, 0, 0, 0}, + {5, 6, 0, 0, 0}, + {6, 5, 0, 0, 0}, + {5, 9, 0, 0, 0}, + {9, 5, 0, 0, 0}, + + {5, 5, 10, 11, 12}, + {5, 6, 10, 11, 12}, + {6, 5, 10, 11, 12}, + {5, 5, 10, 11, 12}, + {5, 9, 10, 11, 12}, + {9, 5, 10, 11, 12}, + + {300, 300, 0, 0, 0}, + {300, 400, 0, 0, 0}, + {400, 300, 0, 0, 0}, + {300, 600, 0, 0, 0}, + {600, 300, 0, 0, 0}, + + {300, 300, 400, 450, 460}, + {300, 400, 500, 550, 560}, + {400, 300, 550, 550, 560}, + {300, 600, 700, 750, 760}, + {600, 300, 700, 750, 760}, + } { + jobU := lapack.SVDAll + jobVT := lapack.SVDAll + + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + ldu := test.ldu + if ldu == 0 { + ldu = m + } + ldvt := test.ldvt + if ldvt == 0 { + ldvt = n + } + + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + + u := make([]float64, m*ldu) + for i := range u { + u[i] = rnd.NormFloat64() + } + + vt := make([]float64, n*ldvt) + for i := range vt { + vt[i] = rnd.NormFloat64() + } + + uAllOrig := make([]float64, len(u)) + copy(uAllOrig, u) + vtAllOrig := make([]float64, len(vt)) + copy(vtAllOrig, vt) + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + s := make([]float64, min(m, n)) + + work := make([]float64, 1) + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, u, ldu, vt, ldvt, work, -1) + + if !floats.Equal(a, aCopy) { + t.Errorf("a changed during call to get work length") + } + + work = make([]float64, int(work[0])) + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, u, ldu, vt, ldvt, work, len(work)) + + errStr := fmt.Sprintf("m = %v, n = %v, lda = %v, ldu = %v, ldv = %v", m, n, lda, ldu, ldvt) + svdCheck(t, false, errStr, m, n, s, a, u, ldu, vt, ldvt, aCopy, lda) + svdCheckPartial(t, impl, lapack.SVDAll, errStr, uAllOrig, vtAllOrig, aCopy, m, n, a, lda, s, u, ldu, vt, ldvt, work, false) + + // Test InPlace + jobU = lapack.SVDInPlace + jobVT = lapack.SVDInPlace + copy(a, aCopy) + copy(u, uAllOrig) + copy(vt, vtAllOrig) + + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, u, ldu, vt, ldvt, work, len(work)) + svdCheck(t, true, errStr, m, n, s, a, u, ldu, vt, ldvt, aCopy, lda) + svdCheckPartial(t, impl, lapack.SVDInPlace, errStr, uAllOrig, vtAllOrig, aCopy, m, n, a, lda, s, u, ldu, vt, ldvt, work, false) + } +} + +// svdCheckPartial checks that the singular values and vectors are computed when +// not all of them are computed. +func svdCheckPartial(t *testing.T, impl Dgesvder, job lapack.SVDJob, errStr string, uAllOrig, vtAllOrig, aCopy []float64, m, n int, a []float64, lda int, s, u []float64, ldu int, vt []float64, ldvt int, work []float64, shortWork bool) { + rnd := rand.New(rand.NewSource(1)) + jobU := job + jobVT := job + // Compare the singular values when computed with {SVDNone, SVDNone.} + sCopy := make([]float64, len(s)) + copy(sCopy, s) + copy(a, aCopy) + for i := range s { + s[i] = rnd.Float64() + } + tmp1 := make([]float64, 1) + tmp2 := make([]float64, 1) + jobU = lapack.SVDNone + jobVT = lapack.SVDNone + + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, tmp1, ldu, tmp2, ldvt, work, -1) + work = make([]float64, int(work[0])) + lwork := len(work) + if shortWork { + lwork-- + } + ok := impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, tmp1, ldu, tmp2, ldvt, work, lwork) + if !ok { + t.Errorf("Dgesvd did not complete successfully") + } + if !floats.EqualApprox(s, sCopy, 1e-10) { + t.Errorf("Singular value mismatch when singular vectors not computed: %s", errStr) + } + // Check that the singular vectors are correctly computed when the other + // is none. + uAll := make([]float64, len(u)) + copy(uAll, u) + vtAll := make([]float64, len(vt)) + copy(vtAll, vt) + + // Copy the original vectors so the data outside the matrix bounds is the same. + copy(u, uAllOrig) + copy(vt, vtAllOrig) + + jobU = job + jobVT = lapack.SVDNone + copy(a, aCopy) + for i := range s { + s[i] = rnd.Float64() + } + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, u, ldu, tmp2, ldvt, work, -1) + work = make([]float64, int(work[0])) + lwork = len(work) + if shortWork { + lwork-- + } + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, u, ldu, tmp2, ldvt, work, len(work)) + if !floats.EqualApprox(uAll, u, 1e-10) { + t.Errorf("U mismatch when VT is not computed: %s", errStr) + } + if !floats.EqualApprox(s, sCopy, 1e-10) { + t.Errorf("Singular value mismatch when U computed VT not") + } + jobU = lapack.SVDNone + jobVT = job + copy(a, aCopy) + for i := range s { + s[i] = rnd.Float64() + } + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, tmp1, ldu, vt, ldvt, work, -1) + work = make([]float64, int(work[0])) + lwork = len(work) + if shortWork { + lwork-- + } + impl.Dgesvd(jobU, jobVT, m, n, a, lda, s, tmp1, ldu, vt, ldvt, work, len(work)) + if !floats.EqualApprox(vtAll, vt, 1e-10) { + t.Errorf("VT mismatch when U is not computed: %s", errStr) + } + if !floats.EqualApprox(s, sCopy, 1e-10) { + t.Errorf("Singular value mismatch when VT computed U not") + } +} + +// svdCheck checks that the singular value decomposition correctly multiplies back +// to the original matrix. +func svdCheck(t *testing.T, thin bool, errStr string, m, n int, s, a, u []float64, ldu int, vt []float64, ldvt int, aCopy []float64, lda int) { + sigma := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + for i := 0; i < min(m, n); i++ { + sigma.Data[i*sigma.Stride+i] = s[i] + } + + uMat := blas64.General{ + Rows: m, + Cols: m, + Stride: ldu, + Data: u, + } + vTMat := blas64.General{ + Rows: n, + Cols: n, + Stride: ldvt, + Data: vt, + } + if thin { + sigma.Rows = min(m, n) + sigma.Cols = min(m, n) + uMat.Cols = min(m, n) + vTMat.Rows = min(m, n) + } + + tmp := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + ans := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + copy(ans.Data, a) + + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, uMat, sigma, 0, tmp) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmp, vTMat, 0, ans) + + if !floats.EqualApprox(ans.Data, aCopy, 1e-8) { + t.Errorf("Decomposition mismatch. Trim = %v, %s", thin, errStr) + } + + if !thin { + // Check that U and V are orthogonal. + for i := 0; i < uMat.Rows; i++ { + for j := i + 1; j < uMat.Rows; j++ { + dot := blas64.Dot(uMat.Cols, + blas64.Vector{Inc: 1, Data: uMat.Data[i*uMat.Stride:]}, + blas64.Vector{Inc: 1, Data: uMat.Data[j*uMat.Stride:]}, + ) + if dot > 1e-8 { + t.Errorf("U not orthogonal %s", errStr) + } + } + } + for i := 0; i < vTMat.Rows; i++ { + for j := i + 1; j < vTMat.Rows; j++ { + dot := blas64.Dot(vTMat.Cols, + blas64.Vector{Inc: 1, Data: vTMat.Data[i*vTMat.Stride:]}, + blas64.Vector{Inc: 1, Data: vTMat.Data[j*vTMat.Stride:]}, + ) + if dot > 1e-8 { + t.Errorf("V not orthogonal %s", errStr) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetf2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetf2.go new file mode 100644 index 00000000..7cb155e9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetf2.go @@ -0,0 +1,195 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dgetf2er interface { + Dgetf2(m, n int, a []float64, lda int, ipiv []int) bool +} + +func Dgetf2Test(t *testing.T, impl Dgetf2er) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, lda int + }{ + {10, 10, 0}, + {10, 5, 0}, + {10, 5, 0}, + + {10, 10, 20}, + {5, 10, 20}, + {10, 5, 20}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + mn := min(m, n) + ipiv := make([]int, mn) + for i := range ipiv { + ipiv[i] = rnd.Int() + } + ok := impl.Dgetf2(m, n, a, lda, ipiv) + checkPLU(t, ok, m, n, lda, ipiv, a, aCopy, 1e-14, true) + } + + // Test with singular matrices (random matrices are almost surely non-singular). + for _, test := range []struct { + m, n, lda int + a []float64 + }{ + { + m: 2, + n: 2, + lda: 2, + a: []float64{ + 1, 0, + 0, 0, + }, + }, + { + m: 2, + n: 2, + lda: 2, + a: []float64{ + 1, 5, + 2, 10, + }, + }, + { + m: 3, + n: 3, + lda: 3, + // row 3 = row1 + 2 * row2 + a: []float64{ + 1, 5, 7, + 2, 10, -3, + 5, 25, 1, + }, + }, + { + m: 3, + n: 4, + lda: 4, + // row 3 = row1 + 2 * row2 + a: []float64{ + 1, 5, 7, 9, + 2, 10, -3, 11, + 5, 25, 1, 31, + }, + }, + } { + if impl.Dgetf2(test.m, test.n, test.a, test.lda, make([]int, min(test.m, test.n))) { + t.Log("Returned ok with singular matrix.") + } + } +} + +// checkPLU checks that the PLU factorization contained in factorize matches +// the original matrix contained in original. +func checkPLU(t *testing.T, ok bool, m, n, lda int, ipiv []int, factorized, original []float64, tol float64, print bool) { + var hasZeroDiagonal bool + for i := 0; i < min(m, n); i++ { + if factorized[i*lda+i] == 0 { + hasZeroDiagonal = true + break + } + } + if hasZeroDiagonal && ok { + t.Error("Has a zero diagonal but returned ok") + } + if !hasZeroDiagonal && !ok { + t.Error("Non-zero diagonal but returned !ok") + } + + // Check that the LU decomposition is correct. + mn := min(m, n) + l := make([]float64, m*mn) + ldl := mn + u := make([]float64, mn*n) + ldu := n + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + v := factorized[i*lda+j] + switch { + case i == j: + l[i*ldl+i] = 1 + u[i*ldu+i] = v + case i > j: + l[i*ldl+j] = v + case i < j: + u[i*ldu+j] = v + } + } + } + + LU := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + U := blas64.General{ + Rows: mn, + Cols: n, + Stride: ldu, + Data: u, + } + L := blas64.General{ + Rows: m, + Cols: mn, + Stride: ldl, + Data: l, + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, L, U, 0, LU) + + p := make([]float64, m*m) + ldp := m + for i := 0; i < m; i++ { + p[i*ldp+i] = 1 + } + for i := len(ipiv) - 1; i >= 0; i-- { + v := ipiv[i] + blas64.Swap(m, blas64.Vector{Inc: 1, Data: p[i*ldp:]}, blas64.Vector{Inc: 1, Data: p[v*ldp:]}) + } + P := blas64.General{ + Rows: m, + Cols: m, + Stride: m, + Data: p, + } + aComp := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + copy(aComp.Data, factorized) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, P, LU, 0, aComp) + if !floats.EqualApprox(aComp.Data, original, tol) { + if print { + t.Errorf("PLU multiplication does not match original matrix.\nWant: %v\nGot: %v", original, aComp.Data) + return + } + t.Error("PLU multiplication does not match original matrix.") + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetrf.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetrf.go new file mode 100644 index 00000000..1c9c6e45 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetrf.go @@ -0,0 +1,65 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" +) + +type Dgetrfer interface { + Dgetrf(m, n int, a []float64, lda int, ipiv []int) bool +} + +func DgetrfTest(t *testing.T, impl Dgetrfer) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, lda int + }{ + {10, 5, 0}, + {5, 10, 0}, + {10, 10, 0}, + {300, 5, 0}, + {3, 500, 0}, + {4, 5, 0}, + {300, 200, 0}, + {204, 300, 0}, + {1, 3000, 0}, + {3000, 1, 0}, + {10, 5, 20}, + {5, 10, 20}, + {10, 10, 20}, + {300, 5, 400}, + {3, 500, 600}, + {200, 200, 300}, + {300, 200, 300}, + {204, 300, 400}, + {1, 3000, 4000}, + {3000, 1, 4000}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + mn := min(m, n) + ipiv := make([]int, mn) + for i := range ipiv { + ipiv[i] = rnd.Int() + } + + // Cannot compare the outputs of Dgetrf and Dgetf2 because the pivoting may + // happen differently. Instead check that the LPQ factorization is correct. + aCopy := make([]float64, len(a)) + copy(aCopy, a) + ok := impl.Dgetrf(m, n, a, lda, ipiv) + checkPLU(t, ok, m, n, lda, ipiv, a, aCopy, 1e-10, false) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetri.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetri.go new file mode 100644 index 00000000..fd79df2a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetri.go @@ -0,0 +1,89 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dgetrier interface { + Dgetrfer + Dgetri(n int, a []float64, lda int, ipiv []int, work []float64, lwork int) bool +} + +func DgetriTest(t *testing.T, impl Dgetrier) { + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + for _, test := range []struct { + n, lda int + }{ + {5, 0}, + {5, 8}, + {45, 0}, + {45, 50}, + {65, 0}, + {65, 70}, + {150, 0}, + {150, 250}, + } { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + // Generate a random well conditioned matrix + perm := rnd.Perm(n) + a := make([]float64, n*lda) + for i := 0; i < n; i++ { + a[i*lda+perm[i]] = 1 + } + for i := range a { + a[i] += 0.01 * rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + ipiv := make([]int, n) + // Compute LU decomposition. + impl.Dgetrf(n, n, a, lda, ipiv) + // Compute inverse. + work := make([]float64, 1) + impl.Dgetri(n, a, lda, ipiv, work, -1) + work = make([]float64, int(work[0])) + lwork := len(work) + + ok := impl.Dgetri(n, a, lda, ipiv, work, lwork) + if !ok { + t.Errorf("Unexpected singular matrix.") + } + + // Check that A(inv) * A = I. + ans := make([]float64, len(a)) + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, n, n, 1, aCopy, lda, a, lda, 0, ans, lda) + isEye := true + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if i == j { + // This tolerance is so high because computing matrix inverses + // is very unstable. + if math.Abs(ans[i*lda+j]-1) > 5e-2 { + isEye = false + } + } else { + if math.Abs(ans[i*lda+j]) > 5e-2 { + isEye = false + } + } + } + } + if !isEye { + t.Errorf("Inv(A) * A != I. n = %v, lda = %v", n, lda) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetrs.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetrs.go new file mode 100644 index 00000000..edc6d502 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dgetrs.go @@ -0,0 +1,113 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dgetrser interface { + Dgetrfer + Dgetrs(trans blas.Transpose, n, nrhs int, a []float64, lda int, ipiv []int, b []float64, ldb int) +} + +func DgetrsTest(t *testing.T, impl Dgetrser) { + rnd := rand.New(rand.NewSource(1)) + // TODO(btracey): Put more thought into creating more regularized matrices + // and what correct tolerances should be. Consider also seeding the random + // number in this test to make it more robust to code changes in other + // parts of the suite. + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, test := range []struct { + n, nrhs, lda, ldb int + tol float64 + }{ + {3, 3, 0, 0, 1e-12}, + {3, 5, 0, 0, 1e-12}, + {5, 3, 0, 0, 1e-12}, + + {3, 3, 8, 10, 1e-12}, + {3, 5, 8, 10, 1e-12}, + {5, 3, 8, 10, 1e-12}, + + {300, 300, 0, 0, 1e-8}, + {300, 500, 0, 0, 1e-8}, + {500, 300, 0, 0, 1e-6}, + + {300, 300, 700, 600, 1e-8}, + {300, 500, 700, 600, 1e-8}, + {500, 300, 700, 600, 1e-6}, + } { + n := test.n + nrhs := test.nrhs + lda := test.lda + if lda == 0 { + lda = n + } + ldb := test.ldb + if ldb == 0 { + ldb = nrhs + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.Float64() + } + b := make([]float64, n*ldb) + for i := range b { + b[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + bCopy := make([]float64, len(b)) + copy(bCopy, b) + + ipiv := make([]int, n) + for i := range ipiv { + ipiv[i] = rnd.Int() + } + + // Compute the LU factorization. + impl.Dgetrf(n, n, a, lda, ipiv) + // Solve the system of equations given the result. + impl.Dgetrs(trans, n, nrhs, a, lda, ipiv, b, ldb) + + // Check that the system of equations holds. + A := blas64.General{ + Rows: n, + Cols: n, + Stride: lda, + Data: aCopy, + } + B := blas64.General{ + Rows: n, + Cols: nrhs, + Stride: ldb, + Data: bCopy, + } + X := blas64.General{ + Rows: n, + Cols: nrhs, + Stride: ldb, + Data: b, + } + tmp := blas64.General{ + Rows: n, + Cols: nrhs, + Stride: ldb, + Data: make([]float64, n*ldb), + } + copy(tmp.Data, bCopy) + blas64.Gemm(trans, blas.NoTrans, 1, A, X, 0, B) + if !floats.EqualApprox(tmp.Data, bCopy, test.tol) { + t.Errorf("Linear solve mismatch. trans = %v, n = %v, nrhs = %v, lda = %v, ldb = %v", trans, n, nrhs, lda, ldb) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dggsvd3.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dggsvd3.go new file mode 100644 index 00000000..0a4af656 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dggsvd3.go @@ -0,0 +1,173 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dggsvd3er interface { + Dggsvd3(jobU, jobV, jobQ lapack.GSVDJob, m, n, p int, a []float64, lda int, b []float64, ldb int, alpha, beta, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, work []float64, lwork int, iwork []int) (k, l int, ok bool) +} + +func Dggsvd3Test(t *testing.T, impl Dggsvd3er) { + rnd := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + m, p, n, lda, ldb, ldu, ldv, ldq int + + ok bool + }{ + {m: 3, p: 3, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 10, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 10, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 5, lda: 10, ldb: 10, ldu: 10, ldv: 10, ldq: 10, ok: true}, + {m: 5, p: 5, n: 5, lda: 10, ldb: 10, ldu: 10, ldv: 10, ldq: 10, ok: true}, + {m: 5, p: 5, n: 10, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20, ok: true}, + {m: 5, p: 5, n: 10, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20, ok: true}, + {m: 5, p: 5, n: 10, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20, ok: true}, + {m: 10, p: 5, n: 5, lda: 10, ldb: 10, ldu: 20, ldv: 10, ldq: 10, ok: true}, + {m: 10, p: 5, n: 5, lda: 10, ldb: 10, ldu: 20, ldv: 10, ldq: 10, ok: true}, + {m: 10, p: 10, n: 10, lda: 20, ldb: 20, ldu: 20, ldv: 20, ldq: 20, ok: true}, + {m: 10, p: 10, n: 10, lda: 20, ldb: 20, ldu: 20, ldv: 20, ldq: 20, ok: true}, + } { + m := test.m + p := test.p + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + ldb := test.ldb + if ldb == 0 { + ldb = n + } + ldu := test.ldu + if ldu == 0 { + ldu = m + } + ldv := test.ldv + if ldv == 0 { + ldv = p + } + ldq := test.ldq + if ldq == 0 { + ldq = n + } + + a := randomGeneral(m, n, lda, rnd) + aCopy := cloneGeneral(a) + b := randomGeneral(p, n, ldb, rnd) + bCopy := cloneGeneral(b) + + alpha := make([]float64, n) + beta := make([]float64, n) + + u := nanGeneral(m, m, ldu) + v := nanGeneral(p, p, ldv) + q := nanGeneral(n, n, ldq) + + iwork := make([]int, n) + + work := []float64{0} + impl.Dggsvd3(lapack.GSVDU, lapack.GSVDV, lapack.GSVDQ, + m, n, p, + a.Data, a.Stride, + b.Data, b.Stride, + alpha, beta, + u.Data, u.Stride, + v.Data, v.Stride, + q.Data, q.Stride, + work, -1, iwork) + + lwork := int(work[0]) + work = make([]float64, lwork) + + k, l, ok := impl.Dggsvd3(lapack.GSVDU, lapack.GSVDV, lapack.GSVDQ, + m, n, p, + a.Data, a.Stride, + b.Data, b.Stride, + alpha, beta, + u.Data, u.Stride, + v.Data, v.Stride, + q.Data, q.Stride, + work, lwork, iwork) + + if !ok { + if test.ok { + t.Errorf("test %d unexpectedly did not converge", cas) + } + continue + } + + // Check orthogonality of U, V and Q. + if !isOrthonormal(u) { + t.Errorf("test %d: U is not orthogonal\n%+v", cas, u) + } + if !isOrthonormal(v) { + t.Errorf("test %d: V is not orthogonal\n%+v", cas, v) + } + if !isOrthonormal(q) { + t.Errorf("test %d: Q is not orthogonal\n%+v", cas, q) + } + + // Check C^2 + S^2 = I. + var elements []float64 + if m-k-l >= 0 { + elements = alpha[k : k+l] + } else { + elements = alpha[k:m] + } + for i := range elements { + i += k + d := alpha[i]*alpha[i] + beta[i]*beta[i] + if !floats.EqualWithinAbsOrRel(d, 1, 1e-14, 1e-14) { + t.Errorf("test %d: alpha_%d^2 + beta_%d^2 != 1: got: %v", cas, i, i, d) + } + } + + zeroR, d1, d2 := constructGSVDresults(n, p, m, k, l, a, b, alpha, beta) + + // Check U^T*A*Q = D1*[ 0 R ]. + uTmp := nanGeneral(m, n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, u, aCopy, 0, uTmp) + uAns := nanGeneral(m, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, uTmp, q, 0, uAns) + + d10r := nanGeneral(m, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, d1, zeroR, 0, d10r) + + if !equalApproxGeneral(uAns, d10r, 1e-14) { + t.Errorf("test %d: U^T*A*Q != D1*[ 0 R ]\nU^T*A*Q:\n%+v\nD1*[ 0 R ]:\n%+v", + cas, uAns, d10r) + } + + // Check V^T*B*Q = D2*[ 0 R ]. + vTmp := nanGeneral(p, n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, v, bCopy, 0, vTmp) + vAns := nanGeneral(p, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, vTmp, q, 0, vAns) + + d20r := nanGeneral(p, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, d2, zeroR, 0, d20r) + + if !equalApproxGeneral(vAns, d20r, 1e-14) { + t.Errorf("test %d: V^T*B*Q != D2*[ 0 R ]\nV^T*B*Q:\n%+v\nD2*[ 0 R ]:\n%+v", + cas, vAns, d20r) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dggsvp3.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dggsvp3.go new file mode 100644 index 00000000..23111518 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dggsvp3.go @@ -0,0 +1,146 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +type Dggsvp3er interface { + Dlanger + Dggsvp3(jobU, jobV, jobQ lapack.GSVDJob, m, p, n int, a []float64, lda int, b []float64, ldb int, tola, tolb float64, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, iwork []int, tau, work []float64, lwork int) (k, l int) +} + +func Dggsvp3Test(t *testing.T, impl Dggsvp3er) { + rnd := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + m, p, n, lda, ldb, ldu, ldv, ldq int + }{ + {m: 3, p: 3, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 5, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 5, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 5, p: 5, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 5, p: 5, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 5, p: 5, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 10, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 10, p: 5, n: 5, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 10, p: 10, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 10, p: 10, n: 10, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0}, + {m: 5, p: 5, n: 5, lda: 10, ldb: 10, ldu: 10, ldv: 10, ldq: 10}, + {m: 5, p: 5, n: 5, lda: 10, ldb: 10, ldu: 10, ldv: 10, ldq: 10}, + {m: 5, p: 5, n: 10, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20}, + {m: 5, p: 5, n: 10, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20}, + {m: 5, p: 5, n: 10, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20}, + {m: 10, p: 5, n: 5, lda: 10, ldb: 10, ldu: 20, ldv: 10, ldq: 10}, + {m: 10, p: 5, n: 5, lda: 10, ldb: 10, ldu: 20, ldv: 10, ldq: 10}, + {m: 10, p: 10, n: 10, lda: 20, ldb: 20, ldu: 20, ldv: 20, ldq: 20}, + {m: 10, p: 10, n: 10, lda: 20, ldb: 20, ldu: 20, ldv: 20, ldq: 20}, + } { + m := test.m + p := test.p + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + ldb := test.ldb + if ldb == 0 { + ldb = n + } + ldu := test.ldu + if ldu == 0 { + ldu = m + } + ldv := test.ldv + if ldv == 0 { + ldv = p + } + ldq := test.ldq + if ldq == 0 { + ldq = n + } + + a := randomGeneral(m, n, lda, rnd) + aCopy := cloneGeneral(a) + b := randomGeneral(p, n, ldb, rnd) + bCopy := cloneGeneral(b) + + tola := float64(max(m, n)) * impl.Dlange(lapack.NormFrob, m, n, a.Data, a.Stride, nil) * dlamchE + tolb := float64(max(p, n)) * impl.Dlange(lapack.NormFrob, p, n, b.Data, b.Stride, nil) * dlamchE + + u := nanGeneral(m, m, ldu) + v := nanGeneral(p, p, ldv) + q := nanGeneral(n, n, ldq) + + iwork := make([]int, n) + tau := make([]float64, n) + + work := []float64{0} + impl.Dggsvp3(lapack.GSVDU, lapack.GSVDV, lapack.GSVDQ, + m, p, n, + a.Data, a.Stride, + b.Data, b.Stride, + tola, tolb, + u.Data, u.Stride, + v.Data, v.Stride, + q.Data, q.Stride, + iwork, tau, + work, -1) + + lwork := int(work[0]) + work = make([]float64, lwork) + + k, l := impl.Dggsvp3(lapack.GSVDU, lapack.GSVDV, lapack.GSVDQ, + m, p, n, + a.Data, a.Stride, + b.Data, b.Stride, + tola, tolb, + u.Data, u.Stride, + v.Data, v.Stride, + q.Data, q.Stride, + iwork, tau, + work, lwork) + + // Check orthogonality of U, V and Q. + if !isOrthonormal(u) { + t.Errorf("test %d: U is not orthogonal\n%+v", cas, u) + } + if !isOrthonormal(v) { + t.Errorf("test %d: V is not orthogonal\n%+v", cas, v) + } + if !isOrthonormal(q) { + t.Errorf("test %d: Q is not orthogonal\n%+v", cas, q) + } + + zeroA, zeroB := constructGSVPresults(n, p, m, k, l, a, b) + + // Check U^T*A*Q = [ 0 RA ]. + uTmp := nanGeneral(m, n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, u, aCopy, 0, uTmp) + uAns := nanGeneral(m, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, uTmp, q, 0, uAns) + + if !equalApproxGeneral(uAns, zeroA, 1e-14) { + t.Errorf("test %d: U^T*A*Q != [ 0 RA ]\nU^T*A*Q:\n%+v\n[ 0 RA ]:\n%+v", + cas, uAns, zeroA) + } + + // Check V^T*B*Q = [ 0 RB ]. + vTmp := nanGeneral(p, n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, v, bCopy, 0, vTmp) + vAns := nanGeneral(p, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, vTmp, q, 0, vAns) + + if !equalApproxGeneral(vAns, zeroB, 1e-14) { + t.Errorf("test %d: V^T*B*Q != [ 0 RB ]\nV^T*B*Q:\n%+v\n[ 0 RB ]:\n%+v", + cas, vAns, zeroB) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dhseqr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dhseqr.go new file mode 100644 index 00000000..85ae5234 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dhseqr.go @@ -0,0 +1,861 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dhseqrer interface { + Dhseqr(job lapack.EVJob, compz lapack.EVComp, n, ilo, ihi int, h []float64, ldh int, wr, wi []float64, + z []float64, ldz int, work []float64, lwork int) int +} + +type dhseqrTest struct { + n int + ilo int + ihi int + h []float64 + tol float64 + + evWant []complex128 +} + +func DhseqrTest(t *testing.T, impl Dhseqrer) { + for i, tc := range dhseqrTests { + for _, job := range []lapack.EVJob{lapack.EigenvaluesOnly, lapack.EigenvaluesAndSchur} { + for _, wantz := range []bool{false, true} { + for _, extra := range []int{0, 11} { + testDhseqr(t, impl, i, tc, job, wantz, extra, true) + testDhseqr(t, impl, i, tc, job, wantz, extra, false) + } + } + } + } +} + +func testDhseqr(t *testing.T, impl Dhseqrer, i int, test dhseqrTest, job lapack.EVJob, wantz bool, extra int, optwork bool) { + const tol = 1e-14 + evTol := test.tol + if evTol == 0 { + evTol = tol + } + + n := test.n + ihi := test.ihi + ilo := test.ilo + h := zeros(n, n, n+extra) + copyGeneral(h, blas64.General{Rows: n, Cols: n, Stride: max(1, n), Data: test.h}) + hCopy := cloneGeneral(h) + + var compz lapack.EVComp = lapack.None + z := blas64.General{Stride: max(1, n)} + if wantz { + // First, let Dhseqr initialize Z to the identity matrix. + compz = lapack.HessEV + z = nanGeneral(n, n, n+extra) + } + + wr := nanSlice(n) + wi := nanSlice(n) + + work := nanSlice(max(1, n)) + if optwork { + impl.Dhseqr(job, lapack.HessEV, n, ilo, ihi, nil, h.Stride, nil, nil, nil, z.Stride, work, -1) + work = nanSlice(int(work[0])) + } + + unconverged := impl.Dhseqr(job, compz, n, ilo, ihi, h.Data, h.Stride, wr, wi, z.Data, z.Stride, work, len(work)) + prefix := fmt.Sprintf("Case %v: job=%v, compz=%v, n=%v, ilo=%v, ihi=%v, extra=%v, optwk=%v", + i, job, compz, n, ilo, ihi, extra, optwork) + if unconverged > 0 { + t.Logf("%v: Dhseqr did not compute all eigenvalues. unconverged=%v", prefix, unconverged) + if unconverged <= ilo { + t.Fatalf("%v: 0 < unconverged <= ilo", prefix) + } + } + + // Check that wr and wi have been assigned completely. + if floats.HasNaN(wr) { + t.Errorf("%v: wr has NaN elements", prefix) + } + if floats.HasNaN(wi) { + t.Errorf("%v: wi has NaN elements", prefix) + } + + // Check that complex eigenvalues are stored in consecutive elements as + // complex conjugate pairs. + for i := 0; i < n; { + if unconverged > 0 && i == ilo { + // Skip the unconverged eigenvalues. + i = unconverged + continue + } + if wi[i] == 0 { + // Real eigenvalue. + i++ + continue + } + // Complex conjugate pair. + if wr[i] != wr[i+1] { + t.Errorf("%v: conjugate pair has real parts unequal", prefix) + } + if wi[i] < 0 { + t.Errorf("%v: first in conjugate pair has negative imaginary part", prefix) + } + if wi[i+1] != -wi[i] { + t.Errorf("%v: complex pair is not conjugate", prefix) + } + i += 2 + } + + // Check that H contains the Schur form T. + if job == lapack.EigenvaluesAndSchur { + for i := 0; i < n; { + if unconverged > 0 && i == ilo { + // Skip the unconverged eigenvalues. + i = unconverged + continue + } + if wi[i] == 0 { + // Real eigenvalue. + if wr[i] != h.Data[i*h.Stride+i] { + t.Errorf("%v: T not in Schur form (real eigenvalue not on diagonal)", prefix) + } + i++ + continue + } + // Complex conjugate pair. + im := math.Sqrt(math.Abs(h.Data[(i+1)*h.Stride+i])) * math.Sqrt(math.Abs(h.Data[i*h.Stride+i+1])) + if wr[i] != h.Data[i*h.Stride+i] || wr[i] != h.Data[(i+1)*h.Stride+i+1] || + math.Abs(wi[i]-im) > tol { + t.Errorf("%v: conjugate pair and 2×2 diagonal block don't correspond", prefix) + } + i += 2 + } + } + + // Check that all the found eigenvalues are really eigenvalues. + foundEV := make([]bool, len(test.evWant)) + for i := 0; i < n; { + if unconverged > 0 && i == ilo { + // Skip the unconverged eigenvalues. + i = unconverged + continue + } + ev := complex(wr[i], wi[i]) + // Use problem-specific tolerance for testing eigenvalues. + found, index := containsComplex(test.evWant, ev, evTol) + if !found { + t.Errorf("%v: unexpected eigenvalue %v", prefix, ev) + } else { + foundEV[index] = true + } + i++ + } + if unconverged == 0 { + // Check that all eigenvalues have been found. + // This simple check assumes that all eigenvalues are + // sufficiently separated from each other at least by evTol. + for i := range foundEV { + if !foundEV[i] { + t.Errorf("%v: %vth eigenvalue not found", prefix, i) + } + } + } + + if !wantz { + return + } + + // Z must be orthogonal. + if !isOrthonormal(z) { + t.Errorf("%v: Z is not orthogonal", prefix) + } + + if job == lapack.EigenvaluesAndSchur { + tz := zeros(n, n, n) + blas64.Gemm(blas.NoTrans, blas.Trans, 1, h, z, 0, tz) + ztz := zeros(n, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, z, tz, 0, ztz) + if !equalApproxGeneral(ztz, hCopy, evTol) { + t.Errorf("%v: H != Z T Z^T", prefix) + } + } + + // Restore H. + copyGeneral(h, hCopy) + // Call Dhseqr again with the identity matrix given explicitly in Q. + q := eye(n, n+extra) + impl.Dhseqr(job, lapack.OriginalEV, n, ilo, ihi, h.Data, h.Stride, wr, wi, q.Data, q.Stride, work, len(work)) + if !equalApproxGeneral(z, q, 0) { + t.Errorf("%v: Z and Q are not equal", prefix) + } +} + +var dhseqrTests = []dhseqrTest{ + { + n: 0, + ilo: 0, + ihi: -1, + }, + { + n: 1, + ilo: 0, + ihi: 0, + h: []float64{0}, + evWant: []complex128{0}, + }, + { + n: 1, + ilo: 0, + ihi: 0, + h: []float64{7.09965484086874e-1}, + evWant: []complex128{7.09965484086874e-1}, + }, + { + n: 2, + ilo: 0, + ihi: 1, + h: []float64{0, 0, 0, 0}, + evWant: []complex128{0}, + }, + { + n: 2, + ilo: 0, + ihi: 1, + h: []float64{ + 1, 0, + 0, 1, + }, + evWant: []complex128{1}, + }, + { + n: 2, + ilo: 0, + ihi: 1, + h: []float64{ + 0, -1, + 1, 0, + }, + evWant: []complex128{1i, -1i}, + }, + { + n: 2, + ilo: 0, + ihi: 1, + h: []float64{ + 6.25219991450918e-1, 8.17510791994361e-1, + 3.31218891622294e-1, 1.24103744878131e-1, + }, + evWant: []complex128{9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + n: 4, + ilo: 1, + ihi: 2, + h: []float64{ + 1, 0, 0, 0, + 0, 6.25219991450918e-1, 8.17510791994361e-1, 0, + 0, 3.31218891622294e-1, 1.24103744878131e-1, 0, + 0, 0, 0, 2, + }, + evWant: []complex128{1, 2, 9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + n: 2, + ilo: 0, + ihi: 1, + h: []float64{ + -1.1219562276608, 6.85473513349362e-1, + -8.19951061145131e-1, 1.93728523178888e-1, + }, + evWant: []complex128{ + -4.64113852240958e-1 + 3.59580510817350e-1i, + -4.64113852240958e-1 - 3.59580510817350e-1i, + }, + }, + { + n: 5, + ilo: 0, + ihi: 4, + h: []float64{ + 9.57590178533658e-1, -5.10651295522708e-1, 9.24974510015869e-1, -1.30016306879522e-1, 2.92601986926954e-2, + -1.08084756637964, 1.77529701001213, -1.36480197632509, 2.23196371219601e-1, 1.12912853063308e-1, + 0, -8.44075612174676e-1, 1.067867614486, -2.55782915176399e-1, -2.00598563137468e-1, + 0, 0, -5.67097237165410e-1, 2.07205057427341e-1, 6.54998340743380e-1, + 0, 0, 0, -1.89441413886041e-1, -4.18125416021786e-1, + }, + evWant: []complex128{ + 2.94393309555622, + 4.97029793606701e-1 + 3.63041654992384e-1i, + 4.97029793606701e-1 - 3.63041654992384e-1i, + -1.74079119166145e-1 + 2.01570009462092e-1i, + -1.74079119166145e-1 - 2.01570009462092e-1i, + }, + }, + { + // BFW62A matrix from MatrixMarket, balanced and factorized into + // upper Hessenberg form in Octave. + // Eigenvalues computed by eig function in Octave. + // Dhseqr considers this matrix small (n <= 75). + n: 62, + ilo: 0, + ihi: 61, + tol: 1e-12, + h: []float64{ + 0.7610708, -0.71474042262732, -1.03373461417302e-17, 8.218284875369092e-18, -4.39003777724509e-18, -7.633870714681998e-18, -9.951525116511751e-18, -6.538760279193677e-18, -1.656240811786753e-18, -4.915424973452908e-18, -7.590492820502813e-18, -4.532592864746854e-18, 1.137360639223451e-18, -2.088794138001457e-18, 4.330727699351238e-18, 4.88172964159538e-18, -6.438459345602974e-18, 7.414402965763168e-18, 8.592387304092668e-19, 2.905505475188102e-18, -5.210204793418634e-18, 2.377023457149656e-18, -1.958364175388968e-18, -8.746122759061733e-20, 1.839015672758814e-18, 3.097454207400904e-18, 1.545856657360309e-18, 1.713923049773744e-21, 1.333951071201153e-18, -1.256151066318485e-18, 5.489655201308922e-19, -2.191335276195054e-18, 3.211054779957158e-18, -4.585099368362507e-19, 4.064807180521144e-18, -3.621561583390336e-18, 4.638803832189033e-19, 1.306132013406548e-18, 7.71710094138792e-19, 2.320760977517361e-18, -6.538298612520761e-19, -3.498839827985687e-18, 2.699116500378558e-18, -1.653627855476782e-18, 7.006984532830204e-19, -2.829108657299736e-18, -5.260772120044258e-18, 1.014346572590618e-18, -1.751563831849658e-18, -1.850186018112724e-19, 2.870415308417256e-18, -8.423700664162806e-19, 3.498345394735042e-19, 1.448350507022323e-18, -3.119800500343431e-18, 4.170966784863917e-18, -4.413795207992463e-19, -2.550853151356032e-18, 2.058575286932081e-18, 1.11609155804576e-18, -2.819648393130598e-18, -2.691434041700446e-19, + -0.71474042262732, 1.938395745278447, -1.179041092366627, 2.994496337305918e-17, -1.886890458028042e-17, -1.696051150581149e-17, -1.066654178739982e-17, -6.29828959344471e-18, -3.017613522337327e-18, -6.087774183044001e-18, -1.623722797471356e-17, -1.609066043798334e-17, 1.1222991062801e-17, -1.199415856132727e-17, 3.254808477409891e-17, 3.032574771313234e-17, -2.950307698970009e-17, 3.390164991463985e-17, 3.580652213399182e-17, -1.363239170451582e-17, 5.318959619432346e-19, -2.094826370136215e-17, 2.503105756608372e-17, 1.02172885473953e-17, 2.072365201436764e-17, 5.419721687057681e-17, 2.946627912791419e-17, -1.348815353957071e-17, -6.109538294302727e-18, 8.919596400140564e-19, -4.965011212156456e-18, -8.892555328798407e-18, -8.533370652960768e-18, 2.670935841220357e-17, 6.294143735482237e-17, -6.631964574578866e-17, 1.610888675267686e-17, -1.914212496162892e-17, 7.491989417296875e-17, 2.433601037912241e-17, -3.471972221532949e-17, 1.239231453972595e-18, 8.477927675716922e-17, 1.832368873558869e-17, -3.15614722379294e-17, -3.481308523858143e-17, 8.753655535825511e-17, -2.311094913977048e-17, -1.97736043621337e-17, -4.591312368362259e-18, -4.090767028097941e-17, 9.630744841167777e-17, 6.376373378245906e-17, 3.517117740157962e-18, -4.504796150838874e-17, 7.517908631343054e-17, 5.08947280115584e-17, -1.382149857389238e-17, -2.198919507523352e-18, 7.280187019637593e-18, -4.195544216643798e-17, -1.69351463438629e-16, + 0, -1.179041092366627, 1.770797890903813, 0.9251612011433773, 0.003661446613681521, -0.005110479724841567, 0.0005014497289028411, 0.00268637752732762, -0.003137790817099964, 0.0001251340392028716, 0.005236816389348038, -0.007596537304410319, -0.003216883293048434, 0.002836879838039065, 0.006069520262676079, 0.002668518333518884, 0.009131523505676264, 0.004626632495050776, 0.00181579510454105, 0.001123900611304629, 0.001677485377614088, 0.00363754391761903, -0.0007470406844762735, 0.002833257933303097, -0.0002375815340930377, -0.002849024657372476, -0.0002629124003065383, -0.0009435052243060314, -0.001501677820905836, 0.0007867717317979819, -0.003255814847476796, 0.0001229596171032013, 0.001899497807037465, 0.001586135347885108, -0.002155598204409179, -0.004095921626627291, -0.004749259183184092, -0.0003901939289968589, -0.00126397970751315, 0.001155644134671306, 0.000291837164140963, -0.0008540793573406925, 0.0005498493646965147, -0.000512747881346778, 0.001308619245804509, -0.001057469234737898, 8.364932352209563e-05, -0.0004759538737373512, 0.0002832407173157385, -2.502295625364179e-05, -0.001116422235449543, 0.0008744887175767913, -0.001577030646119032, 0.0006630051771088335, 0.0008174386956312274, 0.0005885600522543514, -0.000529324123745168, 0.0006462360717703873, -0.0005292503950906053, -0.0008409757119361148, 0.001179292096398777, -7.042243897656571e-05, + 0, 0, 0.9256234889252499, 2.188661152704918, -1.116554836905615, -0.02243454666837822, 0.001818477623431723, 0.01031345522542573, -0.02255181751639313, 0.01064389372187288, 0.02644236613167033, -0.03711341885334873, -0.01368507023909662, 0.005876976997280983, 0.04065670610764593, 0.01666467627475975, 0.04720670725274503, 0.02074371568474985, 0.02492606640786733, -0.0007477579555839802, 0.008780018993769038, 0.02228545976823896, -0.001309713708470288, 0.02515283874752867, -0.002695437114195642, -0.03058898397162627, -0.004721936411831751, -0.01112709820777293, 0.005156744291122814, 0.001266520229863774, -0.0173310067274492, 0.006032177243961209, 0.01546906824241716, 0.004122912475005991, -0.01457685983271352, -0.02472315268907353, -0.0146012575743626, 0.01613627552485761, -0.03570849487210562, 0.009634392591632741, 0.01396210133689555, -0.01085301942984549, 0.02308071799914048, -0.01534806641683973, 0.007461896675297811, 0.001678793578211992, -0.004550709803423801, -0.003543952787451961, 0.01328644094056202, 0.01722933205866279, -0.01604068924890588, 0.01061524273934986, -0.01948663408394128, 0.02488657490054273, 0.002560204204893632, -0.007049942019567433, -0.005861737475764968, 0.007063905438215945, -0.01302170441839208, -0.01452116548010346, 0.008856002952171451, 0.003352799875293177, + 0, 0, 0, -1.131565669446545, 3.458875937128813, -2.92300025604371, 0.0004977656856497978, 0.006279968970473544, 0.0775979532222543, -0.07809248806636047, -0.04323656216106807, 0.05001022064587737, 0.003864067108285046, 0.04141643188583877, -0.1284617838883834, -0.04493800214431209, -0.07456343090218126, -0.01563872481200422, -0.1339020629421785, 0.04186908269102881, -0.01575262227867954, -0.05122401589211525, -0.01356095585891559, -0.1061570482803366, 0.01819813598371521, 0.1481253462698246, 0.02550194602547843, 0.04637287461870648, -0.07444378895306285, 0.01361958240422481, 0.04035022896181466, -0.04232248915252568, -0.06075940528348658, 0.027263798939883, 0.03953143432541723, 0.06518841156851282, -0.03410646432627348, -0.1414076406563496, 0.2323217246349602, -0.03415439789233707, -0.1031903658536844, 0.06725801721048928, -0.1560521418148311, 0.1014900809050588, -0.02098771321982528, -0.03982159107235207, 0.03695361299827822, 0.01067293209294729, -0.09426629859219736, -0.1345822610538289, 0.09362330513280395, -0.05670709861587474, 0.1059566486421828, -0.1760916487632087, 0.003702764511325265, 0.07422105386227762, 0.02742567045198715, -0.03734725575689604, 0.08146131944298318, 0.09081980084945049, -0.03823012624212198, -0.02882941691361127, + 0, 0, 0, 0, -2.935177932025793, 5.590160898106907, -2.264162462726681, -0.02411424982833118, -0.1133643811701465, 0.1104837624251364, 0.05106708784671347, -0.03981053811687705, -0.02554107703230142, -0.06918772930550876, 0.1627330379332113, 0.0515325563326872, 0.0562468014393183, 0.0339155492439978, 0.1634368483167388, -0.06785129040640099, 0.04039982620620088, 0.04044710731973533, 0.0285518510842595, 0.1485759249940305, -0.0304537251951914, -0.2009213484930713, -0.05273834253818357, -0.03107458918212595, 0.09792748883617711, -0.0337039884304953, -0.06657284881035327, 0.04914327832710783, 0.07368372187446774, -0.0404082088678178, -0.04421178865717079, -0.0709487906769288, 0.048430647567918, 0.1864479159285081, -0.3079556699470428, 0.01491993158702447, 0.1333753802314968, -0.09591074161204663, 0.1894696359177905, -0.1319027537070656, 0.03081270942006841, 0.04847952392626505, -0.04816809266890478, -0.0008101823853040729, 0.1149477702272877, 0.1970244006374306, -0.1184305631819092, 0.07656633356645355, -0.140928669738484, 0.2423845347140408, -0.01430733985161339, -0.0967298709856266, -0.03791764167457073, 0.04501910433428818, -0.09499757971636948, -0.1139200858550714, 0.04630019674988028, 0.03975991363586522, + 0, 0, 0, 0, 0, -2.266072850070115, 4.40758227065786, -2.187592801167079, 0.04541318743325212, -0.0292500337966509, -0.02398663294591961, -0.0298607436249778, 0.0765927452101913, 0.03477459705241919, -0.0257224121936686, 0.001477537977391887, 0.04674868179804328, -0.07030659618878905, 0.0114383223715982, 0.04039500147294157, -0.06165490536387656, 0.03052165142437121, -0.03151343169646251, -0.04567511071619659, 0.01389646864038026, 0.03406059858329889, 0.07777247587370216, -0.05562215591676438, -0.02972304398764038, 0.04553302018172632, 0.04905358098395964, 0.02540110963535692, 0.00741827563880251, -0.02406479350578768, 0.00798549007761889, -0.02127832597347739, 0.01170084494509563, 0.002383029926628291, 0.02969332847749644, 0.07478610531483831, 0.01311741704707942, 0.004853415796376565, 0.02254889573704177, -0.0008058983249759786, -0.01674237970384834, 0.007747220993838389, 0.001741724814996781, -0.02678508693786828, 0.03009097476646124, -0.06933693587488159, -0.006894177513041368, -0.003212920179243059, 0.006244662438662574, -0.03261491350065344, 0.03016960268159134, -0.001128724172713099, 0.01002372353957473, 0.01549185843206932, -0.01638802914727083, -0.02186759059889685, 0.02607807397124053, -0.01433672343290503, + 0, 0, 0, 0, 0, 0, -2.208506791141428, 5.240066122406224, -2.182709291422287, -0.04831719550093321, -0.03858222961310988, 0.07090414091109702, 0.07618344970454043, 0.01210977758298604, -0.08775997916346844, -0.04209238321226993, -0.08158937930535407, -0.0691978468647506, -0.0718486976078294, 0.004433709126950578, -0.06338689200675134, -0.03622650750929987, -0.007019326939737634, -0.1038169299762074, -0.003664296783585897, 0.1260404715508425, 0.01449365280740196, 0.02152866502194497, -0.04579662426484265, 0.02137306190373941, 0.02841535413798802, -0.04356497460133966, -0.04882163279365745, 0.0002663261307664017, 0.04049595350038757, 0.05101584504101733, 0.02365749339968924, -0.05799471679730656, 0.1571971147245405, -0.01838060269733261, -0.05301211904637573, 0.02796283933445018, -0.0827747400120639, 0.0826539872568238, -0.004639853234141812, -0.03415100337915269, 0.02043301459221876, -0.01420687321749558, -0.07938788384250468, -0.06984431882951091, 0.01979778686221181, -0.05267713009695951, 0.05803585434476307, -0.1172598583231236, 0.01085942096095348, 0.03045318026097962, 0.03931707061762502, -0.0233260419792624, 0.02886660013519448, 0.03861548107303825, -0.03415507841094348, 0.008098200304311437, + 0, 0, 0, 0, 0, 0, 0, -2.279082737682327, 4.179202389209161, 2.014339592778223, -0.04255211810632337, 0.2215228709530191, 0.04554891291433198, -0.1776754857264893, 0.008167590360928265, -0.03396600462822136, -0.2424067171263278, -0.04982603310212124, 0.08199335145408625, -0.1620942794258422, 0.002338101300086993, -0.07021142224421691, 0.09194811379254013, 0.06141720296344315, -0.04343138202962209, -0.07659354927119244, -0.1361105641705367, 0.04365095033370017, 0.1736465880725596, -0.08740865081391179, -0.01477028109128357, -0.0188999323841316, -0.01077877669937425, -0.04294670860685663, 0.01729899060655344, 0.08739236799944389, 0.182034549192379, 0.1742753783161974, -0.2051811283512857, -0.09696129832199611, 0.08343537923840838, -0.04957366782909829, 0.1265093425463374, -0.07142635715461459, 0.03516617105992843, 0.0383997617140459, -0.04104973319490962, 0.02037353120337982, 0.04757894980296348, 0.2227131172970346, -0.07280127948445575, 0.01933448054625989, -0.05548809149836405, 0.2093056702150173, -0.07255565470500472, -0.123599084041237, -0.01537223729308192, 0.002577573950277644, -0.0733551734670323, -0.03190494711187865, -0.03967527247234395, 0.07966579792866824, + 0, 0, 0, 0, 0, 0, 0, 0, 1.903931035374501, 3.824975942360571, -1.918381148171332, -0.1657229385793016, -0.1612950026821678, 0.06698675826395525, 0.126725548868686, 0.05262161401229534, 0.1736974825351408, 0.1645930486922778, -0.008218244683807857, 0.0481824748986632, 0.1029912224929829, 0.04100531176584442, -0.05027752034197176, 0.03600703924093035, -0.03107821795488815, -0.09759422490480313, -0.04354787932553194, 0.08526304164417117, -0.05355786578034339, -0.0210819410892414, -0.1122497139926173, -0.02837719853579051, 0.02149997813969711, 0.06803627465540676, -0.0458177019216118, -0.09920218030202725, -0.1651400777956252, -0.0455277713939929, 0.003337830551949452, -0.06755253724103881, -0.07801076584667281, -0.04572759847378299, -0.02963338925321968, 0.07597836187621793, 0.01430341925034608, -0.02647305556934371, 0.0228555845523007, 0.01546873666210535, -0.03908905892485317, -0.01513876665871793, 0.0042446623219113, 0.03015387459510092, -0.02120400053387252, -0.03598829734362344, 0.004724005614895581, 0.07940598065515762, 0.01643813194117675, 0.005515400875796831, 0.03057541214871107, -0.01882273722478993, 0.001668026830005827, -0.02913002540516653, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.035489145812599, 3.958195998136282, -2.415518953202652, -0.1018252839623988, 0.09113791429521235, -0.143125166149266, -0.02308820648298807, 0.007900495974597297, 0.0891936029052371, -0.191496963455834, 0.08058392972181647, 0.05211306893716722, -0.02786699591928707, 0.007523375632267236, -0.05648289516476343, 0.06927000214275245, 0.1738730341952659, 0.04931088211870207, 0.03078035118979117, -0.09569654581650394, 0.01335103593932622, 0.06192961771791639, -0.02060940913305214, -0.05414923078827102, 0.06346107123244546, 0.02052335161999402, 0.0759441214578726, -0.1238298106880246, -0.2507681676381417, 0.3220100931816501, -0.01147160193974397, -0.1324548043218159, 0.1477869911354369, -0.2406607672124291, 0.06431201000607845, -0.01766450147458312, -0.0548904673124562, 0.05157233284634812, 0.04488059690309322, -0.06177517133954061, -0.23112183069299, 0.2080819465459902, -0.05619520043449243, 0.1795452492137158, -0.204269300276831, -0.01430899089131678, 0.08951777845217569, -0.02653873178692821, -0.04665500591425999, 0.1362175927592773, 0.1872861054389846, -0.02109220243469613, -0.07237982467321609, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.387825495222564, 5.631333594127314, 1.792900160009439, -0.1292562242890975, 0.1708356554410346, 0.04950951151168896, -0.009914110552264667, 0.1304655891154234, 0.1609748354747077, -0.08607480442007164, 0.1610516858008479, 0.006346254683211893, 0.02530117908848513, 0.2023262116291442, -0.04991598539162005, -0.3298986278194697, -0.1487726465103999, 0.04799870466505981, 0.1882318445518781, -0.1206769872912393, -0.09574976849564885, 0.04601707138105179, 0.0715991702971735, 0.0110319870997898, -0.07468722751312951, -0.06360236467100627, 0.03066807997062939, 0.1978804308092757, -0.4403223814664722, -0.09064370852004526, 0.08638179820445273, -0.1181221434581026, 0.2272147516466281, -0.1254616867610615, -0.0001501123827163629, 0.1032892317050803, -0.05195565185717236, 0.04689531008365307, 0.1236167395644631, 0.2849021718663459, -0.08639934992977449, 0.1211622058496298, -0.1593293433814323, 0.2959939998820938, -0.06193112020165896, -0.06245227757105343, -0.04632893647720479, 0.03583128970774434, -0.07735153068129821, -0.1215213155769518, 0.01117363777162431, 0.01224071348068845, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.970568498833333, 3.432745918572068, -2.179945131289983, 0.1549422681053906, 0.02156733618947362, -0.1743403098753009, 0.04884260166424702, 0.161193984588502, -0.2174611110448761, 0.05521624891494294, -0.05887323587614037, 0.1328019445063764, 0.150653877491827, -0.06531521571304157, -0.1543822385517836, -0.2043044123070031, 0.1255799677545108, 0.1951365223394271, -0.1233664137625445, -0.1191855712864921, -0.04903904444926842, 0.01721465629147372, -0.04824417949824886, -0.001809247060549745, 0.04683387964790045, 0.1406402447048902, 0.2582634735034707, -0.2591765142026595, -0.1617309876246061, 0.1040899633433518, -0.09204034179968526, 0.1659716858767694, -0.07258217699057123, 0.1238542047814545, -0.005315457299413418, -0.04888221850509963, 0.02889824196206881, 0.07250335907166307, 0.3039398127688065, -0.1278843615154275, 0.03794117583347663, -0.08815038995197073, 0.3363118210052076, -0.1106312150714128, -0.1943873573646721, -0.03270119577811206, 0.02061769160692044, -0.1147396461667833, -0.04432517129006736, -0.03624512007085111, 0.1372685073992675, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.971094433373163, 3.959369702740928, 1.887120354843997, -0.05026461165000308, -0.1399839889203879, -0.185627397808518, -0.04596340870656163, 0.008956420059669758, -0.1381531838530755, -0.06179826475610644, 0.03260995306247771, -0.0962297246933979, 0.05268169622571128, 0.2046211566675452, 0.1296024872478153, -0.05109478171641717, -0.06816393508471544, 0.06908783957203835, 0.1203829447316026, 0.01720249086925636, -0.03678250120900584, -0.09954728921499965, 0.08400427932827997, 0.09706474262764897, 0.1099658716687498, -0.02055867348093135, 0.1883358420037133, 0.09179573472650564, 0.0428976892444284, 0.06904499115717885, -0.07352106561747025, -0.01527177851177849, 0.007127245592600535, -0.03478704421611469, 0.003011747710224133, -0.02349766354391826, 0.01004232793292505, -0.1176867876164139, 0.02626695914041232, -0.06316783433824909, 0.07753431035296164, -0.05772959109292543, 0.01954926232340906, -0.06086028308842151, -0.003104675370067428, -0.004923780276110752, 0.008718170992460231, 0.05506074746847181, 0.02126352510068548, 0.02026026825978836, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.051962095286209, 4.783354200058216, -2.891753406247233, 0.1494225282409022, 0.212321254452782, -0.2121415539790813, 0.02466897820188111, 0.06733336624204075, 0.013113247694252, 0.1066584296274234, 0.08752061927245192, 0.07922179944730777, 0.2365701476731576, 0.007588213043408364, -0.05416415411776607, -0.2020969955640969, 0.06349969928685602, -0.06132787289740503, -0.03422718627771316, -0.01952915873386353, 0.0644213739673787, 0.002115696634784188, 0.06255822113535302, -0.199371510170398, -0.3230384741719209, 0.3808208705549075, 0.04071272810763353, -0.01872027971165153, 0.175074940224908, -0.3802378821499527, -0.06108501582393667, 0.06646559313315525, -0.1623676411929772, 0.03990883781119187, 0.04487902512075174, -0.1419408834211026, -0.1568779206082137, 0.1763292664552807, -0.09481989476682466, 0.1344530334023877, -0.1823509060475661, 0.01993854821358784, 0.06058475613302417, -0.08882610769003915, -0.07025689205542202, 0.1720722409076721, 0.2549799182126544, 0.01962928250874243, -0.01708969300024939, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.90166412025067, 5.683663549106058, 1.9210862649828, 0.003584348132213356, -0.04815067261613367, 0.08879292199376522, -0.005675898744132862, 0.03588291164670374, -0.1637463265891401, -0.2197707557186419, -0.08857402261688128, -0.04780383765954515, 0.007843151524149466, 0.1770531910307867, -0.01723997302062695, -0.02612834699223629, -0.00540746785723896, -0.0705490796246758, -0.04457806266766569, 0.06473113864983282, 0.006275761834464256, -0.08950765677362392, -0.1005085571651238, -0.009712772636099888, 0.1241037651167948, -0.1243232786387127, -0.2285046949724745, -0.09330919844079147, 0.05061721851550809, 0.2874490693586184, -0.03620828558028133, 0.009836453811605826, 0.06478449995192533, -0.01171663894787422, 0.006410086373602496, -0.2000108983272982, 0.03916914746487668, 0.03329096249389659, 0.07559233782463498, -0.1503685986635421, -0.006365422116363463, 0.1204026175721976, 0.125722416995956, 0.03865674591865399, -0.0001228620998850972, -0.06816612415831065, -0.03365741691324027, -0.07613321112893839, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.851490093348759, 5.320051320277479, 2.417643700741916, -0.1995237653475895, 0.07621645201183533, -0.1771833255682829, -0.01078146896182771, -0.06438976299009525, -0.2876178310323119, -0.006303714018374637, 0.356885069902641, 0.07024283797935846, 0.01881395860270091, -0.2092513663311028, 0.109718092264327, 0.02854685307727969, -0.1312757974509329, -0.1108285734230257, 0.05182740468109521, 0.07233132504659899, 0.05030539452868459, -0.06059975102985716, -0.2297336103700467, 0.5045083042485633, -0.0004325173131309776, -0.1784693418735473, 0.08394922707081144, -0.2680843663012994, 0.2671400195308918, -0.001793550843300997, -0.1325105555633781, 0.07300804882966573, -0.06897110118534086, -0.2665451791081322, -0.2630899900703882, 0.04369816343226968, -0.156643286665005, 0.1549466071737415, -0.4145076724124122, 0.07488318920361078, 0.1419270611119949, 0.1219043619914908, -0.06378625947413261, 0.08917372812331978, 0.1038377550424948, -0.08072252702869862, 0.009394294196957323, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.53934911433842, 3.08124689760215, -1.480395561682393, 0.2462776680494332, 0.01710234467080554, -0.01750922521427385, -0.08464899612469672, -0.08513339146210799, 0.1497690941692451, 0.2003583687026345, 0.229975304279735, -0.06773544482684146, -0.212962762165994, 0.100805918257745, 0.1387021642494545, 0.05756587177820099, -0.02342135307890196, 0.0413142771758164, 0.01012070144816604, 0.009465626383560421, -0.1768890665508353, -0.3114326451294799, 0.334908331740353, 0.1454336469709651, -0.1253099733433882, 0.187117750616515, -0.2556659183272817, 0.05828504568732875, -0.09923486906264152, -0.01295943412712868, 0.04742766192450461, 0.002467967102260226, -0.09546651038888934, -0.3163510329005083, 0.1861927610821425, -0.06672987133018268, 0.1437750260846377, -0.3332140898455062, 0.07302040974957998, 0.1701107028641413, -0.01658898261297759, -0.05269690883993056, 0.1563566521838276, 0.1337720630335788, 0.01368561538114742, -0.1213888256015452, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.307203302598592, 2.885610538012057, 2.250703368751336, 0.07975315762421138, 0.09370441866373114, -0.1923654024839493, -0.1853398422580131, -0.201205128559576, -0.2125042330970577, -0.1602582952706193, 0.3093660817821342, 0.01852414315637842, -0.09255035727223564, -0.1924195495982953, -0.1559361270247578, -0.02917817624329287, 0.1447862761755991, -0.04690491601291951, -0.1960912348494043, -0.2042284966615884, 0.05841637536106218, 0.02291485689303238, -0.2827174856981686, -0.2943255892311636, -0.2215807563938077, 0.1152617438267267, 0.3936419107039491, 0.02096945169954771, -0.02252698024658075, 0.07773344380322408, -0.006443114230257507, -0.03639999246001423, -0.09084547229099375, -0.0397561686169364, 0.07701104659075265, 0.005605523155556855, -0.09348135695481166, -0.03124263128081152, 0.1542717927672431, 0.175465847613986, 0.0572413755901381, -0.03334819451365621, -0.1404348146594518, -0.06481871409417514, -0.04848557273226619, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.221221516792545, 4.982054100250426, 2.183210516233156, 0.0908360095708884, -0.3019054223643021, -0.5366128211639946, -0.3196918354703204, -0.1253970246067154, -0.02164532399684936, 0.2556280160777759, 0.08182827430850881, -0.03680716913431671, 0.03290225595516987, -0.1262131502004158, -0.09569394699109128, -0.005709824337923843, 0.0821878342740492, -0.1407748396690034, 0.09719614879475127, 0.2301897192422586, 0.04576646414789445, -0.2184893983754594, -0.2792745493536102, -0.363844809151781, 0.3257684950525028, 0.4790184968677053, -0.07652744991329491, 0.06377373985106835, 0.09437678117499698, -0.06131442314952967, 0.1635757313451941, -0.2796573282080887, -0.05643997532345108, 0.1152912068418917, 0.05000521333406865, -0.1112720969259657, 0.0037148809503484, 0.1093948420140112, 0.2980235424512261, 0.1525445958488788, -0.1264302662462978, -0.2913624335279468, -0.003113019822754165, -0.1134308899923566, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.400474057942684, 3.406090954274398, 1.166212384143174, -0.2629422439993046, -0.2702044042321645, -0.06636757078595552, -0.08446798536159737, 0.1313648786119294, 0.1193846426124598, -0.07246210384479049, 0.01554276290017705, 0.07103237282021825, 0.00101034194025556, -0.02392135193032525, 0.06952201574673418, -0.007400528848880757, -0.1551607153718201, -0.1651416045393484, -0.0721038672300459, 0.1237766596982622, -0.03361356917856322, -0.2622129829975602, -0.09615056687603316, 0.06891513871408637, 0.2914707059926323, -0.1250888357080352, 0.06761344442133146, 0.0799843533260796, -0.01371538646021322, 0.07103228925121174, -0.3405952917653196, 0.09927170088586629, 0.07489758155119226, 0.08314980277563824, -0.2366684526630883, 0.04202882159469431, 0.2074629307377897, 0.133356144785867, 0.0637264741453499, 0.0308975379082297, -0.1084379405587302, 0.02099441886765496, -0.1808400593316885, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.086464017862694, 5.114621438496568, 1.930881617131408, 0.1620245301097141, 0.1255287200617495, 0.3368622640783234, -0.07183251945541429, -0.3012926287551759, -0.1116975660537743, 0.113190686135744, -0.04910476738177835, -0.0465386985036234, -0.01788084091497165, 0.06748386592535341, -0.02381369375912231, 0.1493221788544871, 0.02579249903686181, -0.2497357621560777, 0.1787366301893779, 0.1598754145183457, 0.1674188524026742, 0.2477399099122946, -0.3340328954217437, -0.2111911479084411, 0.05086712720251271, -0.1292081829605008, -0.04302551258734066, -0.04971415251604733, -0.3610534332063385, 0.1892568833309398, -0.04472498978753213, -0.2065739236157566, -0.02046944574279112, -0.1756213338724003, 0.07793636245748489, 0.001237377976353086, -0.09033779335999018, -0.160410772384528, 0.08626890948440605, 0.2182749871373348, -0.0838793833068209, 0.1464287335113856, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.723745364788649, 3.894040171351998, -1.604023474297945, 0.3564682842321129, -0.068601028463067, 0.2723514789823699, 0.1226064004710703, -0.1014104100043627, -0.01893991862852569, 0.08732928681306741, 0.1555840779063216, 0.08897747453791588, -0.05848831483689518, -0.0484062742636184, -0.01943252555803195, -0.1897987807964078, -0.04208301117450661, -0.05303588371252462, 0.1133610703860842, -0.02273323404597872, 0.2540238415394855, -0.07855533407962875, -0.06507240945437587, -0.005499676266161271, 0.06537585217565781, -0.04778965574559299, 0.03306331390850831, -0.03674334203422738, 0.03096742123062764, 0.01763537013767625, -0.02727086473016628, -0.003088168719969086, 0.0435625544938414, -0.03476926734733601, -0.03196005989505435, -0.1419829052022682, -0.06959993690169985, 0.04835942714075128, 0.06791350727690673, -0.02769231996290041, 0.02869640238709043, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.887735910703242, 2.376861553923156, -2.059488107339375, -0.1636149309402013, 0.4041266030614025, 0.3896070591189961, -0.2297552131134549, -0.01184707906318158, 0.07039303277467518, 0.09925344398529366, 0.06695981045037805, -0.008491592697259171, -0.04552531630716806, -0.2274274932314481, -0.4148399842074417, -0.04458879883972757, 0.1297363092206598, 0.006733546690957063, -0.3384389296777096, 0.1168946778492827, -0.005399720520138511, 0.3552679244548678, -0.05369187330796665, 0.07272949240516048, 0.04205583963833656, -0.003676655566636833, -0.02270378608066365, -0.2966711461982461, 0.02934135424925877, 0.02865469879716708, 0.06673230222014637, -0.1838317311908014, -0.004436962897364399, 0.1509614176408774, 0.03376168246202512, 0.0005117826261220852, 0.04498835681575293, -0.07866868520578868, -0.0334252458798712, -0.08545921183065397, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.342190295905557, 4.675687708808497, -2.268183880250829, 0.2090893331762786, 0.4578770822708127, -0.01884304914244323, -0.07920602266213114, 0.05860045842795304, -0.009411964143128677, -0.009484130845488712, -0.03376087164847531, 0.01728654546382909, -0.2136063948857168, -0.1250583122943451, 0.2295451258972967, -0.06031125891810103, -0.1745972831925295, -0.3612966512867564, -0.1696417690184429, 0.2894160200659208, 0.5167644047563161, -0.08805909441951841, 0.1382094329850753, 0.05099565505493066, -0.04533499187369815, 0.05797820328595679, -0.1922533222149581, -0.1102035618550493, 0.09431486137300341, -0.001494148493882944, -0.09571326182532253, -0.0247601912770405, 0.1256667582306468, 0.2120425181347171, 0.07968400246820299, -0.09760118083265475, -0.2941239252154335, -0.07105438440442044, -0.06896304227007152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.005975891768637, 3.352830695220589, -1.754960054860547, 0.1623709029576712, -0.01686728241632605, -0.03827200221784547, 0.1561794350456731, 0.1402911103849665, 0.03386692126036084, -0.2383508690881479, 0.08335746314476074, 0.1222986332072196, 0.1365597783993524, 0.1833332391744543, -0.1153402862359182, 0.06132285746330645, 0.103916564083423, 0.1352942358705118, 0.03751837000428822, -0.09780641373392215, 0.01802532012439729, 0.07461290579154131, -0.07340909507755823, 0.0263628669211833, 0.05634194666559207, 0.1326983203399266, -0.07526750794049826, -0.0255602869082238, -0.03079487759048528, 0.2087632832461296, -0.06368900481673745, -0.1885028988850317, -0.09938432303399658, -0.02813603601003281, -0.03116773548046878, -0.01139744596335172, -0.007527417596076127, 0.09996642926056981, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.005352340672642, 4.225811150115511, 2.31447703108509, 0.2404320758625818, -0.1026845105793418, 0.09323203523714457, -0.07188013661735847, -0.04900547068951503, -0.01143900704943617, 0.03127208944683336, -0.1422425637959582, 0.1223555755457385, 0.3629752163517811, -0.1439880981371962, -0.2053548592359871, -0.2670448469719894, -0.2854950646499647, 0.4890836381626159, 0.4252198149550604, -0.04903353665384676, 0.1440097216561384, 0.05263434485402999, -0.05654435812537717, 0.2744897997285071, -0.1869384630385859, -0.0801988284405884, 0.1415754714387316, 0.0461903176790022, 0.07292418854739299, -0.07749396692418822, -0.01197157575397448, 0.2335354584093252, 0.1565196693950396, -0.2175672539551863, -0.294898244011832, -0.04250817996099358, -0.06254226634319582, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.023207199521003, 3.695034404904957, -1.278828575213463, -0.09576460539931182, 0.01293341047109737, -0.1025508423146749, -0.09879959800395338, 0.1293868360344177, 0.02661187351571312, -0.03208813036911215, 0.102284173268301, 0.01897487699556174, -4.171607187027272e-05, -0.2343929177751728, -0.1591895912128799, -0.3479923586821921, 0.2266119442104414, 0.1369767045914879, -0.093264948471121, 0.05584513287015452, 0.1113848723095114, 0.07805629549261404, 0.385159500396428, -0.315090514425508, 0.2619076486635123, 0.2100336864909587, 0.1489157028437222, 0.01899500010404414, -0.05839538028607237, 0.1065294735286251, 0.1429581389759609, 0.1768187396519744, -0.0107077164022975, -0.07184487656799306, 0.1053566314912159, -0.2656344309369447, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.535179041441933, 2.927516278644585, 1.069440149410428, -0.1940154888240462, -0.06435827084629098, 0.03118119256124731, 0.2144814653940334, -0.1459984300204726, -0.01884883111449459, -0.0996859848375896, -0.1929505482810151, -0.142915066638186, 0.04595119246484281, 0.09181030791542119, 0.1046793740137302, -0.1631714112553374, -0.1533173188313381, -0.008178614876768846, -0.03838516939058051, -0.04628352128726964, -0.04001834958725597, -0.3727398948175817, 0.349654467351177, -0.113952499262497, -0.101339746891288, -0.1603850568927218, -0.1309942015965596, 0.07772040042527674, 0.1275463112280693, -0.04252979249843156, -0.1408252690486143, 0.05191953638235136, 0.07165159166941262, -0.1158826338243819, 0.09369294636414835, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.042176179125399, 2.455373013093171, -1.298065125007905, 0.02028671121404909, 0.003306962463612291, -0.1036220220710941, 0.0481345337164661, 0.03315299260062861, 0.04992516180471544, 0.09592872957586211, 0.03096020094331417, 0.009903127869262564, 0.01875056235671545, 0.03272160535846057, 0.01927852349784328, 0.02325854762506147, 0.04608264369572843, -0.009983430343303928, -0.01609838886434818, -0.01003965210423024, 0.02113424938210403, 0.005924265966984703, -0.05179857793569453, -0.0244630676591391, 0.01057802494355381, 0.0691716202360271, -0.02554792020429601, -0.09556309673821282, -0.01109440159507958, 0.002795432770742045, -0.03608009327148794, -0.009904492448746673, -0.004701473084555832, 0.06319402826809284, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.341422080029597, 2.641177760807674, 1.591936295305328, 0.005262995989819829, 0.05712969006064635, -0.05864522459107201, -0.06744950477663363, 0.1271503047471045, 0.2094260695099903, -0.3057531846245879, -0.04037395011724824, -0.02967432474543921, -0.09059292764118339, 0.2862509429106201, 0.1048474566793039, -0.04995247127231636, 0.1184570436074571, -0.03693842645635304, -0.08306079853122639, -0.04945597334476677, 0.2089393586111927, -0.2028924047636768, 0.01499186002602688, -0.1284371246539898, 0.04369426140288886, 0.001107629872198076, 0.002549707872053236, 0.1030701664382734, 0.002039801798898688, -0.1568979174791054, -0.1881891997896287, -0.1100556548512126, 0.06948313266853789, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.629047221760682, 3.633220763136687, 1.407673550411567, 0.0339033673171226, -0.0440877649168133, -0.1309350154964067, -0.05292438726218229, 0.1243733326688556, -0.09611554125353661, -0.01801557361391788, -0.1394535956650391, -0.04800585756898997, 0.2092817652566071, 0.1937706427881193, -0.0316202819028252, 0.08185853657036937, 0.008847184587817514, -0.05390183527194951, 0.0500718698457836, -0.06277970709250076, -0.07596180328240805, 0.04008159730086977, -0.0124923156950488, -0.01841127788787308, -0.008904456301771634, 0.02894837811492813, 0.08379155755674296, 0.038658741027786, -0.1013410184828959, -0.1363862936525638, -0.04609547972146647, -0.01057837708981668, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.387217368144026, 2.728722184696696, 1.424749145313089, -0.01601470906433309, -0.07512459959692018, -0.101188344036713, -0.003441549977747002, 0.06449001937611275, -0.03196276224536809, -0.1213336580505604, -0.009099515848609243, 0.02592480117875633, 0.1486227237292286, -0.00133150660633606, 0.001532054214242922, 0.02645122343613796, -0.01679939752946042, -0.006472860460697598, -0.1046070432475455, 0.002013525317899786, 0.007407876301716394, 0.03426066213629017, -0.07238247076893806, -0.002515176653231992, 0.04897218815805249, 0.04708726516482133, 0.01321800810118652, -0.0106268999083793, -0.03069342204089823, -0.02184119543907794, -0.02064865378574994, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.391700331330132, 3.10873390469995, -1.005261568422076, 0.07033689862768554, -0.01130536743091839, -0.2012624886845097, 0.1894945671077086, 0.07933080126112255, 0.075305885120587, 0.07607468793519609, -0.2915128232499786, -0.05359107726226209, -0.0167141837673077, -0.09941630815355153, -0.003665007998583435, -0.0299234883671778, -0.3018441136613871, 0.06749072049202193, -0.04549007934188216, -0.1272169539451481, -0.04604367173781738, -0.2292387384782596, 0.1104667012348132, 0.1037443269592589, 0.003358877836343526, -0.09748118788274351, 0.1190372958872585, 0.07594840982846023, -0.02118200682737069, 0.04505746778768557, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.040421536922372, 2.090179325079248, 1.054133848546223, 0.1016135668098681, 0.1058908215655909, -0.1395436464948118, -0.0005843093291569908, 0.06576578822426617, -0.01954438761767608, 0.1340460322034086, -0.1079153000090457, 0.008558237228615952, 0.05442003661392834, -0.01948493437734833, 0.03204864462372618, 0.1899187419163797, 0.02651889944688371, 0.04143699821901681, 0.06155302263071664, 0.01361677379827648, 0.1864345911285355, -0.06057118267116334, -0.1079059175548875, -0.04926446070686546, 0.04450551753882914, -0.05461151981988153, -0.001886612406799282, 0.0366915411934175, -0.01306027401322379, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.017217105119183, 2.057885109672617, 1.717830826909398, 0.08026860099733665, -0.229664599517274, 0.08592953162584042, 0.07113555573927616, 0.1205711964241209, 0.06034607492733832, -0.1241960272046997, -0.02576402132560143, 0.100546870611732, -0.06664178017945782, 0.01551828302018928, 0.01075203286396453, 0.1648555544266941, -0.06180621835112392, 0.00904698466380283, -0.08614048879659969, 0.1377785336580386, -0.02458732719586508, -0.06527069420169623, -0.09919539357362668, -0.0371614630248139, -0.01956332576116701, -0.02610087976547117, -0.01636500296481732, 0.04290323999519369, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.73126542682124, 3.177372305562633, 1.069892746405991, -0.3373448837554265, 0.04914183280708707, 0.2222099960511715, 0.1000273467845214, 0.02495153836835336, -0.2988822213671982, 0.09070115558214502, 0.006890792477648951, -0.09774415864582336, 0.01733122536241725, -0.06539161565511441, 0.4180846670181008, -0.1348357420052125, -0.01486736897403777, -0.1707564509631871, 0.275788236310813, -0.03928409265616119, -0.1437568066337482, -0.159713937527644, -0.06441082113320754, -0.04838713636560495, 0.03935472474969938, -0.03034455737023176, 0.1502866267461562, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9860332560182929, 2.457690638088044, 0.7585454975233088, -0.1838919851966072, -0.04382890538941454, -0.140552844264958, 0.09130507944212898, 0.001128260213507534, 0.06804648176327489, -0.03968302808799389, 0.02820745088433483, 0.03697025018803624, 0.06358690037762478, 0.08600302483044212, 0.04484515559448902, 0.08149618479019373, -0.008400294556984093, 0.1073491700579635, -0.06306885174166355, 0.02287587454966997, 0.01464609607772943, 0.03996572206258068, -0.03555777800156044, 0.01763122405260091, -0.01550330692085902, -0.021886735564678, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.8854567164260388, 3.24250422074227, -0.9209580946507911, 0.06835402983935927, 0.05640958121017869, 0.1025591786485125, -0.08943334614410312, -0.06811365067010508, 0.1109007141056824, -0.02177056785348171, 0.03875431100769289, 0.2363367275176182, -0.09273940436583276, 0.1105048998268415, 0.01324218642906586, 0.1204923454912281, 0.1300264818238509, -0.07418265989085007, -0.160155156583538, -0.03336518282890372, 0.03274839794300601, -0.02988917934624772, 0.0313012656489897, 0.02783060486964485, -0.03014058011457086, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.9647900465381067, 1.776310496646176, -1.171438051631132, 0.05140489138825926, 0.1299377347834004, 0.2201816497369831, 0.02994176320228855, 0.04558225788991847, -0.02505795321566107, -0.07354754829932028, -0.07990068462027206, 0.03705853127225793, -0.1892721965231484, -0.0414104999094905, -0.04365760163266805, 0.004082206348271171, -0.01640857151771855, -0.04917783956511107, 0.05677253037720179, -0.01538028417587433, -0.1057997510635607, -0.1262079630007641, -0.09383731776836683, 0.1119867440818691, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.059667715135062, 2.869444516413392, -0.768053436705612, -0.01982926570738622, -0.05898277292649027, 0.08032989813585734, 0.02430925291918696, -0.05541157112738762, 0.01387900032498306, 0.005672434099991189, 0.05365330433412881, -0.04355934883978447, -0.02337398496984892, -0.01686799971841361, 0.1422537288231567, -0.05666452598379437, -0.1164424129736735, -0.154242271156826, -0.04516863877735287, -0.01545725267339097, 0.05268933296374621, -0.01791535900714333, 0.08893369086218253, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.006637453830663, 1.684689844069783, 0.9123803878361401, 0.3537494043954367, -0.0934425457654232, 0.125950163184819, 0.0008929568569579045, -0.05163443135049815, -0.1076491218622526, -0.0453578935139585, -0.1495191189316716, 0.0001415820705124262, -0.05006551799497391, -0.128789667082152, 0.01100316880829279, 0.1037355563583926, 0.1230844198081173, -0.01355995466456035, -0.04069963982836227, -0.2068443754239467, -0.100425014495166, 0.005750041723483063, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7847696566083294, 2.188950883712381, -0.6166420348084849, 0.05427293688357122, -0.09172120702478551, 0.01394828380275868, -0.04214925628047594, -0.2002409114863903, 0.2374547253440619, -0.07586414645695061, -0.02243126761233804, -0.09086994858618591, -0.06440645239833823, 0.02923240705539655, 0.1008328000734136, 0.0681346127852103, -0.03404818684407405, -0.03418035480719885, 0.02177303810889437, -0.08932854185081496, 0.05516897717457826, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.5961213393185251, 2.487671728233433, 0.9779431494823534, -0.08808252008539449, 0.07346845556012158, 0.03791477768403206, 0.1133987101884693, -0.04867168124335965, 0.1007529815412284, 0.07012067318801543, 0.04686393658752402, -0.007976030601315085, 0.009647274715336393, 0.04388047564013912, 0.1448956828911585, 0.09593976527370232, 0.01772056425810449, -0.01920422214800561, 0.07683802973941063, -0.09812807079543846, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.990432056210743, 2.774709587520062, -0.9402258848421475, 0.01395715665576621, 0.05464370856162152, 0.05969855937401768, -0.09840756262028037, 0.1283282686407038, 0.01393286908802421, 0.0953055258318351, 0.007548139187554635, -0.05906283649224034, -0.0006153285921519075, -0.05497497151651637, -0.008769303020395835, 0.05051213594154082, 0.09095589353294919, -0.006367749500199228, -0.04367472066475442, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.9556547348028801, 2.802801220763579, -1.059088183997589, -0.06046741386547052, -0.109550403372664, 0.1079992883617651, -0.1303209308383404, 0.005273660747274722, -0.103872667440789, -0.06600322769700166, 0.05217402045757749, 0.08518450366824531, 0.09805210958705181, 0.003600709399162004, -0.05665622206864503, -0.1159528275969711, -0.04404155725184447, 0.02203210385909037, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.063540216854957, 1.744535368562572, 0.7905163601870416, 0.02656379893207305, -0.007035839152219695, 0.04085917849823771, -0.009245974538993987, 0.0249953312582957, -0.003223257434620091, 0.005723442767043741, -0.01704173254774269, -0.006825269002180425, 0.001391384124621517, 0.005712500889522121, 0.03850120618331365, 0.01404973463460888, -0.01209325063900243, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.788177934248775, 1.912200014248186, -0.7537507368298558, -0.0661262783848291, 0.05943707989564052, 0.02061524812146071, 0.02585592085441167, -0.02083197113611205, 0.003987942029650998, 0.02210665757083753, -0.02360486919891839, 0.005051227537696999, -0.0006754747654496297, 0.01013804196323632, 0.01058372156918393, -0.05401144478196152, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.8186713915600072, 1.708711700739236, 0.6332443934946002, 0.0347014944537665, -0.01300019502207845, 0.01605786260146845, -0.02637192977655575, -0.02304218343188766, 0.02296628976143508, -0.01424547177831386, -0.03972717940911979, -0.1167021874016301, 0.06633764648895558, -0.1293541599290803, 0.004742672723613311, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5157633499563469, 1.976352201317751, 0.6234503597941091, 0.01391296633390046, -0.07272602653366068, 0.0140570704220571, 0.01336752650183375, 0.05902767787103762, -0.08819062077742636, -0.02551451255772886, 0.1312142929003566, 0.01369744243814129, 0.06473360298498254, 0.01231850487143263, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.6533080656351744, 1.758802439425837, 0.4318871049206415, -0.003082957500133511, -0.09814169758462682, 0.04175539354758488, 0.0235289164184994, -0.01629543995009982, -0.05231016932343414, -0.03672204848733453, 0.009389336932342413, -0.06142381433250257, -0.01010858967311151, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.4817927293509213, 1.408851322535897, -0.7676055176021872, -0.04505523423060897, 0.01813562786331449, 0.03138728238085502, 0.0007373169379419269, 0.001847667170281647, -0.01640431370966648, 0.04696818974656805, -0.004393748298759055, -0.02848496648956977, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7883892138973269, 1.746055173045302, 0.4846783430365095, -0.0003922243062844435, 0.01186867835550373, 0.01648380387048428, -0.03174672656471393, -0.03627511739090696, -0.004853687188112606, -0.06885884936290802, -0.004917829299265958, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5208363315616994, 2.037277859382022, 0.5232085356010402, 0.07175407188317283, -0.07019064479939288, -0.02385694223436976, -0.00819063541887864, 0.07192359009199149, -0.06656167507443485, -0.04927759893361527, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.5819314677010843, 2.130167978098713, 0.5667361680393177, -0.01053764587057425, 0.01592751856907668, -0.01111604356574088, -0.004404610058468247, 0.03850545663289814, 0.04729794670040405, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.6488904808178829, 1.974426530381294, -0.2820471741701222, 0.02456494941736511, 0.03486280653024869, -0.01809831529884736, 0.08408521068644187, -0.006474401058818371, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.3312307167387429, 1.235934836863219, -0.2452582871525679, 0.01878427096720662, 0.04975840840483642, 0.05672553943361373, 0.01742942062643791, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.2654365696129733, 2.208256891929066, 0.3360201888498769, 0.06660725081463706, -0.01286437627536736, -0.002070231898763094, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.3639062481633207, 2.248588741393716, -0.1889980205327704, 0.05688507493685012, -0.04579504315826421, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.1624755988486198, 1.590085647221482, 0.1168533202179821, 0.005293082667091636, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.173908380119132, 1.450043378319349, 0.02765965035599782, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.02984095753646376, 1.759629990218614, + }, + evWant: []complex128{ + -0.01716884621227793, + -0.1844331609734137, + 0.05200651487352193, + 0.1336851109127556, + 0.2020936631953806, + 0.3566470363060668, + 0.3627207699831158, + 0.4388555152488943, + 0.4776853636435153, + 0.5598821450074998, + 0.6249350549980947, + 0.6791310689291772, + 0.985877008147705 + 0.01929363300192029i, + 0.985877008147705 - 0.01929363300192029i, + 0.9908483217835712, + 1.011990761364073, + 1.130046345264462, + 1.323698071765709, + 1.348598229483672, + 1.363190626641638 + 0.05400660173350781i, + 1.363190626641638 - 0.05400660173350781i, + 1.632832316477256, + 1.646239548684271, + 1.742738908029794, + 1.763069014878969, + 1.789601126186348, + 1.945228042429256, + 1.946373262056993, + 1.997152389795002, + 2.261322781594966, + 2.286944100979884, + 2.447712649969029, + 2.557857506923634, + 2.608379034892128, + 2.653335615965549, + 2.675270309760236, + 2.964219802766918 + 0.01767482509567778i, + 2.964219802766918 - 0.01767482509567778i, + 3.014604817775139, + 3.158289371199042, + 3.311794215710077, + 3.389894197376214, + 3.553333074879877, + 3.641274442796651, + 3.857556223000175, + 4.045817381029103, + 4.330901939363569, + 4.337313647767939, + 4.527400487637496, + 4.917229128467305, + 4.985609414964091, + 5.687686849958608, + 5.79422309012183, + 5.997813119506478, + 6.732426637899077, + 6.957609338485607, + 7.529842664573327, + 7.609108287806763, + 7.761261355516287, + 8.311941758006698, + 9.07053741884884, + 9.217944588000314, + }, + }, + { + // TOLS90 matrix from MatrixMarket, balanced and factorized into + // upper Hessenberg form in Octave. + // Eigenvalues computed by eig function in Octave. + // Dhseqr considers this matrix big (n > 75). + n: 90, + ilo: 0, + ihi: 89, + tol: 1e-12, + h: []float64{ + 0, 15.87097792952162, -0.08018778146407576, 1.923854288576926, 0.2308884192434597, 0.3394611053158814, -0.137843056509317, 0.08273319299962868, 0.09094485832017182, -0.1932984706702652, 0.1180502933247899, -0.2497600660136686, 0.05058238526630414, 0.1559958264692184, -0.1159258671363344, 0.009240657808439554, -0.07576925270220009, -0.08136563335139357, 0.03812188405626555, 0.08890970810264923, 0.03109600803532232, -0.01649595143487545, -0.03210884292964193, -0.06264912164116895, 0.02576130685189339, 0.07030469513274047, -0.03577429596420342, -0.06755584096587573, -0.01609449751643862, -0.034609250889499, -0.006417485131372289, -0.03097242984568944, 0.009636702832094541, 0.03557221482377193, 0.03197869740177413, 0.006433398911967483, -0.01135683279223704, 0.005555822920782794, 0.005082647305173025, 0.009385366191684759, 0.008128896608623586, -0.02296712755081439, -0.003777413820214802, 0.005123235117691023, -0.001849213959133196, -0.02340110883416673, 0.03713005378535863, 0.001732375396842803, -0.002750608017025007, -0.008067437745595896, 0.007330916864526544, -0.002616316716217023, -0.006297132815168344, -0.005559964495164493, -0.009996463242082429, 0.005115046921377182, 0.001491016327339477, -0.000957347151456719, 0.006745577006930539, -0.004544035710017501, -0.004411949528299773, -0.006799740101884459, 0.0005344071027975155, 0.0004690847920096184, -0.004718575501368472, -0.002540214169642457, 0.00357159293854215, -0.003314789809413553, -0.003402372051470523, 0.0006527769815598059, -0.002716170091878954, -0.001540321517093821, 0.001756589868588563, -0.001379260966541515, 2.681259838616508e-05, -0.004307760317855304, -0.001109087032949234, -0.0001659937040461595, -0.0002235436314482387, -0.00119569899683125, 0.0005623327348935116, -0.0006320070189143994, 0.001043573892153891, -0.0008750118344396425, 0.0005348270042878935, 0.0008273143853381587, -0.0006622544067919339, -0.0008492128694001077, -0.0007986665099336194, -0.0009015882205421384, + -12.61872336344661, -0.7232497785660141, 7.609159226285555, 0.3870426982100038, 5.924856640096555, 0.6102682886559223, -0.1693535996869482, -1.919018099340693, -0.2138609560373459, 0.8042623392399718, 0.8674124147325857, 1.331963567449537, -1.782290696158441, -0.8346237530841022, -1.552156412468403, -0.6151273144224881, -0.7391936693539152, 0.9311934770410842, 0.6166024938842418, -1.54644771695033, -1.776481997993627, -0.934164018650274, 1.955449870926906, -2.082936149197492, -0.222464503236819, 0.1331142802435182, -0.7633944660137448, -0.8176194198678164, 0.2746498608375185, -0.1119720547510174, -0.3046093297897633, 0.093708523663493, -0.1254384253653835, -0.3826156782538976, 0.9720657328245648, 0.4435611080311743, -0.002705519800257373, 0.4068502033494004, 0.8228026417475635, 1.898141183528268, -2.19419418629088, -2.26250233043472, 1.169369389476936, -2.320900757809857, 1.963641620262248, -0.9292511308866737, 1.20566753941007, -3.909359844030778, -1.745106869690986, -0.1674293744185332, 1.824325508201922, -0.611032518780414, -0.8172751651339325, -0.379367811436249, -1.118039132172379, -2.1156899896767, 0.6317312221182597, 1.675601832555065, -0.1958681401344015, 3.202902011360347, 0.2083144054490269, 1.651454396883902, -1.879950006164014, 1.114962429097019, -3.728120039552464, 2.115800549383747, 1.993994934513307, 1.036800346894651, 2.843012388647532, 2.665528597975866, -0.08443708961414848, -1.658265513220315, 2.825691629937317, 1.163068598831327, 1.032612155987785, -0.3464359914213002, -0.7374155713124153, -0.009825846309687306, -1.878310233217088, 1.038183449333641, 0.8683442149070821, 0.2096953654957043, 1.097533010763627, -1.40566207568186, 1.539718090250373, -0.3057191046244732, 0.9596910019319377, 0.4410690813618931, -0.01734977865916698, -0.7028527205475527, + 0, -21.14096588949502, -11.77071611766029, 91.38817973790069, 24.01994594814793, 7.139034668143506, -7.77684013545977, 11.8189112903465, 4.350214240774185, -13.41161300072837, 0.8429515510200203, -0.1960485971162483, -1.892239827255886, -2.481138864200454, -4.993335484535367, -1.462743953230215, -1.649744938703439, -3.306123402194819, 0.6299802354863298, 0.006312776908129815, 0.7029217322720615, 0.1969979096896496, 0.6484394805159026, 0.4612739081461551, 1.218623710778157, 1.937283920899595, -4.274393204137636, -1.417028232311232, 1.761975679896983, -1.207846701077455, -2.947009378633724, -1.111456928119195, 2.001483835367479, -0.3273985739357373, 1.27142153234808, 2.470518283440578, -0.497592748085565, -1.01776837453108, 0.1736631347448449, 0.2170284795451557, -1.102797734602059, -0.8983239378242805, 0.8376082516437703, -1.015605628895311, 1.888662040615523, -1.813946159105028, 3.745871277192266, -1.691058864813766, 0.5544744103796291, -0.95962769863539, 1.495178118153111, 0.1369976805376806, -3.134133785033962, -1.134766199832475, -2.142472928604951, 0.4360359463007911, 1.080773790484485, 0.9136687613609559, 1.421868877932455, -0.4939788885367615, 0.01579620756278606, -0.4041188740514539, -0.3370957888349073, 0.4032844546374829, -1.281049156842126, 1.334866305935072, -0.4288161314791398, -0.4076960827986253, 0.8975402184760907, 0.008483305617251051, -0.02300021991545602, -0.4779200297205075, 0.8640559542693361, 0.6740166979504152, 1.271173988705413, -0.125268363712917, -0.02783785192682384, -0.7952831181002197, -0.1834134462936435, -0.3033906534395994, -0.1842466257842833, 0.3294577790658342, 0.4265858101126394, -1.050551059782219, 0.5557053448408287, -0.07549099980078718, 0.4485085972651929, 0.604772326452039, 0.02668915155289681, -0.35958437456048, + 0, 0, -71.67241414253803, -12.6925239065222, -58.51026881403752, -9.923972440030834, -18.08337737101079, 23.73437311293314, 10.42624729020936, -7.39628437264571, 6.93334510855383, -16.20186028661058, 19.09098951338167, 7.231158491837533, 25.86051183536314, 4.692849852643402, 13.50562601772541, -23.8959783279092, 10.46795736800158, 26.42552249365325, 25.55147405605497, 30.98455252329583, -38.26426057779729, 41.72459242758727, 14.01187370572939, -9.227025126956866, 17.69341876066779, 17.7058942448478, -13.2182156659012, 3.273277215940703, 7.82096407961303, -6.540134857551783, 5.302726399754003, 21.6168229759513, -35.45773268931614, -39.5771763658349, 16.91907564224343, 16.55810765769962, 10.84170890675409, 4.539182245882841, 5.966139065523301, 10.43624249585104, -6.306944364017387, 25.11309378553394, -23.98463112536712, -3.253554932408899, -26.20327820737005, 34.95346757431584, -22.06848426488626, 0.3787905650745691, 12.79793983153946, -15.15662916810503, 30.10820985389998, 17.18239253486946, 26.44238280127885, -17.53916820777098, -21.59984930800645, -20.89069843604591, -10.62614963929214, -4.16861219455282, -15.8281632392319, -15.45413424684084, 7.28126264287692, -17.30978445489622, 25.83878482866339, -18.20409699627451, 1.341279973912325, 6.060701390094514, -0.9930555858249585, -0.4770067839263625, -8.050723322366107, 15.00633993006825, -10.12301020599794, -15.02267685265745, -28.87546819977945, -4.887384695963816, 3.812851132430744, 19.10682316350844, 7.478580657962908, -7.486104775378393, 8.24517564743228, -7.51905558097683, -6.644004835040043, 16.04319982377311, -12.24015636297471, -0.4152718733052826, -15.37260980717165, -14.36579932723399, -1.30513875795791, 5.356894027365968, + 0, 0, 0, 88.73441744471468, -9.667604704172753, -22.84943872004879, 5.044285909895449, -2.76004875036668, 0.3050715430090338, 2.281066203460998, -3.081685045157843, 5.563173468318147, 1.196920824152984, 0.7508125732458136, 3.261490552895722, -0.1915889730517104, 2.178042983750966, -5.719722606964433, -0.808717831824074, 3.567750315780947, 4.405620166473985, 8.068713509838501, -3.974147763943233, 4.024558504483837, 1.343369353638846, -1.554164148226279, 1.397410693322202, 1.549071510171349, -0.6861822032616559, -0.03144220974090741, -1.503375319686877, -1.213563509509453, 1.485658175240746, 1.102628808733887, -2.836353822887371, -2.651198571403894, 1.944770277514162, 1.800720538730825, 2.925044559436877, 2.489394773406274, -3.99962439548742, -1.365153890760246, 1.729186611640552, 0.90732580595284, 0.02970965138899272, -9.802670261550649, -3.377885239589956, 3.311681996737421, -2.102890043550365, -2.752571666784161, 7.725320034635699, -0.8099349955071451, 0.5680350525364315, 2.461090824551101, 1.671002962178604, -4.651796111745832, -3.019627268376409, -1.456848301794733, 0.6765376227892419, -2.208873565004413, -2.755468168868538, -2.723938546851782, 1.844529360647301, -1.962817053181678, 2.77164872022158, -0.6312645341808628, 0.9959732581947718, -0.01141276076056162, -1.047045912982139, 0.9659655272370172, -1.069371622104567, -0.564318267120407, -0.9606489624515147, -0.3731646049074267, -0.4361324066751411, -1.228953081985217, 2.112718903093324, 3.774673462225595, 2.038526286226191, -2.037134562294253, -0.6272498215703869, -0.9130826952549337, -0.5356753186936942, 1.739354952287502, -2.607676632661601, 1.167128690015535, -3.643945638175477, -2.247788469333459, 0.4447578257714688, 0.8814188227164721, + 0, 0, 0, 0, 35.22951028609684, -22.61691132174376, 97.10536643650998, -3.714742139430975, 10.06500336745724, -16.35785983037913, 8.78437693523264, 1.985132974393485, -1.609800726068471, 10.55631691645605, 9.224290477011534, 4.722637143581605, 4.125150731568718, -5.396683914299057, 6.364591301561367, 8.24526687743292, 4.911724566872895, 6.542687463438916, -9.348997687795265, 14.18011100433374, 5.720905431367072, -1.582673805208176, 3.789638114574857, 6.440267872588953, -4.901278147004489, 0.421175984045115, 3.797008789173352, 0.2579925025997163, -1.093437933585557, -1.126991905684307, -4.4057666178694, -6.4297958780832, 4.918610437583255, 4.893900733343752, 7.627382484342153, 6.943539836193181, -10.22700285291435, -5.21717606135954, 5.635670539663245, -0.61979670671329, 1.025327494294112, -29.98298952616265, -10.87852244502099, 6.724183768213139, -5.415447368170939, -9.131548344141406, 25.08685243604318, -0.5163094225162969, 5.436141320006754, 5.254969244047728, 5.189340308692745, -14.05566775803058, -3.790558233978546, -2.867451571946585, -2.265074057881479, -13.27098968249704, -6.419573660857155, -2.44809433119093, 5.262803237338727, -6.396156300345669, 12.9332727436708, -2.828158861124294, 6.494893307712784, -4.900718840392307, -12.17623988734707, 2.132680032576169, -4.239391092443586, -4.723934051879516, -6.984654958110764, -2.787156581230434, 4.744573069448925, -7.311973630803457, 14.86842763617212, 11.70461213488476, 10.92665646005423, -8.812367256417245, -1.725823238463376, -0.599065820210566, -2.268141253505947, 2.588966312561057, -7.560432899806777, 4.711500915754516, -11.63409451724343, -3.784667325499409, 0.9845255581998278, 2.917504056968942, + 0, 0, 0, 0, 0, -116.0630192746665, 5.887300060633501, -55.36418027265255, -2.470006763999332, 13.03531089357281, 0.1172864444746298, 2.336301687054243, 4.34928920056458, 9.106206444726951, -0.8318917014102636, 2.753642271658936, -4.563539972366368, 5.616802475300401, -0.4836767449615566, -6.113950704235537, -7.384788928153566, -6.850835642415652, 4.436028327150289, -4.972441466665182, -5.074617872073305, 2.249115729647296, -1.27635805087233, -1.815933433231301, 2.59978300016936, -0.5676863289525813, 1.704036354039219, 1.966949252223741, -2.742379099660473, -5.759265103182953, 6.226978264278319, 6.392620681348136, -0.2885756166938758, -0.2986490248004344, 5.021918870709579, 7.495865991102269, -15.19741578062141, -10.52747112766237, 9.21669911214595, -12.00882240945578, 9.449065100345695, -22.03792558203701, -5.042603937347324, -5.034444931509023, 3.887859743790752, -4.92423649287837, 15.14459404442214, 4.709447859501895, -10.68403398232012, 2.785222602001631, -3.955139727592788, -10.90921547327889, -3.836568621330626, 5.465232651370832, 4.568243480001632, -2.511523602459496, -0.9621054122709324, -0.6044291916789493, 6.467023010391031, 2.662510020284552, -3.203951737691022, 7.315143747841559, 0.2986491524564562, 0.04345879316587933, -0.3120127984400304, 4.715818739144954, -0.3713148742857386, -7.592585985711748, 1.251675665881772, 5.563320889185214, 8.934186230540199, -1.034540314919822, 1.499762588438347, 3.648805772901489, 1.867765342642769, -3.856064394520797, -4.257325323439929, 0.9065282321682452, 0.9958862297862445, -2.214139637816267, -1.516486450508368, 2.326410461051852, -3.227358821350026, -0.4749483061012461, 2.179821376672413, 0.1114550663371978, + 0, 0, 0, 0, 0, 0, 53.90645393584658, -20.01147603384238, 68.25945706992877, -2.001388852130252, -0.6303875033830074, 7.681723436887633, -2.793396522752484, -3.849646005163192, 7.47502807954784, -2.524396627852584, -1.112160063163965, -0.4457759133018216, -5.425351770541893, -7.213840725579055, -0.6234582007920942, -0.3045445372121888, -1.838748235944519, -3.05429610717454, -5.218058811930899, -0.3089178689448414, -0.07503528649101057, 0.1630591210001797, 2.58742687436071, 0.8589336965724809, 0.3026886986297957, 0.0616540381895139, -1.743768523575526, 2.75507802571559, -2.587808530052548, -1.25512695563184, 3.800814529165174, 3.132593897658502, 9.751967320860086, 12.09676139406092, -18.96514427687867, -10.33529268364038, 9.423861340153673, -8.118494925333524, 6.455831882458702, -13.89851030432216, -5.253096745704963, 1.482474561585576, -0.7990859267629726, -0.1919859569182034, 14.99486076662231, 0.8403897566592956, -9.631758825484061, 7.546859017133015, 1.761650219269993, -14.8002789790671, -12.03184495751378, 1.278761976352118, -1.043958743156598, -6.425946785515577, -5.130193263963021, -8.943747092721882, 6.884559516868113, 0.02054820847870697, 1.622114564484586, 8.27790706580309, -0.4201537658318323, 6.949197674374433, 6.109317458173291, 7.745771202714325, -4.383777284917787, -5.023236465266974, 3.152075902042714, 1.185720299074054, -2.570558625807648, -2.575936989524232, 0.7822876332433506, 11.50350236141349, 2.541100031822599, -6.266519860892538, 5.220802309799155, -2.7113287362323, -0.0782755292810481, -1.306667606835813, 0.9121698644456847, 0.07469182002148761, -4.645428950155893, -1.074584465997386, 0.6604539390114011, -0.1666067442015038, + 0, 0, 0, 0, 0, 0, 0, -85.98674061062438, 1.162623410299333, -104.1491535027204, 7.969764337327856, -6.932488858320204, -6.767747448265724, -7.331077471298601, -1.288550484452708, -5.088257375240862, 2.763979746955463, 2.528081478578727, -2.575430737963284, -6.921068854524492, -4.018385524701809, -1.579042698955484, -0.7534247768022768, -5.324588385519177, -4.241013196984152, -2.113061191594958, 1.678130424336868, -0.2888364599120758, -2.575220703265352, 3.435198525295604, 4.161688539607654, 4.731385858073858, -4.276207990137705, -6.32017796521583, 6.190217309330307, 4.183836067935781, 1.849953972589691, 2.606132984461453, 10.00029158683688, 12.0615055907306, -22.12319815923896, -13.94593423436807, 13.56355336723619, -14.73390655737362, 8.504539865599947, -39.98652916386596, -13.54021158220439, -0.05790828602008728, 3.121363813023208, -10.26329339936837, 29.60358127644879, 5.640693459787456, -6.225202166414575, 8.49263970223689, 1.111516509579903, -18.45973622662288, -10.78955835552373, 3.866537233352727, 8.114971974287389, -7.188761733179074, -3.287441529549332, 5.156604610165261, 10.80793451072269, -1.239076505166311, 4.628996155335966, 5.792922582124358, 2.03417264625456, -4.707373530409962, -9.448778191150614, 6.51155292021117, -3.19382039380789, -7.177226661410774, -6.832018005921634, 3.442244659675745, 10.77505720982952, -1.609927625466521, 4.733127783256045, 7.444153456927645, 6.065657625755138, -7.768628874694797, -8.73223505289636, 1.578394964028069, -0.8054671616028769, 0.5972200288905033, -8.68273678581243, 5.453422469912097, -8.723308411603904, -3.656294698422601, 3.713788968458369, 2.245164999387903, + 0, 0, 0, 0, 0, 0, 0, 0, 82.30322830941419, -13.16495817094656, -40.37221874531644, -7.156146024985344, 6.407626256610186, -3.070719411573423, -1.248781274591569, -0.09188094231426196, -0.14791454863577, 10.46460085885971, 2.511645220965021, -7.306021862635426, -8.821036218813667, -11.27778024004047, 8.299073644975818, -2.786388825153335, -1.404614079695401, 1.895971545970186, -2.374603998420206, -1.895908635885413, 0.4177297064772442, 0.3179694660965782, 2.847483353627781, 2.28314647154709, -4.251315293192437, -7.351627496507233, 8.45101495879304, 6.656324309408108, 0.05811442721379975, 0.352210596662256, 7.158242198776926, 9.604014490962273, -19.05916411574244, -13.48053537548751, 11.11056501341958, -13.44816425524262, 13.03794734916214, -23.56660744892662, -3.179691183297922, -4.31381647439135, 9.383878541906311, -8.241547161602726, 15.17745487655014, 10.50533207581469, -12.3496460656361, 8.196225745083185, -0.03575510420729201, -7.579890340619093, -0.7363093925300244, 8.756813214260761, 11.93727799717407, 0.3635376217139206, 0.4603703423631014, 5.507079480435261, 9.421116342576116, 5.29496740123859, -3.941393949093798, 8.749586295075376, -3.842933870553052, -3.434396636354037, 0.7496949834113942, 5.050293641980197, -2.449146742066287, -0.1213669699610963, -2.640456287197764, 5.565782021620873, 8.693308402974377, 2.307206522787629, -4.138693274221668, -6.245432457269187, 0.202505673386626, -6.566863879917412, -11.74280124769381, 5.642870396242308, -0.659648816152216, -1.690565064770402, -5.93672734719091, 4.422450101243651, -0.7271854445212377, 0.7895970235545322, 3.96205972546395, 0.3762898199575608, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 52.18436402228633, -1.17071077050581, -78.74014811145696, -2.436421299700726, -6.158177326953696, -12.84920002328411, -13.40821294858424, -5.273362519386561, -6.872625202393317, -7.634332724591617, 1.036587235099262, 6.207608782298316, 3.391369867457635, -7.524695482267034, -4.223994548482144, 1.005090702038289, -2.66480555032824, 4.646608362152693, 2.243089562166944, -3.34529856305617, 5.740218757228164, 2.12882450346135, 2.939738798956252, -0.03146392010752049, 3.38958622345852, -0.2577487623574973, -3.051389295629871, -0.697296699287094, 0.6189380855708414, -2.814647546822989, -5.010744640386618, 10.8659101121065, 7.550151766381041, -5.138398331003744, 5.941882913285983, -6.24020929364107, 6.192495406215602, -0.1393925926206985, 3.522667688918142, -0.4029078058202559, -1.086721958116794, -9.106949733745292, 1.080723194973581, 12.43512076939469, -1.559991201757955, 2.834826471699229, 10.91592518979253, 10.14280540179991, -0.4312954736361566, 0.1698301469389144, 5.224021770744672, 1.399356722825569, 3.824858056231203, 1.187505521773207, -1.25027597821317, 3.154667536052018, -8.777523547457038, 1.485334722226234, -4.846848932499968, -5.331464798306308, -2.935610863284922, 2.146754442305868, 3.916678542801113, -5.097848412152915, -1.684939990487824, 2.003333243800943, -2.22594720641393, 4.656849950049951, -5.745353345757918, 0.6044487182322886, 1.596087705639433, -5.155786671036686, 3.16998966590795, -2.175693288642318, 2.801445787424951, -3.130319162400883, 2.85020826323644, 0.1640583474231081, -0.214298568273029, -0.1740891639628268, 1.273833756482144, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70.09446168050651, -11.26895002135244, -48.54705040053749, 4.118431277865748, 10.84591029041512, -0.6748674802174282, -3.045053711060402, 2.014682374966249, 2.306026198573233, -1.350656230483865, -2.329953831978132, -9.588390292055525, 3.269359204435148, 9.980505686658566, 1.082807022265471, 6.273567735324175, -5.719240792932494, -2.503890374538294, 5.253867760378612, -7.368019321193995, -5.092315009287605, -5.608336565960785, 7.85433697392239, 13.05231727795986, -10.24473853042492, -6.497760170002005, 0.7720864098024787, -0.9464942766836045, -5.75736090996403, -6.449685187648799, 14.67091581503414, 7.752227657052853, -8.313707502058552, 7.618733560061307, -10.26315766622777, 49.66932226344804, 9.396595252505557, 4.646105097651882, -1.000511699400161, 17.50139800181348, -24.58127340300144, -11.80138366202307, -5.227433380710831, -10.13287460063552, -3.337359409768342, 12.99698337996271, 3.068027046277927, -1.951738372661316, -7.666145241687218, 6.9088789851311, 0.2649618535564444, -15.99488743024383, -0.7701348417963114, 1.505671187381852, -5.323669521268157, 0.5338896728895715, -6.748253910318381, 14.64352852958436, 23.40931931143844, 4.375219426823375, -1.811045463489342, 4.773508381777763, 10.818209698722, -5.294039411650939, -18.70264738152938, -4.975296365083204, -2.600819681501243, 3.308632477674194, -6.40160106179316, 2.538884420020582, 18.76233248591015, -4.114557081532237, 0.5111695455673799, -4.794755383844113, 16.67507540569322, -6.886183084140394, 7.719834159396155, 4.933410312388084, -6.089459478292116, -3.503666218213469, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66.6637247212457, -0.5663386193537134, 86.66019711942882, -15.20175735117943, 4.314620867702222, -19.41396340483079, -15.38151259581058, -4.248235572512307, -2.600133694847515, 4.086685275316547, 6.543863987851957, -3.556770106796698, -8.862927415679744, 0.5940920961482564, 0.2891990484420937, 1.2985992187588, 0.6463973107839561, -0.1897507095552844, 4.999681085896536, -0.6439357872831064, 2.066718921953054, -0.1085645365015185, 0.1070768393458224, 3.026109517007545, 1.481907260983705, 0.1499047456480452, 0.9514718442208902, 3.068093096347056, 2.714461903454389, -3.99786212133959, -1.490015954498088, 3.704196600400429, -3.084024872438948, 1.383157275632034, -16.26579452857151, -7.173167896042849, 2.321998416940817, 2.275237906163105, -6.307537188875993, 6.209730858735038, 4.018421456135293, 0.9621119492629135, 1.945276954758256, 0.4126375340548999, -3.009694590378986, -2.629957817671035, 1.384131483830782, 5.687116562672569, 1.212032906758187, 0.4457093459378468, 5.044411045879187, 2.653766535846431, 0.2411195122877111, -1.543285991977046, 0.8571968890482712, -2.832787648800616, -6.089862603942122, -4.243058413925725, -0.2712347348375778, -0.7571525905438323, -0.1391757644986091, -3.374311051582727, 0.7719310852064701, 3.726864797116653, -0.7589171772472043, 1.688124623456514, -0.06145796388713081, 2.035112211335303, -1.275417314028715, -6.847693700987137, -1.324382865895411, 1.215308587453588, 3.389389718245654, -4.298340356096036, 3.252289347232091, -3.54897896652072, -2.583331482537173, 1.391546454632447, 1.526078993538325, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76.15771433854052, -11.99852507214444, 27.62893281995865, -8.886170208363085, -9.022500867915554, -6.483908690769347, -6.478797015907496, 5.436632960504888, 10.11648415512398, 11.05236551506778, -6.555078182021158, 0.9926522830872675, 7.012674375514302, -3.958653565895998, 11.89784449953233, 4.997490823792532, -11.71308595491765, 7.473858613545575, 4.526049765812032, 2.627760851429408, -3.543040309678986, -0.6545512958150839, -1.975237359166213, -9.752416598897163, 0.1746629230980583, 3.764199942242819, -3.523765142660245, -6.526579460908251, 12.86892013415631, 9.636987335709112, -7.71437307352219, 9.374585571980461, -10.09888573625552, 2.627000532523575, -14.35239184493451, 17.7934680232572, 12.24617038938174, -6.2027891597684, -2.117824121844527, 2.304085371600412, 14.52899092304767, -1.375604453625678, 9.300885546968621, 18.94646416924206, 20.59266172433305, 2.716897787405002, 14.41056423737162, 4.669781485892746, 2.929418504934519, 8.242335741048715, 5.40876543323668, 2.002902940983452, 5.6098816375921, -14.20093255834947, 3.901682718637671, -7.337643713401271, -8.218284944457553, 3.072811403558771, -2.292798328406445, 10.69584853135417, -9.650335290149327, -4.330515729410567, 0.5204595970152146, -1.624267060418924, 8.140164084847148, -15.7637122001724, 2.453007028561554, -4.499820926337408, -18.34001755668463, 9.796120126023718, -6.012926560200856, 4.434295362280665, -9.67082400790736, 10.4548835691208, -1.769628011664158, 0.4768710210096864, 0.3854758620192356, 3.320903327037195, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -43.98223406015142, -5.032665049120959, 63.89171973078309, -17.03607126733364, -11.37762317554949, -1.901161248292645, -0.8260131144255914, 12.01428472457645, 5.352225349608783, -0.3266225326728286, -15.64216660863595, 0.3825939195623905, -1.494103371722206, -5.375511858816146, -1.862194375089014, 5.63824583310378, 5.360101148587418, -5.696506781095095, -2.080871954585809, -0.7829130324044875, 6.783149785809925, -0.3661710817347401, 2.462769544154133, -0.8126745345164752, -2.507928414100153, -0.7896746658950899, -0.4314818025686951, 3.924872737975131, 3.720963560907183, -0.9854313103876566, 0.5600582865792041, -1.688187106864158, 17.44248034254651, 7.56859337644358, -2.163244623250694, -0.7929207133815144, 6.398869750639878, -6.091736851159077, -4.728849132755795, -2.854085872325754, -4.826855364681831, -3.30106640664588, 0.2719713238103212, 0.2298412502409825, -0.853005758672194, -3.263371003058645, -1.287397261994707, 0.6221723886323094, -3.488369011339807, -1.414828169574871, 0.07717807180754992, -2.684195273815242, 0.2613139899890946, -4.206641018599038, 2.982830136882203, 6.657239919946693, -2.518089625188537, -0.4552654704803235, 2.298800483965624, 2.494983397734763, -1.284395189604125, -4.238400338443188, -0.6366063645353051, -3.325393279736908, -1.764225755959617, -1.813359309843393, -0.2947559613727277, 6.320461175365693, -1.048130219904732, 1.69129533904847, -2.336845279584976, 5.580341689077066, -4.541654669729592, 3.817079261725959, 1.972729191142582, -1.594128333779149, -1.535735104483785, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -59.46738063214526, -16.09510211169977, 75.92651854229776, -6.959588443327999, -2.809913552100682, -9.062449485347019, 2.929935910954824, -6.516445771274741, 5.618312537880061, 9.794206647467506, 10.44206520884292, 1.504143210681085, -1.194672878944117, -1.206412082832246, -1.592792412630419, -0.8713955483970806, -0.4430245993565414, 2.114713938914445, -0.3808503381452496, -0.3361054648766276, 1.810321218052103, 0.06324533489118153, -3.207697984086771, -1.888840647774234, -6.337450722394116, -7.051669943095036, 10.24163394168822, 4.591682020148506, -5.157620119910969, 1.350695165969617, 0.7792033958582947, -0.8363399401868995, 0.8398917333791918, -5.122390663285614, -0.589942253467838, 0.1140765360111759, -8.180634436361872, 0.782695084020231, -0.4316505953196415, -4.677604739058501, -3.371394391221965, 6.790122165196175, 5.900302157317789, -1.138518787666086, -2.696524630738898, 13.39780057844131, 4.194434073284752, 5.363099243116376, 4.110197934071277, -2.070985188896846, -1.165572235840805, -1.241624822428416, -7.086628398680193, -7.575672638929711, -1.486981977191632, -2.042873730189658, 5.495814100326541, 1.841533297055732, -6.033390059069625, 1.625951790058254, 5.031090908642416, -5.215840389266634, 1.850639244782789, 2.092351976481545, -1.480623358531872, 5.911569449582607, -1.869423525406329, -0.8096475091606794, -1.000819809262052, 1.841395444723725, 1.081170909224551, 2.284559473058704, -0.6250480378852277, -1.559903447023968, -1.853970655342937, 1.547744137147876, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -96.3647680893793, 1.199043513223026, 17.60420974833172, -13.06773608748545, -13.86009320666351, 0.1767817722626665, -0.5124263274350351, -16.26448243634644, -7.14143348503811, -14.24141019732697, 2.26049840163611, -0.5232284569456099, -1.920838853591793, 4.846489507057715, 3.042770898035555, 1.294385928313621, 3.262620434881149, -2.270944593759149, -1.408453286683619, 4.497236785795636, 5.977793107223872, 0.1340518117987963, -0.6905643209085197, 4.805322551598841, 6.502377969783907, -10.47261184903601, -4.131639902258459, 5.974051724377973, -4.360075843426007, 4.73500504926485, -9.718847270507625, -2.119804026495935, -5.657677043459689, -2.856025773969369, 1.756942740498222, 1.717927994018707, 2.836097818243513, -4.425043948906356, 4.283315817519375, -2.059940986323201, -6.307828936261935, -11.44715911847551, 0.3006681108636347, -5.507293839810647, 1.536345859738123, -2.26452399462477, -4.716331237978856, -1.255956886329029, 0.7042206945918659, -2.667007107490436, 6.672978852425663, 3.262254896828355, 5.937155133580987, 1.948386865395799, 4.552963709305849, 1.788332867713114, -10.63067323751173, 5.26892419774046, 3.167593513248493, 1.170780576616151, 1.205868492329382, -0.3777966262231325, 12.93219596919667, -1.629499482312095, 5.270759888996531, 6.75414771239083, -5.680238880370791, 1.763910811059415, 0.2558270515454605, 2.632569608785784, -0.6147023174800583, -1.873856188681823, -1.734814810908174, 0.7079064341945942, -0.9150650771583158, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -23.02913191459475, -22.68355714527637, -71.45920181332552, -7.335069133951983, 6.88897969406801, 14.22303129604287, -5.713578960023669, 15.25375807101405, 7.31607076966181, -22.97972556461536, 1.773867719140929, -10.21928707943674, 1.424895097068828, -6.202938372907802, -3.564833182189926, 2.874044501828823, 8.685525653278034, -6.81311188053174, 2.764368126088952, -1.051923578466305, -0.9476817080611526, 1.161644143534287, 0.8923143965210864, -1.986614015969402, -4.795152281813358, -4.571219954943216, 1.206804637019736, 1.189134886949103, -3.389219761826265, -1.403036249676163, 0.1159085048840897, 0.8722638450337192, 0.6308893671254719, 4.417698737007038, -3.617011218574619, -1.59415231672244, -0.4094009736543018, -4.615708070111476, -5.105781556006933, 7.165268502604309, -10.27990343205298, -2.449496798762735, 1.740806437896727, -1.676699767804021, 0.4392602027266447, -2.822535542169061, -7.693191637559086, -0.9799315922761813, -5.464041140223222, 1.890629379194414, -2.234640399497272, -0.9456666715392037, 0.997606186316458, -3.110634577331055, 1.532640947608809, -6.76298600927938, 1.926980466393365, -0.3975761625796731, -0.1074936397088645, 1.428032551521818, -0.2307372170405339, 10.50672618228523, -1.043253387292014, 7.351732297170027, 4.654268870350594, -10.97263974298692, 6.22881607660602, 5.315813011291942, 1.976388766185981, -1.590375718577871, -1.91368371633717, -4.647761418706064, -1.035563975020433, 0.1409584860123588, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75.07192855828178, 12.10308470349448, 73.0310118247737, -9.646003904806241, 4.932961189760345, 1.718589369927463, -15.44305085297956, -19.92076242236019, 1.289853308008594, 19.44625320979492, 4.210588674471425, -2.579319144988436, 2.410104964471558, -3.865247564242535, 0.826851006847084, -3.631426466227551, -2.842039660907502, 2.249433450127177, -3.309261383458769, 0.6757720427689214, 2.35903348697973, 2.568255552039278, -0.321803303996427, -1.108091120089183, -1.412785938851775, 1.785124078160854, 2.573232078948616, -2.076416085393783, -9.312869029610674, -4.310360243055708, 0.07839735762587302, -0.4810908104630088, 0.9952395155647055, -3.886794543907047, 2.525965274526253, 3.540664673781963, -2.704864111340364, -3.864627721141978, 4.457179505634837, -6.813519964253322, -2.007416166791153, -1.607611533013739, 10.38000897763594, -0.3046634977924537, -2.266871922238326, 2.573731821774683, -2.979571190380482, -2.320864784735163, -1.500209869827327, -5.106748863521393, -3.950957911975269, 0.7340374884876252, 1.73889407335216, 2.182641990536762, -6.356098593894809, -5.93055977994974, -0.6040135105288104, 3.029168613692871, -5.042929510576918, 5.833709461846172, 15.29860079283752, -1.235961351707758, 9.34323445595332, 3.785951093156088, -10.34177459105045, 2.911648799971752, 9.281014378066164, -0.4941493880528656, 3.071779513490743, -4.517815603760604, -6.192250219969715, -0.3317883573330157, 1.349445179208848, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -63.45021054279741, -15.82766767521525, 41.22915354775575, 4.664008353213778, -1.654066901130316, -23.18254021974398, -12.84906013980607, -0.9626027911697629, 3.41433891445458, -0.06961595567794145, -1.096971305807928, 0.8698295584855787, 3.772196521299375, 6.631293883425417, -7.052125668571361, -3.200823343555333, 3.814349784726156, 4.941784929229768, 0.6315537523938005, -0.01802357802850369, 3.141620177813325, 3.10250469485239, -4.155135005432694, 1.701739006290255, 1.540814933013846, 0.7387665729315541, -5.311958621040922, -13.02405885670838, -4.942498894115073, 2.149572755504388, 3.341124951208096, 3.870026706159178, -2.46509460954075, 0.4769961681706392, 6.604145321870847, -4.15894453283208, -3.374029939123039, 6.807566765521488, -11.58698328431105, -2.80185415106152, -0.002148524464262543, 7.754192162202266, 0.5225981165001614, 2.195290230986459, -5.408948531637178, 0.1049214015983932, -8.924285492967401, -2.350089393085131, -0.5423255417785425, -3.219609856555158, -4.390973896320624, -1.269742631984241, 4.051212063679165, -10.36139506901704, 0.3230350713187323, 1.674998606949747, 3.540984566900865, 1.18972973091647, 2.057607076615883, 13.40112401714828, -1.748763782836714, 13.13716409027571, -0.2243177932456299, -12.24721484928519, 5.87773220153188, 9.74466077242022, -0.8896869572089892, 2.189477242908632, -5.208603883097037, -8.105641911969411, -0.7300180023457923, 2.022265831725371, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -52.66687486179152, -3.101783038688906, 62.54840137160225, 9.616670950233983, -12.50481143141205, -28.04924352555032, 18.7558503771284, 14.97634693290006, 5.851320122566384, -0.1677270839150571, -2.409084137352026, -9.845991621034058, -3.801336162247693, -0.9907297274053595, -4.664351290089362, 4.309633797495072, 0.6048954669030202, 1.543984136643211, 0.7189536403742964, 5.611415033458477, 2.487672542609962, -8.621934168449286, -10.05094063299714, 8.742063873037001, -3.490157247009134, 2.066460908332703, -4.477586251672978, -5.332933548411357, -5.713234560480118, -8.240059969073409, -3.364164696488402, 6.227061542811854, 0.1791896591361718, -2.507565879175399, 3.698854501954176, -1.007279474702307, -5.481898046206347, -1.72805442027048, 1.655718519783813, -4.101110323704863, 3.320297978932387, -3.684641982534487, -2.130960673414645, 9.904486582652764, -2.376262647862093, 2.148900292669743, 4.759998469058096, -13.36944502872464, -7.978751527858369, 6.863214185815936, -1.882367548219069, -2.561088530514321, 4.873981502571982, -7.579320197588544, -1.497679078782172, 2.35834379567061, -8.385645880902972, 4.09880893561949, 4.828417395745121, 2.282140125429291, -4.833463519506268, 2.913845215609183, -1.612937226837221, -0.5525869262187749, 0.6145753612090259, -1.089608686377456, -0.3258113829684524, -2.210223671018175, -0.8097847014254713, 1.266046990796156, -0.1222971055896021, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -62.97383455884989, -15.72156846847342, -50.52987429444124, -5.821406791941631, -6.271938286848207, -28.08098151092815, 2.368560549147725, -14.39710551246207, 7.569330972477777, -13.4264330861926, 2.75461801976173, 2.688711269115824, 2.764732074458091, 8.408341398358559, -10.04776489918815, -7.396363378028368, -1.149416203511894, -1.054301083542792, -10.04596380901379, -11.69408823775871, 17.38686456253957, 8.299516226227814, -13.25762288717717, 7.349031579684647, -4.534835890890477, 25.89116419268924, -0.01992743860632668, 7.982099277597088, -0.04160883712533649, 2.573520590529096, -11.35149838346194, -4.227617111120538, 0.2168974914804734, -1.795362046493738, 5.631764300285649, 6.008575066010116, 15.72428788595154, -1.842254414189587, -0.5382261085672077, -9.552315485913649, 3.675875209168321, -2.602166724352801, 1.859610651661533, -1.895505270339744, 11.52276237353004, -6.239279748413804, -0.1297742740578715, 0.6991046300254831, -0.4208529689673289, -5.060072193399457, -1.906088726339328, 12.62054139647468, -5.130598829626098, -6.128474594316537, -7.690481592824534, -2.247055264194942, -1.447577869543198, -12.36316455006643, 2.732894276344731, -10.27755222960528, 0.5243468721916534, 9.047719038239586, -4.383971076616716, -4.842518948484556, 1.125600151566935, -1.90225576696169, 4.722031005971605, 5.306544131294808, -1.877228890927751, -0.1571777681548308, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62.52508007922609, -5.719488295515556, -63.28854566104216, -24.50023292372474, -1.974567606587724, 15.49864632949223, 6.998409457393456, -5.489144318408908, -0.6799511450744802, 0.6168873226031361, 7.888491941073679, -11.5213969968209, -12.02867471563315, 7.763694194348873, 8.334853365418969, -2.380451302943409, 0.09020014258787826, 2.3486772567884, 5.673982771176749, -11.02127409093227, -3.603461078419621, 3.167170753763195, -9.711383410279849, 4.723995107208117, -25.16138896067726, -12.23741325241211, -5.007012002050583, 2.190640446078525, -2.216636720328977, -0.5859489793413336, 8.233471386988535, 3.365237643930874, 4.189743657652521, -1.395157859959696, 0.3920210029284703, -7.056426817934152, 2.580560567814978, -2.128975130545938, 4.242435652432224, 2.235031188314527, 3.444275519482045, -0.7064127681508054, 3.521919688523948, -2.59915922665114, 2.796011561611334, 7.213677229286767, -0.2401477293445469, -9.239236230514949, 6.250101954381679, 6.220350851430839, -13.83625185491088, -1.200037472412707, 6.659714118020979, 11.18894360817651, 1.029186325547049, 3.013890675288255, 11.33035543805201, -0.7441654641054523, 9.147248359723497, -2.626393685016684, -5.110468073117602, -0.06530067048820608, 4.76431701962415, -2.253412642242864, 6.519983245052911, -3.976542599366748, -2.604614469192844, 2.348858737245175, 1.219946438299759, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71.32602496514716, -8.756876217814053, 35.04911984263231, 11.85596450877738, 3.138232705310344, -2.194824321913857, -2.176583710259183, -3.343478177638568, -4.236563157562049, -1.392674203474749, -10.32262876392589, -11.63217516576671, 6.360303917047404, 5.478160154717675, -1.373379667953706, 0.1222360308529321, 5.92992964189494, 6.968285486207656, -22.24412202832642, -14.08200805003572, 5.255065130840872, -9.647401891006457, 11.00321233823368, -26.63174562751841, -2.523162844598605, -6.145124307805637, 6.022273738346928, -2.926653347515803, 8.133925760802793, 8.591428362280888, -6.013423802818253, 5.249342941582124, -3.970400887670635, -1.748951928295462, -11.28492868937306, 3.683276522805945, 2.775813620317148, -1.942462052184175, 0.8891846150120821, 1.129690076778026, -5.55530433211887, 6.228804252833361, -6.493720150589822, 9.095196357844529, 8.099379043388204, 3.282276517555831, -3.970254131193375, 7.47529332111375, 3.579752526867083, -14.72795586609742, 5.127558963939634, 7.483150275119841, 8.143770403634198, 5.638865762472385, -1.070704874835951, 9.665581065265565, -1.166404516592552, 7.118528213260745, -2.114185083787445, -6.481345817022934, 2.439165766212086, 1.688770678506234, -1.42208740458422, 3.736908500476163, -2.52099822967916, -1.096365312903943, 3.115453100212649, -0.09261316039995293, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -53.91482041296031, -6.195234141533248, -84.22720528023089, -8.228357964869858, -5.335191448255144, 5.056702938346606, -7.464695583224544, 11.90761078244647, 13.09090097966719, 0.6578496842921259, -10.92616341315019, 13.03744853784803, 12.44023007567226, -1.161373459354644, -1.087744561840636, 5.932731979531396, 9.315732460781408, -21.37551613946766, -11.96248596464901, 13.63024808396517, -9.288714959320243, 7.289554080422293, -28.16285634112625, -9.571761912856207, -12.95118012023273, -3.750611197225868, -3.922432347873787, 6.124510964031026, 8.396222723906581, 0.6148965037770432, 5.13355621975811, -5.15138967657882, -8.114413035924995, -14.85090329064167, 3.39729299292902, -2.657124865451653, 11.34942261680844, -2.606547131090628, 0.1623880304796317, 0.3049177006141654, 1.35635227366094, -6.653050626870728, 8.073015458686122, 4.32132583894199, 2.212964809408603, -2.184076048165147, 9.799834020565784, 5.96606727639304, -17.42599122311193, 2.990347710352649, 8.359376262684071, 11.42371296595421, 0.9821035082629358, 3.26846258160433, 16.37981065781434, -2.885803722420936, 10.97059625603291, 1.611945735717845, -7.260237552742894, 0.9012561107562547, 4.615303611480527, -0.2799207674436057, 5.037467804678709, -4.682042101547799, -3.881526357472375, 2.728902770049329, -0.06849225345413945, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75.12896070864572, -14.55114803420073, -25.88520658421626, 0.3634408911932056, -5.749148081032294, -3.987054468607347, 3.605389714269859, 18.07840198100762, -7.822123425494485, 2.924157083708025, 1.962703760694055, -2.860064629683554, 2.959145172069614, 3.93868226857773, 6.366668810634879, 5.288829466990348, -4.294038560170033, -0.08801626773445168, 5.250702110881997, -0.3152641291658385, 2.199002653107061, -17.67833947760999, -5.045964490505647, 1.211048049454066, 2.421824405506, -4.376451661909966, 6.241973769898392, 4.290964226801218, 5.969309505771088, 0.8555684941579085, -2.217790960392097, -1.35718576281381, -1.746727805108543, 0.5254608653917869, 0.8086186851967726, 5.293064595586645, -0.3599247004146829, 1.959101109902374, 8.947006788222373, -2.378495602576101, 2.723709987744103, -2.329120911932814, -11.05882331472708, -13.0794383091978, -3.452514320213396, -1.512851055243775, 0.1639755205493351, 0.0825479539228451, -15.39065507630122, -3.091131632830409, 5.338329408636449, -8.829569668743607, 8.153591122859282, 9.18321870067153, 3.77411909040066, -0.7259214307321555, -2.707742728847757, -6.070142253582127, 0.8961401710073812, 9.291034725859165, -5.172620787510649, 5.77739330996065, -5.938409073064742, -5.68284811156704, 2.213899420332612, 2.230741101606077, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40.51083229358659, -6.657401086597119, 46.1651355827067, 3.571126140204381, -16.51018529197995, -18.81764925681962, -3.560003960730173, 1.069143039257071, 7.841419461017695, -7.426825297086943, 3.636227586276667, -2.832840975189855, -4.226091127266264, -10.32558071350056, -5.423718841813621, 7.898975963852462, 9.110182036344748, -4.818572270232188, 7.517064129930646, -3.069225466093795, 13.58082569251052, 1.95336044171603, 5.706764456088048, 5.029792791510202, 3.178869494747695, -5.047323754409704, -2.736438120770565, 1.426807143702085, -1.920567914619038, 3.428205422463726, 5.74585589697081, 5.382153677222462, -0.8865556423886194, 3.914778289385668, -6.604066141662078, 3.391876836068548, 3.169728760425306, -4.677156167446953, -1.155070546015535, 3.061191481464817, -3.13123995748959, 6.494562114793292, 3.376621926659731, -4.587404098548453, -4.277527442893002, 1.474886961462322, 3.323795372963384, 5.401089673065682, 0.3253871348814484, -2.369066423960044, 3.865796037257022, -1.638291040075763, -9.722922494527154, 0.5238103099430581, -1.203361374442151, -3.74503959737966, 4.569457144757759, -0.4965825177245843, -2.765019233250034, 0.2829604726448859, -1.146952017594104, 2.265032786536537, 2.680700571952246, -1.255503266954519, 0.1637658162738065, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -45.71426451969628, 0.3451233465733878, -42.83879591649266, -9.652152512053839, 2.943077049148836, 3.595807131194814, 12.07618358595724, 7.583721776261375, -2.798504129600953, 0.3493125113412846, -0.3060685650112926, -1.969954034839694, -2.226643423419492, 0.2775817976926701, 6.61252070570618, 0.2026442823847165, -1.756653814676166, 1.358336152476414, -2.953213341300402, 5.767247508163317, 4.576452080845395, -5.48265868666933, -5.584394192816982, 5.087476338922126, -3.141525913674985, -6.275099033613296, 5.577549390317852, -4.816802787505703, -2.484144702930381, -5.941817033794925, -10.3264911173429, -5.364557843392888, -7.843223405124702, -0.5283376840825795, -0.9570442251031415, -5.24883614050029, -7.185962189820855, -2.977003550332989, 1.181048111506568, -2.173863203462683, 4.403509726183693, 5.789771709589788, -3.251326838177565, 0.833293737507765, 2.197330074627189, -6.70359339703703, 2.969866449959098, -1.167049442438063, -0.3088855619701391, 2.234922153742612, -0.8743490423992627, 9.838111926343993, -3.681537357431789, 6.247482122998323, 10.24712337154277, -4.61734564949215, -0.06307486749200926, 1.334451074280191, 5.336299550216522, -2.297158597383811, -1.096756988788949, -2.950656621747207, -1.793982883674879, -1.379935304922622, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58.4305528833414, -10.93080151481084, -73.47222018485503, 1.299575050569214, 18.14449108892977, -6.050719753243367, 0.5840217211940599, 1.960086594084849, -4.368421952540212, 1.788116554787903, 2.164491069701282, 2.358970020887192, 1.093569678019126, 1.989649218755819, -1.28823196621902, -0.5313187250208743, -0.5624844430654856, -1.907667575555907, 6.909040860485212, 2.408127751390964, 0.4215555707913529, -2.780873876588656, 1.85248203975166, 3.135639744664483, -4.380299973926649, -3.921426250428929, 1.495099382458397, 2.622560565964388, 0.2177544811958763, -0.04339424448668048, -0.2214592105458387, -2.06944907992863, 0.1763703512794778, -2.846732426447117, -0.4639421303306322, 1.287390331822631, 0.6533086995560746, -2.425549690664099, 3.088053892492399, -1.130817472618208, 1.485446373139376, 4.380685859773039, -2.57028748480229, -2.127967029034677, 3.41369029366427, 7.568188803198317, 0.496744282104129, -3.964473757500087, 0.0282299427440213, -1.96849998024905, -3.553514188828535, 0.9438074995728989, -3.104500825703638, 1.724858829778236, 1.800147082209048, 0.224333685578572, -3.291601313990126, 1.370577599850704, -3.565441527576292, 1.823418080577437, 1.52484990001091, -0.828729219973382, -1.06107451712335, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60.4551144650917, -1.112031735605267, 40.52296759779913, -2.279357391039372, 4.563291267943169, 8.295632041224566, -3.939508280061141, 1.942114905022437, 3.077992623697353, 0.6979345603294407, 6.071625856395872, 9.832923870768321, -8.720411873028274, -8.458375209728874, 7.032936679862646, -3.660503707293801, 5.13609182864828, -3.763326595416756, -3.646534951906556, 3.175402986994713, 1.020866860271357, -3.886824646779147, 8.218325748247384, 3.32404792165843, -9.200062655640144, 6.295889066677559, 3.845719933212995, -3.43351185274513, 5.438009428491434, 6.112353772294139, 1.228860655027741, 1.024037136509394, -2.139240304739709, 1.532357918757432, 10.1079544033704, 4.044497472104775, -1.295614976235356, 9.473469973585541, -8.029083475961539, -4.343462366128194, 10.84815682088869, 1.011633882504112, -7.169231098330976, 8.133704565655293, 2.691632282997318, 0.8507816064460101, -3.282652921494739, -4.061244378839357, 0.05112572018852947, -3.547751950024609, 5.30365786223212, -9.690997968552335, -1.734557454096158, 2.931578504521047, -0.5834918591113373, -4.496448398993238, -3.031542637377464, -2.036988448519847, 2.154422493546257, 3.299173741623872, 1.162415691741919, -0.5670591291688311, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -70.06613504205954, -9.835478687386175, 48.52214856712762, 11.48136951108488, 5.892721436902954, -3.703795834979923, 0.8429544617402316, 0.6016790749403919, -1.12542788838987, 2.368548605557095, -0.6822772589146743, -4.287688004185707, -2.594460038219845, 1.811391939430363, -3.268064562811219, 1.460904850276689, -2.864974741945764, -1.034841388002912, 1.745241178328566, 2.486796799228639, -0.2269447058580376, 3.439717265105236, 1.02136554408696, -4.705182655489384, 2.499760827621522, 1.840963673652037, 2.953808675230261, 4.276133519908038, 2.651957942115774, 0.6355241666252862, 0.57194650441768, -0.1440454915229704, 2.242291193237154, 3.579445219558762, 2.752322997747827, -2.639308831991975, 2.4577698710486, -4.752199390601385, -3.863233755634323, 3.10435637509681, -3.028301690338678, -1.02478741743191, 2.754261908266995, 0.03535310362791887, 0.6383262792814937, 0.4368852433821509, -1.380097243200454, 0.281051180629981, -3.521710925389415, 2.247365619297284, -3.14338177048046, -3.302250573466052, 2.012036598405328, 0.1368976717018865, -1.193536497653941, -2.112322112549731, 0.1388066012915721, 0.8364226293226722, 1.307996121331485, 0.8916481210688338, 0.4828704628796113, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -48.35160025190098, -2.541971211171999, -40.68153564873732, 9.207954361446687, -5.556985583068949, -2.844696785788164, 2.796718046185394, 2.464041987072172, 1.893613270308423, 4.028977435880829, 1.580350980861052, -1.926871386712014, 1.936201877177753, 0.03605266371746324, 2.628195057996384, -4.803264934471255, 0.1432706764330213, 0.1079385572562689, 2.678825585163418, -1.064180917349414, -0.5008460410343695, 2.882130267316084, -0.15398049667585, -1.581309397233642, -3.437020133996731, 1.265459202748218, 1.117834225134362, 0.1360954343911673, 0.9375505319888843, 3.243740457337423, 2.092675870695559, 0.04783544042641906, 4.765463295666528, -0.4641437505818906, -0.4785294697426362, 0.9696458103026435, -8.685566793141595, -7.008778621407876, 1.595549810231035, 0.3128462080006037, -1.324425648748344, 1.053200285772633, -9.359526652432077, -1.580936494199254, 3.673447578818254, -5.544913965708159, 2.361010918728093, 4.208995052675768, 0.06177199204784918, -0.7315046900899178, -0.358711190997884, -4.578123417453783, 2.050322078756102, 3.974849259098512, -0.7452561049821164, 1.594734714218798, -1.737806196971752, -2.031916066155333, 0.5613088668818109, 0.7078249129938057, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51.98712898798419, -10.91279555750407, 16.5116520014062, 7.070082094300194, 7.316626743402702, -4.062538962997873, -0.7405273411971364, -2.403988646588473, 4.735499624487429, -2.288345916874214, 1.710004157792464, 0.7759293763857303, 2.319801872864849, 3.523736483172671, -4.063099150658085, -2.492051000480119, 4.11448548909593, 7.129988646336227, -2.243669991226699, -0.01638383640626986, 5.035870505157345, -0.9263294558811588, 2.097755508212908, 1.321512562673401, 3.748642620543865, 3.497629889280451, 2.535560833332076, 6.70155773507767, -2.222025277278504, 3.745469454508642, 4.860671405997067, 1.247993743903351, 1.366709222748014, 0.15728611894614, 2.359412737808513, 2.228713531327038, -1.291887607463255, -2.502446261947766, 0.8576018641230071, 0.2591128365637439, 0.1281550783740285, 1.457088120497456, 2.804040947211357, 3.04089132770398, 0.5933410236497064, 0.5620801447638994, -3.466284049616893, 1.640115928164911, -1.286700740977786, -6.179791106131169, 1.636998061183449, -0.2159342040060719, -0.3846813123879876, -3.023642425428129, 2.529816319670621, 0.03264733953770085, 1.353325216772121, 0.7761992320974147, 0.8335576498590705, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -25.43514166894322, -8.17729396479627, -9.755663509088453, 19.19784728348034, -4.384048886049747, -7.499153400798601, 4.435169145012178, 2.435444086759126, -9.059597245945259, -5.325657224831133, 5.740599830438042, -2.492050052381312, 4.19796696197511, -4.263587721918892, 1.77146723826956, -0.4935403175135217, 0.8862361772476778, 0.718637930367225, 2.234402910854942, 1.153322927018771, -3.443329198738874, 0.6587212840847486, -0.7054120735100874, -3.07872040612198, -1.371786433350092, 1.271824407901802, -3.947941817835058, -0.8336796717965617, 0.6116519681575391, -3.071696553703523, 4.475454076327929, 0.7609188629051276, 1.92281105267744, 3.40184922477059, -8.810192326908565, -4.590741833410618, 3.734024788110379, -1.509040639411721, -1.529465630170008, 0.9461084686824491, -6.75503144580174, -2.037690055578029, 1.030666583912851, -3.882610283293217, 2.375072374836591, 5.361220748281059, 2.030587685343521, -2.594516437562062, 3.173762351676447, -3.470985476419609, 0.8394945737986235, 1.011387559197422, -0.3451056702610979, -0.5600384586317051, -1.250437490195752, -0.6594046924812333, 1.043095979522655, 0.3317341014295642, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28.99829564612994, -7.919492306918029, 14.05556909884386, 7.925941651982717, 1.30923833477671, 2.711408876410578, 1.61295413285611, -1.556599660832906, -0.8098128328747748, 0.4820136628666691, 1.242144749021579, 2.59270514147219, 1.070695817241087, 0.3750106994386846, 0.1725150645491444, 1.817115818968294, -0.4814506723964737, -1.161742890285604, 1.472007131837003, -3.436966082846573, 0.6982494240111369, -0.3149935878404753, 0.423370074395463, -0.9574295293157908, 0.2421056567329433, -0.5049850377885065, -4.679003799785368, 1.836812379169509, -0.6413835068300918, 2.492048982685315, 1.392871072424903, 1.054456102018222, 1.562804344198468, -0.5360913571726491, 0.2289458184750688, -1.348818559581913, -0.7324130913590041, 0.2525553513400682, -0.719825146825839, -0.6622690818866591, -0.05716678780881196, 0.03985333634237294, -0.3355682149483769, -0.1341481930486313, -0.2245769325773339, 1.701054496016564, -2.071735516197021, 0.7197321751353539, -0.5990693757732555, 0.7461182301273023, -1.28537860516808, -0.1752635447217054, -0.01940763082982118, -0.1985636316510818, 0.9478745916084782, 0.2042482439571948, -0.4223294809395653, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26.09223882232648, -12.37682729616652, -21.27874182963862, 4.348357266610032, 4.573400992223148, 5.451216191750214, -3.611392020039598, -0.07921190808374405, -0.8260009529279171, -0.8434890069043338, -0.4552052508830591, -0.4528369276968658, 0.485445048833045, 0.7411599447890793, -0.4977249990635382, 1.190184399027994, 0.5973815546085762, -0.787231230010092, 0.03686032549901305, -0.4890816251224443, 0.5247759592075937, -1.879966027178497, 0.7792555164671459, 1.08723712738975, -1.42032534259863, 0.1721744481327533, 0.1056055009830306, -2.005790677375433, 1.016109801476819, -1.242159849121084, 1.243013696198364, 3.432482241304956, -4.523104088240713, -1.568715574671622, 5.119814672065328, 0.3791289530216432, -2.190682514501041, 2.552754170198622, -0.449368385418214, -0.5848836895616387, -0.9128519962622303, -0.9291921116478306, 0.6344008715643001, 1.688400124637569, 0.3633977049284803, -1.575721206061369, 1.961090047103945, -0.6752069375516031, -0.7855465024767947, -0.2102475861881171, 0.6869577789805948, -1.299232189451566, 0.5683367030798885, 0.3130637568892004, 0.1545378225570001, 0.3790410707685513, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20.78430083032547, 1.185047939349582, 35.77538180501586, -6.08934280503613, -4.628055061913704, 4.470155638785817, 0.1274755893885796, -4.165150926841093, -2.90227906734488, -0.845111562541671, -1.740136245099567, -0.7946086439652909, 0.165908004480544, -0.6322554553948885, -0.7202811048901517, 0.962291525388159, 0.1867569707618253, 0.7090001464102381, -0.9034980429447981, -0.7997832600818465, 0.1057538227773544, -0.2295775902801903, -0.2167480404571516, -1.707234755317263, 2.041285551224553, -0.7878934898873934, -1.430438536425756, 5.730418488030445, 0.6926510312478421, -4.339109958364433, 6.727134105417382, -5.329326344720556, 0.2090167614184525, 9.514829796739471, 6.99752035864157, -5.726866864790069, 2.796275247427376, 2.891078173635352, 0.5284713674492778, -4.068212458937251, 0.007838785072538627, -1.603613176227203, 2.0145967452931, 0.8759256044597022, -3.80096540098218, 3.215984538447468, -2.552801380633107, 0.554399068571981, -0.3103317501790938, 1.208594964868666, -1.283494125131377, 0.7998967241899251, -0.386450465669298, -1.202893469925367, -1.317846847748221, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -47.41309320362173, -6.902809138581961, 24.68993718840007, -3.13534854977696, 7.054619343395385, 5.577611289513071, -3.877117196513223, -0.705447221487262, -0.8099002262119813, -0.1565635558190763, -1.127616075289359, -0.340714841660406, 0.660945871772091, -1.386755567315061, -0.4584883778560444, 0.9198751662032315, 1.002014450214894, -0.8640902794196041, -0.8777171102898179, 2.14825103785315, 0.989246034616117, -0.007095782785030112, 1.73906114106083, 0.6255059446607256, 0.1889696248858352, 1.03385909422522, 2.226668602394364, 0.1698945168834521, -1.873328492302393, 1.635950747204321, -0.6535224611564427, -0.5212140486619968, 1.003703892471871, 3.059411904595601, -1.892088474084682, 0.9339283828820583, 2.372361621792483, 1.133949816931869, -0.1994699011958669, 0.6535725484050933, -0.9195781603438848, -1.005444925904406, 0.06444426676642491, -0.8098171033672705, -1.318065403781523, 0.229094599479945, -0.1458840598162685, 0.2580570421599906, 0.599654091348747, -0.1055495042899468, 0.8993623666137143, 0.2691782537744015, -0.1099774106379499, 0.2977644683250328, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -24.74429137938651, -3.056148054133861, 19.0056932068058, 16.39870702492764, 4.267138497765569, -7.263096879020432, -2.919011924763906, -0.4167087337896431, -0.8396221408817942, -1.296684951975891, 0.7231090234720337, -0.1375746950653319, 0.4893869484915677, 0.3142640879884956, -0.2220967974170002, -1.109112753429507, 1.837593002510292, 1.479112432032976, -1.096302655894103, -1.964525246159897, -0.3280412024354407, -0.9206324506519383, -3.476018583754276, 0.6640599703563438, 0.3918183916355132, -3.395485381429018, -0.003002004945104059, 3.146782410011682, -5.072333819483568, 5.41257407183969, 0.6517585511003233, -7.269221543477382, -4.056630984171059, 4.210313402070434, -4.078813743290807, -2.25180663054022, -1.292189897325851, 1.427646253569202, -0.02497439324399699, 0.4774218280565992, -0.6503459447009956, 0.2399655638403526, 1.867125503961992, -0.9832308658323502, 0.3873487083709633, 0.05281139747950379, -0.3835529630274041, -1.6917245847278, 1.122860683946538, -1.59095315900844, -0.1293462709264742, 0.744401662451372, 0.550681606700183, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -34.33789589268527, -6.878943247619225, -14.64721261322692, 10.01107177766694, -10.23942535961409, -1.01498039173437, -1.897412320562053, 0.1671533339857628, -0.8712694561978971, -1.083706765312663, -0.8072110203673344, 0.8308152015963188, 0.2147544944441696, -0.5493919968376136, 0.1446575439684376, -0.6832698103437359, -0.3948442858808979, -1.115588657559433, 0.3579803772248178, 1.360983446684671, 1.00664254181845, 0.463405794612902, -0.01621384683534825, -0.8228161891870686, -0.9063503571998639, -1.803563811674677, 1.773734326519576, 0.4302873906114944, -1.04322351848609, -2.826856356023816, -1.324768966730078, -3.650267019006124, 0.4946176831514201, 0.9765254105590534, -2.029801194780261, -0.08501190782368655, 2.178344340984078, -1.920968439027878, 1.468087622744764, 0.7608787750954016, -1.000741195716964, 1.504164739818004, -0.2688678814948808, 0.6600983722848048, -1.220320200367525, 0.2410125647060634, 0.1664703506451447, -0.00850398171402288, 0.147174562643468, -0.02779982278043158, 0.8346719111354661, 1.343056942062318, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24.86877278577309, -16.79318934098175, 7.458488104737861, 9.49827773740922, -2.037264532584139, 1.252205231895099, 0.5394711870719748, 2.195699736074124, -0.06182472637253196, 0.7020281028590925, 0.3258270446041916, 0.1103891416148433, 0.2807839830050392, 0.8324674121995713, -0.07707017579260933, 0.04774101018547401, -0.6651862970621468, 0.5716949794838074, 0.2786641675385044, 0.6522299722084175, 0.9870590659751258, 0.07525858148281402, 0.2573717074126062, -0.8694521708682318, -1.166811640779638, 1.298799293918699, -2.203520860482713, 0.6442208455279349, -1.644267690640131, -2.625903488982017, -2.302992147951265, 1.257444945761727, -0.08416130603880936, -1.270800555411265, -0.7611165428890112, 1.039732198091014, -1.251481617872658, 0.668700121789956, -0.6911166576485717, -0.6139792747015455, 1.608281400168625, -0.2867634337303782, 0.1637144135551453, -0.00432411765221891, 0.07102947638320466, -1.167072230215902, 1.020402395737285, -0.8250836936353415, -0.6010780760217853, 0.1575436581466232, 0.3661602997463697, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -25.48744110290001, -0.8196103125693783, -28.12739691634226, -14.66875241082419, -0.615739550477418, 0.7968006490105319, 1.893633537382631, -1.654939455947577, -0.6163475289447353, -1.258986228668871, -0.1685854638534228, 0.3466358666389292, -1.426194843008651, -0.2003994306001548, -1.259905297827965, 1.344072840361883, -0.688819755049539, -1.014480774303581, -0.6295918075499517, 0.1776953465799677, -0.2343489103275878, 1.245580834373049, 0.282925806992274, 0.9010886337902754, -1.886506785726124, -1.464163182582124, 1.060688891787593, 0.9766666550692192, -0.7971522349237924, -0.3026477025841756, 0.1569473405096722, -1.562229392252153, -0.5092349552596337, 0.330008450314712, -0.6335053028536132, 0.4247451599698489, 0.0985199006348359, -0.3513889048599413, 0.06524354177060393, -0.1957245081554103, -0.9317593740728739, 0.1952654121598859, -0.2590026012553117, 0.3001134383078498, 1.986414203689662, -1.071273239462749, 1.253278874165287, 0.33617967896085, 0.7395830923202225, 1.549701849275336, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31.61694956773989, -9.578300913349803, -3.504213982861134, 2.937150834658584, 0.9888020778636044, -1.024980201460239, -0.5118645161888414, -1.146567755798608, -1.444823248641867, 0.119064333528641, -0.4696982483040331, 1.095121262010022, -0.5308991134969057, -0.5197247973700743, 1.05002708888555, 1.818937037971043, -0.464288009797318, 0.6619872266917841, 3.401021092823941, -0.9482749170371739, 2.813315825246367, 1.129476242162393, 0.1981687722797381, -1.019635015614744, -3.307198789311745, -1.432171362179824, -1.184749190478042, -1.044919901810701, -0.6539226010822516, 0.4625979387292016, 0.6826291685753989, -1.87320881210041, -0.02360508954848113, 1.040603087479057, -0.4961300270289009, 1.055913719807241, -2.655638121288787, 0.1835672294990115, -0.2887263743968013, -1.414391072650056, 0.9868620830546826, 0.6374153108068793, 0.1452572712918873, -0.3526782564487305, 0.6972915252755666, -0.01466270301749871, -0.4766248436639112, 0.2560860018610663, 0.5918528531262749, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16.11268891122238, -18.88517791209816, -7.849457648122431, 0.5186009516658268, 0.9174633102810905, -0.4433385845787631, 0.259117803259069, 0.4812800928303352, 0.3809278637536887, 0.1040308979050729, -0.05696819922547338, 0.04177348257977326, -0.19151417247168, -0.9633478211800127, -0.1242642511041362, 0.3111175057895781, -0.0993555030948718, 0.9200983120151756, -0.283630744431747, -0.3768440931992381, 0.2608693517536536, -0.1701114694365957, 0.1657033422918405, 0.5579125426286559, -1.625886334801126, -0.3807035749043056, 0.9640891719563836, -0.1517544113079037, -0.06175882514010688, 0.4876052179200603, -0.1171970532950455, 0.01944444533954101, 0.4490968232071326, -0.4458741922044034, 0.3254420663099036, 0.5282760372591894, -0.05934694150103174, 0.1060201539053977, 0.8283931026778301, -0.4074091722040743, 0.4784701634625882, -0.02952608481148086, -0.1915663172505298, 0.1218560114391382, -0.3518484009580818, -0.2587618544226619, -0.1011116715064274, -0.4008733499435151, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10.28612342841808, -23.92112732279337, 5.771795426117762, -0.8030148991959661, 0.04406286929137412, -0.2462851679259779, -0.0790329685264313, 0.5162614125094603, 0.01081766552358586, -0.3771532498914852, 0.2371657873877063, -0.1121483962706096, -0.598902253817861, -1.018195608367853, -0.01053082672842091, -0.3684877801366509, 0.3508826267234865, -0.2390155682927431, -0.1773909049534708, 0.1757923535233533, 0.2788684363679378, -0.521760862098457, 0.3153403198775502, 0.08909424355874358, 0.3382317489455293, 0.2248194206427477, 0.6112323344458919, -0.05266682106538524, -0.857521487871565, 0.09621919673355192, 0.1820135304582492, -0.03556509270831806, 0.05480383694627229, -0.05236763037981038, 0.9935679652239512, -0.01831786321756342, 0.205863157809067, 0.3066879134775455, -0.5897438503738709, 0.1809856006527006, 0.2304158672123705, 0.1357359363236704, 0.01081706136475033, -0.2019643081867054, -0.2674765180786534, 0.1218826125012657, 0.06599894348285046, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7.508940298192356, -25.92446548490683, 0.8596283612994251, -0.885296785459307, 0.6510912736108546, 0.04489469589179211, 0.1153490121088812, 0.6103383563995985, -0.6314156415588608, 0.01915715564342266, -0.5113720254650198, 0.08321272888636021, 0.2526155635642888, 0.07676680070437664, -0.207069381512334, -0.4238244829828506, 0.1598019632669035, 0.01979690071582769, -0.1131733213057336, 0.1678269137319559, -0.06128460713493483, 0.2950474603493092, -0.05777326473555904, 0.1081544273212701, 0.1350575367841474, -0.1382598662249417, -0.02063619586362458, -0.01748166206219487, 0.1390481463209892, 0.07165704302950053, 0.1349895003361674, 0.06236059106166005, -0.1944785128320574, -0.2787255380331269, 0.01560113047175663, -0.2002320581613433, 0.3115961907926021, 0.1635870368788743, 0.05678294158098499, -0.476018191230865, 0.3068760522389033, -0.3033131104805271, 0.3509349305650783, 0.3398673523876503, -0.02472276597655712, -0.1406202583056918, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.938841061583187, -25.33986700948118, 3.895381103905187, -0.4068328885046618, -1.020248987608946, 1.875210227283616, 0.8326849356539051, 0.3197332657604331, 0.8814021905636888, -0.191597405724302, -1.189763075075068, -1.758874335134983, -0.01899353751647506, 0.0276611350365027, 0.5048267537307356, -0.5806174579955142, -0.02276182921702848, 0.4354081702397676, -0.1913814507405756, -0.1404271457144592, 0.4293939511517911, -0.2455037565707741, -0.6287458194591844, -0.4325390080784384, 0.5663792753160686, 0.06496758462505856, -1.013812891552513, -0.6580075377114708, 0.3012766122553553, 0.7826160029411943, -0.2956334704185347, 0.5829842798108729, 1.888181195419026, 0.2434171191535548, 0.4382404847806721, -0.2260461131572888, -1.002274173244901, 0.1511392353702925, 0.959534113889126, -0.7055427039674402, 0.6121511681849879, -1.070201333103883, -0.85450815461259, 0.3517683076365886, 0.2515058817628869, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.188440162629536, -18.32569924146616, -9.589804523680115, 0.3710427014950839, 0.3218205714481496, -0.2690828162556131, 0.3778764240350382, -0.3074423748293786, 0.005775081556014241, -0.01195607972614768, 0.4411561531339875, -0.03533727446997911, -0.1118188852301485, 0.5245470238731157, -0.01500837976097037, 0.2330462173829136, 0.3097172521421208, -0.1141404752456203, -0.03010554327463865, -0.3053455023961597, -0.568283713910994, -0.4659469523334061, 0.1389552806909783, -0.2547565634519277, -0.08627456156926228, 0.4559236364597809, -0.3852998773859254, -0.2059868514232366, -0.02375049165040808, -0.3131649641419055, 0.1909454021240402, -0.2322739633649241, 0.008020950818914468, -0.08341805591326434, -0.111253448846017, 0.05259516567515898, -0.001122570051102888, 0.1514471161594721, -0.0404691113211848, -0.008872368197677635, 0.0116933627886483, -0.09874720009960319, -0.03877084404075001, 0.05002466574186254, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10.03537283004762, -31.0463181244779, 1.779031435921747, 0.5805779942073915, -0.1697490764077751, -0.01914980853094367, -0.2211539569318829, -0.4216165170128795, -0.6480115775079677, -0.4142538428904219, 0.06564004090328103, -0.4941714579440745, 1.034278660942381, -0.2047718684985376, -0.01268161547420685, 0.517525878890536, -0.1043791000267504, -0.3647396058345162, 0.2111603242370048, -0.9972172123676774, -0.5115981269692284, 0.4959144934872069, 0.04212237503456763, -0.0259339732866725, -0.1242882315804042, -0.4810924645313537, -0.02365156513499566, 0.2627756243130801, -0.5274144495229729, 0.2708662778382719, 0.8165087143124619, -0.1013704061972073, 0.2726522755404825, 0.3850625905291744, -0.5191444285929395, 0.1772802840204757, 0.3334115942202089, 0.1315431110247013, -0.02250684048613707, -0.169616886212142, -0.3125742719244352, 0.04507962853556727, 0.01003848565633635, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.534564874870957, -24.59524017605734, 3.803193767088361, 0.1204388472709394, 0.5761719808045163, -0.1117681261275701, -0.2329370688709992, -0.08102002281001033, 0.1428619986726483, 0.104842791253757, -0.1181730570197248, 0.4589008851142075, -0.1080200483321708, 0.1900878438866454, 0.1999148634974392, -0.1482677353246511, -0.1560253005429775, -0.148698943892873, -0.5439804195128841, -0.4178164555772285, 0.1013788135893234, -0.2170885424796042, -0.02176885122945166, 0.2064156754855712, -0.3206810843761114, -0.04373791424112124, 0.2504839663865664, -0.28090563960889, 0.1385536322071997, -0.08959168523700539, -0.05811267349918002, 0.005219295271455209, -0.0006095068025606334, 0.05188819365042641, 0.05557911001260952, 0.07279423774972828, 0.07138061600398075, -0.03756847423989253, 0.02816926549231814, -0.07480288912090098, -0.006340103202835009, 0.0003644593817090534, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.032984611804681, -27.23593121948949, 10.91195300159838, -0.1955025467061237, -0.3108776615407506, -0.3861125933123738, -0.2335216115611025, -0.9691736965590945, -0.2809799173614512, -0.2879486799582545, 0.2288415268907392, -0.06960881368743468, -0.3354356497684607, -0.3414928741679384, -0.060828537807209, -0.301089195863019, 0.200552261417137, 0.1352398329475678, 0.3340834458703997, 0.07377669861905928, 0.2564987850409935, 0.3238811050529972, -0.7225355496632641, 0.2551257047021489, 0.1771742636853869, 0.06594998613853977, 0.07018408521301191, -0.05587922004114503, 0.9700092972137774, -0.2579283194903866, 0.6519487404137869, 0.5508375252467951, -0.6490234945917377, 0.1447953357975773, 0.2164634615540051, 0.3169200204043436, -0.03463118539302083, -0.151318881732286, -0.2345691835471254, -0.01993158819697678, -0.05040377327442637, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11.4540626253999, -20.77158386493728, 0.8646709228308843, 0.1362724391608822, 0.1719025418456963, -0.2551996740096885, -0.03511714486680503, 0.1843273888070675, 0.1712704953498521, -0.08238211456267275, -0.0278396535204387, 0.09282985085557675, 0.2532178349906294, 0.08197119062309449, 0.0199260300618629, 0.2535665679716856, -0.1152352645199304, -0.1736314115581865, 0.01698268605977707, 0.04658947833988694, -0.1857939567479137, 0.01460595684305768, -0.05830186068372888, 0.03887623804842972, 0.1233901766950485, -0.03958735173141364, 0.07325984287647014, 0.01640653011899173, 0.1584691045459283, -0.2308825423077231, -0.1894450711707396, 0.01097836857891495, 0.04360019357535277, 0.005697416476426774, -0.2056452089585314, 0.04960126421902575, -0.09143466075759629, -0.0152240285154079, 0.07997148646231036, 0.03173856999389955, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.214993452284615, -24.05350963927314, 2.935180686952885, 0.009367576430711424, 0.02897145608792666, 1.037258110070721, 0.1361330302043889, 0.267403438521004, 0.2041268631368911, 0.009677886298345676, 0.4513281035866327, 0.4879183299083247, -0.04366463541582642, 0.1415327697743105, -0.2267638854965378, -0.4997584611277828, -0.6976848080687116, -0.02518594676737141, -0.2588366599642389, -0.2416744762736605, 0.7221885872238599, -0.5539147131834354, -0.1134910123367641, 0.2737448220857051, -0.2927880039131713, 0.2057867576341399, -0.79800324914354, 0.1932584636177841, -0.5035224041067244, -0.5321735749435307, 0.5437275964446536, -0.1399374304829474, -0.07507775144608267, -0.2918402578666227, 0.09771036738785385, 0.1114599184651533, 0.1302712088256483, 0.0519407976536088, 0.06216196476169271, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.947682961146469, -25.70508238397117, -11.46177925662307, -0.3724367020684367, -0.0346498317775926, 0.06864375351559394, 0.07554361694203379, -0.367323229127421, 0.09593202864671034, 0.1377534867847666, 0.1184603670917067, -0.02650248054294359, 0.2092301771249943, -0.009852203175540166, 0.1288173411245062, -0.01556723710218602, -0.2725343716448551, -0.04882125871058738, -0.1164191596901248, -0.01306504969938954, -0.09972247608276598, -0.05244353803868229, 0.08508888288435545, 0.01494712152255306, 0.06488803226510469, -0.1140190552259744, 0.1236269753074166, -0.2360969288917616, -0.1066473633353232, 0.1264867082185493, -0.02483266501799899, -0.04114542787579798, -0.1266313954297545, 0.03448373932480522, -0.05195144188753792, 0.03249420081315806, 0.03713923614715957, 0.01317281111328615, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11.69631299718309, -22.48619259551776, 0.4736607761650089, 0.3364440611411286, 0.001896101447363962, -0.01839142547031177, 0.03683300808928491, 0.04804330923877288, 0.163622475873788, 0.1554000460872887, -0.08113035605009281, 0.0394436822356209, -0.1518190651150113, -0.2391233604051897, -0.1848160862235859, 0.005028918748719988, -0.1738801952717139, -0.1389518165707553, 0.2440059223399533, -0.1912611405349515, -0.1278732887547087, 0.03594552209482393, -0.1239443437214213, 0.07601115720720845, -0.2413170999853679, 0.01830028011033026, -0.1786719142755088, -0.05040746869497416, 0.1855068663687703, -0.01469530719590392, -0.03565818225935036, -0.006393469065442842, -0.02927051217417908, 0.04981431028590561, 0.01896848487153613, -0.02389638792932929, 0.001671298450249839, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7907072650120487, -24.90261765607406, -3.336934808793186, -0.1100561385510806, 0.03806580362882676, -0.9795899124384002, 0.2113562476336533, 0.1210755170917097, -0.5709907672936722, 0.06148724086826907, 0.4281734290575387, -0.1228023758602741, 1.217889711872614, 0.5772065011935688, -0.8854453190120086, -0.02188476051865783, 0.2939683523215479, -0.3364845598685323, 0.4389370528196214, 0.2175645153244334, 0.1003089157346634, 0.5938129566146761, -0.2639007244911475, -0.4694860419564821, 0.0619677643285282, -0.05717000630200545, -0.3202406910706038, 0.378107742758849, -0.14006136421472, -0.248450630677327, -0.1410998107329354, 0.0735235604182249, 0.006870838292283573, 0.1952510899320096, 0.0282675631387419, -0.003424908838937833, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.437730841654131, -33.27385476914327, -6.935734943236623, 0.2090812561111312, 0.3348393450135521, -0.223586923299236, -0.07352664648222718, 0.03785759488211347, -0.1513766386596058, -0.2099960883438794, 0.1017048240174961, 0.04182607962471709, 0.237579420640883, 0.2399067162829091, 0.07523955310772605, 0.05857405848698407, -0.05389473909058243, 0.2636593955046162, 0.1468245947741072, -0.1210583952104068, 0.1524669191535411, -0.214238636532872, -0.03816758506191603, -0.1354966639865573, 0.09316724617238126, -0.01615929313522045, 0.005900244511659499, 0.1042542689707338, 0.02949183866897195, 0.037267365131775, -0.07808591456574898, 0.03857619705636327, -0.07145363560926057, 0.002429628071270416, -0.01721018579426699, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -6.66333148382885, -14.4614219114703, -0.8464300600479908, 0.2514104375223278, -0.09861658442109786, 0.1691348097352446, 0.1896581102869329, -0.08087907706641626, 0.01174408327349146, -0.04072839225976889, -0.21084119330376, -0.2084820021746563, 0.06459499104581255, -0.07220761842989601, -0.08081244480389148, 0.2770967905223476, -0.1130641379249503, 0.01313709061334511, 0.1053117612678122, -0.08548227871695131, 0.04755230373305874, -0.239808392738221, 0.006594669706792055, -0.1160148635147146, -0.1546465218776207, 0.1797178820270592, -0.03514352886331645, -9.157443953328604e-05, -0.08036793482879778, 0.002475861135144963, 0.05097461589006569, 0.01013677531395254, 0.0105449596442005, 0.01367406076786437, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.019923386108676, -26.76235000723083, -5.231507339253204, 0.176832541192354, 0.3017249373834541, -0.1388443978394047, 0.2312643317132779, -0.04464652755082743, 0.07808084544420522, 0.4313216233613872, 0.3080530810133845, -0.3090015643058375, 0.2364897664214366, 0.06604367687341839, -0.1876613180395572, 0.3146210580156822, 0.1784726037504162, -0.02271540068963666, 0.2342699465461129, -0.1343387528471265, 0.06625828689355771, -0.003273887803178955, 0.1450943895905023, 0.00620258099433276, -0.09380102559767173, 0.01798478433460103, -0.07862806231355808, 0.05631636830032596, -0.0196969615930718, 0.04436104332404119, 0.05354400105458426, -0.02354762170847734, -0.02514305223947428, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.177075859399771, -33.39258164773348, 1.63759177075579, -0.06342533195251419, 0.1411980486906961, -0.1464775848775387, -0.04431760714090424, 0.01154744252601158, 0.1026506579361863, -0.02088412824928649, -0.02902179807556261, 0.01304836720502356, -0.07271697524786641, -0.07325213106164481, 0.03704096648459854, -0.05922855466144863, -0.06262650371609046, -0.03182071956590917, 0.009080904737058308, 0.1354599956171088, -0.012606916831903, 0.03239503119872632, 0.1409587222872537, -0.06002807561785677, 0.04627926839441229, 0.02573135330017627, 0.004605365395089219, -0.08725168654474108, 0.002587419133345108, -0.05185185645936881, -0.005849547735873801, -0.009771554197080978, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.064718113513358, -13.12988850942804, -3.438372519392976, 0.1264586180050162, 0.004883996372652178, -0.04481988503927746, 0.09576485030352094, -0.3955235936343703, -0.2087500394183668, 0.3073328906227044, 0.02068102374422703, -0.1083588810681304, 0.1758168533371591, -0.1756277739685251, -0.07450374022378869, -0.01630094419723318, -0.1914647508380139, 0.08895278495397248, 0.1403814278690517, -0.03489253346297209, 0.01598763641739303, 0.1131830343890914, -0.06699742805657724, 0.00240472634967058, 0.05514166821797546, 0.03884124270426484, -0.01101385248527006, 0.01954817931909242, -0.03459346077345329, -0.01274466093412686, -0.003543141293631806, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3.395368558938009, -27.6115795496259, 6.02328924849129, -0.0217949039676702, 0.01713458866911107, 0.1204807990971129, -0.1903985203838578, -0.245494995765684, -0.01567899867737631, -0.0483287391034937, -0.060209365295053, -0.00658859715813279, -0.1748730515278048, -0.1172896416076897, 0.002885900683208647, -0.2725962934388483, 0.1896424602622011, 0.2547718270544993, 0.08930762271234099, -0.05000517893940885, 0.198774168883364, -0.1836169107571341, -0.001441577306058042, 0.02027315191018264, 0.07922510191796643, -0.01081020778347853, -0.05485129878921055, -0.003504265936056936, -0.01741627502898858, -0.004300648475577595, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.881439123068173, -31.86267091719867, 0.3170578648639695, 0.4687236230510464, 0.02662683343011025, -0.3302193472780357, -0.477346463679984, -0.0517454341931882, -0.3336060762108314, 0.09422553730446168, 0.04946779745885752, -0.5432213903814268, -0.2492264416620409, 0.1732279550240386, -0.09454901437534985, 0.243084678749923, 0.184313316080481, 0.110429054715389, -0.03650964419849936, 0.09749969511293206, -0.1326505036247279, 0.05009598527464214, 0.1082240240233409, -0.1489278834552438, -0.08096188906466491, -0.0850388793794887, -0.1125032485965546, 0.05122382376743441, 0.05527189635692931, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7431797386269411, -14.65117500009382, 5.823447882655948, -0.1881157144876831, -0.3008729186775366, -0.2240680575846533, 0.02294923203244657, -0.1328373063914675, 0.01835629292837719, 0.1359000574454446, -0.3469510665265196, -0.1308216630102339, -0.03496464106937285, -0.2440104038689523, 0.04193512042581821, -0.1366336497635793, 0.03231520148337453, -0.1084198723292215, -0.06739647043502352, 0.08740658296680984, -0.05956248732431352, 0.05155443563206404, -0.06543491661245913, 0.06950710262417095, -0.02430554263388206, 0.003834848628751442, 0.03034298318482847, 0.03421651369935733, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.826424710849555, -27.75807925717017, 6.49845414271845, 0.2088222638768245, 0.2567583755247717, 0.1680006630260083, 0.07113722086014379, -0.03228298686790457, -0.1031612528617338, 0.1843360031254731, 0.07332196070209686, -0.01774216015656859, 0.2986364342557484, -0.00134569499401013, 0.05460048981943994, -0.02322575505419388, 0.08264206029436941, 0.08014218496669946, 0.02559186811441928, 0.06346651700418222, -0.0449661723444516, 0.02381879758386176, -0.08682020285221281, 0.08025959489260269, -0.01003292155179478, -0.02340991530415569, -0.02962714897774685, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6.435188878061354, -30.23792586523732, 0.4023394954316882, 0.1442634156119251, -0.1020481640743369, 0.2616580251348765, -0.1059180761079543, -0.08743876827521066, 0.2785769450080205, 0.04428252801918474, 0.0202832410441884, 0.04189636473520755, -0.1103209617823084, 0.08801265177191683, -0.06151324254000396, 0.01355502488640757, 0.1011883046619023, 0.01940829963761287, -0.02376145032104872, -0.04253776187455549, 0.1015931898787959, 0.004439366426774084, 0.02720943797022718, 0.03068092663135336, -0.02169503454248668, -0.04815156165797598, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.23475181130263, -25.85002095399512, -9.61072734631551, -0.2587337302523749, -0.2671090327042298, -0.1373193461266922, -0.01686645319925775, 0.1214524395626546, 0.04787321250564932, -0.0102808929635468, -0.1079687161735285, -0.1204158425469933, -0.01370170730210608, 0.03896661385808254, 0.02006408734658718, -0.01957557336743487, 0.02048657847215082, 0.03186441907330201, 0.01437600500970395, -0.07256365762710008, -0.04268726613146586, -0.004291692030780559, -0.02959742701650543, 0.009784658017416398, -0.001361411062570107, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.668539275335888, -23.18029209894821, -7.104549227457261, 0.009494835170991586, -0.2155484926554607, -0.05117708716304314, 0.09558257063666828, -0.006204864175755139, -0.0535983098279376, -0.1721078109347795, -0.1292907195966384, 0.04463480683436428, 0.03962458796875007, -0.03394918991811541, 0.0360179426993984, -0.05098248960386708, 0.05421613324558673, 0.006517343947994034, -0.02849867886559621, -0.07880371848866945, 0.02642259523254391, -0.03587610810807455, -0.0153740561986479, -0.01461543749433446, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7.000678311567365, -23.41161932249744, 0.1115405160634775, -0.07148023127921439, -0.03829631039398255, 0.4350529946111771, 0.1273341721442011, -0.03309653396004558, 0.07269741094613814, -0.2517627759593927, -0.0916540014643315, -0.09513082346238068, 0.02936404485630485, -0.03887824155586548, 0.03259923092993516, 0.01480224718798229, -0.06089794884744876, 0.04533354466816, -0.04401696277253729, 0.08384757422274537, 0.03447473565697338, -0.03655777066458333, -0.04286881746219928, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.1997455187845329, -23.67906930857953, 3.298493240502194, -0.1847467985210671, 0.1243176781235989, -0.02243375998252476, -0.0004203531178173071, -0.1373119846655697, -0.07119941044543882, 0.0598855239376691, 0.0365497555952217, 0.09940083973287311, 0.02170561702085787, 0.02523145542278863, 0.01398860677045751, -0.02099249665794002, -0.08042834487614063, -0.04514933257707622, 0.0210691994836113, -0.01304565123088667, 0.003317809080060446, 0.01880126864882835, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.363427418619814, -17.41903576009931, 9.186568349711468, 0.1111029283919205, 0.08777631782411636, -0.0106122045071789, 0.1144225997334068, -0.02466841586746403, 0.02750112055321526, -0.05524437334870362, 0.04541263818821106, 0.04741842472464215, 0.03068743352629459, -0.03255656589538247, -0.03729968912772544, 0.01062121564506963, -0.008575892547858845, 0.02301960098527405, 0.01221098646015711, -0.007828736372639752, -0.02174734678713348, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9.23220561660408, -31.51893707701785, 0.629104414809966, -0.002885901152494686, -0.04654352249775812, 0.05655136143073162, 0.04644981489440897, 0.04886269814398012, 0.01421146833364892, -0.02220699538623673, 0.05311321315234985, -0.001358424574760307, 0.00136891734406154, -0.01810167863750104, 0.05846985549778336, 0.02464847599577873, 5.045357884432963e-05, 0.02313650001543124, -0.01897592900555872, -0.01000566869781843, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.6213531321316156, -24.30034243436851, -1.105212323117883, 0.1225585085553164, -0.2970472162797997, -0.1131121492749726, 0.005524192917051245, -0.005016083344128715, -0.05408343623542385, -0.02819561803866161, 0.009006334912992457, -0.02024545484485562, 0.03816393987230592, -0.0007047877611201743, 0.04901678014439114, -0.05163410574806857, -0.03130055103817821, 0.03533492988517593, 0.01195601678346641, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.097158496205909, -16.73710946124244, -9.426989245602673, -0.06261182983602319, -0.1059035148370443, 0.05076346286898199, 0.003678172466163399, -0.0454660155043527, 0.02462054291284395, -0.02110890517636086, 0.008241203910568698, 0.02390589384329424, 0.01198364473687612, -0.02957542631061049, 0.002236629456648171, -0.02809381563903465, 0.001689229093064753, -0.007600764285513168, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -9.412003466484951, -31.65984264675678, -0.1254812244514544, -0.09114636575550933, -0.0366463804259801, -0.03322040198025862, -0.01209970867041294, -0.01021849930537397, 0.02256075215944923, 0.01825223707293363, 0.003993042619294536, -0.008507286595193135, -0.02427249385479496, 0.03381794787948238, -0.02914842372731508, 0.007082873675038417, -0.006655560097220788, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.27548187849782, -16.01246939790233, 5.644600469890476, -0.04244915968443123, -0.0371436610514518, 0.0530212677895391, 0.008626194479801664, -0.02358451461610269, 0.007412437106157236, -0.04628615223361372, 0.0826909370927158, -0.01312239177378535, 0.05019812567992653, 0.05643602731883488, -0.03169977188973144, -0.02409525389114796, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.831745814038495, -20.41725582289098, -1.583013759260222, -0.02098081085371714, -0.03289988933600374, -0.006011309758863401, 0.03459650459981792, 0.01348477813223562, -0.02336540423557105, -0.003969872715414671, -0.05998169351462899, 0.05263821645435009, -0.0144354245014559, -0.005674777729486418, -0.03142277004383006, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.562800616132969, -36.13433050173559, 0.2585654510438173, -0.02913169721040965, 0.002592481347938085, 0.004329834978588065, 0.06325089767860387, 0.01951445115945309, -0.03070674283592272, -0.02183384192678349, 0.009849968434859515, -0.02891816499635688, 0.002667591177598971, -0.02361460878909238, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2286035973327459, -15.02261004686781, 5.184122379409034, -0.0264079721355016, -0.007786216137000334, -0.008663526410932022, -0.005309693290799501, -0.006680538291880966, 0.001397532516833339, -0.01528554327177548, -0.01182046150296639, 0.005955666147884051, 0.003523919303238692, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.214570242697843, -21.4621144179193, -1.555874989179182, -0.001447535808513384, 0.03124103143611023, 0.01560612912433155, 0.01254222023040845, -0.0006565581414721336, -0.005837445535672976, 0.003328905310192099, -0.003109407401498421, -0.001359993487917328, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.575215080762542, -36.12196181704586, -0.009581763987488548, 0.02181190823948241, 0.004249343259232833, 0.008866640947567769, -0.008827428692463307, 0.0111903702615688, -0.008259743446844802, 0.005994103918828306, 0.02884522108807095, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.02332478841374811, -20.31760288431249, 5.902175782312199, 0.01411291075117598, -0.0401626029282366, -0.04333034577745157, 0.006563645334078613, -0.02686027801335236, 1.82653938945055e-05, -0.009451944888619017, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.843446424852287, -17.22694391469142, 4.615021811975704, 0.03880112444568462, 0.01156878860697344, -0.02011735633875036, 0.007254465185871957, 0.006976302646061595, 0.01061407563995378, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.636349195088934, -35.03142250661902, 0.03540637402307944, 0.006380325215592348, -0.01715112535803765, -0.005381045082520479, -0.02796704437114206, -0.01837431744975316, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.03325953074641371, -17.29072432858197, 5.995094557622266, -0.004356649575832386, 0.01324648360020382, -0.002576747161993423, -0.0164552533090047, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.976772821535572, -18.99788030681546, 0.01396461545715264, -0.007601183590626498, 0.005853929901760483, 0.0201199907208218, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.002983340164191267, -20.0342372815637, -5.741448414658583, -0.01215113512395332, -0.00662723431795657, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5.752040939724589, -16.25515722920224, -0.00713497387655803, -0.004958024634924642, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0004916632598946193, -12.09805746213948, 0.000198676020167099, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0001765653829615133, -12.09823117436413, + }, + evWant: []complex128{ + -0.2513649571095319 + 26.5196181977274i, + -0.2513649571095319 - 26.5196181977274i, + -0.3323427794627154 + 14.12147023570828i, + -0.3323427794627154 - 14.12147023570828i, + -0.3885760957072044 + 34.01549575140551i, + -0.3885760957072044 - 34.01549575140551i, + -0.4938394681672298 + 19.28755724237434i, + -0.4938394681672298 - 19.28755724237434i, + -0.5354723308245726 + 44.07811563049843i, + -0.5354723308245726 - 44.07811563049843i, + -0.8831210193505878 + 40.64617136580856i, + -0.8831210193505878 - 40.64617136580856i, + -1.063691744877652 + 54.90113796777709i, + -1.063691744877652 - 54.90113796777709i, + -1.270999250073418 + 55.92169849615225i, + -1.270999250073418 - 55.92169849615225i, + -1.641962795944021 + 124.0727533257146i, + -1.641962795944021 - 124.0727533257146i, + -1.866212165366329 + 67.51198073484791i, + -1.866212165366329 - 67.51198073484791i, + -2.66562659457705 + 102.4818444744388i, + -2.66562659457705 - 102.4818444744388i, + -2.677285588970379 + 109.3976583973073i, + -2.677285588970379 - 109.3976583973073i, + -3.592328373007462 + 116.2450441105874i, + -3.592328373007462 - 116.2450441105874i, + -3.658587455178502 + 105.6223525143237i, + -3.658587455178502 - 105.6223525143237i, + -3.738335632746128 + 95.41374995650723i, + -3.738335632746128 - 95.41374995650723i, + -4.05659124602542 + 85.08673687146815i, + -4.05659124602542 - 85.08673687146815i, + -11.7967401639067 + 0.03421683561959875i, + -11.7967401639067 - 0.03421683561959875i, + -12.06591356324058 + 0.03010079020722811i, + -12.06591356324058 - 0.03010079020722811i, + -12.08354870692898, + -12.09435136773809 + 0.0007639916648241464i, + -12.09435136773809 - 0.0007639916648241464i, + -12.09785209014901 + 0.02991559300476182i, + -12.09785209014901 - 0.02991559300476182i, + -12.09806212746318, + -12.09850417485291, + -12.09864274565634, + -12.10160612637007 + 0.004700099158908263i, + -12.10160612637007 - 0.004700099158908263i, + -12.16873692768957 + 0.02446545858852495i, + -12.16873692768957 - 0.02446545858852495i, + -12.23495190373921 + 0.1453184367031505i, + -12.23495190373921 - 0.1453184367031505i, + -13.54778407074696 + 141.1839768257274i, + -13.54778407074696 - 141.1839768257274i, + -15.38790969472481 + 114.0584849752244i, + -15.38790969472481 - 114.0584849752244i, + -23.60369882806601 + 0.2464158068361128i, + -23.60369882806601 - 0.2464158068361128i, + -24.04314341198735 + 0.3315626206724418i, + -24.04314341198735 - 0.3315626206724418i, + -24.12753399862331 + 0.1634093642552133i, + -24.12753399862331 - 0.1634093642552133i, + -24.18103712080912, + -24.18908889661277, + -24.19357072143492, + -24.19567681157636, + -24.20660003986661, + -24.228086198612 + 0.0220672004906673i, + -24.228086198612 - 0.0220672004906673i, + -24.30677145425284 + 0.1813999700804981i, + -24.30677145425284 - 0.1813999700804981i, + -25.23862373866253 + 0.8733279005402655i, + -25.23862373866253 - 0.8733279005402655i, + -29.42427841595277 + 1.666886570068163i, + -29.42427841595277 - 1.666886570068163i, + -33.94959271558832, + -35.51958918286584, + -36.20666045708104 + 0.1660921702962803i, + -36.20666045708104 - 0.1660921702962803i, + -36.25710351845593 + 0.01052251476620707i, + -36.25710351845593 - 0.01052251476620707i, + -36.28714605125749, + -36.29431583135849, + -36.29711199023137, + -36.31304183793699, + -36.32232768169418, + -36.37871120972082 + 0.1557647672076243i, + -36.37871120972082 - 0.1557647672076243i, + -36.47694233727385 + 0.3738707259908102i, + -36.47694233727385 - 0.3738707259908102i, + -36.66483183150206, + -37.75937189360096, + }, + }, + { + // TUB100 matrix from MatrixMarket, balanced and factorized into + // upper Hessenberg form in Octave, and embedded into a 104×104 + // diagonal matrix to test with ilo != 0 and ihi != n-1. + // Eigenvalues computed by eig function in Octave. + // Dhseqr considers this matrix big (n > 75). + n: 104, + ilo: 2, + ihi: 101, + tol: 1e-10, + h: []float64{ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -1063.761, -960.3970563202379, -0.0006079108185996773, -0.009201940691316367, 0.002442836240270196, 0.01550988534551903, -0.005482455008401117, -0.02216870959395947, 0.009747347615349792, 0.02941831540681939, -0.01530136178573213, -0.03750794345694437, 0.02225359194453896, 0.046705617938318, -0.0307619752542162, -0.05730825585675074, 0.04103856105936231, 0.06965250072575992, -0.05335624663776811, -0.08412633500439758, 0.06805680196063389, 0.1011811513254484, -0.08555957035531082, -0.1213434441393789, 0.106369291926541, 0.1452243676184516, -0.1310809449650698, 0.1735240650736495, 0.1603769717276725, 0.2070245946752049, -0.195009056622052, 0.2465616197175694, 0.2357520481176992, 0.2929587463757468, -0.2833105069304027, 0.3469005841220431, 0.3381503031304328, 0.4087132445918312, -0.4002236126054999, 0.4780213717840138, 0.4685650013761221, 0.5532750093152425, -0.5407842250274101, 0.6312148133425258, 0.6125866029330725, 0.7064838330293224, -0.6776224584955323, 0.7717672671130079, 0.728093737707456, 0.4477228711606641, -1.832801684441419, 1.950252997191289, 0.804390452586547, 0.4832557718849113, 0.3060066166102118, 0.2756451553030591, 0.1719798268352208, 0.1844690914416081, 0.1028522851629666, 0.1338501876768783, 0.05922545829023376, 0.1041210893998114, 0.0294781768570502, 0.08738772703908808, 0.008665658061761334, 0.07957418017688388, -0.005841802748350547, 0.07832978350913038, -0.01561691241238414, 0.08229737118429636, -0.02164114160477788, 0.09076446627208183, -0.02452178964005379, -0.1034535010713481, 0.02461324557496748, 0.1203839900069163, -0.02209524508102444, 0.1417838483570761, -0.01702626635186736, 0.1680394493064578, 0.009377435518891378, -0.1996795871970759, -0.0009558646643977288, 0.2373933824702814, -0.01416583764558031, 0.2820880046959302, 0.03057782300299389, -0.3349961435755344, 0.05073634798692103, -0.3978562481735693, -0.0755607412701291, -0.4732063781751494, 0.1066126139010085, -0.5648764073871733, 0.1465759215609417, 0.67885880956596, 0.2001993093624898, -0.8249735752515708, 0.2762967421832379, -7.383366696690373, 0, 0, + 0, 0, -504.7000323579025, -960.7839130908893, 455.6939154064305, -0.0005890239049151091, 0.01222453307167895, 0.002380254112046573, -0.0183767018575125, -0.005347164384529943, 0.02487432959226112, 0.009507444863507727, -0.03195485414878263, -0.0149219770912947, 0.03986517031337426, 0.02169664773526838, -0.04887103316029169, -0.02998576954964119, 0.05926702273427436, 0.03999696952048423, -0.07138712464416012, -0.05199744338214077, 0.08561585141999975, 0.06632116378894419, -0.1023995009673016, -0.08337613594660015, 0.1222563158317329, 0.1036500341236005, -0.145783656379474, 0.1277114126111218, 0.173658096672846, 0.1562008437363875, -0.2066214365478053, 0.1898032066448404, 0.2454413266872829, 0.2291867817273585, -0.290828708487696, 0.2748879884412016, 0.343286767980235, 0.327114242278849, -0.4028620578438859, 0.3854382883926989, 0.4687761898935385, 0.4483798648521518, -0.5389586517254393, 0.5129393074648648, 0.6095951621601606, 0.5742741750224843, -0.6749584326212456, 0.6258664262549096, 0.7279030750048989, 0.361160520701244, -1.817820120247178, 1.493677993805868, 0.9093218408940651, 0.3437577565805193, 0.362630116371123, 0.182491216989941, 0.221714417427429, 0.1064242506044702, 0.1554403491948274, 0.05893517713417926, 0.1191987572531298, 0.02593630450949156, 0.09940153443435777, 0.001987949044964486, 0.0900967012871452, -0.01567758628187121, 0.08812023104053984, -0.02871634215129631, 0.09168600701701864, -0.03819855166921124, 0.09983277639781361, -0.04483241285443643, 0.112135778661831, 0.04908165568011769, -0.1285288605462619, -0.05123906116349945, 0.1491912175066926, -0.05147890107583802, 0.1744806002258908, -0.04989507359069757, -0.2049040909139878, 0.04652399206028981, -0.2411228487302952, -0.04134974220480257, -0.2839940475275046, -0.03428683940013912, 0.3346573639346669, 0.02513376678028306, 0.3946840836316033, 0.01348469011538719, -0.466320753537143, -0.00142779450121434, 0.5528931223683594, -0.0210105793668851, 0.6595061978534259, 0.04783831497380739, 0.7943401758885881, -0.08674091416897045, 7.282263793289921, 1.964402124200457, 0, 0, + 0, 0, 0, 504.7001065567226, -960.8071533894852, -455.6899665187256, -0.0006381542544069418, -0.01696123848664222, 0.002571421839873352, 0.02356372357492877, -0.005765057328779014, -0.03054576659236009, 0.01023675166561691, 0.03816637411322649, -0.01605159633648196, -0.04669530536153424, 0.02332395960802052, 0.05642332124514469, -0.03222102273610906, -0.06767293164234266, 0.04296780496196387, 0.08080966049331523, -0.05585344634069236, -0.09625362412257953, 0.07123822293842015, 0.1144906642960898, -0.08955981060276022, -0.1360815254382584, 0.1113369911164654, -0.1616662801387938, -0.1371665625346616, -0.1919585350680096, 0.1677064944291291, -0.2277205865868329, -0.2036342514104135, -0.2697050947227386, 0.2455629056115962, -0.3185418058062836, -0.2938904117765113, -0.3745411973588626, 0.3485540671441012, -0.4373871729832214, -0.4086704182323145, -0.5057124011628437, 0.4720841567744535, -0.5766169045256523, -0.5349437472430429, -0.6453152755169759, 0.5915742979267851, -0.705252589538002, -0.6350313138183948, -0.4095510871717013, 1.601644767644169, -1.801430257336091, -0.6783540858316911, -0.4521876448242478, -0.254377814677483, -0.2609137525907964, -0.1390187634586346, -0.1780644458672355, -0.07811098364662258, -0.1332228921784263, -0.03844450844393983, -0.1080065082071247, -0.01031758532230231, -0.09498853030853376, 0.01036100507490249, -0.09032395086444481, 0.02576859065961766, -0.09180684083159034, 0.03723131440198095, -0.09818648544931335, 0.04561209756712017, -0.1088355401035232, 0.05148345180798951, 0.1235465165704314, -0.05522144380747635, -0.1423972092039827, 0.05706613305793608, -0.1656652164809836, 0.0571654881872712, -0.1937812736972878, -0.05560491141385822, 0.2273160612316538, -0.05242306351060358, -0.2670005088314752, -0.04760687919206397, -0.3137829156332985, 0.04106438412981419, 0.3689347453356511, 0.03256097086263596, 0.4342239659065471, -0.02160937448771497, 0.5121963228132351, 0.007270440886606282, 0.6066421962514198, -0.01221319300610655, -0.7234154012137514, -0.04013586770219741, 7.505393492740379, 2.207569919375577, -2.286495948142137, 0, 0, + 0, 0, 0, 0, -504.7004946877645, -960.8313859426444, 455.6868630884425, -0.0004564668894400728, 0.01953047220881932, 0.002110185308335535, -0.02552492771185354, -0.004910008054476974, 0.03185603230051105, 0.008867203935794236, -0.03876493903116766, -0.0140372793617222, 0.04650258449956125, 0.02052143233325077, -0.05533916645715601, -0.02846939294478852, 0.06557394899483331, 0.03808355296447862, -0.07754536439486578, -0.04962400720722794, 0.09164110934556451, 0.06341371783532462, -0.1083072609262454, -0.07984241792495486, 0.1280548395158984, -0.09936692302911229, -0.1514604665622404, -0.1225031219103813, 0.1791553196119899, -0.1498024404391789, -0.2117929820588376, -0.181800940883612, 0.2499814001970585, -0.2189235487704594, -0.2941578702525302, -0.2613208334101781, 0.3443825148816139, -0.3086165449914435, -0.4000320253108334, -0.3595628891688978, 0.4594100673703709, -0.4116578643958037, -0.519368340488319, -0.4608838085460648, 0.5751583010135386, -0.5018561564823436, -0.6208288964715706, -0.2890646136834312, 1.547039886853192, -1.173755403489903, -0.7985207315322997, -0.2625825083083085, -0.321674668942854, -0.1352159819750655, -0.1999732725283456, -0.07366734029347159, -0.1440615953055945, -0.0338692953389332, -0.1147504606082463, -0.005029712242208511, -0.1000175433858401, 0.01695421717090311, -0.09456233266164106, 0.03415869939464086, -0.09556433616678824, 0.04784697925863496, -0.101446550453596, 0.05887259823103022, -0.1113844111571908, 0.06784319765312669, -0.1250437127185277, -0.07520036620749675, 0.1424161499432856, 0.08126890147440424, -0.1637146453439622, 0.08629375258215478, -0.189312804562382, 0.09046906112313131, 0.2197194565251569, -0.09395994411067805, 0.2555854707181692, 0.09691288686658349, 0.2977431307518454, 0.09945154948260918, -0.3472856237053809, -0.1016514559138057, -0.4057014604005721, -0.1034872918659082, 0.475092530300298, -0.1047384672449806, -0.5585328441816623, -0.1048045105961936, -0.6606855376279177, 0.1023541847811403, -7.645111917964669, -2.444190547643892, 3.259474730743878, -1.113400990501543, 0, 0, + 0, 0, 0, 0, 0, 504.7005483880675, -960.8563426765877, -455.6810385506663, -0.0006211890719464708, -0.02717449361052982, 0.002624545711740859, 0.03409357098285602, -0.005942159106883158, -0.04143715413018739, 0.01059135423887447, 0.04948858776950704, -0.0166413313054562, -0.05854418379382578, 0.0242148610679564, 0.06892421088657538, -0.03349146754772453, -0.0809841818387797, 0.04471193925388908, 0.09512623948475284, -0.05818359115254906, -0.1118100512572915, 0.07428496523273895, 0.1315618312735884, -0.09346828354041023, 0.1549790152282817, 0.1162558426750438, 0.1827256545244234, -0.1432240256832661, 0.2155105496963288, 0.1749650364632709, 0.254035038834301, -0.212010638405861, 0.2988909563929731, 0.2546958843850197, 0.3503831721602568, -0.3029377534844611, 0.4082512041088586, 0.3559113648605111, 0.471283605276577, -0.411645725224325, 0.5368790186329719, 0.4666463388955495, 0.6007202940611962, -0.5157903324539884, 0.6568675698020393, 0.5528415071271306, 0.3819646735423662, -1.398313345247025, 1.702130138980118, 0.5594893184855516, 0.4345731607149444, 0.2047273101100171, 0.2544540474780775, 0.1063741954770327, 0.1778805766776483, 0.05255231548952451, 0.137900569051342, 0.01589144268877343, 0.1168704015342846, -0.01147530402843068, 0.1075993573348887, -0.03281602394973369, 0.1063490908368691, -0.04987312975903418, 0.1109852985003045, -0.06374396058252166, 0.1203212709282059, -0.07519208505179932, 0.1337915946504525, -0.08477768059074928, -0.1512472309045833, 0.09292245189830053, 0.1728188948893017, -0.09995295179709891, 0.1988310587279109, -0.1061338258071349, 0.2297560668874317, 0.1116956612897333, -0.2662028365209533, 0.1168534044651449, 0.3089378582466848, 0.1218148638037771, 0.3589424141807773, -0.1267685950073432, -0.417514018459675, -0.1318530493084198, -0.4864325194506035, 0.1370935903164596, -0.5682256141066142, -0.1422822434012505, -0.666604844323565, -0.1467513256218947, 7.839832839255147, -2.591992660256728, 3.08252939024389, -1.472235565518307, 1.200611269528463, 0, 0, + 0, 0, 0, 0, 0, 0, -504.7015918274936, -960.8824172487933, 455.6786628322481, -0.0001386040108547678, 0.02825899575001721, 0.00148000990419925, -0.03396816329492456, -0.003913391729580158, 0.03999719012865367, 0.007442680878789934, -0.04659090322133554, -0.0121162968680667, 0.05400401596298283, 0.01802786748313866, -0.06251037884950617, -0.02531818062112227, 0.07241227284910066, 0.03417801432480141, -0.0840495440103118, -0.04485119411434383, 0.09780784101480898, 0.05763670862206309, -0.1141246897988619, 0.07288798740446953, 0.1334907230535002, 0.09100549877450563, -0.1564413552584702, 0.1124168465460749, 0.1835312438634551, 0.1375347555217266, -0.2152794341013849, 0.1666789233629258, 0.2520679325404323, 0.1999435400148238, -0.2939734797154126, 0.2369931492869313, 0.3405172515888476, 0.2767850762901711, -0.390345045347925, 0.3172634202969561, 0.4409132592457857, 0.3551552329611432, -0.4883580204443008, 0.3861049626417496, 0.5278024954606876, 0.221653617736939, -1.310709133012781, 0.8704550092422116, 0.7079030635461785, 0.1843303003648327, 0.289142189894577, 0.0890031466634482, 0.183755046796533, 0.04093279509465775, 0.1369845466667406, 0.008027106857080303, 0.1140671851302532, -0.01733485053642101, 0.104231064513174, -0.03796088669959809, 0.1026821086919593, -0.05525696194664861, 0.1068620954451136, -0.07011029660696497, 0.115354075966287, -0.08317464933480107, 0.1274397517866654, -0.09497453954477812, 0.1428557674294213, 0.1059485191998991, -0.1616373931580192, -0.116473125434708, 0.184018627644066, -0.1268840153469689, 0.2103748991036934, -0.1374978332735491, -0.2412002758106563, 0.1486321821340762, -0.2771135831612571, -0.1606234825346388, -0.318894700017657, -0.173836022567292, 0.3675540114045308, 0.1886613027997724, 0.4244484685316806, 0.2055082541208365, -0.4914687718702396, 0.224768184994539, 0.571342364466508, 0.246749172743278, 7.942734281408671, -2.790996821413193, -3.416416824440133, 1.502698673759963, -2.74025012280437, 0.4374074524376139, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 504.7014268866499, -960.9091609078547, -455.6702009059838, -0.0004715858695197065, -0.03982840046737102, 0.00242224023844466, 0.04693804869973257, -0.005712413463266942, -0.05453060690126599, 0.01036142963375495, 0.06291484964449161, -0.0164440331698878, -0.07241520054585564, 0.02409153161862073, 0.08338313108173702, -0.03349426180113407, -0.09620848027332857, 0.04490493324477595, 0.1113301550654768, -0.0586415214773373, -0.1292450786759426, 0.07508828443695986, -0.150513154673022, -0.09469143119899404, -0.1757538991751067, 0.1179438613939318, -0.2056275754842778, -0.1453500537954308, -0.2407890904812533, 0.1773573065390127, -0.2817971004678554, -0.2142337181273538, -0.3289552292807281, 0.255870859960439, -0.3820621733814443, -0.3014962025572454, -0.4400643963200938, 0.34931588173307, -0.5006585522123436, -0.3961850233060456, -0.5599910362173445, 0.4375268333475068, -0.612726531008857, -0.4678122672345172, -0.3569120201451431, 1.18831598199679, -1.617583791352987, -0.4321697836882517, -0.4219085060089673, -0.1510420456331972, -0.25146678538168, -0.07059891849129137, -0.1807609333405698, -0.0240329511553917, -0.1456531311906457, 0.009769195529775603, -0.1290384618111746, 0.03669700570302369, -0.1238682627899927, 0.05912761689067447, -0.1264561589974369, 0.07833483431516959, -0.1347055607275304, 0.0951733797931347, -0.1474724563406544, 0.1103088335611947, -0.1642393157936116, 0.1242996284536155, 0.1849045503710836, -0.1376315559768252, -0.2096404850603622, 0.150739321415534, -0.2388041370692126, 0.1640310219820809, -0.2728910081209138, -0.1779123181778702, 0.3125232856726328, -0.1928113592711771, -0.3584705110456833, -0.2091969136508766, -0.4117030466307595, 0.2275912605111247, 0.4734858653437208, 0.2485748286117511, 0.5455291692123926, -0.272779071272836, 0.6302263498990262, 0.3008643534306304, 8.20707478604357, 2.932590880343228, 3.566301858755951, 1.591737361864661, -2.080954844450352, 1.063336818518452, -0.312693340165919, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -504.7034311398602, -960.9369925632403, 455.6692107057009, 0.0004356100354586218, 0.03860199096161918, 0.0003618838493967148, -0.04386380370370079, -0.002169347414784144, 0.04942525667989209, 0.004982545942080307, -0.05553497828831112, -0.008840601544025953, 0.0624511939178053, 0.01382568492204521, -0.07045040500021758, -0.0200635944222586, 0.07983573655308961, 0.02772464186081651, -0.09094444742633617, -0.03702388344715066, 0.1041536259789221, -0.04821924316984402, -0.1198819820124656, -0.06160445551722481, 0.1385840425022496, -0.07749220106038934, -0.1607306169402915, -0.09617998733441638, 0.1867658703825194, -0.1178877608692904, -0.2170271396260865, -0.1426531229291118, 0.2516110942742074, -0.1701709400072701, -0.2901735669785757, -0.1995766655123539, 0.33167198231666, -0.2292104536632618, -0.3741087211620817, -0.2564669531327498, 0.4144141160994378, -0.2779196790709351, -0.4486695658607398, -0.1585148155348832, 1.108326036371431, -0.5816638331406274, -0.6376460733569355, -0.1083863705122823, -0.2651532591988918, -0.04346268036180279, -0.1731791135747381, -0.007919955521890586, -0.1343419559206488, 0.01884997316493552, -0.1172998435413015, 0.04139686964273688, -0.1122109969614702, 0.0612644512371045, -0.1146390321312077, 0.07920415164364861, -0.1222036115318655, 0.09574062739795554, -0.1335955000566879, 0.111342587990221, -0.1481684801491999, 0.1264688165440626, -0.1657058794392267, -0.1415730034357649, 0.1862665137934408, 0.1571022793772566, -0.2100850895889454, 0.1735027646062021, -0.2375159098214737, 0.1912338107828908, 0.2690093363603886, -0.2107891668533592, 0.305116325619871, 0.232719244011093, 0.3465174314368482, 0.2576565915212616, -0.3940792105482042, -0.2863453006006712, -0.4489464059320039, -0.3196699442525448, 0.5126872859904976, -0.3587010976918096, -8.28272768639917, -3.069060360130142, 3.927691039870548, 1.671176660764354, 2.407455234884137, -0.8625377998571393, 2.482297646744782, 0.1292734700574192, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7028824420881, -960.9653940857651, -455.6573959835257, -0.0001045342927213557, -0.05510952876884354, 0.001813256542621175, 0.06227481799574789, -0.004858797016936023, -0.07000242917077827, 0.009264808465575517, 0.07862878594870333, -0.01511232203008351, -0.08850890488940624, 0.02254001315406766, 0.1000277135969499, -0.03174536747972971, -0.1136106715000355, 0.04298556623718725, 0.1297326922178386, -0.05657684359155325, 0.1489234556474868, 0.07288927434017092, 0.1717652930940824, -0.09233189928394896, 0.198877283105147, 0.1153205669594968, 0.2308750852817715, -0.1422162239454809, 0.2682908269428334, 0.1732165788221063, 0.3114322670825245, -0.2081820549922315, 0.3601601689508011, 0.2463834229879688, 0.4135774742746823, -0.2861906631817055, 0.4696707079443848, 0.3247907144321164, 0.5250325498506966, -0.3581320852927125, 0.5749043514816392, 0.3813740651756898, 0.33559864255759, -0.975267052557106, 1.553286395488471, 0.2975654526534304, 0.4156488593431335, 0.09371170961137179, 0.2528219529681863, 0.0318602025876451, 0.1873286487076531, -0.007406320889202832, 0.1569749836318507, -0.03858434309919215, 0.144934740453739, -0.06545817090963257, 0.1441815831728718, -0.08945270328381889, 0.1510120365349771, -0.1113416651259841, 0.1633234601502849, -0.1317257394447766, 0.1799857228617523, -0.1511744615193794, 0.2005086220062386, -0.170257066128721, -0.2248204324462682, 0.1895400302751218, 0.2531160063974417, -0.2095887459424748, 0.2857621049048731, -0.2309786288335811, 0.3232475487327383, 0.2543197035673892, -0.3661698670568465, 0.2802839275652471, 0.4152519125737978, 0.3096388181156818, 0.4713879968706516, -0.3432857433502883, -0.5357238487236324, -0.3823039298241136, -0.6097820756813976, 0.4280142297040914, -8.593418202744859, -3.211955544343986, 4.01550610066904, -1.769542946482932, -2.385993943945727, -0.9351886806923488, 1.364050528322037, -0.9080040622263671, -0.4464199288967212, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7061722826078, -960.9950980825289, 455.6584934644936, 0.001353924213319257, 0.05069804235078336, -0.001403478172758728, -0.05531669887499667, 0.0005546746219488723, 0.0602176601279568, 0.001178736969878009, -0.06565366943648464, -0.003823298510146261, 0.07188614605884883, 0.007444087396122985, -0.07919288756514294, -0.0121433251462564, 0.08787498194637582, 0.01805863608944551, -0.09826218797222715, 0.02535989650826906, 0.1107152897665785, 0.0342421634090001, -0.1256225901932514, 0.04491137284146533, 0.1433858203414038, 0.05755711615621574, -0.1643879418622154, 0.07230425516591216, 0.1889319980546444, 0.08913300093328734, -0.2171379771443038, 0.107757891711349, 0.2487872536298442, 0.1274663214539597, -0.2831201330658301, 0.1469465463422727, 0.3186294299533511, 0.1641875797212851, -0.3529538909796769, 0.1765977012156841, 0.3830228392206152, 0.09923300750079445, -0.9387659102980379, 0.305398543764229, 0.5874526002501284, 0.03421711551743981, 0.2496160794636069, -0.00172104942964322, 0.1682097394146368, -0.02558725561576955, 0.1361268344344931, -0.04691707458719761, 0.1244564737090883, -0.06726669000070251, 0.1239690575086415, -0.08693811269512493, 0.1304369530627798, -0.1060389333362548, 0.141571663489697, -0.1247414524221453, 0.1561163886904096, -0.1433423840955047, 0.1734586694197238, -0.1622500485292275, 0.1933984716847243, 0.1819498382764446, -0.2159900192240643, -0.2029763815613684, 0.2414387822339389, -0.2259034630808185, 0.2700417931160715, -0.2513516107580024, -0.3021617326012637, 0.280007600114253, -0.3382255019637882, -0.3126552129313027, -0.3787429608129044, -0.3502182255490416, 0.4243439334152545, 0.3938138954989248, 0.4758372286628779, 0.4448387377462819, -8.646476556307604, 3.287657641880755, -4.395262558384979, 1.792030252359884, -2.73372973571881, -0.9241141660969929, -1.712422595404809, 0.4359874306747898, -2.432174107259886, -0.6397052114818167, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7050978056665, -961.0251353455429, -455.6426293119019, 0.0005789714464947707, -0.07319751886662666, 0.0006207879061930474, 0.0802799735867732, -0.003129094635399184, -0.08803596071851463, 0.006975460706357075, 0.09683290373786249, -0.01224653915288706, -0.1070596332625383, 0.01908491954449565, 0.1191369742779648, -0.02768776308106317, -0.1335267149602703, 0.03830435886062355, -0.1507372943186485, -0.05122967843956672, -0.1713229356970986, 0.06678971375544743, -0.1958705963395601, -0.08531182846472353, -0.2249654793739225, 0.107069570838405, -0.2591211079527574, -0.1321872027422623, -0.2986553751625171, 0.160487669363109, -0.3434934131000018, -0.191273923827569, -0.3928906485362413, 0.2230621626353611, -0.4451099722739455, -0.2533460049820092, -0.4971642549076689, 0.2785681040388742, -0.5448315365001141, -0.2945449187820606, -0.3188523354151554, 0.7617168830174238, -1.512960882421318, -0.1565418889317566, -0.416770638188017, -0.0330371554958069, -0.2590939561072727, 0.009692898702806391, -0.1979815715767451, 0.04169344337350171, -0.1721638220045798, 0.07052530713197516, -0.1647923498418741, 0.09775169543831891, -0.1687258056803347, 0.1237881291548195, -0.1801639057873346, 0.1488794308490554, -0.1969463086568264, 0.1733613896964222, -0.2179209500175104, 0.1977104526182695, -0.242597178003689, 0.2225166824607487, 0.2709069147142353, -0.2484447312925564, -0.303039084913382, 0.2762089619529779, -0.3393348213625563, 0.3065757332901756, -0.3802323858876161, -0.3403810643090954, 0.4262480705852916, -0.3785664996638002, -0.4779857272391611, -0.4222285054438267, -0.5361702328195965, 0.4726795168378314, 0.6017042384742251, 0.5315431534297506, 8.988404257252103, -3.434234591407497, -4.436704087040918, 1.904958600463788, -2.667252960757383, 1.019315404694702, 1.553413773220462, 0.5240360258904643, -0.8521059937283484, 0.9531203463970385, 1.133055091391562, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7100346863414, -961.0567364446957, 455.646613143601, 0.002722295284934282, 0.06461681973477371, -0.004007947943993217, -0.0683635324772939, 0.004536694220093283, 0.07238640000970466, -0.00433430930478059, -0.07694262150014541, 0.003392025878594218, 0.08229618144787393, -0.001670278858418917, -0.0887242115986121, -0.0008975016974408089, 0.09652212032887546, -0.004400201670914741, -0.1060064440564509, -0.008941741499294128, 0.1175134358385135, -0.01462879396175798, -0.1313898772830384, -0.02154950721841662, 0.1479705007616418, -0.02973757948750487, -0.1675338272440166, -0.03911447566452358, 0.1902263373250469, -0.0494038851796016, -0.2159464070642364, -0.06002011198536771, 0.24419037399957, -0.06995441855483667, -0.2738896861740276, -0.0777218007125729, 0.3033115380943844, -0.08147776924470845, -0.3301302888852998, -0.04342138832490353, 0.800108427299287, -0.04000732313755277, -0.5563775145367175, 0.03855669146460623, -0.2421457122014047, 0.04673467675853111, -0.1685947713495393, 0.05966925766215405, -0.1421356546813504, 0.07617060670611064, -0.1353431117620796, 0.09486340695112068, -0.1392947724748802, 0.1148236878882152, -0.1498272473624081, 0.1355229389653643, -0.1646584030588876, 0.1567892967260354, -0.1825265390991063, 0.1787580887629875, -0.2028097674378218, 0.2017993595211208, -0.2252868325806165, -0.2264439082886397, 0.2499694264649327, 0.2533278498840449, -0.2769901080244833, 0.2831665936584349, -0.3065367197788879, 0.31675352352134, 0.3388193022269569, -0.354979335807952, 0.3740594600432878, 0.3988728455325729, 0.412493048200239, 0.4496557166350698, -0.454379410749675, -0.5088325604398763, -9.020420590072227, -3.450565579378631, -4.828910565671182, -1.874110745373426, 3.031455262150587, -0.9554280057985601, 1.918824600147808, 0.4370410894016331, 1.245159522031377, -0.1566307455549422, 2.552719012229264, 1.137055157228564, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7083084832581, -961.088403701372, -455.6259949644748, 0.001693462288155773, -0.09425609907144253, -0.00135812958186467, 0.1011210298209119, -0.0002358251806337989, -0.1088168511442754, 0.003123702470935177, 0.117746189310862, -0.007394509226016558, -0.1283352037931964, 0.01318721808082886, 0.1410426164823464, -0.02068614552863905, 0.1563657899240353, 0.03011316521908753, 0.1748410515523016, -0.04171287552624901, 0.1970333700401475, 0.05572504926140202, 0.2235071819563995, -0.07233534673786346, 0.2547659637536581, 0.09159167502337025, 0.2911438853529135, -0.1132728046470395, 0.3326320892944551, 0.1367013692972142, 0.3786326012788764, -0.1605193483772494, 0.4276675386247564, 0.1824972953091496, 0.4771381978993297, -0.199534230207109, 0.5233118023773972, 0.2080647751939719, 0.3071312523515405, -0.549473955438997, 1.498520087318462, 0.00989782058163087, 0.4257392836989572, -0.03066419348029967, 0.27053141082994, -0.05385429393158369, 0.2128586455021746, -0.07865838364579553, 0.1912804624944068, -0.1054218514397032, 0.1886052588272439, -0.1333817841205637, 0.1974301330414755, -0.1618922650232225, 0.2137720478898956, -0.1906429188221663, 0.2353555123291881, -0.2196953036046989, 0.2609640871623732, -0.2494334138871651, 0.2900702342300163, -0.2804781709204113, -0.3225735541543351, 0.3136051709871521, 0.3586152379559984, -0.3496963324210602, 0.3984605855948943, -0.3897237334354889, 0.442433754373803, 0.4347674252373997, -0.4908899809534614, 0.48605633051341, 0.5442128827277137, 0.5450303291374311, 0.6028273664098085, -0.6134359722665157, -9.383238747186924, -3.600916739919184, 4.832694315608912, 2.003470413821713, 2.931212798765991, -1.076233974356122, 1.727556840630514, -0.5584158153153711, -0.9677000168663793, -0.2850220760337975, 0.4848137226350174, -1.162124180800043, -1.793676268616248, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7153141286621, -961.1217498954065, 455.6338248564796, 0.004666236513345801, 0.08033835876549655, -0.007676437270062325, -0.08295141844108442, 0.01009977011228604, 0.0858558666115623, -0.01197879976722524, -0.08931330796488612, 0.01333079539699938, 0.09358896098647876, -0.01415383176294858, -0.09895648285762505, -0.0144330727549111, 0.1057012528087135, -0.01414858625643324, -0.114120817737291, -0.01328610322696056, 0.1245201008433383, -0.01185312169985896, -0.1371974259500803, -0.009903932278386084, 0.1524155095853953, -0.007577483035196663, -0.170349858019879, -0.005151094173442019, 0.1910076219888127, -0.003106911843602696, -0.2141162385930753, -0.00219223603220216, 0.2389982098664602, -0.003428653267689329, -0.2644761408819428, -0.007993135284190185, 0.2888757583999775, -0.009238357725273051, -0.689494763421366, -0.2155878440195048, 0.5426652421405607, -0.1100760809768825, 0.2419872852187903, -0.0915757211308498, 0.1738068042043262, -0.09421490159299305, 0.1519131253021238, -0.1063902295366557, 0.1495062851706462, -0.1238496488930524, 0.1576921868225562, -0.144457445676418, 0.1722377145797942, -0.1670559652778887, 0.1907853469363053, -0.1911367180744256, 0.2120098595295308, -0.2166813899045869, 0.2352309624985876, -0.2440312262325445, 0.2601594028118362, 0.2737719046620724, -0.2867127897537385, -0.3066513544997664, 0.3148910096033804, -0.3435341329051073, 0.3446994182012239, -0.3853912741508331, -0.3761050372799959, 0.4333221867749439, -0.4090113357290798, -0.4885956544839816, -0.4432370036767068, -0.5527297958804152, 9.393725843325772, 3.559142669539414, -5.233438534663443, 1.922140772052916, 3.30916008332548, 0.9639922588619462, -2.108426983838054, 0.4210596150978028, -1.37488546401417, -0.126172291118237, -0.9417910946035264, -0.02489482226941209, -2.820413837240554, -1.65719959391188, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.712822627705, -961.1549732256356, -455.6077127096619, 0.003370363513768094, -0.1184233948149237, -0.004352589134933815, 0.1249488727742578, 0.004142598150015885, -0.1325266147065525, -0.002702309633903203, 0.1415989061506627, -5.193242257853952e-05, -0.1526322638582052, 0.004242516041704322, -0.1661238420831387, -0.01002108162905441, -0.1826028877145596, 0.01755321339895132, -0.2026229299653129, -0.02699257791731359, -0.2267375503327169, 0.03843678368101805, -0.2554486834745714, -0.05185463742576753, -0.2891125143344822, 0.06697380838544749, -0.3277869557881715, -0.08312340296797521, -0.3710132247776353, 0.09904931306822057, -0.4175532297672665, -0.1127668418736266, -0.4651618147564519, 0.121590215262521, -0.510544244533257, -0.1225288992181756, -0.3005345609258526, 0.3399230830669571, -1.510041866246306, 0.1414029629131923, -0.4424813889986434, 0.0969566625439009, -0.287030472441386, 0.1002877273344002, -0.2318097264729576, 0.1179696537132148, -0.2141130560573038, 0.1428989401173152, -0.216085496212976, 0.1718969363526398, -0.2299160646037506, 0.2032113426057577, -0.2513516264549205, 0.2359542056548815, -0.2779404049836417, 0.269903604489502, -0.3083522861668259, 0.3053525231567537, -0.3419775604673035, 0.3429586234253998, 0.3786342689363086, -0.3836208986559502, -0.4183589706424067, 0.4283986271914125, -0.4612706968478629, 0.4784824630112978, -0.5074923782141396, -0.5352066248608507, 0.5571092548388775, -0.6000923998546913, -0.6101471292691906, -0.6749305319888952, -9.770051112346868, 3.712532157622387, -5.204107151313059, 2.068330691047585, -3.18125125479366, -1.111446716858055, -1.892155190902516, 0.5769109527951105, -1.074175671579627, 0.2964457689798568, 0.5539281293589068, 0.1648327863802309, -0.2172096485697859, 1.512241614146546, 2.467635656276092, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7224116592663, -961.1902571610938, 455.6205915183505, 0.007332560323131098, 0.09772650675515225, -0.01266681647409895, -0.09890946144936448, 0.01761061930967164, 0.1004319663138764, -0.02223151529100917, -0.1025589734040736, 0.02658527800478494, 0.1055543905435332, 0.0307240137177325, -0.1096846360720932, 0.03470480005138991, 0.1152206928700177, 0.03859926962869588, -0.1224372229859417, 0.04250540794695284, 0.1316063042861069, 0.04656276217394649, -0.1429819416890049, 0.05097254854312608, 0.156770043109164, 0.05602256159687267, -0.1730781884191307, 0.06211263471333318, 0.1918417495221531, 0.06976604123079083, -0.212731221653107, 0.07959687794489242, 0.2350594264866488, 0.09218568189114314, -0.2577207095948243, 0.05895216380708893, 0.6030344606072978, 0.4616425346359402, -0.5436208097610066, 0.1801615878388285, -0.2479542818639472, 0.1359942495801694, -0.1829951211861444, 0.1288696776689487, -0.1647070482516714, 0.1370851711017615, -0.166186009742888, 0.1535729004651733, -0.1783286433187104, 0.175004017949945, -0.1967160001753221, 0.1996016370756137, -0.2188405755084354, 0.2265274150255044, -0.2432545072656078, 0.255616995167631, -0.2691644778819984, 0.287188623645841, -0.296154558573445, -0.3218894031796202, 0.3239813218519342, 0.3605820289961011, -0.3524309991867358, 0.404281451485633, -0.3812277505186181, 0.4541373257413515, 0.4099740685595717, -0.5114462459203447, 0.4381037210394499, 0.5777085075240355, 9.757187794715053, 3.613965379149533, 5.610766740550909, -1.938835199033022, 3.571436149045066, -0.9542168243229318, -2.288013661621963, -0.3938480967566447, 1.496351683252224, -0.08808345484880223, 1.023046330373567, -0.06957848752644458, 0.7559950874575174, 0.1446377341673701, 3.223159785518482, 2.231109599751307, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7190540960186, -961.2250192748934, -455.588180522695, 0.005760119451667827, -0.1458018459472323, -0.008617871967446157, 0.1518886251707371, 0.01036045836723483, -0.1593339434673855, -0.01095512117368798, 0.168623432319206, 0.01033715383235535, 0.1802652315855236, -0.008421308021689847, 0.194792393053006, 0.005117854913200912, 0.2127573865763628, -0.0003573018673901766, 0.2347123846839292, -0.005870115341541783, 0.2611655306170398, 0.0134514921104915, 0.2924997329898752, -0.02205646148738518, 0.3288391697120372, 0.03100724814840945, 0.3698554289066493, -0.0391314172858762, 0.4145293741812473, 0.04465629171074397, 0.4609333830920124, -0.04526915247447261, 0.5061591284697164, 0.03850943070266388, 0.2988211434046964, -0.1343140034874617, 1.545791848932921, -0.2960335360025335, 0.4663736910206594, -0.1651993031618597, 0.3081206807361616, -0.148466528783414, 0.2543776892222589, -0.1590822972569348, 0.2401547949000193, -0.1823264347853362, 0.2466363598796981, -0.2125374666877397, 0.2654664586167893, -0.2468230014420065, 0.2920378799634734, -0.28369945780944, 0.3236595023368128, -0.3226554917179421, 0.3588325700155615, -0.3638932634463122, 0.3968084947760234, -0.4081139430426112, -0.4372603761207967, 0.4563448325195634, 0.4800432615153861, -0.5098306130089106, 0.5250360251830816, -0.5699872792909377, 0.5720443097383854, 0.6384042472680606, -0.620739093955173, 0.7168958955657478, 10.1416026925784, 3.769624166608563, -5.550197612007544, -2.101714625470462, 3.418765229089471, -1.128530918815057, 2.05030202920546, 0.5843666730352316, 1.176141611311618, -0.2998770983489928, 0.6178281648963292, -0.1687738124565776, -0.2572515070648175, -0.1256951327451982, 0.01616907141314794, -1.992214070149926, -3.189662381847132, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7318794445075, -961.2622111936237, 455.6076615218215, 0.01089221138384335, 0.1164944818989575, -0.01927027124317406, -0.1159105114196266, 0.02747804138380453, 0.1157590237274542, -0.03562101111504409, -0.1163053571198556, -0.04381054622555893, 0.11780798689624, -0.05217348627038508, -0.1205218765117039, -0.06086108892227842, 0.1247010612781868, -0.07005691264492792, -0.1305992812196758, -0.07998336769309033, 0.1384666763445831, -0.09090568207321333, -0.148539099266325, -0.103130632313689, 0.1610155426830076, -0.1169945067947107, -0.1760175642549749, -0.1328292092990493, 0.1935251760227961, -0.1508900371219247, -0.2132847544560474, -0.1712230826203191, 0.2346889242553419, -0.1057755931109957, -0.5357642487146973, -0.6973878233988416, 0.5555297188556486, -0.2482482426823123, 0.2583893820691848, -0.1794481217099651, 0.1949556011152848, -0.1629964039187765, 0.1794404990383949, -0.167454966242039, 0.1842879058626768, -0.1830230404376604, 0.2000060175644817, -0.205209645685749, 0.2218995693363221, -0.2316338998877495, 0.2472470804664445, -0.2611383861136601, 0.2744206707423583, -0.2934188634283356, 0.3024520161486941, -0.3287766158418658, 0.330727168992488, 0.3679203274465594, -0.3587549762608285, -0.4118259797084023, 0.3860024176740223, -0.4616568968449378, 0.4117833750068759, -0.5187284681093876, -0.4351768010753159, 0.5845252467597436, -10.10272037837622, -3.615759296992346, 5.961002309639331, -1.925982279272278, -3.820398085376841, 0.9288290974303622, -2.461282861258473, 0.3588964134966156, 1.614524108256882, 0.04643312460190491, -1.101929869918408, -0.1156934037864506, -0.8069532966049089, 0.1939414294536783, -0.6549974120119686, -0.2285123742746999, -3.758505654153285, -2.887002774786242, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7275737129024, -961.2986900862034, -455.5680475291849, 0.00903586301318594, -0.1764481378529507, -0.01443633323006236, 0.1820293926317921, 0.01880447073763833, -0.1893830763324559, -0.02212739922183875, -0.1990394755651686, 0.02438113653662378, -0.2115459961113778, -0.02554785138683405, -0.2274636911241468, 0.02563963642219436, -0.2473516518290995, -0.02473404186599173, -0.271730510328668, 0.02302808689174882, -0.3010128812352733, -0.02091691897707183, -0.3353869095894007, 0.01909834439431709, -0.3746441757811209, -0.01868481784601551, -0.4179627386782013, 0.02126895992019769, -0.4636967305855159, -0.02883173464380446, -0.5092745443586736, 0.04334833925615389, -0.3014407655914791, -0.06601281923988526, -1.602324544766366, 0.4521688717502506, -0.4962602535568542, 0.2344899085974771, -0.3329721059649142, 0.1976354384687227, -0.2798012120081235, 0.201207847611257, -0.2686044483634154, 0.2227918565877333, -0.2793525517309335, 0.254208949035389, -0.3030265762539144, 0.2914075927648672, -0.3345889425740216, 0.3323002062548046, -0.3710472412454519, 0.376082825113517, -0.410672419727643, 0.4228703215020564, -0.4525090987053563, 0.4734101217025521, 0.4960038585709059, -0.5288630443220137, -0.5407310407243179, 0.5906642373893218, -0.5862073308755801, 0.6604544266659836, -0.631770882164199, -0.7400800113225439, 10.4912498465414, -3.773373232627433, 5.869292321428817, -2.105388476297262, 3.643747899009217, 1.129947070197685, -2.20333116034871, 0.5839586073720042, -1.276059903111896, -0.299240532723705, -0.6800685739125477, 0.1698588504724025, -0.2942327379600606, 0.1304150900865758, 0.03800351903695634, 0.1417197104665032, 0.1425294782604167, 2.600515797914067, 3.992077820801224, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7444899137037, -961.3378869284877, 455.5961766575729, 0.01554496586389417, 0.1361607262454429, -0.02781289414814694, -0.1334206115553933, 0.04015195437573545, 0.1312610252962056, 0.0527238328643537, -0.1299420806015547, 0.06571735393480846, 0.1297113267134137, 0.07935679284872428, -0.1308093221619015, 0.09390646392500906, 0.1334765342836597, 0.1096692934744826, -0.137961097981063, 0.1269759901739711, 0.1445257840878497, 0.1461596796124059, -0.1534505818065084, 0.1675090650339144, 0.1650223724407157, 0.1911922811662067, -0.1794965959880791, 0.2171469054347325, 0.1970054498924576, 0.2449372580636083, -0.2173831194355537, 0.1495893184212565, 0.4816785595258409, 0.9209202815588715, -0.5736517097497067, 0.313353604698171, -0.2711605588560934, 0.221082155663423, -0.2081281229339226, 0.195658000237407, -0.1947111978907778, 0.1963739070246782, -0.2023853087811128, 0.2108169700402979, -0.2211665513822386, 0.2333844452691181, -0.2460259436412557, 0.2611196517524419, -0.2739795084733933, 0.2925613936013013, -0.3031638285603235, 0.3272759615201772, -0.3323671520526524, 0.3655494198939995, -0.3606901700963588, -0.4081518881755232, 0.3872850919084128, 0.4561704112264385, -0.411165351471291, 0.5109046669029912, -0.4310695720851319, 0.5738286008172455, 10.42318783741847, -3.566018330179493, -6.283039963892671, 1.885086978417805, -4.056461148196111, 0.8896096623583637, 2.629879524658232, -0.3183134586090979, 1.732009409551348, -0.003597002249112677, -1.181752365540581, 0.1607426656367353, 0.8594318003331071, 0.2409887971627989, 0.6872601018528763, -0.2776927275225095, 0.6162945944580821, 0.2949229569475111, 4.432330830999809, 3.652258417704127, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7391854477888, -961.3761134831929, -455.5483160115629, 0.01339975427289111, -0.2103617083669475, -0.02212129334677451, 0.2154107935057459, 0.02989586468758025, 0.2227762054914026, -0.03675410570225757, 0.233029559420389, 0.04274488714190522, 0.2467489261215965, -0.04795860482498126, 0.2645069025107166, 0.05255917574259697, 0.2868406962417143, -0.05682989248602897, 0.3141931378633969, 0.06123725611583161, 0.3468116005115335, -0.06651167350925496, 0.3845953195758418, 0.07372631291715646, 0.4268969633578305, -0.084324035113474, 0.472317693749994, 0.09999329127000312, 0.5185766012306021, -0.122267111761034, 0.3075794130567557, 0.2594922311530679, 1.674677840688869, -0.6074411217165189, 0.530504621157434, -0.3036489093269464, 0.3604292259290603, -0.2468040165898022, 0.3070437102038547, -0.2433124059830945, 0.2983965063767964, -0.2631034380950553, 0.3130548980457453, -0.2954872738506904, 0.3412458946213262, -0.3352576648480358, 0.3774381296472452, -0.3797257621045876, 0.4182777341843855, -0.4278008133993835, 0.4617385983648974, -0.4795135491180799, 0.5065767007844517, -0.5356633184142464, -0.5519108635118929, 0.5975519447496171, 0.5969093166328796, -0.6668064787959627, 0.6405721802139768, -0.7452989581305071, 10.81295073151522, 3.725997667527157, 6.159022350342218, 2.081113170768998, -3.855102702242159, 1.117501368797665, -2.351235823926313, -0.5777697467504209, 1.374856223267653, -0.29701181947491, 0.7424138377886643, 0.1710585953742098, 0.330797445008233, -0.1353650627227564, 0.0576408564358677, -0.1510793503432264, 0.1322861784530395, -0.1959399824468592, -0.2765948893642101, -3.344039432155814, -4.906745836243842, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7613365642291, -961.4178098908683, 455.5878220684487, 0.02152739456950745, 0.155990589845504, -0.03865954626620611, -0.1506307363154621, -0.05612307601046214, 0.1460612037459447, -0.07415968563775244, -0.1425284489543925, -0.09305949879988605, 0.1402637839647557, -0.1131625092824421, -0.1394959528064121, -0.1348497243264618, 0.1404692206213771, -0.1585184900258227, -0.1434668149614358, -0.1845343498098827, 0.1488370709744961, -0.2131515106483328, -0.1570114703269528, -0.2443967819326662, 0.168490761061717, -0.2779233867878602, -0.1837542375722553, -0.3128574421494117, 0.203035425587468, -0.1900946734061147, -0.433834219025143, -1.129221067589957, 0.5923000478378968, -0.3740906900280064, 0.2836979264745814, -0.2597387711190001, 0.22062681445908, -0.2256295048723918, 0.2088235792854549, -0.2224048277552317, 0.2187578425407568, -0.2352143633671168, 0.2399405360599269, -0.2574227677607072, 0.2669932721109848, -0.2855421185023375, 0.2966388173566911, -0.317835119944384, 0.3267272928345747, -0.3537499822930283, 0.35572663703428, -0.3935627878927179, 0.382347718395156, 0.4381069694359088, -0.4052516396076142, -0.4885743991703206, 0.4228306365409398, -0.546400243704626, 10.7123505563827, -3.467401368528632, 6.574905698665654, 1.817773117729432, 4.278777619641925, -0.8378218541754415, 2.793944829112401, -0.2733177456826802, -1.849759245051467, -0.03915110965119177, -1.264069361132026, -0.2034284048409766, 0.9153371450385213, -0.2846049852576992, -0.7235404151249138, -0.3227953515570327, -0.637237958096172, 0.342187055210012, -0.6250483028853673, -0.3568764257507016, -5.257937304882959, -4.55508554936837, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7550364030109, -961.4583496977284, -455.530480379083, 0.0190938476296795, -0.2474730170941161, -0.0320248394429458, -0.2520068723070391, 0.04409746139951185, -0.2595497997911581, -0.05542064500866747, -0.2707037328264438, 0.06615890175647458, -0.2860590669957729, -0.07656112549161879, -0.3061707763092542, 0.08699898599850459, -0.3315091701035143, -0.09801668999733169, -0.3623728933478695, 0.1103893488200521, -0.3987539286431652, -0.1251703436227577, -0.4401558607610471, 0.1436810276293193, -0.4853934971597049, -0.1673540627022936, -0.5324352881075169, 0.1973214093273239, -0.3162259135719306, -0.4443061610633235, -1.756700779373999, 0.7590020979393318, -0.5670900504193579, 0.3712553167121694, -0.3890806275027168, 0.2947777467691565, -0.3348571513627888, 0.2841510646953452, -0.3282692231155715, 0.3018275022954646, -0.3463689030326972, 0.3346649164831056, -0.3785725697111055, 0.3763313412808598, -0.418806990424517, 0.4235591970882376, -0.4633012783675338, 0.4749833840580253, -0.5096588677124098, 0.5305616262560031, -0.5562508167799632, 0.5911571677427112, 0.6017445089562359, -0.658220168495264, -0.6447469122637461, 0.7335866606257689, -11.10138605254825, 3.631034314442978, 6.416520283055733, -2.030929045438653, -4.050883210517207, -1.09263234274095, 2.492947931639272, -0.5671254785083639, 1.472262538497965, 0.294648565121288, -0.8053212026371659, 0.1740959578194711, -0.3680979667177443, -0.1426477808213935, -0.07701400313898601, 0.1623356308255878, 0.1242639559307309, 0.2112653724844634, -0.2740335801422096, 0.2779853011318764, 0.3991136330708569, 4.237178417243852, 5.966755879689668, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.7839768955486, -961.5031356303735, 455.5850306639925, 0.02912480258648458, 0.1749203040042703, 0.05222060442792607, -0.1663669930730279, 0.07592414985531605, 0.1588763076469116, 0.1005831663097198, -0.1526711551376601, 0.1266078291343768, 0.1479660097637017, 0.1544547454180628, -0.1449948514511539, 0.1845887043750316, 0.1440505633533104, 0.2174126453759208, -0.1455339392818743, 0.253156701007274, 0.1499995768662069, 0.2917237939532877, -0.1581666783968385, 0.3325088566360749, 0.1708317017743966, 0.3742344872602825, -0.188600178511197, 0.2268316604370843, 0.3845480392234077, 1.318322244561246, -0.6050237732153305, 0.428731430577431, -0.2930800029727587, 0.2940064673796119, -0.2303095703759141, 0.2514426080702059, -0.2198597838188783, 0.2438453429385534, -0.2314722939759387, 0.2541700231595779, -0.2542443363261532, 0.2748630106477523, -0.2824784951384094, 0.3019732811307502, -0.3125960540799213, 0.3335263049897976, -0.342113632573852, 0.3688741680327827, -0.3690936466192343, 0.4082952782635644, -0.3917330876661867, -0.4526883946043698, 0.4080384200378837, 0.5033598302349126, -10.96490758246675, 3.324010782640217, 6.833995337770606, 1.726068427677496, -4.485538946284208, -0.7744900179888866, -2.952462441243869, 0.2245238076687357, -1.96746806450077, -0.08132430877219025, 1.349148411398959, 0.2433017034817874, 0.9753204169954288, 0.3244179414574758, -0.7646022741758332, 0.3636921476151955, 0.6637918690093022, 0.3848718174085247, 0.6393750651856561, -0.402120829041611, 0.672076261839223, 0.4236321878220717, 6.255464776858338, 5.625936364814542, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.7767711685316, -961.5466022439307, -455.5167169920276, 0.02641646045759053, 0.2876293875521561, -0.04455269836068995, 0.2917046426611087, 0.06192864199017718, 0.2996413203859867, -0.07877768540105098, 0.3120491459019933, 0.09543210301352055, 0.3294985036302559, -0.1123540725858994, 0.3524803724007334, 0.1301721006693483, 0.3813326175940071, -0.1497179815896551, 0.4161216500474114, 0.1720439307471236, 0.456476553154757, -0.1983762992393827, 0.5013934945639351, 0.229926008851196, 0.5490538865200292, -0.2674630790920627, 0.3262584781762246, 0.6184594756429348, 1.841505465819113, -0.9036920907968744, 0.6037649288986811, -0.435730331781932, 0.4173633503092889, -0.3402273078184248, 0.3618792001829753, -0.3223329221765415, 0.3568694292734518, -0.3373610302359374, 0.3778471175268359, -0.3698307686701466, 0.4133989349283659, -0.4123481977579463, 0.4568802691238098, -0.4611046705689894, 0.5040519090114971, -0.5144902166835649, 0.5520670643889852, -0.5724133548481751, 0.5987991975851327, -0.6358180460131468, -0.6423152491290044, 0.7063313713285493, 11.35202456455329, -3.493500196224254, -6.638568150183083, -1.957344673859988, -4.228485425971068, 1.056606712337717, 2.626551471527081, 0.5527901502998748, -1.5670524346359, 0.2928237369304179, -0.8682190156229788, -0.1797627572714807, 0.4061836395463059, -0.1532886909026603, 0.09679996807476349, 0.1768465936273609, -0.1170417081935488, -0.2292432522445197, -0.2742907297354369, -0.2992562708270863, 0.40201700883393, -0.38229571927536, -0.5200048155415438, -5.301175868637563, -7.207800765406747, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.8146309446975, -961.5954948017205, 455.5912580995108, -0.03868887300459015, 0.1914593508419486, -0.06896288380706332, -0.1789757931782649, -0.1001298844401407, 0.1678836436039876, -0.1326643353856479, -0.1583758389218828, -0.1670959289351405, 0.1506643220501891, -0.2039577762706567, -0.1450354518997625, -0.2436945939407161, 0.1419222648546592, -0.286520727014479, -0.1419791043669855, -0.3322284769841388, 0.1461191154367376, -0.3799736358824325, -0.1554340998005074, -0.4281019938694952, 0.1708890736518134, -0.2592200631304444, -0.3256852567521202, -1.483625349429867, 0.6048929864489581, -0.4753236422915989, 0.2961694592646632, -0.3223046209916502, 0.2348874153138894, -0.2714626999105824, 0.2257895769533033, -0.2588066214268311, 0.2385080365992549, -0.2654198271110554, 0.2619285315116793, -0.2829866644015172, 0.2901165131905762, -0.3071846631133203, 0.3192058852536734, -0.3358595624892154, 0.3463380609514268, -0.3683054470711298, 0.3690746037927644, -0.4048218311662792, 0.3849522860948287, 0.4463965618803197, -11.17658830910763, -3.141599888182389, -7.057308180610275, -1.612632569840935, -4.674228358739717, -0.7006254562246356, 3.103524645986586, 0.1721449712789752, 2.083843108349515, 0.1230344465499392, 1.436244916006413, 0.2805779655633087, -1.039058835442039, -0.3606873771771562, -0.8103535254099236, -0.4007449405027154, 0.6957974817861713, -0.4236310613634878, -0.6603595623427048, -0.4431665472145394, -0.6828038414913131, 0.4676302900407178, -0.7523362731509651, -0.5019606323960604, -7.451487262070271, -6.898592890440204, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.8067442478319, -961.6430987511887, 455.5101352313706, 0.03574672013766993, -0.3305806211988256, -0.06018793703629798, -0.3342789822135747, 0.08398862072600807, -0.3428477394831397, -0.1075626639881692, -0.3568661462114826, 0.1314655734088672, -0.3768341259425303, -0.1564176785432246, -0.4031115942603709, 0.1833201534769062, -0.4358166092177098, -0.2132428552839921, -0.4746756170442514, 0.2473424911876484, -0.5188341233287944, -0.2866404669967078, -0.566654544358885, 0.3315822789153745, -0.3365523808315161, -0.7799477365989287, -1.92204447761313, 1.038304945171675, -0.6382333295246007, 0.4954672252621077, -0.4437009237950818, 0.3817879746615038, -0.3867630435618042, 0.3564182943353214, -0.3828941956014584, 0.3680304652111646, -0.4061335779417263, 0.3989834362533684, -0.4442583228007695, 0.4409123847406293, -0.4900404834181868, 0.4895313969246102, -0.5387255048657738, 0.5430334536942414, -0.5869290800627904, 0.6013145526212335, -0.6318954893637412, 0.6654442464724272, 11.56123863009346, -3.319983549512171, 6.821845065194244, 1.863466932603496, 4.38488470063812, 1.01067094368389, 2.749511386838089, -0.5351194258268466, -1.657256920227764, -0.2915679928571555, 0.9297221747564861, -0.1880812619045127, 0.4442416560586033, 0.167463535694055, -0.1167505114866327, 0.1950254755353985, 0.1102695455592749, -0.2505965089753026, 0.2762752306336164, 0.3233977751863117, 0.4086760961549661, 0.4088566255401637, -0.527180830087615, 0.5067736816255463, 0.6471037120006224, 6.563582277433596, 8.669169878915001, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.8564496879252, -961.6978071512939, -455.611344166528, -0.05065962634433919, -0.2035667717073716, -0.08941939694818055, 0.1861819141070234, -0.1293463728361657, -0.1705641231959824, -0.1710413062870665, 0.1568853187052691, -0.2151073082088822, -0.1454027021144876, -0.2620355483771115, 0.1365557074206818, -0.3120320827642339, -0.1310718629875927, -0.364788555337083, 0.1300347438234267, -0.4192352859893375, -0.1348167335882609, -0.473360750181653, 0.1467438213440089, -0.2866158909387535, -0.2490263897518478, -1.620329947670383, 0.5848677254506903, -0.5118461330390914, 0.2897889114975229, -0.3429946413052233, 0.2320656306481047, -0.2839885316813635, 0.2246136703445073, -0.2653143559437961, 0.2379182651793468, -0.2665902029177392, 0.2609701715451156, -0.2789374326510159, 0.2877297688810677, -0.2977825578364603, 0.3140810644157221, -0.3208740171767074, 0.3367519648803812, -0.347497849625001, 0.3526960178041265, -0.3780240749856291, 11.34415339639681, 2.9276728518795, 7.241716186208386, -1.480912627484681, -4.841851735919054, -0.6174008600345655, -3.244551359081532, -0.1161699839121046, 2.196810963053788, -0.1648403832407603, 1.52378878614412, 0.3160144776303719, 1.105419207445201, 0.3942117305648183, -0.8599720166997633, -0.4347652751226382, -0.7325429176455468, -0.4593657200668957, 0.6870715556985062, -0.4812114897627066, -0.7009216608316468, -0.5083517726327081, -0.7613887957889477, 0.5458417512230326, -0.8637959811793713, -0.5970603500508016, -8.878579618167663, -8.41079729749319, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.8483022209899, -961.7515375401339, -455.515103378266, 0.04757600714722041, 0.3759601994912693, -0.07952182508355922, 0.3793600134854735, 0.1109858526574028, 0.3887731574427825, -0.1426212566623932, 0.4046909058892191, 0.1752498328905884, 0.4274717745852317, -0.2098572245667174, 0.4572568690190124, 0.2475512176980405, 0.4938376701380627, -0.2894449308435921, 0.5364758189264845, 0.3364018036152697, 0.5836858088124017, -0.3885795342274033, 0.3460998677017337, 0.9269607883637689, 1.991751849844172, -1.159894903453939, 0.6683678480468542, -0.5489774865143997, 0.4666584984984303, -0.4181743697237709, 0.4083256137378595, -0.3850224904055522, 0.4052531090492756, -0.3922030940012985, 0.430154764416738, -0.4201452172640414, 0.4700533145873315, -0.4596423877934347, 0.5171413042952349, -0.5060190814650223, 0.5661040793608841, -0.5573376710742627, 0.6129220747774261, -0.6135503322915893, 11.72621780801965, -3.118567404640785, 6.963211382717763, 1.75302164155703, -4.516867569899999, -0.9561071819941682, -2.858888666291709, -0.5141429755265274, -1.740364185208108, 0.2903667692240343, 0.9878145752430977, 0.1983973188452912, -0.4807765726797618, 0.1846015909228558, -0.1358948953187996, -0.2164957212324468, -0.1043808041537456, -0.2751935128773355, -0.279826746444909, 0.3505627343904102, -0.4181686778299342, -0.4382062477600169, -0.5392140048606524, -0.5377014109662097, 0.6579315820212267, -0.6517663504946155, -0.7869275609113959, -8.05753646041288, -10.39414405360874, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.9138637696153, -961.8143515653112, 455.6519677186474, -0.065587947208334, 0.2085029215343718, -0.1141904493380159, -0.1849281174071089, -0.16417292084848, 0.1635422401442634, -0.2162120711863979, -0.1445429665498645, -0.2708523356285875, 0.128343198787713, -0.3282995933633563, -0.115712162032152, -0.3881537124649574, 0.1078796554266659, -0.4491292094201663, -0.1064891874455163, -0.5088711427777188, 0.113241647884544, -0.3083741181691479, -0.1467011040433109, -1.723923205907633, 0.5382296108587682, -0.5363846735303583, 0.27092624926658, -0.3545066321432684, 0.2197099884192319, -0.287363686337111, 0.2145312764451768, -0.2614204612340402, 0.2280211406842278, -0.2553142195422838, 0.2496987336771662, -0.2598467419074491, 0.2735997743104482, -0.2703495132715409, 0.2954157424967072, -0.2845730952075546, 0.311423814533789, -0.3018822827637243, 11.46523893315575, -2.691413015229958, -7.384362245400597, 1.335236216275609, 4.985185235965488, -0.5262745591804759, -3.372485074148798, -0.05648924165287231, -2.303682267268397, 0.2076207204669117, 1.609522758219237, -0.3508002202525652, 1.172561778202216, 0.4262482117585027, 0.9119656734777154, 0.4669796982018008, -0.7727539450790861, -0.4932706593868525, -0.7182401966339386, -0.5175074770463448, 0.7247978830712355, -0.5473237053574408, -0.7783621609313609, -0.5876369322550071, -0.8723083916636201, 0.6419574139158084, -1.00657473616704, -0.7131802559475791, -10.57449072135191, -10.20410649815866, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.9061412862011, -961.8770732639229, 455.5376417683805, 0.06254419195417743, -0.4232684972590032, -0.1032882224080658, -0.4264012907068119, 0.1437641786514711, -0.4367775016311054, -0.1849091479680357, -0.4547230616343913, 0.2278125351396496, -0.4803659165556683, -0.2736445954407336, -0.5135240332136976, 0.3235038064582032, -0.5535385281539781, -0.3781288842484928, -0.5990476261198098, 0.4374274060989551, -0.3541391351405594, -1.058073342162964, -2.045216966325468, 1.266080794797456, -0.6924316493113732, 0.5950376234995193, -0.4851062828675501, 0.4482900280297341, -0.4257039247593362, 0.4069187711414488, -0.4232424419027072, 0.4083834788979941, -0.4493250721690615, 0.4314669583481853, -0.4903032612085907, 0.4662810430706394, -0.5378049265577316, 0.5078722409403839, -0.5859084246214689, 0.5542724904405595, -11.84485447706039, 2.898542856056091, 7.060252299552289, 1.630303727224056, -4.621383723680353, -0.8942453459292238, 2.951610305967167, 0.4895834794482448, 1.813545938433091, 0.2881843187274703, 1.040043542488245, -0.2094177206260044, -0.5137794499925029, -0.2034268577435624, 0.1527024933413826, -0.2401406725930453, -0.1004080668438968, 0.3021385233083859, 0.2854472563703663, 0.3800924576032388, 0.4303872415260588, -0.4699267499381296, 0.5551933085574434, 0.5711417670203969, 0.6747267714850889, 0.6859780125203653, -0.8010046828883495, 0.8192592301466893, 0.94515561658495, 9.820426173212363, 12.42939017103546, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 504.9930103786541, -961.9513356663066, -455.7221717257553, -0.08414743711096713, -0.2026736860667679, -0.1439128065966526, 0.1712281387505495, -0.2050964145610792, -0.1424763186319537, -0.2683067024845924, 0.1167626582609214, -0.333761142126125, -0.0948595784588155, -0.4009780128477423, 0.07811577117355756, -0.4684645116803408, -0.06843920146675211, -0.5335327087101004, 0.0679294038621997, -0.3239054824125787, -0.0116792012931699, -1.790663616927004, 0.4590524896071508, -0.5473106572190689, 0.2369585734237551, -0.3554648484778318, 0.1960271233909658, -0.2800877958506142, 0.1941244183782809, -0.2453078173802557, 0.2076091627418861, -0.2293383987055, 0.227046232106705, -0.2229498501452899, 0.2467672230652324, -0.2215577701206991, 0.2623437054600908, -0.2230571348710727, 11.53795815371153, -2.443315951606555, -7.483391968859528, -1.180817659033836, -5.101147725873458, 0.4291177015601163, 3.484008053855922, 0.006968221311336701, -2.401299468052032, 0.2524588129698827, -1.690603619495555, 0.3864574901609267, 1.238005582549325, -0.4584326101560443, 0.9641940337828574, 0.49897471755453, 0.8145568272198119, 0.5268294835097378, -0.7521215969515586, -0.5534552278380493, -0.7525858951277018, -0.5859592679598992, 0.8009010588386255, -0.6289928712031305, -0.8890676867080832, -0.6859830214698649, -1.014965640327654, 0.7599429084175442, -1.182234401254345, -0.8539617213615083, -12.58037930190747, -12.3224597531326, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -504.9867232586682, -962.0267397173889, -455.5858482841886, 0.08146568040030745, 0.4718570639702241, -0.1323792393628501, 0.4746520270081164, 0.1832926548394762, 0.4859370727590149, -0.2354260094769804, 0.5057808128620681, 0.2900438647951354, 0.5339800783871049, -0.3482656295242084, 0.5699120289626995, 0.410743635210365, 0.612307221970398, -0.4771765920828036, 0.3602759907915838, 1.17231410234708, 2.078779437679099, -1.355247085704674, 0.7092702971335834, -0.6327846462311433, 0.4983600087248974, -0.4713003995691609, 0.4384934063277775, -0.4210960673642488, 0.4367016135277066, -0.4152685840028347, 0.4637359288734594, -0.431277660159945, 0.5053758360548571, -0.4587373301787441, 0.5527030534382514, -0.4925622070803836, 11.91525071372664, -2.669737940207489, -7.112070179658535, -1.499950988056173, -4.695989395278955, -0.8264068408364236, 3.024764719308382, 0.4608488246132006, -1.873884959550882, -0.2834560461830024, -1.083707901266197, -0.2191901436954789, -0.5408889135616145, 0.2219393955259065, 0.1652261958197461, 0.2640887562841959, 0.09983770284304504, 0.3297673240943492, 0.2941272369903571, -0.4105473985768032, -0.4457746369230076, -0.5027821554303129, -0.5749124856717664, 0.6060241185316116, -0.6964125744179374, -0.7222036226954593, -0.8219917097087917, -0.8553991180861862, 0.961952339859114, -1.012160660965054, -1.126829376377705, -11.89125844216821, -14.82268386167739, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505.1021960848271, -962.1169026393795, 455.8338729921806, -0.1071062110747086, 0.1815070603285521, -0.179150267652292, -0.1400998028560625, -0.2522503910014173, 0.1021004970621845, -0.3266542012589974, -0.06823635379950285, -0.4018139642522497, 0.03994126095184518, -0.4760406224002068, -0.01938011015157691, -0.5463234758642321, 0.009080595156260448, -0.332710657886771, 0.1616900475175027, -1.817966811669035, 0.3426834356104604, -0.5434318586351045, 0.1858789109600244, -0.3447965208108256, 0.1597482455188877, -0.260904925528362, 0.1625453870579868, -0.2153733000095499, 0.1761648327255745, -0.1866055914925562, 0.1928056464078325, -0.1656576200451232, 0.2073444379444271, -0.1482507898985436, 11.55984343995971, -2.194330913236887, -7.539191327935495, -1.023568455741856, -5.187360036320147, -0.328277306992068, -3.575805403221234, -0.07408649072083257, 2.486163835875462, 0.3004875937099439, -1.763663794387484, 0.4247125801810033, -1.298641369289637, 0.4926794598061576, 1.013844940412112, -0.5326247822284832, 0.855408835835386, 0.5617664880260144, 0.7863621255143287, 0.5906033658897508, -0.7819719026602904, -0.625663908357995, -0.8264736550053368, -0.6712690869377209, 0.9108668466439265, -0.7306688749077851, -1.031594825877172, -0.8068049947691155, -1.19005694174046, 0.9028377648786338, -1.393080617256989, -1.022486576162642, -14.93725702842511, -14.80858779518792, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505.0986792310538, -962.2097661716811, 455.6702293933568, 0.1053158391624666, -0.5209308336066629, -0.167801730661908, -0.5231587860538264, 0.2305615961092414, -0.5350545218265784, -0.2949981297092716, -0.5563330952365698, 0.3622987997093375, -0.5863529471226727, -0.4330778853603579, -0.6238972077621375, 0.5068738237225937, -0.3645929382416744, -1.269034197433159, -2.091002309996033, 1.426568270000934, -0.7184531759372009, 0.6617359656374076, -0.5062857257808602, 0.4866398522234159, -0.4468522920838534, 0.426758635928322, -0.4461365544464869, 0.4117361542474164, -0.4743095042403939, 0.4180529165899515, -0.5166800360497492, 0.4350417285374433, -11.93487401223153, 2.441424296363036, 7.120614763298893, 1.366543100975028, 4.739536856455961, 0.7537631620120923, 3.07601221737414, 0.4269745581475306, -1.918657953164775, -0.2740524529274999, 1.116076917175963, 0.22506572849195, 0.5595705076145522, 0.2373597796023182, 0.1712561169743348, -0.2856470413363019, 0.1044690985263356, -0.3555730312438909, -0.3071946247653678, -0.4396379038796807, -0.4651362087062904, 0.5346799860173224, 0.5985834061049665, 0.640392538677784, 0.7224826043854548, -0.7585342198697523, 0.8484129027006324, 0.8926513574029241, 0.9861836715435827, 1.048258602424987, -1.145257873605194, 1.233529400113939, 1.336236455566228, 14.30571745164884, 17.61787905052259, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505.2522684045481, -962.3209091459635, -456.0021243571045, -0.135204950106543, -0.1394617235875679, -0.220127550372105, 0.08571928452292403, -0.3049409043236431, -0.03659504642708369, -0.3890574180257759, -0.006436425325169574, -0.4706108350838175, 0.04096694825184889, -0.5462820434899358, -0.06401136348259447, -0.3343815237245166, 0.3770481192076843, -1.804641348780662, 0.1862488607745145, -0.5241026690461806, 0.1165329851236274, -0.3218108422408898, 0.1103182214298427, -0.2288701150093211, 0.1197089351929335, -0.1702872232337064, 0.1340809261902273, -0.1252999394856697, 0.1478955058540885, -0.08560365295523495, 11.52576378974406, -1.954372039977865, -7.556599118670414, -0.8696416229998727, -5.243139426145771, -0.2265893727803473, -3.645001180400495, 0.1444022525350471, -2.554614576511419, -0.3526936465053139, 1.824862320705907, 0.4673053399212604, -1.35071736012791, 0.531014596069754, -1.057368223650742, 0.5699553062659776, 0.8919929683549828, -0.5999463785086376, 0.8178418137071368, 0.630579143988404, 0.809941527510296, 0.6678139095408332, -0.8520024722473533, -0.7156241704641815, -0.934272389637509, -0.7770482361065687, 1.05215121053177, -0.8548848555187463, -1.205491122946197, -0.9521918975626668, -1.398620727934507, 1.072675726622418, -1.64131363116556, -1.220973810147752, -17.67939399433237, -17.69696009914344, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505.253017754159, -962.4364747394324, -455.8036682152643, 0.1351126787098899, 0.5695864039965876, -0.2104884546621504, 0.5708245939994814, 0.2862709367223656, 0.5827540820095056, -0.3637808074554126, 0.6046421105793508, 0.4436589944498553, 0.6352690932451194, -0.5253459950861361, 0.3677303232551267, 1.347453344746686, 2.082926012424898, -1.479753805386014, 0.7203282114221324, -0.6816721371214693, 0.5093388325091368, -0.4939242839721554, 0.4515458590346876, -0.4232358982106663, 0.4527789299653081, -0.396731197291685, 0.482881928016134, -0.3902827551017815, 11.89894466315718, -2.22090063369331, -7.092747734361658, -1.234026593177227, -4.753181046423188, -0.6771950822291326, -3.104140201531702, -0.3866040328596608, -1.945692839472312, -0.2572635974024494, 1.134652874596721, 0.2236606491303219, -0.5673297987656002, -0.2460750486326881, -0.1685020505679479, -0.3012253263999956, 0.116250006339078, 0.3761133268443195, -0.3261558958623166, 0.4641080126177665, 0.4894613648488647, 0.5625417455833565, 0.6266107088037656, -0.6712930493524196, -0.7526658702381472, -0.7920386924545679, -0.8791718349910133, 0.9279565248449416, -1.015643135720146, -1.083803569712843, -1.170845050805069, -1.266390093671474, 1.354037366376675, -1.485576073474351, -1.576400237129784, -17.08748638019799, -20.84557350276546, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505.4566106321672, -962.5733809140785, 456.2446669456525, -0.1688459112995087, 0.07034403444173644, -0.2661925457838576, -0.00201291370003544, -0.360842606721788, -0.05949303565750251, -0.4507864673737421, 0.1115494205452214, -0.5324222730975748, -0.150692878879795, -0.3285617939930261, 0.6352611728442655, -1.750928292301286, -0.01079073303553477, -0.4892798325673497, 0.02887167931331536, -0.2862455254245249, 0.04809364620457122, -0.1833951993284249, 0.06648914871000661, -0.1090258324830243, 0.08288235905924721, -0.04388087225057338, 11.42397334205316, -1.730411869135157, -7.54872126209005, -0.7246099232898299, -5.271259193087543, -0.1273016997487224, -3.689949677751227, 0.2168582799717596, -2.60315967042078, 0.4095966898831329, -1.869993120606597, -0.5156814339442469, 1.38982674111601, 0.5753023219269168, -1.090398441258875, 0.6129015965698307, -0.9200861758805992, 0.6431623698555172, 0.842501341267445, -0.6749156741454959, 0.8325483404989181, 0.713623361375966, 0.8735437835352988, 0.7629401789412279, -0.9551462767593792, -0.8256933589190248, -1.071962632591364, -0.9045223083409126, 1.222727743028186, -1.002327294123344, -1.410056693758905, -1.122638822704943, -1.640877341853048, 1.26995573475215, -1.927844246417485, -1.45003227706329, -20.82307411706698, -21.00155992122358, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505.4627685739322, -962.7160457792522, 456.0005200775191, 0.171584773148045, -0.6169168507138828, -0.2608304899009982, -0.6165570206329561, 0.3501697797170152, -0.627679892134454, -0.4403605479968019, -0.6489829640847168, 0.5308300518602039, -0.3709301239614179, -1.405815328723569, -2.058062413586543, 1.514443425105629, -0.7159719725315271, 0.692368587676033, -0.5085223559524636, 0.4927483234228063, -0.4539119844509412, 0.409786918662957, -0.4585601641836641, 0.369060795992091, -11.79766504079141, 2.012479939028762, 7.043555197226082, 1.105137043752469, 4.741914128289426, 0.5972094437860065, 3.109868363286502, 0.3381216846268515, 1.953867566077465, 0.2299457233923843, 1.137533669668121, 0.2109462622238532, -0.5620043637972509, -0.2436579564637029, 0.1548443572169821, 0.306307345836395, -0.1370525568840376, 0.3869435542219369, -0.3524856590577575, -0.4796460558277326, 0.5197151476832278, -0.5821783731153887, -0.6593590868915518, -0.6946136487705999, -0.7866414714126642, 0.8185951248778229, 0.913148489829942, 0.9570365064732725, 1.048232753669613, -1.114138187570384, 1.200190769798651, 1.295704602378807, 1.377356049197987, 1.509847257194258, -1.589258765649288, 1.768262183131415, 1.848069109594906, 20.23420853365266, 24.50766781694805, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 505.7302235739897, -962.8808897579297, -456.5799751938149, -0.2074665694865197, 0.03179270034629982, -0.314911648796822, -0.1160409354435016, -0.414899941317193, 0.1896042423128672, -0.5035929949910716, -0.2485406654930217, -0.3148720318285624, 0.9334281744469859, -1.658358518134329, -0.2459729705045449, -0.4395368675508144, -0.07575020637815727, -0.238298110932487, -0.02543448920587639, -0.1242798269864487, 0.00493022955061947, -0.03092176867721523, 11.22885110571361, -1.52501965073773, -7.543615992492188, -0.592424165410839, -5.281049101322963, -0.03384112642572992, -3.711740461545836, 0.2895170179898658, -2.629192995613142, 0.4707504030082303, -1.894805671641967, 0.5704662427677495, -1.411023004415436, -0.6267630427501154, 1.107747137626518, 0.662893542409588, -0.934479879776553, 0.692778028843108, -0.8551991883552512, 0.7247338818733859, 0.8447234697913153, -0.763869215310247, 0.8860283550216375, 0.8135940022344247, 0.9682811777983255, 0.8765586475933742, -1.085448060890765, -0.9552512796328857, -1.235412367552187, -1.052408869707694, 1.419557246828857, -1.171343028943237, -1.642863640112578, -1.316259793628108, -1.914688728881414, 1.492601140725079, -2.250602542324417, -1.707371208414184, -24.34911222913227, -24.69682337532403, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -505.741435494995, -963.0504155847199, -456.2741036613125, 0.214479472715505, 0.6621861981953745, -0.3177872890555592, 0.659477202360043, 0.4199363883935496, 0.6686966992655288, -0.5204604440629446, 0.3760250100904552, 1.440136329901755, 2.022077415101587, -1.529242860821105, 0.7070177320978236, -0.6931608182158253, 0.5052503305200324, -0.4823639976910435, 0.4557292865512613, -0.385316970783089, 11.61106437256959, -1.818394061749481, -7.001963622764721, -0.9813357744591734, -4.716881178048456, -0.5141556100260524, -3.0969906159148, -0.280097039848389, -1.943793145915662, -0.1889996708430733, -1.123912478997343, -0.18264542910118, -0.5421787669130134, -0.2251582877779384, 0.1286970772462299, 0.2956319802801666, 0.1683473607021652, -0.3827115546150297, 0.3873303842983701, -0.4809087334725033, 0.5565590506576561, 0.5882754140327704, -0.6968797879222629, 0.7050226515021639, 0.8237435880499643, 0.8327756810598531, 0.9488550233241532, -0.9742434109257527, -1.081502395328126, -1.133196471873608, -1.229668358197086, 1.3146823158554, -1.401016876114531, -1.525516610156299, -1.603885466468684, -1.775180446964151, 1.848426978531237, -2.07736997486411, -2.148126517552196, -23.69694322453203, -28.55450387022301, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506.0870994444517, -963.2380980143934, 457.0227998243373, -0.2485169973393713, -0.1708755956446555, -0.3608775819654662, 0.2702463148020641, -0.4583288971296218, -0.3528976210982101, -0.2928214663649001, 1.263652831351624, -1.529505325655311, -0.5130238387785291, -0.3760704452139064, -0.1942204111583247, -0.1786533015765691, -0.1073884668217014, -0.05177939288958904, 10.88603291358535, -1.337180308687955, -7.596957579622598, -0.4747035515000937, -5.293796730009392, 0.05043538802520772, -3.716922670417109, 0.3592165384067125, -2.632466505734362, 0.5340539274802235, -1.895818658518178, 0.6306645190841967, -1.409275395512805, 0.685196075280273, -1.103655066088433, -0.7201507688034566, 0.929097908006366, 0.7491204140241028, -0.8497455883339168, 0.7802302755862421, -0.8402329799755162, 0.8184522926487809, 0.8831625818888247, -0.8670840673667023, 0.9672225533587266, 0.928669763681313, 1.085819612885373, 1.005581967725039, -1.236140490171399, -1.100404676155905, -1.418629151651308, -1.216231218475, 1.63686735128274, -1.356940773255257, -1.897950583839266, -1.527515842606489, -2.213574416593122, 1.73441741027332, -2.602284267564217, -1.985971407789865, -28.17877747730259, -28.69146328143491, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 506.0995030305882, -963.4251163002542, 456.6319082336776, 0.2614208946746435, -0.7049929537479934, -0.3775469776448249, -0.6990129299253891, 0.4897228036148983, -0.3853539179729928, -1.442770760684808, -1.98216326068838, 1.520548699194699, -0.6953740263821517, 0.6824190354472228, -0.5011233283967811, 0.4613118931865929, -11.29796537330876, 1.64449147211759, 7.022169169615215, 0.8641805347117423, 4.699276336140136, 0.4291404936096105, 3.07407334406547, 0.2123539984677152, 1.918769023964996, 0.1324679335590006, 1.09476296754075, 0.1352170432778689, 0.5077652860572863, 0.185910694584077, 0.08952722613195557, 0.2638426913931702, 0.2107393703819989, -0.3576622830692115, -0.4310960937466334, 0.4619085175014147, -0.5999884739982514, 0.5746756856778464, -0.7385868745992383, -0.6961886963160135, 0.8626657356149082, -0.8280065670824533, -0.9841390899478625, -0.9726569738046391, -1.112325598821782, 1.133551592359431, 1.25500535004336, 1.315134855586846, 1.419345051714987, -1.523232765666847, 1.612773491431782, 1.765677755404849, 1.843930722061922, 2.053380737994717, -2.123837663941296, 2.402145835888836, 2.467526732917271, 27.35441123139784, 32.85590905559759, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 506.535108831963, -963.6167931351213, -457.5765788302061, -0.2861761743318959, 0.3461105740480527, -0.3947395339422998, -0.4564377447058072, -0.2617296324114806, 1.611734008281398, -1.367678013419382, -0.8010059019283635, -0.3006880659872381, -0.3213053025395997, -0.1085392364738896, 10.2725543041519, -1.168526626564622, -7.82064895354263, -0.3713337568773262, -5.352508738636831, 0.1222893217356636, -3.722102280656161, 0.4211608377876347, -2.617734196748431, 0.594901972075254, -1.871992486237874, 0.6925901148668441, -1.38058734154616, 0.74787922336183, -1.072581160949938, 0.7826644587414839, -0.8975809094419182, -0.8105767210582541, 0.8193405723194567, 0.8399098661914142, -0.8120222073214457, 0.875770220099946, -0.8576881155650289, 0.9215289264833487, 0.9444708197958593, -0.9797395325755353, 1.065205863140835, 1.052722623302901, 1.216460299462672, 1.142943964195683, -1.397905992342116, -1.253291158068077, -1.612055771894061, -1.387322544088788, 1.864373007497077, -1.549535917211965, -2.163879565979816, -1.745709327273886, -2.524523036401785, 1.983325027495365, -2.967830167452788, -2.272019538910634, -32.14658674016512, -32.79917505195669, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -506.5385766328296, -963.7950492893284, -457.0688147458119, 0.3064737493454045, 0.7451295489392065, -0.4320824231461616, 0.4015780387117531, 1.401276142639599, 1.946107688605819, -1.48150526542528, 0.6828643239680722, -0.6570927744752225, 10.7638914509755, -1.517523554864524, -7.212410025151229, -0.7594650802490791, -4.727779988834981, -0.3459479511652795, -3.056982946412603, -0.137792378203823, -1.885965897429857, -0.06147034578463532, -1.053619513536147, -0.06771520575915954, -0.4606626658479292, -0.1231959710791077, -0.03846712123960974, -0.2069083481076168, 0.2634078610725342, -0.3068550531907182, -0.4829610805074276, 0.4170585080045313, 0.6489288141016536, -0.5352933146117154, 0.7829424333419256, -0.6615771584317809, 0.9012282823913962, 0.797293809624204, -1.016026767128407, 0.9447489034757597, 1.136789528309099, 1.107026430413602, 1.271196791521118, -1.288051047513149, -1.426037977791292, -1.492842932266066, -1.60802186802236, 1.727960361905206, -1.824590624194746, -2.002232368690374, -2.084863210703189, -2.327985171787624, 2.400861196107053, -2.723108602478969, -2.789278491542184, -30.98867169157857, -37.17333705763805, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507.0685285381397, -963.9513225378075, 458.2239814297878, -0.3105094100833926, -0.5489621604214274, -0.2207001619135986, 1.956288574692065, -1.176681603230856, -1.09375598392015, -0.2158081274278867, 9.039432404200522, -1.044683628994101, -8.468785467802409, -0.2840135792540254, -5.542745543449104, 0.1779572946344857, -3.761606785421675, 0.4684797722662275, -2.598930526573113, 0.6453592933930452, -1.827562760363265, 0.7487181877066253, -1.324101584715386, 0.808286952945908, -1.010847733279209, 0.8449471423636297, -0.8346332998503472, 0.8724833572892089, -0.7577244949265606, -0.8996473668870159, 0.7532210193109008, 0.9319700291879087, -0.8023001449790493, 0.9731169256921198, -0.8923272475697563, 1.025808942383718, 1.015464062032189, -1.092414194595597, 1.167634916611444, 1.175336052505714, 1.34782203022553, 1.277290630873182, -1.557658237162463, -1.401532229855291, -1.801354910586623, -1.552090405661354, 2.085991956058786, -1.734049468830996, -2.422322212155974, -1.953922901839827, -2.826392120689291, 2.220125678702697, -3.322576673428888, -2.543480350687961, -35.98052650947123, -36.71809122641062, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 507.044358239568, -964.0731038498507, 457.5609921269437, 0.339186245230021, -0.4273969477024003, -1.29863116329144, -1.9212155175519, 1.401898391182813, -9.726271535257508, 1.553331598619713, 7.831565439526993, 0.6875158984530817, 4.876888986260434, 0.2743174969664351, 3.073278715408381, 0.06481527948414105, 1.857848936458911, -0.0172058553164797, 1.007270300003323, -0.015493908041739, 0.4052734656641692, 0.03886914827152865, -0.02120544418256508, 0.1245454447689218, -0.3236527085621929, 0.2283392770229724, -0.5404903245807748, 0.3431422365149781, 0.7009598725924222, -0.4659137295498349, -0.8273152365264473, 0.5961381254254794, -0.9363871554481444, 0.7348226673958823, -1.040881025210011, -0.8839501590062537, 1.150503496114657, -1.046240633846492, -1.272940104510185, -1.2251386270737, -1.414709746711867, 1.424957765640063, 1.581930391736834, 1.651204358082938, 1.781057179003545, -1.911084747398959, 2.01966517958886, 2.214321569792053, 2.307406860022854, 2.574510651133963, -2.657307283406697, 3.01140106208788, 3.087681881697911, 34.27753948458455, 41.14981894020637, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 507.6607402118162, -964.1324178062038, -458.9202293050566, -0.1686378441806772, 2.26918481619089, -0.9605814475857066, 5.330862093858574, -1.138949076550252, -10.32445599072876, -0.2278821376240088, -6.053185271755386, 0.2111992660067487, -3.90195016026017, 0.4916948027703619, -2.604992480633718, 0.6736549508248011, -1.775821097551055, 0.7869195888388132, -1.245117363143849, 0.85511197805049, -0.9191931180792211, 0.8969679044521599, -0.7382433689234038, 0.9261198029941115, -0.6611696707630135, 0.9518531231496314, -0.6589875072665196, -0.9803308643977939, 0.7113879440961655, 1.015736615269503, -0.8045956932013681, 1.061136120387407, -0.9298638326235749, 1.119078818816151, 1.082360654284157, -1.191995373104534, 1.260356303986052, 1.282483463463084, 1.46470232087969, 1.393532235248562, -1.698581785001543, -1.528731717952134, -1.967581344572053, -1.69251044093007, 2.280123193492441, -1.890433165088037, -2.648431439034473, -2.129603108392172, -3.090370039310071, 2.419171909638182, -3.632813078727661, -2.770878258545604, -39.30905440906147, -40.04060379184506, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -507.5823569101401, -964.1327952153448, -453.1525519625071, 24.40574541777206, -56.14514099816383, -2.422186406437542, -25.22429964965732, 1.444867813899084, -12.70852566601807, 2.547941134817951, -6.850174344806808, 2.975175307411678, -3.480196946314358, 2.990960801627664, -1.417378358439735, 2.740289627402432, -0.1451237393712128, 2.339923467563752, 0.6224326970934283, 1.877490924183014, 1.064055147754233, 1.410245383546048, 1.298670025286794, 0.9699280356465935, 1.407692033072784, 0.570056365428795, -1.447206482446987, -0.2126606347621276, 1.45549590027687, -0.106700427367443, 1.458217449192367, -0.3956662520866513, 1.472227262174601, 0.6631737994890589, -1.508479947856337, 0.9184906204287088, 1.574231058518403, 1.170872531544465, 1.674716872315271, -1.429622942231864, -1.814460422530907, -1.704464741494625, -1.998356318905909, 2.006172401087063, -2.232676942948992, -2.347554579943283, -2.526186304333157, -2.745015993852846, 2.891570896342571, -3.221095840304374, -3.347521504585615, -36.81977934526557, -44.35189490614219, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -929.5916205582998, -941.0365306526329, -83.0205570677121, 28.17439325219577, 75.87533570257695, -1.696520866989221, 26.60699159785555, -5.409361115615388, 12.56934180801319, -6.877261269176024, 5.687519948140556, -7.195311665250237, 1.882753730836734, -6.793257487426405, -0.243954230030588, -5.985952308839798, -1.376766663139118, -5.007212173644259, -1.909776318300887, -4.012480308119807, -2.086793153052898, -3.09156896456971, -2.063263714473415, -2.286718302219568, -1.938915871123262, 1.609507069182077, 1.776860515294737, -1.053845022404726, -1.615732919376842, -0.6048003006133782, -1.477928334454509, -0.2440699657679927, 1.375377784059099, -0.0469141625735761, 1.313620215666728, 0.2854287861559656, 1.294663638447388, 0.4868539710419071, -1.318984666977386, -0.6646185691294326, -1.386978049510149, -0.8304585614062736, 1.500098994703478, -0.9948396546158864, -1.661963350617514, -1.167481907502111, -1.879718152404978, 1.357937431688009, -2.166151621008019, -1.576149522040385, -22.8426934593021, -23.12611835160169, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39.74325951288207, -1186.431523127095, 891.9981651399358, -63.78630277783328, -227.1996575944138, -21.36263524515902, -134.9940747033731, -11.91053467248452, -92.38872197451053, -7.137773558531492, -66.40883312595787, -4.159839971417969, -48.55372147263157, -2.266393752869894, -35.63597637393651, -1.094787188040574, -26.12268218585725, -0.3740073215893996, -19.11470230422248, 0.09756406262595478, -14.00177931344374, 0.4539441356094622, -10.33193495392373, 0.7738574705683541, 7.757284995888257, -1.098280483037155, -6.008113485615493, 1.446238834722165, -4.877217783576145, 1.8260185749213, -4.208135864627979, -2.242051708641171, 3.885327967594733, -2.698727377102662, -3.825903864288941, -3.202420566106344, -3.972879079281471, 3.762630114298621, 4.289949398982492, 4.392965687767301, 4.757754982238793, -5.112366708632306, 5.371588692477695, 5.947098472803463, 6.140643591545218, 6.934244894234055, -7.089006463457302, 8.127774292215216, 8.258953377781268, 92.70654077487185, 110.8916502269361, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 786.2689336767368, -815.9863464302587, -502.0050839453779, -90.73950140949509, -56.87432228337573, -51.99165992440596, -33.34091308622924, -34.04113075780467, -21.43377478029886, -23.06225529920733, -14.14681954842458, -15.59204793972567, -9.417386184375989, -10.29776713475104, -6.330831000664216, -6.493371297236832, -4.358412747427537, -3.752309549753657, -3.152344856102681, -1.780646844936822, -2.474087100314609, -0.3652993582829661, -2.159473586844666, -0.6519861739832791, 2.096803744336349, 1.389930130712824, -2.211583888600316, 1.937926207260219, -2.455755504596307, 2.363440987643714, 2.800164407662094, -2.717650504667941, 3.229401718516578, 3.039864785640401, 3.738480085017688, 3.361030069362782, -4.33092205126337, -3.706511692235448, -5.018136256707792, -4.098399590204935, 5.820036523452692, -4.557455346103694, -6.767262056924007, -5.104890578388991, -7.905837082177761, 5.763931574597367, -9.306048512065884, -6.560810197006163, -99.50178779115197, -96.99432423638203, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -321.507651312602, -910.0072663299117, -591.4192374647588, 2.348605212951472, -124.3655421160505, 2.519037737123322, -84.26548427045947, 2.573811571186274, -59.67166318149743, 2.542520312756454, -42.7047736707389, 2.300331152371294, -30.40208946365, 1.868906337655643, -21.33294075666419, 1.342284397278395, -14.64893633535513, 0.8120400288034471, -9.763872639971726, 0.3354516359221829, -6.235124240181859, -0.06553144651026029, 3.716540641341441, 0.3931256138944335, -1.936614843167815, -0.6618294981785842, -0.6848912674945181, -0.8900811776756501, 0.199127185761292, 1.095738020332698, -0.8359393889447138, 1.294255063198197, 1.31492328463649, 1.498467646770268, 1.702006092723583, -1.719202962560454, -2.046109758511857, -1.966270920929146, -2.384503193805934, 2.249628522569334, -2.747318106025392, -2.580712635786556, -3.161596749861384, -2.974131519986319, 3.655356432931151, -3.449999148965924, -4.262437651783252, -40.50763259878801, -54.03571513338518, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -344.0713331149046, -952.725510121053, -416.8443995257026, -1.06754986885831, 45.84646413547254, -1.058403868892041, 31.77101137436911, -1.019954379151325, 22.80926291367322, -0.9071659718312616, 16.5022307529763, -0.7068440514134203, 11.86549955113823, -0.4524387095841191, 8.40538251216984, -0.1887047159960708, 5.82217952814256, 0.05065134824649881, 3.9055606710333, 0.2489662036219396, 2.495002070050333, -0.4034520268008114, -1.463934384255092, 0.5196357992327747, 0.7123003579271661, 0.6066099511692123, 0.1617857928516114, 0.6740824416340541, 0.2481361170724213, -0.7308946494537877, 0.5637692276795909, 0.7845255109986143, 0.8204101808272708, 0.8411152733767217, -1.045170820232432, -0.9057592610820282, -1.259454345228306, -0.9828579943559127, 1.481169292533973, -1.076498380875339, -1.726879905570609, -1.190773320672958, -2.014212738164722, 1.33001392092199, -2.365085594225679, -1.498734072363048, -24.7211856905308, -22.78270797180551, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -442.6907539702701, -958.4534825933663, -525.0790057885872, 0.4830776577375593, -34.3647256467903, 0.6314006455905202, -24.3348172625214, 0.7058287395586245, -17.41434346405917, 0.6762376591103615, -12.39697921157262, 0.5581637364705839, -8.69979036834804, 0.3923850266317464, -5.976507461418807, 0.2173455777493897, -3.987524183530083, 0.05722832788370733, -2.551827878146577, -0.07817291001085155, 1.527904886231801, 0.1888356566437113, -0.8048407679343973, -0.2797226979198223, -0.2967379564291665, -0.3574286627927332, 0.06184616772257682, 0.4283754863248733, -0.3199942490552064, 0.4980819539573895, 0.5140709901171847, 0.5710827814267276, 0.6708672126762525, -0.6511525664070008, -0.8102397807569323, -0.741692223923563, -0.9473054632669835, 0.8461535960354408, -1.094295489000015, -0.9685246843169275, -1.262227087133157, -1.113917136472349, 1.462601455450445, -1.289351439294402, -1.709469206945622, -15.37887836207466, -21.35497052390839, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -428.3101323308657, -960.7693411578422, -474.342891355963, 0.04496720051684034, 19.40931799070891, -0.1673280524757375, 13.92731470257143, -0.2557102683826377, 10.07353665325728, -0.242060653548165, 7.24394212742543, -0.1622596506986207, 5.13483244576956, -0.05331961081104578, 3.56174021542921, 0.05739982125560644, 2.395487323148687, 0.1547037661558607, 1.537813226473135, -0.2331433212654467, -0.911475734135779, 0.2933066494077648, 0.4555476781368759, 0.338711646959178, 0.1224074525370889, 0.3738275323799262, 0.1247194820414306, -0.4030263556972666, 0.313950693100759, 0.4301452572858044, 0.4667062381065167, 0.4584109424144206, -0.5994212319450118, -0.4905216003205117, -0.7250428404204554, -0.5287981906358582, 0.8543669982497838, -0.5753440721198483, -0.9973355647586041, -0.6321710321880218, -1.164486942694627, 0.701242039243045, -1.368908791826208, -0.7842864184450526, -14.12684531258338, -12.34623872489789, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453.5947291948034, -961.2035052944622, -514.6492553039509, 0.4825672633043259, -14.63884772835812, 0.4728625789819674, -10.46609788926318, 0.4223503876316634, -7.442448460093368, 0.3329214300137407, -5.216277203642393, 0.2244794898769337, -3.578425180158726, 0.1168914409785088, -2.383907106504585, 0.02230924598695424, -1.523064408492582, -0.05507450668021285, 0.9101446618023145, 0.1163992499184654, -0.4779690543716839, -0.1653691281434937, -0.1745659182869991, -0.2063444223336585, 0.039602682285727, 0.2433424061835201, -0.1941384821064465, 0.2796828695057331, 0.3109312828739628, 0.3179775825463946, 0.4060797546311572, -0.3603111282843304, -0.4915070533384577, -0.4084758403447379, -0.5763074319912898, 0.464226600596208, -0.6678922566067029, -0.5295368917237421, -0.7730382893753434, -0.6068884203575737, 0.89897954742318, -0.699610046209151, -1.054787068983536, -8.609652087354156, -12.8579032884007, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -446.0038881412778, -961.3008847776382, -491.7175432274707, 0.1943007163358473, 9.906958572878336, 0.02345340704111558, 7.173866633051514, -0.04242250621999444, 5.166677008312024, -0.03855525151603313, 3.669944479628774, 0.002466257542828118, 2.552845379807538, 0.05656495909653988, 1.723914622877545, 0.109389231273188, 1.113704343754537, -0.154326556966241, -0.6676835332672917, 0.1897295486417266, 0.3428450695372164, 0.2165827955413441, 0.1055512320135479, 0.2369862849228626, 0.07020719515760521, -0.2532876029564753, 0.2043491608705294, 0.2676915043075377, 0.3120764248151033, 0.2821088161452195, -0.4050727622745833, -0.2981576244336274, -0.4925541862044852, -0.3172019895469589, 0.5822117700075157, -0.3404097672817541, -0.6811329794436601, -0.3687673652742239, -0.7968425416319206, 0.4030092522096378, -0.9387219855322787, -0.4433201240139981, -9.48396669353969, -7.512457904532764, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.4328410845339, -961.0071327788293, -510.5524809166798, 0.4111184351918524, -6.829176411984103, 0.3361386406116716, -4.837760995294381, 0.2502764457319974, -3.37603312459292, 0.1626067927924462, -2.304361871960009, 0.08316396128852019, -1.525802347503765, 0.01755632843579077, -0.9670336043134922, -0.03330222974734559, 0.5708045845795261, 0.07150324591409365, -0.2923816210281723, -0.1003945101884875, -0.09727229178655826, -0.1234001397404901, 0.04066183518259721, 0.1434628037600845, -0.1409083950734027, 0.1628660783751044, 0.2178168134361163, 0.1832999676758237, 0.2819041405558238, -0.2060026677157682, -0.3409546634835108, -0.2319393727963857, -0.4009411424908401, 0.2619589247865226, -0.4668200628062795, -0.296933951573955, -0.5432787484033776, -0.3378788989574256, 0.6355506795869581, -0.3860209451465164, -0.7505093709414847, -5.105954891950948, -8.781352077679234, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452.3304115985688, -960.7608316563131, -498.9493530569109, 0.2350526026148503, 5.452765778836735, 0.1144413317324554, 3.942743416705443, 0.06575193956155491, 2.813198060193881, 0.05979656827468521, 1.967247253532042, 0.07476481999950792, 1.33716927453409, 0.09679248669884244, 0.8715028539151225, -0.1184142632347635, -0.5297539525430655, 0.1364376500843866, 0.279883315023392, 0.1501362016677295, 0.0967277743463185, 0.1600101117691853, 0.0392623455333137, -0.1670646460060667, 0.1431394010753874, 0.1724122128993197, 0.2264583241675105, 0.1770984549392259, -0.2981564198474064, -0.1820260600993679, -0.3653319148757525, -0.1879277629602221, 0.433953340411416, -0.1953399947167113, -0.509568285645821, -0.2045344918635905, -0.5981230469754966, 0.2153519198444021, -0.7071121725209079, -0.2267809863092065, -6.916134867991262, -4.577761093605716, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -457.2821812366932, -960.4249791586459, -508.406803593705, 0.3314600419524246, -3.131681676256192, 0.2387019139078725, -2.160834219382301, 0.1558482495866747, -1.455216313053963, 0.0871664614814559, -0.9473663287775979, 0.03419837662062589, -0.5864332248384088, -0.00432458333663224, 0.3329441537673535, 0.03128353627523617, -0.1562804280922136, -0.04999176058110387, -0.03302664185232766, -0.06346986930062509, 0.05440406541970694, 0.07411879158850035, -0.1190014687949248, 0.08368929303132233, 0.170242902230307, 0.09336390814052453, 0.2150244781654537, -0.1038994057814532, -0.2584450235024301, -0.1157578492126067, -0.3044688209695106, 0.1292115445076401, -0.3565100159947209, -0.144401977523982, -0.4180074998279228, -0.1613341173509704, 0.4930955968984639, -0.1797468301316631, -0.5875758018381303, -2.883918681365754, -6.475332235697652, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455.0155128763931, -960.1981319999863, -502.3405067762259, 0.2542491852062611, 3.131489617552865, 0.1670909868692584, 2.252853211778165, 0.1252928337711295, 1.589512082778476, 0.1095856577497441, 1.091340808355062, 0.1069182126000217, 0.7200044935476559, -0.1094190566032491, -0.4450831238377702, 0.1128668647285452, 0.242278665253527, 0.1152987829103931, 0.09231415427747117, 0.1160486567327278, 0.0199468566918988, -0.1151073353429353, 0.1062892592500759, 0.1127688588569004, 0.1758680910212436, 0.1094184084764459, -0.2358574126255636, -0.1054171918706391, -0.2920380304032841, -0.1010121781961295, 0.3493514987155218, -0.09624584560739964, -0.4124750394872714, -0.09081842264154093, -0.4865154108104184, 0.08383114316573474, -0.5780232680965639, -0.07323520324207744, -5.417494102776475, -2.610329978177295, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -457.4493352528837, -959.989698663586, -507.1401709474283, 0.286121368416555, -1.277585644216466, 0.1965314549725704, -0.8296361757391397, 0.126150204699882, -0.5143609771621193, 0.07411570076725935, -0.2955753603877085, 0.03772510850741548, 0.1456031206933647, -0.01346154359781873, -0.04333286374184881, -0.002152095041771392, 0.02709212845432325, -0.01203934086886425, 0.07735364223423614, 0.0184196895883106, -0.1159068759281938, 0.02282300685654621, 0.1487971666617892, 0.0262064128753012, 0.1803514533516238, -0.02907864514102102, -0.2137591327763108, -0.03161342078618522, -0.2515671959433391, 0.03371538499219204, -0.296132352891611, -0.0350175049709756, -0.3500936488703787, -0.03478013453039555, 0.4169709529674968, -0.03159734770668429, -0.5021045752952693, -1.359189375072352, -5.137658691990629, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.1816434524407, -959.8717700049582, -503.9632365405722, 0.2710790852321758, 1.868103062408168, 0.201731258488131, 1.336518241630041, 0.1607751340471668, 0.9312150774562233, 0.136744864573931, 0.6245135082334604, -0.1220039814863793, -0.3939736948288325, 0.1118064051450731, 0.2212852465254199, 0.1033807000084225, 0.09161715516324435, 0.09519253715708004, 0.006912715432142194, -0.08645745594199336, 0.08374228844933723, 0.07681239647201249, 0.1463556032104103, 0.06610891321647951, -0.2007459498469933, -0.05425819168043056, -0.2518586281471307, -0.0410971094331229, 0.3040320723461977, -0.02624784596427822, -0.3614859250552229, -0.00891781755958999, -0.4289462964027577, -0.01244251094956762, -0.5126072586924517, 0.0408259308513107, -4.58392784156386, -1.246428269166816, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -457.3475780693374, -959.8013715842148, -506.3396543584333, 0.2767928687754797, -0.3507679094211566, 0.1964561308894208, -0.175454380884666, 0.1369018349817932, -0.06171313754209207, 0.0948996407982716, -0.01057868944381583, -0.06660941623334156, 0.05625273023108911, 0.04841249702381548, 0.08604193382443961, 0.03731356346471822, 0.1075373379529352, -0.03107613794426697, -0.1259926823207867, -0.02817283438261568, 0.1449896389440946, -0.02768249041446454, 0.1669869201040142, 0.0291682437735234, -0.1937749805283248, 0.03258348528255475, -0.2268682319663226, -0.03823766887670215, -0.2678770945127273, 0.0468458004168191, -0.318925108122332, 0.05970717770473746, 0.3832225686061499, 0.07913811719945757, -0.4660307877839935, -0.283439945606522, -4.418862273762176, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.6253594082521, -959.785934980976, -504.6940382140627, 0.2905146476860859, 1.164315682401765, 0.2287874192618208, 0.8278901909084367, 0.1855742595690876, 0.5670794972681463, -0.1543255466444327, -0.3664024755348232, 0.1304088025212251, 0.2126108080946933, 0.1106574375165147, 0.09451778970188139, 0.09297359092819958, -0.00282311457116445, -0.07598524984762452, 0.07011698901922347, 0.05880426133990931, 0.1305654348080172, 0.04082738142446098, -0.1837050518882388, -0.02156733869032677, -0.2339588783576583, -0.0004920786516655548, 0.2853442102851388, 0.02315710617373445, -0.3419026525153549, 0.05062046787596538, -0.4082936953470016, -0.08404423049499717, -0.4907590591221084, 0.1273101919619071, -4.206720311439787, -0.3002127507778516, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -457.1342767647928, -959.8106159477925, -505.8018624707027, 0.2900898798822178, 0.09138444482380856, 0.2187118527593231, 0.1292492004000186, 0.1662045097025605, -0.1438635095448789, -0.1291313858324679, 0.146482412369866, 0.104009216338187, 0.1447220224795449, 0.08785328495101051, 0.1435558243554511, -0.07835861397425346, -0.1461036208296098, -0.07391291396692715, 0.1542496939603918, -0.07351683292489485, 0.1691302490659806, 0.07668777947971103, -0.191528688062261, 0.08339243901741469, -0.2222158695109802, -0.09404049750512089, -0.262283667277891, 0.1095744988108133, -0.3135425638449527, 0.1317142932715506, 0.3791044132771236, 0.1635054212875869, -0.4644162154949849, 0.4754117380195617, -4.133127727067452, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.7075938580194, -959.859187561279, -504.9641545879152, 0.3112115826946246, 0.7603819900412184, 0.2515787922254607, 0.5346525976842389, -0.2046698188884306, -0.3549498970832715, 0.1667993851467113, 0.2128194443512869, 0.1349829906843502, 0.1004097453865731, 0.1069128978938258, -0.01069617548430252, -0.08086180012056307, 0.06245121559445837, 0.05554789383536447, 0.1243240851970876, 0.02998652907082099, -0.1795147550946357, -0.003335227685768387, -0.232122564808795, 0.02527939571162375, 0.2860328739068638, 0.05697314553891727, -0.3453056616278151, 0.09340770900657025, -0.4147626826939698, -0.1373004236343103, -0.5009888584183517, 0.1933830034629809, -4.165639675833453, 0.3383554269676927, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.8782696374187, -959.9297648403151, -505.4159286188464, 0.3121561806109645, 0.2822056061123752, 0.247980497057797, -0.2569956304425891, -0.1998295916895239, 0.2284297348242049, 0.1650722678022543, 0.2029125660834568, 0.1410884792635043, 0.1841746600175908, -0.1256771230171495, -0.174184152010238, -0.1171886991653117, 0.1738211936975961, -0.1145301840222644, 0.1833868779235939, 0.1171275690499658, -0.2030007615539205, 0.1248977602701297, -0.2329370726129333, -0.1382764499321328, -0.27395747110102, 0.1583471608991634, -0.3277192476797476, 0.1871380238475298, 0.3974011701543539, 0.2282921486952801, -0.4888358484669846, 0.9965699211078363, -4.174355176167373, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.6116649438044, -960.0038871245156, -505.0023454177997, 0.3295930205438109, 0.5143442094150634, -0.2695356906932027, -0.3518849459077303, 0.2184195529530754, 0.2177473194353936, 0.1742696183299925, 0.107588929061941, 0.1351123343048535, -0.01670816731731302, -0.09919323231873232, 0.05953720029339046, 0.06503073496805913, 0.125532380449224, 0.03137214041729913, -0.1853658264427238, 0.002916428236328955, -0.2429142837357705, 0.03901258336924512, 0.3020465696948311, 0.07836548079886681, -0.3669787240345666, 0.1230474258479728, -0.4428645014247397, -0.1763255542849716, -0.5368662993446999, 0.2437700678950443, -4.391525855268358, 0.7382567408086977, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.6126089063781, -960.0836158047517, -505.1187555600291, 0.3334848577914001, -0.348428051728459, -0.2752367222186492, 0.3006944638633078, 0.2302721093152811, 0.2591967524250096, 0.1970876226025629, 0.2278690906060197, -0.1740115500094767, -0.2085463212280925, -0.1595867622233282, 0.2018162461301135, -0.1527406251408078, 0.2076385119268662, 0.1528504282670753, -0.2258110308909343, 0.1597827219954589, -0.2563523040186093, -0.173969694548823, -0.2998702186943654, 0.1965747840879211, -0.3580175279469813, 0.229863604568186, 0.4341837938265395, 0.277970170008693, -0.5347627558106645, 1.329764914690779, -4.483596648143033, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.4349056684294, -960.156647229524, -504.9319775147893, -0.3423523620698637, -0.3475550534848461, 0.2809466994778753, 0.2215706829932298, 0.2255846777578883, 0.1128246391312395, 0.1754514594654858, -0.01937340515435665, -0.1292864557086762, 0.06168462942056975, 0.08573413224271821, 0.1336954218460845, 0.04347198911094055, -0.2001906469386318, -0.00119376064663685, -0.2648271503726893, 0.04251266830607562, 0.3315045719474604, 0.0893994185444924, -0.4046778456006963, 0.1419228134888831, -0.4899638274253278, -0.2038944668407005, -0.5952966220065167, 0.2817106712351145, -4.848415701454543, 0.9427020574859393, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.3526903101317, -960.2239683681914, 504.8729234307502, -0.3489451907029376, 0.3589886699197148, 0.2961466969614354, 0.310480710370148, 0.2543129428137268, 0.2722939468109425, -0.2230677496498586, -0.2472988907469534, -0.2016181817997352, 0.2366019906197148, -0.1891922917107881, 0.2403800750135453, 0.1852769979754018, -0.2584933857871972, 0.1897672879791922, -0.2909693456884552, -0.2031063479701883, -0.3384573551697876, 0.226529417912314, -0.4027594406465836, 0.2624902798236902, 0.4876253939462449, 0.3155583157701459, -0.6001811424846641, 1.506088170407175, -5.032413448243027, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 456.2281437872571, -960.2817251702837, -504.8181052368888, -0.3473974178704272, -0.2160721566413612, -0.2844115901002985, -0.1109673640897398, -0.2249663433659822, 0.01558619777087037, 0.1691160884458819, -0.07065303999293307, -0.1161602619016208, -0.1496942207346384, -0.06504337994709028, 0.2242986455097327, 0.01449731249119731, 0.2977971368954605, -0.03700838008878649, -0.3740870837044805, -0.09144942901497075, 0.457896128782557, -0.1516347645680779, 0.5553971193015861, 0.221891957236842, 0.6754711755316094, -0.3094582971264419, 5.522765460179463, -0.97751110694022, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -456.1038688686278, -960.3270004185782, 504.6545436979824, -0.356402682870272, -0.351340066980498, -0.309181275719597, -0.3137167192606073, 0.2710350810973345, 0.2878350893000941, 0.2426229671933997, -0.2763168527076123, 0.2239747467509561, -0.280241947819618, -0.214997170417235, 0.3000011000597085, -0.2157829211419849, 0.3359590943512027, 0.2268880461285561, 0.3890394964897786, -0.2496482263626514, 0.4613794461017247, -0.2867172754999331, -0.5572551598551461, -0.3430608494894536, 0.6847182926632671, -1.544015999089003, 5.81277117568367, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 456.0159328177219, -960.3639010644911, -504.6932803542561, 0.3438026307622749, 0.09449263891861819, 0.2791924853298788, -0.0003950261355616105, -0.2158018381788221, 0.08970415379288814, 0.1544060725265021, 0.1757031383879306, 0.09475353685250953, -0.2591866322084164, -0.03594501565049272, -0.3429135694153541, 0.02344530556719954, 0.4306584188832464, 0.08549582247561358, -0.5273917016008263, 0.1532791130988579, -0.6399042657976388, -0.2316168130063649, -0.778179175299526, 0.3285885099115871, -6.416369594901841, 0.8564491667855068, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455.8653704619311, -960.3842612497629, -504.4466252991523, 0.3553710744569122, 0.3464161627180581, -0.3141480426464132, -0.3263434732993854, -0.2805185077726005, 0.318452179605292, -0.2561088381842067, 0.3256076632881188, 0.2417423068618511, -0.3493440004841665, 0.2380375239176739, -0.3907849327216811, -0.2458444207499498, -0.4514338824492233, 0.2667224509879774, -0.5339931109453619, 0.3035639225688179, 0.6434745768399498, 0.3617520533213044, -0.7890836608012997, 1.453287590263238, -6.830587030361006, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455.8082369972718, -960.3994442233231, -504.5727798070742, 0.3313951499504466, 0.03334672491870352, -0.2650323687322864, 0.1237756771616079, 0.1977229200322088, 0.2152372282453819, 0.1308144824330917, -0.3074811043383469, -0.06431874746251602, -0.4022833530695494, 0.002753039484875582, 0.5030555348702184, 0.07234641380894129, -0.6149136653510678, 0.147681447081999, -0.7452813394287314, -0.2340032399414377, -0.9053839955214958, 0.3402398000888476, -7.541821253164034, 0.5849103543979055, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455.6329040043291, -960.3950114540172, -504.2353754001218, -0.3460929449122671, -0.3573008762499605, -0.3114301376926339, 0.3594512386076111, -0.2833177549503088, 0.3742883157355104, 0.2642891667618492, -0.4053000240462633, 0.2559854273447855, -0.4549386843075994, -0.2598956392005766, -0.5256874172585198, 0.2779895068618159, -0.6211224810880993, 0.313525507512514, 0.7472565377041231, 0.3723660978852033, -0.9147314187079836, 1.237565421662729, -8.101822161846965, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455.6073466604758, -960.3894853751993, 504.4633572926642, -0.3103733552874035, 0.1798092000949148, 0.2419934417708158, 0.2733274466086066, 0.170608369891661, -0.3730126262676927, -0.09792141422899953, -0.4790220884834106, -0.02392951925676049, 0.5940246336099106, 0.05285511329060938, -0.72308359247846, 0.1355803277369181, -0.8742174899740623, -0.2298115577107615, -1.060011360233898, 0.3453065574734215, -8.919981193604276, 0.1624134764758667, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455.4000921853053, -960.361309464515, -504.007882194183, 0.3290914395050692, -0.3942786634383071, 0.3016661987186222, -0.4232028367455296, -0.2802278665379578, 0.4661762517445954, -0.2682364496083171, 0.5277412575464714, 0.2683110547053154, 0.6119088573807965, -0.2831724063939194, 0.7235386787769833, -0.3166483539775581, -0.8699916087218257, -0.3752194315750562, 1.063702555577482, -0.8961354452926642, 9.650619636505867, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455.411737801223, -960.33634002581, -504.3683031089997, -0.2810675792469359, -0.3568683235024433, -0.2101973773067176, 0.4610263218581945, 0.1342569173742763, 0.5773846640444537, 0.0549895002126496, -0.7072872888655298, -0.02810812468448988, 0.8554232500908963, -0.1177949641523385, 1.030291473272884, 0.2197751447614384, 1.245920882288997, -0.3445848993688538, 10.57920381944338, 0.4160829872124499, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -455.1591691278096, -960.2853155130464, 503.7506267530316, 0.3049590480459953, -0.4680278418562256, -0.2856076919532088, 0.5295716933187377, -0.2723080782051216, 0.6081924100973243, 0.2695854300651085, 0.7101704945576234, -0.2814097861384926, 0.8422035444139073, -0.3125162969328145, -1.013460137059419, -0.3702351580276053, 1.238618787929362, -0.4245068253530189, 11.50934860393606, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455.2183025514214, -960.2418420556575, 504.2904567527979, 0.2437489235262463, -0.5785902355402166, -0.1696099295696916, -0.7030543018352547, -0.08807726217552897, 0.8477643119258153, -0.0003803922022015914, -1.016538148397893, 0.09536127235557913, -1.218135087789733, -0.2047067633976007, -1.468068679276456, 0.3388478362779086, -12.55632491341529, -1.160129556695031, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454.9011576326581, -960.1679733535419, 503.4480310997173, -0.2743159215154021, 0.59210690664036, -0.2642341403577922, 0.6948327035340854, 0.2611611633095301, 0.820468994814445, -0.2710734389097403, 0.9783065442168752, -0.3001250829922114, -1.179929020129721, -0.3568752809307986, 1.442834925435452, 0.1861860221886378, 13.72072654131889, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455.0234951961737, -960.1065185460631, -504.2341761382918, -0.1985155387376615, -0.8636702893987938, -0.1197570863030018, 1.022005815169442, -0.03046148161363051, -1.212498738675283, 0.06965185900521845, -1.44380567993779, -0.1855411271964486, -1.732900209415532, 0.3288765751169174, -14.89970702904785, -2.085331319125681, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454.6155022554338, -960.0090394364709, 503.080419120223, 0.2378578162407876, -0.7855779404374899, -0.2389268322384859, -0.9427265300586574, 0.2493889345428649, -1.133389617235434, 0.2776001160195384, 1.372380149780934, 0.3338733668864364, -1.680779007748177, -0.9514699644735849, -16.34248127983827, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454.8236752088293, -959.9291937205099, 504.2068595622975, 0.1450192700206833, -1.238921588152978, 0.05908037491561525, 1.451502248422423, -0.04247506464443443, 1.715440182112174, 0.1633637326099601, 2.049030098342237, -0.3153926679720489, 17.67488245777389, 3.216886963304409, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454.2888780517075, -959.8060141768642, 502.6209139189659, -0.1963783784418207, -1.07681015710693, 0.2118129088940946, -1.30957289263114, 0.2416506844030767, 1.594926385284288, 0.2987764905571196, -1.958528602633205, -1.89790052548914, -19.45550897611078, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454.6150435510897, -959.7057073918052, -504.2207918385922, 0.08191276561459389, 1.744978959223401, -0.01623102385292412, 2.044325279439126, 0.139362395300141, 2.428380353063932, -0.2989187527977135, 20.97397716279267, 4.596081079911148, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453.9030102952942, -959.5514771839804, -502.0302313735755, -0.1509069873047727, 1.509921737993699, -0.1866506960156188, -1.853460072170985, -0.2470701568585754, 2.284756111156089, 3.070922511010462, 23.1773864785971, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -454.393273204417, -959.4263564611852, 504.2962075579032, 0.005942404933789297, 2.446660862635643, 0.1147302269971472, 2.888007099445928, -0.2794135351323237, 24.93107187619451, 6.291448555715359, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 453.4308183834945, -959.2306762470356, 501.2467662460859, 0.1030197566665109, 2.15672544959436, 0.1707450834055513, -2.672257869508826, -4.548465509453017, -27.68489865384783, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 454.1521964870133, -959.071043583621, 504.4663679395445, 0.09038098396525029, 3.453184686592636, -0.2556696326547585, 29.74790742438, 8.418178566025752, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 452.828604749646, -958.8118098643598, -500.1677840008083, 0.05562336274628601, -3.140588015388957, -6.465358070370396, -33.25328104675387, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -453.8814454933349, -958.5973523296369, -504.7879798529249, 0.2240186812962395, -35.739305932474, -11.17424401632893, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -452.0207842240151, -958.2280932680816, 498.6099988306628, -9.061273073482408, -40.32955903922403, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 453.5608878051024, -957.9144120234951, 542.7656821084641, 14.91304502929086, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 450.8656330991661, -969.8578951037719, 452.1887612775597, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 787.8967774818433, -898.9789215779133, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + }, + evWant: []complex128{ + 1, + 2, + -0.8238783640171078 + 1.579766228862017i, + -0.8238783640171078 - 1.579766228862017i, + -3.922907917607387 + 1.654540870297146i, + -3.922907917607387 - 1.654540870297146i, + -10.04176861796659 + 1.651471031280953i, + -10.04176861796659 - 1.651471031280953i, + -19.90533512613429 + 1.64196864045227i, + -19.90533512613429 - 1.64196864045227i, + -33.60610872827028 + 1.635560741682501i, + -33.60610872827028 - 1.635560741682501i, + -51.10943733404228 + 1.631805014774364i, + -51.10943733404228 - 1.631805014774364i, + -72.34919707090897 + 1.629522740505929i, + -72.34919707090897 - 1.629522740505929i, + -97.24021794530901 + 1.628064860261413i, + -97.24021794530901 - 1.628064860261413i, + -125.6811625494976 + 1.627074041605065i, + -125.6811625494976 - 1.627074041605065i, + -157.5556174346503 + 1.626392967840776i, + -157.5556174346503 - 1.626392967840776i, + -192.732837945876 + 1.625893674037654i, + -192.732837945876 - 1.625893674037654i, + -231.0684238575969 + 1.625523897559938i, + -231.0684238575969 - 1.625523897559938i, + -272.404932676379 + 1.625248463045784i, + -272.404932676379 - 1.625248463045784i, + -316.5725618120467 + 1.625029322230836i, + -316.5725618120467 - 1.625029322230836i, + -363.3898435346347 + 1.624863705104029i, + -363.3898435346347 - 1.624863705104029i, + -412.6644183160402 + 1.624734783685709i, + -412.6644183160402 - 1.624734783685709i, + -464.1938275598905 + 1.624629407600858i, + -464.1938275598905 - 1.624629407600858i, + -517.7663337295413 + 1.624555040627727i, + -517.7663337295413 - 1.624555040627727i, + -573.1617958392867 + 1.62448889134649i, + -573.1617958392867 - 1.62448889134649i, + -630.1525854166166 + 1.624445355378192i, + -630.1525854166166 - 1.624445355378192i, + -688.5045249303587 + 1.624414401302088i, + -688.5045249303587 - 1.624414401302088i, + -747.9778126976437 + 1.624396390555459i, + -747.9778126976437 - 1.624396390555459i, + -808.3280706224909 + 1.62438480760184i, + -808.3280706224909 - 1.62438480760184i, + -869.3072903249724 + 1.624387678902335i, + -869.3072903249724 - 1.624387678902335i, + -930.6648831979091 + 1.624396130880259i, + -930.6648831979091 - 1.624396130880259i, + -992.1487134378474 + 1.624417808682915i, + -992.1487134378474 - 1.624417808682915i, + -1053.506114553354 + 1.624453056189826i, + -1053.506114553354 - 1.624453056189826i, + -1114.484928198698 + 1.62449544649428i, + -1114.484928198698 - 1.62449544649428i, + -1174.834554234014 + 1.624553207269019i, + -1174.834554234014 - 1.624553207269019i, + -1234.306981514973 + 1.624623553438826i, + -1234.306981514973 - 1.624623553438826i, + -1292.657768972259 + 1.624709216827242i, + -1292.657768972259 - 1.624709216827242i, + -1349.647106741638 + 1.624814444572517i, + -1349.647106741638 - 1.624814444572517i, + -1405.040739357668 + 1.624951632752096i, + -1405.040739357668 - 1.624951632752096i, + -1458.610953350783 + 1.625104547041682i, + -1458.610953350783 - 1.625104547041682i, + -1510.137508646807 + 1.625304666073007i, + -1510.137508646807 - 1.625304666073007i, + -1559.408520122221 + 1.625548293255404i, + -1559.408520122221 - 1.625548293255404i, + -1606.221305250554 + 1.625851986073836i, + -1606.221305250554 - 1.625851986073836i, + -1650.383201531125 + 1.62624202844641i, + -1650.383201531125 - 1.62624202844641i, + -1691.712315735984 + 1.6267345498979i, + -1691.712315735984 - 1.6267345498979i, + -1730.038177420971 + 1.627388968656263i, + -1730.038177420971 - 1.627388968656263i, + -1765.20230058066 + 1.628268412022146i, + -1765.20230058066 - 1.628268412022146i, + -1797.05860162894 + 1.629473972633416i, + -1797.05860162894 - 1.629473972633416i, + -1825.473493639258 + 1.631220665229006i, + -1825.473493639258 - 1.631220665229006i, + -1850.32542664842 + 1.633834593918563i, + -1850.32542664842 - 1.633834593918563i, + -1871.503056018116 + 1.637993570641514i, + -1871.503056018116 - 1.637993570641514i, + -1888.90026514681 + 1.64508855982818i, + -1888.90026514681 - 1.64508855982818i, + -1902.402515327158 + 1.658179541614067i, + -1902.402515327158 - 1.658179541614067i, + -1911.858940404498 + 1.682209391409579i, + -1911.858940404498 - 1.682209391409579i, + -1916.92602113601 + 1.761877988650816i, + -1916.92602113601 - 1.761877988650816i, + -1930.484166851586 + 1.202676762393897i, + -1930.484166851586 - 1.202676762393897i, + 3, + 4, + }, + }, +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlabrd.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlabrd.go new file mode 100644 index 00000000..460cefe7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlabrd.go @@ -0,0 +1,107 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" +) + +type Dlabrder interface { + Dlabrd(m, n, nb int, a []float64, lda int, d, e, tauq, taup, x []float64, ldx int, y []float64, ldy int) +} + +func DlabrdTest(t *testing.T, impl Dlabrder) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, nb, lda, ldx, ldy int + }{ + {4, 5, 2, 0, 0, 0}, + {4, 5, 4, 0, 0, 0}, + {5, 5, 2, 0, 0, 0}, + {5, 5, 5, 0, 0, 0}, + {5, 4, 4, 0, 0, 0}, + {5, 4, 4, 0, 0, 0}, + + {4, 5, 2, 10, 11, 12}, + {4, 5, 4, 10, 11, 12}, + {5, 5, 2, 10, 11, 12}, + {5, 5, 5, 10, 11, 12}, + {5, 4, 2, 10, 11, 12}, + {5, 4, 4, 10, 11, 12}, + + {4, 5, 2, 11, 12, 10}, + {4, 5, 4, 11, 12, 10}, + {5, 5, 2, 11, 12, 10}, + {5, 5, 5, 11, 12, 10}, + {5, 4, 2, 11, 12, 10}, + {5, 4, 4, 11, 12, 10}, + + {4, 5, 2, 12, 11, 10}, + {4, 5, 4, 12, 11, 10}, + {5, 5, 2, 12, 11, 10}, + {5, 5, 5, 12, 11, 10}, + {5, 4, 2, 12, 11, 10}, + {5, 4, 4, 12, 11, 10}, + } { + m := test.m + n := test.n + nb := test.nb + lda := test.lda + if lda == 0 { + lda = n + } + ldy := test.ldy + if ldy == 0 { + ldy = nb + } + ldx := test.ldx + if ldx == 0 { + ldx = nb + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + d := make([]float64, nb) + for i := range d { + d[i] = math.NaN() + } + e := make([]float64, nb) + for i := range e { + e[i] = math.NaN() + } + tauP := make([]float64, nb) + for i := range tauP { + tauP[i] = math.NaN() + } + tauQ := make([]float64, nb) + for i := range tauP { + tauQ[i] = math.NaN() + } + x := make([]float64, m*ldx) + for i := range x { + x[i] = rnd.NormFloat64() + } + y := make([]float64, n*ldy) + for i := range y { + y[i] = rnd.NormFloat64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + // Compute the reduction. + impl.Dlabrd(m, n, nb, a, lda, d, e, tauQ, tauP, x, ldx, y, ldy) + + if m >= n && nb == n { + tauP[n-1] = 0 + } + if m < n && nb == m { + tauQ[m-1] = 0 + } + checkBidiagonal(t, m, n, nb, a, lda, d, e, tauP, tauQ, aCopy) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlacn2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlacn2.go new file mode 100644 index 00000000..9e76c0b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlacn2.go @@ -0,0 +1,72 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlacn2er interface { + Dlacn2(n int, v, x []float64, isgn []int, est float64, kase int, isave *[3]int) (float64, int) +} + +func Dlacn2Test(t *testing.T, impl Dlacn2er) { + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{1, 2, 3, 4, 5, 7, 10, 15, 20, 100} { + for cas := 0; cas < 10; cas++ { + a := randomGeneral(n, n, n, rnd) + + // Compute the 1-norm of A explicitly. + var norm1 float64 + for j := 0; j < n; j++ { + var sum float64 + for i := 0; i < n; i++ { + sum += math.Abs(a.Data[i*a.Stride+j]) + } + if sum > norm1 { + norm1 = sum + } + } + + // Compute the estimate of 1-norm using Dlanc2. + x := make([]float64, n) + work := make([]float64, n) + v := make([]float64, n) + isgn := make([]int, n) + var ( + kase int + isave [3]int + got float64 + ) + loop: + for { + got, kase = impl.Dlacn2(n, v, x, isgn, got, kase, &isave) + switch kase { + default: + panic("Dlacn2 returned invalid value of kase") + case 0: + break loop + case 1: + blas64.Gemv(blas.NoTrans, 1, a, blas64.Vector{1, x}, 0, blas64.Vector{1, work}) + copy(x, work) + case 2: + blas64.Gemv(blas.Trans, 1, a, blas64.Vector{1, x}, 0, blas64.Vector{1, work}) + copy(x, work) + } + } + + // Check that got is either accurate enough or a + // lower estimate of the 1-norm of A. + if math.Abs(got-norm1) > 1e-8 && got > norm1 { + t.Errorf("Case n=%v: not lower estimate. 1-norm %v, estimate %v", n, norm1, got) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlacpy.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlacpy.go new file mode 100644 index 00000000..aa3e5e0f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlacpy.go @@ -0,0 +1,89 @@ +// 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 testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dlacpyer interface { + Dlacpy(uplo blas.Uplo, m, n int, a []float64, lda int, b []float64, ldb int) +} + +func DlacpyTest(t *testing.T, impl Dlacpyer) { + rnd := rand.New(rand.NewSource(1)) + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower, blas.All} { + for _, test := range []struct { + m, n, lda, ldb int + }{ + {3, 5, 0, 0}, + {5, 5, 0, 0}, + {7, 5, 0, 0}, + + {3, 5, 10, 12}, + {5, 5, 10, 12}, + {7, 5, 10, 12}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + ldb := test.ldb + if ldb == 0 { + ldb = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + b := make([]float64, m*ldb) + for i := range b { + b[i] = rnd.Float64() + } + impl.Dlacpy(uplo, m, n, a, lda, b, ldb) + equal := true + switch uplo { + case blas.Upper: + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + if b[i*ldb+j] != a[i*lda+j] { + equal = false + goto DoneCheck + } + } + } + case blas.Lower: + for i := 0; i < m; i++ { + for j := 0; j < min(i, n); j++ { + if b[i*ldb+j] != a[i*lda+j] { + equal = false + goto DoneCheck + } + } + } + case blas.All: + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + if b[i*ldb+j] != a[i*lda+j] { + equal = false + goto DoneCheck + } + } + } + } + DoneCheck: + if !equal { + fmt.Println(blas.Lower) + t.Errorf("Matrices not equal after copy. Uplo = %d, m = %d, n = %d", uplo, m, n) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlae2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlae2.go new file mode 100644 index 00000000..236b3f2b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlae2.go @@ -0,0 +1,53 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "testing" +) + +type Dlae2er interface { + Dlae2(a, b, c float64) (rt1, rt2 float64) +} + +func Dlae2Test(t *testing.T, impl Dlae2er) { + for _, test := range []struct { + a, b, c float64 + }{ + {-10, 5, 3}, + {3, 5, -10}, + {0, 3, 0}, + {1, 3, 1}, + {1, -3, 1}, + {5, 0, 3}, + {3, 0, -5}, + {1, 3, 1.02}, + {1.02, 3, 1}, + {1, -3, -9}, + } { + a := test.a + b := test.b + c := test.c + rt1, rt2 := impl.Dlae2(a, b, c) + + errStr := fmt.Sprintf("a = %v, b = %v, c = %v", a, b, c) + // Check if rt1 and rt2 are eigenvalues by checking if det(a - λI) = 0 + a1 := a - rt1 + c1 := c - rt1 + det := a1*c1 - b*b + if math.Abs(det) > 1e-10 { + t.Errorf("First eigenvalue mismatch. %s. Det = %v", errStr, det) + } + + a2 := a - rt2 + c2 := c - rt2 + det = a2*c2 - b*b + if math.Abs(det) > 1e-10 { + t.Errorf("Second eigenvalue mismatch. %s. Det = %v", errStr, det) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaev2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaev2.go new file mode 100644 index 00000000..3aea2d74 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaev2.go @@ -0,0 +1,46 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" +) + +type Dlaev2er interface { + Dlaev2(a, b, c float64) (rt1, rt2, cs1, sn1 float64) +} + +func Dlaev2Test(t *testing.T, impl Dlaev2er) { + rnd := rand.New(rand.NewSource(1)) + for trial := 0; trial < 100; trial++ { + a := rnd.NormFloat64() + b := rnd.NormFloat64() + c := rnd.NormFloat64() + + rt1, rt2, cs1, sn1 := impl.Dlaev2(a, b, c) + tmp := mul2by2([2][2]float64{{cs1, sn1}, {-sn1, cs1}}, [2][2]float64{{a, b}, {b, c}}) + ans := mul2by2(tmp, [2][2]float64{{cs1, -sn1}, {sn1, cs1}}) + if math.Abs(ans[0][0]-rt1) > 1e-14 { + t.Errorf("Largest eigenvalue mismatch. Returned %v, mul %v", rt1, ans[0][0]) + } + if math.Abs(ans[1][0]) > 1e-14 || math.Abs(ans[0][1]) > 1e-14 { + t.Errorf("Non-zero off diagonal. ans[1][0] = %v, ans[0][1] = %v", ans[1][0], ans[0][1]) + } + if math.Abs(ans[1][1]-rt2) > 1e-14 { + t.Errorf("Smallest eigenvalue mismatch. Returned %v, mul %v", rt2, ans[1][1]) + } + } +} + +func mul2by2(a, b [2][2]float64) [2][2]float64 { + var c [2][2]float64 + c[0][0] = a[0][0]*b[0][0] + a[0][1]*b[1][0] + c[0][1] = a[0][0]*b[0][1] + a[0][1]*b[1][1] + c[1][0] = a[1][0]*b[0][0] + a[1][1]*b[1][0] + c[1][1] = a[1][0]*b[0][1] + a[1][1]*b[1][1] + return c +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaexc.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaexc.go new file mode 100644 index 00000000..e69f41d8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaexc.go @@ -0,0 +1,227 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/cmplx" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlaexcer interface { + Dlaexc(wantq bool, n int, t []float64, ldt int, q []float64, ldq int, j1, n1, n2 int, work []float64) bool +} + +func DlaexcTest(t *testing.T, impl Dlaexcer) { + rnd := rand.New(rand.NewSource(1)) + + for _, wantq := range []bool{true, false} { + for _, n := range []int{1, 2, 3, 4, 5, 6, 10, 18, 31, 53} { + for _, extra := range []int{0, 1, 11} { + for cas := 0; cas < 100; cas++ { + j1 := rnd.Intn(n) + n1 := min(rnd.Intn(3), n-j1) + n2 := min(rnd.Intn(3), n-j1-n1) + testDlaexc(t, impl, wantq, n, j1, n1, n2, extra, rnd) + } + } + } + } +} + +func testDlaexc(t *testing.T, impl Dlaexcer, wantq bool, n, j1, n1, n2, extra int, rnd *rand.Rand) { + const tol = 1e-14 + + tmat := randomGeneral(n, n, n+extra, rnd) + // Zero out the lower triangle. + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + tmat.Data[i*tmat.Stride+j] = 0 + } + } + // Make any 2x2 diagonal block to be in Schur canonical form. + if n1 == 2 { + // Diagonal elements equal. + tmat.Data[(j1+1)*tmat.Stride+j1+1] = tmat.Data[j1*tmat.Stride+j1] + // Off-diagonal elements of opposite sign. + c := rnd.NormFloat64() + if math.Signbit(c) == math.Signbit(tmat.Data[j1*tmat.Stride+j1+1]) { + c *= -1 + } + tmat.Data[(j1+1)*tmat.Stride+j1] = c + } + if n2 == 2 { + // Diagonal elements equal. + tmat.Data[(j1+n1+1)*tmat.Stride+j1+n1+1] = tmat.Data[(j1+n1)*tmat.Stride+j1+n1] + // Off-diagonal elements of opposite sign. + c := rnd.NormFloat64() + if math.Signbit(c) == math.Signbit(tmat.Data[(j1+n1)*tmat.Stride+j1+n1+1]) { + c *= -1 + } + tmat.Data[(j1+n1+1)*tmat.Stride+j1+n1] = c + } + tmatCopy := cloneGeneral(tmat) + var q, qCopy blas64.General + if wantq { + q = eye(n, n+extra) + qCopy = cloneGeneral(q) + } + work := nanSlice(n) + + ok := impl.Dlaexc(wantq, n, tmat.Data, tmat.Stride, q.Data, q.Stride, j1, n1, n2, work) + + prefix := fmt.Sprintf("Case n=%v, j1=%v, n1=%v, n2=%v, wantq=%v, extra=%v", n, j1, n1, n2, wantq, extra) + + if !generalOutsideAllNaN(tmat) { + t.Errorf("%v: out-of-range write to T", prefix) + } + if wantq && !generalOutsideAllNaN(q) { + t.Errorf("%v: out-of-range write to Q", prefix) + } + + if !ok { + if n1 == 1 && n2 == 1 { + t.Errorf("%v: unexpected failure", prefix) + } else { + t.Logf("%v: Dlaexc returned false", prefix) + } + } + + if !ok || n1 == 0 || n2 == 0 || j1+n1 >= n { + // Check that T is not modified. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if tmat.Data[i*tmat.Stride+j] != tmatCopy.Data[i*tmatCopy.Stride+j] { + t.Errorf("%v: ok == false but T[%v,%v] modified", prefix, i, j) + } + } + } + if !wantq { + return + } + // Check that Q is not modified. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if q.Data[i*q.Stride+j] != qCopy.Data[i*qCopy.Stride+j] { + t.Errorf("%v: ok == false but Q[%v,%v] modified", prefix, i, j) + } + } + } + return + } + + // Check that T is not modified outside of rows and columns [j1:j1+n1+n2]. + for i := 0; i < n; i++ { + if j1 <= i && i < j1+n1+n2 { + continue + } + for j := 0; j < n; j++ { + if j1 <= j && j < j1+n1+n2 { + continue + } + diff := tmat.Data[i*tmat.Stride+j] - tmatCopy.Data[i*tmatCopy.Stride+j] + if diff != 0 { + t.Errorf("%v: unexpected modification of T[%v,%v]", prefix, i, j) + } + } + } + + if n1 == 1 { + // 1×1 blocks are swapped exactly. + got := tmat.Data[(j1+n2)*tmat.Stride+j1+n2] + want := tmatCopy.Data[j1*tmatCopy.Stride+j1] + if want != got { + t.Errorf("%v: unexpected value of T[%v,%v]. Want %v, got %v", prefix, j1+n2, j1+n2, want, got) + } + } else { + // Check that the swapped 2×2 block is in Schur canonical form. + // The n1×n1 block is now located at T[j1+n2,j1+n2]. + a, b, c, d := extract2x2Block(tmat.Data[(j1+n2)*tmat.Stride+j1+n2:], tmat.Stride) + if !isSchurCanonical(a, b, c, d) { + t.Errorf("%v: 2×2 block at T[%v,%v] not in Schur canonical form", prefix, j1+n2, j1+n2) + } + ev1Got, ev2Got := schurBlockEigenvalues(a, b, c, d) + + // Check that the swapped 2×2 block has the same eigenvalues. + // The n1×n1 block was originally located at T[j1,j1]. + a, b, c, d = extract2x2Block(tmatCopy.Data[j1*tmatCopy.Stride+j1:], tmatCopy.Stride) + ev1Want, ev2Want := schurBlockEigenvalues(a, b, c, d) + if cmplx.Abs(ev1Got-ev1Want) > tol { + t.Errorf("%v: unexpected first eigenvalue of 2×2 block at T[%v,%v]. Want %v, got %v", + prefix, j1+n2, j1+n2, ev1Want, ev1Got) + } + if cmplx.Abs(ev2Got-ev2Want) > tol { + t.Errorf("%v: unexpected second eigenvalue of 2×2 block at T[%v,%v]. Want %v, got %v", + prefix, j1+n2, j1+n2, ev2Want, ev2Got) + } + } + if n2 == 1 { + // 1×1 blocks are swapped exactly. + got := tmat.Data[j1*tmat.Stride+j1] + want := tmatCopy.Data[(j1+n1)*tmatCopy.Stride+j1+n1] + if want != got { + t.Errorf("%v: unexpected value of T[%v,%v]. Want %v, got %v", prefix, j1, j1, want, got) + } + } else { + // Check that the swapped 2×2 block is in Schur canonical form. + // The n2×n2 block is now located at T[j1,j1]. + a, b, c, d := extract2x2Block(tmat.Data[j1*tmat.Stride+j1:], tmat.Stride) + if !isSchurCanonical(a, b, c, d) { + t.Errorf("%v: 2×2 block at T[%v,%v] not in Schur canonical form", prefix, j1, j1) + } + ev1Got, ev2Got := schurBlockEigenvalues(a, b, c, d) + + // Check that the swapped 2×2 block has the same eigenvalues. + // The n2×n2 block was originally located at T[j1+n1,j1+n1]. + a, b, c, d = extract2x2Block(tmatCopy.Data[(j1+n1)*tmatCopy.Stride+j1+n1:], tmatCopy.Stride) + ev1Want, ev2Want := schurBlockEigenvalues(a, b, c, d) + if cmplx.Abs(ev1Got-ev1Want) > tol { + t.Errorf("%v: unexpected first eigenvalue of 2×2 block at T[%v,%v]. Want %v, got %v", + prefix, j1, j1, ev1Want, ev1Got) + } + if cmplx.Abs(ev2Got-ev2Want) > tol { + t.Errorf("%v: unexpected second eigenvalue of 2×2 block at T[%v,%v]. Want %v, got %v", + prefix, j1, j1, ev2Want, ev2Got) + } + } + + if !wantq { + return + } + + if !isOrthonormal(q) { + t.Errorf("%v: Q is not orthogonal", prefix) + } + // Check that Q is unchanged outside of columns [j1:j1+n1+n2]. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if j1 <= j && j < j1+n1+n2 { + continue + } + diff := q.Data[i*q.Stride+j] - qCopy.Data[i*qCopy.Stride+j] + if diff != 0 { + t.Errorf("%v: unexpected modification of Q[%v,%v]", prefix, i, j) + } + } + } + // Check that Q^T TOrig Q == T. + tq := eye(n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmatCopy, q, 0, tq) + qtq := eye(n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, tq, 0, qtq) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + diff := qtq.Data[i*qtq.Stride+j] - tmat.Data[i*tmat.Stride+j] + if math.Abs(diff) > tol { + t.Errorf("%v: unexpected value of T[%v,%v]", prefix, i, j) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlags2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlags2.go new file mode 100644 index 00000000..2a3da46d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlags2.go @@ -0,0 +1,100 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dlags2er interface { + Dlags2(upper bool, a1, a2, a3, b1, b2, b3 float64) (csu, snu, csv, snv, csq, snq float64) +} + +func Dlags2Test(t *testing.T, impl Dlags2er) { + rnd := rand.New(rand.NewSource(1)) + for _, upper := range []bool{true, false} { + for i := 0; i < 100; i++ { + a1 := rnd.Float64() + a2 := rnd.Float64() + a3 := rnd.Float64() + b1 := rnd.Float64() + b2 := rnd.Float64() + b3 := rnd.Float64() + + csu, snu, csv, snv, csq, snq := impl.Dlags2(upper, a1, a2, a3, b1, b2, b3) + + detU := det2x2(csu, snu, -snu, csu) + if !floats.EqualWithinAbsOrRel(math.Abs(detU), 1, 1e-14, 1e-14) { + t.Errorf("U not orthogonal: det(U)=%v", detU) + } + detV := det2x2(csv, snv, -snv, csv) + if !floats.EqualWithinAbsOrRel(math.Abs(detV), 1, 1e-14, 1e-14) { + t.Errorf("V not orthogonal: det(V)=%v", detV) + } + detQ := det2x2(csq, snq, -snq, csq) + if !floats.EqualWithinAbsOrRel(math.Abs(detQ), 1, 1e-14, 1e-14) { + t.Errorf("Q not orthogonal: det(Q)=%v", detQ) + } + + u := blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{csu, snu, -snu, csu}, + } + v := blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{csv, snv, -snv, csv}, + } + q := blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{csq, snq, -snq, csq}, + } + + a := blas64.General{Rows: 2, Cols: 2, Stride: 2} + b := blas64.General{Rows: 2, Cols: 2, Stride: 2} + if upper { + a.Data = []float64{a1, a2, 0, a3} + b.Data = []float64{b1, b2, 0, b3} + } else { + a.Data = []float64{a1, 0, a2, a3} + b.Data = []float64{b1, 0, b2, b3} + } + + tmp := blas64.General{Rows: 2, Cols: 2, Stride: 2, Data: make([]float64, 4)} + blas64.Gemm(blas.Trans, blas.NoTrans, 1, u, a, 0, tmp) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmp, q, 0, a) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, v, b, 0, tmp) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmp, q, 0, b) + + var gotA, gotB float64 + if upper { + gotA = a.Data[1] + gotB = b.Data[1] + } else { + gotA = a.Data[2] + gotB = b.Data[2] + } + if !floats.EqualWithinAbsOrRel(gotA, 0, 1e-14, 1e-14) { + t.Errorf("unexpected non-zero value for zero triangle of U^T*A*Q: %v", gotA) + } + if !floats.EqualWithinAbsOrRel(gotB, 0, 1e-14, 1e-14) { + t.Errorf("unexpected non-zero value for zero triangle of V^T*B*Q: %v", gotB) + } + } + } +} + +func det2x2(a, b, c, d float64) float64 { return a*d - b*c } diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlahqr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlahqr.go new file mode 100644 index 00000000..c68680a7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlahqr.go @@ -0,0 +1,441 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlahqrer interface { + Dlahqr(wantt, wantz bool, n, ilo, ihi int, h []float64, ldh int, wr, wi []float64, iloz, ihiz int, z []float64, ldz int) int +} + +type dlahqrTest struct { + h blas64.General + ilo, ihi int + iloz, ihiz int + wantt, wantz bool + + evWant []complex128 // Optional slice holding known eigenvalues. +} + +func DlahqrTest(t *testing.T, impl Dlahqrer) { + rnd := rand.New(rand.NewSource(1)) + + // Tests that choose the [ilo:ihi+1,ilo:ihi+1] and + // [iloz:ihiz+1,ilo:ihi+1] blocks randomly. + for _, wantt := range []bool{true, false} { + for _, wantz := range []bool{true, false} { + for _, n := range []int{1, 2, 3, 4, 5, 6, 10, 18, 31, 53} { + for _, extra := range []int{0, 1, 11} { + for cas := 0; cas < 100; cas++ { + ilo := rnd.Intn(n) + ihi := rnd.Intn(n) + if ilo > ihi { + ilo, ihi = ihi, ilo + } + iloz := rnd.Intn(ilo + 1) + ihiz := ihi + rnd.Intn(n-ihi) + h := randomHessenberg(n, n+extra, rnd) + if ilo-1 >= 0 { + h.Data[ilo*h.Stride+ilo-1] = 0 + } + if ihi+1 < n { + h.Data[(ihi+1)*h.Stride+ihi] = 0 + } + test := dlahqrTest{ + h: h, + ilo: ilo, + ihi: ihi, + iloz: iloz, + ihiz: ihiz, + wantt: wantt, + wantz: wantz, + } + testDlahqr(t, impl, test) + } + } + } + } + } + // Tests that make sure that some potentially problematic corner cases, + // like zero-sized matrix, are covered. + for _, wantt := range []bool{true, false} { + for _, wantz := range []bool{true, false} { + for _, extra := range []int{0, 1, 11} { + for _, test := range []dlahqrTest{ + { + h: randomHessenberg(0, extra, rnd), + ilo: 0, + ihi: -1, + iloz: 0, + ihiz: -1, + }, + { + h: randomHessenberg(1, 1+extra, rnd), + ilo: 0, + ihi: 0, + iloz: 0, + ihiz: 0, + }, + { + h: randomHessenberg(2, 2+extra, rnd), + ilo: 1, + ihi: 1, + iloz: 1, + ihiz: 1, + }, + { + h: randomHessenberg(2, 2+extra, rnd), + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 0, + iloz: 0, + ihiz: 0, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 9, + iloz: 0, + ihiz: 9, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 9, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 9, + ihi: 9, + iloz: 0, + ihiz: 9, + }, + } { + if test.ilo-1 >= 0 { + test.h.Data[test.ilo*test.h.Stride+test.ilo-1] = 0 + } + if test.ihi+1 < test.h.Rows { + test.h.Data[(test.ihi+1)*test.h.Stride+test.ihi] = 0 + } + test.wantt = wantt + test.wantz = wantz + testDlahqr(t, impl, test) + } + } + } + } + + // Tests with explicit eigenvalues computed by Octave. + for _, test := range []dlahqrTest{ + { + h: blas64.General{ + Rows: 1, + Cols: 1, + Stride: 1, + Data: []float64{7.09965484086874e-1}, + }, + ilo: 0, + ihi: 0, + iloz: 0, + ihiz: 0, + evWant: []complex128{7.09965484086874e-1}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + 0, -1, + 1, 0, + }, + }, + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{1i, -1i}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + 6.25219991450918e-1, 8.17510791994361e-1, + 3.31218891622294e-1, 1.24103744878131e-1, + }, + }, + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + h: blas64.General{ + Rows: 4, + Cols: 4, + Stride: 4, + Data: []float64{ + 1, 0, 0, 0, + 0, 6.25219991450918e-1, 8.17510791994361e-1, 0, + 0, 3.31218891622294e-1, 1.24103744878131e-1, 0, + 0, 0, 0, 1, + }, + }, + ilo: 1, + ihi: 2, + iloz: 0, + ihiz: 3, + evWant: []complex128{9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + -1.1219562276608, 6.85473513349362e-1, + -8.19951061145131e-1, 1.93728523178888e-1, + }, + }, + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{ + -4.64113852240958e-1 + 3.59580510817350e-1i, + -4.64113852240958e-1 - 3.59580510817350e-1i, + }, + }, + { + h: blas64.General{ + Rows: 5, + Cols: 5, + Stride: 5, + Data: []float64{ + 9.57590178533658e-1, -5.10651295522708e-1, 9.24974510015869e-1, -1.30016306879522e-1, 2.92601986926954e-2, + -1.08084756637964, 1.77529701001213, -1.36480197632509, 2.23196371219601e-1, 1.12912853063308e-1, + 0, -8.44075612174676e-1, 1.067867614486, -2.55782915176399e-1, -2.00598563137468e-1, + 0, 0, -5.67097237165410e-1, 2.07205057427341e-1, 6.54998340743380e-1, + 0, 0, 0, -1.89441413886041e-1, -4.18125416021786e-1, + }, + }, + ilo: 0, + ihi: 4, + iloz: 0, + ihiz: 4, + evWant: []complex128{ + 2.94393309555622, + 4.97029793606701e-1 + 3.63041654992384e-1i, + 4.97029793606701e-1 - 3.63041654992384e-1i, + -1.74079119166145e-1 + 2.01570009462092e-1i, + -1.74079119166145e-1 - 2.01570009462092e-1i, + }, + }, + } { + test.wantt = true + test.wantz = true + testDlahqr(t, impl, test) + } +} + +func testDlahqr(t *testing.T, impl Dlahqrer, test dlahqrTest) { + const tol = 1e-14 + + h := cloneGeneral(test.h) + n := h.Cols + extra := h.Stride - h.Cols + wantt := test.wantt + wantz := test.wantz + ilo := test.ilo + ihi := test.ihi + iloz := test.iloz + ihiz := test.ihiz + + var z, zCopy blas64.General + if wantz { + z = eye(n, n+extra) + zCopy = cloneGeneral(z) + } + + wr := nanSlice(ihi + 1) + wi := nanSlice(ihi + 1) + + unconverged := impl.Dlahqr(wantt, wantz, n, ilo, ihi, h.Data, h.Stride, wr, wi, iloz, ihiz, z.Data, z.Stride) + + prefix := fmt.Sprintf("Case wantt=%v, wantz=%v, n=%v, ilo=%v, ihi=%v, iloz=%v, ihiz=%v, extra=%v", + wantt, wantz, n, ilo, ihi, iloz, ihiz, extra) + + if !generalOutsideAllNaN(h) { + t.Errorf("%v: out-of-range write to H\n%v", prefix, h.Data) + } + if !generalOutsideAllNaN(z) { + t.Errorf("%v: out-of-range write to Z\n%v", prefix, z.Data) + } + + if !isUpperHessenberg(h) { + t.Logf("%v: H is not Hessenberg", prefix) + } + + start := ilo // Index of the first computed eigenvalue. + if unconverged != 0 { + start = unconverged + if start == ihi+1 { + t.Logf("%v: no eigenvalue has converged", prefix) + } + } + + // Check that wr and wi have not been modified in [:start]. + if !isAllNaN(wr[:start]) { + t.Errorf("%v: unexpected modification of wr", prefix) + } + if !isAllNaN(wi[:start]) { + t.Errorf("%v: unexpected modification of wi", prefix) + } + + var hasReal bool + for i := start; i <= ihi; { + if wi[i] == 0 { // Real eigenvalue. + hasReal = true + // Check that the eigenvalue corresponds to a 1×1 block + // on the diagonal of H. + if wantt { + if wr[i] != h.Data[i*h.Stride+i] { + t.Errorf("%v: wr[%v] != H[%v,%v]", prefix, i, i, i) + } + for _, index := range []struct{ r, c int }{ + {i, i - 1}, // h h h + {i + 1, i - 1}, // 0 wr[i] h + {i + 1, i}, // 0 0 h + } { + if index.r >= n || index.c < 0 { + continue + } + if h.Data[index.r*h.Stride+index.c] != 0 { + t.Errorf("%v: H[%v,%v] != 0", prefix, index.r, index.c) + } + } + } + i++ + continue + } + + // Complex eigenvalue. + + // In the conjugate pair the real parts must be equal. + if wr[i] != wr[i+1] { + t.Errorf("%v: real part of conjugate pair not equal, i=%v", prefix, i) + } + // The first imaginary part must be positive. + if wi[i] < 0 { + t.Errorf("%v: wi[%v] not positive", prefix, i) + } + // The second imaginary part must be negative with the same + // magnitude. + if wi[i] != -wi[i+1] { + t.Errorf("%v: wi[%v] != -wi[%v]", prefix, i, i+1) + } + if wantt { + // Check that wi[i] has the correct value. + if wr[i] != h.Data[i*h.Stride+i] { + t.Errorf("%v: wr[%v] != H[%v,%v]", prefix, i, i, i) + } + if wr[i] != h.Data[(i+1)*h.Stride+i+1] { + t.Errorf("%v: wr[%v] != H[%v,%v]", prefix, i, i+1, i+1) + } + prod := math.Abs(h.Data[(i+1)*h.Stride+i] * h.Data[i*h.Stride+i+1]) + if math.Abs(math.Sqrt(prod)-wi[i]) > tol { + t.Errorf("%v: unexpected value of wi[%v]: want %v, got %v", prefix, i, math.Sqrt(prod), wi[i]) + } + + // Check that the corresponding diagonal block is 2×2. + for _, index := range []struct{ r, c int }{ + {i, i - 1}, // i + {i + 1, i - 1}, // h h h h + {i + 2, i - 1}, // 0 wr[i] b h i + {i + 2, i}, // 0 c wr[i+1] h + {i + 2, i + 1}, // 0 0 0 h + } { + if index.r >= n || index.c < 0 { + continue + } + if h.Data[index.r*h.Stride+index.c] != 0 { + t.Errorf("%v: H[%v,%v] != 0", prefix, index.r, index.c) + } + } + } + i += 2 + } + // If the number of found eigenvalues is odd, at least one must be real. + if (ihi+1-start)%2 != 0 && !hasReal { + t.Errorf("%v: expected at least one real eigenvalue", prefix) + } + + // Compare found eigenvalues to the reference, if known. + if test.evWant != nil { + for i := start; i <= ihi; i++ { + ev := complex(wr[i], wi[i]) + found, _ := containsComplex(test.evWant, ev, tol) + if !found { + t.Errorf("%v: unexpected eigenvalue %v", prefix, ev) + } + } + } + + if !wantz { + return + } + + // Z should contain the orthogonal matrix U. + if !isOrthonormal(z) { + t.Errorf("%v: Z is not orthogonal", prefix) + } + // Z should have been modified only in the + // [iloz:ihiz+1,ilo:ihi+1] block. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if iloz <= i && i <= ihiz && ilo <= j && j <= ihi { + continue + } + if z.Data[i*z.Stride+j] != zCopy.Data[i*zCopy.Stride+j] { + t.Errorf("%v: Z modified outside of [iloz:ihiz+1,ilo:ihi+1] block", prefix) + } + } + } + if wantt { + hu := eye(n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, test.h, z, 0, hu) + uhu := eye(n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, z, hu, 0, uhu) + if !equalApproxGeneral(uhu, h, 10*tol) { + t.Errorf("%v: Z^T*(initial H)*Z and (final H) are not equal", prefix) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlahr2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlahr2.go new file mode 100644 index 00000000..28aee344 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlahr2.go @@ -0,0 +1,240 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "compress/gzip" + "encoding/json" + "fmt" + "log" + "math" + "math/rand" + "os" + "path/filepath" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dlahr2er interface { + Dlahr2(n, k, nb int, a []float64, lda int, tau, t []float64, ldt int, y []float64, ldy int) +} + +type Dlahr2test struct { + N, K, NB int + A []float64 + + AWant []float64 + TWant []float64 + YWant []float64 + TauWant []float64 +} + +func Dlahr2Test(t *testing.T, impl Dlahr2er) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + n, k, nb int + }{ + {3, 0, 3}, + {3, 1, 2}, + {3, 1, 1}, + + {5, 0, 5}, + {5, 1, 4}, + {5, 1, 3}, + {5, 1, 2}, + {5, 1, 1}, + {5, 2, 3}, + {5, 2, 2}, + {5, 2, 1}, + {5, 3, 2}, + {5, 3, 1}, + + {7, 3, 4}, + {7, 3, 3}, + {7, 3, 2}, + {7, 3, 1}, + + {10, 0, 10}, + {10, 1, 9}, + {10, 1, 5}, + {10, 1, 1}, + {10, 5, 5}, + {10, 5, 3}, + {10, 5, 1}, + } { + for cas := 0; cas < 100; cas++ { + for _, extraStride := range []int{0, 1, 10} { + n := test.n + k := test.k + nb := test.nb + + a := randomGeneral(n, n-k+1, n-k+1+extraStride, rnd) + aCopy := a + aCopy.Data = make([]float64, len(a.Data)) + copy(aCopy.Data, a.Data) + tmat := nanTriangular(blas.Upper, nb, nb+extraStride) + y := nanGeneral(n, nb, nb+extraStride) + tau := nanSlice(nb) + + impl.Dlahr2(n, k, nb, a.Data, a.Stride, tau, tmat.Data, tmat.Stride, y.Data, y.Stride) + + prefix := fmt.Sprintf("Case n=%v, k=%v, nb=%v, ldex=%v", n, k, nb, extraStride) + + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A\n%v", prefix, a.Data) + } + if !triangularOutsideAllNaN(tmat) { + t.Errorf("%v: out-of-range write to T\n%v", prefix, tmat.Data) + } + if !generalOutsideAllNaN(y) { + t.Errorf("%v: out-of-range write to Y\n%v", prefix, y.Data) + } + + // Check that A[:k,:] and A[:,nb:] blocks were not modified. + for i := 0; i < n; i++ { + for j := 0; j < n-k+1; j++ { + if i >= k && j < nb { + continue + } + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected write to A[%v,%v]", prefix, i, j) + } + } + } + + // Check that all elements of tau were assigned. + for i, v := range tau { + if math.IsNaN(v) { + t.Errorf("%v: tau[%v] not assigned", prefix, i) + } + } + + // Extract V from a. + v := blas64.General{ + Rows: n - k + 1, + Cols: nb, + Stride: nb, + Data: make([]float64, (n-k+1)*nb), + } + for j := 0; j < v.Cols; j++ { + v.Data[(j+1)*v.Stride+j] = 1 + for i := j + 2; i < v.Rows; i++ { + v.Data[i*v.Stride+j] = a.Data[(i+k-1)*a.Stride+j] + } + } + + // VT = V. + vt := v + vt.Data = make([]float64, len(v.Data)) + copy(vt.Data, v.Data) + // VT = V * T. + blas64.Trmm(blas.Right, blas.NoTrans, 1, tmat, vt) + // YWant = A * V * T. + ywant := blas64.General{ + Rows: n, + Cols: nb, + Stride: nb, + Data: make([]float64, n*nb), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aCopy, vt, 0, ywant) + + // Compare Y and YWant. + for i := 0; i < n; i++ { + for j := 0; j < nb; j++ { + diff := math.Abs(ywant.Data[i*ywant.Stride+j] - y.Data[i*y.Stride+j]) + if diff > 1e-14 { + t.Errorf("%v: unexpected Y[%v,%v], diff=%v", prefix, i, j, diff) + } + } + } + + // Construct Q directly from the first nb columns of a. + q := constructQ("QR", n-k, nb, a.Data[k*a.Stride:], a.Stride, tau) + if !isOrthonormal(q) { + t.Errorf("%v: Q is not orthogonal", prefix) + } + // Construct Q as the product Q = I - V*T*V^T. + qwant := blas64.General{ + Rows: n - k + 1, + Cols: n - k + 1, + Stride: n - k + 1, + Data: make([]float64, (n-k+1)*(n-k+1)), + } + for i := 0; i < qwant.Rows; i++ { + qwant.Data[i*qwant.Stride+i] = 1 + } + blas64.Gemm(blas.NoTrans, blas.Trans, -1, vt, v, 1, qwant) + if !isOrthonormal(qwant) { + t.Errorf("%v: Q = I - V*T*V^T is not orthogonal", prefix) + } + + // Compare Q and QWant. Note that since Q is + // (n-k)×(n-k) and QWant is (n-k+1)×(n-k+1), we + // ignore the first row and column of QWant. + for i := 0; i < n-k; i++ { + for j := 0; j < n-k; j++ { + diff := math.Abs(q.Data[i*q.Stride+j] - qwant.Data[(i+1)*qwant.Stride+j+1]) + if diff > 1e-14 { + t.Errorf("%v: unexpected Q[%v,%v], diff=%v", prefix, i, j, diff) + } + } + } + } + } + } + + // Go runs tests from the source directory, so unfortunately we need to + // include the "../testlapack" part. + file, err := os.Open(filepath.FromSlash("../testlapack/testdata/dlahr2data.json.gz")) + if err != nil { + log.Fatal(err) + } + defer file.Close() + r, err := gzip.NewReader(file) + if err != nil { + log.Fatal(err) + } + defer r.Close() + + var tests []Dlahr2test + json.NewDecoder(r).Decode(&tests) + for _, test := range tests { + tau := make([]float64, len(test.TauWant)) + for _, ldex := range []int{0, 1, 20} { + n := test.N + k := test.K + nb := test.NB + + lda := n - k + 1 + ldex + a := make([]float64, (n-1)*lda+n-k+1) + copyMatrix(n, n-k+1, a, lda, test.A) + + ldt := nb + ldex + tmat := make([]float64, (nb-1)*ldt+nb) + + ldy := nb + ldex + y := make([]float64, (n-1)*ldy+nb) + + impl.Dlahr2(n, k, nb, a, lda, tau, tmat, ldt, y, ldy) + + prefix := fmt.Sprintf("Case n=%v, k=%v, nb=%v, ldex=%v", n, k, nb, ldex) + if !equalApprox(n, n-k+1, a, lda, test.AWant, 1e-14) { + t.Errorf("%v: unexpected matrix A\n got=%v\nwant=%v", prefix, a, test.AWant) + } + if !equalApproxTriangular(true, nb, tmat, ldt, test.TWant, 1e-14) { + t.Errorf("%v: unexpected matrix T\n got=%v\nwant=%v", prefix, tmat, test.TWant) + } + if !equalApprox(n, nb, y, ldy, test.YWant, 1e-14) { + t.Errorf("%v: unexpected matrix Y\n got=%v\nwant=%v", prefix, y, test.YWant) + } + if !floats.EqualApprox(tau, test.TauWant, 1e-14) { + t.Errorf("%v: unexpected slice tau\n got=%v\nwant=%v", prefix, tau, test.TauWant) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaln2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaln2.go new file mode 100644 index 00000000..07a322b8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaln2.go @@ -0,0 +1,139 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/cmplx" + "math/rand" + "testing" +) + +type Dlaln2er interface { + Dlaln2(trans bool, na, nw int, smin, ca float64, a []float64, lda int, d1, d2 float64, b []float64, ldb int, wr, wi float64, x []float64, ldx int) (scale, xnorm float64, ok bool) +} + +func Dlaln2Test(t *testing.T, impl Dlaln2er) { + rnd := rand.New(rand.NewSource(1)) + for _, trans := range []bool{true, false} { + for _, na := range []int{1, 2} { + for _, nw := range []int{1, 2} { + for _, extra := range []int{0, 1, 2, 13} { + for cas := 0; cas < 1000; cas++ { + testDlaln2(t, impl, trans, na, nw, extra, rnd) + } + } + } + } + } +} + +func testDlaln2(t *testing.T, impl Dlaln2er, trans bool, na, nw, extra int, rnd *rand.Rand) { + const tol = 1e-12 + const dlamchE = 1.0 / (1 << 53) + const dlamchP = 2 * dlamchE + + ca := rnd.NormFloat64() + d1 := rnd.NormFloat64() + d2 := rnd.NormFloat64() + + var w complex128 + if nw == 1 { + w = complex(rand.NormFloat64(), 0) + } else { + w = complex(rand.NormFloat64(), rand.NormFloat64()) + } + smin := dlamchP * (math.Abs(real(w)) + math.Abs(imag(w))) + + a := randomGeneral(na, na, na+extra, rnd) + b := randomGeneral(na, nw, nw+extra, rnd) + x := randomGeneral(na, nw, nw+extra, rnd) + + scale, xnormGot, ok := impl.Dlaln2(trans, na, nw, smin, ca, a.Data, a.Stride, d1, d2, b.Data, b.Stride, real(w), imag(w), x.Data, x.Stride) + + prefix := fmt.Sprintf("Case trans=%v, na=%v, nw=%v, extra=%v", trans, na, nw, extra) + + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A\n%v", prefix, a.Data) + } + if !generalOutsideAllNaN(b) { + t.Errorf("%v: out-of-range write to B\n%v", prefix, b.Data) + } + if !generalOutsideAllNaN(x) { + t.Errorf("%v: out-of-range write to X\n%v", prefix, x.Data) + } + + if scale <= 0 || 1 < scale { + t.Errorf("%v: invalid value of scale=%v", prefix, scale) + } + + var xnormWant float64 + for i := 0; i < na; i++ { + var rowsum float64 + for j := 0; j < nw; j++ { + rowsum += math.Abs(x.Data[i*x.Stride+j]) + } + if rowsum > xnormWant { + xnormWant = rowsum + } + } + if xnormWant != xnormGot { + t.Errorf("Case %v: unexpected xnorm with scale=%v. Want %v, got %v", prefix, scale, xnormWant, xnormGot) + } + + if !ok { + // If ok is false, the matrix has been perturbed but we don't + // know how. Return without comparing both sides of the + // equation. + return + } + + m := make([]complex128, na*na) + if trans { + for i := 0; i < na; i++ { + for j := 0; j < na; j++ { + m[i*na+j] = complex(ca*a.Data[j*a.Stride+i], 0) + } + } + } else { + for i := 0; i < na; i++ { + for j := 0; j < na; j++ { + m[i*na+j] = complex(ca*a.Data[i*a.Stride+j], 0) + } + } + } + m[0] -= w * complex(d1, 0) + if na == 2 { + m[3] -= w * complex(d2, 0) + } + + cx := make([]complex128, na) + cb := make([]complex128, na) + switch nw { + case 1: + for i := 0; i < na; i++ { + cx[i] = complex(x.Data[i*x.Stride], 0) + cb[i] = complex(scale*b.Data[i*x.Stride], 0) + } + case 2: + for i := 0; i < na; i++ { + cx[i] = complex(x.Data[i*x.Stride], x.Data[i*x.Stride+1]) + cb[i] = complex(scale*b.Data[i*b.Stride], scale*b.Data[i*b.Stride+1]) + } + } + + mx := make([]complex128, na) + for i := 0; i < na; i++ { + for j := 0; j < na; j++ { + mx[i] += m[i*na+j] * cx[j] + } + } + for i := 0; i < na; i++ { + if cmplx.Abs(mx[i]-cb[i]) > tol { + t.Errorf("Case %v: unexpected value of left-hand side at row %v with scale=%v. Want %v, got %v", prefix, i, scale, cb[i], mx[i]) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlange.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlange.go new file mode 100644 index 00000000..33f7efe1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlange.go @@ -0,0 +1,93 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +type Dlanger interface { + Dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int, work []float64) float64 +} + +func DlangeTest(t *testing.T, impl Dlanger) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, lda int + }{ + {4, 3, 0}, + {3, 4, 0}, + {4, 3, 100}, + {3, 4, 100}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() - 0.5 + } + work := make([]float64, n) + for i := range work { + work[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + // Test MaxAbs norm. + norm := impl.Dlange(lapack.MaxAbs, m, n, a, lda, work) + var ans float64 + for i := 0; i < m; i++ { + idx := blas64.Iamax(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]}) + ans = math.Max(ans, math.Abs(a[i*lda+idx])) + } + // Should be strictly equal because there is no floating point summation error. + if ans != norm { + t.Errorf("MaxAbs mismatch. Want %v, got %v.", ans, norm) + } + + // Test MaxColumnSum norm. + norm = impl.Dlange(lapack.MaxColumnSum, m, n, a, lda, work) + ans = 0 + for i := 0; i < n; i++ { + sum := blas64.Asum(m, blas64.Vector{Inc: lda, Data: aCopy[i:]}) + ans = math.Max(ans, sum) + } + if math.Abs(norm-ans) > 1e-14 { + t.Errorf("MaxColumnSum mismatch. Want %v, got %v.", ans, norm) + } + + // Test MaxRowSum norm. + norm = impl.Dlange(lapack.MaxRowSum, m, n, a, lda, work) + ans = 0 + for i := 0; i < m; i++ { + sum := blas64.Asum(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]}) + ans = math.Max(ans, sum) + } + if math.Abs(norm-ans) > 1e-14 { + t.Errorf("MaxRowSum mismatch. Want %v, got %v.", ans, norm) + } + + // Test Frobenius norm + norm = impl.Dlange(lapack.NormFrob, m, n, a, lda, work) + ans = 0 + for i := 0; i < m; i++ { + sum := blas64.Nrm2(n, blas64.Vector{Inc: 1, Data: aCopy[i*lda:]}) + ans += sum * sum + } + ans = math.Sqrt(ans) + if math.Abs(norm-ans) > 1e-14 { + t.Errorf("NormFrob mismatch. Want %v, got %v.", ans, norm) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlanst.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlanst.go new file mode 100644 index 00000000..224f1d07 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlanst.go @@ -0,0 +1,53 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/lapack" +) + +type Dlanster interface { + Dlanst(norm lapack.MatrixNorm, n int, d, e []float64) float64 + Dlanger +} + +func DlanstTest(t *testing.T, impl Dlanster) { + rnd := rand.New(rand.NewSource(1)) + for _, norm := range []lapack.MatrixNorm{lapack.MaxAbs, lapack.MaxColumnSum, lapack.MaxRowSum, lapack.NormFrob} { + for _, n := range []int{1, 3, 10, 100} { + for cas := 0; cas < 100; cas++ { + d := make([]float64, n) + for i := range d { + d[i] = rnd.NormFloat64() + } + e := make([]float64, n-1) + for i := range e { + e[i] = rnd.NormFloat64() + } + + m := n + lda := n + a := make([]float64, m*lda) + for i := 0; i < n; i++ { + a[i*lda+i] = d[i] + } + for i := 0; i < n-1; i++ { + a[i*lda+i+1] = e[i] + a[(i+1)*lda+i] = e[i] + } + work := make([]float64, n) + syNorm := impl.Dlanst(norm, n, d, e) + geNorm := impl.Dlange(norm, m, n, a, lda, work) + if math.Abs(syNorm-geNorm) > 1e-12 { + t.Errorf("Norm mismatch: norm = %v, cas = %v, n = %v. Want %v, got %v.", string(norm), cas, n, geNorm, syNorm) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlansy.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlansy.go new file mode 100644 index 00000000..b38f6bb0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlansy.go @@ -0,0 +1,80 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/lapack" +) + +type Dlansyer interface { + Dlanger + Dlansy(norm lapack.MatrixNorm, uplo blas.Uplo, n int, a []float64, lda int, work []float64) float64 +} + +func DlansyTest(t *testing.T, impl Dlansyer) { + rnd := rand.New(rand.NewSource(1)) + for _, norm := range []lapack.MatrixNorm{lapack.MaxAbs, lapack.MaxColumnSum, lapack.MaxRowSum, lapack.NormFrob} { + for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} { + for _, test := range []struct { + n, lda int + }{ + {1, 0}, + {3, 0}, + + {1, 10}, + {3, 10}, + } { + for trial := 0; trial < 100; trial++ { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, lda*n) + if trial == 0 { + for i := range a { + a[i] = float64(i) + } + } else { + for i := range a { + a[i] = rnd.NormFloat64() + } + } + + aDense := make([]float64, n*n) + if uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := a[i*lda+j] + aDense[i*n+j] = v + aDense[j*n+i] = v + } + } + } else { + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + v := a[i*lda+j] + aDense[i*n+j] = v + aDense[j*n+i] = v + } + } + } + work := make([]float64, n) + got := impl.Dlansy(norm, uplo, n, a, lda, work) + want := impl.Dlange(norm, n, n, aDense, n, work) + if math.Abs(want-got) > 1e-14 { + t.Errorf("Norm mismatch. norm = %c, upper = %v, n = %v, lda = %v, want %v, got %v.", + norm, uplo == blas.Upper, n, lda, got, want) + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlantr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlantr.go new file mode 100644 index 00000000..74f3c656 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlantr.go @@ -0,0 +1,89 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/lapack" +) + +type Dlantrer interface { + Dlanger + Dlantr(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, m, n int, a []float64, lda int, work []float64) float64 +} + +func DlantrTest(t *testing.T, impl Dlantrer) { + rnd := rand.New(rand.NewSource(1)) + for _, norm := range []lapack.MatrixNorm{lapack.MaxAbs, lapack.MaxColumnSum, lapack.MaxRowSum, lapack.NormFrob} { + for _, diag := range []blas.Diag{blas.NonUnit, blas.Unit} { + for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} { + for _, test := range []struct { + m, n, lda int + }{ + {3, 3, 0}, + {3, 5, 0}, + {10, 5, 0}, + + {5, 5, 11}, + {5, 10, 11}, + {10, 5, 11}, + } { + // Do a couple of random trials since the values change. + for trial := 0; trial < 100; trial++ { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + if trial == 0 { + for i := range a { + a[i] = float64(i) + } + } else { + for i := range a { + a[i] = rnd.NormFloat64() + } + } + aDense := make([]float64, len(a)) + if uplo == blas.Lower { + for i := 0; i < m; i++ { + for j := 0; j <= min(i, n-1); j++ { + aDense[i*lda+j] = a[i*lda+j] + } + } + } else { + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + aDense[i*lda+j] = a[i*lda+j] + } + } + } + if diag == blas.Unit { + for i := 0; i < min(m, n); i++ { + aDense[i*lda+i] = 1 + } + } + work := make([]float64, n+6) + for i := range work { + work[i] = rnd.Float64() + } + got := impl.Dlantr(norm, uplo, diag, m, n, a, lda, work) + want := impl.Dlange(norm, m, n, aDense, lda, work) + if math.Abs(got-want) > 1e-13 { + t.Errorf("Norm mismatch. norm = %c, unitdiag = %v, upper = %v, m = %v, n = %v, lda = %v, Want %v, got %v.", + norm, diag == blas.Unit, uplo == blas.Upper, m, n, lda, got, want) + } + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlanv2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlanv2.go new file mode 100644 index 00000000..07cf2c51 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlanv2.go @@ -0,0 +1,69 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" +) + +type Dlanv2er interface { + Dlanv2(a, b, c, d float64) (aa, bb, cc, dd float64, rt1r, rt1i, rt2r, rt2i float64, cs, sn float64) +} + +func Dlanv2Test(t *testing.T, impl Dlanv2er) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < 1000; i++ { + a := rnd.NormFloat64() + b := rnd.NormFloat64() + c := rnd.NormFloat64() + d := rnd.NormFloat64() + aa, bb, cc, dd, rt1r, rt1i, rt2r, rt2i, cs, sn := impl.Dlanv2(a, b, c, d) + + mat := fmt.Sprintf("[%v %v; %v %v]", a, b, c, d) + if cc == 0 { + if rt1i != 0 || rt2i != 0 { + t.Errorf("Unexpected complex eigenvalues for %v", mat) + } + } else { + if aa != dd { + t.Errorf("Diagonal elements not equal for %v: got [%v %v]", mat, aa, dd) + } + if bb*cc >= 0 { + t.Errorf("Non-diagonal elements have the same sign for %v: got [%v %v]", mat, bb, cc) + } else { + im := math.Sqrt(-bb * cc) + if math.Abs(rt1i-im) > 1e-14 && math.Abs(rt1i+im) > 1e-14 { + t.Errorf("Unexpected imaginary part of eigenvalue for %v: got %v, want %v or %v", mat, rt1i, im, -im) + } + if math.Abs(rt2i-im) > 1e-14 && math.Abs(rt2i+im) > 1e-14 { + t.Errorf("Unexpected imaginary part of eigenvalue for %v: got %v, want %v or %v", mat, rt2i, im, -im) + } + } + } + if rt1r != aa && rt1r != dd { + t.Errorf("Unexpected real part of eigenvalue for %v: got %v, want %v or %v", mat, rt1r, aa, dd) + } + if rt2r != aa && rt2r != dd { + t.Errorf("Unexpected real part of eigenvalue for %v: got %v, want %v or %v", mat, rt2r, aa, dd) + } + if math.Abs(math.Hypot(cs, sn)-1) > 1e-14 { + t.Errorf("Unexpected unitary matrix for %v: got cs %v, sn %v", mat, cs, sn) + } + + gota := cs*(aa*cs-bb*sn) - sn*(cc*cs-dd*sn) + gotb := cs*(aa*sn+bb*cs) - sn*(cc*sn+dd*cs) + gotc := sn*(aa*cs-bb*sn) + cs*(cc*cs-dd*sn) + gotd := sn*(aa*sn+bb*cs) + cs*(cc*sn+dd*cs) + if math.Abs(gota-a) > 1e-14 || + math.Abs(gotb-b) > 1e-14 || + math.Abs(gotc-c) > 1e-14 || + math.Abs(gotd-d) > 1e-14 { + t.Errorf("Unexpected factorization: got [%v %v; %v %v], want [%v %v; %v %v]", gota, gotb, gotc, gotd, a, b, c, d) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapll.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapll.go new file mode 100644 index 00000000..1c35f039 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapll.go @@ -0,0 +1,46 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dlapller interface { + Dgesvder + Dlapll(n int, x []float64, incX int, y []float64, incY int) float64 +} + +func DlapllTest(t *testing.T, impl Dlapller) { + rnd := rand.New(rand.NewSource(1)) + for i, m := range []int{5, 6, 9, 300, 400, 600} { + n := 2 + lda := n + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + got := impl.Dlapll(m, a[0:], 2, a[1:], 2) + + s := make([]float64, min(m, n)) + work := make([]float64, 1) + impl.Dgesvd(lapack.SVDNone, lapack.SVDNone, m, n, aCopy, lda, s, nil, 0, nil, 0, work, -1) + work = make([]float64, int(work[0])) + impl.Dgesvd(lapack.SVDNone, lapack.SVDNone, m, n, aCopy, lda, s, nil, 0, nil, 0, work, len(work)) + want := s[len(s)-1] + + if !floats.EqualWithinAbsOrRel(got, want, 1e-14, 1e-14) { + t.Errorf("unexpected ssmin for test %d: got:%f want:%f", i, got, want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapmt.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapmt.go new file mode 100644 index 00000000..b2fd1f8d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapmt.go @@ -0,0 +1,113 @@ +// 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 testlapack + +import ( + "fmt" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlapmter interface { + Dlapmt(forward bool, m, n int, x []float64, ldx int, k []int) +} + +func DlapmtTest(t *testing.T, impl Dlapmter) { + for ti, test := range []struct { + forward bool + k []int + + want blas64.General + }{ + { + forward: true, k: []int{0, 1, 2}, + want: blas64.General{ + Rows: 4, + Cols: 3, + Stride: 3, + Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + }, + }, + }, + { + forward: false, k: []int{0, 1, 2}, + want: blas64.General{ + Rows: 4, + Cols: 3, + Stride: 3, + Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + }, + }, + }, + { + forward: true, k: []int{1, 2, 0}, + want: blas64.General{ + Rows: 4, + Cols: 3, + Stride: 3, + Data: []float64{ + 2, 3, 1, + 5, 6, 4, + 8, 9, 7, + 11, 12, 10, + }, + }, + }, + { + forward: false, k: []int{1, 2, 0}, + want: blas64.General{ + Rows: 4, + Cols: 3, + Stride: 3, + Data: []float64{ + 3, 1, 2, + 6, 4, 5, + 9, 7, 8, + 12, 10, 11, + }, + }, + }, + } { + m := test.want.Rows + n := test.want.Cols + if len(test.k) != n { + panic("bad length of k") + } + + for _, extra := range []int{0, 11} { + x := zeros(m, n, n+extra) + c := 1 + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + x.Data[i*x.Stride+j] = float64(c) + c++ + } + } + + k := make([]int, len(test.k)) + copy(k, test.k) + + impl.Dlapmt(test.forward, m, n, x.Data, x.Stride, k) + + prefix := fmt.Sprintf("Case %v (forward=%t,m=%v,n=%v,extra=%v)", ti, test.forward, m, n, extra) + if !generalOutsideAllNaN(x) { + t.Errorf("%v: out-of-range write to X", prefix) + } + + if !equalApproxGeneral(x, test.want, 0) { + t.Errorf("%v: unexpected X\n%v\n%v", prefix, x, test.want) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapy2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapy2.go new file mode 100644 index 00000000..6efb81d9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlapy2.go @@ -0,0 +1,30 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dlapy2er interface { + Dlapy2(float64, float64) float64 +} + +func Dlapy2Test(t *testing.T, impl Dlapy2er) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < 10; i++ { + x := math.Abs(1e200 * rnd.NormFloat64()) + y := math.Abs(1e200 * rnd.NormFloat64()) + got := impl.Dlapy2(x, y) + want := math.Hypot(x, y) + if !floats.EqualWithinRel(got, want, 1e-16) { + t.Errorf("Dlapy2(%g, %g) = %g, want %g", x, y, got, want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqp2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqp2.go new file mode 100644 index 00000000..230b2ecc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqp2.go @@ -0,0 +1,115 @@ +// 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 testlapack + +import ( + "fmt" + "math" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlaqp2er interface { + Dlapmter + Dlaqp2(m, n, offset int, a []float64, lda int, jpvt []int, tau, vn1, vn2, work []float64) +} + +func Dlaqp2Test(t *testing.T, impl Dlaqp2er) { + for ti, test := range []struct { + m, n, offset int + }{ + {m: 4, n: 3, offset: 0}, + {m: 4, n: 3, offset: 2}, + {m: 4, n: 3, offset: 4}, + {m: 3, n: 4, offset: 0}, + {m: 3, n: 4, offset: 1}, + {m: 3, n: 4, offset: 2}, + {m: 8, n: 3, offset: 0}, + {m: 8, n: 3, offset: 4}, + {m: 8, n: 3, offset: 8}, + {m: 3, n: 8, offset: 0}, + {m: 3, n: 8, offset: 1}, + {m: 3, n: 8, offset: 2}, + {m: 10, n: 10, offset: 0}, + {m: 10, n: 10, offset: 5}, + {m: 10, n: 10, offset: 10}, + } { + m := test.m + n := test.n + jpiv := make([]int, n) + + for _, extra := range []int{0, 11} { + a := zeros(m, n, n+extra) + c := 1 + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Data[i*a.Stride+j] = float64(c) + c++ + } + } + aCopy := cloneGeneral(a) + for j := range jpiv { + jpiv[j] = j + } + + tau := make([]float64, n) + vn1 := columnNorms(m, n, a.Data, a.Stride) + vn2 := columnNorms(m, n, a.Data, a.Stride) + work := make([]float64, n) + + impl.Dlaqp2(m, n, test.offset, a.Data, a.Stride, jpiv, tau, vn1, vn2, work) + + prefix := fmt.Sprintf("Case %v (offset=%d,m=%v,n=%v,extra=%v)", ti, test.offset, m, n, extra) + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A", prefix) + } + + if test.offset == m { + continue + } + + mo := m - test.offset + q := constructQ("QR", mo, n, a.Data[test.offset*a.Stride:], a.Stride, tau) + // Check that q is orthonormal + for i := 0; i < mo; i++ { + nrm := blas64.Nrm2(mo, blas64.Vector{Inc: 1, Data: q.Data[i*mo:]}) + if math.Abs(nrm-1) > 1e-13 { + t.Errorf("Case %v, q not normal", ti) + } + for j := 0; j < i; j++ { + dot := blas64.Dot(mo, blas64.Vector{Inc: 1, Data: q.Data[i*mo:]}, blas64.Vector{Inc: 1, Data: q.Data[j*mo:]}) + if math.Abs(dot) > 1e-14 { + t.Errorf("Case %v, q not orthogonal", ti) + } + } + } + + // Check that A * P = Q * R + r := blas64.General{ + Rows: mo, + Cols: n, + Stride: n, + Data: make([]float64, mo*n), + } + for i := 0; i < mo; i++ { + for j := i; j < n; j++ { + r.Data[i*n+j] = a.Data[(test.offset+i)*a.Stride+j] + } + } + got := nanGeneral(mo, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, 0, got) + + want := aCopy + impl.Dlapmt(true, want.Rows, want.Cols, want.Data, want.Stride, jpiv) + want.Rows = mo + want.Data = want.Data[test.offset*want.Stride:] + if !equalApproxGeneral(got, want, 1e-12) { + t.Errorf("Case %v, Q*R != A*P\nQ*R=%v\nA*P=%v", ti, got, want) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqps.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqps.go new file mode 100644 index 00000000..7bb4800b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqps.go @@ -0,0 +1,112 @@ +// 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 testlapack + +import ( + "fmt" + "math" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlaqpser interface { + Dlapmter + Dlaqps(m, n, offset, nb int, a []float64, lda int, jpvt []int, tau, vn1, vn2, auxv, f []float64, ldf int) (kb int) +} + +func DlaqpsTest(t *testing.T, impl Dlaqpser) { + for ti, test := range []struct { + m, n, nb, offset int + }{ + {m: 4, n: 3, nb: 2, offset: 0}, + {m: 4, n: 3, nb: 1, offset: 2}, + {m: 3, n: 4, nb: 2, offset: 0}, + {m: 3, n: 4, nb: 1, offset: 2}, + {m: 8, n: 3, nb: 2, offset: 0}, + {m: 8, n: 3, nb: 1, offset: 4}, + {m: 3, n: 8, nb: 2, offset: 0}, + {m: 3, n: 8, nb: 1, offset: 1}, + {m: 10, n: 10, nb: 3, offset: 0}, + {m: 10, n: 10, nb: 2, offset: 5}, + } { + m := test.m + n := test.n + jpiv := make([]int, n) + + for _, extra := range []int{0, 11} { + a := zeros(m, n, n+extra) + c := 1 + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Data[i*a.Stride+j] = float64(c) + c++ + } + } + aCopy := cloneGeneral(a) + for j := range jpiv { + jpiv[j] = j + } + + tau := make([]float64, n) + vn1 := columnNorms(m, n, a.Data, a.Stride) + vn2 := columnNorms(m, n, a.Data, a.Stride) + auxv := make([]float64, test.nb) + f := zeros(test.n, test.nb, n) + + kb := impl.Dlaqps(m, n, test.offset, test.nb, a.Data, a.Stride, jpiv, tau, vn1, vn2, auxv, f.Data, f.Stride) + + prefix := fmt.Sprintf("Case %v (offset=%d,m=%v,n=%v,extra=%v)", ti, test.offset, m, n, extra) + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A", prefix) + } + + if test.offset == m { + continue + } + + mo := m - test.offset + q := constructQ("QR", mo, kb, a.Data[test.offset*a.Stride:], a.Stride, tau) + // Check that q is orthonormal + for i := 0; i < mo; i++ { + nrm := blas64.Nrm2(mo, blas64.Vector{Inc: 1, Data: q.Data[i*mo:]}) + if math.Abs(nrm-1) > 1e-13 { + t.Errorf("Case %v, q not normal", ti) + } + for j := 0; j < i; j++ { + dot := blas64.Dot(mo, blas64.Vector{Inc: 1, Data: q.Data[i*mo:]}, blas64.Vector{Inc: 1, Data: q.Data[j*mo:]}) + if math.Abs(dot) > 1e-14 { + t.Errorf("Case %v, q not orthogonal", ti) + } + } + } + + // Check that A * P = Q * R + r := blas64.General{ + Rows: mo, + Cols: kb, + Stride: kb, + Data: make([]float64, mo*kb), + } + for i := 0; i < mo; i++ { + for j := i; j < kb; j++ { + r.Data[i*kb+j] = a.Data[(test.offset+i)*a.Stride+j] + } + } + got := nanGeneral(mo, kb, kb) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, r, 0, got) + + want := aCopy + impl.Dlapmt(true, want.Rows, want.Cols, want.Data, want.Stride, jpiv) + want.Rows = mo + want.Cols = kb + want.Data = want.Data[test.offset*want.Stride:] + if !equalApproxGeneral(got, want, 1e-12) { + t.Errorf("Case %v, Q*R != A*P\nQ*R=%v\nA*P=%v", ti, got, want) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr04.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr04.go new file mode 100644 index 00000000..c92104e7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr04.go @@ -0,0 +1,449 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlaqr04er interface { + Dlaqr04(wantt, wantz bool, n, ilo, ihi int, h []float64, ldh int, wr, wi []float64, iloz, ihiz int, z []float64, ldz int, work []float64, lwork int, recur int) int + + Dlahqrer +} + +type dlaqr04Test struct { + h blas64.General + ilo, ihi int + iloz, ihiz int + wantt, wantz bool + + evWant []complex128 // Optional slice holding known eigenvalues. +} + +func Dlaqr04Test(t *testing.T, impl Dlaqr04er) { + rnd := rand.New(rand.NewSource(1)) + + // Tests for small matrices that choose the ilo,ihi and iloz,ihiz pairs + // randomly. + for _, wantt := range []bool{true, false} { + for _, wantz := range []bool{true, false} { + for _, n := range []int{1, 2, 3, 4, 5, 6, 10, 11, 12, 18, 29} { + for _, extra := range []int{0, 11} { + for recur := 0; recur <= 2; recur++ { + for cas := 0; cas < n; cas++ { + ilo := rnd.Intn(n) + ihi := rnd.Intn(n) + if ilo > ihi { + ilo, ihi = ihi, ilo + } + iloz := rnd.Intn(ilo + 1) + ihiz := ihi + rnd.Intn(n-ihi) + h := randomHessenberg(n, n+extra, rnd) + if ilo-1 >= 0 { + h.Data[ilo*h.Stride+ilo-1] = 0 + } + if ihi+1 < n { + h.Data[(ihi+1)*h.Stride+ihi] = 0 + } + test := dlaqr04Test{ + h: h, + ilo: ilo, + ihi: ihi, + iloz: iloz, + ihiz: ihiz, + wantt: wantt, + wantz: wantz, + } + testDlaqr04(t, impl, test, false, recur) + testDlaqr04(t, impl, test, true, recur) + } + } + } + } + } + } + + // Tests for matrices large enough to possibly use the recursion (but it + // doesn't seem to be the case). + for _, n := range []int{100, 500} { + for cas := 0; cas < 5; cas++ { + h := randomHessenberg(n, n, rnd) + test := dlaqr04Test{ + h: h, + ilo: 0, + ihi: n - 1, + iloz: 0, + ihiz: n - 1, + wantt: true, + wantz: true, + } + testDlaqr04(t, impl, test, true, 1) + } + } + + // Tests that make sure that some potentially problematic corner cases, + // like zero-sized matrix, are covered. + for _, wantt := range []bool{true, false} { + for _, wantz := range []bool{true, false} { + for _, extra := range []int{0, 1, 11} { + for _, test := range []dlaqr04Test{ + { + h: randomHessenberg(0, extra, rnd), + ilo: 0, + ihi: -1, + iloz: 0, + ihiz: -1, + }, + { + h: randomHessenberg(1, 1+extra, rnd), + ilo: 0, + ihi: 0, + iloz: 0, + ihiz: 0, + }, + { + h: randomHessenberg(2, 2+extra, rnd), + ilo: 1, + ihi: 1, + iloz: 1, + ihiz: 1, + }, + { + h: randomHessenberg(2, 2+extra, rnd), + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 0, + iloz: 0, + ihiz: 0, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 9, + iloz: 0, + ihiz: 9, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 9, + }, + { + h: randomHessenberg(10, 10+extra, rnd), + ilo: 9, + ihi: 9, + iloz: 0, + ihiz: 9, + }, + } { + if test.ilo-1 >= 0 { + test.h.Data[test.ilo*test.h.Stride+test.ilo-1] = 0 + } + if test.ihi+1 < test.h.Rows { + test.h.Data[(test.ihi+1)*test.h.Stride+test.ihi] = 0 + } + test.wantt = wantt + test.wantz = wantz + testDlaqr04(t, impl, test, false, 1) + testDlaqr04(t, impl, test, true, 1) + } + } + } + } + + // Tests with known eigenvalues computed by Octave. + for _, test := range []dlaqr04Test{ + { + h: blas64.General{ + Rows: 1, + Cols: 1, + Stride: 1, + Data: []float64{7.09965484086874e-1}, + }, + ilo: 0, + ihi: 0, + iloz: 0, + ihiz: 0, + evWant: []complex128{7.09965484086874e-1}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + 0, -1, + 1, 0, + }, + }, + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{1i, -1i}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + 6.25219991450918e-1, 8.17510791994361e-1, + 3.31218891622294e-1, 1.24103744878131e-1, + }, + }, + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + h: blas64.General{ + Rows: 4, + Cols: 4, + Stride: 4, + Data: []float64{ + 1, 0, 0, 0, + 0, 6.25219991450918e-1, 8.17510791994361e-1, 0, + 0, 3.31218891622294e-1, 1.24103744878131e-1, 0, + 0, 0, 0, 1, + }, + }, + ilo: 1, + ihi: 2, + iloz: 0, + ihiz: 3, + evWant: []complex128{9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + -1.1219562276608, 6.85473513349362e-1, + -8.19951061145131e-1, 1.93728523178888e-1, + }, + }, + ilo: 0, + ihi: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{ + -4.64113852240958e-1 + 3.59580510817350e-1i, + -4.64113852240958e-1 - 3.59580510817350e-1i, + }, + }, + { + h: blas64.General{ + Rows: 5, + Cols: 5, + Stride: 5, + Data: []float64{ + 9.57590178533658e-1, -5.10651295522708e-1, 9.24974510015869e-1, -1.30016306879522e-1, 2.92601986926954e-2, + -1.08084756637964, 1.77529701001213, -1.36480197632509, 2.23196371219601e-1, 1.12912853063308e-1, + 0, -8.44075612174676e-1, 1.067867614486, -2.55782915176399e-1, -2.00598563137468e-1, + 0, 0, -5.67097237165410e-1, 2.07205057427341e-1, 6.54998340743380e-1, + 0, 0, 0, -1.89441413886041e-1, -4.18125416021786e-1, + }, + }, + ilo: 0, + ihi: 4, + iloz: 0, + ihiz: 4, + evWant: []complex128{ + 2.94393309555622, + 4.97029793606701e-1 + 3.63041654992384e-1i, + 4.97029793606701e-1 - 3.63041654992384e-1i, + -1.74079119166145e-1 + 2.01570009462092e-1i, + -1.74079119166145e-1 - 2.01570009462092e-1i, + }, + }, + } { + test.wantt = true + test.wantz = true + testDlaqr04(t, impl, test, false, 1) + testDlaqr04(t, impl, test, true, 1) + } +} + +func testDlaqr04(t *testing.T, impl Dlaqr04er, test dlaqr04Test, optwork bool, recur int) { + const tol = 1e-14 + + h := cloneGeneral(test.h) + n := h.Cols + extra := h.Stride - h.Cols + wantt := test.wantt + wantz := test.wantz + ilo := test.ilo + ihi := test.ihi + iloz := test.iloz + ihiz := test.ihiz + + var z, zCopy blas64.General + if wantz { + z = eye(n, n+extra) + zCopy = cloneGeneral(z) + } + + wr := nanSlice(ihi + 1) + wi := nanSlice(ihi + 1) + + var work []float64 + if optwork { + work = nanSlice(1) + impl.Dlaqr04(wantt, wantz, n, ilo, ihi, nil, 0, nil, nil, iloz, ihiz, nil, 0, work, -1, recur) + work = nanSlice(int(work[0])) + } else { + work = nanSlice(max(1, n)) + } + + unconverged := impl.Dlaqr04(wantt, wantz, n, ilo, ihi, h.Data, h.Stride, wr, wi, iloz, ihiz, z.Data, z.Stride, work, len(work), recur) + + prefix := fmt.Sprintf("Case wantt=%v, wantz=%v, n=%v, ilo=%v, ihi=%v, iloz=%v, ihiz=%v, extra=%v, opt=%v", + wantt, wantz, n, ilo, ihi, iloz, ihiz, extra, optwork) + + if !generalOutsideAllNaN(h) { + t.Errorf("%v: out-of-range write to H\n%v", prefix, h.Data) + } + if !generalOutsideAllNaN(z) { + t.Errorf("%v: out-of-range write to Z\n%v", prefix, z.Data) + } + + start := ilo // Index of the first computed eigenvalue. + if unconverged != 0 { + start = unconverged + if start == ihi+1 { + t.Logf("%v: no eigenvalue has converged", prefix) + } + } + + // Check that wr and wi have not been modified within [:start]. + if !isAllNaN(wr[:start]) { + t.Errorf("%v: unexpected modification of wr", prefix) + } + if !isAllNaN(wi[:start]) { + t.Errorf("%v: unexpected modification of wi", prefix) + } + + var hasReal bool + for i := start; i <= ihi; { + if wi[i] == 0 { // Real eigenvalue. + hasReal = true + // Check that the eigenvalue corresponds to a 1×1 block + // on the diagonal of H. + if wantt && wr[i] != h.Data[i*h.Stride+i] { + t.Errorf("%v: wr[%v] != H[%v,%v]", prefix, i, i, i) + } + i++ + continue + } + + // Complex eigenvalue. + + // In the conjugate pair the real parts must be equal. + if wr[i] != wr[i+1] { + t.Errorf("%v: real part of conjugate pair not equal, i=%v", prefix, i) + } + // The first imaginary part must be positive. + if wi[i] < 0 { + t.Errorf("%v: wi[%v] not positive", prefix, i) + } + // The second imaginary part must be negative with the same + // magnitude. + if wi[i] != -wi[i+1] { + t.Errorf("%v: wi[%v] != wi[%v]", prefix, i, i+1) + } + if wantt { + // Check that wi[i] has the correct value. + if wr[i] != h.Data[i*h.Stride+i] { + t.Errorf("%v: wr[%v] != H[%v,%v]", prefix, i, i, i) + } + if wr[i] != h.Data[(i+1)*h.Stride+i+1] { + t.Errorf("%v: wr[%v] != H[%v,%v]", prefix, i, i+1, i+1) + } + im := math.Sqrt(math.Abs(h.Data[(i+1)*h.Stride+i])) * math.Sqrt(math.Abs(h.Data[i*h.Stride+i+1])) + if math.Abs(im-wi[i]) > tol { + t.Errorf("%v: unexpected value of wi[%v]: want %v, got %v", prefix, i, im, wi[i]) + } + } + i += 2 + } + // If the number of found eigenvalues is odd, at least one must be real. + if (ihi+1-start)%2 != 0 && !hasReal { + t.Errorf("%v: expected at least one real eigenvalue", prefix) + } + + // Compare found eigenvalues to the reference, if known. + if test.evWant != nil { + for i := start; i <= ihi; i++ { + ev := complex(wr[i], wi[i]) + found, _ := containsComplex(test.evWant, ev, tol) + if !found { + t.Errorf("%v: unexpected eigenvalue %v", prefix, ev) + } + } + } + + if !wantz { + return + } + + // Z should contain the orthogonal matrix U. + if !isOrthonormal(z) { + t.Errorf("%v: Z is not orthogonal", prefix) + } + // Z should have been modified only in the + // [iloz:ihiz+1,ilo:ihi+1] block. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if iloz <= i && i <= ihiz && ilo <= j && j <= ihi { + continue + } + if z.Data[i*z.Stride+j] != zCopy.Data[i*zCopy.Stride+j] { + t.Errorf("%v: Z modified outside of [iloz:ihiz+1,ilo:ihi+1] block", prefix) + } + } + } + if wantt { + // Zero out h under the subdiagonal because Dlaqr04 uses it as + // workspace. + for i := 2; i < n; i++ { + for j := 0; j < i-1; j++ { + h.Data[i*h.Stride+j] = 0 + } + } + hz := eye(n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, test.h, z, 0, hz) + zhz := eye(n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, z, hz, 0, zhz) + if !equalApproxGeneral(zhz, h, 10*tol) { + t.Errorf("%v: Z^T*(initial H)*Z and (final H) are not equal", prefix) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr1.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr1.go new file mode 100644 index 00000000..9276bfd5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr1.go @@ -0,0 +1,91 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dlaqr1er interface { + Dlaqr1(n int, h []float64, ldh int, sr1, si1, sr2, si2 float64, v []float64) +} + +func Dlaqr1Test(t *testing.T, impl Dlaqr1er) { + rnd := rand.New(rand.NewSource(1)) + + for _, n := range []int{2, 3} { + for _, ldh := range []int{n, n + 1, n + 10} { + for _, cas := range []int{1, 2} { + for k := 0; k < 100; k++ { + v := make([]float64, n) + for i := range v { + v[i] = math.NaN() + } + h := make([]float64, n*(n-1)*ldh) + for i := range h { + h[i] = math.NaN() + } + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + h[i*ldh+j] = rnd.NormFloat64() + } + } + var sr1, sr2, si1, si2 float64 + if cas == 1 { + sr1 = rnd.NormFloat64() + sr2 = sr1 + si1 = rnd.NormFloat64() + si2 = -si1 + } else { + sr1 = rnd.NormFloat64() + sr2 = rnd.NormFloat64() + si1 = 0 + si2 = 0 + } + impl.Dlaqr1(n, h, ldh, sr1, si1, sr2, si2, v) + + // Matrix H - s1*I. + h1 := make([]complex128, n*n) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + h1[i*n+j] = complex(h[i*ldh+j], 0) + if i == j { + h1[i*n+j] -= complex(sr1, si1) + } + } + } + // First column of H - s2*I. + h2 := make([]complex128, n) + for i := 0; i < n; i++ { + h2[i] = complex(h[i*ldh], 0) + } + h2[0] -= complex(sr2, si2) + + wantv := make([]float64, n) + // Multiply (H-s1*I)*(H-s2*I) to get a tentative + // wantv. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + wantv[i] += real(h1[i*n+j] * h2[j]) + } + } + // Get the unknown scale. + scale := v[0] / wantv[0] + // Compute the actual wantv. + floats.Scale(scale, wantv) + + // The scale must be the same for all elements. + if floats.Distance(wantv, v, math.Inf(1)) > 1e-13 { + t.Errorf("n = %v, ldh = %v, case = %v: Unexpected value of v: got %v, want %v", n, ldh, cas, v, wantv) + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr23.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr23.go new file mode 100644 index 00000000..e55d2bc0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr23.go @@ -0,0 +1,335 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlaqr23er interface { + Dlaqr23(wantt, wantz bool, n, ktop, kbot, nw int, h []float64, ldh int, iloz, ihiz int, z []float64, ldz int, sr, si []float64, v []float64, ldv int, nh int, t []float64, ldt int, nv int, wv []float64, ldwv int, work []float64, lwork int, recur int) (ns, nd int) +} + +type dlaqr23Test struct { + wantt, wantz bool + ktop, kbot int + nw int + h blas64.General + iloz, ihiz int + + evWant []complex128 // Optional slice with known eigenvalues. +} + +func Dlaqr23Test(t *testing.T, impl Dlaqr23er) { + rnd := rand.New(rand.NewSource(1)) + + for _, wantt := range []bool{true, false} { + for _, wantz := range []bool{true, false} { + for _, n := range []int{1, 2, 3, 4, 5, 6, 10, 18, 31, 100} { + for _, extra := range []int{0, 11} { + for cas := 0; cas < 30; cas++ { + var nw int + if nw <= 75 { + nw = rnd.Intn(n) + 1 + } else { + nw = 76 + rnd.Intn(n-75) + } + ktop := rnd.Intn(n - nw + 1) + kbot := ktop + nw - 1 + kbot += rnd.Intn(n - kbot) + h := randomHessenberg(n, n+extra, rnd) + if ktop-1 >= 0 { + h.Data[ktop*h.Stride+ktop-1] = 0 + } + if kbot+1 < n { + h.Data[(kbot+1)*h.Stride+kbot] = 0 + } + iloz := rnd.Intn(ktop + 1) + ihiz := kbot + rnd.Intn(n-kbot) + test := dlaqr23Test{ + wantt: wantt, + wantz: wantz, + ktop: ktop, + kbot: kbot, + nw: nw, + h: h, + iloz: iloz, + ihiz: ihiz, + } + testDlaqr23(t, impl, test, false, 1, rnd) + testDlaqr23(t, impl, test, true, 1, rnd) + testDlaqr23(t, impl, test, false, 0, rnd) + testDlaqr23(t, impl, test, true, 0, rnd) + } + } + } + } + } + + // Tests with n=0. + for _, wantt := range []bool{true, false} { + for _, wantz := range []bool{true, false} { + for _, extra := range []int{0, 1, 11} { + test := dlaqr23Test{ + wantt: wantt, + wantz: wantz, + h: randomHessenberg(0, extra, rnd), + ktop: 0, + kbot: -1, + iloz: 0, + ihiz: -1, + nw: 0, + } + testDlaqr23(t, impl, test, true, 1, rnd) + testDlaqr23(t, impl, test, false, 1, rnd) + testDlaqr23(t, impl, test, true, 0, rnd) + testDlaqr23(t, impl, test, false, 0, rnd) + } + } + } + + // Tests with explicit eigenvalues computed by Octave. + for _, test := range []dlaqr23Test{ + { + h: blas64.General{ + Rows: 1, + Cols: 1, + Stride: 1, + Data: []float64{7.09965484086874e-1}, + }, + ktop: 0, + kbot: 0, + iloz: 0, + ihiz: 0, + evWant: []complex128{7.09965484086874e-1}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + 0, -1, + 1, 0, + }, + }, + ktop: 0, + kbot: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{1i, -1i}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + 6.25219991450918e-1, 8.17510791994361e-1, + 3.31218891622294e-1, 1.24103744878131e-1, + }, + }, + ktop: 0, + kbot: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + h: blas64.General{ + Rows: 4, + Cols: 4, + Stride: 4, + Data: []float64{ + 1, 0, 0, 0, + 0, 6.25219991450918e-1, 8.17510791994361e-1, 0, + 0, 3.31218891622294e-1, 1.24103744878131e-1, 0, + 0, 0, 0, 1, + }, + }, + ktop: 1, + kbot: 2, + iloz: 0, + ihiz: 3, + evWant: []complex128{9.52203547663447e-1, -2.02879811334398e-1}, + }, + { + h: blas64.General{ + Rows: 2, + Cols: 2, + Stride: 2, + Data: []float64{ + -1.1219562276608, 6.85473513349362e-1, + -8.19951061145131e-1, 1.93728523178888e-1, + }, + }, + ktop: 0, + kbot: 1, + iloz: 0, + ihiz: 1, + evWant: []complex128{ + -4.64113852240958e-1 + 3.59580510817350e-1i, + -4.64113852240958e-1 - 3.59580510817350e-1i, + }, + }, + { + h: blas64.General{ + Rows: 5, + Cols: 5, + Stride: 5, + Data: []float64{ + 9.57590178533658e-1, -5.10651295522708e-1, 9.24974510015869e-1, -1.30016306879522e-1, 2.92601986926954e-2, + -1.08084756637964, 1.77529701001213, -1.36480197632509, 2.23196371219601e-1, 1.12912853063308e-1, + 0, -8.44075612174676e-1, 1.067867614486, -2.55782915176399e-1, -2.00598563137468e-1, + 0, 0, -5.67097237165410e-1, 2.07205057427341e-1, 6.54998340743380e-1, + 0, 0, 0, -1.89441413886041e-1, -4.18125416021786e-1, + }, + }, + ktop: 0, + kbot: 4, + iloz: 0, + ihiz: 4, + evWant: []complex128{ + 2.94393309555622, + 4.97029793606701e-1 + 3.63041654992384e-1i, + 4.97029793606701e-1 - 3.63041654992384e-1i, + -1.74079119166145e-1 + 2.01570009462092e-1i, + -1.74079119166145e-1 - 2.01570009462092e-1i, + }, + }, + } { + test.wantt = true + test.wantz = true + test.nw = test.kbot - test.ktop + 1 + testDlaqr23(t, impl, test, true, 1, rnd) + testDlaqr23(t, impl, test, false, 1, rnd) + testDlaqr23(t, impl, test, true, 0, rnd) + testDlaqr23(t, impl, test, false, 0, rnd) + } +} + +func testDlaqr23(t *testing.T, impl Dlaqr23er, test dlaqr23Test, opt bool, recur int, rnd *rand.Rand) { + const tol = 1e-14 + + h := cloneGeneral(test.h) + n := h.Cols + extra := h.Stride - h.Cols + wantt := test.wantt + wantz := test.wantz + ktop := test.ktop + kbot := test.kbot + nw := test.nw + iloz := test.iloz + ihiz := test.ihiz + + var z, zCopy blas64.General + if wantz { + z = eye(n, n+extra) + zCopy = cloneGeneral(z) + } + + sr := nanSlice(kbot + 1) + si := nanSlice(kbot + 1) + + v := randomGeneral(nw, nw, nw+extra, rnd) + var nh int + if nw > 0 { + nh = nw + rnd.Intn(nw) // nh must be at least nw. + } + tmat := randomGeneral(nw, nh, nh+extra, rnd) + var nv int + if nw > 0 { + nv = rnd.Intn(nw) + 1 + } + wv := randomGeneral(nv, nw, nw+extra, rnd) + + var work []float64 + if opt { + work = nanSlice(1) + impl.Dlaqr23(wantt, wantz, n, ktop, kbot, nw, nil, h.Stride, iloz, ihiz, nil, z.Stride, + nil, nil, nil, v.Stride, tmat.Cols, nil, tmat.Stride, wv.Rows, nil, wv.Stride, work, -1, recur) + work = nanSlice(int(work[0])) + } else { + work = nanSlice(max(1, 2*nw)) + } + + ns, nd := impl.Dlaqr23(wantt, wantz, n, ktop, kbot, nw, h.Data, h.Stride, iloz, ihiz, z.Data, z.Stride, + sr, si, v.Data, v.Stride, tmat.Cols, tmat.Data, tmat.Stride, wv.Rows, wv.Data, wv.Stride, work, len(work), recur) + + prefix := fmt.Sprintf("Case wantt=%v, wantz=%v, n=%v, ktop=%v, kbot=%v, nw=%v, iloz=%v, ihiz=%v, extra=%v", + wantt, wantz, n, ktop, kbot, nw, iloz, ihiz, extra) + + if !generalOutsideAllNaN(h) { + t.Errorf("%v: out-of-range write to H\n%v", prefix, h.Data) + } + if !generalOutsideAllNaN(z) { + t.Errorf("%v: out-of-range write to Z\n%v", prefix, z.Data) + } + if !generalOutsideAllNaN(v) { + t.Errorf("%v: out-of-range write to V\n%v", prefix, v.Data) + } + if !generalOutsideAllNaN(tmat) { + t.Errorf("%v: out-of-range write to T\n%v", prefix, tmat.Data) + } + if !generalOutsideAllNaN(wv) { + t.Errorf("%v: out-of-range write to WV\n%v", prefix, wv.Data) + } + if !isAllNaN(sr[:kbot-nd-ns+1]) || !isAllNaN(sr[kbot+1:]) { + t.Errorf("%v: out-of-range write to sr", prefix) + } + if !isAllNaN(si[:kbot-nd-ns+1]) || !isAllNaN(si[kbot+1:]) { + t.Errorf("%v: out-of-range write to si", prefix) + } + + if !isUpperHessenberg(h) { + t.Errorf("%v: H is not upper Hessenberg", prefix) + } + + if test.evWant != nil { + for i := kbot - nd + 1; i <= kbot; i++ { + ev := complex(sr[i], si[i]) + found, _ := containsComplex(test.evWant, ev, tol) + if !found { + t.Errorf("%v: unexpected eigenvalue %v", prefix, ev) + } + } + } + + if !wantz { + return + } + + var zmod bool + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if z.Data[i*z.Stride+j] == zCopy.Data[i*zCopy.Stride+j] { + continue + } + if i < iloz || i > ihiz || j < kbot-nw+1 || j > kbot { + zmod = true + } + } + } + if zmod { + t.Errorf("%v: unexpected modification of Z", prefix) + } + if !isOrthonormal(z) { + t.Errorf("%v: Z is not orthogonal", prefix) + } + if wantt { + hu := eye(n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, test.h, z, 0, hu) + uhu := eye(n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, z, hu, 0, uhu) + if !equalApproxGeneral(uhu, h, 10*tol) { + t.Errorf("%v: Z^T*(initial H)*Z and (final H) are not equal", prefix) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr5.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr5.go new file mode 100644 index 00000000..a93181dc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaqr5.go @@ -0,0 +1,214 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "compress/gzip" + "encoding/json" + "fmt" + "log" + "math" + "math/rand" + "os" + "path/filepath" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlaqr5er interface { + Dlaqr5(wantt, wantz bool, kacc22 int, n, ktop, kbot, nshfts int, sr, si []float64, h []float64, ldh int, iloz, ihiz int, z []float64, ldz int, v []float64, ldv int, u []float64, ldu int, nh int, wh []float64, ldwh int, nv int, wv []float64, ldwv int) +} + +type Dlaqr5test struct { + WantT bool + N int + NShifts int + KTop, KBot int + ShiftR, ShiftI []float64 + H []float64 + + HWant []float64 + ZWant []float64 +} + +func Dlaqr5Test(t *testing.T, impl Dlaqr5er) { + // Test without using reference data. + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{1, 2, 3, 4, 5, 6, 10, 30} { + for _, extra := range []int{0, 1, 20} { + for _, kacc22 := range []int{0, 1, 2} { + for cas := 0; cas < 100; cas++ { + testDlaqr5(t, impl, n, extra, kacc22, rnd) + } + } + } + } + + // Test using reference data computed by the reference netlib + // implementation. + file, err := os.Open(filepath.FromSlash("../testlapack/testdata/dlaqr5data.json.gz")) + if err != nil { + log.Fatal(err) + } + defer file.Close() + r, err := gzip.NewReader(file) + if err != nil { + log.Fatal(err) + } + defer r.Close() + + var tests []Dlaqr5test + json.NewDecoder(r).Decode(&tests) + for _, test := range tests { + wantt := test.WantT + n := test.N + nshfts := test.NShifts + ktop := test.KTop + kbot := test.KBot + sr := test.ShiftR + si := test.ShiftI + + for _, extra := range []int{0, 1, 10} { + v := randomGeneral(nshfts/2, 3, 3+extra, rnd) + u := randomGeneral(3*nshfts-3, 3*nshfts-3, 3*nshfts-3+extra, rnd) + nh := n + wh := randomGeneral(3*nshfts-3, n, n+extra, rnd) + nv := n + wv := randomGeneral(n, 3*nshfts-3, 3*nshfts-3+extra, rnd) + + h := nanGeneral(n, n, n+extra) + + for _, kacc22 := range []int{0, 1, 2} { + copyMatrix(n, n, h.Data, h.Stride, test.H) + z := eye(n, n+extra) + + impl.Dlaqr5(wantt, true, kacc22, + n, ktop, kbot, + nshfts, sr, si, + h.Data, h.Stride, + 0, n-1, z.Data, z.Stride, + v.Data, v.Stride, + u.Data, u.Stride, + nv, wv.Data, wv.Stride, + nh, wh.Data, wh.Stride) + + prefix := fmt.Sprintf("wantt=%v, n=%v, nshfts=%v, ktop=%v, kbot=%v, extra=%v, kacc22=%v", + wantt, n, nshfts, ktop, kbot, extra, kacc22) + if !equalApprox(n, n, h.Data, h.Stride, test.HWant, 1e-13) { + t.Errorf("Case %v: unexpected matrix H\nh =%v\nhwant=%v", prefix, h.Data, test.HWant) + } + if !equalApprox(n, n, z.Data, z.Stride, test.ZWant, 1e-13) { + t.Errorf("Case %v: unexpected matrix Z\nz =%v\nzwant=%v", prefix, z.Data, test.ZWant) + } + } + } + } +} + +func testDlaqr5(t *testing.T, impl Dlaqr5er, n, extra, kacc22 int, rnd *rand.Rand) { + wantt := true + wantz := true + nshfts := 2 * n + sr := make([]float64, nshfts) + si := make([]float64, nshfts) + for i := 0; i < n; i++ { + re := rnd.NormFloat64() + im := rnd.NormFloat64() + sr[2*i], sr[2*i+1] = re, re + si[2*i], si[2*i+1] = im, -im + } + ktop := rnd.Intn(n) + kbot := rnd.Intn(n) + if kbot < ktop { + ktop, kbot = kbot, ktop + } + + v := randomGeneral(nshfts/2, 3, 3+extra, rnd) + u := randomGeneral(3*nshfts-3, 3*nshfts-3, 3*nshfts-3+extra, rnd) + nh := n + wh := randomGeneral(3*nshfts-3, n, n+extra, rnd) + nv := n + wv := randomGeneral(n, 3*nshfts-3, 3*nshfts-3+extra, rnd) + + h := randomHessenberg(n, n+extra, rnd) + if ktop > 0 { + h.Data[ktop*h.Stride+ktop-1] = 0 + } + if kbot < n-1 { + h.Data[(kbot+1)*h.Stride+kbot] = 0 + } + hCopy := h + hCopy.Data = make([]float64, len(h.Data)) + copy(hCopy.Data, h.Data) + + z := eye(n, n+extra) + + impl.Dlaqr5(wantt, wantz, kacc22, + n, ktop, kbot, + nshfts, sr, si, + h.Data, h.Stride, + 0, n-1, z.Data, z.Stride, + v.Data, v.Stride, + u.Data, u.Stride, + nv, wv.Data, wv.Stride, + nh, wh.Data, wh.Stride) + + prefix := fmt.Sprintf("Case n=%v, extra=%v, kacc22=%v", n, extra, kacc22) + + if !generalOutsideAllNaN(h) { + t.Errorf("%v: out-of-range write to H\n%v", prefix, h.Data) + } + if !generalOutsideAllNaN(z) { + t.Errorf("%v: out-of-range write to Z\n%v", prefix, z.Data) + } + if !generalOutsideAllNaN(u) { + t.Errorf("%v: out-of-range write to U\n%v", prefix, u.Data) + } + if !generalOutsideAllNaN(v) { + t.Errorf("%v: out-of-range write to V\n%v", prefix, v.Data) + } + if !generalOutsideAllNaN(wh) { + t.Errorf("%v: out-of-range write to WH\n%v", prefix, wh.Data) + } + if !generalOutsideAllNaN(wv) { + t.Errorf("%v: out-of-range write to WV\n%v", prefix, wv.Data) + } + + for i := 0; i < n; i++ { + for j := 0; j < i-1; j++ { + if h.Data[i*h.Stride+j] != 0 { + t.Errorf("%v: H is not Hessenberg, H[%v,%v]!=0", prefix, i, j) + } + } + } + if !isOrthonormal(z) { + t.Errorf("%v: Z is not orthogonal", prefix) + } + // Construct Z^T * HOrig * Z and check that it is equal to H from Dlaqr5. + hz := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, hCopy, z, 0, hz) + zhz := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + blas64.Gemm(blas.Trans, blas.NoTrans, 1, z, hz, 0, zhz) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + diff := zhz.Data[i*zhz.Stride+j] - h.Data[i*h.Stride+j] + if math.Abs(diff) > 1e-13 { + t.Errorf("%v: Z^T*HOrig*Z and H are not equal, diff at [%v,%v]=%v", prefix, i, j, diff) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarf.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarf.go new file mode 100644 index 00000000..82b2756a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarf.go @@ -0,0 +1,173 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dlarfer interface { + Dlarf(side blas.Side, m, n int, v []float64, incv int, tau float64, c []float64, ldc int, work []float64) +} + +func DlarfTest(t *testing.T, impl Dlarfer) { + rnd := rand.New(rand.NewSource(1)) + for i, test := range []struct { + m, n, ldc int + incv, lastv int + lastr, lastc int + tau float64 + }{ + { + m: 3, + n: 2, + ldc: 2, + + incv: 4, + lastv: 1, + + lastr: 2, + lastc: 1, + + tau: 2, + }, + { + m: 2, + n: 3, + ldc: 3, + + incv: 4, + lastv: 1, + + lastr: 1, + lastc: 2, + + tau: 2, + }, + { + m: 2, + n: 3, + ldc: 3, + + incv: 4, + lastv: 1, + + lastr: 0, + lastc: 1, + + tau: 2, + }, + { + m: 2, + n: 3, + ldc: 3, + + incv: 4, + lastv: 0, + + lastr: 0, + lastc: 1, + + tau: 2, + }, + { + m: 10, + n: 10, + ldc: 10, + + incv: 4, + lastv: 6, + + lastr: 9, + lastc: 8, + + tau: 2, + }, + } { + // Construct a random matrix. + c := make([]float64, test.ldc*test.m) + for i := 0; i <= test.lastr; i++ { + for j := 0; j <= test.lastc; j++ { + c[i*test.ldc+j] = rnd.Float64() + } + } + cCopy := make([]float64, len(c)) + copy(cCopy, c) + cCopy2 := make([]float64, len(c)) + copy(cCopy2, c) + + // Test with side right. + sz := max(test.m, test.n) // so v works for both right and left side. + v := make([]float64, test.incv*sz+1) + // Fill with nonzero entries up until lastv. + for i := 0; i <= test.lastv; i++ { + v[i*test.incv] = rnd.Float64() + } + // Construct h explicitly to compare. + h := make([]float64, test.n*test.n) + for i := 0; i < test.n; i++ { + h[i*test.n+i] = 1 + } + hMat := blas64.General{ + Rows: test.n, + Cols: test.n, + Stride: test.n, + Data: h, + } + vVec := blas64.Vector{ + Inc: test.incv, + Data: v, + } + blas64.Ger(-test.tau, vVec, vVec, hMat) + + // Apply multiplication (2nd copy is to avoid aliasing). + cMat := blas64.General{ + Rows: test.m, + Cols: test.n, + Stride: test.ldc, + Data: cCopy, + } + cMat2 := blas64.General{ + Rows: test.m, + Cols: test.n, + Stride: test.ldc, + Data: cCopy2, + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, cMat2, hMat, 0, cMat) + + // cMat now stores the true answer. Compare with the function call. + work := make([]float64, sz) + impl.Dlarf(blas.Right, test.m, test.n, v, test.incv, test.tau, c, test.ldc, work) + if !floats.EqualApprox(c, cMat.Data, 1e-14) { + t.Errorf("Dlarf mismatch right, case %v. Want %v, got %v", i, cMat.Data, c) + } + + // Test on the left side. + copy(c, cCopy2) + copy(cCopy, c) + // Construct h. + h = make([]float64, test.m*test.m) + for i := 0; i < test.m; i++ { + h[i*test.m+i] = 1 + } + hMat = blas64.General{ + Rows: test.m, + Cols: test.m, + Stride: test.m, + Data: h, + } + blas64.Ger(-test.tau, vVec, vVec, hMat) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, hMat, cMat2, 0, cMat) + impl.Dlarf(blas.Left, test.m, test.n, v, test.incv, test.tau, c, test.ldc, work) + if !floats.EqualApprox(c, cMat.Data, 1e-14) { + t.Errorf("Dlarf mismatch left, case %v. Want %v, got %v", i, cMat.Data, c) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfb.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfb.go new file mode 100644 index 00000000..89e65e64 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfb.go @@ -0,0 +1,161 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dlarfber interface { + Dlarfter + Dlarfb(side blas.Side, trans blas.Transpose, direct lapack.Direct, + store lapack.StoreV, m, n, k int, v []float64, ldv int, t []float64, ldt int, + c []float64, ldc int, work []float64, ldwork int) +} + +func DlarfbTest(t *testing.T, impl Dlarfber) { + rnd := rand.New(rand.NewSource(1)) + for _, store := range []lapack.StoreV{lapack.ColumnWise, lapack.RowWise} { + for _, direct := range []lapack.Direct{lapack.Forward, lapack.Backward} { + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.Trans, blas.NoTrans} { + for cas, test := range []struct { + ma, na, cdim, lda, ldt, ldc int + }{ + {6, 6, 6, 0, 0, 0}, + {6, 8, 10, 0, 0, 0}, + {6, 10, 8, 0, 0, 0}, + {8, 6, 10, 0, 0, 0}, + {8, 10, 6, 0, 0, 0}, + {10, 6, 8, 0, 0, 0}, + {10, 8, 6, 0, 0, 0}, + {6, 6, 6, 12, 15, 30}, + {6, 8, 10, 12, 15, 30}, + {6, 10, 8, 12, 15, 30}, + {8, 6, 10, 12, 15, 30}, + {8, 10, 6, 12, 15, 30}, + {10, 6, 8, 12, 15, 30}, + {10, 8, 6, 12, 15, 30}, + {6, 6, 6, 15, 12, 30}, + {6, 8, 10, 15, 12, 30}, + {6, 10, 8, 15, 12, 30}, + {8, 6, 10, 15, 12, 30}, + {8, 10, 6, 15, 12, 30}, + {10, 6, 8, 15, 12, 30}, + {10, 8, 6, 15, 12, 30}, + } { + // Generate a matrix for QR + ma := test.ma + na := test.na + lda := test.lda + if lda == 0 { + lda = na + } + a := make([]float64, ma*lda) + for i := 0; i < ma; i++ { + for j := 0; j < lda; j++ { + a[i*lda+j] = rnd.Float64() + } + } + k := min(ma, na) + + // H is always ma x ma + var m, n, rowsWork int + switch { + default: + panic("not implemented") + case side == blas.Left: + m = test.ma + n = test.cdim + rowsWork = n + case side == blas.Right: + m = test.cdim + n = test.ma + rowsWork = m + } + + // Use dgeqr2 to find the v vectors + tau := make([]float64, na) + work := make([]float64, na) + impl.Dgeqr2(ma, k, a, lda, tau, work) + + // Correct the v vectors based on the direct and store + vMatTmp := extractVMat(ma, na, a, lda, lapack.Forward, lapack.ColumnWise) + vMat := constructVMat(vMatTmp, store, direct) + v := vMat.Data + ldv := vMat.Stride + + // Use dlarft to find the t vector + ldt := test.ldt + if ldt == 0 { + ldt = k + } + tm := make([]float64, k*ldt) + + impl.Dlarft(direct, store, ma, k, v, ldv, tau, tm, ldt) + + // Generate c matrix + ldc := test.ldc + if ldc == 0 { + ldc = n + } + c := make([]float64, m*ldc) + for i := 0; i < m; i++ { + for j := 0; j < ldc; j++ { + c[i*ldc+j] = rnd.Float64() + } + } + cCopy := make([]float64, len(c)) + copy(cCopy, c) + + ldwork := k + work = make([]float64, rowsWork*k) + + // Call Dlarfb with this information + impl.Dlarfb(side, trans, direct, store, m, n, k, v, ldv, tm, ldt, c, ldc, work, ldwork) + + h := constructH(tau, vMat, store, direct) + + cMat := blas64.General{ + Rows: m, + Cols: n, + Stride: ldc, + Data: make([]float64, m*ldc), + } + copy(cMat.Data, cCopy) + ans := blas64.General{ + Rows: m, + Cols: n, + Stride: ldc, + Data: make([]float64, m*ldc), + } + copy(ans.Data, cMat.Data) + switch { + default: + panic("not implemented") + case side == blas.Left && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, h, cMat, 0, ans) + case side == blas.Left && trans == blas.Trans: + blas64.Gemm(blas.Trans, blas.NoTrans, 1, h, cMat, 0, ans) + case side == blas.Right && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, cMat, h, 0, ans) + case side == blas.Right && trans == blas.Trans: + blas64.Gemm(blas.NoTrans, blas.Trans, 1, cMat, h, 0, ans) + } + if !floats.EqualApprox(ans.Data, c, 1e-14) { + t.Errorf("Cas %v mismatch. Want %v, got %v.", cas, ans.Data, c) + } + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfg.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfg.go new file mode 100644 index 00000000..aa463235 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfg.go @@ -0,0 +1,134 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlarfger interface { + Dlarfg(n int, alpha float64, x []float64, incX int) (beta, tau float64) +} + +func DlarfgTest(t *testing.T, impl Dlarfger) { + rnd := rand.New(rand.NewSource(1)) + for i, test := range []struct { + alpha float64 + n int + x []float64 + }{ + { + alpha: 4, + n: 3, + }, + { + alpha: -2, + n: 3, + }, + { + alpha: 0, + n: 3, + }, + { + alpha: 1, + n: 1, + }, + { + alpha: 1, + n: 2, + x: []float64{4, 5, 6}, + }, + } { + n := test.n + incX := 1 + var x []float64 + if test.x == nil { + x = make([]float64, n-1) + for i := range x { + x[i] = rnd.Float64() + } + } else { + x = make([]float64, n-1) + copy(x, test.x) + } + xcopy := make([]float64, n-1) + copy(xcopy, x) + alpha := test.alpha + beta, tau := impl.Dlarfg(n, alpha, x, incX) + + // Verify the returns and the values in v. Construct h and perform + // the explicit multiplication. + h := make([]float64, n*n) + for i := 0; i < n; i++ { + h[i*n+i] = 1 + } + hmat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: h, + } + v := make([]float64, n) + copy(v[1:], x) + v[0] = 1 + vVec := blas64.Vector{ + Inc: 1, + Data: v, + } + blas64.Ger(-tau, vVec, vVec, hmat) + eye := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + blas64.Gemm(blas.Trans, blas.NoTrans, 1, hmat, hmat, 0, eye) + iseye := true + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if i == j { + if math.Abs(eye.Data[i*n+j]-1) > 1e-14 { + iseye = false + } + } else { + if math.Abs(eye.Data[i*n+j]) > 1e-14 { + iseye = false + } + } + } + } + if !iseye { + t.Errorf("H^T * H is not I %v", eye) + } + + xVec := blas64.Vector{ + Inc: 1, + Data: make([]float64, n), + } + xVec.Data[0] = test.alpha + copy(xVec.Data[1:], xcopy) + + ans := make([]float64, n) + ansVec := blas64.Vector{ + Inc: 1, + Data: ans, + } + blas64.Gemv(blas.NoTrans, 1, hmat, xVec, 0, ansVec) + if math.Abs(ans[0]-beta) > 1e-14 { + t.Errorf("Case %v, beta mismatch. Want %v, got %v", i, ans[0], beta) + } + for i := 1; i < n; i++ { + if math.Abs(ans[i]) > 1e-14 { + t.Errorf("Case %v, nonzero answer %v", i, ans) + break + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarft.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarft.go new file mode 100644 index 00000000..e63abb9e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarft.go @@ -0,0 +1,168 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dlarfter interface { + Dgeqr2er + Dlarft(direct lapack.Direct, store lapack.StoreV, n, k int, v []float64, ldv int, tau []float64, t []float64, ldt int) +} + +func DlarftTest(t *testing.T, impl Dlarfter) { + rnd := rand.New(rand.NewSource(1)) + for _, store := range []lapack.StoreV{lapack.ColumnWise, lapack.RowWise} { + for _, direct := range []lapack.Direct{lapack.Forward, lapack.Backward} { + for _, test := range []struct { + m, n, ldv, ldt int + }{ + {6, 6, 0, 0}, + {8, 6, 0, 0}, + {6, 8, 0, 0}, + {6, 6, 10, 15}, + {8, 6, 10, 15}, + {6, 8, 10, 15}, + {6, 6, 15, 10}, + {8, 6, 15, 10}, + {6, 8, 15, 10}, + } { + // Generate a matrix + m := test.m + n := test.n + lda := n + if lda == 0 { + lda = n + } + + a := make([]float64, m*lda) + for i := 0; i < m; i++ { + for j := 0; j < lda; j++ { + a[i*lda+j] = rnd.Float64() + } + } + // Use dgeqr2 to find the v vectors + tau := make([]float64, n) + work := make([]float64, n) + impl.Dgeqr2(m, n, a, lda, tau, work) + + // Construct H using these answers + vMatTmp := extractVMat(m, n, a, lda, lapack.Forward, lapack.ColumnWise) + vMat := constructVMat(vMatTmp, store, direct) + v := vMat.Data + ldv := vMat.Stride + + h := constructH(tau, vMat, store, direct) + + k := min(m, n) + ldt := test.ldt + if ldt == 0 { + ldt = k + } + // Find T from the actual function + tm := make([]float64, k*ldt) + for i := range tm { + tm[i] = 100 + rnd.Float64() + } + // The v data has been put into a. + impl.Dlarft(direct, store, m, k, v, ldv, tau, tm, ldt) + + tData := make([]float64, len(tm)) + copy(tData, tm) + if direct == lapack.Forward { + // Zero out the lower traingular portion. + for i := 0; i < k; i++ { + for j := 0; j < i; j++ { + tData[i*ldt+j] = 0 + } + } + } else { + // Zero out the upper traingular portion. + for i := 0; i < k; i++ { + for j := i + 1; j < k; j++ { + tData[i*ldt+j] = 0 + } + } + } + + T := blas64.General{ + Rows: k, + Cols: k, + Stride: ldt, + Data: tData, + } + + vMatT := blas64.General{ + Rows: vMat.Cols, + Cols: vMat.Rows, + Stride: vMat.Rows, + Data: make([]float64, vMat.Cols*vMat.Rows), + } + for i := 0; i < vMat.Rows; i++ { + for j := 0; j < vMat.Cols; j++ { + vMatT.Data[j*vMatT.Stride+i] = vMat.Data[i*vMat.Stride+j] + } + } + var comp blas64.General + if store == lapack.ColumnWise { + // H = I - V * T * V^T + tmp := blas64.General{ + Rows: T.Rows, + Cols: vMatT.Cols, + Stride: vMatT.Cols, + Data: make([]float64, T.Rows*vMatT.Cols), + } + // T * V^T + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, T, vMatT, 0, tmp) + comp = blas64.General{ + Rows: vMat.Rows, + Cols: tmp.Cols, + Stride: tmp.Cols, + Data: make([]float64, vMat.Rows*tmp.Cols), + } + // V * (T * V^T) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, vMat, tmp, 0, comp) + } else { + // H = I - V^T * T * V + tmp := blas64.General{ + Rows: T.Rows, + Cols: vMat.Cols, + Stride: vMat.Cols, + Data: make([]float64, T.Rows*vMat.Cols), + } + // T * V + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, T, vMat, 0, tmp) + comp = blas64.General{ + Rows: vMatT.Rows, + Cols: tmp.Cols, + Stride: tmp.Cols, + Data: make([]float64, vMatT.Rows*tmp.Cols), + } + // V^T * (T * V) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, vMatT, tmp, 0, comp) + } + // I - V^T * T * V + for i := 0; i < comp.Rows; i++ { + for j := 0; j < comp.Cols; j++ { + comp.Data[i*m+j] *= -1 + if i == j { + comp.Data[i*m+j] += 1 + } + } + } + if !floats.EqualApprox(comp.Data, h.Data, 1e-14) { + t.Errorf("T does not construct proper H. Store = %v, Direct = %v.\nWant %v\ngot %v.", string(store), string(direct), h.Data, comp.Data) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfx.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfx.go new file mode 100644 index 00000000..a73e4f44 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlarfx.go @@ -0,0 +1,82 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlarfxer interface { + Dlarfx(side blas.Side, m, n int, v []float64, tau float64, c []float64, ldc int, work []float64) +} + +func DlarfxTest(t *testing.T, impl Dlarfxer) { + rnd := rand.New(rand.NewSource(1)) + for _, side := range []blas.Side{blas.Right, blas.Left} { + for m := 1; m < 12; m++ { + for n := 1; n < 12; n++ { + for _, extra := range []int{0, 1, 11} { + for cas := 0; cas < 10; cas++ { + testDlarfx(t, impl, side, m, n, extra, rnd) + } + } + } + } + } +} + +func testDlarfx(t *testing.T, impl Dlarfxer, side blas.Side, m, n, extra int, rnd *rand.Rand) { + const tol = 1e-13 + + c := randomGeneral(m, n, n+extra, rnd) + cWant := randomGeneral(m, n, n+extra, rnd) + tau := rnd.NormFloat64() + + var ( + v []float64 + h blas64.General + ) + if side == blas.Left { + v = randomSlice(m, rnd) + h = eye(m, m+extra) + } else { + v = randomSlice(n, rnd) + h = eye(n, n+extra) + } + blas64.Ger(-tau, blas64.Vector{Inc: 1, Data: v}, blas64.Vector{Inc: 1, Data: v}, h) + if side == blas.Left { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, h, c, 0, cWant) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, c, h, 0, cWant) + } + + var work []float64 + if h.Rows > 10 { + // Allocate work only if H has order > 10. + if side == blas.Left { + work = make([]float64, n) + } else { + work = make([]float64, m) + } + } + + impl.Dlarfx(side, m, n, v, tau, c.Data, c.Stride, work) + + prefix := fmt.Sprintf("Case side=%v, m=%v, n=%v, extra=%v", side, m, n, extra) + + // Check any invalid modifications of c. + if !generalOutsideAllNaN(c) { + t.Errorf("%v: out-of-range write to C\n%v", prefix, c.Data) + } + + if !equalApproxGeneral(c, cWant, tol) { + t.Errorf("%v: unexpected C\n%v", prefix, c.Data) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlartg.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlartg.go new file mode 100644 index 00000000..c7cade84 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlartg.go @@ -0,0 +1,98 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dlartger interface { + Dlartg(f, g float64) (cs, sn, r float64) +} + +func DlartgTest(t *testing.T, impl Dlartger) { + const tol = 1e-14 + // safmn2 and safmx2 are copied from native.Dlartg. + safmn2 := math.Pow(dlamchB, math.Trunc(math.Log(dlamchS/dlamchE)/math.Log(dlamchB)/2)) + safmx2 := 1 / safmn2 + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < 1000; i++ { + var f float64 + var fHuge bool + switch rnd.Intn(3) { + case 0: + // Huge f. + fHuge = true + f = math.Pow(10, 10-20*rnd.Float64()) * safmx2 + case 1: + // Tiny f. + f = math.Pow(10, 10-20*rnd.Float64()) * safmn2 + default: + f = rnd.NormFloat64() + } + if rnd.Intn(2) == 0 { + f *= -1 + } + + var g float64 + var gHuge bool + switch rnd.Intn(3) { + case 0: + // Huge g. + gHuge = true + g = math.Pow(10, 10-20*rnd.Float64()) * safmx2 + case 1: + // Tiny g. + g = math.Pow(10, 10-20*rnd.Float64()) * safmn2 + default: + g = rnd.NormFloat64() + } + if rnd.Intn(2) == 0 { + g *= -1 + } + + cs, sn, r := impl.Dlartg(f, g) + + rWant := cs*f + sn*g + if !floats.EqualWithinAbsOrRel(math.Abs(rWant), math.Abs(r), tol, tol) { + t.Errorf("Case f=%v,g=%v: unexpected r. Want %v, got %v", f, g, rWant, r) + } + oneTest := cs*cs + sn*sn + if math.Abs(oneTest-1) > tol { + t.Errorf("Case f=%v,g=%v: expected cs^2+sn^2==1, got %v", f, g, oneTest) + } + if !fHuge && !gHuge { + zeroTest := -sn*f + cs*g + if math.Abs(zeroTest) > tol { + t.Errorf("Case f=%v,g=%v: expected zero, got %v", f, g, zeroTest) + } + } + if math.Abs(f) > math.Abs(g) && cs < 0 { + t.Errorf("Case f=%v,g=%v: unexpected negative cs %v", f, g, cs) + } + } + for i := 0; i < 100; i++ { + cs, sn, _ := impl.Dlartg(rnd.NormFloat64(), 0) + if cs != 1 { + t.Errorf("Unexpected cs for g=0. Want 1, got %v", cs) + } + if sn != 0 { + t.Errorf("Unexpected sn for g=0. Want 0, got %v", sn) + } + } + for i := 0; i < 100; i++ { + cs, sn, _ := impl.Dlartg(0, rnd.NormFloat64()) + if cs != 0 { + t.Errorf("Unexpected cs for f=0. Want 0, got %v", cs) + } + if sn != 1 { + t.Errorf("Unexpected sn for f=0. Want 1, got %v", sn) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlas2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlas2.go new file mode 100644 index 00000000..a76e2742 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlas2.go @@ -0,0 +1,34 @@ +// 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 testlapack + +import ( + "math" + "testing" +) + +type Dlas2er interface { + Dlas2(f, g, h float64) (min, max float64) +} + +func Dlas2Test(t *testing.T, impl Dlas2er) { + for i, test := range []struct { + f, g, h, ssmin, ssmax float64 + }{ + // Singular values computed from Octave. + {10, 30, 12, 3.567778859365365, 33.634371616111189}, + {10, 30, -12, 3.567778859365365, 33.634371616111189}, + {2, 30, -12, 0.741557056404952, 32.364333658088754}, + {-2, 5, 12, 1.842864429909778, 13.023204317408728}, + } { + ssmin, ssmax := impl.Dlas2(test.f, test.g, test.h) + if math.Abs(ssmin-test.ssmin) > 1e-12 { + t.Errorf("Case %d, minimal singular value mismatch. Want %v, got %v", i, test.ssmin, ssmin) + } + if math.Abs(ssmax-test.ssmax) > 1e-12 { + t.Errorf("Case %d, minimal singular value mismatch. Want %v, got %v", i, test.ssmin, ssmin) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlascl.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlascl.go new file mode 100644 index 00000000..db792a4d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlascl.go @@ -0,0 +1,106 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/lapack" +) + +type Dlascler interface { + Dlascl(kind lapack.MatrixType, kl, ku int, cfrom, cto float64, m, n int, a []float64, lda int) +} + +func DlasclTest(t *testing.T, impl Dlascler) { + const tol = 1e-16 + + rnd := rand.New(rand.NewSource(1)) + for ti, test := range []struct { + m, n int + }{ + {0, 0}, + {1, 1}, + {1, 10}, + {10, 1}, + {2, 2}, + {2, 11}, + {11, 2}, + {3, 3}, + {3, 11}, + {11, 3}, + {11, 11}, + {11, 100}, + {100, 11}, + } { + m := test.m + n := test.n + for _, extra := range []int{0, 11} { + for _, kind := range []lapack.MatrixType{lapack.General, lapack.UpperTri, lapack.LowerTri} { + a := randomGeneral(m, n, n+extra, rnd) + aCopy := cloneGeneral(a) + cfrom := rnd.NormFloat64() + cto := rnd.NormFloat64() + scale := cto / cfrom + + impl.Dlascl(kind, -1, -1, cfrom, cto, m, n, a.Data, a.Stride) + + prefix := fmt.Sprintf("Case #%v: kind=%v,m=%v,n=%v,extra=%v", ti, kind, m, n, extra) + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A", prefix) + } + switch kind { + case lapack.General: + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + want := scale * aCopy.Data[i*aCopy.Stride+j] + got := a.Data[i*a.Stride+j] + if math.Abs(want-got) > tol { + t.Errorf("%v: unexpected A[%v,%v]=%v, want %v", prefix, i, j, got, want) + } + } + } + case lapack.UpperTri: + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + want := scale * aCopy.Data[i*aCopy.Stride+j] + got := a.Data[i*a.Stride+j] + if math.Abs(want-got) > tol { + t.Errorf("%v: unexpected A[%v,%v]=%v, want %v", prefix, i, j, got, want) + } + } + } + for i := 0; i < m; i++ { + for j := 0; j < min(i, n); j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification in lower triangle of A", prefix) + } + } + } + case lapack.LowerTri: + for i := 0; i < m; i++ { + for j := 0; j <= min(i, n-1); j++ { + want := scale * aCopy.Data[i*aCopy.Stride+j] + got := a.Data[i*a.Stride+j] + if math.Abs(want-got) > tol { + t.Errorf("%v: unexpected A[%v,%v]=%v, want %v", prefix, i, j, got, want) + } + } + } + for i := 0; i < m; i++ { + for j := i + 1; j < n; j++ { + if a.Data[i*a.Stride+j] != aCopy.Data[i*aCopy.Stride+j] { + t.Errorf("%v: unexpected modification in upper triangle of A", prefix) + } + } + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaset.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaset.go new file mode 100644 index 00000000..f0af77f5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaset.go @@ -0,0 +1,76 @@ +// 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 testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dlaseter interface { + Dlaset(uplo blas.Uplo, m, n int, alpha, beta float64, a []float64, lda int) +} + +func DlasetTest(t *testing.T, impl Dlaseter) { + rnd := rand.New(rand.NewSource(1)) + for ti, test := range []struct { + m, n int + }{ + {0, 0}, + {1, 1}, + {1, 10}, + {10, 1}, + {2, 2}, + {2, 10}, + {10, 2}, + {11, 11}, + {11, 100}, + {100, 11}, + } { + m := test.m + n := test.n + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower, blas.All} { + for _, extra := range []int{0, 10} { + a := randomGeneral(m, n, n+extra, rnd) + alpha := 1.0 + beta := 2.0 + + impl.Dlaset(uplo, m, n, alpha, beta, a.Data, a.Stride) + + prefix := fmt.Sprintf("Case #%v: m=%v,n=%v,uplo=%v,extra=%v", + ti, m, n, uplo, extra) + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A", prefix) + } + for i := 0; i < min(m, n); i++ { + if a.Data[i*a.Stride+i] != beta { + t.Errorf("%v: unexpected diagonal of A", prefix) + } + } + if uplo == blas.Upper || uplo == blas.All { + for i := 0; i < m; i++ { + for j := i + 1; j < n; j++ { + if a.Data[i*a.Stride+j] != alpha { + t.Errorf("%v: unexpected upper triangle of A", prefix) + } + } + } + } + if uplo == blas.Lower || uplo == blas.All { + for i := 1; i < m; i++ { + for j := 0; j < min(i, n); j++ { + if a.Data[i*a.Stride+j] != alpha { + t.Errorf("%v: unexpected lower triangle of A", prefix) + } + } + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq1.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq1.go new file mode 100644 index 00000000..064eaea0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq1.go @@ -0,0 +1,87 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlasq1er interface { + Dlasq1(n int, d, e, work []float64) int + Dgetrfer +} + +func Dlasq1Test(t *testing.T, impl Dlasq1er) { + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + // TODO(btracey): Increase the size of this test when we have a more numerically + // stable way to test the singular values. + for _, n := range []int{1, 2, 5, 8} { + work := make([]float64, 4*n) + d := make([]float64, n) + e := make([]float64, n-1) + for cas := 0; cas < 1; cas++ { + for i := range work { + work[i] = rnd.Float64() + } + for i := range d { + d[i] = rnd.NormFloat64() + 10 + } + for i := range e { + e[i] = rnd.NormFloat64() + } + ldm := n + m := make([]float64, n*ldm) + // Set up the matrix + for i := 0; i < n; i++ { + m[i*ldm+i] = d[i] + if i != n-1 { + m[(i+1)*ldm+i] = e[i] + } + } + + ldmm := n + mm := make([]float64, n*ldmm) + bi.Dgemm(blas.Trans, blas.NoTrans, n, n, n, 1, m, ldm, m, ldm, 0, mm, ldmm) + + impl.Dlasq1(n, d, e, work) + + // Check that they are singular values. The + // singular values are the square roots of the + // eigenvalues of X^T * X + mmCopy := make([]float64, len(mm)) + copy(mmCopy, mm) + ipiv := make([]int, n) + for elem, sv := range d[0:n] { + copy(mm, mmCopy) + lambda := sv * sv + for i := 0; i < n; i++ { + mm[i*ldm+i] -= lambda + } + + // Compute LU. + ok := impl.Dgetrf(n, n, mm, ldmm, ipiv) + if !ok { + // Definitely singular. + continue + } + // Compute determinant + var logdet float64 + for i := 0; i < n; i++ { + v := mm[i*ldm+i] + logdet += math.Log(math.Abs(v)) + } + if math.Exp(logdet) > 2 { + t.Errorf("Incorrect singular value. n = %d, cas = %d, elem = %d, det = %v", n, cas, elem, math.Exp(logdet)) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq2.go new file mode 100644 index 00000000..80b41b86 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq2.go @@ -0,0 +1,714 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dlasq2er interface { + Dgetrfer + Dlasq2(n int, z []float64) (info int) +} + +func Dlasq2Test(t *testing.T, impl Dlasq2er) { + dTol := 1e-6 + // Answers from calling the netlib Dlasq2 function directly. + for c, test := range []struct { + n int + z []float64 + info int + zOut []float64 + }{ + { + z: []float64{0.9975595900926172E+00, 0.5668247076112733E+00, 0.9659153754961249E+00, 0.7479276854714322E+00, 0.3673908973747557E+00, 0.4806368987547315E+00, 0.7375426363398452E-01, 0.5355229277727247E-02, 0.3470812885180155E+00, 0.3422438160728350E+00, 0.2179517263384726E+00, 0.1331604100136593E+00, 0.9005245144218924E+00, 0.3867660104574036E+00, 0.4454822893878481E+00, 0.6619321808958428E+00, 0.1610830043055933E-01, 0.6508548361039168E+00, 0.6464088254838254E+00, 0.3229872909405558E+00, 0.8556924028853313E+00, 0.4012869193638139E+00, 0.2068743292187569E+00, 0.9685394642165999E+00, 0.5983995343181346E+00, 0.6729807327762632E+00, 0.4568823106729620E+00, 0.3300151235733747E+00, 0.1003829265021773E+00, 0.7554533047597268E+00, 0.6056932669802318E+00, 0.7190479134084530E+00, 0.8973346038865299E+00, 0.6582291204811077E+00, 0.1507168371301046E+00, 0.6123149049967000E+00, 0.9786602381321465E+00, 0.9991422694268032E+00, 0.2567979861831603E+00, 0.5508654031552206E+00, 0.6590475178936379E+00, 0.5540051353968156E+00, 0.9777600986094505E+00, 0.9019233044604550E+00, 0.6579246844202109E+00, 0.7288585083995637E+00, 0.4024552650632751E+00, 0.9286276631540373E+00, 0.1478351900438915E+00, 0.6745292990637881E+00, 0.7696143092758962E+00, 0.3393225521457851E+00, 0.1158188549489931E+00, 0.6143691843615144E+00, 0.8206171394658319E+00, 0.9470946559240657E+00, 0.7311286518535550E+00, 0.4976039064630389E+00, 0.3748017407872005E+00, 0.4215058560045335E+00, 0.5529030382557849E+00, 0.9979192791781042E+00, 0.9903947480415133E+00, 0.7463096553073095E+00, 0.9537590617479789E+00, 0.9327469033343772E-01, 0.7340236871158429E+00, 0.7517616159256260E+00, 0.9468485056759987E+00, 0.7061763632511533E+00, 0.8138096664824992E+00, 0.5585945195965548E+00, 0.6170557687507783E-01, 0.4803807801853603E+00, 0.5976897721963292E+00, 0.1375319188363359E+00, 0.5873952004066820E+00, 0.5199682629163997E+00, 0.8858783448129579E+00, 0.3038101719904888E+00, 0.6696573039722583E+00, 0.6649400915297697E+00, 0.5036768993979404E+00, 0.2615751204119269E+00}, + n: 21, + zOut: []float64{0.2550031738262204E+01, 0.2480977513501848E+01, 0.2366602269912148E+01, 0.2169993432366266E+01, 0.1810817848712033E+01, 0.1681677309759878E+01, 0.1303743375476047E+01, 0.1202161769544433E+01, 0.1183377192742860E+01, 0.1094206688544886E+01, 0.9154376259418607E+00, 0.8241395430971566E+00, 0.7318275341991307E+00, 0.5186198053161721E+00, 0.4143051093784424E+00, 0.2112065329503869E+00, 0.1093987140067686E+00, 0.9751785856405315E-01, 0.2818174710670554E-01, 0.1697846193036144E-01, 0.2117542506861687E-04, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.2171122324673871E+02, 0.2171122324673871E+02, 0.1020000000000000E+03, 0.3081632653061225E+01, 0.2941176470588236E+01, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + info: 0, + }, + { + z: []float64{0.7655950151081736E-01, 0.1012496627944287E+00, 0.5492657397218519E+00, 0.3755849474908193E+00, 0.1514950257902281E-01, 0.7929154460744389E+00, 0.6208775449015512E+00, 0.7736035774285512E+00, 0.9535807609862423E+00, 0.1142443721338974E+00, 0.3184626428755636E+00, 0.5968198462235605E+00, 0.4815290260558158E-01, 0.1142057780273510E+00, 0.2159649191761220E+00, 0.1005733924928321E+00, 0.7334180249993905E-01, 0.2468617397276878E+00, 0.4433842667962828E+00, 0.2083675732544600E+00, 0.5669983427348256E+00, 0.2431239969651688E-01, 0.4202905770712168E+00, 0.3978530241169832E+00, 0.9765854254920880E+00, 0.6926050329928320E+00, 0.4943367486777372E-02, 0.1299210324451839E+00, 0.4677725963527957E-01, 0.8397777412847708E+00, 0.6784888222113696E+00, 0.5819508167748705E+00, 0.7335259194567719E+00, 0.1160427446694747E+00, 0.8402996546275487E+00, 0.8349959735427709E+00, 0.7465363962886192E+00, 0.8432008930683078E+00, 0.5288390014350658E+00, 0.6654846664813405E+00, 0.7307365692392301E+00, 0.4106042636492306E+00, 0.3557215961646439E+00, 0.7353770423280176E+00, 0.4713176648251016E+00, 0.4626254343486430E+00, 0.7596917071958065E+00, 0.7024594192654096E+00, 0.2579658084846748E+00, 0.9377050325544740E+00, 0.4561035840049426E+00, 0.8084892970067921E+00, 0.9088480529888660E+00, 0.6948766633235142E+00, 0.2194885062923195E+00, 0.8549545559228027E+00, 0.7443966896835119E+00, 0.3011130612705175E+00, 0.6719685452983997E+00, 0.6187140363783860E+00, 0.9675736114028010E+00, 0.9902393027740470E+00, 0.3380065169449795E+00, 0.9207672475882130E+00, 0.3390733399571427E+00, 0.9309435300662920E+00, 0.5465285509796513E+00, 0.4655125893217942E+00, 0.1769140958718970E+00, 0.3779940975005719E+00, 0.1752206228227682E+00, 0.3568582675012224E+00, 0.6656764250906758E+00, 0.6185492680730227E+00, 0.4689472437795331E+00, 0.3162518610221317E+00, 0.2688799086902824E+00, 0.1999212438248075E+00, 0.4154279763213168E+00, 0.9793029133347251E+00, 0.5432115888768534E+00, 0.1295182752745038E+00, 0.8047416637896615E+00, 0.8458210244967665E+00}, + n: 21, + zOut: []float64{0.2649710614371106E+01, 0.2321564474027070E+01, 0.2090779203479937E+01, 0.2001510674733695E+01, 0.1702794694134603E+01, 0.1077066053646038E+01, 0.1060140274732043E+01, 0.9894235909971354E+00, 0.9539342071687115E+00, 0.8046649468928653E+00, 0.7009142227469247E+00, 0.5502651835254770E+00, 0.4423863025187732E+00, 0.3697086796938907E+00, 0.1446051340026323E+00, 0.1110032523123295E+00, 0.7513603923341917E-01, 0.6860214953971246E-01, 0.2434478048112329E-01, 0.6989818532012803E-03, 0.7811996215926567E-04, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.1813933158005285E+02, 0.1813933158005285E+02, 0.1090000000000000E+03, 0.3231292517006803E+01, 0.5504587155963303E+01, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + info: 0, + }, + { + z: []float64{0.7090328374865308E+00, 0.5289732604915972E+00, 0.6638408676820399E+00, 0.9007392577685345E+00, 0.9411642674278379E+00, 0.1144202631330921E+00, 0.8666675899972089E+00, 0.6323680737151134E+00, 0.2427877245566508E+00, 0.1603957810123527E+00, 0.2123565414665629E-01, 0.1902539934369850E+00, 0.3123401294447815E+00, 0.8096475663099788E+00, 0.5737184899962203E+00, 0.8262606712006769E+00, 0.2864548736211023E+00, 0.1605147759074373E+00, 0.3309241142010387E+00, 0.2658533720189140E+00, 0.5447811280109880E+00, 0.5535203163154195E+00, 0.2161483615344606E-01, 0.1487480590324270E+00, 0.1049033762317957E+00, 0.6142137665037214E+00, 0.4062909815669834E+00, 0.9015282863354186E+00, 0.9428381000165521E+00, 0.1566198551488233E+00, 0.9369593797444957E+00, 0.1354729715149707E+00, 0.3712821832808397E+00, 0.3215112250898227E+00, 0.7149642455474942E+00, 0.7297077774959745E+00, 0.3785927874981971E+00, 0.8289344072747380E+00, 0.9536643756705742E+00, 0.3084192540817629E+00, 0.5797406195506623E+00, 0.2334488720392539E+00, 0.8444034680728870E+00, 0.2581324672603945E+00, 0.8397436353763532E+00, 0.5376562757207516E+00, 0.6215703771401371E+00, 0.4908247191212207E+00, 0.2848423854658637E+00, 0.2355591822832676E+00, 0.6513799258897619E+00, 0.6071703403704332E+00, 0.3981458512505542E+00, 0.8487946917355450E+00, 0.6376169839751418E+00, 0.2588233361358196E+00, 0.3588309885453386E+00, 0.5618301121344036E+00, 0.1214685095104872E+00, 0.9784693864155333E+00, 0.3832063578469370E+00, 0.7206987579838013E+00, 0.3582640246022534E+00, 0.9098815720988161E+00, 0.5436872318254895E+00, 0.9596753969896468E+00, 0.9294728975416107E+00, 0.6333208483475120E+00, 0.2956089747729942E+00, 0.1747395639573214E+00, 0.8425785962238860E+00, 0.6185896542974498E+00, 0.7058928872472775E+00, 0.2424399357290958E+00, 0.7979610473510427E+00, 0.3910140128664733E+00, 0.1099592891010870E+00, 0.7536879342329168E+00, 0.2979717756246736E-01, 0.7006607890734408E+00, 0.5252033671714352E+00, 0.7525598235593517E+00, 0.6476778890126167E+00, 0.8710847630132640E+00}, + n: 21, + zOut: []float64{0.2486733497028020E+01, 0.2359071020584524E+01, 0.2276435093308226E+01, 0.2061969496713965E+01, 0.1674052496256098E+01, 0.1634406821090099E+01, 0.1324515540477209E+01, 0.1213036064691536E+01, 0.1142092570196908E+01, 0.8479728747156923E+00, 0.7723287409164926E+00, 0.6845846156476076E+00, 0.4690003902541462E+00, 0.3969394481970619E+00, 0.3209839311891622E+00, 0.1762493640751034E+00, 0.1552318325824889E+00, 0.1299582823757977E+00, 0.4568511390642456E-01, 0.2058742849236605E-01, 0.6687292092604351E-04, 0.0000000000000000E+00, 0.9075510178548721E-16, 0.1809089799756099E-15, 0.1324515540477209E+01, 0.1972152263052530E-28, 0.7207148989396829E-15, 0.1135837106477965E-14, 0.1213036064691536E+01, 0.6865185493883853E-20, 0.3862483738583121E-14, 0.5795548067006594E-14, 0.1142092570196908E+01, 0.1237761291638161E-15, 0.1761387669893985E-13, 0.1204467761940304E-13, 0.8479728747156923E+00, 0.5980780785048348E-20, 0.5961915529495600E-12, 0.8546407799162654E-12, 0.7723287409164926E+00, 0.9983823616477125E-26, 0.2019190149561986E+02, 0.2019190149561985E+02, 0.1120000000000000E+03, 0.3267573696145125E+01, 0.7142857142857143E+01, 0.2981196239393922E-10, 0.4690003902541462E+00, 0.1411215361455214E-23, 0.1291839253366726E-09, 0.2114581039065388E-09, 0.3969394481970619E+00, 0.3215018396446338E-24, 0.8992249144513522E-09, 0.1460279739604385E-08, 0.3209839311891622E+00, 0.5301710738582062E-20, 0.5956459688113839E-08, 0.9509260151006140E-08, 0.1762493640751034E+00, 0.3305918938014538E-18, 0.2145126200057182E-06, 0.1391189925457742E-06, 0.1552318325824889E+00, 0.0000000000000000E+00, 0.8222867095540534E-06, 0.8520250895881005E-06, 0.1299582823757977E+00, 0.1946507846527860E-19, 0.4299487364203470E-05, 0.2670451838837521E-05, 0.4568511390642456E-01, 0.1783600337601646E-17, 0.1688330183620908E-03, 0.2840434656464124E-03, 0.2058742849236605E-01, 0.2127174768075152E-17, 0.5266290662212281E-04, 0.3082204001196310E-04, 0.6687292092604351E-04, 0.4725269249209171E-22, 0.3479992598793783E-02, 0.7157534417412210E-03}, + info: 0, + }, + { + z: []float64{0.8307212987388154E+00, 0.9571804405037874E+00, 0.2222674360399970E+00, 0.5794927951917870E+00, 0.9907605078898842E+00, 0.8399673535531696E+00, 0.1748054629244838E+00, 0.7095417514667766E+00, 0.3015507353664195E+00, 0.2504155371033889E-01, 0.9167396887269817E+00, 0.6888065712047682E+00, 0.7567577995550097E+00, 0.9327280452266753E+00, 0.5500991579404824E-01, 0.4989499454693689E+00, 0.5949898652751251E-01, 0.1718660951302574E+00, 0.6883620036166904E+00, 0.3066205390931208E+00, 0.7351901912310475E+00, 0.7521684164853142E+00, 0.3957210266430871E+00, 0.8778502662051324E-01, 0.4896297811280748E-01, 0.7793618951247419E+00, 0.6807766665219679E+00, 0.3115699624095645E+00, 0.5227646665950632E+00, 0.5057964692468060E+00, 0.4385260593432981E+00, 0.5876392780963172E+00, 0.2973252261444674E+00, 0.2948995727695043E+00, 0.7378444260331429E-01, 0.9749457382350615E+00, 0.7281626398300706E+00, 0.7580903878987629E+00, 0.3091762186458183E+00, 0.2464983240671905E+00, 0.2568872936019900E+00, 0.6180627613788815E+00, 0.9377882352337240E+00, 0.9921824152100049E+00, 0.2248192100106184E+00, 0.9472840045361628E+00, 0.8477853668436538E+00, 0.7001263233958666E+00, 0.5544440083201581E+00, 0.4415839019184687E+00, 0.2491818172148126E+00, 0.8976627554942691E+00, 0.1457298176556392E+00, 0.4345936198183369E+00, 0.4573762249453559E+00, 0.3093805347522776E+00, 0.4809246108862507E+00, 0.6897426752489948E+00, 0.8107988692352123E+00, 0.3921644162683642E+00, 0.2931487419364392E+00, 0.5759780604710760E+00, 0.7253418085569345E+00, 0.1427733376597652E+00, 0.3335555091947459E+00, 0.1603897948564823E+00, 0.5345943097231743E+00, 0.7233253065718669E+00, 0.2281802915301432E+00, 0.1990064435881517E+00, 0.9726196083044836E+00, 0.9935713768557323E+00, 0.8195201715007894E-01, 0.2508806553004002E+00, 0.2158489797899930E+00, 0.1957771185505375E+00, 0.8502651710165565E+00, 0.4468235108377239E-01, 0.8639211642125266E+00, 0.6713373034638015E-01, 0.4273173462824215E+00, 0.1373188375801981E+00, 0.1190874985301729E+00, 0.3059495456429208E+00}, + n: 21, + zOut: []float64{0.2399198387954965E+01, 0.2388283868878418E+01, 0.2234728187505421E+01, 0.1947641030296732E+01, 0.1845273105794422E+01, 0.1837097911259683E+01, 0.1471118007292610E+01, 0.1105651020532553E+01, 0.9883044021137968E+00, 0.9478841363642468E+00, 0.8550293065516678E+00, 0.7566674361156733E+00, 0.5310790726859680E+00, 0.3571217714437427E+00, 0.2893653184719416E+00, 0.2534414197270934E+00, 0.2173582726294167E+00, 0.4908458037260943E-01, 0.1246498683649276E-01, 0.5862142085722914E-02, 0.4704104342516643E-04, 0.1939986690620616E-19, 0.1034652479755287E-16, 0.1536368559490732E-16, 0.1471118007292610E+01, 0.5364686198585281E-13, 0.6088846084221820E-07, 0.1529604999486430E-06, 0.1105651020532553E+01, 0.2903008131213323E-27, 0.1160127138141562E-06, 0.1335479603764263E-06, 0.9883044021137968E+00, 0.2125606020077514E-18, 0.5906967539735199E-07, 0.6675815740532400E-07, 0.9478841363642468E+00, 0.1331202777560457E-29, 0.4438231138534822E-07, 0.3948328125271971E-07, 0.8550293065516678E+00, 0.5860341995390921E-20, 0.2049270140595660E+02, 0.2049270140595660E+02, 0.9800000000000000E+02, 0.2893424036281179E+01, 0.4081632653061225E+01, 0.1377712740565197E-07, 0.5310790726859680E+00, 0.1537961403283359E-19, 0.8011211497963711E-08, 0.8400248580143560E-08, 0.3571217714437427E+00, 0.5389497704469953E-25, 0.6965765014245226E-08, 0.7336584331089061E-08, 0.2893653184719416E+00, 0.6081961202185573E-17, 0.9973730165755502E-08, 0.8562226724273748E-08, 0.2534414197270934E+00, 0.3644137891043716E-17, 0.1552441635408352E-06, 0.1605842922922618E-07, 0.2173582726294167E+00, 0.1710250442519154E-26, 0.2805940935843235E-04, 0.1153299285109565E-04, 0.4908458037260943E-01, 0.1140499340513312E-15, 0.3458275194991493E-03, 0.2689727098393103E-03, 0.1246498683649276E-01, 0.4437342591868191E-30, 0.1429141842628293E-03, 0.1683368406483595E-03, 0.5862142085722914E-02, 0.2515327803596613E-22, 0.2394538487567536E-03, 0.1603201011413965E-03, 0.4704104342516643E-04, 0.0000000000000000E+00, 0.2149753858259932E-02, 0.4092589741085703E-02}, + info: 0, + }, + { + z: []float64{0.6132370003914160E+00, 0.6636632940312478E+00, 0.8959100063178993E+00, 0.7536793777540497E+00, 0.6298705159481864E+00, 0.2209880035966978E+00, 0.4838373503885766E+00, 0.6150203746616348E+00, 0.9876587724998732E+00, 0.5591876171910803E+00, 0.3708840600033242E+00, 0.3375947236522073E+00, 0.7454250822233153E+00, 0.5697349010621601E+00, 0.4561367007431339E+00, 0.6481896738286699E+00, 0.6835960923418801E+00, 0.1703905177923075E+00, 0.2730661115049011E+00, 0.4407624886449348E+00, 0.4577220273293221E+00, 0.3952566732937318E+00, 0.6883342106097436E+00, 0.2988887099704991E+00, 0.2052274263883085E+00, 0.1922842703083140E+00, 0.4189999528960880E+00, 0.6906452535299822E+00, 0.1405554539793709E+00, 0.1437412601859918E+00, 0.6624635742176765E+00, 0.5756752017566100E+00, 0.7749505183416766E+00, 0.7752965769666669E+00, 0.7653541054136069E+00, 0.8765107194498384E+00, 0.9921378985956986E-01, 0.3345156485504346E+00, 0.6450936562634260E+00, 0.1316181443467312E+00, 0.8075436662342752E+00, 0.5418723210737144E+00, 0.2657525890099199E+00, 0.4588749915888913E+00, 0.5109250246010762E+00, 0.5048342930643721E+00, 0.9617739307304302E+00, 0.5502351700731637E+00, 0.1896288106400514E+00, 0.2011189112848212E+00, 0.2487376305081674E+00, 0.9700914054633822E+00, 0.7763920500140777E+00, 0.2727004477756484E+00, 0.4969507403482072E+00, 0.3987515903118115E+00, 0.6132963384905279E+00, 0.8526865910258985E-01, 0.7370021348269777E+00, 0.8628692345603857E+00, 0.3410351221174988E+00, 0.6944408188735030E+00, 0.6418832405583447E+00, 0.8549561267667016E-01, 0.7079842121947655E+00, 0.5924596383322266E+00, 0.2327865765542259E+00, 0.7519783901092147E-01, 0.3243359400926964E+00, 0.9130914950306788E+00, 0.2042866226175709E+00, 0.4527677275849958E+00, 0.7271733772634871E+00, 0.2835797318864963E-01, 0.5170298378180002E+00, 0.7676612860726464E+00, 0.8943646165240225E+00, 0.9444900692816881E+00, 0.2898061819682256E+00, 0.5314658042534958E+00, 0.2328255902743269E+00, 0.3127766212762262E+00, 0.1415213232426512E+00, 0.3425808715425687E+00}, + n: 21, + zOut: []float64{0.2568497247033635E+01, 0.2474290441512907E+01, 0.2254355189310800E+01, 0.1987099258783412E+01, 0.1595738223681455E+01, 0.1520583769371047E+01, 0.1349481184037943E+01, 0.1286943522977408E+01, 0.1233633359467258E+01, 0.1105388350935419E+01, 0.8741663391031235E+00, 0.7042784684853729E+00, 0.6809050564171195E+00, 0.5312535309083547E+00, 0.3765999563195902E+00, 0.2982885955048700E+00, 0.1761408438030470E+00, 0.1021950592815966E+00, 0.5149411253987173E-01, 0.2409819364774552E-01, 0.3292801347387554E-02, 0.7649046082865931E-16, 0.2073367755475779E-07, 0.1625592945762753E-07, 0.1349481184037943E+01, 0.1183291357831518E-29, 0.4660703060512034E-13, 0.1807862490656452E-12, 0.1286943522977408E+01, 0.1649665924998180E-25, 0.1294990598064480E-10, 0.5231829186377068E-10, 0.1233633359467258E+01, 0.8526291632353489E-16, 0.3101844497115867E-08, 0.1140775990076438E-07, 0.1105388350935419E+01, 0.9624103043696344E-28, 0.5663389137423196E-06, 0.4346359020206590E-06, 0.8741663391031235E+00, 0.3067428736041242E-19, 0.2119872350446936E+02, 0.2119872350446936E+02, 0.1030000000000000E+03, 0.3056689342403628E+01, 0.2912621359223301E+01, 0.2039882393707806E-06, 0.6809050564171195E+00, 0.0000000000000000E+00, 0.3469744030301619E-06, 0.2644131172050035E-06, 0.5312535309083547E+00, 0.3043881270837009E-21, 0.5541811479797519E-05, 0.3827690844980446E-05, 0.3765999563195902E+00, 0.1909043390634849E-27, 0.3412067971678679E-04, 0.3418356678006945E-04, 0.2982885955048700E+00, 0.1167175485134229E-15, 0.1390598737761422E-03, 0.1685020271483295E-03, 0.1761408438030470E+00, 0.3311298373357662E-16, 0.2687183242739271E-03, 0.2970561145148615E-03, 0.1021950592815966E+00, 0.3861046454850253E-20, 0.3877059717439437E-03, 0.4274183271611622E-03, 0.5149411253987173E-01, 0.3171094621243632E-24, 0.5614281929126997E-03, 0.6201503766753644E-03, 0.2409819364774552E-01, 0.5854827030937197E-31, 0.8580439238194122E-03, 0.9937175751003719E-03, 0.3292801347387554E-02, 0.1687712113428427E-19, 0.6404816195044538E-02, 0.3574263865391779E-02}, + info: 0, + }, + { + z: []float64{0.1535280608392028E+00, 0.8492164242958209E+00, 0.9720508422713467E+00, 0.4409240313091006E+00, 0.7744413453832578E+00, 0.4562143200311385E+00, 0.8645004927526174E+00, 0.7279750979364787E+00, 0.6373358699411871E+00, 0.7240388495630282E+00, 0.6042124182518795E+00, 0.2629417492305242E-01, 0.2927658696806527E+00, 0.1971917075100318E+00, 0.9486620805007744E+00, 0.5318461733579811E+00, 0.1035922758398233E-01, 0.4521355876782263E+00, 0.9635828765019094E+00, 0.9861179636072996E+00, 0.3409131837267612E+00, 0.9592913933135179E+00, 0.3267081303471464E+00, 0.7042329006712417E+00, 0.7904477014671945E+00, 0.7235636505410947E+00, 0.7289557043239185E+00, 0.4453819137782510E+00, 0.3817792285714174E+00, 0.9222246883547156E+00, 0.7484233302016036E+00, 0.4267300781414476E+00, 0.2174272124496083E+00, 0.7294135193889231E+00, 0.7969150359898325E+00, 0.5584233158827989E+00, 0.8854167010119880E+00, 0.3831257236275667E+00, 0.2407966333760054E+00, 0.3150832526072347E+00, 0.4329046703236793E+00, 0.4798261053116015E-01, 0.4240797212710790E+00, 0.7373271503520912E+00, 0.8727856342792233E+00, 0.3079871491200393E+00, 0.8433176604823556E+00, 0.8160920845908722E+00, 0.4068006968345205E+00, 0.8649881745683563E+00, 0.8522504948442566E+00, 0.5120820890311298E+00, 0.7764141319706099E+00, 0.4928600452500731E+00, 0.2048536231221674E+00, 0.4451308747598662E+00, 0.4335546033385644E+00, 0.5471256397417612E-01, 0.7004960984988220E+00, 0.9192372420579460E+00, 0.3890133989146303E+00, 0.2488782917619309E+00, 0.3663470187625480E+00, 0.9986636866778884E+00, 0.6620792031393874E+00, 0.1797345205931197E+00, 0.8723761011602340E+00, 0.2439575243714007E+00, 0.1163919437436586E+00, 0.8182195270597429E+00, 0.5356403226658167E+00, 0.9880537276300997E+00, 0.4163057033602857E+00, 0.8081980088045720E+00, 0.2399383760782623E+00, 0.9702581513812658E+00, 0.3763181880939181E+00, 0.6334004896983517E+00, 0.1368995930243956E+00, 0.7684724492197631E+00, 0.1011989548860721E+00, 0.5519462180485674E+00, 0.8316516728108886E+00, 0.3772586994144635E+00}, + n: 21, + zOut: []float64{0.2579297838383781E+01, 0.2566242251743589E+01, 0.2402206059499122E+01, 0.2314572748831938E+01, 0.2210246243389976E+01, 0.2073991263591532E+01, 0.1647852770173070E+01, 0.1458062583915517E+01, 0.1424747680105817E+01, 0.1229594627898745E+01, 0.8682818248784862E+00, 0.7800126440184885E+00, 0.7769870810337002E+00, 0.4018986220147585E+00, 0.3451236345722463E+00, 0.2059421010707241E+00, 0.1665395041671736E+00, 0.1384541468623413E+00, 0.4569625338134105E-01, 0.3572364569397507E-01, 0.7785678858960618E-04, 0.1325624140040768E-19, 0.1464254707155794E-03, 0.9424803187834284E-04, 0.1647852770173070E+01, 0.1564186274351218E-15, 0.3473328524848360E-05, 0.4592867365821283E-05, 0.1458062583915517E+01, 0.3231174267785264E-26, 0.1403657959312935E-04, 0.9634257574341414E-05, 0.1424747680105817E+01, 0.1020140793606197E-15, 0.1723203566561169E-05, 0.6067379842882497E-05, 0.1229594627898745E+01, 0.2663149152121406E-17, 0.1061013981937667E-04, 0.1674993264096194E-04, 0.8682818248784862E+00, 0.8099755562101574E-24, 0.2367155138201492E+02, 0.2367155138201491E+02, 0.1110000000000000E+03, 0.3174603174603174E+01, 0.5405405405405405E+01, 0.8398559432747079E-06, 0.7769870810337002E+00, 0.0000000000000000E+00, 0.6532651675838807E-05, 0.1393736055608104E-04, 0.4018986220147585E+00, 0.1488702756444268E-16, 0.4786924897797409E-03, 0.2484818164296786E-03, 0.3451236345722463E+00, 0.1393994753571567E-18, 0.7967956438667165E-06, 0.1566848631115136E-05, 0.2059421010707241E+00, 0.1872521839860791E-17, 0.1674828806776016E-04, 0.3829209207735075E-04, 0.1665395041671736E+00, 0.5127595883936577E-29, 0.1145979873394449E-04, 0.6763541499702777E-05, 0.1384541468623413E+00, 0.6162975822039155E-31, 0.1509781169748205E-03, 0.4934238518442497E-04, 0.4569625338134105E-01, 0.3815207438965640E-25, 0.3298388086972868E-02, 0.1367005987525658E-02, 0.3572364569397507E-01, 0.2773930797150972E-21, 0.3955985102398275E-03, 0.3433403686203228E-03, 0.7785678858960618E-04, 0.7790054198074833E-21, 0.1914938157793930E-01, 0.1330976133014081E-01}, + info: 0, + }, + { + z: []float64{0.8677677383100214E+00, 0.6246622741727026E+00, 0.5523136647126087E+00, 0.2116103484147348E+00, 0.8227197076777661E+00, 0.3636019443697256E+00, 0.2305222034118074E+00, 0.3291143648196290E+00, 0.6800926583943011E+00, 0.4290450477605455E+00, 0.4523048516285796E+00, 0.9276084588261152E+00, 0.4462311938877914E+00, 0.6672491542978151E+00, 0.7808537049355564E+00, 0.7908271145868994E+00, 0.1977402045683964E+00, 0.2563794060302639E+00, 0.6768044668199432E+00, 0.8985309013607360E+00, 0.3750140409512910E+00, 0.2003663066929584E-01, 0.4020022629723622E+00, 0.9909625073113403E+00, 0.9747495116121061E+00, 0.9702779584867087E+00, 0.9688371740876045E+00, 0.3747269639045615E+00, 0.9728403214040160E-01, 0.7507234588709335E+00, 0.8245099981459856E+00, 0.7244448753186800E+00, 0.3670523289486082E+00, 0.6220520718362722E+00, 0.3063226611493952E+00, 0.3012769332894331E+00, 0.6763821017483275E+00, 0.8300640433662996E+00, 0.5563237542291373E+00, 0.5594449054752113E+00, 0.3278038518373678E+00, 0.7307041435680680E+00, 0.1582529760475658E+00, 0.5328751876026443E+00, 0.7841944053171677E+00, 0.2157818394558657E+00, 0.3253134136288985E+00, 0.5014502641306768E+00, 0.2229178930043155E+00, 0.4664985859426845E+00, 0.1867987929192785E+00, 0.1951091673564507E+00, 0.2069185156156168E+00, 0.9058058542218750E+00, 0.7999188612304056E+00, 0.7349484002829904E+00, 0.4153480749961962E+00, 0.8109879258422723E+00, 0.9883741464101338E+00, 0.4911202582082937E+00, 0.2193166361224579E+00, 0.7618820222564749E+00, 0.9073087210515056E+00, 0.5896383620860655E+00, 0.8706198942119541E+00, 0.3860710050052940E-01, 0.9380336544251486E+00, 0.4690283060543987E-01, 0.8970820572284144E+00, 0.1974579201509297E-01, 0.9992442335759629E+00, 0.9801967887432729E+00, 0.6116617864086051E+00, 0.5875675950916066E+00, 0.9622537584002233E+00, 0.8934200351761762E+00, 0.2022182729782195E+00, 0.1273316669652236E-01, 0.2549904925850485E+00, 0.8904280763656908E+00, 0.2695748922419082E+00, 0.8890196843116763E+00, 0.5191439214393291E+00, 0.3672061831861048E+00}, + n: 21, + zOut: []float64{0.3071910136434907E+01, 0.2366684893081943E+01, 0.2247985022656176E+01, 0.2134160618983571E+01, 0.1929380862422316E+01, 0.1895668448583188E+01, 0.1735809456784568E+01, 0.1390623822795548E+01, 0.1372853012616850E+01, 0.1197489438156041E+01, 0.1106600205023489E+01, 0.8564547950868329E+00, 0.4949238197552136E+00, 0.3889452841496929E+00, 0.3405947975938995E+00, 0.2516597920662951E+00, 0.2113890461921598E+00, 0.1169778386549868E+00, 0.1072268106836703E+00, 0.7646784687889400E-02, 0.1286588928027629E-02, 0.1194767075191949E-22, 0.1162094363453686E-09, 0.8691558890693288E-10, 0.1735809456784568E+01, 0.8134816760001801E-14, 0.1019665656815186E-08, 0.1906916241197346E-08, 0.1390623822795548E+01, 0.0000000000000000E+00, 0.1594323424098234E-05, 0.3312168640703357E-05, 0.1372853012616850E+01, 0.0000000000000000E+00, 0.3830524268846776E-04, 0.1577534719508939E-04, 0.1197489438156041E+01, 0.1592850300841939E-16, 0.1256296423282912E-03, 0.1149042579564614E-03, 0.1106600205023489E+01, 0.6530365529382261E-18, 0.2322627147533726E+02, 0.2322627147533726E+02, 0.1020000000000000E+03, 0.2963718820861678E+01, 0.3921568627450980E+01, 0.6483516393063832E-03, 0.4949238197552136E+00, 0.1972152263052530E-28, 0.5430985229870038E-04, 0.4447663749968261E-04, 0.3889452841496929E+00, 0.1329049288162406E-17, 0.2738942590248176E-04, 0.1582812372822289E-04, 0.3405947975938995E+00, 0.1187508759187252E-18, 0.7465410105999781E-04, 0.1255487400488340E-03, 0.2516597920662951E+00, 0.4141519752410312E-29, 0.2152266118694742E-04, 0.6710408995051273E-05, 0.2113890461921598E+00, 0.3333294884283764E-18, 0.6132111109262542E-03, 0.4277764486586744E-03, 0.1169778386549868E+00, 0.2711709361697228E-30, 0.3832079371139971E-03, 0.3904887652242632E-03, 0.1072268106836703E+00, 0.2176254805972020E-18, 0.4306247975784355E-03, 0.4948147025217374E-03, 0.7646784687889400E-02, 0.1110488679882733E-19, 0.1569670832436511E-02, 0.2092370053382882E-02, 0.1286588928027629E-02, 0.5442848430598922E-18, 0.4460307636637516E-02, 0.7046212350403941E-02}, + info: 0, + }, + { + z: []float64{0.9838241499564321E+00, 0.8769514477589457E+00, 0.6814467524843054E+00, 0.3624618995089947E+00, 0.1981908649829056E+00, 0.1872278407669582E+00, 0.9876554444003832E+00, 0.1826583579385833E+00, 0.1183269767614670E-01, 0.9437175277915953E+00, 0.4919320768587329E+00, 0.9805291749478650E+00, 0.6132842150855770E+00, 0.3626870797541525E+00, 0.5323780753704027E+00, 0.1457937981484730E+00, 0.1328300737138376E+00, 0.3811835111034733E+00, 0.7003413504474413E+00, 0.5497308136521228E+00, 0.8255713255718768E+00, 0.5373393799690840E+00, 0.6623327475759663E+00, 0.5316913920782962E-01, 0.1714649183335913E+00, 0.6186592957613974E+00, 0.7587327126921758E+00, 0.9100586255702885E+00, 0.7140000863381626E+00, 0.7400119974078728E+00, 0.3567025022071233E+00, 0.8218612151637966E+00, 0.5520556331010515E+00, 0.6508027169553372E+00, 0.1875664464519897E+00, 0.8183092398415237E+00, 0.2239662369231676E-01, 0.6571790154721793E+00, 0.1196415656369646E+00, 0.3853512775546503E+00, 0.2426450009067070E+00, 0.9653447575661293E+00, 0.4852906340727067E+00, 0.9923496603563310E+00, 0.2812811891225394E+00, 0.9784300144088514E+00, 0.9528689986126391E+00, 0.2431080020200448E+00, 0.4166208849723857E+00, 0.7357806826601304E+00, 0.1952831632199464E+00, 0.6393407699957093E+00, 0.6296804002658308E+00, 0.1028694374663701E+00, 0.1387452591062114E+00, 0.4549213107961220E+00, 0.9843671628976580E+00, 0.4249152858158138E+00, 0.7048043599695387E+00, 0.3653998904622074E+00, 0.2003765309007774E+00, 0.4095912484595889E+00, 0.2392233396621621E+00, 0.7050044605645847E+00, 0.7908086424110450E-01, 0.2038177493661538E+00, 0.1735168081909322E-01, 0.3343100300667304E+00, 0.2848572906345944E+00, 0.8454138442968477E+00, 0.4944340369822147E+00, 0.7101083458004501E+00, 0.2546477176633619E+00, 0.8227235336957786E+00, 0.2816146807741101E+00, 0.6247995550265835E+00, 0.7458069042729408E+00, 0.8739345864578790E+00, 0.1278937298671606E+00, 0.2791833532060612E+00, 0.9234762152279486E+00, 0.9863012584972185E+00, 0.7892913846591531E+00, 0.3479266835120939E+00}, + n: 21, + zOut: []float64{0.2623495482601064E+01, 0.2337512212773574E+01, 0.2310508039367694E+01, 0.2188663096012427E+01, 0.1954141717332891E+01, 0.1371476701077329E+01, 0.1267869950064541E+01, 0.1203016320141301E+01, 0.1132845050819559E+01, 0.9979737678355206E+00, 0.8633053234635751E+00, 0.6603430282082061E+00, 0.6064350433288983E+00, 0.4855760962077864E+00, 0.4280373135604714E+00, 0.3659370670152315E+00, 0.1453682093766173E+00, 0.9617861239701422E-01, 0.7192949634365248E-01, 0.1892143303127712E-02, 0.3946528731286962E-05, 0.0000000000000000E+00, 0.9258243476772570E-07, 0.9000418438492766E-07, 0.1267869950064541E+01, 0.0000000000000000E+00, 0.2500234135491857E-07, 0.1856395032302831E-07, 0.1203016320141301E+01, 0.2658426139847422E-18, 0.4168972835699797E-07, 0.5531467635213317E-07, 0.1132845050819559E+01, 0.2518044009465470E-24, 0.1194059466661935E-08, 0.2159625808467239E-08, 0.9979737678355206E+00, 0.1047506307937635E-23, 0.4478743649191460E-07, 0.9991281120631680E-07, 0.8633053234635751E+00, 0.5895762127714383E-22, 0.2111250861775921E+02, 0.2111250861775921E+02, 0.9900000000000000E+02, 0.2927437641723356E+01, 0.4040404040404041E+01, 0.9244672049175682E-07, 0.6064350433288983E+00, 0.1817535525629211E-26, 0.9398974933478891E-07, 0.9547946669183887E-07, 0.4855760962077864E+00, 0.3185418565406740E-17, 0.9937648506460343E-07, 0.9792626502078532E-07, 0.4280373135604714E+00, 0.2958228394578794E-30, 0.9921525775570031E-07, 0.1006425128472401E-06, 0.3659370670152315E+00, 0.4461863922899316E-21, 0.1047488573169732E-06, 0.1032270990738791E-06, 0.1453682093766173E+00, 0.6504493884088473E-15, 0.1102576940374778E-06, 0.1180293023862048E-06, 0.9617861239701422E-01, 0.6467797587852522E-18, 0.1844536574504796E-06, 0.1488485108626942E-06, 0.7192949634365248E-01, 0.2114103686638959E-13, 0.8531410278849863E-06, 0.1408572284551695E-05, 0.1892143303127712E-02, 0.0000000000000000E+00, 0.6242841403373791E-04, 0.3522115697192072E-04, 0.3946528731286962E-05, 0.6203854594147708E-24, 0.1209929086462260E-02, 0.4906802871097585E-03}, + info: 0, + }, + { + z: []float64{0.7643247442799757E+00, 0.1930914554442843E+00, 0.6441117687067544E-01, 0.4522061669974708E-01, 0.1465182320932497E+00, 0.8069033698425149E+00, 0.6560188128523874E+00, 0.2446749124420051E+00, 0.3243649544497533E+00, 0.9836733438970116E+00, 0.6137527621157332E+00, 0.2925225554635034E+00, 0.4955619768673408E+00, 0.7361289066349539E+00, 0.3953262269487445E-01, 0.1565854250658760E-01, 0.4785236355428808E+00, 0.7766165270899886E+00, 0.9069259340739989E+00, 0.9151936268801151E+00, 0.3338292872636017E+00, 0.2993135005490550E+00, 0.8287022194584887E+00, 0.4593628480546942E+00, 0.1484428934315618E-01, 0.3390977660295040E+00, 0.5819746692101802E-01, 0.9277352020779983E-01, 0.6517310862845033E+00, 0.3951866136249272E+00, 0.6199300068296295E+00, 0.8252199884043853E+00, 0.3390764160478065E+00, 0.3084679704183562E+00, 0.3609211283483548E+00, 0.4116857210304998E+00, 0.4609476939442378E+00, 0.3824129844545763E+00, 0.6431169626236315E+00, 0.2416519334621993E+00, 0.7156780768158061E+00, 0.8568018406565006E+00, 0.1639408452444666E+00, 0.7313040585903831E+00, 0.5099183572592548E+00, 0.2801641590611897E+00, 0.9930562568266591E+00, 0.7612468327164370E+00, 0.3271886985411110E-01, 0.7066605591101006E+00, 0.6720867845388043E+00, 0.9004209067318458E-01, 0.4611918168927077E+00, 0.2638384667560661E+00, 0.3554909044606102E+00, 0.7231384727137510E+00, 0.2729268177075039E-01, 0.5848397641916390E+00, 0.6942450598380807E+00, 0.1106927451590289E+00, 0.5262572286481777E+00, 0.9936768911750095E+00, 0.7262536107933111E+00, 0.7604873714570974E+00, 0.2036182130165832E+00, 0.8632527217998969E+00, 0.1924957421132846E+00, 0.8815968660524154E-01, 0.2412813036310424E+00, 0.9105232147744077E+00, 0.8298587923387578E+00, 0.7754575363227978E-01, 0.8714764594177653E+00, 0.5571901679066804E+00, 0.3971870017409277E+00, 0.9993097753535422E+00, 0.7700188328643205E+00, 0.7856615172810383E+00, 0.7533953600915489E+00, 0.5602208064288483E+00, 0.6944234372397261E+00, 0.8756090822068926E+00, 0.1433700749181099E-01, 0.2857413018245216E+00}, + n: 21, + zOut: []float64{0.2546753248931182E+01, 0.2051980365170268E+01, 0.1958366389726797E+01, 0.1631238683423845E+01, 0.1586034790683645E+01, 0.1538534425510682E+01, 0.1255412586747036E+01, 0.1121690972560896E+01, 0.9718147643766369E+00, 0.9049110982817965E+00, 0.7946671649858114E+00, 0.5884376759528481E+00, 0.4050217422474118E+00, 0.3189813042957475E+00, 0.2502079076659038E+00, 0.1378021633219403E+00, 0.1230588999356998E+00, 0.5024634530670342E-01, 0.4118371112977081E-01, 0.5279820157992808E-02, 0.1421284452028254E-03, 0.2680065184671810E-21, 0.2301930285321580E-14, 0.5132436462785431E-14, 0.1255412586747036E+01, 0.2424007516335156E-18, 0.1913029885324846E-10, 0.9021761757831104E-11, 0.1121690972560896E+01, 0.1977581519346623E-22, 0.4602280167506019E-08, 0.2460881124989248E-08, 0.9718147643766369E+00, 0.1104484640438811E-18, 0.4278245612761057E-07, 0.2387897413722468E-07, 0.9049110982817965E+00, 0.2768434971275651E-16, 0.3015076539683485E-07, 0.2961312447326530E-07, 0.7946671649858114E+00, 0.1262042385269225E-19, 0.1828176618885781E+02, 0.1828176618885782E+02, 0.1040000000000000E+03, 0.3122448979591837E+01, 0.3846153846153846E+01, 0.1851926648424158E-06, 0.4050217422474118E+00, 0.9293221980374701E-17, 0.1284245841610550E-05, 0.2164676294343609E-05, 0.3189813042957475E+00, 0.1378649105642637E-16, 0.4610281885819925E-06, 0.1003327305702036E-05, 0.2502079076659038E+00, 0.2177821011994986E-13, 0.3677246803752887E-04, 0.3095541926811936E-04, 0.1378021633219403E+00, 0.9210656120777790E-20, 0.9401458780737957E-05, 0.1039122642078444E-04, 0.1230588999356998E+00, 0.4930380657631324E-30, 0.6528493871226699E-06, 0.1524653341983116E-05, 0.5024634530670342E-01, 0.6838275466788171E-23, 0.2104276631320477E-03, 0.3160258883556432E-03, 0.4118371112977081E-01, 0.6162975822039155E-32, 0.9318133168194381E-04, 0.1261364640367337E-03, 0.5279820157992808E-02, 0.7005084838362585E-27, 0.1903158606362315E-02, 0.7288242235414376E-03, 0.1421284452028254E-03, 0.7703719777548943E-33, 0.7890744155827079E-03, 0.6129022301104231E-03}, + info: 0, + }, + { + z: []float64{0.1813251202119042E+00, 0.8077156210855166E+00, 0.5525396662071069E+00, 0.4858391136124270E+00, 0.5367389425969793E+00, 0.4534294101162717E-01, 0.1438386197304258E+00, 0.7801305810912117E+00, 0.7706244548712898E+00, 0.1595286891781422E+00, 0.4689597797472277E+00, 0.1630160981693277E+00, 0.5488525733069047E+00, 0.3050379405729475E+00, 0.1544160351990825E+00, 0.5750210099163514E+00, 0.1440876969429373E+00, 0.1932969959898051E+00, 0.6910796187912660E+00, 0.9501882645686455E+00, 0.1314109921701710E+00, 0.7099941843070685E+00, 0.3797313713209320E+00, 0.3979808845174081E+00, 0.1006018923100482E-02, 0.4131896358268045E+00, 0.8038132966802857E+00, 0.8778643630407806E+00, 0.1407889867849830E+00, 0.4305134083308382E-01, 0.5656496703997997E+00, 0.5820188952601091E-01, 0.8713537916178680E+00, 0.3443162753417257E+00, 0.4898335360866699E+00, 0.2822165738696382E+00, 0.2385629061714932E+00, 0.5496478420286478E+00, 0.7138724344268773E+00, 0.9028268569137332E+00, 0.7573748459251011E+00, 0.5392259606733280E+00, 0.6459213128573325E+00, 0.7769497211063184E+00, 0.8790154346127051E+00, 0.6027389165195913E+00, 0.6151696559086139E-01, 0.4391208291942791E+00, 0.8705350585502258E-02, 0.2995750933531418E+00, 0.9735013653226658E+00, 0.9551710085419519E+00, 0.2132875677034638E+00, 0.6739668529657764E+00, 0.5361543284664445E+00, 0.3596977928604983E+00, 0.1373006735837845E-02, 0.8494363479416891E+00, 0.4214720423022895E+00, 0.7478449906096684E+00, 0.1164429527473354E-01, 0.6143683285709396E+00, 0.4444360064738268E+00, 0.6626608299302873E+00, 0.6887459689591686E+00, 0.9391262494647765E+00, 0.7167310461528731E+00, 0.4516657019045726E+00, 0.6345059624902227E+00, 0.2241941493026407E+00, 0.3981621310014529E+00, 0.8300976429090324E+00, 0.1390103241004258E+00, 0.7559319384422415E+00, 0.7929892786129927E+00, 0.2279061631835571E+00, 0.5280867615120838E+00, 0.1374499172030500E+00, 0.1739503966093568E+00, 0.1475298919309330E+00, 0.8100098524713260E+00, 0.2514850916075489E+00, 0.4100580488172028E+00, 0.9565966467338131E+00}, + n: 21, + zOut: []float64{0.2319179815575576E+01, 0.1965907124623829E+01, 0.1887317422176422E+01, 0.1806195743608332E+01, 0.1738584542532610E+01, 0.1518839817892385E+01, 0.1233018482483247E+01, 0.1147944957333420E+01, 0.8847632334488245E+00, 0.7964611162721277E+00, 0.7478364459856081E+00, 0.6404526251941426E+00, 0.4533452491188792E+00, 0.4218888103472739E+00, 0.2727838365998446E+00, 0.2511907405802137E+00, 0.9874721307137806E-01, 0.7639943902083833E-01, 0.4105860224136690E-01, 0.2835039177122555E-01, 0.1849635761425839E-05, 0.5687744349931984E-17, 0.4733652108368680E-16, 0.8474188088642906E-16, 0.1233018482483247E+01, 0.2772075531849652E-16, 0.2588283290162890E-14, 0.3835910828290052E-14, 0.1147944957333420E+01, 0.1246926305809672E-21, 0.2331804915191085E-13, 0.1628473983494628E-13, 0.8847632334488245E+00, 0.1029638495848151E-18, 0.6869501877456999E-13, 0.5177641249986829E-13, 0.7964611162721277E+00, 0.2366582715663035E-28, 0.1931319748910825E-12, 0.1483226506162133E-12, 0.7478364459856081E+00, 0.0000000000000000E+00, 0.1833026745951331E+02, 0.1833026745951330E+02, 0.1060000000000000E+03, 0.3281179138321995E+01, 0.4716981132075472E+01, 0.1032982741787823E-11, 0.4533452491188792E+00, 0.1306947070833229E-13, 0.7648022419924529E-11, 0.9563864191611805E-11, 0.4218888103472739E+00, 0.2958228394578794E-30, 0.1901963755802408E-10, 0.2450915092704452E-10, 0.2727838365998446E+00, 0.2459678163240430E-25, 0.5533379126041796E-09, 0.3623624255644135E-09, 0.2511907405802137E+00, 0.1890110728909544E-26, 0.3358805149198491E-08, 0.5375184613165106E-08, 0.9874721307137806E-01, 0.5174927538249837E-27, 0.5300164302540724E-07, 0.8261446474891677E-07, 0.7639943902083833E-01, 0.5686866711287438E-23, 0.3075058441398368E-06, 0.1980286028193141E-06, 0.4105860224136690E-01, 0.3391723239215845E-21, 0.3233943307567427E-08, 0.7908141105983331E-09, 0.2835039177122555E-01, 0.0000000000000000E+00, 0.6263230510933575E-04, 0.3843833760247782E-04, 0.1849635761425839E-05, 0.1263270231490984E-18, 0.3749684628997549E-02, 0.9345197933294263E-02}, + info: 0, + }, + { + z: []float64{0.7197398584131909E+00, 0.8353840049537183E+00, 0.7768334206137515E+00, 0.5378835466874095E+00, 0.6112887154160760E+00, 0.6941229566444685E+00, 0.6006831303610110E+00, 0.9634869426512738E-01, 0.5491965547787625E+00, 0.2928965321959978E+00, 0.2058564636772363E+00, 0.8430652032339261E+00, 0.6514967955084195E+00, 0.9630832188959448E+00, 0.6099558369768557E+00, 0.4038812997556026E+00, 0.1286146012481256E+00, 0.1377932216741019E+00, 0.2151249629422850E+00, 0.5230096632076910E+00, 0.7097266420339532E+00, 0.5223889086485353E+00, 0.1844557902493219E+00, 0.8630886970819189E+00, 0.3143018526841452E+00, 0.3064747008129198E-02, 0.9995777893655772E+00, 0.8804003743833377E+00, 0.2437734590599224E+00, 0.5439224193002447E+00, 0.7609946860078259E+00, 0.6816222186177212E+00, 0.4213100187092527E+00, 0.5947299218072758E+00, 0.4464510683518146E+00, 0.9444991162538406E+00, 0.1663546170185037E+00, 0.9745722490509305E+00, 0.8691156687582791E-01, 0.1511122923287322E+00, 0.9099013034006386E+00, 0.2055280668016559E+00, 0.2215435147609097E+00, 0.1341458340087506E+00, 0.6974464577249216E+00, 0.9770585050570383E+00, 0.2836484389736937E-02, 0.4942205711890229E+00, 0.2476589071081227E+00, 0.9025674475802441E+00, 0.1043173067377164E+00, 0.7752297952628227E+00, 0.1045812556997563E+00, 0.6207135868564088E+00, 0.3343332589884191E+00, 0.9777410164371825E+00, 0.6919265640807399E+00, 0.8276791372331573E+00, 0.9681277631171376E+00, 0.2774385945770376E+00, 0.3660516291700039E+00, 0.1542243233614283E+00, 0.9809065840498956E+00, 0.9317468521553756E+00, 0.2342755587307467E+00, 0.1233924367977165E+00, 0.3662228319745224E+00, 0.8394462754756703E+00, 0.1257927855780998E+00, 0.9899742295380913E+00, 0.4800112259347978E+00, 0.9614338190585195E+00, 0.9605383026678687E+00, 0.7532278237974727E+00, 0.6455994058946259E+00, 0.6648840697262024E+00, 0.8792931963163917E+00, 0.7296338860815629E+00, 0.6962759488463338E+00, 0.5343477930729980E+00, 0.7488075021642351E+00, 0.8267598422017227E+00, 0.4128864062622362E-02, 0.2248794313377519E+00}, + n: 21, + zOut: []float64{0.2440396187223568E+01, 0.2429593845031884E+01, 0.2248977224883395E+01, 0.1983141106497864E+01, 0.1775047097539426E+01, 0.1685850120713433E+01, 0.1685238074648001E+01, 0.1228212776246503E+01, 0.1167582065653490E+01, 0.1163468828895948E+01, 0.9840288601088477E+00, 0.8446765744020336E+00, 0.5858419229944851E+00, 0.5828733061329966E+00, 0.4321746091262585E+00, 0.2506332278777725E+00, 0.1601952029039821E+00, 0.9519704710728188E-01, 0.5380488026634178E-01, 0.2070966044404248E-02, 0.4144953892415127E-03, 0.1577721810442024E-28, 0.2622007349295965E-13, 0.1959395597612919E-13, 0.1685238074648001E+01, 0.5298116057209151E-24, 0.4690429322435832E-13, 0.6275308499802102E-13, 0.1228212776246503E+01, 0.3786532345060857E-26, 0.6968636880972768E-12, 0.1483661956038748E-11, 0.1167582065653490E+01, 0.4135903062764930E-23, 0.1852086238235612E-10, 0.7750996975985970E-11, 0.1163468828895948E+01, 0.1171277614412583E-17, 0.1085363071939462E-09, 0.2643024434742409E-09, 0.9840288601088477E+00, 0.6878867093527223E-27, 0.2179941841968715E+02, 0.2179941841968716E+02, 0.1010000000000000E+03, 0.3140589569160998E+01, 0.4950495049504950E+01, 0.1077573597463830E-06, 0.5858419229944851E+00, 0.3627601229823987E-15, 0.8463992810044351E-06, 0.7647582718993818E-06, 0.5828733061329966E+00, 0.5798443197736525E-25, 0.5805124866712180E-06, 0.5336279095847515E-06, 0.4321746091262585E+00, 0.1164890830118439E-21, 0.3270430863981586E-06, 0.3120015969970153E-06, 0.2506332278777725E+00, 0.1344740577327136E-22, 0.6612009870063018E-06, 0.4716796838663449E-06, 0.1601952029039821E+00, 0.0000000000000000E+00, 0.1909143391170965E-04, 0.1029106625513428E-04, 0.9519704710728188E-01, 0.5127595883936577E-28, 0.3722911957200607E-04, 0.5334790194682025E-04, 0.5380488026634178E-01, 0.4916199468524512E-16, 0.8145434425645190E-04, 0.4879722252791062E-03, 0.2070966044404248E-02, 0.2051115390772406E-31, 0.1886522673573371E-02, 0.1146190938097804E-02, 0.4144953892415127E-03, 0.1134788402846185E-20, 0.5837570815253673E-02, 0.1435831510150291E-01}, + info: 0, + }, + { + z: []float64{0.4141124863190200E+00, 0.6286592513493726E+00, 0.4875442526190354E-01, 0.6631999174821102E+00, 0.1778328741285358E+00, 0.5820997881750413E+00, 0.9610329112936564E+00, 0.2860180457593013E+00, 0.2800413372286658E+00, 0.8782990052007664E+00, 0.6769848820880126E+00, 0.2361981145928655E+00, 0.1864129841856804E+00, 0.6207802268756868E-01, 0.1668832170172669E+00, 0.2136536864861034E+00, 0.4266698341219798E+00, 0.9672331991204097E-01, 0.2350195655513042E+00, 0.1297162551474343E+00, 0.9428942697229301E+00, 0.3355426683568981E+00, 0.6977568272344947E-01, 0.4926170514192555E+00, 0.6966571762613959E+00, 0.7422949877167778E+00, 0.1216493993328296E+00, 0.5414775352707472E+00, 0.4507250901570525E+00, 0.6851601412475350E+00, 0.8339584749808495E+00, 0.9321374665508209E+00, 0.7664819871766777E+00, 0.5935455015911359E+00, 0.4047285985374618E+00, 0.9996987445838635E+00, 0.1347158425141065E+00, 0.3601395592420920E+00, 0.1128763847009464E+00, 0.6316809196633902E+00, 0.1559195263655234E+00, 0.4041853050912981E+00, 0.1854167847278504E+00, 0.6852913644854558E+00, 0.6126092157077416E+00, 0.2444516268314137E+00, 0.1447238269517732E+00, 0.7179956614587130E+00, 0.8198652148251639E+00, 0.1186997025611126E+00, 0.1267596520196094E+00, 0.2863431547875360E+00, 0.9867539057590858E+00, 0.2454746550565152E+00, 0.4891318294681372E+00, 0.2969454310391295E-01, 0.2349636207332649E+00, 0.4537731552146703E+00, 0.2883801124165087E+00, 0.7150664117598651E+00, 0.4359050919721921E+00, 0.6116081525473241E+00, 0.5619840590438748E+00, 0.3431726287099235E+00, 0.7715898362788249E+00, 0.4981359837313185E+00, 0.4537925078699018E+00, 0.6956466175473529E+00, 0.1814680828887681E+00, 0.4413903687143481E+00, 0.4367593306147978E+00, 0.5875066776157845E-01, 0.3688522862246468E+00, 0.4308468783440871E+00, 0.1986553761412286E+00, 0.3949957841484223E+00, 0.2468986938324821E+00, 0.6216444107315144E-01, 0.9076510210089642E+00, 0.5197394332656491E+00, 0.8460559187475114E-01, 0.3959477165848089E+00, 0.1014864219123556E+00, 0.4789226780612066E-01}, + n: 21, + zOut: []float64{0.2746085040517442E+01, 0.2006646947029628E+01, 0.1843368381126182E+01, 0.1738309804669461E+01, 0.1678478075610122E+01, 0.1408432532104903E+01, 0.1219097982435216E+01, 0.1121569511965291E+01, 0.9315294884679637E+00, 0.7914377647612258E+00, 0.7334412101899261E+00, 0.6113376828240070E+00, 0.4134386595159317E+00, 0.3303980566325673E+00, 0.2866331058299493E+00, 0.2287206720574312E+00, 0.1408981800627584E+00, 0.6649497607659796E-01, 0.5733628497886722E-01, 0.1387598234001070E-02, 0.2497701489633820E-04, 0.3487740233155725E-22, 0.3361270559917294E-05, 0.1214091727263821E-05, 0.1219097982435216E+01, 0.2843433355651033E-23, 0.3877657623657789E-06, 0.2861458561047538E-06, 0.1121569511965291E+01, 0.1501849799666580E-22, 0.7980776610337536E-07, 0.1296132789777516E-06, 0.9315294884679637E+00, 0.1397279453391396E-14, 0.3797866386428551E-06, 0.5462183171930727E-06, 0.7914377647612258E+00, 0.1231982124821006E-21, 0.6463973892160826E-06, 0.4555968092429713E-06, 0.7334412101899261E+00, 0.9423416829408119E-25, 0.1835506693210437E+02, 0.1835506693210436E+02, 0.9800000000000000E+02, 0.2884353741496599E+01, 0.2040816326530612E+01, 0.6355562713716383E-07, 0.4134386595159317E+00, 0.4284860196510039E-21, 0.4931868922851139E-05, 0.2760082849901006E-05, 0.3303980566325673E+00, 0.1448288531514775E-16, 0.4631299886341806E-05, 0.9149811670123540E-05, 0.2866331058299493E+00, 0.1558000287811498E-28, 0.1337090019087612E-05, 0.8008074996380075E-06, 0.2287206720574312E+00, 0.2366582715663035E-29, 0.4303808308110317E-06, 0.3181248709867330E-06, 0.1408981800627584E+00, 0.2443697032165075E-19, 0.2973006759321362E-05, 0.5017304713868616E-05, 0.6649497607659796E-01, 0.1131941655598205E-16, 0.8328041136745409E-04, 0.8552508571764750E-04, 0.5733628497886722E-01, 0.9398173280441046E-25, 0.5097763200650848E-04, 0.5644224660768206E-04, 0.1387598234001070E-02, 0.8888394955180400E-22, 0.1868721561136477E-03, 0.1091351925463373E-03, 0.2497701489633820E-04, 0.0000000000000000E+00, 0.1020791029288490E-01, 0.2791888375404797E-02}, + info: 0, + }, + { + z: []float64{0.2396228092919251E+00, 0.6434601049058037E+00, 0.5488667726527494E+00, 0.1843504645657519E+00, 0.4269001369847240E+00, 0.6276093013166625E+00, 0.8724336393628729E-01, 0.5371039952903035E+00, 0.8447460457667564E+00, 0.4094766929502263E+00, 0.2031514124499976E+00, 0.8271428312997948E+00, 0.9658284302973903E+00, 0.3777353969048113E+00, 0.6471334022587341E+00, 0.6777435175679861E+00, 0.4456890557292859E+00, 0.1720826572683752E+00, 0.3520207432901141E+00, 0.3291396508341311E+00, 0.7468262262373744E+00, 0.2715104496960554E+00, 0.5612917863396235E+00, 0.1324429469286776E+00, 0.7983766064014711E+00, 0.2059599586019641E+00, 0.2655510256425775E-01, 0.1962390264484870E+00, 0.7845246896371560E-02, 0.8217737559711210E+00, 0.9444498218704492E+00, 0.4679957695831033E+00, 0.1135918053039552E+00, 0.1604948252571132E+00, 0.8452381101613837E+00, 0.8537070814716049E+00, 0.3013932596816266E+00, 0.2511715406702125E+00, 0.2008647638036438E+00, 0.2607897573444329E+00, 0.2571050910078490E+00, 0.6286174024463315E+00, 0.4739701849723611E+00, 0.8698947534844018E+00, 0.6486079589595961E+00, 0.8894321904301987E+00, 0.7952475840185558E+00, 0.8801661721215410E+00, 0.2147272194381030E+00, 0.9518356646476019E+00, 0.7191152289414877E+00, 0.1106524971173308E+00, 0.9574587230734148E+00, 0.6469474230679395E+00, 0.5818260757443584E+00, 0.1292202837075540E-01, 0.2761722913438078E+00, 0.8004535925585585E+00, 0.3278973855590038E+00, 0.5794037438664289E+00, 0.2396155443104175E-01, 0.6699048475753794E+00, 0.1814492937128086E+00, 0.2866184936222242E+00, 0.6584557212506269E+00, 0.5889651227775431E+00, 0.6369766519060738E-01, 0.1328193529598596E+00, 0.7416631417262871E+00, 0.5003318278706693E+00, 0.3144077296395376E-01, 0.9907393156403193E+00, 0.3423696594914594E-02, 0.6992922072850826E+00, 0.7590519617064543E+00, 0.2542182514116359E+00, 0.3314657184555089E+00, 0.5728659684019645E+00, 0.9915854796414423E+00, 0.4896749730105238E+00, 0.5611369720796141E+00, 0.6064142215043516E+00, 0.8567590164766914E-01, 0.2581731932678185E+00}, + n: 21, + zOut: []float64{0.2319327880258489E+01, 0.2079713994229665E+01, 0.1953873370330741E+01, 0.1755147049127663E+01, 0.1569664109844580E+01, 0.1497177879850755E+01, 0.1442939549198070E+01, 0.1142654640257259E+01, 0.1037259380018118E+01, 0.7336163063097807E+00, 0.6300572204242147E+00, 0.3966542874116493E+00, 0.3925821156107781E+00, 0.2721798695257625E+00, 0.2365431978248397E+00, 0.2044065204974935E+00, 0.1570073942488483E+00, 0.8918832674569614E-01, 0.5938710196407761E-01, 0.3241742658191688E-02, 0.4778146591607052E-04, 0.1325286320771300E-27, 0.1485620696270319E-14, 0.4653485276256090E-14, 0.1442939549198070E+01, 0.1846131417899111E-22, 0.1162592678154001E-11, 0.3263011919854044E-11, 0.1142654640257259E+01, 0.4412642697382792E-11, 0.1735169830505648E-08, 0.3333560963091213E-08, 0.1037259380018118E+01, 0.1055565179678919E-18, 0.1940309609380032E-07, 0.3465529731850831E-07, 0.7336163063097807E+00, 0.4440642298320086E-11, 0.3810071749579748E-06, 0.5916980508399715E-06, 0.6300572204242147E+00, 0.4658681208910640E-20, 0.1797266971780259E+02, 0.1797266971780259E+02, 0.1110000000000000E+03, 0.3253968253968254E+01, 0.3603603603603604E+01, 0.2492194730770069E-13, 0.3925821156107781E+00, 0.0000000000000000E+00, 0.7667233942003248E-12, 0.2416678934089916E-12, 0.2721798695257625E+00, 0.2051915459060795E-16, 0.1487877135020801E-08, 0.6143545671036994E-08, 0.2365431978248397E+00, 0.1972152263052530E-29, 0.1960096418178738E-05, 0.2274829676605902E-05, 0.2044065204974935E+00, 0.2021903259098794E-21, 0.8745843979356665E-06, 0.9251106153042376E-06, 0.1570073942488483E+00, 0.5482898835648120E-25, 0.7118492322907369E-04, 0.3316595178521346E-03, 0.8918832674569614E-01, 0.1022725463125710E-19, 0.2167108979032774E-02, 0.1228336641518804E-02, 0.5938710196407761E-01, 0.1994240368398718E-26, 0.2711464061500906E-02, 0.2561834534417173E-02, 0.3241742658191688E-02, 0.1814380082008327E-27, 0.4237092909216320E-02, 0.4420407214578293E-02, 0.4778146591607052E-04, 0.2596519942803954E-20, 0.1820843269063370E-02, 0.8929397931439835E-02}, + info: 0, + }, + { + z: []float64{0.4704013808869884E+00, 0.8133248937317098E+00, 0.7246209022332254E+00, 0.9930301346620946E+00, 0.6565279241713462E-01, 0.7480498761899035E-01, 0.8311943018468732E+00, 0.4127487814312358E+00, 0.6620288516904083E+00, 0.2540390589975015E+00, 0.4830377447593585E+00, 0.6124023244542695E+00, 0.6830062885714996E+00, 0.4006497306883100E+00, 0.2108017907398356E+00, 0.9099126499549155E+00, 0.4756780627224959E+00, 0.8563186613679700E+00, 0.9168447467108382E+00, 0.5153963449488133E+00, 0.7188966629304918E+00, 0.2875525393671987E+00, 0.6200986280097742E-01, 0.3765186242141257E+00, 0.2589923271177115E+00, 0.5404093081826918E+00, 0.5343437371907505E+00, 0.3104227497255196E-01, 0.4221838478889377E+00, 0.4233113354732956E+00, 0.6486058235731677E+00, 0.1590032665029245E+00, 0.3877113621801469E+00, 0.6038849620024899E+00, 0.5400341407425849E+00, 0.7060013907006117E+00, 0.1173345165878200E+00, 0.8548311704210352E+00, 0.5804532700087333E+00, 0.5231399784962363E+00, 0.4754841524148748E+00, 0.3395282932287647E-01, 0.7668594432348432E+00, 0.8184682560752043E+00, 0.5633264054575460E-01, 0.2127176392631261E+00, 0.7432372685121402E+00, 0.3098453278874418E+00, 0.1150335122169536E+00, 0.8681635561145716E+00, 0.3593935949259885E+00, 0.9085822737263088E+00, 0.2122810259380176E+00, 0.3589456483065394E+00, 0.9437026007300053E-01, 0.6518875210051764E+00, 0.9046367728621729E+00, 0.7638617707854546E+00, 0.8924521343092110E+00, 0.8353112965912926E+00, 0.5076189975461921E+00, 0.4955137299922637E+00, 0.5041148053921253E+00, 0.7686114107944846E+00, 0.3833696141187980E+00, 0.9181102072361824E-01, 0.9260679284685853E+00, 0.7081687340916837E+00, 0.8312629527805896E+00, 0.8010881636433624E+00, 0.5891143654107377E+00, 0.8149927954305255E+00, 0.7192672792238343E+00, 0.9981622901025261E+00, 0.9368513325443091E+00, 0.6909941993236977E+00, 0.7208744872845105E+00, 0.6334330703247726E+00, 0.8856108044732016E+00, 0.7612967011342276E+00, 0.6840498257884192E+00, 0.8627400929877541E+00, 0.2970500386847904E+00, 0.9828991929119790E+00}, + n: 21, + zOut: []float64{0.2548749189884266E+01, 0.2318283655447516E+01, 0.1949991272828373E+01, 0.1903113092077109E+01, 0.1681173723989745E+01, 0.1621144658162279E+01, 0.1435953736019784E+01, 0.1373215273744876E+01, 0.1276544145324249E+01, 0.8508650942792525E+00, 0.7433578075251207E+00, 0.7333566617981635E+00, 0.6327824956484905E+00, 0.5146506379994326E+00, 0.4497218333883862E+00, 0.2736876649003249E+00, 0.2262999758546705E+00, 0.6320618886076086E-01, 0.1413547856395308E-01, 0.6182735080657475E-02, 0.1223662826415605E-02, 0.9844984097158227E-26, 0.2664250906052687E-13, 0.8143635875649387E-14, 0.1435953736019784E+01, 0.7237830359838992E-24, 0.1147364015889613E-09, 0.4819137169184198E-10, 0.1373215273744876E+01, 0.5490471900338242E-27, 0.1654936529088367E-07, 0.7460880307437913E-08, 0.1276544145324249E+01, 0.2958228394578794E-30, 0.1455672577071588E-05, 0.7169454013791148E-06, 0.8508650942792525E+00, 0.4041314959719700E-19, 0.1917383253612269E-05, 0.1657209462004936E-05, 0.7433578075251207E+00, 0.2357464745776125E-22, 0.2061763898420382E+02, 0.2061763898420383E+02, 0.9600000000000000E+02, 0.2888888888888889E+01, 0.3125000000000000E+01, 0.6718966036888534E-06, 0.6327824956484905E+00, 0.1006441314168352E-20, 0.4252254757420258E-06, 0.3750418335727261E-06, 0.5146506379994326E+00, 0.1125208173090593E-20, 0.1634173128014842E-06, 0.1777130114194832E-06, 0.4497218333883862E+00, 0.1397861524051633E-26, 0.1373153840978587E-06, 0.1424351942740530E-06, 0.2736876649003249E+00, 0.3055476705078142E-15, 0.2530372171390620E-06, 0.3073674645773779E-06, 0.2262999758546705E+00, 0.3987473575125276E-15, 0.5814400581048744E-06, 0.7370753629310487E-06, 0.6320618886076086E-01, 0.9597492304117215E-21, 0.2453687283764395E-05, 0.3193610655869065E-05, 0.1413547856395308E-01, 0.8528167491936360E-20, 0.7231103044220720E-05, 0.9769896858142881E-05, 0.6182735080657475E-02, 0.0000000000000000E+00, 0.3039337033448658E-04, 0.5367078032707280E-04, 0.1223662826415605E-02, 0.6617444900424221E-23, 0.7353916438463039E-03, 0.2144171525794732E-02}, + info: 0, + }, + { + z: []float64{0.9714680453643365E-01, 0.6357804703219754E+00, 0.6664990519488578E-01, 0.1729636879767130E+00, 0.4638342338705743E+00, 0.4390808892462035E+00, 0.8041041328438946E+00, 0.4288731182982508E+00, 0.7624625505229141E+00, 0.7083386603826051E+00, 0.2464792096944004E+00, 0.9011775040224685E+00, 0.6339539510596026E-01, 0.1795036824346197E-01, 0.9473751738931280E+00, 0.4886196718733559E+00, 0.3845982510172906E+00, 0.8175566437299375E-01, 0.4796454941504319E+00, 0.1995303497008669E+00, 0.3542217290845850E+00, 0.4313075601907782E+00, 0.9062634832132850E+00, 0.9362490171108290E+00, 0.7454458344912314E+00, 0.9678028365928690E+00, 0.8785588729275070E+00, 0.2582842558253936E+00, 0.7937433110799214E+00, 0.7912406502001545E-01, 0.1813501620770241E-01, 0.3340784700607168E+00, 0.3348119644971841E+00, 0.5042866134297835E+00, 0.3808798817625770E+00, 0.8932448815066745E+00, 0.2612469692343123E+00, 0.4943911382967600E+00, 0.7396437014435053E+00, 0.6180267747680381E+00, 0.6768529193184074E+00, 0.7346572400466492E+00, 0.8658232798365260E+00, 0.6590888814314796E+00, 0.9020629495832085E+00, 0.2719526227756762E+00, 0.9337960905099231E+00, 0.1402012445044727E+00, 0.3363383773836534E+00, 0.4741712787560632E+00, 0.1270352327896518E-02, 0.2317652069389444E+00, 0.9583986396877475E+00, 0.8857657675309066E+00, 0.5564654172742324E+00, 0.3373121694331064E+00, 0.1866413892025005E+00, 0.3829716065530064E+00, 0.6660176769447556E+00, 0.9140619394089379E+00, 0.4126532961354976E+00, 0.9883322088463480E+00, 0.1678362296131076E+00, 0.1246866166129172E+00, 0.5083959276848560E+00, 0.4743484764552197E+00, 0.1561141239638767E+00, 0.4867628897662705E+00, 0.8068909470080686E+00, 0.9878597697456749E+00, 0.8535449450676436E-01, 0.9609706407601909E+00, 0.7015171470525342E+00, 0.4808513401395343E+00, 0.4421870922261545E+00, 0.2476919441028158E-01, 0.2417065613871903E+00, 0.1174043678151601E+00, 0.4259626380136439E-02, 0.2614829171642307E+00, 0.5973781466265196E+00, 0.3195524674053074E-01, 0.4778949570977242E+00, 0.2741401812748340E+00}, + n: 21, + zOut: []float64{0.2956562879292357E+01, 0.2160920112738185E+01, 0.2057048821491083E+01, 0.1826665062315388E+01, 0.1626476426276149E+01, 0.1617659828407750E+01, 0.1458559932420392E+01, 0.1037845007643388E+01, 0.9436387491729998E+00, 0.8889042931978449E+00, 0.8147110102488896E+00, 0.7938854029224469E+00, 0.5240642869032099E+00, 0.4281570616174346E+00, 0.4032231719469492E+00, 0.2134769254146812E+00, 0.1570954054223686E+00, 0.5771888278451791E-01, 0.2771650645038780E-01, 0.1168397530048623E-02, 0.8626671344136174E-03, 0.6837796509826355E-18, 0.5416843762303492E-12, 0.3045298824248355E-12, 0.1458559932420392E+01, 0.8473754517266856E-24, 0.4783112378014045E-11, 0.8163747631331082E-11, 0.1037845007643388E+01, 0.8077935669463161E-27, 0.2442833758035109E-10, 0.3576901446935589E-10, 0.9436387491729998E+00, 0.1292469707114106E-25, 0.1060154010453575E-09, 0.7148292157772074E-10, 0.8889042931978449E+00, 0.5995342879679690E-28, 0.2265830666026058E-09, 0.3413067902462323E-09, 0.8147110102488896E+00, 0.6874131484520357E-19, 0.1999636083133089E+02, 0.1999636083133089E+02, 0.1000000000000000E+03, 0.3002267573696145E+01, 0.2000000000000000E+01, 0.2441378744031031E-06, 0.5240642869032099E+00, 0.2169367489357782E-29, 0.9564347597274963E-06, 0.8629398155870994E-06, 0.4281570616174346E+00, 0.1533177238774536E-16, 0.2198723423439569E-05, 0.1852641299824983E-05, 0.4032231719469492E+00, 0.1742814620686677E-24, 0.6898774546312495E-05, 0.1242988026413374E-04, 0.2134769254146812E+00, 0.1303198215425112E-25, 0.3054946518379762E-04, 0.2458010895625246E-04, 0.1570954054223686E+00, 0.2480178686014861E-25, 0.5573684427056079E-04, 0.2879079609909993E-04, 0.5771888278451791E-01, 0.0000000000000000E+00, 0.4895501114079361E-04, 0.6615663653270374E-04, 0.2771650645038780E-01, 0.6559433690090112E-18, 0.2090848897194263E-03, 0.3843856621792604E-03, 0.1168397530048623E-02, 0.0000000000000000E+00, 0.2396113765895983E-02, 0.4353699886144585E-02, 0.8626671344136174E-03, 0.1420984816841217E-20, 0.3572874909786609E-04, 0.2591037812233495E-05}, + info: 0, + }, + { + z: []float64{0.7761482897976135E-01, 0.7690133527529974E-01, 0.8589697242168557E+00, 0.5718901484414876E+00, 0.8450349347421171E-01, 0.5688250545090190E+00, 0.6202247495663940E+00, 0.7388100008042665E+00, 0.9890328265375476E+00, 0.2969659976080158E+00, 0.5442392738534707E-01, 0.9562602329262000E+00, 0.8530135563879812E+00, 0.5471012261519459E-01, 0.9710076793297340E+00, 0.4869447961696205E+00, 0.4659851368281548E+00, 0.7647605444900396E-01, 0.7872766307526106E+00, 0.3237029299700311E+00, 0.7194522935712468E+00, 0.7270865543961295E+00, 0.5183429612108851E+00, 0.3145688411100903E+00, 0.9096514649777033E+00, 0.7816253592835525E+00, 0.4809049584349555E+00, 0.2052154618933422E-01, 0.1481963756328628E+00, 0.8742358520807045E+00, 0.4565878430880338E+00, 0.1977913919695908E+00, 0.6526813957349178E+00, 0.8032154703264597E+00, 0.2356108621359847E+00, 0.4857415898450358E+00, 0.2259727396620309E+00, 0.1176413330041139E+00, 0.8335507369731385E+00, 0.4539477133958770E+00, 0.8910876835374724E+00, 0.1559757847548392E+00, 0.1885199219441583E+00, 0.1520953639100613E+00, 0.6035948595957944E+00, 0.9286538294716984E+00, 0.9676298024186124E+00, 0.1209629819848071E+00, 0.1660874781174386E+00, 0.8622065054293394E+00, 0.7485077140876945E+00, 0.9420716698171637E+00, 0.2904751962009996E+00, 0.2180437045655230E+00, 0.6692025851955981E+00, 0.9258369042460884E+00, 0.6243742234586596E+00, 0.6760203577391158E+00, 0.2199572443863818E-02, 0.5981650670220221E+00, 0.8252506688545779E+00, 0.9433813762695346E+00, 0.5320093960532474E+00, 0.3846966829839934E+00, 0.6727780061271659E+00, 0.4937802596181958E+00, 0.1177802539787526E+00, 0.2963448754612064E-01, 0.2479547713122239E+00, 0.2694003173993550E+00, 0.8186090816580105E+00, 0.2886041049393229E-01, 0.7384561600560133E+00, 0.8345282295575730E+00, 0.1740871089016751E+00, 0.7946006936544379E+00, 0.5640836203667244E+00, 0.4951346622832815E+00, 0.4981407974176422E+00, 0.2513094341381288E+00, 0.4316077257561814E+00, 0.1685190107506288E+00, 0.3264570829830372E+00, 0.1676643753771256E-01}, + n: 21, + zOut: []float64{0.2309990065237698E+01, 0.2261037149894265E+01, 0.1946075797700671E+01, 0.1868880050926239E+01, 0.1838164096767709E+01, 0.1792848619787804E+01, 0.1601503570675395E+01, 0.1526383850720226E+01, 0.1395433670210245E+01, 0.1010109387319946E+01, 0.8644978203099237E+00, 0.7632668975571170E+00, 0.4552388959212355E+00, 0.4364144823342648E+00, 0.2696980874891977E+00, 0.1302983706884531E+00, 0.1278582769210706E+00, 0.7956979307866878E-01, 0.7389266586143965E-01, 0.8102308371415692E-02, 0.2690335013870282E-02, 0.5752609692135112E-13, 0.2842400234743069E-06, 0.1045980487121886E-05, 0.1601503570675395E+01, 0.1668093198756260E-18, 0.5190756964721459E-05, 0.2367180586416983E-05, 0.1526383850720226E+01, 0.1262177448353619E-27, 0.1974011051185169E-03, 0.4728862593194215E-03, 0.1395433670210245E+01, 0.2337388813815525E-19, 0.1632969150852556E-06, 0.4026698297028720E-06, 0.1010109387319946E+01, 0.3802651360818291E-21, 0.1380334146666910E-03, 0.1568641113059460E-03, 0.8644978203099237E+00, 0.2788260408793746E-19, 0.2076195419278686E+02, 0.2076195419278686E+02, 0.1070000000000000E+03, 0.3183673469387755E+01, 0.2803738317757009E+01, 0.1273578837393323E-04, 0.4552388959212355E+00, 0.1016579123433529E-20, 0.9426551662020599E-04, 0.5179870206653002E-04, 0.4364144823342648E+00, 0.7336406418555410E-28, 0.1112142557098828E-05, 0.1460057881679474E-05, 0.2696980874891977E+00, 0.8909623382378835E-18, 0.3232451044433717E-03, 0.3229988347563871E-03, 0.1302983706884531E+00, 0.0000000000000000E+00, 0.2867336104451064E-03, 0.2890982620847502E-03, 0.1278582769210706E+00, 0.6875938841518755E-23, 0.2127348925826359E-06, 0.9655734242129450E-07, 0.7956979307866878E-01, 0.3291208348307372E-17, 0.5717743824937758E-07, 0.2183606505996598E-06, 0.7389266586143965E-01, 0.7801771243763389E-24, 0.1012732311499954E-04, 0.2863554462185051E-05, 0.8102308371415692E-02, 0.5719241562852336E-29, 0.6292939995324734E-04, 0.3382281194073554E-04, 0.2690335013870282E-02, 0.4951522129891247E-25, 0.3008856418189283E-03, 0.2691027365699742E-03}, + info: 0, + }, + { + z: []float64{0.1834451937168287E+00, 0.4501020603239488E+00, 0.9673873583575473E+00, 0.2207688184907047E+00, 0.4205773270263516E+00, 0.6767264871143511E+00, 0.2493506785870784E+00, 0.7809638015955807E+00, 0.8297195492174936E+00, 0.1617611869044215E+00, 0.9206032300762146E+00, 0.1914715918877316E+00, 0.7976268296797403E+00, 0.9839522457816396E+00, 0.8841932579084628E+00, 0.6979540605797908E+00, 0.8049859576106227E+00, 0.8117504351099887E+00, 0.3842107296635322E+00, 0.6368881208030270E+00, 0.2369530469547876E+00, 0.8005533377467571E+00, 0.7105152962140180E+00, 0.5356376472112734E-02, 0.2192323464228777E+00, 0.8992715082939398E+00, 0.5988055508193698E+00, 0.4081645962203215E+00, 0.1002944447483383E+00, 0.1052431248059748E+00, 0.5730054733733171E+00, 0.2386396328544268E+00, 0.6503058109411604E+00, 0.9019164849722401E+00, 0.4702244241412763E+00, 0.5759947448793571E+00, 0.7588959717342861E+00, 0.4126392985506339E+00, 0.9987799941641187E+00, 0.5598172962702971E+00, 0.2151524348024290E+00, 0.7511708041336773E-01, 0.1539602741757972E+00, 0.4584191954304165E+00, 0.8937659116858414E+00, 0.6186897030318780E+00, 0.6386630452844105E+00, 0.9151803046984296E+00, 0.3614526997644965E+00, 0.9143967867261915E+00, 0.1523575506386343E+00, 0.9745493424336691E+00, 0.4149640117372425E+00, 0.7418302113477876E+00, 0.3041602774831942E-01, 0.4852660298208696E+00, 0.9115870107661288E+00, 0.9024516441581734E+00, 0.9201550825657324E+00, 0.5200815862126855E+00, 0.7353784634707106E+00, 0.8264932398040087E+00, 0.7035838297463828E+00, 0.6738634069153341E+00, 0.7657166064092835E-01, 0.4678396966074577E+00, 0.9927685693816569E+00, 0.5845157970225999E+00, 0.5638346985777254E+00, 0.5850492500516753E+00, 0.3856054034589584E+00, 0.8134648529141429E+00, 0.4174766661784889E+00, 0.3336151222017159E+00, 0.5355530597844248E+00, 0.9274106499154580E+00, 0.7442750408730826E+00, 0.2948331405701974E+00, 0.5696937454611060E+00, 0.3104181547964658E+00, 0.4694844160987418E+00, 0.1538578615150018E+00, 0.5969883537795497E+00, 0.3873507919637014E+00}, + n: 21, + zOut: []float64{0.2914952592069403E+01, 0.2353566179964282E+01, 0.2062119351173516E+01, 0.1965819938313762E+01, 0.1942714243081098E+01, 0.1812271492844174E+01, 0.1712144141310849E+01, 0.1666892005264074E+01, 0.1208030687686805E+01, 0.1159871012571561E+01, 0.9581193432281622E+00, 0.7738358894690665E+00, 0.7454032361827709E+00, 0.3901865930581417E+00, 0.3240765847275939E+00, 0.2173673669709887E+00, 0.1778074780703053E+00, 0.5660863840842725E-01, 0.3038731391621440E-01, 0.1466323002394464E-01, 0.7362797481955845E-02, 0.1496427221292385E-15, 0.2798385737764086E-17, 0.6348906733176861E-18, 0.1712144141310849E+01, 0.2625127144183791E-23, 0.5842516095868784E-15, 0.1699577922475928E-15, 0.1666892005264074E+01, 0.2934562567422164E-27, 0.7233314809955462E-13, 0.2286859678494404E-12, 0.1208030687686805E+01, 0.8467561517631538E-12, 0.2143114506868008E-08, 0.4305471816838367E-08, 0.1159871012571561E+01, 0.4930380657631324E-31, 0.3270528389239616E-07, 0.6410715811146478E-07, 0.9581193432281622E+00, 0.8911174733768286E-23, 0.2249420011581710E+02, 0.2249420011581710E+02, 0.1050000000000000E+03, 0.3197278911564626E+01, 0.2857142857142857E+01, 0.6896683202589802E-07, 0.7454032361827709E+00, 0.3255610023185390E-23, 0.5315428740895598E-04, 0.2875762635390457E-03, 0.3901865930581417E+00, 0.4610239445276015E-22, 0.9146669702187219E-04, 0.4183987855699404E-04, 0.3240765847275939E+00, 0.4688433862556419E-23, 0.8204008598914952E-05, 0.1523341313649621E-04, 0.2173673669709887E+00, 0.4570683409889788E-20, 0.9316307389873694E-05, 0.2741587710667867E-05, 0.1778074780703053E+00, 0.3706159570762342E-17, 0.9605798472890332E-04, 0.3099752510959849E-03, 0.5660863840842725E-01, 0.5638682600030866E-16, 0.1627758109301002E-02, 0.5977814903797443E-03, 0.3038731391621440E-01, 0.7161878634670464E-18, 0.4935537640644100E-05, 0.4281293465082162E-05, 0.1466323002394464E-01, 0.9343665470806783E-19, 0.1384059308707374E-05, 0.7139695062761456E-05, 0.7362797481955845E-02, 0.1252221392641006E-22, 0.1398979151771859E-02, 0.1830558814226920E-02}, + info: 0, + }, + { + z: []float64{0.1901253435444810E+00, 0.1005117877448146E+00, 0.7431497892893435E-02, 0.4180244733822649E+00, 0.5723993917742813E+00, 0.5092276894610764E+00, 0.6914570054828403E+00, 0.6343440208263138E+00, 0.9714240100252226E+00, 0.9708780190932921E+00, 0.7346948492781401E+00, 0.9261658900466149E+00, 0.6500321763704298E-01, 0.2101988980308164E+00, 0.2569765082490436E+00, 0.6872855071573251E+00, 0.7393915007490531E+00, 0.5293076476804583E+00, 0.5736721160165409E+00, 0.6249080544922647E+00, 0.1805969142240157E+00, 0.6235867578362418E+00, 0.3156395994838945E+00, 0.6768110107418109E+00, 0.5036038244498190E+00, 0.2096885591435443E+00, 0.2471056170621776E+00, 0.4420201221816504E+00, 0.5954916898507195E+00, 0.6849385183400085E+00, 0.6865376402638398E+00, 0.5015659601935997E+00, 0.9646916309223035E+00, 0.1976274617660123E+00, 0.6173831761654865E+00, 0.9161785290588952E+00, 0.8303766381148641E+00, 0.4163407208236638E+00, 0.2406183750735502E-01, 0.9033217043220854E+00, 0.3435327703530300E-01, 0.4851293431546745E+00, 0.1308952665690980E+00, 0.1639949900839996E+00, 0.6530528840204755E+00, 0.4007776795656349E+00, 0.6520732821596675E-01, 0.2482448577499247E+00, 0.6417548063561368E+00, 0.6287927677318972E+00, 0.2491821746122613E+00, 0.1309766085785375E+00, 0.1799023200797401E+00, 0.6166520678731939E+00, 0.4068347418426869E+00, 0.8022499378251485E+00, 0.2090643045880468E+00, 0.9552039287477454E-01, 0.3405285833145572E+00, 0.9010017729234689E+00, 0.8087026571264999E-01, 0.6784547103017031E+00, 0.5001579210546183E+00, 0.9044563563261202E+00, 0.6248337185292430E-01, 0.7231216956646513E+00, 0.3330924448715603E+00, 0.5906941805835393E+00, 0.6144619726434308E-01, 0.4494963607638514E-01, 0.5817524116985039E+00, 0.4323943825883398E+00, 0.9871518362913079E-01, 0.9577530955877981E+00, 0.7720928198042669E+00, 0.1473259710759589E+00, 0.7227644962870149E+00, 0.9964485210410867E+00, 0.3235582385765219E+00, 0.5984954533580267E-01, 0.1531719633524309E-01, 0.8969070444410814E+00, 0.8320043732823273E+00, 0.7541623800831910E+00}, + n: 21, + zOut: []float64{0.2943190889471759E+01, 0.2404733889291933E+01, 0.2164120218254414E+01, 0.2101040443717650E+01, 0.1828309865967689E+01, 0.1647179310188885E+01, 0.1393092850251358E+01, 0.1217421086377993E+01, 0.1157068329170861E+01, 0.9693609911235493E+00, 0.7556225164779018E+00, 0.6051010122910800E+00, 0.5244111548905432E+00, 0.4204021043595824E+00, 0.3294230503008973E+00, 0.2905705444026201E+00, 0.1318042053167392E+00, 0.6748792703931331E-01, 0.3115549452672914E-01, 0.3850968595106850E-02, 0.1766035472385010E-05, 0.2996366283941816E-12, 0.8018633237482923E-17, 0.2249911398990393E-16, 0.1393092850251358E+01, 0.8588781736260544E-19, 0.1768526861021460E-14, 0.8068659675231548E-15, 0.1217421086377993E+01, 0.2465190328815662E-30, 0.6841595655394777E-14, 0.1344694857995563E-13, 0.1157068329170861E+01, 0.2714422906896024E-19, 0.9771202940807984E-13, 0.1895423136689650E-12, 0.9693609911235493E+00, 0.1093011646009194E-15, 0.5148224565067754E-11, 0.9904113235317579E-11, 0.7556225164779018E+00, 0.6752649348691861E-27, 0.2098534861805207E+02, 0.2098534861805208E+02, 0.9600000000000000E+02, 0.2832199546485261E+01, 0.2083333333333333E+01, 0.3437245789676428E-09, 0.5244111548905432E+00, 0.2665011951551765E-23, 0.6566411319039389E-08, 0.3635282930812000E-08, 0.4204021043595824E+00, 0.1249353725478346E-22, 0.6690013285699780E-07, 0.1185995569029548E-06, 0.3294230503008973E+00, 0.3250106929510569E-26, 0.6264577969246473E-06, 0.1086745069147475E-05, 0.2905705444026201E+00, 0.1121066009627684E-24, 0.5553814969713904E-05, 0.9554866377781883E-05, 0.1318042053167392E+00, 0.1875595688253478E-25, 0.3215548179944659E-03, 0.4036498498040293E-03, 0.6748792703931331E-01, 0.4043956767801041E-20, 0.1191830515693705E-02, 0.1851908589351717E-02, 0.3115549452672914E-01, 0.1124126789939942E-28, 0.7898349055483677E-03, 0.3617649115749287E-02, 0.3850968595106850E-02, 0.4455486392688275E-26, 0.3971779475237804E-01, 0.1814591379891354E-01, 0.1766035472385010E-05, 0.2780981219403279E-20, 0.1014029004767683E-01, 0.8718057102094371E-02}, + info: 0, + }, + { + z: []float64{0.3437994630115073E+00, 0.2969584004763312E+00, 0.5428789456218400E+00, 0.3643219910857877E+00, 0.8842011736515154E-01, 0.4426793535323088E+00, 0.9851327949196382E+00, 0.9928836193844874E+00, 0.9294888334528270E+00, 0.5131906939013953E+00, 0.8372743749579292E-01, 0.3799113781856175E+00, 0.9980979619320958E+00, 0.1940068951405882E+00, 0.1265916571930514E+00, 0.7533120158726621E+00, 0.7604310151358937E+00, 0.9521608240404056E-01, 0.6048411980078113E+00, 0.8887307551694945E-01, 0.9109406880842844E+00, 0.9457532858494480E+00, 0.7192031611135805E+00, 0.5051759890546635E+00, 0.1927673350758418E+00, 0.6784576615085791E+00, 0.4582307655806892E+00, 0.4110913566635671E+00, 0.5843861752552199E+00, 0.1849014446101248E+00, 0.5286425989283670E+00, 0.9425316584065953E+00, 0.9757360470900053E+00, 0.4697986765545260E+00, 0.5423082602059015E-01, 0.4516134263086808E+00, 0.2022962345269688E+00, 0.4899666677522230E-01, 0.9657583521001409E+00, 0.7147044884479304E+00, 0.8698989147298346E+00, 0.1620630683580001E+00, 0.4917083507892124E+00, 0.6587971895356357E+00, 0.2830046270176211E+00, 0.8907428232631098E-01, 0.3385480253038764E-01, 0.3808208973559474E+00, 0.6301790073720519E+00, 0.7283330529106518E+00, 0.8754045015579843E+00, 0.5691786300850922E+00, 0.2221459247333947E+00, 0.3807253530058278E+00, 0.5099681617674874E+00, 0.8815981352292609E+00, 0.2670679959789202E-02, 0.3061419069919761E+00, 0.9088634553510815E+00, 0.3137439308670030E+00, 0.3256630871489109E+00, 0.7397175549546020E-01, 0.8600700672393357E+00, 0.2944165267259768E-01, 0.1962740610392520E+00, 0.7223088666910011E+00, 0.1555262415199788E+00, 0.7683934132272936E+00, 0.9837306979871404E+00, 0.4307236017454147E+00, 0.2763099157748476E+00, 0.5623054633156477E-01, 0.1414438705425911E+00, 0.3910643421231946E+00, 0.3414855836828583E+00, 0.4833767934540261E+00, 0.1874948602631823E+00, 0.6456680649630069E+00, 0.5377739930676261E+00, 0.4911199998049517E+00, 0.3925147326457343E+00, 0.1205990368593943E+00, 0.6208170182205421E+00, 0.4308681300066786E+00}, + n: 21, + zOut: []float64{0.2838978926644850E+01, 0.2478331275466363E+01, 0.2456585262660691E+01, 0.2180185738821122E+01, 0.1712066680562540E+01, 0.1602701074250422E+01, 0.1503969746560551E+01, 0.1233768461187729E+01, 0.9787455830966086E+00, 0.9668289373592873E+00, 0.7729605529095109E+00, 0.7035556930615693E+00, 0.5295938697567051E+00, 0.4165425267136870E+00, 0.3781386605204551E+00, 0.3701077812928417E+00, 0.1575477292510020E+00, 0.7328369731218511E-01, 0.3974472017556452E-01, 0.4256064253578745E-02, 0.1985700463370783E-02, 0.0000000000000000E+00, 0.2182718854229073E-04, 0.3091215918753839E-04, 0.1503969746560551E+01, 0.7889046064910921E-15, 0.8525655623819580E-10, 0.5987167574554257E-09, 0.1233768461187729E+01, 0.1850899338648654E-19, 0.6965867087478826E-06, 0.6532556049979120E-06, 0.9787455830966086E+00, 0.3101927297073854E-24, 0.3608646891594891E-06, 0.2907657476508735E-06, 0.9668289373592873E+00, 0.5936688180990121E-20, 0.1421522625242826E-07, 0.7063390122609291E-08, 0.7729605529095109E+00, 0.1231338578304599E-17, 0.2139987868232064E+02, 0.2139987868232063E+02, 0.9600000000000000E+02, 0.2854875283446712E+01, 0.2083333333333333E+01, 0.2575545978160743E-06, 0.5295938697567051E+00, 0.8537368260663878E-24, 0.6647760383095535E-05, 0.6726768703723720E-05, 0.4165425267136870E+00, 0.5898327163094257E-18, 0.6007815560144262E-05, 0.6070984870789135E-05, 0.3781386605204551E+00, 0.1932242212135588E-23, 0.5780348596252855E-05, 0.5727260717649887E-05, 0.3701077812928417E+00, 0.2291245128765917E-16, 0.5589406660782675E-05, 0.5617175435749363E-05, 0.1575477292510020E+00, 0.3855952104720306E-26, 0.8404567502440466E-05, 0.1060626986994499E-04, 0.7328369731218511E-01, 0.1176980470589750E-26, 0.3402042835087641E-05, 0.5518338211116594E-05, 0.3974472017556452E-01, 0.3697785493223493E-30, 0.6423930978115149E-05, 0.5690659965930955E-05, 0.4256064253578745E-02, 0.1813010266067178E-20, 0.3330330670135602E-05, 0.3509207052336586E-05, 0.1985700463370783E-02, 0.9911627066431288E-23, 0.2656536456367949E-04, 0.9644853918428974E-05}, + info: 0, + }, + { + z: []float64{0.6087347824331316E+00, 0.2344592930815549E+00, 0.1839180152431182E+00, 0.8946895357068063E-01, 0.3789275576065679E+00, 0.1028144130339237E-01, 0.8432962228323871E+00, 0.5720035990048252E+00, 0.9674750777949459E+00, 0.1387850858951470E+00, 0.1049983295079311E+00, 0.1869597635484084E+00, 0.2049847474830355E+00, 0.9353902309354832E+00, 0.7711597045807418E+00, 0.6677931698783810E+00, 0.5710020050743191E+00, 0.7559352115290241E+00, 0.8799700817290574E+00, 0.2989086447618220E+00, 0.7223221852829088E+00, 0.9172044263776469E-01, 0.8222766733565161E+00, 0.4357755436106698E+00, 0.3174399370719186E+00, 0.3716323007311311E+00, 0.5710261889832198E+00, 0.5875728000816982E-01, 0.1970825867540514E+00, 0.7514821290356389E+00, 0.4768968814440278E+00, 0.1414806690779697E+00, 0.5126469713172739E+00, 0.2618595999903317E-01, 0.3414455658478163E+00, 0.7845736413672471E+00, 0.3193997824316201E+00, 0.5244207174429636E+00, 0.7114985438553419E+00, 0.6380953409710879E+00, 0.5110544105167975E+00, 0.6987353947091863E+00, 0.2359552404464268E+00, 0.1389779414569779E+00, 0.4283565484470430E+00, 0.5978343235372734E+00, 0.8941068622870674E+00, 0.9993918591572127E+00, 0.9276104816334276E+00, 0.6840640077048410E+00, 0.1906252952212643E+00, 0.3896055694019390E+00, 0.8889540838698040E-01, 0.6972017776398595E+00, 0.7403854978121883E+00, 0.9624319129844994E-01, 0.7107468555423346E-01, 0.2167351328914763E+00, 0.5250363507339506E-01, 0.3012298012035964E+00, 0.7467053513110199E+00, 0.6311877906561809E+00, 0.6465457722939830E+00, 0.9462483307457270E-01, 0.1615629644808589E+00, 0.3714392567485900E+00, 0.5909086992570731E+00, 0.2147078824711308E+00, 0.8083150503324107E+00, 0.1136496291628873E+00, 0.3556622878263437E+00, 0.1687673308056986E+00, 0.2663369573375586E+00, 0.9992292880074174E+00, 0.4743706799728067E+00, 0.3784791276003248E+00, 0.9641428139214289E+00, 0.4526980047510465E-01, 0.5291384859598749E+00, 0.9114927597067145E+00, 0.2015740390806801E+00, 0.9111109510473957E+00, 0.4797378470164849E+00, 0.4344842342843944E+00}, + n: 21, + zOut: []float64{0.2535248843080872E+01, 0.2027297538476471E+01, 0.1999341423958793E+01, 0.1905819580237666E+01, 0.1558994176508815E+01, 0.1443542425236611E+01, 0.1321312714967014E+01, 0.1044341128979687E+01, 0.9175998827905956E+00, 0.8543653487373744E+00, 0.6128068085852322E+00, 0.5723484802692980E+00, 0.4865842293721045E+00, 0.4743009418296827E+00, 0.4424121716041568E+00, 0.2157744105271115E+00, 0.1401155020588904E+00, 0.9545054691199920E-01, 0.4846378139764250E-01, 0.2597131641839770E-01, 0.9574417588705024E-02, 0.7983827718913915E-23, 0.5897957913656464E-08, 0.4905965358471980E-08, 0.1321312714967014E+01, 0.1437620113674772E-24, 0.2330664696165742E-08, 0.2036082149427908E-08, 0.1044341128979687E+01, 0.7099748146989106E-29, 0.1191493821660667E-08, 0.1294122655697948E-08, 0.9175998827905956E+00, 0.7069460558567906E-16, 0.2320495180901029E-08, 0.3242686959161780E-08, 0.8543653487373744E+00, 0.3414430154917050E-13, 0.2143028595220802E-07, 0.3181347787023606E-07, 0.6128068085852322E+00, 0.0000000000000000E+00, 0.1873166566953712E+02, 0.1873166566953712E+02, 0.1040000000000000E+03, 0.3224489795918367E+01, 0.2884615384615385E+01, 0.3533200143891392E-06, 0.4865842293721045E+00, 0.4552522969733916E-17, 0.1776353409716398E-09, 0.6419018055060889E-09, 0.4743009418296827E+00, 0.4679164786798698E-18, 0.4782181507340309E-06, 0.1264406900548246E-06, 0.4424121716041568E+00, 0.1728289684559415E-20, 0.3046857378867568E-04, 0.2182730305393890E-04, 0.2157744105271115E+00, 0.1120182485413837E-27, 0.4003877877583194E-03, 0.2588513428463001E-03, 0.1401155020588904E+00, 0.0000000000000000E+00, 0.6916990427934659E-04, 0.5501406364660823E-04, 0.9545054691199920E-01, 0.6162975822039155E-32, 0.1059944134272042E-03, 0.1421052287262650E-03, 0.4846378139764250E-01, 0.1755514705909767E-17, 0.4499204819889415E-04, 0.2567010249779503E-03, 0.2597131641839770E-01, 0.1143848312570467E-28, 0.5289175880660015E-04, 0.5437725505075631E-04, 0.9574417588705024E-02, 0.3697785493223493E-31, 0.2606391166909807E-05, 0.6294847321319143E-06}, + info: 0, + }, + { + z: []float64{0.3257261020965838E+00, 0.9499222527145429E+00, 0.3597416524070001E+00, 0.7608369220069154E+00, 0.3348964244425234E-01, 0.9918240230913730E+00, 0.2435073049094116E-01, 0.2927090414647138E-01, 0.2724578324033788E+00, 0.7486167980650003E+00, 0.2854897136111678E+00, 0.2267361867398041E+00, 0.4294380831801550E+00, 0.7722184192395405E+00, 0.5889718788171796E+00, 0.5201154937785833E+00, 0.1341644467607439E-01, 0.3251983707424297E+00, 0.3712514383296180E+00, 0.8346822920283823E+00, 0.2613611110008908E+00, 0.7377020224374462E+00, 0.4290238209924468E-01, 0.8422463567888154E+00, 0.1390406385354674E+00, 0.8899155813346852E+00, 0.5366293959824918E+00, 0.1311808378334547E+00, 0.5127829646320820E+00, 0.3806825827063995E+00, 0.9008244723505014E+00, 0.8397173164045483E+00, 0.8005434668537068E+00, 0.4188784622408616E+00, 0.4815341947551696E+00, 0.2004130034689415E+00, 0.9620560381224039E+00, 0.9936712626034268E+00, 0.7996240982628953E+00, 0.9066259300527590E+00, 0.7119745510778175E+00, 0.4009593231138309E+00, 0.7503038869147766E+00, 0.2307657656692345E+00, 0.5796381959344894E+00, 0.4564585857276309E+00, 0.3087632483431468E-01, 0.4925813444884515E+00, 0.2548189626174928E+00, 0.7548007003619551E+00, 0.2595357873879023E+00, 0.2576161595637174E+00, 0.6530834734960895E+00, 0.9659056802808288E+00, 0.4073417244577716E+00, 0.7973054858347279E+00, 0.1098542135402614E-03, 0.5270152208809449E+00, 0.9503221531609122E+00, 0.3389760481404548E+00, 0.2936463197963648E+00, 0.1532837593240226E+00, 0.7039965742744211E+00, 0.1538522429841973E+00, 0.4565500206514618E+00, 0.4890306322657354E+00, 0.7406911389536464E+00, 0.4609110724077861E+00, 0.3010957214922741E+00, 0.4706875322819619E+00, 0.9245411658881026E+00, 0.1225486958523536E-02, 0.7513538867599376E+00, 0.7480092012350148E+00, 0.1668544624863488E+00, 0.6027497133760584E+00, 0.4060848284780354E+00, 0.7777661676033926E+00, 0.5476587806685121E+00, 0.3318235867866506E+00, 0.4865355710680780E+00, 0.9789804028805801E+00, 0.6449091593541079E-01, 0.3386899175207851E+00}, + n: 21, + zOut: []float64{0.2916446272919928E+01, 0.2518523111789073E+01, 0.1881620740030630E+01, 0.1802535552376618E+01, 0.1705712498790935E+01, 0.1630934300031556E+01, 0.1493206464268041E+01, 0.1289863129801601E+01, 0.1141879970494692E+01, 0.1064939765404915E+01, 0.9148995873510519E+00, 0.6667419164223021E+00, 0.5793746811807822E+00, 0.5763823737203533E+00, 0.5577209455074719E+00, 0.2258972104173268E+00, 0.1775772659782911E+00, 0.1224839196229167E+00, 0.7643325286481288E-01, 0.1088888144792382E-01, 0.1013218159024319E-07, 0.1529626957613473E-16, 0.4760904670371191E-26, 0.1685698503770275E-25, 0.1493206464268041E+01, 0.4740164255731978E-15, 0.6203207773025231E-22, 0.1697026618649852E-21, 0.1289863129801601E+01, 0.1555744028694447E-17, 0.2220966892754199E-18, 0.8352563633635413E-19, 0.1141879970494692E+01, 0.8283039504820624E-29, 0.9137114046044313E-17, 0.2186983724354431E-16, 0.1064939765404915E+01, 0.7560947786617519E-24, 0.1476623491156538E-14, 0.6521525514986541E-15, 0.9148995873510519E+00, 0.3956572890903056E-23, 0.2135406185055340E+02, 0.2135406185055340E+02, 0.1110000000000000E+03, 0.3462585034013606E+01, 0.7207207207207207E+01, 0.3107640874581820E-11, 0.5793746811807822E+00, 0.0000000000000000E+00, 0.5611258671513064E-10, 0.1000932867794445E-09, 0.5763823737203533E+00, 0.2935229715008717E-19, 0.5869279282596528E-09, 0.3232392517855140E-09, 0.5577209455074719E+00, 0.7161080495560552E-17, 0.6771347567635994E-08, 0.1273942735381484E-07, 0.2258972104173268E+00, 0.2531843062293473E-19, 0.3233128964696781E-05, 0.1839431244951091E-05, 0.1775772659782911E+00, 0.1025519176787315E-28, 0.1632093348006395E-04, 0.1394944946706296E-04, 0.1224839196229167E+00, 0.3147671031182890E-20, 0.4090539240175316E-04, 0.3499438731982919E-04, 0.7643325286481288E-01, 0.4418024966021139E-23, 0.7751221398283570E-04, 0.6522231732461535E-04, 0.1088888144792382E-01, 0.0000000000000000E+00, 0.1168516922729128E-02, 0.6798960389683572E-03, 0.1013218159024319E-07, 0.8311253061997563E-15, 0.2266806408535672E-02, 0.8228900118596701E-02}, + info: 0, + }, + { + z: []float64{0.9013837094783728E-01, 0.4093071371456288E+00, 0.7563443593246222E-01, 0.6047712831067179E+00, 0.3616734158068488E+00, 0.3179352368154293E+00, 0.4877726790168605E+00, 0.7283754332956183E+00, 0.6564126870433257E+00, 0.7426267273836333E+00, 0.9575970808689874E+00, 0.2328163542816707E+00, 0.9804488839127946E+00, 0.5880329556580101E+00, 0.6720101508999355E+00, 0.3029641470022006E+00, 0.9176198736416905E+00, 0.9273523415722473E-01, 0.7356501689695268E+00, 0.3516482504433937E+00, 0.5613309946663773E+00, 0.8064085547776983E+00, 0.2421909924481950E+00, 0.4321291285180304E+00, 0.7195726435630079E+00, 0.4201959590716675E-01, 0.6971840239025084E-03, 0.6931587576362976E+00, 0.4512374813335629E+00, 0.9105433528826555E+00, 0.8233348499205092E+00, 0.5270028711667427E+00, 0.5092902528068642E+00, 0.6527825111058926E+00, 0.8077059946216197E+00, 0.5037249441803524E+00, 0.7474524841642615E+00, 0.8361353459662745E+00, 0.6675800963161582E+00, 0.5004244151247563E+00, 0.7976263900002633E+00, 0.1983499023889042E+00, 0.7522366994446783E+00, 0.3654861843844912E+00, 0.8247542543249066E+00, 0.9124235995852386E+00, 0.1818459043196227E+00, 0.8196813052173683E+00, 0.5538880208895494E+00, 0.9080443570480472E+00, 0.2981632101337024E+00, 0.6044133722200155E+00, 0.1883025355842233E+00, 0.2434431972046255E+00, 0.3420561860884004E+00, 0.3312086041097358E+00, 0.8261796050670067E-01, 0.2597483126975232E+00, 0.9037350022806145E+00, 0.5691251256015616E+00, 0.5433137600205407E-01, 0.2948423088781353E+00, 0.7125818959241866E+00, 0.1168360183447441E+00, 0.2271931321361120E-01, 0.5832011197836875E+00, 0.4321285977614958E+00, 0.9214755199664483E+00, 0.2929460789941122E+00, 0.9911839954873096E+00, 0.9352897353900299E+00, 0.6549195608155846E+00, 0.7733376794047198E-01, 0.7345459966842849E+00, 0.2997108680399072E+00, 0.6923968300089707E+00, 0.9895794156524929E+00, 0.2694202749089550E+00, 0.2419924375765692E-01, 0.2728256718882756E+00, 0.7688978378093437E+00, 0.6794051971520565E-01, 0.8211384369868754E+00, 0.7581877817293103E-01}, + n: 21, + zOut: []float64{0.2587082763537058E+01, 0.2518438946693926E+01, 0.2381638511714923E+01, 0.2064758819607097E+01, 0.1861546331198453E+01, 0.1823771413694203E+01, 0.1462413605342042E+01, 0.1295483717305927E+01, 0.1204792654692795E+01, 0.1153126691944095E+01, 0.9646786889507554E+00, 0.8876075724637406E+00, 0.7328920239265601E+00, 0.5128961040525114E+00, 0.4187721082034697E+00, 0.3198505150609477E+00, 0.1661143074789019E+00, 0.1249876230738883E+00, 0.5554047196429147E-01, 0.2079344839078052E-02, 0.4713171572265143E-04, 0.1874281408120013E-19, 0.2104034717604745E-09, 0.2619972849686678E-09, 0.1462413605342042E+01, 0.9259545558536950E-18, 0.2890370685025388E-10, 0.3242632456342165E-10, 0.1295483717305927E+01, 0.1323488980084844E-22, 0.2279224462592833E-10, 0.2555931367214743E-10, 0.1204792654692795E+01, 0.2978738778114541E-26, 0.7485181957332586E-10, 0.4566030880095840E-10, 0.1153126691944095E+01, 0.6733803272339514E-21, 0.2633277318950464E-08, 0.1440235383519861E-08, 0.9646786889507554E+00, 0.7499216124683276E-17, 0.2253851934746039E+02, 0.2253851934746038E+02, 0.1040000000000000E+03, 0.3111111111111111E+01, 0.5769230769230769E+01, 0.2633869415622400E-06, 0.7328920239265601E+00, 0.6980417424693642E-13, 0.1603044445805627E-06, 0.1255532606981617E-06, 0.5128961040525114E+00, 0.6981404369947554E-21, 0.8484909168369356E-07, 0.7367232980661418E-07, 0.4187721082034697E+00, 0.2465190328815662E-30, 0.1470967366725541E-06, 0.2274394647752198E-06, 0.3198505150609477E+00, 0.9424343740971753E-25, 0.8932721831570202E-05, 0.5259727349591482E-05, 0.1661143074789019E+00, 0.1697763391846713E-18, 0.4712327641645974E-05, 0.7305995006514358E-05, 0.1249876230738883E+00, 0.9266645908481002E-19, 0.3596318120009657E-04, 0.2001742175196116E-04, 0.5554047196429147E-01, 0.5985976337495067E-16, 0.4811066675748340E-03, 0.3416912105856511E-03, 0.2079344839078052E-02, 0.8697917232094458E-24, 0.5710266423841766E-02, 0.2981491759065521E-02, 0.4713171572265143E-04, 0.0000000000000000E+00, 0.3288287603570621E-02, 0.1038987759212308E-02}, + info: 0, + }, + { + z: []float64{0.3453921918700114E+00, 0.8256584009865165E+00, 0.5027306146870630E+00, 0.5014619412470180E+00, 0.9910264683396075E+00, 0.7385152238869899E+00, 0.9936695869989243E+00, 0.6206355260490602E+00, 0.6835539321104728E+00, 0.3987727521414011E+00, 0.2155721742355131E+00, 0.8212295891891395E+00, 0.7021626430853991E+00, 0.3753314442932942E+00, 0.2575710525141791E+00, 0.6551328468445583E+00, 0.3738398426943970E+00, 0.8805730558289802E+00, 0.6848909798416613E+00, 0.5520069040756137E-01, 0.8817067703079440E+00, 0.3238117712584516E+00, 0.1001825089826291E+00, 0.7369585910327309E+00, 0.7601318359400422E+00, 0.4312449588193277E+00, 0.4932891154015395E+00, 0.1099211239093930E+00, 0.5764729343614433E+00, 0.1286539516629047E+00, 0.5170000684627285E+00, 0.4006756226519864E+00, 0.5897018197291505E+00, 0.3774659871747915E+00, 0.4211183018281148E+00, 0.6260997273722376E+00, 0.7810234892670644E+00, 0.9934154489086249E+00, 0.5116204079460294E+00, 0.7948452919719275E+00, 0.5998807734230309E+00, 0.4868691071952969E-01, 0.7977221292955683E+00, 0.4907992372099745E+00, 0.4337635562764541E-01, 0.4865658084478622E+00, 0.7887982210525304E+00, 0.6218441262679077E+00, 0.1807768964120138E-01, 0.7341707407508724E+00, 0.4738048273586776E+00, 0.9324751870816922E+00, 0.4643019354540665E+00, 0.2401905271601299E+00, 0.6072757133952530E+00, 0.6257046236339610E+00, 0.1662572295885112E-01, 0.3360107439465247E+00, 0.5925152832499899E+00, 0.4206234399601897E+00, 0.1828405120649758E+00, 0.8923354266778754E+00, 0.6211472795399554E+00, 0.3215240169291051E+00, 0.3967102459115966E+00, 0.4376502563326659E+00, 0.4571232280132043E-01, 0.2973405440159681E+00, 0.1737124961451384E+00, 0.1123665207380958E+00, 0.8069742345287393E+00, 0.5302931605046994E+00, 0.2541675285808478E+00, 0.9099997182043015E+00, 0.7562530283478575E-01, 0.2521110146593245E+00, 0.2525672524245413E+00, 0.8930826245328107E+00, 0.8545394186204489E+00, 0.1856025965008533E+00, 0.8541401621096930E+00, 0.7406868214039234E+00, 0.5851270108744718E+00, 0.7554853143122133E+00}, + n: 21, + zOut: []float64{0.2818806710434786E+01, 0.2596766072486540E+01, 0.2041400548479265E+01, 0.1919012388179902E+01, 0.1900863080415201E+01, 0.1778136512482050E+01, 0.1649297429111022E+01, 0.1375943901620400E+01, 0.1287933944237744E+01, 0.1246950647018126E+01, 0.9346701076388835E+00, 0.8619836761278706E+00, 0.6928534822715838E+00, 0.5816592049742084E+00, 0.4759893592204403E+00, 0.2537953742738920E+00, 0.2205935192530503E+00, 0.8350022078832350E-01, 0.3307087507037688E-01, 0.2105652896299196E-01, 0.3857874617179747E-02, 0.9177981866196648E-17, 0.6043035417783778E-14, 0.7682115486038763E-14, 0.1649297429111022E+01, 0.9047287949798740E-23, 0.2120842457393041E-14, 0.2617862539054627E-14, 0.1375943901620400E+01, 0.1499552906513639E-17, 0.3376573256769321E-15, 0.2886563968474245E-15, 0.1287933944237744E+01, 0.1966621906344823E-17, 0.2937881411718043E-15, 0.4577311861870994E-15, 0.1246950647018126E+01, 0.2742371736879744E-17, 0.2913637797754287E-14, 0.1483948533056680E-14, 0.9346701076388835E+00, 0.5800058106323822E-18, 0.2277814145766384E+02, 0.2277814145766384E+02, 0.9800000000000000E+02, 0.2997732426303855E+01, 0.1020408163265306E+01, 0.9030119244814722E-12, 0.6928534822715838E+00, 0.1471303281095442E-16, 0.2634125396797654E-10, 0.5071585384120369E-10, 0.5816592049742084E+00, 0.1365675999118616E-25, 0.3358753759221612E-09, 0.6258446588335648E-09, 0.4759893592204403E+00, 0.1479114197289397E-30, 0.3734630956704811E-08, 0.6716634735981551E-08, 0.2537953742738920E+00, 0.7467396771867359E-25, 0.3072344915986320E-06, 0.1829961043616119E-06, 0.2205935192530503E+00, 0.4437342591868191E-30, 0.2385309167517414E-05, 0.3978543929472447E-05, 0.8350022078832350E-01, 0.2436129622029919E-19, 0.4589207629691226E-04, 0.2836221395611648E-04, 0.3307087507037688E-01, 0.3081487911019577E-32, 0.1362072635971665E-04, 0.2978962617014088E-04, 0.2105652896299196E-01, 0.2711709361697228E-30, 0.2444625596237189E-05, 0.7827983423195974E-05, 0.3857874617179747E-02, 0.8925769947935872E-20, 0.9826965253502863E-02, 0.1259209175531780E-01}, + info: 0, + }, + { + z: []float64{0.9560856702670685E+00, 0.5885863857778361E+00, 0.8071258175651005E+00, 0.5175476341605639E+00, 0.1941426739297742E+00, 0.8451490614471896E+00, 0.9052305950784733E+00, 0.6791526261185319E+00, 0.6480230038264980E+00, 0.8438040949137990E+00, 0.3034844043967853E+00, 0.3090582723248356E+00, 0.3282769832503399E+00, 0.7489751201458807E+00, 0.6672021557248126E+00, 0.1697989591956236E+00, 0.5723860504781838E+00, 0.3660621222567975E+00, 0.1505291330148173E-01, 0.7436839329892437E+00, 0.3679212455376497E+00, 0.5305714072096270E+00, 0.5792221354999488E+00, 0.3031533452885045E+00, 0.9514596930492207E+00, 0.3278419583960311E+00, 0.5742176036064726E+00, 0.7216680447710266E+00, 0.6608941225668634E+00, 0.3887216422692293E+00, 0.6952172825541724E+00, 0.8072929471269218E+00, 0.8776672848787970E-01, 0.9363773133978057E+00, 0.3470717327786855E+00, 0.9438495003134180E+00, 0.5511880105145929E+00, 0.5826637033513504E+00, 0.3416802173197317E+00, 0.5650234571673005E+00, 0.2927187699119284E+00, 0.4936451925034285E+00, 0.7496439056333554E+00, 0.8462697295115110E+00, 0.4661250827466905E+00, 0.3912590593193351E+00, 0.9140228064649625E+00, 0.4016314378444454E+00, 0.7105479239000361E+00, 0.3751330850058705E+00, 0.7309804928539319E+00, 0.1378037023247644E+00, 0.7527056268407295E+00, 0.1640478774378548E+00, 0.6030857470066908E+00, 0.7427119073248016E+00, 0.9996405952923426E-01, 0.7406467144237725E+00, 0.3762498316380406E+00, 0.8295145255291534E+00, 0.8322845800948830E-01, 0.6101670185797291E+00, 0.9451596878306588E+00, 0.1176379504958335E+00, 0.7940514845464750E+00, 0.3068100097277620E+00, 0.2371282369406802E+00, 0.2163781309135768E+00, 0.4705542393165623E+00, 0.4003463805482307E+00, 0.2731285781388088E+00, 0.8862626881898287E+00, 0.5854390777280626E+00, 0.4661955367614972E+00, 0.1993415035442425E+00, 0.9213995968359628E+00, 0.1542739762296447E+00, 0.9419076789558214E+00, 0.9611493561784724E+00, 0.7596360150269755E+00, 0.6590873675145426E+00, 0.3894853423829039E+00, 0.8407621320868611E+00, 0.4517123559923821E+00}, + n: 21, + zOut: []float64{0.2583735261373388E+01, 0.2239759728480232E+01, 0.2157858012928955E+01, 0.2146305201359927E+01, 0.1853050031878152E+01, 0.1788497392649839E+01, 0.1558387970436693E+01, 0.1494017846927041E+01, 0.1323723239351723E+01, 0.1188003233397794E+01, 0.9827022795744828E+00, 0.8335582164080391E+00, 0.7854672559750093E+00, 0.6236176061997519E+00, 0.4677974993044671E+00, 0.2968385185647548E+00, 0.2304456569541352E+00, 0.1793008998018142E+00, 0.2471364396669566E-01, 0.7537422761275628E-02, 0.3241997301555496E-04, 0.1184063810429910E-21, 0.1281976731077423E-10, 0.2849227344309828E-10, 0.1558387970436693E+01, 0.3001369155282220E-19, 0.2940080271049715E-08, 0.1685793775386140E-08, 0.1494017846927041E+01, 0.1696366490587264E-24, 0.4557030850938984E-08, 0.5166797185591864E-08, 0.1323723239351723E+01, 0.1862197338326049E-12, 0.1908610209474282E-08, 0.1816527091730617E-08, 0.1188003233397794E+01, 0.1613415991578665E-17, 0.2801618631477443E-08, 0.2177314380835442E-08, 0.9827022795744828E+00, 0.1073695634537585E-17, 0.2276534933826718E+02, 0.2276534933826718E+02, 0.1060000000000000E+03, 0.3113378684807256E+01, 0.3773584905660377E+01, 0.2107018980320373E-07, 0.7854672559750093E+00, 0.7395570986446986E-31, 0.5134101120680572E-07, 0.6949862017183880E-07, 0.6236176061997519E+00, 0.1700003115737185E-12, 0.4917011909790346E-06, 0.6444201346122313E-06, 0.4677974993044671E+00, 0.1676329423594650E-29, 0.2178752696080751E-05, 0.1697685142168825E-05, 0.2968385185647548E+00, 0.2903323170704433E-20, 0.9062193610690628E-05, 0.7062135859641892E-05, 0.2304456569541352E+00, 0.9860761315262648E-30, 0.1460945060339096E-04, 0.1904220434906198E-04, 0.1793008998018142E+00, 0.4606947686490709E-27, 0.4451684144215141E-07, 0.1728984935219646E-06, 0.2471364396669566E-01, 0.1407327854914285E-26, 0.1942342839475662E-02, 0.3052712133602924E-02, 0.7537422761275628E-02, 0.9865964111678957E-20, 0.3214451590395407E-02, 0.5215635567340069E-02, 0.3241997301555496E-04, 0.0000000000000000E+00, 0.1184307710713820E-01, 0.9427403294935964E-02}, + info: 0, + }, + { + z: []float64{0.4101594051788160E+00, 0.1002974419660251E+00, 0.8434067081152193E+00, 0.7258916354493068E+00, 0.9256853341957688E+00, 0.8379265467529036E+00, 0.1564408324797836E+00, 0.8292039738515364E+00, 0.3771190822561328E+00, 0.8236097732630416E+00, 0.3320638300046872E+00, 0.6850750205938005E-01, 0.5616647045816037E+00, 0.8305938719521835E+00, 0.6006351465721590E+00, 0.8469146468608777E+00, 0.1179160781320751E+00, 0.6975716721259332E+00, 0.3237957597653003E+00, 0.1297318227605904E-01, 0.8416519209661123E+00, 0.2623987624579764E+00, 0.3323289069826861E+00, 0.9848995259497869E+00, 0.1295798367899781E-01, 0.4196318718239949E+00, 0.8791346827157692E+00, 0.9015205418757779E+00, 0.2557984197164971E+00, 0.7295221077613672E+00, 0.8796719157178668E+00, 0.6983240767110626E+00, 0.6461186804049626E+00, 0.5003600760145155E-01, 0.3411701822058120E+00, 0.6026846298507913E+00, 0.4649210011845201E+00, 0.4169632595817018E+00, 0.9745024564197420E+00, 0.9159749674174896E+00, 0.3798779762430529E+00, 0.6757581567027395E+00, 0.1501600637708167E+00, 0.8841295845033917E+00, 0.1700642059156726E+00, 0.5745602516925833E+00, 0.7146078194346678E+00, 0.7876321314233041E+00, 0.3623958693011297E+00, 0.1316504845867333E+00, 0.6150819295249010E+00, 0.9948396700221377E+00, 0.2186788175334711E+00, 0.3433450548510013E+00, 0.4434886569716980E+00, 0.6596978167473024E+00, 0.7067569387667516E+00, 0.2710992196058543E+00, 0.2531644393448058E+00, 0.6179743389634106E+00, 0.6395694224823617E+00, 0.6233992467844496E-01, 0.9270082862838847E-01, 0.6813409948026068E+00, 0.8489230752840353E+00, 0.4248777519526148E+00, 0.9258241367507150E+00, 0.7591306919901064E-01, 0.1337231221457533E+00, 0.6673452115706187E+00, 0.3161361894802919E+00, 0.9287930266484576E+00, 0.9211411715651807E+00, 0.7110889130885073E+00, 0.6783920645346327E+00, 0.5798290672446252E+00, 0.6003988035906362E+00, 0.8338909998640337E+00, 0.1150264810560550E+00, 0.8268177524919460E+00, 0.2868686997384918E+00, 0.7734675037869032E+00, 0.8495624932870276E+00, 0.7382167415731139E+00}, + n: 21, + zOut: []float64{0.2565771617602568E+01, 0.2464815559540473E+01, 0.2377249642737961E+01, 0.2182027799722737E+01, 0.1994511663794419E+01, 0.1777930797653110E+01, 0.1532836111328556E+01, 0.1298104160091711E+01, 0.1162548328490141E+01, 0.1031426069242260E+01, 0.9067767207978197E+00, 0.7702116437984168E+00, 0.7023507576840374E+00, 0.5846573732521254E+00, 0.3836750731694669E+00, 0.3732780616075560E+00, 0.2146097506115993E+00, 0.5462411591703480E-01, 0.3208967690429450E-01, 0.2788258306628742E-02, 0.1838228532938987E-03, 0.1703684557466520E-17, 0.8886730161731292E-14, 0.1725592004801531E-13, 0.1532836111328556E+01, 0.2310659810285515E-15, 0.8778995686431983E-12, 0.1396745951735637E-11, 0.1298104160091711E+01, 0.0000000000000000E+00, 0.8497749401208094E-11, 0.5925398902948847E-11, 0.1162548328490141E+01, 0.1292469707114106E-25, 0.1515360700076446E-10, 0.2085752134421418E-10, 0.1031426069242260E+01, 0.1195331315767287E-17, 0.8898419915788489E-10, 0.1186621585503233E-09, 0.9067767207978197E+00, 0.1888339631531495E-12, 0.2241246700510621E+02, 0.2241246700510621E+02, 0.1190000000000000E+03, 0.3539682539682540E+01, 0.7563025210084033E+01, 0.2596357213906324E-08, 0.7023507576840374E+00, 0.1416275483756143E-17, 0.5106480833143134E-08, 0.6438584684288567E-08, 0.5846573732521254E+00, 0.1317619996636992E-15, 0.1896058302301025E-07, 0.2367797858508706E-07, 0.3836750731694669E+00, 0.9199951564453634E-11, 0.8967796171107713E-07, 0.1296821709728121E-06, 0.3732780616075560E+00, 0.1615587133892578E-26, 0.3088999981101691E-06, 0.2343043411729366E-06, 0.2146097506115993E+00, 0.2055968734232262E-28, 0.9134179982896841E-05, 0.6280501592969192E-05, 0.5462411591703480E-01, 0.1901142159808155E-23, 0.3768301572228235E-05, 0.8777513601148953E-05, 0.3208967690429450E-01, 0.1479114197289397E-29, 0.1428515450408294E-03, 0.5208612044311805E-04, 0.2788258306628742E-02, 0.2057124874537592E-17, 0.2063479623178836E-02, 0.3566698154744510E-02, 0.1838228532938987E-03, 0.3273772756667199E-28, 0.8538542526496483E-03, 0.1571849612061994E-03}, + info: 0, + }, + { + z: []float64{0.1589037341524596E+00, 0.1455226073481288E+00, 0.1938395273812957E+00, 0.1962691615573132E+00, 0.1687822326883440E+00, 0.6650981615477494E+00, 0.8270615916362424E+00, 0.1710502783654970E+00, 0.2206713720159043E+00, 0.4369721197399372E+00, 0.9301314325299896E+00, 0.5722466234411457E+00, 0.1135089451836189E+00, 0.5846068541971138E+00, 0.9216025315561343E+00, 0.9066267701445474E+00, 0.5584279552920539E+00, 0.4343925455049338E+00, 0.9858452060735702E+00, 0.6563046209578444E+00, 0.7077011175365495E+00, 0.4947310926689127E+00, 0.7385820400647596E+00, 0.5937728681009750E+00, 0.9762402194896037E+00, 0.3450302019452143E+00, 0.3805099852593911E+00, 0.7529397554746390E+00, 0.7330092480109731E+00, 0.3330086450808912E+00, 0.9038518043983117E+00, 0.6574079221280790E+00, 0.2509077957372493E+00, 0.6249580721461656E+00, 0.2757992349681960E+00, 0.5001238277403597E+00, 0.9621194298806066E+00, 0.3061711826567661E+00, 0.1119838022409911E+00, 0.2976298035182879E+00, 0.6363137835930621E-01, 0.4930031667447814E+00, 0.1865676338649569E-01, 0.4250211458984191E+00, 0.1095501188334868E+00, 0.2763357459722963E+00, 0.7075737347301593E+00, 0.5363987747039417E+00, 0.3986581101260644E+00, 0.2692140175173962E+00, 0.5588052030209328E+00, 0.5539805437492590E+00, 0.6882419411200217E+00, 0.6525011142322502E+00, 0.2351213214810641E+00, 0.4862287407564582E+00, 0.9494457572755843E-01, 0.2775605674126462E+00, 0.6088686305117397E-01, 0.1602712446759722E+00, 0.6726078044316741E-01, 0.1771280849255007E+00, 0.9403546682132294E+00, 0.1182787468569617E+00, 0.6084837514797026E+00, 0.4725411123129805E+00, 0.2891346904124859E-01, 0.3056197468639377E-01, 0.3597281640784106E+00, 0.3047108802830497E+00, 0.9462624965987684E+00, 0.6795048656132132E+00, 0.3142878274718968E+00, 0.2255775176392846E+00, 0.5741746909618360E+00, 0.6125119194512041E+00, 0.8636232492271716E+00, 0.5595270150362563E-01, 0.4894380312911951E+00, 0.2945948126181174E+00, 0.4782956027971728E+00, 0.1100404727801326E+00, 0.2692801555328298E+00, 0.4567347029351195E+00}, + n: 21, + zOut: []float64{0.2662663085210597E+01, 0.2404979690430721E+01, 0.2214109781172517E+01, 0.2010332580463078E+01, 0.1879931283999763E+01, 0.1831239586461748E+01, 0.1664682288858752E+01, 0.1512516241203824E+01, 0.1081258277181201E+01, 0.8471473481460485E+00, 0.6221178288483303E+00, 0.5493156782308360E+00, 0.4496825320738197E+00, 0.3768653101376996E+00, 0.2833465507506064E+00, 0.2013980912694376E+00, 0.1418989984144841E+00, 0.7096946004385345E-01, 0.4542843847166723E-01, 0.6747056508451696E-02, 0.1343590842619022E-02, 0.4141519752410312E-28, 0.4845145585707669E-05, 0.3343357997526164E-05, 0.1664682288858752E+01, 0.8527270841077049E-25, 0.1655046287299363E-04, 0.2231546414257453E-04, 0.1512516241203824E+01, 0.5692210911982269E-19, 0.1383329297784762E-03, 0.1072264803352635E-03, 0.1081258277181201E+01, 0.1459392674658872E-28, 0.4158771817821724E-03, 0.3910579975830214E-03, 0.8471473481460485E+00, 0.2949199315750023E-16, 0.2216793811640345E-03, 0.2203201078239036E-03, 0.6221178288483303E+00, 0.2055113688275276E-18, 0.2085797369872005E+02, 0.2085797369872006E+02, 0.9000000000000000E+02, 0.2732426303854875E+01, 0.0000000000000000E+00, 0.1772659828830871E-05, 0.4496825320738197E+00, 0.4437342591868191E-30, 0.2138076899966292E-04, 0.1340116970023588E-04, 0.3768653101376996E+00, 0.2904017873172006E-24, 0.4668906275608195E-04, 0.7182837805013731E-04, 0.2833465507506064E+00, 0.4888968615550842E-22, 0.1290326696826671E-05, 0.6479808231987577E-06, 0.2013980912694376E+00, 0.4436553730962970E-26, 0.1673384055036320E-03, 0.7106703019344439E-04, 0.1418989984144841E+00, 0.3443985257364436E-16, 0.1415746442632383E-02, 0.1286112519803737E-02, 0.7096946004385345E-01, 0.1380506584136771E-29, 0.1898294559619081E-02, 0.3536485589649533E-02, 0.4542843847166723E-01, 0.9860761315262648E-31, 0.1085724134073318E-03, 0.2838967874935677E-03, 0.6747056508451696E-02, 0.2742900553697359E-16, 0.1307657950440773E-02, 0.4192938789348323E-02, 0.1343590842619022E-02, 0.2423380700838948E-25, 0.4340570868086748E-02, 0.9691995934364128E-02}, + info: 0, + }, + { + z: []float64{0.6603307676446488E+00, 0.5215490552441340E+00, 0.9279560414420993E+00, 0.3871591216009305E+00, 0.4489001158072897E+00, 0.2115798060938074E+00, 0.6013990647859857E-01, 0.6977506014884622E+00, 0.8981757899514635E+00, 0.6366966965554082E+00, 0.5447619366248987E+00, 0.2926906196279220E+00, 0.9538633412864880E+00, 0.4052441866103130E+00, 0.9970193775088028E+00, 0.1550480233350559E+00, 0.9697068099139655E+00, 0.3748402815554551E+00, 0.3906465669660910E+00, 0.4103562008634933E+00, 0.9514404866677418E+00, 0.5608812699221558E+00, 0.6226680723027547E+00, 0.8653188982275728E+00, 0.3999642050403411E+00, 0.8968004947108832E+00, 0.1007886665847859E+00, 0.2055140520989622E+00, 0.8479005785073866E+00, 0.4772281284198989E+00, 0.3664785333935638E+00, 0.9311163393120341E+00, 0.2051534177095988E+00, 0.5588930379235971E+00, 0.9385948972790567E+00, 0.1380523811906209E+00, 0.9076293986285472E+00, 0.9937542903014829E+00, 0.5330397746663563E+00, 0.5373590340921116E+00, 0.2667502750074380E-01, 0.9996497580467543E+00, 0.7460509377370035E+00, 0.5868152625248035E+00, 0.2352631583529476E+00, 0.2062979890255305E+00, 0.1864397664760209E-02, 0.1562262993494207E+00, 0.1880894213999632E+00, 0.5369024951393064E+00, 0.6560943776892021E+00, 0.9558063214302399E+00, 0.1463497248954505E+00, 0.6977928179134164E+00, 0.8204108917709737E+00, 0.9530026100161404E+00, 0.7191901603465490E+00, 0.4974721533134605E+00, 0.8445129869563219E+00, 0.9007488855711614E+00, 0.4164322161987429E+00, 0.5750362072910759E+00, 0.1935672755254650E+00, 0.2663393354536251E+00, 0.3913931132271733E+00, 0.7724103066167269E+00, 0.7871420607985310E+00, 0.3766724710952808E+00, 0.9224124235283799E+00, 0.1080194858843619E+00, 0.3512364719709385E+00, 0.9868075881536598E-02, 0.9893144531298202E+00, 0.5983612801716819E+00, 0.2882889058269555E-01, 0.2759662054778022E+00, 0.4865673169207868E+00, 0.4317793431152178E+00, 0.4039098350536063E-01, 0.7594353556100967E+00, 0.6702102151313558E+00, 0.5757953377080282E+00, 0.7036908158147406E+00, 0.3078985083785768E+00}, + n: 21, + zOut: []float64{0.2422149931211175E+01, 0.2394118175176597E+01, 0.2305882752563478E+01, 0.2031709011458775E+01, 0.2015634640599460E+01, 0.1933740155888154E+01, 0.1715509223328114E+01, 0.1559424733880939E+01, 0.1425500044444135E+01, 0.1021162532677627E+01, 0.8999999270989295E+00, 0.8371987758218183E+00, 0.7469639623683311E+00, 0.6494523294995699E+00, 0.4251816116188064E+00, 0.2881024603279346E+00, 0.2247792687845145E+00, 0.8318936570759092E-01, 0.1886599847837073E-01, 0.1029977709531541E-01, 0.8015530498900421E-03, 0.8380373580927862E-22, 0.1621276583815588E-04, 0.5889624784943332E-05, 0.1715509223328114E+01, 0.2616454581976124E-17, 0.2563506401168800E-03, 0.3048038004625151E-03, 0.1559424733880939E+01, 0.5629222562364776E-20, 0.1824080863602310E-03, 0.8021857862878124E-04, 0.1425500044444135E+01, 0.1078233452249475E-15, 0.2986624164553499E-03, 0.4306384056300427E-03, 0.1021162532677627E+01, 0.2425965640253176E-21, 0.3415477187080772E-04, 0.2730971166672021E-04, 0.8999999270989295E+00, 0.1110716154551185E-26, 0.2300966623107952E+02, 0.2300966623107953E+02, 0.9800000000000000E+02, 0.2877551020408163E+01, 0.3061224489795918E+01, 0.5341669529353412E-07, 0.7469639623683311E+00, 0.1147369787651374E-23, 0.3199917396615717E-04, 0.1114773640824220E-03, 0.6494523294995699E+00, 0.1324417262847731E-16, 0.4143040953885707E-03, 0.3815591968277185E-03, 0.4251816116188064E+00, 0.4294702353329713E-20, 0.5586157832836348E-03, 0.4985099391803953E-03, 0.2881024603279346E+00, 0.3449343154346125E-19, 0.3018840928486242E-04, 0.4804099248496092E-04, 0.2247792687845145E+00, 0.8223054085459871E-16, 0.6535536077614123E-03, 0.5704051254743707E-03, 0.8318936570759092E-01, 0.1269822990867506E-16, 0.2750660948852983E-03, 0.2439371709019565E-03, 0.1886599847837073E-01, 0.2261821987449685E-25, 0.1693307421164339E-03, 0.1879460762504110E-03, 0.1029977709531541E-01, 0.2207699818464282E-23, 0.8362752373159153E-06, 0.5564443135649789E-05, 0.8015530498900421E-03, 0.1142002837193949E-22, 0.2005722186927794E-03, 0.1790331282576109E-02}, + info: 0, + }, + { + z: []float64{0.7180522604364612E+00, 0.1926580568606098E+00, 0.9998274874952506E-01, 0.5945840846677781E+00, 0.6814004826706310E-01, 0.6532586662527488E+00, 0.6162535781196632E+00, 0.6323752897874746E+00, 0.6913197528064650E+00, 0.8218961980054600E+00, 0.2391583485552943E+00, 0.6893465701234240E+00, 0.8646254741258573E+00, 0.4399082441653793E+00, 0.7657207697437258E+00, 0.6442902814401660E+00, 0.2997828758931008E+00, 0.3311754429773528E+00, 0.4602753981904284E-01, 0.2937498413335546E+00, 0.9438033090912972E+00, 0.6689413829611792E+00, 0.3690605709328096E+00, 0.1297746871929878E+00, 0.5761771518385747E+00, 0.9470476076636891E+00, 0.6065387228873672E+00, 0.3279182193602236E+00, 0.7521029317260848E+00, 0.3448791591170053E-01, 0.8260379882894462E+00, 0.3381289908082724E+00, 0.6350192899014672E+00, 0.6181098759446546E+00, 0.7961594478307139E+00, 0.9929813242449080E+00, 0.4678192142649594E+00, 0.8317252674327552E+00, 0.1301328932823079E+00, 0.9710090231649569E+00, 0.1522128889234372E+00, 0.8594558260240532E+00, 0.6013715693159983E+00, 0.8742383713574672E+00, 0.7309721379377087E+00, 0.5021385621750218E+00, 0.9190365975533138E+00, 0.8027800227596282E-01, 0.1149439815205374E+00, 0.3491372322884074E+00, 0.3638810075690350E+00, 0.7397316797734275E+00, 0.6765505976038609E+00, 0.6412509132149137E+00, 0.6636796276324973E+00, 0.2769301898862327E+00, 0.6293983439129569E+00, 0.7661949976862148E+00, 0.1787796367414251E+00, 0.2134901744318570E+00, 0.8213730837735125E+00, 0.5732135541056227E+00, 0.8956530012694059E+00, 0.5095442527120628E+00, 0.8428538487299666E+00, 0.6837140150023939E+00, 0.1256023460764972E+00, 0.1828667371827231E-01, 0.3922785557614588E+00, 0.9906794824083128E+00, 0.6528984219237121E+00, 0.2175815548938115E+00, 0.5215238469901794E+00, 0.6874084104558049E+00, 0.4144717036123762E+00, 0.5901719497674505E+00, 0.3178975712304457E+00, 0.7061784208820305E+00, 0.6028763180221938E+00, 0.6012903376000152E+00, 0.6812913355997376E+00, 0.7728807542206401E+00, 0.4888911469874758E+00, 0.1012713084879602E+00}, + n: 21, + zOut: []float64{0.2588311953706596E+01, 0.2370344164465735E+01, 0.2152772432177807E+01, 0.2121020324458281E+01, 0.1935798000017230E+01, 0.1639966751245229E+01, 0.1447991497477954E+01, 0.1303796318075928E+01, 0.1122178474206467E+01, 0.1028684266176079E+01, 0.9663785372526962E+00, 0.8401839996503420E+00, 0.6468021461987292E+00, 0.5148128374433424E+00, 0.4081393344645305E+00, 0.3744044838513741E+00, 0.1951863401557736E+00, 0.1222936930600034E+00, 0.3610852087288927E-01, 0.2215175692702855E-02, 0.1055251342481684E-03, 0.5816113682013476E-24, 0.3490790538048844E-06, 0.5279190866861155E-06, 0.1447991497477954E+01, 0.6749793798367842E-21, 0.1187240552619153E-05, 0.8669686727541259E-06, 0.1303796318075928E+01, 0.2818270319791895E-16, 0.1425495821091504E-08, 0.4238958678865879E-08, 0.1122178474206467E+01, 0.1974523135472784E-17, 0.8140039386639262E-06, 0.3278912117172865E-06, 0.1028684266176079E+01, 0.3004196424688596E-17, 0.2459469608149132E-06, 0.1027360875624831E-06, 0.9663785372526962E+00, 0.8319175140295936E-21, 0.2181749477578394E+02, 0.2181749477578394E+02, 0.1040000000000000E+03, 0.3040816326530612E+01, 0.3846153846153846E+01, 0.3006532860022149E-05, 0.6468021461987292E+00, 0.2129924444096732E-28, 0.3097317061779137E-05, 0.3301766384461962E-05, 0.5148128374433424E+00, 0.5841522899747606E-17, 0.6589564866042633E-05, 0.8825655271690012E-05, 0.4081393344645305E+00, 0.5522026336547083E-29, 0.6929345622607317E-04, 0.1121666398022498E-03, 0.3744044838513741E+00, 0.4071868297361024E-19, 0.4964849153130707E-03, 0.6240579194345771E-03, 0.1951863401557736E+00, 0.3096999756315481E-22, 0.1538823843362176E-02, 0.5557701536471033E-03, 0.1222936930600034E+00, 0.9508642973366516E-17, 0.9344625728185554E-03, 0.1303932473154565E-02, 0.3610852087288927E-01, 0.2671050208464689E-19, 0.5349955893117279E-02, 0.9991286391872665E-02, 0.2215175692702855E-02, 0.2465190328815662E-30, 0.2737788875312504E-02, 0.2378589653250575E-02, 0.1055251342481684E-03, 0.0000000000000000E+00, 0.1487915832966980E-01, 0.9945584373260818E-02}, + info: 0, + }, + { + z: []float64{0.2443960928887767E+00, 0.5306690011327519E+00, 0.8844980893594125E+00, 0.8505050348613927E+00, 0.1179365025679910E+00, 0.6787232231004032E+00, 0.4781425309482933E+00, 0.8596658025119301E+00, 0.7267566040500681E+00, 0.7988986860541384E+00, 0.5066697395752245E+00, 0.9256193759419001E+00, 0.1614174453766865E+00, 0.7938782145253169E+00, 0.3207377639351938E+00, 0.5936236877473402E+00, 0.5294512496859689E+00, 0.3341300959064973E+00, 0.8739309914591177E+00, 0.1643518115289022E-01, 0.9695643985202173E+00, 0.9508789318813814E+00, 0.6599781146531454E+00, 0.8013437877388673E+00, 0.1929493765752847E+00, 0.7655052376601326E+00, 0.6319580998438735E+00, 0.6831519307583876E+00, 0.3834927697748418E+00, 0.7094548193343077E+00, 0.7020510393185050E+00, 0.6520146205437408E+00, 0.6562814689912274E+00, 0.5240471964184201E+00, 0.2362557689024753E+00, 0.4347621644220048E+00, 0.1660979681267404E+00, 0.2422730270980831E+00, 0.7891782502389337E+00, 0.5007812255281535E+00, 0.4444633531981611E+00, 0.3026778693869716E+00, 0.9990331636150707E-02, 0.4097233632314936E+00, 0.9940240633376396E+00, 0.1626467187830966E+00, 0.3461071508544706E+00, 0.6476433090511620E+00, 0.7204399230581238E-01, 0.6885344672911693E+00, 0.1941295874559149E+00, 0.5883115695765473E+00, 0.7359955011333836E+00, 0.4277388472789430E+00, 0.4017294206583021E+00, 0.7838762945853397E+00, 0.9128155969033611E+00, 0.4856080402782125E+00, 0.4763260467232836E+00, 0.5586410048770161E+00, 0.8031586091432461E+00, 0.6068401118620381E-01, 0.9247455618544214E+00, 0.5857147883918616E+00, 0.7467203590494284E+00, 0.1453563221196804E+00, 0.2297646010524917E+00, 0.8950965613541395E+00, 0.3335127494359967E+00, 0.9671078623732762E+00, 0.8023166958816280E+00, 0.1059134943829219E+00, 0.7122485680883537E+00, 0.3211310961264330E+00, 0.1626983074059779E+00, 0.4042697895935750E+00, 0.4799615975845870E+00, 0.3426607739026810E-02, 0.5147088911567483E+00, 0.7533023355653040E+00, 0.9693400349159813E+00, 0.7251923493536844E+00, 0.9132309180417886E-01, 0.4001770994110867E+00}, + n: 21, + zOut: []float64{0.2574587707602998E+01, 0.2548516143888565E+01, 0.2328646361106399E+01, 0.2152335028165169E+01, 0.1900054508136636E+01, 0.1821843561986577E+01, 0.1641395708303600E+01, 0.1593513640807486E+01, 0.1254245828754644E+01, 0.1184500984874290E+01, 0.9407518766665146E+00, 0.8321813659237318E+00, 0.6961683120499664E+00, 0.5315544763312857E+00, 0.4082285577131941E+00, 0.4022023658419822E+00, 0.2892256147411429E+00, 0.1412172326671640E+00, 0.7919841586115514E-01, 0.2055312514153672E-02, 0.1458583715266580E-03, 0.5995342879679690E-28, 0.2082901809770958E-07, 0.9383395476751434E-08, 0.1641395708303600E+01, 0.1321835131711384E-15, 0.1191741688360734E-04, 0.3695487724817346E-05, 0.1593513640807486E+01, 0.5607617048340495E-15, 0.5232768419257040E-05, 0.4082864434107817E-05, 0.1254245828754644E+01, 0.1850697850686327E-14, 0.2071860298001858E-05, 0.2753629328588578E-05, 0.1184500984874290E+01, 0.3549874073494553E-29, 0.9441520198112501E-05, 0.5871348343515868E-05, 0.9407518766665146E+00, 0.3656881477565973E-23, 0.2332256886230818E+02, 0.2332256886230818E+02, 0.1000000000000000E+03, 0.2984126984126984E+01, 0.3000000000000000E+01, 0.1218265160373847E-03, 0.6961683120499664E+00, 0.3847797347882626E-19, 0.2944801840696127E-03, 0.4565874591840146E-03, 0.5315544763312857E+00, 0.2366582715663035E-29, 0.5951942600827748E-04, 0.7082415940475930E-04, 0.4082285577131941E+00, 0.1744834104604043E-24, 0.4087064324555941E-04, 0.4051735857075661E-04, 0.4022023658419822E+00, 0.5055621275172978E-20, 0.1443306547898801E-05, 0.5013891517830428E-06, 0.2892256147411429E+00, 0.1446770900175336E-26, 0.7439355829951562E-04, 0.1741194257531676E-03, 0.1412172326671640E+00, 0.3448013628188340E-14, 0.2774107535050150E-02, 0.3338675080262731E-02, 0.7919841586115514E-01, 0.2413026984508734E-18, 0.7157138061395222E-03, 0.6803125903293225E-03, 0.2055312514153672E-02, 0.3994185778863994E-23, 0.5722078415717462E-03, 0.5910838594703896E-03, 0.1458583715266580E-03, 0.1183291357831518E-27, 0.8602246198024520E-03, 0.1402897408133881E-02}, + info: 0, + }, + { + z: []float64{0.6756942057876089E+00, 0.6579919202857232E+00, 0.8168130848194743E+00, 0.2483963371195050E+00, 0.2866280219451008E+00, 0.7172808579862799E-03, 0.2411898945446896E+00, 0.5534360794587689E-02, 0.3878248310175912E+00, 0.4256983490856848E+00, 0.7118512164413080E+00, 0.8762976594477806E+00, 0.6850772131038755E+00, 0.4603991232581716E+00, 0.6546622425118448E+00, 0.3103854094723100E+00, 0.7913005955185648E+00, 0.4864788053022765E+00, 0.6214717223070496E+00, 0.7079028836241165E+00, 0.2446362485461124E+00, 0.3062353821816216E+00, 0.8766788389923219E-01, 0.4381267847541642E+00, 0.4459912790878073E-01, 0.9432264671740954E+00, 0.3830574008366420E+00, 0.3381025391982955E+00, 0.6585260539196298E+00, 0.1004337858849739E+00, 0.9320890528134474E+00, 0.3322930037041504E+00, 0.7282334590214989E-02, 0.8367863647557111E+00, 0.9736104021592913E+00, 0.1613168640897539E+00, 0.6409545774446285E+00, 0.8441218931570360E-01, 0.9793937208019250E+00, 0.8303681522642254E+00, 0.1022316826967604E+00, 0.3021608972738009E+00, 0.1238379032543057E+00, 0.3839961366681232E+00, 0.8871553342676223E+00, 0.2909019998361990E+00, 0.7955411369197152E-01, 0.6476593477808288E+00, 0.1739219408315845E+00, 0.6498034164943688E+00, 0.3405210004266120E+00, 0.5459816771585898E+00, 0.2574285667818188E-01, 0.8691155035114945E+00, 0.4320450067500660E+00, 0.6967311316847606E+00, 0.9186339034853966E+00, 0.9491091410944081E+00, 0.2046793386144015E+00, 0.4114169869296881E+00, 0.9170199522695309E+00, 0.1514288291023066E+00, 0.2203325773257230E+00, 0.7891126546748299E+00, 0.4738113210301682E+00, 0.6729225031084131E+00, 0.2382373075875677E+00, 0.4180455054749687E+00, 0.9185761229203592E+00, 0.8030412579733187E+00, 0.4789612026295414E+00, 0.5038982716350845E+00, 0.9959829239394621E+00, 0.3087119711461705E-01, 0.6615773194242809E+00, 0.4461280013353816E+00, 0.1982838436639324E+00, 0.7583555141388076E+00, 0.7946309632008934E+00, 0.6749216068143323E+00, 0.9948312782688508E+00, 0.2854132428873886E+00, 0.8405396060835862E+00, 0.3412432527462372E-01}, + n: 21, + zOut: []float64{0.2393193272196224E+01, 0.2018136210599260E+01, 0.1995725670346335E+01, 0.1962470040389077E+01, 0.1880885332732760E+01, 0.1640866198530974E+01, 0.1381237309251015E+01, 0.1349378962361067E+01, 0.9454836406584929E+00, 0.7636867441308103E+00, 0.6820433637129892E+00, 0.6091604279437030E+00, 0.5856982990037397E+00, 0.4957297472312800E+00, 0.2553870576469542E+00, 0.2360257010865909E+00, 0.1371029529316844E+00, 0.8102847375475340E-01, 0.5521596879227348E-01, 0.9135542089709688E-02, 0.7426079491367038E-04, 0.1040308236944517E-14, 0.7301351780522185E-10, 0.7774740781328628E-10, 0.1381237309251015E+01, 0.2169367489357782E-29, 0.6020076428884570E-10, 0.5781767346304832E-10, 0.1349378962361067E+01, 0.1885108385497271E-16, 0.6878646083705261E-10, 0.6530919047819172E-10, 0.9454836406584929E+00, 0.5778430642028005E-17, 0.9207835097245334E-10, 0.7637719283517905E-10, 0.7636867441308103E+00, 0.1387778780781446E-16, 0.1259777267883337E-09, 0.1656656563258317E-09, 0.6820433637129892E+00, 0.0000000000000000E+00, 0.1947766517618461E+02, 0.1947766517618461E+02, 0.1070000000000000E+03, 0.3197278911564626E+01, 0.3738317757009346E+01, 0.5169611983503601E-09, 0.5856982990037397E+00, 0.2460562659624748E-15, 0.4628473083370263E-08, 0.9345989594028561E-08, 0.4957297472312800E+00, 0.2615714135774493E-18, 0.2264320058754590E-06, 0.2929148984854635E-06, 0.2553870576469542E+00, 0.1029104326196136E-18, 0.2640422579955958E-07, 0.2108896012270181E-07, 0.2360257010865909E+00, 0.3005450327091600E-17, 0.6822175517251369E-08, 0.8519370047734521E-08, 0.1371029529316844E+00, 0.3395257336071235E-24, 0.2687435952714477E-08, 0.2177398712709520E-08, 0.8102847375475340E-01, 0.0000000000000000E+00, 0.5343374415472690E-09, 0.5384901342094013E-09, 0.5521596879227348E-01, 0.2914620163738177E-24, 0.6457803167637477E-08, 0.2258738450739571E-07, 0.9135542089709688E-02, 0.5326388832052272E-25, 0.9576323906120589E-06, 0.3243967823107194E-05, 0.7426079491367038E-04, 0.3164925372525892E-18, 0.6752170208452239E-05, 0.3302115586194402E-04}, + info: 0, + }, + { + z: []float64{0.1859840927709887E+00, 0.1326482709507555E+00, 0.1830793816152183E+00, 0.4955347339015181E+00, 0.7174832323677909E+00, 0.1239131234434754E-01, 0.8960455455727024E+00, 0.1883195594308053E+00, 0.3701760109540279E+00, 0.5189832590024491E+00, 0.8746518205444311E+00, 0.5127960794741733E+00, 0.2715029219143491E+00, 0.3130984190329523E+00, 0.6427011945330067E+00, 0.2728531634457195E+00, 0.4849915812764480E+00, 0.4474855195890282E-01, 0.1232624016522375E+00, 0.4054507321320544E+00, 0.8168182420396084E+00, 0.5779650563825861E+00, 0.3336575737681243E+00, 0.4793345429794458E+00, 0.3323762775436829E+00, 0.4013874798394268E-01, 0.3250840079396182E+00, 0.3339528328323188E+00, 0.6534745789256358E+00, 0.1592419685588734E+00, 0.4882641395765897E-01, 0.3378473153079410E+00, 0.1498873352536064E+00, 0.9366519936638189E+00, 0.8628314489246045E+00, 0.9035188141748132E+00, 0.3376603415628452E+00, 0.8754867721780122E+00, 0.4314313357227496E+00, 0.6689080802643724E+00, 0.7427192946427073E+00, 0.8408966332922378E+00, 0.3923135283693152E+00, 0.9856346160535667E+00, 0.5253798946684216E+00, 0.4589666030610524E+00, 0.3627813920321372E+00, 0.6650592661455799E+00, 0.5488555419923284E+00, 0.8723519563008553E+00, 0.5759829964509324E+00, 0.8314551283704829E+00, 0.8033910216639006E-01, 0.5533270198466882E+00, 0.4579854660280547E-01, 0.8805162884999327E+00, 0.7798601625088321E+00, 0.3998529604552336E+00, 0.2290634020126769E-01, 0.4087780821380217E+00, 0.8084384129630373E-01, 0.1651045317338867E+00, 0.5138876592921692E+00, 0.1502237554834691E+00, 0.3139451210283801E+00, 0.4951417832103121E+00, 0.4305502836911147E+00, 0.4221379680427187E+00, 0.6629276271381638E+00, 0.6032939209531929E+00, 0.7486429236694788E+00, 0.4603187644190643E+00, 0.9910999698454684E+00, 0.9830579802970648E+00, 0.1327788029232968E+00, 0.7906300391462903E+00, 0.4870686063503010E+00, 0.9107501765395865E-01, 0.5847999740468798E+00, 0.5237055378474927E+00, 0.1949033413503392E+00, 0.6706570830152104E+00, 0.4839742423553839E+00, 0.6933746141255293E+00}, + n: 21, + zOut: []float64{0.2594702985921864E+01, 0.1963381202215380E+01, 0.1899121104965353E+01, 0.1852857657580134E+01, 0.1352179381057759E+01, 0.1316420368068040E+01, 0.1223907530772361E+01, 0.1104722051320913E+01, 0.1042814535040686E+01, 0.9392359492223399E+00, 0.5879944547218380E+00, 0.5343064059199153E+00, 0.3616892068472140E+00, 0.3474187565935542E+00, 0.3132932870269020E+00, 0.2394766491234008E+00, 0.1924620369224269E+00, 0.5796610832720670E-01, 0.4900919199482741E-01, 0.2087594658763894E-01, 0.6804292520862544E-03, 0.2186403793390500E-19, 0.2668268315891067E-16, 0.1216320938093713E-16, 0.1223907530772361E+01, 0.3077822220048293E-18, 0.9690290545884895E-18, 0.1677534925257981E-18, 0.1104722051320913E+01, 0.3294338264035954E-18, 0.1270509199570000E-13, 0.4678488073918506E-13, 0.1042814535040686E+01, 0.2740439675865377E-23, 0.1047809983111396E-11, 0.5781643460797313E-12, 0.9392359492223399E+00, 0.3379215452805658E-16, 0.8350045830190690E-10, 0.5730922211948388E-10, 0.5879944547218380E+00, 0.6938893903907228E-17, 0.1799451523948185E+02, 0.1799451523948184E+02, 0.1150000000000000E+03, 0.3578231292517007E+01, 0.6086956521739131E+01, 0.8630088713732289E-10, 0.3616892068472140E+00, 0.1664229231319872E-20, 0.9644621511794884E-10, 0.9354199679969641E-10, 0.3474187565935542E+00, 0.0000000000000000E+00, 0.1015403419286529E-09, 0.1046840761330470E-09, 0.3132932870269020E+00, 0.6366107505133565E-27, 0.3071873418074744E-11, 0.5342885575500614E-12, 0.2394766491234008E+00, 0.2599072586631376E-18, 0.1837414559126179E-09, 0.2303923049314304E-09, 0.1924620369224269E+00, 0.3400814535759169E-17, 0.9192916981159684E-08, 0.4803632388224207E-08, 0.5796610832720670E-01, 0.0000000000000000E+00, 0.1565526746702558E-05, 0.8408463868497472E-06, 0.4900919199482741E-01, 0.7888609052210118E-30, 0.1903794116022181E-04, 0.1014775117962413E-04, 0.2087594658763894E-01, 0.9734740470109229E-22, 0.4676468030348868E-06, 0.4248047233272650E-05, 0.6804292520862544E-03, 0.3161038140634776E-18, 0.1818811163938070E-02, 0.3653457173655013E-02}, + info: 0, + }, + { + z: []float64{0.2029039404458555E-01, 0.4529725864625287E+00, 0.6412066909421453E+00, 0.6139288440336396E+00, 0.3661028502807454E+00, 0.9178254749803582E+00, 0.4307551173824371E+00, 0.4985808870906128E+00, 0.8171615510934167E+00, 0.8279058065788196E+00, 0.3035261047197422E+00, 0.7877147223127390E+00, 0.7688130520483442E+00, 0.4834409462671818E-01, 0.3121145202501183E+00, 0.5269232357652766E+00, 0.7600633371694686E+00, 0.5251092877920901E+00, 0.8263235554592012E+00, 0.6894073332954654E+00, 0.3521429062439027E+00, 0.6447189811681343E+00, 0.1105592548668879E+00, 0.1049454508922576E+00, 0.7381247076050562E+00, 0.7320584094686099E+00, 0.7003114013559573E+00, 0.9638534557041758E+00, 0.5727311775052889E+00, 0.3930768970870516E+00, 0.7640649329763241E+00, 0.3221407324893386E+00, 0.9725443946255905E+00, 0.6922592425787558E+00, 0.3449642467056757E-01, 0.1384627086161467E+00, 0.4398391723165511E+00, 0.8406456486574913E+00, 0.4126144976348992E+00, 0.5351779876797247E-01, 0.6669497026260232E+00, 0.5746288223886410E+00, 0.4589594741804619E+00, 0.7484833637036891E+00, 0.3274476209575072E-01, 0.7067960763848782E+00, 0.8759136475280368E+00, 0.3284828537280239E+00, 0.2536109230678856E+00, 0.8799264273691800E+00, 0.8159607815416694E+00, 0.5729670098854700E-01, 0.8884200881604851E+00, 0.5249116128877267E+00, 0.6498061599007876E-01, 0.6075292761444269E+00, 0.2428201413403417E+00, 0.2668460043818345E+00, 0.1429723702275580E+00, 0.6942338078813951E+00, 0.9271225003121289E+00, 0.8931957344289477E+00, 0.6420336733834545E+00, 0.3786225606645894E+00, 0.9421368123010410E-01, 0.9476439119845459E+00, 0.6497389318978118E+00, 0.3841806572586668E+00, 0.1329188317035728E+00, 0.6545507077812880E+00, 0.4430247695845350E+00, 0.1753161904868739E+00, 0.2413409779703910E+00, 0.1476409499735053E+00, 0.1179852848482287E+00, 0.3704631210033814E+00, 0.1967445635592234E+00, 0.2100970549835486E+00, 0.5744473538919733E+00, 0.1093206314301038E+00, 0.5132572818416121E+00, 0.4964557538937117E+00, 0.7518888363275744E-02, 0.9720615373003737E+00}, + n: 21, + zOut: []float64{0.2563191374817756E+01, 0.2359364796169898E+01, 0.2296884847589588E+01, 0.2056943321577226E+01, 0.1949112826206492E+01, 0.1629835138023691E+01, 0.1562766390641567E+01, 0.1422208590143927E+01, 0.1368481726990307E+01, 0.1150114414099739E+01, 0.8482773777570239E+00, 0.7665061168435710E+00, 0.7135198036652551E+00, 0.3486547062556205E+00, 0.2456691453437445E+00, 0.2203009969871996E+00, 0.1404417091680581E+00, 0.1160909181211330E+00, 0.2112854362928769E-01, 0.5069559443178203E-02, 0.5650407111696261E-03, 0.3717112585401408E-26, 0.2316306425767847E-08, 0.1632477182259275E-08, 0.1562766390641567E+01, 0.6446192664231602E-24, 0.9634960729667980E-08, 0.6524712961691138E-08, 0.1422208590143927E+01, 0.1932709217791479E-28, 0.4932058767625490E-07, 0.7860293908453283E-07, 0.1368481726990307E+01, 0.1238511621196989E-27, 0.2778987342481399E-06, 0.5558918854266694E-06, 0.1150114414099739E+01, 0.2156683454185074E-19, 0.1662595987219070E-04, 0.2580299679298412E-04, 0.8482773777570239E+00, 0.7914569980025776E-17, 0.2178512734418544E+02, 0.2178512734418543E+02, 0.1000000000000000E+03, 0.2934240362811791E+01, 0.1000000000000000E+01, 0.1715129124192563E-05, 0.7135198036652551E+00, 0.1613909508212798E-19, 0.2836076293001813E-04, 0.1595224464977716E-04, 0.3486547062556205E+00, 0.3352658847189300E-29, 0.8812160938383347E-04, 0.1178320764067675E-03, 0.2456691453437445E+00, 0.0000000000000000E+00, 0.5251568647637462E-04, 0.4480459044047029E-04, 0.2203009969871996E+00, 0.6471183777709004E-25, 0.1114279427921990E-09, 0.2270576453660371E-10, 0.1404417091680581E+00, 0.2855676476900063E-27, 0.2886261726979772E-05, 0.5470704056451658E-06, 0.1160909181211330E+00, 0.3526208246337923E-27, 0.3588687949078309E-02, 0.5383294574404876E-02, 0.2112854362928769E-01, 0.2896602354076833E-17, 0.1732996915625309E-02, 0.1499310228751921E-02, 0.5069559443178203E-02, 0.1003594455767978E-17, 0.5081816639203317E-03, 0.1080637708244138E-02, 0.5650407111696261E-03, 0.0000000000000000E+00, 0.5066428376081889E-02, 0.3247326449492487E-02}, + info: 0, + }, + { + z: []float64{0.7177806115181969E+00, 0.9619042524298227E+00, 0.9756290650460009E-01, 0.2695657197860104E+00, 0.5092382615580680E+00, 0.2216490915715645E+00, 0.7713962041593733E+00, 0.9019626308054164E+00, 0.1009043823109016E+00, 0.7164892891763703E+00, 0.6972336574704985E+00, 0.5604456603447616E-01, 0.4658944020177349E+00, 0.4677429402719713E+00, 0.9395972368396054E+00, 0.6567060928508761E-01, 0.6711470087762763E+00, 0.3572615865847095E-01, 0.7841795004355456E-01, 0.2100489732227784E+00, 0.1528790147771258E+00, 0.2944728557463859E+00, 0.6929796239262105E+00, 0.5593689694083593E+00, 0.5600220347177359E+00, 0.6885800745012647E+00, 0.1441376161827218E+00, 0.2468678391528564E+00, 0.2219056216366488E+00, 0.7828887069679423E+00, 0.1781536622262658E-01, 0.9712383516530864E+00, 0.1031071887927941E+00, 0.5428204596104211E+00, 0.9920375605622551E+00, 0.2231614148449633E+00, 0.1774197365731667E+00, 0.1667803739895276E+00, 0.2293956181863850E+00, 0.8453959149417756E+00, 0.2211895679989639E+00, 0.5610288802043042E+00, 0.3749535737701304E-01, 0.7418144847444434E+00, 0.2593245755300763E+00, 0.5358881543370908E-01, 0.9118629582226685E+00, 0.6483736004795430E+00, 0.7595140552166778E+00, 0.2981894989055883E+00, 0.6091779707233183E+00, 0.7798268953767704E+00, 0.1682114110436058E+00, 0.3801835867597201E+00, 0.6380508025759659E+00, 0.7892946000460455E-01, 0.7607559424299619E+00, 0.3271484239841950E+00, 0.7700240256278714E+00, 0.5894107219393652E+00, 0.6207117138108632E+00, 0.4725019923733027E+00, 0.3616574024313524E+00, 0.6744122205664662E+00, 0.5489632027065386E+00, 0.1532930834122788E+00, 0.1692473010839316E+00, 0.7515070367293223E+00, 0.1186783750638719E+00, 0.1028479850139022E+00, 0.3468642488228025E+00, 0.5278752643808988E+00, 0.3849250707234438E+00, 0.7889573536656195E+00, 0.4738712276132427E+00, 0.7058571493185843E+00, 0.8948240863202030E+00, 0.3494029097065446E+00, 0.4916843795342892E+00, 0.1993321046695898E+00, 0.3650043431665774E+00, 0.2403686388300026E+00, 0.5474155466298688E+00, 0.6157434374908201E+00}, + n: 21, + zOut: []float64{0.1955717973339200E+01, 0.1915826728710446E+01, 0.1780143898982495E+01, 0.1751081083154649E+01, 0.1679171531306522E+01, 0.1398798787154148E+01, 0.1289579288306139E+01, 0.1171599632002814E+01, 0.9950381700653156E+00, 0.9008548767119643E+00, 0.7944341357698450E+00, 0.7347990252582277E+00, 0.4053391427425183E+00, 0.3415476013970046E+00, 0.2769292856200630E+00, 0.2086988709391624E+00, 0.7594980741000955E-01, 0.5721582845751132E-01, 0.5152297043277422E-01, 0.6186350115045150E-02, 0.5774958135565486E-05, 0.6722096271457334E-14, 0.6635533119216432E-06, 0.1048982691930868E-05, 0.1289579288306139E+01, 0.0000000000000000E+00, 0.9172850657907766E-08, 0.6527900227304331E-08, 0.1171599632002814E+01, 0.0000000000000000E+00, 0.3386861611239913E-06, 0.1115072165646295E-06, 0.9950381700653156E+00, 0.1044578056257455E-24, 0.5793689136913799E-11, 0.1625904890507595E-10, 0.9008548767119643E+00, 0.8883435102679349E-21, 0.3220671712964998E-09, 0.8453946299986560E-09, 0.7944341357698450E+00, 0.1653452457343241E-26, 0.1779044076283400E+02, 0.1779044076283399E+02, 0.1120000000000000E+03, 0.3267573696145125E+01, 0.3571428571428572E+01, 0.1211740269624600E-06, 0.4053391427425183E+00, 0.5298753945086544E-14, 0.1515410194583574E-06, 0.2069357347527298E-06, 0.3415476013970046E+00, 0.0000000000000000E+00, 0.2579333883676927E-05, 0.8435987645777294E-05, 0.2769292856200630E+00, 0.2465190328815662E-30, 0.1658852164453815E-08, 0.3207072615633299E-09, 0.2086988709391624E+00, 0.2017246551328580E-19, 0.6091457019925236E-05, 0.6297972233022177E-05, 0.7594980741000955E-01, 0.2553131970482608E-15, 0.2736366650719638E-04, 0.2348362771705736E-04, 0.5721582845751132E-01, 0.1141311335899276E-23, 0.6030351005218485E-04, 0.3385365250818500E-04, 0.5152297043277422E-01, 0.0000000000000000E+00, 0.4442856906399686E-04, 0.3980460155412817E-04, 0.6186350115045150E-02, 0.2711709361697228E-30, 0.1322896557202734E-03, 0.3209571887096705E-03, 0.5774958135565486E-05, 0.0000000000000000E+00, 0.9248295446812529E-03, 0.1317994001905306E-02}, + info: 0, + }, + { + z: []float64{0.7669589114699304E-01, 0.2959120838012549E+00, 0.8617075527885690E+00, 0.3774472194278293E+00, 0.7430204868341380E+00, 0.3337487204025202E-01, 0.2115072947611989E+00, 0.8195300149220009E+00, 0.4610153087687133E+00, 0.1049580467270205E+00, 0.6553761031646719E+00, 0.2044425657813468E+00, 0.1419536829746254E+00, 0.8338399989758465E+00, 0.9917105482281005E+00, 0.3698082853107363E+00, 0.5656210986926330E+00, 0.5849265049217818E+00, 0.9018145207330325E+00, 0.7089264704350354E+00, 0.2562038341655152E+00, 0.1524378342317656E-01, 0.9206210351037002E+00, 0.1877259832276945E+00, 0.3637451600309541E+00, 0.9979742594017312E+00, 0.8919698496914060E+00, 0.3716780472994426E+00, 0.3142548907151147E+00, 0.4170439734847903E+00, 0.3197415298896636E+00, 0.7285365914169133E+00, 0.5784968714882697E+00, 0.6831919512327895E+00, 0.6057174197537164E+00, 0.6413693987683566E-01, 0.8827799219498907E+00, 0.4192891003797022E+00, 0.6040167945472836E+00, 0.6469271762278970E+00, 0.7359461974470041E+00, 0.5539488596393002E+00, 0.4023966166720030E+00, 0.9915288950117843E+00, 0.3043860170301459E+00, 0.4917889743094436E+00, 0.1179472550216760E+00, 0.9125202427370891E+00, 0.8786441005384636E+00, 0.4634730997209351E+00, 0.1080276946115265E+00, 0.6187727001119313E+00, 0.6709766557170562E+00, 0.3818949179452977E+00, 0.8906457783485427E+00, 0.8010289089804480E+00, 0.6931910498827129E+00, 0.8914072225833563E+00, 0.3822463769530011E+00, 0.5898102885291842E+00, 0.1092049166271940E+00, 0.8496011938807149E+00, 0.2304394290731624E+00, 0.5949006075515944E+00, 0.3290638194228065E+00, 0.1971699984758039E+00, 0.7443144303888384E+00, 0.4653555333092598E+00, 0.8207632269304853E+00, 0.4152482306441556E+00, 0.1689785233215235E+00, 0.1721084345877374E+00, 0.3931596107353640E+00, 0.5403345228237123E+00, 0.6387555392172577E+00, 0.1804790096977364E+00, 0.5783025205396422E+00, 0.7395837791384520E+00, 0.5701597209798811E+00, 0.1952734055752668E+00, 0.9661114908130567E+00, 0.4893113195434146E+00, 0.6562980654604210E+00, 0.1879394621701417E+00}, + n: 21, + zOut: []float64{0.2390558120678448E+01, 0.2326196956724044E+01, 0.2071676597874671E+01, 0.1995424877356871E+01, 0.1973795189776371E+01, 0.1728273264358535E+01, 0.1492322130169846E+01, 0.1216694895544233E+01, 0.1149617898796123E+01, 0.1007011094632661E+01, 0.9207056739913982E+00, 0.7404938152461292E+00, 0.6082352700464410E+00, 0.5965144149455339E+00, 0.2276577044879657E+00, 0.1776272681811473E+00, 0.1662286875439616E+00, 0.8310804130734020E-01, 0.4604735683437314E-01, 0.1806926893972028E-01, 0.1257133375345320E-01, 0.3600386373101646E-15, 0.6280777483216298E-03, 0.1060573000233681E-02, 0.1492322130169846E+01, 0.1292469707114105E-25, 0.5799349861429450E-06, 0.5584709508928944E-06, 0.1216694895544233E+01, 0.2047280287874868E-18, 0.1299955932331242E-09, 0.8534229075832313E-10, 0.1149617898796123E+01, 0.5088714046955349E-16, 0.6001732451841635E-09, 0.4081989685050919E-09, 0.1007011094632661E+01, 0.5578719308559292E-21, 0.1498995168909837E-07, 0.5625367692005608E-08, 0.9207056739913982E+00, 0.2728742825015995E-21, 0.2094882986118927E+02, 0.2094882986118927E+02, 0.9800000000000000E+02, 0.3004535147392290E+01, 0.4081632653061225E+01, 0.6223967900246754E-04, 0.6082352700464410E+00, 0.4038967834731580E-26, 0.1122996207538654E-05, 0.1754126012223728E-05, 0.5965144149455339E+00, 0.4386207914826929E-19, 0.1334483593164094E-04, 0.6982705884252015E-05, 0.2276577044879657E+00, 0.3148538924591216E-18, 0.9085150621800872E-04, 0.4628114404518947E-04, 0.1776272681811473E+00, 0.1149284743081177E-19, 0.3934684725502468E-05, 0.5044161242313764E-05, 0.1662286875439616E+00, 0.3944304526105059E-30, 0.1149340461723492E-04, 0.8510588625472410E-05, 0.8310804130734020E-01, 0.1540743955509789E-32, 0.1285467894756909E-02, 0.9239857033877289E-03, 0.4604735683437314E-01, 0.2169367489357782E-29, 0.2808730938050547E-03, 0.3455059327639833E-03, 0.1806926893972028E-01, 0.4614836295542919E-28, 0.7683442768713957E-06, 0.1846813906304985E-05, 0.1257133375345320E-01, 0.2538554393001216E-26, 0.4028502005942143E-04, 0.8466712427867894E-04}, + info: 0, + }, + { + z: []float64{0.5568197491282034E+00, 0.7338530212513171E+00, 0.1711270247791036E+00, 0.6696990680288049E+00, 0.1107644593582661E+00, 0.1487844153251054E+00, 0.6221478836712087E+00, 0.3739707210550620E+00, 0.6142936216832375E+00, 0.4504419047617665E+00, 0.1390832371836795E+00, 0.9602056283222130E+00, 0.4128383897877478E+00, 0.6202590221465013E+00, 0.5716294881431405E+00, 0.7009876531280159E+00, 0.8556346552408018E+00, 0.4300043005510307E+00, 0.5625488786064613E+00, 0.5236571943623558E+00, 0.2035297706440273E+00, 0.5324677179555473E+00, 0.9854023908952125E+00, 0.8088580870995794E+00, 0.7902887218423563E+00, 0.4196418643524230E+00, 0.5294914665193529E+00, 0.5947417442754066E-01, 0.2753919335549286E+00, 0.8807083336864044E+00, 0.6016279529290567E+00, 0.4144655693858035E-01, 0.4808953029705748E+00, 0.8506686680287934E-01, 0.2145404015834380E+00, 0.3020133878086849E+00, 0.8967140938263458E+00, 0.5344538485865815E+00, 0.2536120629120923E+00, 0.2552452828610304E+00, 0.9211096671641958E+00, 0.9028760680202415E+00, 0.3005599522329846E+00, 0.1197919551028395E+00, 0.3772579707039786E+00, 0.4157715274081910E+00, 0.2203607291065889E+00, 0.1084188329562713E+00, 0.5463193166123409E+00, 0.8107359194268960E+00, 0.6676190072779817E+00, 0.6711454730587799E+00, 0.6360708014875704E-01, 0.8242026716736568E+00, 0.3687006444230088E+00, 0.2216898043026083E-01, 0.4978612409817640E+00, 0.3144452507777135E+00, 0.3412289603988730E+00, 0.3266626310182044E+00, 0.4581662376370765E+00, 0.6985218227047190E+00, 0.6594479039269319E-01, 0.3938130402504401E+00, 0.9907371819490932E+00, 0.2478499678343852E+00, 0.3565435772734814E+00, 0.8420455744018336E+00, 0.2692247454903065E+00, 0.7327570909626056E+00, 0.1752776205164243E+00, 0.3569190164542581E+00, 0.2122621782757903E+00, 0.2056257129895300E+00, 0.6641092684756426E+00, 0.5386917539530447E+00, 0.8420713652275945E+00, 0.3587226239611645E+00, 0.9561844063661247E+00, 0.9126272291387975E+00, 0.5768542567999925E+00, 0.1972168939311342E+00, 0.5763304496236371E+00, 0.9478337554439876E+00}, + n: 21, + zOut: []float64{0.2593664459139222E+01, 0.2338172956520739E+01, 0.1783072679058981E+01, 0.1768637196043293E+01, 0.1688808722758796E+01, 0.1535694950136988E+01, 0.1488691522387158E+01, 0.1290354539321546E+01, 0.1187570436840380E+01, 0.1077679082742636E+01, 0.7925423484101771E+00, 0.6549022645335129E+00, 0.6315653598883190E+00, 0.5184441284206909E+00, 0.3791491409939438E+00, 0.3105722740860607E+00, 0.1128189367670211E+00, 0.7036440937731858E-01, 0.4999153992819697E-01, 0.2730914559941030E-01, 0.7241089204639656E-03, 0.7344040350490801E-18, 0.1828200693350630E-07, 0.2226187377323797E-07, 0.1488691522387158E+01, 0.4586948101010510E-17, 0.3930142187345605E-07, 0.5206893736347286E-07, 0.1290354539321546E+01, 0.6658190007940994E-20, 0.1499933495859733E-06, 0.7910043275590841E-07, 0.1187570436840380E+01, 0.2370536763713858E-16, 0.1192422432592963E-05, 0.6065280015592916E-06, 0.1077679082742636E+01, 0.6803770690793804E-23, 0.5360141282897325E-04, 0.3254990522417721E-04, 0.7925423484101771E+00, 0.8404284270509473E-23, 0.2030073020187486E+02, 0.2030073020187486E+02, 0.9700000000000000E+02, 0.2975056689342404E+01, 0.1030927835051546E+01, 0.1762395614510388E-04, 0.6315653598883190E+00, 0.2034005362457094E-16, 0.3178492515415974E-08, 0.1141868824523976E-08, 0.5184441284206909E+00, 0.1631704231140345E-20, 0.1154759308961600E-04, 0.3555504775624820E-05, 0.3791491409939438E+00, 0.9251916923707874E-19, 0.1302644751785016E-04, 0.1874642271188771E-04, 0.3105722740860607E+00, 0.1235671721938193E-25, 0.8697586673438179E-05, 0.7595546859022038E-05, 0.1128189367670211E+00, 0.1175733067685735E-18, 0.2174688695641498E-03, 0.1411064498403114E-03, 0.7036440937731858E-01, 0.5916456789157589E-30, 0.4997004849851516E-03, 0.7625846015345374E-03, 0.4999153992819697E-01, 0.3710108611279200E-20, 0.2898431160817185E-04, 0.2329024376647231E-03, 0.2730914559941030E-01, 0.1593079290931123E-17, 0.5731904499848677E-04, 0.7071520517918782E-04, 0.7241089204639656E-03, 0.1043820749788443E-25, 0.2096656950463827E-03, 0.4915700720935459E-03}, + info: 0, + }, + { + z: []float64{0.2129092067945103E+00, 0.6174796583507793E+00, 0.2209275310088966E+00, 0.1770681976597738E+00, 0.8468210663920229E+00, 0.7900600194799612E+00, 0.8319584509547915E+00, 0.8077183726155964E+00, 0.7964773509287093E+00, 0.2479492923952727E+00, 0.5169395370002006E-01, 0.6312063121285433E+00, 0.5688486960732374E+00, 0.3049379579822397E+00, 0.3779887662042721E+00, 0.4551165943302187E+00, 0.8807128836121972E+00, 0.1333615670826408E+00, 0.6901278826487529E+00, 0.8360350720177558E+00, 0.4190492004641316E+00, 0.9067077556412378E+00, 0.9762584494767094E+00, 0.9959763915912888E+00, 0.8503724779590973E+00, 0.6671116075685212E+00, 0.8841807167789617E+00, 0.6917331852931945E+00, 0.3414398718690443E+00, 0.2211364241075178E+00, 0.8057250135329493E+00, 0.4405475768508057E+00, 0.9321382353755537E+00, 0.6976358515081519E+00, 0.3254605598548291E+00, 0.1144237265035558E+00, 0.8547099978727912E-01, 0.3131314226614652E+00, 0.6940029038044814E+00, 0.2327469211945017E+00, 0.3523896044562020E+00, 0.6443116162172926E+00, 0.5382708884344491E+00, 0.9378966459649967E+00, 0.7274262519928346E+00, 0.4882092650189528E+00, 0.4497457043638882E+00, 0.8803511251742836E+00, 0.1077837527475992E+00, 0.4760275900323754E+00, 0.9725944612716640E+00, 0.4013370227296387E+00, 0.8188706727711300E+00, 0.7549128555022213E+00, 0.3045373312490215E+00, 0.9776368127163177E+00, 0.5516094182757485E+00, 0.8449472155130459E+00, 0.9309695118211208E+00, 0.6985346927019656E+00, 0.3270836933831586E+00, 0.2305805980953167E+00, 0.9135598850313159E+00, 0.2886818807914165E+00, 0.6607756604738726E+00, 0.7992086772120486E+00, 0.9191714969823802E+00, 0.9956222713515444E+00, 0.1646632133753003E+00, 0.8114783440114911E+00, 0.9650128806412454E+00, 0.1382218488636167E-01, 0.8464890579713791E+00, 0.2866238720970538E+00, 0.4485743907736028E-01, 0.5384705384174762E+00, 0.2996807710312754E-01, 0.7020716858392958E+00, 0.6280049430389886E+00, 0.2750308929159380E+00, 0.1648004007672321E-01, 0.8720570971091830E+00, 0.9962373992422624E+00, 0.8022759164194093E-01}, + n: 21, + zOut: []float64{0.3179557858974794E+01, 0.2694788878259719E+01, 0.2281326093492730E+01, 0.2196001939032204E+01, 0.1828355236773963E+01, 0.1586247682528960E+01, 0.1454772213395289E+01, 0.1286809233158695E+01, 0.1269332746846940E+01, 0.1099355321362049E+01, 0.9971216943768625E+00, 0.8310914612054856E+00, 0.4047131081238095E+00, 0.3869245862172090E+00, 0.3328473924133467E+00, 0.2908704078018756E+00, 0.1880200745280021E+00, 0.5784266149949692E-01, 0.4139216712761701E-01, 0.1651732519409763E-01, 0.3149646326524349E-02, 0.0000000000000000E+00, 0.5227593374295754E-11, 0.1202138413496143E-10, 0.1454772213395289E+01, 0.1393199790273629E-16, 0.1121878363020271E-09, 0.5353121918082171E-10, 0.1286809233158695E+01, 0.8659547037664508E-24, 0.1645814283637519E-08, 0.8601359367531547E-09, 0.1269332746846940E+01, 0.2823844361652584E-22, 0.5929700276768749E-08, 0.1126902625809321E-07, 0.1099355321362049E+01, 0.2358945595467410E-22, 0.2764360194400850E-05, 0.1553001254800959E-05, 0.9971216943768625E+00, 0.4450651748190101E-21, 0.2242703772863968E+02, 0.2242703772863967E+02, 0.1000000000000000E+03, 0.3015873015873016E+01, 0.3000000000000000E+01, 0.2632919892231646E-04, 0.4047131081238095E+00, 0.5820888909768840E-10, 0.2209233784503674E-04, 0.4136287504408153E-04, 0.3869245862172090E+00, 0.6462348535570008E-26, 0.3088379129783557E-03, 0.1528857353804532E-03, 0.3328473924133467E+00, 0.5549599819233453E-15, 0.8893453420684614E-08, 0.8741044673362129E-07, 0.2908704078018756E+00, 0.2289589891313465E-25, 0.5532514209995071E-04, 0.2183152999074702E-03, 0.1880200745280021E+00, 0.6113672015462841E-28, 0.9851023787951559E-03, 0.2769770083415459E-02, 0.5784266149949692E-01, 0.3571962178840741E-24, 0.3360295855593957E-02, 0.3874576703777444E-02, 0.4139216712761701E-01, 0.1555002616371658E-25, 0.3047908004675713E-02, 0.4283880536865950E-02, 0.1651732519409763E-01, 0.1498533807074276E-21, 0.9218134151523294E-06, 0.6993690185531638E-05, 0.3149646326524349E-02, 0.5476587948406352E-25, 0.9434027266146764E-03, 0.1032678112098284E-02}, + info: 0, + }, + { + z: []float64{0.5325973817915391E+00, 0.8075384328404875E+00, 0.2063920576624930E+00, 0.4895050697482526E+00, 0.3224859392283662E+00, 0.4597919629142447E+00, 0.5480240110168966E-01, 0.5228709929272914E+00, 0.9956836568223112E+00, 0.3978480622803672E+00, 0.9124816118920143E-01, 0.3247027355683270E+00, 0.9224658967837341E+00, 0.9984579111484309E+00, 0.8533112174943273E+00, 0.8907006920892125E+00, 0.3659539504394835E+00, 0.5561036191465061E+00, 0.7570794287369270E+00, 0.7781602931894585E+00, 0.8583979385494303E+00, 0.5883490719908564E+00, 0.2958788793535505E+00, 0.8441503484168636E+00, 0.7171074610327245E+00, 0.6324186559935309E+00, 0.6889002812298057E+00, 0.9679449699589238E-01, 0.8071604187540067E+00, 0.5036464295967858E+00, 0.3075050973746345E+00, 0.4354181299061508E+00, 0.5397482510302705E+00, 0.3266316370831254E+00, 0.7127302469392831E+00, 0.7822329043112050E+00, 0.1787867076882754E+00, 0.5059399114486356E+00, 0.1635357104384569E+00, 0.7923616792404551E+00, 0.8527619409672080E+00, 0.6624868870738707E+00, 0.6395827198572863E+00, 0.5045303635733072E+00, 0.5207053335438128E-01, 0.3872927271413512E+00, 0.8590236531191382E+00, 0.8644737695336893E+00, 0.5447620155822054E+00, 0.3420775682173337E+00, 0.1787889858336624E+00, 0.2962040723342502E+00, 0.1197091589896203E+00, 0.2582729465177200E+00, 0.8564224654785235E+00, 0.1003255861450059E+00, 0.5792751794645187E+00, 0.3553877787422808E+00, 0.3515051629979192E+00, 0.7026347035497048E+00, 0.7851727410421285E+00, 0.9451470000488936E+00, 0.1482591966327134E+00, 0.8035088707163867E+00, 0.8018983228501475E-02, 0.5992223740738118E+00, 0.3369698862429809E+00, 0.9971168486495201E+00, 0.7449267587097297E+00, 0.5929357935363798E+00, 0.8575900212486389E+00, 0.8115297023854162E+00, 0.3380359989630263E+00, 0.8328174310878843E+00, 0.8255713836908419E+00, 0.7399149789721748E+00, 0.1725333812438860E+00, 0.6828663265380140E+00, 0.6234367510076171E+00, 0.5628070366267671E+00, 0.8501068267959022E-01, 0.9315797050119701E+00, 0.1842029704669090E+00, 0.9504814303233714E+00}, + n: 21, + zOut: []float64{0.2923425454171414E+01, 0.2535311958925162E+01, 0.2192080092128743E+01, 0.1925146455902099E+01, 0.1841700496719334E+01, 0.1753280727277585E+01, 0.1582442080550360E+01, 0.1581069533140902E+01, 0.1420113611638973E+01, 0.1070153147168429E+01, 0.9980373856163754E+00, 0.9531244298503998E+00, 0.7077665812605668E+00, 0.5659990522281487E+00, 0.3146390113583965E+00, 0.2516605740660456E+00, 0.1663945631562664E+00, 0.1260010860507715E+00, 0.4255237190875141E-01, 0.7100815132372204E-02, 0.1566331927046113E-03, 0.4122332130840440E-22, 0.4572750287882177E-06, 0.8150029788456509E-06, 0.1582442080550360E+01, 0.6246970091107327E-19, 0.1184058245159526E-05, 0.5957129004529113E-06, 0.1581069533140902E+01, 0.2712893915232508E-21, 0.4684400026881307E-05, 0.9374804625040887E-05, 0.1420113611638973E+01, 0.4814409269321697E-22, 0.2425457953812455E-04, 0.3059673263223507E-04, 0.1070153147168429E+01, 0.4457872866361589E-11, 0.2849702090992769E-05, 0.4079444611357521E-05, 0.9980373856163754E+00, 0.2148022614677702E-19, 0.2295815606144379E+02, 0.2295815606144380E+02, 0.9700000000000000E+02, 0.2981859410430839E+01, 0.2061855670103093E+01, 0.4336961109868880E-06, 0.7077665812605668E+00, 0.3355216099479021E-19, 0.2178215603335118E-03, 0.1596478432727446E-03, 0.5659990522281487E+00, 0.3777948407501058E-19, 0.1732350582817826E-03, 0.1687341431970761E-03, 0.3146390113583965E+00, 0.4215672677501087E-24, 0.8708765796225133E-03, 0.5753505295482449E-03, 0.2516605740660456E+00, 0.8872339250080977E-20, 0.2809442395187102E-02, 0.2330568324677941E-02, 0.1663945631562664E+00, 0.1848892746611746E-31, 0.7424955400801435E-06, 0.1353946060853610E-06, 0.1260010860507715E+00, 0.7099748146989106E-27, 0.5320431162642944E-03, 0.1085271179151602E-03, 0.4255237190875141E-01, 0.2808116620904140E-21, 0.1709028753951538E-02, 0.8528114742759547E-03, 0.7100815132372204E-02, 0.4930380657631324E-31, 0.2904056487242609E-02, 0.3026916823887611E-02, 0.1566331927046113E-03, 0.0000000000000000E+00, 0.2549645590833870E-02, 0.2592045976400073E-02}, + info: 0, + }, + { + z: []float64{0.6141085085904113E+00, 0.3421028526671319E+00, 0.2523050636037050E-01, 0.6894939888024587E+00, 0.1106696902059259E+00, 0.3232796216228777E+00, 0.5026462674631121E+00, 0.4061906185674803E+00, 0.2489870821257593E+00, 0.5655528330838598E+00, 0.8215445521378404E+00, 0.6847122058387792E+00, 0.1058838690465073E+00, 0.3150742731806708E+00, 0.6299058795873502E-01, 0.2792122534089967E+00, 0.6156682980944264E+00, 0.6784924553414444E+00, 0.5548029179057333E+00, 0.9875334352131669E+00, 0.7114388615166174E+00, 0.4680838251435693E+00, 0.9939378516921551E+00, 0.9317334719497590E+00, 0.7166727913665860E+00, 0.9133735504519750E+00, 0.6652039093977162E+00, 0.8687642647047388E+00, 0.5616945762819415E+00, 0.3985759546461669E+00, 0.7431799484571856E+00, 0.7126935860242257E+00, 0.1006984098734091E+00, 0.3341210154632034E+00, 0.8752290131259591E+00, 0.9044047683690323E+00, 0.2748574881470656E+00, 0.9153414825361147E+00, 0.1879700367171477E-01, 0.4139829057070108E+00, 0.6163962814716032E+00, 0.4758310984958897E+00, 0.7283265374189019E-01, 0.4293121596195046E+00, 0.1627494487778676E+00, 0.6477819718948226E+00, 0.1769525517070647E-01, 0.8315284238294101E+00, 0.3951374239126071E-01, 0.8607842403091001E+00, 0.4542147501441236E+00, 0.7533183963616871E+00, 0.3860688952521878E+00, 0.7194066659377851E+00, 0.5625319388225433E+00, 0.2666855367146020E+00, 0.1952117588514313E+00, 0.4351982558470283E+00, 0.5735131371596182E+00, 0.6135067797741378E-01, 0.6627925797553079E+00, 0.5958408703801275E+00, 0.1272760770553625E+00, 0.9764806486481753E+00, 0.3738230266231765E+00, 0.8498786384730982E+00, 0.9509621583287799E+00, 0.5442964253426497E+00, 0.1274761736897801E+00, 0.8749459887021185E+00, 0.5319902581507450E+00, 0.4050330112540623E-01, 0.4679445276719574E-01, 0.6398654173496683E+00, 0.1619398995392787E+00, 0.2834692561637309E-01, 0.7369067773846130E+00, 0.2655208002136908E+00, 0.1902643003388997E+00, 0.7054378485643029E+00, 0.8869999325574263E+00, 0.1700725746174213E+00, 0.7638558771240449E+00, 0.3965145662986846E+00}, + n: 21, + zOut: []float64{0.3026266675500349E+01, 0.2485098580281992E+01, 0.2208517136068298E+01, 0.2089817225148914E+01, 0.1987605159106218E+01, 0.1671782272803828E+01, 0.1288709839574181E+01, 0.1226108028801468E+01, 0.1094715872236073E+01, 0.9893293804315401E+00, 0.9470004635866569E+00, 0.8354737908875075E+00, 0.7678170961167213E+00, 0.5139691139127377E+00, 0.3402258729602133E+00, 0.2640682732152568E+00, 0.1814642316568930E+00, 0.9210283120697343E-01, 0.5017295169510767E-01, 0.1311272184039149E-01, 0.2605821149103687E-06, 0.8821141249794507E-26, 0.1703621403540070E-06, 0.1022946688596755E-06, 0.1288709839574181E+01, 0.0000000000000000E+00, 0.7771811135093639E-06, 0.1129025861285597E-05, 0.1226108028801468E+01, 0.8850832554089860E-22, 0.6461044606060110E-07, 0.3214361230688769E-07, 0.1094715872236073E+01, 0.5589172803550431E-19, 0.3128365184192157E-08, 0.1088448901615084E-07, 0.9893293804315401E+00, 0.4249640396990678E-22, 0.2862531707476509E-05, 0.1047704834723032E-05, 0.9470004635866569E+00, 0.2336393132634786E-16, 0.2207335777761344E+02, 0.2207335777761343E+02, 0.1020000000000000E+03, 0.3043083900226757E+01, 0.9803921568627451E+00, 0.1031792375203169E-03, 0.7678170961167213E+00, 0.8633839815190009E-18, 0.1747705279299585E-04, 0.1213546251050483E-04, 0.5139691139127377E+00, 0.2016356967855187E-17, 0.7704963297163309E-04, 0.2063636533685701E-03, 0.3402258729602133E+00, 0.5916456789157589E-30, 0.2417908304509407E-03, 0.2207145059751390E-03, 0.2640682732152568E+00, 0.1479114197289397E-30, 0.1687694376453652E-02, 0.8888286778685235E-03, 0.1814642316568930E+00, 0.1064934658613210E-15, 0.3591290150683059E-02, 0.7604711042910346E-02, 0.9210283120697343E-01, 0.2042102137240287E-23, 0.1463034917919357E-02, 0.1882622569903463E-02, 0.5017295169510767E-01, 0.2551739098626718E-22, 0.3961160948815250E-03, 0.9438210467320612E-03, 0.1311272184039149E-01, 0.1972152263052530E-29, 0.6693623055505279E-03, 0.9046122259092353E-03, 0.2605821149103687E-06, 0.3100321587303656E-14, 0.3978735902689679E-02, 0.4253573989104679E-02}, + info: 0, + }, + { + z: []float64{0.8778106868894964E+00, 0.4777882175260769E+00, 0.1820603962716897E+00, 0.7891460918977841E+00, 0.7131176407472852E+00, 0.2166796106605611E+00, 0.7093860568912320E+00, 0.6747559124413653E+00, 0.1755802732664898E+00, 0.2538529139601842E-01, 0.3839736304139417E+00, 0.4972278527690542E+00, 0.2219918935874782E+00, 0.6587468361459490E+00, 0.6959875726535614E+00, 0.8785259347357933E+00, 0.4385001119617188E+00, 0.2992124106963234E-01, 0.9853525010355352E+00, 0.1842422327604198E-01, 0.7939453301916002E+00, 0.8502867854292200E+00, 0.6683895767567380E+00, 0.8502503508041696E+00, 0.2705991244761674E-02, 0.2273590703395093E+00, 0.1996606140173212E+00, 0.5828845765712893E+00, 0.7928614954547730E+00, 0.1675870051229429E+00, 0.3078809727828886E+00, 0.6073537805183471E-01, 0.3498986727103111E+00, 0.4266607326484094E+00, 0.7790595486765419E+00, 0.6274781693151706E+00, 0.3468808495278470E+00, 0.4002308549977796E+00, 0.8927740819756569E+00, 0.5380209790008849E+00, 0.9944530064668308E+00, 0.8382845348910617E+00, 0.6578833875204938E+00, 0.6784609218227333E-01, 0.9880398702345439E-01, 0.1591591396324092E+00, 0.3625625292925116E-01, 0.7834491156107602E+00, 0.8935128283958205E-01, 0.6534249936105881E+00, 0.9608003610697393E+00, 0.9122649849010867E+00, 0.3064782192618438E+00, 0.6165812021330105E+00, 0.3942978367050161E+00, 0.2389206118855702E+00, 0.4357310309586615E+00, 0.6366539061757281E+00, 0.2487697657706114E+00, 0.3158114775243555E+00, 0.4359459725257834E+00, 0.8521387333399649E+00, 0.7376171834812397E+00, 0.7198918826028659E+00, 0.3787355957929660E+00, 0.5132345781976363E+00, 0.5880413889667653E+00, 0.8394688090887562E+00, 0.3673771632022454E+00, 0.1291928261630060E+00, 0.6552015571219838E+00, 0.7918941075374089E+00, 0.3759434916876330E+00, 0.2131514444401432E+00, 0.5997464643577372E+00, 0.8626895671971565E+00, 0.1962050188754781E+00, 0.6291330853690040E+00, 0.6873926281549517E+00, 0.8949666870308315E-01, 0.1384684788210775E+00, 0.8959871983479050E+00, 0.5967626810459625E+00, 0.6838507108780668E+00}, + n: 21, + zOut: []float64{0.2344484145674817E+01, 0.2205594465347172E+01, 0.2180337141043826E+01, 0.1936893457336740E+01, 0.1819297464222486E+01, 0.1595314798543036E+01, 0.1497965290687764E+01, 0.1192635586559562E+01, 0.1109297670462514E+01, 0.1021894664697417E+01, 0.8474592078637809E+00, 0.7996737801504824E+00, 0.5357931354846659E+00, 0.5077230661246940E+00, 0.4005808269588222E+00, 0.2350964781455809E+00, 0.1732854339186359E+00, 0.5510322151786835E-01, 0.3865442753785928E-01, 0.1308309165665133E-01, 0.1986637888070920E-03, 0.1267902442921281E-19, 0.1632713022477316E-10, 0.9197304681744396E-11, 0.1497965290687764E+01, 0.6540946849634405E-22, 0.1644600422568816E-11, 0.2569557641484267E-11, 0.1192635586559562E+01, 0.1886570321166912E-23, 0.1155544514329289E-09, 0.3178796095468434E-10, 0.1109297670462514E+01, 0.2958228394578794E-30, 0.1814581278982536E-06, 0.5763166468812303E-07, 0.1021894664697417E+01, 0.1648133134119960E-16, 0.5817023408243420E-07, 0.2381874475610022E-07, 0.8474592078637809E+00, 0.5828670879282072E-15, 0.2051036601772319E+02, 0.2051036601772318E+02, 0.1250000000000000E+03, 0.3639455782312925E+01, 0.8800000000000001E+01, 0.1964091724818299E-07, 0.5357931354846659E+00, 0.3518203713570956E-14, 0.1200151291154190E-07, 0.2251426423705210E-07, 0.5077230661246940E+00, 0.6882401190382613E-24, 0.1803872146382089E-06, 0.4763453660743515E-06, 0.4005808269588222E+00, 0.1559915108945621E-18, 0.4978941410546894E-05, 0.5275156660739611E-05, 0.2350964781455809E+00, 0.1004043408045437E-17, 0.5647304839276210E-04, 0.2873291365503010E-04, 0.1732854339186359E+00, 0.2485883728081419E-23, 0.9907264920144563E-04, 0.1293007080503375E-03, 0.5510322151786835E-01, 0.0000000000000000E+00, 0.9623294785827948E-04, 0.7898847596644510E-04, 0.3865442753785928E-01, 0.0000000000000000E+00, 0.2279226510196514E-03, 0.3149968919986460E-03, 0.1308309165665133E-01, 0.4893402802699089E-27, 0.4145854568122489E-03, 0.3196372933697030E-03, 0.1986637888070920E-03, 0.1930680189793120E-17, 0.2183385452652873E-03, 0.3171631588309268E-03}, + info: 0, + }, + { + z: []float64{0.3053504558052776E+00, 0.2234484687205406E+00, 0.6531459952011753E+00, 0.3122060875846019E+00, 0.9991431676363117E+00, 0.2727966396486101E+00, 0.9325466197866266E+00, 0.9368849148298319E+00, 0.8561644447997885E+00, 0.1054815122266185E+00, 0.4923718332155202E-01, 0.9268095624277023E+00, 0.1888864280722891E+00, 0.7655148720572605E+00, 0.1232767826602820E+00, 0.5903563091717590E+00, 0.9248190356569348E+00, 0.5395288290327440E+00, 0.9028402566412551E+00, 0.9500520891471187E-01, 0.8953008781613688E+00, 0.2933361506740548E+00, 0.8453264440546789E+00, 0.5481580781657376E+00, 0.3587646761786403E+00, 0.5176903549368316E+00, 0.7562422108585272E+00, 0.9675296263022207E+00, 0.8986594456301542E+00, 0.5421338625853966E-01, 0.1201688601088308E+00, 0.6190380352364769E+00, 0.5038255434020116E+00, 0.6721007162690862E+00, 0.5702376374225947E+00, 0.9284095682432886E+00, 0.3695163217482177E+00, 0.6039359484498441E-01, 0.4652604684312921E+00, 0.8651698808632446E-01, 0.7546245127264203E+00, 0.7397909213681499E+00, 0.1212064081570199E+00, 0.3507242515197573E+00, 0.1903823153835104E+00, 0.7217789084869874E-01, 0.4631739813227773E+00, 0.4692891642215747E+00, 0.4583968848602870E+00, 0.1862358222844885E+00, 0.2939086301666586E+00, 0.5739509914073745E+00, 0.2602639918141684E+00, 0.7265362515535626E+00, 0.2180031380994948E+00, 0.1132710387386646E+00, 0.7997129355612416E+00, 0.7503609043894605E+00, 0.7921549516519859E+00, 0.2820213454373731E+00, 0.3757885220124352E+00, 0.7700990985029622E+00, 0.7233316318551536E+00, 0.1305854233773539E+00, 0.7245124401476205E+00, 0.5999815977622437E+00, 0.3886468370487757E+00, 0.5608149286383455E+00, 0.4298380566755162E+00, 0.6436590616913128E+00, 0.3743035898091585E-01, 0.4516061963302198E-01, 0.3504820364503235E+00, 0.4814816352089226E+00, 0.5678245050510763E+00, 0.5711961955150159E+00, 0.9549329198325482E+00, 0.8527165734568565E-01, 0.4185783350739758E-01, 0.5702414021975877E-01, 0.2302271730247050E+00, 0.7442529870754924E+00, 0.5366636699040384E+00, 0.8085683101567075E+00}, + n: 21, + zOut: []float64{0.2590499366480712E+01, 0.2541239603587953E+01, 0.2259909426243320E+01, 0.2181782566945434E+01, 0.1886341857097904E+01, 0.1651483296972034E+01, 0.1427705031981996E+01, 0.1248256205386413E+01, 0.1112814709657656E+01, 0.9343995210628773E+00, 0.8379224813887226E+00, 0.8181328249547786E+00, 0.6165308413237942E+00, 0.4939038343854810E+00, 0.4603621358717260E+00, 0.3639045182225083E+00, 0.3137819362841643E+00, 0.1577326270698492E+00, 0.8198100142281199E-01, 0.9578206270736807E-02, 0.4942793252781514E-03, 0.1292469707114106E-22, 0.1980335658106781E-04, 0.1681298419390782E-04, 0.1427705031981996E+01, 0.2584939414228211E-25, 0.8200031816835676E-05, 0.9102296987148495E-05, 0.1248256205386413E+01, 0.4930380657631324E-30, 0.4104488055426074E-09, 0.2576051753309951E-09, 0.1112814709657656E+01, 0.6452508963690269E-19, 0.2339325112754308E-08, 0.4010758969857423E-08, 0.9343995210628773E+00, 0.2041003537989240E-20, 0.4754834042401540E-06, 0.1343807701186157E-06, 0.8379224813887226E+00, 0.2942145729531872E-22, 0.2198875627193616E+02, 0.2198875627193615E+02, 0.1030000000000000E+03, 0.3158730158730159E+01, 0.5825242718446602E+01, 0.2325395492704734E-05, 0.6165308413237942E+00, 0.1475671084242936E-18, 0.4982404846255511E-06, 0.2497087821784679E-06, 0.4939038343854810E+00, 0.1295808538938520E-16, 0.6559194735079054E-05, 0.3408173383041987E-05, 0.4603621358717260E+00, 0.5811344985782108E-17, 0.9559725090946887E-05, 0.1189458663431952E-04, 0.3639045182225083E+00, 0.2913839059670682E-18, 0.4863259217476146E-04, 0.7411068946771063E-04, 0.3137819362841643E+00, 0.2338183723075079E-26, 0.4219303942492233E-03, 0.5983359002845232E-03, 0.1577326270698492E+00, 0.3451266460341927E-30, 0.4370512454739224E-03, 0.2953761682364422E-03, 0.8198100142281199E-01, 0.2482356093574565E-20, 0.7632038538424591E-04, 0.1389505478745866E-03, 0.9578206270736807E-02, 0.1680537859656637E-20, 0.1168521819007177E-01, 0.1200804951998557E-01, 0.4942793252781514E-03, 0.1967697241141140E-19, 0.1184783913560175E-01, 0.1590443390723593E-01}, + info: 0, + }, + { + z: []float64{0.9721612501531746E+00, 0.9226086145236946E+00, 0.6294635256706198E+00, 0.3023176111891041E+00, 0.6049371291087220E+00, 0.2862933293136216E+00, 0.8819078559307578E+00, 0.5258944749310531E+00, 0.1024274135843443E+00, 0.4745865163816484E+00, 0.3569366663070145E+00, 0.5081536020377282E+00, 0.6994675492692721E+00, 0.3184330055525583E+00, 0.4062572718658636E+00, 0.8497577069296732E+00, 0.7686323719242980E+00, 0.8873781649289114E+00, 0.5445815352331720E+00, 0.5465168091072755E+00, 0.2655612328242208E+00, 0.7149116271405493E+00, 0.2779393895548951E+00, 0.1344927254674255E-01, 0.4544708454847078E+00, 0.5332505496545747E-01, 0.3223583007255554E+00, 0.4314145703973596E+00, 0.6194759383350579E+00, 0.9673744275195654E+00, 0.5445933229599376E-01, 0.2359803760372408E+00, 0.4349989237395262E+00, 0.3983243124260842E+00, 0.1549760127081995E+00, 0.6483062457720113E+00, 0.9796384288763583E+00, 0.2088098624466561E-01, 0.7266086220595113E+00, 0.7787182393455840E+00, 0.2714545750078465E+00, 0.3281766266219532E-01, 0.4443206765749519E+00, 0.7385116967559627E+00, 0.4742748966298079E+00, 0.2719801119596308E+00, 0.5535252469642412E+00, 0.6819653774052530E+00, 0.5802197659205470E+00, 0.8706014802153047E+00, 0.7899732601913489E-01, 0.6149130585720997E+00, 0.1184080138409910E+00, 0.7335155686110397E+00, 0.3161056790243246E+00, 0.4751009230144272E+00, 0.6074228340613933E+00, 0.1834459697241099E+00, 0.5602196728537751E+00, 0.6036792416269905E+00, 0.4996379576165632E+00, 0.5762117563802562E+00, 0.4313302593954876E+00, 0.2357090997139660E+00, 0.5266696040444221E+00, 0.4943568418910921E+00, 0.5194970579745682E+00, 0.8729901711287622E+00, 0.1253423978225398E+00, 0.3249303186427334E+00, 0.1476841747547597E+00, 0.8115004890141919E+00, 0.3358761522855614E+00, 0.6267425544884889E+00, 0.8684373664078195E+00, 0.3410509649937432E+00, 0.1223171934609151E+00, 0.6692100819077175E+00, 0.8714060240466885E+00, 0.8435328911476530E+00, 0.3613173587051273E+00, 0.5970888673100956E+00, 0.4814113673780336E+00, 0.9518076426657822E+00}, + n: 21, + zOut: []float64{0.2554276088974017E+01, 0.2353122577016648E+01, 0.1866240795386955E+01, 0.1792222013488891E+01, 0.1776522631286352E+01, 0.1671843747376224E+01, 0.1608565757744856E+01, 0.1413448668253747E+01, 0.9978397039940720E+00, 0.9776727877490632E+00, 0.8701050228770406E+00, 0.6522479060818760E+00, 0.6295532782699175E+00, 0.4076513128864766E+00, 0.3045303763029391E+00, 0.2026925943270836E+00, 0.1597713759311400E+00, 0.1149331809326307E+00, 0.5501161781795570E-01, 0.3472328989596482E-02, 0.1615352262160075E-02, 0.2261810287929078E-15, 0.1434223756681676E-21, 0.1189989751754647E-20, 0.1608565757744856E+01, 0.1068494074045434E-17, 0.1018285523195584E-14, 0.1812446834981097E-15, 0.1413448668253747E+01, 0.8361925595342725E-26, 0.5806129122189708E-11, 0.1848580748818003E-11, 0.9978397039940720E+00, 0.5222833230866609E-21, 0.9842396145073251E-07, 0.4923018478143697E-07, 0.9776727877490632E+00, 0.9540591325261466E-21, 0.1504532523487471E-05, 0.7619936176069947E-06, 0.8701050228770406E+00, 0.2405710216561998E-25, 0.2041333911794964E+02, 0.2041333911794964E+02, 0.1050000000000000E+03, 0.3108843537414966E+01, 0.6666666666666667E+01, 0.1010063659896995E-05, 0.6295532782699175E+00, 0.2958228394578794E-30, 0.7231781167780556E-06, 0.8027785243996724E-06, 0.4076513128864766E+00, 0.2327139670401985E-28, 0.4311361064418766E-06, 0.4365718303993244E-06, 0.3045303763029391E+00, 0.3511198893363720E-17, 0.5813968676396444E-06, 0.4990623034093460E-06, 0.2026925943270836E+00, 0.5787194672316798E-22, 0.1414410322798341E-05, 0.1084116171450400E-05, 0.1597713759311400E+00, 0.3368436065293720E-27, 0.4438807230072854E-05, 0.3295442179394680E-05, 0.1149331809326307E+00, 0.3973698114522315E-22, 0.1450590122472916E-04, 0.1074561246336364E-04, 0.5501161781795570E-01, 0.1153335343143272E-20, 0.9954779132989017E-07, 0.6305695341872095E-07, 0.3472328989596482E-02, 0.7183968878891587E-15, 0.2465868832870137E-03, 0.3524118878925340E-03, 0.1615352262160075E-02, 0.1517768381645227E-26, 0.5410549418889337E-03, 0.6396403869804795E-03}, + info: 0, + }, + { + z: []float64{0.9945523629868341E+00, 0.6311483525653909E+00, 0.7029190400645571E+00, 0.6452581068575963E+00, 0.9353553331334358E+00, 0.1547193049011500E+00, 0.5087511216875095E+00, 0.8821879483245458E+00, 0.5873463835171173E+00, 0.3391476900726194E+00, 0.3121839954924539E+00, 0.2777103145160921E+00, 0.2404463284577694E+00, 0.9114535183484027E+00, 0.4707329974301702E+00, 0.8965398451252625E+00, 0.6082343132413309E+00, 0.6509204493235183E+00, 0.1573499033176421E+00, 0.7416865701488552E+00, 0.1617007503826062E-01, 0.9896605969885931E+00, 0.3427350027671039E+00, 0.9677837053324486E+00, 0.1744936477417883E+00, 0.1063275349300943E+00, 0.7956875801511568E+00, 0.8998967378241718E-01, 0.9957418429488507E-01, 0.2587083053394715E+00, 0.3753593926504107E+00, 0.7537263520315082E+00, 0.1726167393116790E+00, 0.1420490749456633E+00, 0.1475360304745418E+00, 0.3281044300775052E+00, 0.4011897283558843E+00, 0.5039659382748809E+00, 0.8444659776686902E-01, 0.6685320205580927E+00, 0.8425776598223370E+00, 0.6334616337862548E+00, 0.6754035119469365E+00, 0.3594856315188868E+00, 0.4308279252773916E+00, 0.2170629535054914E+00, 0.5040120070238915E+00, 0.3780998968579012E+00, 0.9176188652711103E+00, 0.1603892455353655E+00, 0.2475008720560291E+00, 0.4414989878913728E+00, 0.3466658552370731E+00, 0.3098329951977107E+00, 0.8940921934240968E+00, 0.6686136942966417E+00, 0.4049936818549904E-01, 0.1308695446239941E+00, 0.8770734618597430E+00, 0.7917220872288512E+00, 0.5736823795257117E+00, 0.5474219864141461E+00, 0.3320663514826834E+00, 0.5824816531032581E+00, 0.6748067573570548E+00, 0.8139348519761679E+00, 0.1984641509226878E+00, 0.5557729841117627E+00, 0.1101812804319026E+00, 0.2169710965518002E+00, 0.5846617154920911E+00, 0.9784843983810533E+00, 0.8650267562586114E+00, 0.4041298540058539E+00, 0.9548165813531374E+00, 0.3839697059508718E+00, 0.4296171922210591E+00, 0.9617664542372570E+00, 0.2102779850721345E+00, 0.6135130181658475E+00, 0.3331715196673474E+00, 0.3177082868916457E+00, 0.2836520073686416E+00, 0.4452894940247868E+00}, + n: 21, + zOut: []float64{0.2413112525759640E+01, 0.2309698811549223E+01, 0.1971065496840386E+01, 0.1839093033734385E+01, 0.1586321309986888E+01, 0.1384287501933647E+01, 0.1357349915568794E+01, 0.1342137050614370E+01, 0.1098398899504136E+01, 0.1013688381736709E+01, 0.8838922773071145E+00, 0.7023193003094995E+00, 0.6083268670387161E+00, 0.3967105732701523E+00, 0.3295901758335739E+00, 0.2610566591740404E+00, 0.2254040681461952E+00, 0.1107925081061023E+00, 0.7084089717166595E-01, 0.5790734022898784E-02, 0.1162539701808497E-05, 0.2217532248565769E-17, 0.1400266087055540E-09, 0.1806586784837133E-09, 0.1357349915568794E+01, 0.1160047396826257E-18, 0.1994113072724655E-16, 0.4228494360227003E-16, 0.1342137050614370E+01, 0.1172187884313513E-15, 0.1255075745859590E-14, 0.2503873040081153E-15, 0.1098398899504136E+01, 0.3711182370878063E-20, 0.5744299067797088E-08, 0.4873476684669810E-08, 0.1013688381736709E+01, 0.1283916659070448E-18, 0.9737119066622311E-08, 0.8382615528986061E-08, 0.8838922773071145E+00, 0.3385457556489824E-15, 0.1990987815014785E+02, 0.1990987815014784E+02, 0.1050000000000000E+03, 0.3324263038548753E+01, 0.5714285714285714E+01, 0.5531678096648157E-07, 0.6083268670387161E+00, 0.9327491343333244E-26, 0.3094358165149238E-06, 0.4992693882721107E-06, 0.3967105732701523E+00, 0.1615587133892632E-26, 0.5013465632663534E-06, 0.4474558637993164E-06, 0.3295901758335739E+00, 0.7527343574232552E-22, 0.6917755140723670E-06, 0.9191878134168280E-06, 0.2610566591740404E+00, 0.8992644540970212E-27, 0.3283328599477859E-08, 0.8980185396558612E-09, 0.2254040681461952E+00, 0.2761013168273541E-29, 0.1566859737304233E-05, 0.9651044230345755E-05, 0.1107925081061023E+00, 0.7853700447084989E-18, 0.2494389596499284E-03, 0.3103855763358142E-03, 0.7084089717166595E-01, 0.7910121402691465E-20, 0.9848486231185840E-03, 0.1285663115805527E-02, 0.5790734022898784E-02, 0.1925929944387236E-33, 0.1531134660067926E-02, 0.1103959511478054E-02, 0.1162539701808497E-05, 0.0000000000000000E+00, 0.3553926119432854E-02, 0.1161337136649311E-01}, + info: 0, + }, + { + z: []float64{0.6912525216559012E+00, 0.7535513505900934E+00, 0.9471932644608124E+00, 0.3186447229836621E+00, 0.5324891284853083E+00, 0.8568362673509099E+00, 0.7683599820389093E+00, 0.5584553004793524E+00, 0.5571013534938567E+00, 0.9300192917069305E-01, 0.8580829209571639E+00, 0.7019126526839274E+00, 0.6637712341629651E+00, 0.1211000088170944E+00, 0.6340253546080570E+00, 0.8089912896293909E+00, 0.9056005723453709E+00, 0.8259750504337368E+00, 0.7787230128973186E+00, 0.5552567089885843E+00, 0.1575217143336131E+00, 0.6258385609742768E+00, 0.3943745586872103E+00, 0.2414131111537543E-02, 0.1491577729788018E-01, 0.3231570165180105E+00, 0.6629837458829935E+00, 0.3692715436026686E+00, 0.4217957028148089E+00, 0.9587355452830710E+00, 0.2048474370070816E+00, 0.9514275263988156E+00, 0.6824099372375696E+00, 0.4368303647429550E-01, 0.1779948598152153E+00, 0.8894462775192779E+00, 0.5101271266317630E+00, 0.9448652224292025E+00, 0.2265718177112338E+00, 0.3995811139403516E+00, 0.8380789267629041E+00, 0.6621441253102893E+00, 0.1548712624835822E+00, 0.6028850196944033E+00, 0.6938032609628844E+00, 0.6847684356722229E+00, 0.5160938472467536E+00, 0.2489894297094153E+00, 0.1603949345362032E-01, 0.8469682453172568E+00, 0.1332301650751776E+00, 0.4964641576870391E+00, 0.8955382322295532E+00, 0.8913224930710517E-01, 0.1632933980261509E+00, 0.7671629642421702E+00, 0.1918190416387825E+00, 0.4660642407804531E+00, 0.3421851388276426E+00, 0.6793284417353496E-03, 0.4856583571413033E+00, 0.6596584184483706E+00, 0.3999565195667565E-01, 0.4265147212719423E+00, 0.1721559491949431E-01, 0.4779030554385033E-01, 0.9628058707102425E+00, 0.4575395386200597E+00, 0.3526890078762277E+00, 0.7271726865364773E+00, 0.1741804541232641E+00, 0.3524640041347155E+00, 0.2143698389021181E+00, 0.9553499123803968E+00, 0.7803670081719427E+00, 0.7906509834069840E+00, 0.5939624443460740E+00, 0.5439294231719827E+00, 0.4026522884432556E+00, 0.2400403086558794E+00, 0.1695045416332096E+00, 0.8774151073165960E+00, 0.9528799076371641E-01, 0.6357307125994049E-01}, + n: 21, + zOut: []float64{0.2768602537214622E+01, 0.2449987435840808E+01, 0.2103617452638331E+01, 0.2091492233971247E+01, 0.2040261542124423E+01, 0.1984511273424848E+01, 0.1507960384149227E+01, 0.1491386484166052E+01, 0.1283295633334833E+01, 0.1065640575633715E+01, 0.9760063516861833E+00, 0.9535053549649605E+00, 0.6117733318422185E+00, 0.5156356643703764E+00, 0.4217391763517565E+00, 0.2514332616796913E+00, 0.1056943786041289E+00, 0.6556299181229375E-01, 0.2554189252987301E-01, 0.1599343544217954E-01, 0.7248128851221257E-03, 0.1757582096832414E-26, 0.8938568486456872E-12, 0.7801064326234513E-12, 0.1507960384149227E+01, 0.1792073872399063E-19, 0.2167105506392983E-08, 0.2566615495401212E-08, 0.1491386484166052E+01, 0.2939740300877914E-17, 0.1513553473151668E-08, 0.1292098164447321E-08, 0.1283295633334833E+01, 0.5002192774679673E-18, 0.3422853236655498E-09, 0.3087733884567774E-09, 0.1065640575633715E+01, 0.2649562899583917E-24, 0.1824851422869684E-09, 0.1969539993879423E-09, 0.9760063516861833E+00, 0.4849588587138365E-15, 0.2273036620466689E+02, 0.2273036620466689E+02, 0.1110000000000000E+03, 0.3401360544217687E+01, 0.6306306306306307E+01, 0.7012703734578152E-09, 0.6117733318422185E+00, 0.2636779683484747E-15, 0.8832037497597917E-08, 0.1377654767646391E-07, 0.5156356643703764E+00, 0.0000000000000000E+00, 0.4403364729024244E-07, 0.2921450058151117E-07, 0.4217391763517565E+00, 0.5116160632510206E-16, 0.4627032593211780E-06, 0.6780935482482274E-06, 0.2514332616796913E+00, 0.3477119313860159E-18, 0.8396751469149006E-05, 0.1191099168408868E-04, 0.1056943786041289E+00, 0.3125614770312806E-14, 0.3873238345753621E-04, 0.1564927337192913E-03, 0.6556299181229375E-01, 0.2145521217817673E-17, 0.9476510350371504E-03, 0.9104754488359111E-03, 0.2554189252987301E-01, 0.1508279173816323E-23, 0.1093077353977330E-02, 0.3191708039391989E-03, 0.1599343544217954E-01, 0.1319576415787468E-18, 0.1003863779460019E-02, 0.1271197433268307E-02, 0.7248128851221257E-03, 0.5169135658374832E-21, 0.1128681157512944E-02, 0.4574374031799749E-02}, + info: 0, + }, + { + z: []float64{0.8514967554120231E+00, 0.1903564904561825E+00, 0.9315134585755248E+00, 0.6865565499502658E+00, 0.9874780893034819E+00, 0.4243732836164926E-01, 0.4493254789963134E+00, 0.1218497220886967E+00, 0.3032420422448456E-01, 0.4472006833337416E+00, 0.7764061193501844E+00, 0.2765680149425037E+00, 0.1540380964603436E+00, 0.8227084597523057E+00, 0.1281873340097673E+00, 0.2797045229662546E+00, 0.1723485697940061E+00, 0.5407468670158238E+00, 0.3703892253237170E+00, 0.3275545813562609E+00, 0.1384768695152372E+00, 0.8683661690082241E+00, 0.2417038393999236E+00, 0.1573965961648072E+00, 0.7549703050710239E+00, 0.4197135409081310E+00, 0.5565257749798536E-01, 0.7494783707245707E+00, 0.8342833407960080E+00, 0.7207413539297494E+00, 0.3936911272324267E+00, 0.8307872407436112E-01, 0.5696677800088412E-01, 0.2580569153061851E-01, 0.3976149332803511E+00, 0.4082340292723502E+00, 0.3620800929220623E+00, 0.2078006460748600E+00, 0.6810562489816266E+00, 0.8414616295760738E+00, 0.2053319202340824E+00, 0.7745582586901971E+00, 0.8243869237197288E-01, 0.7513634029365589E+00, 0.8658814490552211E+00, 0.7014202441287165E-01, 0.8786892218281559E+00, 0.2415414918645031E-01, 0.1648367770784782E+00, 0.5852629690413500E+00, 0.6558826026732849E+00, 0.3505171007322015E+00, 0.5959744796861849E+00, 0.6000199298251039E+00, 0.5156931460104713E+00, 0.1010243586499049E-01, 0.2804608587164645E+00, 0.7088599878489240E+00, 0.3159377781412633E+00, 0.1196632783263437E+00, 0.8053993759743566E+00, 0.9537751230670044E+00, 0.6890540876884894E+00, 0.7327967809533995E+00, 0.1752177926983489E-01, 0.1176294169286665E+00, 0.1417165464977135E+00, 0.1128117051181837E+00, 0.4431718138373526E+00, 0.6383761487884151E+00, 0.4394388749172047E+00, 0.4496324720961747E+00, 0.2336818223819791E+00, 0.8283237197456694E+00, 0.5968446077081969E+00, 0.2123688346867825E-03, 0.2316409292069651E+00, 0.4041203764036865E+00, 0.5989557684304492E-01, 0.1751475090786662E+00, 0.3300532749209990E+00, 0.5257653351639615E+00, 0.9423173850128755E+00, 0.5110067889308013E+00}, + n: 21, + zOut: []float64{0.2298367449128524E+01, 0.2183508003369306E+01, 0.1768578955898148E+01, 0.1497740650820804E+01, 0.1451044171656134E+01, 0.1248562072819587E+01, 0.1096241131844911E+01, 0.1047761158237631E+01, 0.1036921434023463E+01, 0.1001878203872264E+01, 0.6028997776208512E+00, 0.5966927468392602E+00, 0.3787547972649039E+00, 0.3164597916816877E+00, 0.2770907680746649E+00, 0.1378928396715414E+00, 0.1008983167754413E+00, 0.7523836829300481E-01, 0.4549396861483578E-01, 0.2905908538794771E-01, 0.1164397397714791E-04, 0.2593449025859535E-11, 0.4028878361793870E-19, 0.4523833078775027E-19, 0.1096241131844911E+01, 0.2254118867995285E-20, 0.6781252758190456E-19, 0.6132859990189332E-19, 0.1047761158237631E+01, 0.2208810534618833E-28, 0.7941399228881527E-19, 0.8755467647203911E-19, 0.1036921434023463E+01, 0.2697904295855860E-27, 0.1193508568348155E-18, 0.1375302458176128E-18, 0.1001878203872264E+01, 0.1808754486438286E-19, 0.1585460437287443E-17, 0.7110442921296878E-18, 0.6028997776208512E+00, 0.1121217470921487E-23, 0.1719109533586889E+02, 0.1719109533586889E+02, 0.1020000000000000E+03, 0.3002267573696145E+01, 0.7843137254901960E+01, 0.6126841018734423E-14, 0.3787547972649039E+00, 0.2514494135391975E-29, 0.3694268515215640E-12, 0.2142184401680204E-12, 0.3164597916816877E+00, 0.2495880173472380E-22, 0.1052194788283320E-11, 0.1801542652052392E-11, 0.2770907680746649E+00, 0.2042405059827892E-23, 0.3416315088185822E-10, 0.1784450556067769E-10, 0.1378928396715414E+00, 0.2231720057459842E-17, 0.5936850868223322E-09, 0.2792901329469146E-09, 0.1008983167754413E+00, 0.4009937753419447E-25, 0.1438568455567306E-07, 0.6376284135652434E-08, 0.7523836829300481E-01, 0.1673899732006569E-23, 0.3811420638095229E-06, 0.1677978014843256E-06, 0.4549396861483578E-01, 0.4108428387966160E-20, 0.9969899927958168E-05, 0.2238705130236833E-04, 0.2905908538794771E-01, 0.5621738354967019E-25, 0.1622697124847995E-03, 0.1340889241809050E-03, 0.1164397397714791E-04, 0.4733165431326071E-29, 0.2205086015306072E-02, 0.1109731617446849E-02}, + info: 0, + }, + { + z: []float64{0.9566341326420642E+00, 0.1368890791339401E+00, 0.1041033686995702E+00, 0.1843288381431366E+00, 0.9983016155690853E+00, 0.1786866722264480E+00, 0.3401743522788719E+00, 0.3857333052582377E+00, 0.5001620282112933E+00, 0.9013417473823726E+00, 0.9483009872337210E+00, 0.8066933876879568E+00, 0.5299205541713562E+00, 0.1746250429119467E-01, 0.9676426134678857E+00, 0.9451210738656991E+00, 0.4964770237154315E+00, 0.7837324008636358E+00, 0.9355959680316486E+00, 0.6160646886859618E+00, 0.3400424465599898E+00, 0.5332164761252830E+00, 0.3086260018745091E+00, 0.7161810741898500E+00, 0.9586563909920308E+00, 0.5072089025298385E+00, 0.5345428289191819E+00, 0.3564033548208417E+00, 0.5073508962435702E-01, 0.5457190349920044E+00, 0.5924351087865416E+00, 0.4551284321479383E+00, 0.1212070325395470E+00, 0.4136992969230449E+00, 0.9668715153070689E+00, 0.5158905905227948E+00, 0.3815356588296225E+00, 0.9643666102790432E+00, 0.2243124357596349E-01, 0.1865949320717719E+00, 0.7081123336136068E+00, 0.8847286955309422E+00, 0.8075237017566694E+00, 0.7058935338718864E+00, 0.8930194548226011E-01, 0.5968683124630468E+00, 0.6423123320238798E+00, 0.4264046421741549E+00, 0.6535060636263267E+00, 0.8848885990305457E+00, 0.1727496532173951E+00, 0.2233116713730792E+00, 0.5179656160482806E+00, 0.8833427955005373E+00, 0.5463392573098168E+00, 0.2339495215057854E+00, 0.2531599269911875E+00, 0.8693933445310196E+00, 0.9904673923253784E+00, 0.5001765262594373E+00, 0.8475066901059425E+00, 0.7747140538451288E+00, 0.8097617518836179E+00, 0.6177833422496881E+00, 0.4294196301939426E+00, 0.8754149021622922E+00, 0.1154777972031917E+00, 0.4002319777705416E+00, 0.8948519482752643E+00, 0.2680092666078437E-01, 0.4982362166797213E+00, 0.8946688039099321E+00, 0.6004540842339657E+00, 0.7864972660235388E+00, 0.5343742612900907E+00, 0.6804570163829448E+00, 0.8534533212497195E+00, 0.6588190749186591E+00, 0.3987256626502571E+00, 0.9641448737959348E+00, 0.8049200655531427E+00, 0.8429466638354991E+00, 0.3173537092974966E+00, 0.2969758130071765E+00}, + n: 21, + zOut: []float64{0.2691092090580979E+01, 0.2651656165852700E+01, 0.2273892452779949E+01, 0.2046491657483657E+01, 0.1856589708219707E+01, 0.1474606896148613E+01, 0.1449970763396692E+01, 0.1157826920722246E+01, 0.1131422765724169E+01, 0.1103316690199991E+01, 0.1081571209422854E+01, 0.8863514547656711E+00, 0.7487688552248520E+00, 0.4946957959671176E+00, 0.3261665336572834E+00, 0.2704116388140369E+00, 0.1035778920187539E+00, 0.8274904671505576E-01, 0.4712842456001845E-01, 0.3463118683574901E-01, 0.5254769424391846E-04, 0.2373014771939845E-22, 0.2238209824420786E-09, 0.1516830937674482E-09, 0.1449970763396692E+01, 0.6496080927593321E-18, 0.4705401432274776E-09, 0.6877602609145650E-09, 0.1157826920722246E+01, 0.9485735114056482E-11, 0.6765447972194981E-08, 0.9075269590011981E-08, 0.1131422765724169E+01, 0.0000000000000000E+00, 0.2115471642425146E-07, 0.1586124232313620E-07, 0.1103316690199991E+01, 0.1685550134725853E-21, 0.9651672077875321E-13, 0.7184159896265294E-12, 0.1081571209422854E+01, 0.5505416081326749E-23, 0.2191297069678434E+02, 0.2191297069678434E+02, 0.1080000000000000E+03, 0.3308390022675737E+01, 0.4629629629629630E+01, 0.3615019372146533E-05, 0.7487688552248520E+00, 0.2711157159063573E-25, 0.1185348717221526E-04, 0.1538970705040117E-04, 0.4946957959671176E+00, 0.7711572887860419E-23, 0.5228762878644057E-04, 0.2140066476035995E-04, 0.3261665336572834E+00, 0.1027012207743053E-16, 0.1058102716324823E-03, 0.1097923206605328E-03, 0.2704116388140369E+00, 0.1419949629397821E-27, 0.3075139383959133E-03, 0.2041016121130936E-03, 0.1035778920187539E+00, 0.1569288801032274E-18, 0.2245437021601444E-03, 0.2161294383881767E-03, 0.8274904671505576E-01, 0.1322963914266329E-22, 0.4098429023844965E-03, 0.2685224923308173E-03, 0.4712842456001845E-01, 0.1972152263052530E-27, 0.1445743106447529E-03, 0.3591079434142046E-04, 0.3463118683574901E-01, 0.1109335647967048E-30, 0.1752604588321185E-04, 0.1168961103966469E-04, 0.5254769424391846E-04, 0.0000000000000000E+00, 0.7596773881065606E-02, 0.6101958366533248E-02}, + info: 0, + }, + { + z: []float64{0.8353120998595153E+00, 0.2762691216596785E+00, 0.4005263075088337E+00, 0.2013066591993183E+00, 0.7159087664363259E+00, 0.6826958051178053E+00, 0.3940626911632166E+00, 0.4990834556070268E+00, 0.6760530863202496E-02, 0.5490926358579395E-01, 0.1673564807759778E+00, 0.6884305772394704E+00, 0.3902830106720901E+00, 0.9394502319309270E+00, 0.1453732258871473E+00, 0.6913382271536774E+00, 0.4797608951630542E+00, 0.8813081041297155E+00, 0.7179153476502249E+00, 0.8684015860527726E+00, 0.4912919359735076E+00, 0.2734537604788182E+00, 0.6687443482830383E+00, 0.1554406884207427E+00, 0.2919860915775756E+00, 0.2642733542167044E+00, 0.8429147529046822E+00, 0.2888320698097314E+00, 0.8826173246454528E+00, 0.8977386905269689E+00, 0.7688524109189127E+00, 0.9833521147086286E+00, 0.9216258197795713E-01, 0.4886212819310254E-01, 0.2266462269156035E+00, 0.3411440109054314E+00, 0.3008601997419669E-01, 0.6174499545648404E+00, 0.5004878789063633E+00, 0.6820549240543587E+00, 0.2697209119346977E-01, 0.5561910637447186E+00, 0.5496066776611622E+00, 0.5185759009159874E+00, 0.1533641991284778E+00, 0.9896294286837857E+00, 0.3752499036369343E+00, 0.6748924776803822E-01, 0.2328081038279309E+00, 0.6721552304404512E+00, 0.5472950056303504E+00, 0.9949773164461492E+00, 0.5646629720515278E+00, 0.4280389734679516E+00, 0.4488723317267336E+00, 0.7263390986042261E+00, 0.2371171913738990E-01, 0.2980895305269504E-01, 0.2561842200752050E+00, 0.2554059142478259E+00, 0.5952758446711104E-01, 0.7921877816291150E+00, 0.2045719212105177E+00, 0.9215889426626128E+00, 0.7130733301970400E+00, 0.1420514661017834E+00, 0.8292002693849506E+00, 0.5327095640926792E+00, 0.9857821333545339E+00, 0.6686900428841760E+00, 0.1963263366455671E+00, 0.2881353528210300E+00, 0.7077457532403378E+00, 0.9075905470440924E+00, 0.1600253949359417E+00, 0.1037543259304946E+00, 0.3343707004174388E+00, 0.7287034220491817E-01, 0.8402900560224008E+00, 0.1343632243665364E+00, 0.8746515522185468E+00, 0.4102434537961821E+00, 0.1922774302984470E+00, 0.7386986269659255E+00}, + n: 21, + zOut: []float64{0.2705701250380865E+01, 0.2517516394575531E+01, 0.1823532784589120E+01, 0.1787562059778101E+01, 0.1543666662169401E+01, 0.1517718677289282E+01, 0.1380407836894782E+01, 0.1248997815711926E+01, 0.1005808190406691E+01, 0.8278526045363968E+00, 0.6708485238929687E+00, 0.6082664705845506E+00, 0.5949155529076431E+00, 0.3419285270749396E+00, 0.2930861537880754E+00, 0.2677590880174420E+00, 0.1897681878114907E+00, 0.4498262444281959E-01, 0.4027859329477797E-01, 0.1212960387301111E-02, 0.4788271754899720E-05, 0.2113479533223326E-17, 0.1072835726919963E-07, 0.2769573896400322E-08, 0.1380407836894782E+01, 0.2075077381359190E-19, 0.2509615479685493E-12, 0.8472237738633739E-13, 0.1248997815711926E+01, 0.8862433277732312E-18, 0.5565142852935547E-10, 0.1115246324111066E-09, 0.1005808190406691E+01, 0.1508363342119467E-20, 0.4766364300104371E-06, 0.1686414207934524E-06, 0.8278526045363968E+00, 0.2958228394578794E-30, 0.1339811587116281E-04, 0.9618739022097639E-05, 0.6708485238929687E+00, 0.5096041447727736E-27, 0.1941181574680586E+02, 0.1941181574680586E+02, 0.1100000000000000E+03, 0.3301587301587301E+01, 0.6363636363636363E+01, 0.2769598741382734E-05, 0.5949155529076431E+00, 0.1660823573641619E-23, 0.5008194680845295E-05, 0.3644576454263968E-05, 0.3419285270749396E+00, 0.8597611808520244E-19, 0.8197192371775147E-05, 0.1495511835801176E-04, 0.2930861537880754E+00, 0.6452008777913547E-22, 0.7613853051650506E-05, 0.9176969716117157E-05, 0.2677590880174420E+00, 0.1626694295438144E-23, 0.2172962611604878E-06, 0.9910144268854854E-06, 0.1897681878114907E+00, 0.5698278443334010E-17, 0.3051734820342141E-03, 0.3112883552318466E-03, 0.4498262444281959E-01, 0.6022708464481807E-24, 0.1205042765713422E-04, 0.1759326252954196E-04, 0.4027859329477797E-01, 0.1150776253123047E-20, 0.1426316484726719E-04, 0.9508927802446297E-05, 0.1212960387301111E-02, 0.3136662420452545E-23, 0.9384394253406367E-03, 0.4268700521479601E-03, 0.4788271754899720E-05, 0.0000000000000000E+00, 0.1227549320701017E-01, 0.5132215250850077E-02}, + info: 0, + }, + { + z: []float64{0.6118263281058917E+00, 0.9095172470423057E+00, 0.3600259528878788E+00, 0.2816648927398081E+00, 0.1399164597780194E+00, 0.8570391268113827E+00, 0.6056165732881742E+00, 0.8852338629006543E+00, 0.5421670517489531E+00, 0.6780884449288360E+00, 0.8758212925230515E+00, 0.8288674605669587E+00, 0.6440226363310471E+00, 0.5894956271378661E+00, 0.5783475018163303E+00, 0.3156005123186516E+00, 0.8703974350876685E+00, 0.2617715240366199E+00, 0.8370578409687427E+00, 0.5560169751702698E+00, 0.7455275952513329E-01, 0.7082615127868872E+00, 0.1297707357428401E-02, 0.3064709066297203E+00, 0.8391571848933236E+00, 0.9253805128965463E+00, 0.1130984054668048E+00, 0.8319072101853607E+00, 0.7799276064931965E+00, 0.8579163369971375E+00, 0.5543120979067712E+00, 0.1549966158329672E+00, 0.2643029344048516E+00, 0.8314141615883028E+00, 0.5782452249644381E+00, 0.6319732449892587E+00, 0.4892864093075822E+00, 0.1584418066385224E+00, 0.1120577745932696E+00, 0.6617954786615949E+00, 0.1159882395495345E+00, 0.2876505945591634E+00, 0.7061058070010036E+00, 0.7252986915993946E+00, 0.6775944839786487E+00, 0.7230010551819884E+00, 0.6571938557215073E+00, 0.7482251296401533E+00, 0.9684494841571512E-01, 0.1940071502680237E+00, 0.8896785746779762E+00, 0.9170179284973872E+00, 0.8053995841969270E+00, 0.9321965525342302E+00, 0.7288973738137661E-01, 0.3849028957514653E+00, 0.4410947536600551E+00, 0.4770808300783691E-01, 0.3690162722923055E+00, 0.1908498348358704E+00, 0.8094133574022262E+00, 0.4809437445509840E+00, 0.1405808283203624E+00, 0.4482801388864215E+00, 0.7023724161235537E+00, 0.5041894616412674E+00, 0.2984594028552712E+00, 0.8510121345026274E+00, 0.7612412832182369E-01, 0.8890771840141870E+00, 0.8611357776125709E+00, 0.7702458212424681E+00, 0.8813091992976040E+00, 0.3838156614335277E+00, 0.1536911508311884E+00, 0.2763378258408019E+00, 0.7613349010649187E+00, 0.4228084592762277E+00, 0.5894002697827440E+00, 0.5744691724607953E-01, 0.3014767112059925E+00, 0.7221203248495245E-01, 0.7619553096876313E+00, 0.5154237548276358E+00}, + n: 21, + zOut: []float64{0.2723457737035386E+01, 0.2426437846006860E+01, 0.2169822787916940E+01, 0.1997417054976096E+01, 0.1928996526776896E+01, 0.1891356815602834E+01, 0.1803418741268920E+01, 0.1442378108645599E+01, 0.1026854281138765E+01, 0.9766368850685674E+00, 0.8449303421617025E+00, 0.7575761304896602E+00, 0.7013909577306906E+00, 0.6362631409338654E+00, 0.3605885444762012E+00, 0.1912852882240109E+00, 0.1837209447646653E+00, 0.1221129878112117E+00, 0.2486838916706533E-01, 0.9765050532318768E-02, 0.3171294864219318E-06, 0.1371236688474761E-19, 0.2987011438498780E-15, 0.8087574764480620E-15, 0.1803418741268920E+01, 0.5451390847569379E-21, 0.7270236634641202E-11, 0.2896404140496822E-11, 0.1442378108645599E+01, 0.6954964380428437E-14, 0.4131395561099005E-08, 0.7275670618661885E-08, 0.1026854281138765E+01, 0.1292469707114106E-25, 0.1838064307199299E-06, 0.1238204560933622E-06, 0.9766368850685674E+00, 0.3388131789017201E-20, 0.3880169268725981E-06, 0.5681289313967714E-06, 0.8449303421617025E+00, 0.6785686819474261E-17, 0.2221927887785774E+02, 0.2221927887785774E+02, 0.1080000000000000E+03, 0.3244897959183673E+01, 0.4629629629629630E+01, 0.3025393053677348E-08, 0.7013909577306906E+00, 0.1341063538875720E-28, 0.3767849368753714E-07, 0.3184959175038880E-07, 0.6362631409338654E+00, 0.8874685183736383E-29, 0.5999352088776256E-07, 0.7114794232343430E-07, 0.3605885444762012E+00, 0.1582265649256097E-24, 0.2391907791779699E-03, 0.3344095791507466E-03, 0.1912852882240109E+00, 0.1130832107634320E-25, 0.4040482702647743E-03, 0.3567248396804949E-03, 0.1837209447646653E+00, 0.4930380657631324E-31, 0.1016317982961682E-02, 0.8970313840717793E-03, 0.1221129878112117E+00, 0.2076836816009399E-16, 0.1892596629513954E-02, 0.2329446640559320E-02, 0.2486838916706533E-01, 0.1713835026472478E-23, 0.3568672048225553E-04, 0.1599561599209249E-03, 0.9765050532318768E-02, 0.0000000000000000E+00, 0.3650779499194616E-03, 0.5712243726145556E-03, 0.3171294864219318E-06, 0.8599783076848839E-19, 0.2181668718924628E-02, 0.9598847336904798E-03}, + info: 0, + }, + { + z: []float64{0.1133237741366075E+00, 0.6519297783748091E+00, 0.1419059404596466E+00, 0.6942573823108688E+00, 0.4899507169502382E-03, 0.4408585439270172E+00, 0.4089484333544855E+00, 0.8087151633238087E+00, 0.7299241994604067E-01, 0.7772039339909241E+00, 0.6160100823712519E+00, 0.1679565169487562E+00, 0.3276744683398485E+00, 0.8481565553508272E+00, 0.5614085421003249E+00, 0.5889702994117808E+00, 0.9865181317193454E+00, 0.5686958983255483E+00, 0.2173616127956169E+00, 0.6617740807852496E+00, 0.1324295788322836E+00, 0.5932751564887147E+00, 0.4417023572495267E+00, 0.8308006832392040E+00, 0.6963900525231828E+00, 0.7023649910778577E+00, 0.2540087053190563E+00, 0.5116605124111596E+00, 0.4580501208371790E+00, 0.9900881058795367E+00, 0.6233054379975522E+00, 0.5093215893644945E+00, 0.8805051397371310E+00, 0.5918749676473295E+00, 0.8024628157090720E+00, 0.1089848141144264E+00, 0.9385822032209372E+00, 0.9676954608704463E+00, 0.7567544231269694E+00, 0.7763472508927070E+00, 0.7544500156824916E+00, 0.7080578938468585E-02, 0.8622695184492650E+00, 0.1268681530179145E+00, 0.2408963669487220E+00, 0.1909503620360825E+00, 0.9251648557888137E-01, 0.4447315055648083E+00, 0.1504005134322962E+00, 0.6245252202415555E+00, 0.8432800589533600E+00, 0.1408178180805120E+00, 0.8538656063298837E+00, 0.6959250082173740E-01, 0.7452290984944354E-01, 0.8186895700534982E+00, 0.4817344889163616E+00, 0.8941802149688474E+00, 0.8277272846279742E+00, 0.3122760515919010E+00, 0.4631046821883726E+00, 0.9939521405533804E+00, 0.5067334594578294E+00, 0.3251044449945518E+00, 0.4514296322650755E+00, 0.9520015267726308E+00, 0.3811787795610073E+00, 0.6466473208499942E+00, 0.1035647165455822E-01, 0.3768739780085785E+00, 0.7301131130949717E+00, 0.6341150979687762E+00, 0.2006486990564113E+00, 0.7995641372737874E+00, 0.3501522989293299E+00, 0.7212117404145123E+00, 0.3724384783514179E+00, 0.2704745802524587E+00, 0.5954948132025037E+00, 0.8796174543237598E+00, 0.2533217117523398E+00, 0.2406431629179949E+00, 0.4238947154458014E+00, 0.1002294321190256E+00}, + n: 21, + zOut: []float64{0.2763722715135843E+01, 0.2473753815483350E+01, 0.2367461218794171E+01, 0.2245079256722998E+01, 0.1833576927640889E+01, 0.1670289128561736E+01, 0.1457654822263786E+01, 0.1350493275779479E+01, 0.1277854548609735E+01, 0.1156481310792204E+01, 0.1106963375568883E+01, 0.8704957369830484E+00, 0.6845380809859644E+00, 0.4950109522946930E+00, 0.4198272059610658E+00, 0.2867476262636770E+00, 0.2180239597616727E+00, 0.1578141753335409E+00, 0.1153511714179556E+00, 0.2506658150747594E-01, 0.5048803894682267E-08, 0.8470329472540474E-20, 0.3080709680328647E-07, 0.2263725078605666E-07, 0.1457654822263786E+01, 0.6882142696441190E-21, 0.4511645736903135E-07, 0.5799182381327367E-07, 0.1350493275779479E+01, 0.3225542408567476E-17, 0.3673248914261325E-08, 0.2431637013515395E-08, 0.1277854548609735E+01, 0.1479114197289397E-30, 0.1457855695816495E-07, 0.1029378003116242E-07, 0.1156481310792204E+01, 0.9441087313685069E-24, 0.4178859307872738E-07, 0.3166226192774972E-07, 0.1106963375568883E+01, 0.1745440919131533E-19, 0.2297620589091097E+02, 0.2297620589091097E+02, 0.9600000000000000E+02, 0.3092970521541950E+01, 0.3125000000000000E+01, 0.2193086683474567E-06, 0.6845380809859644E+00, 0.6815668447404457E-13, 0.1173742870849872E-05, 0.2415236474615244E-05, 0.4950109522946930E+00, 0.4604423331594002E-25, 0.1089056660110428E-04, 0.1249035785040860E-04, 0.4198272059610658E+00, 0.2034864306780130E-21, 0.1807219455044531E-04, 0.1582973453084106E-04, 0.2867476262636770E+00, 0.1157544870450433E-16, 0.1788428346885188E-06, 0.1048647571833164E-05, 0.2180239597616727E+00, 0.2820966597070338E-26, 0.2675556367648033E-04, 0.1965631735302374E-04, 0.1578141753335409E+00, 0.4632909363938796E-19, 0.6657143729168815E-04, 0.2311126907684945E-04, 0.1153511714179556E+00, 0.7089566920435294E-17, 0.2519028315687161E-03, 0.1126597449160621E-03, 0.2506658150747594E-01, 0.1511791266627385E-18, 0.1819059120658101E-02, 0.1223404988252185E-02, 0.5048803894682267E-08, 0.5048803894682267E-08, 0.1176483960189416E-01, 0.7561758166988619E-02}, + info: 0, + }, + { + z: []float64{0.6007483099411913E+00, 0.8757604992442719E+00, 0.3498665716095440E+00, 0.4974125174432915E+00, 0.3942177430818359E+00, 0.4655097178512825E+00, 0.7062255099400584E+00, 0.5955461614709365E+00, 0.5705117921786074E+00, 0.2580859610386106E+00, 0.5213970441770472E+00, 0.3227485215512098E+00, 0.8200431655548257E-01, 0.9521784777464899E+00, 0.9768302381970198E+00, 0.5401259459761943E+00, 0.2876249345369413E+00, 0.9928912621382637E+00, 0.9068004769556834E+00, 0.8136746797372185E+00, 0.6557906174128045E+00, 0.7593059043472016E+00, 0.7306718357524993E+00, 0.7872142480398446E+00, 0.2169453387448870E+00, 0.1236189910537125E+00, 0.4376414329540577E+00, 0.2475974410903709E+00, 0.5743712937757064E+00, 0.8451940172770922E+00, 0.2954362279165403E+00, 0.9333330371592371E+00, 0.7261884685452219E+00, 0.2905925760133674E+00, 0.3022535752338255E+00, 0.6907049310391071E+00, 0.2616870809800952E+00, 0.3758121789769751E+00, 0.7112612645989228E+00, 0.9602233026485287E+00, 0.7212734445945013E+00, 0.9266335266312882E+00, 0.7829804394259932E-01, 0.6683939253194693E+00, 0.3539007443404153E+00, 0.1629995906155713E+00, 0.2470024645126471E+00, 0.7250237828800384E+00, 0.9725422312806663E+00, 0.1983270881451602E+00, 0.2167236969811593E+00, 0.2406674239058443E+00, 0.3811046126380717E+00, 0.6358718370494476E-01, 0.6038903598347725E+00, 0.2622945348536884E+00, 0.4871669697876424E+00, 0.1853788955105938E+00, 0.3471794920367192E+00, 0.9520318129455714E+00, 0.9596274379126818E+00, 0.5893179749928269E+00, 0.8560240909608330E-01, 0.9435308110759013E+00, 0.2058424446004554E+00, 0.2877465111691004E+00, 0.6254635389850627E+00, 0.5518846905281638E-01, 0.1132608874973561E+00, 0.8191427866511807E+00, 0.1031178242713734E+00, 0.1909407653284053E+00, 0.5428362177906626E+00, 0.2973328401307228E+00, 0.6079142025065691E+00, 0.1448090006401505E+00, 0.5807148716343321E+00, 0.2207276122221573E+00, 0.4617526470734991E+00, 0.2133930631010816E-01, 0.8719991154365724E+00, 0.4224743304865443E+00, 0.7012315055540164E+00, 0.9970966526798359E+00}, + n: 21, + zOut: []float64{0.2875734378878489E+01, 0.2344615299508293E+01, 0.2292398069608056E+01, 0.2200897502376554E+01, 0.2016889876654445E+01, 0.1997885510503641E+01, 0.1786196162676624E+01, 0.1505330793574375E+01, 0.1193246823746953E+01, 0.1153847743209180E+01, 0.9864509519829328E+00, 0.8076407462080507E+00, 0.6427729668463894E+00, 0.4808392927305387E+00, 0.3994667257867982E+00, 0.3273321022655395E+00, 0.1654363687174887E+00, 0.1176242694536732E+00, 0.4639514928819789E-01, 0.1592499252046327E-01, 0.3521629889976334E-03, 0.1784216669875992E-16, 0.7121431862167897E-10, 0.2812798494121821E-10, 0.1786196162676624E+01, 0.4108568523994154E-17, 0.4438281217193102E-07, 0.2274689950145052E-07, 0.1505330793574375E+01, 0.7499168293791558E-11, 0.5226296435976747E-05, 0.8641809444662033E-05, 0.1193246823746953E+01, 0.0000000000000000E+00, 0.2628223783350490E-04, 0.3987870710471355E-04, 0.1153847743209180E+01, 0.5865702946789929E-16, 0.1241308452869419E-07, 0.3894882997253744E-08, 0.9864509519829328E+00, 0.7673863643253590E-18, 0.2335727788952568E+02, 0.2335727788952568E+02, 0.1040000000000000E+03, 0.3058956916099773E+01, 0.2884615384615385E+01, 0.3948721236408985E-04, 0.6427729668463894E+00, 0.1028674620408199E-26, 0.2391232675375281E-03, 0.2086678697444007E-03, 0.4808392927305387E+00, 0.3130051437900657E-19, 0.1426864276581422E-03, 0.1522473256880454E-03, 0.3994667257867982E+00, 0.2101777886998446E-24, 0.1526280399103512E-05, 0.7002070790936748E-06, 0.3273321022655395E+00, 0.1242239255406691E-15, 0.1253374424171423E-04, 0.2848254240665514E-04, 0.1654363687174887E+00, 0.2455402723507254E-17, 0.1659752591164777E-02, 0.8476830847116842E-03, 0.1176242694536732E+00, 0.1344218982496604E-26, 0.1195138829435961E-02, 0.1583065192028977E-02, 0.4639514928819789E-01, 0.2205655090997949E-26, 0.2795062437264197E-03, 0.9604240981222648E-03, 0.1592499252046327E-01, 0.6574583373762050E-21, 0.7008887495297913E-02, 0.4078689360266482E-02, 0.3521629889976334E-03, 0.2981894221735425E-26, 0.7785429009218255E-02, 0.8697865294154498E-02}, + info: 0, + }, + { + z: []float64{0.3565428176835072E+00, 0.1947118362244993E+00, 0.7741156920152520E+00, 0.2422304602782238E+00, 0.6344560478781652E+00, 0.6454994272905118E+00, 0.1782236022643452E+00, 0.1761708296759242E+00, 0.4902923959906477E+00, 0.3501715044277058E+00, 0.8606282659620700E+00, 0.4671519599404039E-03, 0.9177061631942818E+00, 0.9869535184930249E+00, 0.9615604930014852E+00, 0.2283553018405985E+00, 0.2470322441623238E+00, 0.5789642646481346E+00, 0.9797717987449011E+00, 0.2628090453859127E+00, 0.1063995753795172E+00, 0.9446865880365994E+00, 0.8109285339456792E+00, 0.4534650679402863E-01, 0.9560542860825706E+00, 0.7338084401822241E+00, 0.4719995459594307E+00, 0.8981162685661518E+00, 0.6088366551058919E+00, 0.4061662134958367E+00, 0.6141507801286759E+00, 0.7683300427463863E+00, 0.2030033710532269E+00, 0.5109903203799075E+00, 0.1295039929316932E-01, 0.1313823831505738E+00, 0.4600541675974348E+00, 0.8052912479215125E+00, 0.7315674921483241E+00, 0.1311059905375703E+00, 0.9372521946935908E-01, 0.2804058432106148E+00, 0.1426401168120447E+00, 0.1302494454623315E-01, 0.9936953989155247E+00, 0.7109841901452127E+00, 0.8438933393801377E+00, 0.5599779486257196E+00, 0.6224094357036947E-01, 0.3722277721927331E+00, 0.2128496963914419E+00, 0.2132595627624145E+00, 0.1761474673379855E+00, 0.5003566260610350E+00, 0.5448249098276142E+00, 0.5701738373290982E+00, 0.5196161461339291E+00, 0.4684002904633344E-01, 0.3091316721875115E+00, 0.9311143262655500E+00, 0.5165589926587729E+00, 0.4230658512580241E+00, 0.1580095970610971E+00, 0.9213403630754643E+00, 0.8395102804227733E+00, 0.6279936637330286E-01, 0.2118369865058433E+00, 0.5654902136914255E+00, 0.8603345552081203E+00, 0.6355651085391135E+00, 0.9504788095745560E+00, 0.4928822316317183E+00, 0.8546738890428598E+00, 0.1506739079739667E+00, 0.7955004699434830E+00, 0.8623803468730415E+00, 0.3328976137523824E+00, 0.6282681071703561E+00, 0.5253150183233042E+00, 0.5508861108006231E+00, 0.8482246434328706E+00, 0.3438184421622726E+00, 0.4546750663905129E+00, 0.2702842147468514E+00}, + n: 21, + zOut: []float64{0.2599043716461175E+01, 0.2392272222815941E+01, 0.1945154273268249E+01, 0.1882117601080557E+01, 0.1808214125087810E+01, 0.1701027479657859E+01, 0.1674631474676720E+01, 0.1432830957842129E+01, 0.1245386641860508E+01, 0.1003047986420639E+01, 0.5925499318269597E+00, 0.5737323778075372E+00, 0.4619197085153934E+00, 0.3795861721644865E+00, 0.2896752472940557E+00, 0.2024598813435771E+00, 0.1753335138277014E+00, 0.8865983947068434E-01, 0.4088280438555415E-01, 0.2271023207656241E-01, 0.3207012114254504E-03, 0.1328658858913301E-22, 0.6931093261583948E-12, 0.1962539051213948E-11, 0.1674631474676720E+01, 0.1972152263052530E-30, 0.1003060686577864E-09, 0.7786971971568132E-10, 0.1432830957842129E+01, 0.3552283923653146E-20, 0.1335875663368593E-08, 0.1098996752778210E-08, 0.1245386641860508E+01, 0.6078417508770261E-16, 0.6005521677860925E-08, 0.4565873133117504E-08, 0.1003047986420639E+01, 0.4907378230941548E-20, 0.6042756667162823E-07, 0.1337733817342293E-06, 0.5925499318269597E+00, 0.7849166006949067E-28, 0.2051155688909552E+02, 0.2051155688909552E+02, 0.1190000000000000E+03, 0.3632653061224490E+01, 0.6722689075630252E+01, 0.9823469248695270E-04, 0.4619197085153934E+00, 0.3582825487703231E-19, 0.4408755124729528E-13, 0.6425665938157879E-14, 0.3795861721644865E+00, 0.3049769924381334E-19, 0.2649002399507504E-08, 0.1284693180187630E-07, 0.2896752472940557E+00, 0.2730342256278547E-24, 0.3857186710932351E-04, 0.7729247272182434E-05, 0.2024598813435771E+00, 0.2411244474478362E-13, 0.9974443273860175E-04, 0.7715885583051736E-04, 0.1753335138277014E+00, 0.1003583340528496E-19, 0.1275804036051463E-05, 0.1384195629265487E-05, 0.8865983947068434E-01, 0.1976477763343393E-17, 0.9250271469637329E-05, 0.1838436200742544E-04, 0.4088280438555415E-01, 0.1570480975080192E-18, 0.1665813744256122E-03, 0.9368787794988337E-04, 0.2271023207656241E-01, 0.1120555887990158E-19, 0.1174000031728850E-02, 0.1217958466428532E-03, 0.3207012114254504E-03, 0.0000000000000000E+00, 0.1126152474028795E-01, 0.4219515300090987E-02}, + info: 0, + }, + { + z: []float64{0.1431540885741494E+00, 0.8417471667062104E+00, 0.3721480902981644E-01, 0.9023772086815021E+00, 0.7374866167630612E-01, 0.8092071841305744E+00, 0.8019394206305236E+00, 0.4350675566733520E+00, 0.8704440278245326E+00, 0.8549104680538234E+00, 0.1422025173760633E+00, 0.8968456705882693E+00, 0.1647179447265090E-01, 0.8994077105608889E-01, 0.8596481603583839E-02, 0.3900328616396558E+00, 0.4012630844305533E+00, 0.8262908556770313E+00, 0.9026062467432411E+00, 0.6485345137550630E+00, 0.5598932241080331E+00, 0.6084992568220661E+00, 0.5039450314115669E+00, 0.3490854750626526E+00, 0.9921372250281116E+00, 0.1522469068827847E-01, 0.9395473455386270E+00, 0.3928498832803473E-01, 0.1672951108814763E+00, 0.9480670302336689E+00, 0.8743929741539138E+00, 0.9201765927311700E-01, 0.8641536356563365E+00, 0.8867562289118487E+00, 0.7156446870854873E+00, 0.5025184567500440E-01, 0.4878799838415181E+00, 0.5568327059782646E+00, 0.4596548235310455E+00, 0.6857902774944131E+00, 0.4795565553491499E-01, 0.4752906527216701E+00, 0.9288351773531449E+00, 0.7419018575576386E+00, 0.9987802353476521E+00, 0.8896105755435116E+00, 0.3190450046252536E+00, 0.9685806853440787E+00, 0.3396383774694021E+00, 0.9164401886915974E+00, 0.1269879571285023E+00, 0.7912318128907188E+00, 0.9987805345221650E+00, 0.4107567957671243E+00, 0.4798441760727139E+00, 0.2357309197085595E+00, 0.3404494185276096E+00, 0.7067865773496134E+00, 0.2931542927088892E+00, 0.6654441577727066E+00, 0.9279529535770864E+00, 0.9667208022109988E+00, 0.5518920376663735E+00, 0.1657487215954807E+00, 0.3897636058410684E+00, 0.9489706352102197E+00, 0.9626390247015670E+00, 0.1020775856599213E+00, 0.3545784768064359E+00, 0.3098089336816090E+00, 0.3791089991258285E+00, 0.6519489570740321E+00, 0.4763523952410913E+00, 0.3754524631080590E+00, 0.9792813089520809E+00, 0.1998301915332230E+00, 0.7618060057813935E+00, 0.1923436350325713E+00, 0.2507012719817848E+00, 0.9704520069999245E-01, 0.2277384851702763E+00, 0.7790727508043876E+00, 0.9105177383528497E+00, 0.9714469561729607E+00}, + n: 21, + zOut: []float64{0.2499720115178021E+01, 0.2371028651009860E+01, 0.2298220416774619E+01, 0.1883765650093571E+01, 0.1735426237683963E+01, 0.1616050162695453E+01, 0.1545275083087796E+01, 0.1187762610175739E+01, 0.1136805332133151E+01, 0.9576839460725933E+00, 0.9184986446054146E+00, 0.7702442640767845E+00, 0.6433137908930019E+00, 0.6160049176831036E+00, 0.3208789970551323E+00, 0.1900871628722621E+00, 0.9670499780074775E-01, 0.7460708611062000E-01, 0.6486083888512703E-01, 0.9966295048259487E-02, 0.4462615269650136E-07, 0.2765885173224186E-23, 0.3446029508568731E-11, 0.2660256849760007E-11, 0.1545275083087796E+01, 0.1351675564459578E-15, 0.5238898174323723E-11, 0.6640890994279970E-11, 0.1187762610175739E+01, 0.1020402561847179E-21, 0.5048392892414130E-10, 0.4263729817754413E-10, 0.1136805332133151E+01, 0.1429794613494979E-24, 0.1140378416083416E-09, 0.8548580688939750E-10, 0.9576839460725933E+00, 0.1302866745903472E-12, 0.1207358062805810E-07, 0.1106598026337004E-07, 0.9184986446054146E+00, 0.3538135823224864E-23, 0.2093690524456137E+02, 0.2093690524456137E+02, 0.1130000000000000E+03, 0.3331065759637188E+01, 0.7964601769911504E+01, 0.4249897555997367E-08, 0.6433137908930019E+00, 0.4627357327667341E-16, 0.5702383148705814E-08, 0.8656383665454304E-08, 0.6160049176831036E+00, 0.0000000000000000E+00, 0.4551987331271016E-07, 0.8434005257711676E-07, 0.3208789970551323E+00, 0.2939872200043623E-13, 0.4894684795516590E-05, 0.8200734504818474E-05, 0.1900871628722621E+00, 0.9080407486043539E-23, 0.2659953011765320E-05, 0.2713538128245964E-05, 0.9670499780074775E-01, 0.1949336478520425E-16, 0.1287973346598181E-04, 0.3266830247798530E-04, 0.7460708611062000E-01, 0.0000000000000000E+00, 0.5588793940970657E-03, 0.8233963212342685E-03, 0.6486083888512703E-01, 0.1680331387617770E-17, 0.5510428852120968E-02, 0.6166917183278490E-02, 0.9966295048259487E-02, 0.9229672591085838E-28, 0.3019065027713110E-04, 0.7674568090533565E-04, 0.4462615269650136E-07, 0.1609276246650864E-27, 0.6212935138424260E-03, 0.6196304337665942E-02}, + info: 0, + }, + { + z: []float64{0.2117689827794353E+00, 0.3469390325266096E+00, 0.8556157513093896E+00, 0.4757820823688597E-01, 0.8174618541686680E+00, 0.7502623797079592E+00, 0.3473865910309967E+00, 0.1102061280439136E+00, 0.3838366632541155E+00, 0.4335750892772081E+00, 0.8350483733926333E+00, 0.8472841724322083E+00, 0.7001411292294977E+00, 0.1602971622162627E+00, 0.8475208106005836E+00, 0.1606731136869689E+00, 0.1282020202063155E+00, 0.7021142414638628E+00, 0.6509542291315448E+00, 0.3403267711628978E+00, 0.2783715946342622E+00, 0.2391807909006515E+00, 0.9326061845277929E+00, 0.8200594229325990E+00, 0.5326312099842309E+00, 0.4390518762985745E+00, 0.9087332134146432E+00, 0.8586305843825174E+00, 0.5289458618923581E+00, 0.6098713986238019E+00, 0.4124733909450122E+00, 0.2730411694523917E+00, 0.8437528550291284E+00, 0.6776322145297138E+00, 0.6772761566308538E+00, 0.6457716484911746E+00, 0.4290441069454122E+00, 0.9486890113840626E+00, 0.1145429178800543E+00, 0.8512453512490206E+00, 0.6435458910126746E+00, 0.6571563420730420E-01, 0.6473933144723745E+00, 0.2355560081089225E+00, 0.1262112692360912E+00, 0.6892345322103945E+00, 0.9088034154559810E-01, 0.5725023743105110E+00, 0.8924086653580375E+00, 0.6645221244511262E+00, 0.7287357579298158E+00, 0.6462379994906295E+00, 0.8254375000545862E+00, 0.2402799002378904E+00, 0.2312499677892260E+00, 0.7164295349077132E-01, 0.1216505240532725E+00, 0.5279275209153104E+00, 0.2010432640871422E+00, 0.2335833224032272E+00, 0.7053869472451330E+00, 0.1271428628255256E-01, 0.5920854820119847E-01, 0.1973220586788875E+00, 0.9024202349843203E+00, 0.2696040474399301E+00, 0.2399100427530529E+00, 0.4936945945994136E+00, 0.7377918193661529E+00, 0.4454167008139350E+00, 0.6822934143143184E+00, 0.1980205964978332E+00, 0.9382259163150929E+00, 0.7952650736079295E+00, 0.2147267423149601E+00, 0.2160850567828982E+00, 0.2063316967709339E-02, 0.4613555480251579E+00, 0.2983741464914229E+00, 0.7653433710630531E+00, 0.9319255930520460E+00, 0.9624604653562387E+00, 0.7921958309630666E+00, 0.3349247737517954E+00}, + n: 21, + zOut: []float64{0.2554012710728313E+01, 0.2350385283314499E+01, 0.2336543487584985E+01, 0.2078331003959482E+01, 0.1819938506810449E+01, 0.1751888604422140E+01, 0.1642765030717598E+01, 0.1391850148176030E+01, 0.1265614265169072E+01, 0.1192296172100378E+01, 0.1118290194286764E+01, 0.7471001949454404E+00, 0.6602310515087256E+00, 0.5223373748122110E+00, 0.3101567956620342E+00, 0.2634177676934227E+00, 0.1468471914237014E+00, 0.9669691105737251E-01, 0.6862527639473751E-01, 0.2251868425683227E-01, 0.2442899974694956E-02, 0.0000000000000000E+00, 0.3247526756203984E-07, 0.3301672636248404E-07, 0.1642765030717598E+01, 0.2849742554922193E-13, 0.2093860354423170E-09, 0.9504157619668633E-09, 0.1391850148176030E+01, 0.5471978423050590E-17, 0.2765846142955850E-06, 0.3763175370346248E-06, 0.1265614265169072E+01, 0.7099748146989106E-29, 0.8629250150360319E-06, 0.7218261937815504E-06, 0.1192296172100378E+01, 0.0000000000000000E+00, 0.1792585742344500E-05, 0.1391262462240339E-05, 0.1118290194286764E+01, 0.2158808112824856E-22, 0.2234228955499889E+02, 0.2234228955499888E+02, 0.1130000000000000E+03, 0.3253968253968254E+01, 0.7079646017699115E+01, 0.1273852622682608E-03, 0.6602310515087256E+00, 0.1370219837932689E-23, 0.6841106514156665E-04, 0.6915431692027581E-04, 0.5223373748122110E+00, 0.8086955524743426E-16, 0.3151324787101243E-03, 0.4936870820060986E-03, 0.3101567956620342E+00, 0.1690864291947714E-17, 0.5342613094053112E-03, 0.4525307423692253E-03, 0.2634177676934227E+00, 0.1569544193046020E-19, 0.8085628512848309E-03, 0.5320256570924908E-03, 0.1468471914237014E+00, 0.1725633230170963E-30, 0.2171574910172427E-04, 0.7393923467130197E-05, 0.9669691105737251E-01, 0.8185725058097063E-19, 0.6259416979424432E-04, 0.7993629240914341E-04, 0.6862527639473751E-01, 0.1144304443709360E-17, 0.8363460972147480E-05, 0.2145990923718838E-04, 0.2251868425683227E-01, 0.3423656328659191E-26, 0.4258124540743150E-02, 0.4456054742147899E-02, 0.2442899974694956E-02, 0.7553929676107889E-20, 0.1657093833399320E-01, 0.2123214045479585E-01}, + info: 0, + }, + { + z: []float64{0.5143465832338334E-01, 0.9671338481452775E+00, 0.2594126021369855E+00, 0.4887933538896223E+00, 0.4809357095031462E+00, 0.1648852435705869E+00, 0.5382296047886386E+00, 0.2404093745709619E+00, 0.5749849863516346E+00, 0.8755417117410101E+00, 0.6479432781744229E+00, 0.8462387170859478E+00, 0.1030360983310576E+00, 0.2790419505795448E+00, 0.2643216914883461E+00, 0.5072751399665939E+00, 0.9813013168637370E+00, 0.5270325239254721E+00, 0.1341185443667956E+00, 0.1666757001787883E+00, 0.8421762037577841E+00, 0.6333707418037352E+00, 0.9714076539879462E+00, 0.8133030640726957E-01, 0.5961674478430062E+00, 0.9962348063653491E+00, 0.9690228851917282E-02, 0.4933763527820312E-01, 0.1005560439675963E+00, 0.9794838233988775E+00, 0.8412211319105695E+00, 0.4530689238841823E+00, 0.9824397821984348E+00, 0.9435184376619912E+00, 0.5899369853858024E+00, 0.3347062982138894E+00, 0.6634688706474758E+00, 0.7781534216536603E+00, 0.5213269680559092E+00, 0.2415498257414400E+00, 0.4153017903771141E+00, 0.6142268391585892E-01, 0.1582256219487426E+00, 0.5180630943028907E+00, 0.2531248086553088E+00, 0.4588063905612799E+00, 0.9850645955475579E-01, 0.4386688206276981E+00, 0.6723312445641013E+00, 0.2417358982121058E+00, 0.9102202020018957E+00, 0.4790528316718639E+00, 0.8645283277006380E+00, 0.5896385561561974E+00, 0.3547186358320912E+00, 0.2570702739547999E+00, 0.8872414069371877E+00, 0.7977277358714381E+00, 0.2283476919840042E+00, 0.5481349489617042E+00, 0.9565429487676439E+00, 0.3941453871538936E-01, 0.2005355998230810E+00, 0.6815820255993522E+00, 0.8827641753074383E+00, 0.3721138471690448E+00, 0.3473678385941080E+00, 0.5958558861949184E+00, 0.5289126915593071E+00, 0.7848410946975201E+00, 0.9380898148044153E+00, 0.4238368524709774E+00, 0.9095202310640094E-01, 0.5205916750079600E+00, 0.3388678441932766E+00, 0.9218715971576251E+00, 0.2785357832665022E+00, 0.7353529037048490E+00, 0.3430576699659011E+00, 0.1583386336396764E-03, 0.1574217518812531E+00, 0.2808549182652627E+00, 0.9165809855463820E+00, 0.2729923295285186E-01}, + n: 21, + zOut: []float64{0.2740279952468604E+01, 0.2296796691149573E+01, 0.2162929780566866E+01, 0.2022438316208162E+01, 0.1971555203048247E+01, 0.1712998698314224E+01, 0.1596820997274643E+01, 0.1536702996895977E+01, 0.1112897445143912E+01, 0.8259900943746278E+00, 0.7751147071242228E+00, 0.6231241133597348E+00, 0.5263220334234422E+00, 0.4481765711163059E+00, 0.4215577615769598E+00, 0.1440581718410880E+00, 0.1296344814538628E+00, 0.5340807481344281E-01, 0.1871489185523312E-01, 0.3434703213692513E-02, 0.2376961512853157E-03, 0.2255238469879073E-22, 0.1711146112720571E-14, 0.5183409008081618E-15, 0.1596820997274643E+01, 0.0000000000000000E+00, 0.1075504130778587E-11, 0.4005497363076952E-12, 0.1536702996895977E+01, 0.1981618593915182E-26, 0.4700742807330894E-10, 0.1164621641126979E-09, 0.1112897445143912E+01, 0.4726602108594632E-24, 0.9459556816770867E-09, 0.1692486098434743E-08, 0.8259900943746278E+00, 0.0000000000000000E+00, 0.4245107391668450E-08, 0.4612248550244559E-08, 0.7751147071242228E+00, 0.8284213834597216E-21, 0.2112319338137411E+02, 0.2112319338137411E+02, 0.1000000000000000E+03, 0.2931972789115646E+01, 0.2000000000000000E+01, 0.1818678155237499E-07, 0.5263220334234422E+00, 0.4246772729828520E-23, 0.1119198730079850E-06, 0.4602199017952358E-06, 0.4481765711163059E+00, 0.1035379938102578E-29, 0.2940687130487931E-04, 0.4282452030972280E-04, 0.4215577615769598E+00, 0.5276311108751726E-20, 0.8277389737129399E-05, 0.6004055084531256E-05, 0.1440581718410880E+00, 0.0000000000000000E+00, 0.8355340113184283E-05, 0.1023986211128489E-04, 0.1296344814538628E+00, 0.1552281967638183E-19, 0.6343521312985942E-05, 0.6697527987420460E-05, 0.5340807481344281E-01, 0.6040133837432384E-17, 0.1556990792688111E-03, 0.3593183434334682E-03, 0.1871489185523312E-01, 0.1153562559317783E-18, 0.8237486079760113E-03, 0.4973426416094711E-03, 0.3434703213692513E-02, 0.0000000000000000E+00, 0.1008741049678482E-02, 0.1888495698860201E-02, 0.2376961512853157E-03, 0.2773339119917620E-31, 0.6098206042824776E-05, 0.1474144332182451E-03}, + info: 0, + }, + { + z: []float64{0.1099031735712288E+00, 0.5724174842808358E+00, 0.3122550743498126E+00, 0.7231231021981217E+00, 0.6175771623314344E+00, 0.5814310193624382E+00, 0.6423493353686718E+00, 0.8309609356975209E+00, 0.6400193102877816E-01, 0.8728840273137624E+00, 0.8682274216885312E+00, 0.7829529646382269E+00, 0.4658588928084396E+00, 0.4997300418007194E+00, 0.5750522308672811E+00, 0.5282811502940782E+00, 0.7877382060309071E+00, 0.2242905591148447E-01, 0.9672168595892823E+00, 0.9229185948074735E+00, 0.7120977511666169E+00, 0.9513613307832994E+00, 0.6495350224590044E+00, 0.1796094611119584E+00, 0.6238202085518583E+00, 0.4056553414984787E-01, 0.2863733551163383E-01, 0.7740758620163646E-01, 0.1652368945937387E+00, 0.5017774327613052E+00, 0.6445125305703996E+00, 0.5670374114090049E-01, 0.1147723121006077E+00, 0.5126855432858525E+00, 0.9526888308153642E+00, 0.1724272641761350E+00, 0.9682495468226523E+00, 0.2579549866163475E+00, 0.5365442422680400E+00, 0.7055455249537391E+00, 0.6510869341601188E+00, 0.6910931676909811E+00, 0.8245356137796966E+00, 0.2467134555988069E+00, 0.2932965007679977E-01, 0.3174819406165880E+00, 0.1008447548759832E+00, 0.7998426243165985E+00, 0.6780870841109060E+00, 0.2896057920811994E+00, 0.9303619290394473E+00, 0.3607716194531815E+00, 0.5211419140438559E+00, 0.1046120770241560E+00, 0.7683871590101677E+00, 0.2147990043395044E+00, 0.6702055898403114E+00, 0.2446830800671760E+00, 0.1275992810549672E+00, 0.9234458715873217E+00, 0.6974016894347440E+00, 0.2461420250226486E+00, 0.2448954779360711E+00, 0.1956976010946661E+00, 0.8608131397075515E+00, 0.7387865940798233E-01, 0.5053692911917109E+00, 0.3354069180988316E+00, 0.4024076719528004E+00, 0.5167351886997615E+00, 0.7829885112810930E-01, 0.3735275576161866E+00, 0.9546718920527260E+00, 0.5321377922787256E+00, 0.6121034951800618E+00, 0.8028222695558183E+00, 0.3295254582685344E+00, 0.5907471536091985E+00, 0.8247143229089846E+00, 0.1329486496858557E+00, 0.9484305946158008E+00, 0.4510190965747323E+00, 0.1159598040227069E+00, 0.7290524870797256E+00}, + n: 21, + zOut: []float64{0.2759844065448739E+01, 0.2469029941309663E+01, 0.2170232676307031E+01, 0.1960369893365743E+01, 0.1773994559660628E+01, 0.1654180064160601E+01, 0.1454572475268221E+01, 0.1398795476174613E+01, 0.1260788731803824E+01, 0.1011169812035994E+01, 0.9032283997666860E+00, 0.7344998632955592E+00, 0.6915613254033124E+00, 0.3097922830021908E+00, 0.2074097203460417E+00, 0.1750683611049406E+00, 0.1335859329381489E+00, 0.1070304609992355E+00, 0.6466361262660925E-01, 0.1024517112836532E-01, 0.4658519939343828E-03, 0.5916456789157589E-30, 0.2414839775472174E-07, 0.1563475838564645E-07, 0.1454572475268221E+01, 0.5710570490785520E-12, 0.1598956453701674E-05, 0.9938094799470723E-06, 0.1398795476174613E+01, 0.7078291130367095E-25, 0.1301105456376455E-06, 0.7650088290739393E-07, 0.1260788731803824E+01, 0.6660939091008025E-19, 0.3865722666202593E-07, 0.5454440035759107E-07, 0.1011169812035994E+01, 0.5414223942436753E-17, 0.3344051754361652E-04, 0.2635566037358100E-04, 0.9032283997666860E+00, 0.5272968833424410E-16, 0.2125052867814009E+02, 0.2125052867814008E+02, 0.1090000000000000E+03, 0.3179138321995465E+01, 0.2752293577981651E+01, 0.8667028517906969E-06, 0.6915613254033124E+00, 0.6016648435007899E-23, 0.2921486269254270E-05, 0.9773987035049091E-05, 0.3097922830021908E+00, 0.6500213859021137E-26, 0.6786203908623285E-05, 0.1231548092049969E-04, 0.2074097203460417E+00, 0.0000000000000000E+00, 0.7819652657144090E-06, 0.1217347772587842E-05, 0.1750683611049406E+00, 0.6582255393164123E-26, 0.1458540666485106E-06, 0.3789967922095048E-07, 0.1335859329381489E+00, 0.1232595164407831E-31, 0.4615373247666497E-05, 0.3177332815969559E-05, 0.1070304609992355E+00, 0.5947376905467984E-20, 0.9914288367235413E-05, 0.1492808588608919E-04, 0.6466361262660925E-01, 0.5865227530883812E-22, 0.3814164765172745E-05, 0.1095283410948310E-05, 0.1024517112836532E-01, 0.3761300629007363E-24, 0.3159730783704485E-04, 0.5907442037524074E-05, 0.4658519939343828E-03, 0.2094421310984266E-20, 0.1426408794386696E-02, 0.1350744215392459E-02}, + info: 0, + }, + { + z: []float64{0.1337238926382778E+00, 0.3106335653974364E+00, 0.8951406789337562E+00, 0.2282076226383426E+00, 0.3559900270036094E+00, 0.1333708564991680E+00, 0.9225357561814306E+00, 0.6383337981459615E+00, 0.7455817572577521E+00, 0.9604635037498299E-01, 0.1362822625756884E+00, 0.7894982141438661E+00, 0.5371956247017955E+00, 0.2757551089818502E+00, 0.9298698100988576E+00, 0.8755382224220718E+00, 0.2542040210765101E+00, 0.1287904754285962E+00, 0.6810846780454294E+00, 0.6526638813043742E+00, 0.5955845877046446E+00, 0.4670096896697419E+00, 0.5475207984291373E+00, 0.6684162034597571E+00, 0.5235410539200527E+00, 0.7337617639827179E+00, 0.8903194008545992E+00, 0.8072217495300122E+00, 0.3881183186356038E+00, 0.9675156751063907E+00, 0.4869149855955625E+00, 0.4861129300486463E+00, 0.5200718178308463E+00, 0.7592798686765068E+00, 0.7809192005748844E+00, 0.9939952535261979E+00, 0.4314053553650160E+00, 0.3880099380329156E+00, 0.9349849386467751E+00, 0.5291872418075704E+00, 0.7655812944336832E+00, 0.7077741471317599E+00, 0.5275519688342463E+00, 0.1415092279196126E+00, 0.1904335663118598E+00, 0.3699272115054363E+00, 0.7445484920377089E+00, 0.8400049615316296E+00, 0.8734700661006028E+00, 0.8683217518669656E+00, 0.8515176384024258E+00, 0.6202080985416659E+00, 0.3604998919630682E+00, 0.2403115969743893E+00, 0.9554672796937618E+00, 0.1693873282831592E+00, 0.5994144523705257E+00, 0.1384422941659869E-01, 0.6596251817370012E+00, 0.5636231004812753E+00, 0.5389166856740800E+00, 0.2607457441602791E+00, 0.5920539595206202E+00, 0.2966504229935458E+00, 0.5816050348468149E+00, 0.9328164339475690E+00, 0.5805507576670368E+00, 0.6771712743677023E+00, 0.9823651336988842E+00, 0.9793282488782439E+00, 0.4667245203343464E+00, 0.7134684364121646E+00, 0.4880671978756712E-01, 0.8383078993270572E+00, 0.7936419849408084E+00, 0.5385800856643647E+00, 0.4634644976924968E+00, 0.3931501879746360E+00, 0.1248524879525928E+00, 0.3152310060096000E+00, 0.9363438862709352E+00, 0.3520470715344234E+00, 0.1429338846554544E+00, 0.1326946626315275E+00}, + n: 21, + zOut: []float64{0.2657315323020249E+01, 0.2572905823883155E+01, 0.2192663626292596E+01, 0.2071095653426940E+01, 0.2044494413445205E+01, 0.1999166174223334E+01, 0.1788414821296782E+01, 0.1468335212647637E+01, 0.1398203839606685E+01, 0.1347197234417596E+01, 0.1032902470665773E+01, 0.6608948302945201E+00, 0.5911878145202527E+00, 0.5378924504889658E+00, 0.3142273934265400E+00, 0.2842363451796606E+00, 0.2019484989227465E+00, 0.1206949829709270E+00, 0.7426269792367300E-01, 0.2567909008435554E-01, 0.2199972943425967E-02, 0.1467781105980630E-22, 0.1166962122444304E-12, 0.3923264640094201E-13, 0.1788414821296782E+01, 0.4047127357551305E-19, 0.1945479305169457E-09, 0.9334440121571419E-10, 0.1468335212647637E+01, 0.0000000000000000E+00, 0.9722951216797492E-08, 0.1689489155058893E-07, 0.1398203839606685E+01, 0.0000000000000000E+00, 0.7669133926546234E-07, 0.4506074380002258E-07, 0.1347197234417596E+01, 0.5319335283638860E-18, 0.5446647026201709E-11, 0.3163064243829271E-10, 0.1032902470665773E+01, 0.4430813007685208E-16, 0.2338591866968101E+02, 0.2338591866968102E+02, 0.1020000000000000E+03, 0.3054421768707483E+01, 0.2941176470588236E+01, 0.1546723845733498E-03, 0.5911878145202527E+00, 0.3652829585034170E-19, 0.1702044288822486E-03, 0.2177596193354961E-03, 0.5378924504889658E+00, 0.1350864780951217E-19, 0.2554902108144373E-06, 0.3466691719880105E-07, 0.3142273934265400E+00, 0.2387932220615686E-11, 0.6740109938598231E-04, 0.1019437079103270E-03, 0.2842363451796606E+00, 0.4338734978715565E-28, 0.4438729696644533E-03, 0.6983868198931385E-03, 0.2019484989227465E+00, 0.2612058427213185E-17, 0.1559412966194519E-03, 0.4467949014161081E-04, 0.1206949829709270E+00, 0.7367960854764250E-27, 0.5572085070843593E-03, 0.6756387538188178E-03, 0.7426269792367300E-01, 0.4936220984925504E-18, 0.5280924471496804E-02, 0.4881438130898638E-02, 0.2567909008435554E-01, 0.4675428386128583E-22, 0.7885638578366546E-02, 0.6344653647355715E-02, 0.2199972943425967E-02, 0.1043187069080892E-15, 0.1144606019330652E-02, 0.5299576363060843E-02}, + info: 0, + }, + { + z: []float64{0.2890643798273074E-01, 0.8912209063965303E+00, 0.7091793456137876E+00, 0.8245039023218966E+00, 0.5191833323605244E+00, 0.9894484508239253E+00, 0.5658659268235589E-01, 0.1289734762146678E+00, 0.3341027001588562E+00, 0.6587235353882195E+00, 0.7097532970603662E+00, 0.5025058684824796E+00, 0.5130835936402325E+00, 0.6692657853529054E+00, 0.2879265169895939E+00, 0.8181258306911487E-01, 0.2380388408780171E+00, 0.1056636973917433E+00, 0.4227669640232596E+00, 0.8862610364887391E+00, 0.3174262171725216E+00, 0.4110634725577023E+00, 0.6279625314936111E+00, 0.2325114979496041E+00, 0.5638889949786475E+00, 0.7596856267416864E+00, 0.8240081240110467E+00, 0.9973320050910897E+00, 0.5587421997876323E+00, 0.4288334013103122E+00, 0.8314043340979348E+00, 0.5650188659610876E+00, 0.2964679109455457E+00, 0.8407175605087841E+00, 0.1058970658656445E+00, 0.6883026296612506E+00, 0.9166830669002658E+00, 0.7992763288082885E+00, 0.5373538962118501E+00, 0.8167960120885054E-01, 0.9998997916538879E+00, 0.1975674901149639E+00, 0.7582212604798201E+00, 0.2860808530483561E+00, 0.5862675745609662E+00, 0.4334284293442484E+00, 0.9545191575190999E+00, 0.5542276060509370E+00, 0.9135493345204525E+00, 0.9597250519108470E+00, 0.4020434518393716E+00, 0.2147209304773570E+00, 0.8396072187357826E+00, 0.5371494282057584E+00, 0.9930506172699961E+00, 0.3818967451326610E+00, 0.8312670748053316E+00, 0.7518558266385443E+00, 0.7897281313428761E+00, 0.4898691976861856E+00, 0.9259118998644267E+00, 0.2411762039549979E+00, 0.3003769542607895E+00, 0.9868194969589331E+00, 0.1841003538786936E+00, 0.1211293694641126E+00, 0.7968556025054743E+00, 0.5500013093928259E+00, 0.1705581246551358E-01, 0.5695318221187962E-02, 0.1626907733376057E+00, 0.3178865594423397E-01, 0.6489383021126400E+00, 0.3661200730578906E-01, 0.9937238435410299E+00, 0.8693948290233534E+00, 0.8108974262339508E-01, 0.4858895290851201E+00, 0.5417752479164495E+00, 0.3742432440371155E+00, 0.4593696265617863E+00, 0.7058043658513553E+00, 0.3505553117224474E+00, 0.9647100571711842E+00}, + n: 21, + zOut: []float64{0.2698643664756728E+01, 0.2430046536911446E+01, 0.2385739474636754E+01, 0.2028138720182182E+01, 0.1901894919230603E+01, 0.1736372633374239E+01, 0.1325608228839813E+01, 0.1300504895564844E+01, 0.1261345481029282E+01, 0.1136052475360616E+01, 0.1031365869480280E+01, 0.7689316276636458E+00, 0.5233321832080760E+00, 0.4817169321317593E+00, 0.3418348106633131E+00, 0.2652183763191593E+00, 0.1871042345023881E+00, 0.9160826173360032E-01, 0.4317601760647842E-01, 0.3303497213448481E-02, 0.1231458285303120E-03, 0.9226440439387837E-18, 0.2555628409159789E-14, 0.2440793084913596E-14, 0.1325608228839813E+01, 0.0000000000000000E+00, 0.5589422112493051E-13, 0.3085898188945034E-13, 0.1300504895564844E+01, 0.7444625512849138E-23, 0.1759654299048522E-12, 0.9781103208866350E-13, 0.1261345481029282E+01, 0.6802337789204302E-18, 0.3650786119252150E-16, 0.3306223266172732E-17, 0.1136052475360616E+01, 0.9063201483067583E-22, 0.4434055300668524E-09, 0.2614666143660316E-09, 0.1031365869480280E+01, 0.2213258132402469E-23, 0.2194206198623719E+02, 0.2194206198623719E+02, 0.1100000000000000E+03, 0.3090702947845805E+01, 0.2727272727272727E+01, 0.1493749053307339E-05, 0.5233321832080760E+00, 0.6795157417200880E-17, 0.4382394072074649E-04, 0.6871024518289093E-04, 0.4817169321317593E+00, 0.6227468015696590E-20, 0.2332676874935389E-03, 0.1644354889791431E-03, 0.3418348106633131E+00, 0.8455074291031222E-24, 0.5211421342985135E-03, 0.2133578004049512E-03, 0.2652183763191593E+00, 0.4572942646937810E-19, 0.1472671843690071E-04, 0.1084821769416695E-04, 0.1871042345023881E+00, 0.4930380657631324E-31, 0.2208706795255935E-03, 0.1179477310012027E-03, 0.9160826173360032E-01, 0.2210123199165121E-23, 0.1806566548732391E-03, 0.1927419907906541E-03, 0.4317601760647842E-01, 0.5416053917983313E-23, 0.1030445327331746E-02, 0.1902956416897231E-02, 0.3303497213448481E-02, 0.8065145389241560E-19, 0.2031248978330205E-02, 0.9946626682395031E-03, 0.1231458285303120E-03, 0.1613264727387662E-23, 0.1026826157383968E-01, 0.7685291223570192E-02}, + info: 0, + }, + { + z: []float64{0.9180725347208115E+00, 0.2301506372544524E+00, 0.2276838071944142E+00, 0.3342400207211600E+00, 0.9639463843013925E+00, 0.5437724527901152E+00, 0.1580993234156807E+00, 0.7877490287014776E+00, 0.3507533849023979E+00, 0.8833112450245699E+00, 0.3185731691946991E-01, 0.4118134066759526E+00, 0.8069686780110494E+00, 0.8681061806796153E-01, 0.6859948674552803E+00, 0.3663178920382139E+00, 0.3720291416615038E+00, 0.8903287156706564E+00, 0.1324429304812152E+00, 0.1008541223140741E+00, 0.8373883396136816E-01, 0.6715628313581425E+00, 0.1594467086953334E+00, 0.5413131938455139E+00, 0.1818140526389971E+00, 0.8685248287187100E+00, 0.5132298455242696E+00, 0.6886095101515632E+00, 0.4005049001067575E+00, 0.6084237383755163E+00, 0.7877676299774720E+00, 0.7102138904901485E+00, 0.6423372229000449E+00, 0.5613660527307726E+00, 0.9158966894941798E+00, 0.4933711427035579E+00, 0.7338439214039514E+00, 0.9908978412238557E+00, 0.5798575644928616E-01, 0.8977291910051136E+00, 0.9253772304099678E+00, 0.3904911857418987E+00, 0.4422593302764081E+00, 0.8489177311215401E+00, 0.7212670509555793E+00, 0.9615617648004515E+00, 0.8226716687395509E+00, 0.9612871412036802E+00, 0.1291974168797438E-01, 0.4488531482063538E+00, 0.2469769340642032E+00, 0.3614360453900619E+00, 0.2074351009622584E+00, 0.7016685284881871E+00, 0.1548060648394445E-01, 0.7311687113133817E+00, 0.9296728393442250E+00, 0.9396166536686752E+00, 0.8501954423645642E+00, 0.4336964896981472E+00, 0.6496017727538979E+00, 0.4464862127725214E+00, 0.4878335970157573E+00, 0.3486784051750773E+00, 0.7455411052079824E+00, 0.5444043691163374E+00, 0.3832092245164885E+00, 0.2030848069834680E+00, 0.9785068556455849E+00, 0.4981273340936699E+00, 0.2968547769748885E+00, 0.8139137104995479E+00, 0.5979876314385963E+00, 0.7890959952347512E+00, 0.1396638856742113E+00, 0.6423356747667288E+00, 0.4204101650717844E+00, 0.3861511203891811E+00, 0.5255853602620404E+00, 0.8105960955427686E+00, 0.1919308380441287E-01, 0.5308532240470543E-01, 0.3836913823972644E+00, 0.5510156269652182E+00}, + n: 21, + zOut: []float64{0.2573005090179951E+01, 0.2214810120454235E+01, 0.1922733254389488E+01, 0.1915272191491466E+01, 0.1796031325760082E+01, 0.1645710570695390E+01, 0.1570469265391087E+01, 0.1354841927194508E+01, 0.1294466452193999E+01, 0.1181212352080131E+01, 0.1084541549607215E+01, 0.7996017680870424E+00, 0.7671322760534200E+00, 0.5413194973828868E+00, 0.4525283650095193E+00, 0.2478901170080125E+00, 0.2160828479985811E+00, 0.1019188530491480E+00, 0.3154199687907010E-01, 0.6039114283538317E-02, 0.2585297601905087E-05, 0.1842779074596284E-25, 0.3846373205279405E-07, 0.1879918241657939E-07, 0.1570469265391087E+01, 0.5301607341005493E-20, 0.5291292043249480E-06, 0.9680604951014117E-06, 0.1354841927194508E+01, 0.4298088920574052E-25, 0.7835178780587823E-04, 0.5534134534297650E-04, 0.1294466452193999E+01, 0.1009741958682895E-27, 0.1198198722705974E-04, 0.2465537083987539E-04, 0.1181212352080131E+01, 0.6309019138365174E-17, 0.1614759348306573E-06, 0.9017894254302745E-07, 0.1084541549607215E+01, 0.2228464273087314E-11, 0.2171715152048637E+02, 0.2171715152048638E+02, 0.1110000000000000E+03, 0.3170068027210884E+01, 0.4504504504504505E+01, 0.2430910851731611E-05, 0.7671322760534200E+00, 0.2706512346053632E-23, 0.6377722122869933E-05, 0.4589261521941547E-05, 0.5413194973828868E+00, 0.6745076284001739E-23, 0.1892848367477632E-04, 0.2486261833151780E-04, 0.4525283650095193E+00, 0.4943696629711454E-24, 0.8902582280300076E-04, 0.6878116767917398E-04, 0.2478901170080125E+00, 0.2843433355651033E-22, 0.3448699135776589E-03, 0.2736188045956721E-03, 0.2160828479985811E+00, 0.6002787666751380E-18, 0.2577148216451160E-04, 0.6049628369117275E-04, 0.1019188530491480E+00, 0.1341063538875720E-28, 0.1448550797531803E-02, 0.1280708514177034E-02, 0.3154199687907010E-01, 0.6162975822039155E-32, 0.1183522807025889E-02, 0.1098677799367788E-02, 0.6039114283538317E-02, 0.2067951531379678E-24, 0.3575820084217755E-02, 0.2195872556012757E-02, 0.2585297601905087E-05, 0.1137373342260413E-23, 0.1063898509008824E-02, 0.9861644892506420E-03}, + info: 0, + }, + { + z: []float64{0.9985296910189717E+00, 0.8831740589213332E+00, 0.2324113848518039E+00, 0.7533238559688371E+00, 0.3064992106368385E+00, 0.3932363212439300E+00, 0.5064743635322475E+00, 0.2720810167440399E+00, 0.1759478514683438E+00, 0.1390889491193166E+00, 0.1132483424706631E+00, 0.7690628781223635E+00, 0.9618570638759271E+00, 0.5440138404508711E+00, 0.4137500693527351E+00, 0.1092888165750733E+00, 0.3873107100859553E+00, 0.6511277223354393E+00, 0.2155123791160785E-02, 0.9398729888067584E+00, 0.6720352720616287E+00, 0.1535603342192503E+00, 0.1531061200685264E+00, 0.7545904619621174E+00, 0.7663253741916968E+00, 0.9523625338296001E+00, 0.7564452546028717E+00, 0.3871338859213032E+00, 0.8414924166180344E+00, 0.9656526120147547E+00, 0.8983142486291256E+00, 0.4931225086134777E+00, 0.2402429523967143E+00, 0.2566457485714786E+00, 0.6291482026295649E+00, 0.3102713820139572E+00, 0.8907835976003569E+00, 0.7576089622962475E+00, 0.4268794706004859E+00, 0.9679759265393412E+00, 0.8761096912299335E+00, 0.8367482459498927E+00, 0.6924039391525048E+00, 0.1390797616032549E+00, 0.4788493402292462E+00, 0.4619292003991998E+00, 0.6108276748986761E+00, 0.4236594210420574E-01, 0.1642264441572165E+00, 0.3019681501044491E+00, 0.6872347566608095E-01, 0.4797791709329366E+00, 0.3191437336153862E+00, 0.4231397520665843E+00, 0.9123119461602809E+00, 0.4032629658718287E+00, 0.3761450089120290E+00, 0.1152232563042578E+00, 0.9954630682646954E+00, 0.5373824202779058E+00, 0.6106178691724040E-01, 0.8364420731639322E-01, 0.8933845816890847E+00, 0.5581653322395922E+00, 0.2899731736068278E-01, 0.1770979452363362E+00, 0.5004901441174880E-01, 0.7090935149513330E+00, 0.6196074778714252E+00, 0.7620558730426811E+00, 0.3663579087238161E+00, 0.7799033559850937E+00, 0.5196335588513137E+00, 0.2674625162438964E+00, 0.2943854187199277E+00, 0.7770221064689762E+00, 0.1654873860303906E+00, 0.1664508117665333E+00, 0.4846990191351895E+00, 0.8900931539882498E+00, 0.1193560423223905E-01, 0.7974122776570580E+00, 0.1940680748090599E+00, 0.6554519288132757E+00}, + n: 21, + zOut: []float64{0.2834962035267250E+01, 0.2457739633394971E+01, 0.2412615740112653E+01, 0.2205350258735166E+01, 0.2102070731548960E+01, 0.1691268502125131E+01, 0.1682341944223941E+01, 0.1365229052855181E+01, 0.1159748452086257E+01, 0.1104152264055237E+01, 0.9082896055849982E+00, 0.8350561719565637E+00, 0.6006322679527780E+00, 0.5944104151258589E+00, 0.3054714512857917E+00, 0.1934898777304675E+00, 0.1070106456037005E+00, 0.7977404013852835E-01, 0.4467492857453391E-01, 0.1796045849894196E-01, 0.1273912617121224E-04, 0.5392013224803094E-11, 0.7047397633000775E-04, 0.4975950204285101E-04, 0.1682341944223941E+01, 0.0000000000000000E+00, 0.1776257168565356E-04, 0.2478687660984077E-04, 0.1365229052855181E+01, 0.2904595710528663E-17, 0.2723859519581362E-08, 0.9106491605280572E-08, 0.1159748452086257E+01, 0.1011100673149366E-15, 0.1332628661445848E-04, 0.5871026575773219E-05, 0.1104152264055237E+01, 0.8308334390451641E-18, 0.8332699889408906E-05, 0.9212653513444334E-05, 0.9082896055849982E+00, 0.3518078502828044E-18, 0.2270226121598308E+02, 0.2270226121598308E+02, 0.1240000000000000E+03, 0.3505668934240363E+01, 0.5645161290322581E+01, 0.2479678732743906E-05, 0.6006322679527780E+00, 0.0000000000000000E+00, 0.7879659138115500E-06, 0.7199236433698600E-06, 0.5944104151258589E+00, 0.3024585909035025E-20, 0.8203337497349541E-06, 0.8765068833865939E-06, 0.3054714512857917E+00, 0.4733165431326071E-26, 0.3737214231038995E-06, 0.3923468144379782E-06, 0.1934898777304675E+00, 0.4260044778133448E-20, 0.3232147542049518E-06, 0.3376352641996194E-06, 0.1070106456037005E+00, 0.3308722450212072E-23, 0.5070207875063323E-06, 0.4107488228647395E-06, 0.7977404013852835E-01, 0.6162975822039155E-32, 0.1529214528521930E-08, 0.6332986682625979E-08, 0.4467492857453391E-01, 0.1074272623509048E-20, 0.2583088473438835E-04, 0.1663016813733052E-04, 0.1796045849894196E-01, 0.7053209140113412E-22, 0.1477449551257491E-03, 0.9547349784916723E-04, 0.1273912617121224E-04, 0.0000000000000000E+00, 0.2066074227952428E-02, 0.2903362394245088E-02}, + info: 0, + }, + { + z: []float64{0.9711900205601530E+00, 0.1638861523026915E+00, 0.1833187318057834E+00, 0.9072755753374127E+00, 0.2283578849017619E+00, 0.7520216236020175E+00, 0.3999380553956507E+00, 0.2624503967963340E+00, 0.4831766333071612E+00, 0.5439216550253211E+00, 0.6414566703448968E+00, 0.4958417903972772E+00, 0.6484413600580574E+00, 0.7544273119845675E+00, 0.7061059155531373E+00, 0.9606326194792012E+00, 0.5067069535242709E+00, 0.3029510615023524E+00, 0.6987030441702768E+00, 0.9783205951302908E+00, 0.1548952654742521E+00, 0.9315036439248046E+00, 0.5516706717897903E+00, 0.5168328579759034E+00, 0.3596295330063849E+00, 0.4476574932894306E-01, 0.9741728325615778E+00, 0.2804678894509116E-01, 0.3902916772468864E+00, 0.8530466945184888E+00, 0.2969904800916723E-01, 0.1860020491995459E+00, 0.7523094177753908E-01, 0.1049676044274535E+00, 0.9260152605248726E+00, 0.4316992548719201E+00, 0.7469073285915341E+00, 0.9833774639100495E+00, 0.4974597252506658E+00, 0.4177634673241238E+00, 0.2822911131407428E+00, 0.8441017127353869E+00, 0.3634452570924520E+00, 0.3139202807660985E+00, 0.3006600055674361E+00, 0.3009046530704764E+00, 0.5749841775931973E+00, 0.8312625997674838E+00, 0.7353697939061690E+00, 0.5347208541042444E+00, 0.3745659295783104E+00, 0.2530774659476339E+00, 0.4186076940004666E+00, 0.9926397860987635E+00, 0.9744627902125954E+00, 0.5156862870399348E-01, 0.9609885826474012E+00, 0.1340044668459911E+00, 0.4269295726396694E+00, 0.1323606439861225E+00, 0.9547002490565327E+00, 0.3235500895339022E+00, 0.9408694232081565E+00, 0.5256315334453321E-01, 0.5435043012268493E+00, 0.8290694048290136E+00, 0.3690485876123201E+00, 0.1315626820984572E+00, 0.7782838224801890E+00, 0.4824080201008953E+00, 0.4904940544366522E+00, 0.7125669967024466E+00, 0.2079010288312985E+00, 0.3154779356788950E+00, 0.8039212621301359E+00, 0.1606576564727077E+00, 0.9470564071979923E+00, 0.9189825217362574E+00, 0.4332760074849629E+00, 0.2823180730446854E+00, 0.8869162317432342E+00, 0.9632623909785668E+00, 0.5010388463829042E+00, 0.4287967421178640E+00}, + n: 21, + zOut: []float64{0.2578695081979337E+01, 0.2397185171350384E+01, 0.2122428254475021E+01, 0.1845603260474165E+01, 0.1680081614592041E+01, 0.1588339204725779E+01, 0.1309467974766432E+01, 0.1299839243529426E+01, 0.1209324813016549E+01, 0.1078225499420584E+01, 0.1021574489264402E+01, 0.8212075951361281E+00, 0.6252200086865959E+00, 0.5691142568406321E+00, 0.4167987738801949E+00, 0.2624912719101158E+00, 0.1530089161378868E+00, 0.6867147881453296E-01, 0.2505166907249862E-01, 0.2349256929716605E-02, 0.7151879759250424E-03, 0.1577721810442024E-29, 0.4511324342265551E-10, 0.2432911773654117E-10, 0.1309467974766432E+01, 0.0000000000000000E+00, 0.2950215161815511E-09, 0.4606013118502744E-09, 0.1299839243529426E+01, 0.0000000000000000E+00, 0.1717787641934460E-08, 0.1104907179077728E-08, 0.1209324813016549E+01, 0.2227112107619961E-25, 0.8047601721100021E-14, 0.3064349892439287E-13, 0.1078225499420584E+01, 0.1519533811285116E-12, 0.1082897652895214E-09, 0.2849698526408556E-09, 0.1021574489264402E+01, 0.9160719227198137E-18, 0.2107539302297835E+02, 0.2107539302297835E+02, 0.1110000000000000E+03, 0.3317460317460318E+01, 0.3603603603603604E+01, 0.1689224645784323E-04, 0.6252200086865959E+00, 0.1615587133892632E-26, 0.8276137867398754E-04, 0.1155304449854771E-03, 0.5691142568406321E+00, 0.1852884571782062E-20, 0.2098842504693311E-03, 0.1630830816462844E-03, 0.4167987738801949E+00, 0.7013543182763534E-16, 0.5750632050789642E-07, 0.3137720527277731E-06, 0.2624912719101158E+00, 0.1295300917428640E-14, 0.8049639874935534E-04, 0.1584688939577041E-03, 0.1530089161378868E+00, 0.3636550670570672E-17, 0.1206768167404478E-03, 0.2128462525136164E-03, 0.6867147881453296E-01, 0.4176548246217679E-19, 0.3626791442965051E-04, 0.6269592722343766E-04, 0.2505166907249862E-01, 0.8628166150854817E-31, 0.1144078296038157E-02, 0.1062123559861287E-02, 0.2349256929716605E-02, 0.1853343815383365E-22, 0.1348818609641394E-03, 0.1209095310981735E-04, 0.7151879759250424E-03, 0.2331746618088476E-23, 0.3639492207606013E-03, 0.1002254703741813E-03}, + info: 0, + }, + { + z: []float64{0.5145122753774686E+00, 0.7453791781450037E+00, 0.4937919697078275E-01, 0.9600912461125237E+00, 0.5558575009096904E+00, 0.9202496102671529E+00, 0.1803962777705234E+00, 0.6732582413383450E+00, 0.3646300420523177E+00, 0.4351523227625338E+00, 0.5258615952095320E+00, 0.2618724553334706E-01, 0.6600255279090639E+00, 0.4323183918305084E+00, 0.2184526174816337E+00, 0.7758998738943313E+00, 0.3700044944947983E+00, 0.9075309916724112E+00, 0.7873590137849384E-02, 0.6422780210226944E+00, 0.7012374235504933E+00, 0.3225317189575561E-01, 0.9626413579028830E+00, 0.2957325301869758E+00, 0.9393912496594896E+00, 0.3122772343061888E+00, 0.3372582329155205E-01, 0.6694758703662361E+00, 0.5160501222108982E-03, 0.9689575293997177E-01, 0.3780626069308365E+00, 0.1243877469635841E+00, 0.3753610862140089E+00, 0.7686454249086220E+00, 0.8958999262270639E+00, 0.9484254659678725E+00, 0.7229120985603210E-01, 0.7282046499931183E+00, 0.1602916509824523E+00, 0.3708722215113680E+00, 0.5328491413896952E+00, 0.7547173918812869E+00, 0.4313535833192655E+00, 0.5849601017371611E+00, 0.5030126650939655E+00, 0.3345267020968724E+00, 0.8264894134567216E+00, 0.3997968176112487E+00, 0.7977852660508306E+00, 0.3214021056175872E+00, 0.4636510192825659E+00, 0.6796405156053968E+00, 0.6279823358542748E+00, 0.1573806073104234E-01, 0.6382889890358745E-01, 0.5417145287154319E+00, 0.2343304174607242E+00, 0.7662339681589646E+00, 0.6291880658725347E+00, 0.5139706179483768E+00, 0.1583956600060378E+00, 0.9391868842090931E+00, 0.2645051239078070E+00, 0.7814123021217941E+00, 0.8945112708258808E+00, 0.7464898217422987E+00, 0.3770460515219444E+00, 0.3622886345531428E+00, 0.2208273216958112E-01, 0.7102940678247979E+00, 0.2735151315490909E+00, 0.4039400600381490E+00, 0.9317363313474538E+00, 0.5754441557390587E+00, 0.5886999087747160E+00, 0.3030246870939485E+00, 0.8507721951782303E+00, 0.3043440840669203E+00, 0.6021496993262363E+00, 0.4505272689007913E+00, 0.3874595231430722E+00, 0.2566155965014733E+00, 0.2521494866083717E+00, 0.7091848125152684E+00}, + n: 21, + zOut: []float64{0.2432728498446405E+01, 0.2127807422546525E+01, 0.1810603620342434E+01, 0.1754551066335428E+01, 0.1442239744319712E+01, 0.1358471286041730E+01, 0.1268104094970585E+01, 0.1166598518949770E+01, 0.1142749842956014E+01, 0.8038795081997708E+00, 0.7842646316799070E+00, 0.7340488722153766E+00, 0.6406325830516326E+00, 0.6326463399427553E+00, 0.4829120798428922E+00, 0.4021501496449236E+00, 0.3628067219099092E+00, 0.1315077965186685E-01, 0.3447035773652165E-02, 0.9829838131645125E-03, 0.5542446906743292E-07, 0.3726944967513355E-18, 0.7775649827661083E-15, 0.4707679240410040E-15, 0.1268104094970585E+01, 0.4204313080465905E-25, 0.2081271826241763E-14, 0.3549560565109884E-14, 0.1166598518949770E+01, 0.0000000000000000E+00, 0.3900682806423283E-13, 0.2423637210496787E-13, 0.1142749842956014E+01, 0.1408856084028437E-16, 0.9605918786201080E-13, 0.6043593726409546E-13, 0.8038795081997708E+00, 0.8160364745046778E-12, 0.9063031760991450E-12, 0.1255592191298957E-11, 0.7842646316799070E+00, 0.2274746684496083E-23, 0.1936477583605892E+02, 0.1936477583605892E+02, 0.1150000000000000E+03, 0.3673469387755102E+01, 0.7826086956521739E+01, 0.1055105767279683E-11, 0.6406325830516326E+00, 0.7534418653829021E-12, 0.2026915084594321E-10, 0.1938443898507311E-10, 0.6326463399427553E+00, 0.7428954317778491E-22, 0.1822158222411987E-10, 0.2310105649781206E-10, 0.4829120798428922E+00, 0.6818472407494482E-21, 0.4806621018591031E-08, 0.3430760494577760E-08, 0.4021501496449236E+00, 0.9407638730741502E-13, 0.4934881466368944E-07, 0.7682525823543034E-07, 0.3628067219099092E+00, 0.4641733924717305E-17, 0.3006332568302334E-06, 0.4841414710438772E-06, 0.1315077965186685E-01, 0.0000000000000000E+00, 0.4649166787994157E-03, 0.6126205080519521E-03, 0.3447035773652165E-02, 0.0000000000000000E+00, 0.8654037114492079E-03, 0.1518309118546661E-02, 0.9829838131645125E-03, 0.2948446519354054E-25, 0.2136365904689920E-10, 0.9493111427282873E-09, 0.5542446906743292E-07, 0.0000000000000000E+00, 0.8210503952597113E-02, 0.1866280792966489E-03}, + info: 0, + }, + { + z: []float64{0.1382149566425072E+00, 0.6575474867299980E+00, 0.6348472674088155E+00, 0.2171300387013793E+00, 0.8255967246227341E+00, 0.3006539504418347E+00, 0.2997341048143420E+00, 0.8472159875058289E+00, 0.6738978429295159E+00, 0.5424646868297128E+00, 0.4120014569672862E+00, 0.8343380028244362E+00, 0.3003911043596160E+00, 0.4710045367840567E+00, 0.4862652198104067E-01, 0.7471894777046170E+00, 0.1793049886163456E+00, 0.7023511329140396E+00, 0.7338019696975340E-02, 0.6396982308318109E+00, 0.9907774162255600E-01, 0.9295761484947797E+00, 0.9648060362942152E+00, 0.9280158186031068E+00, 0.2707915909911263E-01, 0.3838735516497237E+00, 0.1682677327524866E+00, 0.2113105759433432E+00, 0.9045861188128749E+00, 0.7471063495001966E+00, 0.8342180430544732E-01, 0.1412979915701199E+00, 0.8279925714974835E+00, 0.1155895711297670E+00, 0.9231783969041454E+00, 0.3728782651185074E+00, 0.6830046202574890E+00, 0.9069008465878121E+00, 0.9754648591267837E+00, 0.8893150707687680E-01, 0.6771275111272185E+00, 0.9913978119103384E+00, 0.7253101374756428E+00, 0.9967636737323063E+00, 0.8627812047783159E+00, 0.3179382291892185E-01, 0.3971194218951257E+00, 0.1929798662828303E+00, 0.8983406738830656E+00, 0.8696986427722838E+00, 0.1626550211323166E+00, 0.5446758738044107E+00, 0.7791897500950196E+00, 0.5495589328822522E+00, 0.2598162756138545E+00, 0.4878822167962611E+00, 0.1063554708684851E+00, 0.9205986422545666E+00, 0.2525019548845375E+00, 0.6202404757545382E+00, 0.4398012123976176E+00, 0.3367811528280380E+00, 0.2846930465290612E+00, 0.3637854092863660E+00, 0.2816012898088578E+00, 0.8253973364224151E+00, 0.1068693035499244E+00, 0.6335234891165292E+00, 0.4457012705011152E+00, 0.3822128202770037E-01, 0.8044679788500431E-02, 0.1644333417433916E+00, 0.8243501026702226E+00, 0.3724822902257573E+00, 0.3284619434713851E+00, 0.8284230195063381E+00, 0.9834160248288059E+00, 0.5390643127606534E+00, 0.4874602694948874E+00, 0.3393327340444893E+00, 0.9478697182248690E+00, 0.9005921446100461E+00, 0.6870582101064761E+00, 0.8753727823211164E+00}, + n: 21, + zOut: []float64{0.2520205603715150E+01, 0.2467591671122728E+01, 0.2156156465592955E+01, 0.1830603796963098E+01, 0.1688980285573207E+01, 0.1475729352347043E+01, 0.1457403847234258E+01, 0.1216096979409916E+01, 0.1020221539309743E+01, 0.9109792709218910E+00, 0.7786685137433046E+00, 0.6943983149907305E+00, 0.5952732619368740E+00, 0.5747064141061984E+00, 0.4193783470766816E+00, 0.2849493660130012E+00, 0.2000335007304226E+00, 0.1879518797669419E+00, 0.9250201866750386E-01, 0.6720326503698931E-01, 0.2522304426258675E-08, 0.0000000000000000E+00, 0.6146929522129176E-12, 0.1808448588630822E-11, 0.1457403847234258E+01, 0.4890937612370273E-28, 0.1829381779873047E-10, 0.6063479072736104E-11, 0.1216096979409916E+01, 0.3707772472283591E-24, 0.7129364201262979E-09, 0.6841733798178873E-09, 0.1020221539309743E+01, 0.2138261883449577E-21, 0.5257033338238628E-09, 0.5072654023074907E-09, 0.9109792709218910E+00, 0.7953858577580093E-22, 0.4258628064439383E-09, 0.4402488234184115E-09, 0.7786685137433046E+00, 0.2050608176139579E-11, 0.2063903369678094E+02, 0.2063903369678095E+02, 0.1070000000000000E+03, 0.3256235827664399E+01, 0.7476635514018692E+01, 0.2680505535092421E-09, 0.5952732619368740E+00, 0.3490920289236852E-22, 0.2767075275933556E-09, 0.2579359628684292E-09, 0.5747064141061984E+00, 0.6550779105727953E-17, 0.5565909614599560E-09, 0.4340922452181151E-09, 0.4193783470766816E+00, 0.3307688474446419E-20, 0.4344481061547019E-08, 0.2950068756973984E-08, 0.2849493660130012E+00, 0.2114500635677851E-23, 0.2105683914952377E-07, 0.1386409244069912E-07, 0.2000335007304226E+00, 0.2552627671550359E-24, 0.1231406445198996E-06, 0.7724199195397155E-07, 0.1879518797669419E+00, 0.2762617809804602E-19, 0.3259696859933768E-06, 0.5428848805276070E-06, 0.9250201866750386E-01, 0.2465190328815662E-31, 0.5308529636258477E-04, 0.3674504775836459E-04, 0.6720326503698931E-01, 0.4910144116114772E-20, 0.8312610965835068E-03, 0.3682729181838852E-03, 0.2522304426258675E-08, 0.0000000000000000E+00, 0.2850162708346282E-01, 0.1272924532804709E-01}, + info: 0, + }, + { + z: []float64{0.8107097465650837E+00, 0.6284212325752714E-02, 0.8801609468679439E-01, 0.1317925189426976E+00, 0.7816238529622888E+00, 0.5138440552812117E+00, 0.8491910920486024E+00, 0.5354109734403600E-01, 0.9922209940223927E+00, 0.5302203883752287E+00, 0.7634020308181488E-01, 0.1679415943232965E+00, 0.2329711998757648E+00, 0.1414305919938111E+00, 0.1841480420952157E-01, 0.3417588803467335E+00, 0.2555749764808386E+00, 0.5793635436480560E-01, 0.5867939998055902E+00, 0.9699556000711096E+00, 0.2545002439558014E+00, 0.6318762794888357E+00, 0.3917398730545906E+00, 0.5624711052874073E+00, 0.4151753215255505E-01, 0.2323556867603191E+00, 0.8346423132579881E+00, 0.4193569213002444E+00, 0.5070048505400149E+00, 0.9880568155195324E-01, 0.6350898210108906E+00, 0.2370382383359541E+00, 0.3299228061150288E+00, 0.4349239764921071E+00, 0.5262500692361848E+00, 0.5263549923651836E+00, 0.8161052184432745E+00, 0.5568267671289201E+00, 0.7852669932205985E+00, 0.4481607592551184E-01, 0.6290146498792036E+00, 0.9736787804665343E+00, 0.5369941621471508E+00, 0.6750777504837204E+00, 0.9452511173220645E+00, 0.3252402467696922E+00, 0.8149000487070703E+00, 0.8087485664240622E+00, 0.8643101435258340E+00, 0.4683483752594740E+00, 0.5054760923588362E+00, 0.9646412930917844E+00, 0.1611953384510251E+00, 0.6426851941066625E-01, 0.3732266796993424E+00, 0.6384029126799168E+00, 0.3844644469584264E+00, 0.6635273633462982E+00, 0.2553934870916856E+00, 0.7037835913610216E+00, 0.7783327991001192E+00, 0.7381327592761330E+00, 0.2765915485450557E+00, 0.9846188872724937E-01, 0.1992562101416243E+00, 0.2440052895970430E+00, 0.3301477999473963E+00, 0.5338134839029927E+00, 0.5498293871712301E+00, 0.1974401363114953E+00, 0.7407533997655510E+00, 0.6821638940995054E+00, 0.9814777780110351E+00, 0.4891456709117443E+00, 0.6868139367703679E+00, 0.4181531426430654E+00, 0.6623070699739451E+00, 0.9202771282456093E+00, 0.2973080397025486E+00, 0.4403051603022431E+00, 0.1603780540263299E+00, 0.4910562348998989E+00, 0.7838834745165658E+00, 0.1931809149066596E+00}, + n: 21, + zOut: []float64{0.2163023058341640E+01, 0.1906105992609667E+01, 0.1885682431608721E+01, 0.1629672232824707E+01, 0.1530256904983391E+01, 0.1307296833197682E+01, 0.1220997281181084E+01, 0.9674288853031870E+00, 0.8179252376135864E+00, 0.6735586841320580E+00, 0.6320597056120635E+00, 0.5126868322939253E+00, 0.4828683228163860E+00, 0.4745823594217251E+00, 0.3685025909289511E+00, 0.2947763441663148E+00, 0.8912041525268403E-01, 0.6456597576955210E-01, 0.6259461554584676E-01, 0.1853533814873023E-01, 0.2023108580404890E-03, 0.8671199725506423E-13, 0.1722304485286045E-09, 0.1666294529992108E-09, 0.1220997281181084E+01, 0.1774302413926244E-21, 0.1370178691819834E-09, 0.1399340123848638E-09, 0.9674288853031870E+00, 0.4276620702127187E-22, 0.3173068333548179E-09, 0.2274343348931791E-09, 0.8179252376135864E+00, 0.7888609052210118E-30, 0.5644994943584269E-09, 0.8117631577107350E-09, 0.6735586841320580E+00, 0.2962158340816585E-16, 0.9564613436107998E-08, 0.6775718950029066E-08, 0.6320597056120635E+00, 0.4964115825120276E-16, 0.1710244235260994E+02, 0.1710244235260994E+02, 0.1120000000000000E+03, 0.3265306122448980E+01, 0.6250000000000000E+01, 0.5299633299932952E-07, 0.4828683228163860E+00, 0.2680954403830288E-19, 0.1311205982337445E-05, 0.9790063018353157E-06, 0.4745823594217251E+00, 0.5160286279848935E-24, 0.1890785247579508E-05, 0.1394729630636152E-05, 0.3685025909289511E+00, 0.4693722386065020E-28, 0.6031882082954460E-05, 0.2415384446316590E-05, 0.2947763441663148E+00, 0.1882813323774143E-21, 0.7814092950831008E-04, 0.8799876387761915E-04, 0.8912041525268403E-01, 0.1005797654156790E-28, 0.3017726164846613E-06, 0.1278833151586840E-06, 0.6456597576955210E-01, 0.4635851024992188E-19, 0.2982580055136947E-07, 0.4759731822531787E-07, 0.6259461554584676E-01, 0.4490807166402986E-22, 0.9170799331172770E-06, 0.3025792024297308E-06, 0.1853533814873023E-01, 0.4985600920996795E-27, 0.9814614537388964E-04, 0.3116488226164178E-03, 0.2023108580404890E-03, 0.0000000000000000E+00, 0.9878507322060364E-03, 0.9125548412055403E-03}, + info: 0, + }, + { + z: []float64{0.4943635351465083E+00, 0.1295760812930432E+00, 0.7491711827268356E+00, 0.8583007697336751E+00, 0.8597988452333791E+00, 0.9020619105716389E+00, 0.2915077046929524E+00, 0.2667690273281318E+00, 0.2640508133196529E-01, 0.6592981688042527E+00, 0.5004017812459820E+00, 0.7056211227388411E+00, 0.2254860841977465E+00, 0.8570117342825790E+00, 0.6863131135194549E+00, 0.6029337708611949E+00, 0.6631267757314846E+00, 0.5332167960220966E+00, 0.3047497072553197E+00, 0.3019927731659721E+00, 0.6244714872283929E+00, 0.3204566006732108E+00, 0.9437738905138152E+00, 0.4462876020196550E+00, 0.6693016494515551E+00, 0.5687239407477801E+00, 0.5130358959101252E+00, 0.1634623710980615E+00, 0.6356065394794165E+00, 0.9187737904031696E+00, 0.8612817405760382E+00, 0.1602125514297330E+00, 0.5297426144233635E+00, 0.3699984812614213E+00, 0.3455622529703073E+00, 0.9962779456692529E+00, 0.3564481259772661E+00, 0.2073475342531472E-01, 0.5839325153640170E+00, 0.6856088547326490E+00, 0.1606020836922776E+00, 0.2475573692197572E+00, 0.8169030104559274E+00, 0.1727021335202554E+00, 0.8794153095346040E+00, 0.1052546999951709E-01, 0.4332903851899277E+00, 0.4302943891085251E+00, 0.6360909664440160E+00, 0.1924830187263967E+00, 0.6792019925733094E+00, 0.7328300669715262E+00, 0.8282900281692296E+00, 0.1586820387506954E+00, 0.5999731076117462E+00, 0.4873494502000296E+00, 0.4446262392098149E+00, 0.6430807880043099E-01, 0.4949024386471711E+00, 0.7324156973660632E+00, 0.4547667791304575E+00, 0.7542985454738853E+00, 0.3755946849636591E+00, 0.7135765429513076E+00, 0.7888131931751277E+00, 0.6384460726826821E+00, 0.4685063200928931E+00, 0.1343379262734882E+00, 0.8857603211032115E+00, 0.5798608180272281E+00, 0.8765662925729737E+00, 0.2107645345329755E+00, 0.7032612644639602E-01, 0.2672549085142431E+00, 0.5322118352980683E+00, 0.4697779217142906E-01, 0.1959612687762308E+00, 0.7346288295330818E+00, 0.4373432557584073E+00, 0.2514178299506654E+00, 0.7845430350805238E+00, 0.7823648156079857E+00, 0.6098686444303012E+00, 0.2687771415020881E+00}, + n: 21, + zOut: []float64{0.2638973127799410E+01, 0.2299941431214051E+01, 0.2280019421450360E+01, 0.2103910562764817E+01, 0.1753406216295798E+01, 0.1675269066003242E+01, 0.1419658234290438E+01, 0.1365959224584141E+01, 0.1187696680558471E+01, 0.1126073702945326E+01, 0.8926412592525027E+00, 0.7715773240739381E+00, 0.5428647577479762E+00, 0.4329885186763779E+00, 0.3589145864992100E+00, 0.2461266947628802E+00, 0.1802035742271595E+00, 0.1083562693061272E+00, 0.7909884021715781E-01, 0.2853616071040153E-01, 0.1859995500862765E-03, 0.5169878828456423E-25, 0.7099412452593561E-13, 0.1129160994681896E-12, 0.1419658234290438E+01, 0.7523863534922662E-17, 0.1645873945742296E-11, 0.1162641799741134E-11, 0.1365959224584141E+01, 0.3171195595439500E-23, 0.6168272840237550E-11, 0.8582511762369885E-11, 0.1187696680558471E+01, 0.8519789992808060E-16, 0.1934844654065141E-10, 0.2568816579510325E-10, 0.1126073702945326E+01, 0.8564308176121538E-22, 0.5690968370753065E-10, 0.7456610067231580E-10, 0.8926412592525027E+00, 0.4500097668303756E-13, 0.2149240165292988E+02, 0.2149240165292987E+02, 0.1030000000000000E+03, 0.2950113378684807E+01, 0.4854368932038835E+01, 0.1146501122497315E-08, 0.5428647577479762E+00, 0.2966117003631004E-27, 0.2887486457338918E-08, 0.3484100742696835E-08, 0.4329885186763779E+00, 0.9478952637135678E-26, 0.8311221870318503E-08, 0.6953572191921854E-08, 0.3589145864992100E+00, 0.2375820297137957E-16, 0.1629548458200623E-07, 0.1368379043565619E-07, 0.2461266947628802E+00, 0.1012567897168591E-16, 0.3168042687452701E-07, 0.3807114536183845E-07, 0.1802035742271595E+00, 0.8688408444571280E-16, 0.7017919615597339E-07, 0.9241973720004823E-07, 0.1083562693061272E+00, 0.3747089299799806E-28, 0.3320058009883818E-06, 0.6266972429387508E-06, 0.7909884021715781E-01, 0.9269115636346889E-29, 0.6452918276099027E-05, 0.1508443954686445E-04, 0.2853616071040153E-01, 0.2499111347740165E-24, 0.3360677328899296E-03, 0.1546059694047028E-03, 0.1859995500862765E-03, 0.1972152263052530E-28, 0.5448826922428762E-03, 0.1724316467181159E-02}, + info: 0, + }, + { + z: []float64{0.5641760158025995E+00, 0.2227931624220032E+00, 0.1040729150876691E+00, 0.7228520011975436E+00, 0.2490915552877161E+00, 0.4463107957028827E+00, 0.6882435259034004E+00, 0.2173580561342540E+00, 0.8146865135594571E+00, 0.3630549548424193E+00, 0.2813912484076728E+00, 0.7560034280086618E+00, 0.7800835186160227E-01, 0.9984316063995433E+00, 0.2057310185040729E+00, 0.4428139729521006E+00, 0.1946530136132755E+00, 0.8953866467149748E+00, 0.5910093704925600E+00, 0.9736056943014803E+00, 0.7342559355497796E+00, 0.5630651274913434E+00, 0.3586901690989497E+00, 0.1859950386974873E-01, 0.4012559193852120E+00, 0.5767984160414075E-01, 0.3379735138652440E+00, 0.6337834884220164E+00, 0.8830566914548466E-01, 0.2985048049064926E+00, 0.9820684138520455E+00, 0.1144932752938616E+00, 0.5905532956519596E+00, 0.4757653978696945E+00, 0.1997612463043563E-01, 0.6356348606671800E+00, 0.8478495728965164E+00, 0.4997410778119411E+00, 0.6861774168985810E+00, 0.6912919871514965E+00, 0.1276032443467088E+00, 0.2695430969348002E+00, 0.9446688115451145E+00, 0.5104603739010690E+00, 0.8863068797328323E+00, 0.3347723354379355E+00, 0.2977917172311930E+00, 0.9464871506253476E+00, 0.4279639349386329E+00, 0.6378279454376028E+00, 0.2778621310060349E+00, 0.6971058794896068E-01, 0.6309805553452471E+00, 0.3447281367207256E-01, 0.8480855191050544E+00, 0.6700112511333863E+00, 0.1616260465745026E+00, 0.7744510887458210E+00, 0.8408544531170117E+00, 0.8444763755373497E-01, 0.3286971575766536E+00, 0.8244867044222992E+00, 0.8036107174439190E+00, 0.4654902702844697E+00, 0.8300602115903392E+00, 0.5911511948645825E+00, 0.5734805041784674E+00, 0.6046912223886362E+00, 0.4400460907177143E+00, 0.4069795298963303E+00, 0.2413714645456244E+00, 0.7838758775665940E+00, 0.1371288591293247E+00, 0.8435169936355635E-01, 0.4867567406491472E+00, 0.2914527168883616E+00, 0.7540094160758792E+00, 0.6792178828893637E+00, 0.8924641252729165E+00, 0.2188072300242774E+00, 0.1899571860965691E+00, 0.7806965639263314E+00, 0.8706240780095753E-01, 0.7170634647198669E+00}, + n: 21, + zOut: []float64{0.2553381332090116E+01, 0.2166390759033473E+01, 0.1737362408504838E+01, 0.1528419999405254E+01, 0.1507484707859341E+01, 0.1334735890703865E+01, 0.1222641790395049E+01, 0.1186722126839839E+01, 0.1073660052771764E+01, 0.9488489095119069E+00, 0.9141860725715962E+00, 0.7726247731371300E+00, 0.6075856291402457E+00, 0.5409244297850613E+00, 0.4230641503671385E+00, 0.2356839373494127E+00, 0.1583434617720056E+00, 0.3187519618749328E-01, 0.2747107248999187E-01, 0.1480095837386152E-02, 0.5569185181399456E-04, 0.3215260779752862E-17, 0.2284971140234050E-13, 0.6915955898032105E-13, 0.1222641790395049E+01, 0.9860761315262648E-31, 0.9831000121605633E-10, 0.3802561298586086E-10, 0.1186722126839839E+01, 0.2066815571679051E-27, 0.6142487424703478E-09, 0.1524532000885779E-08, 0.1073660052771764E+01, 0.3155443620884047E-29, 0.1933670198753400E-07, 0.4311109498288097E-07, 0.9488489095119069E+00, 0.6613963504021090E-17, 0.7125410558010122E-07, 0.6137903750393884E-07, 0.9141860725715962E+00, 0.2713620929442760E-22, 0.1897294248760472E+02, 0.1897294248760472E+02, 0.1070000000000000E+03, 0.3233560090702948E+01, 0.4672897196261682E+01, 0.2313496546014482E-05, 0.6075856291402457E+00, 0.2008094738046662E-26, 0.6354651604911740E-04, 0.4633045629030685E-04, 0.5409244297850613E+00, 0.2465190328815662E-30, 0.8082164119218066E-03, 0.5151838483992701E-03, 0.4230641503671385E+00, 0.3299331849996360E-25, 0.9881103085087938E-03, 0.1036550305023510E-02, 0.2356839373494127E+00, 0.2111622871095604E-25, 0.1203513003711909E-02, 0.1300398061184096E-02, 0.1583434617720056E+00, 0.1737664936697394E-23, 0.8260928074113359E-03, 0.9484297179228856E-03, 0.3187519618749328E-01, 0.0000000000000000E+00, 0.1785275423606748E-03, 0.4485462762371783E-03, 0.2747107248999187E-01, 0.8804949879714635E-25, 0.5200632154389635E-08, 0.3234666977722410E-08, 0.1480095837386152E-02, 0.5399595124056782E-24, 0.5661901580915454E-02, 0.5860254353052324E-02, 0.5569185181399456E-04, 0.0000000000000000E+00, 0.1190560893471898E-01, 0.9131404251707014E-02}, + info: 0, + }, + { + z: []float64{0.7290518158132969E+00, 0.5196659176766039E-03, 0.6083923160589086E+00, 0.3459319602615154E+00, 0.3277021139736517E+00, 0.6020592719504614E-01, 0.4608784204502808E+00, 0.8430478676154098E+00, 0.3856212930081542E+00, 0.6602823264317716E+00, 0.4451601253283373E+00, 0.4130313322309198E-01, 0.7414750648249350E+00, 0.1630235543068703E-01, 0.6004925370465983E+00, 0.6953287054569501E+00, 0.7809046354974044E+00, 0.7892746585788727E+00, 0.8348704064067982E+00, 0.5999411739898802E+00, 0.5502575606089829E+00, 0.4392206918044746E+00, 0.7984758158185817E+00, 0.9084185319619590E+00, 0.1786837110145214E+00, 0.2414921532322530E+00, 0.5630913108462098E+00, 0.7820323704275389E+00, 0.5523326888742272E+00, 0.9015512185421630E+00, 0.6659841765947113E+00, 0.2845604319423287E+00, 0.3491764093356571E+00, 0.9628247275953050E-01, 0.6976897044251388E+00, 0.2960314575787897E+00, 0.5554565606281359E-01, 0.3558757052257084E+00, 0.9341850945519581E+00, 0.6665938574616496E+00, 0.9614102712845256E+00, 0.8607214960584614E+00, 0.4038740733880183E+00, 0.8195623831081322E+00, 0.6129183541897144E+00, 0.7215327066311872E-01, 0.5031970254369666E-01, 0.1396452298202989E+00, 0.9662061833347503E+00, 0.1270920838674061E+00, 0.4311106155362532E+00, 0.8052749852152479E+00, 0.4015794631208873E+00, 0.9090852867289334E-01, 0.6606775367976888E+00, 0.1481179966505828E+00, 0.9638580924515038E+00, 0.9709844996525795E+00, 0.1150673643193312E-01, 0.1429293205078334E+00, 0.2900042758147406E+00, 0.9072348766684573E+00, 0.5781273728635536E+00, 0.5436950045999074E+00, 0.1857622262967125E+00, 0.9164714647876027E+00, 0.1370982861482903E+00, 0.4992756875010576E+00, 0.1554652709586491E+00, 0.3126479857720679E+00, 0.4107075699045055E+00, 0.2895846225773548E+00, 0.6273125726015746E+00, 0.2838905730735005E+00, 0.5809021463377108E+00, 0.7647718231557297E+00, 0.2069816461533343E+00, 0.3140055757156704E+00, 0.1235726138058405E+00, 0.4368723232060789E-01, 0.7675622822273089E+00, 0.9898297711455730E+00, 0.5845844813092991E+00, 0.3724928805727834E+00}, + n: 21, + zOut: []float64{0.2656606156715505E+01, 0.2361088067613179E+01, 0.2270460825471249E+01, 0.2122871466419806E+01, 0.1864972075992565E+01, 0.1483766917780093E+01, 0.1313593002893207E+01, 0.1121546276208008E+01, 0.1100149868182268E+01, 0.9659264313206680E+00, 0.7624972132947719E+00, 0.7289080649182198E+00, 0.6752163576811447E+00, 0.6611764720975886E+00, 0.5004340625462813E+00, 0.2440674815088013E+00, 0.2171809202435314E+00, 0.1235497606154792E+00, 0.3737121186344041E-01, 0.2834840406904476E-01, 0.5846755428136478E-02, 0.7443896006885402E-16, 0.5016677150024004E-07, 0.3707799983650212E-07, 0.1313593002893207E+01, 0.2958228394578794E-29, 0.1581957950672119E-06, 0.2298083114979900E-06, 0.1121546276208008E+01, 0.1915993820645148E-16, 0.4749045639556273E-06, 0.4145613346073258E-06, 0.1100149868182268E+01, 0.9026685982667287E-18, 0.2821283116535875E-06, 0.3158894087015811E-06, 0.9659264313206680E+00, 0.2037048580685469E-20, 0.2246093425341190E-06, 0.2076005360058006E-06, 0.7624972132947719E+00, 0.1234566306928925E-21, 0.2124557779286299E+02, 0.2124557779286298E+02, 0.1010000000000000E+03, 0.3002267573696145E+01, 0.2970297029702970E+01, 0.4897987464996691E-04, 0.6752163576811447E+00, 0.7461812581271996E-18, 0.7761124913531668E-04, 0.7483244468930916E-04, 0.6611764720975886E+00, 0.1038114253693458E-19, 0.1582094808245393E-03, 0.1235322388201987E-03, 0.5004340625462813E+00, 0.1010613662291919E-16, 0.2610534203903574E-03, 0.4450812691210283E-03, 0.2440674815088013E+00, 0.1110435042389887E-20, 0.5668320309921573E-04, 0.5311544381771655E-04, 0.2171809202435314E+00, 0.4733165431326071E-27, 0.6599010146996593E-04, 0.7896621041843452E-04, 0.1235497606154792E+00, 0.3155385912111625E-18, 0.1746230697391169E-01, 0.1331928313395539E-01, 0.3737121186344041E-01, 0.7395570986446986E-31, 0.1364698415102933E-02, 0.9400709901879650E-03, 0.2834840406904476E-01, 0.1581043861486090E-22, 0.9826835453665868E-03, 0.1307033404080312E-02, 0.5846755428136478E-02, 0.5593364605928029E-23, 0.6675960788692170E-02, 0.6853670175678725E-02}, + info: 0, + }, + { + z: []float64{0.4059771234161322E+00, 0.9607215623246773E+00, 0.2458768097786967E-01, 0.2349999394464353E-01, 0.5195584553698999E+00, 0.4267565401751807E+00, 0.5653505726897825E+00, 0.1993982232067181E+00, 0.7123509462851438E+00, 0.7322091078130321E+00, 0.6397865818692764E+00, 0.7795245712118530E+00, 0.9924677795119503E+00, 0.9446777193650685E+00, 0.9161440637569995E+00, 0.4356325057978820E+00, 0.6968317286853016E+00, 0.8623411680463823E+00, 0.8789901991689911E+00, 0.3964880116495537E+00, 0.3452640838632506E+00, 0.2457053330236874E+00, 0.3088650440709877E+00, 0.3819576657222301E+00, 0.3428589632713919E-01, 0.5108638376023356E-01, 0.1646491337519898E+00, 0.4402398340108123E+00, 0.6741907107293844E+00, 0.8399512836956711E+00, 0.5689849385173426E+00, 0.5208530271268840E+00, 0.1800472375386978E+00, 0.7659410457647264E+00, 0.2320702606914905E+00, 0.1105800266048680E+00, 0.9555355666039600E-02, 0.1859192596152662E+00, 0.7825627400019242E-02, 0.5286418396370182E+00, 0.2569279638014341E+00, 0.5549104171411018E+00, 0.7406835450501670E+00, 0.8319568443444482E+00, 0.1523286720686696E+00, 0.6741822248281739E+00, 0.7686049385045001E+00, 0.7046090895325479E+00, 0.5187887151753254E+00, 0.1082987708911324E+00, 0.1267838014025160E+00, 0.1115865001832446E+00, 0.9799554493413084E+00, 0.2112830058825086E+00, 0.1414836977037485E+00, 0.6416690587599562E+00, 0.7257743058080667E+00, 0.5941533679852271E+00, 0.2889670048515264E+00, 0.2352763591376699E+00, 0.4250778140801711E+00, 0.1017573282390372E-01, 0.7592168685641336E+00, 0.1236630021486789E+00, 0.3794258137484455E+00, 0.3894249799986492E+00, 0.3467719607731882E+00, 0.5651244918121399E+00, 0.7941305753999619E+00, 0.7160004674307343E+00, 0.6194397297375442E+00, 0.1453439098617406E+00, 0.3817157280391337E-03, 0.9381666563671931E+00, 0.8543357988390619E+00, 0.4675645670082479E+00, 0.8133557631373793E+00, 0.1160066189475003E+00, 0.6551894700973839E+00, 0.6157191087148942E+00, 0.4651705119652626E+00, 0.2935400080400429E+00, 0.4317648586994048E+00, 0.8522331953027451E-01}, + n: 21, + zOut: []float64{0.3090946182879871E+01, 0.2427731098824810E+01, 0.2178358732328273E+01, 0.1944657148720347E+01, 0.1388313875420951E+01, 0.1366009016577358E+01, 0.1254539813854158E+01, 0.1096743376160052E+01, 0.8976114875705017E+00, 0.7925182471468240E+00, 0.7633415317747125E+00, 0.5940562138773567E+00, 0.3406702196684873E+00, 0.2541261981011808E+00, 0.2081990106830526E+00, 0.1967266434974441E+00, 0.8212572008660911E-01, 0.6231598248219099E-01, 0.2121611392818772E-01, 0.6627852439078377E-02, 0.2020564063973749E-05, 0.5156511541642804E-17, 0.3563959083802911E-09, 0.2193664839500192E-09, 0.1254539813854158E+01, 0.5107396913706617E-17, 0.2245013704648247E-08, 0.3514139913607919E-08, 0.1096743376160052E+01, 0.1770166510860316E-21, 0.1137128600534393E-07, 0.7589514151253922E-08, 0.8976114875705017E+00, 0.3631375006656261E-16, 0.1027683956127825E-09, 0.1703981899256795E-09, 0.7925182471468240E+00, 0.0000000000000000E+00, 0.2692111438183261E-08, 0.1491447500870467E-08, 0.7633415317747125E+00, 0.3655079503368504E-18, 0.1896683648658551E+02, 0.1896683648658551E+02, 0.9800000000000000E+02, 0.2941043083900227E+01, 0.3061224489795918E+01, 0.1473194721443778E-07, 0.3406702196684873E+00, 0.8487843002529896E-19, 0.1107295924775035E-05, 0.6897939613884539E-06, 0.2541261981011808E+00, 0.8699892772041781E-19, 0.4010969039165872E-05, 0.5564243023106877E-05, 0.2081990106830526E+00, 0.1258849778182470E-17, 0.2192657884798391E-05, 0.1921286515322920E-05, 0.1967266434974441E+00, 0.1498835719919922E-28, 0.3181611995531238E-06, 0.2328457188758453E-05, 0.8212572008660911E-01, 0.9162137014768053E-16, 0.4655593170815260E-04, 0.2906458517213153E-04, 0.6231598248219099E-01, 0.7111877894410489E-19, 0.1084455050840344E-03, 0.4940544045928809E-04, 0.2121611392818772E-01, 0.1296887328183343E-24, 0.1059468102013224E-02, 0.9250155264543548E-03, 0.6627852439078377E-02, 0.2014616961124939E-22, 0.1082171160654875E-03, 0.1415095048461561E-03, 0.2020564063973749E-05, 0.0000000000000000E+00, 0.6572087989553770E-04, 0.6490933881766271E-04}, + info: 0, + }, + { + z: []float64{0.3515867373170093E+00, 0.6900024519663606E-01, 0.2562617636787797E+00, 0.4448144612254716E+00, 0.1882829208975508E+00, 0.5473764707914393E+00, 0.2385465140832452E+00, 0.1069888484826550E+00, 0.6650479699038470E+00, 0.5577458834974632E+00, 0.3827016483759793E-01, 0.2430476485682098E-01, 0.4730689827049095E-01, 0.7028807845337007E+00, 0.2183345614483843E+00, 0.4504620631941809E+00, 0.4989666416356805E+00, 0.3524179690092576E+00, 0.2245980971932510E+00, 0.4235501615333767E+00, 0.5262756658101302E+00, 0.9543218824354944E+00, 0.7932768470961233E+00, 0.6115989702914060E-01, 0.5090745247561921E+00, 0.6231416396947956E+00, 0.5848645563028462E+00, 0.4261243979220120E-01, 0.7488050001299923E+00, 0.1371419590365067E+00, 0.2276573560104874E+00, 0.3333510148295767E+00, 0.8801005866377587E+00, 0.1783788042757909E+00, 0.7167665061134074E+00, 0.8328416386285911E+00, 0.3239179761297745E+00, 0.3396256067647054E+00, 0.3124818554244235E-01, 0.3558253686357221E+00, 0.3434895378785284E+00, 0.5623459587025392E-01, 0.2638452014850361E+00, 0.8291744484791080E+00, 0.1974847584119865E+00, 0.7319795333910079E+00, 0.2610606436005336E+00, 0.5710127034520260E+00, 0.1439281438102160E+00, 0.9086761346521347E+00, 0.8079247890865698E+00, 0.9018578929430654E+00, 0.4900454364738460E+00, 0.8138610668520670E+00, 0.6711229676830790E+00, 0.5055629692453131E+00, 0.7743169767236130E+00, 0.4534345901632091E+00, 0.9064089158232752E+00, 0.4827899713942460E+00, 0.7358703780808750E+00, 0.9369729458478693E-02, 0.8597279323370060E+00, 0.7253136203352766E+00, 0.9571052925069841E+00, 0.2164676786228616E+00, 0.5574107740713430E-05, 0.7154716238932374E+00, 0.1141135068223202E+00, 0.6209438587853456E+00, 0.7851847140042024E+00, 0.4215540797089058E+00, 0.9132020640887749E+00, 0.1510454496157759E+00, 0.4172986352579149E+00, 0.5037450189692434E+00, 0.4485087403424131E+00, 0.5740668076879305E+00, 0.2978796610784261E+00, 0.6581099078338648E-01, 0.8930273171304047E+00, 0.8152477689300778E+00, 0.1069556485483132E+00, 0.6932157626522990E+00}, + n: 21, + zOut: []float64{0.2205969711876647E+01, 0.1949821527895322E+01, 0.1555841877124327E+01, 0.1396030697440207E+01, 0.1339074151471965E+01, 0.1304928492707023E+01, 0.1082549957806062E+01, 0.9163938874206132E+00, 0.8887122139609793E+00, 0.7285328536138327E+00, 0.6136134334950112E+00, 0.5962413214799335E+00, 0.4250735423840991E+00, 0.3604939377250871E+00, 0.2295486599338548E+00, 0.1443459206161604E+00, 0.1184188267216090E+00, 0.7075746168152415E-01, 0.2006576919306350E-01, 0.3756273174580983E-02, 0.4503973951446061E-03, 0.2214970142320351E-19, 0.1258326061053631E-10, 0.9003557400980630E-11, 0.1082549957806062E+01, 0.1308878013942703E-25, 0.3368372626791194E-10, 0.2572022209508410E-10, 0.9163938874206132E+00, 0.7614331624527915E-16, 0.1049500061330476E-08, 0.2928487158224854E-08, 0.8887122139609793E+00, 0.1203547791264655E-21, 0.7079518778653070E-07, 0.2057204985301009E-06, 0.7285328536138327E+00, 0.1084769825180869E-21, 0.6504687546036223E-07, 0.2011551828019932E-07, 0.6136134334950112E+00, 0.1678480469223895E-16, 0.1595062091511705E+02, 0.1595062091511705E+02, 0.1020000000000000E+03, 0.3156462585034014E+01, 0.2941176470588236E+01, 0.1336032003974816E-08, 0.4250735423840991E+00, 0.1033222323690773E-11, 0.1230907576002882E-05, 0.1377773980605759E-05, 0.3604939377250871E+00, 0.5435093612356237E-21, 0.5904438579725169E-05, 0.1247176535660427E-04, 0.2295486599338548E+00, 0.3794809073678436E-22, 0.8654598111714590E-03, 0.7607233838455693E-03, 0.1443459206161604E+00, 0.2335329392584174E-18, 0.9486551585203510E-04, 0.5848864829043123E-04, 0.1184188267216090E+00, 0.2421802979028506E-27, 0.4440929582264130E-04, 0.3669242548994226E-04, 0.7075746168152415E-01, 0.1891688450719986E-26, 0.5237855019006247E-04, 0.2468105637453731E-04, 0.2006576919306350E-01, 0.1180787648903814E-27, 0.8134126440113327E-03, 0.8865157422262554E-03, 0.3756273174580983E-02, 0.2581152881883151E-26, 0.5819544721666204E-02, 0.3152501351079271E-02, 0.4503973951446061E-03, 0.0000000000000000E+00, 0.5880303886253363E-04, 0.1585743718762697E-03}, + info: 0, + }, + { + z: []float64{0.5610544265871693E+00, 0.3865731523333528E+00, 0.8792353035941016E+00, 0.8523516652694250E+00, 0.1444314813898040E-01, 0.8826603847895033E+00, 0.6868176286586357E+00, 0.1885799699020001E+00, 0.8756021324147915E+00, 0.9000748303342890E+00, 0.6057362077051875E+00, 0.7116572505145777E+00, 0.4651180401287146E+00, 0.2732222796277717E-01, 0.4226433912686857E+00, 0.2137613193249559E+00, 0.8364980217841237E+00, 0.7760779616422476E+00, 0.4204777290352190E+00, 0.6224635225380051E+00, 0.2764474942580449E+00, 0.3783169947455127E+00, 0.5180995217194659E+00, 0.3065081068358929E+00, 0.7865831746887696E+00, 0.1478697978858728E+00, 0.9439830303880672E+00, 0.8253272390565236E-01, 0.3067445628749279E+00, 0.7129198739696287E+00, 0.1655397340526111E+00, 0.1744497852178990E+00, 0.8123176080018479E-01, 0.7468152661528306E+00, 0.8702942511684653E-01, 0.2665897748347560E+00, 0.9213749341388631E+00, 0.1523897006311256E+00, 0.9645030292913545E+00, 0.9612618327522493E-01, 0.4802656873918926E+00, 0.9400504426452867E+00, 0.4625574582408437E+00, 0.7387695442245192E+00, 0.7695082904503155E+00, 0.1394488941705607E+00, 0.4086909510206329E+00, 0.8420266381115991E+00, 0.9564685490270811E+00, 0.7091850518571272E+00, 0.5799173993611073E+00, 0.1780919033120022E+00, 0.4196947685163247E+00, 0.9892865772966106E+00, 0.5502405891255741E+00, 0.7805747931381838E+00, 0.8443114386354278E-01, 0.3818004737775779E+00, 0.5006744900666209E+00, 0.8330036981446504E+00, 0.6972526215524509E+00, 0.5997317354738497E+00, 0.6745658299087246E+00, 0.2369187863883299E+00, 0.4162907871251388E+00, 0.3987550165661536E+00, 0.3127240434721901E+00, 0.9587921004875174E+00, 0.9734600215022703E+00, 0.9507333301136496E+00, 0.3445022862066339E+00, 0.6240012410156072E+00, 0.3036264632031094E-01, 0.6999839547669153E+00, 0.4672138296892350E+00, 0.4669965382645248E+00, 0.7561275857160221E-01, 0.9250454776547237E+00, 0.8620177110728862E+00, 0.5266728805873626E+00, 0.6377535363121675E+00, 0.6098026285363055E+00, 0.8075088997828720E+00, 0.8486821693163010E+00}, + n: 21, + zOut: []float64{0.2468092632282687E+01, 0.2093427673862981E+01, 0.2055392019191517E+01, 0.1647867143267642E+01, 0.1615849876515927E+01, 0.1589328968238607E+01, 0.1271214388518367E+01, 0.1121382381594411E+01, 0.1069461264755295E+01, 0.1002295596318809E+01, 0.8815764834354939E+00, 0.8051252546404786E+00, 0.6374343329196452E+00, 0.5469723867709347E+00, 0.4015178604185544E+00, 0.3707602923265790E+00, 0.1795105850679969E+00, 0.1400595531050117E+00, 0.2548349514639473E-01, 0.1561366451013735E-02, 0.1155321273825210E-02, 0.3137752941767923E-22, 0.1448569525610494E-09, 0.1682297708320945E-10, 0.1271214388518367E+01, 0.3747089299799806E-29, 0.3127891707973917E-07, 0.1432924100618686E-07, 0.1121382381594411E+01, 0.1829309924661015E-19, 0.1414348814679943E-06, 0.1338467241717145E-06, 0.1069461264755295E+01, 0.2814655709828570E-26, 0.1421706541245010E-06, 0.1494636997707923E-06, 0.1002295596318809E+01, 0.2555408239179452E-16, 0.1745096068338993E-06, 0.1639215185470380E-06, 0.8815764834354939E+00, 0.5195421261043265E-21, 0.1992546887610216E+02, 0.1992546887610217E+02, 0.1040000000000000E+03, 0.3263038548752835E+01, 0.3846153846153846E+01, 0.5490557769901970E-06, 0.6374343329196452E+00, 0.1696050946225175E-28, 0.4391959465127471E-06, 0.4441570425561870E-06, 0.5469723867709347E+00, 0.4122920742224575E-16, 0.4792107785920969E-06, 0.5244422797027597E-06, 0.4015178604185544E+00, 0.4437342591868191E-30, 0.1189624719598388E-05, 0.1545254324980458E-05, 0.3707602923265790E+00, 0.0000000000000000E+00, 0.3830671301160838E-05, 0.5436396467135237E-05, 0.1795105850679969E+00, 0.1558228073167050E-14, 0.5423210427919237E-04, 0.1228583690085413E-03, 0.1400595531050117E+00, 0.8832743148296122E-19, 0.1395228897382397E-04, 0.1537585917376726E-04, 0.2548349514639473E-01, 0.0000000000000000E+00, 0.8277350694369951E-03, 0.9528953717632958E-03, 0.1561366451013735E-02, 0.2465190328815662E-31, 0.7095009159403311E-03, 0.6952609237045969E-03, 0.1155321273825210E-02, 0.1309509102666880E-27, 0.9046555260897671E-03, 0.1226313636978587E-02}, + info: 0, + }, + { + z: []float64{0.1242522906682814E+00, 0.6390609620209767E+00, 0.4481822861180138E+00, 0.4850355616354706E+00, 0.4018997557884576E+00, 0.7075817751574985E+00, 0.3076496509717662E+00, 0.9845619472128853E+00, 0.4421050939804582E+00, 0.3472138710835164E+00, 0.7694977672753175E+00, 0.4786944038481857E+00, 0.6974278852457209E+00, 0.5004517708240744E+00, 0.7658513494839985E+00, 0.7508522623862479E-01, 0.8645614962374704E-02, 0.2513671118506070E+00, 0.9355687048630774E+00, 0.2836435232395548E+00, 0.8653687008315966E+00, 0.3043727382738487E+00, 0.8973655399535756E+00, 0.7135517870607274E+00, 0.4956863425678929E+00, 0.8362506849216409E+00, 0.9829450079482006E+00, 0.9413718361369072E+00, 0.2542921002853715E-01, 0.5951158954104814E+00, 0.9317747763384295E+00, 0.9085271053958202E+00, 0.9993466426511500E+00, 0.2497009223772528E-01, 0.8726460080387569E+00, 0.3868463012727243E+00, 0.5820757557404177E-01, 0.7974577837432384E-01, 0.8242609714155934E+00, 0.1887913799920241E+00, 0.3268225406700475E+00, 0.2264596835393817E+00, 0.4020160264981738E+00, 0.8597685353848280E+00, 0.5429598215579996E+00, 0.4134507486351844E+00, 0.8781720494573462E+00, 0.3655827200857601E+00, 0.2876763179222336E+00, 0.9193112804533413E+00, 0.3958413207165046E-01, 0.7980401670837647E+00, 0.5101422689515223E-01, 0.2194050847732673E+00, 0.6115669547384739E-02, 0.9036470382476453E+00, 0.6696681747677364E+00, 0.1689100553906829E+00, 0.9284887836539969E+00, 0.8748192507086142E+00, 0.7181738874264668E+00, 0.8990747837549429E-01, 0.7166811698029575E+00, 0.8712804839027968E+00, 0.2571898936326318E+00, 0.2264160460654618E+00, 0.6364724288557849E+00, 0.9550337894922362E+00, 0.8995892333665090E+00, 0.3728949594240628E+00, 0.6496276036419958E+00, 0.7218580021816370E+00, 0.2620053580399828E+00, 0.8492826434932900E+00, 0.1090756692624820E+00, 0.1230806328807070E+00, 0.5326342483791896E+00, 0.3425391815117244E+00, 0.4714474424671373E+00, 0.9044440560476328E+00, 0.2298320061743346E+00, 0.7771450381369926E+00, 0.4623588499686800E+00, 0.8996441805847293E+00}, + n: 21, + zOut: []float64{0.2749036998648791E+01, 0.2657147938200912E+01, 0.2156780738808330E+01, 0.2057290308234013E+01, 0.1910481192038085E+01, 0.1550197528741744E+01, 0.1531663815430223E+01, 0.1307411568456853E+01, 0.1180055477995477E+01, 0.1145160315453326E+01, 0.8462599780670359E+00, 0.8196023258344234E+00, 0.7505058481318937E+00, 0.3802378569170251E+00, 0.3493658644293456E+00, 0.2733852715996189E+00, 0.1920071438579977E+00, 0.3602127141457542E-01, 0.1503353393017178E-01, 0.5047074669949666E-02, 0.4814167031169938E-03, 0.1615587133892632E-26, 0.3701495167228324E-14, 0.8166164251788096E-14, 0.1531663815430223E+01, 0.5400326177233737E-21, 0.8345943934662111E-13, 0.3845954584916692E-13, 0.1307411568456853E+01, 0.2270604060615577E-17, 0.1098158814550649E-11, 0.6011774632275279E-12, 0.1180055477995477E+01, 0.6617444900424221E-23, 0.1039362721731823E-10, 0.1780733867152956E-10, 0.1145160315453326E+01, 0.3193234771665464E-17, 0.8582967920523009E-10, 0.1451582492090454E-09, 0.8462599780670359E+00, 0.4268426102972081E-16, 0.2191317346756291E+02, 0.2191317346756291E+02, 0.1100000000000000E+03, 0.3303854875283447E+01, 0.6363636363636363E+01, 0.9730504757902699E-07, 0.7505058481318937E+00, 0.1718125187449148E-14, 0.1758342086676891E-05, 0.2642640058729254E-05, 0.3802378569170251E+00, 0.9047523974206004E-14, 0.3754566725544834E-04, 0.5673943129185001E-04, 0.3493658644293456E+00, 0.2726303288443817E-26, 0.2006689219611138E-03, 0.1777791597062721E-03, 0.2733852715996189E+00, 0.1852245405458936E-26, 0.4273484804153724E-06, 0.2289494629295668E-05, 0.1920071438579977E+00, 0.7673537210642012E-17, 0.3631464818839244E-02, 0.3052322482564877E-02, 0.3602127141457542E-01, 0.1402889840288648E-17, 0.2065820498676818E-02, 0.7907462477517949E-03, 0.1503353393017178E-01, 0.3588277137446075E-19, 0.9842420036565967E-03, 0.4295497278130008E-03, 0.5047074669949666E-02, 0.1100487290795119E-18, 0.2169791314757801E-02, 0.2746294001732303E-02, 0.4814167031169938E-03, 0.9926167349879280E-23, 0.2524480967032520E-02, 0.1685323473608901E-02}, + info: 0, + }, + { + z: []float64{0.4452569544189223E+00, 0.3712416527218666E+00, 0.4540009468556715E+00, 0.9149505778015055E-01, 0.9825460881415958E+00, 0.8144387623295611E+00, 0.4257438310114644E+00, 0.4055209729019219E+00, 0.1358301754544711E-01, 0.6660365069195171E+00, 0.4791028777450690E-01, 0.3657122138300755E+00, 0.9244230955293443E+00, 0.2570776992045346E+00, 0.5718524872194095E+00, 0.6959027703199671E+00, 0.8022093165313721E+00, 0.4495167304148069E+00, 0.4533829141769831E+00, 0.4399857636092745E+00, 0.8343772053001745E+00, 0.5841091089133705E+00, 0.9225724116024000E+00, 0.3646730358635919E+00, 0.4342402996301750E+00, 0.1979669913465428E+00, 0.2710080252534286E+00, 0.4064878156937679E+00, 0.1329017000110605E+00, 0.3577863781516848E+00, 0.7737638611946227E+00, 0.3628629851888825E+00, 0.6191378950237536E+00, 0.9181610808896479E-01, 0.3164967052049129E+00, 0.1800354212961807E+00, 0.5261304159866632E+00, 0.2095779664090124E+00, 0.4734470785970568E+00, 0.8233700542774806E+00, 0.1405149000531442E+00, 0.5739228235076023E+00, 0.4484023224779539E+00, 0.7953415183519565E+00, 0.5683020712105596E+00, 0.3828815589637512E+00, 0.9478512018818865E+00, 0.9398576744287683E+00, 0.6799918835962694E+00, 0.9795978835389229E+00, 0.9415167003494995E+00, 0.9804631144197878E+00, 0.4529282233852833E+00, 0.6987441800620822E+00, 0.1071819561656476E+00, 0.6287695276127018E+00, 0.2573913359217608E+00, 0.5283299892256954E-01, 0.1312057002484920E+00, 0.2566822109082798E+00, 0.5022596747022927E+00, 0.3755634037822867E+00, 0.7687685406410046E+00, 0.9286257388850563E+00, 0.2460950353669618E+00, 0.4615682752011302E+00, 0.2668978314403934E+00, 0.9526334220011422E+00, 0.7113266960956600E+00, 0.8033610237680390E+00, 0.2049912091857929E+00, 0.9104136201043411E+00, 0.9905140155095393E+00, 0.5284892163797259E+00, 0.4617116226676921E-01, 0.7638541825257228E+00, 0.8058860223281950E-01, 0.6562405799504624E+00, 0.4217948031372573E+00, 0.8444441663937204E+00, 0.4135300708069887E+00, 0.3992676961789670E+00, 0.9443059736340937E+00, 0.4697907769676380E+00}, + n: 21, + zOut: []float64{0.2339652518244840E+01, 0.2127240999798084E+01, 0.2122097736373912E+01, 0.1640409192349226E+01, 0.1522936721900112E+01, 0.1513900850773956E+01, 0.1190428480890818E+01, 0.1098839257111754E+01, 0.9060499827420537E+00, 0.8483833633939547E+00, 0.7423625631343986E+00, 0.6441873762582893E+00, 0.5561064852023264E+00, 0.5332801819376103E+00, 0.3323799891685881E+00, 0.2356658160961767E+00, 0.1910001776595044E+00, 0.1052937995306845E+00, 0.3493206724380617E-01, 0.1582963148293342E-01, 0.1362410302334481E-03, 0.2902907641693595E-19, 0.1235088787739235E-18, 0.5938156039510254E-18, 0.1190428480890818E+01, 0.2366582715663035E-29, 0.1736669751992271E-12, 0.4479686287025860E-12, 0.1098839257111754E+01, 0.4930380657631324E-31, 0.6845104399398104E-11, 0.1631652613834293E-10, 0.9060499827420537E+00, 0.3623410171350593E-13, 0.4397239464622790E-08, 0.8783797026819435E-08, 0.8483833633939547E+00, 0.1680831004707752E-20, 0.6292544501750849E-07, 0.1207646260809090E-06, 0.7423625631343986E+00, 0.1044536639065691E-17, 0.1870111343232326E+02, 0.1870111343232326E+02, 0.1030000000000000E+03, 0.3002267573696145E+01, 0.3883495145631068E+01, 0.8796985420666049E-06, 0.5561064852023264E+00, 0.6232001151245993E-28, 0.4765675419124029E-06, 0.5281771988202168E-06, 0.5332801819376103E+00, 0.5995342879679690E-28, 0.3211676631039122E-06, 0.3513325837054497E-06, 0.3323799891685881E+00, 0.2177256098409993E-25, 0.1826919937583927E-06, 0.1747056528730059E-06, 0.2356658160961767E+00, 0.1311326116357865E-17, 0.1784537561302489E-06, 0.2175474607275274E-06, 0.1910001776595044E+00, 0.3862262991962074E-24, 0.9127544222909640E-06, 0.4962248419758332E-06, 0.1052937995306845E+00, 0.1072850831100576E-26, 0.2872845137271569E-03, 0.1413151427897814E-03, 0.3493206724380617E-01, 0.8028654523313936E-17, 0.5779626756191757E-04, 0.4784930511330926E-04, 0.1582963148293342E-01, 0.9359045779542084E-26, 0.9339546012110267E-04, 0.6206712854083305E-04, 0.1362410302334481E-03, 0.4535950205020818E-29, 0.1799327870469576E-03, 0.1621654177500190E-02}, + info: 0, + }, + { + z: []float64{0.6327743759434090E-01, 0.8874473183212240E+00, 0.1587228549487630E+00, 0.1869853022948459E+00, 0.1852952724381735E+00, 0.2190328352455733E+00, 0.7936705141328082E+00, 0.1573124860628259E+00, 0.2446308768539528E+00, 0.2441044501798444E+00, 0.4435884001235265E+00, 0.1783624365771731E+00, 0.6874700271616803E+00, 0.4796486989431838E+00, 0.2471425348644392E+00, 0.4391077480264999E+00, 0.9973269002312380E+00, 0.4770343529783838E+00, 0.3451566405930041E+00, 0.5011834710046675E+00, 0.8072188861666797E+00, 0.5748577907200507E+00, 0.2986003422862493E+00, 0.4760318526964945E+00, 0.5838957192070238E-01, 0.1760621214885278E+00, 0.7926085978219721E+00, 0.3379849703418611E+00, 0.6012719579585296E+00, 0.1130783704430351E+00, 0.5590675745254436E-01, 0.8616930340961984E+00, 0.9917564091315376E+00, 0.4219575368674273E+00, 0.1044382974319413E+00, 0.1886528536659160E-01, 0.9337085742573710E+00, 0.6447952074628677E+00, 0.7158824182577913E+00, 0.3883216757352448E+00, 0.2116568255149501E+00, 0.9819105316462939E+00, 0.8471687522868032E-01, 0.2785996362910685E+00, 0.8775405646426044E+00, 0.5671584270354416E+00, 0.4912868754910720E+00, 0.5767395813214109E+00, 0.7327323379759062E+00, 0.8184048812627022E+00, 0.3325270745990432E+00, 0.3026500963479654E+00, 0.7228591188664935E+00, 0.1094677581261434E+00, 0.5280482398171430E+00, 0.9974727380694979E+00, 0.5087630734843742E+00, 0.6953603638889684E+00, 0.9103967979863506E+00, 0.2584730811693510E+00, 0.5498750728524477E+00, 0.9758543899455846E+00, 0.8309066632970131E+00, 0.4311646442586020E+00, 0.4732818688792167E+00, 0.4096051739313099E+00, 0.7479697576436509E+00, 0.9369473766445329E+00, 0.7380538090811954E+00, 0.1199951604231148E+00, 0.5672128274092054E+00, 0.7150763241893471E+00, 0.6134240647991112E+00, 0.7095501841622953E-01, 0.1510080432732774E-01, 0.2912426074708729E+00, 0.1611746025295486E+00, 0.3946903662654964E+00, 0.7408818971566200E-01, 0.3978128748254128E+00, 0.3580504147215868E+00, 0.2603799996304434E-01, 0.8990784999913340E+00, 0.1985602490013758E+00}, + n: 21, + zOut: []float64{0.2139906798692060E+01, 0.2104052265745164E+01, 0.2080474521860817E+01, 0.1784368581097839E+01, 0.1501145759273247E+01, 0.1395549430074518E+01, 0.1236063891814824E+01, 0.1123736402991315E+01, 0.8211474325690415E+00, 0.7411912844479571E+00, 0.7336682913123216E+00, 0.5274366057326734E+00, 0.3715621485686555E+00, 0.3171624722931449E+00, 0.2809062056956198E+00, 0.1668884413843382E+00, 0.9744092162322979E-01, 0.7613224124753509E-01, 0.1665106039654164E-01, 0.4700366860927376E-02, 0.1401918312945850E-02, 0.1084683744678891E-29, 0.4021673570416241E-08, 0.3931910860092540E-08, 0.1236063891814824E+01, 0.1439956010332256E-19, 0.3626387646080745E-08, 0.3543555828237728E-08, 0.1123736402991315E+01, 0.3006506681978320E-24, 0.3371387381785702E-08, 0.3448854867663729E-08, 0.8211474325690415E+00, 0.6197291271416269E-26, 0.2831422041774839E-08, 0.2886341750444270E-08, 0.7411912844479571E+00, 0.0000000000000000E+00, 0.2880306038760265E-08, 0.2936321908308739E-08, 0.7336682913123216E+00, 0.2406371799476454E-20, 0.1752158704199472E+02, 0.1752158704199472E+02, 0.1050000000000000E+03, 0.3111111111111111E+01, 0.7619047619047619E+01, 0.3652487989473621E-08, 0.3715621485686555E+00, 0.1451701975030564E-21, 0.4296538801302010E-08, 0.3992227758256396E-08, 0.3171624722931449E+00, 0.6162975822039155E-31, 0.5151357395533313E-08, 0.5974032086218965E-08, 0.2809062056956198E+00, 0.2039658356197591E-16, 0.1134165265363298E-07, 0.1513934018844884E-07, 0.1668884413843382E+00, 0.2400943524542200E-24, 0.1781584505522029E-06, 0.1218300442987205E-06, 0.9744092162322979E-01, 0.6162975822039155E-31, 0.9557876398738343E-06, 0.5872690889712619E-06, 0.7613224124753509E-01, 0.5074727415413836E-17, 0.2309052370169074E-04, 0.5924498773169641E-04, 0.1665106039654164E-01, 0.1400228106767296E-28, 0.5116509326795711E-04, 0.5154480234673206E-04, 0.4700366860927376E-02, 0.1956855682120442E-20, 0.1061141342429108E-03, 0.9755516139369119E-04, 0.1401918312945850E-02, 0.0000000000000000E+00, 0.1229085807195224E-02, 0.8009097549502667E-02}, + info: 0, + }, + { + z: []float64{0.7225493913848618E+00, 0.3268825038779278E+00, 0.2580957584922012E+00, 0.4222896610254372E+00, 0.8243187922209068E+00, 0.3973391932422579E+00, 0.3700698452657641E+00, 0.2073422474585492E+00, 0.3071746797249822E+00, 0.2370168833330754E+00, 0.7779583030993944E+00, 0.4350651843345934E+00, 0.7867543754352369E+00, 0.3439673345654075E+00, 0.3736479358698906E+00, 0.8450641599616520E+00, 0.3880138308747846E+00, 0.2479782080134303E+00, 0.3220864609073060E+00, 0.8460149388339712E+00, 0.6082870752479030E+00, 0.3396261004129498E+00, 0.1231305479976765E+00, 0.6514493424347317E+00, 0.4987273421671501E-01, 0.2199653339283912E+00, 0.5626339029868159E+00, 0.6755574738917364E+00, 0.7016850168758351E+00, 0.7957347983005405E+00, 0.3394687111682781E-01, 0.1490794513934588E+00, 0.9837873705641814E+00, 0.5038299137267350E+00, 0.8394265886439850E+00, 0.1438624872728633E-01, 0.4444190467253504E+00, 0.1489248400425094E+00, 0.6410535698206483E+00, 0.2739267916732867E+00, 0.6522097474411971E+00, 0.9086492388715542E+00, 0.1949071722314141E+00, 0.7176724675018002E+00, 0.9247176136838016E+00, 0.4929580602677628E+00, 0.3824418236647242E+00, 0.2425574232540663E+00, 0.7085287909144397E+00, 0.2574302555167504E+00, 0.6093160252921369E+00, 0.2417561032032995E+00, 0.4795262420397247E+00, 0.4658200993830509E+00, 0.9033699918994937E+00, 0.1295021719769064E+00, 0.6219991535812029E+00, 0.7040800557612208E+00, 0.8644629036591867E-01, 0.5129394685202899E+00, 0.7988983132437487E+00, 0.8322467913624354E+00, 0.9905487172695071E-01, 0.7093832076693246E+00, 0.1992462440538834E-01, 0.6378263512182120E+00, 0.5823949252324323E-02, 0.7826279628890456E+00, 0.5919828344466795E+00, 0.3815528510244244E+00, 0.6537355893096064E-01, 0.6459825623191251E-01, 0.4466210788758083E+00, 0.6620124961190184E+00, 0.6318809895815939E+00, 0.8145861476435108E+00, 0.5938169865214039E+00, 0.8092284578140500E+00, 0.5378701643349270E+00, 0.1648044346935199E+00, 0.9874291179811017E+00, 0.3210667070512012E+00, 0.6809988920516613E+00, 0.6410080963943865E+00}, + n: 21, + zOut: []float64{0.2108032684782400E+01, 0.1971253922847928E+01, 0.1952878543820764E+01, 0.1839982524288513E+01, 0.1730503177731785E+01, 0.1509287569836986E+01, 0.1316544049683026E+01, 0.1117715356834192E+01, 0.9058841126016787E+00, 0.8452427684353671E+00, 0.7582219581243467E+00, 0.6392786878439012E+00, 0.5749674919024932E+00, 0.5111167278611346E+00, 0.3859485208834002E+00, 0.2295319067023061E+00, 0.2262113890497363E+00, 0.1122658486667464E+00, 0.7234153262002044E-01, 0.4527048542558528E-01, 0.8319414807792288E-04, 0.2547288901631409E-13, 0.9052716547280089E-04, 0.7818093042872877E-04, 0.1316544049683026E+01, 0.0000000000000000E+00, 0.2537869832861900E-04, 0.2058109204222074E-04, 0.1117715356834192E+01, 0.0000000000000000E+00, 0.1154377886785102E-04, 0.1215574110748570E-04, 0.9058841126016787E+00, 0.8843729980912407E-17, 0.1391102994778336E-08, 0.5248885105740662E-08, 0.8452427684353671E+00, 0.2445468806185137E-28, 0.2192473584471834E-06, 0.3792344586441173E-06, 0.7582219581243467E+00, 0.6480317173221865E-17, 0.1885256245409039E+02, 0.1885256245409039E+02, 0.1090000000000000E+03, 0.3303854875283447E+01, 0.3669724770642202E+01, 0.3715603111278862E-08, 0.5749674919024932E+00, 0.4928548884551519E-18, 0.2515491583997865E-07, 0.9138389520203617E-08, 0.5111167278611346E+00, 0.6587911462745685E-21, 0.7857712130631377E-05, 0.2298529163657988E-05, 0.3859485208834002E+00, 0.6162975822039155E-32, 0.1022329296046741E-03, 0.8680151473672892E-04, 0.2295319067023061E+00, 0.0000000000000000E+00, 0.4616464530663241E-04, 0.3877924919889212E-04, 0.2262113890497363E+00, 0.5522026336547083E-29, 0.2365660345682357E-03, 0.1990352708186489E-03, 0.1122658486667464E+00, 0.9015102222917331E-20, 0.6825572508936817E-03, 0.6443371781720532E-03, 0.7234153262002044E-01, 0.1168271446196110E-24, 0.1518594231951364E-05, 0.3554999772664582E-05, 0.4527048542558528E-01, 0.1023373475125114E-24, 0.5037539097182833E-02, 0.4761613742874584E-02, 0.8319414807792288E-04, 0.1479114197289397E-30, 0.9105689905446296E-02, 0.4825995872157137E-02}, + info: 0, + }, + { + z: []float64{0.3256696334281521E+00, 0.7530856859911462E+00, 0.8853989127988440E+00, 0.4058112879440673E+00, 0.4296659748141172E+00, 0.5414662225246791E-01, 0.7727106089758434E+00, 0.8219533891865206E+00, 0.8804898818241804E+00, 0.2701661776792790E+00, 0.3062100113053869E+00, 0.7616550925245322E+00, 0.7441861437457686E+00, 0.1208643477044503E+00, 0.1894387751691341E+00, 0.5502297763300060E+00, 0.7033314588214317E+00, 0.9049640752657374E+00, 0.7642474001418834E+00, 0.6461873559439021E+00, 0.7323555348666727E+00, 0.6137344390498661E+00, 0.4469041036073067E+00, 0.6120974783290001E+00, 0.3695185251601272E+00, 0.9332999793731735E+00, 0.3981597952563400E+00, 0.5926926060619504E+00, 0.2218776156238759E+00, 0.5556127447847847E-01, 0.2642041684868913E+00, 0.3100431241269808E-01, 0.7617158805289858E+00, 0.5576464290832684E+00, 0.1499291988028689E+00, 0.6071627267784354E+00, 0.2903444085740193E+00, 0.8982141027722228E+00, 0.3437740722392461E+00, 0.5257340992985249E-02, 0.9772197173932363E+00, 0.2743313505008338E-01, 0.5939995532981283E+00, 0.8125099455585232E+00, 0.8394050677385213E+00, 0.2410326841076476E+00, 0.6066214991817382E+00, 0.1828025638429278E+00, 0.5406675263078469E+00, 0.1108622672142920E+00, 0.2412280709874803E+00, 0.5713495470758625E+00, 0.6315445401927943E+00, 0.2035563756883153E+00, 0.8696814083183412E+00, 0.2313134367709406E+00, 0.4474447231170641E+00, 0.6238312383525342E+00, 0.4961806049996582E+00, 0.8121574484576765E+00, 0.8702938949430352E+00, 0.4187164629520156E+00, 0.9204090241956668E+00, 0.8587176140225750E-02, 0.5171057705188283E+00, 0.5195595031109387E+00, 0.1704600468811621E+00, 0.3205951022793651E+00, 0.5643494948239225E-01, 0.9895063272544601E+00, 0.5554681247022339E+00, 0.6098243547887802E+00, 0.4730289261335907E+00, 0.1850396134174421E+00, 0.9997475966289492E+00, 0.6812817712215841E+00, 0.8515433432907883E+00, 0.7377047940023331E+00, 0.2280516830782600E+00, 0.7204549837953970E+00, 0.6096260713045146E+00, 0.9381128478076188E+00, 0.8446173293023428E+00, 0.6255387686605924E+00}, + n: 21, + zOut: []float64{0.2655567567233002E+01, 0.2307219644143945E+01, 0.2068899090176533E+01, 0.2040332602619700E+01, 0.1742115921396612E+01, 0.1681856112031183E+01, 0.1680515965675234E+01, 0.1379580829731510E+01, 0.1074312270120212E+01, 0.9816962393879983E+00, 0.7217300335876665E+00, 0.6931029681515243E+00, 0.5680300928567689E+00, 0.5098239945058581E+00, 0.4280073603039590E+00, 0.2868581986899945E+00, 0.1650069923584772E+00, 0.9685136354131559E-01, 0.5953175886938158E-01, 0.1010639579838301E-01, 0.1940920539235378E-02, 0.0000000000000000E+00, 0.6683246174917478E-10, 0.4267275295503314E-10, 0.1680515965675234E+01, 0.3510431028233503E-28, 0.1660414363340253E-09, 0.1048896312812690E-09, 0.1379580829731510E+01, 0.1462018530271286E-15, 0.3421106985799154E-06, 0.1788748688597153E-06, 0.1074312270120212E+01, 0.6708481546523056E-14, 0.2133146148219686E-04, 0.4629406838917969E-04, 0.9816962393879983E+00, 0.1747667198202037E-19, 0.5113942524303023E-03, 0.6287577911928029E-03, 0.7217300335876665E+00, 0.3213860550383917E-17, 0.2115308632171850E+02, 0.2115308632171849E+02, 0.1090000000000000E+03, 0.3217687074829932E+01, 0.4587155963302752E+01, 0.4202140396420195E-04, 0.5680300928567689E+00, 0.4489765112701642E-21, 0.3523329095202763E-09, 0.1167512512099963E-08, 0.5098239945058581E+00, 0.1652551767516096E-21, 0.2872281528375301E-06, 0.1040291448945555E-06, 0.4280073603039590E+00, 0.3262461795428160E-16, 0.6249760558326680E-04, 0.5475920486023645E-04, 0.2868581986899945E+00, 0.1568256893218114E-20, 0.1414968677825121E-03, 0.1814031293335571E-03, 0.1650069923584772E+00, 0.8677469957431130E-28, 0.6720068122740940E-03, 0.4975589868187537E-03, 0.9685136354131559E-01, 0.5127595883936577E-29, 0.9260272777115331E-03, 0.1730290225790419E-02, 0.5953175886938158E-01, 0.7227833914448031E-23, 0.5968169418548035E-04, 0.1670361992731526E-04, 0.1010639579838301E-01, 0.1295106991551472E-19, 0.1213518994781533E-03, 0.2534883535393275E-03, 0.1940920539235378E-02, 0.0000000000000000E+00, 0.1005634135102979E-02, 0.2318000467665894E-02}, + info: 0, + }, + { + z: []float64{0.1944566011999833E+00, 0.2181910996636003E+00, 0.3150099357031281E+00, 0.2091722274105127E+00, 0.6593858021341683E+00, 0.9426815336068497E+00, 0.5288011644568881E+00, 0.7784091503839152E+00, 0.1751638954124558E+00, 0.6164772800195180E+00, 0.6225196859922683E+00, 0.2786175486675760E+00, 0.1945914328217568E+00, 0.5779085626077999E+00, 0.5568218939451671E+00, 0.5170566254269496E+00, 0.5742861029155353E+00, 0.6923056150383281E+00, 0.5876692361605969E+00, 0.4295639666640205E+00, 0.8612105519992207E+00, 0.9963836880013683E+00, 0.2692934182903581E+00, 0.6181020857251435E+00, 0.1251902537663725E+00, 0.2838625146280274E+00, 0.2999174442521634E+00, 0.7258439193048929E+00, 0.2048904835805728E+00, 0.1174987481558037E+00, 0.6887427109309550E+00, 0.7409107864964065E+00, 0.5306892441542433E+00, 0.6214581212205206E-01, 0.1234501953117273E-01, 0.2038789370511589E+00, 0.6180963044354376E+00, 0.2820746320472540E+00, 0.4643004781082601E+00, 0.2642696366861867E+00, 0.4102198269957935E-01, 0.1495900075045802E+00, 0.2060405615637534E+00, 0.3399183002928583E+00, 0.7918555051917199E+00, 0.9699614514519834E+00, 0.2922678000248715E+00, 0.1376674512222148E+00, 0.2496993200590716E+00, 0.3432539555227123E+00, 0.5835005548357151E+00, 0.4094205671447549E+00, 0.4876670000237163E+00, 0.7973523995663028E+00, 0.8851386592921134E+00, 0.1523554028450115E+00, 0.7049520832902729E+00, 0.4689643982524618E+00, 0.4347705823917429E+00, 0.8152140283905303E+00, 0.9259201525760803E+00, 0.3175789772106010E+00, 0.3950010049586650E+00, 0.7107346574834400E+00, 0.8109922991383097E+00, 0.6889072760433030E+00, 0.7861311781839575E-02, 0.7751963519893628E+00, 0.7382950156197396E+00, 0.9729693586970557E+00, 0.7283826758396350E+00, 0.1269651196972527E+00, 0.3530947260257147E+00, 0.2061448083515627E-01, 0.5931058475369740E+00, 0.9689379021952851E+00, 0.3254887771415839E+00, 0.2808523639662175E-01, 0.6211468186653845E+00, 0.6037463613076512E+00, 0.8746435454108382E+00, 0.5300695323546331E+00, 0.5276801989236730E+00, 0.2128951663669798E-01}, + n: 21, + zOut: []float64{0.2424279264689105E+01, 0.2270324150901105E+01, 0.1935128898096250E+01, 0.1814500336114905E+01, 0.1538233405195664E+01, 0.1297421320254112E+01, 0.1267282488999314E+01, 0.1249158514677014E+01, 0.9155076211264116E+00, 0.8242950831432680E+00, 0.5949232544739386E+00, 0.5630079212779312E+00, 0.4530053256303904E+00, 0.3458193312768856E+00, 0.2146623096050983E+00, 0.1686454472303586E+00, 0.1155214217797334E+00, 0.5180948935108346E-01, 0.2789744048901975E-01, 0.8268186305777192E-02, 0.6680158028153346E-04, 0.0000000000000000E+00, 0.3986945646893946E-08, 0.7023072825762287E-08, 0.1267282488999314E+01, 0.0000000000000000E+00, 0.2355158572444734E-07, 0.1877711213087836E-07, 0.1249158514677014E+01, 0.3384506411488746E-20, 0.2648360770785381E-11, 0.1741394977127960E-10, 0.9155076211264116E+00, 0.3299177303725225E-12, 0.2487861145673591E-05, 0.4028407591944186E-05, 0.8242950831432680E+00, 0.2441420600100056E-16, 0.1869515956083083E-05, 0.1842279235203962E-05, 0.5949232544739386E+00, 0.2024938139529812E-20, 0.1807975801219765E+02, 0.1807975801219765E+02, 0.9300000000000000E+02, 0.2836734693877551E+01, 0.1075268817204301E+01, 0.9521662195121400E-05, 0.4530053256303904E+00, 0.1259501632163109E-23, 0.1468124594065504E-05, 0.4670591953230941E-05, 0.3458193312768856E+00, 0.7975064420889996E-22, 0.1308295990671250E-06, 0.6690001990389955E-07, 0.2146623096050983E+00, 0.1927976052360153E-26, 0.3812574759844485E-05, 0.3580340604691736E-05, 0.1686454472303586E+00, 0.3739200690747596E-27, 0.6844384387279355E-05, 0.5557405125771409E-05, 0.1155214217797334E+00, 0.7506098603421864E-21, 0.2139339757899294E-04, 0.3026575107963825E-04, 0.5180948935108346E-01, 0.3886068668379982E-20, 0.1983680974127293E-03, 0.1336830557694390E-03, 0.2789744048901975E-01, 0.1991084924777834E-26, 0.4443273484877918E-03, 0.6821022035819646E-03, 0.8268186305777192E-02, 0.1921747358113822E-20, 0.1778955160858100E-05, 0.3048292256883238E-06, 0.6680158028153346E-04, 0.7915528772828604E-21, 0.4499131616906370E-02, 0.1547765737453591E-02}, + info: 0, + }, + { + z: []float64{0.3849545441014558E+00, 0.9201984078647510E+00, 0.4611893507512446E+00, 0.9426704990067624E+00, 0.4513996483425642E+00, 0.3546824995764211E+00, 0.2673932938327498E+00, 0.2250322436282782E+00, 0.3003875396759296E+00, 0.8637078150569484E+00, 0.2463125523040188E-01, 0.6381498516846796E+00, 0.9054059378226459E+00, 0.9211368359293561E+00, 0.6899055937753183E+00, 0.6469675067081565E+00, 0.2524386712411693E+00, 0.4816130873217878E+00, 0.8437265349008123E+00, 0.8843672501609817E+00, 0.3917808232071412E+00, 0.4109107468556734E+00, 0.6294664210780233E+00, 0.5231064834871043E+00, 0.6006449315760222E+00, 0.2321330919598237E+00, 0.9857216391074231E-01, 0.5246894901632879E+00, 0.2429723268334654E+00, 0.3385437000243748E+00, 0.1784805178646218E+00, 0.8008314854810928E+00, 0.3388059467143087E+00, 0.4957241256656372E+00, 0.6108069077503485E+00, 0.8350989375447051E+00, 0.1087391555565628E+00, 0.5847974581188020E+00, 0.8316850716702742E+00, 0.8921011586703487E+00, 0.1947070853010260E+00, 0.1394928972102342E+00, 0.7929088249487071E+00, 0.4078510186300481E+00, 0.6849316610029904E+00, 0.1436003498260631E+00, 0.5673845335495399E+00, 0.7998164012861997E-01, 0.6667892725157643E+00, 0.7612117828169483E+00, 0.8195812739875934E+00, 0.1507277483884870E+00, 0.6683936863561600E+00, 0.1889659251016290E+00, 0.7979363461805246E+00, 0.9481151487908223E+00, 0.3017570036067704E+00, 0.2677628114499495E+00, 0.4479716416042271E+00, 0.3773062273227097E+00, 0.1756267436681674E+00, 0.6251009447636316E+00, 0.3010990216120933E+00, 0.6044916624270988E+00, 0.3012752666004853E+00, 0.7113839134297870E+00, 0.7355680503868338E+00, 0.1830572310895536E+00, 0.2065116792960049E+00, 0.2432895898830973E+00, 0.9615089470298006E+00, 0.3137165160357294E+00, 0.5335631824040450E+00, 0.8324142824771229E+00, 0.9749825715503555E+00, 0.3108065469391890E+00, 0.2584483510692804E+00, 0.5679665509067858E+00, 0.9084113884935793E+00, 0.3061643504016712E+00, 0.1856860631474661E+00, 0.4086356189591027E+00, 0.2761517708925276E+00, 0.9203155374121844E+00}, + n: 21, + zOut: []float64{0.2651616639993538E+01, 0.2278042999629812E+01, 0.2198077975076974E+01, 0.2185608493228643E+01, 0.1866238785250178E+01, 0.1694317687161655E+01, 0.1314780820581521E+01, 0.1267230115137409E+01, 0.1165102366599241E+01, 0.1094106513205574E+01, 0.9375639320451692E+00, 0.7228525903025090E+00, 0.5063995930233953E+00, 0.4433597755655621E+00, 0.3782868675227946E+00, 0.2710178897462153E+00, 0.1447594933682902E+00, 0.1060101050946834E+00, 0.8449698031014202E-01, 0.1468593250969371E-01, 0.8406928034951682E-06, 0.3591986573571771E-20, 0.3864386735331416E-10, 0.3252595492372177E-10, 0.1314780820581521E+01, 0.1447952803137974E-21, 0.5374081097788385E-10, 0.4849713226733927E-10, 0.1267230115137409E+01, 0.2958228394578794E-29, 0.8017357434413146E-10, 0.7063808972759981E-10, 0.1165102366599241E+01, 0.1139115147139141E-26, 0.1961041727821929E-09, 0.1374026522849091E-09, 0.1094106513205574E+01, 0.3915388343685865E-19, 0.1756082891845291E-08, 0.3338672481507716E-08, 0.9375639320451692E+00, 0.4870203640784043E-16, 0.2132455639604580E+02, 0.2132455639604580E+02, 0.9900000000000000E+02, 0.2972789115646258E+01, 0.5050505050505050E+01, 0.1300256830939750E-04, 0.5063995930233953E+00, 0.4338734978715565E-29, 0.3205424704587136E-04, 0.3879495859639124E-04, 0.4433597755655621E+00, 0.9466330862652142E-25, 0.6653798840082298E-04, 0.6266988927201412E-04, 0.3782868675227946E+00, 0.2274100449667269E-22, 0.3059080514749475E-04, 0.2450157710629126E-04, 0.2710178897462153E+00, 0.2739429933906694E-24, 0.4451877567018950E-05, 0.2739439060253447E-05, 0.1447594933682902E+00, 0.1897052704875489E-25, 0.3311215248867682E-05, 0.2822048496282046E-05, 0.1060101050946834E+00, 0.7924889161564951E-19, 0.2588042287900903E-05, 0.3305698843095029E-05, 0.8449698031014202E-01, 0.2523395625690618E-18, 0.1425730854724969E-04, 0.2612802087529877E-04, 0.1468593250969371E-01, 0.7520086356827106E-20, 0.6278930605158724E-03, 0.1193309863751681E-02, 0.8406928034951682E-06, 0.0000000000000000E+00, 0.8769018979884540E-02, 0.6748334476252631E-02}, + info: 0, + }, + { + z: []float64{0.5539290016733247E+00, 0.6936589108803458E+00, 0.1862325586311042E-01, 0.3903593359823143E+00, 0.1387446022374186E+00, 0.9230050933369500E+00, 0.1655735508788293E+00, 0.5464594833562775E+00, 0.4407574799078734E+00, 0.7597516703282015E+00, 0.3240675365298944E+00, 0.8527429657828770E+00, 0.6134024974884296E+00, 0.1359668624923763E+00, 0.8589771621484943E+00, 0.8334002673394481E+00, 0.3811010712979018E+00, 0.4518439634289880E+00, 0.4121953913957921E-01, 0.1499929777106017E+00, 0.7537932319194001E+00, 0.1137770685080763E+00, 0.9362285670837264E+00, 0.2284833451474525E+00, 0.4661006612092690E+00, 0.3461611111488332E+00, 0.1608705680575839E-01, 0.9250298701911358E+00, 0.5983544857783111E+00, 0.9400090024445320E+00, 0.6595514287179831E+00, 0.2725099566160494E+00, 0.6509556024164401E+00, 0.8851211780351773E+00, 0.5925872091724521E+00, 0.5318402341230010E+00, 0.3225952236300995E+00, 0.6233031538827258E+00, 0.1806586091116282E+00, 0.9476369741031940E+00, 0.6784219735316235E+00, 0.6934023884718178E+00, 0.5000312772557033E+00, 0.6725383579734943E+00, 0.6771923299216058E+00, 0.9125469473100194E+00, 0.9862018367238429E+00, 0.7259311136907298E+00, 0.9021849324334038E+00, 0.6032549715715884E+00, 0.9017706724408630E+00, 0.8975979926873651E+00, 0.5949035726420406E+00, 0.6903449880442312E+00, 0.7574844360343417E+00, 0.2889632382233942E-01, 0.9428474184445177E+00, 0.5555118914598791E+00, 0.8663544108664935E+00, 0.6853450780608091E+00, 0.1464483859238053E+00, 0.6491672315887742E+00, 0.2994712877436206E+00, 0.3101752077576794E+00, 0.4920466664329196E+00, 0.2135103260181662E+00, 0.3809190441316870E+00, 0.8437350743416491E+00, 0.5443983884818225E+00, 0.7426189539459086E+00, 0.1055227287563778E+00, 0.3059118205598027E+00, 0.8189910523272392E+00, 0.9773505795713493E+00, 0.7305661438576656E+00, 0.6062516615534109E+00, 0.4660033490547544E+00, 0.5413353206637471E+00, 0.2388208915142312E+00, 0.6428463909118429E+00, 0.2982699820336984E+00, 0.2856298024316706E-01, 0.5487207914459959E+00, 0.4464180688275057E+00}, + n: 21, + zOut: []float64{0.2448593467642387E+01, 0.2141330855004301E+01, 0.2126430153924173E+01, 0.1907639051889359E+01, 0.1812500110390200E+01, 0.1510069013602020E+01, 0.1441897976798092E+01, 0.1263171337642769E+01, 0.1138107892295268E+01, 0.1088450894719558E+01, 0.9398511957468885E+00, 0.8468227425873083E+00, 0.6124964740092524E+00, 0.5436278175488470E+00, 0.4066256939946141E+00, 0.3972422051503922E+00, 0.2390787026361968E+00, 0.4848296808782174E-01, 0.2905803980602126E-01, 0.1302961362478940E-02, 0.3616542154739030E-05, 0.3187755557432356E-18, 0.8836722322771784E-05, 0.6065531139006927E-05, 0.1441897976798092E+01, 0.7730421460348975E-16, 0.3574427637238573E-07, 0.1935178018527985E-07, 0.1263171337642769E+01, 0.8058524406205312E-18, 0.1418632976070110E-05, 0.4069026170914173E-05, 0.1138107892295268E+01, 0.1371633476674845E-23, 0.4721385684453755E-04, 0.3623692584267971E-04, 0.1088450894719558E+01, 0.1790018845564752E-20, 0.4055026077404345E-04, 0.2446096735206838E-04, 0.9398511957468885E+00, 0.3178330447896772E-25, 0.2094278317138010E+02, 0.2094278317138010E+02, 0.1040000000000000E+03, 0.3031746031746032E+01, 0.4807692307692307E+01, 0.8138465546053722E-05, 0.6124964740092524E+00, 0.1019617235038814E-22, 0.4736809894069740E-03, 0.1915264360566004E-03, 0.5436278175488470E+00, 0.2004410489406572E-21, 0.1259085689345719E-03, 0.2338760337361548E-03, 0.4066256939946141E+00, 0.1231392444306089E-15, 0.6226403214695822E-04, 0.7644683470656998E-04, 0.3972422051503922E+00, 0.5914962592392188E-17, 0.1887068321547840E-03, 0.1345267246510674E-03, 0.2390787026361968E+00, 0.1936824017247308E-20, 0.7333182971373067E-03, 0.1062997506116107E-02, 0.4848296808782174E-01, 0.3799154119544393E-26, 0.1269933545612727E-03, 0.1297822869175177E-03, 0.2905803980602126E-01, 0.8465676581597317E-24, 0.5642309440908588E-03, 0.2732446225021143E-03, 0.1302961362478940E-02, 0.2467375723434259E-18, 0.9177892725485271E-03, 0.8034707353774361E-03, 0.3616542154739030E-05, 0.2761013168273541E-28, 0.6531167933367503E-03, 0.6727959129527735E-03}, + info: 0, + }, + { + z: []float64{0.7455810318731756E+00, 0.1881309445499726E+00, 0.6290241532486281E+00, 0.9426231091333456E+00, 0.1402641401457146E+00, 0.5545071521563689E+00, 0.3467970399972181E+00, 0.6378935846273492E-01, 0.8187242451993508E+00, 0.8444039716090014E+00, 0.8807815832461214E+00, 0.6871811349512845E+00, 0.6041217734774926E+00, 0.2285364565760638E+00, 0.6287288909172152E+00, 0.5441550558534458E+00, 0.6062929607453951E+00, 0.1528830611582420E+00, 0.7289323622783690E+00, 0.8693274251763169E+00, 0.1210720262902459E+00, 0.4752572018677603E+00, 0.8160358228459934E+00, 0.5003926181135285E+00, 0.2800920281530351E+00, 0.3817159580569316E+00, 0.1419563352692587E+00, 0.9738793587569783E+00, 0.2402077997739175E+00, 0.5021080238100061E+00, 0.5325521311583831E+00, 0.7002793445871702E+00, 0.2004913666518293E-01, 0.6858750037076770E+00, 0.5705320248969311E+00, 0.6000416876176061E+00, 0.9254592880635680E+00, 0.2987366812581649E+00, 0.8838368946481180E+00, 0.7495294261248863E+00, 0.2516401660161148E+00, 0.5770724542103510E+00, 0.8689432882806168E+00, 0.3108844333247283E+00, 0.7611598373381380E+00, 0.9533545884676758E+00, 0.6146629999183371E+00, 0.7337933880625785E+00, 0.1335018938357140E+00, 0.4054745880121539E+00, 0.9816031767048012E+00, 0.5190257866591561E+00, 0.9457220484783406E+00, 0.2563725588490263E+00, 0.8953616129834293E+00, 0.1343673038869742E+00, 0.1198867110907023E+00, 0.7765966504091196E+00, 0.1685346783514826E+00, 0.9322265874533907E+00, 0.4968937019786546E+00, 0.3933065437909874E+00, 0.7046190939244956E-01, 0.5772052710604483E+00, 0.1220174671595003E+00, 0.3586914192309758E+00, 0.4743117898783903E+00, 0.1205436116155321E+00, 0.2068106627971966E-01, 0.5035688415619853E+00, 0.2656792568844590E-01, 0.4951625786650252E+00, 0.1600264513881963E+00, 0.4218870487180432E+00, 0.4847863747130776E-01, 0.9478135093620923E+00, 0.1811694594266104E+00, 0.5311488460048615E+00, 0.2296061187775216E+00, 0.9932681440344262E+00, 0.2007921586496573E+00, 0.9684478357621775E+00, 0.9322927111902295E+00, 0.6234102172880590E+00}, + n: 21, + zOut: []float64{0.2617080551859897E+01, 0.2305187568066598E+01, 0.1942735806791493E+01, 0.1834812272403632E+01, 0.1760060933961288E+01, 0.1720372963502770E+01, 0.1676173250234917E+01, 0.1530300579122039E+01, 0.1214313538868506E+01, 0.1146550683576815E+01, 0.9555081169996513E+00, 0.8235353939361046E+00, 0.7281321711646775E+00, 0.5964515885643180E+00, 0.4105953672636856E+00, 0.2154672622243388E+00, 0.1469861329023305E+00, 0.1350631498164301E+00, 0.8120368457133148E-01, 0.1548517647968005E-01, 0.1861612641330624E-04, 0.6389970231972139E-21, 0.6259229043737505E-18, 0.1065975851985723E-17, 0.1676173250234917E+01, 0.1398996249446581E-17, 0.1485385179581525E-16, 0.5390878377546583E-16, 0.1530300579122039E+01, 0.1934286939601921E-26, 0.4995235293268131E-13, 0.1480097232724468E-13, 0.1214313538868506E+01, 0.1393981231259665E-11, 0.4031414073293921E-10, 0.9065983401759033E-10, 0.1146550683576815E+01, 0.7754818242684634E-25, 0.9068533370171412E-09, 0.1932480064220526E-08, 0.9555081169996513E+00, 0.5937598997073433E-12, 0.2185603480843691E+02, 0.2185603480843692E+02, 0.1010000000000000E+03, 0.3183673469387755E+01, 0.2970297029702970E+01, 0.4106209724092858E-05, 0.7281321711646775E+00, 0.2221432309102369E-26, 0.2012416535197213E-04, 0.1179395510019159E-04, 0.5964515885643180E+00, 0.6492360922940637E-17, 0.6055695087058826E-05, 0.1676327789285107E-04, 0.4105953672636856E+00, 0.1174834768927548E-24, 0.8526024871833974E-05, 0.9608606324255413E-05, 0.2154672622243388E+00, 0.1186446801452402E-26, 0.9887524717240814E-05, 0.1072842889916555E-04, 0.1469861329023305E+00, 0.0000000000000000E+00, 0.1666923382276663E-04, 0.2139923074663986E-04, 0.1350631498164301E+00, 0.4860988391194038E-18, 0.4968094868839375E-08, 0.1325007303324406E-08, 0.8120368457133148E-01, 0.5476819983069490E-18, 0.5501364953991437E-04, 0.1068949633822309E-04, 0.1548517647968005E-01, 0.6621786174648700E-13, 0.4934492558904634E-03, 0.7815729865935395E-03, 0.1861612641330624E-04, 0.0000000000000000E+00, 0.2047621357235247E-01, 0.1218736604744046E-01}, + info: 0, + }, + { + z: []float64{0.1913768959569714E+00, 0.7347223265181069E+00, 0.9087350122086006E+00, 0.8876448886267929E-02, 0.1794058368310475E+00, 0.3375830657319635E+00, 0.4153249303964603E+00, 0.3079259326141542E+00, 0.5095638682609168E+00, 0.6300946130469818E+00, 0.5367870439046851E-02, 0.6082577193589970E+00, 0.6096872650047096E+00, 0.8098482943683755E+00, 0.4018780482667224E+00, 0.1612961166583111E+00, 0.4165836183710623E+00, 0.6711774659609234E+00, 0.1871437048914691E+00, 0.2043648411447756E+00, 0.4603921058522200E+00, 0.5138380788557162E-01, 0.3299651081607302E+00, 0.5178779891127856E+00, 0.8488474652006981E+00, 0.4000528745818374E+00, 0.7038372186752184E-01, 0.1091866126814279E+00, 0.4601541814804277E-01, 0.2814862519917873E+00, 0.5969661695911915E+00, 0.1111325580672384E+00, 0.1377964900539917E+00, 0.4488655138014651E+00, 0.5793089439934721E+00, 0.4068390675279384E+00, 0.3141858292757815E-01, 0.3803058398371814E+00, 0.6865263808463873E-01, 0.6565571596516916E+00, 0.4227763797508006E+00, 0.9281332433572439E+00, 0.2549706813172651E+00, 0.1472316879439791E+00, 0.8389980826186394E+00, 0.4949206978487660E+00, 0.8778524239605636E+00, 0.8125876339222501E+00, 0.6384442407604712E+00, 0.6297206683503800E+00, 0.1074594814776241E+00, 0.4635106216187717E+00, 0.2149027083261391E+00, 0.2926633791426133E+00, 0.8718806127632718E+00, 0.9358351753143842E+00, 0.5812389276262170E+00, 0.8361764419241092E+00, 0.1334582685582402E+00, 0.6700349085889619E+00, 0.1370175035793201E+00, 0.2605729802823288E+00, 0.7055670307426516E+00, 0.1974656950667419E-01, 0.9516894704106690E+00, 0.7509460514650641E+00, 0.9770872584819335E-01, 0.1679929405438133E+00, 0.2605432695744189E+00, 0.7255281751885829E+00, 0.2060091110826470E+00, 0.5123028703888126E+00, 0.5392241233948379E+00, 0.3215743887975069E+00, 0.4306560982435532E+00, 0.9326432909148183E+00, 0.1891146429259456E+00, 0.5585690444839775E+00, 0.8103752159402208E+00, 0.3850798219907741E+00, 0.6027394925107610E-01, 0.6960376568363590E+00, 0.6132631218829975E+00, 0.5859904896405407E+00}, + n: 21, + zOut: []float64{0.1948845699194504E+01, 0.1757754653408917E+01, 0.1739740003489702E+01, 0.1427189755042558E+01, 0.1354312190162734E+01, 0.1300861212306309E+01, 0.1144086431430055E+01, 0.9728683413380136E+00, 0.7924660843958955E+00, 0.7190108168957414E+00, 0.5334843173898538E+00, 0.4234595469843583E+00, 0.3840099969172215E+00, 0.2310167712576353E+00, 0.1706582281146164E+00, 0.1481114719972525E+00, 0.9844570800522298E-01, 0.8643465546688130E-01, 0.2116850399857309E-01, 0.1490679637756442E-02, 0.9506251872618699E-05, 0.0000000000000000E+00, 0.3139247800552953E-11, 0.1114956279480716E-10, 0.1144086431430055E+01, 0.2611946364919696E-16, 0.1910542599593587E-05, 0.1867627468366115E-05, 0.9728683413380136E+00, 0.3548331964791209E-13, 0.9422609200466975E-06, 0.3861796048985941E-05, 0.7924660843958955E+00, 0.4543838814073028E-27, 0.1545075054473009E-06, 0.2314398440634665E-06, 0.7190108168957414E+00, 0.1033975765689929E-24, 0.9239329035775786E-07, 0.1002180390059042E-06, 0.5334843173898538E+00, 0.0000000000000000E+00, 0.1525542457368567E+02, 0.1525542457368567E+02, 0.1120000000000000E+03, 0.3308390022675737E+01, 0.5357142857142857E+01, 0.1175851227353848E-05, 0.3840099969172215E+00, 0.1009741958682895E-27, 0.6285056589702800E-05, 0.7777675415159152E-05, 0.2310167712576353E+00, 0.4642054879586336E-19, 0.2707022647265855E-04, 0.1462219920606713E-04, 0.1706582281146164E+00, 0.0000000000000000E+00, 0.1442808298792521E-03, 0.1499267314065209E-03, 0.1481114719972525E+00, 0.1784642171583157E-21, 0.9060208842449760E-06, 0.2604899516157433E-05, 0.9844570800522298E-01, 0.3285517707584525E-17, 0.4009882974094740E-08, 0.9813054658490708E-08, 0.8643465546688130E-01, 0.1441804758967627E-17, 0.1005867330167897E-05, 0.3548177460196556E-06, 0.2116850399857309E-01, 0.1161145423573808E-16, 0.4264476922944564E-04, 0.6523019800084465E-04, 0.1490679637756442E-02, 0.5282426871388410E-23, 0.4120097727637851E-03, 0.5256559484655862E-03, 0.9506251872618699E-05, 0.7858215819253763E-23, 0.4122429400478702E-03, 0.4195795458123320E-03}, + info: 0, + }, + { + z: []float64{0.8707866955342474E+00, 0.7817747598907121E-01, 0.3395074897480099E-01, 0.4299950297507704E+00, 0.8088090483755312E+00, 0.8059665333356031E+00, 0.8715468955879169E-01, 0.7726332912417854E+00, 0.8113440783694211E+00, 0.3884398998833286E+00, 0.2376236729669906E+00, 0.1163685212573567E+00, 0.9165435854442110E+00, 0.6267984817484763E+00, 0.9624876615834328E+00, 0.3034180669232360E+00, 0.2061796047621195E+00, 0.5768621491208505E+00, 0.9925917678590149E+00, 0.6443157924817072E+00, 0.5967958277754652E+00, 0.6529032825080359E+00, 0.2463148548215904E+00, 0.3434579503978075E+00, 0.9563439871443443E+00, 0.2121028540747388E+00, 0.7195547303990343E+00, 0.2508441805243417E+00, 0.1006260142041168E+00, 0.8893309100691102E+00, 0.5028754540045453E+00, 0.8271029410166070E+00, 0.1744058577319449E+00, 0.1497291367846938E+00, 0.9760674104574272E+00, 0.1217237467828105E+00, 0.5182991497218187E+00, 0.9638099804000833E-01, 0.3920754919448237E+00, 0.5405769677178972E+00, 0.2099631365577761E+00, 0.7305783624173950E+00, 0.5230361650507421E+00, 0.3249231142539155E+00, 0.6943021078034506E+00, 0.8039502137729849E+00, 0.5430939865698426E+00, 0.5802454813209417E+00, 0.4521353811622019E+00, 0.6022646695138674E+00, 0.5085578584349214E+00, 0.2084880202460930E+00, 0.7893764544854661E+00, 0.8499187425465698E+00, 0.6507732600828079E+00, 0.6030189256946239E+00, 0.2748834677816949E+00, 0.7991444375081345E+00, 0.3953548021356785E+00, 0.8063610109500122E+00, 0.9322494176165492E+00, 0.2295756744488692E+00, 0.9380170922026533E+00, 0.6349173046266506E+00, 0.8138238710526029E+00, 0.1723717901392456E+00, 0.7436778507578146E+00, 0.9748296910217159E+00, 0.9719004334667378E+00, 0.1097372829332979E+00, 0.6782829454939702E+00, 0.5097404868982898E+00, 0.9485025358778609E+00, 0.7313319469015522E-01, 0.6156780373408383E+00, 0.8764490831370680E+00, 0.2737186188000360E+00, 0.3500606337779347E+00, 0.7029831161979777E+00, 0.1747477098480691E+00, 0.8887436470613648E+00, 0.8441051781034927E+00, 0.3534934185139980E+00, 0.9278581973721739E+00}, + n: 21, + zOut: []float64{0.2399590582568773E+01, 0.2223029747781157E+01, 0.2028465681071774E+01, 0.1928601105940012E+01, 0.1734632538043284E+01, 0.1705587556623443E+01, 0.1335586809119933E+01, 0.1201248979220471E+01, 0.1103973785860777E+01, 0.9516762968928613E+00, 0.8501027578146555E+00, 0.7334218559333251E+00, 0.5694462065979470E+00, 0.4616704914677346E+00, 0.3869349008726894E+00, 0.2370229392379994E+00, 0.1895639186923105E+00, 0.6837204156138489E-01, 0.3336561258733767E-01, 0.4796873010443177E-02, 0.8309969413683648E-03, 0.1974829088984998E-20, 0.1178494024155901E-08, 0.8095343015842228E-09, 0.1335586809119933E+01, 0.2220446049250313E-15, 0.1020576889344504E-06, 0.1802026823995536E-06, 0.1201248979220471E+01, 0.0000000000000000E+00, 0.6243063866214613E-06, 0.3862955415798747E-06, 0.1103973785860777E+01, 0.6981113564263453E-22, 0.3544097463307990E-10, 0.1357364267827356E-10, 0.9516762968928613E+00, 0.9072531498765813E-25, 0.7979152396248553E-09, 0.3946058728874109E-09, 0.8501027578146555E+00, 0.3130538746543124E-14, 0.2014792167783968E+02, 0.2014792167783968E+02, 0.1020000000000000E+03, 0.3129251700680272E+01, 0.5882352941176471E+01, 0.5818593578868780E-05, 0.5694462065979470E+00, 0.1588643710672175E-16, 0.4031382989989102E-05, 0.4054337523014161E-05, 0.4616704914677346E+00, 0.4437342591868191E-30, 0.3922192530785082E-05, 0.4209867122852495E-05, 0.3869349008726894E+00, 0.1490631566505624E-25, 0.4185837521330395E-06, 0.8450171931154743E-06, 0.2370229392379994E+00, 0.9509832565716118E-20, 0.2486232683772935E-03, 0.1020105306066691E-03, 0.1895639186923105E+00, 0.4152563805083406E-26, 0.4122104994398350E-03, 0.2603466333914367E-03, 0.6837204156138489E-01, 0.2482703040911568E-24, 0.1451022916339763E-02, 0.8718585538326752E-03, 0.3336561258733767E-01, 0.7888609052210118E-30, 0.3124612722893384E-02, 0.2800832977531187E-02, 0.4796873010443177E-02, 0.5945360652724886E-23, 0.1330631700030230E-06, 0.1700369028500688E-07, 0.8309969413683648E-03, 0.0000000000000000E+00, 0.1665788949608015E-02, 0.1927727749653244E-02}, + info: 0, + }, + { + z: []float64{0.5557143146495949E+00, 0.5989968816903124E+00, 0.2940668070493605E+00, 0.6865591553636113E+00, 0.2538362881116337E+00, 0.8562930572057048E-01, 0.8935270452331215E+00, 0.2427258280604294E-01, 0.8872146530392093E+00, 0.8383596820641517E+00, 0.7298494135137694E+00, 0.5456106579379609E+00, 0.5284508278981448E+00, 0.4551015440756836E+00, 0.8310297436868961E+00, 0.2533050402685522E+00, 0.8204820449217906E+00, 0.3961557150240700E+00, 0.9768702237400030E+00, 0.2370292739142171E+00, 0.2559318188841475E-02, 0.9750517337670606E-01, 0.4332045279801727E+00, 0.9393777930670477E+00, 0.1401411199977110E-01, 0.6412771440674316E+00, 0.3992540155849937E+00, 0.6710909099058460E+00, 0.7286319488310415E+00, 0.2796269361967505E+00, 0.7441899058930037E+00, 0.6626826587793098E+00, 0.9214594500725222E+00, 0.3161807402236700E+00, 0.5522479249937589E+00, 0.8328895958825197E+00, 0.3188368475648113E+00, 0.7495883496609020E+00, 0.7525354981370723E+00, 0.4819658709067065E-01, 0.8655147680740739E+00, 0.9438778396406793E+00, 0.2488475915004000E+00, 0.6823535213934872E+00, 0.1937525404626215E+00, 0.5005903164733780E+00, 0.8863816362271992E-01, 0.8279647895785316E+00, 0.7576076924432378E+00, 0.7026499641621615E+00, 0.4430381204856144E+00, 0.7250369983032848E+00, 0.6848785243425647E+00, 0.4460397323983623E+00, 0.4708648248777212E+00, 0.2715064773162834E+00, 0.3027887490966231E+00, 0.7428389405348396E+00, 0.4450045451144832E+00, 0.4683793136386452E+00, 0.2207684946192057E+00, 0.2427030064074031E+00, 0.9554840783351275E+00, 0.4627007756736100E+00, 0.2498171419709001E+00, 0.6457883819068694E+00, 0.9852852516910280E+00, 0.1549706320399313E-01, 0.5863698153730145E+00, 0.8639664213849532E+00, 0.3535803218615043E+00, 0.5300900503312423E+00, 0.6390014357018353E+00, 0.7961857807391770E+00, 0.2691637990251612E+00, 0.5302467438659471E+00, 0.3050412123368091E+00, 0.6256487701731338E+00, 0.3334512397543001E+00, 0.4160884062357342E+00, 0.1255438899512573E+00, 0.1645317210625844E+00, 0.3238197294562333E+00, 0.8765325383521217E+00}, + n: 21, + zOut: []float64{0.2427342887003738E+01, 0.2350720031505609E+01, 0.2023223336640000E+01, 0.1998000565720247E+01, 0.1766392007527096E+01, 0.1571733737439641E+01, 0.1560415852981921E+01, 0.1417948678305651E+01, 0.1258973312710257E+01, 0.1056655934390461E+01, 0.8835393928887348E+00, 0.8723851974669989E+00, 0.7820423442972025E+00, 0.7419840433476598E+00, 0.4998280519834369E+00, 0.4045332331022956E+00, 0.9795545665796999E-01, 0.6816976350034422E-01, 0.5040003524610775E-01, 0.3066447317814986E-01, 0.1707038609221110E-04, 0.0000000000000000E+00, 0.7788285758834551E-10, 0.4967814553062384E-10, 0.1560415852981921E+01, 0.2584939414223288E-25, 0.2197123097785426E-09, 0.1273532664170934E-09, 0.1417948678305651E+01, 0.1666074231826777E-26, 0.1275101209751314E-13, 0.3690153580151478E-13, 0.1258973312710257E+01, 0.3205217501722064E-17, 0.9823174457391989E-10, 0.2521354047663225E-09, 0.1056655934390461E+01, 0.7258232531419596E-14, 0.3712131332588551E-06, 0.9470624651125662E-06, 0.8835393928887348E+00, 0.1013078509970455E-14, 0.2186292540627962E+02, 0.2186292540627962E+02, 0.1200000000000000E+03, 0.3639455782312925E+01, 0.8333333333333334E+01, 0.8044662327724623E-11, 0.7820423442972025E+00, 0.1609007833004439E-16, 0.1435272653873044E-05, 0.2709954877521105E-06, 0.7419840433476598E+00, 0.7040565915227063E-17, 0.3841536774665796E-05, 0.2871402006582635E-05, 0.4998280519834369E+00, 0.2100142105025380E-22, 0.2079096157763567E-04, 0.3245111531694086E-04, 0.4045332331022956E+00, 0.1391829401523057E-17, 0.6737785910120600E-04, 0.9764140649613147E-04, 0.9795545665796999E-01, 0.0000000000000000E+00, 0.6779864796214124E-03, 0.3130513090482015E-03, 0.6816976350034422E-01, 0.2326445472805242E-24, 0.3547436816484852E-02, 0.2240007954218211E-02, 0.5040003524610775E-01, 0.1487168151587342E-22, 0.3710761871988309E-06, 0.2590766399899962E-07, 0.3066447317814986E-01, 0.7395570986446986E-31, 0.2806228106658499E-03, 0.1300265719680322E-02, 0.1707038609221110E-04, 0.5107323294632100E-21, 0.5584126334680110E-02, 0.2863707539154273E-03}, + info: 0, + }, + { + z: []float64{0.8091224458140820E+00, 0.8008972278830493E+00, 0.2578176398184776E+00, 0.1256248089219657E+00, 0.6581359192692769E+00, 0.2304361454551056E+00, 0.7582551898966047E+00, 0.1757884371165862E+00, 0.3186400696162690E+00, 0.7479165768101737E+00, 0.3726824047207358E+00, 0.8797387692666324E+00, 0.5750380180879821E+00, 0.5660816893967801E+00, 0.4438713938433396E+00, 0.1758644078670230E+00, 0.5631776732547016E+00, 0.3584358301396408E+00, 0.9436101806256550E+00, 0.5626737326978751E+00, 0.6424649400467324E+00, 0.8481112336470399E+00, 0.5655978701315552E+00, 0.8705727446437589E+00, 0.2336253154027212E-01, 0.5296192722406249E+00, 0.2416414888807097E+00, 0.8901032371078870E+00, 0.6213866196646989E+00, 0.7130035148592161E+00, 0.7957781913464947E+00, 0.8476792055481847E+00, 0.9456821938668590E+00, 0.9119251640705257E+00, 0.6793496748825844E+00, 0.1959111178023272E+00, 0.1712010119398182E+00, 0.1826738976471362E+00, 0.2526159624017289E+00, 0.1636253698204285E+00, 0.5186411299293459E+00, 0.9760895321955887E-01, 0.6893646610477002E+00, 0.9919227436537437E-01, 0.3790249398464486E+00, 0.9060767708258410E+00, 0.1329141344440885E+00, 0.8748053076614649E+00, 0.3613991427617499E+00, 0.1317424493721138E+00, 0.1676759484196766E-01, 0.7195688942861501E+00, 0.7508197149131951E+00, 0.1084062966598669E+00, 0.7799888885196686E+00, 0.8731271868042269E+00, 0.7281667421703623E+00, 0.5506096404209293E+00, 0.2344365678709384E+00, 0.8253982006984435E+00, 0.6925029659724733E+00, 0.2137159289768908E+00, 0.6304949708624844E+00, 0.2263541700174215E+00, 0.3731966957484361E+00, 0.4056710443895672E-01, 0.1518575777839423E+00, 0.7000182640684851E+00, 0.5207195688041865E+00, 0.3546513077756396E+00, 0.5223091585165126E+00, 0.1312526670646489E+00, 0.6075518716591177E+00, 0.7815133160786110E+00, 0.1466092133856621E+00, 0.6908403097208041E+00, 0.5289383481177163E+00, 0.3060973141340825E+00, 0.2719751878023001E+00, 0.4367099092855503E+00, 0.1678669773704986E+00, 0.2384522838837465E+00, 0.7578135131488263E+00, 0.2260651503779529E+00}, + n: 21, + zOut: []float64{0.3001718609114466E+01, 0.2461580649918252E+01, 0.2139800724137603E+01, 0.2110198913058292E+01, 0.1773285881581521E+01, 0.1731854037718996E+01, 0.1434868444776101E+01, 0.1292334845681036E+01, 0.1202898865215905E+01, 0.9074690574580867E+00, 0.8145281637318031E+00, 0.6833997197084192E+00, 0.6303801796404412E+00, 0.5115989792032534E+00, 0.4365028215455523E+00, 0.3347059637856380E+00, 0.2704761845997483E+00, 0.1007567293499011E+00, 0.7404356572986662E-01, 0.2225224658576705E-01, 0.1003499792335912E-03, 0.1163915500165708E-19, 0.5702083577853931E-06, 0.6235005324467382E-06, 0.1434868444776101E+01, 0.7352183636659830E-27, 0.3221030091629643E-04, 0.6932009635225803E-04, 0.1292334845681036E+01, 0.1547654926086715E-20, 0.2859096049606110E-03, 0.1689403705904475E-03, 0.1202898865215905E+01, 0.5187952724823741E-19, 0.3457740509453089E-04, 0.1548723988845099E-04, 0.9074690574580867E+00, 0.1883346903736854E-18, 0.4924250006037621E-06, 0.3064183963004930E-06, 0.8145281637318031E+00, 0.7436271633171000E-16, 0.2193475493251988E+02, 0.2193475493251988E+02, 0.9400000000000000E+02, 0.2913832199546485E+01, 0.3191489361702128E+01, 0.6928384721316203E-06, 0.6303801796404412E+00, 0.4344707644406440E-17, 0.8243004381261832E-06, 0.1242944619712133E-05, 0.5115989792032534E+00, 0.1321342016245195E-28, 0.6830327722875946E-05, 0.4610227507804771E-05, 0.4365028215455523E+00, 0.7922538128148438E-16, 0.5185315150043044E-04, 0.9574812800552337E-04, 0.3347059637856380E+00, 0.4042912139257686E-29, 0.6190562688247171E-03, 0.1111720505727282E-02, 0.2704761845997483E+00, 0.1659171176970474E-17, 0.3895087988050344E-03, 0.1929449868539905E-03, 0.1007567293499011E+00, 0.2919870821923328E-23, 0.2088900906409071E-03, 0.1786849109209585E-03, 0.7404356572986662E-01, 0.6310887241768094E-28, 0.1266951898160773E-03, 0.1217799054154213E-03, 0.2225224658576705E-01, 0.3697785493223493E-31, 0.1828672832615040E-03, 0.2196698921083079E-03, 0.1003499792335912E-03, 0.0000000000000000E+00, 0.1256202468809242E-02, 0.9158129895566399E-03}, + info: 0, + }, + { + z: []float64{0.7473165994595915E+00, 0.9383144044637891E+00, 0.9705766820209645E+00, 0.3093136353727625E+00, 0.7158638842786125E+00, 0.8927477442087851E+00, 0.5846837014009232E-02, 0.2823227977987499E+00, 0.4656399961948744E+00, 0.1783480145929806E-01, 0.8517241739910267E+00, 0.2968236367983081E+00, 0.3828703962512207E+00, 0.1618551942929359E+00, 0.8422815023410849E+00, 0.9667213467147939E+00, 0.1872774458350456E+00, 0.9673785609387944E+00, 0.1668393270938346E+00, 0.1793363294699661E+00, 0.3882509817575230E+00, 0.9322497724034516E+00, 0.1678634979113953E+00, 0.4000730353927472E+00, 0.1370854040387474E+00, 0.1383728853360747E+00, 0.8728086099072359E+00, 0.7142605368034651E+00, 0.1298497843576266E+00, 0.4890695005398649E+00, 0.6561831309305255E+00, 0.2551502145039813E+00, 0.3137603328050955E+00, 0.4725573834392259E+00, 0.1864194559915778E+00, 0.2476903242862807E+00, 0.3016682498100809E-01, 0.6028908129301045E+00, 0.9699532639034771E+00, 0.6804787742392342E+00, 0.5085224418131328E+00, 0.8160312832212636E+00, 0.4537844508149779E+00, 0.7698002058576117E+00, 0.9102837491884663E-01, 0.7957963901796614E+00, 0.4129806172970929E+00, 0.1183929303892000E+00, 0.7231979382284242E+00, 0.6908050716155305E+00, 0.9129211251463741E+00, 0.8407226028232299E+00, 0.7511043357392063E+00, 0.6614037096770188E+00, 0.5816383867961591E+00, 0.9508597818692400E+00, 0.6671834981267941E+00, 0.5353731249555691E+00, 0.8270836995328532E+00, 0.4748649574057349E+00, 0.7310961648034807E+00, 0.5329698192925740E+00, 0.5537463638220994E+00, 0.8202244086458278E+00, 0.3089778794417031E-01, 0.8347421543151022E+00, 0.7341688304615497E+00, 0.6293051268804178E+00, 0.9685330131023850E-01, 0.2218306173097127E+00, 0.4005982063157664E+00, 0.8004209862846372E+00, 0.9322471342744776E-02, 0.5252230232113276E+00, 0.8078446044346348E+00, 0.8663675770089085E-02, 0.4174348230921995E+00, 0.5316704871571061E+00, 0.8080873214304936E+00, 0.3191328650837369E+00, 0.2265528787275422E+00, 0.1299687059183835E+00, 0.5606006275148095E+00, 0.2716326223111132E+00}, + n: 21, + zOut: []float64{0.2557856639061994E+01, 0.2221569823028635E+01, 0.2113175506056959E+01, 0.1791034203034858E+01, 0.1626866366713385E+01, 0.1553853827140545E+01, 0.1378038738404736E+01, 0.1313711478279983E+01, 0.1103021858691488E+01, 0.8924372074434684E+00, 0.7465727975101516E+00, 0.5658880123536838E+00, 0.5427616116084486E+00, 0.3934406603234193E+00, 0.3139076008306549E+00, 0.2922956394268174E+00, 0.1324157743308766E+00, 0.8492495339426936E-01, 0.1726019296564064E-01, 0.1478900502211735E-02, 0.3047316799617542E-04, 0.0000000000000000E+00, 0.2209423397088722E-18, 0.1230851536694111E-18, 0.1378038738404736E+01, 0.4653537180464338E-22, 0.4724643033910209E-17, 0.2943893377745906E-17, 0.1313711478279983E+01, 0.2193156221990361E-16, 0.1119006893822957E-16, 0.1741431705208298E-16, 0.1103021858691488E+01, 0.2831227495869906E-12, 0.2860829853751284E-15, 0.4129571258389818E-15, 0.8924372074434684E+00, 0.1711229892219076E-22, 0.2249832739645017E-14, 0.3254005212313171E-14, 0.7465727975101516E+00, 0.5231751935973153E-19, 0.1964254226427022E+02, 0.1964254226427022E+02, 0.1110000000000000E+03, 0.3285714285714286E+01, 0.8108108108108109E+01, 0.1373504512438542E-12, 0.5427616116084486E+00, 0.0000000000000000E+00, 0.2663664432452481E-11, 0.1451131289962852E-11, 0.3934406603234193E+00, 0.3021704178298789E-14, 0.8991877456137337E-10, 0.1576401145017008E-09, 0.3139076008306549E+00, 0.2274554202459952E-24, 0.7202855721215940E-08, 0.4214854283718170E-08, 0.2922956394268174E+00, 0.3975858962313899E-27, 0.6024353396932969E-07, 0.1022672043122323E-06, 0.1324157743308766E+00, 0.6969933701296916E-21, 0.1098572510799548E-05, 0.1404105143401733E-05, 0.8492495339426936E-01, 0.6511321020566649E-24, 0.5604469692434887E-06, 0.6104659421650381E-06, 0.1726019296564064E-01, 0.9860761315262648E-31, 0.7747760678878360E-06, 0.1026260244983655E-05, 0.1478900502211735E-02, 0.1334496117765360E-28, 0.5102973157105362E-05, 0.1258609455819239E-04, 0.3047316799617542E-04, 0.0000000000000000E+00, 0.4753862314998056E-03, 0.1863315015192667E-02}, + info: 0, + }, + { + z: []float64{0.2548672807470598E-01, 0.1495421137012933E+00, 0.6637277283391485E-01, 0.6233200993667132E-01, 0.4958061473131723E+00, 0.9804571594196556E+00, 0.5741929121502225E+00, 0.9319350517768583E+00, 0.5154498317218548E-01, 0.4165283024496188E+00, 0.9821854184367015E+00, 0.7510033276340442E+00, 0.2648151368970406E+00, 0.9698327797382789E-01, 0.1433813304773114E+00, 0.1687421369042604E+00, 0.6230509959313209E+00, 0.8106153730403777E+00, 0.5719487513699320E+00, 0.5761793262532514E+00, 0.4983158430615118E+00, 0.8860830618783583E+00, 0.7136722399358287E+00, 0.6310350013419201E+00, 0.5509601824732582E+00, 0.5806336147624858E-01, 0.1818648959869262E+00, 0.2346005241916651E+00, 0.5346851174706903E+00, 0.4444466121668155E+00, 0.8418378722202517E+00, 0.6164532479196363E+00, 0.4298553148227666E+00, 0.2296849794057675E+00, 0.3620982682376475E+00, 0.3645096805309075E+00, 0.9980228064491022E+00, 0.7106112428543574E+00, 0.6651697421094976E+00, 0.9830151455980368E+00, 0.3483046917749841E+00, 0.3668589729383628E+00, 0.5655614401040915E+00, 0.8891526728148491E+00, 0.9164649086142118E+00, 0.4065736846475075E+00, 0.1470436468080603E+00, 0.5802557267939668E+00, 0.8272597245263099E+00, 0.7163617706554632E+00, 0.3488790096540706E+00, 0.6404227109073246E+00, 0.1472796557920839E+00, 0.8764536863696604E-02, 0.5020645462548778E-01, 0.6906675094909457E+00, 0.4668434450047272E+00, 0.7886435616506033E+00, 0.8775817704321313E+00, 0.4246952359284411E+00, 0.1646609549881360E+00, 0.6697681588293083E+00, 0.7914692739599321E+00, 0.1396674072195736E-01, 0.5167232939537366E+00, 0.9374340964740459E+00, 0.4228531365925756E+00, 0.9727064517088465E+00, 0.5765501520393458E+00, 0.5648508784605104E+00, 0.3049637657479770E+00, 0.3063190445223624E+00, 0.5204528216889723E+00, 0.8180178920731451E+00, 0.4938773599630263E+00, 0.8975563911549045E-01, 0.5983688838646251E+00, 0.3698925131813697E+00, 0.2992530973981942E+00, 0.7463539101278609E+00, 0.8005980511688328E+00, 0.7944834752945218E-01, 0.3132925544163919E+00, 0.8866951016419623E+00}, + n: 21, + zOut: []float64{0.2548744028948828E+01, 0.2439584200134194E+01, 0.2276898263864132E+01, 0.2083856178014486E+01, 0.2039342663979975E+01, 0.1949418505713503E+01, 0.1425638870874207E+01, 0.1087729835971203E+01, 0.9667696375323971E+00, 0.8022433247488755E+00, 0.5846254874613492E+00, 0.5355025899480791E+00, 0.3940805795947064E+00, 0.2663780336330241E+00, 0.2413081251593111E+00, 0.1817740817404329E+00, 0.1073144197241267E+00, 0.4327520903789019E-01, 0.3141654146246065E-01, 0.2017433957164045E-01, 0.3181705377209195E-03, 0.2778526523712400E-12, 0.1839247883012458E-10, 0.2248848580297948E-10, 0.1425638870874207E+01, 0.4660214926831417E-16, 0.5684400877302917E-10, 0.6387162891082867E-10, 0.1087729835971203E+01, 0.6729715978266918E-13, 0.1741585337702246E-09, 0.2256709509706825E-09, 0.9667696375323971E+00, 0.8583633357857125E-17, 0.5122248377584688E-09, 0.7095864943104643E-09, 0.8022433247488755E+00, 0.1479114197289397E-30, 0.3545102092401686E-08, 0.2547082836533246E-08, 0.5846254874613492E+00, 0.1684748530176799E-17, 0.2002639308765254E+02, 0.2002639308765254E+02, 0.9900000000000000E+02, 0.2829931972789116E+01, 0.2020202020202020E+01, 0.1450844904575395E-08, 0.3940805795947064E+00, 0.8431345355002174E-26, 0.2834737824482197E-07, 0.1323731756234205E-07, 0.2663780336330241E+00, 0.1205202152489745E-19, 0.2553256673132341E-06, 0.1983391491151363E-06, 0.2413081251593111E+00, 0.5052150994009667E-21, 0.4174664103103917E-06, 0.5361294231508838E-06, 0.1817740817404329E+00, 0.4777592300362271E-19, 0.1103166278762495E-05, 0.1411552925870387E-05, 0.1073144197241267E+00, 0.1369462531463676E-25, 0.4868310689385493E-05, 0.3749559753873054E-05, 0.4327520903789019E-01, 0.6517810995642209E-18, 0.3308901711413922E-04, 0.5021439046381042E-04, 0.3141654146246065E-01, 0.3980258690751375E-19, 0.2091355707842741E-03, 0.1263714817696205E-03, 0.2017433957164045E-01, 0.9608259223012324E-19, 0.2907989762339014E-03, 0.3270695437261140E-04, 0.3181705377209195E-03, 0.2078018254813854E-20, 0.5046681645946245E-02, 0.5971971384809690E-02}, + info: 0, + }, + { + z: []float64{0.7556699778432414E+00, 0.9264145479756024E+00, 0.2732571748073197E+00, 0.6411921070422063E+00, 0.9885815056247259E+00, 0.3723918099656685E+00, 0.8347397513753253E+00, 0.1449609854320509E+00, 0.7237973270068254E+00, 0.7937879503069174E+00, 0.1580314367294657E+00, 0.6183123759968190E-01, 0.8526562423479169E+00, 0.4515796037285547E+00, 0.4273610709781387E+00, 0.9916977661043136E-01, 0.6106106148524300E+00, 0.8331371477897991E+00, 0.3226596180395027E+00, 0.9411873968460633E+00, 0.4713107215814810E+00, 0.2408559451890391E-01, 0.8159283865403915E+00, 0.2484819964854622E+00, 0.9053457264816500E-01, 0.7765873412573800E+00, 0.6903393919382517E-01, 0.4737861094943234E+00, 0.2953181034757211E+00, 0.1455852388723616E+00, 0.3595484224812872E+00, 0.7546693773577520E+00, 0.2176499262400425E+00, 0.2180463762362660E+00, 0.4619066216292487E+00, 0.9195384505328125E+00, 0.7817199663072332E+00, 0.7252058550809327E+00, 0.7231496659924924E+00, 0.4997135548263443E+00, 0.7857040551775740E-01, 0.9096915224111880E+00, 0.5048166916632318E+00, 0.9737715836828489E+00, 0.6597329703373522E+00, 0.1262659377119990E-01, 0.3525536903406803E+00, 0.6167857219758321E+00, 0.7408468432196044E+00, 0.7867196986400673E+00, 0.2313289425583596E+00, 0.8524506859175643E+00, 0.1392061690435467E+00, 0.4799927308227143E+00, 0.5988201473645773E+00, 0.8148615971957359E+00, 0.9991849415795491E+00, 0.4062458282025133E+00, 0.8021012361110058E-01, 0.7041715844729369E+00, 0.9319571339573152E-01, 0.9303801779957639E+00, 0.6825635414858495E+00, 0.2651022334979941E+00, 0.2966022780498856E-01, 0.2756350604456157E+00, 0.3996117016882065E+00, 0.4084803031952775E+00, 0.7693093419592285E+00, 0.5425247266459055E+00, 0.7317803042615013E+00, 0.9398853135227920E+00, 0.5923013015298344E+00, 0.6749323490534131E-01, 0.2677632908794654E+00, 0.1468441510303787E+00, 0.1088650133568649E+00, 0.2179701521651023E+00, 0.8673093102161434E+00, 0.5667697713082290E+00, 0.5061732946886482E+00, 0.4707781162637231E+00, 0.4572852405093119E+00, 0.2817384205908577E+00}, + n: 21, + zOut: []float64{0.2549866140639053E+01, 0.2289692363298807E+01, 0.2042824675422646E+01, 0.1807091836494319E+01, 0.1608583829794490E+01, 0.1518595775727545E+01, 0.1431682400757094E+01, 0.1278141352537376E+01, 0.1218077200015686E+01, 0.1115746594519385E+01, 0.9489661418934578E+00, 0.7950491688285616E+00, 0.6705557578092293E+00, 0.4223587911677574E+00, 0.3211641543143434E+00, 0.1395786344205778E+00, 0.9463219952875908E-01, 0.4563841563552573E-01, 0.3718976888616738E-01, 0.2766660139323238E-01, 0.2861060880329385E-03, 0.1489369389057270E-25, 0.4009456273839574E-11, 0.5913965075566282E-11, 0.1431682400757094E+01, 0.9808641529204798E-18, 0.1658075466067222E-10, 0.2375182467377229E-10, 0.1278141352537376E+01, 0.1561716996498461E-20, 0.5563872147228742E-10, 0.4003249215027731E-10, 0.1218077200015686E+01, 0.8198555146385643E-18, 0.1047304739332037E-09, 0.1509388346471184E-09, 0.1115746594519385E+01, 0.6804594514014344E-21, 0.1132515351796206E-08, 0.7305070647547987E-09, 0.9489661418934578E+00, 0.6324297261214257E-19, 0.2036338790917205E+02, 0.2036338790917205E+02, 0.1050000000000000E+03, 0.3147392290249433E+01, 0.2857142857142857E+01, 0.1188392639382130E-06, 0.6705557578092293E+00, 0.2287929633195320E-19, 0.1283168907741916E-05, 0.1048613283787068E-05, 0.4223587911677574E+00, 0.1189072130544977E-23, 0.1798535669474704E-05, 0.2477367923932174E-05, 0.3211641543143434E+00, 0.8187795594567816E-23, 0.5813187502570164E-05, 0.4274698539216166E-05, 0.1395786344205778E+00, 0.4387796946624011E-14, 0.1512969274311187E-04, 0.4383088766938462E-04, 0.9463219952875908E-01, 0.2802074325023381E-22, 0.1713816584845726E-03, 0.1715892923902221E-03, 0.4563841563552573E-01, 0.8331483361628599E-18, 0.1806157324013782E-06, 0.1193242630586832E-05, 0.3718976888616738E-01, 0.1396316416906445E-20, 0.3480495660704905E-03, 0.4402048010276426E-03, 0.2766660139323238E-01, 0.1504073756330590E-24, 0.6353091961964474E-03, 0.1317363577877200E-03, 0.2861060880329385E-03, 0.4589883047388968E-23, 0.3883745848947868E-02, 0.5358907697572753E-02}, + info: 0, + }, + { + z: []float64{0.8456683250225028E-01, 0.3058015837199188E+00, 0.4317902183064470E-01, 0.3671979469896071E+00, 0.3595487854233631E+00, 0.8791524368561765E+00, 0.1256853689373587E+00, 0.3494000337993621E+00, 0.2131672180923028E+00, 0.4488324680055523E+00, 0.9452502344450827E+00, 0.7197446096567599E+00, 0.8918071015747069E+00, 0.5551949519753436E+00, 0.5627883747367335E+00, 0.6930858113379974E+00, 0.7026202611250518E+00, 0.3856840921343180E+00, 0.4453224782611998E+00, 0.9627551339340559E+00, 0.6255469039377685E+00, 0.6093210861157965E+00, 0.1297243619022892E-01, 0.2745425059216151E+00, 0.5902573930769862E+00, 0.3658719785914519E+00, 0.8179101736936932E+00, 0.4251816548465440E+00, 0.3319568042078717E+00, 0.8294675656951641E+00, 0.1906193594777114E+00, 0.6862699206380130E+00, 0.6832362040809048E+00, 0.8968537122850908E+00, 0.3753636108676777E+00, 0.9926770667520373E+00, 0.7473790867948205E-01, 0.3653635034012445E+00, 0.6553100464759598E-01, 0.1045856631958887E+00, 0.2265961870023414E+00, 0.3205967446655300E-01, 0.1845082884370131E+00, 0.2250092498055734E+00, 0.5876866067653603E+00, 0.2146512915654570E+00, 0.3937206506545190E+00, 0.4110924225795073E+00, 0.3228836105384403E+00, 0.3531543308069818E-01, 0.9472843614842231E+00, 0.2348052564069324E+00, 0.1315455878409307E+00, 0.2246729768637089E+00, 0.8445861542610614E+00, 0.9528962673528295E+00, 0.4907499555456967E+00, 0.9420172239501383E+00, 0.4896535244350841E-01, 0.5088622551995382E+00, 0.1789066474661110E+00, 0.3566730680524121E+00, 0.4279936896698711E-01, 0.5241586506933626E-02, 0.9191361995860731E+00, 0.7666474814508011E+00, 0.8302596584023555E+00, 0.4738482866502817E+00, 0.2085735695866969E+00, 0.3976808123484415E+00, 0.4364253757027529E+00, 0.2407360056333678E+00, 0.4002772343201099E+00, 0.7717338386755229E+00, 0.5023514841326452E+00, 0.8988902694804358E+00, 0.4259852339101408E+00, 0.2067093317010162E+00, 0.8456128611542781E+00, 0.1290027044731792E+00, 0.2598901078235174E+00, 0.5836006873243835E+00, 0.9777637054617091E+00, 0.4896357840832322E+00}, + n: 21, + zOut: []float64{0.2625813250937807E+01, 0.2316814186652984E+01, 0.2239421861777163E+01, 0.1853308891402210E+01, 0.1827033391537137E+01, 0.1481398580531558E+01, 0.1385699025778513E+01, 0.1101045596651604E+01, 0.1077490875294086E+01, 0.6790358065311344E+00, 0.6361857378195889E+00, 0.5095707085100130E+00, 0.4739579905788711E+00, 0.4209497658895578E+00, 0.3012142858983374E+00, 0.2432742659092710E+00, 0.2088674538811938E+00, 0.1664409530858738E+00, 0.2606656040091844E-01, 0.1205810631995507E-01, 0.9325512290661112E-07, 0.1292469707114106E-24, 0.1719039818430849E-04, 0.1845080438772963E-04, 0.1385699025778513E+01, 0.2224123229986848E-19, 0.6819642419856913E-05, 0.9079053758699490E-05, 0.1101045596651604E+01, 0.6054420446023063E-14, 0.5392861994521241E-06, 0.8422816920290823E-06, 0.1077490875294086E+01, 0.7330726620037819E-25, 0.4290042344637304E-06, 0.3471234449409943E-06, 0.6790358065311344E+00, 0.1969273319091676E-18, 0.8635424232755040E-07, 0.8294124288205587E-07, 0.6361857378195889E+00, 0.4466775307674635E-22, 0.1958564738864290E+02, 0.1958564738864290E+02, 0.9700000000000000E+02, 0.2927437641723356E+01, 0.2061855670103093E+01, 0.4284285350948107E-09, 0.4739579905788711E+00, 0.4844247598072386E-17, 0.1501956526577450E-07, 0.4599310764980267E-07, 0.4209497658895578E+00, 0.5697556379758414E-13, 0.1468884761079027E-05, 0.1935721204206928E-05, 0.3012142858983374E+00, 0.3414189997796539E-26, 0.7129394687116921E-05, 0.9262068822983554E-05, 0.2432742659092710E+00, 0.2465190328815662E-31, 0.3320148255009530E-04, 0.2563439348523979E-04, 0.2088674538811938E+00, 0.8874685183736383E-29, 0.9377671959730327E-04, 0.7166613903737452E-04, 0.1664409530858738E+00, 0.1175218723307338E-19, 0.5883141447281398E-03, 0.4140832085136277E-03, 0.2606656040091844E-01, 0.2634795423438179E-27, 0.4797918408258123E-02, 0.4833036765864798E-02, 0.1205810631995507E-01, 0.6530371216255944E-19, 0.7811358433513861E-02, 0.1392611548870054E-01, 0.9325512290661112E-07, 0.1190420191421466E-12, 0.6274023555637595E-01, 0.1241063086176471E-01}, + info: 0, + }, + { + z: []float64{0.6345014789904082E+00, 0.9828013844807603E+00, 0.5292373213190880E+00, 0.3345627500234365E+00, 0.9345959669050260E+00, 0.5873733336147081E+00, 0.8888462128293518E+00, 0.1044020545901757E+00, 0.9375280272458696E+00, 0.1233411973951652E+00, 0.3330283913003940E+00, 0.2432208394685875E-01, 0.6106490172620382E+00, 0.9136489477065954E+00, 0.8250850334045809E+00, 0.7866479843500775E+00, 0.1629924039124250E+00, 0.2349971551206693E+00, 0.1024684774133804E+00, 0.7852727749024598E+00, 0.1427984573527686E+00, 0.4315181982028241E+00, 0.6564047419338838E+00, 0.5555590030741936E+00, 0.8205569452257172E+00, 0.4368031922318115E+00, 0.2897575605849890E+00, 0.6163386054890784E+00, 0.7016794584968877E+00, 0.7265422079630662E+00, 0.6393115149906525E+00, 0.7552597718778955E+00, 0.5029129969011173E+00, 0.4874732646810529E+00, 0.5094624150009296E+00, 0.4766369914172104E+00, 0.9003818070855094E+00, 0.6813014247956244E+00, 0.2988296447575162E+00, 0.6597790416796705E+00, 0.5646192150605487E+00, 0.3275024686793908E+00, 0.2725061169408716E-01, 0.8098076662320616E+00, 0.3345276190659139E+00, 0.1812780354242056E+00, 0.1997802571871318E+00, 0.5440765633504190E+00, 0.9774510594766147E+00, 0.1863483792916641E+00, 0.5910097330685633E+00, 0.2734489448477760E+00, 0.4395818444416557E+00, 0.9022786559097939E+00, 0.1029995124123335E+00, 0.9437933734967648E+00, 0.1226746192846208E+00, 0.1122541771291640E+00, 0.1756516455268763E+00, 0.9109529416432673E+00, 0.3050345572159197E-01, 0.1746678233544180E+00, 0.3750993781268622E+00, 0.4476224977918100E+00, 0.5437446694835568E+00, 0.3729575052852190E+00, 0.3542378566336749E+00, 0.7449948633772266E+00, 0.3157555204945224E+00, 0.7753984984296890E+00, 0.3284038993889418E+00, 0.5159361949232710E-01, 0.4529339074400007E-01, 0.5693581512511349E+00, 0.2213156237057901E+00, 0.9395831428155459E+00, 0.3843047271617620E+00, 0.2968653921042081E+00, 0.6156090467550724E+00, 0.3170556612853570E-01, 0.8265655132088339E+00, 0.3165750369023552E+00, 0.7055602587055542E+00, 0.8365600455841105E+00}, + n: 21, + zOut: []float64{0.2473859321883559E+01, 0.2422834159796051E+01, 0.2342770718537345E+01, 0.2190393245355733E+01, 0.2048748874742353E+01, 0.1880327408972340E+01, 0.1569014269461521E+01, 0.1302496773444914E+01, 0.1193514796722045E+01, 0.1150651682141956E+01, 0.8969794111087930E+00, 0.8226581338194529E+00, 0.6917042463755413E+00, 0.5972139808466055E+00, 0.3480375932216391E+00, 0.2932789944580818E+00, 0.2090971942801221E+00, 0.1221616224423389E+00, 0.1000478595340333E+00, 0.3412207557320287E-01, 0.3160927987836547E-03, 0.2386777554836693E-25, 0.1787847554062023E-08, 0.1930667016131883E-08, 0.1569014269461521E+01, 0.5039432348921582E-18, 0.3047636948536222E-07, 0.1223330280849913E-07, 0.1302496773444914E+01, 0.0000000000000000E+00, 0.7408697490815375E-06, 0.1498788057488595E-05, 0.1193514796722045E+01, 0.6273021918317486E-26, 0.8867922405978688E-08, 0.3710956866722375E-08, 0.1150651682141956E+01, 0.1462883977034466E-17, 0.2681277488017278E-06, 0.6188429230273071E-06, 0.8969794111087930E+00, 0.4930380657631324E-31, 0.2269022845551642E+02, 0.2269022845551641E+02, 0.1110000000000000E+03, 0.3215419501133787E+01, 0.4504504504504505E+01, 0.4606971433208740E-07, 0.6917042463755413E+00, 0.7123549154360197E-18, 0.1197511514786163E-07, 0.1386949181837661E-07, 0.5972139808466055E+00, 0.4652335183636722E-20, 0.1082703076660205E-07, 0.1003906263016573E-07, 0.3480375932216391E+00, 0.3573127201018094E-16, 0.2388210318135170E-06, 0.5694782222336181E-06, 0.2932789944580818E+00, 0.7601337464964823E-24, 0.7791755144624492E-05, 0.3242296896441773E-05, 0.2090971942801221E+00, 0.1663630656286764E-22, 0.9916420504550920E-06, 0.3916254919710180E-05, 0.1221616224423389E+00, 0.1406614427791829E-18, 0.1356917845842480E-04, 0.1379449187478977E-04, 0.1000478595340333E+00, 0.2800456213534592E-28, 0.3213444959426999E-04, 0.2790230345312924E-04, 0.3412207557320287E-01, 0.1075846717720530E-17, 0.8531299184272352E-03, 0.1419520770966347E-02, 0.3160927987836547E-03, 0.1848892746611746E-31, 0.7376316906583622E-02, 0.6546496744187779E-02}, + info: 0, + }, + { + z: []float64{0.7781991870339823E+00, 0.3799726947828087E+00, 0.8225406656461727E+00, 0.4322410258771066E+00, 0.4965834581857734E+00, 0.1642548945285990E+00, 0.4773703559733889E+00, 0.7580746486223987E+00, 0.9220155673403277E+00, 0.1624062232083541E+00, 0.5664470130564820E+00, 0.7367013127895712E+00, 0.4720756942873998E+00, 0.8695958825780965E+00, 0.6045812450089678E+00, 0.8503421320137978E+00, 0.7291568033584502E+00, 0.9563602214514951E+00, 0.1245752972610169E+00, 0.2621011209284912E+00, 0.8642265339858576E+00, 0.9528021036615359E+00, 0.9515862784178062E+00, 0.2632504807072628E+00, 0.8585529108378003E+00, 0.3025834513231899E+00, 0.7125877353473579E+00, 0.9221275053156179E+00, 0.9787992369955746E+00, 0.8789465750552752E+00, 0.9318675804398889E+00, 0.8827440896392771E+00, 0.3124337393280541E+00, 0.3124656972853590E-01, 0.5860766227864144E+00, 0.9812515177915087E+00, 0.4480000254042209E+00, 0.5121903109069345E+00, 0.1837298514334742E+00, 0.2680410429176278E+00, 0.5529294510898309E+00, 0.3627557909974974E+00, 0.9282219359125773E+00, 0.2173723036967439E+00, 0.7593665130145739E+00, 0.6245533364325671E+00, 0.1767680905493787E+00, 0.3823356866170564E+00, 0.5171578058722374E+00, 0.5376155024979712E+00, 0.5280269975706942E-01, 0.7947058949878518E+00, 0.1214716509814368E+00, 0.6840110600217510E+00, 0.7041243787921371E+00, 0.6945194787199669E+00, 0.8184844284849127E+00, 0.3440855810599863E+00, 0.1619958520504678E+00, 0.6990470088709023E+00, 0.3532225659848430E+00, 0.8229090368317697E+00, 0.8349696782028652E+00, 0.6932180266797183E-01, 0.6880274120498576E+00, 0.7566065163897195E+00, 0.2981422921509080E-01, 0.8636153925759227E-02, 0.7928093803058089E-01, 0.3096144259285381E+00, 0.6829886066202427E+00, 0.8246144682759358E+00, 0.2007259621364732E+00, 0.8710862365466575E+00, 0.6898755422119236E+00, 0.9105030198433044E+00, 0.8974818523094739E+00, 0.8909991694059211E+00, 0.8084341913662618E-01, 0.6072211485624930E+00, 0.9680950749726419E+00, 0.3932275197607872E+00, 0.8781208296025552E+00, 0.5527043030768199E+00}, + n: 21, + zOut: []float64{0.3158195987040060E+01, 0.2674397094280163E+01, 0.2611167345511754E+01, 0.2117792657212280E+01, 0.2026395303611904E+01, 0.1943316400161173E+01, 0.1877195462180231E+01, 0.1801757023901512E+01, 0.1273111869927408E+01, 0.1088705127135854E+01, 0.9559661931705944E+00, 0.9013607966201198E+00, 0.6445742634037150E+00, 0.5446175180211763E+00, 0.4486902226406620E+00, 0.3854842198344371E+00, 0.2741584921777233E+00, 0.1210105287753585E+00, 0.6940868812740908E-01, 0.2059029850850508E-01, 0.3673564803695461E-02, 0.8077935669463161E-25, 0.2195808487174199E-10, 0.8449955132778232E-10, 0.1877195462180231E+01, 0.1633831636278255E-19, 0.3497961877980620E-08, 0.7650955873935623E-08, 0.1801757023901512E+01, 0.4072241987713803E-24, 0.2126842707416970E-06, 0.1130018646589442E-06, 0.1273111869927408E+01, 0.1740941751301712E-20, 0.3388039768888790E-03, 0.2863573324805332E-03, 0.1088705127135854E+01, 0.2858227958137079E-16, 0.2905468688553340E-03, 0.2787380120464217E-03, 0.9559661931705944E+00, 0.1315475667900737E-21, 0.2494156905704573E+02, 0.2494156905704573E+02, 0.1010000000000000E+03, 0.3074829931972789E+01, 0.1980198019801980E+01, 0.2647338938369395E-05, 0.6445742634037150E+00, 0.2341846562030201E-22, 0.2667503836084351E-03, 0.1510510164587073E-03, 0.5446175180211763E+00, 0.2242636890234710E-24, 0.5495840118850513E-05, 0.4810476319752364E-05, 0.4486902226406620E+00, 0.3552400222016096E-16, 0.2740332708518062E-05, 0.2562621073339741E-05, 0.3854842198344371E+00, 0.1036641484462207E-22, 0.2248949759797675E-05, 0.2492010005917310E-05, 0.2741584921777233E+00, 0.6071156729318302E-20, 0.4130294607665845E-03, 0.1141603094124651E-03, 0.1210105287753585E+00, 0.2468629837810345E-16, 0.7230132634032991E-02, 0.6618694284253705E-02, 0.6940868812740908E-01, 0.5487745597049798E-23, 0.4151017130761703E-02, 0.4525758324635968E-02, 0.2059029850850508E-01, 0.6083695301064443E-26, 0.3095027772299370E-02, 0.3218440937246976E-02, 0.3673564803695461E-02, 0.6106717417722413E-22, 0.6443405665983428E-02, 0.1622720765285148E-02}, + info: 0, + }, + { + z: []float64{0.1985414918961074E+00, 0.4386372064833388E-01, 0.9272679997999695E+00, 0.9276564660006267E+00, 0.9509373652834754E+00, 0.6247274629358034E+00, 0.4838472987754385E+00, 0.6222976111124274E+00, 0.4248800474043221E+00, 0.9755567793536163E+00, 0.8912410754920851E+00, 0.2313492132656925E-01, 0.1563015923526294E+00, 0.7905214363406186E+00, 0.4927898149840948E+00, 0.5370919594301193E+00, 0.4644799081842790E+00, 0.9960946978984735E+00, 0.2493095982292803E+00, 0.3814725574373231E+00, 0.2940816225707878E+00, 0.6535898793246008E+00, 0.2084037192546966E+00, 0.5132959253232522E+00, 0.4251209694264122E+00, 0.9378579353373483E+00, 0.9786807729708236E+00, 0.7781441628535176E+00, 0.3951333405907657E+00, 0.3920742203259495E+00, 0.1500883321285087E+00, 0.9121803806188729E+00, 0.8516361075320147E+00, 0.6824417668614835E-01, 0.1390781730568696E+00, 0.3112124735573820E+00, 0.2535919561468232E+00, 0.7644352497405866E+00, 0.9218252733114815E+00, 0.9901458352558505E+00, 0.3279511469507669E+00, 0.8365860218696105E+00, 0.3198677553816687E+00, 0.6133665370063144E+00, 0.2580491557527305E+00, 0.6586714927743139E+00, 0.3933698458458805E+00, 0.7194383869235133E-01, 0.2213903901048253E-02, 0.1496106697134404E+00, 0.6766438239122079E+00, 0.7197724372602395E+00, 0.4797148651858846E+00, 0.5998154083597278E+00, 0.5590962662612089E+00, 0.6336887670809047E+00, 0.1072453740736307E+00, 0.7505878626477551E+00, 0.1427362910235584E+00, 0.6016163404777434E+00, 0.9488238354107547E+00, 0.4206748665323531E+00, 0.4473756257202280E+00, 0.2658295729210566E+00, 0.2340075619597504E+00, 0.9617320234413022E+00, 0.5962761690405762E+00, 0.8519099982463364E+00, 0.5571747680961063E+00, 0.1982921114470393E-01, 0.2779304562486129E-01, 0.7924439389736488E+00, 0.9672136382383878E-01, 0.8417095886148459E+00, 0.7473598542298929E+00, 0.9746159458640847E+00, 0.5038819873190444E+00, 0.9169242656654556E+00, 0.5252626769192049E+00, 0.5100979601115528E+00, 0.2790149607164115E+00, 0.4554892778467722E+00, 0.9762420639370454E+00, 0.9832519154713986E+00}, + n: 21, + zOut: []float64{0.2773247209998878E+01, 0.2684570079202721E+01, 0.2535407140485478E+01, 0.2251849067745984E+01, 0.2036533658934636E+01, 0.1904369707782458E+01, 0.1446171755624304E+01, 0.1299751831669502E+01, 0.1269533063987320E+01, 0.1007664938847636E+01, 0.8251797533661941E+00, 0.5818474246453018E+00, 0.5486201168977923E+00, 0.3772420051451134E+00, 0.3380340897724159E+00, 0.2023767003460897E+00, 0.1840234711841343E+00, 0.9225167203340243E-01, 0.4232592978815707E-01, 0.2771262583534443E-01, 0.7321455618534900E-04, 0.2977163580658995E-22, 0.3752078887401622E-10, 0.4179376226086309E-10, 0.1446171755624304E+01, 0.2236367039610280E-12, 0.1299965948722022E-10, 0.1595321259646779E-10, 0.1299751831669502E+01, 0.9926167350636332E-23, 0.8604643146515003E-10, 0.1864418628665438E-09, 0.1269533063987320E+01, 0.1306353659045996E-24, 0.1991121186029356E-08, 0.8983175437487846E-09, 0.1007664938847636E+01, 0.1213184768518325E-22, 0.3444432736029153E-07, 0.6437805745712839E-07, 0.8251797533661941E+00, 0.7772022937681214E-16, 0.2242878545784906E+02, 0.2242878545784905E+02, 0.1000000000000000E+03, 0.3024943310657596E+01, 0.3000000000000000E+01, 0.1709907812443784E-06, 0.5486201168977923E+00, 0.2972680326362443E-23, 0.1350081364219064E-06, 0.1255933647347444E-06, 0.3772420051451134E+00, 0.8046381233254320E-28, 0.7022416754922569E-08, 0.2768431074740138E-07, 0.3380340897724159E+00, 0.1719716773381806E-27, 0.7079953450794871E-07, 0.6648251035830866E-07, 0.2023767003460897E+00, 0.1940724044588524E-24, 0.4764709677102475E-07, 0.4597049352360845E-07, 0.1840234711841343E+00, 0.3459682911934042E-21, 0.4438757837191216E-07, 0.4402069254647340E-07, 0.9225167203340243E-01, 0.2596900924099520E-17, 0.8125925620122143E-07, 0.6770863964779914E-07, 0.4232592978815707E-01, 0.1280067631025782E-15, 0.3584234088053806E-06, 0.4822962810861105E-06, 0.2771262583534443E-01, 0.1012934875847350E-18, 0.1556396151524861E-05, 0.2916279508701459E-05, 0.7321455618534900E-04, 0.1540743955509789E-32, 0.4190434742116713E-02, 0.1362677535010021E-02}, + info: 0, + }, + { + z: []float64{0.6703344952482478E+00, 0.3577116069291627E+00, 0.8432263018920840E+00, 0.9584130033491455E+00, 0.2861685401430958E+00, 0.9668570623620085E+00, 0.6957796127156375E+00, 0.7603022900919236E+00, 0.7677099838587329E+00, 0.2702658617954818E+00, 0.9607212720070546E-01, 0.3973573502375266E+00, 0.8455511814548733E+00, 0.6862903202354254E-01, 0.1789860417278408E+00, 0.1112926642215833E+00, 0.8320621955974556E+00, 0.2637090148175287E+00, 0.7109403389502641E+00, 0.6494529820495407E+00, 0.8828985636942858E+00, 0.9098303542318168E+00, 0.1777489928582532E+00, 0.8977650882542143E-01, 0.7154356412046237E-01, 0.2693107133832517E-01, 0.7956794415059365E-02, 0.8852594037406200E+00, 0.2162284138438216E+00, 0.9216829080200467E+00, 0.9874282279096652E+00, 0.6087745498247736E+00, 0.7694028142872190E+00, 0.5918349824988693E+00, 0.1915561020798640E+00, 0.1135335598824661E-01, 0.6670902390154858E+00, 0.6601113994758983E+00, 0.7779237148990382E+00, 0.9023999203058302E+00, 0.1848842750705929E+00, 0.6120355291150891E+00, 0.7209828136916797E+00, 0.3124354740483853E+00, 0.9520753904353354E+00, 0.9694533109968584E+00, 0.6869212426966154E+00, 0.3510392134251344E+00, 0.7696249856763533E+00, 0.9203915575905880E+00, 0.4616165896255233E+00, 0.6796681592119477E+00, 0.9261196886552191E+00, 0.4511929507295228E+00, 0.5162093776469306E+00, 0.3093101029632945E+00, 0.1162653262260159E+00, 0.1951366360676013E+00, 0.7945099687545387E+00, 0.9707806531485516E+00, 0.4161172559602336E+00, 0.5813461713597171E+00, 0.8442974147064882E+00, 0.9135490286183924E+00, 0.3261094875410662E+00, 0.7080588637364270E+00, 0.3833080381406134E+00, 0.9095051028453779E+00, 0.6909172438403831E+00, 0.5187928284332267E+00, 0.5783778059525303E+00, 0.9615928062069277E+00, 0.2127624116065856E+00, 0.7254035177440832E+00, 0.2587362009618467E+00, 0.7570212065831576E+00, 0.2401238007004233E+00, 0.2744934873404078E+00, 0.9420426561890750E+00, 0.7098059460475599E+00, 0.2691363643891775E+00, 0.4536316870833661E+00, 0.6839445343274818E+00, 0.9336823543434762E+00}, + n: 21, + zOut: []float64{0.2634467575625416E+01, 0.2594635276829839E+01, 0.2463070407655619E+01, 0.2293127065694029E+01, 0.2072673505384417E+01, 0.1459936798288049E+01, 0.1378497856793854E+01, 0.1333239471494390E+01, 0.1102542278566289E+01, 0.8930469384549427E+00, 0.8520787727779708E+00, 0.6953298055150813E+00, 0.6847648677749263E+00, 0.2185116940651705E+00, 0.2008337976176149E+00, 0.1757551361146239E+00, 0.1271484717317025E+00, 0.5049064582277562E-01, 0.3515271339576785E-01, 0.7966224551514293E-02, 0.1685389559757755E-03, 0.1635721388548769E-22, 0.3551032227485648E-11, 0.3089325791958004E-11, 0.1378497856793854E+01, 0.6463020148652660E-17, 0.4439365591922079E-11, 0.5247211770454983E-11, 0.1333239471494390E+01, 0.8616343098037817E-25, 0.4343651596456738E-10, 0.2452653826174233E-10, 0.1102542278566289E+01, 0.9876517884224792E-16, 0.1549700306365952E-08, 0.1012434062383302E-08, 0.8930469384549427E+00, 0.4606319384654338E-19, 0.1115188986357716E-08, 0.1237013304894199E-08, 0.8520787727779708E+00, 0.1447566071967798E-23, 0.2127343784310997E+02, 0.2127343784310997E+02, 0.1270000000000000E+03, 0.3675736961451247E+01, 0.9448818897637794E+01, 0.2782364756724027E-11, 0.6847648677749263E+00, 0.6100457017578579E-23, 0.1535488071926541E-09, 0.5733950833190260E-09, 0.2185116940651705E+00, 0.6436934318898579E-12, 0.5207333190112868E-06, 0.4302907440331721E-06, 0.2008337976176149E+00, 0.1972152263052530E-30, 0.2421587237749379E-06, 0.2920528765870267E-06, 0.1757551361146239E+00, 0.8101601496619791E-27, 0.1434500575863456E-11, 0.9045851929625007E-13, 0.1271484717317025E+00, 0.1560107593833772E-17, 0.1620731838764033E-06, 0.1206839073349329E-06, 0.5049064582277562E-01, 0.3155443620884047E-29, 0.7221494757183839E-05, 0.4279630756550309E-05, 0.3515271339576785E-01, 0.0000000000000000E+00, 0.2092539651031481E-04, 0.3641666945464839E-04, 0.7966224551514293E-02, 0.1018583906139065E-23, 0.4276808715243643E-05, 0.6380573645111411E-06, 0.1685389559757755E-03, 0.0000000000000000E+00, 0.2828744147621957E-02, 0.2649548441232189E-02}, + info: 0, + }, + { + z: []float64{0.7647749557731113E+00, 0.1439440544256733E+00, 0.7500486933916728E+00, 0.6414832886183546E+00, 0.8122572937542115E+00, 0.9529234674941257E+00, 0.3352470221802866E+00, 0.6936226545338587E+00, 0.9931729574752579E-01, 0.3187856199297912E-01, 0.1671537284832858E+00, 0.6799274061730229E+00, 0.8177446911383146E+00, 0.5321042755342652E+00, 0.1611635863708949E+00, 0.1556305029012977E+00, 0.8064987994430675E+00, 0.6086425937675999E-01, 0.9539387771768112E+00, 0.5483826791143146E+00, 0.1624656726546599E+00, 0.8604262189788422E+00, 0.3348601405085260E+00, 0.6512790728986305E+00, 0.3357978279833680E+00, 0.7104789129438286E+00, 0.4161092786312924E+00, 0.8790797243791704E+00, 0.1469866181354552E+00, 0.7277776395098579E-01, 0.4317417806367096E-01, 0.8731968970940820E+00, 0.4856440529809196E+00, 0.2315660100703048E+00, 0.2955911335168215E+00, 0.4119299294790694E+00, 0.4565975215473586E+00, 0.8915397570999283E+00, 0.1639735129501203E+00, 0.5055946074157277E+00, 0.9530743160791620E+00, 0.9836351183281582E+00, 0.2913429799811792E+00, 0.9289008959282562E+00, 0.5996674664338365E+00, 0.6609996028219567E+00, 0.7317528474660470E+00, 0.9903648665746729E+00, 0.3982305249886617E+00, 0.3563571411857538E+00, 0.8851540908639802E+00, 0.8253410045707608E+00, 0.8085297859672740E+00, 0.3918185712378985E+00, 0.7922842941861202E+00, 0.7487878715845681E+00, 0.3117744132747395E+00, 0.7135433852632408E+00, 0.8969220948763633E+00, 0.5840741001028926E+00, 0.3261515465187765E+00, 0.5368137772779212E+00, 0.6371156779602756E+00, 0.5575308178040213E+00, 0.1319054467962255E+00, 0.6274305773732142E+00, 0.9230553933157697E+00, 0.3589158151867838E+00, 0.1429059780004028E+00, 0.6433214640390554E+00, 0.9159704795536289E+00, 0.8998439182451070E+00, 0.5665265465351250E+00, 0.4290736239553739E+00, 0.4923118412965143E+00, 0.3733795042755129E+00, 0.4008465132226234E+00, 0.8630963810875470E+00, 0.2835407905147469E+00, 0.8431337072866282E+00, 0.7450545748778526E+00, 0.2948369760127234E+00, 0.6896108484670013E+00, 0.1073791710993542E+00}, + n: 21, + zOut: []float64{0.2492440020550355E+01, 0.1951232214041701E+01, 0.1924880150346451E+01, 0.1800337146913507E+01, 0.1731259644349016E+01, 0.1515025732591961E+01, 0.1392131403063820E+01, 0.1337121843604905E+01, 0.1335944341051471E+01, 0.9695979508906304E+00, 0.8602855628657217E+00, 0.7598736716193354E+00, 0.5663438341779535E+00, 0.4991982558529897E+00, 0.3900147250500268E+00, 0.2612685334229408E+00, 0.1040703325016068E+00, 0.5095987426708586E-01, 0.4270469018444285E-01, 0.6313950453962554E-02, 0.4526318588114864E-04, 0.1623810366421630E-16, 0.5786287269352850E-19, 0.2440824886543042E-19, 0.1392131403063820E+01, 0.1972152263052530E-30, 0.1305662432930495E-17, 0.2687054746502436E-17, 0.1337121843604905E+01, 0.6807276388656606E-23, 0.2125450465832215E-16, 0.4166517172824519E-16, 0.1335944341051471E+01, 0.3971441341244662E-25, 0.3131313418539388E-15, 0.1598422579069803E-15, 0.9695979508906304E+00, 0.2612707318091991E-24, 0.3703169268599905E-13, 0.5897085302084673E-13, 0.8602855628657217E+00, 0.3944304526105059E-30, 0.1999104914098575E+02, 0.1999104914098576E+02, 0.1050000000000000E+03, 0.3185941043083900E+01, 0.4761904761904762E+01, 0.3815530651290367E-11, 0.5663438341779535E+00, 0.4442864618204738E-26, 0.2314135864505331E-10, 0.3280099800133426E-10, 0.4991982558529897E+00, 0.2524354896707238E-28, 0.8792792965154248E-10, 0.6284153656438893E-10, 0.3900147250500268E+00, 0.2716911819042188E-17, 0.6371083763388994E-09, 0.9063994743331422E-09, 0.2612685334229408E+00, 0.7682295356186976E-14, 0.2615630848198228E-07, 0.4934681155229334E-07, 0.1040703325016068E+00, 0.3134368286722418E-21, 0.1338644268367565E-05, 0.2571041054206291E-05, 0.5095987426708586E-01, 0.6829203137199389E-20, 0.1734538060272007E-04, 0.9160403953625247E-05, 0.4270469018444285E-01, 0.5620633949699709E-29, 0.1970936154220316E-07, 0.7875060113736862E-07, 0.6313950453962554E-02, 0.1074365444038600E-22, 0.1950342748319920E-02, 0.1960570817697857E-02, 0.4526318588114864E-04, 0.5045801736573469E-22, 0.2719687288170513E-02, 0.7229547441545878E-02}, + info: 0, + }, + { + z: []float64{0.6830594937182136E+00, 0.2806903427821971E+00, 0.3842580501524426E+00, 0.7113293946876786E+00, 0.6120481717427926E+00, 0.4087522624125913E+00, 0.2683959794755927E+00, 0.1982680719912362E+00, 0.5503761648124630E+00, 0.9947639519912582E+00, 0.4817851020535202E-01, 0.1841410650783141E+00, 0.7364485595361944E+00, 0.2204876163244174E+00, 0.8785531172976315E+00, 0.3900984044089164E+00, 0.9898399332392419E+00, 0.4652324815840650E+00, 0.6574114801218780E+00, 0.6641201888165797E+00, 0.5371222655177923E+00, 0.2241732155112269E+00, 0.6726821610374456E-01, 0.2361953456198683E+00, 0.5602287124209401E+00, 0.7836687903368798E+00, 0.2633616918428828E+00, 0.9669553142730151E+00, 0.3692579170869618E+00, 0.5395054150347700E-01, 0.4776047537674022E-01, 0.5691410116455676E+00, 0.1304181940038973E+00, 0.2107738642513712E+00, 0.5434523182333528E-01, 0.4019375962886824E+00, 0.7125153526157032E+00, 0.5305712841430671E+00, 0.1164846974244694E+00, 0.2037577925839799E+00, 0.2045617511271008E+00, 0.6122054957321945E+00, 0.5114531146106966E+00, 0.2882478115017332E+00, 0.5304873168821023E+00, 0.1796380649103803E+00, 0.9949092378946756E-01, 0.5448372048900864E+00, 0.1971761401002603E+00, 0.9487011110186927E+00, 0.8526405089060669E+00, 0.4533764477818548E+00, 0.8410819408489681E+00, 0.7592016862970913E+00, 0.8131142938762341E+00, 0.1445496351282255E+00, 0.6614974180377753E+00, 0.3394841721225367E+00, 0.4878107636737276E+00, 0.5499609605641745E+00, 0.1789798083030991E+00, 0.2008397619575961E+00, 0.5247567247775218E+00, 0.7394478154071386E+00, 0.6713478520024037E+00, 0.3894295843862983E+00, 0.9099978858741096E+00, 0.9872931573704680E-01, 0.5370559804237263E+00, 0.8492599321050560E+00, 0.4671993983916084E+00, 0.6397070306147701E+00, 0.2884512208824136E+00, 0.5002881141083532E+00, 0.3356213102526899E+00, 0.4102730364689955E+00, 0.8172446941984062E+00, 0.1463391840674726E+00, 0.6374760821459636E+00, 0.2986995049911381E+00, 0.6932950085590186E+00, 0.8475246239619540E+00, 0.3550038162879430E+00, 0.9747731646460122E+00}, + n: 21, + zOut: []float64{0.2302037253547019E+01, 0.1904432769194928E+01, 0.1838629010091233E+01, 0.1679631021950300E+01, 0.1638588328999231E+01, 0.1556939208705248E+01, 0.1154775776884602E+01, 0.1123025367728587E+01, 0.1005963210310813E+01, 0.7892040895461047E+00, 0.6171474041407791E+00, 0.5107385873854940E+00, 0.4745466376069911E+00, 0.2987072329916590E+00, 0.2518976395749056E+00, 0.1562926917018191E+00, 0.1208002043434920E+00, 0.1117929648180551E+00, 0.3025264937486962E-01, 0.5461437067005637E-02, 0.3901591662109151E-04, 0.2028008633963607E-17, 0.1197298285059118E-05, 0.1163352934520667E-05, 0.1154775776884602E+01, 0.2502221352972909E-22, 0.7438201518083012E-06, 0.8784873727121712E-06, 0.1123025367728587E+01, 0.2368236188315088E-19, 0.3676741199329849E-11, 0.3039307086935086E-11, 0.1005963210310813E+01, 0.2065553394230697E-24, 0.6686270095375819E-11, 0.8550052948388210E-11, 0.7892040895461047E+00, 0.1239058396467615E-20, 0.2067843352216928E-06, 0.6687212675645054E-07, 0.6171474041407791E+00, 0.2620094590259913E-21, 0.1757090250187976E+02, 0.1757090250187975E+02, 0.9500000000000000E+02, 0.2798185941043084E+01, 0.1052631578947368E+01, 0.6997553999213272E-08, 0.4745466376069911E+00, 0.5994838008700348E-24, 0.1052996378646298E-04, 0.6312169743031761E-04, 0.2987072329916590E+00, 0.9860761315262648E-30, 0.1466875513591431E-03, 0.1024839055944592E-03, 0.2518976395749056E+00, 0.7516632826070909E-17, 0.5524256710713082E-08, 0.1151290676113078E-07, 0.1562926917018191E+00, 0.1348952147927930E-27, 0.1222984298841777E-06, 0.3042067118561864E-06, 0.1208002043434920E+00, 0.4760428464210509E-23, 0.9492582004636672E-05, 0.3402727365723720E-04, 0.1117929648180551E+00, 0.7018716354804804E-22, 0.2431231599464108E-03, 0.1315672135071063E-03, 0.3025264937486962E-01, 0.4377821080194221E-21, 0.1333575496853992E-02, 0.6988231628130009E-03, 0.5461437067005637E-02, 0.2193916840728260E-24, 0.1845211740639344E-02, 0.8881725247692956E-03, 0.3901591662109151E-04, 0.2067951531382569E-23, 0.6469870796864946E-02, 0.1027022788337614E-01}, + info: 0, + }, + { + z: []float64{0.3270384527330652E+00, 0.4068565573647237E+00, 0.5445258191923925E+00, 0.9571802305689175E+00, 0.1840747434207346E-01, 0.8759261930487382E+00, 0.3018283835341639E+00, 0.4754674889513868E+00, 0.9620709342523251E+00, 0.3596342978433105E+00, 0.1820397917245298E+00, 0.9562190617892271E+00, 0.8004073710305811E+00, 0.9503584926946729E+00, 0.1634422399578277E+00, 0.3053134184266467E+00, 0.3871438286377282E+00, 0.1225252880124038E+00, 0.5955538022158587E+00, 0.9831372787057571E+00, 0.2130378801829313E+00, 0.1502296787149880E+00, 0.5120891507658710E+00, 0.2769158347903287E+00, 0.6740978559159013E+00, 0.6671510755324899E+00, 0.5252429573239310E+00, 0.7312875683466940E+00, 0.6359518339326128E+00, 0.3635213813950466E-01, 0.7509704695539338E+00, 0.2796455326190517E+00, 0.3929933998036216E+00, 0.2441550702438192E+00, 0.5181887041338979E+00, 0.2149631476903890E-01, 0.1922157358558590E+00, 0.8352708839021310E+00, 0.2143118694803675E+00, 0.8099207585987700E+00, 0.4013415573783083E+00, 0.8990854368069680E+00, 0.2274365144039603E-01, 0.1574221848735892E+00, 0.5021896402707141E+00, 0.6811320055313477E+00, 0.4008235511220088E+00, 0.2607115591315068E+00, 0.8396807341169598E+00, 0.3393611517447541E+00, 0.3095200315094494E+00, 0.8849677836408325E+00, 0.3309280721041051E+00, 0.2177939175852258E+00, 0.7396054658394657E-02, 0.5387313739545944E+00, 0.5592732178453728E+00, 0.4422242955757759E+00, 0.6010599951901635E+00, 0.2729214395073326E+00, 0.8861412244709392E+00, 0.3303460134234409E+00, 0.3230906405176623E+00, 0.5979281304041633E+00, 0.1747480524852378E+00, 0.5019201598522602E+00, 0.3041629115671023E+00, 0.7344252813174572E+00, 0.5145018596354390E+00, 0.7032668540687012E+00, 0.4542245378490408E+00, 0.6883469599293311E+00, 0.7365046871633816E+00, 0.6892200550994384E+00, 0.9612097768268251E+00, 0.3687306903044788E+00, 0.4902139977664450E+00, 0.4004732628576805E+00, 0.2121831569752699E+00, 0.3483027732062219E+00, 0.4140454821962284E+00, 0.5590476647584736E+00, 0.1191647727722587E+00, 0.7126611758207085E+00}, + n: 21, + zOut: []float64{0.2451808019367049E+01, 0.2128252216129400E+01, 0.1884015768998821E+01, 0.1793403527862625E+01, 0.1731698897481475E+01, 0.1605979322764491E+01, 0.1346135733575790E+01, 0.1222183737737495E+01, 0.1054517637460965E+01, 0.8541696661721662E+00, 0.8335553929836017E+00, 0.7643627371640215E+00, 0.6493538020248019E+00, 0.5117674171078171E+00, 0.4801902398267136E+00, 0.1830481952424627E+00, 0.1336751260833609E+00, 0.7548204386515513E-01, 0.4276641694583261E-01, 0.1152852330305948E-01, 0.4825291327526518E-04, 0.1046558665109411E-21, 0.5148060409033168E-10, 0.1742874021361670E-10, 0.1346135733575790E+01, 0.3944304526105059E-30, 0.1177385120842054E-08, 0.5739784145251797E-09, 0.1222183737737495E+01, 0.5228352308675503E-16, 0.2817945521555932E-11, 0.1891433639936970E-11, 0.1054517637460965E+01, 0.1775328283321620E-16, 0.9506244555381454E-11, 0.6780149876052939E-11, 0.8541696661721662E+00, 0.4289572169691169E-11, 0.3560204585171959E-10, 0.5552509181949502E-10, 0.8335553929836017E+00, 0.8925278809447169E-21, 0.1975794267501038E+02, 0.1975794267501038E+02, 0.9900000000000000E+02, 0.3029478458049887E+01, 0.2020202020202020E+01, 0.4057773458399609E-09, 0.6493538020248019E+00, 0.3196600703119960E-17, 0.4936238682205707E-06, 0.2172173957444601E-06, 0.5117674171078171E+00, 0.2475160268480207E-20, 0.1127880382626992E-04, 0.1031817493791828E-04, 0.4801902398267136E+00, 0.2327139670401985E-28, 0.8359957951383868E-05, 0.8045173068477057E-05, 0.1830481952424627E+00, 0.2763487036072314E-23, 0.1049648761427048E-04, 0.8607871065540926E-05, 0.1336751260833609E+00, 0.6392286336815055E-18, 0.5478798785309189E-04, 0.3178071334079827E-04, 0.7548204386515513E-01, 0.1886324196564483E-25, 0.4604839715747456E-05, 0.3206078546562559E-04, 0.4276641694583261E-01, 0.2130807968310579E-24, 0.2160396768988393E-02, 0.2401524776593251E-02, 0.1152852330305948E-01, 0.4597153189491485E-23, 0.1577121702032026E-02, 0.1548884890976950E-02, 0.4825291327526518E-04, 0.0000000000000000E+00, 0.1144436370534878E-01, 0.4805213857273134E-02}, + info: 0, + }, + { + z: []float64{0.1204296195656108E+00, 0.2644532009534747E+00, 0.2981945708465356E+00, 0.3379851046426219E-01, 0.5872157683391875E+00, 0.3661495849020495E+00, 0.2783310889774259E+00, 0.8471009797765506E+00, 0.6087926721027869E+00, 0.7227374835926721E+00, 0.1157491272838733E+00, 0.5565144099551486E+00, 0.8949691253636921E+00, 0.4271566773654165E+00, 0.6387841251831913E+00, 0.3125047228733280E-01, 0.2092736013478247E-01, 0.9188324418961444E+00, 0.2275180796997284E+00, 0.4519662960462961E+00, 0.1155877493866434E+00, 0.3574940735178409E+00, 0.1489772525039219E+00, 0.3847908470095970E+00, 0.4780110568180811E+00, 0.3489586723075616E+00, 0.2559758537216194E+00, 0.7015930720521131E+00, 0.6512181083044030E+00, 0.1619173394771481E+00, 0.5094142654629881E+00, 0.9037662631759247E+00, 0.8829671919577533E+00, 0.5739200804260277E+00, 0.6584413366512047E+00, 0.7174965427568090E+00, 0.2705911606916550E+00, 0.6519148889036277E+00, 0.8284421625450799E+00, 0.1417109678591228E+00, 0.8472265674806589E-01, 0.3638971914001953E+00, 0.8802661885427909E-01, 0.5730596475071164E+00, 0.6156880168413905E+00, 0.3769532609458294E+00, 0.6302840487845919E+00, 0.8652028697564479E+00, 0.5886269364510055E-01, 0.9901772381773877E-01, 0.9679961670969370E+00, 0.9025028618130532E+00, 0.2858592550914936E+00, 0.4523960301168739E-01, 0.9961073801516410E+00, 0.5404176614913075E+00, 0.2161216977420954E+00, 0.6517643909270738E+00, 0.1408193879882935E-01, 0.2323315528058443E+00, 0.4040647670376405E+00, 0.5063393857452272E+00, 0.2149141182072994E+00, 0.8405813011731451E+00, 0.8044826512704509E+00, 0.5364711289689184E+00, 0.2922476360373625E+00, 0.9518940562302493E+00, 0.1980063292193738E+00, 0.6243757640305569E-01, 0.3641799792979717E+00, 0.4781083740929701E+00, 0.3488268687432241E+00, 0.8284107864073382E+00, 0.5855039308834178E+00, 0.2593007284605915E+00, 0.9998845891621441E+00, 0.5048349794999019E+00, 0.5828201446782487E+00, 0.8921301000231074E+00, 0.2672402237051515E+00, 0.3352853759971494E+00, 0.5977528180071631E+00, 0.1151194604047919E+00}, + n: 21, + zOut: []float64{0.2557315455353142E+01, 0.2083235685800309E+01, 0.1875944452104717E+01, 0.1852714062580819E+01, 0.1643995946812320E+01, 0.1314218355716144E+01, 0.1293789198407225E+01, 0.1108624029644386E+01, 0.1060866236520538E+01, 0.6893140608436983E+00, 0.6265017468006577E+00, 0.6169803536834606E+00, 0.4472638275156540E+00, 0.3909824987049766E+00, 0.2990543016857948E+00, 0.1644755201813542E+00, 0.1145158516686298E+00, 0.6240413476421734E-01, 0.2540980528285533E-01, 0.1114684260186565E-01, 0.3077034058364147E-04, 0.1514612938024343E-27, 0.1068838715614041E-10, 0.1816953714834036E-10, 0.1293789198407225E+01, 0.1634858280249726E-16, 0.1546152805249061E-09, 0.7139985980503436E-10, 0.1108624029644386E+01, 0.1852295205932338E-17, 0.2931760870340471E-08, 0.5717158524063146E-08, 0.1060866236520538E+01, 0.1656986554198631E-24, 0.3897819821179759E-07, 0.2050786216968739E-07, 0.6893140608436983E+00, 0.1054613376713825E-21, 0.1114796130440952E-06, 0.1754727955273104E-06, 0.6265017468006577E+00, 0.0000000000000000E+00, 0.1823878313701335E+02, 0.1823878313701335E+02, 0.1020000000000000E+03, 0.3172335600907029E+01, 0.3921568627450980E+01, 0.4944285541926277E-08, 0.4472638275156540E+00, 0.7188113412291574E-19, 0.5360570179815202E-09, 0.5055207828345367E-09, 0.3909824987049766E+00, 0.7011182861561962E-17, 0.5424596001050196E-08, 0.1149191082508281E-07, 0.2990543016857948E+00, 0.1397964075969312E-24, 0.2148922978775398E-05, 0.1039924072201963E-05, 0.1644755201813542E+00, 0.1424715207546021E-19, 0.1286356681922344E-03, 0.6709371685087021E-04, 0.1145158516686298E+00, 0.1923558431290915E-24, 0.1040681698574874E-03, 0.9690504707177204E-04, 0.6240413476421734E-01, 0.3021337266996475E-27, 0.3740811812377314E-06, 0.8725750691496404E-06, 0.2540980528285533E-01, 0.6622271595176623E-28, 0.2937391640354928E-03, 0.1148070460566611E-03, 0.1114684260186565E-01, 0.3845696912952433E-29, 0.9582588059437623E-03, 0.1284334386264186E-02, 0.3077034058364147E-04, 0.1610185014413679E-23, 0.1713355521956925E-01, 0.1560043716021792E-01}, + info: 0, + }, + { + z: []float64{0.6550531738065145E+00, 0.9006303757888976E+00, 0.9204609778380736E+00, 0.4658341923257867E+00, 0.5436644687290008E+00, 0.2908556755036122E+00, 0.1209811495723523E+00, 0.6227378829506942E+00, 0.3843019792679099E+00, 0.4431829610151485E+00, 0.4903210952175132E+00, 0.4210264133022774E+00, 0.3200750839632230E+00, 0.2252794777033682E+00, 0.5128630958928748E-01, 0.5136099492114639E+00, 0.4906286803922755E+00, 0.1747340137845675E+00, 0.6367238354860758E+00, 0.7515407582129341E+00, 0.4275500565044866E+00, 0.2014278558825494E+00, 0.7137603260056157E+00, 0.8686875192977085E+00, 0.7169591605793454E+00, 0.9050302202813415E+00, 0.9899533400874350E-01, 0.9969046692447475E+00, 0.6121260436585757E+00, 0.6518683331715626E+00, 0.5607404970528083E+00, 0.4000687152662108E-03, 0.1221862374388689E+00, 0.4484923714483016E+00, 0.4074629631039243E+00, 0.2322333097032281E-01, 0.4732551077558298E+00, 0.7342979327909982E+00, 0.3458749207719752E+00, 0.7729568887054280E+00, 0.2047858477824707E+00, 0.7991048365911296E+00, 0.5370237056253078E+00, 0.2233168849800682E-01, 0.5135288197983614E+00, 0.9129664417816657E+00, 0.9407166870649586E+00, 0.4321958081203685E+00, 0.5563774896630214E-01, 0.9494906037764664E+00, 0.9674063566885983E+00, 0.2302624676329315E+00, 0.1506811640032519E+00, 0.4445855507514112E+00, 0.6038782945102905E-01, 0.4499742519338505E+00, 0.1940991655604004E+00, 0.6493052482066142E-01, 0.2902929850901331E+00, 0.2876163569026815E+00, 0.9140475482126542E+00, 0.7006705577674063E+00, 0.2819386709216735E+00, 0.9125816873773608E+00, 0.9433170896498744E-01, 0.1632821600392161E+00, 0.3150556796654537E+00, 0.4051206017420083E+00, 0.2687493393481850E+00, 0.5768057516945001E+00, 0.4306858988251338E+00, 0.3827211690774009E+00, 0.3593520435650671E+00, 0.5610694397953092E+00, 0.7151178950427733E+00, 0.7138830385076256E-01, 0.5281951083990266E-01, 0.4880677722651299E+00, 0.9334247489037772E+00, 0.6764242544288053E+00, 0.8551178347453967E+00, 0.1876923010834376E+00, 0.7408118952029578E+00, 0.7967219280126981E+00}, + n: 21, + zOut: []float64{0.2493394334366539E+01, 0.2460477172068809E+01, 0.2083159145455880E+01, 0.1779228959307519E+01, 0.1724095029781113E+01, 0.1560812668654360E+01, 0.1120482054552078E+01, 0.1088744749350826E+01, 0.9613598859526896E+00, 0.9456175481954929E+00, 0.9119552728538921E+00, 0.7767939725863090E+00, 0.6893167116879397E+00, 0.4408717103973492E+00, 0.2706330695081346E+00, 0.2343515836463984E+00, 0.6795401725828518E-01, 0.6600498464192311E-01, 0.2004873521291848E-01, 0.1421097732958122E-01, 0.4015560238058376E-03, 0.2226481018895784E-25, 0.2564499425740104E-12, 0.2658329977886514E-12, 0.1120482054552078E+01, 0.4315813836253463E-23, 0.1335501643346940E-12, 0.1368307862991113E-12, 0.1088744749350826E+01, 0.3926080427856238E-18, 0.1185565636052547E-12, 0.1214013431095007E-12, 0.9613598859526896E+00, 0.2719992401202049E-26, 0.9906513980413714E-13, 0.1012398200894782E-12, 0.9456175481954929E+00, 0.3937993638863291E-26, 0.9389079133840153E-13, 0.9189527811944332E-13, 0.9119552728538921E+00, 0.1580250204306566E-21, 0.1970991413883184E+02, 0.1970991413883184E+02, 0.1080000000000000E+03, 0.3401360544217687E+01, 0.8333333333333334E+01, 0.6496201881821226E-13, 0.6893167116879397E+00, 0.2040319821514109E-19, 0.6886568712781699E-13, 0.6342531805840532E-13, 0.4408717103973492E+00, 0.9116462109840799E-16, 0.6575726430673280E-12, 0.1146915438924438E-11, 0.2706330695081346E+00, 0.6100742213737356E-14, 0.5548784478521690E-10, 0.9411844035493366E-10, 0.2343515836463984E+00, 0.2464780121144947E-24, 0.1267470050081896E-08, 0.7549586177318002E-09, 0.6795401725828518E-01, 0.6058451752097371E-27, 0.2494439518946058E-07, 0.4030144639288306E-07, 0.6600498464192311E-01, 0.1931466728993349E-20, 0.1742718098912744E-06, 0.1063050845015484E-06, 0.2004873521291848E-01, 0.2078695185822955E-22, 0.1365398583912438E-05, 0.6056776980192580E-06, 0.1421097732958122E-01, 0.3944304526105059E-30, 0.8436693551699617E-06, 0.8772483974218289E-06, 0.4015560238058376E-03, 0.5424456586666688E-20, 0.1372662528173007E-02, 0.2323379424199439E-03}, + info: 0, + }, + { + z: []float64{0.5955158028190186E+00, 0.9601282390728449E-01, 0.2944266054820921E+00, 0.3924250378682403E+00, 0.4462256781176310E-01, 0.5690757232665151E+00, 0.7855339329019884E-01, 0.8681545225840360E+00, 0.7288006955920397E+00, 0.2963229749240101E+00, 0.2728029241156386E+00, 0.4237536504971896E+00, 0.9003368942847588E+00, 0.7357957067011865E+00, 0.4901129309073038E-01, 0.4716171621744532E+00, 0.4890099406800087E+00, 0.3570165784460172E+00, 0.7160897857565474E-01, 0.6109824519907316E+00, 0.1221913259189585E+00, 0.1847302629402909E+00, 0.4009366884871202E-01, 0.9703472440233364E+00, 0.6369052870991366E+00, 0.5580400433416689E+00, 0.9024815855223057E+00, 0.1227045689636573E+00, 0.9668897094172768E+00, 0.5989409973498315E+00, 0.9709139844325040E+00, 0.9532564522700616E+00, 0.6239574483953332E+00, 0.7056703505253071E+00, 0.9506691238320553E-01, 0.7998586962365666E+00, 0.6556519136464994E+00, 0.4181856697120553E+00, 0.9478314170226607E+00, 0.3832663309972284E-01, 0.4257218688507075E+00, 0.2049443327129853E+00, 0.9168853967010917E+00, 0.5423988966788751E-02, 0.3002879152136316E+00, 0.7743151012217909E+00, 0.5154350917338609E+00, 0.9658560730800175E+00, 0.6314599250676610E+00, 0.5584937104443134E+00, 0.4741445335250092E+00, 0.3157508358915576E+00, 0.4349529093465575E+00, 0.7860003715032308E+00, 0.8695087804152180E-02, 0.3920445280700808E+00, 0.3765485221235618E+00, 0.4334604109656897E+00, 0.1636117026415890E+00, 0.3006093728066712E+00, 0.2129148932459900E+00, 0.3092975700919495E+00, 0.1986761620686717E-01, 0.9075541031649185E+00, 0.9781911433730479E+00, 0.6945955075731600E+00, 0.9959584477684137E+00, 0.7505944883792014E+00, 0.7627854018352902E+00, 0.1267035334952504E+00, 0.8056780234474171E+00, 0.4507060196586773E+00, 0.1799397964631048E+00, 0.7554691089798000E+00, 0.3012534688386570E+00, 0.9612172487804931E+00, 0.4056708256608614E+00, 0.6648221051068217E+00, 0.1966051207552482E+00, 0.6661008672469584E+00, 0.6875730168317549E+00, 0.9591133633640367E+00, 0.8995318056907078E+00, 0.1435403265941513E+00}, + n: 21, + zOut: []float64{0.2826953331143077E+01, 0.2184946373215138E+01, 0.2011432985807930E+01, 0.1983939371799505E+01, 0.1783403572375380E+01, 0.1527291743334771E+01, 0.1218359458122959E+01, 0.1031625203087357E+01, 0.9141017580644314E+00, 0.8935891545682184E+00, 0.7995009441187808E+00, 0.6760292370761557E+00, 0.5375939998175604E+00, 0.5031272745805969E+00, 0.4136950654384539E+00, 0.4077555149266558E+00, 0.1977184484214556E+00, 0.1172157517521918E+00, 0.4197144528461013E-01, 0.1336078057720851E-01, 0.3545889291755145E-06, 0.2544082546855865E-16, 0.2583036406189355E-05, 0.3206950450307273E-05, 0.1218359458122959E+01, 0.6512835633504673E-25, 0.5241867641497365E-06, 0.5644106780290774E-06, 0.1031625203087357E+01, 0.0000000000000000E+00, 0.4305359229680111E-07, 0.8271940560154021E-07, 0.9141017580644314E+00, 0.0000000000000000E+00, 0.3911233321019150E-06, 0.2241550799736728E-06, 0.8935891545682184E+00, 0.2385737520619250E-22, 0.4206034452718400E-11, 0.9899461762377114E-11, 0.7995009441187808E+00, 0.9331359083488707E-16, 0.2008361176810137E+02, 0.2008361176810137E+02, 0.1130000000000000E+03, 0.3444444444444445E+01, 0.6194690265486726E+01, 0.1651034509856568E-04, 0.5375939998175604E+00, 0.1421716677825516E-23, 0.1528222338287967E-04, 0.2433829126418849E-04, 0.5031272745805969E+00, 0.6632003279205155E-19, 0.4757657931696731E-05, 0.2751276356124619E-05, 0.4136950654384539E+00, 0.1680371209901916E-16, 0.1318069984220972E-06, 0.1659409431372840E-06, 0.4077555149266558E+00, 0.2554525986432683E-22, 0.5944173486813264E-06, 0.1429245864393051E-05, 0.1977184484214556E+00, 0.1494891415393817E-27, 0.8465737022131437E-03, 0.4160790916597339E-03, 0.1172157517521918E+00, 0.6780166836549887E-20, 0.3655496023749206E-04, 0.5562211290196199E-04, 0.4197144528461013E-01, 0.1803076020780872E-22, 0.2337686132102848E-02, 0.5241185550833300E-02, 0.1336078057720851E-01, 0.3234329711406148E-27, 0.6369386968947829E-02, 0.2727172056719641E-02, 0.3545889291755145E-06, 0.0000000000000000E+00, 0.6135698199493001E-02, 0.4453215245051444E-02}, + info: 0, + }, + { + z: []float64{0.5256994769563229E+00, 0.4751970954150097E+00, 0.5550798296722601E+00, 0.3565746805143110E+00, 0.3971523551134015E-01, 0.7088262788771817E+00, 0.6369448567868402E+00, 0.6372974860231623E+00, 0.5963599363854956E+00, 0.7996832763398349E+00, 0.7266271077857295E+00, 0.3813393981851099E+00, 0.8884393254050771E-01, 0.8685934834267716E+00, 0.3797066359545181E+00, 0.4541910736411658E+00, 0.6285354031372432E+00, 0.5295256159852654E+00, 0.8908170817260027E+00, 0.5793264969983637E+00, 0.6056871126785802E+00, 0.6045507124525907E+00, 0.9734230310286895E-01, 0.9482358811543057E+00, 0.8804820874856442E+00, 0.4472263119108183E+00, 0.5843860139759072E+00, 0.5372922689923049E+00, 0.5799351791336661E+00, 0.5116182356749631E+00, 0.3816355069915517E+00, 0.6475808331559241E+00, 0.8746013736579017E-02, 0.8411650861050215E+00, 0.2992737481736951E-01, 0.6246901010621124E+00, 0.3123078564554325E+00, 0.7411164234121632E+00, 0.5960432842954070E+00, 0.8102594121204127E+00, 0.3552957522458323E+00, 0.6235337320803771E+00, 0.5962195242077326E+00, 0.4845790335098474E+00, 0.4045953379382708E+00, 0.2452522545656534E+00, 0.2743318280596185E+00, 0.2023077390748810E+00, 0.4206973723636350E+00, 0.4039949452544738E+00, 0.9114680949622015E+00, 0.7779482986378454E+00, 0.6812819304160683E+00, 0.5580962104642140E-01, 0.4287711156774094E+00, 0.9817581515129085E+00, 0.4431516884275333E+00, 0.6237912221093689E-01, 0.8364254576520689E+00, 0.8759899245723605E+00, 0.8787473635901457E+00, 0.4702211826699049E+00, 0.8284521047414805E+00, 0.2041855966018515E+00, 0.8060130309143703E+00, 0.5501723689038956E+00, 0.2188842792675016E-01, 0.5672241818001204E+00, 0.6450459353754012E+00, 0.2431902854401001E+00, 0.5193698672717711E+00, 0.1962120228423043E+00, 0.6361488000943472E-01, 0.5342761659162559E+00, 0.1758994081846166E-01, 0.7459187699999678E+00, 0.5953394313659540E+00, 0.9379918174958790E+00, 0.4032831592210619E+00, 0.7704238877222783E+00, 0.9410981148731864E+00, 0.8355998775704846E+00, 0.7904637124553195E+00, 0.4324126135288506E+00}, + n: 21, + zOut: []float64{0.2360605380677641E+01, 0.2349812365456326E+01, 0.2259072978559188E+01, 0.2074669549844899E+01, 0.1734529465065066E+01, 0.1635336277856887E+01, 0.1535245292061319E+01, 0.1453596007978833E+01, 0.1156130097482147E+01, 0.1084746900314168E+01, 0.1034520391904089E+01, 0.8201881896309742E+00, 0.6191782955028541E+00, 0.5267433243518804E+00, 0.4355086546946592E+00, 0.4155619327338856E+00, 0.3396295360604018E+00, 0.9317218785919168E-01, 0.5773665727788814E-01, 0.1842462732727454E-01, 0.2018232369069597E-07, 0.4517585523147273E-24, 0.2167663685989129E-10, 0.1523023581682742E-10, 0.1535245292061319E+01, 0.1340432450151543E-25, 0.8069500146896454E-10, 0.1279555645700667E-09, 0.1453596007978833E+01, 0.6673291668607916E-16, 0.1337219714947293E-07, 0.4537550993048733E-08, 0.1156130097482147E+01, 0.2388039732285047E-25, 0.6170125127971897E-05, 0.1353762614268721E-04, 0.1084746900314168E+01, 0.3862470231561244E-18, 0.2338329578753200E-04, 0.2318969913953679E-04, 0.1034520391904089E+01, 0.6409494854920721E-30, 0.2200440813282189E+02, 0.2200440813282190E+02, 0.9400000000000000E+02, 0.2857142857142857E+01, 0.0000000000000000E+00, 0.2156912239043876E-04, 0.6191782955028541E+00, 0.4311940021813490E-19, 0.2098085305628239E-04, 0.2047701462113856E-04, 0.5267433243518804E+00, 0.7292491488692259E-18, 0.2483658471590867E-04, 0.2278231239253353E-04, 0.4355086546946592E+00, 0.6335396825622830E-16, 0.5560492899787359E-04, 0.8068766398366361E-04, 0.4155619327338856E+00, 0.7336406418555410E-28, 0.3220618566867426E-03, 0.1956958209756436E-03, 0.3396295360604018E+00, 0.1297676189088564E-27, 0.4121897802138222E-02, 0.2587205720417875E-02, 0.9317218785919168E-01, 0.7651950780643815E-28, 0.2826512581544380E-02, 0.2814359488753958E-02, 0.5773665727788814E-01, 0.4923437167052441E-21, 0.1821079370679042E-04, 0.2969056479875054E-04, 0.1842462732727454E-01, 0.4842851680813876E-21, 0.4217326450522519E-02, 0.5738852897157041E-02, 0.2018232369069597E-07, 0.2018232369069597E-07, 0.3702854219118327E-02, 0.7091388009151286E-02}, + info: 0, + }, + { + z: []float64{0.5196081465664333E+00, 0.1450873999446859E+00, 0.1902498073897446E+00, 0.9459083122514356E-01, 0.6971960507146802E-01, 0.2126447963850432E+00, 0.1693138701795316E-01, 0.6615449591751588E-01, 0.6671851537110856E+00, 0.7116922416084167E+00, 0.7735840319989629E+00, 0.8593705742984634E+00, 0.6060015557980403E+00, 0.1071620560007485E+00, 0.6056582690297291E+00, 0.2064801115284116E+00, 0.4992099275808294E+00, 0.9056413330105546E+00, 0.6051575714193578E+00, 0.1395071235858423E+00, 0.3386142237730057E+00, 0.2065895571122717E+00, 0.2774285740015214E-01, 0.4649920904615868E+00, 0.9062834189437683E+00, 0.3022801499192989E+00, 0.2125071125007829E+00, 0.2366624610094756E+00, 0.3232052419625674E+00, 0.5879745505340277E+00, 0.3212955913685801E+00, 0.9110441809347004E+00, 0.2144184579231917E+00, 0.5617161155671668E-01, 0.9725855527757206E+00, 0.9798782363582490E+00, 0.9666637418953663E+00, 0.1842420381101751E+00, 0.9810363127661145E+00, 0.4061071205983764E+00, 0.4929437214282740E+00, 0.3087398230344144E+00, 0.8692083335886002E+00, 0.7401065606674918E+00, 0.6829833274325647E+00, 0.9797795404622264E+00, 0.6101846761247042E+00, 0.7796537878703258E+00, 0.4568641605073986E-01, 0.1752946998854403E+00, 0.7558659638245062E+00, 0.4081915619381170E+00, 0.5344465439920063E+00, 0.3199118710728778E+00, 0.3613720388280138E+00, 0.1409062127217534E+00, 0.2811520826338662E+00, 0.9462348779627723E+00, 0.4911007415294493E+00, 0.2488061765237712E+00, 0.1661818317483100E+00, 0.1203910774987040E+00, 0.4544163143251944E+00, 0.8767242907488393E+00, 0.6688224142601292E+00, 0.2497550267789769E+00, 0.2658845545571695E+00, 0.4072601097670568E+00, 0.5517137496493807E+00, 0.4206663434956901E+00, 0.3655154771809294E+00, 0.6509199815744504E-01, 0.6480911975614350E+00, 0.1271267318339999E+00, 0.8874102966539428E+00, 0.9607257650026479E+00, 0.8902777005093224E+00, 0.7074702462790970E+00, 0.5045879991550398E+00, 0.3357826713243962E+00, 0.9303671751018463E+00, 0.3667268693834904E+00, 0.7709773173263057E+00, 0.1274123220614284E+00}, + n: 21, + zOut: []float64{0.2669666350125788E+01, 0.2458073928301015E+01, 0.1960648799383531E+01, 0.1674511937828339E+01, 0.1629444569956276E+01, 0.1605168511500282E+01, 0.1169506153633164E+01, 0.8378899015114316E+00, 0.8214470290652885E+00, 0.7290022816300561E+00, 0.5956393798847858E+00, 0.5147057006185641E+00, 0.3415078453317431E+00, 0.3316800239182673E+00, 0.2245847640277715E+00, 0.1981086483360383E+00, 0.1729134064527326E+00, 0.1081292683666610E+00, 0.4856623040087921E-01, 0.2705373732739987E-02, 0.9745444154776346E-03, 0.7298616502634276E-19, 0.4601636530183765E-14, 0.3001385089664378E-13, 0.1169506153633164E+01, 0.5522026336547083E-28, 0.9439817212889541E-12, 0.1534086358433234E-11, 0.8378899015114316E+00, 0.7174347921301560E-11, 0.1095021852663145E-10, 0.1580074435702411E-10, 0.8214470290652885E+00, 0.3131705799125763E-20, 0.2247124942125492E-10, 0.3228253356903498E-10, 0.7290022816300561E+00, 0.6063934311659721E-18, 0.3794147471177530E-13, 0.3318524623173314E-12, 0.5956393798847858E+00, 0.3765687391680646E-13, 0.1809487464842083E+02, 0.1809487464842083E+02, 0.1050000000000000E+03, 0.3215419501133787E+01, 0.3809523809523809E+01, 0.2077325438490571E-07, 0.3415078453317431E+00, 0.1645262238367970E-20, 0.7912752069326401E-07, 0.6053132028546428E-07, 0.3316800239182673E+00, 0.4184118241292247E-26, 0.1343987419983520E-06, 0.1754397466154310E-06, 0.2245847640277715E+00, 0.3340387958036406E-22, 0.6150231447604006E-06, 0.4780001259056422E-06, 0.1981086483360383E+00, 0.1070733604161610E-20, 0.1003229473607176E-05, 0.1287291281183416E-05, 0.1729134064527326E+00, 0.1298955481663118E-20, 0.1611116216931278E-05, 0.3807035614938680E-06, 0.1081292683666610E+00, 0.4901279578837721E-23, 0.3565927169328702E-03, 0.2312261838015572E-03, 0.4856623040087921E-01, 0.3325573155747123E-13, 0.4389787505319806E-03, 0.9715248586459800E-03, 0.2705373732739987E-02, 0.1348432029845013E-20, 0.7371401467208961E-04, 0.2975668602269332E-04, 0.9745444154776346E-03, 0.4135903062570168E-24, 0.7273370201297700E-04, 0.3602244970122637E-04}, + info: 0, + }, + { + z: []float64{0.3441168249350421E+00, 0.7064572711980356E+00, 0.6589781374655990E+00, 0.8687841598825752E+00, 0.7811747459515918E+00, 0.7470750719206745E+00, 0.7591454338662803E+00, 0.7956934079357347E-01, 0.3416983743372617E+00, 0.3365394610260509E+00, 0.8635365040683821E+00, 0.4793906833418223E+00, 0.9394584418725971E+00, 0.7354375226759881E+00, 0.3959912256877245E+00, 0.4088558388864650E+00, 0.6899389113237457E+00, 0.6329180251180861E+00, 0.6760812245614891E+00, 0.1743991444245150E+00, 0.3881927716152306E+00, 0.2103848624556167E+00, 0.5309784956583943E+00, 0.5758384660199964E+00, 0.6542468116269122E+00, 0.2141275453071043E+00, 0.4917208240158387E+00, 0.6996271491850585E+00, 0.7074081025976766E+00, 0.1896811377589238E+00, 0.4872676647104760E+00, 0.8987347035581787E+00, 0.1651654313203957E+00, 0.7969431328829826E+00, 0.8979672856778195E+00, 0.2621352236509209E+00, 0.2994430908669790E+00, 0.8412000921937168E+00, 0.6910228781616401E-01, 0.9849719192333963E+00, 0.2835195798153757E+00, 0.6126955834278749E+00, 0.9957514180764350E+00, 0.4133859474205875E+00, 0.2126790023013077E+00, 0.9230696247878700E-01, 0.5165813646587417E+00, 0.9232126059423650E+00, 0.6160486127374017E+00, 0.5529065454633691E+00, 0.6862175458708878E+00, 0.2677675454795836E-01, 0.6729513992144193E+00, 0.8612993184178528E+00, 0.5455358966165057E+00, 0.2518716982253303E+00, 0.5312849864208884E+00, 0.7551228210749875E+00, 0.1095520838657484E+00, 0.8767983608629261E+00, 0.9578119141004069E+00, 0.6878921114137557E+00, 0.2890574974795965E+00, 0.9851780344062913E+00, 0.9392886821673129E+00, 0.4125982690623264E+00, 0.6817912182549608E+00, 0.7805388095263401E+00, 0.1567802887930034E+00, 0.1901362770322003E+00, 0.5155717108920093E+00, 0.5470641908290981E+00, 0.9496522047623522E+00, 0.4367251554723609E+00, 0.7016249991347693E+00, 0.6652534390290816E+00, 0.3892590437090979E+00, 0.1464591367640408E+00, 0.9179795596761495E+00, 0.1527313083317114E+00, 0.8661173016992874E+00, 0.8044520995141484E+00, 0.4399581275677011E+00, 0.6590078920726725E+00}, + n: 21, + zOut: []float64{0.2654671686308588E+01, 0.2409077903364995E+01, 0.2090082174851482E+01, 0.1940605709090538E+01, 0.1909776782011245E+01, 0.1629990303184568E+01, 0.1566043989638403E+01, 0.1473218419964192E+01, 0.1321200673977518E+01, 0.1275771383585936E+01, 0.9826159405158056E+00, 0.8184731809209335E+00, 0.6715230178331039E+00, 0.5669018352800101E+00, 0.3641671875118937E+00, 0.2699135892930649E+00, 0.1446269090001342E+00, 0.8937359624216266E-01, 0.5860931848549461E-01, 0.3094108728329079E-01, 0.6182329613034853E-03, 0.9233403587623171E-22, 0.2552413399194827E-12, 0.1309204970235786E-12, 0.1566043989638403E+01, 0.2003762315848454E-18, 0.9222125989396634E-12, 0.1831545934750265E-11, 0.1473218419964192E+01, 0.1899959664962892E-11, 0.5682525570474145E-10, 0.1113952503246639E-09, 0.1321200673977518E+01, 0.5311918312726658E-16, 0.2115322762070563E-08, 0.1208354514490733E-08, 0.1275771383585936E+01, 0.1424261829852281E-16, 0.6059411460508015E-08, 0.1032477558436010E-07, 0.9826159405158056E+00, 0.5397353496908506E-22, 0.2226820292130466E+02, 0.2226820292130466E+02, 0.9500000000000000E+02, 0.2927437641723356E+01, 0.1052631578947368E+01, 0.2555943178691847E-06, 0.6715230178331039E+00, 0.1218922493912602E-18, 0.4789189736721279E-06, 0.5466231772857101E-06, 0.5669018352800101E+00, 0.1893266172530428E-27, 0.9952011217509916E-06, 0.1128113648538554E-05, 0.3641671875118937E+00, 0.1993230626440035E-24, 0.2427606592544749E-05, 0.2156829827516489E-05, 0.2699135892930649E+00, 0.2761013168273541E-29, 0.3900010091178873E-05, 0.3393761026267541E-05, 0.1446269090001342E+00, 0.2150416673893778E-15, 0.8242388755752233E-05, 0.1105863902029246E-04, 0.8937359624216266E-01, 0.2934562567422164E-27, 0.3455780897358792E-04, 0.2250328346305790E-04, 0.5860931848549461E-01, 0.8147325136863849E-21, 0.2346512312055719E-04, 0.8962661529405173E-05, 0.3094108728329079E-01, 0.2460979885389816E-17, 0.5238375287742530E-03, 0.1080192509223090E-02, 0.6182329613034853E-03, 0.8383483586160605E-23, 0.7400552677463828E-02, 0.1581674273722876E-01}, + info: 0, + }, + { + z: []float64{0.7940281584071446E+00, 0.8540600349699839E+00, 0.8158431165852809E-01, 0.5431841788581357E+00, 0.3696613346727944E+00, 0.2343742079469738E+00, 0.4891909888056500E-01, 0.6769876984160987E+00, 0.4777767465052760E+00, 0.1867381312399053E+00, 0.2018744873845245E+00, 0.5511201479607295E+00, 0.6938788283912793E+00, 0.8167542438070282E+00, 0.7904606414789531E+00, 0.9443564310071292E+00, 0.7287247677237652E-01, 0.8645122013586991E+00, 0.1884651475116826E+00, 0.3844755283611681E+00, 0.9959264361467982E+00, 0.6424370932833342E+00, 0.1972122925077952E+00, 0.2842024247377670E+00, 0.9819646913482807E+00, 0.9118347224008859E+00, 0.8184691845197246E+00, 0.7051587281589254E+00, 0.7604703230109544E+00, 0.6312964755149379E+00, 0.5240863862347888E+00, 0.3442050916384676E-01, 0.2415614308212055E+00, 0.2814868323669945E+00, 0.6529284673126197E+00, 0.3727305084153835E+00, 0.5033733868757848E+00, 0.2317122058804952E+00, 0.7555584130128312E+00, 0.5854566742645219E+00, 0.5481204696337160E+00, 0.8479425268049923E+00, 0.2310874615764000E+00, 0.1250993726775007E-01, 0.6243285982203539E-01, 0.8533587246073391E+00, 0.9203815588639257E+00, 0.9256849509751471E+00, 0.6691405057262187E+00, 0.8847091531299658E+00, 0.6783572983386376E+00, 0.4701257141291857E+00, 0.8976078424378102E+00, 0.8575018884445876E+00, 0.4119363561363949E+00, 0.2824477027676924E+00, 0.2787507690368071E+00, 0.7994878185780909E+00, 0.6141832897278305E+00, 0.6772728066124333E+00, 0.1568652581579784E+00, 0.8025492691231176E+00, 0.2609459151100056E+00, 0.4956700691019098E+00, 0.1008839464621498E+00, 0.6129709499983976E+00, 0.4551038858718992E-02, 0.8382785474023564E+00, 0.9327452694814308E+00, 0.9710431593941808E+00, 0.3785578217695214E+00, 0.9620839159000718E+00, 0.3183561960196257E-01, 0.9167635157854341E+00, 0.8989971039988554E+00, 0.2723769512210017E-01, 0.4176537489735596E+00, 0.9619881273217982E+00, 0.8761769579995293E+00, 0.6385245520487358E+00, 0.6821739872929905E+00, 0.3927943300877799E+00, 0.3299501391296433E-01, 0.6026481165267817E+00}, + n: 21, + zOut: []float64{0.2841529467847260E+01, 0.2556740368064117E+01, 0.2029069210305357E+01, 0.1816492749229813E+01, 0.1807397947918166E+01, 0.1724050761249482E+01, 0.1394683696862690E+01, 0.1363282300837870E+01, 0.1235317529564993E+01, 0.1007821728138393E+01, 0.9728972767837659E+00, 0.8110838192609224E+00, 0.6190683239156912E+00, 0.3314348466978195E+00, 0.2969816495631171E+00, 0.2506421226611442E+00, 0.1551624233480766E+00, 0.1141049603637759E+00, 0.6806098279643324E-01, 0.4065442795375918E-01, 0.1509783792061944E-04, 0.2745446733802996E-19, 0.2334033424405603E-14, 0.7232047343832039E-15, 0.1394683696862690E+01, 0.7652022750203868E-17, 0.1502464319787860E-09, 0.5990324067027169E-10, 0.1363282300837870E+01, 0.5511008105786353E-19, 0.1215529748555577E-07, 0.3576186028975079E-08, 0.1235317529564993E+01, 0.6271335389136957E-17, 0.2589527811059762E-05, 0.3563684464760320E-05, 0.1007821728138393E+01, 0.6928731028484552E-15, 0.2286607739649456E-04, 0.2916328836696281E-04, 0.9728972767837659E+00, 0.4013724285764508E-25, 0.2143649169120057E+02, 0.2143649169120056E+02, 0.1080000000000000E+03, 0.3174603174603174E+01, 0.5555555555555555E+01, 0.5006788488237952E-04, 0.6190683239156912E+00, 0.1272779738919789E-24, 0.5392273695714327E-05, 0.6586751690782050E-05, 0.3314348466978195E+00, 0.9952016744778614E-24, 0.4588114650322476E-05, 0.4104030919118472E-05, 0.2969816495631171E+00, 0.1254277227268884E-20, 0.1579210272170037E-05, 0.2523508055026877E-05, 0.2506421226611442E+00, 0.1514835081255253E-22, 0.9117975197333799E-05, 0.1415311657319248E-04, 0.1551624233480766E+00, 0.3272195034856757E-26, 0.3128414626489953E-04, 0.4770966856082524E-04, 0.1141049603637759E+00, 0.7575261888623807E-20, 0.6277758538102519E-05, 0.4644422903178713E-05, 0.6806098279643324E-01, 0.3715389965619895E-21, 0.5956965112658162E-05, 0.4447744978930882E-05, 0.4065442795375918E-01, 0.1972152263052530E-30, 0.2965586553650948E-04, 0.1900611263569203E-04, 0.1509783792061944E-04, 0.1009741958682895E-26, 0.1608958133772104E-02, 0.9583670521235791E-03}, + info: 0, + }, + } { + z := make([]float64, len(test.z)) + copy(z, test.z) + + info := impl.Dlasq2(test.n, z) + if !floats.EqualApprox(test.zOut, z, dTol) { + diff := make([]float64, len(z)) + floats.SubTo(diff, z, test.zOut) + for i := range diff { + diff[i] = math.Abs(diff[i]) + } + t.Errorf("Case %v, Z Mismatch", c) + } + if test.info != info { + t.Errorf("Info mismatch. Want %v, got %v", test.info, info) + } + } + + rnd := rand.New(rand.NewSource(1)) + // Perform a bunch of random tests to check for access out of bounds or + // infinite loops. + // TODO(btracey): Implement direct tests. + // bi := blas64.Implementation() + for _, n := range []int{5, 8, 20, 25} { + for k := 0; k < 10; k++ { + z := make([]float64, 4*n) + for i := range z { + z[i] = rnd.Float64() + } + zCopy := make([]float64, len(z)) + copy(zCopy, z) + + // Compute the eigenvalues + impl.Dlasq2(n, z) + + // Below is the code to test the eigenvalues. Eventually implement + // real tests. + // The code below is missing the transformation from L and U into + // the symmetric tridiagonal matrix. + // See discussion http://icl.cs.utk.edu/lapack-forum/viewtopic.php?f=5&t=4839 + // for format. + + /* + ldl := n + ldu := n + u := make([]float64, n*n) + for i := 0; i < n; i++ { + u[i*ldu+i] = zCopy[2*i] + if i != n-1 { + u[i*ldu+i+1] = 1 + } + } + l := make([]float64, n*n) + for i := 0; i < n; i++ { + l[i*ldl+i] = 1 + if i != n-1 { + l[(i+1)*ldl+i] = zCopy[2*i+1] + } + } + + ldTriDi := n + triDi := make([]float64, n*n) + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, n, n, 1, l, ldl, u, ldu, 0, triDi, ldTriDi) + + tridi2 := make([]float64, n*n) + bi.Dgemm(blas.Trans, blas.NoTrans, n, n, n, 1, triDi, n, triDi, n, 0, tridi2, n) + + // Eigenvalues have the property that det(A - lambda I ) = 0 + triDiCopy := make([]float64, len(triDi)) + copy(triDiCopy, triDi) + for _, lambda := range z[1:n] { + copy(triDi, triDiCopy) + for i := 0; i < n; i++ { + triDi[i*n+i] -= lambda + } + + // Compute LU + //ipiv := make([]int, n) + //impl.Dgetrf(n, n, triDi, n, ipiv) + ok := impl.Dpotrf(blas.Upper, n, triDi, n) + fmt.Println(ok) + + var det float64 + for i := 0; i < n; i++ { + det += math.Log(math.Abs(triDi[i*n+i])) + } + fmt.Println("det = ", math.Exp(det)) + } + */ + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq3.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq3.go new file mode 100644 index 00000000..f48bad17 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq3.go @@ -0,0 +1,2703 @@ +// 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 testlapack + +import ( + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dlasq3er interface { + Dlasq3(i0, n0 int, z []float64, pp int, dmin, sigma, desig, qmax float64, nFail, iter, nDiv int, ttype int, dmin1, dmin2, dn, dn1, dn2, g, tau float64) ( + i0Out, n0Out, ppOut int, dminOut, sigmaOut, desigOut, qmaxOut float64, nFailOut, iterOut, nDivOut, ttypeOut int, dmin1Out, dmin2Out, dnOut, dn1Out, dn2Out, gOut, tauOut float64) +} + +type dlasq3teststruct struct { + z []float64 + i0, n0, pp int + dmin, desig, sigma, qmax float64 + nFail, iter, nDiv, ttype int + dmin1, dmin2, dn, dn1, dn2, g, tau float64 + + zOut []float64 + i0Out, n0Out, ppOut int + dminOut, desigOut, sigmaOut, qmaxOut float64 + nFailOut, iterOut, nDivOut, ttypeOut int + dmin1Out, dmin2Out, dnOut, dn1Out, dn2Out, gOut, tauOut float64 +} + +func Dlasq3Test(t *testing.T, impl Dlasq3er) { + dTol := 1e-14 + // Tests computed from calling the netlib Dlasq + for _, test := range []dlasq3teststruct{ + { + i0: 1, + n0: 21, + z: []float64{0.1914365246180821E+01, 0.1564384297703890E+01, 0.2493389162143899E+00, 0.3499809484769305E+00, 0.1315996513131545E+01, 0.1363862112490627E+01, 0.9898466611970759E-01, 0.2014733168553078E+00, 0.6023973979587287E+00, 0.6465544792741794E+00, 0.2210033410638781E-02, 0.5482758480425683E-01, 0.9861857233678967E-01, 0.2428190810745492E-01, 0.4756321484454819E+00, 0.7654669763997353E-01, 0.2588748143677115E+00, 0.6127784069508770E+00, 0.1078611376690004E+00, 0.1217285558623164E+00, 0.6442896492255246E+00, 0.2293835804898155E+00, 0.6203230486639705E+00, 0.5227672064047094E+00, 0.3695660678607585E+00, 0.7645233184745865E+00, 0.5378838054252265E+00, 0.2253657980501426E+00, 0.3562533181264623E+00, 0.8820486722335483E+00, 0.2222132496436145E-01, 0.1208845131814035E-01, 0.1275094303021685E+01, 0.6548746852163357E+00, 0.1647324354821218E+00, 0.6424409427697111E+00, 0.1007530576543866E+01, 0.3269551736546701E+00, 0.3453881601783118E+00, 0.8453078383713172E+00, 0.2679391719153404E+00, 0.4116714838778281E+00, 0.7328677736683723E+00, 0.2016558482158241E+00, 0.8360828138307410E+00, 0.9737579452195326E+00, 0.4813660709592822E+00, 0.5951926422795808E+00, 0.6495370513676459E+00, 0.6761876248148171E+00, 0.2325475880222648E+00, 0.4547154975121112E+00, 0.1993624802893807E+00, 0.3321819367342255E+00, 0.3782318916911257E+00, 0.9972813157741996E-01, 0.9830449403503746E+00, 0.7561080996844842E+00, 0.4429733864040367E+00, 0.6051687323570161E+00, 0.1173279550602403E+01, 0.7195724480316686E+00, 0.5035524069144587E+00, 0.8966804889747714E+00, 0.3058980395058521E+00, 0.6588832353928662E+00, 0.3014634433415453E+00, 0.1505672110274446E+00, 0.1289422237567578E+01, 0.6124645310993601E+00, 0.7583364305799440E+00, 0.9784211498097629E+00, 0.4977814779461571E+00, 0.9993813577491869E+00, 0.2841468847862598E+00, 0.2567365507769143E+00, 0.9257539794205765E+00, 0.5509268385614666E+00, 0.5231355605450990E-04, 0.6589740256453697E+00, 0.2117869221381033E-04, 0.7349224826832024E-04, 0.0000000000000000E+00, 0.0000000000000000E+00}, + pp: 0, + dmin: -0.0000000000000000, + desig: 0.0000000000000000, + qmax: 2.1637041623952107, + ttype: 0, + dmin1: 0.0000000000000000, + dmin2: 0.0000000000000000, + dn: 0.0000000000000000, + dn1: 0.0000000000000000, + dn2: 0.0000000000000000, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 2, + sigma: 0.0000000000000000, + nDiv: 40, + zOut: []float64{0.1914365246180821E+01, 0.2163704162395211E+01, 0.2493389162143899E+00, 0.1516515751224039E+00, 0.1315996513131545E+01, 0.1263329604128848E+01, 0.9898466611970759E-01, 0.4719916727467415E-01, 0.6023973979587287E+00, 0.5574082640946934E+00, 0.2210033410638781E-02, 0.3910066531356214E-03, 0.9861857233678967E-01, 0.5738597141291359E+00, 0.4756321484454819E+00, 0.2145632131068746E+00, 0.2588748143677115E+00, 0.1521727389298373E+00, 0.1078611376690004E+00, 0.4566771620366771E+00, 0.6442896492255246E+00, 0.8079355358528180E+00, 0.6203230486639705E+00, 0.2837483186776231E+00, 0.3695660678607585E+00, 0.6237015546083620E+00, 0.5378838054252265E+00, 0.3072349091217998E+00, 0.3562533181264623E+00, 0.7123973396902394E-01, 0.2222132496436145E-01, 0.3977314805803597E+00, 0.1275094303021685E+01, 0.1042095257923447E+01, 0.1647324354821218E+00, 0.1592685164190333E+00, 0.1007530576543866E+01, 0.1193650220303144E+01, 0.3453881601783118E+00, 0.7752942700755104E-01, 0.2679391719153404E+00, 0.9232775185761617E+00, 0.7328677736683723E+00, 0.6636554427529671E+00, 0.8360828138307410E+00, 0.6537934420370561E+00, 0.4813660709592822E+00, 0.4782322339990674E+00, 0.6495370513676459E+00, 0.4038524053908432E+00, 0.2325475880222648E+00, 0.1147975431483785E+00, 0.1993624802893807E+00, 0.4627968288321279E+00, 0.3782318916911257E+00, 0.8034172324482011E+00, 0.9830449403503746E+00, 0.6226010943062101E+00, 0.4429733864040367E+00, 0.8347746582554776E+00, 0.1173279550602403E+01, 0.8420572992613844E+00, 0.5035524069144587E+00, 0.1829278057427913E+00, 0.3058980395058521E+00, 0.4244336771046062E+00, 0.3014634433415453E+00, 0.9158407747236312E+00, 0.1289422237567578E+01, 0.1131917893423890E+01, 0.7583364305799440E+00, 0.3334922359541972E+00, 0.4977814779461571E+00, 0.4484361267782198E+00, 0.2841468847862598E+00, 0.5865943745895725E+00, 0.9257539794205765E+00, 0.3392119183870583E+00, 0.5231355605450990E-04, 0.3266196269153995E-08, 0.2117869221381033E-04, 0.2117542601754118E-04, 0.0000000000000000E+00, 0.3910066531356214E-03}, + i0Out: 1, + n0Out: 21, + ppOut: 0, + dminOut: 2.1175426017541180E-005, + desigOut: 0.0000000000000000, + sigmaOut: 0.0000000000000000, + qmaxOut: 2.1637041623952107, + nFailOut: 0, + iterOut: 3, + nDivOut: 62, + ttypeOut: -1, + dmin1Out: 4.4311601260836921E-002, + dmin2Out: 4.4311601260836921E-002, + dnOut: 2.1175426017541180E-005, + dn1Out: 0.33915960483100382, + dn2Out: 0.16428924199195991, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 21, + z: []float64{0.1914365246180821E+01, 0.2163704162395211E+01, 0.2493389162143899E+00, 0.1516515751224039E+00, 0.1315996513131545E+01, 0.1263329604128848E+01, 0.9898466611970759E-01, 0.4719916727467415E-01, 0.6023973979587287E+00, 0.5574082640946934E+00, 0.2210033410638781E-02, 0.3910066531356214E-03, 0.9861857233678967E-01, 0.5738597141291359E+00, 0.4756321484454819E+00, 0.2145632131068746E+00, 0.2588748143677115E+00, 0.1521727389298373E+00, 0.1078611376690004E+00, 0.4566771620366771E+00, 0.6442896492255246E+00, 0.8079355358528180E+00, 0.6203230486639705E+00, 0.2837483186776231E+00, 0.3695660678607585E+00, 0.6237015546083620E+00, 0.5378838054252265E+00, 0.3072349091217998E+00, 0.3562533181264623E+00, 0.7123973396902394E-01, 0.2222132496436145E-01, 0.3977314805803597E+00, 0.1275094303021685E+01, 0.1042095257923447E+01, 0.1647324354821218E+00, 0.1592685164190333E+00, 0.1007530576543866E+01, 0.1193650220303144E+01, 0.3453881601783118E+00, 0.7752942700755104E-01, 0.2679391719153404E+00, 0.9232775185761617E+00, 0.7328677736683723E+00, 0.6636554427529671E+00, 0.8360828138307410E+00, 0.6537934420370561E+00, 0.4813660709592822E+00, 0.4782322339990674E+00, 0.6495370513676459E+00, 0.4038524053908432E+00, 0.2325475880222648E+00, 0.1147975431483785E+00, 0.1993624802893807E+00, 0.4627968288321279E+00, 0.3782318916911257E+00, 0.8034172324482011E+00, 0.9830449403503746E+00, 0.6226010943062101E+00, 0.4429733864040367E+00, 0.8347746582554776E+00, 0.1173279550602403E+01, 0.8420572992613844E+00, 0.5035524069144587E+00, 0.1829278057427913E+00, 0.3058980395058521E+00, 0.4244336771046062E+00, 0.3014634433415453E+00, 0.9158407747236312E+00, 0.1289422237567578E+01, 0.1131917893423890E+01, 0.7583364305799440E+00, 0.3334922359541972E+00, 0.4977814779461571E+00, 0.4484361267782198E+00, 0.2841468847862598E+00, 0.5865943745895725E+00, 0.9257539794205765E+00, 0.3392119183870583E+00, 0.5231355605450990E-04, 0.3266196269153995E-08, 0.2117869221381033E-04, 0.2117542601754118E-04, 0.0000000000000000E+00, 0.3910066531356214E-03}, + pp: 1, + dmin: 2.1175426017541180E-005, + desig: 0.0000000000000000, + qmax: 2.1637041623952107, + ttype: -1, + dmin1: 4.4311601260836921E-002, + dmin2: 4.4311601260836921E-002, + dn: 2.1175426017541180E-005, + dn1: 0.33915960483100382, + dn2: 0.16428924199195991, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 3, + sigma: 0.0000000000000000, + nDiv: 62, + zOut: []float64{0.2315355737517615E+01, 0.2163704162395211E+01, 0.8274578340618610E-01, 0.1516515751224039E+00, 0.1227782987997336E+01, 0.1263329604128848E+01, 0.2142822156235013E-01, 0.4719916727467415E-01, 0.5363710491854788E+00, 0.5574082640946934E+00, 0.4183353417969536E-03, 0.3910066531356214E-03, 0.7880045918942136E+00, 0.5738597141291359E+00, 0.4143462125464707E-01, 0.2145632131068746E+00, 0.5674152797118673E+00, 0.1521727389298373E+00, 0.6502569120260687E+00, 0.4566771620366771E+00, 0.4414269425043723E+00, 0.8079355358528180E+00, 0.4009140594652070E+00, 0.2837483186776231E+00, 0.5300224042649548E+00, 0.6237015546083620E+00, 0.4129510944388858E-01, 0.3072349091217998E+00, 0.4276761051054951E+00, 0.7123973396902394E-01, 0.9691308092544145E+00, 0.3977314805803597E+00, 0.2322329650880660E+00, 0.1042095257923447E+01, 0.8186215063776209E+00, 0.1592685164190333E+00, 0.4525581409330741E+00, 0.1193650220303144E+01, 0.1581701233715052E+00, 0.7752942700755104E-01, 0.1428762837957623E+01, 0.9232775185761617E+00, 0.3036848136842134E+00, 0.6636554427529671E+00, 0.8283408623519102E+00, 0.6537934420370561E+00, 0.2331591338951825E+00, 0.4782322339990674E+00, 0.2854908146440392E+00, 0.4038524053908432E+00, 0.1860933389154074E+00, 0.1147975431483785E+00, 0.1080120722364922E+01, 0.4627968288321279E+00, 0.4631042046962229E+00, 0.8034172324482011E+00, 0.9942715478654648E+00, 0.6226010943062101E+00, 0.7069779837626068E+00, 0.8347746582554776E+00, 0.3180071212415688E+00, 0.8420572992613844E+00, 0.2441477440283845E+00, 0.1829278057427913E+00, 0.1096126707799853E+01, 0.4244336771046062E+00, 0.9457451890006905E+00, 0.9158407747236312E+00, 0.5196649403773971E+00, 0.1131917893423890E+01, 0.2877815203259632E+00, 0.3334922359541972E+00, 0.7472489810418290E+00, 0.4484361267782198E+00, 0.2662831374385604E+00, 0.5865943745895725E+00, 0.7292878421469419E-01, 0.3392119183870583E+00, 0.9483648767903632E-12, 0.3266196269153995E-08, 0.2117542506917630E-04, 0.2117542601754118E-04, 0.4183353417969536E-03, 0.3910066531356214E-03}, + i0Out: 1, + n0Out: 21, + ppOut: 1, + dminOut: 2.1175425069176302E-005, + desigOut: 0.0000000000000000, + sigmaOut: 0.0000000000000000, + qmaxOut: 2.1637041623952107, + nFailOut: 0, + iterOut: 4, + nDivOut: 84, + ttypeOut: -4, + dmin1Out: 2.9944624525135358E-002, + dmin2Out: 2.9944624525135358E-002, + dnOut: 2.1175425069176302E-005, + dn1Out: 7.2928780948497918E-002, + dn2Out: 0.16065460645225654, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 21, + z: []float64{0.2315355737517615E+01, 0.2163704162395211E+01, 0.8274578340618610E-01, 0.1516515751224039E+00, 0.1227782987997336E+01, 0.1263329604128848E+01, 0.2142822156235013E-01, 0.4719916727467415E-01, 0.5363710491854788E+00, 0.5574082640946934E+00, 0.4183353417969536E-03, 0.3910066531356214E-03, 0.7880045918942136E+00, 0.5738597141291359E+00, 0.4143462125464707E-01, 0.2145632131068746E+00, 0.5674152797118673E+00, 0.1521727389298373E+00, 0.6502569120260687E+00, 0.4566771620366771E+00, 0.4414269425043723E+00, 0.8079355358528180E+00, 0.4009140594652070E+00, 0.2837483186776231E+00, 0.5300224042649548E+00, 0.6237015546083620E+00, 0.4129510944388858E-01, 0.3072349091217998E+00, 0.4276761051054951E+00, 0.7123973396902394E-01, 0.9691308092544145E+00, 0.3977314805803597E+00, 0.2322329650880660E+00, 0.1042095257923447E+01, 0.8186215063776209E+00, 0.1592685164190333E+00, 0.4525581409330741E+00, 0.1193650220303144E+01, 0.1581701233715052E+00, 0.7752942700755104E-01, 0.1428762837957623E+01, 0.9232775185761617E+00, 0.3036848136842134E+00, 0.6636554427529671E+00, 0.8283408623519102E+00, 0.6537934420370561E+00, 0.2331591338951825E+00, 0.4782322339990674E+00, 0.2854908146440392E+00, 0.4038524053908432E+00, 0.1860933389154074E+00, 0.1147975431483785E+00, 0.1080120722364922E+01, 0.4627968288321279E+00, 0.4631042046962229E+00, 0.8034172324482011E+00, 0.9942715478654648E+00, 0.6226010943062101E+00, 0.7069779837626068E+00, 0.8347746582554776E+00, 0.3180071212415688E+00, 0.8420572992613844E+00, 0.2441477440283845E+00, 0.1829278057427913E+00, 0.1096126707799853E+01, 0.4244336771046062E+00, 0.9457451890006905E+00, 0.9158407747236312E+00, 0.5196649403773971E+00, 0.1131917893423890E+01, 0.2877815203259632E+00, 0.3334922359541972E+00, 0.7472489810418290E+00, 0.4484361267782198E+00, 0.2662831374385604E+00, 0.5865943745895725E+00, 0.7292878421469419E-01, 0.3392119183870583E+00, 0.9483648767903632E-12, 0.3266196269153995E-08, 0.2117542506917630E-04, 0.2117542601754118E-04, 0.4183353417969536E-03, 0.3910066531356214E-03}, + pp: 0, + dmin: 2.1175425069176302E-005, + desig: 0.0000000000000000, + qmax: 2.1637041623952107, + ttype: -4, + dmin1: 2.9944624525135358E-002, + dmin2: 2.9944624525135358E-002, + dn: 2.1175425069176302E-005, + dn1: 7.2928780948497918E-002, + dn2: 0.16065460645225654, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 4, + sigma: 0.0000000000000000, + nDiv: 84, + zOut: []float64{0.2315355737517615E+01, 0.2398080345610006E+01, 0.8274578340618610E-01, 0.4236466279397526E-01, 0.1227782987997336E+01, 0.1206825371451915E+01, 0.2142822156235013E-01, 0.9523728911788614E-02, 0.5363710491854788E+00, 0.5272444803016919E+00, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.7880045918942136E+00, 0.8287928057414093E+00, 0.4143462125464707E-01, 0.2836732781232222E-01, 0.5674152797118673E+00, 0.1189283688611819E+01, 0.6502569120260687E+00, 0.2413561400585997E+00, 0.4414269425043723E+00, 0.6009636865971842E+00, 0.4009140594652070E+00, 0.3535878097802652E+00, 0.5300224042649548E+00, 0.2177085286147829E+00, 0.4129510944388858E-01, 0.8112190955144877E-01, 0.4276761051054951E+00, 0.1315663829494665E+01, 0.9691308092544145E+00, 0.1710650671895379E+00, 0.2322329650880660E+00, 0.8797682289623537E+00, 0.8186215063776209E+00, 0.4211038940233675E+00, 0.4525581409330741E+00, 0.1896031949674164E+00, 0.1581701233715052E+00, 0.1191897606932286E+01, 0.1428762837957623E+01, 0.5405288693957555E+00, 0.3036848136842134E+00, 0.4653859482687157E+00, 0.8283408623519102E+00, 0.5960928726645816E+00, 0.2331591338951825E+00, 0.1116684901463164E+00, 0.2854908146440392E+00, 0.3598944880993349E+00, 0.1860933389154074E+00, 0.5585061130503639E+00, 0.1080120722364922E+01, 0.9846976386969850E+00, 0.4631042046962229E+00, 0.4676068229793028E+00, 0.9942715478654648E+00, 0.1233621533334973E+01, 0.7069779837626068E+00, 0.1822471700779458E+00, 0.3180071212415688E+00, 0.3798865198782122E+00, 0.2441477440283845E+00, 0.7044652781161848E+00, 0.1096126707799853E+01, 0.1337385443370563E+01, 0.9457451890006905E+00, 0.3674861422265960E+00, 0.5196649403773971E+00, 0.4399391431629689E+00, 0.2877815203259632E+00, 0.4888049885267526E+00, 0.7472489810418290E+00, 0.5247059546398414E+00, 0.2662831374385604E+00, 0.3701064434002514E-01, 0.7292878421469419E-01, 0.3589696456182207E-01, 0.9483648767903632E-12, 0.5594353069081231E-15, 0.2117542506917630E-04, 0.1112732565966979E-09, 0.4183353417969536E-03, 0.6252320936560726E-03}, + i0Out: 1, + n0Out: 21, + ppOut: 0, + dminOut: 1.1127325659669794E-010, + desigOut: 0.0000000000000000, + sigmaOut: 2.1175313795360271E-005, + qmaxOut: 2.1637041623952107, + nFailOut: 0, + iterOut: 5, + nDivOut: 106, + ttypeOut: -4, + dmin1Out: 3.1433071595911154E-002, + dmin2Out: 3.1433071595911154E-002, + dnOut: 1.1127325659669794E-010, + dn1Out: 3.5896964560873705E-002, + dn2Out: 0.25842281720128102, + gOut: 0.0000000000000000, + tauOut: 2.1175313795360271E-005, + }, + { + i0: 1, + n0: 21, + z: []float64{0.2315355737517615E+01, 0.2398080345610006E+01, 0.8274578340618610E-01, 0.4236466279397526E-01, 0.1227782987997336E+01, 0.1206825371451915E+01, 0.2142822156235013E-01, 0.9523728911788614E-02, 0.5363710491854788E+00, 0.5272444803016919E+00, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.7880045918942136E+00, 0.8287928057414093E+00, 0.4143462125464707E-01, 0.2836732781232222E-01, 0.5674152797118673E+00, 0.1189283688611819E+01, 0.6502569120260687E+00, 0.2413561400585997E+00, 0.4414269425043723E+00, 0.6009636865971842E+00, 0.4009140594652070E+00, 0.3535878097802652E+00, 0.5300224042649548E+00, 0.2177085286147829E+00, 0.4129510944388858E-01, 0.8112190955144877E-01, 0.4276761051054951E+00, 0.1315663829494665E+01, 0.9691308092544145E+00, 0.1710650671895379E+00, 0.2322329650880660E+00, 0.8797682289623537E+00, 0.8186215063776209E+00, 0.4211038940233675E+00, 0.4525581409330741E+00, 0.1896031949674164E+00, 0.1581701233715052E+00, 0.1191897606932286E+01, 0.1428762837957623E+01, 0.5405288693957555E+00, 0.3036848136842134E+00, 0.4653859482687157E+00, 0.8283408623519102E+00, 0.5960928726645816E+00, 0.2331591338951825E+00, 0.1116684901463164E+00, 0.2854908146440392E+00, 0.3598944880993349E+00, 0.1860933389154074E+00, 0.5585061130503639E+00, 0.1080120722364922E+01, 0.9846976386969850E+00, 0.4631042046962229E+00, 0.4676068229793028E+00, 0.9942715478654648E+00, 0.1233621533334973E+01, 0.7069779837626068E+00, 0.1822471700779458E+00, 0.3180071212415688E+00, 0.3798865198782122E+00, 0.2441477440283845E+00, 0.7044652781161848E+00, 0.1096126707799853E+01, 0.1337385443370563E+01, 0.9457451890006905E+00, 0.3674861422265960E+00, 0.5196649403773971E+00, 0.4399391431629689E+00, 0.2877815203259632E+00, 0.4888049885267526E+00, 0.7472489810418290E+00, 0.5247059546398414E+00, 0.2662831374385604E+00, 0.3701064434002514E-01, 0.7292878421469419E-01, 0.3589696456182207E-01, 0.9483648767903632E-12, 0.5594353069081231E-15, 0.2117542506917630E-04, 0.1112732565966979E-09, 0.4183353417969536E-03, 0.6252320936560726E-03}, + pp: 1, + dmin: 1.1127325659669794E-010, + desig: 0.0000000000000000, + qmax: 2.1637041623952107, + ttype: -4, + dmin1: 3.1433071595911154E-002, + dmin2: 3.1433071595911154E-002, + dn: 1.1127325659669794E-010, + dn1: 3.5896964560873705E-002, + dn2: 0.25842281720128102, + g: 0.0000000000000000, + tau: 2.1175313795360271E-005, + nFail: 0, + iter: 5, + sigma: 2.1175313795360271E-005, + nDiv: 106, + zOut: []float64{0.2440445008292708E+01, 0.2398080345610006E+01, 0.2094976520226600E-01, 0.4236466279397526E-01, 0.1195399335050165E+01, 0.1206825371451915E+01, 0.4200549016048655E-02, 0.9523728911788614E-02, 0.5236691632680260E+00, 0.5272444803016919E+00, 0.9895328911616120E-03, 0.6252320936560726E-03, 0.8561706005512968E+00, 0.8287928057414093E+00, 0.3940429656773515E-01, 0.2836732781232222E-01, 0.1391235531991410E+01, 0.1189283688611819E+01, 0.1042571673718422E+00, 0.2413561400585997E+00, 0.8502943288943339E+00, 0.6009636865971842E+00, 0.9053227710395735E-01, 0.3535878097802652E+00, 0.2082981609510011E+00, 0.2177085286147829E+00, 0.5123864833424303E+00, 0.8112190955144877E-01, 0.9743424132304999E+00, 0.1315663829494665E+01, 0.1544607000116935E+00, 0.1710650671895379E+00, 0.1146411422862754E+01, 0.8797682289623537E+00, 0.6964571542795012E-01, 0.4211038940233675E+00, 0.1311855086360479E+01, 0.1896031949674164E+00, 0.4911023119923957E+00, 0.1191897606932286E+01, 0.5148125055608023E+00, 0.5405288693957555E+00, 0.5388626806938843E+00, 0.4653859482687157E+00, 0.1688986820057405E+00, 0.5960928726645816E+00, 0.2379466412690434E+00, 0.1116684901463164E+00, 0.6804539597693821E+00, 0.3598944880993349E+00, 0.8082246312519304E+00, 0.5585061130503639E+00, 0.6440798303130841E+00, 0.9846976386969850E+00, 0.8956185534970393E+00, 0.4676068229793028E+00, 0.5202501498046066E+00, 0.1233621533334973E+01, 0.1330768347199243E+00, 0.1822471700779458E+00, 0.9512749631631994E+00, 0.3798865198782122E+00, 0.9903988276741268E+00, 0.7044652781161848E+00, 0.7144727578117591E+00, 0.1337385443370563E+01, 0.2262808998212762E+00, 0.3674861422265960E+00, 0.7024632317571722E+00, 0.4399391431629689E+00, 0.3651136124179467E+00, 0.4888049885267526E+00, 0.1966029864506465E+00, 0.5247059546398414E+00, 0.6757627705811050E-02, 0.3701064434002514E-01, 0.2913933674473832E-01, 0.3589696456182207E-01, 0.2136293938333395E-23, 0.5594353069081231E-15, 0.0000000000000000E+00, 0.1112732565966979E-09, 0.9895328911616120E-03, 0.6252320936560726E-03}, + i0Out: 1, + n0Out: 21, + ppOut: 1, + dminOut: 0.0000000000000000, + desigOut: -5.1698788284564230E-026, + sigmaOut: 2.1175425068616867E-005, + qmaxOut: 2.1637041623952107, + nFailOut: 1, + iterOut: 7, + nDivOut: 150, + ttypeOut: -15, + dmin1Out: 2.9139336744737766E-002, + dmin2Out: 4.9426557292086552E-002, + dnOut: -2.0808762284537102E-024, + dn1Out: 2.9139336744737766E-002, + dn2Out: 0.15959234211062134, + gOut: 0.0000000000000000, + tauOut: 1.1127325659669789E-010, + }, + { + i0: 1, + n0: 21, + z: []float64{0.2440445008292708E+01, 0.2398080345610006E+01, 0.2094976520226600E-01, 0.4236466279397526E-01, 0.1195399335050165E+01, 0.1206825371451915E+01, 0.4200549016048655E-02, 0.9523728911788614E-02, 0.5236691632680260E+00, 0.5272444803016919E+00, 0.9895328911616120E-03, 0.6252320936560726E-03, 0.8561706005512968E+00, 0.8287928057414093E+00, 0.3940429656773515E-01, 0.2836732781232222E-01, 0.1391235531991410E+01, 0.1189283688611819E+01, 0.1042571673718422E+00, 0.2413561400585997E+00, 0.8502943288943339E+00, 0.6009636865971842E+00, 0.9053227710395735E-01, 0.3535878097802652E+00, 0.2082981609510011E+00, 0.2177085286147829E+00, 0.5123864833424303E+00, 0.8112190955144877E-01, 0.9743424132304999E+00, 0.1315663829494665E+01, 0.1544607000116935E+00, 0.1710650671895379E+00, 0.1146411422862754E+01, 0.8797682289623537E+00, 0.6964571542795012E-01, 0.4211038940233675E+00, 0.1311855086360479E+01, 0.1896031949674164E+00, 0.4911023119923957E+00, 0.1191897606932286E+01, 0.5148125055608023E+00, 0.5405288693957555E+00, 0.5388626806938843E+00, 0.4653859482687157E+00, 0.1688986820057405E+00, 0.5960928726645816E+00, 0.2379466412690434E+00, 0.1116684901463164E+00, 0.6804539597693821E+00, 0.3598944880993349E+00, 0.8082246312519304E+00, 0.5585061130503639E+00, 0.6440798303130841E+00, 0.9846976386969850E+00, 0.8956185534970393E+00, 0.4676068229793028E+00, 0.5202501498046066E+00, 0.1233621533334973E+01, 0.1330768347199243E+00, 0.1822471700779458E+00, 0.9512749631631994E+00, 0.3798865198782122E+00, 0.9903988276741268E+00, 0.7044652781161848E+00, 0.7144727578117591E+00, 0.1337385443370563E+01, 0.2262808998212762E+00, 0.3674861422265960E+00, 0.7024632317571722E+00, 0.4399391431629689E+00, 0.3651136124179467E+00, 0.4888049885267526E+00, 0.1966029864506465E+00, 0.5247059546398414E+00, 0.6757627705811050E-02, 0.3701064434002514E-01, 0.2913933674473832E-01, 0.3589696456182207E-01, 0.2136293938333395E-23, 0.5594353069081231E-15, 0.0000000000000000E+00, 0.1112732565966979E-09, 0.9895328911616120E-03, 0.6252320936560726E-03}, + pp: 0, + dmin: 0.0000000000000000, + desig: -5.1698788284564230E-026, + qmax: 2.1637041623952107, + ttype: -15, + dmin1: 2.9139336744737766E-002, + dmin2: 4.9426557292086552E-002, + dn: -2.0808762284537102E-024, + dn1: 2.9139336744737766E-002, + dn2: 0.15959234211062134, + g: 0.0000000000000000, + tau: 1.1127325659669789E-010, + nFail: 1, + iter: 7, + sigma: 2.1175425068616867E-005, + nDiv: 150, + zOut: []float64{0.2440445008292708E+01, 0.2461394773494974E+01, 0.2094976520226600E-01, 0.1017444891892999E-01, 0.1195399335050165E+01, 0.1189425435147283E+01, 0.4200549016048655E-02, 0.1849378635683999E-02, 0.5236691632680260E+00, 0.5228093175235037E+00, 0.9895328911616120E-03, 0.1620493249248586E-02, 0.8561706005512968E+00, 0.8939544038697832E+00, 0.3940429656773515E-01, 0.6132377362967349E-01, 0.1391235531991410E+01, 0.1434168925733579E+01, 0.1042571673718422E+00, 0.6181229879703373E-01, 0.8502943288943339E+00, 0.8790143072012576E+00, 0.9053227710395735E-01, 0.2145324219750511E-01, 0.2082981609510011E+00, 0.6992314020959263E+00, 0.5123864833424303E+00, 0.7139837844669097E+00, 0.9743424132304999E+00, 0.4148193287752837E+00, 0.1544607000116935E+00, 0.4268738185358478E+00, 0.1146411422862754E+01, 0.7891833197548568E+00, 0.6964571542795012E-01, 0.1157716892137957E+00, 0.1311855086360479E+01, 0.1687185709139079E+01, 0.4911023119923957E+00, 0.1498504938454686E+00, 0.5148125055608023E+00, 0.9038246924092180E+00, 0.5388626806938843E+00, 0.1006978425303630E+00, 0.1688986820057405E+00, 0.3061474807444209E+00, 0.2379466412690434E+00, 0.5288684194677825E+00, 0.6804539597693821E+00, 0.9598101715535300E+00, 0.8082246312519304E+00, 0.5423584775195998E+00, 0.6440798303130841E+00, 0.9973399062905237E+00, 0.8956185534970393E+00, 0.4671884516860899E+00, 0.5202501498046066E+00, 0.1861385328384410E+00, 0.1330768347199243E+00, 0.6800991665489665E+00, 0.9512749631631994E+00, 0.1261574624288360E+01, 0.9903988276741268E+00, 0.5608966509936130E+00, 0.7144727578117591E+00, 0.3798570066394223E+00, 0.2262808998212762E+00, 0.4184574968871406E+00, 0.7024632317571722E+00, 0.6491193472879784E+00, 0.3651136124179467E+00, 0.1105843276664904E+00, 0.1966029864506465E+00, 0.9277628648996712E-01, 0.6757627705811050E-02, 0.2122447413720272E-02, 0.2913933674473832E-01, 0.2701688933101806E-01, 0.2136293938333395E-23, 0.0000000000000000E+00, 0.0000000000000000E+00, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 21, + ppOut: 0, + dminOut: 0.0000000000000000, + desigOut: -5.1698788284564230E-026, + sigmaOut: 2.1175425068616867E-005, + qmaxOut: 2.1637041623952107, + nFailOut: 1, + iterOut: 8, + nDivOut: 172, + ttypeOut: -1, + dmin1Out: 2.7016889331018056E-002, + dmin2Out: 5.3061698118516694E-002, + dnOut: 0.0000000000000000, + dn1Out: 2.7016889331018056E-002, + dn2Out: 8.6018658784156071E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 21, + z: []float64{0.2440445008292708E+01, 0.2461394773494974E+01, 0.2094976520226600E-01, 0.1017444891892999E-01, 0.1195399335050165E+01, 0.1189425435147283E+01, 0.4200549016048655E-02, 0.1849378635683999E-02, 0.5236691632680260E+00, 0.5228093175235037E+00, 0.9895328911616120E-03, 0.1620493249248586E-02, 0.8561706005512968E+00, 0.8939544038697832E+00, 0.3940429656773515E-01, 0.6132377362967349E-01, 0.1391235531991410E+01, 0.1434168925733579E+01, 0.1042571673718422E+00, 0.6181229879703373E-01, 0.8502943288943339E+00, 0.8790143072012576E+00, 0.9053227710395735E-01, 0.2145324219750511E-01, 0.2082981609510011E+00, 0.6992314020959263E+00, 0.5123864833424303E+00, 0.7139837844669097E+00, 0.9743424132304999E+00, 0.4148193287752837E+00, 0.1544607000116935E+00, 0.4268738185358478E+00, 0.1146411422862754E+01, 0.7891833197548568E+00, 0.6964571542795012E-01, 0.1157716892137957E+00, 0.1311855086360479E+01, 0.1687185709139079E+01, 0.4911023119923957E+00, 0.1498504938454686E+00, 0.5148125055608023E+00, 0.9038246924092180E+00, 0.5388626806938843E+00, 0.1006978425303630E+00, 0.1688986820057405E+00, 0.3061474807444209E+00, 0.2379466412690434E+00, 0.5288684194677825E+00, 0.6804539597693821E+00, 0.9598101715535300E+00, 0.8082246312519304E+00, 0.5423584775195998E+00, 0.6440798303130841E+00, 0.9973399062905237E+00, 0.8956185534970393E+00, 0.4671884516860899E+00, 0.5202501498046066E+00, 0.1861385328384410E+00, 0.1330768347199243E+00, 0.6800991665489665E+00, 0.9512749631631994E+00, 0.1261574624288360E+01, 0.9903988276741268E+00, 0.5608966509936130E+00, 0.7144727578117591E+00, 0.3798570066394223E+00, 0.2262808998212762E+00, 0.4184574968871406E+00, 0.7024632317571722E+00, 0.6491193472879784E+00, 0.3651136124179467E+00, 0.1105843276664904E+00, 0.1966029864506465E+00, 0.9277628648996712E-01, 0.6757627705811050E-02, 0.2122447413720272E-02, 0.2913933674473832E-01, 0.2701688933101806E-01, 0.2136293938333395E-23, 0.0000000000000000E+00, 0.0000000000000000E+00, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 0.0000000000000000, + desig: -5.1698788284564230E-026, + qmax: 2.1637041623952107, + ttype: -1, + dmin1: 2.7016889331018056E-002, + dmin2: 5.3061698118516694E-002, + dn: 0.0000000000000000, + dn1: 2.7016889331018056E-002, + dn2: 8.6018658784156071E-002, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 1, + iter: 8, + sigma: 2.1175425068616867E-005, + nDiv: 172, + zOut: []float64{0.2471569222413904E+01, 0.2461394773494974E+01, 0.4896382518051712E-02, 0.1017444891892999E-01, 0.1186378431264915E+01, 0.1189425435147283E+01, 0.8149780515932184E-03, 0.1849378635683999E-02, 0.5236148327211592E+00, 0.5228093175235037E+00, 0.2766627272719901E-02, 0.1620493249248586E-02, 0.9525115502267366E+00, 0.8939544038697832E+00, 0.9233342160256496E-01, 0.6132377362967349E-01, 0.1403647802928048E+01, 0.1434168925733579E+01, 0.3870906568602875E-01, 0.6181229879703373E-01, 0.8617584837127339E+00, 0.8790143072012576E+00, 0.1740717486950262E-01, 0.2145324219750511E-01, 0.1395808011693333E+01, 0.6992314020959263E+00, 0.2121884039551361E+00, 0.7139837844669097E+00, 0.6295047433559955E+00, 0.4148193287752837E+00, 0.5351535485381410E+00, 0.4268738185358478E+00, 0.3698014604305115E+00, 0.7891833197548568E+00, 0.5281978587564573E+00, 0.1157716892137957E+00, 0.1308838344228090E+01, 0.1687185709139079E+01, 0.1034799882693896E+00, 0.1498504938454686E+00, 0.9010425466701916E+00, 0.9038246924092180E+00, 0.3421413441684364E-01, 0.1006978425303630E+00, 0.8008017657953598E+00, 0.3061474807444209E+00, 0.6338813300623194E+00, 0.5288684194677825E+00, 0.8682873190108105E+00, 0.9598101715535300E+00, 0.6229686202966810E+00, 0.5423584775195998E+00, 0.8415597376799326E+00, 0.9973399062905237E+00, 0.1033340463692495E+00, 0.4671884516860899E+00, 0.7629036530181579E+00, 0.1861385328384410E+00, 0.1124645093942705E+01, 0.6800991665489665E+00, 0.6978261813392677E+00, 0.1261574624288360E+01, 0.3053203341720497E+00, 0.5608966509936130E+00, 0.4929941693545132E+00, 0.3798570066394223E+00, 0.5509778292160957E+00, 0.4184574968871406E+00, 0.2087258457383731E+00, 0.6491193472879784E+00, 0.4915348757406203E-01, 0.1105843276664904E+00, 0.4574524632962537E-01, 0.9277628648996712E-01, 0.1253505697055357E-02, 0.2122447413720272E-02, 0.2576338363396270E-01, 0.2701688933101806E-01, 0.8149780515932184E-03, 0.0000000000000000E+00, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 1, + dminOut: 2.5763383633962696E-002, + desigOut: -5.1698788284564230E-026, + sigmaOut: 2.1175425068616867E-005, + qmaxOut: 2.1637041623952107, + nFailOut: 1, + iterOut: 9, + nDivOut: 193, + ttypeOut: -1, + dmin1Out: 4.3622798915905092E-002, + dmin2Out: 7.4536672467372611E-002, + dnOut: 2.5763383633962696E-002, + dn1Out: 4.3622798915905092E-002, + dn2Out: 9.8141518071882677E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2471569222413904E+01, 0.2461394773494974E+01, 0.4896382518051712E-02, 0.1017444891892999E-01, 0.1186378431264915E+01, 0.1189425435147283E+01, 0.8149780515932184E-03, 0.1849378635683999E-02, 0.5236148327211592E+00, 0.5228093175235037E+00, 0.2766627272719901E-02, 0.1620493249248586E-02, 0.9525115502267366E+00, 0.8939544038697832E+00, 0.9233342160256496E-01, 0.6132377362967349E-01, 0.1403647802928048E+01, 0.1434168925733579E+01, 0.3870906568602875E-01, 0.6181229879703373E-01, 0.8617584837127339E+00, 0.8790143072012576E+00, 0.1740717486950262E-01, 0.2145324219750511E-01, 0.1395808011693333E+01, 0.6992314020959263E+00, 0.2121884039551361E+00, 0.7139837844669097E+00, 0.6295047433559955E+00, 0.4148193287752837E+00, 0.5351535485381410E+00, 0.4268738185358478E+00, 0.3698014604305115E+00, 0.7891833197548568E+00, 0.5281978587564573E+00, 0.1157716892137957E+00, 0.1308838344228090E+01, 0.1687185709139079E+01, 0.1034799882693896E+00, 0.1498504938454686E+00, 0.9010425466701916E+00, 0.9038246924092180E+00, 0.3421413441684364E-01, 0.1006978425303630E+00, 0.8008017657953598E+00, 0.3061474807444209E+00, 0.6338813300623194E+00, 0.5288684194677825E+00, 0.8682873190108105E+00, 0.9598101715535300E+00, 0.6229686202966810E+00, 0.5423584775195998E+00, 0.8415597376799326E+00, 0.9973399062905237E+00, 0.1033340463692495E+00, 0.4671884516860899E+00, 0.7629036530181579E+00, 0.1861385328384410E+00, 0.1124645093942705E+01, 0.6800991665489665E+00, 0.6978261813392677E+00, 0.1261574624288360E+01, 0.3053203341720497E+00, 0.5608966509936130E+00, 0.4929941693545132E+00, 0.3798570066394223E+00, 0.5509778292160957E+00, 0.4184574968871406E+00, 0.2087258457383731E+00, 0.6491193472879784E+00, 0.4915348757406203E-01, 0.1105843276664904E+00, 0.4574524632962537E-01, 0.9277628648996712E-01, 0.1253505697055357E-02, 0.2122447413720272E-02, 0.2576338363396270E-01, 0.2701688933101806E-01, 0.8149780515932184E-03, 0.1620493249248586E-02, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 2.5763383633962696E-002, + desig: -5.1698788284564230E-026, + qmax: 2.4715692224139039, + ttype: -1, + dmin1: 4.3622798915905092E-002, + dmin2: 7.4536672467372611E-002, + dn: 2.5763383633962696E-002, + dn1: 4.3622798915905092E-002, + dn2: 9.8141518071882677E-002, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 1, + iter: 9, + sigma: 2.1175425068616867E-005, + nDiv: 193, + zOut: []float64{0.2471569222413904E+01, 0.2471445466333236E+01, 0.4896382518051712E-02, 0.2350431231346416E-02, 0.1186378431264915E+01, 0.1179822839486443E+01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.5236148327211592E+00, 0.5209996276036221E+00, 0.2766627272719901E-02, 0.5058054349403302E-02, 0.9525115502267366E+00, 0.1034766778881179E+01, 0.9233342160256496E-01, 0.1252490967185870E+00, 0.1403647802928048E+01, 0.1312087633296770E+01, 0.3870906568602875E-01, 0.2542350442532051E-01, 0.8617584837127339E+00, 0.8487220155581966E+00, 0.1740717486950262E-01, 0.2862783537884150E-01, 0.1395808011693333E+01, 0.1574348441670908E+01, 0.2121884039551361E+00, 0.8484373804386666E-01, 0.6295047433559955E+00, 0.1074794415251550E+01, 0.5351535485381410E+00, 0.1841287608083240E+00, 0.3698014604305115E+00, 0.7088504197799252E+00, 0.5281978587564573E+00, 0.9752771411128711E+00, 0.1308838344228090E+01, 0.4320210527858890E+00, 0.1034799882693896E+00, 0.2158225196628609E+00, 0.9010425466701916E+00, 0.7144140228254550E+00, 0.3421413441684364E-01, 0.3835134583138245E-01, 0.8008017657953598E+00, 0.1391311611427577E+01, 0.6338813300623194E+00, 0.3955915526975877E+00, 0.8682873190108105E+00, 0.1090644248011184E+01, 0.6229686202966810E+00, 0.4806932321292802E+00, 0.8415597376799326E+00, 0.4591804133211825E+00, 0.1033340463692495E+00, 0.1716839812178710E+00, 0.7629036530181579E+00, 0.1710844627144272E+01, 0.1124645093942705E+01, 0.4587247601659613E+00, 0.6978261813392677E+00, 0.5394016167466366E+00, 0.3053203341720497E+00, 0.2790520826393697E+00, 0.4929941693545132E+00, 0.7598997773325197E+00, 0.5509778292160957E+00, 0.1513401067044909E+00, 0.2087258457383731E+00, 0.1015190880092246E+00, 0.4915348757406203E-01, 0.2214892234681356E-01, 0.4574524632962537E-01, 0.1982969108114764E-01, 0.1253505697055357E-02, 0.1628595626045726E-02, 0.2576338363396270E-01, 0.1911464940919745E-01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 0, + dminOut: 1.8576185384092288E-002, + desigOut: 2.6427422784455342E-019, + sigmaOut: 5.0413140237881371E-003, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 11, + nDivOut: 235, + ttypeOut: -15, + dmin1Out: 1.8576185384092288E-002, + dmin2Out: 5.2365600435162571E-002, + dnOut: 1.9114649409197451E-002, + dn1Out: 1.8576185384092288E-002, + dn2Out: 5.2365600435162571E-002, + gOut: 0.0000000000000000, + tauOut: 5.0201385987195205E-003, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2471569222413904E+01, 0.2471445466333236E+01, 0.4896382518051712E-02, 0.2350431231346416E-02, 0.1186378431264915E+01, 0.1179822839486443E+01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.5236148327211592E+00, 0.5209996276036221E+00, 0.2766627272719901E-02, 0.5058054349403302E-02, 0.9525115502267366E+00, 0.1034766778881179E+01, 0.9233342160256496E-01, 0.1252490967185870E+00, 0.1403647802928048E+01, 0.1312087633296770E+01, 0.3870906568602875E-01, 0.2542350442532051E-01, 0.8617584837127339E+00, 0.8487220155581966E+00, 0.1740717486950262E-01, 0.2862783537884150E-01, 0.1395808011693333E+01, 0.1574348441670908E+01, 0.2121884039551361E+00, 0.8484373804386666E-01, 0.6295047433559955E+00, 0.1074794415251550E+01, 0.5351535485381410E+00, 0.1841287608083240E+00, 0.3698014604305115E+00, 0.7088504197799252E+00, 0.5281978587564573E+00, 0.9752771411128711E+00, 0.1308838344228090E+01, 0.4320210527858890E+00, 0.1034799882693896E+00, 0.2158225196628609E+00, 0.9010425466701916E+00, 0.7144140228254550E+00, 0.3421413441684364E-01, 0.3835134583138245E-01, 0.8008017657953598E+00, 0.1391311611427577E+01, 0.6338813300623194E+00, 0.3955915526975877E+00, 0.8682873190108105E+00, 0.1090644248011184E+01, 0.6229686202966810E+00, 0.4806932321292802E+00, 0.8415597376799326E+00, 0.4591804133211825E+00, 0.1033340463692495E+00, 0.1716839812178710E+00, 0.7629036530181579E+00, 0.1710844627144272E+01, 0.1124645093942705E+01, 0.4587247601659613E+00, 0.6978261813392677E+00, 0.5394016167466366E+00, 0.3053203341720497E+00, 0.2790520826393697E+00, 0.4929941693545132E+00, 0.7598997773325197E+00, 0.5509778292160957E+00, 0.1513401067044909E+00, 0.2087258457383731E+00, 0.1015190880092246E+00, 0.4915348757406203E-01, 0.2214892234681356E-01, 0.4574524632962537E-01, 0.1982969108114764E-01, 0.1253505697055357E-02, 0.1628595626045726E-02, 0.2576338363396270E-01, 0.1911464940919745E-01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 1.8576185384092288E-002, + desig: 2.6427422784455342E-019, + qmax: 2.4715692224139039, + ttype: -15, + dmin1: 1.8576185384092288E-002, + dmin2: 5.2365600435162571E-002, + dn: 1.9114649409197451E-002, + dn1: 1.8576185384092288E-002, + dn2: 5.2365600435162571E-002, + g: 0.0000000000000000, + tau: 5.0201385987195205E-003, + nFail: 2, + iter: 11, + sigma: 5.0413140237881371E-003, + nDiv: 235, + zOut: []float64{0.2468318984233055E+01, 0.2471445466333236E+01, 0.1123474100024551E-02, 0.2350431231346416E-02, 0.1173584145846428E+01, 0.1179822839486443E+01, 0.1605699355811189E-03, 0.3616937915375072E-03, 0.5204201986859162E+00, 0.5209996276036221E+00, 0.1005707814522541E-01, 0.5058054349403302E-02, 0.1144481884123012E+01, 0.1034766778881179E+01, 0.1435914304680996E+00, 0.1252490967185870E+00, 0.1188442793922463E+01, 0.1312087633296770E+01, 0.1815610143690141E-01, 0.2542350442532051E-01, 0.8537168361686087E+00, 0.8487220155581966E+00, 0.5279290053521807E-01, 0.2862783537884150E-01, 0.1600922365848029E+01, 0.1574348441670908E+01, 0.5696064828871891E-01, 0.8484373804386666E-01, 0.1196485614439627E+01, 0.1074794415251550E+01, 0.1090859328498209E+00, 0.1841287608083240E+00, 0.1569564714711448E+01, 0.7088504197799252E+00, 0.2684440171930437E+00, 0.9752771411128711E+00, 0.3739226419241781E+00, 0.4320210527858890E+00, 0.4123490187575627E+00, 0.2158225196628609E+00, 0.3349394365677468E+00, 0.7144140228254550E+00, 0.1593084209965356E+00, 0.3835134583138245E-01, 0.1622117829797102E+01, 0.1391311611427577E+01, 0.2659792301064862E+00, 0.3955915526975877E+00, 0.1299881336702450E+01, 0.1090644248011184E+01, 0.1698038973078534E+00, 0.4806932321292802E+00, 0.4555835838996722E+00, 0.4591804133211825E+00, 0.6447216871142054E+00, 0.1716839812178710E+00, 0.1519370786864500E+01, 0.1710844627144272E+01, 0.1628548339973444E+00, 0.4587247601659613E+00, 0.6501219520571339E+00, 0.5394016167466366E+00, 0.3261720586281595E+00, 0.2790520826393697E+00, 0.5795909120773233E+00, 0.7598997773325197E+00, 0.2650819619788820E-01, 0.1513401067044909E+00, 0.9168290082662192E-01, 0.1015190880092246E+00, 0.4790492926791300E-02, 0.2214892234681356E-01, 0.1119088044887405E-01, 0.1982969108114764E-01, 0.2781732372482683E-02, 0.1628595626045726E-02, 0.1085600370518675E-01, 0.1911464940919745E-01, 0.1605699355811189E-03, 0.3616937915375072E-03, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 1, + dminOut: 9.5622848228283271E-003, + desigOut: -6.0308751014385013E-019, + sigmaOut: 1.0518227355316156E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 12, + nDivOut: 256, + ttypeOut: -4, + dmin1Out: 9.5622848228283271E-003, + dmin2Out: 6.9533978479808370E-002, + dnOut: 1.0856003705186750E-002, + dn1Out: 9.5622848228283271E-003, + dn2Out: 6.9533978479808370E-002, + gOut: 0.0000000000000000, + tauOut: 5.4769133315280185E-003, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2468318984233055E+01, 0.2471445466333236E+01, 0.1123474100024551E-02, 0.2350431231346416E-02, 0.1173584145846428E+01, 0.1179822839486443E+01, 0.1605699355811189E-03, 0.3616937915375072E-03, 0.5204201986859162E+00, 0.5209996276036221E+00, 0.1005707814522541E-01, 0.5058054349403302E-02, 0.1144481884123012E+01, 0.1034766778881179E+01, 0.1435914304680996E+00, 0.1252490967185870E+00, 0.1188442793922463E+01, 0.1312087633296770E+01, 0.1815610143690141E-01, 0.2542350442532051E-01, 0.8537168361686087E+00, 0.8487220155581966E+00, 0.5279290053521807E-01, 0.2862783537884150E-01, 0.1600922365848029E+01, 0.1574348441670908E+01, 0.5696064828871891E-01, 0.8484373804386666E-01, 0.1196485614439627E+01, 0.1074794415251550E+01, 0.1090859328498209E+00, 0.1841287608083240E+00, 0.1569564714711448E+01, 0.7088504197799252E+00, 0.2684440171930437E+00, 0.9752771411128711E+00, 0.3739226419241781E+00, 0.4320210527858890E+00, 0.4123490187575627E+00, 0.2158225196628609E+00, 0.3349394365677468E+00, 0.7144140228254550E+00, 0.1593084209965356E+00, 0.3835134583138245E-01, 0.1622117829797102E+01, 0.1391311611427577E+01, 0.2659792301064862E+00, 0.3955915526975877E+00, 0.1299881336702450E+01, 0.1090644248011184E+01, 0.1698038973078534E+00, 0.4806932321292802E+00, 0.4555835838996722E+00, 0.4591804133211825E+00, 0.6447216871142054E+00, 0.1716839812178710E+00, 0.1519370786864500E+01, 0.1710844627144272E+01, 0.1628548339973444E+00, 0.4587247601659613E+00, 0.6501219520571339E+00, 0.5394016167466366E+00, 0.3261720586281595E+00, 0.2790520826393697E+00, 0.5795909120773233E+00, 0.7598997773325197E+00, 0.2650819619788820E-01, 0.1513401067044909E+00, 0.9168290082662192E-01, 0.1015190880092246E+00, 0.4790492926791300E-02, 0.2214892234681356E-01, 0.1119088044887405E-01, 0.1982969108114764E-01, 0.2781732372482683E-02, 0.1628595626045726E-02, 0.1085600370518675E-01, 0.1911464940919745E-01, 0.1605699355811189E-03, 0.3616937915375072E-03, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 9.5622848228283271E-003, + desig: -6.0308751014385013E-019, + qmax: 2.4715692224139039, + ttype: -4, + dmin1: 9.5622848228283271E-003, + dmin2: 6.9533978479808370E-002, + dn: 1.0856003705186750E-002, + dn1: 9.5622848228283271E-003, + dn2: 6.9533978479808370E-002, + g: 0.0000000000000000, + tau: 5.4769133315280185E-003, + nFail: 2, + iter: 12, + sigma: 1.0518227355316156E-002, + nDiv: 256, + zOut: []float64{0.2468318984233055E+01, 0.2464320851971913E+01, 0.1123474100024551E-02, 0.5350323562789559E-03, 0.1173584145846428E+01, 0.1168088077064565E+01, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.5204201986859162E+00, 0.5252841314829605E+00, 0.1005707814522541E-01, 0.2191222436498315E-01, 0.1144481884123012E+01, 0.1261039483864963E+01, 0.1435914304680996E+00, 0.1353250258951489E+00, 0.1188442793922463E+01, 0.1066152263103050E+01, 0.1815610143690141E-01, 0.1453842008528346E-01, 0.8537168361686087E+00, 0.8868497102573779E+00, 0.5279290053521807E-01, 0.9530062900995111E-01, 0.1600922365848029E+01, 0.1557460778765631E+01, 0.5696064828871891E-01, 0.4375878814786067E-01, 0.1196485614439627E+01, 0.1256691152780422E+01, 0.1090859328498209E+00, 0.1362446379077657E+00, 0.1569564714711448E+01, 0.1696642487635560E+01, 0.2684440171930437E+00, 0.5916231430550117E-01, 0.3739226419241781E+00, 0.7219877400150740E+00, 0.4123490187575627E+00, 0.1912940350054112E+00, 0.3349394365677468E+00, 0.2978322161977056E+00, 0.1593084209965356E+00, 0.8676597630518320E+00, 0.1622117829797102E+01, 0.1015315690490590E+01, 0.2659792301064862E+00, 0.3405260456467969E+00, 0.1299881336702450E+01, 0.1124037582002341E+01, 0.1698038973078534E+00, 0.6882320425428856E-01, 0.4555835838996722E+00, 0.1026360460398424E+01, 0.6447216871142054E+00, 0.9544125430154021E+00, 0.1519370786864500E+01, 0.7226914714852769E+00, 0.1628548339973444E+00, 0.1465016632377001E+00, 0.6501219520571339E+00, 0.8246707410864278E+00, 0.3261720586281595E+00, 0.2292385937027206E+00, 0.5795909120773233E+00, 0.3717389082113253E+00, 0.2650819619788820E-01, 0.6537783023029759E-02, 0.9168290082662192E-01, 0.8481400436921797E-01, 0.4790492926791300E-02, 0.6320870478125323E-03, 0.1119088044887405E-01, 0.8218919412378699E-02, 0.2781732372482683E-02, 0.3674266095981827E-02, 0.1085600370518675E-01, 0.2060131248039419E-02, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 0, + dminOut: 2.0601312480394186E-003, + desigOut: 0.0000000000000000, + sigmaOut: 1.5639833716481661E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 13, + nDivOut: 277, + ttypeOut: -4, + dmin1Out: 5.4371870398960158E-003, + dmin2Out: 8.0023511442426670E-002, + dnOut: 2.0601312480394186E-003, + dn1Out: 5.4371870398960158E-003, + dn2Out: 8.0023511442426670E-002, + gOut: 0.0000000000000000, + tauOut: 5.1216063611655054E-003, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2468318984233055E+01, 0.2464320851971913E+01, 0.1123474100024551E-02, 0.5350323562789559E-03, 0.1173584145846428E+01, 0.1168088077064565E+01, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.5204201986859162E+00, 0.5252841314829605E+00, 0.1005707814522541E-01, 0.2191222436498315E-01, 0.1144481884123012E+01, 0.1261039483864963E+01, 0.1435914304680996E+00, 0.1353250258951489E+00, 0.1188442793922463E+01, 0.1066152263103050E+01, 0.1815610143690141E-01, 0.1453842008528346E-01, 0.8537168361686087E+00, 0.8868497102573779E+00, 0.5279290053521807E-01, 0.9530062900995111E-01, 0.1600922365848029E+01, 0.1557460778765631E+01, 0.5696064828871891E-01, 0.4375878814786067E-01, 0.1196485614439627E+01, 0.1256691152780422E+01, 0.1090859328498209E+00, 0.1362446379077657E+00, 0.1569564714711448E+01, 0.1696642487635560E+01, 0.2684440171930437E+00, 0.5916231430550117E-01, 0.3739226419241781E+00, 0.7219877400150740E+00, 0.4123490187575627E+00, 0.1912940350054112E+00, 0.3349394365677468E+00, 0.2978322161977056E+00, 0.1593084209965356E+00, 0.8676597630518320E+00, 0.1622117829797102E+01, 0.1015315690490590E+01, 0.2659792301064862E+00, 0.3405260456467969E+00, 0.1299881336702450E+01, 0.1124037582002341E+01, 0.1698038973078534E+00, 0.6882320425428856E-01, 0.4555835838996722E+00, 0.1026360460398424E+01, 0.6447216871142054E+00, 0.9544125430154021E+00, 0.1519370786864500E+01, 0.7226914714852769E+00, 0.1628548339973444E+00, 0.1465016632377001E+00, 0.6501219520571339E+00, 0.8246707410864278E+00, 0.3261720586281595E+00, 0.2292385937027206E+00, 0.5795909120773233E+00, 0.3717389082113253E+00, 0.2650819619788820E-01, 0.6537783023029759E-02, 0.9168290082662192E-01, 0.8481400436921797E-01, 0.4790492926791300E-02, 0.6320870478125323E-03, 0.1119088044887405E-01, 0.8218919412378699E-02, 0.2781732372482683E-02, 0.3674266095981827E-02, 0.1085600370518675E-01, 0.2060131248039419E-02, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 2.0601312480394186E-003, + desig: 0.0000000000000000, + qmax: 2.4715692224139039, + ttype: -4, + dmin1: 5.4371870398960158E-003, + dmin2: 8.0023511442426670E-002, + dn: 2.0601312480394186E-003, + dn1: 5.4371870398960158E-003, + dn2: 8.0023511442426670E-002, + g: 0.0000000000000000, + tau: 5.1216063611655054E-003, + nFail: 2, + iter: 13, + sigma: 1.5639833716481661E-002, + nDiv: 277, + zOut: []float64{0.2463574096511276E+01, 0.2464320851971913E+01, 0.2536822079344948E-03, 0.5350323562789559E-03, 0.1166624146026729E+01, 0.1168088077064565E+01, 0.3221114082852138E-04, 0.7153898701552432E-04, 0.5458823568901986E+00, 0.5252841314829605E+00, 0.5061929508212644E-01, 0.2191222436498315E-01, 0.1344463426861069E+01, 0.1261039483864963E+01, 0.1073120173669855E+00, 0.1353250258951489E+00, 0.9720968780044319E+00, 0.1066152263103050E+01, 0.1326348631702415E-01, 0.1453842008528346E-01, 0.9676050651333883E+00, 0.8868497102573779E+00, 0.1533962535161303E+00, 0.9530062900995111E-01, 0.1446541525580445E+01, 0.1557460778765631E+01, 0.3801569533217738E-01, 0.4375878814786067E-01, 0.1353638307539094E+01, 0.1256691152780422E+01, 0.1707682473962209E+00, 0.1362446379077657E+00, 0.1583754766727924E+01, 0.1696642487635560E+01, 0.2697037855661164E-01, 0.5916231430550117E-01, 0.8850296086469572E+00, 0.7219877400150740E+00, 0.6437471225190403E-01, 0.1912940350054112E+00, 0.1099835479180717E+01, 0.2978322161977056E+00, 0.8009821360646626E+00, 0.8676597630518320E+00, 0.5535778122558079E+00, 0.1015315690490590E+01, 0.6914368034330997E+00, 0.3405260456467969E+00, 0.5001421950066134E+00, 0.1124037582002341E+01, 0.1412346654806686E+00, 0.6882320425428856E-01, 0.1838256550116241E+01, 0.1026360460398424E+01, 0.3752173792456719E+00, 0.9544125430154021E+00, 0.4926939676603885E+00, 0.7226914714852769E+00, 0.2452143584512202E+00, 0.1465016632377001E+00, 0.8074131885210117E+00, 0.8246707410864278E+00, 0.1055431169003394E+00, 0.2292385937027206E+00, 0.2714517865170992E+00, 0.3717389082113253E+00, 0.2042703660177667E-02, 0.6537783023029759E-02, 0.8212159993993635E-01, 0.8481400436921797E-01, 0.6326073178529442E-04, 0.6320870478125323E-03, 0.1054813695965874E-01, 0.8218919412378699E-02, 0.7176120699696391E-03, 0.3674266095981827E-02, 0.6073136115328898E-04, 0.2060131248039419E-02, 0.3221114082852138E-04, 0.7153898701552432E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 1, + dminOut: 6.0731361153288982E-005, + desigOut: 1.7347234759768071E-018, + sigmaOut: 1.6921621533398150E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 14, + nDivOut: 298, + ttypeOut: -2, + dmin1Out: 6.8738708636769136E-003, + dmin2Out: 8.1489512892123819E-002, + dnOut: 6.0731361153288982E-005, + dn1Out: 6.8738708636769136E-003, + dn2Out: 8.1489512892123819E-002, + gOut: 0.0000000000000000, + tauOut: 1.2817878169164906E-003, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2463574096511276E+01, 0.2464320851971913E+01, 0.2536822079344948E-03, 0.5350323562789559E-03, 0.1166624146026729E+01, 0.1168088077064565E+01, 0.3221114082852138E-04, 0.7153898701552432E-04, 0.5458823568901986E+00, 0.5252841314829605E+00, 0.5061929508212644E-01, 0.2191222436498315E-01, 0.1344463426861069E+01, 0.1261039483864963E+01, 0.1073120173669855E+00, 0.1353250258951489E+00, 0.9720968780044319E+00, 0.1066152263103050E+01, 0.1326348631702415E-01, 0.1453842008528346E-01, 0.9676050651333883E+00, 0.8868497102573779E+00, 0.1533962535161303E+00, 0.9530062900995111E-01, 0.1446541525580445E+01, 0.1557460778765631E+01, 0.3801569533217738E-01, 0.4375878814786067E-01, 0.1353638307539094E+01, 0.1256691152780422E+01, 0.1707682473962209E+00, 0.1362446379077657E+00, 0.1583754766727924E+01, 0.1696642487635560E+01, 0.2697037855661164E-01, 0.5916231430550117E-01, 0.8850296086469572E+00, 0.7219877400150740E+00, 0.6437471225190403E-01, 0.1912940350054112E+00, 0.1099835479180717E+01, 0.2978322161977056E+00, 0.8009821360646626E+00, 0.8676597630518320E+00, 0.5535778122558079E+00, 0.1015315690490590E+01, 0.6914368034330997E+00, 0.3405260456467969E+00, 0.5001421950066134E+00, 0.1124037582002341E+01, 0.1412346654806686E+00, 0.6882320425428856E-01, 0.1838256550116241E+01, 0.1026360460398424E+01, 0.3752173792456719E+00, 0.9544125430154021E+00, 0.4926939676603885E+00, 0.7226914714852769E+00, 0.2452143584512202E+00, 0.1465016632377001E+00, 0.8074131885210117E+00, 0.8246707410864278E+00, 0.1055431169003394E+00, 0.2292385937027206E+00, 0.2714517865170992E+00, 0.3717389082113253E+00, 0.2042703660177667E-02, 0.6537783023029759E-02, 0.8212159993993635E-01, 0.8481400436921797E-01, 0.6326073178529442E-04, 0.6320870478125323E-03, 0.1054813695965874E-01, 0.8218919412378699E-02, 0.7176120699696391E-03, 0.3674266095981827E-02, 0.6073136115328898E-04, 0.2060131248039419E-02, 0.3221114082852138E-04, 0.7153898701552432E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 6.0731361153288982E-005, + desig: 1.7347234759768071E-018, + qmax: 2.4715692224139039, + ttype: -2, + dmin1: 6.8738708636769136E-003, + dmin2: 8.1489512892123819E-002, + dn: 6.0731361153288982E-005, + dn1: 6.8738708636769136E-003, + dn2: 8.1489512892123819E-002, + g: 0.0000000000000000, + tau: 1.2817878169164906E-003, + nFail: 2, + iter: 14, + sigma: 1.6921621533398150E-002, + nDiv: 298, + zOut: []float64{0.2463574096511276E+01, 0.2463770941477959E+01, 0.2536822079344948E-03, 0.1201214707955848E-03, 0.1166624146026729E+01, 0.1166479398455512E+01, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.5458823568901986E+00, 0.5964297407456295E+00, 0.5061929508212644E-01, 0.1141052940222717E+00, 0.1344463426861069E+01, 0.1337613312964532E+01, 0.1073120173669855E+00, 0.7798791776646297E-01, 0.9720968780044319E+00, 0.9073156093137420E+00, 0.1326348631702415E-01, 0.1414482062243694E-01, 0.9676050651333883E+00, 0.1106799660785830E+01, 0.1533962535161303E+00, 0.2004825791345134E+00, 0.1446541525580445E+01, 0.1284017804536858E+01, 0.3801569533217738E-01, 0.4007693764646178E-01, 0.1353638307539094E+01, 0.1484272780047602E+01, 0.1707682473962209E+00, 0.1822138285193538E+00, 0.1583754766727924E+01, 0.1428454479523931E+01, 0.2697037855661164E-01, 0.1671007646458111E-01, 0.8850296086469572E+00, 0.9326374071930291E+00, 0.6437471225190403E-01, 0.7591545433480534E-01, 0.1099835479180717E+01, 0.1824845323669324E+01, 0.8009821360646626E+00, 0.2429827519008994E+00, 0.5535778122558079E+00, 0.1001975026546757E+01, 0.6914368034330997E+00, 0.3451350696526060E+00, 0.5001421950066134E+00, 0.2961849535934249E+00, 0.1412346654806686E+00, 0.8765656248686587E+00, 0.1838256550116241E+01, 0.1336851467252003E+01, 0.3752173792456719E+00, 0.1382856239786244E+00, 0.4926939676603885E+00, 0.5995658648917332E+00, 0.2452143584512202E+00, 0.3302211126778973E+00, 0.8074131885210117E+00, 0.5826783555022028E+00, 0.1055431169003394E+00, 0.4916926700063749E-01, 0.2714517865170992E+00, 0.2242683859353883E+00, 0.2042703660177667E-02, 0.7479881396448043E-03, 0.8212159993993635E-01, 0.8138003529082581E-01, 0.6326073178529442E-04, 0.8199589256196194E-05, 0.1054813695965874E-01, 0.1120071219912114E-01, 0.7176120699696391E-03, 0.3890963093641941E-05, 0.6073136115328898E-04, 0.3156808608191942E-08, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 0, + dminOut: 3.1568086081919418E-009, + desigOut: 4.7433845046240819E-020, + sigmaOut: 1.6978458774649190E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 15, + nDivOut: 319, + ttypeOut: -2, + dmin1Out: 1.0483100129151506E-002, + dmin2Out: 8.1316774559040517E-002, + dnOut: 3.1568086081919418E-009, + dn1Out: 1.0483100129151506E-002, + dn2Out: 8.1316774559040517E-002, + gOut: 0.0000000000000000, + tauOut: 5.6837241251038845E-005, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2463574096511276E+01, 0.2463770941477959E+01, 0.2536822079344948E-03, 0.1201214707955848E-03, 0.1166624146026729E+01, 0.1166479398455512E+01, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.5458823568901986E+00, 0.5964297407456295E+00, 0.5061929508212644E-01, 0.1141052940222717E+00, 0.1344463426861069E+01, 0.1337613312964532E+01, 0.1073120173669855E+00, 0.7798791776646297E-01, 0.9720968780044319E+00, 0.9073156093137420E+00, 0.1326348631702415E-01, 0.1414482062243694E-01, 0.9676050651333883E+00, 0.1106799660785830E+01, 0.1533962535161303E+00, 0.2004825791345134E+00, 0.1446541525580445E+01, 0.1284017804536858E+01, 0.3801569533217738E-01, 0.4007693764646178E-01, 0.1353638307539094E+01, 0.1484272780047602E+01, 0.1707682473962209E+00, 0.1822138285193538E+00, 0.1583754766727924E+01, 0.1428454479523931E+01, 0.2697037855661164E-01, 0.1671007646458111E-01, 0.8850296086469572E+00, 0.9326374071930291E+00, 0.6437471225190403E-01, 0.7591545433480534E-01, 0.1099835479180717E+01, 0.1824845323669324E+01, 0.8009821360646626E+00, 0.2429827519008994E+00, 0.5535778122558079E+00, 0.1001975026546757E+01, 0.6914368034330997E+00, 0.3451350696526060E+00, 0.5001421950066134E+00, 0.2961849535934249E+00, 0.1412346654806686E+00, 0.8765656248686587E+00, 0.1838256550116241E+01, 0.1336851467252003E+01, 0.3752173792456719E+00, 0.1382856239786244E+00, 0.4926939676603885E+00, 0.5995658648917332E+00, 0.2452143584512202E+00, 0.3302211126778973E+00, 0.8074131885210117E+00, 0.5826783555022028E+00, 0.1055431169003394E+00, 0.4916926700063749E-01, 0.2714517865170992E+00, 0.2242683859353883E+00, 0.2042703660177667E-02, 0.7479881396448043E-03, 0.8212159993993635E-01, 0.8138003529082581E-01, 0.6326073178529442E-04, 0.8199589256196194E-05, 0.1054813695965874E-01, 0.1120071219912114E-01, 0.7176120699696391E-03, 0.3890963093641941E-05, 0.6073136115328898E-04, 0.3156808608191942E-08, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 3.1568086081919418E-009, + desig: 4.7433845046240819E-020, + qmax: 2.4715692224139039, + ttype: -2, + dmin1: 1.0483100129151506E-002, + dmin2: 8.1316774559040517E-002, + dn: 3.1568086081919418E-009, + dn1: 1.0483100129151506E-002, + dn2: 8.1316774559040517E-002, + g: 0.0000000000000000, + tau: 5.6837241251038845E-005, + nFail: 2, + iter: 15, + sigma: 1.6978458774649190E-002, + nDiv: 319, + zOut: []float64{0.2463891059793043E+01, 0.2463770941477959E+01, 0.5686908130061341E-04, 0.1201214707955848E-03, 0.1166437600203943E+01, 0.1166479398455512E+01, 0.7707718980490818E-05, 0.1507398544447245E-04, 0.7105273238932086E+00, 0.5964297407456295E+00, 0.2148105431436762E+00, 0.1141052940222717E+00, 0.1200790684431606E+01, 0.1337613312964532E+01, 0.5892755169139442E-01, 0.7798791776646297E-01, 0.8625328750890724E+00, 0.9073156093137420E+00, 0.1815059242254727E-01, 0.1414482062243694E-01, 0.1289131644342084E+01, 0.1106799660785830E+01, 0.1996872873596725E+00, 0.2004825791345134E+00, 0.1124407451667935E+01, 0.1284017804536858E+01, 0.5290351604133232E-01, 0.4007693764646178E-01, 0.1613583089369911E+01, 0.1484272780047602E+01, 0.1613081850537457E+00, 0.1822138285193538E+00, 0.1283856367779054E+01, 0.1428454479523931E+01, 0.1213877407087503E-01, 0.1671007646458111E-01, 0.9964140843012472E+00, 0.9326374071930291E+00, 0.1390325207358455E+00, 0.7591545433480534E-01, 0.1928795551678665E+01, 0.1824845323669324E+01, 0.1262252233392066E+00, 0.2429827519008994E+00, 0.1220884869704444E+01, 0.1001975026546757E+01, 0.8372928285471114E-01, 0.3451350696526060E+00, 0.1089021292451660E+01, 0.2961849535934249E+00, 0.1076046951396362E+01, 0.8765656248686587E+00, 0.3990901366785531E+00, 0.1336851467252003E+01, 0.2077509116934600E+00, 0.1382856239786244E+00, 0.7220360627204584E+00, 0.5995658648917332E+00, 0.2664862668525171E+00, 0.3302211126778973E+00, 0.3653613524946110E+00, 0.5826783555022028E+00, 0.3018138637972599E-01, 0.4916926700063749E-01, 0.1948349845395949E+00, 0.2242683859353883E+00, 0.3124249032854923E-03, 0.7479881396448043E-03, 0.8107580682108434E-01, 0.8138003529082581E-01, 0.1132782305976083E-05, 0.8199589256196194E-05, 0.1120346722419663E-01, 0.1120071219912114E-01, 0.1096359327194516E-11, 0.3890963093641941E-05, 0.6968497581336674E-16, 0.3156808608191942E-08, 0.7707718980490818E-05, 0.1507398544447245E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 1, + dminOut: 6.9684975813366743E-017, + desigOut: 1.5445815365207740E-018, + sigmaOut: 1.6978461930361368E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 16, + nDivOut: 340, + ttypeOut: -2, + dmin1Out: 1.1199576261102989E-002, + dmin2Out: 8.1067607231828140E-002, + dnOut: 6.9684975813366743E-017, + dn1Out: 1.1199576261102989E-002, + dn2Out: 8.1067607231828140E-002, + gOut: 0.0000000000000000, + tauOut: 3.1557121791797713E-009, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2463891059793043E+01, 0.2463770941477959E+01, 0.5686908130061341E-04, 0.1201214707955848E-03, 0.1166437600203943E+01, 0.1166479398455512E+01, 0.7707718980490818E-05, 0.1507398544447245E-04, 0.7105273238932086E+00, 0.5964297407456295E+00, 0.2148105431436762E+00, 0.1141052940222717E+00, 0.1200790684431606E+01, 0.1337613312964532E+01, 0.5892755169139442E-01, 0.7798791776646297E-01, 0.8625328750890724E+00, 0.9073156093137420E+00, 0.1815059242254727E-01, 0.1414482062243694E-01, 0.1289131644342084E+01, 0.1106799660785830E+01, 0.1996872873596725E+00, 0.2004825791345134E+00, 0.1124407451667935E+01, 0.1284017804536858E+01, 0.5290351604133232E-01, 0.4007693764646178E-01, 0.1613583089369911E+01, 0.1484272780047602E+01, 0.1613081850537457E+00, 0.1822138285193538E+00, 0.1283856367779054E+01, 0.1428454479523931E+01, 0.1213877407087503E-01, 0.1671007646458111E-01, 0.9964140843012472E+00, 0.9326374071930291E+00, 0.1390325207358455E+00, 0.7591545433480534E-01, 0.1928795551678665E+01, 0.1824845323669324E+01, 0.1262252233392066E+00, 0.2429827519008994E+00, 0.1220884869704444E+01, 0.1001975026546757E+01, 0.8372928285471114E-01, 0.3451350696526060E+00, 0.1089021292451660E+01, 0.2961849535934249E+00, 0.1076046951396362E+01, 0.8765656248686587E+00, 0.3990901366785531E+00, 0.1336851467252003E+01, 0.2077509116934600E+00, 0.1382856239786244E+00, 0.7220360627204584E+00, 0.5995658648917332E+00, 0.2664862668525171E+00, 0.3302211126778973E+00, 0.3653613524946110E+00, 0.5826783555022028E+00, 0.3018138637972599E-01, 0.4916926700063749E-01, 0.1948349845395949E+00, 0.2242683859353883E+00, 0.3124249032854923E-03, 0.7479881396448043E-03, 0.8107580682108434E-01, 0.8138003529082581E-01, 0.1132782305976083E-05, 0.8199589256196194E-05, 0.1120346722419663E-01, 0.1120071219912114E-01, 0.1096359327194516E-11, 0.3890963093641941E-05, 0.6968497581336674E-16, 0.3156808608191942E-08, 0.7707718980490818E-05, 0.1507398544447245E-04, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 6.9684975813366743E-017, + desig: 1.5445815365207740E-018, + qmax: 2.4715692224139039, + ttype: -2, + dmin1: 1.1199576261102989E-002, + dmin2: 8.1067607231828140E-002, + dn: 6.9684975813366743E-017, + dn1: 1.1199576261102989E-002, + dn2: 8.1067607231828140E-002, + g: 0.0000000000000000, + tau: 3.1557121791797713E-009, + nFail: 2, + iter: 16, + sigma: 1.6978461930361368E-002, + nDiv: 340, + zOut: []float64{0.2463891059793043E+01, 0.2463947928874343E+01, 0.5686908130061341E-04, 0.2692193042748079E-04, 0.1166437600203943E+01, 0.1166418385992496E+01, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.7105273238932086E+00, 0.9253331718563164E+00, 0.2148105431436762E+00, 0.2787563517334627E+00, 0.1200790684431606E+01, 0.9809618843895378E+00, 0.5892755169139442E-01, 0.5181337969514327E-01, 0.8625328750890724E+00, 0.8288700878164763E+00, 0.1815059242254727E-01, 0.2822939734392020E-01, 0.1289131644342084E+01, 0.1460589534357837E+01, 0.1996872873596725E+00, 0.1537255119449346E+00, 0.1124407451667935E+01, 0.1023585455764333E+01, 0.5290351604133232E-01, 0.8339725654733963E-01, 0.1613583089369911E+01, 0.1691494017876317E+01, 0.1613081850537457E+00, 0.1224340957564512E+00, 0.1283856367779054E+01, 0.1173561046093478E+01, 0.1213877407087503E-01, 0.1030644761994533E-01, 0.9964140843012472E+00, 0.1125140157417147E+01, 0.1390325207358455E+00, 0.2383394688796517E+00, 0.1928795551678665E+01, 0.1816681306138221E+01, 0.1262252233392066E+00, 0.8482856339700598E-01, 0.1220884869704444E+01, 0.1219785589162149E+01, 0.8372928285471114E-01, 0.7475327847832687E-01, 0.1089021292451660E+01, 0.2090314965369696E+01, 0.1076046951396362E+01, 0.2054425921547012E+00, 0.3990901366785531E+00, 0.4013984562173118E+00, 0.2077509116934600E+00, 0.3737026089221466E+00, 0.7220360627204584E+00, 0.6148197206508288E+00, 0.2664862668525171E+00, 0.1583615157552351E+00, 0.3653613524946110E+00, 0.2371812231191019E+00, 0.3018138637972599E-01, 0.2479281399828426E-01, 0.1948349845395949E+00, 0.1703545954445960E+00, 0.3124249032854923E-03, 0.1486904479375115E-03, 0.8107580682108434E-01, 0.8092824915545274E-01, 0.1132782305976083E-05, 0.1568190288260776E-06, 0.1120346722419663E-01, 0.1120331040626409E-01, 0.1096359327194516E-11, 0.6819392699821255E-26, 0.6968497581336674E-16, 0.6162975822039155E-31, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 0, + dminOut: 6.1629758220391547E-032, + desigOut: -1.6288286479578371E-018, + sigmaOut: 1.6978461930361441E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 17, + nDivOut: 361, + ttypeOut: -2, + dmin1Out: 1.1203310405167735E-002, + dmin2Out: 8.0927116373146771E-002, + dnOut: 6.1629758220391547E-032, + dn1Out: 1.1203310405167735E-002, + dn2Out: 8.0927116373146771E-002, + gOut: 0.0000000000000000, + tauOut: 6.9684975806547287E-017, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2463891059793043E+01, 0.2463947928874343E+01, 0.5686908130061341E-04, 0.2692193042748079E-04, 0.1166437600203943E+01, 0.1166418385992496E+01, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.7105273238932086E+00, 0.9253331718563164E+00, 0.2148105431436762E+00, 0.2787563517334627E+00, 0.1200790684431606E+01, 0.9809618843895378E+00, 0.5892755169139442E-01, 0.5181337969514327E-01, 0.8625328750890724E+00, 0.8288700878164763E+00, 0.1815059242254727E-01, 0.2822939734392020E-01, 0.1289131644342084E+01, 0.1460589534357837E+01, 0.1996872873596725E+00, 0.1537255119449346E+00, 0.1124407451667935E+01, 0.1023585455764333E+01, 0.5290351604133232E-01, 0.8339725654733963E-01, 0.1613583089369911E+01, 0.1691494017876317E+01, 0.1613081850537457E+00, 0.1224340957564512E+00, 0.1283856367779054E+01, 0.1173561046093478E+01, 0.1213877407087503E-01, 0.1030644761994533E-01, 0.9964140843012472E+00, 0.1125140157417147E+01, 0.1390325207358455E+00, 0.2383394688796517E+00, 0.1928795551678665E+01, 0.1816681306138221E+01, 0.1262252233392066E+00, 0.8482856339700598E-01, 0.1220884869704444E+01, 0.1219785589162149E+01, 0.8372928285471114E-01, 0.7475327847832687E-01, 0.1089021292451660E+01, 0.2090314965369696E+01, 0.1076046951396362E+01, 0.2054425921547012E+00, 0.3990901366785531E+00, 0.4013984562173118E+00, 0.2077509116934600E+00, 0.3737026089221466E+00, 0.7220360627204584E+00, 0.6148197206508288E+00, 0.2664862668525171E+00, 0.1583615157552351E+00, 0.3653613524946110E+00, 0.2371812231191019E+00, 0.3018138637972599E-01, 0.2479281399828426E-01, 0.1948349845395949E+00, 0.1703545954445960E+00, 0.3124249032854923E-03, 0.1486904479375115E-03, 0.8107580682108434E-01, 0.8092824915545274E-01, 0.1132782305976083E-05, 0.1568190288260776E-06, 0.1120346722419663E-01, 0.1120331040626409E-01, 0.1096359327194516E-11, 0.6819392699821255E-26, 0.6968497581336674E-16, 0.6162975822039155E-31, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 6.1629758220391547E-032, + desig: -1.6288286479578371E-018, + qmax: 2.4715692224139039, + ttype: -2, + dmin1: 1.1203310405167735E-002, + dmin2: 8.0927116373146771E-002, + dn: 6.1629758220391547E-032, + dn1: 1.1203310405167735E-002, + dn2: 8.0927116373146771E-002, + g: 0.0000000000000000, + tau: 6.9684975806547287E-017, + nFail: 2, + iter: 17, + sigma: 1.6978461930361441E-002, + nDiv: 361, + zOut: []float64{0.2463974850804771E+01, 0.2463947928874343E+01, 0.1274454348702788E-04, 0.2692193042748079E-04, 0.1166410336629578E+01, 0.1166418385992496E+01, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.1204085798823124E+01, 0.9253331718563164E+00, 0.2271012218143261E+00, 0.2787563517334627E+00, 0.8056740422703550E+00, 0.9809618843895378E+00, 0.5330513126246473E-01, 0.5181337969514327E-01, 0.8037943538979316E+00, 0.8288700878164763E+00, 0.5129615818002433E-01, 0.2822939734392020E-01, 0.1563018888122747E+01, 0.1460589534357837E+01, 0.1006713350698832E+00, 0.1537255119449346E+00, 0.1006311377241790E+01, 0.1023585455764333E+01, 0.1401812239704283E+00, 0.8339725654733963E-01, 0.1673746889662340E+01, 0.1691494017876317E+01, 0.8584564749956700E-01, 0.1224340957564512E+00, 0.1098021846213856E+01, 0.1173561046093478E+01, 0.1056099032774466E-01, 0.1030644761994533E-01, 0.1352918635969054E+01, 0.1125140157417147E+01, 0.3200390963041470E+00, 0.2383394688796517E+00, 0.1581470773231080E+01, 0.1816681306138221E+01, 0.6542811978092533E-01, 0.8482856339700598E-01, 0.1229110747859551E+01, 0.1219785589162149E+01, 0.1271308521106110E+00, 0.7475327847832687E-01, 0.2168626705413786E+01, 0.2090314965369696E+01, 0.3802606466401751E-01, 0.2054425921547012E+00, 0.7370750004754409E+00, 0.4013984562173118E+00, 0.3117182559112661E+00, 0.3737026089221466E+00, 0.4614629804947978E+00, 0.6148197206508288E+00, 0.8139413038408401E-01, 0.1583615157552351E+00, 0.1805799067333021E+00, 0.2371812231191019E+00, 0.2338892446571373E-01, 0.2479281399828426E-01, 0.1471143614268198E+00, 0.1703545954445960E+00, 0.8179526119010886E-04, 0.1486904479375115E-03, 0.8084661071329148E-01, 0.8092824915545274E-01, 0.2173118009582292E-07, 0.1568190288260776E-06, 0.1120328867508400E-01, 0.1120331040626409E-01, 0.3751376363572422E-55, 0.6819392699821255E-26, 0.6162975822039155E-31, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 20, + ppOut: 1, + dminOut: 6.1629758220391547E-032, + desigOut: -1.6288286479578371E-018, + sigmaOut: 1.6978461930361441E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 18, + nDivOut: 382, + ttypeOut: -2, + dmin1Out: 1.1203288675083998E-002, + dmin2Out: 8.0846453894262649E-002, + dnOut: 6.1629758220391547E-032, + dn1Out: 1.1203288675083998E-002, + dn2Out: 8.0846453894262649E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2463974850804771E+01, 0.2463947928874343E+01, 0.1274454348702788E-04, 0.2692193042748079E-04, 0.1166410336629578E+01, 0.1166418385992496E+01, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.1204085798823124E+01, 0.9253331718563164E+00, 0.2271012218143261E+00, 0.2787563517334627E+00, 0.8056740422703550E+00, 0.9809618843895378E+00, 0.5330513126246473E-01, 0.5181337969514327E-01, 0.8037943538979316E+00, 0.8288700878164763E+00, 0.5129615818002433E-01, 0.2822939734392020E-01, 0.1563018888122747E+01, 0.1460589534357837E+01, 0.1006713350698832E+00, 0.1537255119449346E+00, 0.1006311377241790E+01, 0.1023585455764333E+01, 0.1401812239704283E+00, 0.8339725654733963E-01, 0.1673746889662340E+01, 0.1691494017876317E+01, 0.8584564749956700E-01, 0.1224340957564512E+00, 0.1098021846213856E+01, 0.1173561046093478E+01, 0.1056099032774466E-01, 0.1030644761994533E-01, 0.1352918635969054E+01, 0.1125140157417147E+01, 0.3200390963041470E+00, 0.2383394688796517E+00, 0.1581470773231080E+01, 0.1816681306138221E+01, 0.6542811978092533E-01, 0.8482856339700598E-01, 0.1229110747859551E+01, 0.1219785589162149E+01, 0.1271308521106110E+00, 0.7475327847832687E-01, 0.2168626705413786E+01, 0.2090314965369696E+01, 0.3802606466401751E-01, 0.2054425921547012E+00, 0.7370750004754409E+00, 0.4013984562173118E+00, 0.3117182559112661E+00, 0.3737026089221466E+00, 0.4614629804947978E+00, 0.6148197206508288E+00, 0.8139413038408401E-01, 0.1583615157552351E+00, 0.1805799067333021E+00, 0.2371812231191019E+00, 0.2338892446571373E-01, 0.2479281399828426E-01, 0.1471143614268198E+00, 0.1703545954445960E+00, 0.8179526119010886E-04, 0.1486904479375115E-03, 0.8084661071329148E-01, 0.8092824915545274E-01, 0.2173118009582292E-07, 0.1568190288260776E-06, 0.1120328867508400E-01, 0.1120331040626409E-01, 0.3751376363572422E-55, 0.6819392699821255E-26, 0.6162975822039155E-31, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 6.1629758220391547E-032, + desig: -1.6288286479578371E-018, + qmax: 2.4715692224139039, + ttype: -2, + dmin1: 1.1203288675083998E-002, + dmin2: 8.0846453894262649E-002, + dn: 6.1629758220391547E-032, + dn1: 1.1203288675083998E-002, + dn2: 8.0846453894262649E-002, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 2, + iter: 18, + sigma: 1.6978461930361441E-002, + nDiv: 382, + zOut: []float64{0.2463974850804771E+01, 0.2452784311062345E+01, 0.1274454348702788E-04, 0.6060609239813679E-05, 0.1166410336629578E+01, 0.1155204716501079E+01, 0.3724766654883956E-05, 0.3882375624867434E-05, 0.1204085798823124E+01, 0.1419979853975912E+01, 0.2271012218143261E+00, 0.1288536304732592E+00, 0.8056740422703550E+00, 0.7189222587736472E+00, 0.5330513126246473E-01, 0.5959804835594534E-01, 0.8037943538979316E+00, 0.7842891794360973E+00, 0.5129615818002433E-01, 0.1022287011292917E+00, 0.1563018888122747E+01, 0.1550258237777425E+01, 0.1006713350698832E+00, 0.6534828028921505E-01, 0.1006311377241790E+01, 0.1069941036637090E+01, 0.1401812239704283E+00, 0.2192904838448094E+00, 0.1673746889662340E+01, 0.1529098769031184E+01, 0.8584564749956700E-01, 0.6164441320989392E-01, 0.1098021846213856E+01, 0.1035735139045794E+01, 0.1056099032774466E-01, 0.1379518767882891E-01, 0.1352918635969054E+01, 0.1647959260308459E+01, 0.3200390963041470E+00, 0.3071268139247320E+00, 0.1581470773231080E+01, 0.1328568794801360E+01, 0.6542811978092533E-01, 0.6053010243026304E-01, 0.1229110747859551E+01, 0.1284508213253985E+01, 0.1271308521106110E+00, 0.2146341752620367E+00, 0.2168626705413786E+01, 0.1980815310529854E+01, 0.3802606466401751E-01, 0.1414976019284330E-01, 0.7370750004754409E+00, 0.1023440211907950E+01, 0.3117182559112661E+00, 0.1405518698344743E+00, 0.4614629804947978E+00, 0.3911019567584944E+00, 0.8139413038408401E-01, 0.3758136265851575E-01, 0.1805799067333021E+00, 0.1551841842545868E+00, 0.2338892446571373E-01, 0.2217266343062855E-01, 0.1471143614268198E+00, 0.1138202089714681E+00, 0.8179526119010886E-04, 0.5809925758690545E-04, 0.8084661071329148E-01, 0.6958524890097138E-01, 0.2173118009582292E-07, 0.3498739858072780E-08, 0.1120328867508400E-01, 0.8904308505808256E-09, 0.3751376363572422E-55, 0.3882375624867434E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 19, + ppOut: 0, + dminOut: 8.9043085058082561E-010, + desigOut: 1.7347234759768071E-018, + sigmaOut: 2.8181746216274728E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 19, + nDivOut: 402, + ttypeOut: -7, + dmin1Out: 6.9585227169791292E-002, + dmin2Out: 0.11373841371027797, + dnOut: 8.9043085058082561E-010, + dn1Out: 6.9585227169791292E-002, + dn2Out: 0.11373841371027797, + gOut: 0.0000000000000000, + tauOut: 1.1203284285913290E-002, + }, + { + i0: 1, + n0: 19, + z: []float64{0.2463974850804771E+01, 0.2452784311062345E+01, 0.1274454348702788E-04, 0.6060609239813679E-05, 0.1166410336629578E+01, 0.1155204716501079E+01, 0.3724766654883956E-05, 0.3882375624867434E-05, 0.1204085798823124E+01, 0.1419979853975912E+01, 0.2271012218143261E+00, 0.1288536304732592E+00, 0.8056740422703550E+00, 0.7189222587736472E+00, 0.5330513126246473E-01, 0.5959804835594534E-01, 0.8037943538979316E+00, 0.7842891794360973E+00, 0.5129615818002433E-01, 0.1022287011292917E+00, 0.1563018888122747E+01, 0.1550258237777425E+01, 0.1006713350698832E+00, 0.6534828028921505E-01, 0.1006311377241790E+01, 0.1069941036637090E+01, 0.1401812239704283E+00, 0.2192904838448094E+00, 0.1673746889662340E+01, 0.1529098769031184E+01, 0.8584564749956700E-01, 0.6164441320989392E-01, 0.1098021846213856E+01, 0.1035735139045794E+01, 0.1056099032774466E-01, 0.1379518767882891E-01, 0.1352918635969054E+01, 0.1647959260308459E+01, 0.3200390963041470E+00, 0.3071268139247320E+00, 0.1581470773231080E+01, 0.1328568794801360E+01, 0.6542811978092533E-01, 0.6053010243026304E-01, 0.1229110747859551E+01, 0.1284508213253985E+01, 0.1271308521106110E+00, 0.2146341752620367E+00, 0.2168626705413786E+01, 0.1980815310529854E+01, 0.3802606466401751E-01, 0.1414976019284330E-01, 0.7370750004754409E+00, 0.1023440211907950E+01, 0.3117182559112661E+00, 0.1405518698344743E+00, 0.4614629804947978E+00, 0.3911019567584944E+00, 0.8139413038408401E-01, 0.3758136265851575E-01, 0.1805799067333021E+00, 0.1551841842545868E+00, 0.2338892446571373E-01, 0.2217266343062855E-01, 0.1471143614268198E+00, 0.1138202089714681E+00, 0.8179526119010886E-04, 0.5809925758690545E-04, 0.8084661071329148E-01, 0.6958524890097138E-01, 0.2173118009582292E-07, 0.3498739858072780E-08, 0.1120328867508400E-01, 0.8904308505808256E-09, 0.3751376363572422E-55, 0.3882375624867434E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 8.9043085058082561E-010, + desig: 1.7347234759768071E-018, + qmax: 2.4715692224139039, + ttype: -7, + dmin1: 6.9585227169791292E-002, + dmin2: 0.11373841371027797, + dn: 8.9043085058082561E-010, + dn1: 6.9585227169791292E-002, + dn2: 0.11373841371027797, + g: 0.0000000000000000, + tau: 1.1203284285913290E-002, + nFail: 2, + iter: 19, + sigma: 2.8181746216274728E-002, + nDiv: 402, + zOut: []float64{0.2452790370781154E+01, 0.2452784311062345E+01, 0.2854399814229969E-05, 0.6060609239813679E-05, 0.1155205743586459E+01, 0.1155204716501079E+01, 0.4772219324121025E-05, 0.3882375624867434E-05, 0.1548828711339416E+01, 0.1419979853975912E+01, 0.5981019230390531E-01, 0.1288536304732592E+00, 0.7187101139352565E+00, 0.7189222587736472E+00, 0.6503610222645050E-01, 0.5959804835594534E-01, 0.8214817774485077E+00, 0.7842891794360973E+00, 0.1929207566298143E+00, 0.1022287011292917E+00, 0.1422685760546395E+01, 0.1550258237777425E+01, 0.4914564318703864E-01, 0.6534828028921505E-01, 0.1240085876404429E+01, 0.1069941036637090E+01, 0.2703980549150243E+00, 0.2192904838448094E+00, 0.1320345126435623E+01, 0.1529098769031184E+01, 0.4835651195207321E-01, 0.6164441320989392E-01, 0.1001173813882118E+01, 0.1035735139045794E+01, 0.2270725319399537E-01, 0.1379518767882891E-01, 0.1932378820148765E+01, 0.1647959260308459E+01, 0.2111589595024383E+00, 0.3071268139247320E+00, 0.1177939936838754E+01, 0.1328568794801360E+01, 0.6600626338337756E-01, 0.6053010243026304E-01, 0.1433136124242214E+01, 0.1284508213253985E+01, 0.2966575563411978E+00, 0.2146341752620367E+00, 0.1698307513491068E+01, 0.1980815310529854E+01, 0.8526979628348903E-02, 0.1414976019284330E-01, 0.1155465101223645E+01, 0.1023440211907950E+01, 0.4757401262929915E-01, 0.1405518698344743E+00, 0.3811093058972801E+00, 0.3911019567584944E+00, 0.1530278326215801E-01, 0.3758136265851575E-01, 0.1620540635326265E+00, 0.1551841842545868E+00, 0.1557318051836492E-01, 0.2217266343062855E-01, 0.9830512682025924E-01, 0.1138202089714681E+00, 0.4112553872737890E-04, 0.5809925758690545E-04, 0.6954412597055305E-01, 0.6958524890097138E-01, 0.4479725446695418E-16, 0.3498739858072780E-08, 0.1396210563637444E-18, 0.8904308505808256E-09, 0.2854399814229969E-05, 0.3882375624867434E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 19, + ppOut: 1, + dminOut: 1.3962105636374437E-019, + desigOut: -1.5687885635568321E-018, + sigmaOut: 2.8181747106705537E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 20, + nDivOut: 422, + ttypeOut: -2, + dmin1Out: 6.9544122471813200E-002, + dmin2Out: 9.8247027562672340E-002, + dnOut: 1.3962105636374437E-019, + dn1Out: 6.9544122471813200E-002, + dn2Out: 9.8247027562672340E-002, + gOut: 0.0000000000000000, + tauOut: 8.9043080564395014E-010, + }, + { + i0: 1, + n0: 19, + z: []float64{0.2452790370781154E+01, 0.2452784311062345E+01, 0.2854399814229969E-05, 0.6060609239813679E-05, 0.1155205743586459E+01, 0.1155204716501079E+01, 0.4772219324121025E-05, 0.3882375624867434E-05, 0.1548828711339416E+01, 0.1419979853975912E+01, 0.5981019230390531E-01, 0.1288536304732592E+00, 0.7187101139352565E+00, 0.7189222587736472E+00, 0.6503610222645050E-01, 0.5959804835594534E-01, 0.8214817774485077E+00, 0.7842891794360973E+00, 0.1929207566298143E+00, 0.1022287011292917E+00, 0.1422685760546395E+01, 0.1550258237777425E+01, 0.4914564318703864E-01, 0.6534828028921505E-01, 0.1240085876404429E+01, 0.1069941036637090E+01, 0.2703980549150243E+00, 0.2192904838448094E+00, 0.1320345126435623E+01, 0.1529098769031184E+01, 0.4835651195207321E-01, 0.6164441320989392E-01, 0.1001173813882118E+01, 0.1035735139045794E+01, 0.2270725319399537E-01, 0.1379518767882891E-01, 0.1932378820148765E+01, 0.1647959260308459E+01, 0.2111589595024383E+00, 0.3071268139247320E+00, 0.1177939936838754E+01, 0.1328568794801360E+01, 0.6600626338337756E-01, 0.6053010243026304E-01, 0.1433136124242214E+01, 0.1284508213253985E+01, 0.2966575563411978E+00, 0.2146341752620367E+00, 0.1698307513491068E+01, 0.1980815310529854E+01, 0.8526979628348903E-02, 0.1414976019284330E-01, 0.1155465101223645E+01, 0.1023440211907950E+01, 0.4757401262929915E-01, 0.1405518698344743E+00, 0.3811093058972801E+00, 0.3911019567584944E+00, 0.1530278326215801E-01, 0.3758136265851575E-01, 0.1620540635326265E+00, 0.1551841842545868E+00, 0.1557318051836492E-01, 0.2217266343062855E-01, 0.9830512682025924E-01, 0.1138202089714681E+00, 0.4112553872737890E-04, 0.5809925758690545E-04, 0.6954412597055305E-01, 0.6958524890097138E-01, 0.4479725446695418E-16, 0.3498739858072780E-08, 0.1396210563637444E-18, 0.8904308505808256E-09, 0.2854399814229969E-05, 0.3882375624867434E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 1.3962105636374437E-019, + desig: -1.5687885635568321E-018, + qmax: 2.4715692224139039, + ttype: -2, + dmin1: 6.9544122471813200E-002, + dmin2: 9.8247027562672340E-002, + dn: 1.3962105636374437E-019, + dn1: 6.9544122471813200E-002, + dn2: 9.8247027562672340E-002, + g: 0.0000000000000000, + tau: 8.9043080564395014E-010, + nFail: 2, + iter: 20, + sigma: 2.8181747106705537E-002, + nDiv: 422, + zOut: []float64{0.2452790370781154E+01, 0.2452793225180968E+01, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1155205743586459E+01, 0.1155209171453138E+01, 0.4772219324121025E-05, 0.6398278760815103E-05, 0.1548828711339416E+01, 0.1608632505364561E+01, 0.5981019230390531E-01, 0.2672219415054498E-01, 0.7187101139352565E+00, 0.7570240220111620E+00, 0.6503610222645050E-01, 0.7057368234283014E-01, 0.8214817774485077E+00, 0.9438288517354918E+00, 0.1929207566298143E+00, 0.2908001941945216E+00, 0.1422685760546395E+01, 0.1181031209538913E+01, 0.4914564318703864E-01, 0.5160305461093759E-01, 0.1240085876404429E+01, 0.1458880876708516E+01, 0.2703980549150243E+00, 0.2447209773632920E+00, 0.1320345126435623E+01, 0.1123980661024405E+01, 0.4835651195207321E-01, 0.4307304847484577E-01, 0.1001173813882118E+01, 0.9808080186012680E+00, 0.2270725319399537E-01, 0.4473761868138884E-01, 0.1932378820148765E+01, 0.2098800160969815E+01, 0.2111589595024383E+00, 0.1185117935689049E+00, 0.1177939936838754E+01, 0.1125434406653226E+01, 0.6600626338337756E-01, 0.8405284210411720E-01, 0.1433136124242214E+01, 0.1645740838479294E+01, 0.2966575563411978E+00, 0.3061331074057168E+00, 0.1698307513491068E+01, 0.1400701385713701E+01, 0.8526979628348903E-02, 0.7034066989504621E-02, 0.1155465101223645E+01, 0.1196005046863439E+01, 0.4757401262929915E-01, 0.1515955052150448E-01, 0.3811093058972801E+00, 0.3812525386379337E+00, 0.1530278326215801E-01, 0.6504555274179689E-02, 0.1620540635326265E+00, 0.1711226887768117E+00, 0.1557318051836492E-01, 0.8946350111698947E-02, 0.9830512682025924E-01, 0.8939990224728768E-01, 0.4112553872737890E-04, 0.3199152990069927E-04, 0.6954412597055305E-01, 0.6951213444065239E-01, 0.4479725446695418E-16, 0.8997910999570377E-34, 0.1396210563637444E-18, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 19, + ppOut: 0, + dminOut: 1.3962105636374430E-019, + desigOut: -1.5687885635568321E-018, + sigmaOut: 2.8181747106705537E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 21, + nDivOut: 442, + ttypeOut: -2, + dmin1Out: 6.9512134440652351E-002, + dmin2Out: 8.9358776708560295E-002, + dnOut: 1.3962105636374430E-019, + dn1Out: 6.9512134440652351E-002, + dn2Out: 8.9358776708560295E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 19, + z: []float64{0.2452790370781154E+01, 0.2452793225180968E+01, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1155205743586459E+01, 0.1155209171453138E+01, 0.4772219324121025E-05, 0.6398278760815103E-05, 0.1548828711339416E+01, 0.1608632505364561E+01, 0.5981019230390531E-01, 0.2672219415054498E-01, 0.7187101139352565E+00, 0.7570240220111620E+00, 0.6503610222645050E-01, 0.7057368234283014E-01, 0.8214817774485077E+00, 0.9438288517354918E+00, 0.1929207566298143E+00, 0.2908001941945216E+00, 0.1422685760546395E+01, 0.1181031209538913E+01, 0.4914564318703864E-01, 0.5160305461093759E-01, 0.1240085876404429E+01, 0.1458880876708516E+01, 0.2703980549150243E+00, 0.2447209773632920E+00, 0.1320345126435623E+01, 0.1123980661024405E+01, 0.4835651195207321E-01, 0.4307304847484577E-01, 0.1001173813882118E+01, 0.9808080186012680E+00, 0.2270725319399537E-01, 0.4473761868138884E-01, 0.1932378820148765E+01, 0.2098800160969815E+01, 0.2111589595024383E+00, 0.1185117935689049E+00, 0.1177939936838754E+01, 0.1125434406653226E+01, 0.6600626338337756E-01, 0.8405284210411720E-01, 0.1433136124242214E+01, 0.1645740838479294E+01, 0.2966575563411978E+00, 0.3061331074057168E+00, 0.1698307513491068E+01, 0.1400701385713701E+01, 0.8526979628348903E-02, 0.7034066989504621E-02, 0.1155465101223645E+01, 0.1196005046863439E+01, 0.4757401262929915E-01, 0.1515955052150448E-01, 0.3811093058972801E+00, 0.3812525386379337E+00, 0.1530278326215801E-01, 0.6504555274179689E-02, 0.1620540635326265E+00, 0.1711226887768117E+00, 0.1557318051836492E-01, 0.8946350111698947E-02, 0.9830512682025924E-01, 0.8939990224728768E-01, 0.4112553872737890E-04, 0.3199152990069927E-04, 0.6954412597055305E-01, 0.6951213444065239E-01, 0.4479725446695418E-16, 0.8997910999570377E-34, 0.1396210563637444E-18, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 1.3962105636374430E-019, + desig: -1.5687885635568321E-018, + qmax: 2.4715692224139039, + ttype: -2, + dmin1: 6.9512134440652351E-002, + dmin2: 8.9358776708560295E-002, + dn: 1.3962105636374430E-019, + dn1: 6.9512134440652351E-002, + dn2: 8.9358776708560295E-002, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 2, + iter: 21, + sigma: 2.8181747106705537E-002, + nDiv: 442, + zOut: []float64{0.2384705997428018E+01, 0.2452793225180968E+01, 0.6512368848977837E-06, 0.1344352644992036E-05, 0.1087126346389419E+01, 0.1155209171453138E+01, 0.9467601652019932E-05, 0.6398278760815103E-05, 0.1567256659807859E+01, 0.1608632505364561E+01, 0.1290748567965171E-01, 0.2672219415054498E-01, 0.7466016465687454E+00, 0.7570240220111620E+00, 0.8921689079377818E-01, 0.7057368234283014E-01, 0.1077323583030640E+01, 0.9438288517354918E+00, 0.3187938243378626E+00, 0.2908001941945216E+00, 0.8457518677063927E+00, 0.1181031209538913E+01, 0.8901276181133644E-01, 0.5160305461093759E-01, 0.1546500520154876E+01, 0.1458880876708516E+01, 0.1778606876095877E+00, 0.2447209773632920E+00, 0.9211044497840675E+00, 0.1123980661024405E+01, 0.4586493023634136E-01, 0.4307304847484577E-01, 0.9115921349407204E+00, 0.9808080186012680E+00, 0.1030014605117353E+00, 0.4473761868138884E-01, 0.2046221921921390E+01, 0.2098800160969815E+01, 0.6518220171905387E-01, 0.1185117935689049E+00, 0.1076216474932694E+01, 0.1125434406653226E+01, 0.1285328723941422E+00, 0.8405284210411720E-01, 0.1755252501385274E+01, 0.1645740838479294E+01, 0.2442959445536252E+00, 0.3061331074057168E+00, 0.1095350936043985E+01, 0.1400701385713701E+01, 0.7680442260639305E-02, 0.7034066989504621E-02, 0.1135395583018709E+01, 0.1196005046863439E+01, 0.5090399511302622E-02, 0.1515955052150448E-01, 0.3145781222952156E+00, 0.3812525386379337E+00, 0.3538316586334169E-02, 0.6504555274179689E-02, 0.1084421501965814E+00, 0.1711226887768117E+00, 0.7375387005938499E-02, 0.8946350111698947E-02, 0.1396793466565477E-01, 0.8939990224728768E-01, 0.1592074691534444E-03, 0.3199152990069927E-04, 0.1264354865903830E-02, 0.6951213444065239E-01, 0.6512368848977837E-06, 0.8997910999570377E-34, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 18, + ppOut: 1, + dminOut: 1.2643548659038301E-003, + desigOut: -5.0382355155104463E-018, + sigmaOut: 9.6270319212300656E-002, + qmaxOut: 2.4715692224139039, + nFailOut: 2, + iterOut: 22, + nDivOut: 461, + ttypeOut: -8, + dmin1Out: 1.3935943135754067E-002, + dmin2Out: 9.9495800084882416E-002, + dnOut: 1.2643548659038301E-003, + dn1Out: 1.3935943135754067E-002, + dn2Out: 9.9495800084882416E-002, + gOut: 0.0000000000000000, + tauOut: 6.8088572105595116E-002, + }, + { + i0: 1, + n0: 18, + z: []float64{0.2384705997428018E+01, 0.2452793225180968E+01, 0.6512368848977837E-06, 0.1344352644992036E-05, 0.1087126346389419E+01, 0.1155209171453138E+01, 0.9467601652019932E-05, 0.6398278760815103E-05, 0.1567256659807859E+01, 0.1608632505364561E+01, 0.1290748567965171E-01, 0.2672219415054498E-01, 0.7466016465687454E+00, 0.7570240220111620E+00, 0.8921689079377818E-01, 0.7057368234283014E-01, 0.1077323583030640E+01, 0.9438288517354918E+00, 0.3187938243378626E+00, 0.2908001941945216E+00, 0.8457518677063927E+00, 0.1181031209538913E+01, 0.8901276181133644E-01, 0.5160305461093759E-01, 0.1546500520154876E+01, 0.1458880876708516E+01, 0.1778606876095877E+00, 0.2447209773632920E+00, 0.9211044497840675E+00, 0.1123980661024405E+01, 0.4586493023634136E-01, 0.4307304847484577E-01, 0.9115921349407204E+00, 0.9808080186012680E+00, 0.1030014605117353E+00, 0.4473761868138884E-01, 0.2046221921921390E+01, 0.2098800160969815E+01, 0.6518220171905387E-01, 0.1185117935689049E+00, 0.1076216474932694E+01, 0.1125434406653226E+01, 0.1285328723941422E+00, 0.8405284210411720E-01, 0.1755252501385274E+01, 0.1645740838479294E+01, 0.2442959445536252E+00, 0.3061331074057168E+00, 0.1095350936043985E+01, 0.1400701385713701E+01, 0.7680442260639305E-02, 0.7034066989504621E-02, 0.1135395583018709E+01, 0.1196005046863439E+01, 0.5090399511302622E-02, 0.1515955052150448E-01, 0.3145781222952156E+00, 0.3812525386379337E+00, 0.3538316586334169E-02, 0.6504555274179689E-02, 0.1084421501965814E+00, 0.1711226887768117E+00, 0.7375387005938499E-02, 0.8946350111698947E-02, 0.1396793466565477E-01, 0.8939990224728768E-01, 0.1592074691534444E-03, 0.3199152990069927E-04, 0.1264354865903830E-02, 0.6951213444065239E-01, 0.6512368848977837E-06, 0.1344352644992036E-05, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 1.2643548659038301E-003, + desig: -5.0382355155104463E-018, + qmax: 2.3847059974280183, + ttype: -8, + dmin1: 1.3935943135754067E-002, + dmin2: 9.9495800084882416E-002, + dn: 1.2643548659038301E-003, + dn1: 1.3935943135754067E-002, + dn2: 9.9495800084882416E-002, + g: 0.0000000000000000, + tau: 6.8088572105595116E-002, + nFail: 2, + iter: 22, + sigma: 9.6270319212300656E-002, + nDiv: 461, + zOut: []float64{0.2384705997428018E+01, 0.2383460331210544E+01, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.1087126346389419E+01, 0.1085889199499347E+01, 0.9467601652019932E-05, 0.1366452649899944E-04, 0.1567256659807859E+01, 0.1578904163506652E+01, 0.1290748567965171E-01, 0.6103442048115082E-02, 0.7466016465687454E+00, 0.8284687778600495E+00, 0.8921689079377818E-01, 0.1160157908485996E+00, 0.1077323583030640E+01, 0.1278855299065544E+01, 0.3187938243378626E+00, 0.2108295383723412E+00, 0.8457518677063927E+00, 0.7226887736910288E+00, 0.8901276181133644E-01, 0.1904807262171572E+00, 0.1546500520154876E+01, 0.1532634164092948E+01, 0.1778606876095877E+00, 0.1068932656188067E+00, 0.9211044497840675E+00, 0.8588297969472432E+00, 0.4586493023634136E-01, 0.4868264913684867E-01, 0.9115921349407204E+00, 0.9646646288612479E+00, 0.1030014605117353E+00, 0.2184840619043245E+00, 0.2046221921921390E+01, 0.1891673744281760E+01, 0.6518220171905387E-01, 0.3708364593761750E-01, 0.1076216474932694E+01, 0.1166419383934860E+01, 0.1285328723941422E+00, 0.1934189785315259E+00, 0.1755252501385274E+01, 0.1804883149953014E+01, 0.2442959445536252E+00, 0.1482587897978486E+00, 0.1095350936043985E+01, 0.9535262710524167E+00, 0.7680442260639305E-02, 0.9145359161143373E-02, 0.1135395583018709E+01, 0.1130094305914509E+01, 0.5090399511302622E-02, 0.1416986451145964E-02, 0.3145781222952156E+00, 0.3154531349760448E+00, 0.3538316586334169E-02, 0.1216353924418735E-02, 0.1084421501965814E+00, 0.1133548658237420E+00, 0.7375387005938499E-02, 0.9088178357782586E-03, 0.1396793466565477E-01, 0.1197200684467082E-01, 0.1592074691534444E-03, 0.1681378409852773E-04, 0.1264354865903830E-02, 0.1223627446170173E-05, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 18, + ppOut: 0, + dminOut: 1.2236274461701734E-006, + desigOut: -3.2526065174565133E-018, + sigmaOut: 9.7516636666659787E-002, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 23, + nDivOut: 480, + ttypeOut: -2, + dmin1Out: 1.1812799375517376E-002, + dmin2Out: 0.10597947881780349, + dnOut: 1.2236274461701734E-006, + dn1Out: 1.1812799375517376E-002, + dn2Out: 0.10597947881780349, + gOut: 0.0000000000000000, + tauOut: 1.2463174543591322E-003, + }, + { + i0: 1, + n0: 18, + z: []float64{0.2384705997428018E+01, 0.2383460331210544E+01, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.1087126346389419E+01, 0.1085889199499347E+01, 0.9467601652019932E-05, 0.1366452649899944E-04, 0.1567256659807859E+01, 0.1578904163506652E+01, 0.1290748567965171E-01, 0.6103442048115082E-02, 0.7466016465687454E+00, 0.8284687778600495E+00, 0.8921689079377818E-01, 0.1160157908485996E+00, 0.1077323583030640E+01, 0.1278855299065544E+01, 0.3187938243378626E+00, 0.2108295383723412E+00, 0.8457518677063927E+00, 0.7226887736910288E+00, 0.8901276181133644E-01, 0.1904807262171572E+00, 0.1546500520154876E+01, 0.1532634164092948E+01, 0.1778606876095877E+00, 0.1068932656188067E+00, 0.9211044497840675E+00, 0.8588297969472432E+00, 0.4586493023634136E-01, 0.4868264913684867E-01, 0.9115921349407204E+00, 0.9646646288612479E+00, 0.1030014605117353E+00, 0.2184840619043245E+00, 0.2046221921921390E+01, 0.1891673744281760E+01, 0.6518220171905387E-01, 0.3708364593761750E-01, 0.1076216474932694E+01, 0.1166419383934860E+01, 0.1285328723941422E+00, 0.1934189785315259E+00, 0.1755252501385274E+01, 0.1804883149953014E+01, 0.2442959445536252E+00, 0.1482587897978486E+00, 0.1095350936043985E+01, 0.9535262710524167E+00, 0.7680442260639305E-02, 0.9145359161143373E-02, 0.1135395583018709E+01, 0.1130094305914509E+01, 0.5090399511302622E-02, 0.1416986451145964E-02, 0.3145781222952156E+00, 0.3154531349760448E+00, 0.3538316586334169E-02, 0.1216353924418735E-02, 0.1084421501965814E+00, 0.1133548658237420E+00, 0.7375387005938499E-02, 0.9088178357782586E-03, 0.1396793466565477E-01, 0.1197200684467082E-01, 0.1592074691534444E-03, 0.1681378409852773E-04, 0.1264354865903830E-02, 0.1223627446170173E-05, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 1.2236274461701734E-006, + desig: -3.2526065174565133E-018, + qmax: 2.3847059974280183, + ttype: -2, + dmin1: 1.1812799375517376E-002, + dmin2: 0.10597947881780349, + dn: 1.2236274461701734E-006, + dn1: 1.1812799375517376E-002, + dn2: 0.10597947881780349, + g: 0.0000000000000000, + tau: 1.2463174543591322E-003, + nFail: 2, + iter: 23, + sigma: 9.7516636666659787E-002, + nDiv: 480, + zOut: []float64{0.2383459406360114E+01, 0.2383460331210544E+01, 0.1353283656358167E-06, 0.2970373645586866E-06, 0.1085901506809686E+01, 0.1085889199499347E+01, 0.1986826396898849E-04, 0.1366452649899944E-04, 0.1584986515403004E+01, 0.1578904163506652E+01, 0.3190255011763210E-02, 0.6103442048115082E-02, 0.9412930918090910E+00, 0.8284687778600495E+00, 0.1576208411525267E+00, 0.1160157908485996E+00, 0.1332062774397564E+01, 0.1278855299065544E+01, 0.1143821023097510E+00, 0.2108295383723412E+00, 0.7987861757106404E+00, 0.7226887736910288E+00, 0.3654761154847582E+00, 0.1904807262171572E+00, 0.1274050092339202E+01, 0.1532634164092948E+01, 0.7205613198290631E-01, 0.1068932656188067E+00, 0.8354550922133908E+00, 0.8588297969472432E+00, 0.5621179414582513E-01, 0.4868264913684867E-01, 0.1126935674731953E+01, 0.9646646288612479E+00, 0.3667472533840468E+00, 0.2184840619043245E+00, 0.1562008914947536E+01, 0.1891673744281760E+01, 0.2769195683500124E-01, 0.3708364593761750E-01, 0.1332145183743590E+01, 0.1166419383934860E+01, 0.2620575140703801E+00, 0.1934189785315259E+00, 0.1691083203792688E+01, 0.1804883149953014E+01, 0.8359650824372877E-01, 0.1482587897978486E+00, 0.8790739000820365E+00, 0.9535262710524167E+00, 0.1175682535061811E-01, 0.9145359161143373E-02, 0.1119753245127243E+01, 0.1130094305914509E+01, 0.3991886785572840E-03, 0.1416986451145964E-02, 0.3162690783341116E+00, 0.3154531349760448E+00, 0.4359567385560517E-03, 0.1216353924418735E-02, 0.1138265050331695E+00, 0.1133548658237420E+00, 0.9558734450579545E-04, 0.9088178357782586E-03, 0.1189201139646886E-01, 0.1197200684467082E-01, 0.1730052806966466E-08, 0.1681378409852773E-04, 0.9598672791582074E-11, 0.1223627446170173E-05, 0.1353283656358167E-06, 0.2970373645586866E-06, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 18, + ppOut: 1, + dminOut: 9.5986727915820745E-012, + desigOut: 6.4755668817591261E-018, + sigmaOut: 9.7517858554454467E-002, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 24, + nDivOut: 499, + ttypeOut: -2, + dmin1Out: 1.1875197612370336E-002, + dmin2Out: 0.11291768719739126, + dnOut: 9.5986727915820745E-012, + dn1Out: 1.1875197612370336E-002, + dn2Out: 0.11291768719739126, + gOut: 0.0000000000000000, + tauOut: 1.2218877946904154E-006, + }, + { + i0: 1, + n0: 18, + z: []float64{0.2383459406360114E+01, 0.2383460331210544E+01, 0.1353283656358167E-06, 0.2970373645586866E-06, 0.1085901506809686E+01, 0.1085889199499347E+01, 0.1986826396898849E-04, 0.1366452649899944E-04, 0.1584986515403004E+01, 0.1578904163506652E+01, 0.3190255011763210E-02, 0.6103442048115082E-02, 0.9412930918090910E+00, 0.8284687778600495E+00, 0.1576208411525267E+00, 0.1160157908485996E+00, 0.1332062774397564E+01, 0.1278855299065544E+01, 0.1143821023097510E+00, 0.2108295383723412E+00, 0.7987861757106404E+00, 0.7226887736910288E+00, 0.3654761154847582E+00, 0.1904807262171572E+00, 0.1274050092339202E+01, 0.1532634164092948E+01, 0.7205613198290631E-01, 0.1068932656188067E+00, 0.8354550922133908E+00, 0.8588297969472432E+00, 0.5621179414582513E-01, 0.4868264913684867E-01, 0.1126935674731953E+01, 0.9646646288612479E+00, 0.3667472533840468E+00, 0.2184840619043245E+00, 0.1562008914947536E+01, 0.1891673744281760E+01, 0.2769195683500124E-01, 0.3708364593761750E-01, 0.1332145183743590E+01, 0.1166419383934860E+01, 0.2620575140703801E+00, 0.1934189785315259E+00, 0.1691083203792688E+01, 0.1804883149953014E+01, 0.8359650824372877E-01, 0.1482587897978486E+00, 0.8790739000820365E+00, 0.9535262710524167E+00, 0.1175682535061811E-01, 0.9145359161143373E-02, 0.1119753245127243E+01, 0.1130094305914509E+01, 0.3991886785572840E-03, 0.1416986451145964E-02, 0.3162690783341116E+00, 0.3154531349760448E+00, 0.4359567385560517E-03, 0.1216353924418735E-02, 0.1138265050331695E+00, 0.1133548658237420E+00, 0.9558734450579545E-04, 0.9088178357782586E-03, 0.1189201139646886E-01, 0.1197200684467082E-01, 0.1730052806966466E-08, 0.1681378409852773E-04, 0.9598672791582074E-11, 0.1223627446170173E-05, 0.1353283656358167E-06, 0.2970373645586866E-06, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 9.5986727915820745E-012, + desig: 6.4755668817591261E-018, + qmax: 2.3847059974280183, + ttype: -2, + dmin1: 1.1875197612370336E-002, + dmin2: 0.11291768719739126, + dn: 9.5986727915820745E-012, + dn1: 1.1875197612370336E-002, + dn2: 0.11291768719739126, + g: 0.0000000000000000, + tau: 1.2218877946904154E-006, + nFail: 2, + iter: 24, + sigma: 9.7517858554454467E-002, + nDiv: 499, + zOut: []float64{0.2383459406360114E+01, 0.2383459541678881E+01, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.1085901506809686E+01, 0.1085921313408604E+01, 0.1986826396898849E-04, 0.2899927470478232E-04, 0.1584986515403004E+01, 0.1588147771130463E+01, 0.3190255011763210E-02, 0.1890859942802736E-02, 0.9412930918090910E+00, 0.1097023073009216E+01, 0.1576208411525267E+00, 0.1913914667196325E+00, 0.1332062774397564E+01, 0.1255053409978084E+01, 0.1143821023097510E+00, 0.7279916643176543E-01, 0.7987861757106404E+00, 0.1091463124754034E+01, 0.3654761154847582E+00, 0.4266153094141972E+00, 0.1274050092339202E+01, 0.9194909148983121E+00, 0.7205613198290631E-01, 0.6547064404326042E-01, 0.8354550922133908E+00, 0.8261962423063568E+00, 0.5621179414582513E-01, 0.7667315937770838E-01, 0.1126935674731953E+01, 0.1417009768728692E+01, 0.3667472533840468E+00, 0.4042756034295816E+00, 0.1562008914947536E+01, 0.1185425268343357E+01, 0.2769195683500124E-01, 0.3111938635974581E-01, 0.1332145183743590E+01, 0.1563083311444625E+01, 0.2620575140703801E+00, 0.2835172362390010E+00, 0.1691083203792688E+01, 0.1491162475787817E+01, 0.8359650824372877E-01, 0.4928202642453804E-01, 0.8790739000820365E+00, 0.8415486989985177E+00, 0.1175682535061811E-01, 0.1564347179719430E-01, 0.1119753245127243E+01, 0.1104508961999007E+01, 0.3991886785572840E-03, 0.1143051254380294E-03, 0.3162690783341116E+00, 0.3165907299376309E+00, 0.4359567385560517E-03, 0.1567431614478116E-03, 0.1138265050331695E+00, 0.1137653492066288E+00, 0.9558734450579545E-04, 0.9991845479738400E-05, 0.1189201139646886E-01, 0.1188202127144326E-01, 0.1730052806966466E-08, 0.1397591405272086E-17, 0.9598672791582074E-11, 0.6617412588681544E-21, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 18, + ppOut: 0, + dminOut: 6.6174125886815435E-022, + desigOut: -5.0906815225379586E-018, + sigmaOut: 9.7517858564053150E-002, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 25, + nDivOut: 518, + ttypeOut: -2, + dmin1Out: 1.1882019541390456E-002, + dmin2Out: 0.11366976186212303, + dnOut: 6.6174125886815435E-022, + dn1Out: 1.1882019541390456E-002, + dn2Out: 0.11366976186212303, + gOut: 0.0000000000000000, + tauOut: 9.5986713933289272E-012, + }, + { + i0: 1, + n0: 18, + z: []float64{0.2383459406360114E+01, 0.2383459541678881E+01, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.1085901506809686E+01, 0.1085921313408604E+01, 0.1986826396898849E-04, 0.2899927470478232E-04, 0.1584986515403004E+01, 0.1588147771130463E+01, 0.3190255011763210E-02, 0.1890859942802736E-02, 0.9412930918090910E+00, 0.1097023073009216E+01, 0.1576208411525267E+00, 0.1913914667196325E+00, 0.1332062774397564E+01, 0.1255053409978084E+01, 0.1143821023097510E+00, 0.7279916643176543E-01, 0.7987861757106404E+00, 0.1091463124754034E+01, 0.3654761154847582E+00, 0.4266153094141972E+00, 0.1274050092339202E+01, 0.9194909148983121E+00, 0.7205613198290631E-01, 0.6547064404326042E-01, 0.8354550922133908E+00, 0.8261962423063568E+00, 0.5621179414582513E-01, 0.7667315937770838E-01, 0.1126935674731953E+01, 0.1417009768728692E+01, 0.3667472533840468E+00, 0.4042756034295816E+00, 0.1562008914947536E+01, 0.1185425268343357E+01, 0.2769195683500124E-01, 0.3111938635974581E-01, 0.1332145183743590E+01, 0.1563083311444625E+01, 0.2620575140703801E+00, 0.2835172362390010E+00, 0.1691083203792688E+01, 0.1491162475787817E+01, 0.8359650824372877E-01, 0.4928202642453804E-01, 0.8790739000820365E+00, 0.8415486989985177E+00, 0.1175682535061811E-01, 0.1564347179719430E-01, 0.1119753245127243E+01, 0.1104508961999007E+01, 0.3991886785572840E-03, 0.1143051254380294E-03, 0.3162690783341116E+00, 0.3165907299376309E+00, 0.4359567385560517E-03, 0.1567431614478116E-03, 0.1138265050331695E+00, 0.1137653492066288E+00, 0.9558734450579545E-04, 0.9991845479738400E-05, 0.1189201139646886E-01, 0.1188202127144326E-01, 0.1730052806966466E-08, 0.1397591405272086E-17, 0.9598672791582074E-11, 0.6617412588681544E-21, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 6.6174125886815435E-022, + desig: -5.0906815225379586E-018, + qmax: 2.3847059974280183, + ttype: -2, + dmin1: 1.1882019541390456E-002, + dmin2: 0.11366976186212303, + dn: 6.6174125886815435E-022, + dn1: 1.1882019541390456E-002, + dn2: 0.11366976186212303, + g: 0.0000000000000000, + tau: 9.5986713933289272E-012, + nFail: 2, + iter: 25, + sigma: 9.7517858564053150E-002, + nDiv: 518, + zOut: []float64{0.2383459603334333E+01, 0.2383459541678881E+01, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.1085950284592642E+01, 0.1085921313408604E+01, 0.4240998334843304E-04, 0.2899927470478232E-04, 0.1589996221089918E+01, 0.1588147771130463E+01, 0.1304604978030436E-02, 0.1890859942802736E-02, 0.1287109934750819E+01, 0.1097023073009216E+01, 0.1866247058326724E+00, 0.1913914667196325E+00, 0.1141227870577177E+01, 0.1255053409978084E+01, 0.6962466280543776E-01, 0.7279916643176543E-01, 0.1448453771362794E+01, 0.1091463124754034E+01, 0.2708190685256155E+00, 0.4266153094141972E+00, 0.7141424904159570E+00, 0.9194909148983121E+00, 0.7574342769943966E-01, 0.6547064404326042E-01, 0.8271259739846255E+00, 0.8261962423063568E+00, 0.1313543755784947E+00, 0.7667315937770838E-01, 0.1689930996579779E+01, 0.1417009768728692E+01, 0.2835846650840220E+00, 0.4042756034295816E+00, 0.9329599896190804E+00, 0.1185425268343357E+01, 0.5213749144931325E-01, 0.3111938635974581E-01, 0.1794463056234313E+01, 0.1563083311444625E+01, 0.2355970842920850E+00, 0.2835172362390010E+00, 0.1304847417920270E+01, 0.1491162475787817E+01, 0.3178396542921673E-01, 0.4928202642453804E-01, 0.8254082053664953E+00, 0.8415486989985177E+00, 0.2093310277804656E-01, 0.1564347179719430E-01, 0.1083690164346398E+01, 0.1104508961999007E+01, 0.3339325601415243E-04, 0.1143051254380294E-03, 0.3167140798430647E+00, 0.3165907299376309E+00, 0.5630296103885627E-04, 0.1567431614478116E-03, 0.1137190380910697E+00, 0.1137653492066288E+00, 0.1044005669799533E-05, 0.9991845479738400E-05, 0.1188097726577346E-01, 0.1188202127144326E-01, 0.7784240935906335E-37, 0.1397591405272086E-17, 0.6617412588681543E-21, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 18, + ppOut: 1, + dminOut: 6.6174125886815426E-022, + desigOut: -5.0906815225379586E-018, + sigmaOut: 9.7517858564053150E-002, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 26, + nDivOut: 537, + ttypeOut: -2, + dmin1Out: 1.1880977265773463E-002, + dmin2Out: 0.11370904624558997, + dnOut: 6.6174125886815426E-022, + dn1Out: 1.1880977265773463E-002, + dn2Out: 0.11370904624558997, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 18, + z: []float64{0.2383459603334333E+01, 0.2383459541678881E+01, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.1085950284592642E+01, 0.1085921313408604E+01, 0.4240998334843304E-04, 0.2899927470478232E-04, 0.1589996221089918E+01, 0.1588147771130463E+01, 0.1304604978030436E-02, 0.1890859942802736E-02, 0.1287109934750819E+01, 0.1097023073009216E+01, 0.1866247058326724E+00, 0.1913914667196325E+00, 0.1141227870577177E+01, 0.1255053409978084E+01, 0.6962466280543776E-01, 0.7279916643176543E-01, 0.1448453771362794E+01, 0.1091463124754034E+01, 0.2708190685256155E+00, 0.4266153094141972E+00, 0.7141424904159570E+00, 0.9194909148983121E+00, 0.7574342769943966E-01, 0.6547064404326042E-01, 0.8271259739846255E+00, 0.8261962423063568E+00, 0.1313543755784947E+00, 0.7667315937770838E-01, 0.1689930996579779E+01, 0.1417009768728692E+01, 0.2835846650840220E+00, 0.4042756034295816E+00, 0.9329599896190804E+00, 0.1185425268343357E+01, 0.5213749144931325E-01, 0.3111938635974581E-01, 0.1794463056234313E+01, 0.1563083311444625E+01, 0.2355970842920850E+00, 0.2835172362390010E+00, 0.1304847417920270E+01, 0.1491162475787817E+01, 0.3178396542921673E-01, 0.4928202642453804E-01, 0.8254082053664953E+00, 0.8415486989985177E+00, 0.2093310277804656E-01, 0.1564347179719430E-01, 0.1083690164346398E+01, 0.1104508961999007E+01, 0.3339325601415243E-04, 0.1143051254380294E-03, 0.3167140798430647E+00, 0.3165907299376309E+00, 0.5630296103885627E-04, 0.1567431614478116E-03, 0.1137190380910697E+00, 0.1137653492066288E+00, 0.1044005669799533E-05, 0.9991845479738400E-05, 0.1188097726577346E-01, 0.1188202127144326E-01, 0.7784240935906335E-37, 0.1397591405272086E-17, 0.6617412588681543E-21, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 6.6174125886815426E-022, + desig: -5.0906815225379586E-018, + qmax: 2.3847059974280183, + ttype: -2, + dmin1: 1.1880977265773463E-002, + dmin2: 0.11370904624558997, + dn: 6.6174125886815426E-022, + dn1: 1.1880977265773463E-002, + dn2: 0.11370904624558997, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 2, + iter: 26, + sigma: 9.7517858564053150E-002, + nDiv: 537, + zOut: []float64{0.2383459603334333E+01, 0.2371578799269292E+01, 0.2809066689524106E-07, 0.1286276792433928E-07, 0.1085950284592642E+01, 0.1074111849557515E+01, 0.4240998334843304E-04, 0.6277904232066118E-04, 0.1589996221089918E+01, 0.1579357214869920E+01, 0.1304604978030436E-02, 0.1063198377376995E-02, 0.1287109934750819E+01, 0.1460790610050406E+01, 0.1866247058326724E+00, 0.1457986614708343E+00, 0.1141227870577177E+01, 0.1053173039756072E+01, 0.6962466280543776E-01, 0.9575644420574685E-01, 0.1448453771362794E+01, 0.1611635563526955E+01, 0.2708190685256155E+00, 0.1200044280642223E+00, 0.7141424904159570E+00, 0.6580006578954666E+00, 0.7574342769943966E-01, 0.9521169265880262E-01, 0.8271259739846255E+00, 0.8513878247486099E+00, 0.1313543755784947E+00, 0.2607270439790754E+00, 0.1689930996579779E+01, 0.1700907785529018E+01, 0.2835846650840220E+00, 0.1555482010511415E+00, 0.9329599896190804E+00, 0.8176684478615445E+00, 0.5213749144931325E-01, 0.1144214412274440E+00, 0.1794463056234313E+01, 0.1903757867143247E+01, 0.2355970842920850E+00, 0.1614796988702029E+00, 0.1304847417920270E+01, 0.1163270852323576E+01, 0.3178396542921673E-01, 0.2255256874351997E-01, 0.8254082053664953E+00, 0.8119079072453143E+00, 0.2093310277804656E-01, 0.2794035799797570E-01, 0.1083690164346398E+01, 0.1043902367448729E+01, 0.3339325601415243E-04, 0.1013132519024162E-04, 0.3167140798430647E+00, 0.3048794193232055E+00, 0.5630296103885627E-04, 0.2100082250625822E-04, 0.1137190380910697E+00, 0.1018182491185255E+00, 0.1044005669799533E-05, 0.1218230301111122E-06, 0.1188097726577346E-01, 0.2328703557243073E-07, 0.7784240935906335E-37, 0.1286276792433928E-07, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 17, + ppOut: 0, + dminOut: 2.3287035572430725E-008, + desigOut: 1.7347234759768071E-018, + sigmaOut: 0.10939869071976092, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 27, + nDivOut: 555, + ttypeOut: -7, + dmin1Out: 0.10181720511285566, + dmin2Out: 0.30482311636216664, + dnOut: 2.3287035572430725E-008, + dn1Out: 0.10181720511285566, + dn2Out: 0.30482311636216664, + gOut: 0.0000000000000000, + tauOut: 1.1880832155707781E-002, + }, + { + i0: 1, + n0: 17, + z: []float64{0.2383459603334333E+01, 0.2371578799269292E+01, 0.2809066689524106E-07, 0.1286276792433928E-07, 0.1085950284592642E+01, 0.1074111849557515E+01, 0.4240998334843304E-04, 0.6277904232066118E-04, 0.1589996221089918E+01, 0.1579357214869920E+01, 0.1304604978030436E-02, 0.1063198377376995E-02, 0.1287109934750819E+01, 0.1460790610050406E+01, 0.1866247058326724E+00, 0.1457986614708343E+00, 0.1141227870577177E+01, 0.1053173039756072E+01, 0.6962466280543776E-01, 0.9575644420574685E-01, 0.1448453771362794E+01, 0.1611635563526955E+01, 0.2708190685256155E+00, 0.1200044280642223E+00, 0.7141424904159570E+00, 0.6580006578954666E+00, 0.7574342769943966E-01, 0.9521169265880262E-01, 0.8271259739846255E+00, 0.8513878247486099E+00, 0.1313543755784947E+00, 0.2607270439790754E+00, 0.1689930996579779E+01, 0.1700907785529018E+01, 0.2835846650840220E+00, 0.1555482010511415E+00, 0.9329599896190804E+00, 0.8176684478615445E+00, 0.5213749144931325E-01, 0.1144214412274440E+00, 0.1794463056234313E+01, 0.1903757867143247E+01, 0.2355970842920850E+00, 0.1614796988702029E+00, 0.1304847417920270E+01, 0.1163270852323576E+01, 0.3178396542921673E-01, 0.2255256874351997E-01, 0.8254082053664953E+00, 0.8119079072453143E+00, 0.2093310277804656E-01, 0.2794035799797570E-01, 0.1083690164346398E+01, 0.1043902367448729E+01, 0.3339325601415243E-04, 0.1013132519024162E-04, 0.3167140798430647E+00, 0.3048794193232055E+00, 0.5630296103885627E-04, 0.2100082250625822E-04, 0.1137190380910697E+00, 0.1018182491185255E+00, 0.1044005669799533E-05, 0.1218230301111122E-06, 0.1188097726577346E-01, 0.2328703557243073E-07, 0.7784240935906335E-37, 0.1286276792433928E-07, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 2.3287035572430725E-008, + desig: 1.7347234759768071E-018, + qmax: 2.3847059974280183, + ttype: -7, + dmin1: 0.10181720511285566, + dmin2: 0.30482311636216664, + dn: 2.3287035572430725E-008, + dn1: 0.10181720511285566, + dn2: 0.30482311636216664, + g: 0.0000000000000000, + tau: 1.1880832155707781E-002, + nFail: 2, + iter: 27, + sigma: 0.10939869071976092, + nDiv: 555, + zOut: []float64{0.2371578788845052E+01, 0.2371578799269292E+01, 0.5825676764620370E-08, 0.1286276792433928E-07, 0.1074174599487151E+01, 0.1074111849557515E+01, 0.9230392664199863E-04, 0.6277904232066118E-04, 0.1580328086033647E+01, 0.1579357214869920E+01, 0.9827770701659698E-03, 0.1063198377376995E-02, 0.1605606471164067E+01, 0.1460790610050406E+01, 0.9563440497488795E-01, 0.1457986614708343E+00, 0.1053295055699924E+01, 0.1053173039756072E+01, 0.1465159169633776E+00, 0.9575644420574685E-01, 0.1585124051340792E+01, 0.1611635563526955E+01, 0.4981502397231050E-01, 0.1200044280642223E+00, 0.7033973032949510E+00, 0.6580006578954666E+00, 0.1152436546510613E+00, 0.9521169265880262E-01, 0.9968711907896164E+00, 0.8513878247486099E+00, 0.4448645553200346E+00, 0.2607270439790754E+00, 0.1411591407973117E+01, 0.1700907785529018E+01, 0.9010174998427344E-01, 0.1555482010511415E+00, 0.8419881158177074E+00, 0.8176684478615445E+00, 0.2587099684834221E+00, 0.1144214412274440E+00, 0.1806527574243020E+01, 0.1903757867143247E+01, 0.1039810460775319E+00, 0.1614796988702029E+00, 0.1081842351702556E+01, 0.1163270852323576E+01, 0.1692539477932339E-01, 0.2255256874351997E-01, 0.8229228471769590E+00, 0.8119079072453143E+00, 0.3544318396494814E-01, 0.2794035799797570E-01, 0.1008469291521964E+01, 0.1043902367448729E+01, 0.3062892015595061E-05, 0.1013132519024162E-04, 0.3048973339666884E+00, 0.3048794193232055E+00, 0.7013072071892081E-05, 0.2100082250625822E-04, 0.1018113345824760E+00, 0.1018182491185255E+00, 0.2786425742647189E-13, 0.1218230301111122E-06, 0.2696165428114542E-17, 0.2328703557243073E-07, 0.5825676764620370E-08, 0.1286276792433928E-07, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 17, + ppOut: 1, + dminOut: 2.6961654281145418E-018, + desigOut: -3.8251180717391650E-018, + sigmaOut: 0.10939871400676864, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 28, + nDivOut: 573, + ttypeOut: -2, + dmin1Out: 0.10181121275944585, + dmin2Out: 0.30487633314418217, + dnOut: 2.6961654281145418E-018, + dn1Out: 0.10181121275944585, + dn2Out: 0.30487633314418217, + gOut: 0.0000000000000000, + tauOut: 2.3287007705477136E-008, + }, + { + i0: 1, + n0: 17, + z: []float64{0.2371578788845052E+01, 0.2371578799269292E+01, 0.5825676764620370E-08, 0.1286276792433928E-07, 0.1074174599487151E+01, 0.1074111849557515E+01, 0.9230392664199863E-04, 0.6277904232066118E-04, 0.1580328086033647E+01, 0.1579357214869920E+01, 0.9827770701659698E-03, 0.1063198377376995E-02, 0.1605606471164067E+01, 0.1460790610050406E+01, 0.9563440497488795E-01, 0.1457986614708343E+00, 0.1053295055699924E+01, 0.1053173039756072E+01, 0.1465159169633776E+00, 0.9575644420574685E-01, 0.1585124051340792E+01, 0.1611635563526955E+01, 0.4981502397231050E-01, 0.1200044280642223E+00, 0.7033973032949510E+00, 0.6580006578954666E+00, 0.1152436546510613E+00, 0.9521169265880262E-01, 0.9968711907896164E+00, 0.8513878247486099E+00, 0.4448645553200346E+00, 0.2607270439790754E+00, 0.1411591407973117E+01, 0.1700907785529018E+01, 0.9010174998427344E-01, 0.1555482010511415E+00, 0.8419881158177074E+00, 0.8176684478615445E+00, 0.2587099684834221E+00, 0.1144214412274440E+00, 0.1806527574243020E+01, 0.1903757867143247E+01, 0.1039810460775319E+00, 0.1614796988702029E+00, 0.1081842351702556E+01, 0.1163270852323576E+01, 0.1692539477932339E-01, 0.2255256874351997E-01, 0.8229228471769590E+00, 0.8119079072453143E+00, 0.3544318396494814E-01, 0.2794035799797570E-01, 0.1008469291521964E+01, 0.1043902367448729E+01, 0.3062892015595061E-05, 0.1013132519024162E-04, 0.3048973339666884E+00, 0.3048794193232055E+00, 0.7013072071892081E-05, 0.2100082250625822E-04, 0.1018113345824760E+00, 0.1018182491185255E+00, 0.2786425742647189E-13, 0.1218230301111122E-06, 0.2696165428114542E-17, 0.2328703557243073E-07, 0.5825676764620370E-08, 0.1286276792433928E-07, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 2.6961654281145418E-018, + desig: -3.8251180717391650E-018, + qmax: 2.3847059974280183, + ttype: -2, + dmin1: 0.10181121275944585, + dmin2: 0.30487633314418217, + dn: 2.6961654281145418E-018, + dn1: 0.10181121275944585, + dn2: 0.30487633314418217, + g: 0.0000000000000000, + tau: 2.3287007705477136E-008, + nFail: 2, + iter: 28, + sigma: 0.10939871400676864, + nDiv: 573, + zOut: []float64{0.2371578788845052E+01, 0.2371578794670729E+01, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.1074174599487151E+01, 0.1074266900775131E+01, 0.9230392664199863E-04, 0.1357860766428602E-03, 0.1580328086033647E+01, 0.1581175077027170E+01, 0.9827770701659698E-03, 0.9979623676695663E-03, 0.1605606471164067E+01, 0.1700242913771285E+01, 0.9563440497488795E-01, 0.5924520849284005E-01, 0.1053295055699924E+01, 0.1140565764170461E+01, 0.1465159169633776E+00, 0.2036234219705987E+00, 0.1585124051340792E+01, 0.1431315653342504E+01, 0.4981502397231050E-01, 0.2448080089382756E-01, 0.7033973032949510E+00, 0.7941601570521848E+00, 0.1152436546510613E+00, 0.1446598374682775E+00, 0.9968711907896164E+00, 0.1297075908641373E+01, 0.4448645553200346E+00, 0.4841405038964208E+00, 0.1411591407973117E+01, 0.1017552654060970E+01, 0.9010174998427344E-01, 0.7455594793877945E-01, 0.8419881158177074E+00, 0.1026142136362350E+01, 0.2587099684834221E+00, 0.4554599945126984E+00, 0.1806527574243020E+01, 0.1455048625807853E+01, 0.1039810460775319E+00, 0.7731088667813635E-01, 0.1081842351702556E+01, 0.1021456859803743E+01, 0.1692539477932339E-01, 0.1363571444815687E-01, 0.8229228471769590E+00, 0.8447303166937503E+00, 0.3544318396494814E-01, 0.4231334180394086E-01, 0.1008469291521964E+01, 0.9661590126100381E+00, 0.3062892015595061E-05, 0.9665775484099522E-06, 0.3048973339666884E+00, 0.3049033804612119E+00, 0.7013072071892081E-05, 0.2341758973227438E-05, 0.1018113345824760E+00, 0.1018089928235306E+00, 0.2786425742647189E-13, 0.7379175991216932E-30, 0.2696165428114542E-17, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 17, + ppOut: 0, + dminOut: 2.6961654281138038E-018, + desigOut: -3.8251180717391650E-018, + sigmaOut: 0.10939871400676864, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 29, + nDivOut: 591, + ttypeOut: -2, + dmin1Out: 0.10180899282350273, + dmin2Out: 0.30489636738914000, + dnOut: 2.6961654281138038E-018, + dn1Out: 0.10180899282350273, + dn2Out: 0.30489636738914000, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 17, + z: []float64{0.2371578788845052E+01, 0.2371578794670729E+01, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.1074174599487151E+01, 0.1074266900775131E+01, 0.9230392664199863E-04, 0.1357860766428602E-03, 0.1580328086033647E+01, 0.1581175077027170E+01, 0.9827770701659698E-03, 0.9979623676695663E-03, 0.1605606471164067E+01, 0.1700242913771285E+01, 0.9563440497488795E-01, 0.5924520849284005E-01, 0.1053295055699924E+01, 0.1140565764170461E+01, 0.1465159169633776E+00, 0.2036234219705987E+00, 0.1585124051340792E+01, 0.1431315653342504E+01, 0.4981502397231050E-01, 0.2448080089382756E-01, 0.7033973032949510E+00, 0.7941601570521848E+00, 0.1152436546510613E+00, 0.1446598374682775E+00, 0.9968711907896164E+00, 0.1297075908641373E+01, 0.4448645553200346E+00, 0.4841405038964208E+00, 0.1411591407973117E+01, 0.1017552654060970E+01, 0.9010174998427344E-01, 0.7455594793877945E-01, 0.8419881158177074E+00, 0.1026142136362350E+01, 0.2587099684834221E+00, 0.4554599945126984E+00, 0.1806527574243020E+01, 0.1455048625807853E+01, 0.1039810460775319E+00, 0.7731088667813635E-01, 0.1081842351702556E+01, 0.1021456859803743E+01, 0.1692539477932339E-01, 0.1363571444815687E-01, 0.8229228471769590E+00, 0.8447303166937503E+00, 0.3544318396494814E-01, 0.4231334180394086E-01, 0.1008469291521964E+01, 0.9661590126100381E+00, 0.3062892015595061E-05, 0.9665775484099522E-06, 0.3048973339666884E+00, 0.3049033804612119E+00, 0.7013072071892081E-05, 0.2341758973227438E-05, 0.1018113345824760E+00, 0.1018089928235306E+00, 0.2786425742647189E-13, 0.7379175991216932E-30, 0.2696165428114542E-17, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 2.6961654281138038E-018, + desig: -3.8251180717391650E-018, + qmax: 2.3847059974280183, + ttype: -2, + dmin1: 0.10180899282350273, + dmin2: 0.30489636738914000, + dn: 2.6961654281138038E-018, + dn1: 0.10180899282350273, + dn2: 0.30489636738914000, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 2, + iter: 29, + sigma: 0.10939871400676864, + nDiv: 591, + zOut: []float64{0.2269772292606755E+01, 0.2371578794670729E+01, 0.1248859578385863E-08, 0.2638661645752538E-08, 0.9725961809002787E+00, 0.1074266900775131E+01, 0.2207509801202943E-03, 0.1357860766428602E-03, 0.1480145783712083E+01, 0.1581175077027170E+01, 0.1146359002276934E-02, 0.9979623676695663E-03, 0.1656535258559212E+01, 0.1700242913771285E+01, 0.4079180092843103E-01, 0.5924520849284005E-01, 0.1201590880509993E+01, 0.1140565764170461E+01, 0.2425529321011353E+00, 0.2036234219705987E+00, 0.1111437017432560E+01, 0.1431315653342504E+01, 0.1749237822536809E-01, 0.2448080089382756E-01, 0.8195211115924584E+00, 0.7941601570521848E+00, 0.2289566278084960E+00, 0.1446598374682775E+00, 0.1450453280026662E+01, 0.1297075908641373E+01, 0.3396444831847066E+00, 0.4841405038964208E+00, 0.6506576141124067E+00, 0.1017552654060970E+01, 0.1175810411452473E+00, 0.7455594793877945E-01, 0.1262214585027166E+01, 0.1026142136362350E+01, 0.5250426092262996E+00, 0.4554599945126984E+00, 0.9055103985570538E+00, 0.1455048625807853E+01, 0.8721019179982008E-01, 0.7731088667813635E-01, 0.8460758777494440E+00, 0.1021456859803743E+01, 0.1361402882064932E-01, 0.1363571444815687E-01, 0.7716231249744060E+00, 0.8447303166937503E+00, 0.5298106707064092E-01, 0.4231334180394086E-01, 0.8113724074143097E+00, 0.9661590126100381E+00, 0.3632274887524200E-06, 0.9665775484099522E-06, 0.2030988542900605E+00, 0.3049033804612119E+00, 0.1173872316183806E-05, 0.2341758973227438E-05, 0.1314248578535016E-05, 0.1018089928235306E+00, 0.1248859578385863E-08, 0.7379175991216932E-30, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 16, + ppOut: 1, + dminOut: 1.3142485785350155E-006, + desigOut: 0.0000000000000000, + sigmaOut: 0.21120521870940451, + qmaxOut: 2.3847059974280183, + nFailOut: 2, + iterOut: 30, + nDivOut: 608, + ttypeOut: -7, + dmin1Out: 0.20309651253108729, + dmin2Out: 0.57610166617362735, + dnOut: 1.3142485785350155E-006, + dn1Out: 0.20309651253108729, + dn2Out: 0.81137144083676127, + gOut: 0.0000000000000000, + tauOut: 0.10180650470263587, + }, + { + i0: 1, + n0: 16, + z: []float64{0.2269772292606755E+01, 0.2371578794670729E+01, 0.1248859578385863E-08, 0.2638661645752538E-08, 0.9725961809002787E+00, 0.1074266900775131E+01, 0.2207509801202943E-03, 0.1357860766428602E-03, 0.1480145783712083E+01, 0.1581175077027170E+01, 0.1146359002276934E-02, 0.9979623676695663E-03, 0.1656535258559212E+01, 0.1700242913771285E+01, 0.4079180092843103E-01, 0.5924520849284005E-01, 0.1201590880509993E+01, 0.1140565764170461E+01, 0.2425529321011353E+00, 0.2036234219705987E+00, 0.1111437017432560E+01, 0.1431315653342504E+01, 0.1749237822536809E-01, 0.2448080089382756E-01, 0.8195211115924584E+00, 0.7941601570521848E+00, 0.2289566278084960E+00, 0.1446598374682775E+00, 0.1450453280026662E+01, 0.1297075908641373E+01, 0.3396444831847066E+00, 0.4841405038964208E+00, 0.6506576141124067E+00, 0.1017552654060970E+01, 0.1175810411452473E+00, 0.7455594793877945E-01, 0.1262214585027166E+01, 0.1026142136362350E+01, 0.5250426092262996E+00, 0.4554599945126984E+00, 0.9055103985570538E+00, 0.1455048625807853E+01, 0.8721019179982008E-01, 0.7731088667813635E-01, 0.8460758777494440E+00, 0.1021456859803743E+01, 0.1361402882064932E-01, 0.1363571444815687E-01, 0.7716231249744060E+00, 0.8447303166937503E+00, 0.5298106707064092E-01, 0.4231334180394086E-01, 0.8113724074143097E+00, 0.9661590126100381E+00, 0.3632274887524200E-06, 0.9665775484099522E-06, 0.2030988542900605E+00, 0.3049033804612119E+00, 0.1173872316183806E-05, 0.2341758973227438E-05, 0.1314248578535016E-05, 0.1018089928235306E+00, 0.1248859578385863E-08, 0.2638661645752538E-08, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 1.3142485785350155E-006, + desig: 0.0000000000000000, + qmax: 2.2697722926067549, + ttype: -7, + dmin1: 0.20309651253108729, + dmin2: 0.57610166617362735, + dn: 1.3142485785350155E-006, + dn1: 0.20309651253108729, + dn2: 0.81137144083676127, + g: 0.0000000000000000, + tau: 0.10180650470263587, + nFail: 2, + iter: 30, + sigma: 0.21120521870940451, + nDiv: 608, + zOut: []float64{0.2269772292606755E+01, 0.2269770979614632E+01, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.9725961809002787E+00, 0.9728156171042807E+00, 0.2207509801202943E-03, 0.3358741643642203E-03, 0.1480145783712083E+01, 0.1480954954309013E+01, 0.1146359002276934E-02, 0.1282269997958535E-02, 0.1656535258559212E+01, 0.1696043475248702E+01, 0.4079180092843103E-01, 0.2889964597634762E-01, 0.1201590880509993E+01, 0.1415242852393798E+01, 0.2425529321011353E+00, 0.1904848393814713E+00, 0.1111437017432560E+01, 0.9384432420354740E+00, 0.1749237822536809E-01, 0.1527569554079381E-01, 0.8195211115924584E+00, 0.1033200729619178E+01, 0.2289566278084960E+00, 0.3214195289148511E+00, 0.1450453280026662E+01, 0.1468676920055535E+01, 0.3396444831847066E+00, 0.1504703083827628E+00, 0.6506576141124067E+00, 0.6177670326339089E+00, 0.1175810411452473E+00, 0.2402402478867145E+00, 0.1262214585027166E+01, 0.1547015632125768E+01, 0.5250426092262996E+00, 0.3073217441808570E+00, 0.9055103985570538E+00, 0.6853975319350345E+00, 0.8721019179982008E-01, 0.1076549537133787E+00, 0.8460758777494440E+00, 0.7520336386157322E+00, 0.1361402882064932E-01, 0.1396865635082151E-01, 0.7716231249744060E+00, 0.8106342214532430E+00, 0.5298106707064092E-01, 0.5302931309687425E-01, 0.8113724074143097E+00, 0.7583421433039418E+00, 0.3632274887524200E-06, 0.9727942389020712E-07, 0.2030988542900605E+00, 0.2030986166419704E+00, 0.1173872316183806E-05, 0.7596112905317353E-11, 0.1314248578535016E-05, 0.8411884199182457E-17, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 16, + ppOut: 0, + dminOut: 8.4118841991824567E-018, + desigOut: 1.0739530738237274E-017, + sigmaOut: 0.21120653295038691, + qmaxOut: 2.2697722926067549, + nFailOut: 2, + iterOut: 31, + nDivOut: 625, + ttypeOut: -2, + dmin1Out: 0.20309744276965425, + dmin2Out: 0.50018599148866161, + dnOut: 8.4118841991824567E-018, + dn1Out: 0.20309744276965425, + dn2Out: 0.75834178007645303, + gOut: 0.0000000000000000, + tauOut: 1.3142409824136984E-006, + }, + { + i0: 1, + n0: 16, + z: []float64{0.2269772292606755E+01, 0.2269770979614632E+01, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.9725961809002787E+00, 0.9728156171042807E+00, 0.2207509801202943E-03, 0.3358741643642203E-03, 0.1480145783712083E+01, 0.1480954954309013E+01, 0.1146359002276934E-02, 0.1282269997958535E-02, 0.1656535258559212E+01, 0.1696043475248702E+01, 0.4079180092843103E-01, 0.2889964597634762E-01, 0.1201590880509993E+01, 0.1415242852393798E+01, 0.2425529321011353E+00, 0.1904848393814713E+00, 0.1111437017432560E+01, 0.9384432420354740E+00, 0.1749237822536809E-01, 0.1527569554079381E-01, 0.8195211115924584E+00, 0.1033200729619178E+01, 0.2289566278084960E+00, 0.3214195289148511E+00, 0.1450453280026662E+01, 0.1468676920055535E+01, 0.3396444831847066E+00, 0.1504703083827628E+00, 0.6506576141124067E+00, 0.6177670326339089E+00, 0.1175810411452473E+00, 0.2402402478867145E+00, 0.1262214585027166E+01, 0.1547015632125768E+01, 0.5250426092262996E+00, 0.3073217441808570E+00, 0.9055103985570538E+00, 0.6853975319350345E+00, 0.8721019179982008E-01, 0.1076549537133787E+00, 0.8460758777494440E+00, 0.7520336386157322E+00, 0.1361402882064932E-01, 0.1396865635082151E-01, 0.7716231249744060E+00, 0.8106342214532430E+00, 0.5298106707064092E-01, 0.5302931309687425E-01, 0.8113724074143097E+00, 0.7583421433039418E+00, 0.3632274887524200E-06, 0.9727942389020712E-07, 0.2030988542900605E+00, 0.2030986166419704E+00, 0.1173872316183806E-05, 0.7596112905317353E-11, 0.1314248578535016E-05, 0.8411884199182457E-17, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 8.4118841991824567E-018, + desig: 1.0739530738237274E-017, + qmax: 2.2697722926067549, + ttype: -2, + dmin1: 0.20309744276965425, + dmin2: 0.50018599148866161, + dn: 8.4118841991824567E-018, + dn1: 0.20309744276965425, + dn2: 0.75834178007645303, + g: 0.0000000000000000, + tau: 1.3142409824136984E-006, + nFail: 2, + iter: 31, + sigma: 0.21120653295038691, + nDiv: 625, + zOut: []float64{0.2269770980149768E+01, 0.2269770979614632E+01, 0.2293573303077261E-09, 0.5351359530665278E-09, 0.9731514910392876E+00, 0.9728156171042807E+00, 0.5111377954200868E-03, 0.3358741643642203E-03, 0.1481726086511552E+01, 0.1480954954309013E+01, 0.1467737987028945E-02, 0.1282269997958535E-02, 0.1723475383238021E+01, 0.1696043475248702E+01, 0.2373112943910766E-01, 0.2889964597634762E-01, 0.1581996562336162E+01, 0.1415242852393798E+01, 0.1129959536471923E+00, 0.1904848393814713E+00, 0.8407229839290754E+00, 0.9384432420354740E+00, 0.1877296098701645E-01, 0.1527569554079381E-01, 0.1335847297547013E+01, 0.1033200729619178E+01, 0.3533797947109679E+00, 0.3214195289148511E+00, 0.1265767433727330E+01, 0.1468676920055535E+01, 0.7343813202351114E-01, 0.1504703083827628E+00, 0.7845691484971122E+00, 0.6177670326339089E+00, 0.4737063898809231E+00, 0.2402402478867145E+00, 0.1380630986425702E+01, 0.1547015632125768E+01, 0.1525661578238559E+00, 0.3073217441808570E+00, 0.6404863278245572E+00, 0.6853975319350345E+00, 0.1264041760751794E+00, 0.1076549537133787E+00, 0.6395981188913744E+00, 0.7520336386157322E+00, 0.1770404028911661E-01, 0.1396865635082151E-01, 0.8459594942610007E+00, 0.8106342214532430E+00, 0.4753698401003136E-01, 0.5302931309687425E-01, 0.7108052565733343E+00, 0.7583421433039418E+00, 0.2779568135873871E-07, 0.9727942389020712E-07, 0.2030985888538852E+00, 0.2030986166419704E+00, 0.3146138162949754E-27, 0.7596112905317353E-11, 0.8411884198867843E-17, 0.8411884199182457E-17, 0.2293573303077261E-09, 0.5351359530665278E-09, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 16, + ppOut: 1, + dminOut: 8.4118841988678429E-018, + desigOut: 1.0739530738237274E-017, + sigmaOut: 0.21120653295038691, + qmaxOut: 2.2697722926067549, + nFailOut: 2, + iterOut: 32, + nDivOut: 642, + ttypeOut: -2, + dmin1Out: 0.20309858884628909, + dmin2Out: 0.53283137411117854, + dnOut: 8.4118841988678429E-018, + dn1Out: 0.20309858884628909, + dn2Out: 0.71080515929391042, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 16, + z: []float64{0.2269770980149768E+01, 0.2269770979614632E+01, 0.2293573303077261E-09, 0.5351359530665278E-09, 0.9731514910392876E+00, 0.9728156171042807E+00, 0.5111377954200868E-03, 0.3358741643642203E-03, 0.1481726086511552E+01, 0.1480954954309013E+01, 0.1467737987028945E-02, 0.1282269997958535E-02, 0.1723475383238021E+01, 0.1696043475248702E+01, 0.2373112943910766E-01, 0.2889964597634762E-01, 0.1581996562336162E+01, 0.1415242852393798E+01, 0.1129959536471923E+00, 0.1904848393814713E+00, 0.8407229839290754E+00, 0.9384432420354740E+00, 0.1877296098701645E-01, 0.1527569554079381E-01, 0.1335847297547013E+01, 0.1033200729619178E+01, 0.3533797947109679E+00, 0.3214195289148511E+00, 0.1265767433727330E+01, 0.1468676920055535E+01, 0.7343813202351114E-01, 0.1504703083827628E+00, 0.7845691484971122E+00, 0.6177670326339089E+00, 0.4737063898809231E+00, 0.2402402478867145E+00, 0.1380630986425702E+01, 0.1547015632125768E+01, 0.1525661578238559E+00, 0.3073217441808570E+00, 0.6404863278245572E+00, 0.6853975319350345E+00, 0.1264041760751794E+00, 0.1076549537133787E+00, 0.6395981188913744E+00, 0.7520336386157322E+00, 0.1770404028911661E-01, 0.1396865635082151E-01, 0.8459594942610007E+00, 0.8106342214532430E+00, 0.4753698401003136E-01, 0.5302931309687425E-01, 0.7108052565733343E+00, 0.7583421433039418E+00, 0.2779568135873871E-07, 0.9727942389020712E-07, 0.2030985888538852E+00, 0.2030986166419704E+00, 0.3146138162949754E-27, 0.7596112905317353E-11, 0.8411884198867843E-17, 0.8411884199182457E-17, 0.2293573303077261E-09, 0.5351359530665278E-09, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 8.4118841988678429E-018, + desig: 1.0739530738237274E-017, + qmax: 2.2697722926067549, + ttype: -2, + dmin1: 0.20309858884628909, + dmin2: 0.53283137411117854, + dn: 8.4118841988678429E-018, + dn1: 0.20309858884628909, + dn2: 0.71080515929391042, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 2, + iter: 32, + sigma: 0.21120653295038691, + nDiv: 642, + zOut: []float64{0.2269770980149768E+01, 0.2269770980379126E+01, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.9731514910392876E+00, 0.9736626287363720E+00, 0.5111377954200868E-03, 0.7778528033461282E-03, 0.1481726086511552E+01, 0.1482415971695234E+01, 0.1467737987028945E-02, 0.1706410574351102E-02, 0.1723475383238021E+01, 0.1745500102102777E+01, 0.2373112943910766E-01, 0.2150819994097728E-01, 0.1581996562336162E+01, 0.1673484316042377E+01, 0.1129959536471923E+00, 0.5676676764251993E-01, 0.8407229839290754E+00, 0.8027291772735718E+00, 0.1877296098701645E-01, 0.3124068479314146E-01, 0.1335847297547013E+01, 0.1657986407464839E+01, 0.3533797947109679E+00, 0.2697830536296953E+00, 0.1265767433727330E+01, 0.1069422512121146E+01, 0.7343813202351114E-01, 0.5387701498318342E-01, 0.7845691484971122E+00, 0.1204398523394852E+01, 0.4737063898809231E+00, 0.5430210247136315E+00, 0.1380630986425702E+01, 0.9901761195359265E+00, 0.1525661578238559E+00, 0.9868601781741700E-01, 0.6404863278245572E+00, 0.6682044860823195E+00, 0.1264041760751794E+00, 0.1209927124430272E+00, 0.6395981188913744E+00, 0.5363094467374639E+00, 0.1770404028911661E-01, 0.2792585709699239E-01, 0.8459594942610007E+00, 0.8655706211740396E+00, 0.4753698401003136E-01, 0.3903729781186600E-01, 0.7108052565733343E+00, 0.6717679865571495E+00, 0.2779568135873871E-07, 0.8403591378512072E-08, 0.2030985888538852E+00, 0.2030985804502939E+00, 0.3146138162949754E-27, 0.1303059324279677E-43, 0.8411884198867843E-17, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 16, + ppOut: 0, + dminOut: 8.4118841988678429E-018, + desigOut: 1.0739530738237274E-017, + sigmaOut: 0.21120653295038691, + qmaxOut: 2.2697722926067549, + nFailOut: 2, + iterOut: 33, + nDivOut: 659, + ttypeOut: -2, + dmin1Out: 0.20309858045029386, + dmin2Out: 0.51860540644834729, + dnOut: 8.4118841988678429E-018, + dn1Out: 0.20309858045029386, + dn2Out: 0.67176795876146822, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 16, + z: []float64{0.2269770980149768E+01, 0.2269770980379126E+01, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.9731514910392876E+00, 0.9736626287363720E+00, 0.5111377954200868E-03, 0.7778528033461282E-03, 0.1481726086511552E+01, 0.1482415971695234E+01, 0.1467737987028945E-02, 0.1706410574351102E-02, 0.1723475383238021E+01, 0.1745500102102777E+01, 0.2373112943910766E-01, 0.2150819994097728E-01, 0.1581996562336162E+01, 0.1673484316042377E+01, 0.1129959536471923E+00, 0.5676676764251993E-01, 0.8407229839290754E+00, 0.8027291772735718E+00, 0.1877296098701645E-01, 0.3124068479314146E-01, 0.1335847297547013E+01, 0.1657986407464839E+01, 0.3533797947109679E+00, 0.2697830536296953E+00, 0.1265767433727330E+01, 0.1069422512121146E+01, 0.7343813202351114E-01, 0.5387701498318342E-01, 0.7845691484971122E+00, 0.1204398523394852E+01, 0.4737063898809231E+00, 0.5430210247136315E+00, 0.1380630986425702E+01, 0.9901761195359265E+00, 0.1525661578238559E+00, 0.9868601781741700E-01, 0.6404863278245572E+00, 0.6682044860823195E+00, 0.1264041760751794E+00, 0.1209927124430272E+00, 0.6395981188913744E+00, 0.5363094467374639E+00, 0.1770404028911661E-01, 0.2792585709699239E-01, 0.8459594942610007E+00, 0.8655706211740396E+00, 0.4753698401003136E-01, 0.3903729781186600E-01, 0.7108052565733343E+00, 0.6717679865571495E+00, 0.2779568135873871E-07, 0.8403591378512072E-08, 0.2030985888538852E+00, 0.2030985804502939E+00, 0.3146138162949754E-27, 0.1303059324279677E-43, 0.8411884198867843E-17, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 8.4118841988678429E-018, + desig: 1.0739530738237274E-017, + qmax: 2.2697722926067549, + ttype: -2, + dmin1: 0.20309858045029386, + dmin2: 0.51860540644834729, + dn: 8.4118841988678429E-018, + dn1: 0.20309858045029386, + dn2: 0.67176795876146822, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 2, + iter: 33, + sigma: 0.21120653295038691, + nDiv: 659, + zOut: []float64{0.2168221690252314E+01, 0.2269770980379126E+01, 0.4415865678637858E-10, 0.9833566024906726E-10, 0.8728911912704126E+00, 0.9736626287363720E+00, 0.1321013925721922E-02, 0.7778528033461282E-03, 0.1381252078118717E+01, 0.1482415971695234E+01, 0.2156405683614187E-02, 0.1706410574351102E-02, 0.1663302606134993E+01, 0.1745500102102777E+01, 0.2163985983955575E-01, 0.2150819994097728E-01, 0.1607061933620194E+01, 0.1673484316042377E+01, 0.2835506195054301E-01, 0.5676676764251993E-01, 0.7040655098910235E+00, 0.8027291772735718E+00, 0.7356791380810462E-01, 0.3124068479314146E-01, 0.1752652257061283E+01, 0.1657986407464839E+01, 0.1646145547572216E+00, 0.2697830536296953E+00, 0.8571356821219610E+00, 0.1069422512121146E+01, 0.7570493055431493E-01, 0.5387701498318342E-01, 0.1570165327329021E+01, 0.1204398523394852E+01, 0.3424393862982660E+00, 0.5430210247136315E+00, 0.6448734608299306E+00, 0.9901761195359265E+00, 0.1022564019526126E+00, 0.9868601781741700E-01, 0.5853915063475871E+00, 0.6682044860823195E+00, 0.1108480973262629E+00, 0.1209927124430272E+00, 0.3518379162830466E+00, 0.5363094467374639E+00, 0.6870152520689508E-01, 0.2792585709699239E-01, 0.7343571035538636E+00, 0.8655706211740396E+00, 0.3571015630515456E-01, 0.3903729781186600E-01, 0.5345085484304394E+00, 0.6717679865571495E+00, 0.3193134112956561E-08, 0.8403591378512072E-08, 0.1015492870320128E+00, 0.2030985804502939E+00, 0.4415865678637858E-10, 0.1303059324279677E-43, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 15, + ppOut: 1, + dminOut: 0.10154928703201281, + desigOut: 0.0000000000000000, + sigmaOut: 0.31275582317553385, + qmaxOut: 2.2697722926067549, + nFailOut: 2, + iterOut: 34, + nDivOut: 675, + ttypeOut: -9, + dmin1Out: 0.32391205918605420, + dmin2Out: 0.32391205918605420, + dnOut: 0.10154928703201281, + dn1Out: 0.53450854002684800, + dn2Out: 0.69531980574199759, + gOut: 0.0000000000000000, + tauOut: 0.10154929022514693, + }, + { + i0: 1, + n0: 15, + z: []float64{0.2168221690252314E+01, 0.2269770980379126E+01, 0.4415865678637858E-10, 0.9833566024906726E-10, 0.8728911912704126E+00, 0.9736626287363720E+00, 0.1321013925721922E-02, 0.7778528033461282E-03, 0.1381252078118717E+01, 0.1482415971695234E+01, 0.2156405683614187E-02, 0.1706410574351102E-02, 0.1663302606134993E+01, 0.1745500102102777E+01, 0.2163985983955575E-01, 0.2150819994097728E-01, 0.1607061933620194E+01, 0.1673484316042377E+01, 0.2835506195054301E-01, 0.5676676764251993E-01, 0.7040655098910235E+00, 0.8027291772735718E+00, 0.7356791380810462E-01, 0.3124068479314146E-01, 0.1752652257061283E+01, 0.1657986407464839E+01, 0.1646145547572216E+00, 0.2697830536296953E+00, 0.8571356821219610E+00, 0.1069422512121146E+01, 0.7570493055431493E-01, 0.5387701498318342E-01, 0.1570165327329021E+01, 0.1204398523394852E+01, 0.3424393862982660E+00, 0.5430210247136315E+00, 0.6448734608299306E+00, 0.9901761195359265E+00, 0.1022564019526126E+00, 0.9868601781741700E-01, 0.5853915063475871E+00, 0.6682044860823195E+00, 0.1108480973262629E+00, 0.1209927124430272E+00, 0.3518379162830466E+00, 0.5363094467374639E+00, 0.6870152520689508E-01, 0.2792585709699239E-01, 0.7343571035538636E+00, 0.8655706211740396E+00, 0.3571015630515456E-01, 0.3903729781186600E-01, 0.5345085484304394E+00, 0.6717679865571495E+00, 0.3193134112956561E-08, 0.8403591378512072E-08, 0.1015492870320128E+00, 0.2030985804502939E+00, 0.4415865678637858E-10, 0.9833566024906726E-10, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 0.10154928703201281, + desig: 0.0000000000000000, + qmax: 2.1682216902523144, + ttype: -9, + dmin1: 0.32391205918605420, + dmin2: 0.32391205918605420, + dn: 0.10154928703201281, + dn1: 0.53450854002684800, + dn2: 0.69531980574199759, + g: 0.0000000000000000, + tau: 0.10154929022514693, + nFail: 2, + iter: 34, + sigma: 0.31275582317553385, + nDiv: 675, + zOut: []float64{0.2168221690252314E+01, 0.2066680684115085E+01, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.8728911912704126E+00, 0.7726711989960955E+00, 0.1321013925721922E-02, 0.2361487308570419E-02, 0.1381252078118717E+01, 0.1279505990312372E+01, 0.2156405683614187E-02, 0.2803234389363145E-02, 0.1663302606134993E+01, 0.1580598225403798E+01, 0.2163985983955575E-01, 0.2200217261925751E-01, 0.1607061933620194E+01, 0.1511873816770092E+01, 0.2835506195054301E-01, 0.1320468740761088E-01, 0.7040655098910235E+00, 0.6628877301101292E+00, 0.7356791380810462E-01, 0.1945110224949301E+00, 0.1752652257061283E+01, 0.1621214783142186E+01, 0.1646145547572216E+00, 0.8703165684534678E-01, 0.8571356821219610E+00, 0.7442679496495411E+00, 0.7570493055431493E-01, 0.1597129865933493E+00, 0.1570165327329021E+01, 0.1651350720852550E+01, 0.3424393862982660E+00, 0.1337269360034139E+00, 0.6448734608299306E+00, 0.5118619205977412E+00, 0.1022564019526126E+00, 0.1169456581236225E+00, 0.5853915063475871E+00, 0.4777529393688394E+00, 0.1108480973262629E+00, 0.8163333047984263E-01, 0.3518379162830466E+00, 0.2373651048287110E+00, 0.6870152520689508E-01, 0.2125478936639627E+00, 0.7343571035538636E+00, 0.4559783600136673E+00, 0.3571015630515456E-01, 0.4186028435717903E-01, 0.5345085484304394E+00, 0.3911072610850064E+00, 0.3193134112956561E-08, 0.8290832843879624E-09, 0.1015492870320128E+00, 0.8280021541434701E-05, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 15, + ppOut: 0, + dminOut: 8.2800215414347011E-006, + desigOut: -1.3877787807814457E-017, + sigmaOut: 0.41429682935692197, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 35, + nDivOut: 691, + ttypeOut: -4, + dmin1Out: 0.16866357962181588, + dmin2Out: 0.16866357962181588, + dnOut: 8.2800215414347011E-006, + dn1Out: 0.39110725789187228, + dn2Out: 0.42026820370851276, + gOut: 0.0000000000000000, + tauOut: 0.10154100618138810, + }, + { + i0: 1, + n0: 11, + z: []float64{0.1565539912114361E+01, 0.1565539887559990E+01, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.1185508165627851E+01, 0.1209595044804978E+01, 0.2408690373149840E-01, 0.1773879145177052E-01, 0.8908058287637680E+00, 0.9017845275302323E+00, 0.2871751477260568E-01, 0.4376453959373496E-01, 0.1374289696466428E+01, 0.1388278114489740E+01, 0.5775298217141787E-01, 0.3977262621431848E-01, 0.9560626040960629E+00, 0.9795790109656241E+00, 0.6328905763825028E-01, 0.5927283946360358E-01, 0.9174165586530958E+00, 0.1200347187817445E+01, 0.3422034931823232E+00, 0.1225138368952072E+00, 0.4297417838091302E+00, 0.3072280530227507E+00, 0.1306631986684747E-06, 0.1577236754259593E-06, 0.3708552845063717E+00, 0.3753559465594062E+00, 0.4500844331080801E-02, 0.3315910790466669E-02, 0.2765362989488873E+00, 0.2810497954194954E+00, 0.7829431815445537E-02, 0.5406547261581845E-02, 0.1940765355151052E+00, 0.1886700618399915E+00, 0.9814083907923291E-07, 0.1277249852674422E-13, 0.2455438642568072E-07, 0.2764930279233778E-14, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 2.7649302792337775E-015, + desig: 4.8519526217661568E-017, + qmax: 2.1682216902523144, + ttype: -2, + dmin1: 0.18866996369915248, + dmin2: 0.27322036360404983, + dn: 2.7649302792337775E-015, + dn1: 0.18866996369915248, + dn2: 0.27322036360404983, + g: 0.0000000000000000, + tau: 2.4554370888251911E-008, + nFail: 2, + iter: 57, + sigma: 0.91543762594185796, + nDiv: 1001, + zOut: []float64{0.1565539887559988E+01, 0.1565539887559990E+01, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.1227333836256746E+01, 0.1209595044804978E+01, 0.1303359134714337E-01, 0.1773879145177052E-01, 0.9325154757768211E+00, 0.9017845275302323E+00, 0.6515425651042277E-01, 0.4376453959373496E-01, 0.1362896484193633E+01, 0.1388278114489740E+01, 0.2858649229958118E-01, 0.3977262621431848E-01, 0.1010265358129644E+01, 0.9795790109656241E+00, 0.7042504782685149E-01, 0.5927283946360358E-01, 0.1252435976885798E+01, 0.1200347187817445E+01, 0.3005318297487194E-01, 0.1225138368952072E+00, 0.2771750277715515E+00, 0.3072280530227507E+00, 0.2135925446109612E-06, 0.1577236754259593E-06, 0.3786716437573254E+00, 0.3753559465594062E+00, 0.2461066374135985E-02, 0.3315910790466669E-02, 0.2839952763069384E+00, 0.2810497954194954E+00, 0.3591797791316158E-02, 0.5406547261581845E-02, 0.1850782640486854E+00, 0.1886700618399915E+00, 0.1908115364037247E-27, 0.1277249852674422E-13, 0.3470987982972452E-28, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 11, + ppOut: 1, + dminOut: 3.4709879829724519E-029, + desigOut: 3.7892243888322520E-017, + sigmaOut: 0.91543762594186073, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 58, + nDivOut: 1013, + ttypeOut: -2, + dmin1Out: 0.18507826404867261, + dmin2Out: 0.27717487004787600, + dnOut: 3.4709879829724519E-029, + dn1Out: 0.18507826404867261, + dn2Out: 0.27858872904535659, + gOut: 0.0000000000000000, + tauOut: 2.7649302792335523E-015, + }, + { + i0: 1, + n0: 11, + z: []float64{0.1565539887559988E+01, 0.1565539887559990E+01, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.1227333836256746E+01, 0.1209595044804978E+01, 0.1303359134714337E-01, 0.1773879145177052E-01, 0.9325154757768211E+00, 0.9017845275302323E+00, 0.6515425651042277E-01, 0.4376453959373496E-01, 0.1362896484193633E+01, 0.1388278114489740E+01, 0.2858649229958118E-01, 0.3977262621431848E-01, 0.1010265358129644E+01, 0.9795790109656241E+00, 0.7042504782685149E-01, 0.5927283946360358E-01, 0.1252435976885798E+01, 0.1200347187817445E+01, 0.3005318297487194E-01, 0.1225138368952072E+00, 0.2771750277715515E+00, 0.3072280530227507E+00, 0.2135925446109612E-06, 0.1577236754259593E-06, 0.3786716437573254E+00, 0.3753559465594062E+00, 0.2461066374135985E-02, 0.3315910790466669E-02, 0.2839952763069384E+00, 0.2810497954194954E+00, 0.3591797791316158E-02, 0.5406547261581845E-02, 0.1850782640486854E+00, 0.1886700618399915E+00, 0.1908115364037247E-27, 0.1277249852674422E-13, 0.3470987982972452E-28, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 3.4709879829724519E-029, + desig: 3.7892243888322520E-017, + qmax: 2.1682216902523144, + ttype: -2, + dmin1: 0.18507826404867261, + dmin2: 0.27717487004787600, + dn: 3.4709879829724519E-029, + dn1: 0.18507826404867261, + dn2: 0.27858872904535659, + g: 0.0000000000000000, + tau: 2.7649302792335523E-015, + nFail: 2, + iter: 58, + sigma: 0.91543762594186073, + nDiv: 1013, + zOut: []float64{0.1565539887559988E+01, 0.1473000755535651E+01, 0.5964194309842799E-17, 0.4969486576955697E-17, 0.1227333836256746E+01, 0.1147828295579553E+01, 0.1303359134714337E-01, 0.1058871408116432E-01, 0.9325154757768211E+00, 0.8945418861817434E+00, 0.6515425651042277E-01, 0.9926701980086396E-01, 0.1362896484193633E+01, 0.1199676824668014E+01, 0.2858649229958118E-01, 0.2407310226126826E-01, 0.1010265358129644E+01, 0.9640781716708908E+00, 0.7042504782685149E-01, 0.9148932748822959E-01, 0.1252435976885798E+01, 0.1098460700348104E+01, 0.3005318297487194E-01, 0.7583331677723075E-02, 0.2771750277715515E+00, 0.1770527776620367E+00, 0.2135925446109612E-06, 0.4568210735249311E-06, 0.3786716437573254E+00, 0.2885931212860515E+00, 0.2461066374135985E-02, 0.2421856840585221E-02, 0.2839952763069384E+00, 0.1926260852333330E+00, 0.3591797791316158E-02, 0.3451057520197492E-02, 0.1850782640486854E+00, 0.8908807450415157E-01, 0.1908115364037247E-27, 0.4969486576955697E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 10, + ppOut: 0, + dminOut: 8.9088074504151571E-002, + desigOut: -4.1633363423443370E-017, + sigmaOut: 1.0079767579661971, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 59, + nDivOut: 1024, + ttypeOut: -9, + dmin1Out: 0.17705256406949207, + dmin2Out: 0.17705256406949207, + dnOut: 8.9088074504151571E-002, + dn1Out: 0.18903428744201686, + dn2Out: 0.28613205491191551, + gOut: 0.0000000000000000, + tauOut: 9.2539132024336307E-002, + }, + { + i0: 1, + n0: 10, + z: []float64{0.1565539887559988E+01, 0.1473000755535651E+01, 0.5964194309842799E-17, 0.4969486576955697E-17, 0.1227333836256746E+01, 0.1147828295579553E+01, 0.1303359134714337E-01, 0.1058871408116432E-01, 0.9325154757768211E+00, 0.8945418861817434E+00, 0.6515425651042277E-01, 0.9926701980086396E-01, 0.1362896484193633E+01, 0.1199676824668014E+01, 0.2858649229958118E-01, 0.2407310226126826E-01, 0.1010265358129644E+01, 0.9640781716708908E+00, 0.7042504782685149E-01, 0.9148932748822959E-01, 0.1252435976885798E+01, 0.1098460700348104E+01, 0.3005318297487194E-01, 0.7583331677723075E-02, 0.2771750277715515E+00, 0.1770527776620367E+00, 0.2135925446109612E-06, 0.4568210735249311E-06, 0.3786716437573254E+00, 0.2885931212860515E+00, 0.2461066374135985E-02, 0.2421856840585221E-02, 0.2839952763069384E+00, 0.1926260852333330E+00, 0.3591797791316158E-02, 0.3451057520197492E-02, 0.1850782640486854E+00, 0.8908807450415157E-01, 0.1908115364037247E-27, 0.4969486576955697E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 8.9088074504151571E-002, + desig: -4.1633363423443370E-017, + qmax: 2.1682216902523144, + ttype: -9, + dmin1: 0.17705256406949207, + dmin2: 0.17705256406949207, + dn: 8.9088074504151571E-002, + dn1: 0.18903428744201686, + dn2: 0.28613205491191551, + g: 0.0000000000000000, + tau: 9.2539132024336307E-002, + nFail: 2, + iter: 59, + sigma: 1.0079767579661971, + nDiv: 1024, + zOut: []float64{0.1397612833703614E+01, 0.1473000755535651E+01, 0.4081328655531061E-17, 0.4969486576955697E-17, 0.1083029087828680E+01, 0.1147828295579553E+01, 0.8745885380967966E-02, 0.1058871408116432E-01, 0.9096750987696016E+00, 0.8945418861817434E+00, 0.1309130515609722E+00, 0.9926701980086396E-01, 0.1017448953536272E+01, 0.1199676824668014E+01, 0.2281033592282574E-01, 0.2407310226126826E-01, 0.9573692414042568E+00, 0.9640781716708908E+00, 0.1049724875218357E+00, 0.9148932748822959E-01, 0.9256836226719531E+00, 0.1098460700348104E+01, 0.1450441494900679E-02, 0.7583331677723075E-02, 0.1002148711561719E+00, 0.1770527776620367E+00, 0.1315527505616969E-05, 0.4568210735249311E-06, 0.2156257407670935E+00, 0.2885931212860515E+00, 0.2163530200698068E-02, 0.2421856840585221E-02, 0.1185256907207948E+00, 0.1926260852333330E+00, 0.2593936112987583E-02, 0.3451057520197492E-02, 0.1110621655912630E-01, 0.8908807450415157E-01, 0.4081328655531061E-17, 0.4969486576955697E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 10, + ppOut: 1, + dminOut: 1.1106216559126303E-002, + desigOut: -4.1633363423443370E-017, + sigmaOut: 1.0833646797982348, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 60, + nDivOut: 1035, + ttypeOut: -4, + dmin1Out: 0.10021441433509834, + dmin2Out: 0.10021441433509834, + dnOut: 1.1106216559126303E-002, + dn1Out: 0.11507463320059727, + dn2Out: 0.21320388392650824, + gOut: 0.0000000000000000, + tauOut: 7.5387921832037685E-002, + }, + { + i0: 1, + n0: 10, + z: []float64{0.1397612833703614E+01, 0.1473000755535651E+01, 0.4081328655531061E-17, 0.4969486576955697E-17, 0.1083029087828680E+01, 0.1147828295579553E+01, 0.8745885380967966E-02, 0.1058871408116432E-01, 0.9096750987696016E+00, 0.8945418861817434E+00, 0.1309130515609722E+00, 0.9926701980086396E-01, 0.1017448953536272E+01, 0.1199676824668014E+01, 0.2281033592282574E-01, 0.2407310226126826E-01, 0.9573692414042568E+00, 0.9640781716708908E+00, 0.1049724875218357E+00, 0.9148932748822959E-01, 0.9256836226719531E+00, 0.1098460700348104E+01, 0.1450441494900679E-02, 0.7583331677723075E-02, 0.1002148711561719E+00, 0.1770527776620367E+00, 0.1315527505616969E-05, 0.4568210735249311E-06, 0.2156257407670935E+00, 0.2885931212860515E+00, 0.2163530200698068E-02, 0.2421856840585221E-02, 0.1185256907207948E+00, 0.1926260852333330E+00, 0.2593936112987583E-02, 0.3451057520197492E-02, 0.1110621655912630E-01, 0.8908807450415157E-01, 0.4081328655531061E-17, 0.4969486576955697E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 1.1106216559126303E-002, + desig: -4.1633363423443370E-017, + qmax: 2.1682216902523144, + ttype: -4, + dmin1: 0.10021441433509834, + dmin2: 0.10021441433509834, + dn: 1.1106216559126303E-002, + dn1: 0.11507463320059727, + dn2: 0.21320388392650824, + g: 0.0000000000000000, + tau: 7.5387921832037685E-002, + nFail: 2, + iter: 60, + sigma: 1.0833646797982348, + nDiv: 1035, + zOut: []float64{0.1397612833703614E+01, 0.1388412169967495E+01, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.1083029087828680E+01, 0.1082574309473529E+01, 0.8745885380967966E-02, 0.7349069784991225E-02, 0.9096750987696016E+00, 0.1024038416809464E+01, 0.1309130515609722E+00, 0.1300706547025319E+00, 0.1017448953536272E+01, 0.9009879710204475E+00, 0.2281033592282574E-01, 0.2423774201322422E-01, 0.9573692414042568E+00, 0.1028903323176749E+01, 0.1049724875218357E+00, 0.9444163542020824E-01, 0.9256836226719531E+00, 0.8234917650105269E+00, 0.1450441494900679E-02, 0.1765115496075164E-03, 0.1002148711561719E+00, 0.9083901139795122E-01, 0.1315527505616969E-05, 0.3122684720284652E-05, 0.2156257407670935E+00, 0.2085854845469525E+00, 0.2163530200698068E-02, 0.1229394806594584E-02, 0.1185256907207948E+00, 0.1106895682910690E+00, 0.2593936112987583E-02, 0.2602667681892373E-03, 0.1110621655912630E-01, 0.1645286054818337E-02, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 10, + ppOut: 0, + dminOut: 1.6452860548183366E-003, + desigOut: 7.9797279894933126E-017, + sigmaOut: 1.0925653435343534, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 61, + nDivOut: 1046, + ttypeOut: -4, + dmin1Out: 9.0837695870445614E-002, + dmin2Out: 9.0837695870445614E-002, + dnOut: 1.6452860548183366E-003, + dn1Out: 0.10809563217808144, + dn2Out: 0.20642195434625446, + gOut: 0.0000000000000000, + tauOut: 9.2006637361187298E-003, + }, + { + i0: 1, + n0: 10, + z: []float64{0.1397612833703614E+01, 0.1388412169967495E+01, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.1083029087828680E+01, 0.1082574309473529E+01, 0.8745885380967966E-02, 0.7349069784991225E-02, 0.9096750987696016E+00, 0.1024038416809464E+01, 0.1309130515609722E+00, 0.1300706547025319E+00, 0.1017448953536272E+01, 0.9009879710204475E+00, 0.2281033592282574E-01, 0.2423774201322422E-01, 0.9573692414042568E+00, 0.1028903323176749E+01, 0.1049724875218357E+00, 0.9444163542020824E-01, 0.9256836226719531E+00, 0.8234917650105269E+00, 0.1450441494900679E-02, 0.1765115496075164E-03, 0.1002148711561719E+00, 0.9083901139795122E-01, 0.1315527505616969E-05, 0.3122684720284652E-05, 0.2156257407670935E+00, 0.2085854845469525E+00, 0.2163530200698068E-02, 0.1229394806594584E-02, 0.1185256907207948E+00, 0.1106895682910690E+00, 0.2593936112987583E-02, 0.2602667681892373E-03, 0.1110621655912630E-01, 0.1645286054818337E-02, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 1.6452860548183366E-003, + desig: 7.9797279894933126E-017, + qmax: 2.1682216902523144, + ttype: -4, + dmin1: 9.0837695870445614E-002, + dmin2: 9.0837695870445614E-002, + dn: 1.6452860548183366E-003, + dn1: 0.10809563217808144, + dn2: 0.20642195434625446, + g: 0.0000000000000000, + tau: 9.2006637361187298E-003, + nFail: 2, + iter: 61, + sigma: 1.0925653435343534, + nDiv: 1046, + zOut: []float64{0.1386852748028120E+01, 0.1388412169967495E+01, 0.2485138759635906E-17, 0.3183635051997810E-17, 0.1088363957319145E+01, 0.1082574309473529E+01, 0.6914717946174950E-02, 0.7349069784991225E-02, 0.1145634931626446E+01, 0.1024038416809464E+01, 0.1022944500333619E+00, 0.1300706547025319E+00, 0.8213718410609353E+00, 0.9009879710204475E+00, 0.3036175828902931E-01, 0.2423774201322422E-01, 0.1091423778368554E+01, 0.1028903323176749E+01, 0.7125729765473905E-01, 0.9444163542020824E-01, 0.7508515569660207E+00, 0.8234917650105269E+00, 0.2135460001102832E-04, 0.1765115496075164E-03, 0.8926135754328580E-01, 0.9083901139795122E-01, 0.7297073710223142E-05, 0.3122684720284652E-05, 0.2082481603404622E+00, 0.2085854845469525E+00, 0.6534568189162364E-03, 0.1229394806594584E-02, 0.1087369563009673E+00, 0.1106895682910690E+00, 0.3938065757966957E-05, 0.2602667681892373E-03, 0.8192604968568760E-04, 0.1645286054818337E-02, 0.2485138759635906E-17, 0.3183635051997810E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 10, + ppOut: 1, + dminOut: 8.1926049685687600E-005, + desigOut: -9.9312918999672206E-017, + sigmaOut: 1.0941247654737283, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 62, + nDivOut: 1057, + ttypeOut: -4, + dmin1Out: 8.9258234858565516E-002, + dmin2Out: 8.9258234858565516E-002, + dnOut: 8.1926049685687600E-005, + dn1Out: 0.10847668953277810, + dn2Out: 0.20701876553386761, + gOut: 0.0000000000000000, + tauOut: 1.5594219393746818E-003, + }, + { + i0: 1, + n0: 10, + z: []float64{0.1386852748028120E+01, 0.1388412169967495E+01, 0.2485138759635906E-17, 0.3183635051997810E-17, 0.1088363957319145E+01, 0.1082574309473529E+01, 0.6914717946174950E-02, 0.7349069784991225E-02, 0.1145634931626446E+01, 0.1024038416809464E+01, 0.1022944500333619E+00, 0.1300706547025319E+00, 0.8213718410609353E+00, 0.9009879710204475E+00, 0.3036175828902931E-01, 0.2423774201322422E-01, 0.1091423778368554E+01, 0.1028903323176749E+01, 0.7125729765473905E-01, 0.9444163542020824E-01, 0.7508515569660207E+00, 0.8234917650105269E+00, 0.2135460001102832E-04, 0.1765115496075164E-03, 0.8926135754328580E-01, 0.9083901139795122E-01, 0.7297073710223142E-05, 0.3122684720284652E-05, 0.2082481603404622E+00, 0.2085854845469525E+00, 0.6534568189162364E-03, 0.1229394806594584E-02, 0.1087369563009673E+00, 0.1106895682910690E+00, 0.3938065757966957E-05, 0.2602667681892373E-03, 0.8192604968568760E-04, 0.1645286054818337E-02, 0.2485138759635906E-17, 0.3183635051997810E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 8.1926049685687600E-005, + desig: -9.9312918999672206E-017, + qmax: 2.1682216902523144, + ttype: -4, + dmin1: 8.9258234858565516E-002, + dmin2: 8.9258234858565516E-002, + dn: 8.1926049685687600E-005, + dn1: 0.10847668953277810, + dn2: 0.20701876553386761, + g: 0.0000000000000000, + tau: 1.5594219393746818E-003, + nFail: 2, + iter: 62, + sigma: 1.0941247654737283, + nDiv: 1057, + zOut: []float64{0.1386852748028120E+01, 0.1386771331083530E+01, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.1088363957319145E+01, 0.1095197258320730E+01, 0.6914717946174950E-02, 0.7233164949324962E-02, 0.1145634931626446E+01, 0.1240614799765893E+01, 0.1022944500333619E+00, 0.6772592167212049E-01, 0.8213718410609353E+00, 0.7839262607332537E+00, 0.3036175828902931E-01, 0.4227125255215914E-01, 0.1091423778368554E+01, 0.1120328406526543E+01, 0.7125729765473905E-01, 0.4775711530437247E-01, 0.7508515569660207E+00, 0.7030343793170689E+00, 0.2135460001102832E-04, 0.2711304941630149E-05, 0.8926135754328580E-01, 0.8918452636746399E-01, 0.7297073710223142E-05, 0.1703885458517271E-04, 0.2082481603404622E+00, 0.2088031613602029E+00, 0.6534568189162364E-03, 0.3402961195615630E-03, 0.1087369563009673E+00, 0.1083191813025733E+00, 0.3938065757966957E-05, 0.2978513750500819E-08, 0.8192604968568760E-04, 0.5061265815246250E-06, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 10, + ppOut: 0, + dminOut: 5.0612658152462498E-007, + desigOut: -9.3553094958342964E-017, + sigmaOut: 1.0942061824183187, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 63, + nDivOut: 1068, + ttypeOut: -4, + dmin1Out: 8.9177229293753768E-002, + dmin2Out: 8.9177229293753768E-002, + dnOut: 5.0612658152462498E-007, + dn1Out: 0.10831524323681536, + dn2Out: 0.20814970454128662, + gOut: 0.0000000000000000, + tauOut: 8.1416944590412474E-005, + }, + { + i0: 1, + n0: 10, + z: []float64{0.1386852748028120E+01, 0.1386771331083530E+01, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.1088363957319145E+01, 0.1095197258320730E+01, 0.6914717946174950E-02, 0.7233164949324962E-02, 0.1145634931626446E+01, 0.1240614799765893E+01, 0.1022944500333619E+00, 0.6772592167212049E-01, 0.8213718410609353E+00, 0.7839262607332537E+00, 0.3036175828902931E-01, 0.4227125255215914E-01, 0.1091423778368554E+01, 0.1120328406526543E+01, 0.7125729765473905E-01, 0.4775711530437247E-01, 0.7508515569660207E+00, 0.7030343793170689E+00, 0.2135460001102832E-04, 0.2711304941630149E-05, 0.8926135754328580E-01, 0.8918452636746399E-01, 0.7297073710223142E-05, 0.1703885458517271E-04, 0.2082481603404622E+00, 0.2088031613602029E+00, 0.6534568189162364E-03, 0.3402961195615630E-03, 0.1087369563009673E+00, 0.1083191813025733E+00, 0.3938065757966957E-05, 0.2978513750500819E-08, 0.8192604968568760E-04, 0.5061265815246250E-06, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 5.0612658152462498E-007, + desig: -9.3553094958342964E-017, + qmax: 2.1682216902523144, + ttype: -4, + dmin1: 8.9177229293753768E-002, + dmin2: 8.9177229293753768E-002, + dn: 5.0612658152462498E-007, + dn1: 0.10831524323681536, + dn2: 0.20814970454128662, + g: 0.0000000000000000, + tau: 8.1416944590412474E-005, + nFail: 2, + iter: 63, + sigma: 1.0942061824183187, + nDiv: 1068, + zOut: []float64{0.1386770825043033E+01, 0.1386771331083530E+01, 0.1540308069724697E-17, 0.1950383162890474E-17, 0.1102429917229558E+01, 0.1095197258320730E+01, 0.8139811288713328E-02, 0.7233164949324962E-02, 0.1300200404108803E+01, 0.1240614799765893E+01, 0.4083380405309871E-01, 0.6772592167212049E-01, 0.7853632031918177E+00, 0.7839262607332537E+00, 0.6030036143936175E-01, 0.4227125255215914E-01, 0.1107784654351057E+01, 0.1120328406526543E+01, 0.3030814137396716E-01, 0.4775711530437247E-01, 0.6727284432075471E+00, 0.7030343793170689E+00, 0.3594413905024206E-06, 0.2711304941630149E-05, 0.8920069974016231E-01, 0.8918452636746399E-01, 0.3988496406087022E-04, 0.1703885458517271E-04, 0.2091030664752072E+00, 0.2088031613602029E+00, 0.1762795624794033E-03, 0.3402961195615630E-03, 0.1081423986781113E+00, 0.1083191813025733E+00, 0.1393999949133917E-13, 0.2978513750500819E-08, 0.8607124697139263E-10, 0.5061265815246250E-06, 0.1540308069724697E-17, 0.1950383162890474E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 10, + ppOut: 1, + dminOut: 8.6071246971392626E-011, + desigOut: 7.0901951641105278E-017, + sigmaOut: 1.0942066884588149, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 64, + nDivOut: 1079, + ttypeOut: -4, + dmin1Out: 8.9183660885577137E-002, + dmin2Out: 8.9183660885577137E-002, + dnOut: 8.6071246971392626E-011, + dn1Out: 0.10814239569959758, + dn2Out: 0.20876277035564564, + gOut: 0.0000000000000000, + tauOut: 5.0604049633765406E-007, + }, + { + i0: 1, + n0: 10, + z: []float64{0.1386770825043033E+01, 0.1386771331083530E+01, 0.1540308069724697E-17, 0.1950383162890474E-17, 0.1102429917229558E+01, 0.1095197258320730E+01, 0.8139811288713328E-02, 0.7233164949324962E-02, 0.1300200404108803E+01, 0.1240614799765893E+01, 0.4083380405309871E-01, 0.6772592167212049E-01, 0.7853632031918177E+00, 0.7839262607332537E+00, 0.6030036143936175E-01, 0.4227125255215914E-01, 0.1107784654351057E+01, 0.1120328406526543E+01, 0.3030814137396716E-01, 0.4775711530437247E-01, 0.6727284432075471E+00, 0.7030343793170689E+00, 0.3594413905024206E-06, 0.2711304941630149E-05, 0.8920069974016231E-01, 0.8918452636746399E-01, 0.3988496406087022E-04, 0.1703885458517271E-04, 0.2091030664752072E+00, 0.2088031613602029E+00, 0.1762795624794033E-03, 0.3402961195615630E-03, 0.1081423986781113E+00, 0.1083191813025733E+00, 0.1393999949133917E-13, 0.2978513750500819E-08, 0.8607124697139263E-10, 0.5061265815246250E-06, 0.1540308069724697E-17, 0.1950383162890474E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 8.6071246971392626E-011, + desig: 7.0901951641105278E-017, + qmax: 2.1682216902523144, + ttype: -4, + dmin1: 8.9183660885577137E-002, + dmin2: 8.9183660885577137E-002, + dn: 8.6071246971392626E-011, + dn1: 0.10814239569959758, + dn2: 0.20876277035564564, + g: 0.0000000000000000, + tau: 5.0604049633765406E-007, + nFail: 2, + iter: 64, + sigma: 1.0942066884588149, + nDiv: 1079, + zOut: []float64{0.1386770825043033E+01, 0.1386770824956962E+01, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.1102429917229558E+01, 0.1110569728432201E+01, 0.8139811288713328E-02, 0.9529690622753703E-02, 0.1300200404108803E+01, 0.1331504517453077E+01, 0.4083380405309871E-01, 0.2408506071837550E-01, 0.7853632031918177E+00, 0.8215785038267327E+00, 0.6030036143936175E-01, 0.8130667336500198E-01, 0.1107784654351057E+01, 0.1056786122273951E+01, 0.3030814137396716E-01, 0.1929354325655847E-01, 0.6727284432075471E+00, 0.6534352593063080E+00, 0.3594413905024206E-06, 0.4906748310831983E-07, 0.8920069974016231E-01, 0.8924053555066887E-01, 0.3988496406087022E-04, 0.9345605379795243E-04, 0.2091030664752072E+00, 0.2091858898978174E+00, 0.1762795624794033E-03, 0.9113088236382798E-04, 0.1081423986781113E+00, 0.1080512677096902E+00, 0.1393999949133917E-13, 0.1110429488179469E-22, 0.8607124697139263E-10, 0.3167883469916549E-16, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 10, + ppOut: 0, + dminOut: 3.1678834699165494E-017, + desigOut: -8.6057196331979189E-017, + sigmaOut: 1.0942066885448862, + qmaxOut: 2.1682216902523144, + nFailOut: 2, + iterOut: 65, + nDivOut: 1090, + ttypeOut: -4, + dmin1Out: 8.9200650586607991E-002, + dmin2Out: 8.9200650586607991E-002, + dnOut: 3.1678834699165494E-017, + dn1Out: 0.10805126770967630, + dn2Out: 0.20900961033533805, + gOut: 0.0000000000000000, + tauOut: 8.6071215292546838E-011, + }, + { + i0: 1, + n0: 3, + z: []float64{0.1143865217830237E+00, 0.1154808079639322E+00, 0.2932453102768040E-16, 0.1817901582187390E-16, 0.1834406364024603E+00, 0.1845166504084682E+00, 0.1101341475930520E-06, 0.1827217490071947E-04, 0.1127820009512990E-04, 0.1105674515151256E-02, 0.1845166504084682E+00, 0.2816548643828996E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 1.1278200095129901E-005, + desig: 1.1991276027689679E-016, + qmax: 0.41760242607758735, + ttype: -4, + dmin1: 0.11438652178302365, + dmin2: 0.11438652178302365, + dn: 1.1278200095129901E-005, + dn1: 0.18342236422755959, + dn2: 0.11438652178302365, + g: 0.0000000000000000, + tau: 1.0942861809085330E-003, + nFail: 3, + iter: 99, + sigma: 2.3665909917188244, + nDiv: 1347, + zOut: []float64{0.1143865217830237E+00, 0.1143752525446631E+00, 0.2932453102768040E-16, 0.4703212027287794E-16, 0.1834406364024603E+00, 0.1834294772982473E+00, 0.1101341475930520E-06, 0.6771621290952006E-11, 0.1127820009512990E-04, 0.8954962962003413E-08, 0.1845166504084682E+00, 0.1834406364024603E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 3, + ppOut: 0, + dminOut: 8.9549629620034135E-009, + desigOut: -3.3964327119002935E-017, + sigmaOut: 2.3666022609571851, + qmaxOut: 0.41760242607758735, + nFailOut: 3, + iterOut: 100, + nDivOut: 1351, + ttypeOut: -4, + dmin1Out: 0.11437525254466312, + dmin2Out: 0.11437525254466312, + dnOut: 8.9549629620034135E-009, + dn1Out: 0.18342936716409974, + dn2Out: 0.11437525254466312, + gOut: 0.0000000000000000, + tauOut: 1.1269238360546607E-005, + }, + { + i0: 1, + n0: 3, + z: []float64{0.1143865217830237E+00, 0.1143752525446631E+00, 0.2932453102768040E-16, 0.4703212027287794E-16, 0.1834406364024603E+00, 0.1834294772982473E+00, 0.1101341475930520E-06, 0.6771621290952006E-11, 0.1127820009512990E-04, 0.8954962962003413E-08, 0.1845166504084682E+00, 0.1834406364024603E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 8.9549629620034135E-009, + desig: -3.3964327119002935E-017, + qmax: 0.41760242607758735, + ttype: -4, + dmin1: 0.11437525254466312, + dmin2: 0.11437525254466312, + dn: 8.9549629620034135E-009, + dn1: 0.18342936716409974, + dn2: 0.11437525254466312, + g: 0.0000000000000000, + tau: 1.1269238360546607E-005, + nFail: 3, + iter: 100, + sigma: 2.3666022609571851, + nDiv: 1351, + zOut: []float64{0.1143752435897560E+00, 0.1143752525446631E+00, 0.7542783706608855E-16, 0.4703212027287794E-16, 0.1834294683501117E+00, 0.1834294772982473E+00, 0.3305882004599510E-18, 0.6771621290952006E-11, 0.5575326929115112E-13, 0.8954962962003413E-08, 0.1834294772982473E+00, 0.1834406364024603E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 3, + ppOut: 1, + dminOut: 5.5753269291151117E-014, + desigOut: 1.3632246356731358E-016, + sigmaOut: 2.3666022699120921, + qmaxOut: 0.41760242607758735, + nFailOut: 3, + iterOut: 101, + nDivOut: 1355, + ttypeOut: -4, + dmin1Out: 0.11437524358975594, + dmin2Out: 0.11437524358975594, + dnOut: 5.5753269291151117E-014, + dn1Out: 0.18342946834334006, + dn2Out: 0.11437524358975594, + gOut: 0.0000000000000000, + tauOut: 8.9549072084035346E-009, + }, + { + i0: 1, + n0: 3, + z: []float64{0.1143752435897560E+00, 0.1143752525446631E+00, 0.7542783706608855E-16, 0.4703212027287794E-16, 0.1834294683501117E+00, 0.1834294772982473E+00, 0.3305882004599510E-18, 0.6771621290952006E-11, 0.5575326929115112E-13, 0.8954962962003413E-08, 0.1834294772982473E+00, 0.1834406364024603E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 0, + dmin: 5.5753269291151117E-014, + desig: 1.3632246356731358E-016, + qmax: 0.41760242607758735, + ttype: -4, + dmin1: 0.11437524358975594, + dmin2: 0.11437524358975594, + dn: 5.5753269291151117E-014, + dn1: 0.18342946834334006, + dn2: 0.11437524358975594, + g: 0.0000000000000000, + tau: 8.9549072084035346E-009, + nFail: 3, + iter: 101, + sigma: 2.3666022699120921, + nDiv: 1355, + zOut: []float64{0.1143752435897560E+00, 0.1143752435897003E+00, 0.7542783706608855E-16, 0.1209675067575323E-15, 0.1834294683501117E+00, 0.1834294683500558E+00, 0.3305882004599510E-18, 0.1004820715586787E-30, 0.5575326929115112E-13, 0.7669624420364386E-22, 0.1834294772982473E+00, 0.1834294683501117E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 3, + ppOut: 0, + dminOut: 7.6696244203643861E-023, + desigOut: -6.5648763085702813E-017, + sigmaOut: 2.3666022699121481, + qmaxOut: 0.41760242607758735, + nFailOut: 3, + iterOut: 102, + nDivOut: 1359, + ttypeOut: -4, + dmin1Out: 0.11437524358970023, + dmin2Out: 0.11437524358970023, + dnOut: 7.6696244203643861E-023, + dn1Out: 0.18342946835005580, + dn2Out: 0.11437524358970023, + gOut: 0.0000000000000000, + tauOut: 5.5753269214454873E-014, + }, + { + i0: 1, + n0: 3, + z: []float64{0.1143752435897560E+00, 0.1143752435897003E+00, 0.7542783706608855E-16, 0.1209675067575323E-15, 0.1834294683501117E+00, 0.1834294683500558E+00, 0.3305882004599510E-18, 0.1004820715586787E-30, 0.5575326929115112E-13, 0.7669624420364386E-22, 0.1834294772982473E+00, 0.1834294683501117E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + pp: 1, + dmin: 7.6696244203643861E-023, + desig: -6.5648763085702813E-017, + qmax: 0.41760242607758735, + ttype: -4, + dmin1: 0.11437524358970023, + dmin2: 0.11437524358970023, + dn: 7.6696244203643861E-023, + dn1: 0.18342946835005580, + dn2: 0.11437524358970023, + g: 0.0000000000000000, + tau: 5.5753269214454873E-014, + nFail: 3, + iter: 102, + sigma: 2.3666022699121481, + nDiv: 1359, + zOut: []float64{0.2550031738262204E+01, 0.1834294683500561E+00, 0.7542783706608855E-16, 0.1209675067575323E-15, 0.2480977513501848E+01, 0.1143752435897001E+00, 0.3305882004599510E-18, 0.1004820715586787E-30, 0.2366602269912148E+01, 0.7669624420364386E-22, 0.1834294772982473E+00, 0.1834294683501117E+00, 0.2169993432366266E+01, 0.5067642455139780E-26, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.1810817848712033E+01, 0.1972152263052530E-29, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.1681677309759878E+01, 0.5241368559131172E-22, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.1303743375476047E+01, 0.0000000000000000E+00, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1202161769544433E+01, 0.0000000000000000E+00, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1183377192742860E+01, 0.2033579915108999E-22, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1094206688544886E+01, 0.3167883469916549E-16, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.9154376259418607E+00, 0.2764930279233778E-14, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.8241395430971566E+00, 0.2245698748385924E-16, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.7318275341991307E+00, 0.4959852501050381E-23, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.5186198053161721E+00, 0.1503295986001297E-14, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.4143051093784424E+00, 0.1303656847202082E-15, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.2112065329503869E+00, 0.8411884198867843E-17, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.1093987140067686E+00, 0.2696165428113804E-17, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.9751785856405315E-01, 0.6617412588681544E-21, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.2818174710670554E-01, 0.1396210563637443E-18, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1697846193036144E-01, 0.6162975822039155E-31, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.2117542506861687E-04, 0.0000000000000000E+00, 0.9895328911616120E-03, 0.1620493249248586E-02}, + i0Out: 1, + n0Out: 0, + ppOut: 1, + dminOut: 7.6696244203643861E-023, + desigOut: -6.5648763085702813E-017, + sigmaOut: 2.3666022699121481, + qmaxOut: 0.41760242607758735, + nFailOut: 3, + iterOut: 102, + nDivOut: 1359, + ttypeOut: -4, + dmin1Out: 0.11437524358970023, + dmin2Out: 0.11437524358970023, + dnOut: 7.6696244203643861E-023, + dn1Out: 0.18342946835005580, + dn2Out: 0.11437524358970023, + gOut: 0.0000000000000000, + tauOut: 5.5753269214454873E-014, + }, + { + i0: 1, + n0: 21, + z: []float64{0.1648283185136998E+01, 0.1396221235720571E+01, 0.1712714336271993E+00, 0.2520619494164272E+00, 0.1510753432847732E+01, 0.1119977945086946E+01, 0.3792800633372563E+00, 0.5620469213879850E+00, 0.1328441621586708E+01, 0.1019485448443405E+01, 0.1388998759717073E+00, 0.6882362364805590E+00, 0.4466938077796418E+00, 0.2681061628164644E+00, 0.7093206047768255E+00, 0.3174875209348847E+00, 0.6843112870203156E+00, 0.9979892152967577E+00, 0.6490582981441884E+00, 0.3956426765003833E+00, 0.5085572738629487E+00, 0.1122623886995757E+01, 0.9750235054014829E-02, 0.3499168501137979E-01, 0.1364886053450573E+00, 0.1417066070690837E+00, 0.2301225778544498E-01, 0.4532233329988395E-02, 0.1646009972289452E+01, 0.6930161671496210E+00, 0.2362515608142310E+00, 0.9760060629252760E+00, 0.5818602562677768E+00, 0.3984323866837953E+00, 0.1797665269485310E-01, 0.4196794303982125E+00, 0.5600419521166516E+00, 0.2492354636952108E-01, 0.2195137569256029E+00, 0.5530950584419837E+00, 0.4184071984843414E+00, 0.2222708575473020E+00, 0.2727864547293006E+00, 0.4156500978626423E+00, 0.6774373914466536E-01, 0.2745959086613283E+00, 0.1050967099374242E+00, 0.6593428521263771E-01, 0.2040338718098096E+00, 0.1079809097801335E+00, 0.1271971985482246E+00, 0.2011496719671002E+00, 0.4444741998443960E-01, 0.1290210252363728E+00, 0.5776327498150620E+00, 0.4262359329629137E-01, 0.3402556968467140E+00, 0.6023491555328507E+00, 0.1086565805630269E+00, 0.3155392911289253E+00, 0.9382999256694983E+00, 0.1171677238805356E+00, 0.7901625299559836E+00, 0.9297887823519896E+00, 0.6095853796269167E+00, 0.7973955560628040E+00, 0.8018125008387630E+00, 0.6023523535200964E+00, 0.2443177602187348E-01, 0.8114406374558937E+00, 0.2277830378453201E+00, 0.1480363940474286E-01, 0.6969081780841352E+00, 0.3759308106650992E+00, 0.8012406122589412E-01, 0.5487604052643561E+00, 0.9781022865072954E-01, 0.1017549972519246E+00, 0.2961248981181939E-03, 0.7617929262469909E-01, 0.8408398800007548E-04, 0.3802088861182694E-03, 0.0000000000000000E+00, 0.0000000000000000E+00}, + pp: 0, + dmin: -0.0000000000000000, + desig: 0.0000000000000000, + qmax: 1.8900334961849885, + ttype: 0, + dmin1: 0.0000000000000000, + dmin2: 0.0000000000000000, + dn: 0.0000000000000000, + dn1: 0.0000000000000000, + dn2: 0.0000000000000000, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 2, + sigma: 0.0000000000000000, + nDiv: 40, + zOut: []float64{0.1648283185136998E+01, 0.1819554618764197E+01, 0.1712714336271993E+00, 0.1422045283129674E+00, 0.1510753432847732E+01, 0.1747828967872021E+01, 0.3792800633372563E+00, 0.2882727267008810E+00, 0.1328441621586708E+01, 0.1179068770857534E+01, 0.1388998759717073E+00, 0.5262264257308433E-01, 0.4466938077796418E+00, 0.1103391769983383E+01, 0.7093206047768255E+00, 0.4399127392187891E+00, 0.6843112870203156E+00, 0.8934568459457148E+00, 0.6490582981441884E+00, 0.3694451726238032E+00, 0.5085572738629487E+00, 0.1488623362931603E+00, 0.9750235054014829E-02, 0.8939776288934402E-02, 0.1364886053450573E+00, 0.1505610868415679E+00, 0.2301225778544498E-01, 0.2515816443301624E+00, 0.1646009972289452E+01, 0.1630679888773521E+01, 0.2362515608142310E+00, 0.8429943526342391E-01, 0.5818602562677768E+00, 0.5155374736992060E+00, 0.1797665269485310E-01, 0.1952851185677853E-01, 0.5600419521166516E+00, 0.7600271971854760E+00, 0.2195137569256029E+00, 0.1208458544696003E+00, 0.4184071984843414E+00, 0.5703477987440417E+00, 0.2727864547293006E+00, 0.3240053608004366E-01, 0.6774373914466536E-01, 0.1404399130020459E+00, 0.1050967099374242E+00, 0.1526865702536626E+00, 0.2040338718098096E+00, 0.1785445001043715E+00, 0.1271971985482246E+00, 0.3166486394939177E-01, 0.4444741998443960E-01, 0.5904153058501098E+00, 0.5776327498150620E+00, 0.3328891237445398E+00, 0.3402556968467140E+00, 0.1160231536652011E+00, 0.1086565805630269E+00, 0.8787251358464724E+00, 0.9382999256694983E+00, 0.8497373197790092E+00, 0.7901625299559836E+00, 0.5668475593321608E+00, 0.6095853796269167E+00, 0.8445503211335190E+00, 0.8018125008387630E+00, 0.2319542476253924E-01, 0.2443177602187348E-01, 0.2290193891046544E+00, 0.2277830378453201E+00, 0.6931459494493321E+00, 0.6969081780841352E+00, 0.8388628986069724E-01, 0.8012406122589412E-01, 0.9342352322344821E-01, 0.9781022865072954E-01, 0.4682830325399513E-02, 0.2961248981181939E-03, 0.5317160915449039E-05, 0.8408398800007548E-04, 0.7876682708462645E-04, 0.0000000000000000E+00, 0.8939776288934402E-02}, + i0Out: 1, + n0Out: 21, + ppOut: 0, + dminOut: 7.8766827084626452E-005, + desigOut: 0.0000000000000000, + sigmaOut: 0.0000000000000000, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 3, + nDivOut: 62, + ttypeOut: -1, + dmin1Out: 1.2363512593342330E-003, + dmin2Out: 1.2363512593342330E-003, + dnOut: 7.8766827084626452E-005, + dn1Out: 4.3867054272813191E-003, + dn2Out: 3.7622286348031123E-003, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 21, + z: []float64{0.1648283185136998E+01, 0.1819554618764197E+01, 0.1712714336271993E+00, 0.1422045283129674E+00, 0.1510753432847732E+01, 0.1747828967872021E+01, 0.3792800633372563E+00, 0.2882727267008810E+00, 0.1328441621586708E+01, 0.1179068770857534E+01, 0.1388998759717073E+00, 0.5262264257308433E-01, 0.4466938077796418E+00, 0.1103391769983383E+01, 0.7093206047768255E+00, 0.4399127392187891E+00, 0.6843112870203156E+00, 0.8934568459457148E+00, 0.6490582981441884E+00, 0.3694451726238032E+00, 0.5085572738629487E+00, 0.1488623362931603E+00, 0.9750235054014829E-02, 0.8939776288934402E-02, 0.1364886053450573E+00, 0.1505610868415679E+00, 0.2301225778544498E-01, 0.2515816443301624E+00, 0.1646009972289452E+01, 0.1630679888773521E+01, 0.2362515608142310E+00, 0.8429943526342391E-01, 0.5818602562677768E+00, 0.5155374736992060E+00, 0.1797665269485310E-01, 0.1952851185677853E-01, 0.5600419521166516E+00, 0.7600271971854760E+00, 0.2195137569256029E+00, 0.1208458544696003E+00, 0.4184071984843414E+00, 0.5703477987440417E+00, 0.2727864547293006E+00, 0.3240053608004366E-01, 0.6774373914466536E-01, 0.1404399130020459E+00, 0.1050967099374242E+00, 0.1526865702536626E+00, 0.2040338718098096E+00, 0.1785445001043715E+00, 0.1271971985482246E+00, 0.3166486394939177E-01, 0.4444741998443960E-01, 0.5904153058501098E+00, 0.5776327498150620E+00, 0.3328891237445398E+00, 0.3402556968467140E+00, 0.1160231536652011E+00, 0.1086565805630269E+00, 0.8787251358464724E+00, 0.9382999256694983E+00, 0.8497373197790092E+00, 0.7901625299559836E+00, 0.5668475593321608E+00, 0.6095853796269167E+00, 0.8445503211335190E+00, 0.8018125008387630E+00, 0.2319542476253924E-01, 0.2443177602187348E-01, 0.2290193891046544E+00, 0.2277830378453201E+00, 0.6931459494493321E+00, 0.6969081780841352E+00, 0.8388628986069724E-01, 0.8012406122589412E-01, 0.9342352322344821E-01, 0.9781022865072954E-01, 0.4682830325399513E-02, 0.2961248981181939E-03, 0.5317160915449039E-05, 0.8408398800007548E-04, 0.7876682708462645E-04, 0.0000000000000000E+00, 0.8939776288934402E-02}, + pp: 1, + dmin: 7.8766827084626452E-005, + desig: 0.0000000000000000, + qmax: 1.8900334961849885, + ttype: -1, + dmin1: 1.2363512593342330E-003, + dmin2: 1.2363512593342330E-003, + dn: 7.8766827084626452E-005, + dn1: 4.3867054272813191E-003, + dn2: 3.7622286348031123E-003, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 3, + sigma: 0.0000000000000000, + nDiv: 62, + zOut: []float64{0.1961759147077164E+01, 0.1819554618764197E+01, 0.1266970995487882E+00, 0.1422045283129674E+00, 0.1909404595024114E+01, 0.1747828967872021E+01, 0.1780101349021133E+00, 0.2882727267008810E+00, 0.1053681278528505E+01, 0.1179068770857534E+01, 0.5510526941411123E-01, 0.5262264257308433E-01, 0.1488199239788061E+01, 0.1103391769983383E+01, 0.2641064704009213E+00, 0.4399127392187891E+00, 0.9987955481685968E+00, 0.8934568459457148E+00, 0.5506279200968747E-01, 0.3694451726238032E+00, 0.1027393205724072E+00, 0.1488623362931603E+00, 0.1310094739466220E-01, 0.8939776288934402E-02, 0.3890417837770681E+00, 0.1505610868415679E+00, 0.1054511738587064E+01, 0.2515816443301624E+00, 0.6604675854498806E+00, 0.1630679888773521E+01, 0.6580113672099847E-01, 0.8429943526342391E-01, 0.4692648488349861E+00, 0.5155374736992060E+00, 0.3162862116895929E-01, 0.1952851185677853E-01, 0.8492444304861170E+00, 0.7600271971854760E+00, 0.8115939841327705E-01, 0.1208458544696003E+00, 0.5215889364108083E+00, 0.5703477987440417E+00, 0.8723974284448969E-02, 0.3240053608004366E-01, 0.2844025089712595E+00, 0.1404399130020459E+00, 0.9585480612390133E-01, 0.1526865702536626E+00, 0.1143545579298620E+00, 0.1785445001043715E+00, 0.1634864466429828E+00, 0.3166486394939177E-01, 0.7598179829516669E+00, 0.5904153058501098E+00, 0.5083170815153470E-01, 0.3328891237445398E+00, 0.9439165813601388E+00, 0.1160231536652011E+00, 0.7910503496831139E+00, 0.8787251358464724E+00, 0.6255345294280562E+00, 0.8497373197790092E+00, 0.7653155273545736E+00, 0.5668475593321608E+00, 0.1024302185414846E+00, 0.8445503211335190E+00, 0.5186166821452450E-01, 0.2319542476253924E-01, 0.8703036703394620E+00, 0.2290193891046544E+00, 0.6681052144545734E-01, 0.6931459494493321E+00, 0.1104992916386881E+00, 0.8388628986069724E-01, 0.3959179295799719E-02, 0.9342352322344821E-01, 0.7289681905152429E-03, 0.4682830325399513E-02, 0.5745324691222600E-06, 0.5317160915449039E-05, 0.7819229461550419E-04, 0.7876682708462645E-04, 0.8723974284448969E-02, 0.8939776288934402E-02}, + i0Out: 1, + n0Out: 21, + ppOut: 1, + dminOut: 7.8192294615504193E-005, + desigOut: 0.0000000000000000, + sigmaOut: 0.0000000000000000, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 4, + nDivOut: 84, + ttypeOut: -4, + dmin1Out: 7.2365102959979382E-004, + dmin2Out: 1.7075768415239889E-002, + dnOut: 7.8192294615504193E-005, + dn1Out: 7.2365102959979382E-004, + dn2Out: 1.7075768415239889E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 21, + z: []float64{0.1961759147077164E+01, 0.1819554618764197E+01, 0.1266970995487882E+00, 0.1422045283129674E+00, 0.1909404595024114E+01, 0.1747828967872021E+01, 0.1780101349021133E+00, 0.2882727267008810E+00, 0.1053681278528505E+01, 0.1179068770857534E+01, 0.5510526941411123E-01, 0.5262264257308433E-01, 0.1488199239788061E+01, 0.1103391769983383E+01, 0.2641064704009213E+00, 0.4399127392187891E+00, 0.9987955481685968E+00, 0.8934568459457148E+00, 0.5506279200968747E-01, 0.3694451726238032E+00, 0.1027393205724072E+00, 0.1488623362931603E+00, 0.1310094739466220E-01, 0.8939776288934402E-02, 0.3890417837770681E+00, 0.1505610868415679E+00, 0.1054511738587064E+01, 0.2515816443301624E+00, 0.6604675854498806E+00, 0.1630679888773521E+01, 0.6580113672099847E-01, 0.8429943526342391E-01, 0.4692648488349861E+00, 0.5155374736992060E+00, 0.3162862116895929E-01, 0.1952851185677853E-01, 0.8492444304861170E+00, 0.7600271971854760E+00, 0.8115939841327705E-01, 0.1208458544696003E+00, 0.5215889364108083E+00, 0.5703477987440417E+00, 0.8723974284448969E-02, 0.3240053608004366E-01, 0.2844025089712595E+00, 0.1404399130020459E+00, 0.9585480612390133E-01, 0.1526865702536626E+00, 0.1143545579298620E+00, 0.1785445001043715E+00, 0.1634864466429828E+00, 0.3166486394939177E-01, 0.7598179829516669E+00, 0.5904153058501098E+00, 0.5083170815153470E-01, 0.3328891237445398E+00, 0.9439165813601388E+00, 0.1160231536652011E+00, 0.7910503496831139E+00, 0.8787251358464724E+00, 0.6255345294280562E+00, 0.8497373197790092E+00, 0.7653155273545736E+00, 0.5668475593321608E+00, 0.1024302185414846E+00, 0.8445503211335190E+00, 0.5186166821452450E-01, 0.2319542476253924E-01, 0.8703036703394620E+00, 0.2290193891046544E+00, 0.6681052144545734E-01, 0.6931459494493321E+00, 0.1104992916386881E+00, 0.8388628986069724E-01, 0.3959179295799719E-02, 0.9342352322344821E-01, 0.7289681905152429E-03, 0.4682830325399513E-02, 0.5745324691222600E-06, 0.5317160915449039E-05, 0.7819229461550419E-04, 0.7876682708462645E-04, 0.8723974284448969E-02, 0.8939776288934402E-02}, + pp: 0, + dmin: 7.8192294615504193E-005, + desig: 0.0000000000000000, + qmax: 1.8900334961849885, + ttype: -4, + dmin1: 7.2365102959979382E-004, + dmin2: 1.7075768415239889E-002, + dn: 7.8192294615504193E-005, + dn1: 7.2365102959979382E-004, + dn2: 1.7075768415239889E-002, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 4, + sigma: 0.0000000000000000, + nDiv: 84, + zOut: []float64{0.1961759147077164E+01, 0.2088378163269771E+01, 0.1266970995487882E+00, 0.1158391848322702E+00, 0.1909404595024114E+01, 0.1971497461737776E+01, 0.1780101349021133E+00, 0.9513882222772962E-01, 0.1053681278528505E+01, 0.1013569642358705E+01, 0.5510526941411123E-01, 0.8090970429970110E-01, 0.1488199239788061E+01, 0.1671317922533099E+01, 0.2641064704009213E+00, 0.1578325483874163E+00, 0.9987955481685968E+00, 0.8959477084346864E+00, 0.5506279200968747E-01, 0.6314111623521673E-02, 0.1027393205724072E+00, 0.1094480729873660E+00, 0.1310094739466220E-01, 0.4656834793406785E-01, 0.3890417837770681E+00, 0.1396907091073883E+01, 0.1054511738587064E+01, 0.4985806330739840E+00, 0.6604675854498806E+00, 0.2276100057407134E+00, 0.6580113672099847E-01, 0.1356625794022653E+00, 0.4692648488349861E+00, 0.3651528072454984E+00, 0.3162862116895929E-01, 0.7355942454424362E-01, 0.8492444304861170E+00, 0.8567663209989688E+00, 0.8115939841327705E-01, 0.4940885660487250E-01, 0.5215889364108083E+00, 0.4808259707342031E+00, 0.8723974284448969E-02, 0.5160120970399038E-02, 0.2844025089712595E+00, 0.3750191107685802E+00, 0.9585480612390133E-01, 0.2922900104287094E-01, 0.1143545579298620E+00, 0.2485339201737921E+00, 0.1634864466429828E+00, 0.4998108187459615E+00, 0.7598179829516669E+00, 0.3107607890010585E+00, 0.5083170815153470E-01, 0.1543981540828483E+00, 0.9439165813601388E+00, 0.1580490693604223E+01, 0.7910503496831139E+00, 0.3130858727896049E+00, 0.6255345294280562E+00, 0.1077686100636843E+01, 0.7653155273545736E+00, 0.7274051012980143E-01, 0.1024302185414846E+00, 0.8147329327002600E-01, 0.5186166821452450E-01, 0.5539901283655780E+00, 0.8703036703394620E+00, 0.3830459800631597E+00, 0.6681052144545734E-01, 0.1927318305890360E-01, 0.1104992916386881E+00, 0.9510720451940254E-01, 0.3959179295799719E-02, 0.3034592154998885E-04, 0.7289681905152429E-03, 0.6211134452527084E-03, 0.5745324691222600E-06, 0.7232819130731082E-07, 0.7819229461550419E-04, 0.3661024252896476E-07, 0.8723974284448969E-02, 0.5160120970399038E-02}, + i0Out: 1, + n0Out: 21, + ppOut: 0, + dminOut: 3.6610242528964756E-008, + desigOut: 0.0000000000000000, + sigmaOut: 7.8083356181667918E-005, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 5, + nDivOut: 106, + ttypeOut: -2, + dmin1Out: 6.2053891278358614E-004, + dmin2Out: 2.9611625055501498E-002, + dnOut: 3.6610242528964756E-008, + dn1Out: 6.2053891278358614E-004, + dn2Out: 9.1148025223602810E-002, + gOut: 0.0000000000000000, + tauOut: 7.8083356181667918E-005, + }, + { + i0: 1, + n0: 21, + z: []float64{0.1961759147077164E+01, 0.2088378163269771E+01, 0.1266970995487882E+00, 0.1158391848322702E+00, 0.1909404595024114E+01, 0.1971497461737776E+01, 0.1780101349021133E+00, 0.9513882222772962E-01, 0.1053681278528505E+01, 0.1013569642358705E+01, 0.5510526941411123E-01, 0.8090970429970110E-01, 0.1488199239788061E+01, 0.1671317922533099E+01, 0.2641064704009213E+00, 0.1578325483874163E+00, 0.9987955481685968E+00, 0.8959477084346864E+00, 0.5506279200968747E-01, 0.6314111623521673E-02, 0.1027393205724072E+00, 0.1094480729873660E+00, 0.1310094739466220E-01, 0.4656834793406785E-01, 0.3890417837770681E+00, 0.1396907091073883E+01, 0.1054511738587064E+01, 0.4985806330739840E+00, 0.6604675854498806E+00, 0.2276100057407134E+00, 0.6580113672099847E-01, 0.1356625794022653E+00, 0.4692648488349861E+00, 0.3651528072454984E+00, 0.3162862116895929E-01, 0.7355942454424362E-01, 0.8492444304861170E+00, 0.8567663209989688E+00, 0.8115939841327705E-01, 0.4940885660487250E-01, 0.5215889364108083E+00, 0.4808259707342031E+00, 0.8723974284448969E-02, 0.5160120970399038E-02, 0.2844025089712595E+00, 0.3750191107685802E+00, 0.9585480612390133E-01, 0.2922900104287094E-01, 0.1143545579298620E+00, 0.2485339201737921E+00, 0.1634864466429828E+00, 0.4998108187459615E+00, 0.7598179829516669E+00, 0.3107607890010585E+00, 0.5083170815153470E-01, 0.1543981540828483E+00, 0.9439165813601388E+00, 0.1580490693604223E+01, 0.7910503496831139E+00, 0.3130858727896049E+00, 0.6255345294280562E+00, 0.1077686100636843E+01, 0.7653155273545736E+00, 0.7274051012980143E-01, 0.1024302185414846E+00, 0.8147329327002600E-01, 0.5186166821452450E-01, 0.5539901283655780E+00, 0.8703036703394620E+00, 0.3830459800631597E+00, 0.6681052144545734E-01, 0.1927318305890360E-01, 0.1104992916386881E+00, 0.9510720451940254E-01, 0.3959179295799719E-02, 0.3034592154998885E-04, 0.7289681905152429E-03, 0.6211134452527084E-03, 0.5745324691222600E-06, 0.7232819130731082E-07, 0.7819229461550419E-04, 0.3661024252896476E-07, 0.8723974284448969E-02, 0.5160120970399038E-02}, + pp: 1, + dmin: 3.6610242528964756E-008, + desig: 0.0000000000000000, + qmax: 1.8900334961849885, + ttype: -2, + dmin1: 6.2053891278358614E-004, + dmin2: 2.9611625055501498E-002, + dn: 3.6610242528964756E-008, + dn1: 6.2053891278358614E-004, + dn2: 9.1148025223602810E-002, + g: 0.0000000000000000, + tau: 7.8083356181667918E-005, + nFail: 0, + iter: 5, + sigma: 7.8083356181667918E-005, + nDiv: 106, + zOut: []float64{0.2204217311496068E+01, 0.2088378163269771E+01, 0.1036089580076783E+00, 0.1158391848322702E+00, 0.1963027289351853E+01, 0.1971497461737776E+01, 0.4912301654839819E-01, 0.9513882222772962E-01, 0.1045356293504034E+01, 0.1013569642358705E+01, 0.1293586117415210E+00, 0.8090970429970110E-01, 0.1699791822573021E+01, 0.1671317922533099E+01, 0.8319236989271818E-01, 0.1578325483874163E+00, 0.8190694135595162E+00, 0.8959477084346864E+00, 0.8437225690290790E-03, 0.6314111623521673E-02, 0.1551726617464312E+00, 0.1094480729873660E+00, 0.4192211096758560E+00, 0.4656834793406785E-01, 0.1476266577866037E+01, 0.1396907091073883E+01, 0.7687090018675194E-01, 0.4985806330739840E+00, 0.2864016483502532E+00, 0.2276100057407134E+00, 0.1729653861709652E+00, 0.1356625794022653E+00, 0.2657468090128033E+00, 0.3651528072454984E+00, 0.2371551996266359E+00, 0.7355942454424362E-01, 0.6690199413712319E+00, 0.8567663209989688E+00, 0.3551024412099299E-01, 0.4940885660487250E-01, 0.4504758109776356E+00, 0.4808259707342031E+00, 0.4295777776785939E-02, 0.5160120970399038E-02, 0.3999522974286917E+00, 0.3750191107685802E+00, 0.1816316160365039E-01, 0.2922900104287094E-01, 0.7301815407101296E+00, 0.2485339201737921E+00, 0.2127164214993764E+00, 0.4998108187459615E+00, 0.2524424849785568E+00, 0.3107607890010585E+00, 0.9666552191416621E+00, 0.1543981540828483E+00, 0.9269213106461920E+00, 0.1580490693604223E+01, 0.3640096408786760E+00, 0.3130858727896049E+00, 0.7864169332819952E+00, 0.1077686100636843E+01, 0.7535963003344312E-02, 0.7274051012980143E-01, 0.6279274220262862E+00, 0.8147329327002600E-01, 0.3379430237022286E+00, 0.5539901283655780E+00, 0.6437610281386123E-01, 0.3830459800631597E+00, 0.2847358698029713E-01, 0.1927318305890360E-01, 0.6666392685468185E-01, 0.9510720451940254E-01, 0.2827355178816361E-06, 0.3034592154998885E-04, 0.6208664319525956E-03, 0.6211134452527084E-03, 0.4264931214133004E-11, 0.7232819130731082E-07, 0.4059351646211308E-14, 0.3661024252896476E-07, 0.8437225690290790E-03, 0.5160120970399038E-02}, + i0Out: 1, + n0Out: 21, + ppOut: 1, + dminOut: 4.0593516462113082E-015, + desigOut: 4.3344264097778650E-021, + sigmaOut: 7.8119962155206313E-005, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 6, + nDivOut: 128, + ttypeOut: -2, + dmin1Out: 6.2079410376128833E-004, + dmin2Out: 4.5102919754957636E-002, + dnOut: 4.0593516462113082E-015, + dn1Out: 6.2079410376128833E-004, + dn2Out: 6.6633580933131861E-002, + gOut: 0.0000000000000000, + tauOut: 3.6605973538398975E-008, + }, + { + i0: 1, + n0: 21, + z: []float64{0.2204217311496068E+01, 0.2088378163269771E+01, 0.1036089580076783E+00, 0.1158391848322702E+00, 0.1963027289351853E+01, 0.1971497461737776E+01, 0.4912301654839819E-01, 0.9513882222772962E-01, 0.1045356293504034E+01, 0.1013569642358705E+01, 0.1293586117415210E+00, 0.8090970429970110E-01, 0.1699791822573021E+01, 0.1671317922533099E+01, 0.8319236989271818E-01, 0.1578325483874163E+00, 0.8190694135595162E+00, 0.8959477084346864E+00, 0.8437225690290790E-03, 0.6314111623521673E-02, 0.1551726617464312E+00, 0.1094480729873660E+00, 0.4192211096758560E+00, 0.4656834793406785E-01, 0.1476266577866037E+01, 0.1396907091073883E+01, 0.7687090018675194E-01, 0.4985806330739840E+00, 0.2864016483502532E+00, 0.2276100057407134E+00, 0.1729653861709652E+00, 0.1356625794022653E+00, 0.2657468090128033E+00, 0.3651528072454984E+00, 0.2371551996266359E+00, 0.7355942454424362E-01, 0.6690199413712319E+00, 0.8567663209989688E+00, 0.3551024412099299E-01, 0.4940885660487250E-01, 0.4504758109776356E+00, 0.4808259707342031E+00, 0.4295777776785939E-02, 0.5160120970399038E-02, 0.3999522974286917E+00, 0.3750191107685802E+00, 0.1816316160365039E-01, 0.2922900104287094E-01, 0.7301815407101296E+00, 0.2485339201737921E+00, 0.2127164214993764E+00, 0.4998108187459615E+00, 0.2524424849785568E+00, 0.3107607890010585E+00, 0.9666552191416621E+00, 0.1543981540828483E+00, 0.9269213106461920E+00, 0.1580490693604223E+01, 0.3640096408786760E+00, 0.3130858727896049E+00, 0.7864169332819952E+00, 0.1077686100636843E+01, 0.7535963003344312E-02, 0.7274051012980143E-01, 0.6279274220262862E+00, 0.8147329327002600E-01, 0.3379430237022286E+00, 0.5539901283655780E+00, 0.6437610281386123E-01, 0.3830459800631597E+00, 0.2847358698029713E-01, 0.1927318305890360E-01, 0.6666392685468185E-01, 0.9510720451940254E-01, 0.2827355178816361E-06, 0.3034592154998885E-04, 0.6208664319525956E-03, 0.6211134452527084E-03, 0.4264931214133004E-11, 0.7232819130731082E-07, 0.4059351646211308E-14, 0.3661024252896476E-07, 0.8437225690290790E-03, 0.5160120970399038E-02}, + pp: 0, + dmin: 4.0593516462113082E-015, + desig: 4.3344264097778650E-021, + qmax: 1.8900334961849885, + ttype: -2, + dmin1: 6.2079410376128833E-004, + dmin2: 4.5102919754957636E-002, + dn: 4.0593516462113082E-015, + dn1: 6.2079410376128833E-004, + dn2: 6.6633580933131861E-002, + g: 0.0000000000000000, + tau: 3.6605973538398975E-008, + nFail: 0, + iter: 6, + sigma: 7.8119962155206313E-005, + nDiv: 128, + zOut: []float64{0.2204217311496068E+01, 0.2307826269503742E+01, 0.1036089580076783E+00, 0.8812934261040264E-01, 0.1963027289351853E+01, 0.1924020963289845E+01, 0.4912301654839819E-01, 0.2668944646890268E-01, 0.1045356293504034E+01, 0.1148025458776649E+01, 0.1293586117415210E+00, 0.1915312145184878E+00, 0.1699791822573021E+01, 0.1591452977947247E+01, 0.8319236989271818E-01, 0.4281642408847453E-01, 0.8190694135595162E+00, 0.7770967120400667E+00, 0.8437225690290790E-03, 0.1684766835109566E-03, 0.1551726617464312E+00, 0.5742252947387723E+00, 0.4192211096758560E+00, 0.1077768810640642E+01, 0.1476266577866037E+01, 0.4753686674121431E+00, 0.7687090018675194E-01, 0.4631342794110950E-01, 0.2864016483502532E+00, 0.4130536065801048E+00, 0.1729653861709652E+00, 0.1112809541240190E+00, 0.2657468090128033E+00, 0.3916210545154161E+00, 0.2371551996266359E+00, 0.4051405202062471E+00, 0.6690199413712319E+00, 0.2993896652859737E+00, 0.3551024412099299E-01, 0.5343038813025977E-01, 0.4504758109776356E+00, 0.4013412006241577E+00, 0.4295777776785939E-02, 0.4280911574482486E-02, 0.3999522974286917E+00, 0.4138345474578556E+00, 0.1816316160365039E-01, 0.3204760309498118E-01, 0.7301815407101296E+00, 0.9108503591145208E+00, 0.2127164214993764E+00, 0.5895442813598011E-01, 0.2524424849785568E+00, 0.1160143275984235E+01, 0.9666552191416621E+00, 0.7723298847804961E+00, 0.9269213106461920E+00, 0.5186010667443678E+00, 0.3640096408786760E+00, 0.5519914319921668E+00, 0.7864169332819952E+00, 0.2419614642931688E+00, 0.7535963003344312E-02, 0.1955698951896722E-01, 0.6279274220262862E+00, 0.9463134562095434E+00, 0.3379430237022286E+00, 0.2298969194226957E-01, 0.6437610281386123E-01, 0.6985999785188474E-01, 0.2847358698029713E-01, 0.2717093011896993E-01, 0.6666392685468185E-01, 0.3949327947122574E-01, 0.2827355178816361E-06, 0.4444831994804014E-08, 0.6208664319525956E-03, 0.6208619913814727E-03, 0.4264931214133004E-11, 0.2788519153273688E-22, 0.4059351646211308E-14, 0.3786532345060857E-28, 0.8437225690290790E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 21, + ppOut: 0, + dminOut: 3.7865323450608567E-029, + desigOut: -5.4012504887129591E-021, + sigmaOut: 7.8119962159265674E-005, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 7, + nDivOut: 150, + ttypeOut: -2, + dmin1Out: 6.2086198711654151E-004, + dmin2Out: 3.9492996735707858E-002, + dnOut: 3.7865323450608567E-029, + dn1Out: 6.2086198711654151E-004, + dn2Out: 3.9492996735707858E-002, + gOut: 0.0000000000000000, + tauOut: 4.0593516183260787E-015, + }, + { + i0: 1, + n0: 21, + z: []float64{0.2204217311496068E+01, 0.2307826269503742E+01, 0.1036089580076783E+00, 0.8812934261040264E-01, 0.1963027289351853E+01, 0.1924020963289845E+01, 0.4912301654839819E-01, 0.2668944646890268E-01, 0.1045356293504034E+01, 0.1148025458776649E+01, 0.1293586117415210E+00, 0.1915312145184878E+00, 0.1699791822573021E+01, 0.1591452977947247E+01, 0.8319236989271818E-01, 0.4281642408847453E-01, 0.8190694135595162E+00, 0.7770967120400667E+00, 0.8437225690290790E-03, 0.1684766835109566E-03, 0.1551726617464312E+00, 0.5742252947387723E+00, 0.4192211096758560E+00, 0.1077768810640642E+01, 0.1476266577866037E+01, 0.4753686674121431E+00, 0.7687090018675194E-01, 0.4631342794110950E-01, 0.2864016483502532E+00, 0.4130536065801048E+00, 0.1729653861709652E+00, 0.1112809541240190E+00, 0.2657468090128033E+00, 0.3916210545154161E+00, 0.2371551996266359E+00, 0.4051405202062471E+00, 0.6690199413712319E+00, 0.2993896652859737E+00, 0.3551024412099299E-01, 0.5343038813025977E-01, 0.4504758109776356E+00, 0.4013412006241577E+00, 0.4295777776785939E-02, 0.4280911574482486E-02, 0.3999522974286917E+00, 0.4138345474578556E+00, 0.1816316160365039E-01, 0.3204760309498118E-01, 0.7301815407101296E+00, 0.9108503591145208E+00, 0.2127164214993764E+00, 0.5895442813598011E-01, 0.2524424849785568E+00, 0.1160143275984235E+01, 0.9666552191416621E+00, 0.7723298847804961E+00, 0.9269213106461920E+00, 0.5186010667443678E+00, 0.3640096408786760E+00, 0.5519914319921668E+00, 0.7864169332819952E+00, 0.2419614642931688E+00, 0.7535963003344312E-02, 0.1955698951896722E-01, 0.6279274220262862E+00, 0.9463134562095434E+00, 0.3379430237022286E+00, 0.2298969194226957E-01, 0.6437610281386123E-01, 0.6985999785188474E-01, 0.2847358698029713E-01, 0.2717093011896993E-01, 0.6666392685468185E-01, 0.3949327947122574E-01, 0.2827355178816361E-06, 0.4444831994804014E-08, 0.6208664319525956E-03, 0.6208619913814727E-03, 0.4264931214133004E-11, 0.2788519153273688E-22, 0.4059351646211308E-14, 0.3786532345060857E-28, 0.8437225690290790E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 3.7865323450608567E-029, + desig: -5.4012504887129591E-021, + qmax: 1.8900334961849885, + ttype: -2, + dmin1: 6.2086198711654151E-004, + dmin2: 3.9492996735707858E-002, + dn: 3.7865323450608567E-029, + dn1: 6.2086198711654151E-004, + dn2: 3.9492996735707858E-002, + g: 0.0000000000000000, + tau: 4.0593516183260787E-015, + nFail: 0, + iter: 7, + sigma: 7.8119962159265674E-005, + nDiv: 150, + zOut: []float64{0.2395955612114145E+01, 0.2307826269503742E+01, 0.7077038564739886E-01, 0.8812934261040264E-01, 0.1879940024111348E+01, 0.1924020963289845E+01, 0.1629847954401656E-01, 0.2668944646890268E-01, 0.1323258193751120E+01, 0.1148025458776649E+01, 0.2303502998543534E+00, 0.1915312145184878E+00, 0.1403919102181368E+01, 0.1591452977947247E+01, 0.2369972908607684E-01, 0.4281642408847453E-01, 0.7535654596375009E+00, 0.7770967120400667E+00, 0.1283811140869274E-03, 0.1684766835109566E-03, 0.1651865724265327E+01, 0.5742252947387723E+00, 0.3101568824672333E+00, 0.1077768810640642E+01, 0.2115252128860193E+00, 0.4753686674121431E+00, 0.9043805314343908E-01, 0.4631342794110950E-01, 0.4338965075606848E+00, 0.4130536065801048E+00, 0.1004386157577793E+00, 0.1112809541240190E+00, 0.6963229589638840E+00, 0.3916210545154161E+00, 0.1741934301847783E+00, 0.4051405202062471E+00, 0.1786266232314551E+00, 0.2993896652859737E+00, 0.1200482645536405E+00, 0.5343038813025977E-01, 0.2855738476449996E+00, 0.4013412006241577E+00, 0.6203611145567293E-02, 0.4280911574482486E-02, 0.4396785394072695E+00, 0.4138345474578556E+00, 0.6639071087521134E-01, 0.3204760309498118E-01, 0.9034140763752896E+00, 0.9108503591145208E+00, 0.7570790092830114E-01, 0.5895442813598011E-01, 0.1856765259836430E+01, 0.1160143275984235E+01, 0.2157144528657351E+00, 0.7723298847804961E+00, 0.8548780458707995E+00, 0.5186010667443678E+00, 0.1562335771835849E+00, 0.5519914319921668E+00, 0.1052848766285511E+00, 0.2419614642931688E+00, 0.1757806338135458E+00, 0.1955698951896722E-01, 0.7935225143382671E+00, 0.9463134562095434E+00, 0.2023962522401480E-02, 0.2298969194226957E-01, 0.9500696544845319E-01, 0.6985999785188474E-01, 0.1129463646814219E-01, 0.2717093011896993E-01, 0.2819864744791555E-01, 0.3949327947122574E-01, 0.9786381594178541E-10, 0.4444831994804014E-08, 0.6208618935176568E-03, 0.6208619913814727E-03, 0.1700670967075909E-47, 0.2788519153273688E-22, 0.3786532345060857E-28, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 21, + ppOut: 1, + dminOut: 3.7865323450608567E-029, + desigOut: -5.4012504887129591E-021, + sigmaOut: 7.8119962159265674E-005, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 8, + nDivOut: 172, + ttypeOut: -2, + dmin1Out: 6.2086189351765679E-004, + dmin2Out: 2.8198643003083550E-002, + dnOut: 3.7865323450608567E-029, + dn1Out: 6.2086189351765679E-004, + dn2Out: 2.8198643003083550E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 21, + z: []float64{0.2395955612114145E+01, 0.2307826269503742E+01, 0.7077038564739886E-01, 0.8812934261040264E-01, 0.1879940024111348E+01, 0.1924020963289845E+01, 0.1629847954401656E-01, 0.2668944646890268E-01, 0.1323258193751120E+01, 0.1148025458776649E+01, 0.2303502998543534E+00, 0.1915312145184878E+00, 0.1403919102181368E+01, 0.1591452977947247E+01, 0.2369972908607684E-01, 0.4281642408847453E-01, 0.7535654596375009E+00, 0.7770967120400667E+00, 0.1283811140869274E-03, 0.1684766835109566E-03, 0.1651865724265327E+01, 0.5742252947387723E+00, 0.3101568824672333E+00, 0.1077768810640642E+01, 0.2115252128860193E+00, 0.4753686674121431E+00, 0.9043805314343908E-01, 0.4631342794110950E-01, 0.4338965075606848E+00, 0.4130536065801048E+00, 0.1004386157577793E+00, 0.1112809541240190E+00, 0.6963229589638840E+00, 0.3916210545154161E+00, 0.1741934301847783E+00, 0.4051405202062471E+00, 0.1786266232314551E+00, 0.2993896652859737E+00, 0.1200482645536405E+00, 0.5343038813025977E-01, 0.2855738476449996E+00, 0.4013412006241577E+00, 0.6203611145567293E-02, 0.4280911574482486E-02, 0.4396785394072695E+00, 0.4138345474578556E+00, 0.6639071087521134E-01, 0.3204760309498118E-01, 0.9034140763752896E+00, 0.9108503591145208E+00, 0.7570790092830114E-01, 0.5895442813598011E-01, 0.1856765259836430E+01, 0.1160143275984235E+01, 0.2157144528657351E+00, 0.7723298847804961E+00, 0.8548780458707995E+00, 0.5186010667443678E+00, 0.1562335771835849E+00, 0.5519914319921668E+00, 0.1052848766285511E+00, 0.2419614642931688E+00, 0.1757806338135458E+00, 0.1955698951896722E-01, 0.7935225143382671E+00, 0.9463134562095434E+00, 0.2023962522401480E-02, 0.2298969194226957E-01, 0.9500696544845319E-01, 0.6985999785188474E-01, 0.1129463646814219E-01, 0.2717093011896993E-01, 0.2819864744791555E-01, 0.3949327947122574E-01, 0.9786381594178541E-10, 0.4444831994804014E-08, 0.6208618935176568E-03, 0.6208619913814727E-03, 0.1700670967075909E-47, 0.2788519153273688E-22, 0.3786532345060857E-28, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 3.7865323450608567E-029, + desig: -5.4012504887129591E-021, + qmax: 1.8900334961849885, + ttype: -2, + dmin1: 6.2086189351765679E-004, + dmin2: 2.8198643003083550E-002, + dn: 3.7865323450608567E-029, + dn1: 6.2086189351765679E-004, + dn2: 2.8198643003083550E-002, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 8, + sigma: 7.8119962159265674E-005, + nDiv: 172, + zOut: []float64{0.2395955612114145E+01, 0.2466725997761544E+01, 0.7077038564739886E-01, 0.5393549207373363E-01, 0.1879940024111348E+01, 0.1842303011581631E+01, 0.1629847954401656E-01, 0.1170659574821484E-01, 0.1323258193751120E+01, 0.1541901897857258E+01, 0.2303502998543534E+00, 0.2097365510789915E+00, 0.1403919102181368E+01, 0.1217882280188454E+01, 0.2369972908607684E-01, 0.1466422291592108E-01, 0.7535654596375009E+00, 0.7390296178356669E+00, 0.1283811140869274E-03, 0.2869551596920546E-03, 0.1651865724265327E+01, 0.1961735651572868E+01, 0.3101568824672333E+00, 0.3344283443049241E-01, 0.2115252128860193E+00, 0.2685204315989660E+00, 0.9043805314343908E-01, 0.1461369444993732E+00, 0.4338965075606848E+00, 0.3881981788190908E+00, 0.1004386157577793E+00, 0.1801598202532681E+00, 0.6963229589638840E+00, 0.6903565688953941E+00, 0.1741934301847783E+00, 0.4507175802324546E-01, 0.1786266232314551E+00, 0.2536031297618502E+00, 0.1200482645536405E+00, 0.1351822623162481E+00, 0.2855738476449996E+00, 0.1565951964743188E+00, 0.6203611145567293E-02, 0.1741812487831326E-01, 0.4396785394072695E+00, 0.4886511254041676E+00, 0.6639071087521134E-01, 0.1227425859208231E+00, 0.9034140763752896E+00, 0.8563793913827676E+00, 0.7570790092830114E-01, 0.1641466407918003E+00, 0.1856765259836430E+01, 0.1908333071910365E+01, 0.2157144528657351E+00, 0.9663383852973971E-01, 0.8548780458707995E+00, 0.9144777845246447E+00, 0.1562335771835849E+00, 0.1798735100772441E-01, 0.1052848766285511E+00, 0.2630781594343725E+00, 0.1757806338135458E+00, 0.5302070335887964E+00, 0.7935225143382671E+00, 0.2653394432718723E+00, 0.2023962522401480E-02, 0.7246963929058098E-03, 0.9500696544845319E-01, 0.1055769055236896E+00, 0.1129463646814219E-01, 0.3016696409481782E-02, 0.2819864744791555E-01, 0.2518195113629758E-01, 0.9786381594178541E-10, 0.2412835834031154E-11, 0.6208618935176568E-03, 0.6208618911048210E-03, 0.1700670967075909E-47, 0.2869551596920546E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 20, + ppOut: 0, + dminOut: 6.2086189110482101E-004, + desigOut: -5.4012504887129591E-021, + sigmaOut: 7.8119962159265674E-005, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 9, + nDivOut: 193, + ttypeOut: -7, + dmin1Out: 2.5181951038433764E-002, + dmin2Out: 8.7297525620826724E-002, + dnOut: 6.2086189110482101E-004, + dn1Out: 2.5181951038433764E-002, + dn2Out: 9.4282269055547374E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2395955612114145E+01, 0.2466725997761544E+01, 0.7077038564739886E-01, 0.5393549207373363E-01, 0.1879940024111348E+01, 0.1842303011581631E+01, 0.1629847954401656E-01, 0.1170659574821484E-01, 0.1323258193751120E+01, 0.1541901897857258E+01, 0.2303502998543534E+00, 0.2097365510789915E+00, 0.1403919102181368E+01, 0.1217882280188454E+01, 0.2369972908607684E-01, 0.1466422291592108E-01, 0.7535654596375009E+00, 0.7390296178356669E+00, 0.1283811140869274E-03, 0.2869551596920546E-03, 0.1651865724265327E+01, 0.1961735651572868E+01, 0.3101568824672333E+00, 0.3344283443049241E-01, 0.2115252128860193E+00, 0.2685204315989660E+00, 0.9043805314343908E-01, 0.1461369444993732E+00, 0.4338965075606848E+00, 0.3881981788190908E+00, 0.1004386157577793E+00, 0.1801598202532681E+00, 0.6963229589638840E+00, 0.6903565688953941E+00, 0.1741934301847783E+00, 0.4507175802324546E-01, 0.1786266232314551E+00, 0.2536031297618502E+00, 0.1200482645536405E+00, 0.1351822623162481E+00, 0.2855738476449996E+00, 0.1565951964743188E+00, 0.6203611145567293E-02, 0.1741812487831326E-01, 0.4396785394072695E+00, 0.4886511254041676E+00, 0.6639071087521134E-01, 0.1227425859208231E+00, 0.9034140763752896E+00, 0.8563793913827676E+00, 0.7570790092830114E-01, 0.1641466407918003E+00, 0.1856765259836430E+01, 0.1908333071910365E+01, 0.2157144528657351E+00, 0.9663383852973971E-01, 0.8548780458707995E+00, 0.9144777845246447E+00, 0.1562335771835849E+00, 0.1798735100772441E-01, 0.1052848766285511E+00, 0.2630781594343725E+00, 0.1757806338135458E+00, 0.5302070335887964E+00, 0.7935225143382671E+00, 0.2653394432718723E+00, 0.2023962522401480E-02, 0.7246963929058098E-03, 0.9500696544845319E-01, 0.1055769055236896E+00, 0.1129463646814219E-01, 0.3016696409481782E-02, 0.2819864744791555E-01, 0.2518195113629758E-01, 0.9786381594178541E-10, 0.2412835834031154E-11, 0.6208618935176568E-03, 0.6208618911048210E-03, 0.1700670967075909E-47, 0.2869551596920546E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 6.2086189110482101E-004, + desig: -5.4012504887129591E-021, + qmax: 1.8900334961849885, + ttype: -7, + dmin1: 2.5181951038433764E-002, + dmin2: 8.7297525620826724E-002, + dn: 6.2086189110482101E-004, + dn1: 2.5181951038433764E-002, + dn2: 9.4282269055547374E-002, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 9, + sigma: 7.8119962159265674E-005, + nDiv: 193, + zOut: []float64{0.2520040627944239E+01, 0.2466725997761544E+01, 0.3943012599746679E-01, 0.5393549207373363E-01, 0.1813958619441340E+01, 0.1842303011581631E+01, 0.9950845630193767E-02, 0.1170659574821484E-01, 0.1741066741415017E+01, 0.1541901897857258E+01, 0.1467114516582776E+00, 0.2097365510789915E+00, 0.1085214189555058E+01, 0.1217882280188454E+01, 0.9986318978978259E-02, 0.1466422291592108E-01, 0.7287093921253419E+00, 0.7390296178356669E+00, 0.7725029665513934E-03, 0.2869551596920546E-03, 0.1993785121145770E+01, 0.1961735651572868E+01, 0.4504038193447841E-02, 0.3344283443049241E-01, 0.4095324760138526E+00, 0.2685204315989660E+00, 0.1385240464077977E+00, 0.1461369444993732E+00, 0.4292130907735224E+00, 0.3881981788190908E+00, 0.2897733504323247E+00, 0.1801598202532681E+00, 0.4450341145952761E+00, 0.6903565688953941E+00, 0.2568418582687495E-01, 0.4507175802324546E-01, 0.3624803443601846E+00, 0.2536031297618502E+00, 0.5840011260368079E-01, 0.1351822623162481E+00, 0.1149923468579125E+00, 0.1565951964743188E+00, 0.7401698075381481E-01, 0.1741812487831326E-01, 0.5367558686801371E+00, 0.4886511254041676E+00, 0.1958324578473516E+00, 0.1227425859208231E+00, 0.8240727124361776E+00, 0.8563793913827676E+00, 0.3801199318200257E+00, 0.1641466407918003E+00, 0.1624226116729040E+01, 0.1908333071910365E+01, 0.5440714051978934E-01, 0.9663383852973971E-01, 0.8774371331215411E+00, 0.9144777845246447E+00, 0.5393069221241477E-02, 0.1798735100772441E-01, 0.7872712619108886E+00, 0.2630781594343725E+00, 0.1786993199393658E+00, 0.5302070335887964E+00, 0.8674395783437358E-01, 0.2653394432718723E+00, 0.8820349511059155E-03, 0.7246963929058098E-03, 0.1070907050910267E+00, 0.1055769055236896E+00, 0.7093640994523618E-03, 0.3016696409481782E-02, 0.2385172514821930E-01, 0.2518195113629758E-01, 0.6280626703238275E-13, 0.2412835834031154E-11, 0.3257377007015450E-14, 0.6208618911048210E-03, 0.7725029665513934E-03, 0.2869551596920546E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 20, + ppOut: 1, + dminOut: 3.2573770070154495E-015, + desigOut: 2.1703803823424652E-020, + sigmaOut: 6.9898185319802297E-004, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 10, + nDivOut: 214, + ttypeOut: -2, + dmin1Out: 2.3851725145806461E-002, + dmin2Out: 8.6019261441467765E-002, + dnOut: 3.2573770070154495E-015, + dn1Out: 2.3851725145806461E-002, + dn2Out: 0.10407400868154487, + gOut: 0.0000000000000000, + tauOut: 6.2086189103875732E-004, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2520040627944239E+01, 0.2466725997761544E+01, 0.3943012599746679E-01, 0.5393549207373363E-01, 0.1813958619441340E+01, 0.1842303011581631E+01, 0.9950845630193767E-02, 0.1170659574821484E-01, 0.1741066741415017E+01, 0.1541901897857258E+01, 0.1467114516582776E+00, 0.2097365510789915E+00, 0.1085214189555058E+01, 0.1217882280188454E+01, 0.9986318978978259E-02, 0.1466422291592108E-01, 0.7287093921253419E+00, 0.7390296178356669E+00, 0.7725029665513934E-03, 0.2869551596920546E-03, 0.1993785121145770E+01, 0.1961735651572868E+01, 0.4504038193447841E-02, 0.3344283443049241E-01, 0.4095324760138526E+00, 0.2685204315989660E+00, 0.1385240464077977E+00, 0.1461369444993732E+00, 0.4292130907735224E+00, 0.3881981788190908E+00, 0.2897733504323247E+00, 0.1801598202532681E+00, 0.4450341145952761E+00, 0.6903565688953941E+00, 0.2568418582687495E-01, 0.4507175802324546E-01, 0.3624803443601846E+00, 0.2536031297618502E+00, 0.5840011260368079E-01, 0.1351822623162481E+00, 0.1149923468579125E+00, 0.1565951964743188E+00, 0.7401698075381481E-01, 0.1741812487831326E-01, 0.5367558686801371E+00, 0.4886511254041676E+00, 0.1958324578473516E+00, 0.1227425859208231E+00, 0.8240727124361776E+00, 0.8563793913827676E+00, 0.3801199318200257E+00, 0.1641466407918003E+00, 0.1624226116729040E+01, 0.1908333071910365E+01, 0.5440714051978934E-01, 0.9663383852973971E-01, 0.8774371331215411E+00, 0.9144777845246447E+00, 0.5393069221241477E-02, 0.1798735100772441E-01, 0.7872712619108886E+00, 0.2630781594343725E+00, 0.1786993199393658E+00, 0.5302070335887964E+00, 0.8674395783437358E-01, 0.2653394432718723E+00, 0.8820349511059155E-03, 0.7246963929058098E-03, 0.1070907050910267E+00, 0.1055769055236896E+00, 0.7093640994523618E-03, 0.3016696409481782E-02, 0.2385172514821930E-01, 0.2518195113629758E-01, 0.6280626703238275E-13, 0.2412835834031154E-11, 0.3257377007015450E-14, 0.6208618911048210E-03, 0.7725029665513934E-03, 0.2869551596920546E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 3.2573770070154495E-015, + desig: 2.1703803823424652E-020, + qmax: 1.8900334961849885, + ttype: -2, + dmin1: 2.3851725145806461E-002, + dmin2: 8.6019261441467765E-002, + dn: 3.2573770070154495E-015, + dn1: 2.3851725145806461E-002, + dn2: 0.10407400868154487, + g: 0.0000000000000000, + tau: 6.2086189103875732E-004, + nFail: 0, + iter: 10, + sigma: 6.9898185319802297E-004, + nDiv: 214, + zOut: []float64{0.2520040627944239E+01, 0.2559470753941703E+01, 0.3943012599746679E-01, 0.2794508075882943E-01, 0.1813958619441340E+01, 0.1795964384312701E+01, 0.9950845630193767E-02, 0.9646675917972324E-02, 0.1741066741415017E+01, 0.1878131517155319E+01, 0.1467114516582776E+00, 0.8477220453173254E-01, 0.1085214189555058E+01, 0.1010428304002300E+01, 0.9986318978978259E-02, 0.7202019583097946E-02, 0.7287093921253419E+00, 0.7222798755087921E+00, 0.7725029665513934E-03, 0.2132421202606784E-02, 0.1993785121145770E+01, 0.1996156738136608E+01, 0.4504038193447841E-02, 0.9240506410060376E-03, 0.4095324760138526E+00, 0.5471324717806409E+00, 0.1385240464077977E+00, 0.1086689918286978E+00, 0.4292130907735224E+00, 0.6103174493771462E+00, 0.2897733504323247E+00, 0.2112982785836522E+00, 0.4450341145952761E+00, 0.2594200218384955E+00, 0.2568418582687495E-01, 0.3588779484774172E-01, 0.3624803443601846E+00, 0.3849926621161204E+00, 0.5840011260368079E-01, 0.1744336104525046E-01, 0.1149923468579125E+00, 0.1715659665664736E+00, 0.7401698075381481E-01, 0.2315671901408358E+00, 0.5367558686801371E+00, 0.5010211363866497E+00, 0.1958324578473516E+00, 0.3221025481782661E+00, 0.8240727124361776E+00, 0.8820900960779340E+00, 0.3801199318200257E+00, 0.6999293195746292E+00, 0.1624226116729040E+01, 0.9787039376741966E+00, 0.5440714051978934E-01, 0.4877761656142095E-01, 0.8774371331215411E+00, 0.8340525857813585E+00, 0.5393069221241477E-02, 0.5090576402208483E-02, 0.7872712619108886E+00, 0.9608800054480426E+00, 0.1786993199393658E+00, 0.1613217694817542E-01, 0.8674395783437358E-01, 0.7149381583730083E-01, 0.8820349511059155E-03, 0.1321201613351008E-02, 0.1070907050910267E+00, 0.1064788675771248E+00, 0.7093640994523618E-03, 0.1589006148839502E-03, 0.2385172514821930E-01, 0.2369282453339490E-01, 0.6280626703238275E-13, 0.8634837515442557E-26, 0.3257377007015450E-14, 0.9466330862652142E-28, 0.7725029665513934E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 20, + ppOut: 0, + dminOut: 9.4663308626521417E-029, + desigOut: 2.1703795093889875E-020, + sigmaOut: 6.9898185320128035E-004, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 11, + nDivOut: 235, + ttypeOut: -2, + dmin1Out: 2.3692824533332088E-002, + dmin2Out: 7.0611780886194908E-002, + dnOut: 9.4663308626521417E-029, + dn1Out: 2.3692824533332088E-002, + dn2Out: 0.10576950347767239, + gOut: 0.0000000000000000, + tauOut: 3.2573770070067200E-015, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2520040627944239E+01, 0.2559470753941703E+01, 0.3943012599746679E-01, 0.2794508075882943E-01, 0.1813958619441340E+01, 0.1795964384312701E+01, 0.9950845630193767E-02, 0.9646675917972324E-02, 0.1741066741415017E+01, 0.1878131517155319E+01, 0.1467114516582776E+00, 0.8477220453173254E-01, 0.1085214189555058E+01, 0.1010428304002300E+01, 0.9986318978978259E-02, 0.7202019583097946E-02, 0.7287093921253419E+00, 0.7222798755087921E+00, 0.7725029665513934E-03, 0.2132421202606784E-02, 0.1993785121145770E+01, 0.1996156738136608E+01, 0.4504038193447841E-02, 0.9240506410060376E-03, 0.4095324760138526E+00, 0.5471324717806409E+00, 0.1385240464077977E+00, 0.1086689918286978E+00, 0.4292130907735224E+00, 0.6103174493771462E+00, 0.2897733504323247E+00, 0.2112982785836522E+00, 0.4450341145952761E+00, 0.2594200218384955E+00, 0.2568418582687495E-01, 0.3588779484774172E-01, 0.3624803443601846E+00, 0.3849926621161204E+00, 0.5840011260368079E-01, 0.1744336104525046E-01, 0.1149923468579125E+00, 0.1715659665664736E+00, 0.7401698075381481E-01, 0.2315671901408358E+00, 0.5367558686801371E+00, 0.5010211363866497E+00, 0.1958324578473516E+00, 0.3221025481782661E+00, 0.8240727124361776E+00, 0.8820900960779340E+00, 0.3801199318200257E+00, 0.6999293195746292E+00, 0.1624226116729040E+01, 0.9787039376741966E+00, 0.5440714051978934E-01, 0.4877761656142095E-01, 0.8774371331215411E+00, 0.8340525857813585E+00, 0.5393069221241477E-02, 0.5090576402208483E-02, 0.7872712619108886E+00, 0.9608800054480426E+00, 0.1786993199393658E+00, 0.1613217694817542E-01, 0.8674395783437358E-01, 0.7149381583730083E-01, 0.8820349511059155E-03, 0.1321201613351008E-02, 0.1070907050910267E+00, 0.1064788675771248E+00, 0.7093640994523618E-03, 0.1589006148839502E-03, 0.2385172514821930E-01, 0.2369282453339490E-01, 0.6280626703238275E-13, 0.8634837515442557E-26, 0.3257377007015450E-14, 0.9466330862652142E-28, 0.7725029665513934E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 9.4663308626521417E-029, + desig: 2.1703795093889875E-020, + qmax: 1.8900334961849885, + ttype: -2, + dmin1: 2.3692824533332088E-002, + dmin2: 7.0611780886194908E-002, + dn: 9.4663308626521417E-029, + dn1: 2.3692824533332088E-002, + dn2: 0.10576950347767239, + g: 0.0000000000000000, + tau: 3.2573770070067200E-015, + nFail: 0, + iter: 11, + sigma: 6.9898185320128035E-004, + nDiv: 235, + zOut: []float64{0.2587415834700532E+01, 0.2559470753941703E+01, 0.1939710234687058E-01, 0.2794508075882943E-01, 0.1786213957883803E+01, 0.1795964384312701E+01, 0.1014308840067055E-01, 0.9646675917972324E-02, 0.1952760633286381E+01, 0.1878131517155319E+01, 0.4386417535844126E-01, 0.8477220453173254E-01, 0.9737661482269571E+00, 0.1010428304002300E+01, 0.5342015449359675E-02, 0.7202019583097946E-02, 0.7190702812620393E+00, 0.7222798755087921E+00, 0.5919653562455767E-02, 0.2132421202606784E-02, 0.1991161135215158E+01, 0.1996156738136608E+01, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.6555475524103290E+00, 0.5471324717806409E+00, 0.1011712753337584E+00, 0.1086689918286978E+00, 0.7204444526270400E+00, 0.6103174493771462E+00, 0.7608498315828412E-01, 0.2112982785836522E+00, 0.2192228335279531E+00, 0.2594200218384955E+00, 0.6302508481237896E-01, 0.3588779484774172E-01, 0.3394109383489919E+00, 0.3849926621161204E+00, 0.8817297145618809E-02, 0.1744336104525046E-01, 0.3943158595616905E+00, 0.1715659665664736E+00, 0.2942312715577539E+00, 0.2315671901408358E+00, 0.5288924130071619E+00, 0.5010211363866497E+00, 0.5372046576619481E+00, 0.3221025481782661E+00, 0.1044814757990615E+01, 0.8820900960779340E+00, 0.6556411803358774E+00, 0.6999293195746292E+00, 0.3718403738997403E+00, 0.9787039376741966E+00, 0.1094101127175453E+00, 0.4877761656142095E-01, 0.7297330494660218E+00, 0.8340525857813585E+00, 0.6703044469024726E-02, 0.5090576402208483E-02, 0.9703091379271934E+00, 0.9608800054480426E+00, 0.1188642714683105E-02, 0.1613217694817542E-01, 0.7162637473596872E-01, 0.7149381583730083E-01, 0.1964081696850700E-02, 0.1321201613351008E-02, 0.1046736864951580E+00, 0.1064788675771248E+00, 0.3596705640885345E-04, 0.1589006148839502E-03, 0.2365685747698604E-01, 0.2369282453339490E-01, 0.3455244592226135E-52, 0.8634837515442557E-26, 0.9466330862652142E-28, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 20, + ppOut: 1, + dminOut: 9.4663308626521417E-029, + desigOut: 2.1703795093889875E-020, + sigmaOut: 6.9898185320128035E-004, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 12, + nDivOut: 256, + ttypeOut: -2, + dmin1Out: 2.3656857476986041E-002, + dmin2Out: 7.0305173122617720E-002, + dnOut: 9.4663308626521417E-029, + dn1Out: 2.3656857476986041E-002, + dn2Out: 0.10451478588027406, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 20, + z: []float64{0.2587415834700532E+01, 0.2559470753941703E+01, 0.1939710234687058E-01, 0.2794508075882943E-01, 0.1786213957883803E+01, 0.1795964384312701E+01, 0.1014308840067055E-01, 0.9646675917972324E-02, 0.1952760633286381E+01, 0.1878131517155319E+01, 0.4386417535844126E-01, 0.8477220453173254E-01, 0.9737661482269571E+00, 0.1010428304002300E+01, 0.5342015449359675E-02, 0.7202019583097946E-02, 0.7190702812620393E+00, 0.7222798755087921E+00, 0.5919653562455767E-02, 0.2132421202606784E-02, 0.1991161135215158E+01, 0.1996156738136608E+01, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.6555475524103290E+00, 0.5471324717806409E+00, 0.1011712753337584E+00, 0.1086689918286978E+00, 0.7204444526270400E+00, 0.6103174493771462E+00, 0.7608498315828412E-01, 0.2112982785836522E+00, 0.2192228335279531E+00, 0.2594200218384955E+00, 0.6302508481237896E-01, 0.3588779484774172E-01, 0.3394109383489919E+00, 0.3849926621161204E+00, 0.8817297145618809E-02, 0.1744336104525046E-01, 0.3943158595616905E+00, 0.1715659665664736E+00, 0.2942312715577539E+00, 0.2315671901408358E+00, 0.5288924130071619E+00, 0.5010211363866497E+00, 0.5372046576619481E+00, 0.3221025481782661E+00, 0.1044814757990615E+01, 0.8820900960779340E+00, 0.6556411803358774E+00, 0.6999293195746292E+00, 0.3718403738997403E+00, 0.9787039376741966E+00, 0.1094101127175453E+00, 0.4877761656142095E-01, 0.7297330494660218E+00, 0.8340525857813585E+00, 0.6703044469024726E-02, 0.5090576402208483E-02, 0.9703091379271934E+00, 0.9608800054480426E+00, 0.1188642714683105E-02, 0.1613217694817542E-01, 0.7162637473596872E-01, 0.7149381583730083E-01, 0.1964081696850700E-02, 0.1321201613351008E-02, 0.1046736864951580E+00, 0.1064788675771248E+00, 0.3596705640885345E-04, 0.1589006148839502E-03, 0.2365685747698604E-01, 0.2369282453339490E-01, 0.3455244592226135E-52, 0.8634837515442557E-26, 0.9466330862652142E-28, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 9.4663308626521417E-029, + desig: 2.1703795093889875E-020, + qmax: 1.8900334961849885, + ttype: -2, + dmin1: 2.3656857476986041E-002, + dmin2: 7.0305173122617720E-002, + dn: 9.4663308626521417E-029, + dn1: 2.3656857476986041E-002, + dn2: 0.10451478588027406, + g: 0.0000000000000000, + tau: 0.0000000000000000, + nFail: 0, + iter: 12, + sigma: 6.9898185320128035E-004, + nDiv: 256, + zOut: []float64{0.2587415834700532E+01, 0.2594984508308910E+01, 0.1939710234687058E-01, 0.1335166928493912E-01, 0.1786213957883803E+01, 0.1771176948261041E+01, 0.1014308840067055E-01, 0.1118297285215907E-01, 0.1952760633286381E+01, 0.1973613407054170E+01, 0.4386417535844126E-01, 0.2164225725832272E-01, 0.9737661482269571E+00, 0.9456374776795010E+00, 0.5342015449359675E-02, 0.4062111160297227E-02, 0.7190702812620393E+00, 0.7090993949257048E+00, 0.5919653562455767E-02, 0.1662247097070905E-01, 0.1991161135215158E+01, 0.1962964146704966E+01, 0.2539111990097616E-03, 0.8479567256479229E-04, 0.6555475524103290E+00, 0.7448056033330296E+00, 0.1011712753337584E+00, 0.9786215859981671E-01, 0.7204444526270400E+00, 0.6868388484470145E+00, 0.7608498315828412E-01, 0.2428454015756268E-01, 0.2192228335279531E+00, 0.2461349494442763E+00, 0.6302508481237896E-01, 0.8690924724014965E-01, 0.3394109383489919E+00, 0.2494905595159681E+00, 0.8817297145618809E-02, 0.1393559784278329E-01, 0.3943158595616905E+00, 0.6627831045381681E+00, 0.2942312715577539E+00, 0.2347927793131975E+00, 0.5288924130071619E+00, 0.8194758626174196E+00, 0.5372046576619481E+00, 0.6849248159595133E+00, 0.1044814757990615E+01, 0.1003702693628486E+01, 0.6556411803358774E+00, 0.2428944977310168E+00, 0.3718403738997403E+00, 0.2265275601477758E+00, 0.1094101127175453E+00, 0.3524523689025369E+00, 0.7297330494660218E+00, 0.3721552962940165E+00, 0.6703044469024726E-02, 0.1747664312451059E-01, 0.9703091379271934E+00, 0.9421927087788731E+00, 0.1188642714683105E-02, 0.9036173567869616E-04, 0.7162637473596872E-01, 0.6167166595864771E-01, 0.1964081696850700E-02, 0.3333583884775863E-02, 0.1046736864951580E+00, 0.8954764092829798E-01, 0.3596705640885345E-04, 0.9501841907954501E-05, 0.2365685747698604E-01, 0.1181892689658507E-01, 0.3455244592226135E-52, 0.8479567256479229E-04, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 19, + ppOut: 0, + dminOut: 1.1818926896585069E-002, + desigOut: 3.4696444683954120E-019, + sigmaOut: 1.2527410591694300E-002, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 13, + nDivOut: 276, + ttypeOut: -9, + dmin1Out: 5.9707584261797009E-002, + dmin2Out: 5.9707584261797009E-002, + dnOut: 1.1818926896585069E-002, + dn1Out: 8.9511673871889130E-002, + dn2Out: 5.9707584261797009E-002, + gOut: 0.0000000000000000, + tauOut: 1.1828428738493020E-002, + }, + { + i0: 1, + n0: 19, + z: []float64{0.2587415834700532E+01, 0.2594984508308910E+01, 0.1939710234687058E-01, 0.1335166928493912E-01, 0.1786213957883803E+01, 0.1771176948261041E+01, 0.1014308840067055E-01, 0.1118297285215907E-01, 0.1952760633286381E+01, 0.1973613407054170E+01, 0.4386417535844126E-01, 0.2164225725832272E-01, 0.9737661482269571E+00, 0.9456374776795010E+00, 0.5342015449359675E-02, 0.4062111160297227E-02, 0.7190702812620393E+00, 0.7090993949257048E+00, 0.5919653562455767E-02, 0.1662247097070905E-01, 0.1991161135215158E+01, 0.1962964146704966E+01, 0.2539111990097616E-03, 0.8479567256479229E-04, 0.6555475524103290E+00, 0.7448056033330296E+00, 0.1011712753337584E+00, 0.9786215859981671E-01, 0.7204444526270400E+00, 0.6868388484470145E+00, 0.7608498315828412E-01, 0.2428454015756268E-01, 0.2192228335279531E+00, 0.2461349494442763E+00, 0.6302508481237896E-01, 0.8690924724014965E-01, 0.3394109383489919E+00, 0.2494905595159681E+00, 0.8817297145618809E-02, 0.1393559784278329E-01, 0.3943158595616905E+00, 0.6627831045381681E+00, 0.2942312715577539E+00, 0.2347927793131975E+00, 0.5288924130071619E+00, 0.8194758626174196E+00, 0.5372046576619481E+00, 0.6849248159595133E+00, 0.1044814757990615E+01, 0.1003702693628486E+01, 0.6556411803358774E+00, 0.2428944977310168E+00, 0.3718403738997403E+00, 0.2265275601477758E+00, 0.1094101127175453E+00, 0.3524523689025369E+00, 0.7297330494660218E+00, 0.3721552962940165E+00, 0.6703044469024726E-02, 0.1747664312451059E-01, 0.9703091379271934E+00, 0.9421927087788731E+00, 0.1188642714683105E-02, 0.9036173567869616E-04, 0.7162637473596872E-01, 0.6167166595864771E-01, 0.1964081696850700E-02, 0.3333583884775863E-02, 0.1046736864951580E+00, 0.8954764092829798E-01, 0.3596705640885345E-04, 0.9501841907954501E-05, 0.2365685747698604E-01, 0.1181892689658507E-01, 0.3455244592226135E-52, 0.8479567256479229E-04, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 1.1818926896585069E-002, + desig: 3.4696444683954120E-019, + qmax: 1.8900334961849885, + ttype: -9, + dmin1: 5.9707584261797009E-002, + dmin2: 5.9707584261797009E-002, + dn: 1.1818926896585069E-002, + dn1: 8.9511673871889130E-002, + dn2: 5.9707584261797009E-002, + g: 0.0000000000000000, + tau: 1.1828428738493020E-002, + nFail: 0, + iter: 13, + sigma: 1.2527410591694300E-002, + nDiv: 276, + zOut: []float64{0.2596646703688871E+01, 0.2594984508308910E+01, 0.9107195378059658E-02, 0.1335166928493912E-01, 0.1761563251830163E+01, 0.1771176948261041E+01, 0.1252913577120413E-01, 0.1118297285215907E-01, 0.1971037054636311E+01, 0.1973613407054170E+01, 0.1038322923301279E-01, 0.2164225725832272E-01, 0.9276268857018078E+00, 0.9456374776795010E+00, 0.3105171497598932E-02, 0.4062111160297227E-02, 0.7109272204938374E+00, 0.7090993949257048E+00, 0.4589684232723624E-01, 0.1662247097070905E-01, 0.1905462626145317E+01, 0.1962964146704966E+01, 0.3314486004504485E-04, 0.8479567256479229E-04, 0.8309451431678238E+00, 0.7448056033330296E+00, 0.8089045693556918E-01, 0.9786215859981671E-01, 0.6185434577640304E+00, 0.6868388484470145E+00, 0.9663466631053550E-02, 0.2428454015756268E-01, 0.3116912561483949E+00, 0.2461349494442763E+00, 0.6956575230565126E-01, 0.8690924724014965E-01, 0.1821709311481225E+00, 0.2494905595159681E+00, 0.5070116699532772E-01, 0.1393559784278329E-01, 0.8351852429510604E+00, 0.6627831045381681E+00, 0.2303764547900405E+00, 0.2347927793131975E+00, 0.1262334749881915E+01, 0.8194758626174196E+00, 0.5445947541061251E+00, 0.6849248159595133E+00, 0.6903129633483998E+00, 0.1003702693628486E+01, 0.7970630839299049E-01, 0.2428944977310168E+00, 0.4875841467523446E+00, 0.2265275601477758E+00, 0.2690141110044630E+00, 0.3524523689025369E+00, 0.1089283545090865E+00, 0.3721552962940165E+00, 0.1511669372043137E+00, 0.1747664312451059E-01, 0.7794266594052606E+00, 0.9421927087788731E+00, 0.7149818024536710E-05, 0.9036173567869616E-04, 0.5330862612042146E-01, 0.6167166595864771E-01, 0.5599742376476567E-02, 0.3333583884775863E-02, 0.7226792648875177E-01, 0.8954764092829798E-01, 0.1553961492315709E-05, 0.9501841907954501E-05, 0.1278990301151681E-03, 0.1181892689658507E-01, 0.7149818024536710E-05, 0.8479567256479229E-04, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 19, + ppOut: 1, + dminOut: 1.2789903011516807E-004, + desigOut: 0.0000000000000000, + sigmaOut: 2.4216884496671885E-002, + qmaxOut: 1.8900334961849885, + nFailOut: 0, + iterOut: 14, + nDivOut: 296, + ttypeOut: -4, + dmin1Out: 4.9975042235645591E-002, + dmin2Out: 4.9975042235645591E-002, + dnOut: 1.2789903011516807E-004, + dn1Out: 7.2258424646843816E-002, + dn2Out: 4.9975042235645591E-002, + gOut: 0.0000000000000000, + tauOut: 1.1689473904977585E-002, + }, + { + i0: 1, + n0: 19, + z: []float64{0.2596646703688871E+01, 0.2594984508308910E+01, 0.9107195378059658E-02, 0.1335166928493912E-01, 0.1761563251830163E+01, 0.1771176948261041E+01, 0.1252913577120413E-01, 0.1118297285215907E-01, 0.1971037054636311E+01, 0.1973613407054170E+01, 0.1038322923301279E-01, 0.2164225725832272E-01, 0.9276268857018078E+00, 0.9456374776795010E+00, 0.3105171497598932E-02, 0.4062111160297227E-02, 0.7109272204938374E+00, 0.7090993949257048E+00, 0.4589684232723624E-01, 0.1662247097070905E-01, 0.1905462626145317E+01, 0.1962964146704966E+01, 0.3314486004504485E-04, 0.8479567256479229E-04, 0.8309451431678238E+00, 0.7448056033330296E+00, 0.8089045693556918E-01, 0.9786215859981671E-01, 0.6185434577640304E+00, 0.6868388484470145E+00, 0.9663466631053550E-02, 0.2428454015756268E-01, 0.3116912561483949E+00, 0.2461349494442763E+00, 0.6956575230565126E-01, 0.8690924724014965E-01, 0.1821709311481225E+00, 0.2494905595159681E+00, 0.5070116699532772E-01, 0.1393559784278329E-01, 0.8351852429510604E+00, 0.6627831045381681E+00, 0.2303764547900405E+00, 0.2347927793131975E+00, 0.1262334749881915E+01, 0.8194758626174196E+00, 0.5445947541061251E+00, 0.6849248159595133E+00, 0.6903129633483998E+00, 0.1003702693628486E+01, 0.7970630839299049E-01, 0.2428944977310168E+00, 0.4875841467523446E+00, 0.2265275601477758E+00, 0.2690141110044630E+00, 0.3524523689025369E+00, 0.1089283545090865E+00, 0.3721552962940165E+00, 0.1511669372043137E+00, 0.1747664312451059E-01, 0.7794266594052606E+00, 0.9421927087788731E+00, 0.7149818024536710E-05, 0.9036173567869616E-04, 0.5330862612042146E-01, 0.6167166595864771E-01, 0.5599742376476567E-02, 0.3333583884775863E-02, 0.7226792648875177E-01, 0.8954764092829798E-01, 0.1553961492315709E-05, 0.9501841907954501E-05, 0.1278990301151681E-03, 0.1181892689658507E-01, 0.7149818024536710E-05, 0.8479567256479229E-04, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 1.2789903011516807E-004, + desig: 0.0000000000000000, + qmax: 1.8900334961849885, + ttype: -4, + dmin1: 4.9975042235645591E-002, + dmin2: 4.9975042235645591E-002, + dn: 1.2789903011516807E-004, + dn1: 7.2258424646843816E-002, + dn2: 4.9975042235645591E-002, + g: 0.0000000000000000, + tau: 1.1689473904977585E-002, + nFail: 0, + iter: 14, + sigma: 2.4216884496671885E-002, + nDiv: 296, + zOut: []float64{0.2596646703688871E+01, 0.2605626003858251E+01, 0.9107195378059658E-02, 0.6157023564192275E-02, 0.1761563251830163E+01, 0.1767807468828494E+01, 0.1252913577120413E-01, 0.1396950250695455E-01, 0.1971037054636311E+01, 0.1967322886153689E+01, 0.1038322923301279E-01, 0.4895872794820515E-02, 0.9276268857018078E+00, 0.9257082891959054E+00, 0.3105171497598932E-02, 0.2384715539127593E-02, 0.7109272204938374E+00, 0.7543114520732653E+00, 0.4589684232723624E-01, 0.1159397984377132E+00, 0.1905462626145317E+01, 0.1789428077358968E+01, 0.3314486004504485E-04, 0.1539126429493388E-04, 0.8309451431678238E+00, 0.9116923136304173E+00, 0.8089045693556918E-01, 0.5488064578914756E-01, 0.6185434577640304E+00, 0.5731983833972557E+00, 0.9663466631053550E-02, 0.5254756712901782E-02, 0.3116912561483949E+00, 0.3758743565324636E+00, 0.6956575230565126E-01, 0.3371567560620648E-01, 0.1821709311481225E+00, 0.1990285273285630E+00, 0.5070116699532772E-01, 0.2127577741907859E+00, 0.8351852429510604E+00, 0.8526760283416343E+00, 0.2303764547900405E+00, 0.3410582621885915E+00, 0.1262334749881915E+01, 0.1465743346590768E+01, 0.5445947541061251E+00, 0.2564847518533230E+00, 0.6903129633483998E+00, 0.5134066246793865E+00, 0.7970630839299049E-01, 0.7569737222001199E-01, 0.4875841467523446E+00, 0.6807729903281149E+00, 0.2690141110044630E+00, 0.4304410555024735E-01, 0.1089283545090865E+00, 0.2169232909544721E+00, 0.1511669372043137E+00, 0.5431576312495270E+00, 0.7794266594052606E+00, 0.2361482827650774E+00, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.5330862612042146E-01, 0.5877885927277143E-01, 0.5599742376476567E-02, 0.6884818375619963E-02, 0.7226792648875177E-01, 0.6525676686594341E-01, 0.1553961492315709E-05, 0.3045663725752605E-08, 0.1278990301151681E-03, 0.7757707209639971E-09, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 19, + ppOut: 0, + dminOut: 7.7577072096399712E-010, + desigOut: -5.4210108624275222E-020, + sigmaOut: 2.4344779705352607E-002, + qmaxOut: 1.8900334961849885, + nFailOut: 1, + iterOut: 16, + nDivOut: 336, + ttypeOut: -15, + dmin1Out: 5.3179116896294863E-002, + dmin2Out: 5.3179116896294863E-002, + dnOut: 7.7577072096399712E-010, + dn1Out: 6.5255212904451090E-002, + dn2Out: 5.3179116896294863E-002, + gOut: 0.0000000000000000, + tauOut: 1.2789520868072135E-004, + }, + { + i0: 1, + n0: 19, + z: []float64{0.2596646703688871E+01, 0.2605626003858251E+01, 0.9107195378059658E-02, 0.6157023564192275E-02, 0.1761563251830163E+01, 0.1767807468828494E+01, 0.1252913577120413E-01, 0.1396950250695455E-01, 0.1971037054636311E+01, 0.1967322886153689E+01, 0.1038322923301279E-01, 0.4895872794820515E-02, 0.9276268857018078E+00, 0.9257082891959054E+00, 0.3105171497598932E-02, 0.2384715539127593E-02, 0.7109272204938374E+00, 0.7543114520732653E+00, 0.4589684232723624E-01, 0.1159397984377132E+00, 0.1905462626145317E+01, 0.1789428077358968E+01, 0.3314486004504485E-04, 0.1539126429493388E-04, 0.8309451431678238E+00, 0.9116923136304173E+00, 0.8089045693556918E-01, 0.5488064578914756E-01, 0.6185434577640304E+00, 0.5731983833972557E+00, 0.9663466631053550E-02, 0.5254756712901782E-02, 0.3116912561483949E+00, 0.3758743565324636E+00, 0.6956575230565126E-01, 0.3371567560620648E-01, 0.1821709311481225E+00, 0.1990285273285630E+00, 0.5070116699532772E-01, 0.2127577741907859E+00, 0.8351852429510604E+00, 0.8526760283416343E+00, 0.2303764547900405E+00, 0.3410582621885915E+00, 0.1262334749881915E+01, 0.1465743346590768E+01, 0.5445947541061251E+00, 0.2564847518533230E+00, 0.6903129633483998E+00, 0.5134066246793865E+00, 0.7970630839299049E-01, 0.7569737222001199E-01, 0.4875841467523446E+00, 0.6807729903281149E+00, 0.2690141110044630E+00, 0.4304410555024735E-01, 0.1089283545090865E+00, 0.2169232909544721E+00, 0.1511669372043137E+00, 0.5431576312495270E+00, 0.7794266594052606E+00, 0.2361482827650774E+00, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.5330862612042146E-01, 0.5877885927277143E-01, 0.5599742376476567E-02, 0.6884818375619963E-02, 0.7226792648875177E-01, 0.6525676686594341E-01, 0.1553961492315709E-05, 0.3045663725752605E-08, 0.1278990301151681E-03, 0.7757707209639971E-09, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 7.7577072096399712E-010, + desig: -5.4210108624275222E-020, + qmax: 1.8900334961849885, + ttype: -15, + dmin1: 5.3179116896294863E-002, + dmin2: 5.3179116896294863E-002, + dn: 7.7577072096399712E-010, + dn1: 6.5255212904451090E-002, + dn2: 5.3179116896294863E-002, + g: 0.0000000000000000, + tau: 1.2789520868072135E-004, + nFail: 1, + iter: 16, + sigma: 2.4344779705352607E-002, + nDiv: 336, + zOut: []float64{0.2611783026646672E+01, 0.2605626003858251E+01, 0.4167433562238479E-02, 0.6157023564192275E-02, 0.1777609536997439E+01, 0.1767807468828494E+01, 0.1546038171944878E-01, 0.1396950250695455E-01, 0.1956758376453290E+01, 0.1967322886153689E+01, 0.2316152103168096E-02, 0.4895872794820515E-02, 0.9257768518560943E+00, 0.9257082891959054E+00, 0.1943036529261404E-02, 0.2384715539127593E-02, 0.8683082132059464E+00, 0.7543114520732653E+00, 0.2389312083572061E+00, 0.1159397984377132E+00, 0.1550512259490286E+01, 0.1789428077358968E+01, 0.9049975109102588E-05, 0.1539126429493388E-04, 0.9665639086686850E+00, 0.9116923136304173E+00, 0.3254569838994440E-01, 0.5488064578914756E-01, 0.5459074409444424E+00, 0.5731983833972557E+00, 0.3618064437406363E-02, 0.5254756712901782E-02, 0.4059719669254931E+00, 0.3758743565324636E+00, 0.1652917395900484E-01, 0.3371567560620648E-01, 0.3952571267845734E+00, 0.1990285273285630E+00, 0.4589757947481138E+00, 0.2127577741907859E+00, 0.7347584950063413E+00, 0.8526760283416343E+00, 0.6803648845168142E+00, 0.3410582621885915E+00, 0.1041863213151506E+01, 0.1465743346590768E+01, 0.1263898840735783E+00, 0.2564847518533230E+00, 0.4627141120500496E+00, 0.5134066246793865E+00, 0.1113705527974558E+00, 0.7569737222001199E-01, 0.6124465423051357E+00, 0.6807729903281149E+00, 0.1524585149425051E-01, 0.4304410555024735E-01, 0.7448350699339780E+00, 0.2169232909544721E+00, 0.1722069046798406E+00, 0.5431576312495270E+00, 0.6394299132491200E-01, 0.2361482827650774E+00, 0.1483665133446019E-05, 0.1614015445872399E-05, 0.6566219320748727E-01, 0.5877885927277143E-01, 0.6842308575232983E-02, 0.6884818375619963E-02, 0.5841446056060346E-01, 0.6525676686594341E-01, 0.4044780558898965E-16, 0.3045663725752605E-08, 0.1013559914197710E-18, 0.7757707209639971E-09, 0.1483665133446019E-05, 0.1614015445872399E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 19, + ppOut: 1, + dminOut: 1.0135599141977102E-019, + desigOut: 2.7104744119407903E-020, + sigmaOut: 2.4344780481123287E-002, + qmaxOut: 1.8900334961849885, + nFailOut: 2, + iterOut: 18, + nDivOut: 376, + ttypeOut: -15, + dmin1Out: 5.8414457514939733E-002, + dmin2Out: 5.8777374831867304E-002, + dnOut: 1.0135599141977102E-019, + dn1Out: 5.8414457514939733E-002, + dn2Out: 5.8777374831867304E-002, + gOut: 0.0000000000000000, + tauOut: 7.7577068041483555E-010, + }, + { + i0: 1, + n0: 19, + z: []float64{0.2611783026646672E+01, 0.2605626003858251E+01, 0.4167433562238479E-02, 0.6157023564192275E-02, 0.1777609536997439E+01, 0.1767807468828494E+01, 0.1546038171944878E-01, 0.1396950250695455E-01, 0.1956758376453290E+01, 0.1967322886153689E+01, 0.2316152103168096E-02, 0.4895872794820515E-02, 0.9257768518560943E+00, 0.9257082891959054E+00, 0.1943036529261404E-02, 0.2384715539127593E-02, 0.8683082132059464E+00, 0.7543114520732653E+00, 0.2389312083572061E+00, 0.1159397984377132E+00, 0.1550512259490286E+01, 0.1789428077358968E+01, 0.9049975109102588E-05, 0.1539126429493388E-04, 0.9665639086686850E+00, 0.9116923136304173E+00, 0.3254569838994440E-01, 0.5488064578914756E-01, 0.5459074409444424E+00, 0.5731983833972557E+00, 0.3618064437406363E-02, 0.5254756712901782E-02, 0.4059719669254931E+00, 0.3758743565324636E+00, 0.1652917395900484E-01, 0.3371567560620648E-01, 0.3952571267845734E+00, 0.1990285273285630E+00, 0.4589757947481138E+00, 0.2127577741907859E+00, 0.7347584950063413E+00, 0.8526760283416343E+00, 0.6803648845168142E+00, 0.3410582621885915E+00, 0.1041863213151506E+01, 0.1465743346590768E+01, 0.1263898840735783E+00, 0.2564847518533230E+00, 0.4627141120500496E+00, 0.5134066246793865E+00, 0.1113705527974558E+00, 0.7569737222001199E-01, 0.6124465423051357E+00, 0.6807729903281149E+00, 0.1524585149425051E-01, 0.4304410555024735E-01, 0.7448350699339780E+00, 0.2169232909544721E+00, 0.1722069046798406E+00, 0.5431576312495270E+00, 0.6394299132491200E-01, 0.2361482827650774E+00, 0.1483665133446019E-05, 0.1614015445872399E-05, 0.6566219320748727E-01, 0.5877885927277143E-01, 0.6842308575232983E-02, 0.6884818375619963E-02, 0.5841446056060346E-01, 0.6525676686594341E-01, 0.4044780558898965E-16, 0.3045663725752605E-08, 0.1013559914197710E-18, 0.7757707209639971E-09, 0.1483665133446019E-05, 0.1614015445872399E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 1.0135599141977102E-019, + desig: 2.7104744119407903E-020, + qmax: 1.8900334961849885, + ttype: -15, + dmin1: 5.8414457514939733E-002, + dmin2: 5.8777374831867304E-002, + dn: 1.0135599141977102E-019, + dn1: 5.8414457514939733E-002, + dn2: 5.8777374831867304E-002, + g: 0.0000000000000000, + tau: 7.7577068041483555E-010, + nFail: 2, + iter: 18, + sigma: 2.4344780481123287E-002, + nDiv: 376, + zOut: []float64{0.2611783026646672E+01, 0.2615950460208911E+01, 0.4167433562238479E-02, 0.2831884532112553E-02, 0.1777609536997439E+01, 0.1790238034184775E+01, 0.1546038171944878E-01, 0.1689844079671380E-01, 0.1956758376453290E+01, 0.1942176087759744E+01, 0.2316152103168096E-02, 0.1104039956008399E-02, 0.9257768518560943E+00, 0.9266158484293474E+00, 0.1943036529261404E-02, 0.1820770257466081E-02, 0.8683082132059464E+00, 0.1105418651305687E+01, 0.2389312083572061E+00, 0.3351361651941490E+00, 0.1550512259490286E+01, 0.1215385144271246E+01, 0.9049975109102588E-05, 0.7197207696703830E-05, 0.9665639086686850E+00, 0.9991024098509327E+00, 0.3254569838994440E-01, 0.1778290067827487E-01, 0.5459074409444424E+00, 0.5317426047035739E+00, 0.3618064437406363E-02, 0.2762300261676148E-02, 0.4059719669254931E+00, 0.4197388406228219E+00, 0.1652917395900484E-01, 0.1556509232613395E-01, 0.3952571267845734E+00, 0.8386678292065533E+00, 0.4589757947481138E+00, 0.4021095747913879E+00, 0.7347584950063413E+00, 0.1013013804731768E+01, 0.6803648845168142E+00, 0.6997408538631263E+00, 0.1041863213151506E+01, 0.4685122433619579E+00, 0.1263898840735783E+00, 0.1248257304047288E+00, 0.4627141120500496E+00, 0.4492589344427766E+00, 0.1113705527974558E+00, 0.1518244930621437E+00, 0.6124465423051357E+00, 0.4758679007372426E+00, 0.1524585149425051E-01, 0.2386301922514691E-01, 0.7448350699339780E+00, 0.8931789553886716E+00, 0.1722069046798406E+00, 0.1232835205710967E-01, 0.6394299132491200E-01, 0.5161612293293578E-01, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6566219320748727E-01, 0.7250261437426894E-01, 0.6842308575232983E-02, 0.5512763475647510E-02, 0.5841446056060346E-01, 0.5290169708495600E-01, 0.4044780558898965E-16, 0.7749519698096867E-34, 0.1013559914197710E-18, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 19, + ppOut: 0, + dminOut: 1.0135599141977093E-019, + desigOut: 2.7104744119407903E-020, + sigmaOut: 2.4344780481123287E-002, + qmaxOut: 1.8900334961849885, + nFailOut: 2, + iterOut: 19, + nDivOut: 396, + ttypeOut: -2, + dmin1Out: 5.1614639267802333E-002, + dmin2Out: 5.1614639267802333E-002, + dnOut: 1.0135599141977093E-019, + dn1Out: 5.2901697084955956E-002, + dn2Out: 6.5660305799035965E-002, + gOut: 0.0000000000000000, + tauOut: 0.0000000000000000, + }, + { + i0: 1, + n0: 4, + z: []float64{0.6482015258643838E+00, 0.6481999396438409E+00, 0.2115037983241246E-16, 0.2912830939801045E-17, 0.8927011497345719E-01, 0.8926852875357447E-01, 0.6601400172354812E-12, 0.2332164496627946E-11, 0.3153708122363886E+00, 0.3200537757344777E+00, 0.4684549720964035E-02, 0.2356209328895529E-07, 0.1609789066298190E-05, 0.6430148075154844E-11, 0.2115037983241246E-16, 0.2912830939801045E-17, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 6.4301480751548441E-012, + desig: -2.0633404957759536E-016, + qmax: 1.6602870234255678, + ttype: -2, + dmin1: 8.9268528752914328E-002, + dmin2: 8.9268528752914328E-002, + dn: 6.4301480751548441E-012, + dn1: 0.31536922601351364, + dn2: 8.9268528752914328E-002, + g: 0.49975000000000003, + tau: 1.5862205428611591E-006, + nFail: 5, + iter: 102, + sigma: 2.0015106747272648, + nDiv: 1395, + zOut: []float64{0.6481999396374125E+00, 0.6481999396438409E+00, 0.4011480356653261E-18, 0.2912830939801045E-17, 0.8926852874947827E-01, 0.8926852875357447E-01, 0.8361491594360282E-11, 0.2332164496627946E-11, 0.3200537992817811E+00, 0.3200537757344777E+00, 0.4733821287189426E-18, 0.2356209328895529E-07, 0.1787791211067534E-14, 0.6430148075154844E-11, 0.4011480356653261E-18, 0.2912830939801045E-17, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 4, + ppOut: 1, + dminOut: 1.7877912110675335E-015, + desigOut: -3.7836067586147711E-017, + sigmaOut: 2.0015106747336930, + qmaxOut: 1.6602870234255678, + nFailOut: 5, + iterOut: 103, + nDivOut: 1400, + ttypeOut: -4, + dmin1Out: 8.9268528747146109E-002, + dmin2Out: 8.9268528747146109E-002, + dnOut: 1.7877912110675335E-015, + dn1Out: 0.32005377571968785, + dn2Out: 8.9268528747146109E-002, + gOut: 0.49975000000000003, + tauOut: 6.4283598105616478E-012, + }, + { + i0: 1, + n0: 4, + z: []float64{0.6481999396374125E+00, 0.6481999396438409E+00, 0.4011480356653261E-18, 0.2912830939801045E-17, 0.8926852874947827E-01, 0.8926852875357447E-01, 0.8361491594360282E-11, 0.2332164496627946E-11, 0.3200537992817811E+00, 0.3200537757344777E+00, 0.4733821287189426E-18, 0.2356209328895529E-07, 0.1787791211067534E-14, 0.6430148075154844E-11, 0.4011480356653261E-18, 0.2912830939801045E-17, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 1.7877912110675335E-015, + desig: -3.7836067586147711E-017, + qmax: 1.6602870234255678, + ttype: -4, + dmin1: 8.9268528747146109E-002, + dmin2: 8.9268528747146109E-002, + dn: 1.7877912110675335E-015, + dn1: 0.32005377571968785, + dn2: 8.9268528747146109E-002, + g: 0.49975000000000003, + tau: 6.4283598105616478E-012, + nFail: 5, + iter: 103, + sigma: 2.0015106747336930, + nDiv: 1400, + zOut: []float64{0.6481999396374125E+00, 0.6481999396374107E+00, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.8926852874947827E-01, 0.8926852875783797E-01, 0.8361491594360282E-11, 0.2997839428604580E-10, 0.3200537992817811E+00, 0.3200537992518009E+00, 0.4733821287189426E-18, 0.2644269217171004E-32, 0.1787791211067534E-14, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 4, + ppOut: 0, + dminOut: 2.2279522444840209E-024, + desigOut: -2.6401698146816920E-017, + sigmaOut: 2.0015106747336948, + qmaxOut: 1.6602870234255678, + nFailOut: 5, + iterOut: 104, + nDivOut: 1405, + ttypeOut: -4, + dmin1Out: 8.9268528749476481E-002, + dmin2Out: 8.9268528749476481E-002, + dnOut: 2.2279522444840209E-024, + dn1Out: 0.32005379925180094, + dn2Out: 8.9268528749476481E-002, + gOut: 0.49975000000000003, + tauOut: 1.7877912088395813E-015, + }, + { + i0: 1, + n0: 4, + z: []float64{0.6481999396374125E+00, 0.6481999396374107E+00, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.8926852874947827E-01, 0.8926852875783797E-01, 0.8361491594360282E-11, 0.2997839428604580E-10, 0.3200537992817811E+00, 0.3200537992518009E+00, 0.4733821287189426E-18, 0.2644269217171004E-32, 0.1787791211067534E-14, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 2.2279522444840209E-024, + desig: -2.6401698146816920E-017, + qmax: 1.6602870234255678, + ttype: -4, + dmin1: 8.9268528749476481E-002, + dmin2: 8.9268528749476481E-002, + dn: 2.2279522444840209E-024, + dn1: 0.32005379925180094, + dn2: 8.9268528749476481E-002, + g: 0.49975000000000003, + tau: 1.7877912088395813E-015, + nFail: 5, + iter: 104, + sigma: 2.0015106747336948, + nDiv: 1405, + zOut: []float64{0.6258828074500417E+00, 0.6481999396374107E+00, 0.7879513719234823E-20, 0.5524513774965514E-19, 0.6695139660044724E-01, 0.8926852875783797E-01, 0.1433084218388560E-09, 0.2997839428604580E-10, 0.2977366669211234E+00, 0.3200537992518009E+00, 0.8926852875783797E-01, 0.2644269217171004E-32, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 3, + ppOut: 1, + dminOut: 6.6951396570468849E-002, + desigOut: -1.0061396160665481E-016, + sigmaOut: 2.0238278069210640, + qmaxOut: 1.6602870234255678, + nFailOut: 5, + iterOut: 105, + nDivOut: 1409, + ttypeOut: -9, + dmin1Out: 6.6951396570468849E-002, + dmin2Out: 0.62588280745004166, + dnOut: 0.29773666692112338, + dn1Out: 6.6951396570468849E-002, + dn2Out: 0.62588280745004166, + gOut: 0.49975000000000003, + tauOut: 2.2317132187369120E-002, + }, + { + i0: 1, + n0: 3, + z: []float64{0.6258828074500417E+00, 0.6481999396374107E+00, 0.7879513719234823E-20, 0.5524513774965514E-19, 0.6695139660044724E-01, 0.8926852875783797E-01, 0.1433084218388560E-09, 0.2997839428604580E-10, 0.2977366669211234E+00, 0.3200537992518009E+00, 0.8926852875783797E-01, 0.2644269217171004E-32, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 6.6951396570468849E-002, + desig: -1.0061396160665481E-016, + qmax: 1.6602870234255678, + ttype: -9, + dmin1: 6.6951396570468849E-002, + dmin2: 0.62588280745004166, + dn: 0.29773666692112338, + dn1: 6.6951396570468849E-002, + dn2: 0.62588280745004166, + g: 0.49975000000000003, + tau: 2.2317132187369120E-002, + nFail: 5, + iter: 105, + sigma: 2.0238278069210640, + nDiv: 1409, + zOut: []float64{0.6258828074500417E+00, 0.5589320748538995E+00, 0.7879513719234823E-20, 0.9438435755776795E-21, 0.6695139660044724E-01, 0.6641476135588615E-06, 0.1433084218388560E-09, 0.6424501268835132E-04, 0.2977366669211234E+00, 0.2307216893122929E+00, 0.8926852875783797E-01, 0.6695139660044724E-01, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 3, + ppOut: 0, + dminOut: 6.6400430513702258E-007, + desigOut: 1.9428902930940239E-016, + sigmaOut: 2.0907785395172058, + qmaxOut: 1.6602870234255678, + nFailOut: 5, + iterOut: 106, + nDivOut: 1413, + ttypeOut: -4, + dmin1Out: 6.6400430513702258E-007, + dmin2Out: 0.55893207485389951, + dnOut: 0.23072168931229292, + dn1Out: 6.6400430513702258E-007, + dn2Out: 0.55893207485389951, + gOut: 0.49975000000000003, + tauOut: 6.6950732596142107E-002, + }, + { + i0: 1, + n0: 3, + z: []float64{0.6258828074500417E+00, 0.5589320748538995E+00, 0.7879513719234823E-20, 0.9438435755776795E-21, 0.6695139660044724E-01, 0.6641476135588615E-06, 0.1433084218388560E-09, 0.6424501268835132E-04, 0.2977366669211234E+00, 0.2307216893122929E+00, 0.8926852875783797E-01, 0.6695139660044724E-01, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 6.6400430513702258E-007, + desig: 1.9428902930940239E-016, + qmax: 1.6602870234255678, + ttype: -4, + dmin1: 6.6400430513702258E-007, + dmin2: 0.55893207485389951, + dn: 0.23072168931229292, + dn1: 6.6400430513702258E-007, + dn2: 0.55893207485389951, + g: 0.49975000000000003, + tau: 6.6950732596142107E-002, + nFail: 5, + iter: 106, + sigma: 2.0907785395172058, + nDiv: 1413, + zOut: []float64{0.5589315065851642E+00, 0.5589320748538995E+00, 0.1121517486324177E-26, 0.9438435755776795E-21, 0.6434089156657428E-04, 0.6641476135588615E-06, 0.2303778747300831E+00, 0.6424501268835132E-04, 0.3432463134744483E-03, 0.2307216893122929E+00, 0.6641476135588615E-06, 0.6695139660044724E-01, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 3, + ppOut: 1, + dminOut: 9.5878878222950548E-008, + desigOut: -9.3233975295464906E-017, + sigmaOut: 2.0907791077859414, + qmaxOut: 1.6602870234255678, + nFailOut: 6, + iterOut: 108, + nDivOut: 1421, + ttypeOut: -15, + dmin1Out: 9.5878878222950548E-008, + dmin2Out: 0.55893150658516422, + dnOut: 3.4324631347444829E-004, + dn1Out: 9.5878878222950548E-008, + dn2Out: 0.55893150658516422, + gOut: 0.49975000000000003, + tauOut: 5.6826873533591094E-007, + }, + { + i0: 1, + n0: 3, + z: []float64{0.5589315065851642E+00, 0.5589320748538995E+00, 0.1121517486324177E-26, 0.9438435755776795E-21, 0.6434089156657428E-04, 0.6641476135588615E-06, 0.2303778747300831E+00, 0.6424501268835132E-04, 0.3432463134744483E-03, 0.2307216893122929E+00, 0.6641476135588615E-06, 0.6695139660044724E-01, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 0, + dmin: 9.5878878222950548E-008, + desig: -9.3233975295464906E-017, + qmax: 1.6602870234255678, + ttype: -15, + dmin1: 9.5878878222950548E-008, + dmin2: 0.55893150658516422, + dn: 3.4324631347444829E-004, + dn1: 9.5878878222950548E-008, + dn2: 0.55893150658516422, + g: 0.49975000000000003, + tau: 5.6826873533591094E-007, + nFail: 6, + iter: 108, + sigma: 2.0907791077859414, + nDiv: 1421, + zOut: []float64{0.5589315065851642E+00, 0.5589314123732620E+00, 0.1121517486324177E-26, 0.1291024862446124E-30, 0.6434089156657428E-04, 0.2304421214097475E+00, 0.2303778747300831E+00, 0.3431506172718059E-03, 0.3432463134744483E-03, 0.1484300435548105E-08, 0.6641476135588615E-06, 0.6434089156657428E-04, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 3, + ppOut: 0, + dminOut: 1.4843004355481051E-009, + desigOut: -1.6593817482031092E-016, + sigmaOut: 2.0907792019978437, + qmaxOut: 1.6602870234255678, + nFailOut: 6, + iterOut: 109, + nDivOut: 1425, + ttypeOut: -4, + dmin1Out: 6.4246679664367451E-005, + dmin2Out: 0.55893141237326205, + dnOut: 1.4843004355481051E-009, + dn1Out: 6.4246679664367451E-005, + dn2Out: 0.55893141237326205, + gOut: 0.49975000000000003, + tauOut: 9.4211902206835373E-008, + }, + { + i0: 1, + n0: 3, + z: []float64{0.5589315065851642E+00, 0.5589314123732620E+00, 0.1121517486324177E-26, 0.1291024862446124E-30, 0.6434089156657428E-04, 0.2304421214097475E+00, 0.2303778747300831E+00, 0.3431506172718059E-03, 0.3432463134744483E-03, 0.1484300435548105E-08, 0.6641476135588615E-06, 0.6434089156657428E-04, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + pp: 1, + dmin: 1.4843004355481051E-009, + desig: -1.6593817482031092E-016, + qmax: 1.6602870234255678, + ttype: -4, + dmin1: 6.4246679664367451E-005, + dmin2: 0.55893141237326205, + dn: 1.4843004355481051E-009, + dn1: 6.4246679664367451E-005, + dn2: 0.55893141237326205, + g: 0.49975000000000003, + tau: 9.4211902206835373E-008, + nFail: 6, + iter: 109, + sigma: 2.0907792019978437, + nDiv: 1425, + zOut: []float64{0.2649710614371106E+01, 0.5589314123732620E+00, 0.1121517486324177E-26, 0.1291024862446124E-30, 0.2321564474027070E+01, 0.2307852720292263E+00, 0.2303778747300831E+00, 0.3431506172718059E-03, 0.2090779203479937E+01, 0.1482093454966231E-08, 0.6641476135588615E-06, 0.6434089156657428E-04, 0.2001510674733695E+01, 0.2227952244484021E-23, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.1702794694134603E+01, 0.2545269924803487E-17, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.1077066053646038E+01, 0.7156177943897596E-01, 0.2292199980814605E-03, 0.1899018778701386E-03, 0.1060140274732043E+01, 0.8660746506696473E-01, 0.1357005210961402E-39, 0.1331360138522907E-23, 0.9894235909971354E+00, 0.8804208964992894E-17, 0.8660746506696473E-01, 0.8679736700028205E-01, 0.9539342071687115E+00, 0.2761013168273541E-29, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.8046649468928653E+00, 0.5098326619997980E-22, 0.1416795225784663E-10, 0.1216165317638265E-10, 0.7009142227469247E+00, 0.1183291357831518E-29, 0.4806926318247711E-11, 0.3824647564366386E-11, 0.5502651835254770E+00, 0.1368072596837427E-11, 0.1169503544861386E-10, 0.4068037876491279E-10, 0.4423863025187732E+00, 0.2477754901417239E-20, 0.1737857614720001E-07, 0.5295826057530262E-07, 0.3697086796938907E+00, 0.5143373102040997E-26, 0.1312431380925897E-05, 0.1614374370413396E-05, 0.1446051340026323E+00, 0.9928287808749566E-25, 0.3777515963415321E-05, 0.2773141909621761E-05, 0.1110032523123295E+00, 0.0000000000000000E+00, 0.2532463507333992E-05, 0.2934028940292093E-05, 0.7513603923341917E-01, 0.5394210206791908E-19, 0.6032617175984252E-07, 0.2575740214720034E-06, 0.6860214953971246E-01, 0.7542232825258426E-19, 0.3784397549471832E-09, 0.1131370986389306E-09, 0.2434478048112329E-01, 0.1013559914197709E-18, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6989818532012803E-03, 0.9466330862652142E-28, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.7811996215926567E-04, 0.3786532345060857E-28, 0.1283811140869274E-03, 0.1684766835109566E-03}, + i0Out: 1, + n0Out: 0, + ppOut: 1, + dminOut: 1.4843004355481051E-009, + desigOut: -1.6593817482031092E-016, + sigmaOut: 2.0907792019978437, + qmaxOut: 1.6602870234255678, + nFailOut: 6, + iterOut: 109, + nDivOut: 1425, + ttypeOut: -4, + dmin1Out: 6.4246679664367451E-005, + dmin2Out: 0.55893141237326205, + dnOut: 1.4843004355481051E-009, + dn1Out: 6.4246679664367451E-005, + dn2Out: 0.55893141237326205, + gOut: 0.49975000000000003, + tauOut: 9.4211902206835373E-008, + }, + } { + z := make([]float64, len(test.z)) + copy(z, test.z) + i0 := test.i0 - 1 // zero index + n0 := test.n0 - 1 // zero index + + i0Out, n0Out, ppOut, dminOut, sigmaOut, desigOut, qmaxOut, nFailOut, iterOut, nDivOut, ttypeOut, dmin1Out, dmin2Out, dnOut, dn1Out, dn2Out, gOut, tauOut := + impl.Dlasq3(i0, n0, z, test.pp, test.dmin, test.sigma, test.desig, test.qmax, test.nFail, test.iter, test.nDiv, test.ttype, test.dmin1, test.dmin2, test.dn, test.dn1, test.dn2, test.g, test.tau) + + if !floats.EqualApprox(z, test.zOut, dTol) { + t.Error("Z mismatch") + } + if i0Out != test.i0Out-1 { + t.Errorf("i0 mismatch. Want %v, got %v", test.n0Out, n0Out) + } + if n0Out != test.n0Out-1 { + t.Errorf("n0 mismatch. Want %v, got %v", test.n0Out, n0Out) + } + if ppOut != test.ppOut { + t.Errorf("pp mismatch. Want %v, got %v", test.ppOut, ppOut) + } + if !floats.EqualWithinAbsOrRel(dminOut, test.dminOut, dTol, dTol) { + t.Errorf("dmin mismatch. Want %v, got %v", test.dminOut, dminOut) + } + if !floats.EqualWithinAbsOrRel(desigOut, test.desigOut, dTol, dTol) { + t.Errorf("desig mismatch. Want %v, got %v", test.desigOut, desigOut) + } + if !floats.EqualWithinAbsOrRel(sigmaOut, test.sigmaOut, dTol, dTol) { + t.Errorf("sigma mismatch. Want %v, got %v", test.sigmaOut, sigmaOut) + } + if !floats.EqualWithinAbsOrRel(qmaxOut, test.qmaxOut, dTol, dTol) { + t.Errorf("qmax mismatch. Want %v, got %v", test.qmaxOut, qmaxOut) + } + if nFailOut != test.nFailOut { + t.Errorf("nFail mismatch. Want %v, got %v", test.nFailOut, nFailOut) + } + if iterOut != test.iterOut { + t.Errorf("iter mismatch. Want %v, got %v", test.iterOut, iterOut) + } + if nDivOut != test.nDivOut { + t.Errorf("nFail mismatch. Want %v, got %v", test.nDivOut, nDivOut) + } + if ttypeOut != test.ttypeOut { + t.Errorf("ttype mismatch. Want %v, got %v", test.ttypeOut, ttypeOut) + } + if !floats.EqualWithinAbsOrRel(dmin1Out, test.dmin1Out, dTol, dTol) { + t.Errorf("dmin1 mismatch. Want %v, got %v", test.dmin1Out, dmin1Out) + } + if !floats.EqualWithinAbsOrRel(dmin2Out, test.dmin2Out, dTol, dTol) { + t.Errorf("dmin2 mismatch. Want %v, got %v", test.dmin2Out, dmin2Out) + } + if !floats.EqualWithinAbsOrRel(dnOut, test.dnOut, dTol, dTol) { + t.Errorf("dn mismatch. Want %v, got %v", test.dnOut, dnOut) + } + if !floats.EqualWithinAbsOrRel(dn1Out, test.dn1Out, dTol, dTol) { + t.Errorf("dn1 mismatch. Want %v, got %v", test.dn1Out, dn1Out) + } + if !floats.EqualWithinAbsOrRel(dn2Out, test.dn2Out, dTol, dTol) { + t.Errorf("dn2 mismatch. Want %v, got %v", test.dn2Out, dn2Out) + } + if !floats.EqualWithinAbsOrRel(gOut, test.gOut, dTol, dTol) { + t.Errorf("g mismatch. Want %v, got %v", test.gOut, gOut) + } + if !floats.EqualWithinAbsOrRel(tauOut, test.tauOut, dTol, dTol) { + t.Errorf("tau mismatch. Want %v, got %v", test.tauOut, tauOut) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq4.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq4.go new file mode 100644 index 00000000..03d71946 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq4.go @@ -0,0 +1,3101 @@ +// 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 testlapack + +import ( + "testing" + + "gonum.org/v1/gonum/floats" +) + +type dlasq4teststruct struct { + z []float64 + i0, n0, pp, n0in int + dmin, dmin1, dmin2, dn, dn1, dn2, tau float64 + ttype int + g float64 + + zOut []float64 + tauOut float64 + ttypeOut int + gOut float64 +} + +type Dlasq4er interface { + Dlasq4(i0, n0 int, z []float64, pp int, n0in int, dmin, dmin1, dmin2, dn, dn1, dn2, tau float64, ttype int, g float64) (tauOut float64, ttypeOut int, gOut float64) +} + +func Dlasq4Test(t *testing.T, impl Dlasq4er) { + dTol := 1e-14 + // Tests computed from calling the netlib Dlasq + for cas, test := range []dlasq4teststruct{ + { + z: []float64{0.1914365246180821E+01, 0.1564384297703890E+01, 0.2493389162143899E+00, 0.3499809484769305E+00, 0.1315996513131545E+01, 0.1363862112490627E+01, 0.9898466611970759E-01, 0.2014733168553078E+00, 0.6023973979587287E+00, 0.6465544792741794E+00, 0.2210033410638781E-02, 0.5482758480425683E-01, 0.9861857233678967E-01, 0.2428190810745492E-01, 0.4756321484454819E+00, 0.7654669763997353E-01, 0.2588748143677115E+00, 0.6127784069508770E+00, 0.1078611376690004E+00, 0.1217285558623164E+00, 0.6442896492255246E+00, 0.2293835804898155E+00, 0.6203230486639705E+00, 0.5227672064047094E+00, 0.3695660678607585E+00, 0.7645233184745865E+00, 0.5378838054252265E+00, 0.2253657980501426E+00, 0.3562533181264623E+00, 0.8820486722335483E+00, 0.2222132496436145E-01, 0.1208845131814035E-01, 0.1275094303021685E+01, 0.6548746852163357E+00, 0.1647324354821218E+00, 0.6424409427697111E+00, 0.1007530576543866E+01, 0.3269551736546701E+00, 0.3453881601783118E+00, 0.8453078383713172E+00, 0.2679391719153404E+00, 0.4116714838778281E+00, 0.7328677736683723E+00, 0.2016558482158241E+00, 0.8360828138307410E+00, 0.9737579452195326E+00, 0.4813660709592822E+00, 0.5951926422795808E+00, 0.6495370513676459E+00, 0.6761876248148171E+00, 0.2325475880222648E+00, 0.4547154975121112E+00, 0.1993624802893807E+00, 0.3321819367342255E+00, 0.3782318916911257E+00, 0.9972813157741996E-01, 0.9830449403503746E+00, 0.7561080996844842E+00, 0.4429733864040367E+00, 0.6051687323570161E+00, 0.1173279550602403E+01, 0.7195724480316686E+00, 0.5035524069144587E+00, 0.8966804889747714E+00, 0.3058980395058521E+00, 0.6588832353928662E+00, 0.3014634433415453E+00, 0.1505672110274446E+00, 0.1289422237567578E+01, 0.6124645310993601E+00, 0.7583364305799440E+00, 0.9784211498097629E+00, 0.4977814779461571E+00, 0.9993813577491869E+00, 0.2841468847862598E+00, 0.2567365507769143E+00, 0.9257539794205765E+00, 0.5509268385614666E+00, 0.5231355605450990E-04, 0.6589740256453697E+00, 0.2117869221381033E-04, 0.7349224826832024E-04, 0.0000000000000000E+00, 0.0000000000000000E+00}, + i0: 1, + n0: 21, + pp: 0, + n0in: 21, + dmin: -0.0000000000000000, + dmin1: 0.0000000000000000, + dmin2: 0.0000000000000000, + dn: 0.0000000000000000, + dn1: 0.0000000000000000, + dn2: 0.0000000000000000, + tau: 0.0000000000000000, + ttype: 0, + g: 0.0000000000000000, + zOut: []float64{0.1914365246180821E+01, 0.1564384297703890E+01, 0.2493389162143899E+00, 0.3499809484769305E+00, 0.1315996513131545E+01, 0.1363862112490627E+01, 0.9898466611970759E-01, 0.2014733168553078E+00, 0.6023973979587287E+00, 0.6465544792741794E+00, 0.2210033410638781E-02, 0.5482758480425683E-01, 0.9861857233678967E-01, 0.2428190810745492E-01, 0.4756321484454819E+00, 0.7654669763997353E-01, 0.2588748143677115E+00, 0.6127784069508770E+00, 0.1078611376690004E+00, 0.1217285558623164E+00, 0.6442896492255246E+00, 0.2293835804898155E+00, 0.6203230486639705E+00, 0.5227672064047094E+00, 0.3695660678607585E+00, 0.7645233184745865E+00, 0.5378838054252265E+00, 0.2253657980501426E+00, 0.3562533181264623E+00, 0.8820486722335483E+00, 0.2222132496436145E-01, 0.1208845131814035E-01, 0.1275094303021685E+01, 0.6548746852163357E+00, 0.1647324354821218E+00, 0.6424409427697111E+00, 0.1007530576543866E+01, 0.3269551736546701E+00, 0.3453881601783118E+00, 0.8453078383713172E+00, 0.2679391719153404E+00, 0.4116714838778281E+00, 0.7328677736683723E+00, 0.2016558482158241E+00, 0.8360828138307410E+00, 0.9737579452195326E+00, 0.4813660709592822E+00, 0.5951926422795808E+00, 0.6495370513676459E+00, 0.6761876248148171E+00, 0.2325475880222648E+00, 0.4547154975121112E+00, 0.1993624802893807E+00, 0.3321819367342255E+00, 0.3782318916911257E+00, 0.9972813157741996E-01, 0.9830449403503746E+00, 0.7561080996844842E+00, 0.4429733864040367E+00, 0.6051687323570161E+00, 0.1173279550602403E+01, 0.7195724480316686E+00, 0.5035524069144587E+00, 0.8966804889747714E+00, 0.3058980395058521E+00, 0.6588832353928662E+00, 0.3014634433415453E+00, 0.1505672110274446E+00, 0.1289422237567578E+01, 0.6124645310993601E+00, 0.7583364305799440E+00, 0.9784211498097629E+00, 0.4977814779461571E+00, 0.9993813577491869E+00, 0.2841468847862598E+00, 0.2567365507769143E+00, 0.9257539794205765E+00, 0.5509268385614666E+00, 0.5231355605450990E-04, 0.6589740256453697E+00, 0.2117869221381033E-04, 0.7349224826832024E-04, 0.0000000000000000E+00, 0.0000000000000000E+00}, + tauOut: 0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1914365246180821E+01, 0.2163704162395211E+01, 0.2493389162143899E+00, 0.1516515751224039E+00, 0.1315996513131545E+01, 0.1263329604128848E+01, 0.9898466611970759E-01, 0.4719916727467415E-01, 0.6023973979587287E+00, 0.5574082640946934E+00, 0.2210033410638781E-02, 0.3910066531356214E-03, 0.9861857233678967E-01, 0.5738597141291359E+00, 0.4756321484454819E+00, 0.2145632131068746E+00, 0.2588748143677115E+00, 0.1521727389298373E+00, 0.1078611376690004E+00, 0.4566771620366771E+00, 0.6442896492255246E+00, 0.8079355358528180E+00, 0.6203230486639705E+00, 0.2837483186776231E+00, 0.3695660678607585E+00, 0.6237015546083620E+00, 0.5378838054252265E+00, 0.3072349091217998E+00, 0.3562533181264623E+00, 0.7123973396902394E-01, 0.2222132496436145E-01, 0.3977314805803597E+00, 0.1275094303021685E+01, 0.1042095257923447E+01, 0.1647324354821218E+00, 0.1592685164190333E+00, 0.1007530576543866E+01, 0.1193650220303144E+01, 0.3453881601783118E+00, 0.7752942700755104E-01, 0.2679391719153404E+00, 0.9232775185761617E+00, 0.7328677736683723E+00, 0.6636554427529671E+00, 0.8360828138307410E+00, 0.6537934420370561E+00, 0.4813660709592822E+00, 0.4782322339990674E+00, 0.6495370513676459E+00, 0.4038524053908432E+00, 0.2325475880222648E+00, 0.1147975431483785E+00, 0.1993624802893807E+00, 0.4627968288321279E+00, 0.3782318916911257E+00, 0.8034172324482011E+00, 0.9830449403503746E+00, 0.6226010943062101E+00, 0.4429733864040367E+00, 0.8347746582554776E+00, 0.1173279550602403E+01, 0.8420572992613844E+00, 0.5035524069144587E+00, 0.1829278057427913E+00, 0.3058980395058521E+00, 0.4244336771046062E+00, 0.3014634433415453E+00, 0.9158407747236312E+00, 0.1289422237567578E+01, 0.1131917893423890E+01, 0.7583364305799440E+00, 0.3334922359541972E+00, 0.4977814779461571E+00, 0.4484361267782198E+00, 0.2841468847862598E+00, 0.5865943745895725E+00, 0.9257539794205765E+00, 0.3392119183870583E+00, 0.5231355605450990E-04, 0.3266196269153995E-08, 0.2117869221381033E-04, 0.2117542601754118E-04, 0.0000000000000000E+00, 0.3910066531356214E-03, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + n0in: 21, + dmin: 2.1175426017541180E-005, + dmin1: 4.4311601260836921E-002, + dmin2: 4.4311601260836921E-002, + dn: 2.1175426017541180E-005, + dn1: 0.33915960483100382, + dn2: 0.16428924199195991, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.1914365246180821E+01, 0.2163704162395211E+01, 0.2493389162143899E+00, 0.1516515751224039E+00, 0.1315996513131545E+01, 0.1263329604128848E+01, 0.9898466611970759E-01, 0.4719916727467415E-01, 0.6023973979587287E+00, 0.5574082640946934E+00, 0.2210033410638781E-02, 0.3910066531356214E-03, 0.9861857233678967E-01, 0.5738597141291359E+00, 0.4756321484454819E+00, 0.2145632131068746E+00, 0.2588748143677115E+00, 0.1521727389298373E+00, 0.1078611376690004E+00, 0.4566771620366771E+00, 0.6442896492255246E+00, 0.8079355358528180E+00, 0.6203230486639705E+00, 0.2837483186776231E+00, 0.3695660678607585E+00, 0.6237015546083620E+00, 0.5378838054252265E+00, 0.3072349091217998E+00, 0.3562533181264623E+00, 0.7123973396902394E-01, 0.2222132496436145E-01, 0.3977314805803597E+00, 0.1275094303021685E+01, 0.1042095257923447E+01, 0.1647324354821218E+00, 0.1592685164190333E+00, 0.1007530576543866E+01, 0.1193650220303144E+01, 0.3453881601783118E+00, 0.7752942700755104E-01, 0.2679391719153404E+00, 0.9232775185761617E+00, 0.7328677736683723E+00, 0.6636554427529671E+00, 0.8360828138307410E+00, 0.6537934420370561E+00, 0.4813660709592822E+00, 0.4782322339990674E+00, 0.6495370513676459E+00, 0.4038524053908432E+00, 0.2325475880222648E+00, 0.1147975431483785E+00, 0.1993624802893807E+00, 0.4627968288321279E+00, 0.3782318916911257E+00, 0.8034172324482011E+00, 0.9830449403503746E+00, 0.6226010943062101E+00, 0.4429733864040367E+00, 0.8347746582554776E+00, 0.1173279550602403E+01, 0.8420572992613844E+00, 0.5035524069144587E+00, 0.1829278057427913E+00, 0.3058980395058521E+00, 0.4244336771046062E+00, 0.3014634433415453E+00, 0.9158407747236312E+00, 0.1289422237567578E+01, 0.1131917893423890E+01, 0.7583364305799440E+00, 0.3334922359541972E+00, 0.4977814779461571E+00, 0.4484361267782198E+00, 0.2841468847862598E+00, 0.5865943745895725E+00, 0.9257539794205765E+00, 0.3392119183870583E+00, 0.5231355605450990E-04, 0.3266196269153995E-08, 0.2117869221381033E-04, 0.2117542601754118E-04, 0.0000000000000000E+00, 0.3910066531356214E-03, 0.1037537856266618 - 321}, + tauOut: 0.0000000000000000, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2315355737517615E+01, 0.2163704162395211E+01, 0.8274578340618610E-01, 0.1516515751224039E+00, 0.1227782987997336E+01, 0.1263329604128848E+01, 0.2142822156235013E-01, 0.4719916727467415E-01, 0.5363710491854788E+00, 0.5574082640946934E+00, 0.4183353417969536E-03, 0.3910066531356214E-03, 0.7880045918942136E+00, 0.5738597141291359E+00, 0.4143462125464707E-01, 0.2145632131068746E+00, 0.5674152797118673E+00, 0.1521727389298373E+00, 0.6502569120260687E+00, 0.4566771620366771E+00, 0.4414269425043723E+00, 0.8079355358528180E+00, 0.4009140594652070E+00, 0.2837483186776231E+00, 0.5300224042649548E+00, 0.6237015546083620E+00, 0.4129510944388858E-01, 0.3072349091217998E+00, 0.4276761051054951E+00, 0.7123973396902394E-01, 0.9691308092544145E+00, 0.3977314805803597E+00, 0.2322329650880660E+00, 0.1042095257923447E+01, 0.8186215063776209E+00, 0.1592685164190333E+00, 0.4525581409330741E+00, 0.1193650220303144E+01, 0.1581701233715052E+00, 0.7752942700755104E-01, 0.1428762837957623E+01, 0.9232775185761617E+00, 0.3036848136842134E+00, 0.6636554427529671E+00, 0.8283408623519102E+00, 0.6537934420370561E+00, 0.2331591338951825E+00, 0.4782322339990674E+00, 0.2854908146440392E+00, 0.4038524053908432E+00, 0.1860933389154074E+00, 0.1147975431483785E+00, 0.1080120722364922E+01, 0.4627968288321279E+00, 0.4631042046962229E+00, 0.8034172324482011E+00, 0.9942715478654648E+00, 0.6226010943062101E+00, 0.7069779837626068E+00, 0.8347746582554776E+00, 0.3180071212415688E+00, 0.8420572992613844E+00, 0.2441477440283845E+00, 0.1829278057427913E+00, 0.1096126707799853E+01, 0.4244336771046062E+00, 0.9457451890006905E+00, 0.9158407747236312E+00, 0.5196649403773971E+00, 0.1131917893423890E+01, 0.2877815203259632E+00, 0.3334922359541972E+00, 0.7472489810418290E+00, 0.4484361267782198E+00, 0.2662831374385604E+00, 0.5865943745895725E+00, 0.7292878421469419E-01, 0.3392119183870583E+00, 0.9483648767903632E-12, 0.3266196269153995E-08, 0.2117542506917630E-04, 0.2117542601754118E-04, 0.4183353417969536E-03, 0.3910066531356214E-03}, + i0: 1, + n0: 21, + pp: 0, + n0in: 21, + dmin: 2.1175425069176302E-005, + dmin1: 2.9944624525135358E-002, + dmin2: 2.9944624525135358E-002, + dn: 2.1175425069176302E-005, + dn1: 7.2928780948497918E-002, + dn2: 0.16065460645225654, + tau: 0.0000000000000000, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2315355737517615E+01, 0.2163704162395211E+01, 0.8274578340618610E-01, 0.1516515751224039E+00, 0.1227782987997336E+01, 0.1263329604128848E+01, 0.2142822156235013E-01, 0.4719916727467415E-01, 0.5363710491854788E+00, 0.5574082640946934E+00, 0.4183353417969536E-03, 0.3910066531356214E-03, 0.7880045918942136E+00, 0.5738597141291359E+00, 0.4143462125464707E-01, 0.2145632131068746E+00, 0.5674152797118673E+00, 0.1521727389298373E+00, 0.6502569120260687E+00, 0.4566771620366771E+00, 0.4414269425043723E+00, 0.8079355358528180E+00, 0.4009140594652070E+00, 0.2837483186776231E+00, 0.5300224042649548E+00, 0.6237015546083620E+00, 0.4129510944388858E-01, 0.3072349091217998E+00, 0.4276761051054951E+00, 0.7123973396902394E-01, 0.9691308092544145E+00, 0.3977314805803597E+00, 0.2322329650880660E+00, 0.1042095257923447E+01, 0.8186215063776209E+00, 0.1592685164190333E+00, 0.4525581409330741E+00, 0.1193650220303144E+01, 0.1581701233715052E+00, 0.7752942700755104E-01, 0.1428762837957623E+01, 0.9232775185761617E+00, 0.3036848136842134E+00, 0.6636554427529671E+00, 0.8283408623519102E+00, 0.6537934420370561E+00, 0.2331591338951825E+00, 0.4782322339990674E+00, 0.2854908146440392E+00, 0.4038524053908432E+00, 0.1860933389154074E+00, 0.1147975431483785E+00, 0.1080120722364922E+01, 0.4627968288321279E+00, 0.4631042046962229E+00, 0.8034172324482011E+00, 0.9942715478654648E+00, 0.6226010943062101E+00, 0.7069779837626068E+00, 0.8347746582554776E+00, 0.3180071212415688E+00, 0.8420572992613844E+00, 0.2441477440283845E+00, 0.1829278057427913E+00, 0.1096126707799853E+01, 0.4244336771046062E+00, 0.9457451890006905E+00, 0.9158407747236312E+00, 0.5196649403773971E+00, 0.1131917893423890E+01, 0.2877815203259632E+00, 0.3334922359541972E+00, 0.7472489810418290E+00, 0.4484361267782198E+00, 0.2662831374385604E+00, 0.5865943745895725E+00, 0.7292878421469419E-01, 0.3392119183870583E+00, 0.9483648767903632E-12, 0.3266196269153995E-08, 0.2117542506917630E-04, 0.2117542601754118E-04, 0.4183353417969536E-03, 0.3910066531356214E-03}, + tauOut: 2.1175313795360271E-005, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2315355737517615E+01, 0.2398080345610006E+01, 0.8274578340618610E-01, 0.4236466279397526E-01, 0.1227782987997336E+01, 0.1206825371451915E+01, 0.2142822156235013E-01, 0.9523728911788614E-02, 0.5363710491854788E+00, 0.5272444803016919E+00, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.7880045918942136E+00, 0.8287928057414093E+00, 0.4143462125464707E-01, 0.2836732781232222E-01, 0.5674152797118673E+00, 0.1189283688611819E+01, 0.6502569120260687E+00, 0.2413561400585997E+00, 0.4414269425043723E+00, 0.6009636865971842E+00, 0.4009140594652070E+00, 0.3535878097802652E+00, 0.5300224042649548E+00, 0.2177085286147829E+00, 0.4129510944388858E-01, 0.8112190955144877E-01, 0.4276761051054951E+00, 0.1315663829494665E+01, 0.9691308092544145E+00, 0.1710650671895379E+00, 0.2322329650880660E+00, 0.8797682289623537E+00, 0.8186215063776209E+00, 0.4211038940233675E+00, 0.4525581409330741E+00, 0.1896031949674164E+00, 0.1581701233715052E+00, 0.1191897606932286E+01, 0.1428762837957623E+01, 0.5405288693957555E+00, 0.3036848136842134E+00, 0.4653859482687157E+00, 0.8283408623519102E+00, 0.5960928726645816E+00, 0.2331591338951825E+00, 0.1116684901463164E+00, 0.2854908146440392E+00, 0.3598944880993349E+00, 0.1860933389154074E+00, 0.5585061130503639E+00, 0.1080120722364922E+01, 0.9846976386969850E+00, 0.4631042046962229E+00, 0.4676068229793028E+00, 0.9942715478654648E+00, 0.1233621533334973E+01, 0.7069779837626068E+00, 0.1822471700779458E+00, 0.3180071212415688E+00, 0.3798865198782122E+00, 0.2441477440283845E+00, 0.7044652781161848E+00, 0.1096126707799853E+01, 0.1337385443370563E+01, 0.9457451890006905E+00, 0.3674861422265960E+00, 0.5196649403773971E+00, 0.4399391431629689E+00, 0.2877815203259632E+00, 0.4888049885267526E+00, 0.7472489810418290E+00, 0.5247059546398414E+00, 0.2662831374385604E+00, 0.3701064434002514E-01, 0.7292878421469419E-01, 0.3589696456182207E-01, 0.9483648767903632E-12, 0.5594353069081231E-15, 0.2117542506917630E-04, 0.1112732565966979E-09, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + n0in: 21, + dmin: 1.1127325659669794E-010, + dmin1: 3.1433071595911154E-002, + dmin2: 3.1433071595911154E-002, + dn: 1.1127325659669794E-010, + dn1: 3.5896964560873705E-002, + dn2: 0.25842281720128102, + tau: 2.1175313795360271E-005, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2315355737517615E+01, 0.2398080345610006E+01, 0.8274578340618610E-01, 0.4236466279397526E-01, 0.1227782987997336E+01, 0.1206825371451915E+01, 0.2142822156235013E-01, 0.9523728911788614E-02, 0.5363710491854788E+00, 0.5272444803016919E+00, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.7880045918942136E+00, 0.8287928057414093E+00, 0.4143462125464707E-01, 0.2836732781232222E-01, 0.5674152797118673E+00, 0.1189283688611819E+01, 0.6502569120260687E+00, 0.2413561400585997E+00, 0.4414269425043723E+00, 0.6009636865971842E+00, 0.4009140594652070E+00, 0.3535878097802652E+00, 0.5300224042649548E+00, 0.2177085286147829E+00, 0.4129510944388858E-01, 0.8112190955144877E-01, 0.4276761051054951E+00, 0.1315663829494665E+01, 0.9691308092544145E+00, 0.1710650671895379E+00, 0.2322329650880660E+00, 0.8797682289623537E+00, 0.8186215063776209E+00, 0.4211038940233675E+00, 0.4525581409330741E+00, 0.1896031949674164E+00, 0.1581701233715052E+00, 0.1191897606932286E+01, 0.1428762837957623E+01, 0.5405288693957555E+00, 0.3036848136842134E+00, 0.4653859482687157E+00, 0.8283408623519102E+00, 0.5960928726645816E+00, 0.2331591338951825E+00, 0.1116684901463164E+00, 0.2854908146440392E+00, 0.3598944880993349E+00, 0.1860933389154074E+00, 0.5585061130503639E+00, 0.1080120722364922E+01, 0.9846976386969850E+00, 0.4631042046962229E+00, 0.4676068229793028E+00, 0.9942715478654648E+00, 0.1233621533334973E+01, 0.7069779837626068E+00, 0.1822471700779458E+00, 0.3180071212415688E+00, 0.3798865198782122E+00, 0.2441477440283845E+00, 0.7044652781161848E+00, 0.1096126707799853E+01, 0.1337385443370563E+01, 0.9457451890006905E+00, 0.3674861422265960E+00, 0.5196649403773971E+00, 0.4399391431629689E+00, 0.2877815203259632E+00, 0.4888049885267526E+00, 0.7472489810418290E+00, 0.5247059546398414E+00, 0.2662831374385604E+00, 0.3701064434002514E-01, 0.7292878421469419E-01, 0.3589696456182207E-01, 0.9483648767903632E-12, 0.5594353069081231E-15, 0.2117542506917630E-04, 0.1112732565966979E-09, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.1037537856266618 - 321}, + tauOut: 2.1175313795360271E-005, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2440445008292708E+01, 0.2398080345610006E+01, 0.2094976520226600E-01, 0.4236466279397526E-01, 0.1195399335050165E+01, 0.1206825371451915E+01, 0.4200549016048655E-02, 0.9523728911788614E-02, 0.5236691632680260E+00, 0.5272444803016919E+00, 0.9895328911616120E-03, 0.6252320936560726E-03, 0.8561706005512968E+00, 0.8287928057414093E+00, 0.3940429656773515E-01, 0.2836732781232222E-01, 0.1391235531991410E+01, 0.1189283688611819E+01, 0.1042571673718422E+00, 0.2413561400585997E+00, 0.8502943288943339E+00, 0.6009636865971842E+00, 0.9053227710395735E-01, 0.3535878097802652E+00, 0.2082981609510011E+00, 0.2177085286147829E+00, 0.5123864833424303E+00, 0.8112190955144877E-01, 0.9743424132304999E+00, 0.1315663829494665E+01, 0.1544607000116935E+00, 0.1710650671895379E+00, 0.1146411422862754E+01, 0.8797682289623537E+00, 0.6964571542795012E-01, 0.4211038940233675E+00, 0.1311855086360479E+01, 0.1896031949674164E+00, 0.4911023119923957E+00, 0.1191897606932286E+01, 0.5148125055608023E+00, 0.5405288693957555E+00, 0.5388626806938843E+00, 0.4653859482687157E+00, 0.1688986820057405E+00, 0.5960928726645816E+00, 0.2379466412690434E+00, 0.1116684901463164E+00, 0.6804539597693821E+00, 0.3598944880993349E+00, 0.8082246312519304E+00, 0.5585061130503639E+00, 0.6440798303130841E+00, 0.9846976386969850E+00, 0.8956185534970393E+00, 0.4676068229793028E+00, 0.5202501498046066E+00, 0.1233621533334973E+01, 0.1330768347199243E+00, 0.1822471700779458E+00, 0.9512749631631994E+00, 0.3798865198782122E+00, 0.9903988276741268E+00, 0.7044652781161848E+00, 0.7144727578117591E+00, 0.1337385443370563E+01, 0.2262808998212762E+00, 0.3674861422265960E+00, 0.7024632317571722E+00, 0.4399391431629689E+00, 0.3651136124179467E+00, 0.4888049885267526E+00, 0.1966029864506465E+00, 0.5247059546398414E+00, 0.6757627705811050E-02, 0.3701064434002514E-01, 0.2913933674473832E-01, 0.3589696456182207E-01, 0.2136293938333395E-23, 0.5594353069081231E-15, 0.0000000000000000E+00, 0.1112732565966979E-09, 0.9895328911616120E-03, 0.6252320936560726E-03}, + i0: 1, + n0: 21, + pp: 0, + n0in: 21, + dmin: 0.0000000000000000, + dmin1: 2.9139336744737766E-002, + dmin2: 4.9426557292086552E-002, + dn: -2.0808762284537102E-024, + dn1: 2.9139336744737766E-002, + dn2: 0.15959234211062134, + tau: 1.1127325659669789E-010, + ttype: -15, + g: 0.0000000000000000, + zOut: []float64{0.2440445008292708E+01, 0.2398080345610006E+01, 0.2094976520226600E-01, 0.4236466279397526E-01, 0.1195399335050165E+01, 0.1206825371451915E+01, 0.4200549016048655E-02, 0.9523728911788614E-02, 0.5236691632680260E+00, 0.5272444803016919E+00, 0.9895328911616120E-03, 0.6252320936560726E-03, 0.8561706005512968E+00, 0.8287928057414093E+00, 0.3940429656773515E-01, 0.2836732781232222E-01, 0.1391235531991410E+01, 0.1189283688611819E+01, 0.1042571673718422E+00, 0.2413561400585997E+00, 0.8502943288943339E+00, 0.6009636865971842E+00, 0.9053227710395735E-01, 0.3535878097802652E+00, 0.2082981609510011E+00, 0.2177085286147829E+00, 0.5123864833424303E+00, 0.8112190955144877E-01, 0.9743424132304999E+00, 0.1315663829494665E+01, 0.1544607000116935E+00, 0.1710650671895379E+00, 0.1146411422862754E+01, 0.8797682289623537E+00, 0.6964571542795012E-01, 0.4211038940233675E+00, 0.1311855086360479E+01, 0.1896031949674164E+00, 0.4911023119923957E+00, 0.1191897606932286E+01, 0.5148125055608023E+00, 0.5405288693957555E+00, 0.5388626806938843E+00, 0.4653859482687157E+00, 0.1688986820057405E+00, 0.5960928726645816E+00, 0.2379466412690434E+00, 0.1116684901463164E+00, 0.6804539597693821E+00, 0.3598944880993349E+00, 0.8082246312519304E+00, 0.5585061130503639E+00, 0.6440798303130841E+00, 0.9846976386969850E+00, 0.8956185534970393E+00, 0.4676068229793028E+00, 0.5202501498046066E+00, 0.1233621533334973E+01, 0.1330768347199243E+00, 0.1822471700779458E+00, 0.9512749631631994E+00, 0.3798865198782122E+00, 0.9903988276741268E+00, 0.7044652781161848E+00, 0.7144727578117591E+00, 0.1337385443370563E+01, 0.2262808998212762E+00, 0.3674861422265960E+00, 0.7024632317571722E+00, 0.4399391431629689E+00, 0.3651136124179467E+00, 0.4888049885267526E+00, 0.1966029864506465E+00, 0.5247059546398414E+00, 0.6757627705811050E-02, 0.3701064434002514E-01, 0.2913933674473832E-01, 0.3589696456182207E-01, 0.2136293938333395E-23, 0.5594353069081231E-15, 0.0000000000000000E+00, 0.1112732565966979E-09, 0.9895328911616120E-03, 0.6252320936560726E-03}, + tauOut: -0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2440445008292708E+01, 0.2461394773494974E+01, 0.2094976520226600E-01, 0.1017444891892999E-01, 0.1195399335050165E+01, 0.1189425435147283E+01, 0.4200549016048655E-02, 0.1849378635683999E-02, 0.5236691632680260E+00, 0.5228093175235037E+00, 0.9895328911616120E-03, 0.1620493249248586E-02, 0.8561706005512968E+00, 0.8939544038697832E+00, 0.3940429656773515E-01, 0.6132377362967349E-01, 0.1391235531991410E+01, 0.1434168925733579E+01, 0.1042571673718422E+00, 0.6181229879703373E-01, 0.8502943288943339E+00, 0.8790143072012576E+00, 0.9053227710395735E-01, 0.2145324219750511E-01, 0.2082981609510011E+00, 0.6992314020959263E+00, 0.5123864833424303E+00, 0.7139837844669097E+00, 0.9743424132304999E+00, 0.4148193287752837E+00, 0.1544607000116935E+00, 0.4268738185358478E+00, 0.1146411422862754E+01, 0.7891833197548568E+00, 0.6964571542795012E-01, 0.1157716892137957E+00, 0.1311855086360479E+01, 0.1687185709139079E+01, 0.4911023119923957E+00, 0.1498504938454686E+00, 0.5148125055608023E+00, 0.9038246924092180E+00, 0.5388626806938843E+00, 0.1006978425303630E+00, 0.1688986820057405E+00, 0.3061474807444209E+00, 0.2379466412690434E+00, 0.5288684194677825E+00, 0.6804539597693821E+00, 0.9598101715535300E+00, 0.8082246312519304E+00, 0.5423584775195998E+00, 0.6440798303130841E+00, 0.9973399062905237E+00, 0.8956185534970393E+00, 0.4671884516860899E+00, 0.5202501498046066E+00, 0.1861385328384410E+00, 0.1330768347199243E+00, 0.6800991665489665E+00, 0.9512749631631994E+00, 0.1261574624288360E+01, 0.9903988276741268E+00, 0.5608966509936130E+00, 0.7144727578117591E+00, 0.3798570066394223E+00, 0.2262808998212762E+00, 0.4184574968871406E+00, 0.7024632317571722E+00, 0.6491193472879784E+00, 0.3651136124179467E+00, 0.1105843276664904E+00, 0.1966029864506465E+00, 0.9277628648996712E-01, 0.6757627705811050E-02, 0.2122447413720272E-02, 0.2913933674473832E-01, 0.2701688933101806E-01, 0.2136293938333395E-23, 0.0000000000000000E+00, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + n0in: 21, + dmin: 0.0000000000000000, + dmin1: 2.7016889331018056E-002, + dmin2: 5.3061698118516694E-002, + dn: 0.0000000000000000, + dn1: 2.7016889331018056E-002, + dn2: 8.6018658784156071E-002, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.2440445008292708E+01, 0.2461394773494974E+01, 0.2094976520226600E-01, 0.1017444891892999E-01, 0.1195399335050165E+01, 0.1189425435147283E+01, 0.4200549016048655E-02, 0.1849378635683999E-02, 0.5236691632680260E+00, 0.5228093175235037E+00, 0.9895328911616120E-03, 0.1620493249248586E-02, 0.8561706005512968E+00, 0.8939544038697832E+00, 0.3940429656773515E-01, 0.6132377362967349E-01, 0.1391235531991410E+01, 0.1434168925733579E+01, 0.1042571673718422E+00, 0.6181229879703373E-01, 0.8502943288943339E+00, 0.8790143072012576E+00, 0.9053227710395735E-01, 0.2145324219750511E-01, 0.2082981609510011E+00, 0.6992314020959263E+00, 0.5123864833424303E+00, 0.7139837844669097E+00, 0.9743424132304999E+00, 0.4148193287752837E+00, 0.1544607000116935E+00, 0.4268738185358478E+00, 0.1146411422862754E+01, 0.7891833197548568E+00, 0.6964571542795012E-01, 0.1157716892137957E+00, 0.1311855086360479E+01, 0.1687185709139079E+01, 0.4911023119923957E+00, 0.1498504938454686E+00, 0.5148125055608023E+00, 0.9038246924092180E+00, 0.5388626806938843E+00, 0.1006978425303630E+00, 0.1688986820057405E+00, 0.3061474807444209E+00, 0.2379466412690434E+00, 0.5288684194677825E+00, 0.6804539597693821E+00, 0.9598101715535300E+00, 0.8082246312519304E+00, 0.5423584775195998E+00, 0.6440798303130841E+00, 0.9973399062905237E+00, 0.8956185534970393E+00, 0.4671884516860899E+00, 0.5202501498046066E+00, 0.1861385328384410E+00, 0.1330768347199243E+00, 0.6800991665489665E+00, 0.9512749631631994E+00, 0.1261574624288360E+01, 0.9903988276741268E+00, 0.5608966509936130E+00, 0.7144727578117591E+00, 0.3798570066394223E+00, 0.2262808998212762E+00, 0.4184574968871406E+00, 0.7024632317571722E+00, 0.6491193472879784E+00, 0.3651136124179467E+00, 0.1105843276664904E+00, 0.1966029864506465E+00, 0.9277628648996712E-01, 0.6757627705811050E-02, 0.2122447413720272E-02, 0.2913933674473832E-01, 0.2701688933101806E-01, 0.2136293938333395E-23, 0.0000000000000000E+00, 0.2117542506861687E-04}, + tauOut: -0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2471569222413904E+01, 0.2461394773494974E+01, 0.4896382518051712E-02, 0.1017444891892999E-01, 0.1186378431264915E+01, 0.1189425435147283E+01, 0.8149780515932184E-03, 0.1849378635683999E-02, 0.5236148327211592E+00, 0.5228093175235037E+00, 0.2766627272719901E-02, 0.1620493249248586E-02, 0.9525115502267366E+00, 0.8939544038697832E+00, 0.9233342160256496E-01, 0.6132377362967349E-01, 0.1403647802928048E+01, 0.1434168925733579E+01, 0.3870906568602875E-01, 0.6181229879703373E-01, 0.8617584837127339E+00, 0.8790143072012576E+00, 0.1740717486950262E-01, 0.2145324219750511E-01, 0.1395808011693333E+01, 0.6992314020959263E+00, 0.2121884039551361E+00, 0.7139837844669097E+00, 0.6295047433559955E+00, 0.4148193287752837E+00, 0.5351535485381410E+00, 0.4268738185358478E+00, 0.3698014604305115E+00, 0.7891833197548568E+00, 0.5281978587564573E+00, 0.1157716892137957E+00, 0.1308838344228090E+01, 0.1687185709139079E+01, 0.1034799882693896E+00, 0.1498504938454686E+00, 0.9010425466701916E+00, 0.9038246924092180E+00, 0.3421413441684364E-01, 0.1006978425303630E+00, 0.8008017657953598E+00, 0.3061474807444209E+00, 0.6338813300623194E+00, 0.5288684194677825E+00, 0.8682873190108105E+00, 0.9598101715535300E+00, 0.6229686202966810E+00, 0.5423584775195998E+00, 0.8415597376799326E+00, 0.9973399062905237E+00, 0.1033340463692495E+00, 0.4671884516860899E+00, 0.7629036530181579E+00, 0.1861385328384410E+00, 0.1124645093942705E+01, 0.6800991665489665E+00, 0.6978261813392677E+00, 0.1261574624288360E+01, 0.3053203341720497E+00, 0.5608966509936130E+00, 0.4929941693545132E+00, 0.3798570066394223E+00, 0.5509778292160957E+00, 0.4184574968871406E+00, 0.2087258457383731E+00, 0.6491193472879784E+00, 0.4915348757406203E-01, 0.1105843276664904E+00, 0.4574524632962537E-01, 0.9277628648996712E-01, 0.1253505697055357E-02, 0.2122447413720272E-02, 0.2576338363396270E-01, 0.2701688933101806E-01, 0.8149780515932184E-03, 0.1620493249248586E-02}, + i0: 1, + n0: 20, + pp: 0, + n0in: 20, + dmin: 2.5763383633962696E-002, + dmin1: 4.3622798915905092E-002, + dmin2: 7.4536672467372611E-002, + dn: 2.5763383633962696E-002, + dn1: 4.3622798915905092E-002, + dn2: 9.8141518071882677E-002, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.2471569222413904E+01, 0.2461394773494974E+01, 0.4896382518051712E-02, 0.1017444891892999E-01, 0.1186378431264915E+01, 0.1189425435147283E+01, 0.8149780515932184E-03, 0.1849378635683999E-02, 0.5236148327211592E+00, 0.5228093175235037E+00, 0.2766627272719901E-02, 0.1620493249248586E-02, 0.9525115502267366E+00, 0.8939544038697832E+00, 0.9233342160256496E-01, 0.6132377362967349E-01, 0.1403647802928048E+01, 0.1434168925733579E+01, 0.3870906568602875E-01, 0.6181229879703373E-01, 0.8617584837127339E+00, 0.8790143072012576E+00, 0.1740717486950262E-01, 0.2145324219750511E-01, 0.1395808011693333E+01, 0.6992314020959263E+00, 0.2121884039551361E+00, 0.7139837844669097E+00, 0.6295047433559955E+00, 0.4148193287752837E+00, 0.5351535485381410E+00, 0.4268738185358478E+00, 0.3698014604305115E+00, 0.7891833197548568E+00, 0.5281978587564573E+00, 0.1157716892137957E+00, 0.1308838344228090E+01, 0.1687185709139079E+01, 0.1034799882693896E+00, 0.1498504938454686E+00, 0.9010425466701916E+00, 0.9038246924092180E+00, 0.3421413441684364E-01, 0.1006978425303630E+00, 0.8008017657953598E+00, 0.3061474807444209E+00, 0.6338813300623194E+00, 0.5288684194677825E+00, 0.8682873190108105E+00, 0.9598101715535300E+00, 0.6229686202966810E+00, 0.5423584775195998E+00, 0.8415597376799326E+00, 0.9973399062905237E+00, 0.1033340463692495E+00, 0.4671884516860899E+00, 0.7629036530181579E+00, 0.1861385328384410E+00, 0.1124645093942705E+01, 0.6800991665489665E+00, 0.6978261813392677E+00, 0.1261574624288360E+01, 0.3053203341720497E+00, 0.5608966509936130E+00, 0.4929941693545132E+00, 0.3798570066394223E+00, 0.5509778292160957E+00, 0.4184574968871406E+00, 0.2087258457383731E+00, 0.6491193472879784E+00, 0.4915348757406203E-01, 0.1105843276664904E+00, 0.4574524632962537E-01, 0.9277628648996712E-01, 0.1253505697055357E-02, 0.2122447413720272E-02, 0.2576338363396270E-01, 0.2701688933101806E-01, 0.8149780515932184E-03, 0.1620493249248586E-02}, + tauOut: 2.0080554394878082E-002, + ttypeOut: -3, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2471569222413904E+01, 0.2471445466333236E+01, 0.4896382518051712E-02, 0.2350431231346416E-02, 0.1186378431264915E+01, 0.1179822839486443E+01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.5236148327211592E+00, 0.5209996276036221E+00, 0.2766627272719901E-02, 0.5058054349403302E-02, 0.9525115502267366E+00, 0.1034766778881179E+01, 0.9233342160256496E-01, 0.1252490967185870E+00, 0.1403647802928048E+01, 0.1312087633296770E+01, 0.3870906568602875E-01, 0.2542350442532051E-01, 0.8617584837127339E+00, 0.8487220155581966E+00, 0.1740717486950262E-01, 0.2862783537884150E-01, 0.1395808011693333E+01, 0.1574348441670908E+01, 0.2121884039551361E+00, 0.8484373804386666E-01, 0.6295047433559955E+00, 0.1074794415251550E+01, 0.5351535485381410E+00, 0.1841287608083240E+00, 0.3698014604305115E+00, 0.7088504197799252E+00, 0.5281978587564573E+00, 0.9752771411128711E+00, 0.1308838344228090E+01, 0.4320210527858890E+00, 0.1034799882693896E+00, 0.2158225196628609E+00, 0.9010425466701916E+00, 0.7144140228254550E+00, 0.3421413441684364E-01, 0.3835134583138245E-01, 0.8008017657953598E+00, 0.1391311611427577E+01, 0.6338813300623194E+00, 0.3955915526975877E+00, 0.8682873190108105E+00, 0.1090644248011184E+01, 0.6229686202966810E+00, 0.4806932321292802E+00, 0.8415597376799326E+00, 0.4591804133211825E+00, 0.1033340463692495E+00, 0.1716839812178710E+00, 0.7629036530181579E+00, 0.1710844627144272E+01, 0.1124645093942705E+01, 0.4587247601659613E+00, 0.6978261813392677E+00, 0.5394016167466366E+00, 0.3053203341720497E+00, 0.2790520826393697E+00, 0.4929941693545132E+00, 0.7598997773325197E+00, 0.5509778292160957E+00, 0.1513401067044909E+00, 0.2087258457383731E+00, 0.1015190880092246E+00, 0.4915348757406203E-01, 0.2214892234681356E-01, 0.4574524632962537E-01, 0.1982969108114764E-01, 0.1253505697055357E-02, 0.1628595626045726E-02, 0.2576338363396270E-01, 0.1911464940919745E-01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + n0in: 20, + dmin: 1.8576185384092288E-002, + dmin1: 1.8576185384092288E-002, + dmin2: 5.2365600435162571E-002, + dn: 1.9114649409197451E-002, + dn1: 1.8576185384092288E-002, + dn2: 5.2365600435162571E-002, + tau: 5.0201385987195205E-003, + ttype: -15, + g: 0.0000000000000000, + zOut: []float64{0.2471569222413904E+01, 0.2471445466333236E+01, 0.4896382518051712E-02, 0.2350431231346416E-02, 0.1186378431264915E+01, 0.1179822839486443E+01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.5236148327211592E+00, 0.5209996276036221E+00, 0.2766627272719901E-02, 0.5058054349403302E-02, 0.9525115502267366E+00, 0.1034766778881179E+01, 0.9233342160256496E-01, 0.1252490967185870E+00, 0.1403647802928048E+01, 0.1312087633296770E+01, 0.3870906568602875E-01, 0.2542350442532051E-01, 0.8617584837127339E+00, 0.8487220155581966E+00, 0.1740717486950262E-01, 0.2862783537884150E-01, 0.1395808011693333E+01, 0.1574348441670908E+01, 0.2121884039551361E+00, 0.8484373804386666E-01, 0.6295047433559955E+00, 0.1074794415251550E+01, 0.5351535485381410E+00, 0.1841287608083240E+00, 0.3698014604305115E+00, 0.7088504197799252E+00, 0.5281978587564573E+00, 0.9752771411128711E+00, 0.1308838344228090E+01, 0.4320210527858890E+00, 0.1034799882693896E+00, 0.2158225196628609E+00, 0.9010425466701916E+00, 0.7144140228254550E+00, 0.3421413441684364E-01, 0.3835134583138245E-01, 0.8008017657953598E+00, 0.1391311611427577E+01, 0.6338813300623194E+00, 0.3955915526975877E+00, 0.8682873190108105E+00, 0.1090644248011184E+01, 0.6229686202966810E+00, 0.4806932321292802E+00, 0.8415597376799326E+00, 0.4591804133211825E+00, 0.1033340463692495E+00, 0.1716839812178710E+00, 0.7629036530181579E+00, 0.1710844627144272E+01, 0.1124645093942705E+01, 0.4587247601659613E+00, 0.6978261813392677E+00, 0.5394016167466366E+00, 0.3053203341720497E+00, 0.2790520826393697E+00, 0.4929941693545132E+00, 0.7598997773325197E+00, 0.5509778292160957E+00, 0.1513401067044909E+00, 0.2087258457383731E+00, 0.1015190880092246E+00, 0.4915348757406203E-01, 0.2214892234681356E-01, 0.4574524632962537E-01, 0.1982969108114764E-01, 0.1253505697055357E-02, 0.1628595626045726E-02, 0.2576338363396270E-01, 0.1911464940919745E-01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.2117542506861687E-04}, + tauOut: 5.4769133315280185E-003, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2468318984233055E+01, 0.2471445466333236E+01, 0.1123474100024551E-02, 0.2350431231346416E-02, 0.1173584145846428E+01, 0.1179822839486443E+01, 0.1605699355811189E-03, 0.3616937915375072E-03, 0.5204201986859162E+00, 0.5209996276036221E+00, 0.1005707814522541E-01, 0.5058054349403302E-02, 0.1144481884123012E+01, 0.1034766778881179E+01, 0.1435914304680996E+00, 0.1252490967185870E+00, 0.1188442793922463E+01, 0.1312087633296770E+01, 0.1815610143690141E-01, 0.2542350442532051E-01, 0.8537168361686087E+00, 0.8487220155581966E+00, 0.5279290053521807E-01, 0.2862783537884150E-01, 0.1600922365848029E+01, 0.1574348441670908E+01, 0.5696064828871891E-01, 0.8484373804386666E-01, 0.1196485614439627E+01, 0.1074794415251550E+01, 0.1090859328498209E+00, 0.1841287608083240E+00, 0.1569564714711448E+01, 0.7088504197799252E+00, 0.2684440171930437E+00, 0.9752771411128711E+00, 0.3739226419241781E+00, 0.4320210527858890E+00, 0.4123490187575627E+00, 0.2158225196628609E+00, 0.3349394365677468E+00, 0.7144140228254550E+00, 0.1593084209965356E+00, 0.3835134583138245E-01, 0.1622117829797102E+01, 0.1391311611427577E+01, 0.2659792301064862E+00, 0.3955915526975877E+00, 0.1299881336702450E+01, 0.1090644248011184E+01, 0.1698038973078534E+00, 0.4806932321292802E+00, 0.4555835838996722E+00, 0.4591804133211825E+00, 0.6447216871142054E+00, 0.1716839812178710E+00, 0.1519370786864500E+01, 0.1710844627144272E+01, 0.1628548339973444E+00, 0.4587247601659613E+00, 0.6501219520571339E+00, 0.5394016167466366E+00, 0.3261720586281595E+00, 0.2790520826393697E+00, 0.5795909120773233E+00, 0.7598997773325197E+00, 0.2650819619788820E-01, 0.1513401067044909E+00, 0.9168290082662192E-01, 0.1015190880092246E+00, 0.4790492926791300E-02, 0.2214892234681356E-01, 0.1119088044887405E-01, 0.1982969108114764E-01, 0.2781732372482683E-02, 0.1628595626045726E-02, 0.1085600370518675E-01, 0.1911464940919745E-01, 0.1605699355811189E-03, 0.3616937915375072E-03}, + i0: 1, + n0: 20, + pp: 0, + n0in: 20, + dmin: 9.5622848228283271E-003, + dmin1: 9.5622848228283271E-003, + dmin2: 6.9533978479808370E-002, + dn: 1.0856003705186750E-002, + dn1: 9.5622848228283271E-003, + dn2: 6.9533978479808370E-002, + tau: 5.4769133315280185E-003, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2468318984233055E+01, 0.2471445466333236E+01, 0.1123474100024551E-02, 0.2350431231346416E-02, 0.1173584145846428E+01, 0.1179822839486443E+01, 0.1605699355811189E-03, 0.3616937915375072E-03, 0.5204201986859162E+00, 0.5209996276036221E+00, 0.1005707814522541E-01, 0.5058054349403302E-02, 0.1144481884123012E+01, 0.1034766778881179E+01, 0.1435914304680996E+00, 0.1252490967185870E+00, 0.1188442793922463E+01, 0.1312087633296770E+01, 0.1815610143690141E-01, 0.2542350442532051E-01, 0.8537168361686087E+00, 0.8487220155581966E+00, 0.5279290053521807E-01, 0.2862783537884150E-01, 0.1600922365848029E+01, 0.1574348441670908E+01, 0.5696064828871891E-01, 0.8484373804386666E-01, 0.1196485614439627E+01, 0.1074794415251550E+01, 0.1090859328498209E+00, 0.1841287608083240E+00, 0.1569564714711448E+01, 0.7088504197799252E+00, 0.2684440171930437E+00, 0.9752771411128711E+00, 0.3739226419241781E+00, 0.4320210527858890E+00, 0.4123490187575627E+00, 0.2158225196628609E+00, 0.3349394365677468E+00, 0.7144140228254550E+00, 0.1593084209965356E+00, 0.3835134583138245E-01, 0.1622117829797102E+01, 0.1391311611427577E+01, 0.2659792301064862E+00, 0.3955915526975877E+00, 0.1299881336702450E+01, 0.1090644248011184E+01, 0.1698038973078534E+00, 0.4806932321292802E+00, 0.4555835838996722E+00, 0.4591804133211825E+00, 0.6447216871142054E+00, 0.1716839812178710E+00, 0.1519370786864500E+01, 0.1710844627144272E+01, 0.1628548339973444E+00, 0.4587247601659613E+00, 0.6501219520571339E+00, 0.5394016167466366E+00, 0.3261720586281595E+00, 0.2790520826393697E+00, 0.5795909120773233E+00, 0.7598997773325197E+00, 0.2650819619788820E-01, 0.1513401067044909E+00, 0.9168290082662192E-01, 0.1015190880092246E+00, 0.4790492926791300E-02, 0.2214892234681356E-01, 0.1119088044887405E-01, 0.1982969108114764E-01, 0.2781732372482683E-02, 0.1628595626045726E-02, 0.1085600370518675E-01, 0.1911464940919745E-01, 0.1605699355811189E-03, 0.3616937915375072E-03}, + tauOut: 5.1216063611655054E-003, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2468318984233055E+01, 0.2464320851971913E+01, 0.1123474100024551E-02, 0.5350323562789559E-03, 0.1173584145846428E+01, 0.1168088077064565E+01, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.5204201986859162E+00, 0.5252841314829605E+00, 0.1005707814522541E-01, 0.2191222436498315E-01, 0.1144481884123012E+01, 0.1261039483864963E+01, 0.1435914304680996E+00, 0.1353250258951489E+00, 0.1188442793922463E+01, 0.1066152263103050E+01, 0.1815610143690141E-01, 0.1453842008528346E-01, 0.8537168361686087E+00, 0.8868497102573779E+00, 0.5279290053521807E-01, 0.9530062900995111E-01, 0.1600922365848029E+01, 0.1557460778765631E+01, 0.5696064828871891E-01, 0.4375878814786067E-01, 0.1196485614439627E+01, 0.1256691152780422E+01, 0.1090859328498209E+00, 0.1362446379077657E+00, 0.1569564714711448E+01, 0.1696642487635560E+01, 0.2684440171930437E+00, 0.5916231430550117E-01, 0.3739226419241781E+00, 0.7219877400150740E+00, 0.4123490187575627E+00, 0.1912940350054112E+00, 0.3349394365677468E+00, 0.2978322161977056E+00, 0.1593084209965356E+00, 0.8676597630518320E+00, 0.1622117829797102E+01, 0.1015315690490590E+01, 0.2659792301064862E+00, 0.3405260456467969E+00, 0.1299881336702450E+01, 0.1124037582002341E+01, 0.1698038973078534E+00, 0.6882320425428856E-01, 0.4555835838996722E+00, 0.1026360460398424E+01, 0.6447216871142054E+00, 0.9544125430154021E+00, 0.1519370786864500E+01, 0.7226914714852769E+00, 0.1628548339973444E+00, 0.1465016632377001E+00, 0.6501219520571339E+00, 0.8246707410864278E+00, 0.3261720586281595E+00, 0.2292385937027206E+00, 0.5795909120773233E+00, 0.3717389082113253E+00, 0.2650819619788820E-01, 0.6537783023029759E-02, 0.9168290082662192E-01, 0.8481400436921797E-01, 0.4790492926791300E-02, 0.6320870478125323E-03, 0.1119088044887405E-01, 0.8218919412378699E-02, 0.2781732372482683E-02, 0.3674266095981827E-02, 0.1085600370518675E-01, 0.2060131248039419E-02, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + n0in: 20, + dmin: 2.0601312480394186E-003, + dmin1: 5.4371870398960158E-003, + dmin2: 8.0023511442426670E-002, + dn: 2.0601312480394186E-003, + dn1: 5.4371870398960158E-003, + dn2: 8.0023511442426670E-002, + tau: 5.1216063611655054E-003, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2468318984233055E+01, 0.2464320851971913E+01, 0.1123474100024551E-02, 0.5350323562789559E-03, 0.1173584145846428E+01, 0.1168088077064565E+01, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.5204201986859162E+00, 0.5252841314829605E+00, 0.1005707814522541E-01, 0.2191222436498315E-01, 0.1144481884123012E+01, 0.1261039483864963E+01, 0.1435914304680996E+00, 0.1353250258951489E+00, 0.1188442793922463E+01, 0.1066152263103050E+01, 0.1815610143690141E-01, 0.1453842008528346E-01, 0.8537168361686087E+00, 0.8868497102573779E+00, 0.5279290053521807E-01, 0.9530062900995111E-01, 0.1600922365848029E+01, 0.1557460778765631E+01, 0.5696064828871891E-01, 0.4375878814786067E-01, 0.1196485614439627E+01, 0.1256691152780422E+01, 0.1090859328498209E+00, 0.1362446379077657E+00, 0.1569564714711448E+01, 0.1696642487635560E+01, 0.2684440171930437E+00, 0.5916231430550117E-01, 0.3739226419241781E+00, 0.7219877400150740E+00, 0.4123490187575627E+00, 0.1912940350054112E+00, 0.3349394365677468E+00, 0.2978322161977056E+00, 0.1593084209965356E+00, 0.8676597630518320E+00, 0.1622117829797102E+01, 0.1015315690490590E+01, 0.2659792301064862E+00, 0.3405260456467969E+00, 0.1299881336702450E+01, 0.1124037582002341E+01, 0.1698038973078534E+00, 0.6882320425428856E-01, 0.4555835838996722E+00, 0.1026360460398424E+01, 0.6447216871142054E+00, 0.9544125430154021E+00, 0.1519370786864500E+01, 0.7226914714852769E+00, 0.1628548339973444E+00, 0.1465016632377001E+00, 0.6501219520571339E+00, 0.8246707410864278E+00, 0.3261720586281595E+00, 0.2292385937027206E+00, 0.5795909120773233E+00, 0.3717389082113253E+00, 0.2650819619788820E-01, 0.6537783023029759E-02, 0.9168290082662192E-01, 0.8481400436921797E-01, 0.4790492926791300E-02, 0.6320870478125323E-03, 0.1119088044887405E-01, 0.8218919412378699E-02, 0.2781732372482683E-02, 0.3674266095981827E-02, 0.1085600370518675E-01, 0.2060131248039419E-02, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.2117542506861687E-04}, + tauOut: 1.2817878169164906E-003, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2463574096511276E+01, 0.2464320851971913E+01, 0.2536822079344948E-03, 0.5350323562789559E-03, 0.1166624146026729E+01, 0.1168088077064565E+01, 0.3221114082852138E-04, 0.7153898701552432E-04, 0.5458823568901986E+00, 0.5252841314829605E+00, 0.5061929508212644E-01, 0.2191222436498315E-01, 0.1344463426861069E+01, 0.1261039483864963E+01, 0.1073120173669855E+00, 0.1353250258951489E+00, 0.9720968780044319E+00, 0.1066152263103050E+01, 0.1326348631702415E-01, 0.1453842008528346E-01, 0.9676050651333883E+00, 0.8868497102573779E+00, 0.1533962535161303E+00, 0.9530062900995111E-01, 0.1446541525580445E+01, 0.1557460778765631E+01, 0.3801569533217738E-01, 0.4375878814786067E-01, 0.1353638307539094E+01, 0.1256691152780422E+01, 0.1707682473962209E+00, 0.1362446379077657E+00, 0.1583754766727924E+01, 0.1696642487635560E+01, 0.2697037855661164E-01, 0.5916231430550117E-01, 0.8850296086469572E+00, 0.7219877400150740E+00, 0.6437471225190403E-01, 0.1912940350054112E+00, 0.1099835479180717E+01, 0.2978322161977056E+00, 0.8009821360646626E+00, 0.8676597630518320E+00, 0.5535778122558079E+00, 0.1015315690490590E+01, 0.6914368034330997E+00, 0.3405260456467969E+00, 0.5001421950066134E+00, 0.1124037582002341E+01, 0.1412346654806686E+00, 0.6882320425428856E-01, 0.1838256550116241E+01, 0.1026360460398424E+01, 0.3752173792456719E+00, 0.9544125430154021E+00, 0.4926939676603885E+00, 0.7226914714852769E+00, 0.2452143584512202E+00, 0.1465016632377001E+00, 0.8074131885210117E+00, 0.8246707410864278E+00, 0.1055431169003394E+00, 0.2292385937027206E+00, 0.2714517865170992E+00, 0.3717389082113253E+00, 0.2042703660177667E-02, 0.6537783023029759E-02, 0.8212159993993635E-01, 0.8481400436921797E-01, 0.6326073178529442E-04, 0.6320870478125323E-03, 0.1054813695965874E-01, 0.8218919412378699E-02, 0.7176120699696391E-03, 0.3674266095981827E-02, 0.6073136115328898E-04, 0.2060131248039419E-02, 0.3221114082852138E-04, 0.7153898701552432E-04}, + i0: 1, + n0: 20, + pp: 0, + n0in: 20, + dmin: 6.0731361153288982E-005, + dmin1: 6.8738708636769136E-003, + dmin2: 8.1489512892123819E-002, + dn: 6.0731361153288982E-005, + dn1: 6.8738708636769136E-003, + dn2: 8.1489512892123819E-002, + tau: 1.2817878169164906E-003, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2463574096511276E+01, 0.2464320851971913E+01, 0.2536822079344948E-03, 0.5350323562789559E-03, 0.1166624146026729E+01, 0.1168088077064565E+01, 0.3221114082852138E-04, 0.7153898701552432E-04, 0.5458823568901986E+00, 0.5252841314829605E+00, 0.5061929508212644E-01, 0.2191222436498315E-01, 0.1344463426861069E+01, 0.1261039483864963E+01, 0.1073120173669855E+00, 0.1353250258951489E+00, 0.9720968780044319E+00, 0.1066152263103050E+01, 0.1326348631702415E-01, 0.1453842008528346E-01, 0.9676050651333883E+00, 0.8868497102573779E+00, 0.1533962535161303E+00, 0.9530062900995111E-01, 0.1446541525580445E+01, 0.1557460778765631E+01, 0.3801569533217738E-01, 0.4375878814786067E-01, 0.1353638307539094E+01, 0.1256691152780422E+01, 0.1707682473962209E+00, 0.1362446379077657E+00, 0.1583754766727924E+01, 0.1696642487635560E+01, 0.2697037855661164E-01, 0.5916231430550117E-01, 0.8850296086469572E+00, 0.7219877400150740E+00, 0.6437471225190403E-01, 0.1912940350054112E+00, 0.1099835479180717E+01, 0.2978322161977056E+00, 0.8009821360646626E+00, 0.8676597630518320E+00, 0.5535778122558079E+00, 0.1015315690490590E+01, 0.6914368034330997E+00, 0.3405260456467969E+00, 0.5001421950066134E+00, 0.1124037582002341E+01, 0.1412346654806686E+00, 0.6882320425428856E-01, 0.1838256550116241E+01, 0.1026360460398424E+01, 0.3752173792456719E+00, 0.9544125430154021E+00, 0.4926939676603885E+00, 0.7226914714852769E+00, 0.2452143584512202E+00, 0.1465016632377001E+00, 0.8074131885210117E+00, 0.8246707410864278E+00, 0.1055431169003394E+00, 0.2292385937027206E+00, 0.2714517865170992E+00, 0.3717389082113253E+00, 0.2042703660177667E-02, 0.6537783023029759E-02, 0.8212159993993635E-01, 0.8481400436921797E-01, 0.6326073178529442E-04, 0.6320870478125323E-03, 0.1054813695965874E-01, 0.8218919412378699E-02, 0.7176120699696391E-03, 0.3674266095981827E-02, 0.6073136115328898E-04, 0.2060131248039419E-02, 0.3221114082852138E-04, 0.7153898701552432E-04}, + tauOut: 5.6837241251038845E-005, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2463574096511276E+01, 0.2463770941477959E+01, 0.2536822079344948E-03, 0.1201214707955848E-03, 0.1166624146026729E+01, 0.1166479398455512E+01, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.5458823568901986E+00, 0.5964297407456295E+00, 0.5061929508212644E-01, 0.1141052940222717E+00, 0.1344463426861069E+01, 0.1337613312964532E+01, 0.1073120173669855E+00, 0.7798791776646297E-01, 0.9720968780044319E+00, 0.9073156093137420E+00, 0.1326348631702415E-01, 0.1414482062243694E-01, 0.9676050651333883E+00, 0.1106799660785830E+01, 0.1533962535161303E+00, 0.2004825791345134E+00, 0.1446541525580445E+01, 0.1284017804536858E+01, 0.3801569533217738E-01, 0.4007693764646178E-01, 0.1353638307539094E+01, 0.1484272780047602E+01, 0.1707682473962209E+00, 0.1822138285193538E+00, 0.1583754766727924E+01, 0.1428454479523931E+01, 0.2697037855661164E-01, 0.1671007646458111E-01, 0.8850296086469572E+00, 0.9326374071930291E+00, 0.6437471225190403E-01, 0.7591545433480534E-01, 0.1099835479180717E+01, 0.1824845323669324E+01, 0.8009821360646626E+00, 0.2429827519008994E+00, 0.5535778122558079E+00, 0.1001975026546757E+01, 0.6914368034330997E+00, 0.3451350696526060E+00, 0.5001421950066134E+00, 0.2961849535934249E+00, 0.1412346654806686E+00, 0.8765656248686587E+00, 0.1838256550116241E+01, 0.1336851467252003E+01, 0.3752173792456719E+00, 0.1382856239786244E+00, 0.4926939676603885E+00, 0.5995658648917332E+00, 0.2452143584512202E+00, 0.3302211126778973E+00, 0.8074131885210117E+00, 0.5826783555022028E+00, 0.1055431169003394E+00, 0.4916926700063749E-01, 0.2714517865170992E+00, 0.2242683859353883E+00, 0.2042703660177667E-02, 0.7479881396448043E-03, 0.8212159993993635E-01, 0.8138003529082581E-01, 0.6326073178529442E-04, 0.8199589256196194E-05, 0.1054813695965874E-01, 0.1120071219912114E-01, 0.7176120699696391E-03, 0.3890963093641941E-05, 0.6073136115328898E-04, 0.3156808608191942E-08, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + n0in: 20, + dmin: 3.1568086081919418E-009, + dmin1: 1.0483100129151506E-002, + dmin2: 8.1316774559040517E-002, + dn: 3.1568086081919418E-009, + dn1: 1.0483100129151506E-002, + dn2: 8.1316774559040517E-002, + tau: 5.6837241251038845E-005, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2463574096511276E+01, 0.2463770941477959E+01, 0.2536822079344948E-03, 0.1201214707955848E-03, 0.1166624146026729E+01, 0.1166479398455512E+01, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.5458823568901986E+00, 0.5964297407456295E+00, 0.5061929508212644E-01, 0.1141052940222717E+00, 0.1344463426861069E+01, 0.1337613312964532E+01, 0.1073120173669855E+00, 0.7798791776646297E-01, 0.9720968780044319E+00, 0.9073156093137420E+00, 0.1326348631702415E-01, 0.1414482062243694E-01, 0.9676050651333883E+00, 0.1106799660785830E+01, 0.1533962535161303E+00, 0.2004825791345134E+00, 0.1446541525580445E+01, 0.1284017804536858E+01, 0.3801569533217738E-01, 0.4007693764646178E-01, 0.1353638307539094E+01, 0.1484272780047602E+01, 0.1707682473962209E+00, 0.1822138285193538E+00, 0.1583754766727924E+01, 0.1428454479523931E+01, 0.2697037855661164E-01, 0.1671007646458111E-01, 0.8850296086469572E+00, 0.9326374071930291E+00, 0.6437471225190403E-01, 0.7591545433480534E-01, 0.1099835479180717E+01, 0.1824845323669324E+01, 0.8009821360646626E+00, 0.2429827519008994E+00, 0.5535778122558079E+00, 0.1001975026546757E+01, 0.6914368034330997E+00, 0.3451350696526060E+00, 0.5001421950066134E+00, 0.2961849535934249E+00, 0.1412346654806686E+00, 0.8765656248686587E+00, 0.1838256550116241E+01, 0.1336851467252003E+01, 0.3752173792456719E+00, 0.1382856239786244E+00, 0.4926939676603885E+00, 0.5995658648917332E+00, 0.2452143584512202E+00, 0.3302211126778973E+00, 0.8074131885210117E+00, 0.5826783555022028E+00, 0.1055431169003394E+00, 0.4916926700063749E-01, 0.2714517865170992E+00, 0.2242683859353883E+00, 0.2042703660177667E-02, 0.7479881396448043E-03, 0.8212159993993635E-01, 0.8138003529082581E-01, 0.6326073178529442E-04, 0.8199589256196194E-05, 0.1054813695965874E-01, 0.1120071219912114E-01, 0.7176120699696391E-03, 0.3890963093641941E-05, 0.6073136115328898E-04, 0.3156808608191942E-08, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.2117542506861687E-04}, + tauOut: 3.1557121791797713E-009, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2463891059793043E+01, 0.2463770941477959E+01, 0.5686908130061341E-04, 0.1201214707955848E-03, 0.1166437600203943E+01, 0.1166479398455512E+01, 0.7707718980490818E-05, 0.1507398544447245E-04, 0.7105273238932086E+00, 0.5964297407456295E+00, 0.2148105431436762E+00, 0.1141052940222717E+00, 0.1200790684431606E+01, 0.1337613312964532E+01, 0.5892755169139442E-01, 0.7798791776646297E-01, 0.8625328750890724E+00, 0.9073156093137420E+00, 0.1815059242254727E-01, 0.1414482062243694E-01, 0.1289131644342084E+01, 0.1106799660785830E+01, 0.1996872873596725E+00, 0.2004825791345134E+00, 0.1124407451667935E+01, 0.1284017804536858E+01, 0.5290351604133232E-01, 0.4007693764646178E-01, 0.1613583089369911E+01, 0.1484272780047602E+01, 0.1613081850537457E+00, 0.1822138285193538E+00, 0.1283856367779054E+01, 0.1428454479523931E+01, 0.1213877407087503E-01, 0.1671007646458111E-01, 0.9964140843012472E+00, 0.9326374071930291E+00, 0.1390325207358455E+00, 0.7591545433480534E-01, 0.1928795551678665E+01, 0.1824845323669324E+01, 0.1262252233392066E+00, 0.2429827519008994E+00, 0.1220884869704444E+01, 0.1001975026546757E+01, 0.8372928285471114E-01, 0.3451350696526060E+00, 0.1089021292451660E+01, 0.2961849535934249E+00, 0.1076046951396362E+01, 0.8765656248686587E+00, 0.3990901366785531E+00, 0.1336851467252003E+01, 0.2077509116934600E+00, 0.1382856239786244E+00, 0.7220360627204584E+00, 0.5995658648917332E+00, 0.2664862668525171E+00, 0.3302211126778973E+00, 0.3653613524946110E+00, 0.5826783555022028E+00, 0.3018138637972599E-01, 0.4916926700063749E-01, 0.1948349845395949E+00, 0.2242683859353883E+00, 0.3124249032854923E-03, 0.7479881396448043E-03, 0.8107580682108434E-01, 0.8138003529082581E-01, 0.1132782305976083E-05, 0.8199589256196194E-05, 0.1120346722419663E-01, 0.1120071219912114E-01, 0.1096359327194516E-11, 0.3890963093641941E-05, 0.6968497581336674E-16, 0.3156808608191942E-08, 0.7707718980490818E-05, 0.1507398544447245E-04}, + i0: 1, + n0: 20, + pp: 0, + n0in: 20, + dmin: 6.9684975813366743E-017, + dmin1: 1.1199576261102989E-002, + dmin2: 8.1067607231828140E-002, + dn: 6.9684975813366743E-017, + dn1: 1.1199576261102989E-002, + dn2: 8.1067607231828140E-002, + tau: 3.1557121791797713E-009, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2463891059793043E+01, 0.2463770941477959E+01, 0.5686908130061341E-04, 0.1201214707955848E-03, 0.1166437600203943E+01, 0.1166479398455512E+01, 0.7707718980490818E-05, 0.1507398544447245E-04, 0.7105273238932086E+00, 0.5964297407456295E+00, 0.2148105431436762E+00, 0.1141052940222717E+00, 0.1200790684431606E+01, 0.1337613312964532E+01, 0.5892755169139442E-01, 0.7798791776646297E-01, 0.8625328750890724E+00, 0.9073156093137420E+00, 0.1815059242254727E-01, 0.1414482062243694E-01, 0.1289131644342084E+01, 0.1106799660785830E+01, 0.1996872873596725E+00, 0.2004825791345134E+00, 0.1124407451667935E+01, 0.1284017804536858E+01, 0.5290351604133232E-01, 0.4007693764646178E-01, 0.1613583089369911E+01, 0.1484272780047602E+01, 0.1613081850537457E+00, 0.1822138285193538E+00, 0.1283856367779054E+01, 0.1428454479523931E+01, 0.1213877407087503E-01, 0.1671007646458111E-01, 0.9964140843012472E+00, 0.9326374071930291E+00, 0.1390325207358455E+00, 0.7591545433480534E-01, 0.1928795551678665E+01, 0.1824845323669324E+01, 0.1262252233392066E+00, 0.2429827519008994E+00, 0.1220884869704444E+01, 0.1001975026546757E+01, 0.8372928285471114E-01, 0.3451350696526060E+00, 0.1089021292451660E+01, 0.2961849535934249E+00, 0.1076046951396362E+01, 0.8765656248686587E+00, 0.3990901366785531E+00, 0.1336851467252003E+01, 0.2077509116934600E+00, 0.1382856239786244E+00, 0.7220360627204584E+00, 0.5995658648917332E+00, 0.2664862668525171E+00, 0.3302211126778973E+00, 0.3653613524946110E+00, 0.5826783555022028E+00, 0.3018138637972599E-01, 0.4916926700063749E-01, 0.1948349845395949E+00, 0.2242683859353883E+00, 0.3124249032854923E-03, 0.7479881396448043E-03, 0.8107580682108434E-01, 0.8138003529082581E-01, 0.1132782305976083E-05, 0.8199589256196194E-05, 0.1120346722419663E-01, 0.1120071219912114E-01, 0.1096359327194516E-11, 0.3890963093641941E-05, 0.6968497581336674E-16, 0.3156808608191942E-08, 0.7707718980490818E-05, 0.1507398544447245E-04}, + tauOut: 6.9684975806547287E-017, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2463891059793043E+01, 0.2463947928874343E+01, 0.5686908130061341E-04, 0.2692193042748079E-04, 0.1166437600203943E+01, 0.1166418385992496E+01, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.7105273238932086E+00, 0.9253331718563164E+00, 0.2148105431436762E+00, 0.2787563517334627E+00, 0.1200790684431606E+01, 0.9809618843895378E+00, 0.5892755169139442E-01, 0.5181337969514327E-01, 0.8625328750890724E+00, 0.8288700878164763E+00, 0.1815059242254727E-01, 0.2822939734392020E-01, 0.1289131644342084E+01, 0.1460589534357837E+01, 0.1996872873596725E+00, 0.1537255119449346E+00, 0.1124407451667935E+01, 0.1023585455764333E+01, 0.5290351604133232E-01, 0.8339725654733963E-01, 0.1613583089369911E+01, 0.1691494017876317E+01, 0.1613081850537457E+00, 0.1224340957564512E+00, 0.1283856367779054E+01, 0.1173561046093478E+01, 0.1213877407087503E-01, 0.1030644761994533E-01, 0.9964140843012472E+00, 0.1125140157417147E+01, 0.1390325207358455E+00, 0.2383394688796517E+00, 0.1928795551678665E+01, 0.1816681306138221E+01, 0.1262252233392066E+00, 0.8482856339700598E-01, 0.1220884869704444E+01, 0.1219785589162149E+01, 0.8372928285471114E-01, 0.7475327847832687E-01, 0.1089021292451660E+01, 0.2090314965369696E+01, 0.1076046951396362E+01, 0.2054425921547012E+00, 0.3990901366785531E+00, 0.4013984562173118E+00, 0.2077509116934600E+00, 0.3737026089221466E+00, 0.7220360627204584E+00, 0.6148197206508288E+00, 0.2664862668525171E+00, 0.1583615157552351E+00, 0.3653613524946110E+00, 0.2371812231191019E+00, 0.3018138637972599E-01, 0.2479281399828426E-01, 0.1948349845395949E+00, 0.1703545954445960E+00, 0.3124249032854923E-03, 0.1486904479375115E-03, 0.8107580682108434E-01, 0.8092824915545274E-01, 0.1132782305976083E-05, 0.1568190288260776E-06, 0.1120346722419663E-01, 0.1120331040626409E-01, 0.1096359327194516E-11, 0.6819392699821255E-26, 0.6968497581336674E-16, 0.6162975822039155E-31, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + n0in: 20, + dmin: 6.1629758220391547E-032, + dmin1: 1.1203310405167735E-002, + dmin2: 8.0927116373146771E-002, + dn: 6.1629758220391547E-032, + dn1: 1.1203310405167735E-002, + dn2: 8.0927116373146771E-002, + tau: 6.9684975806547287E-017, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2463891059793043E+01, 0.2463947928874343E+01, 0.5686908130061341E-04, 0.2692193042748079E-04, 0.1166437600203943E+01, 0.1166418385992496E+01, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.7105273238932086E+00, 0.9253331718563164E+00, 0.2148105431436762E+00, 0.2787563517334627E+00, 0.1200790684431606E+01, 0.9809618843895378E+00, 0.5892755169139442E-01, 0.5181337969514327E-01, 0.8625328750890724E+00, 0.8288700878164763E+00, 0.1815059242254727E-01, 0.2822939734392020E-01, 0.1289131644342084E+01, 0.1460589534357837E+01, 0.1996872873596725E+00, 0.1537255119449346E+00, 0.1124407451667935E+01, 0.1023585455764333E+01, 0.5290351604133232E-01, 0.8339725654733963E-01, 0.1613583089369911E+01, 0.1691494017876317E+01, 0.1613081850537457E+00, 0.1224340957564512E+00, 0.1283856367779054E+01, 0.1173561046093478E+01, 0.1213877407087503E-01, 0.1030644761994533E-01, 0.9964140843012472E+00, 0.1125140157417147E+01, 0.1390325207358455E+00, 0.2383394688796517E+00, 0.1928795551678665E+01, 0.1816681306138221E+01, 0.1262252233392066E+00, 0.8482856339700598E-01, 0.1220884869704444E+01, 0.1219785589162149E+01, 0.8372928285471114E-01, 0.7475327847832687E-01, 0.1089021292451660E+01, 0.2090314965369696E+01, 0.1076046951396362E+01, 0.2054425921547012E+00, 0.3990901366785531E+00, 0.4013984562173118E+00, 0.2077509116934600E+00, 0.3737026089221466E+00, 0.7220360627204584E+00, 0.6148197206508288E+00, 0.2664862668525171E+00, 0.1583615157552351E+00, 0.3653613524946110E+00, 0.2371812231191019E+00, 0.3018138637972599E-01, 0.2479281399828426E-01, 0.1948349845395949E+00, 0.1703545954445960E+00, 0.3124249032854923E-03, 0.1486904479375115E-03, 0.8107580682108434E-01, 0.8092824915545274E-01, 0.1132782305976083E-05, 0.1568190288260776E-06, 0.1120346722419663E-01, 0.1120331040626409E-01, 0.1096359327194516E-11, 0.6819392699821255E-26, 0.6968497581336674E-16, 0.6162975822039155E-31, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.2117542506861687E-04}, + tauOut: 6.1629758220391547E-032, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2463974850804771E+01, 0.2463947928874343E+01, 0.1274454348702788E-04, 0.2692193042748079E-04, 0.1166410336629578E+01, 0.1166418385992496E+01, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.1204085798823124E+01, 0.9253331718563164E+00, 0.2271012218143261E+00, 0.2787563517334627E+00, 0.8056740422703550E+00, 0.9809618843895378E+00, 0.5330513126246473E-01, 0.5181337969514327E-01, 0.8037943538979316E+00, 0.8288700878164763E+00, 0.5129615818002433E-01, 0.2822939734392020E-01, 0.1563018888122747E+01, 0.1460589534357837E+01, 0.1006713350698832E+00, 0.1537255119449346E+00, 0.1006311377241790E+01, 0.1023585455764333E+01, 0.1401812239704283E+00, 0.8339725654733963E-01, 0.1673746889662340E+01, 0.1691494017876317E+01, 0.8584564749956700E-01, 0.1224340957564512E+00, 0.1098021846213856E+01, 0.1173561046093478E+01, 0.1056099032774466E-01, 0.1030644761994533E-01, 0.1352918635969054E+01, 0.1125140157417147E+01, 0.3200390963041470E+00, 0.2383394688796517E+00, 0.1581470773231080E+01, 0.1816681306138221E+01, 0.6542811978092533E-01, 0.8482856339700598E-01, 0.1229110747859551E+01, 0.1219785589162149E+01, 0.1271308521106110E+00, 0.7475327847832687E-01, 0.2168626705413786E+01, 0.2090314965369696E+01, 0.3802606466401751E-01, 0.2054425921547012E+00, 0.7370750004754409E+00, 0.4013984562173118E+00, 0.3117182559112661E+00, 0.3737026089221466E+00, 0.4614629804947978E+00, 0.6148197206508288E+00, 0.8139413038408401E-01, 0.1583615157552351E+00, 0.1805799067333021E+00, 0.2371812231191019E+00, 0.2338892446571373E-01, 0.2479281399828426E-01, 0.1471143614268198E+00, 0.1703545954445960E+00, 0.8179526119010886E-04, 0.1486904479375115E-03, 0.8084661071329148E-01, 0.8092824915545274E-01, 0.2173118009582292E-07, 0.1568190288260776E-06, 0.1120328867508400E-01, 0.1120331040626409E-01, 0.3751376363572422E-55, 0.6819392699821255E-26}, + i0: 1, + n0: 19, + pp: 0, + n0in: 20, + dmin: 6.1629758220391547E-032, + dmin1: 1.1203288675083998E-002, + dmin2: 8.0846453894262649E-002, + dn: 6.1629758220391547E-032, + dn1: 1.1203288675083998E-002, + dn2: 8.0846453894262649E-002, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2463974850804771E+01, 0.2463947928874343E+01, 0.1274454348702788E-04, 0.2692193042748079E-04, 0.1166410336629578E+01, 0.1166418385992496E+01, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.1204085798823124E+01, 0.9253331718563164E+00, 0.2271012218143261E+00, 0.2787563517334627E+00, 0.8056740422703550E+00, 0.9809618843895378E+00, 0.5330513126246473E-01, 0.5181337969514327E-01, 0.8037943538979316E+00, 0.8288700878164763E+00, 0.5129615818002433E-01, 0.2822939734392020E-01, 0.1563018888122747E+01, 0.1460589534357837E+01, 0.1006713350698832E+00, 0.1537255119449346E+00, 0.1006311377241790E+01, 0.1023585455764333E+01, 0.1401812239704283E+00, 0.8339725654733963E-01, 0.1673746889662340E+01, 0.1691494017876317E+01, 0.8584564749956700E-01, 0.1224340957564512E+00, 0.1098021846213856E+01, 0.1173561046093478E+01, 0.1056099032774466E-01, 0.1030644761994533E-01, 0.1352918635969054E+01, 0.1125140157417147E+01, 0.3200390963041470E+00, 0.2383394688796517E+00, 0.1581470773231080E+01, 0.1816681306138221E+01, 0.6542811978092533E-01, 0.8482856339700598E-01, 0.1229110747859551E+01, 0.1219785589162149E+01, 0.1271308521106110E+00, 0.7475327847832687E-01, 0.2168626705413786E+01, 0.2090314965369696E+01, 0.3802606466401751E-01, 0.2054425921547012E+00, 0.7370750004754409E+00, 0.4013984562173118E+00, 0.3117182559112661E+00, 0.3737026089221466E+00, 0.4614629804947978E+00, 0.6148197206508288E+00, 0.8139413038408401E-01, 0.1583615157552351E+00, 0.1805799067333021E+00, 0.2371812231191019E+00, 0.2338892446571373E-01, 0.2479281399828426E-01, 0.1471143614268198E+00, 0.1703545954445960E+00, 0.8179526119010886E-04, 0.1486904479375115E-03, 0.8084661071329148E-01, 0.8092824915545274E-01, 0.2173118009582292E-07, 0.1568190288260776E-06, 0.1120328867508400E-01, 0.1120331040626409E-01, 0.3751376363572422E-55, 0.6819392699821255E-26}, + tauOut: 1.1203284285913290E-002, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2463974850804771E+01, 0.2452784311062345E+01, 0.1274454348702788E-04, 0.6060609239813679E-05, 0.1166410336629578E+01, 0.1155204716501079E+01, 0.3724766654883956E-05, 0.3882375624867434E-05, 0.1204085798823124E+01, 0.1419979853975912E+01, 0.2271012218143261E+00, 0.1288536304732592E+00, 0.8056740422703550E+00, 0.7189222587736472E+00, 0.5330513126246473E-01, 0.5959804835594534E-01, 0.8037943538979316E+00, 0.7842891794360973E+00, 0.5129615818002433E-01, 0.1022287011292917E+00, 0.1563018888122747E+01, 0.1550258237777425E+01, 0.1006713350698832E+00, 0.6534828028921505E-01, 0.1006311377241790E+01, 0.1069941036637090E+01, 0.1401812239704283E+00, 0.2192904838448094E+00, 0.1673746889662340E+01, 0.1529098769031184E+01, 0.8584564749956700E-01, 0.6164441320989392E-01, 0.1098021846213856E+01, 0.1035735139045794E+01, 0.1056099032774466E-01, 0.1379518767882891E-01, 0.1352918635969054E+01, 0.1647959260308459E+01, 0.3200390963041470E+00, 0.3071268139247320E+00, 0.1581470773231080E+01, 0.1328568794801360E+01, 0.6542811978092533E-01, 0.6053010243026304E-01, 0.1229110747859551E+01, 0.1284508213253985E+01, 0.1271308521106110E+00, 0.2146341752620367E+00, 0.2168626705413786E+01, 0.1980815310529854E+01, 0.3802606466401751E-01, 0.1414976019284330E-01, 0.7370750004754409E+00, 0.1023440211907950E+01, 0.3117182559112661E+00, 0.1405518698344743E+00, 0.4614629804947978E+00, 0.3911019567584944E+00, 0.8139413038408401E-01, 0.3758136265851575E-01, 0.1805799067333021E+00, 0.1551841842545868E+00, 0.2338892446571373E-01, 0.2217266343062855E-01, 0.1471143614268198E+00, 0.1138202089714681E+00, 0.8179526119010886E-04, 0.5809925758690545E-04, 0.8084661071329148E-01, 0.6958524890097138E-01, 0.2173118009582292E-07, 0.3498739858072780E-08, 0.1120328867508400E-01, 0.8904308505808256E-09, 0.3751376363572422E-55, 0.3882375624867434E-05, 0.1697846193036144E-01}, + i0: 1, + n0: 19, + pp: 1, + n0in: 19, + dmin: 8.9043085058082561E-010, + dmin1: 6.9585227169791292E-002, + dmin2: 0.11373841371027797, + dn: 8.9043085058082561E-010, + dn1: 6.9585227169791292E-002, + dn2: 0.11373841371027797, + tau: 1.1203284285913290E-002, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.2463974850804771E+01, 0.2452784311062345E+01, 0.1274454348702788E-04, 0.6060609239813679E-05, 0.1166410336629578E+01, 0.1155204716501079E+01, 0.3724766654883956E-05, 0.3882375624867434E-05, 0.1204085798823124E+01, 0.1419979853975912E+01, 0.2271012218143261E+00, 0.1288536304732592E+00, 0.8056740422703550E+00, 0.7189222587736472E+00, 0.5330513126246473E-01, 0.5959804835594534E-01, 0.8037943538979316E+00, 0.7842891794360973E+00, 0.5129615818002433E-01, 0.1022287011292917E+00, 0.1563018888122747E+01, 0.1550258237777425E+01, 0.1006713350698832E+00, 0.6534828028921505E-01, 0.1006311377241790E+01, 0.1069941036637090E+01, 0.1401812239704283E+00, 0.2192904838448094E+00, 0.1673746889662340E+01, 0.1529098769031184E+01, 0.8584564749956700E-01, 0.6164441320989392E-01, 0.1098021846213856E+01, 0.1035735139045794E+01, 0.1056099032774466E-01, 0.1379518767882891E-01, 0.1352918635969054E+01, 0.1647959260308459E+01, 0.3200390963041470E+00, 0.3071268139247320E+00, 0.1581470773231080E+01, 0.1328568794801360E+01, 0.6542811978092533E-01, 0.6053010243026304E-01, 0.1229110747859551E+01, 0.1284508213253985E+01, 0.1271308521106110E+00, 0.2146341752620367E+00, 0.2168626705413786E+01, 0.1980815310529854E+01, 0.3802606466401751E-01, 0.1414976019284330E-01, 0.7370750004754409E+00, 0.1023440211907950E+01, 0.3117182559112661E+00, 0.1405518698344743E+00, 0.4614629804947978E+00, 0.3911019567584944E+00, 0.8139413038408401E-01, 0.3758136265851575E-01, 0.1805799067333021E+00, 0.1551841842545868E+00, 0.2338892446571373E-01, 0.2217266343062855E-01, 0.1471143614268198E+00, 0.1138202089714681E+00, 0.8179526119010886E-04, 0.5809925758690545E-04, 0.8084661071329148E-01, 0.6958524890097138E-01, 0.2173118009582292E-07, 0.3498739858072780E-08, 0.1120328867508400E-01, 0.8904308505808256E-09, 0.3751376363572422E-55, 0.3882375624867434E-05, 0.1697846193036144E-01}, + tauOut: 8.9043080564395014E-010, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2452790370781154E+01, 0.2452784311062345E+01, 0.2854399814229969E-05, 0.6060609239813679E-05, 0.1155205743586459E+01, 0.1155204716501079E+01, 0.4772219324121025E-05, 0.3882375624867434E-05, 0.1548828711339416E+01, 0.1419979853975912E+01, 0.5981019230390531E-01, 0.1288536304732592E+00, 0.7187101139352565E+00, 0.7189222587736472E+00, 0.6503610222645050E-01, 0.5959804835594534E-01, 0.8214817774485077E+00, 0.7842891794360973E+00, 0.1929207566298143E+00, 0.1022287011292917E+00, 0.1422685760546395E+01, 0.1550258237777425E+01, 0.4914564318703864E-01, 0.6534828028921505E-01, 0.1240085876404429E+01, 0.1069941036637090E+01, 0.2703980549150243E+00, 0.2192904838448094E+00, 0.1320345126435623E+01, 0.1529098769031184E+01, 0.4835651195207321E-01, 0.6164441320989392E-01, 0.1001173813882118E+01, 0.1035735139045794E+01, 0.2270725319399537E-01, 0.1379518767882891E-01, 0.1932378820148765E+01, 0.1647959260308459E+01, 0.2111589595024383E+00, 0.3071268139247320E+00, 0.1177939936838754E+01, 0.1328568794801360E+01, 0.6600626338337756E-01, 0.6053010243026304E-01, 0.1433136124242214E+01, 0.1284508213253985E+01, 0.2966575563411978E+00, 0.2146341752620367E+00, 0.1698307513491068E+01, 0.1980815310529854E+01, 0.8526979628348903E-02, 0.1414976019284330E-01, 0.1155465101223645E+01, 0.1023440211907950E+01, 0.4757401262929915E-01, 0.1405518698344743E+00, 0.3811093058972801E+00, 0.3911019567584944E+00, 0.1530278326215801E-01, 0.3758136265851575E-01, 0.1620540635326265E+00, 0.1551841842545868E+00, 0.1557318051836492E-01, 0.2217266343062855E-01, 0.9830512682025924E-01, 0.1138202089714681E+00, 0.4112553872737890E-04, 0.5809925758690545E-04, 0.6954412597055305E-01, 0.6958524890097138E-01, 0.4479725446695418E-16, 0.3498739858072780E-08, 0.1396210563637444E-18, 0.8904308505808256E-09, 0.2854399814229969E-05, 0.3882375624867434E-05}, + i0: 1, + n0: 19, + pp: 0, + n0in: 19, + dmin: 1.3962105636374437E-019, + dmin1: 6.9544122471813200E-002, + dmin2: 9.8247027562672340E-002, + dn: 1.3962105636374437E-019, + dn1: 6.9544122471813200E-002, + dn2: 9.8247027562672340E-002, + tau: 8.9043080564395014E-010, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2452790370781154E+01, 0.2452784311062345E+01, 0.2854399814229969E-05, 0.6060609239813679E-05, 0.1155205743586459E+01, 0.1155204716501079E+01, 0.4772219324121025E-05, 0.3882375624867434E-05, 0.1548828711339416E+01, 0.1419979853975912E+01, 0.5981019230390531E-01, 0.1288536304732592E+00, 0.7187101139352565E+00, 0.7189222587736472E+00, 0.6503610222645050E-01, 0.5959804835594534E-01, 0.8214817774485077E+00, 0.7842891794360973E+00, 0.1929207566298143E+00, 0.1022287011292917E+00, 0.1422685760546395E+01, 0.1550258237777425E+01, 0.4914564318703864E-01, 0.6534828028921505E-01, 0.1240085876404429E+01, 0.1069941036637090E+01, 0.2703980549150243E+00, 0.2192904838448094E+00, 0.1320345126435623E+01, 0.1529098769031184E+01, 0.4835651195207321E-01, 0.6164441320989392E-01, 0.1001173813882118E+01, 0.1035735139045794E+01, 0.2270725319399537E-01, 0.1379518767882891E-01, 0.1932378820148765E+01, 0.1647959260308459E+01, 0.2111589595024383E+00, 0.3071268139247320E+00, 0.1177939936838754E+01, 0.1328568794801360E+01, 0.6600626338337756E-01, 0.6053010243026304E-01, 0.1433136124242214E+01, 0.1284508213253985E+01, 0.2966575563411978E+00, 0.2146341752620367E+00, 0.1698307513491068E+01, 0.1980815310529854E+01, 0.8526979628348903E-02, 0.1414976019284330E-01, 0.1155465101223645E+01, 0.1023440211907950E+01, 0.4757401262929915E-01, 0.1405518698344743E+00, 0.3811093058972801E+00, 0.3911019567584944E+00, 0.1530278326215801E-01, 0.3758136265851575E-01, 0.1620540635326265E+00, 0.1551841842545868E+00, 0.1557318051836492E-01, 0.2217266343062855E-01, 0.9830512682025924E-01, 0.1138202089714681E+00, 0.4112553872737890E-04, 0.5809925758690545E-04, 0.6954412597055305E-01, 0.6958524890097138E-01, 0.4479725446695418E-16, 0.3498739858072780E-08, 0.1396210563637444E-18, 0.8904308505808256E-09, 0.2854399814229969E-05, 0.3882375624867434E-05}, + tauOut: 1.3962105636374427E-019, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2452790370781154E+01, 0.2452793225180968E+01, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1155205743586459E+01, 0.1155209171453138E+01, 0.4772219324121025E-05, 0.6398278760815103E-05, 0.1548828711339416E+01, 0.1608632505364561E+01, 0.5981019230390531E-01, 0.2672219415054498E-01, 0.7187101139352565E+00, 0.7570240220111620E+00, 0.6503610222645050E-01, 0.7057368234283014E-01, 0.8214817774485077E+00, 0.9438288517354918E+00, 0.1929207566298143E+00, 0.2908001941945216E+00, 0.1422685760546395E+01, 0.1181031209538913E+01, 0.4914564318703864E-01, 0.5160305461093759E-01, 0.1240085876404429E+01, 0.1458880876708516E+01, 0.2703980549150243E+00, 0.2447209773632920E+00, 0.1320345126435623E+01, 0.1123980661024405E+01, 0.4835651195207321E-01, 0.4307304847484577E-01, 0.1001173813882118E+01, 0.9808080186012680E+00, 0.2270725319399537E-01, 0.4473761868138884E-01, 0.1932378820148765E+01, 0.2098800160969815E+01, 0.2111589595024383E+00, 0.1185117935689049E+00, 0.1177939936838754E+01, 0.1125434406653226E+01, 0.6600626338337756E-01, 0.8405284210411720E-01, 0.1433136124242214E+01, 0.1645740838479294E+01, 0.2966575563411978E+00, 0.3061331074057168E+00, 0.1698307513491068E+01, 0.1400701385713701E+01, 0.8526979628348903E-02, 0.7034066989504621E-02, 0.1155465101223645E+01, 0.1196005046863439E+01, 0.4757401262929915E-01, 0.1515955052150448E-01, 0.3811093058972801E+00, 0.3812525386379337E+00, 0.1530278326215801E-01, 0.6504555274179689E-02, 0.1620540635326265E+00, 0.1711226887768117E+00, 0.1557318051836492E-01, 0.8946350111698947E-02, 0.9830512682025924E-01, 0.8939990224728768E-01, 0.4112553872737890E-04, 0.3199152990069927E-04, 0.6954412597055305E-01, 0.6951213444065239E-01, 0.4479725446695418E-16, 0.8997910999570377E-34, 0.2818174710670554E-01}, + i0: 1, + n0: 18, + pp: 1, + n0in: 19, + dmin: 1.3962105636374430E-019, + dmin1: 6.9512134440652351E-002, + dmin2: 8.9358776708560295E-002, + dn: 1.3962105636374430E-019, + dn1: 6.9512134440652351E-002, + dn2: 8.9358776708560295E-002, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2452790370781154E+01, 0.2452793225180968E+01, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1155205743586459E+01, 0.1155209171453138E+01, 0.4772219324121025E-05, 0.6398278760815103E-05, 0.1548828711339416E+01, 0.1608632505364561E+01, 0.5981019230390531E-01, 0.2672219415054498E-01, 0.7187101139352565E+00, 0.7570240220111620E+00, 0.6503610222645050E-01, 0.7057368234283014E-01, 0.8214817774485077E+00, 0.9438288517354918E+00, 0.1929207566298143E+00, 0.2908001941945216E+00, 0.1422685760546395E+01, 0.1181031209538913E+01, 0.4914564318703864E-01, 0.5160305461093759E-01, 0.1240085876404429E+01, 0.1458880876708516E+01, 0.2703980549150243E+00, 0.2447209773632920E+00, 0.1320345126435623E+01, 0.1123980661024405E+01, 0.4835651195207321E-01, 0.4307304847484577E-01, 0.1001173813882118E+01, 0.9808080186012680E+00, 0.2270725319399537E-01, 0.4473761868138884E-01, 0.1932378820148765E+01, 0.2098800160969815E+01, 0.2111589595024383E+00, 0.1185117935689049E+00, 0.1177939936838754E+01, 0.1125434406653226E+01, 0.6600626338337756E-01, 0.8405284210411720E-01, 0.1433136124242214E+01, 0.1645740838479294E+01, 0.2966575563411978E+00, 0.3061331074057168E+00, 0.1698307513491068E+01, 0.1400701385713701E+01, 0.8526979628348903E-02, 0.7034066989504621E-02, 0.1155465101223645E+01, 0.1196005046863439E+01, 0.4757401262929915E-01, 0.1515955052150448E-01, 0.3811093058972801E+00, 0.3812525386379337E+00, 0.1530278326215801E-01, 0.6504555274179689E-02, 0.1620540635326265E+00, 0.1711226887768117E+00, 0.1557318051836492E-01, 0.8946350111698947E-02, 0.9830512682025924E-01, 0.8939990224728768E-01, 0.4112553872737890E-04, 0.3199152990069927E-04, 0.6954412597055305E-01, 0.6951213444065239E-01, 0.4479725446695418E-16, 0.8997910999570377E-34, 0.2818174710670554E-01}, + tauOut: 6.8088572105595116E-002, + ttypeOut: -8, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2384705997428018E+01, 0.2452793225180968E+01, 0.6512368848977837E-06, 0.1344352644992036E-05, 0.1087126346389419E+01, 0.1155209171453138E+01, 0.9467601652019932E-05, 0.6398278760815103E-05, 0.1567256659807859E+01, 0.1608632505364561E+01, 0.1290748567965171E-01, 0.2672219415054498E-01, 0.7466016465687454E+00, 0.7570240220111620E+00, 0.8921689079377818E-01, 0.7057368234283014E-01, 0.1077323583030640E+01, 0.9438288517354918E+00, 0.3187938243378626E+00, 0.2908001941945216E+00, 0.8457518677063927E+00, 0.1181031209538913E+01, 0.8901276181133644E-01, 0.5160305461093759E-01, 0.1546500520154876E+01, 0.1458880876708516E+01, 0.1778606876095877E+00, 0.2447209773632920E+00, 0.9211044497840675E+00, 0.1123980661024405E+01, 0.4586493023634136E-01, 0.4307304847484577E-01, 0.9115921349407204E+00, 0.9808080186012680E+00, 0.1030014605117353E+00, 0.4473761868138884E-01, 0.2046221921921390E+01, 0.2098800160969815E+01, 0.6518220171905387E-01, 0.1185117935689049E+00, 0.1076216474932694E+01, 0.1125434406653226E+01, 0.1285328723941422E+00, 0.8405284210411720E-01, 0.1755252501385274E+01, 0.1645740838479294E+01, 0.2442959445536252E+00, 0.3061331074057168E+00, 0.1095350936043985E+01, 0.1400701385713701E+01, 0.7680442260639305E-02, 0.7034066989504621E-02, 0.1135395583018709E+01, 0.1196005046863439E+01, 0.5090399511302622E-02, 0.1515955052150448E-01, 0.3145781222952156E+00, 0.3812525386379337E+00, 0.3538316586334169E-02, 0.6504555274179689E-02, 0.1084421501965814E+00, 0.1711226887768117E+00, 0.7375387005938499E-02, 0.8946350111698947E-02, 0.1396793466565477E-01, 0.8939990224728768E-01, 0.1592074691534444E-03, 0.3199152990069927E-04, 0.1264354865903830E-02, 0.6951213444065239E-01, 0.6512368848977837E-06, 0.1344352644992036E-05}, + i0: 1, + n0: 18, + pp: 0, + n0in: 18, + dmin: 1.2643548659038301E-003, + dmin1: 1.3935943135754067E-002, + dmin2: 9.9495800084882416E-002, + dn: 1.2643548659038301E-003, + dn1: 1.3935943135754067E-002, + dn2: 9.9495800084882416E-002, + tau: 6.8088572105595116E-002, + ttype: -8, + g: 0.0000000000000000, + zOut: []float64{0.2384705997428018E+01, 0.2452793225180968E+01, 0.6512368848977837E-06, 0.1344352644992036E-05, 0.1087126346389419E+01, 0.1155209171453138E+01, 0.9467601652019932E-05, 0.6398278760815103E-05, 0.1567256659807859E+01, 0.1608632505364561E+01, 0.1290748567965171E-01, 0.2672219415054498E-01, 0.7466016465687454E+00, 0.7570240220111620E+00, 0.8921689079377818E-01, 0.7057368234283014E-01, 0.1077323583030640E+01, 0.9438288517354918E+00, 0.3187938243378626E+00, 0.2908001941945216E+00, 0.8457518677063927E+00, 0.1181031209538913E+01, 0.8901276181133644E-01, 0.5160305461093759E-01, 0.1546500520154876E+01, 0.1458880876708516E+01, 0.1778606876095877E+00, 0.2447209773632920E+00, 0.9211044497840675E+00, 0.1123980661024405E+01, 0.4586493023634136E-01, 0.4307304847484577E-01, 0.9115921349407204E+00, 0.9808080186012680E+00, 0.1030014605117353E+00, 0.4473761868138884E-01, 0.2046221921921390E+01, 0.2098800160969815E+01, 0.6518220171905387E-01, 0.1185117935689049E+00, 0.1076216474932694E+01, 0.1125434406653226E+01, 0.1285328723941422E+00, 0.8405284210411720E-01, 0.1755252501385274E+01, 0.1645740838479294E+01, 0.2442959445536252E+00, 0.3061331074057168E+00, 0.1095350936043985E+01, 0.1400701385713701E+01, 0.7680442260639305E-02, 0.7034066989504621E-02, 0.1135395583018709E+01, 0.1196005046863439E+01, 0.5090399511302622E-02, 0.1515955052150448E-01, 0.3145781222952156E+00, 0.3812525386379337E+00, 0.3538316586334169E-02, 0.6504555274179689E-02, 0.1084421501965814E+00, 0.1711226887768117E+00, 0.7375387005938499E-02, 0.8946350111698947E-02, 0.1396793466565477E-01, 0.8939990224728768E-01, 0.1592074691534444E-03, 0.3199152990069927E-04, 0.1264354865903830E-02, 0.6951213444065239E-01, 0.6512368848977837E-06, 0.1344352644992036E-05}, + tauOut: 1.2463174543591322E-003, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2384705997428018E+01, 0.2383460331210544E+01, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.1087126346389419E+01, 0.1085889199499347E+01, 0.9467601652019932E-05, 0.1366452649899944E-04, 0.1567256659807859E+01, 0.1578904163506652E+01, 0.1290748567965171E-01, 0.6103442048115082E-02, 0.7466016465687454E+00, 0.8284687778600495E+00, 0.8921689079377818E-01, 0.1160157908485996E+00, 0.1077323583030640E+01, 0.1278855299065544E+01, 0.3187938243378626E+00, 0.2108295383723412E+00, 0.8457518677063927E+00, 0.7226887736910288E+00, 0.8901276181133644E-01, 0.1904807262171572E+00, 0.1546500520154876E+01, 0.1532634164092948E+01, 0.1778606876095877E+00, 0.1068932656188067E+00, 0.9211044497840675E+00, 0.8588297969472432E+00, 0.4586493023634136E-01, 0.4868264913684867E-01, 0.9115921349407204E+00, 0.9646646288612479E+00, 0.1030014605117353E+00, 0.2184840619043245E+00, 0.2046221921921390E+01, 0.1891673744281760E+01, 0.6518220171905387E-01, 0.3708364593761750E-01, 0.1076216474932694E+01, 0.1166419383934860E+01, 0.1285328723941422E+00, 0.1934189785315259E+00, 0.1755252501385274E+01, 0.1804883149953014E+01, 0.2442959445536252E+00, 0.1482587897978486E+00, 0.1095350936043985E+01, 0.9535262710524167E+00, 0.7680442260639305E-02, 0.9145359161143373E-02, 0.1135395583018709E+01, 0.1130094305914509E+01, 0.5090399511302622E-02, 0.1416986451145964E-02, 0.3145781222952156E+00, 0.3154531349760448E+00, 0.3538316586334169E-02, 0.1216353924418735E-02, 0.1084421501965814E+00, 0.1133548658237420E+00, 0.7375387005938499E-02, 0.9088178357782586E-03, 0.1396793466565477E-01, 0.1197200684467082E-01, 0.1592074691534444E-03, 0.1681378409852773E-04, 0.1264354865903830E-02, 0.1223627446170173E-05, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.2818174710670554E-01}, + i0: 1, + n0: 18, + pp: 1, + n0in: 18, + dmin: 1.2236274461701734E-006, + dmin1: 1.1812799375517376E-002, + dmin2: 0.10597947881780349, + dn: 1.2236274461701734E-006, + dn1: 1.1812799375517376E-002, + dn2: 0.10597947881780349, + tau: 1.2463174543591322E-003, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2384705997428018E+01, 0.2383460331210544E+01, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.1087126346389419E+01, 0.1085889199499347E+01, 0.9467601652019932E-05, 0.1366452649899944E-04, 0.1567256659807859E+01, 0.1578904163506652E+01, 0.1290748567965171E-01, 0.6103442048115082E-02, 0.7466016465687454E+00, 0.8284687778600495E+00, 0.8921689079377818E-01, 0.1160157908485996E+00, 0.1077323583030640E+01, 0.1278855299065544E+01, 0.3187938243378626E+00, 0.2108295383723412E+00, 0.8457518677063927E+00, 0.7226887736910288E+00, 0.8901276181133644E-01, 0.1904807262171572E+00, 0.1546500520154876E+01, 0.1532634164092948E+01, 0.1778606876095877E+00, 0.1068932656188067E+00, 0.9211044497840675E+00, 0.8588297969472432E+00, 0.4586493023634136E-01, 0.4868264913684867E-01, 0.9115921349407204E+00, 0.9646646288612479E+00, 0.1030014605117353E+00, 0.2184840619043245E+00, 0.2046221921921390E+01, 0.1891673744281760E+01, 0.6518220171905387E-01, 0.3708364593761750E-01, 0.1076216474932694E+01, 0.1166419383934860E+01, 0.1285328723941422E+00, 0.1934189785315259E+00, 0.1755252501385274E+01, 0.1804883149953014E+01, 0.2442959445536252E+00, 0.1482587897978486E+00, 0.1095350936043985E+01, 0.9535262710524167E+00, 0.7680442260639305E-02, 0.9145359161143373E-02, 0.1135395583018709E+01, 0.1130094305914509E+01, 0.5090399511302622E-02, 0.1416986451145964E-02, 0.3145781222952156E+00, 0.3154531349760448E+00, 0.3538316586334169E-02, 0.1216353924418735E-02, 0.1084421501965814E+00, 0.1133548658237420E+00, 0.7375387005938499E-02, 0.9088178357782586E-03, 0.1396793466565477E-01, 0.1197200684467082E-01, 0.1592074691534444E-03, 0.1681378409852773E-04, 0.1264354865903830E-02, 0.1223627446170173E-05, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.2818174710670554E-01}, + tauOut: 1.2218877946904154E-006, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2383459406360114E+01, 0.2383460331210544E+01, 0.1353283656358167E-06, 0.2970373645586866E-06, 0.1085901506809686E+01, 0.1085889199499347E+01, 0.1986826396898849E-04, 0.1366452649899944E-04, 0.1584986515403004E+01, 0.1578904163506652E+01, 0.3190255011763210E-02, 0.6103442048115082E-02, 0.9412930918090910E+00, 0.8284687778600495E+00, 0.1576208411525267E+00, 0.1160157908485996E+00, 0.1332062774397564E+01, 0.1278855299065544E+01, 0.1143821023097510E+00, 0.2108295383723412E+00, 0.7987861757106404E+00, 0.7226887736910288E+00, 0.3654761154847582E+00, 0.1904807262171572E+00, 0.1274050092339202E+01, 0.1532634164092948E+01, 0.7205613198290631E-01, 0.1068932656188067E+00, 0.8354550922133908E+00, 0.8588297969472432E+00, 0.5621179414582513E-01, 0.4868264913684867E-01, 0.1126935674731953E+01, 0.9646646288612479E+00, 0.3667472533840468E+00, 0.2184840619043245E+00, 0.1562008914947536E+01, 0.1891673744281760E+01, 0.2769195683500124E-01, 0.3708364593761750E-01, 0.1332145183743590E+01, 0.1166419383934860E+01, 0.2620575140703801E+00, 0.1934189785315259E+00, 0.1691083203792688E+01, 0.1804883149953014E+01, 0.8359650824372877E-01, 0.1482587897978486E+00, 0.8790739000820365E+00, 0.9535262710524167E+00, 0.1175682535061811E-01, 0.9145359161143373E-02, 0.1119753245127243E+01, 0.1130094305914509E+01, 0.3991886785572840E-03, 0.1416986451145964E-02, 0.3162690783341116E+00, 0.3154531349760448E+00, 0.4359567385560517E-03, 0.1216353924418735E-02, 0.1138265050331695E+00, 0.1133548658237420E+00, 0.9558734450579545E-04, 0.9088178357782586E-03, 0.1189201139646886E-01, 0.1197200684467082E-01, 0.1730052806966466E-08, 0.1681378409852773E-04, 0.9598672791582074E-11, 0.1223627446170173E-05, 0.1353283656358167E-06, 0.2970373645586866E-06}, + i0: 1, + n0: 18, + pp: 0, + n0in: 18, + dmin: 9.5986727915820745E-012, + dmin1: 1.1875197612370336E-002, + dmin2: 0.11291768719739126, + dn: 9.5986727915820745E-012, + dn1: 1.1875197612370336E-002, + dn2: 0.11291768719739126, + tau: 1.2218877946904154E-006, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2383459406360114E+01, 0.2383460331210544E+01, 0.1353283656358167E-06, 0.2970373645586866E-06, 0.1085901506809686E+01, 0.1085889199499347E+01, 0.1986826396898849E-04, 0.1366452649899944E-04, 0.1584986515403004E+01, 0.1578904163506652E+01, 0.3190255011763210E-02, 0.6103442048115082E-02, 0.9412930918090910E+00, 0.8284687778600495E+00, 0.1576208411525267E+00, 0.1160157908485996E+00, 0.1332062774397564E+01, 0.1278855299065544E+01, 0.1143821023097510E+00, 0.2108295383723412E+00, 0.7987861757106404E+00, 0.7226887736910288E+00, 0.3654761154847582E+00, 0.1904807262171572E+00, 0.1274050092339202E+01, 0.1532634164092948E+01, 0.7205613198290631E-01, 0.1068932656188067E+00, 0.8354550922133908E+00, 0.8588297969472432E+00, 0.5621179414582513E-01, 0.4868264913684867E-01, 0.1126935674731953E+01, 0.9646646288612479E+00, 0.3667472533840468E+00, 0.2184840619043245E+00, 0.1562008914947536E+01, 0.1891673744281760E+01, 0.2769195683500124E-01, 0.3708364593761750E-01, 0.1332145183743590E+01, 0.1166419383934860E+01, 0.2620575140703801E+00, 0.1934189785315259E+00, 0.1691083203792688E+01, 0.1804883149953014E+01, 0.8359650824372877E-01, 0.1482587897978486E+00, 0.8790739000820365E+00, 0.9535262710524167E+00, 0.1175682535061811E-01, 0.9145359161143373E-02, 0.1119753245127243E+01, 0.1130094305914509E+01, 0.3991886785572840E-03, 0.1416986451145964E-02, 0.3162690783341116E+00, 0.3154531349760448E+00, 0.4359567385560517E-03, 0.1216353924418735E-02, 0.1138265050331695E+00, 0.1133548658237420E+00, 0.9558734450579545E-04, 0.9088178357782586E-03, 0.1189201139646886E-01, 0.1197200684467082E-01, 0.1730052806966466E-08, 0.1681378409852773E-04, 0.9598672791582074E-11, 0.1223627446170173E-05, 0.1353283656358167E-06, 0.2970373645586866E-06}, + tauOut: 9.5986713933289272E-012, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2383459406360114E+01, 0.2383459541678881E+01, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.1085901506809686E+01, 0.1085921313408604E+01, 0.1986826396898849E-04, 0.2899927470478232E-04, 0.1584986515403004E+01, 0.1588147771130463E+01, 0.3190255011763210E-02, 0.1890859942802736E-02, 0.9412930918090910E+00, 0.1097023073009216E+01, 0.1576208411525267E+00, 0.1913914667196325E+00, 0.1332062774397564E+01, 0.1255053409978084E+01, 0.1143821023097510E+00, 0.7279916643176543E-01, 0.7987861757106404E+00, 0.1091463124754034E+01, 0.3654761154847582E+00, 0.4266153094141972E+00, 0.1274050092339202E+01, 0.9194909148983121E+00, 0.7205613198290631E-01, 0.6547064404326042E-01, 0.8354550922133908E+00, 0.8261962423063568E+00, 0.5621179414582513E-01, 0.7667315937770838E-01, 0.1126935674731953E+01, 0.1417009768728692E+01, 0.3667472533840468E+00, 0.4042756034295816E+00, 0.1562008914947536E+01, 0.1185425268343357E+01, 0.2769195683500124E-01, 0.3111938635974581E-01, 0.1332145183743590E+01, 0.1563083311444625E+01, 0.2620575140703801E+00, 0.2835172362390010E+00, 0.1691083203792688E+01, 0.1491162475787817E+01, 0.8359650824372877E-01, 0.4928202642453804E-01, 0.8790739000820365E+00, 0.8415486989985177E+00, 0.1175682535061811E-01, 0.1564347179719430E-01, 0.1119753245127243E+01, 0.1104508961999007E+01, 0.3991886785572840E-03, 0.1143051254380294E-03, 0.3162690783341116E+00, 0.3165907299376309E+00, 0.4359567385560517E-03, 0.1567431614478116E-03, 0.1138265050331695E+00, 0.1137653492066288E+00, 0.9558734450579545E-04, 0.9991845479738400E-05, 0.1189201139646886E-01, 0.1188202127144326E-01, 0.1730052806966466E-08, 0.1397591405272086E-17, 0.9598672791582074E-11, 0.6617412588681544E-21, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.2818174710670554E-01}, + i0: 1, + n0: 18, + pp: 1, + n0in: 18, + dmin: 6.6174125886815435E-022, + dmin1: 1.1882019541390456E-002, + dmin2: 0.11366976186212303, + dn: 6.6174125886815435E-022, + dn1: 1.1882019541390456E-002, + dn2: 0.11366976186212303, + tau: 9.5986713933289272E-012, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2383459406360114E+01, 0.2383459541678881E+01, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.1085901506809686E+01, 0.1085921313408604E+01, 0.1986826396898849E-04, 0.2899927470478232E-04, 0.1584986515403004E+01, 0.1588147771130463E+01, 0.3190255011763210E-02, 0.1890859942802736E-02, 0.9412930918090910E+00, 0.1097023073009216E+01, 0.1576208411525267E+00, 0.1913914667196325E+00, 0.1332062774397564E+01, 0.1255053409978084E+01, 0.1143821023097510E+00, 0.7279916643176543E-01, 0.7987861757106404E+00, 0.1091463124754034E+01, 0.3654761154847582E+00, 0.4266153094141972E+00, 0.1274050092339202E+01, 0.9194909148983121E+00, 0.7205613198290631E-01, 0.6547064404326042E-01, 0.8354550922133908E+00, 0.8261962423063568E+00, 0.5621179414582513E-01, 0.7667315937770838E-01, 0.1126935674731953E+01, 0.1417009768728692E+01, 0.3667472533840468E+00, 0.4042756034295816E+00, 0.1562008914947536E+01, 0.1185425268343357E+01, 0.2769195683500124E-01, 0.3111938635974581E-01, 0.1332145183743590E+01, 0.1563083311444625E+01, 0.2620575140703801E+00, 0.2835172362390010E+00, 0.1691083203792688E+01, 0.1491162475787817E+01, 0.8359650824372877E-01, 0.4928202642453804E-01, 0.8790739000820365E+00, 0.8415486989985177E+00, 0.1175682535061811E-01, 0.1564347179719430E-01, 0.1119753245127243E+01, 0.1104508961999007E+01, 0.3991886785572840E-03, 0.1143051254380294E-03, 0.3162690783341116E+00, 0.3165907299376309E+00, 0.4359567385560517E-03, 0.1567431614478116E-03, 0.1138265050331695E+00, 0.1137653492066288E+00, 0.9558734450579545E-04, 0.9991845479738400E-05, 0.1189201139646886E-01, 0.1188202127144326E-01, 0.1730052806966466E-08, 0.1397591405272086E-17, 0.9598672791582074E-11, 0.6617412588681544E-21, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.2818174710670554E-01}, + tauOut: 6.6174125886815426E-022, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2383459603334333E+01, 0.2383459541678881E+01, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.1085950284592642E+01, 0.1085921313408604E+01, 0.4240998334843304E-04, 0.2899927470478232E-04, 0.1589996221089918E+01, 0.1588147771130463E+01, 0.1304604978030436E-02, 0.1890859942802736E-02, 0.1287109934750819E+01, 0.1097023073009216E+01, 0.1866247058326724E+00, 0.1913914667196325E+00, 0.1141227870577177E+01, 0.1255053409978084E+01, 0.6962466280543776E-01, 0.7279916643176543E-01, 0.1448453771362794E+01, 0.1091463124754034E+01, 0.2708190685256155E+00, 0.4266153094141972E+00, 0.7141424904159570E+00, 0.9194909148983121E+00, 0.7574342769943966E-01, 0.6547064404326042E-01, 0.8271259739846255E+00, 0.8261962423063568E+00, 0.1313543755784947E+00, 0.7667315937770838E-01, 0.1689930996579779E+01, 0.1417009768728692E+01, 0.2835846650840220E+00, 0.4042756034295816E+00, 0.9329599896190804E+00, 0.1185425268343357E+01, 0.5213749144931325E-01, 0.3111938635974581E-01, 0.1794463056234313E+01, 0.1563083311444625E+01, 0.2355970842920850E+00, 0.2835172362390010E+00, 0.1304847417920270E+01, 0.1491162475787817E+01, 0.3178396542921673E-01, 0.4928202642453804E-01, 0.8254082053664953E+00, 0.8415486989985177E+00, 0.2093310277804656E-01, 0.1564347179719430E-01, 0.1083690164346398E+01, 0.1104508961999007E+01, 0.3339325601415243E-04, 0.1143051254380294E-03, 0.3167140798430647E+00, 0.3165907299376309E+00, 0.5630296103885627E-04, 0.1567431614478116E-03, 0.1137190380910697E+00, 0.1137653492066288E+00, 0.1044005669799533E-05, 0.9991845479738400E-05, 0.1188097726577346E-01, 0.1188202127144326E-01, 0.7784240935906335E-37, 0.1397591405272086E-17}, + i0: 1, + n0: 17, + pp: 0, + n0in: 18, + dmin: 6.6174125886815426E-022, + dmin1: 1.1880977265773463E-002, + dmin2: 0.11370904624558997, + dn: 6.6174125886815426E-022, + dn1: 1.1880977265773463E-002, + dn2: 0.11370904624558997, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2383459603334333E+01, 0.2383459541678881E+01, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.1085950284592642E+01, 0.1085921313408604E+01, 0.4240998334843304E-04, 0.2899927470478232E-04, 0.1589996221089918E+01, 0.1588147771130463E+01, 0.1304604978030436E-02, 0.1890859942802736E-02, 0.1287109934750819E+01, 0.1097023073009216E+01, 0.1866247058326724E+00, 0.1913914667196325E+00, 0.1141227870577177E+01, 0.1255053409978084E+01, 0.6962466280543776E-01, 0.7279916643176543E-01, 0.1448453771362794E+01, 0.1091463124754034E+01, 0.2708190685256155E+00, 0.4266153094141972E+00, 0.7141424904159570E+00, 0.9194909148983121E+00, 0.7574342769943966E-01, 0.6547064404326042E-01, 0.8271259739846255E+00, 0.8261962423063568E+00, 0.1313543755784947E+00, 0.7667315937770838E-01, 0.1689930996579779E+01, 0.1417009768728692E+01, 0.2835846650840220E+00, 0.4042756034295816E+00, 0.9329599896190804E+00, 0.1185425268343357E+01, 0.5213749144931325E-01, 0.3111938635974581E-01, 0.1794463056234313E+01, 0.1563083311444625E+01, 0.2355970842920850E+00, 0.2835172362390010E+00, 0.1304847417920270E+01, 0.1491162475787817E+01, 0.3178396542921673E-01, 0.4928202642453804E-01, 0.8254082053664953E+00, 0.8415486989985177E+00, 0.2093310277804656E-01, 0.1564347179719430E-01, 0.1083690164346398E+01, 0.1104508961999007E+01, 0.3339325601415243E-04, 0.1143051254380294E-03, 0.3167140798430647E+00, 0.3165907299376309E+00, 0.5630296103885627E-04, 0.1567431614478116E-03, 0.1137190380910697E+00, 0.1137653492066288E+00, 0.1044005669799533E-05, 0.9991845479738400E-05, 0.1188097726577346E-01, 0.1188202127144326E-01, 0.7784240935906335E-37, 0.1397591405272086E-17}, + tauOut: 1.1880832155707781E-002, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2383459603334333E+01, 0.2371578799269292E+01, 0.2809066689524106E-07, 0.1286276792433928E-07, 0.1085950284592642E+01, 0.1074111849557515E+01, 0.4240998334843304E-04, 0.6277904232066118E-04, 0.1589996221089918E+01, 0.1579357214869920E+01, 0.1304604978030436E-02, 0.1063198377376995E-02, 0.1287109934750819E+01, 0.1460790610050406E+01, 0.1866247058326724E+00, 0.1457986614708343E+00, 0.1141227870577177E+01, 0.1053173039756072E+01, 0.6962466280543776E-01, 0.9575644420574685E-01, 0.1448453771362794E+01, 0.1611635563526955E+01, 0.2708190685256155E+00, 0.1200044280642223E+00, 0.7141424904159570E+00, 0.6580006578954666E+00, 0.7574342769943966E-01, 0.9521169265880262E-01, 0.8271259739846255E+00, 0.8513878247486099E+00, 0.1313543755784947E+00, 0.2607270439790754E+00, 0.1689930996579779E+01, 0.1700907785529018E+01, 0.2835846650840220E+00, 0.1555482010511415E+00, 0.9329599896190804E+00, 0.8176684478615445E+00, 0.5213749144931325E-01, 0.1144214412274440E+00, 0.1794463056234313E+01, 0.1903757867143247E+01, 0.2355970842920850E+00, 0.1614796988702029E+00, 0.1304847417920270E+01, 0.1163270852323576E+01, 0.3178396542921673E-01, 0.2255256874351997E-01, 0.8254082053664953E+00, 0.8119079072453143E+00, 0.2093310277804656E-01, 0.2794035799797570E-01, 0.1083690164346398E+01, 0.1043902367448729E+01, 0.3339325601415243E-04, 0.1013132519024162E-04, 0.3167140798430647E+00, 0.3048794193232055E+00, 0.5630296103885627E-04, 0.2100082250625822E-04, 0.1137190380910697E+00, 0.1018182491185255E+00, 0.1044005669799533E-05, 0.1218230301111122E-06, 0.1188097726577346E-01, 0.2328703557243073E-07, 0.7784240935906335E-37, 0.1286276792433928E-07, 0.9751785856405315E-01}, + i0: 1, + n0: 17, + pp: 1, + n0in: 17, + dmin: 2.3287035572430725E-008, + dmin1: 0.10181720511285566, + dmin2: 0.30482311636216664, + dn: 2.3287035572430725E-008, + dn1: 0.10181720511285566, + dn2: 0.30482311636216664, + tau: 1.1880832155707781E-002, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.2383459603334333E+01, 0.2371578799269292E+01, 0.2809066689524106E-07, 0.1286276792433928E-07, 0.1085950284592642E+01, 0.1074111849557515E+01, 0.4240998334843304E-04, 0.6277904232066118E-04, 0.1589996221089918E+01, 0.1579357214869920E+01, 0.1304604978030436E-02, 0.1063198377376995E-02, 0.1287109934750819E+01, 0.1460790610050406E+01, 0.1866247058326724E+00, 0.1457986614708343E+00, 0.1141227870577177E+01, 0.1053173039756072E+01, 0.6962466280543776E-01, 0.9575644420574685E-01, 0.1448453771362794E+01, 0.1611635563526955E+01, 0.2708190685256155E+00, 0.1200044280642223E+00, 0.7141424904159570E+00, 0.6580006578954666E+00, 0.7574342769943966E-01, 0.9521169265880262E-01, 0.8271259739846255E+00, 0.8513878247486099E+00, 0.1313543755784947E+00, 0.2607270439790754E+00, 0.1689930996579779E+01, 0.1700907785529018E+01, 0.2835846650840220E+00, 0.1555482010511415E+00, 0.9329599896190804E+00, 0.8176684478615445E+00, 0.5213749144931325E-01, 0.1144214412274440E+00, 0.1794463056234313E+01, 0.1903757867143247E+01, 0.2355970842920850E+00, 0.1614796988702029E+00, 0.1304847417920270E+01, 0.1163270852323576E+01, 0.3178396542921673E-01, 0.2255256874351997E-01, 0.8254082053664953E+00, 0.8119079072453143E+00, 0.2093310277804656E-01, 0.2794035799797570E-01, 0.1083690164346398E+01, 0.1043902367448729E+01, 0.3339325601415243E-04, 0.1013132519024162E-04, 0.3167140798430647E+00, 0.3048794193232055E+00, 0.5630296103885627E-04, 0.2100082250625822E-04, 0.1137190380910697E+00, 0.1018182491185255E+00, 0.1044005669799533E-05, 0.1218230301111122E-06, 0.1188097726577346E-01, 0.2328703557243073E-07, 0.7784240935906335E-37, 0.1286276792433928E-07, 0.9751785856405315E-01}, + tauOut: 2.3287007705477136E-008, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2371578788845052E+01, 0.2371578799269292E+01, 0.5825676764620370E-08, 0.1286276792433928E-07, 0.1074174599487151E+01, 0.1074111849557515E+01, 0.9230392664199863E-04, 0.6277904232066118E-04, 0.1580328086033647E+01, 0.1579357214869920E+01, 0.9827770701659698E-03, 0.1063198377376995E-02, 0.1605606471164067E+01, 0.1460790610050406E+01, 0.9563440497488795E-01, 0.1457986614708343E+00, 0.1053295055699924E+01, 0.1053173039756072E+01, 0.1465159169633776E+00, 0.9575644420574685E-01, 0.1585124051340792E+01, 0.1611635563526955E+01, 0.4981502397231050E-01, 0.1200044280642223E+00, 0.7033973032949510E+00, 0.6580006578954666E+00, 0.1152436546510613E+00, 0.9521169265880262E-01, 0.9968711907896164E+00, 0.8513878247486099E+00, 0.4448645553200346E+00, 0.2607270439790754E+00, 0.1411591407973117E+01, 0.1700907785529018E+01, 0.9010174998427344E-01, 0.1555482010511415E+00, 0.8419881158177074E+00, 0.8176684478615445E+00, 0.2587099684834221E+00, 0.1144214412274440E+00, 0.1806527574243020E+01, 0.1903757867143247E+01, 0.1039810460775319E+00, 0.1614796988702029E+00, 0.1081842351702556E+01, 0.1163270852323576E+01, 0.1692539477932339E-01, 0.2255256874351997E-01, 0.8229228471769590E+00, 0.8119079072453143E+00, 0.3544318396494814E-01, 0.2794035799797570E-01, 0.1008469291521964E+01, 0.1043902367448729E+01, 0.3062892015595061E-05, 0.1013132519024162E-04, 0.3048973339666884E+00, 0.3048794193232055E+00, 0.7013072071892081E-05, 0.2100082250625822E-04, 0.1018113345824760E+00, 0.1018182491185255E+00, 0.2786425742647189E-13, 0.1218230301111122E-06, 0.2696165428114542E-17, 0.2328703557243073E-07, 0.5825676764620370E-08, 0.1286276792433928E-07}, + i0: 1, + n0: 17, + pp: 0, + n0in: 17, + dmin: 2.6961654281145418E-018, + dmin1: 0.10181121275944585, + dmin2: 0.30487633314418217, + dn: 2.6961654281145418E-018, + dn1: 0.10181121275944585, + dn2: 0.30487633314418217, + tau: 2.3287007705477136E-008, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2371578788845052E+01, 0.2371578799269292E+01, 0.5825676764620370E-08, 0.1286276792433928E-07, 0.1074174599487151E+01, 0.1074111849557515E+01, 0.9230392664199863E-04, 0.6277904232066118E-04, 0.1580328086033647E+01, 0.1579357214869920E+01, 0.9827770701659698E-03, 0.1063198377376995E-02, 0.1605606471164067E+01, 0.1460790610050406E+01, 0.9563440497488795E-01, 0.1457986614708343E+00, 0.1053295055699924E+01, 0.1053173039756072E+01, 0.1465159169633776E+00, 0.9575644420574685E-01, 0.1585124051340792E+01, 0.1611635563526955E+01, 0.4981502397231050E-01, 0.1200044280642223E+00, 0.7033973032949510E+00, 0.6580006578954666E+00, 0.1152436546510613E+00, 0.9521169265880262E-01, 0.9968711907896164E+00, 0.8513878247486099E+00, 0.4448645553200346E+00, 0.2607270439790754E+00, 0.1411591407973117E+01, 0.1700907785529018E+01, 0.9010174998427344E-01, 0.1555482010511415E+00, 0.8419881158177074E+00, 0.8176684478615445E+00, 0.2587099684834221E+00, 0.1144214412274440E+00, 0.1806527574243020E+01, 0.1903757867143247E+01, 0.1039810460775319E+00, 0.1614796988702029E+00, 0.1081842351702556E+01, 0.1163270852323576E+01, 0.1692539477932339E-01, 0.2255256874351997E-01, 0.8229228471769590E+00, 0.8119079072453143E+00, 0.3544318396494814E-01, 0.2794035799797570E-01, 0.1008469291521964E+01, 0.1043902367448729E+01, 0.3062892015595061E-05, 0.1013132519024162E-04, 0.3048973339666884E+00, 0.3048794193232055E+00, 0.7013072071892081E-05, 0.2100082250625822E-04, 0.1018113345824760E+00, 0.1018182491185255E+00, 0.2786425742647189E-13, 0.1218230301111122E-06, 0.2696165428114542E-17, 0.2328703557243073E-07, 0.5825676764620370E-08, 0.1286276792433928E-07}, + tauOut: 2.6961654281138038E-018, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2371578788845052E+01, 0.2371578794670729E+01, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.1074174599487151E+01, 0.1074266900775131E+01, 0.9230392664199863E-04, 0.1357860766428602E-03, 0.1580328086033647E+01, 0.1581175077027170E+01, 0.9827770701659698E-03, 0.9979623676695663E-03, 0.1605606471164067E+01, 0.1700242913771285E+01, 0.9563440497488795E-01, 0.5924520849284005E-01, 0.1053295055699924E+01, 0.1140565764170461E+01, 0.1465159169633776E+00, 0.2036234219705987E+00, 0.1585124051340792E+01, 0.1431315653342504E+01, 0.4981502397231050E-01, 0.2448080089382756E-01, 0.7033973032949510E+00, 0.7941601570521848E+00, 0.1152436546510613E+00, 0.1446598374682775E+00, 0.9968711907896164E+00, 0.1297075908641373E+01, 0.4448645553200346E+00, 0.4841405038964208E+00, 0.1411591407973117E+01, 0.1017552654060970E+01, 0.9010174998427344E-01, 0.7455594793877945E-01, 0.8419881158177074E+00, 0.1026142136362350E+01, 0.2587099684834221E+00, 0.4554599945126984E+00, 0.1806527574243020E+01, 0.1455048625807853E+01, 0.1039810460775319E+00, 0.7731088667813635E-01, 0.1081842351702556E+01, 0.1021456859803743E+01, 0.1692539477932339E-01, 0.1363571444815687E-01, 0.8229228471769590E+00, 0.8447303166937503E+00, 0.3544318396494814E-01, 0.4231334180394086E-01, 0.1008469291521964E+01, 0.9661590126100381E+00, 0.3062892015595061E-05, 0.9665775484099522E-06, 0.3048973339666884E+00, 0.3049033804612119E+00, 0.7013072071892081E-05, 0.2341758973227438E-05, 0.1018113345824760E+00, 0.1018089928235306E+00, 0.2786425742647189E-13, 0.7379175991216932E-30, 0.1093987140067686E+00}, + i0: 1, + n0: 16, + pp: 1, + n0in: 17, + dmin: 2.6961654281138038E-018, + dmin1: 0.10180899282350273, + dmin2: 0.30489636738914000, + dn: 2.6961654281138038E-018, + dn1: 0.10180899282350273, + dn2: 0.30489636738914000, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2371578788845052E+01, 0.2371578794670729E+01, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.1074174599487151E+01, 0.1074266900775131E+01, 0.9230392664199863E-04, 0.1357860766428602E-03, 0.1580328086033647E+01, 0.1581175077027170E+01, 0.9827770701659698E-03, 0.9979623676695663E-03, 0.1605606471164067E+01, 0.1700242913771285E+01, 0.9563440497488795E-01, 0.5924520849284005E-01, 0.1053295055699924E+01, 0.1140565764170461E+01, 0.1465159169633776E+00, 0.2036234219705987E+00, 0.1585124051340792E+01, 0.1431315653342504E+01, 0.4981502397231050E-01, 0.2448080089382756E-01, 0.7033973032949510E+00, 0.7941601570521848E+00, 0.1152436546510613E+00, 0.1446598374682775E+00, 0.9968711907896164E+00, 0.1297075908641373E+01, 0.4448645553200346E+00, 0.4841405038964208E+00, 0.1411591407973117E+01, 0.1017552654060970E+01, 0.9010174998427344E-01, 0.7455594793877945E-01, 0.8419881158177074E+00, 0.1026142136362350E+01, 0.2587099684834221E+00, 0.4554599945126984E+00, 0.1806527574243020E+01, 0.1455048625807853E+01, 0.1039810460775319E+00, 0.7731088667813635E-01, 0.1081842351702556E+01, 0.1021456859803743E+01, 0.1692539477932339E-01, 0.1363571444815687E-01, 0.8229228471769590E+00, 0.8447303166937503E+00, 0.3544318396494814E-01, 0.4231334180394086E-01, 0.1008469291521964E+01, 0.9661590126100381E+00, 0.3062892015595061E-05, 0.9665775484099522E-06, 0.3048973339666884E+00, 0.3049033804612119E+00, 0.7013072071892081E-05, 0.2341758973227438E-05, 0.1018113345824760E+00, 0.1018089928235306E+00, 0.2786425742647189E-13, 0.7379175991216932E-30, 0.1093987140067686E+00}, + tauOut: 0.10180650470263587, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2269772292606755E+01, 0.2371578794670729E+01, 0.1248859578385863E-08, 0.2638661645752538E-08, 0.9725961809002787E+00, 0.1074266900775131E+01, 0.2207509801202943E-03, 0.1357860766428602E-03, 0.1480145783712083E+01, 0.1581175077027170E+01, 0.1146359002276934E-02, 0.9979623676695663E-03, 0.1656535258559212E+01, 0.1700242913771285E+01, 0.4079180092843103E-01, 0.5924520849284005E-01, 0.1201590880509993E+01, 0.1140565764170461E+01, 0.2425529321011353E+00, 0.2036234219705987E+00, 0.1111437017432560E+01, 0.1431315653342504E+01, 0.1749237822536809E-01, 0.2448080089382756E-01, 0.8195211115924584E+00, 0.7941601570521848E+00, 0.2289566278084960E+00, 0.1446598374682775E+00, 0.1450453280026662E+01, 0.1297075908641373E+01, 0.3396444831847066E+00, 0.4841405038964208E+00, 0.6506576141124067E+00, 0.1017552654060970E+01, 0.1175810411452473E+00, 0.7455594793877945E-01, 0.1262214585027166E+01, 0.1026142136362350E+01, 0.5250426092262996E+00, 0.4554599945126984E+00, 0.9055103985570538E+00, 0.1455048625807853E+01, 0.8721019179982008E-01, 0.7731088667813635E-01, 0.8460758777494440E+00, 0.1021456859803743E+01, 0.1361402882064932E-01, 0.1363571444815687E-01, 0.7716231249744060E+00, 0.8447303166937503E+00, 0.5298106707064092E-01, 0.4231334180394086E-01, 0.8113724074143097E+00, 0.9661590126100381E+00, 0.3632274887524200E-06, 0.9665775484099522E-06, 0.2030988542900605E+00, 0.3049033804612119E+00, 0.1173872316183806E-05, 0.2341758973227438E-05, 0.1314248578535016E-05, 0.1018089928235306E+00, 0.1248859578385863E-08, 0.2638661645752538E-08}, + i0: 1, + n0: 16, + pp: 0, + n0in: 16, + dmin: 1.3142485785350155E-006, + dmin1: 0.20309651253108729, + dmin2: 0.57610166617362735, + dn: 1.3142485785350155E-006, + dn1: 0.20309651253108729, + dn2: 0.81137144083676127, + tau: 0.10180650470263587, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.2269772292606755E+01, 0.2371578794670729E+01, 0.1248859578385863E-08, 0.2638661645752538E-08, 0.9725961809002787E+00, 0.1074266900775131E+01, 0.2207509801202943E-03, 0.1357860766428602E-03, 0.1480145783712083E+01, 0.1581175077027170E+01, 0.1146359002276934E-02, 0.9979623676695663E-03, 0.1656535258559212E+01, 0.1700242913771285E+01, 0.4079180092843103E-01, 0.5924520849284005E-01, 0.1201590880509993E+01, 0.1140565764170461E+01, 0.2425529321011353E+00, 0.2036234219705987E+00, 0.1111437017432560E+01, 0.1431315653342504E+01, 0.1749237822536809E-01, 0.2448080089382756E-01, 0.8195211115924584E+00, 0.7941601570521848E+00, 0.2289566278084960E+00, 0.1446598374682775E+00, 0.1450453280026662E+01, 0.1297075908641373E+01, 0.3396444831847066E+00, 0.4841405038964208E+00, 0.6506576141124067E+00, 0.1017552654060970E+01, 0.1175810411452473E+00, 0.7455594793877945E-01, 0.1262214585027166E+01, 0.1026142136362350E+01, 0.5250426092262996E+00, 0.4554599945126984E+00, 0.9055103985570538E+00, 0.1455048625807853E+01, 0.8721019179982008E-01, 0.7731088667813635E-01, 0.8460758777494440E+00, 0.1021456859803743E+01, 0.1361402882064932E-01, 0.1363571444815687E-01, 0.7716231249744060E+00, 0.8447303166937503E+00, 0.5298106707064092E-01, 0.4231334180394086E-01, 0.8113724074143097E+00, 0.9661590126100381E+00, 0.3632274887524200E-06, 0.9665775484099522E-06, 0.2030988542900605E+00, 0.3049033804612119E+00, 0.1173872316183806E-05, 0.2341758973227438E-05, 0.1314248578535016E-05, 0.1018089928235306E+00, 0.1248859578385863E-08, 0.2638661645752538E-08}, + tauOut: 1.3142409824136984E-006, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2269772292606755E+01, 0.2269770979614632E+01, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.9725961809002787E+00, 0.9728156171042807E+00, 0.2207509801202943E-03, 0.3358741643642203E-03, 0.1480145783712083E+01, 0.1480954954309013E+01, 0.1146359002276934E-02, 0.1282269997958535E-02, 0.1656535258559212E+01, 0.1696043475248702E+01, 0.4079180092843103E-01, 0.2889964597634762E-01, 0.1201590880509993E+01, 0.1415242852393798E+01, 0.2425529321011353E+00, 0.1904848393814713E+00, 0.1111437017432560E+01, 0.9384432420354740E+00, 0.1749237822536809E-01, 0.1527569554079381E-01, 0.8195211115924584E+00, 0.1033200729619178E+01, 0.2289566278084960E+00, 0.3214195289148511E+00, 0.1450453280026662E+01, 0.1468676920055535E+01, 0.3396444831847066E+00, 0.1504703083827628E+00, 0.6506576141124067E+00, 0.6177670326339089E+00, 0.1175810411452473E+00, 0.2402402478867145E+00, 0.1262214585027166E+01, 0.1547015632125768E+01, 0.5250426092262996E+00, 0.3073217441808570E+00, 0.9055103985570538E+00, 0.6853975319350345E+00, 0.8721019179982008E-01, 0.1076549537133787E+00, 0.8460758777494440E+00, 0.7520336386157322E+00, 0.1361402882064932E-01, 0.1396865635082151E-01, 0.7716231249744060E+00, 0.8106342214532430E+00, 0.5298106707064092E-01, 0.5302931309687425E-01, 0.8113724074143097E+00, 0.7583421433039418E+00, 0.3632274887524200E-06, 0.9727942389020712E-07, 0.2030988542900605E+00, 0.2030986166419704E+00, 0.1173872316183806E-05, 0.7596112905317353E-11, 0.1314248578535016E-05, 0.8411884199182457E-17, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.1093987140067686E+00}, + i0: 1, + n0: 16, + pp: 1, + n0in: 16, + dmin: 8.4118841991824567E-018, + dmin1: 0.20309744276965425, + dmin2: 0.50018599148866161, + dn: 8.4118841991824567E-018, + dn1: 0.20309744276965425, + dn2: 0.75834178007645303, + tau: 1.3142409824136984E-006, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2269772292606755E+01, 0.2269770979614632E+01, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.9725961809002787E+00, 0.9728156171042807E+00, 0.2207509801202943E-03, 0.3358741643642203E-03, 0.1480145783712083E+01, 0.1480954954309013E+01, 0.1146359002276934E-02, 0.1282269997958535E-02, 0.1656535258559212E+01, 0.1696043475248702E+01, 0.4079180092843103E-01, 0.2889964597634762E-01, 0.1201590880509993E+01, 0.1415242852393798E+01, 0.2425529321011353E+00, 0.1904848393814713E+00, 0.1111437017432560E+01, 0.9384432420354740E+00, 0.1749237822536809E-01, 0.1527569554079381E-01, 0.8195211115924584E+00, 0.1033200729619178E+01, 0.2289566278084960E+00, 0.3214195289148511E+00, 0.1450453280026662E+01, 0.1468676920055535E+01, 0.3396444831847066E+00, 0.1504703083827628E+00, 0.6506576141124067E+00, 0.6177670326339089E+00, 0.1175810411452473E+00, 0.2402402478867145E+00, 0.1262214585027166E+01, 0.1547015632125768E+01, 0.5250426092262996E+00, 0.3073217441808570E+00, 0.9055103985570538E+00, 0.6853975319350345E+00, 0.8721019179982008E-01, 0.1076549537133787E+00, 0.8460758777494440E+00, 0.7520336386157322E+00, 0.1361402882064932E-01, 0.1396865635082151E-01, 0.7716231249744060E+00, 0.8106342214532430E+00, 0.5298106707064092E-01, 0.5302931309687425E-01, 0.8113724074143097E+00, 0.7583421433039418E+00, 0.3632274887524200E-06, 0.9727942389020712E-07, 0.2030988542900605E+00, 0.2030986166419704E+00, 0.1173872316183806E-05, 0.7596112905317353E-11, 0.1314248578535016E-05, 0.8411884199182457E-17, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.1093987140067686E+00}, + tauOut: 8.4118841988678429E-018, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2269770980149768E+01, 0.2269770979614632E+01, 0.2293573303077261E-09, 0.5351359530665278E-09, 0.9731514910392876E+00, 0.9728156171042807E+00, 0.5111377954200868E-03, 0.3358741643642203E-03, 0.1481726086511552E+01, 0.1480954954309013E+01, 0.1467737987028945E-02, 0.1282269997958535E-02, 0.1723475383238021E+01, 0.1696043475248702E+01, 0.2373112943910766E-01, 0.2889964597634762E-01, 0.1581996562336162E+01, 0.1415242852393798E+01, 0.1129959536471923E+00, 0.1904848393814713E+00, 0.8407229839290754E+00, 0.9384432420354740E+00, 0.1877296098701645E-01, 0.1527569554079381E-01, 0.1335847297547013E+01, 0.1033200729619178E+01, 0.3533797947109679E+00, 0.3214195289148511E+00, 0.1265767433727330E+01, 0.1468676920055535E+01, 0.7343813202351114E-01, 0.1504703083827628E+00, 0.7845691484971122E+00, 0.6177670326339089E+00, 0.4737063898809231E+00, 0.2402402478867145E+00, 0.1380630986425702E+01, 0.1547015632125768E+01, 0.1525661578238559E+00, 0.3073217441808570E+00, 0.6404863278245572E+00, 0.6853975319350345E+00, 0.1264041760751794E+00, 0.1076549537133787E+00, 0.6395981188913744E+00, 0.7520336386157322E+00, 0.1770404028911661E-01, 0.1396865635082151E-01, 0.8459594942610007E+00, 0.8106342214532430E+00, 0.4753698401003136E-01, 0.5302931309687425E-01, 0.7108052565733343E+00, 0.7583421433039418E+00, 0.2779568135873871E-07, 0.9727942389020712E-07, 0.2030985888538852E+00, 0.2030986166419704E+00, 0.3146138162949754E-27, 0.7596112905317353E-11, 0.8411884198867843E-17, 0.8411884199182457E-17, 0.2293573303077261E-09, 0.5351359530665278E-09}, + i0: 1, + n0: 16, + pp: 0, + n0in: 16, + dmin: 8.4118841988678429E-018, + dmin1: 0.20309858884628909, + dmin2: 0.53283137411117854, + dn: 8.4118841988678429E-018, + dn1: 0.20309858884628909, + dn2: 0.71080515929391042, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2269770980149768E+01, 0.2269770979614632E+01, 0.2293573303077261E-09, 0.5351359530665278E-09, 0.9731514910392876E+00, 0.9728156171042807E+00, 0.5111377954200868E-03, 0.3358741643642203E-03, 0.1481726086511552E+01, 0.1480954954309013E+01, 0.1467737987028945E-02, 0.1282269997958535E-02, 0.1723475383238021E+01, 0.1696043475248702E+01, 0.2373112943910766E-01, 0.2889964597634762E-01, 0.1581996562336162E+01, 0.1415242852393798E+01, 0.1129959536471923E+00, 0.1904848393814713E+00, 0.8407229839290754E+00, 0.9384432420354740E+00, 0.1877296098701645E-01, 0.1527569554079381E-01, 0.1335847297547013E+01, 0.1033200729619178E+01, 0.3533797947109679E+00, 0.3214195289148511E+00, 0.1265767433727330E+01, 0.1468676920055535E+01, 0.7343813202351114E-01, 0.1504703083827628E+00, 0.7845691484971122E+00, 0.6177670326339089E+00, 0.4737063898809231E+00, 0.2402402478867145E+00, 0.1380630986425702E+01, 0.1547015632125768E+01, 0.1525661578238559E+00, 0.3073217441808570E+00, 0.6404863278245572E+00, 0.6853975319350345E+00, 0.1264041760751794E+00, 0.1076549537133787E+00, 0.6395981188913744E+00, 0.7520336386157322E+00, 0.1770404028911661E-01, 0.1396865635082151E-01, 0.8459594942610007E+00, 0.8106342214532430E+00, 0.4753698401003136E-01, 0.5302931309687425E-01, 0.7108052565733343E+00, 0.7583421433039418E+00, 0.2779568135873871E-07, 0.9727942389020712E-07, 0.2030985888538852E+00, 0.2030986166419704E+00, 0.3146138162949754E-27, 0.7596112905317353E-11, 0.8411884198867843E-17, 0.8411884199182457E-17, 0.2293573303077261E-09, 0.5351359530665278E-09}, + tauOut: 8.4118841988678429E-018, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2269770980149768E+01, 0.2269770980379126E+01, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.9731514910392876E+00, 0.9736626287363720E+00, 0.5111377954200868E-03, 0.7778528033461282E-03, 0.1481726086511552E+01, 0.1482415971695234E+01, 0.1467737987028945E-02, 0.1706410574351102E-02, 0.1723475383238021E+01, 0.1745500102102777E+01, 0.2373112943910766E-01, 0.2150819994097728E-01, 0.1581996562336162E+01, 0.1673484316042377E+01, 0.1129959536471923E+00, 0.5676676764251993E-01, 0.8407229839290754E+00, 0.8027291772735718E+00, 0.1877296098701645E-01, 0.3124068479314146E-01, 0.1335847297547013E+01, 0.1657986407464839E+01, 0.3533797947109679E+00, 0.2697830536296953E+00, 0.1265767433727330E+01, 0.1069422512121146E+01, 0.7343813202351114E-01, 0.5387701498318342E-01, 0.7845691484971122E+00, 0.1204398523394852E+01, 0.4737063898809231E+00, 0.5430210247136315E+00, 0.1380630986425702E+01, 0.9901761195359265E+00, 0.1525661578238559E+00, 0.9868601781741700E-01, 0.6404863278245572E+00, 0.6682044860823195E+00, 0.1264041760751794E+00, 0.1209927124430272E+00, 0.6395981188913744E+00, 0.5363094467374639E+00, 0.1770404028911661E-01, 0.2792585709699239E-01, 0.8459594942610007E+00, 0.8655706211740396E+00, 0.4753698401003136E-01, 0.3903729781186600E-01, 0.7108052565733343E+00, 0.6717679865571495E+00, 0.2779568135873871E-07, 0.8403591378512072E-08, 0.2030985888538852E+00, 0.2030985804502939E+00, 0.3146138162949754E-27, 0.1303059324279677E-43, 0.2112065329503869E+00}, + i0: 1, + n0: 15, + pp: 1, + n0in: 16, + dmin: 8.4118841988678429E-018, + dmin1: 0.20309858045029386, + dmin2: 0.51860540644834729, + dn: 8.4118841988678429E-018, + dn1: 0.20309858045029386, + dn2: 0.67176795876146822, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2269770980149768E+01, 0.2269770980379126E+01, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.9731514910392876E+00, 0.9736626287363720E+00, 0.5111377954200868E-03, 0.7778528033461282E-03, 0.1481726086511552E+01, 0.1482415971695234E+01, 0.1467737987028945E-02, 0.1706410574351102E-02, 0.1723475383238021E+01, 0.1745500102102777E+01, 0.2373112943910766E-01, 0.2150819994097728E-01, 0.1581996562336162E+01, 0.1673484316042377E+01, 0.1129959536471923E+00, 0.5676676764251993E-01, 0.8407229839290754E+00, 0.8027291772735718E+00, 0.1877296098701645E-01, 0.3124068479314146E-01, 0.1335847297547013E+01, 0.1657986407464839E+01, 0.3533797947109679E+00, 0.2697830536296953E+00, 0.1265767433727330E+01, 0.1069422512121146E+01, 0.7343813202351114E-01, 0.5387701498318342E-01, 0.7845691484971122E+00, 0.1204398523394852E+01, 0.4737063898809231E+00, 0.5430210247136315E+00, 0.1380630986425702E+01, 0.9901761195359265E+00, 0.1525661578238559E+00, 0.9868601781741700E-01, 0.6404863278245572E+00, 0.6682044860823195E+00, 0.1264041760751794E+00, 0.1209927124430272E+00, 0.6395981188913744E+00, 0.5363094467374639E+00, 0.1770404028911661E-01, 0.2792585709699239E-01, 0.8459594942610007E+00, 0.8655706211740396E+00, 0.4753698401003136E-01, 0.3903729781186600E-01, 0.7108052565733343E+00, 0.6717679865571495E+00, 0.2779568135873871E-07, 0.8403591378512072E-08, 0.2030985888538852E+00, 0.2030985804502939E+00, 0.3146138162949754E-27, 0.1303059324279677E-43, 0.2112065329503869E+00}, + tauOut: 0.10154929022514693, + ttypeOut: -9, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2168221690252314E+01, 0.2269770980379126E+01, 0.4415865678637858E-10, 0.9833566024906726E-10, 0.8728911912704126E+00, 0.9736626287363720E+00, 0.1321013925721922E-02, 0.7778528033461282E-03, 0.1381252078118717E+01, 0.1482415971695234E+01, 0.2156405683614187E-02, 0.1706410574351102E-02, 0.1663302606134993E+01, 0.1745500102102777E+01, 0.2163985983955575E-01, 0.2150819994097728E-01, 0.1607061933620194E+01, 0.1673484316042377E+01, 0.2835506195054301E-01, 0.5676676764251993E-01, 0.7040655098910235E+00, 0.8027291772735718E+00, 0.7356791380810462E-01, 0.3124068479314146E-01, 0.1752652257061283E+01, 0.1657986407464839E+01, 0.1646145547572216E+00, 0.2697830536296953E+00, 0.8571356821219610E+00, 0.1069422512121146E+01, 0.7570493055431493E-01, 0.5387701498318342E-01, 0.1570165327329021E+01, 0.1204398523394852E+01, 0.3424393862982660E+00, 0.5430210247136315E+00, 0.6448734608299306E+00, 0.9901761195359265E+00, 0.1022564019526126E+00, 0.9868601781741700E-01, 0.5853915063475871E+00, 0.6682044860823195E+00, 0.1108480973262629E+00, 0.1209927124430272E+00, 0.3518379162830466E+00, 0.5363094467374639E+00, 0.6870152520689508E-01, 0.2792585709699239E-01, 0.7343571035538636E+00, 0.8655706211740396E+00, 0.3571015630515456E-01, 0.3903729781186600E-01, 0.5345085484304394E+00, 0.6717679865571495E+00, 0.3193134112956561E-08, 0.8403591378512072E-08, 0.1015492870320128E+00, 0.2030985804502939E+00, 0.4415865678637858E-10, 0.9833566024906726E-10}, + i0: 1, + n0: 15, + pp: 0, + n0in: 15, + dmin: 0.10154928703201281, + dmin1: 0.32391205918605420, + dmin2: 0.32391205918605420, + dn: 0.10154928703201281, + dn1: 0.53450854002684800, + dn2: 0.69531980574199759, + tau: 0.10154929022514693, + ttype: -9, + g: 0.0000000000000000, + zOut: []float64{0.2168221690252314E+01, 0.2269770980379126E+01, 0.4415865678637858E-10, 0.9833566024906726E-10, 0.8728911912704126E+00, 0.9736626287363720E+00, 0.1321013925721922E-02, 0.7778528033461282E-03, 0.1381252078118717E+01, 0.1482415971695234E+01, 0.2156405683614187E-02, 0.1706410574351102E-02, 0.1663302606134993E+01, 0.1745500102102777E+01, 0.2163985983955575E-01, 0.2150819994097728E-01, 0.1607061933620194E+01, 0.1673484316042377E+01, 0.2835506195054301E-01, 0.5676676764251993E-01, 0.7040655098910235E+00, 0.8027291772735718E+00, 0.7356791380810462E-01, 0.3124068479314146E-01, 0.1752652257061283E+01, 0.1657986407464839E+01, 0.1646145547572216E+00, 0.2697830536296953E+00, 0.8571356821219610E+00, 0.1069422512121146E+01, 0.7570493055431493E-01, 0.5387701498318342E-01, 0.1570165327329021E+01, 0.1204398523394852E+01, 0.3424393862982660E+00, 0.5430210247136315E+00, 0.6448734608299306E+00, 0.9901761195359265E+00, 0.1022564019526126E+00, 0.9868601781741700E-01, 0.5853915063475871E+00, 0.6682044860823195E+00, 0.1108480973262629E+00, 0.1209927124430272E+00, 0.3518379162830466E+00, 0.5363094467374639E+00, 0.6870152520689508E-01, 0.2792585709699239E-01, 0.7343571035538636E+00, 0.8655706211740396E+00, 0.3571015630515456E-01, 0.3903729781186600E-01, 0.5345085484304394E+00, 0.6717679865571495E+00, 0.3193134112956561E-08, 0.8403591378512072E-08, 0.1015492870320128E+00, 0.2030985804502939E+00, 0.4415865678637858E-10, 0.9833566024906726E-10}, + tauOut: 0.10154100618138810, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2168221690252314E+01, 0.2066680684115085E+01, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.8728911912704126E+00, 0.7726711989960955E+00, 0.1321013925721922E-02, 0.2361487308570419E-02, 0.1381252078118717E+01, 0.1279505990312372E+01, 0.2156405683614187E-02, 0.2803234389363145E-02, 0.1663302606134993E+01, 0.1580598225403798E+01, 0.2163985983955575E-01, 0.2200217261925751E-01, 0.1607061933620194E+01, 0.1511873816770092E+01, 0.2835506195054301E-01, 0.1320468740761088E-01, 0.7040655098910235E+00, 0.6628877301101292E+00, 0.7356791380810462E-01, 0.1945110224949301E+00, 0.1752652257061283E+01, 0.1621214783142186E+01, 0.1646145547572216E+00, 0.8703165684534678E-01, 0.8571356821219610E+00, 0.7442679496495411E+00, 0.7570493055431493E-01, 0.1597129865933493E+00, 0.1570165327329021E+01, 0.1651350720852550E+01, 0.3424393862982660E+00, 0.1337269360034139E+00, 0.6448734608299306E+00, 0.5118619205977412E+00, 0.1022564019526126E+00, 0.1169456581236225E+00, 0.5853915063475871E+00, 0.4777529393688394E+00, 0.1108480973262629E+00, 0.8163333047984263E-01, 0.3518379162830466E+00, 0.2373651048287110E+00, 0.6870152520689508E-01, 0.2125478936639627E+00, 0.7343571035538636E+00, 0.4559783600136673E+00, 0.3571015630515456E-01, 0.4186028435717903E-01, 0.5345085484304394E+00, 0.3911072610850064E+00, 0.3193134112956561E-08, 0.8290832843879624E-09, 0.1015492870320128E+00, 0.8280021541434701E-05, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.2112065329503869E+00}, + i0: 1, + n0: 15, + pp: 1, + n0in: 15, + dmin: 8.2800215414347011E-006, + dmin1: 0.16866357962181588, + dmin2: 0.16866357962181588, + dn: 8.2800215414347011E-006, + dn1: 0.39110725789187228, + dn2: 0.42026820370851276, + tau: 0.10154100618138810, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2168221690252314E+01, 0.2066680684115085E+01, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.8728911912704126E+00, 0.7726711989960955E+00, 0.1321013925721922E-02, 0.2361487308570419E-02, 0.1381252078118717E+01, 0.1279505990312372E+01, 0.2156405683614187E-02, 0.2803234389363145E-02, 0.1663302606134993E+01, 0.1580598225403798E+01, 0.2163985983955575E-01, 0.2200217261925751E-01, 0.1607061933620194E+01, 0.1511873816770092E+01, 0.2835506195054301E-01, 0.1320468740761088E-01, 0.7040655098910235E+00, 0.6628877301101292E+00, 0.7356791380810462E-01, 0.1945110224949301E+00, 0.1752652257061283E+01, 0.1621214783142186E+01, 0.1646145547572216E+00, 0.8703165684534678E-01, 0.8571356821219610E+00, 0.7442679496495411E+00, 0.7570493055431493E-01, 0.1597129865933493E+00, 0.1570165327329021E+01, 0.1651350720852550E+01, 0.3424393862982660E+00, 0.1337269360034139E+00, 0.6448734608299306E+00, 0.5118619205977412E+00, 0.1022564019526126E+00, 0.1169456581236225E+00, 0.5853915063475871E+00, 0.4777529393688394E+00, 0.1108480973262629E+00, 0.8163333047984263E-01, 0.3518379162830466E+00, 0.2373651048287110E+00, 0.6870152520689508E-01, 0.2125478936639627E+00, 0.7343571035538636E+00, 0.4559783600136673E+00, 0.3571015630515456E-01, 0.4186028435717903E-01, 0.5345085484304394E+00, 0.3911072610850064E+00, 0.3193134112956561E-08, 0.8290832843879624E-09, 0.1015492870320128E+00, 0.8280021541434701E-05, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.2112065329503869E+00}, + tauOut: 8.2795951083136037E-006, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2066672404538628E+01, 0.2066680684115085E+01, 0.6973096395115281E-11, 0.1865101988102620E-10, 0.7750244067025847E+00, 0.7726711989960955E+00, 0.3898634844569491E-02, 0.2361487308570419E-02, 0.1278402310262057E+01, 0.1279505990312372E+01, 0.3465878671879142E-02, 0.2803234389363145E-02, 0.1599126239756068E+01, 0.1580598225403798E+01, 0.2080167773382635E-01, 0.2200217261925751E-01, 0.1504268546848768E+01, 0.1511873816770092E+01, 0.5818924606767697E-02, 0.1320468740761088E-01, 0.8515715484031834E+00, 0.6628877301101292E+00, 0.3703084558710277E+00, 0.1945110224949301E+00, 0.1337929704521397E+01, 0.1621214783142186E+01, 0.4841425717359337E-01, 0.8703165684534678E-01, 0.8555583994741887E+00, 0.7442679496495411E+00, 0.3082690272254148E+00, 0.1597129865933493E+00, 0.1476800350035441E+01, 0.1651350720852550E+01, 0.4635002036444261E-01, 0.1337269360034139E+00, 0.5824492787618127E+00, 0.5118619205977412E+00, 0.9592445892242578E-01, 0.1169456581236225E+00, 0.4634535313311479E+00, 0.4777529393688394E+00, 0.4180980990954932E-01, 0.8163333047984263E-01, 0.4080949089880160E+00, 0.2373651048287110E+00, 0.2374870106014949E+00, 0.2125478936639627E+00, 0.2603433541742431E+00, 0.4559783600136673E+00, 0.6288565043307552E-01, 0.4186028435717903E-01, 0.3282133318859058E+00, 0.3911072610850064E+00, 0.2091574834858362E-13, 0.8290832843879624E-09, 0.4264122053484397E-09, 0.8280021541434701E-05, 0.6973096395115281E-11, 0.1865101988102620E-10}, + i0: 1, + n0: 15, + pp: 0, + n0in: 15, + dmin: 4.2641220534843968E-010, + dmin1: 0.19554701532405336, + dmin2: 0.19554701532405336, + dn: 4.2641220534843968E-010, + dn1: 0.32821333105682254, + dn2: 0.21848306981706411, + tau: 8.2795951083136037E-006, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2066672404538628E+01, 0.2066680684115085E+01, 0.6973096395115281E-11, 0.1865101988102620E-10, 0.7750244067025847E+00, 0.7726711989960955E+00, 0.3898634844569491E-02, 0.2361487308570419E-02, 0.1278402310262057E+01, 0.1279505990312372E+01, 0.3465878671879142E-02, 0.2803234389363145E-02, 0.1599126239756068E+01, 0.1580598225403798E+01, 0.2080167773382635E-01, 0.2200217261925751E-01, 0.1504268546848768E+01, 0.1511873816770092E+01, 0.5818924606767697E-02, 0.1320468740761088E-01, 0.8515715484031834E+00, 0.6628877301101292E+00, 0.3703084558710277E+00, 0.1945110224949301E+00, 0.1337929704521397E+01, 0.1621214783142186E+01, 0.4841425717359337E-01, 0.8703165684534678E-01, 0.8555583994741887E+00, 0.7442679496495411E+00, 0.3082690272254148E+00, 0.1597129865933493E+00, 0.1476800350035441E+01, 0.1651350720852550E+01, 0.4635002036444261E-01, 0.1337269360034139E+00, 0.5824492787618127E+00, 0.5118619205977412E+00, 0.9592445892242578E-01, 0.1169456581236225E+00, 0.4634535313311479E+00, 0.4777529393688394E+00, 0.4180980990954932E-01, 0.8163333047984263E-01, 0.4080949089880160E+00, 0.2373651048287110E+00, 0.2374870106014949E+00, 0.2125478936639627E+00, 0.2603433541742431E+00, 0.4559783600136673E+00, 0.6288565043307552E-01, 0.4186028435717903E-01, 0.3282133318859058E+00, 0.3911072610850064E+00, 0.2091574834858362E-13, 0.8290832843879624E-09, 0.4264122053484397E-09, 0.8280021541434701E-05, 0.6973096395115281E-11, 0.1865101988102620E-10}, + tauOut: 4.2641207498271701E-010, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2066672404538628E+01, 0.2066672404119188E+01, 0.6973096395115281E-11, 0.2614986238618434E-11, 0.7750244067025847E+00, 0.7789230411181270E+00, 0.3898634844569491E-02, 0.6398608757305904E-02, 0.1278402310262057E+01, 0.1275469579750218E+01, 0.3465878671879142E-02, 0.4345362379476143E-02, 0.1599126239756068E+01, 0.1615582554684006E+01, 0.2080167773382635E-01, 0.1936843737632438E-01, 0.1504268546848768E+01, 0.1490719033652799E+01, 0.5818924606767697E-02, 0.3324054047451484E-02, 0.8515715484031834E+00, 0.1218555949800348E+01, 0.3703084558710277E+00, 0.4065850919906259E+00, 0.1337929704521397E+01, 0.9797588692779520E+00, 0.4841425717359337E-01, 0.4227695780870786E-01, 0.8555583994741887E+00, 0.1121550468464483E+01, 0.3082690272254148E+00, 0.4059129037098644E+00, 0.1476800350035441E+01, 0.1117237466263607E+01, 0.4635002036444261E-01, 0.2416365074306882E-01, 0.5824492787618127E+00, 0.6542100865147574E+00, 0.9592445892242578E-01, 0.6795451513972497E-01, 0.4634535313311479E+00, 0.4373088256745602E+00, 0.4180980990954932E-01, 0.3901675330591518E-01, 0.4080949089880160E+00, 0.6065651658571838E+00, 0.2374870106014949E+00, 0.1019316116273065E+00, 0.2603433541742431E+00, 0.2212973925536000E+00, 0.6288565043307552E-01, 0.9326774535516916E-01, 0.3282133318859058E+00, 0.2349455861043456E+00, 0.2091574834858362E-13, 0.3796083394336032E-22, 0.4264122053484397E-09, 0.1303656847202082E-15, 0.6973096395115281E-11, 0.2614986238618434E-11, 0.2112065329503869E+00}, + i0: 1, + n0: 15, + pp: 1, + n0in: 15, + dmin: 1.3036568472020817E-016, + dmin1: 0.15841174212052453, + dmin2: 0.15841174212052453, + dn: 1.3036568472020817E-016, + dn1: 0.23494558610432464, + dn2: 0.15841174212052453, + tau: 4.2641207498271701E-010, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2066672404538628E+01, 0.2066672404119188E+01, 0.6973096395115281E-11, 0.2614986238618434E-11, 0.7750244067025847E+00, 0.7789230411181270E+00, 0.3898634844569491E-02, 0.6398608757305904E-02, 0.1278402310262057E+01, 0.1275469579750218E+01, 0.3465878671879142E-02, 0.4345362379476143E-02, 0.1599126239756068E+01, 0.1615582554684006E+01, 0.2080167773382635E-01, 0.1936843737632438E-01, 0.1504268546848768E+01, 0.1490719033652799E+01, 0.5818924606767697E-02, 0.3324054047451484E-02, 0.8515715484031834E+00, 0.1218555949800348E+01, 0.3703084558710277E+00, 0.4065850919906259E+00, 0.1337929704521397E+01, 0.9797588692779520E+00, 0.4841425717359337E-01, 0.4227695780870786E-01, 0.8555583994741887E+00, 0.1121550468464483E+01, 0.3082690272254148E+00, 0.4059129037098644E+00, 0.1476800350035441E+01, 0.1117237466263607E+01, 0.4635002036444261E-01, 0.2416365074306882E-01, 0.5824492787618127E+00, 0.6542100865147574E+00, 0.9592445892242578E-01, 0.6795451513972497E-01, 0.4634535313311479E+00, 0.4373088256745602E+00, 0.4180980990954932E-01, 0.3901675330591518E-01, 0.4080949089880160E+00, 0.6065651658571838E+00, 0.2374870106014949E+00, 0.1019316116273065E+00, 0.2603433541742431E+00, 0.2212973925536000E+00, 0.6288565043307552E-01, 0.9326774535516916E-01, 0.3282133318859058E+00, 0.2349455861043456E+00, 0.2091574834858362E-13, 0.3796083394336032E-22, 0.4264122053484397E-09, 0.1303656847202082E-15, 0.6973096395115281E-11, 0.2614986238618434E-11, 0.2112065329503869E+00}, + tauOut: 1.3036568471812905E-016, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2066672404121803E+01, 0.2066672404119188E+01, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.7853216498744473E+00, 0.7789230411181270E+00, 0.1039221422709001E-01, 0.6398608757305904E-02, 0.1269422727902604E+01, 0.1275469579750218E+01, 0.5530302475095172E-02, 0.4345362379476143E-02, 0.1629420689585235E+01, 0.1615582554684006E+01, 0.1771973219288664E-01, 0.1936843737632438E-01, 0.1476323355507364E+01, 0.1490719033652799E+01, 0.2743671176012720E-02, 0.3324054047451484E-02, 0.1622397370614960E+01, 0.1218555949800348E+01, 0.2455350071499520E+00, 0.4065850919906259E+00, 0.7765008199367077E+00, 0.9797588692779520E+00, 0.6106335063429082E-01, 0.4227695780870786E-01, 0.1466400021540057E+01, 0.1121550468464483E+01, 0.3092615230516922E+00, 0.4059129037098644E+00, 0.8321395939549830E+00, 0.1117237466263607E+01, 0.1899693772291602E-01, 0.2416365074306882E-01, 0.7031676639315663E+00, 0.6542100865147574E+00, 0.4226176876348708E-01, 0.6795451513972497E-01, 0.4340638102169883E+00, 0.4373088256745602E+00, 0.5452240634477346E-01, 0.3901675330591518E-01, 0.6539743711397168E+00, 0.6065651658571838E+00, 0.3449248298919955E-01, 0.1019316116273065E+00, 0.2800726549195695E+00, 0.2212973925536000E+00, 0.7823985923721809E-01, 0.9326774535516916E-01, 0.1567057268671274E+00, 0.2349455861043456E+00, 0.3158014839988858E-37, 0.3796083394336032E-22}, + i0: 1, + n0: 14, + pp: 0, + n0in: 15, + dmin: 2.0791168714198411E-027, + dmin1: 0.15670572686712736, + dmin2: 0.18680490956440032, + dn: 2.0791168714198411E-027, + dn1: 0.15670572686712736, + dn2: 0.18680490956440032, + tau: 1.3036568471812905E-016, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2066672404121803E+01, 0.2066672404119188E+01, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.7853216498744473E+00, 0.7789230411181270E+00, 0.1039221422709001E-01, 0.6398608757305904E-02, 0.1269422727902604E+01, 0.1275469579750218E+01, 0.5530302475095172E-02, 0.4345362379476143E-02, 0.1629420689585235E+01, 0.1615582554684006E+01, 0.1771973219288664E-01, 0.1936843737632438E-01, 0.1476323355507364E+01, 0.1490719033652799E+01, 0.2743671176012720E-02, 0.3324054047451484E-02, 0.1622397370614960E+01, 0.1218555949800348E+01, 0.2455350071499520E+00, 0.4065850919906259E+00, 0.7765008199367077E+00, 0.9797588692779520E+00, 0.6106335063429082E-01, 0.4227695780870786E-01, 0.1466400021540057E+01, 0.1121550468464483E+01, 0.3092615230516922E+00, 0.4059129037098644E+00, 0.8321395939549830E+00, 0.1117237466263607E+01, 0.1899693772291602E-01, 0.2416365074306882E-01, 0.7031676639315663E+00, 0.6542100865147574E+00, 0.4226176876348708E-01, 0.6795451513972497E-01, 0.4340638102169883E+00, 0.4373088256745602E+00, 0.5452240634477346E-01, 0.3901675330591518E-01, 0.6539743711397168E+00, 0.6065651658571838E+00, 0.3449248298919955E-01, 0.1019316116273065E+00, 0.2800726549195695E+00, 0.2212973925536000E+00, 0.7823985923721809E-01, 0.9326774535516916E-01, 0.1567057268671274E+00, 0.2349455861043456E+00, 0.3158014839988858E-37, 0.3796083394336032E-22}, + tauOut: 5.2226904068357879E-002, + ttypeOut: -8, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2066672404121803E+01, 0.2014445500054431E+01, 0.9855809897129084E-12, 0.3842238913414725E-12, 0.7853216498744473E+00, 0.7434869600327952E+00, 0.1039221422709001E-01, 0.1774357001838869E-01, 0.1269422727902604E+01, 0.1204982556290953E+01, 0.5530302475095172E-02, 0.7478273627729330E-02, 0.1629420689585235E+01, 0.1587435244082034E+01, 0.1771973219288664E-01, 0.1647944669694028E-01, 0.1476323355507364E+01, 0.1410360675918078E+01, 0.2743671176012720E-02, 0.3156160674217245E-02, 0.1622397370614960E+01, 0.1812549313022337E+01, 0.2455350071499520E+00, 0.1051878329628395E+00, 0.7765008199367077E+00, 0.6801494335398012E+00, 0.6106335063429082E-01, 0.1316523902981273E+00, 0.1466400021540057E+01, 0.1591782250225264E+01, 0.3092615230516922E+00, 0.1616733433116970E+00, 0.8321395939549830E+00, 0.6372362842978442E+00, 0.1899693772291602E-01, 0.2096244776016672E-01, 0.7031676639315663E+00, 0.6722400808665288E+00, 0.4226176876348708E-01, 0.2728832287468248E-01, 0.4340638102169883E+00, 0.4090709896187213E+00, 0.5452240634477346E-01, 0.8716398206477828E-01, 0.6539743711397168E+00, 0.5490759679957803E+00, 0.3449248298919955E-01, 0.1759392479116377E-01, 0.2800726549195695E+00, 0.2884916852972659E+00, 0.7823985923721809E-01, 0.4249908970207047E-01, 0.1567057268671274E+00, 0.6197973309669901E-01, 0.3158014839988858E-37, 0.3842238913414725E-12, 0.4143051093784424E+00}, + i0: 1, + n0: 14, + pp: 1, + n0in: 14, + dmin: 6.1979733096699005E-002, + dmin1: 0.21025182606004778, + dmin2: 0.35454858327394784, + dn: 6.1979733096699005E-002, + dn1: 0.21025182606004778, + dn2: 0.51458348500658069, + tau: 5.2226904068357879E-002, + ttype: -8, + g: 0.0000000000000000, + zOut: []float64{0.2066672404121803E+01, 0.2014445500054431E+01, 0.9855809897129084E-12, 0.3842238913414725E-12, 0.7853216498744473E+00, 0.7434869600327952E+00, 0.1039221422709001E-01, 0.1774357001838869E-01, 0.1269422727902604E+01, 0.1204982556290953E+01, 0.5530302475095172E-02, 0.7478273627729330E-02, 0.1629420689585235E+01, 0.1587435244082034E+01, 0.1771973219288664E-01, 0.1647944669694028E-01, 0.1476323355507364E+01, 0.1410360675918078E+01, 0.2743671176012720E-02, 0.3156160674217245E-02, 0.1622397370614960E+01, 0.1812549313022337E+01, 0.2455350071499520E+00, 0.1051878329628395E+00, 0.7765008199367077E+00, 0.6801494335398012E+00, 0.6106335063429082E-01, 0.1316523902981273E+00, 0.1466400021540057E+01, 0.1591782250225264E+01, 0.3092615230516922E+00, 0.1616733433116970E+00, 0.8321395939549830E+00, 0.6372362842978442E+00, 0.1899693772291602E-01, 0.2096244776016672E-01, 0.7031676639315663E+00, 0.6722400808665288E+00, 0.4226176876348708E-01, 0.2728832287468248E-01, 0.4340638102169883E+00, 0.4090709896187213E+00, 0.5452240634477346E-01, 0.8716398206477828E-01, 0.6539743711397168E+00, 0.5490759679957803E+00, 0.3449248298919955E-01, 0.1759392479116377E-01, 0.2800726549195695E+00, 0.2884916852972659E+00, 0.7823985923721809E-01, 0.4249908970207047E-01, 0.1567057268671274E+00, 0.6197973309669901E-01, 0.3158014839988858E-37, 0.3842238913414725E-12, 0.4143051093784424E+00}, + tauOut: 4.3992746597899146E-002, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1970452753456916E+01, 0.2014445500054431E+01, 0.1449745254963753E-12, 0.3842238913414725E-12, 0.7172377834531399E+00, 0.7434869600327952E+00, 0.2980976860358389E-01, 0.1774357001838869E-01, 0.1138658314717199E+01, 0.1204982556290953E+01, 0.1042566937606312E-01, 0.7478273627729330E-02, 0.1549496274805013E+01, 0.1587435244082034E+01, 0.1499968987352189E-01, 0.1647944669694028E-01, 0.1354524400120875E+01, 0.1410360675918078E+01, 0.4223398900256122E-02, 0.3156160674217245E-02, 0.1869521000487022E+01, 0.1812549313022337E+01, 0.3826832915293116E-01, 0.1051878329628395E+00, 0.7295407480870981E+00, 0.6801494335398012E+00, 0.2872518617030954E+00, 0.1316523902981273E+00, 0.1422210985235967E+01, 0.1591782250225264E+01, 0.7243940711431240E-01, 0.1616733433116970E+00, 0.5417665783457993E+00, 0.6372362842978442E+00, 0.2601082853889214E-01, 0.2096244776016672E-01, 0.6295248286044199E+00, 0.6722400808665288E+00, 0.1773220171177086E-01, 0.2728832287468248E-01, 0.4345100233738295E+00, 0.4090709896187213E+00, 0.1101462457758059E+00, 0.8716398206477828E-01, 0.4125309004132391E+00, 0.5490759679957803E+00, 0.1230380805149813E-01, 0.1759392479116377E-01, 0.2746942203499391E+00, 0.2884916852972659E+00, 0.9589143278047064E-02, 0.4249908970207047E-01, 0.8397843220752800E-02, 0.6197973309669901E-01, 0.1449745254963753E-12, 0.3842238913414725E-12}, + i0: 1, + n0: 14, + pp: 0, + n0in: 14, + dmin: 8.3978432207528000E-003, + dmin1: 0.23219513064786862, + dmin2: 0.34734604130905122, + dn: 8.3978432207528000E-003, + dn1: 0.23219513064786862, + dn2: 0.39493697562207530, + tau: 4.3992746597899146E-002, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1970452753456916E+01, 0.2014445500054431E+01, 0.1449745254963753E-12, 0.3842238913414725E-12, 0.7172377834531399E+00, 0.7434869600327952E+00, 0.2980976860358389E-01, 0.1774357001838869E-01, 0.1138658314717199E+01, 0.1204982556290953E+01, 0.1042566937606312E-01, 0.7478273627729330E-02, 0.1549496274805013E+01, 0.1587435244082034E+01, 0.1499968987352189E-01, 0.1647944669694028E-01, 0.1354524400120875E+01, 0.1410360675918078E+01, 0.4223398900256122E-02, 0.3156160674217245E-02, 0.1869521000487022E+01, 0.1812549313022337E+01, 0.3826832915293116E-01, 0.1051878329628395E+00, 0.7295407480870981E+00, 0.6801494335398012E+00, 0.2872518617030954E+00, 0.1316523902981273E+00, 0.1422210985235967E+01, 0.1591782250225264E+01, 0.7243940711431240E-01, 0.1616733433116970E+00, 0.5417665783457993E+00, 0.6372362842978442E+00, 0.2601082853889214E-01, 0.2096244776016672E-01, 0.6295248286044199E+00, 0.6722400808665288E+00, 0.1773220171177086E-01, 0.2728832287468248E-01, 0.4345100233738295E+00, 0.4090709896187213E+00, 0.1101462457758059E+00, 0.8716398206477828E-01, 0.4125309004132391E+00, 0.5490759679957803E+00, 0.1230380805149813E-01, 0.1759392479116377E-01, 0.2746942203499391E+00, 0.2884916852972659E+00, 0.9589143278047064E-02, 0.4249908970207047E-01, 0.8397843220752800E-02, 0.6197973309669901E-01, 0.1449745254963753E-12, 0.3842238913414725E-12}, + tauOut: 8.0121275381568099E-003, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1970452753456916E+01, 0.1962440625918904E+01, 0.1449745254963753E-12, 0.5298565773193886E-13, 0.7172377834531399E+00, 0.7390354245185139E+00, 0.2980976860358389E-01, 0.4592897681783073E-01, 0.1138658314717199E+01, 0.1095142879737275E+01, 0.1042566937606312E-01, 0.1475107600976594E-01, 0.1549496274805013E+01, 0.1541732761130612E+01, 0.1499968987352189E-01, 0.1317831886314191E-01, 0.1354524400120875E+01, 0.1337557352619832E+01, 0.4223398900256122E-02, 0.5903098601340335E-02, 0.1869521000487022E+01, 0.1893874103500456E+01, 0.3826832915293116E-01, 0.1474137347708128E-01, 0.7295407480870981E+00, 0.9940391087749554E+00, 0.2872518617030954E+00, 0.4109825756725979E+00, 0.1422210985235967E+01, 0.1075655689139524E+01, 0.7243940711431240E-01, 0.3648495529374628E-01, 0.5417665783457993E+00, 0.5232803240527883E+00, 0.2601082853889214E-01, 0.3129195122603765E-01, 0.6295248286044199E+00, 0.6079529515519964E+00, 0.1773220171177086E-01, 0.1267338099203561E-01, 0.4345100233738295E+00, 0.5239707606194429E+00, 0.1101462457758059E+00, 0.8671997249104711E-01, 0.4125309004132391E+00, 0.3301026084355332E+00, 0.1230380805149813E-01, 0.1023858907404432E-01, 0.2746942203499391E+00, 0.2660326470157850E+00, 0.9589143278047064E-02, 0.3027001489241909E-03, 0.8397843220752800E-02, 0.8301553367179998E-04, 0.1449745254963753E-12, 0.5298565773193886E-13, 0.4143051093784424E+00}, + i0: 1, + n0: 14, + pp: 1, + n0in: 14, + dmin: 8.3015533671799979E-005, + dmin1: 0.25644350373773794, + dmin2: 0.31779880038403513, + dn: 8.3015533671799979E-005, + dn1: 0.25644350373773794, + dn2: 0.31779880038403513, + tau: 8.0121275381568099E-003, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1970452753456916E+01, 0.1962440625918904E+01, 0.1449745254963753E-12, 0.5298565773193886E-13, 0.7172377834531399E+00, 0.7390354245185139E+00, 0.2980976860358389E-01, 0.4592897681783073E-01, 0.1138658314717199E+01, 0.1095142879737275E+01, 0.1042566937606312E-01, 0.1475107600976594E-01, 0.1549496274805013E+01, 0.1541732761130612E+01, 0.1499968987352189E-01, 0.1317831886314191E-01, 0.1354524400120875E+01, 0.1337557352619832E+01, 0.4223398900256122E-02, 0.5903098601340335E-02, 0.1869521000487022E+01, 0.1893874103500456E+01, 0.3826832915293116E-01, 0.1474137347708128E-01, 0.7295407480870981E+00, 0.9940391087749554E+00, 0.2872518617030954E+00, 0.4109825756725979E+00, 0.1422210985235967E+01, 0.1075655689139524E+01, 0.7243940711431240E-01, 0.3648495529374628E-01, 0.5417665783457993E+00, 0.5232803240527883E+00, 0.2601082853889214E-01, 0.3129195122603765E-01, 0.6295248286044199E+00, 0.6079529515519964E+00, 0.1773220171177086E-01, 0.1267338099203561E-01, 0.4345100233738295E+00, 0.5239707606194429E+00, 0.1101462457758059E+00, 0.8671997249104711E-01, 0.4125309004132391E+00, 0.3301026084355332E+00, 0.1230380805149813E-01, 0.1023858907404432E-01, 0.2746942203499391E+00, 0.2660326470157850E+00, 0.9589143278047064E-02, 0.3027001489241909E-03, 0.8397843220752800E-02, 0.8301553367179998E-04, 0.1449745254963753E-12, 0.5298565773193886E-13, 0.4143051093784424E+00}, + tauOut: 8.2898056486573887E-005, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1962357727862470E+01, 0.1962440625918904E+01, 0.1995470932711637E-13, 0.5298565773193886E-13, 0.7848815032798381E+00, 0.7390354245185139E+00, 0.6408456783027588E-01, 0.4592897681783073E-01, 0.1045726489860278E+01, 0.1095142879737275E+01, 0.2174776805091989E-01, 0.1475107600976594E-01, 0.1533080413886347E+01, 0.1541732761130612E+01, 0.1149760777771624E-01, 0.1317831886314191E-01, 0.1331879945386970E+01, 0.1337557352619832E+01, 0.8393943921304423E-02, 0.5903098601340335E-02, 0.1900138634999746E+01, 0.1893874103500456E+01, 0.7711806645770664E-02, 0.1474137347708128E-01, 0.1397226979745296E+01, 0.9940391087749554E+00, 0.3163950825942626E+00, 0.4109825756725979E+00, 0.7956626637825215E+00, 0.1075655689139524E+01, 0.2399491656225486E-01, 0.3648495529374628E-01, 0.5304944606600845E+00, 0.5232803240527883E+00, 0.3586094769777509E-01, 0.3129195122603765E-01, 0.5846824867897703E+00, 0.6079529515519964E+00, 0.1135741402906866E-01, 0.1267338099203561E-01, 0.5992504210249349E+00, 0.5239707606194429E+00, 0.4777049480214081E-01, 0.8671997249104711E-01, 0.2924878046509502E+00, 0.3301026084355332E+00, 0.9312521444528056E-02, 0.1023858907404432E-01, 0.2569399276636945E+00, 0.2660326470157850E+00, 0.9780034825247492E-07, 0.3027001489241909E-03, 0.1967683697362142E-07, 0.8301553367179998E-04, 0.1995470932711637E-13, 0.5298565773193886E-13}, + i0: 1, + n0: 14, + pp: 0, + n0in: 14, + dmin: 1.9676836973621424E-008, + dmin1: 0.25663722751477031, + dmin2: 0.28224921557690585, + dn: 1.9676836973621424E-008, + dn1: 0.25663722751477031, + dn2: 0.28224921557690585, + tau: 8.2898056486573887E-005, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1962357727862470E+01, 0.1962440625918904E+01, 0.1995470932711637E-13, 0.5298565773193886E-13, 0.7848815032798381E+00, 0.7390354245185139E+00, 0.6408456783027588E-01, 0.4592897681783073E-01, 0.1045726489860278E+01, 0.1095142879737275E+01, 0.2174776805091989E-01, 0.1475107600976594E-01, 0.1533080413886347E+01, 0.1541732761130612E+01, 0.1149760777771624E-01, 0.1317831886314191E-01, 0.1331879945386970E+01, 0.1337557352619832E+01, 0.8393943921304423E-02, 0.5903098601340335E-02, 0.1900138634999746E+01, 0.1893874103500456E+01, 0.7711806645770664E-02, 0.1474137347708128E-01, 0.1397226979745296E+01, 0.9940391087749554E+00, 0.3163950825942626E+00, 0.4109825756725979E+00, 0.7956626637825215E+00, 0.1075655689139524E+01, 0.2399491656225486E-01, 0.3648495529374628E-01, 0.5304944606600845E+00, 0.5232803240527883E+00, 0.3586094769777509E-01, 0.3129195122603765E-01, 0.5846824867897703E+00, 0.6079529515519964E+00, 0.1135741402906866E-01, 0.1267338099203561E-01, 0.5992504210249349E+00, 0.5239707606194429E+00, 0.4777049480214081E-01, 0.8671997249104711E-01, 0.2924878046509502E+00, 0.3301026084355332E+00, 0.9312521444528056E-02, 0.1023858907404432E-01, 0.2569399276636945E+00, 0.2660326470157850E+00, 0.9780034825247492E-07, 0.3027001489241909E-03, 0.1967683697362142E-07, 0.8301553367179998E-04, 0.1995470932711637E-13, 0.5298565773193886E-13}, + tauOut: 1.9676827722764296E-008, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1962357727862470E+01, 0.1962357708185662E+01, 0.1995470932711637E-13, 0.7981257539768321E-14, 0.7848815032798381E+00, 0.8489660514332782E+00, 0.6408456783027588E-01, 0.7893711422056097E-01, 0.1045726489860278E+01, 0.9885371240138099E+00, 0.2174776805091989E-01, 0.3372769361380378E-01, 0.1533080413886347E+01, 0.1510850308373431E+01, 0.1149760777771624E-01, 0.1013563894066502E-01, 0.1331879945386970E+01, 0.1330138230690781E+01, 0.8393943921304423E-02, 0.1199097716077874E-01, 0.1900138634999746E+01, 0.1895859444807910E+01, 0.7711806645770664E-02, 0.5683514322519618E-02, 0.1397226979745296E+01, 0.1707938528340212E+01, 0.3163950825942626E+00, 0.1473962616612956E+00, 0.7956626637825215E+00, 0.6722612990066530E+00, 0.2399491656225486E-01, 0.1893485515094503E-01, 0.5304944606600845E+00, 0.5474205335300870E+00, 0.3586094769777509E-01, 0.3830193935796279E-01, 0.5846824867897703E+00, 0.5577379417840483E+00, 0.1135741402906866E-01, 0.1220274725600271E-01, 0.5992504210249349E+00, 0.6348181488942451E+00, 0.4777049480214081E-01, 0.2200990500366971E-01, 0.2924878046509502E+00, 0.2797904014149808E+00, 0.9312521444528056E-02, 0.8551968095484232E-02, 0.2569399276636945E+00, 0.2483880376917308E+00, 0.9780034825247492E-07, 0.7747561140265878E-14, 0.1967683697362142E-07, 0.1503295986001297E-14, 0.1995470932711637E-13, 0.7981257539768321E-14, 0.4143051093784424E+00}, + i0: 1, + n0: 14, + pp: 1, + n0in: 14, + dmin: 1.5032959860012969E-015, + dmin1: 0.24838793989138258, + dmin2: 0.27047787997045275, + dn: 1.5032959860012969E-015, + dn1: 0.24838793989138258, + dn2: 0.27047787997045275, + tau: 1.9676827722764296E-008, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1962357727862470E+01, 0.1962357708185662E+01, 0.1995470932711637E-13, 0.7981257539768321E-14, 0.7848815032798381E+00, 0.8489660514332782E+00, 0.6408456783027588E-01, 0.7893711422056097E-01, 0.1045726489860278E+01, 0.9885371240138099E+00, 0.2174776805091989E-01, 0.3372769361380378E-01, 0.1533080413886347E+01, 0.1510850308373431E+01, 0.1149760777771624E-01, 0.1013563894066502E-01, 0.1331879945386970E+01, 0.1330138230690781E+01, 0.8393943921304423E-02, 0.1199097716077874E-01, 0.1900138634999746E+01, 0.1895859444807910E+01, 0.7711806645770664E-02, 0.5683514322519618E-02, 0.1397226979745296E+01, 0.1707938528340212E+01, 0.3163950825942626E+00, 0.1473962616612956E+00, 0.7956626637825215E+00, 0.6722612990066530E+00, 0.2399491656225486E-01, 0.1893485515094503E-01, 0.5304944606600845E+00, 0.5474205335300870E+00, 0.3586094769777509E-01, 0.3830193935796279E-01, 0.5846824867897703E+00, 0.5577379417840483E+00, 0.1135741402906866E-01, 0.1220274725600271E-01, 0.5992504210249349E+00, 0.6348181488942451E+00, 0.4777049480214081E-01, 0.2200990500366971E-01, 0.2924878046509502E+00, 0.2797904014149808E+00, 0.9312521444528056E-02, 0.8551968095484232E-02, 0.2569399276636945E+00, 0.2483880376917308E+00, 0.9780034825247492E-07, 0.7747561140265878E-14, 0.1967683697362142E-07, 0.1503295986001297E-14, 0.1995470932711637E-13, 0.7981257539768321E-14, 0.4143051093784424E+00}, + tauOut: 1.5032959860012393E-015, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1962357708185669E+01, 0.1962357708185662E+01, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.9279031656538340E+00, 0.8489660514332782E+00, 0.8409527066820451E-01, 0.7893711422056097E-01, 0.9381695469594078E+00, 0.9885371240138099E+00, 0.5431587122209677E-01, 0.3372769361380378E-01, 0.1466670076091998E+01, 0.1510850308373431E+01, 0.9192115573380727E-02, 0.1013563894066502E-01, 0.1332937092278178E+01, 0.1330138230690781E+01, 0.1705497388769041E-01, 0.1199097716077874E-01, 0.1884487985242738E+01, 0.1895859444807910E+01, 0.5151050664063701E-02, 0.5683514322519618E-02, 0.1850183739337442E+01, 0.1707938528340212E+01, 0.5355619565040129E-01, 0.1473962616612956E+00, 0.6376399585071952E+00, 0.6722612990066530E+00, 0.1625577000116482E-01, 0.1893485515094503E-01, 0.5694667028868834E+00, 0.5474205335300870E+00, 0.3751307094084999E-01, 0.3830193935796279E-01, 0.5324276180991995E+00, 0.5577379417840483E+00, 0.1454944326918194E-01, 0.1220274725600271E-01, 0.6422786106287314E+00, 0.6348181488942451E+00, 0.9587988848101409E-02, 0.2200990500366971E-01, 0.2787543806623621E+00, 0.2797904014149808E+00, 0.7620352256320365E-02, 0.8551968095484232E-02, 0.2407676854354167E+00, 0.2483880376917308E+00, 0.4837392336267432E-28, 0.7747561140265878E-14}, + i0: 1, + n0: 13, + pp: 0, + n0in: 14, + dmin: 9.2691156363468887E-030, + dmin1: 0.24076768543540897, + dmin2: 0.27020241256687788, + dn: 9.2691156363468887E-030, + dn1: 0.24076768543540897, + dn2: 0.27020241256687788, + tau: 1.5032959860012393E-015, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1962357708185669E+01, 0.1962357708185662E+01, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.9279031656538340E+00, 0.8489660514332782E+00, 0.8409527066820451E-01, 0.7893711422056097E-01, 0.9381695469594078E+00, 0.9885371240138099E+00, 0.5431587122209677E-01, 0.3372769361380378E-01, 0.1466670076091998E+01, 0.1510850308373431E+01, 0.9192115573380727E-02, 0.1013563894066502E-01, 0.1332937092278178E+01, 0.1330138230690781E+01, 0.1705497388769041E-01, 0.1199097716077874E-01, 0.1884487985242738E+01, 0.1895859444807910E+01, 0.5151050664063701E-02, 0.5683514322519618E-02, 0.1850183739337442E+01, 0.1707938528340212E+01, 0.5355619565040129E-01, 0.1473962616612956E+00, 0.6376399585071952E+00, 0.6722612990066530E+00, 0.1625577000116482E-01, 0.1893485515094503E-01, 0.5694667028868834E+00, 0.5474205335300870E+00, 0.3751307094084999E-01, 0.3830193935796279E-01, 0.5324276180991995E+00, 0.5577379417840483E+00, 0.1454944326918194E-01, 0.1220274725600271E-01, 0.6422786106287314E+00, 0.6348181488942451E+00, 0.9587988848101409E-02, 0.2200990500366971E-01, 0.2787543806623621E+00, 0.2797904014149808E+00, 0.7620352256320365E-02, 0.8551968095484232E-02, 0.2407676854354167E+00, 0.2483880376917308E+00, 0.4837392336267432E-28, 0.7747561140265878E-14}, + tauOut: 0.19361025134591583, + ttypeOut: -8, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1962357708185669E+01, 0.1768747456839757E+01, 0.3452895805257589E-14, 0.1811424766142649E-14, 0.9279031656538340E+00, 0.8183881849761209E+00, 0.8409527066820451E-01, 0.9640366690596863E-01, 0.9381695469594078E+00, 0.7024714999296202E+00, 0.5431587122209677E-01, 0.1134045480653624E+00, 0.1466670076091998E+01, 0.1168847392254101E+01, 0.9192115573380727E-02, 0.1048255904531585E-01, 0.1332937092278178E+01, 0.1145899255774637E+01, 0.1705497388769041E-01, 0.2804774784346500E-01, 0.1884487985242738E+01, 0.1667981036717421E+01, 0.5151050664063701E-02, 0.5713728135608638E-02, 0.1850183739337442E+01, 0.1704415955506319E+01, 0.5355619565040129E-01, 0.2003593680404179E-01, 0.6376399585071952E+00, 0.4402495403584025E+00, 0.1625577000116482E-01, 0.2102698332839761E-01, 0.5694667028868834E+00, 0.3923425391534199E+00, 0.3751307094084999E-01, 0.5090703407211448E-01, 0.5324276180991995E+00, 0.3024597759503511E+00, 0.1454944326918194E-01, 0.3089599659653809E-01, 0.6422786106287314E+00, 0.4273603515343789E+00, 0.9587988848101409E-02, 0.6253958476854957E-02, 0.2787543806623621E+00, 0.8651052309591171E-01, 0.7620352256320365E-02, 0.2120822426333837E-01, 0.2407676854354167E+00, 0.2594920982616250E-01, 0.4837392336267432E-28, 0.1811424766142649E-14, 0.5186198053161721E+00}, + i0: 1, + n0: 13, + pp: 1, + n0in: 13, + dmin: 2.5949209826162500E-002, + dmin1: 7.8890170839591350E-002, + dmin2: 0.28791033268116917, + dn: 2.5949209826162500E-002, + dn1: 7.8890170839591350E-002, + dn2: 0.41777236268627749, + tau: 0.19361025134591583, + ttype: -8, + g: 0.0000000000000000, + zOut: []float64{0.1962357708185669E+01, 0.1768747456839757E+01, 0.3452895805257589E-14, 0.1811424766142649E-14, 0.9279031656538340E+00, 0.8183881849761209E+00, 0.8409527066820451E-01, 0.9640366690596863E-01, 0.9381695469594078E+00, 0.7024714999296202E+00, 0.5431587122209677E-01, 0.1134045480653624E+00, 0.1466670076091998E+01, 0.1168847392254101E+01, 0.9192115573380727E-02, 0.1048255904531585E-01, 0.1332937092278178E+01, 0.1145899255774637E+01, 0.1705497388769041E-01, 0.2804774784346500E-01, 0.1884487985242738E+01, 0.1667981036717421E+01, 0.5151050664063701E-02, 0.5713728135608638E-02, 0.1850183739337442E+01, 0.1704415955506319E+01, 0.5355619565040129E-01, 0.2003593680404179E-01, 0.6376399585071952E+00, 0.4402495403584025E+00, 0.1625577000116482E-01, 0.2102698332839761E-01, 0.5694667028868834E+00, 0.3923425391534199E+00, 0.3751307094084999E-01, 0.5090703407211448E-01, 0.5324276180991995E+00, 0.3024597759503511E+00, 0.1454944326918194E-01, 0.3089599659653809E-01, 0.6422786106287314E+00, 0.4273603515343789E+00, 0.9587988848101409E-02, 0.6253958476854957E-02, 0.2787543806623621E+00, 0.8651052309591171E-01, 0.7620352256320365E-02, 0.2120822426333837E-01, 0.2407676854354167E+00, 0.2594920982616250E-01, 0.4837392336267432E-28, 0.1811424766142649E-14, 0.5186198053161721E+00}, + tauOut: 1.8780556192507153E-002, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1749966900647251E+01, 0.1768747456839757E+01, 0.8471295234418270E-15, 0.1811424766142649E-14, 0.8960112956895816E+00, 0.8183881849761209E+00, 0.7558032897122403E-01, 0.9640366690596863E-01, 0.7215151628312513E+00, 0.7024714999296202E+00, 0.1837142406762631E+00, 0.1134045480653624E+00, 0.9768351544306461E+00, 0.1168847392254101E+01, 0.1229681032071614E-01, 0.1048255904531585E-01, 0.1142869637104878E+01, 0.1145899255774637E+01, 0.4093477506677201E-01, 0.2804774784346500E-01, 0.1613979433593750E+01, 0.1667981036717421E+01, 0.6033886923870183E-02, 0.5713728135608638E-02, 0.1699637449193983E+01, 0.1704415955506319E+01, 0.5189819730562233E-02, 0.2003593680404179E-01, 0.4373061477637308E+00, 0.4402495403584025E+00, 0.1886499897608887E-01, 0.2102698332839761E-01, 0.4056040180569384E+00, 0.3923425391534199E+00, 0.3796148320598534E-01, 0.5090703407211448E-01, 0.2766137331483968E+00, 0.3024597759503511E+00, 0.4773343613933298E-01, 0.3089599659653809E-01, 0.3671003176793937E+00, 0.4273603515343789E+00, 0.1473802100398464E-02, 0.6253958476854957E-02, 0.8746438906634448E-01, 0.8651052309591171E-01, 0.6292122626412339E-02, 0.2120822426333837E-01, 0.8765310072430081E-03, 0.2594920982616250E-01, 0.8471295234418270E-15, 0.1811424766142649E-14}, + i0: 1, + n0: 13, + pp: 0, + n0in: 13, + dmin: 8.7653100724300811E-004, + dmin1: 6.6256164803006098E-002, + dmin2: 0.24571773655185866, + dn: 8.7653100724300811E-004, + dn1: 6.6256164803006098E-002, + dn2: 0.36084635920253871, + tau: 1.8780556192507153E-002, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1749966900647251E+01, 0.1768747456839757E+01, 0.8471295234418270E-15, 0.1811424766142649E-14, 0.8960112956895816E+00, 0.8183881849761209E+00, 0.7558032897122403E-01, 0.9640366690596863E-01, 0.7215151628312513E+00, 0.7024714999296202E+00, 0.1837142406762631E+00, 0.1134045480653624E+00, 0.9768351544306461E+00, 0.1168847392254101E+01, 0.1229681032071614E-01, 0.1048255904531585E-01, 0.1142869637104878E+01, 0.1145899255774637E+01, 0.4093477506677201E-01, 0.2804774784346500E-01, 0.1613979433593750E+01, 0.1667981036717421E+01, 0.6033886923870183E-02, 0.5713728135608638E-02, 0.1699637449193983E+01, 0.1704415955506319E+01, 0.5189819730562233E-02, 0.2003593680404179E-01, 0.4373061477637308E+00, 0.4402495403584025E+00, 0.1886499897608887E-01, 0.2102698332839761E-01, 0.4056040180569384E+00, 0.3923425391534199E+00, 0.3796148320598534E-01, 0.5090703407211448E-01, 0.2766137331483968E+00, 0.3024597759503511E+00, 0.4773343613933298E-01, 0.3089599659653809E-01, 0.3671003176793937E+00, 0.4273603515343789E+00, 0.1473802100398464E-02, 0.6253958476854957E-02, 0.8746438906634448E-01, 0.8651052309591171E-01, 0.6292122626412339E-02, 0.2120822426333837E-01, 0.8765310072430081E-03, 0.2594920982616250E-01, 0.8471295234418270E-15, 0.1811424766142649E-14}, + tauOut: 8.1622622999092049E-004, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1749966900647251E+01, 0.1749150674417261E+01, 0.8471295234418270E-15, 0.4339463906783712E-15, 0.8960112956895816E+00, 0.9707753984308143E+00, 0.7558032897122403E-01, 0.5617401661873561E-01, 0.7215151628312513E+00, 0.8482391606587878E+00, 0.1837142406762631E+00, 0.2115659556707206E+00, 0.9768351544306461E+00, 0.7767497828506508E+00, 0.1229681032071614E-01, 0.1809289356632693E-01, 0.1142869637104878E+01, 0.1164895292375332E+01, 0.4093477506677201E-01, 0.5671572845129930E-01, 0.1613979433593750E+01, 0.1562481365836330E+01, 0.6033886923870183E-02, 0.6563547191183529E-02, 0.1699637449193983E+01, 0.1697447495503371E+01, 0.5189819730562233E-02, 0.1337031089310571E-02, 0.4373061477637308E+00, 0.4540178894205181E+00, 0.1886499897608887E-01, 0.1685334336738995E-01, 0.4056040180569384E+00, 0.4258959316655428E+00, 0.3796148320598534E-01, 0.2465547755855056E-01, 0.2766137331483968E+00, 0.2988754654991882E+00, 0.4773343613933298E-01, 0.5862963539483231E-01, 0.3671003176793937E+00, 0.3091282581549689E+00, 0.1473802100398464E-02, 0.4169958485368410E-03, 0.8746438906634448E-01, 0.9252328961422907E-01, 0.6292122626412339E-02, 0.5960921413863723E-04, 0.8765310072430081E-03, 0.6955631134505013E-06, 0.8471295234418270E-15, 0.4339463906783712E-15, 0.5186198053161721E+00}, + i0: 1, + n0: 13, + pp: 1, + n0in: 13, + dmin: 6.9556311345050133E-007, + dmin1: 8.6231166987816729E-002, + dmin2: 0.25114202935985525, + dn: 6.9556311345050133E-007, + dn1: 8.6231166987816729E-002, + dn2: 0.30765445605457048, + tau: 8.1622622999092049E-004, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1749966900647251E+01, 0.1749150674417261E+01, 0.8471295234418270E-15, 0.4339463906783712E-15, 0.8960112956895816E+00, 0.9707753984308143E+00, 0.7558032897122403E-01, 0.5617401661873561E-01, 0.7215151628312513E+00, 0.8482391606587878E+00, 0.1837142406762631E+00, 0.2115659556707206E+00, 0.9768351544306461E+00, 0.7767497828506508E+00, 0.1229681032071614E-01, 0.1809289356632693E-01, 0.1142869637104878E+01, 0.1164895292375332E+01, 0.4093477506677201E-01, 0.5671572845129930E-01, 0.1613979433593750E+01, 0.1562481365836330E+01, 0.6033886923870183E-02, 0.6563547191183529E-02, 0.1699637449193983E+01, 0.1697447495503371E+01, 0.5189819730562233E-02, 0.1337031089310571E-02, 0.4373061477637308E+00, 0.4540178894205181E+00, 0.1886499897608887E-01, 0.1685334336738995E-01, 0.4056040180569384E+00, 0.4258959316655428E+00, 0.3796148320598534E-01, 0.2465547755855056E-01, 0.2766137331483968E+00, 0.2988754654991882E+00, 0.4773343613933298E-01, 0.5862963539483231E-01, 0.3671003176793937E+00, 0.3091282581549689E+00, 0.1473802100398464E-02, 0.4169958485368410E-03, 0.8746438906634448E-01, 0.9252328961422907E-01, 0.6292122626412339E-02, 0.5960921413863723E-04, 0.8765310072430081E-03, 0.6955631134505013E-06, 0.8471295234418270E-15, 0.4339463906783712E-15, 0.5186198053161721E+00}, + tauOut: 6.9511331676175615E-007, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1749149979303945E+01, 0.1749150674417261E+01, 0.2408395422307052E-15, 0.4339463906783712E-15, 0.1026948719936233E+01, 0.9707753984308143E+00, 0.4639861736277134E-01, 0.5617401661873561E-01, 0.1013405803853420E+01, 0.8482391606587878E+00, 0.1621599259654447E+00, 0.2115659556707206E+00, 0.6326820553382161E+00, 0.7767497828506508E+00, 0.3331266686486833E-01, 0.1809289356632693E-01, 0.1188297658848447E+01, 0.1164895292375332E+01, 0.7457497555020480E-01, 0.5671572845129930E-01, 0.1494469242363992E+01, 0.1562481365836330E+01, 0.7455005714048079E-02, 0.6563547191183529E-02, 0.1691328825765317E+01, 0.1697447495503371E+01, 0.3589107121045615E-03, 0.1337031089310571E-02, 0.4705116269624868E+00, 0.4540178894205181E+00, 0.1525524548983380E-01, 0.1685334336738995E-01, 0.4352954686209429E+00, 0.4258959316655428E+00, 0.1692854133253905E-01, 0.2465547755855056E-01, 0.3405758644481647E+00, 0.2988754654991882E+00, 0.5321597610926388E-01, 0.5862963539483231E-01, 0.2563285827809251E+00, 0.3091282581549689E+00, 0.1505170716567330E-03, 0.4169958485368410E-03, 0.9243168664339420E-01, 0.9252328961422907E-01, 0.4485687980202113E-09, 0.5960921413863723E-04, 0.1227890724922389E-11, 0.6955631134505013E-06, 0.2408395422307052E-15, 0.4339463906783712E-15}, + i0: 1, + n0: 13, + pp: 0, + n0in: 13, + dmin: 1.2278907249223888E-012, + dmin1: 9.2372077429255559E-002, + dmin2: 0.25591158693238830, + dn: 1.2278907249223888E-012, + dn1: 9.2372077429255559E-002, + dn2: 0.25591158693238830, + tau: 6.9511331676175615E-007, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1749149979303945E+01, 0.1749150674417261E+01, 0.2408395422307052E-15, 0.4339463906783712E-15, 0.1026948719936233E+01, 0.9707753984308143E+00, 0.4639861736277134E-01, 0.5617401661873561E-01, 0.1013405803853420E+01, 0.8482391606587878E+00, 0.1621599259654447E+00, 0.2115659556707206E+00, 0.6326820553382161E+00, 0.7767497828506508E+00, 0.3331266686486833E-01, 0.1809289356632693E-01, 0.1188297658848447E+01, 0.1164895292375332E+01, 0.7457497555020480E-01, 0.5671572845129930E-01, 0.1494469242363992E+01, 0.1562481365836330E+01, 0.7455005714048079E-02, 0.6563547191183529E-02, 0.1691328825765317E+01, 0.1697447495503371E+01, 0.3589107121045615E-03, 0.1337031089310571E-02, 0.4705116269624868E+00, 0.4540178894205181E+00, 0.1525524548983380E-01, 0.1685334336738995E-01, 0.4352954686209429E+00, 0.4258959316655428E+00, 0.1692854133253905E-01, 0.2465547755855056E-01, 0.3405758644481647E+00, 0.2988754654991882E+00, 0.5321597610926388E-01, 0.5862963539483231E-01, 0.2563285827809251E+00, 0.3091282581549689E+00, 0.1505170716567330E-03, 0.4169958485368410E-03, 0.9243168664339420E-01, 0.9252328961422907E-01, 0.4485687980202113E-09, 0.5960921413863723E-04, 0.1227890724922389E-11, 0.6955631134505013E-06, 0.2408395422307052E-15, 0.4339463906783712E-15}, + tauOut: 1.2278907189544363E-012, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1749149979303945E+01, 0.1749149979302717E+01, 0.2408395422307052E-15, 0.1414000300319855E-15, 0.1026948719936233E+01, 0.1073347337297776E+01, 0.4639861736277134E-01, 0.4380746706334982E-01, 0.1013405803853420E+01, 0.1131758262754287E+01, 0.1621599259654447E+00, 0.9065158049178278E-01, 0.6326820553382161E+00, 0.5753431417100738E+00, 0.3331266686486833E-01, 0.6880305191066147E-01, 0.1188297658848447E+01, 0.1194069582486762E+01, 0.7457497555020480E-01, 0.9333627524262254E-01, 0.1494469242363992E+01, 0.1408587972834190E+01, 0.7455005714048079E-02, 0.8951422490882578E-02, 0.1691328825765317E+01, 0.1682736313985311E+01, 0.3589107121045615E-03, 0.1003553923945662E-03, 0.4705116269624868E+00, 0.4856665170586981E+00, 0.1525524548983380E-01, 0.1367304312976171E-01, 0.4352954686209429E+00, 0.4385509668224923E+00, 0.1692854133253905E-01, 0.1314659648329904E-01, 0.3405758644481647E+00, 0.3806452440729016E+00, 0.5321597610926388E-01, 0.3583592846566260E-01, 0.2563285827809251E+00, 0.2206431713856914E+00, 0.1505170716567330E-03, 0.6305450884558253E-04, 0.9243168664339420E-01, 0.9236863258188953E-01, 0.4485687980202113E-09, 0.5962992535266723E-20, 0.1227890724922389E-11, 0.4959852501050381E-23, 0.2408395422307052E-15, 0.1414000300319855E-15, 0.5186198053161721E+00}, + i0: 1, + n0: 13, + pp: 1, + n0in: 13, + dmin: 4.9598525010503808E-024, + dmin1: 9.2368632133320736E-002, + dmin2: 0.22049265431403467, + dn: 4.9598525010503808E-024, + dn1: 9.2368632133320736E-002, + dn2: 0.22049265431403467, + tau: 1.2278907189544363E-012, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1749149979303945E+01, 0.1749149979302717E+01, 0.2408395422307052E-15, 0.1414000300319855E-15, 0.1026948719936233E+01, 0.1073347337297776E+01, 0.4639861736277134E-01, 0.4380746706334982E-01, 0.1013405803853420E+01, 0.1131758262754287E+01, 0.1621599259654447E+00, 0.9065158049178278E-01, 0.6326820553382161E+00, 0.5753431417100738E+00, 0.3331266686486833E-01, 0.6880305191066147E-01, 0.1188297658848447E+01, 0.1194069582486762E+01, 0.7457497555020480E-01, 0.9333627524262254E-01, 0.1494469242363992E+01, 0.1408587972834190E+01, 0.7455005714048079E-02, 0.8951422490882578E-02, 0.1691328825765317E+01, 0.1682736313985311E+01, 0.3589107121045615E-03, 0.1003553923945662E-03, 0.4705116269624868E+00, 0.4856665170586981E+00, 0.1525524548983380E-01, 0.1367304312976171E-01, 0.4352954686209429E+00, 0.4385509668224923E+00, 0.1692854133253905E-01, 0.1314659648329904E-01, 0.3405758644481647E+00, 0.3806452440729016E+00, 0.5321597610926388E-01, 0.3583592846566260E-01, 0.2563285827809251E+00, 0.2206431713856914E+00, 0.1505170716567330E-03, 0.6305450884558253E-04, 0.9243168664339420E-01, 0.9236863258188953E-01, 0.4485687980202113E-09, 0.5962992535266723E-20, 0.1227890724922389E-11, 0.4959852501050381E-23, 0.2408395422307052E-15, 0.1414000300319855E-15, 0.5186198053161721E+00}, + tauOut: 4.9598525010503808E-024, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1749149979302717E+01, 0.1749149979302717E+01, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.1117154804361126E+01, 0.1073347337297776E+01, 0.4438011869593646E-01, 0.4380746706334982E-01, 0.1178029724550133E+01, 0.1131758262754287E+01, 0.4427372589519608E-01, 0.9065158049178278E-01, 0.5998724677255393E+00, 0.5753431417100738E+00, 0.1369551627869799E+00, 0.6880305191066147E-01, 0.1150450694942405E+01, 0.1194069582486762E+01, 0.1142789997988411E+00, 0.9333627524262254E-01, 0.1303260395526232E+01, 0.1408587972834190E+01, 0.1155784656615063E-01, 0.8951422490882578E-02, 0.1671278822811555E+01, 0.1682736313985311E+01, 0.2916285016424428E-04, 0.1003553923945662E-03, 0.4993103973382956E+00, 0.4856665170586981E+00, 0.1200921574220688E-01, 0.1367304312976171E-01, 0.4396883475635844E+00, 0.4385509668224923E+00, 0.1138121911768345E-01, 0.1314659648329904E-01, 0.4050999534208807E+00, 0.3806452440729016E+00, 0.1951852336551518E-01, 0.3583592846566260E-01, 0.2011877025290218E+00, 0.2206431713856914E+00, 0.2894937755625969E-04, 0.6305450884558253E-04, 0.9233968320433328E-01, 0.9236863258188953E-01, 0.3202909346606844E-42, 0.5962992535266723E-20}, + i0: 1, + n0: 12, + pp: 0, + n0in: 13, + dmin: 4.9598525010503808E-024, + dmin1: 9.2339683204333278E-002, + dmin2: 0.20112464802017624, + dn: 4.9598525010503808E-024, + dn1: 9.2339683204333278E-002, + dn2: 0.20112464802017624, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1749149979302717E+01, 0.1749149979302717E+01, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.1117154804361126E+01, 0.1073347337297776E+01, 0.4438011869593646E-01, 0.4380746706334982E-01, 0.1178029724550133E+01, 0.1131758262754287E+01, 0.4427372589519608E-01, 0.9065158049178278E-01, 0.5998724677255393E+00, 0.5753431417100738E+00, 0.1369551627869799E+00, 0.6880305191066147E-01, 0.1150450694942405E+01, 0.1194069582486762E+01, 0.1142789997988411E+00, 0.9333627524262254E-01, 0.1303260395526232E+01, 0.1408587972834190E+01, 0.1155784656615063E-01, 0.8951422490882578E-02, 0.1671278822811555E+01, 0.1682736313985311E+01, 0.2916285016424428E-04, 0.1003553923945662E-03, 0.4993103973382956E+00, 0.4856665170586981E+00, 0.1200921574220688E-01, 0.1367304312976171E-01, 0.4396883475635844E+00, 0.4385509668224923E+00, 0.1138121911768345E-01, 0.1314659648329904E-01, 0.4050999534208807E+00, 0.3806452440729016E+00, 0.1951852336551518E-01, 0.3583592846566260E-01, 0.2011877025290218E+00, 0.2206431713856914E+00, 0.2894937755625969E-04, 0.6305450884558253E-04, 0.9233968320433328E-01, 0.9236863258188953E-01, 0.3202909346606844E-42, 0.5962992535266723E-20}, + tauOut: 9.2159326345418235E-002, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1749149979302717E+01, 0.1656990652957299E+01, 0.8676862906242004E-16, 0.5850002270797901E-16, 0.1117154804361126E+01, 0.1069375596711644E+01, 0.4438011869593646E-01, 0.4888936980013561E-01, 0.1178029724550133E+01, 0.1081254754299776E+01, 0.4427372589519608E-01, 0.2456274906772994E-01, 0.5998724677255393E+00, 0.6201055550993710E+00, 0.1369551627869799E+00, 0.2540860356894923E+00, 0.1150450694942405E+01, 0.9184843327063353E+00, 0.1142789997988411E+00, 0.1621533314992303E+00, 0.1303260395526232E+01, 0.1060505584247734E+01, 0.1155784656615063E-01, 0.1821431635083262E-01, 0.1671278822811555E+01, 0.1560934342965469E+01, 0.2916285016424428E-04, 0.9328588590960435E-05, 0.4993103973382956E+00, 0.4191509581464933E+00, 0.1200921574220688E-01, 0.1259763844648080E-01, 0.4396883475635844E+00, 0.3463126018893689E+00, 0.1138121911768345E-01, 0.1331320693873929E-01, 0.4050999534208807E+00, 0.3191459435022383E+00, 0.1951852336551518E-01, 0.1230436091267282E-01, 0.2011877025290218E+00, 0.9675296464848704E-01, 0.2894937755625969E-04, 0.2762888312745317E-04, 0.9233968320433328E-01, 0.1527279757875810E-03, 0.3202909346606844E-42, 0.5850002270797901E-16, 0.7318275341991307E+00}, + i0: 1, + n0: 12, + pp: 1, + n0in: 12, + dmin: 1.5272797578758102E-004, + dmin1: 9.6724015270930774E-002, + dmin2: 0.29962742013672317, + dn: 1.5272797578758102E-004, + dn1: 9.6724015270930774E-002, + dn2: 0.29962742013672317, + tau: 9.2159326345418235E-002, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.1749149979302717E+01, 0.1656990652957299E+01, 0.8676862906242004E-16, 0.5850002270797901E-16, 0.1117154804361126E+01, 0.1069375596711644E+01, 0.4438011869593646E-01, 0.4888936980013561E-01, 0.1178029724550133E+01, 0.1081254754299776E+01, 0.4427372589519608E-01, 0.2456274906772994E-01, 0.5998724677255393E+00, 0.6201055550993710E+00, 0.1369551627869799E+00, 0.2540860356894923E+00, 0.1150450694942405E+01, 0.9184843327063353E+00, 0.1142789997988411E+00, 0.1621533314992303E+00, 0.1303260395526232E+01, 0.1060505584247734E+01, 0.1155784656615063E-01, 0.1821431635083262E-01, 0.1671278822811555E+01, 0.1560934342965469E+01, 0.2916285016424428E-04, 0.9328588590960435E-05, 0.4993103973382956E+00, 0.4191509581464933E+00, 0.1200921574220688E-01, 0.1259763844648080E-01, 0.4396883475635844E+00, 0.3463126018893689E+00, 0.1138121911768345E-01, 0.1331320693873929E-01, 0.4050999534208807E+00, 0.3191459435022383E+00, 0.1951852336551518E-01, 0.1230436091267282E-01, 0.2011877025290218E+00, 0.9675296464848704E-01, 0.2894937755625969E-04, 0.2762888312745317E-04, 0.9233968320433328E-01, 0.1527279757875810E-03, 0.3202909346606844E-42, 0.5850002270797901E-16, 0.7318275341991307E+00}, + tauOut: 1.5267965277267402E-004, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1656837973304527E+01, 0.1656990652957299E+01, 0.3775776370348287E-16, 0.5850002270797901E-16, 0.1118112286859007E+01, 0.1069375596711644E+01, 0.4727777715386321E-01, 0.4888936980013561E-01, 0.1058387046560870E+01, 0.1081254754299776E+01, 0.1439123541326830E-01, 0.2456274906772994E-01, 0.8596476757228223E+00, 0.6201055550993710E+00, 0.2714763844897646E+00, 0.2540860356894923E+00, 0.8090086000630283E+00, 0.9184843327063353E+00, 0.2125620340079330E+00, 0.1621533314992303E+00, 0.8660051869378607E+00, 0.1060505584247734E+01, 0.3283046378299830E-01, 0.1821431635083262E-01, 0.1527960528118289E+01, 0.1560934342965469E+01, 0.2559023465659061E-05, 0.9328588590960435E-05, 0.4315933579167358E+00, 0.4191509581464933E+00, 0.1010840613748274E-01, 0.1259763844648080E-01, 0.3493647230378528E+00, 0.3463126018893689E+00, 0.1216166289646864E-01, 0.1331320693873929E-01, 0.3191359618656699E+00, 0.3191459435022383E+00, 0.3730332957296599E-02, 0.1230436091267282E-01, 0.9289758092154521E-01, 0.9675296464848704E-01, 0.4542317842367971E-07, 0.2762888312745317E-04, 0.2899836483324881E-08, 0.1527279757875810E-03, 0.3775776370348287E-16, 0.5850002270797901E-16}, + i0: 1, + n0: 12, + pp: 0, + n0in: 12, + dmin: 2.8998364833248812E-009, + dmin1: 9.2869952038417761E-002, + dmin2: 0.30683160095299705, + dn: 2.8998364833248812E-009, + dn1: 9.2869952038417761E-002, + dn2: 0.30683160095299705, + tau: 1.5267965277267402E-004, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1656837973304527E+01, 0.1656990652957299E+01, 0.3775776370348287E-16, 0.5850002270797901E-16, 0.1118112286859007E+01, 0.1069375596711644E+01, 0.4727777715386321E-01, 0.4888936980013561E-01, 0.1058387046560870E+01, 0.1081254754299776E+01, 0.1439123541326830E-01, 0.2456274906772994E-01, 0.8596476757228223E+00, 0.6201055550993710E+00, 0.2714763844897646E+00, 0.2540860356894923E+00, 0.8090086000630283E+00, 0.9184843327063353E+00, 0.2125620340079330E+00, 0.1621533314992303E+00, 0.8660051869378607E+00, 0.1060505584247734E+01, 0.3283046378299830E-01, 0.1821431635083262E-01, 0.1527960528118289E+01, 0.1560934342965469E+01, 0.2559023465659061E-05, 0.9328588590960435E-05, 0.4315933579167358E+00, 0.4191509581464933E+00, 0.1010840613748274E-01, 0.1259763844648080E-01, 0.3493647230378528E+00, 0.3463126018893689E+00, 0.1216166289646864E-01, 0.1331320693873929E-01, 0.3191359618656699E+00, 0.3191459435022383E+00, 0.3730332957296599E-02, 0.1230436091267282E-01, 0.9289758092154521E-01, 0.9675296464848704E-01, 0.4542317842367971E-07, 0.2762888312745317E-04, 0.2899836483324881E-08, 0.1527279757875810E-03, 0.3775776370348287E-16, 0.5850002270797901E-16}, + tauOut: 2.8998350258011044E-009, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1656837973304527E+01, 0.1656837970404692E+01, 0.3775776370348287E-16, 0.2548071704976161E-16, 0.1118112286859007E+01, 0.1165390061113035E+01, 0.4727777715386321E-01, 0.4293685745187325E-01, 0.1058387046560870E+01, 0.1029841421622430E+01, 0.1439123541326830E-01, 0.1201290976848257E-01, 0.8596476757228223E+00, 0.1119111147544269E+01, 0.2714763844897646E+00, 0.1962510428460807E+00, 0.8090086000630283E+00, 0.8253195883250457E+00, 0.2125620340079330E+00, 0.2230406579474441E+00, 0.8660051869378607E+00, 0.6757949898735797E+00, 0.3283046378299830E-01, 0.7422909836846008E-01, 0.1527960528118289E+01, 0.1453733985873459E+01, 0.2559023465659061E-05, 0.7597383986781573E-06, 0.4315933579167358E+00, 0.4417010014159849E+00, 0.1010840613748274E-01, 0.7995273950601426E-02, 0.3493647230378528E+00, 0.3535311090838850E+00, 0.1216166289646864E-01, 0.1097845108004235E-01, 0.3191359618656699E+00, 0.3118878408430891E+00, 0.3730332957296599E-02, 0.1111101051031713E-02, 0.9289758092154521E-01, 0.9178652239385691E-01, 0.4542317842367971E-07, 0.1435066789177947E-14, 0.2899836483324881E-08, 0.2245698748385924E-16, 0.3775776370348287E-16, 0.2548071704976161E-16, 0.7318275341991307E+00}, + i0: 1, + n0: 12, + pp: 1, + n0in: 12, + dmin: 2.2456987483859239E-017, + dmin1: 9.1786476970678488E-002, + dmin2: 0.30815750788579249, + dn: 2.2456987483859239E-017, + dn1: 9.1786476970678488E-002, + dn2: 0.30815750788579249, + tau: 2.8998350258011044E-009, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1656837973304527E+01, 0.1656837970404692E+01, 0.3775776370348287E-16, 0.2548071704976161E-16, 0.1118112286859007E+01, 0.1165390061113035E+01, 0.4727777715386321E-01, 0.4293685745187325E-01, 0.1058387046560870E+01, 0.1029841421622430E+01, 0.1439123541326830E-01, 0.1201290976848257E-01, 0.8596476757228223E+00, 0.1119111147544269E+01, 0.2714763844897646E+00, 0.1962510428460807E+00, 0.8090086000630283E+00, 0.8253195883250457E+00, 0.2125620340079330E+00, 0.2230406579474441E+00, 0.8660051869378607E+00, 0.6757949898735797E+00, 0.3283046378299830E-01, 0.7422909836846008E-01, 0.1527960528118289E+01, 0.1453733985873459E+01, 0.2559023465659061E-05, 0.7597383986781573E-06, 0.4315933579167358E+00, 0.4417010014159849E+00, 0.1010840613748274E-01, 0.7995273950601426E-02, 0.3493647230378528E+00, 0.3535311090838850E+00, 0.1216166289646864E-01, 0.1097845108004235E-01, 0.3191359618656699E+00, 0.3118878408430891E+00, 0.3730332957296599E-02, 0.1111101051031713E-02, 0.9289758092154521E-01, 0.9178652239385691E-01, 0.4542317842367971E-07, 0.1435066789177947E-14, 0.2899836483324881E-08, 0.2245698748385924E-16, 0.3775776370348287E-16, 0.2548071704976161E-16, 0.7318275341991307E+00}, + tauOut: 2.2456987483858885E-017, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1656837970404692E+01, 0.1656837970404692E+01, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.1208326918564908E+01, 0.1165390061113035E+01, 0.3659452888027460E-01, 0.4293685745187325E-01, 0.1005259802510638E+01, 0.1029841421622430E+01, 0.1337343958524596E-01, 0.1201290976848257E-01, 0.1301988750805104E+01, 0.1119111147544269E+01, 0.1244018658302015E+00, 0.1962510428460807E+00, 0.9239583804422884E+00, 0.8253195883250457E+00, 0.1631347930486186E+00, 0.2230406579474441E+00, 0.5868892951934211E+00, 0.6757949898735797E+00, 0.1838666404767374E+00, 0.7422909836846008E-01, 0.1269868105135121E+01, 0.1453733985873459E+01, 0.2642614694812039E-06, 0.7597383986781573E-06, 0.4496960111051168E+00, 0.4417010014159849E+00, 0.6285530663790794E-02, 0.7995273950601426E-02, 0.3582240295001366E+00, 0.3535311090838850E+00, 0.9558391177537082E-02, 0.1097845108004235E-01, 0.3034405507165837E+00, 0.3118878408430891E+00, 0.3360925270585024E-03, 0.1111101051031713E-02, 0.9145042986679984E-01, 0.9178652239385691E-01, 0.3524015903480299E-30, 0.1435066789177947E-14}, + i0: 1, + n0: 11, + pp: 0, + n0in: 12, + dmin: 2.2456987483858888E-017, + dmin1: 9.1450429866798411E-002, + dmin2: 0.30232944966555197, + dn: 2.2456987483858888E-017, + dn1: 9.1450429866798411E-002, + dn2: 0.30232944966555197, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1656837970404692E+01, 0.1656837970404692E+01, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.1208326918564908E+01, 0.1165390061113035E+01, 0.3659452888027460E-01, 0.4293685745187325E-01, 0.1005259802510638E+01, 0.1029841421622430E+01, 0.1337343958524596E-01, 0.1201290976848257E-01, 0.1301988750805104E+01, 0.1119111147544269E+01, 0.1244018658302015E+00, 0.1962510428460807E+00, 0.9239583804422884E+00, 0.8253195883250457E+00, 0.1631347930486186E+00, 0.2230406579474441E+00, 0.5868892951934211E+00, 0.6757949898735797E+00, 0.1838666404767374E+00, 0.7422909836846008E-01, 0.1269868105135121E+01, 0.1453733985873459E+01, 0.2642614694812039E-06, 0.7597383986781573E-06, 0.4496960111051168E+00, 0.4417010014159849E+00, 0.6285530663790794E-02, 0.7995273950601426E-02, 0.3582240295001366E+00, 0.3535311090838850E+00, 0.9558391177537082E-02, 0.1097845108004235E-01, 0.3034405507165837E+00, 0.3118878408430891E+00, 0.3360925270585024E-03, 0.1111101051031713E-02, 0.9145042986679984E-01, 0.9178652239385691E-01, 0.3524015903480299E-30, 0.1435066789177947E-14}, + tauOut: 9.1173077708044642E-002, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1656837970404692E+01, 0.1565664892696647E+01, 0.1792267857826344E-16, 0.1383211380667930E-16, 0.1208326918564908E+01, 0.1153748369737138E+01, 0.3659452888027460E-01, 0.3188477647299814E-01, 0.1005259802510638E+01, 0.8955753879148407E+00, 0.1337343958524596E-01, 0.1944232516271161E-01, 0.1301988750805104E+01, 0.1315775213764550E+01, 0.1244018658302015E+00, 0.8735697805677015E-01, 0.9239583804422884E+00, 0.9085631177260922E+00, 0.1631347930486186E+00, 0.1053774491236745E+00, 0.5868892951934211E+00, 0.5742054088384394E+00, 0.1838666404767374E+00, 0.4066251880351924E+00, 0.1269868105135121E+01, 0.7720701036533529E+00, 0.2642614694812039E-06, 0.1539203864417861E-06, 0.4496960111051168E+00, 0.3648083101404764E+00, 0.6285530663790794E-02, 0.6172085611379779E-02, 0.3582240295001366E+00, 0.2704372573582493E+00, 0.9558391177537082E-02, 0.1072486650400470E-01, 0.3034405507165837E+00, 0.2018786990315928E+00, 0.3360925270585024E-03, 0.1522488812438262E-03, 0.9145042986679984E-01, 0.1251032775113764E-03, 0.3524015903480299E-30, 0.1383211380667930E-16, 0.8241395430971566E+00}, + i0: 1, + n0: 11, + pp: 1, + n0in: 11, + dmin: 1.2510327751137640E-004, + dmin1: 0.20154260650453434, + dmin2: 0.26087886618071221, + dn: 1.2510327751137640E-004, + dn1: 0.20154260650453434, + dn2: 0.26087886618071221, + tau: 9.1173077708044642E-002, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.1656837970404692E+01, 0.1565664892696647E+01, 0.1792267857826344E-16, 0.1383211380667930E-16, 0.1208326918564908E+01, 0.1153748369737138E+01, 0.3659452888027460E-01, 0.3188477647299814E-01, 0.1005259802510638E+01, 0.8955753879148407E+00, 0.1337343958524596E-01, 0.1944232516271161E-01, 0.1301988750805104E+01, 0.1315775213764550E+01, 0.1244018658302015E+00, 0.8735697805677015E-01, 0.9239583804422884E+00, 0.9085631177260922E+00, 0.1631347930486186E+00, 0.1053774491236745E+00, 0.5868892951934211E+00, 0.5742054088384394E+00, 0.1838666404767374E+00, 0.4066251880351924E+00, 0.1269868105135121E+01, 0.7720701036533529E+00, 0.2642614694812039E-06, 0.1539203864417861E-06, 0.4496960111051168E+00, 0.3648083101404764E+00, 0.6285530663790794E-02, 0.6172085611379779E-02, 0.3582240295001366E+00, 0.2704372573582493E+00, 0.9558391177537082E-02, 0.1072486650400470E-01, 0.3034405507165837E+00, 0.2018786990315928E+00, 0.3360925270585024E-03, 0.1522488812438262E-03, 0.9145042986679984E-01, 0.1251032775113764E-03, 0.3524015903480299E-30, 0.1383211380667930E-16, 0.8241395430971566E+00}, + tauOut: 1.2498058228587147E-004, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1565539912114361E+01, 0.1565664892696647E+01, 0.1019378594629470E-16, 0.1383211380667930E-16, 0.1185508165627851E+01, 0.1153748369737138E+01, 0.2408690373149840E-01, 0.3188477647299814E-01, 0.8908058287637680E+00, 0.8955753879148407E+00, 0.2871751477260568E-01, 0.1944232516271161E-01, 0.1374289696466428E+01, 0.1315775213764550E+01, 0.5775298217141787E-01, 0.8735697805677015E-01, 0.9560626040960629E+00, 0.9085631177260922E+00, 0.6328905763825028E-01, 0.1053774491236745E+00, 0.9174165586530958E+00, 0.5742054088384394E+00, 0.3422034931823232E+00, 0.4066251880351924E+00, 0.4297417838091302E+00, 0.7720701036533529E+00, 0.1306631986684747E-06, 0.1539203864417861E-06, 0.3708552845063717E+00, 0.3648083101404764E+00, 0.4500844331080801E-02, 0.6172085611379779E-02, 0.2765362989488873E+00, 0.2704372573582493E+00, 0.7829431815445537E-02, 0.1072486650400470E-01, 0.1940765355151052E+00, 0.2018786990315928E+00, 0.9814083907923291E-07, 0.1522488812438262E-03, 0.2455438642568072E-07, 0.1251032775113764E-03, 0.1019378594629470E-16, 0.1383211380667930E-16}, + i0: 1, + n0: 11, + pp: 0, + n0in: 11, + dmin: 2.4554386425680716E-008, + dmin1: 0.19392428663386141, + dmin2: 0.26581143244488259, + dn: 2.4554386425680716E-008, + dn1: 0.19392428663386141, + dn2: 0.26581143244488259, + tau: 1.2498058228587147E-004, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1565539912114361E+01, 0.1565664892696647E+01, 0.1019378594629470E-16, 0.1383211380667930E-16, 0.1185508165627851E+01, 0.1153748369737138E+01, 0.2408690373149840E-01, 0.3188477647299814E-01, 0.8908058287637680E+00, 0.8955753879148407E+00, 0.2871751477260568E-01, 0.1944232516271161E-01, 0.1374289696466428E+01, 0.1315775213764550E+01, 0.5775298217141787E-01, 0.8735697805677015E-01, 0.9560626040960629E+00, 0.9085631177260922E+00, 0.6328905763825028E-01, 0.1053774491236745E+00, 0.9174165586530958E+00, 0.5742054088384394E+00, 0.3422034931823232E+00, 0.4066251880351924E+00, 0.4297417838091302E+00, 0.7720701036533529E+00, 0.1306631986684747E-06, 0.1539203864417861E-06, 0.3708552845063717E+00, 0.3648083101404764E+00, 0.4500844331080801E-02, 0.6172085611379779E-02, 0.2765362989488873E+00, 0.2704372573582493E+00, 0.7829431815445537E-02, 0.1072486650400470E-01, 0.1940765355151052E+00, 0.2018786990315928E+00, 0.9814083907923291E-07, 0.1522488812438262E-03, 0.2455438642568072E-07, 0.1251032775113764E-03, 0.1019378594629470E-16, 0.1383211380667930E-16}, + tauOut: 2.4554370888251911E-008, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1565539912114361E+01, 0.1565539887559990E+01, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.1185508165627851E+01, 0.1209595044804978E+01, 0.2408690373149840E-01, 0.1773879145177052E-01, 0.8908058287637680E+00, 0.9017845275302323E+00, 0.2871751477260568E-01, 0.4376453959373496E-01, 0.1374289696466428E+01, 0.1388278114489740E+01, 0.5775298217141787E-01, 0.3977262621431848E-01, 0.9560626040960629E+00, 0.9795790109656241E+00, 0.6328905763825028E-01, 0.5927283946360358E-01, 0.9174165586530958E+00, 0.1200347187817445E+01, 0.3422034931823232E+00, 0.1225138368952072E+00, 0.4297417838091302E+00, 0.3072280530227507E+00, 0.1306631986684747E-06, 0.1577236754259593E-06, 0.3708552845063717E+00, 0.3753559465594062E+00, 0.4500844331080801E-02, 0.3315910790466669E-02, 0.2765362989488873E+00, 0.2810497954194954E+00, 0.7829431815445537E-02, 0.5406547261581845E-02, 0.1940765355151052E+00, 0.1886700618399915E+00, 0.9814083907923291E-07, 0.1277249852674422E-13, 0.2455438642568072E-07, 0.2764930279233778E-14, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.8241395430971566E+00}, + i0: 1, + n0: 11, + pp: 1, + n0in: 11, + dmin: 2.7649302792337775E-015, + dmin1: 0.18866996369915248, + dmin2: 0.27322036360404983, + dn: 2.7649302792337775E-015, + dn1: 0.18866996369915248, + dn2: 0.27322036360404983, + tau: 2.4554370888251911E-008, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1565539912114361E+01, 0.1565539887559990E+01, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.1185508165627851E+01, 0.1209595044804978E+01, 0.2408690373149840E-01, 0.1773879145177052E-01, 0.8908058287637680E+00, 0.9017845275302323E+00, 0.2871751477260568E-01, 0.4376453959373496E-01, 0.1374289696466428E+01, 0.1388278114489740E+01, 0.5775298217141787E-01, 0.3977262621431848E-01, 0.9560626040960629E+00, 0.9795790109656241E+00, 0.6328905763825028E-01, 0.5927283946360358E-01, 0.9174165586530958E+00, 0.1200347187817445E+01, 0.3422034931823232E+00, 0.1225138368952072E+00, 0.4297417838091302E+00, 0.3072280530227507E+00, 0.1306631986684747E-06, 0.1577236754259593E-06, 0.3708552845063717E+00, 0.3753559465594062E+00, 0.4500844331080801E-02, 0.3315910790466669E-02, 0.2765362989488873E+00, 0.2810497954194954E+00, 0.7829431815445537E-02, 0.5406547261581845E-02, 0.1940765355151052E+00, 0.1886700618399915E+00, 0.9814083907923291E-07, 0.1277249852674422E-13, 0.2455438642568072E-07, 0.2764930279233778E-14, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.8241395430971566E+00}, + tauOut: 2.7649302792335523E-015, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1565539887559988E+01, 0.1565539887559990E+01, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.1227333836256746E+01, 0.1209595044804978E+01, 0.1303359134714337E-01, 0.1773879145177052E-01, 0.9325154757768211E+00, 0.9017845275302323E+00, 0.6515425651042277E-01, 0.4376453959373496E-01, 0.1362896484193633E+01, 0.1388278114489740E+01, 0.2858649229958118E-01, 0.3977262621431848E-01, 0.1010265358129644E+01, 0.9795790109656241E+00, 0.7042504782685149E-01, 0.5927283946360358E-01, 0.1252435976885798E+01, 0.1200347187817445E+01, 0.3005318297487194E-01, 0.1225138368952072E+00, 0.2771750277715515E+00, 0.3072280530227507E+00, 0.2135925446109612E-06, 0.1577236754259593E-06, 0.3786716437573254E+00, 0.3753559465594062E+00, 0.2461066374135985E-02, 0.3315910790466669E-02, 0.2839952763069384E+00, 0.2810497954194954E+00, 0.3591797791316158E-02, 0.5406547261581845E-02, 0.1850782640486854E+00, 0.1886700618399915E+00, 0.1908115364037247E-27, 0.1277249852674422E-13}, + i0: 1, + n0: 10, + pp: 0, + n0in: 11, + dmin: 3.4709879829724519E-029, + dmin1: 0.18507826404867261, + dmin2: 0.27717487004787600, + dn: 3.4709879829724519E-029, + dn1: 0.18507826404867261, + dn2: 0.27858872904535659, + tau: 2.7649302792335523E-015, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1565539887559988E+01, 0.1565539887559990E+01, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.1227333836256746E+01, 0.1209595044804978E+01, 0.1303359134714337E-01, 0.1773879145177052E-01, 0.9325154757768211E+00, 0.9017845275302323E+00, 0.6515425651042277E-01, 0.4376453959373496E-01, 0.1362896484193633E+01, 0.1388278114489740E+01, 0.2858649229958118E-01, 0.3977262621431848E-01, 0.1010265358129644E+01, 0.9795790109656241E+00, 0.7042504782685149E-01, 0.5927283946360358E-01, 0.1252435976885798E+01, 0.1200347187817445E+01, 0.3005318297487194E-01, 0.1225138368952072E+00, 0.2771750277715515E+00, 0.3072280530227507E+00, 0.2135925446109612E-06, 0.1577236754259593E-06, 0.3786716437573254E+00, 0.3753559465594062E+00, 0.2461066374135985E-02, 0.3315910790466669E-02, 0.2839952763069384E+00, 0.2810497954194954E+00, 0.3591797791316158E-02, 0.5406547261581845E-02, 0.1850782640486854E+00, 0.1886700618399915E+00, 0.1908115364037247E-27, 0.1277249852674422E-13}, + tauOut: 9.2539132024336307E-002, + ttypeOut: -9, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1565539887559988E+01, 0.1473000755535651E+01, 0.5964194309842799E-17, 0.4969486576955697E-17, 0.1227333836256746E+01, 0.1147828295579553E+01, 0.1303359134714337E-01, 0.1058871408116432E-01, 0.9325154757768211E+00, 0.8945418861817434E+00, 0.6515425651042277E-01, 0.9926701980086396E-01, 0.1362896484193633E+01, 0.1199676824668014E+01, 0.2858649229958118E-01, 0.2407310226126826E-01, 0.1010265358129644E+01, 0.9640781716708908E+00, 0.7042504782685149E-01, 0.9148932748822959E-01, 0.1252435976885798E+01, 0.1098460700348104E+01, 0.3005318297487194E-01, 0.7583331677723075E-02, 0.2771750277715515E+00, 0.1770527776620367E+00, 0.2135925446109612E-06, 0.4568210735249311E-06, 0.3786716437573254E+00, 0.2885931212860515E+00, 0.2461066374135985E-02, 0.2421856840585221E-02, 0.2839952763069384E+00, 0.1926260852333330E+00, 0.3591797791316158E-02, 0.3451057520197492E-02, 0.1850782640486854E+00, 0.8908807450415157E-01, 0.1908115364037247E-27, 0.4969486576955697E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + n0in: 10, + dmin: 8.9088074504151571E-002, + dmin1: 0.17705256406949207, + dmin2: 0.17705256406949207, + dn: 8.9088074504151571E-002, + dn1: 0.18903428744201686, + dn2: 0.28613205491191551, + tau: 9.2539132024336307E-002, + ttype: -9, + g: 0.0000000000000000, + zOut: []float64{0.1565539887559988E+01, 0.1473000755535651E+01, 0.5964194309842799E-17, 0.4969486576955697E-17, 0.1227333836256746E+01, 0.1147828295579553E+01, 0.1303359134714337E-01, 0.1058871408116432E-01, 0.9325154757768211E+00, 0.8945418861817434E+00, 0.6515425651042277E-01, 0.9926701980086396E-01, 0.1362896484193633E+01, 0.1199676824668014E+01, 0.2858649229958118E-01, 0.2407310226126826E-01, 0.1010265358129644E+01, 0.9640781716708908E+00, 0.7042504782685149E-01, 0.9148932748822959E-01, 0.1252435976885798E+01, 0.1098460700348104E+01, 0.3005318297487194E-01, 0.7583331677723075E-02, 0.2771750277715515E+00, 0.1770527776620367E+00, 0.2135925446109612E-06, 0.4568210735249311E-06, 0.3786716437573254E+00, 0.2885931212860515E+00, 0.2461066374135985E-02, 0.2421856840585221E-02, 0.2839952763069384E+00, 0.1926260852333330E+00, 0.3591797791316158E-02, 0.3451057520197492E-02, 0.1850782640486854E+00, 0.8908807450415157E-01, 0.1908115364037247E-27, 0.4969486576955697E-17, 0.9154376259418607E+00}, + tauOut: 7.5387921832037685E-002, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1397612833703614E+01, 0.1473000755535651E+01, 0.4081328655531061E-17, 0.4969486576955697E-17, 0.1083029087828680E+01, 0.1147828295579553E+01, 0.8745885380967966E-02, 0.1058871408116432E-01, 0.9096750987696016E+00, 0.8945418861817434E+00, 0.1309130515609722E+00, 0.9926701980086396E-01, 0.1017448953536272E+01, 0.1199676824668014E+01, 0.2281033592282574E-01, 0.2407310226126826E-01, 0.9573692414042568E+00, 0.9640781716708908E+00, 0.1049724875218357E+00, 0.9148932748822959E-01, 0.9256836226719531E+00, 0.1098460700348104E+01, 0.1450441494900679E-02, 0.7583331677723075E-02, 0.1002148711561719E+00, 0.1770527776620367E+00, 0.1315527505616969E-05, 0.4568210735249311E-06, 0.2156257407670935E+00, 0.2885931212860515E+00, 0.2163530200698068E-02, 0.2421856840585221E-02, 0.1185256907207948E+00, 0.1926260852333330E+00, 0.2593936112987583E-02, 0.3451057520197492E-02, 0.1110621655912630E-01, 0.8908807450415157E-01, 0.4081328655531061E-17, 0.4969486576955697E-17}, + i0: 1, + n0: 10, + pp: 0, + n0in: 10, + dmin: 1.1106216559126303E-002, + dmin1: 0.10021441433509834, + dmin2: 0.10021441433509834, + dn: 1.1106216559126303E-002, + dn1: 0.11507463320059727, + dn2: 0.21320388392650824, + tau: 7.5387921832037685E-002, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1397612833703614E+01, 0.1473000755535651E+01, 0.4081328655531061E-17, 0.4969486576955697E-17, 0.1083029087828680E+01, 0.1147828295579553E+01, 0.8745885380967966E-02, 0.1058871408116432E-01, 0.9096750987696016E+00, 0.8945418861817434E+00, 0.1309130515609722E+00, 0.9926701980086396E-01, 0.1017448953536272E+01, 0.1199676824668014E+01, 0.2281033592282574E-01, 0.2407310226126826E-01, 0.9573692414042568E+00, 0.9640781716708908E+00, 0.1049724875218357E+00, 0.9148932748822959E-01, 0.9256836226719531E+00, 0.1098460700348104E+01, 0.1450441494900679E-02, 0.7583331677723075E-02, 0.1002148711561719E+00, 0.1770527776620367E+00, 0.1315527505616969E-05, 0.4568210735249311E-06, 0.2156257407670935E+00, 0.2885931212860515E+00, 0.2163530200698068E-02, 0.2421856840585221E-02, 0.1185256907207948E+00, 0.1926260852333330E+00, 0.2593936112987583E-02, 0.3451057520197492E-02, 0.1110621655912630E-01, 0.8908807450415157E-01, 0.4081328655531061E-17, 0.4969486576955697E-17}, + tauOut: 9.2006637361187298E-003, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1397612833703614E+01, 0.1388412169967495E+01, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.1083029087828680E+01, 0.1082574309473529E+01, 0.8745885380967966E-02, 0.7349069784991225E-02, 0.9096750987696016E+00, 0.1024038416809464E+01, 0.1309130515609722E+00, 0.1300706547025319E+00, 0.1017448953536272E+01, 0.9009879710204475E+00, 0.2281033592282574E-01, 0.2423774201322422E-01, 0.9573692414042568E+00, 0.1028903323176749E+01, 0.1049724875218357E+00, 0.9444163542020824E-01, 0.9256836226719531E+00, 0.8234917650105269E+00, 0.1450441494900679E-02, 0.1765115496075164E-03, 0.1002148711561719E+00, 0.9083901139795122E-01, 0.1315527505616969E-05, 0.3122684720284652E-05, 0.2156257407670935E+00, 0.2085854845469525E+00, 0.2163530200698068E-02, 0.1229394806594584E-02, 0.1185256907207948E+00, 0.1106895682910690E+00, 0.2593936112987583E-02, 0.2602667681892373E-03, 0.1110621655912630E-01, 0.1645286054818337E-02, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + n0in: 10, + dmin: 1.6452860548183366E-003, + dmin1: 9.0837695870445614E-002, + dmin2: 9.0837695870445614E-002, + dn: 1.6452860548183366E-003, + dn1: 0.10809563217808144, + dn2: 0.20642195434625446, + tau: 9.2006637361187298E-003, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1397612833703614E+01, 0.1388412169967495E+01, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.1083029087828680E+01, 0.1082574309473529E+01, 0.8745885380967966E-02, 0.7349069784991225E-02, 0.9096750987696016E+00, 0.1024038416809464E+01, 0.1309130515609722E+00, 0.1300706547025319E+00, 0.1017448953536272E+01, 0.9009879710204475E+00, 0.2281033592282574E-01, 0.2423774201322422E-01, 0.9573692414042568E+00, 0.1028903323176749E+01, 0.1049724875218357E+00, 0.9444163542020824E-01, 0.9256836226719531E+00, 0.8234917650105269E+00, 0.1450441494900679E-02, 0.1765115496075164E-03, 0.1002148711561719E+00, 0.9083901139795122E-01, 0.1315527505616969E-05, 0.3122684720284652E-05, 0.2156257407670935E+00, 0.2085854845469525E+00, 0.2163530200698068E-02, 0.1229394806594584E-02, 0.1185256907207948E+00, 0.1106895682910690E+00, 0.2593936112987583E-02, 0.2602667681892373E-03, 0.1110621655912630E-01, 0.1645286054818337E-02, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.9154376259418607E+00}, + tauOut: 1.5594219393746818E-003, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1386852748028120E+01, 0.1388412169967495E+01, 0.2485138759635906E-17, 0.3183635051997810E-17, 0.1088363957319145E+01, 0.1082574309473529E+01, 0.6914717946174950E-02, 0.7349069784991225E-02, 0.1145634931626446E+01, 0.1024038416809464E+01, 0.1022944500333619E+00, 0.1300706547025319E+00, 0.8213718410609353E+00, 0.9009879710204475E+00, 0.3036175828902931E-01, 0.2423774201322422E-01, 0.1091423778368554E+01, 0.1028903323176749E+01, 0.7125729765473905E-01, 0.9444163542020824E-01, 0.7508515569660207E+00, 0.8234917650105269E+00, 0.2135460001102832E-04, 0.1765115496075164E-03, 0.8926135754328580E-01, 0.9083901139795122E-01, 0.7297073710223142E-05, 0.3122684720284652E-05, 0.2082481603404622E+00, 0.2085854845469525E+00, 0.6534568189162364E-03, 0.1229394806594584E-02, 0.1087369563009673E+00, 0.1106895682910690E+00, 0.3938065757966957E-05, 0.2602667681892373E-03, 0.8192604968568760E-04, 0.1645286054818337E-02, 0.2485138759635906E-17, 0.3183635051997810E-17}, + i0: 1, + n0: 10, + pp: 0, + n0in: 10, + dmin: 8.1926049685687600E-005, + dmin1: 8.9258234858565516E-002, + dmin2: 8.9258234858565516E-002, + dn: 8.1926049685687600E-005, + dn1: 0.10847668953277810, + dn2: 0.20701876553386761, + tau: 1.5594219393746818E-003, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1386852748028120E+01, 0.1388412169967495E+01, 0.2485138759635906E-17, 0.3183635051997810E-17, 0.1088363957319145E+01, 0.1082574309473529E+01, 0.6914717946174950E-02, 0.7349069784991225E-02, 0.1145634931626446E+01, 0.1024038416809464E+01, 0.1022944500333619E+00, 0.1300706547025319E+00, 0.8213718410609353E+00, 0.9009879710204475E+00, 0.3036175828902931E-01, 0.2423774201322422E-01, 0.1091423778368554E+01, 0.1028903323176749E+01, 0.7125729765473905E-01, 0.9444163542020824E-01, 0.7508515569660207E+00, 0.8234917650105269E+00, 0.2135460001102832E-04, 0.1765115496075164E-03, 0.8926135754328580E-01, 0.9083901139795122E-01, 0.7297073710223142E-05, 0.3122684720284652E-05, 0.2082481603404622E+00, 0.2085854845469525E+00, 0.6534568189162364E-03, 0.1229394806594584E-02, 0.1087369563009673E+00, 0.1106895682910690E+00, 0.3938065757966957E-05, 0.2602667681892373E-03, 0.8192604968568760E-04, 0.1645286054818337E-02, 0.2485138759635906E-17, 0.3183635051997810E-17}, + tauOut: 8.1416944590412474E-005, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1386852748028120E+01, 0.1386771331083530E+01, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.1088363957319145E+01, 0.1095197258320730E+01, 0.6914717946174950E-02, 0.7233164949324962E-02, 0.1145634931626446E+01, 0.1240614799765893E+01, 0.1022944500333619E+00, 0.6772592167212049E-01, 0.8213718410609353E+00, 0.7839262607332537E+00, 0.3036175828902931E-01, 0.4227125255215914E-01, 0.1091423778368554E+01, 0.1120328406526543E+01, 0.7125729765473905E-01, 0.4775711530437247E-01, 0.7508515569660207E+00, 0.7030343793170689E+00, 0.2135460001102832E-04, 0.2711304941630149E-05, 0.8926135754328580E-01, 0.8918452636746399E-01, 0.7297073710223142E-05, 0.1703885458517271E-04, 0.2082481603404622E+00, 0.2088031613602029E+00, 0.6534568189162364E-03, 0.3402961195615630E-03, 0.1087369563009673E+00, 0.1083191813025733E+00, 0.3938065757966957E-05, 0.2978513750500819E-08, 0.8192604968568760E-04, 0.5061265815246250E-06, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + n0in: 10, + dmin: 5.0612658152462498E-007, + dmin1: 8.9177229293753768E-002, + dmin2: 8.9177229293753768E-002, + dn: 5.0612658152462498E-007, + dn1: 0.10831524323681536, + dn2: 0.20814970454128662, + tau: 8.1416944590412474E-005, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1386852748028120E+01, 0.1386771331083530E+01, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.1088363957319145E+01, 0.1095197258320730E+01, 0.6914717946174950E-02, 0.7233164949324962E-02, 0.1145634931626446E+01, 0.1240614799765893E+01, 0.1022944500333619E+00, 0.6772592167212049E-01, 0.8213718410609353E+00, 0.7839262607332537E+00, 0.3036175828902931E-01, 0.4227125255215914E-01, 0.1091423778368554E+01, 0.1120328406526543E+01, 0.7125729765473905E-01, 0.4775711530437247E-01, 0.7508515569660207E+00, 0.7030343793170689E+00, 0.2135460001102832E-04, 0.2711304941630149E-05, 0.8926135754328580E-01, 0.8918452636746399E-01, 0.7297073710223142E-05, 0.1703885458517271E-04, 0.2082481603404622E+00, 0.2088031613602029E+00, 0.6534568189162364E-03, 0.3402961195615630E-03, 0.1087369563009673E+00, 0.1083191813025733E+00, 0.3938065757966957E-05, 0.2978513750500819E-08, 0.8192604968568760E-04, 0.5061265815246250E-06, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.9154376259418607E+00}, + tauOut: 5.0604049633765406E-007, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1386770825043033E+01, 0.1386771331083530E+01, 0.1540308069724697E-17, 0.1950383162890474E-17, 0.1102429917229558E+01, 0.1095197258320730E+01, 0.8139811288713328E-02, 0.7233164949324962E-02, 0.1300200404108803E+01, 0.1240614799765893E+01, 0.4083380405309871E-01, 0.6772592167212049E-01, 0.7853632031918177E+00, 0.7839262607332537E+00, 0.6030036143936175E-01, 0.4227125255215914E-01, 0.1107784654351057E+01, 0.1120328406526543E+01, 0.3030814137396716E-01, 0.4775711530437247E-01, 0.6727284432075471E+00, 0.7030343793170689E+00, 0.3594413905024206E-06, 0.2711304941630149E-05, 0.8920069974016231E-01, 0.8918452636746399E-01, 0.3988496406087022E-04, 0.1703885458517271E-04, 0.2091030664752072E+00, 0.2088031613602029E+00, 0.1762795624794033E-03, 0.3402961195615630E-03, 0.1081423986781113E+00, 0.1083191813025733E+00, 0.1393999949133917E-13, 0.2978513750500819E-08, 0.8607124697139263E-10, 0.5061265815246250E-06, 0.1540308069724697E-17, 0.1950383162890474E-17}, + i0: 1, + n0: 10, + pp: 0, + n0in: 10, + dmin: 8.6071246971392626E-011, + dmin1: 8.9183660885577137E-002, + dmin2: 8.9183660885577137E-002, + dn: 8.6071246971392626E-011, + dn1: 0.10814239569959758, + dn2: 0.20876277035564564, + tau: 5.0604049633765406E-007, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1386770825043033E+01, 0.1386771331083530E+01, 0.1540308069724697E-17, 0.1950383162890474E-17, 0.1102429917229558E+01, 0.1095197258320730E+01, 0.8139811288713328E-02, 0.7233164949324962E-02, 0.1300200404108803E+01, 0.1240614799765893E+01, 0.4083380405309871E-01, 0.6772592167212049E-01, 0.7853632031918177E+00, 0.7839262607332537E+00, 0.6030036143936175E-01, 0.4227125255215914E-01, 0.1107784654351057E+01, 0.1120328406526543E+01, 0.3030814137396716E-01, 0.4775711530437247E-01, 0.6727284432075471E+00, 0.7030343793170689E+00, 0.3594413905024206E-06, 0.2711304941630149E-05, 0.8920069974016231E-01, 0.8918452636746399E-01, 0.3988496406087022E-04, 0.1703885458517271E-04, 0.2091030664752072E+00, 0.2088031613602029E+00, 0.1762795624794033E-03, 0.3402961195615630E-03, 0.1081423986781113E+00, 0.1083191813025733E+00, 0.1393999949133917E-13, 0.2978513750500819E-08, 0.8607124697139263E-10, 0.5061265815246250E-06, 0.1540308069724697E-17, 0.1950383162890474E-17}, + tauOut: 8.6071215292546838E-011, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1386770825043033E+01, 0.1386770824956962E+01, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.1102429917229558E+01, 0.1110569728432201E+01, 0.8139811288713328E-02, 0.9529690622753703E-02, 0.1300200404108803E+01, 0.1331504517453077E+01, 0.4083380405309871E-01, 0.2408506071837550E-01, 0.7853632031918177E+00, 0.8215785038267327E+00, 0.6030036143936175E-01, 0.8130667336500198E-01, 0.1107784654351057E+01, 0.1056786122273951E+01, 0.3030814137396716E-01, 0.1929354325655847E-01, 0.6727284432075471E+00, 0.6534352593063080E+00, 0.3594413905024206E-06, 0.4906748310831983E-07, 0.8920069974016231E-01, 0.8924053555066887E-01, 0.3988496406087022E-04, 0.9345605379795243E-04, 0.2091030664752072E+00, 0.2091858898978174E+00, 0.1762795624794033E-03, 0.9113088236382798E-04, 0.1081423986781113E+00, 0.1080512677096902E+00, 0.1393999949133917E-13, 0.1110429488179469E-22, 0.8607124697139263E-10, 0.3167883469916549E-16, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + n0in: 10, + dmin: 3.1678834699165494E-017, + dmin1: 8.9200650586607991E-002, + dmin2: 8.9200650586607991E-002, + dn: 3.1678834699165494E-017, + dn1: 0.10805126770967630, + dn2: 0.20900961033533805, + tau: 8.6071215292546838E-011, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1386770825043033E+01, 0.1386770824956962E+01, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.1102429917229558E+01, 0.1110569728432201E+01, 0.8139811288713328E-02, 0.9529690622753703E-02, 0.1300200404108803E+01, 0.1331504517453077E+01, 0.4083380405309871E-01, 0.2408506071837550E-01, 0.7853632031918177E+00, 0.8215785038267327E+00, 0.6030036143936175E-01, 0.8130667336500198E-01, 0.1107784654351057E+01, 0.1056786122273951E+01, 0.3030814137396716E-01, 0.1929354325655847E-01, 0.6727284432075471E+00, 0.6534352593063080E+00, 0.3594413905024206E-06, 0.4906748310831983E-07, 0.8920069974016231E-01, 0.8924053555066887E-01, 0.3988496406087022E-04, 0.9345605379795243E-04, 0.2091030664752072E+00, 0.2091858898978174E+00, 0.1762795624794033E-03, 0.9113088236382798E-04, 0.1081423986781113E+00, 0.1080512677096902E+00, 0.1393999949133917E-13, 0.1110429488179469E-22, 0.8607124697139263E-10, 0.3167883469916549E-16, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.9154376259418607E+00}, + tauOut: 3.1678834698836348E-017, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1386770824956962E+01, 0.1386770824956962E+01, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.1120099419054954E+01, 0.1110569728432201E+01, 0.1132830345080667E-01, 0.9529690622753703E-02, 0.1344261274720646E+01, 0.1331504517453077E+01, 0.1472018016266302E-01, 0.2408506071837550E-01, 0.8881649970290716E+00, 0.8215785038267327E+00, 0.9674301998819117E-01, 0.8130667336500198E-01, 0.9793366455423188E+00, 0.1056786122273951E+01, 0.1287308250760436E-01, 0.1929354325655847E-01, 0.6405622258661866E+00, 0.6534352593063080E+00, 0.6835883063177366E-08, 0.4906748310831983E-07, 0.8933398476858376E-01, 0.8924053555066887E-01, 0.2188381927740679E-03, 0.9345605379795243E-04, 0.2090581825874072E+00, 0.2091858898978174E+00, 0.4710079866305792E-04, 0.9113088236382798E-04, 0.1080041669110272E+00, 0.1080512677096902E+00, 0.3257014354834561E-38, 0.1110429488179469E-22}, + i0: 1, + n0: 9, + pp: 0, + n0in: 10, + dmin: 3.1678834699165494E-017, + dmin1: 8.9240528714785800E-002, + dmin2: 8.9240528714785800E-002, + dn: 3.1678834699165494E-017, + dn1: 0.10800416691102718, + dn2: 0.20896705170504334, + tau: 0.0000000000000000, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1386770824956962E+01, 0.1386770824956962E+01, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.1120099419054954E+01, 0.1110569728432201E+01, 0.1132830345080667E-01, 0.9529690622753703E-02, 0.1344261274720646E+01, 0.1331504517453077E+01, 0.1472018016266302E-01, 0.2408506071837550E-01, 0.8881649970290716E+00, 0.8215785038267327E+00, 0.9674301998819117E-01, 0.8130667336500198E-01, 0.9793366455423188E+00, 0.1056786122273951E+01, 0.1287308250760436E-01, 0.1929354325655847E-01, 0.6405622258661866E+00, 0.6534352593063080E+00, 0.6835883063177366E-08, 0.4906748310831983E-07, 0.8933398476858376E-01, 0.8924053555066887E-01, 0.2188381927740679E-03, 0.9345605379795243E-04, 0.2090581825874072E+00, 0.2091858898978174E+00, 0.4710079866305792E-04, 0.9113088236382798E-04, 0.1080041669110272E+00, 0.1080512677096902E+00, 0.3257014354834561E-38, 0.1110429488179469E-22}, + tauOut: 2.2310132178696450E-002, + ttypeOut: -9, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1386770824956962E+01, 0.1364460692778266E+01, 0.9806070694382835E-18, 0.8049901434408684E-18, 0.1120099419054954E+01, 0.1109117590327065E+01, 0.1132830345080667E-01, 0.1373001363427395E-01, 0.1344261274720646E+01, 0.1322941309070339E+01, 0.1472018016266302E-01, 0.9882485852396858E-02, 0.8881649970290716E+00, 0.9527153989861693E+00, 0.9674301998819117E-01, 0.9944626147083412E-01, 0.9793366455423188E+00, 0.8704533344003925E+00, 0.1287308250760436E-01, 0.9473236598617136E-02, 0.6405622258661866E+00, 0.6087788639247561E+00, 0.6835883063177366E-08, 0.1003117403762534E-08, 0.8933398476858376E-01, 0.6724268977954398E-01, 0.2188381927740679E-03, 0.6803700894781421E-03, 0.2090581825874072E+00, 0.1861147811178956E+00, 0.4710079866305792E-04, 0.2733303872960605E-04, 0.1080041669110272E+00, 0.8566670169360113E-01, 0.3257014354834561E-38, 0.8049901434408684E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 6.7023851586769906E-002, + dmin1: 6.7023851586769906E-002, + dmin2: 6.7023851586769906E-002, + dn: 8.5666701693601133E-002, + dn1: 0.18606768031923254, + dn2: 6.7023851586769906E-002, + tau: 2.2310132178696450E-002, + ttype: -9, + g: 0.0000000000000000, + zOut: []float64{0.1386770824956962E+01, 0.1364460692778266E+01, 0.9806070694382835E-18, 0.8049901434408684E-18, 0.1120099419054954E+01, 0.1109117590327065E+01, 0.1132830345080667E-01, 0.1373001363427395E-01, 0.1344261274720646E+01, 0.1322941309070339E+01, 0.1472018016266302E-01, 0.9882485852396858E-02, 0.8881649970290716E+00, 0.9527153989861693E+00, 0.9674301998819117E-01, 0.9944626147083412E-01, 0.9793366455423188E+00, 0.8704533344003925E+00, 0.1287308250760436E-01, 0.9473236598617136E-02, 0.6405622258661866E+00, 0.6087788639247561E+00, 0.6835883063177366E-08, 0.1003117403762534E-08, 0.8933398476858376E-01, 0.6724268977954398E-01, 0.2188381927740679E-03, 0.6803700894781421E-03, 0.2090581825874072E+00, 0.1861147811178956E+00, 0.4710079866305792E-04, 0.2733303872960605E-04, 0.1080041669110272E+00, 0.8566670169360113E-01, 0.3257014354834561E-38, 0.8049901434408684E-18, 0.1094206688544886E+01}, + tauOut: 6.4730147312741043E-002, + ttypeOut: -5, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1299730545465525E+01, 0.1364460692778266E+01, 0.6869337119490330E-18, 0.8049901434408684E-18, 0.1058117456648598E+01, 0.1109117590327065E+01, 0.1716633828952343E-01, 0.1373001363427395E-01, 0.1250927309320471E+01, 0.1322941309070339E+01, 0.7526573591998700E-02, 0.9882485852396858E-02, 0.9799049395522637E+00, 0.9527153989861693E+00, 0.8833849733474472E-01, 0.9944626147083412E-01, 0.7268579263515238E+00, 0.8704533344003925E+00, 0.7934296380510910E-02, 0.9473236598617136E-02, 0.5361144212346215E+00, 0.6087788639247561E+00, 0.1258170079408221E-09, 0.1003117403762534E-08, 0.3192912430464083E-02, 0.6724268977954398E-01, 0.3965875451961033E-01, 0.6803700894781421E-03, 0.8175321232427381E-01, 0.1861147811178956E+00, 0.2864145895504550E-04, 0.2733303872960605E-04, 0.2090791292190505E-01, 0.8566670169360113E-01, 0.6869337119490330E-18, 0.8049901434408684E-18}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 2.5125423409859404E-003, + dmin1: 2.5125423409859404E-003, + dmin2: 2.5125423409859404E-003, + dn: 2.0907912921905053E-002, + dn1: 8.1725879285544201E-002, + dn2: 2.5125423409859404E-003, + tau: 6.4730147312741043E-002, + ttype: -5, + g: 0.0000000000000000, + zOut: []float64{0.1299730545465525E+01, 0.1364460692778266E+01, 0.6869337119490330E-18, 0.8049901434408684E-18, 0.1058117456648598E+01, 0.1109117590327065E+01, 0.1716633828952343E-01, 0.1373001363427395E-01, 0.1250927309320471E+01, 0.1322941309070339E+01, 0.7526573591998700E-02, 0.9882485852396858E-02, 0.9799049395522637E+00, 0.9527153989861693E+00, 0.8833849733474472E-01, 0.9944626147083412E-01, 0.7268579263515238E+00, 0.8704533344003925E+00, 0.7934296380510910E-02, 0.9473236598617136E-02, 0.5361144212346215E+00, 0.6087788639247561E+00, 0.1258170079408221E-09, 0.1003117403762534E-08, 0.3192912430464083E-02, 0.6724268977954398E-01, 0.3965875451961033E-01, 0.6803700894781421E-03, 0.8175321232427381E-01, 0.1861147811178956E+00, 0.2864145895504550E-04, 0.2733303872960605E-04, 0.2090791292190505E-01, 0.8566670169360113E-01, 0.6869337119490330E-18, 0.8049901434408684E-18}, + tauOut: 2.3478378904869292E-003, + ttypeOut: -5, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1299730545465525E+01, 0.1299143585992903E+01, 0.6869337119490330E-18, 0.5594890049187079E-18, 0.1058117456648598E+01, 0.1074696835465499E+01, 0.1716633828952343E-01, 0.1998130138542489E-01, 0.1250927309320471E+01, 0.1237885622054423E+01, 0.7526573591998700E-02, 0.5958003315736791E-02, 0.9799049395522637E+00, 0.1061698474098650E+01, 0.8833849733474472E-01, 0.6047812873071532E-01, 0.7268579263515238E+00, 0.6737271345286977E+00, 0.7934296380510910E-02, 0.6313669873066943E-02, 0.5361144212346215E+00, 0.5292137920147498E+00, 0.1258170079408221E-09, 0.7590933847144573E-12, 0.3192912430464083E-02, 0.4226470747669359E-01, 0.3965875451961033E-01, 0.7671248122433710E-01, 0.8175321232427381E-01, 0.4482413086270017E-02, 0.2864145895504550E-04, 0.1335961497218277E-03, 0.2090791292190505E-01, 0.2018735729956149E-01, 0.6869337119490330E-18, 0.5594890049187079E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 2.6059529570832572E-003, + dmin1: 2.6059529570832572E-003, + dmin2: 2.6059529570832572E-003, + dn: 2.0187357299561493E-002, + dn1: 4.4537716273149721E-003, + dn2: 2.6059529570832572E-003, + tau: 5.8695947262173229E-004, + ttype: -17, + g: 0.0000000000000000, + zOut: []float64{0.1299730545465525E+01, 0.1299143585992903E+01, 0.6869337119490330E-18, 0.5594890049187079E-18, 0.1058117456648598E+01, 0.1074696835465499E+01, 0.1716633828952343E-01, 0.1998130138542489E-01, 0.1250927309320471E+01, 0.1237885622054423E+01, 0.7526573591998700E-02, 0.5958003315736791E-02, 0.9799049395522637E+00, 0.1061698474098650E+01, 0.8833849733474472E-01, 0.6047812873071532E-01, 0.7268579263515238E+00, 0.6737271345286977E+00, 0.7934296380510910E-02, 0.6313669873066943E-02, 0.5361144212346215E+00, 0.5292137920147498E+00, 0.1258170079408221E-09, 0.7590933847144573E-12, 0.3192912430464083E-02, 0.4226470747669359E-01, 0.3965875451961033E-01, 0.7671248122433710E-01, 0.8175321232427381E-01, 0.4482413086270017E-02, 0.2864145895504550E-04, 0.1335961497218277E-03, 0.2090791292190505E-01, 0.2018735729956149E-01, 0.6869337119490330E-18, 0.5594890049187079E-18, 0.1094206688544886E+01}, + tauOut: 4.9324499328963489E-004, + ttypeOut: -5, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1298650340999613E+01, 0.1299143585992903E+01, 0.4630045856693428E-18, 0.5594890049187079E-18, 0.1094184891857634E+01, 0.1074696835465499E+01, 0.2260547177996662E-01, 0.1998130138542489E-01, 0.1220744908596903E+01, 0.1237885622054423E+01, 0.5181756634367578E-02, 0.5958003315736791E-02, 0.1116501601201708E+01, 0.1061698474098650E+01, 0.3649413160495897E-01, 0.6047812873071532E-01, 0.6430534278035160E+00, 0.6737271345286977E+00, 0.5195962000339362E-02, 0.6313669873066943E-02, 0.5235245850218799E+00, 0.5292137920147498E+00, 0.6128243213469890E-13, 0.7590933847144573E-12, 0.1184839437076798E+00, 0.4226470747669359E-01, 0.2902140315050332E-02, 0.7671248122433710E-01, 0.1220623927651878E-02, 0.4482413086270017E-02, 0.2209487416380896E-02, 0.1335961497218277E-03, 0.1748462488989096E-01, 0.2018735729956149E-01, 0.4630045856693428E-18, 0.5594890049187079E-18}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 1.0870277779300500E-003, + dmin1: 1.0870277779300500E-003, + dmin2: 4.1771462483342674E-002, + dn: 1.7484624889890960E-002, + dn1: 1.0870277779300500E-003, + dn2: 4.1771462483342674E-002, + tau: 4.9324499328963489E-004, + ttype: -5, + g: 0.0000000000000000, + zOut: []float64{0.1298650340999613E+01, 0.1299143585992903E+01, 0.4630045856693428E-18, 0.5594890049187079E-18, 0.1094184891857634E+01, 0.1074696835465499E+01, 0.2260547177996662E-01, 0.1998130138542489E-01, 0.1220744908596903E+01, 0.1237885622054423E+01, 0.5181756634367578E-02, 0.5958003315736791E-02, 0.1116501601201708E+01, 0.1061698474098650E+01, 0.3649413160495897E-01, 0.6047812873071532E-01, 0.6430534278035160E+00, 0.6737271345286977E+00, 0.5195962000339362E-02, 0.6313669873066943E-02, 0.5235245850218799E+00, 0.5292137920147498E+00, 0.6128243213469890E-13, 0.7590933847144573E-12, 0.1184839437076798E+00, 0.4226470747669359E-01, 0.2902140315050332E-02, 0.7671248122433710E-01, 0.1220623927651878E-02, 0.4482413086270017E-02, 0.2209487416380896E-02, 0.1335961497218277E-03, 0.1748462488989096E-01, 0.2018735729956149E-01, 0.4630045856693428E-18, 0.5594890049187079E-18}, + tauOut: 8.6238530354903250E-004, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1298650340999613E+01, 0.1297787955696064E+01, 0.4630045856693428E-18, 0.3903662538064461E-18, 0.1094184891857634E+01, 0.1115927978334052E+01, 0.2260547177996662E-01, 0.2472875948770642E-01, 0.1220744908596903E+01, 0.1200335520440015E+01, 0.5181756634367578E-02, 0.4819852017032840E-02, 0.1116501601201708E+01, 0.1147313495486085E+01, 0.3649413160495897E-01, 0.2045445862496274E-01, 0.6430534278035160E+00, 0.6269325458753436E+00, 0.5195962000339362E-02, 0.4338925882718484E-02, 0.5235245850218799E+00, 0.5183232738356738E+00, 0.6128243213469890E-13, 0.1400860159256393E-13, 0.1184839437076798E+00, 0.1205236987191671E+00, 0.2902140315050332E-02, 0.2939191169537379E-04, 0.1220623927651878E-02, 0.2538334128788367E-02, 0.2209487416380896E-02, 0.1521945367089819E-01, 0.1748462488989096E-01, 0.1402785915443734E-02, 0.4630045856693428E-18, 0.3903662538064461E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 3.2884671240747138E-004, + dmin1: 3.2884671240747138E-004, + dmin2: 0.11762155840411674, + dn: 1.4027859154437344E-003, + dn1: 3.2884671240747138E-004, + dn2: 0.11762155840411674, + tau: 8.6238530354903250E-004, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1298650340999613E+01, 0.1297787955696064E+01, 0.4630045856693428E-18, 0.3903662538064461E-18, 0.1094184891857634E+01, 0.1115927978334052E+01, 0.2260547177996662E-01, 0.2472875948770642E-01, 0.1220744908596903E+01, 0.1200335520440015E+01, 0.5181756634367578E-02, 0.4819852017032840E-02, 0.1116501601201708E+01, 0.1147313495486085E+01, 0.3649413160495897E-01, 0.2045445862496274E-01, 0.6430534278035160E+00, 0.6269325458753436E+00, 0.5195962000339362E-02, 0.4338925882718484E-02, 0.5235245850218799E+00, 0.5183232738356738E+00, 0.6128243213469890E-13, 0.1400860159256393E-13, 0.1184839437076798E+00, 0.1205236987191671E+00, 0.2902140315050332E-02, 0.2939191169537379E-04, 0.1220623927651878E-02, 0.2538334128788367E-02, 0.2209487416380896E-02, 0.1521945367089819E-01, 0.1748462488989096E-01, 0.1402785915443734E-02, 0.4630045856693428E-18, 0.3903662538064461E-18, 0.1094206688544886E+01}, + tauOut: 1.8442717265434725E-004, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1297603528523410E+01, 0.1297787955696064E+01, 0.3357116521683426E-18, 0.3903662538064461E-18, 0.1140472310649104E+01, 0.1115927978334052E+01, 0.2602676813137004E-01, 0.2472875948770642E-01, 0.1178944177153024E+01, 0.1200335520440015E+01, 0.4690536984322235E-02, 0.4819852017032840E-02, 0.1162892989954071E+01, 0.1147313495486085E+01, 0.1102729651913737E-01, 0.2045445862496274E-01, 0.6200597480662705E+00, 0.6269325458753436E+00, 0.3627015421456806E-02, 0.4338925882718484E-02, 0.5145118312415766E+00, 0.5183232738356738E+00, 0.3281495925457712E-14, 0.1400860159256393E-13, 0.1203686634582048E+00, 0.1205236987191671E+00, 0.6198165737098726E-06, 0.2939191169537379E-04, 0.1757274081045850E-01, 0.2538334128788367E-02, 0.1214929161054836E-02, 0.1521945367089819E-01, 0.3429581734551261E-05, 0.1402785915443734E-02, 0.3357116521683426E-18, 0.3903662538064461E-18}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 3.4295817345512611E-006, + dmin1: 2.3532871395603098E-003, + dmin2: 0.12033927154650945, + dn: 3.4295817345512611E-006, + dn1: 2.3532871395603098E-003, + dn2: 0.12033927154650945, + tau: 1.8442717265434725E-004, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1297603528523410E+01, 0.1297787955696064E+01, 0.3357116521683426E-18, 0.3903662538064461E-18, 0.1140472310649104E+01, 0.1115927978334052E+01, 0.2602676813137004E-01, 0.2472875948770642E-01, 0.1178944177153024E+01, 0.1200335520440015E+01, 0.4690536984322235E-02, 0.4819852017032840E-02, 0.1162892989954071E+01, 0.1147313495486085E+01, 0.1102729651913737E-01, 0.2045445862496274E-01, 0.6200597480662705E+00, 0.6269325458753436E+00, 0.3627015421456806E-02, 0.4338925882718484E-02, 0.5145118312415766E+00, 0.5183232738356738E+00, 0.3281495925457712E-14, 0.1400860159256393E-13, 0.1203686634582048E+00, 0.1205236987191671E+00, 0.6198165737098726E-06, 0.2939191169537379E-04, 0.1757274081045850E-01, 0.2538334128788367E-02, 0.1214929161054836E-02, 0.1521945367089819E-01, 0.3429581734551261E-05, 0.1402785915443734E-02, 0.3357116521683426E-18, 0.3903662538064461E-18}, + tauOut: 3.2077610710809750E-006, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1297603528523410E+01, 0.1297600320762339E+01, 0.3357116521683426E-18, 0.2950599175525191E-18, 0.1140472310649104E+01, 0.1166495871019403E+01, 0.2602676813137004E-01, 0.2630451380147252E-01, 0.1178944177153024E+01, 0.1157326992574803E+01, 0.4690536984322235E-02, 0.4713095445958055E-02, 0.1162892989954071E+01, 0.1169203983266179E+01, 0.1102729651913737E-01, 0.5848066547299594E-02, 0.6200597480662705E+00, 0.6178354891793567E+00, 0.3627015421456806E-02, 0.3020451850239120E-02, 0.5145118312415766E+00, 0.5114881716302697E+00, 0.3281495925457712E-14, 0.7722354114894537E-15, 0.1203686634582048E+00, 0.1203660755137067E+00, 0.6198165737098726E-06, 0.9048958315991394E-07, 0.1757274081045850E-01, 0.1878437172085910E-01, 0.1214929161054836E-02, 0.2218173128942313E-06, 0.3429581734551261E-05, 0.3350576054907334E-11, 0.3357116521683426E-18, 0.2950599175525191E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 3.3505760549073344E-012, + dmin1: 1.7569442559804263E-002, + dmin2: 0.12036545569713296, + dn: 3.3505760549073344E-012, + dn1: 1.7569442559804263E-002, + dn2: 0.12036545569713296, + tau: 3.2077610710809750E-006, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1297603528523410E+01, 0.1297600320762339E+01, 0.3357116521683426E-18, 0.2950599175525191E-18, 0.1140472310649104E+01, 0.1166495871019403E+01, 0.2602676813137004E-01, 0.2630451380147252E-01, 0.1178944177153024E+01, 0.1157326992574803E+01, 0.4690536984322235E-02, 0.4713095445958055E-02, 0.1162892989954071E+01, 0.1169203983266179E+01, 0.1102729651913737E-01, 0.5848066547299594E-02, 0.6200597480662705E+00, 0.6178354891793567E+00, 0.3627015421456806E-02, 0.3020451850239120E-02, 0.5145118312415766E+00, 0.5114881716302697E+00, 0.3281495925457712E-14, 0.7722354114894537E-15, 0.1203686634582048E+00, 0.1203660755137067E+00, 0.6198165737098726E-06, 0.9048958315991394E-07, 0.1757274081045850E-01, 0.1878437172085910E-01, 0.1214929161054836E-02, 0.2218173128942313E-06, 0.3429581734551261E-05, 0.3350576054907334E-11, 0.3357116521683426E-18, 0.2950599175525191E-18, 0.1094206688544886E+01}, + tauOut: 3.3505364896797715E-012, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1297600320758988E+01, 0.1297600320762339E+01, 0.2652482201353177E-18, 0.2950599175525191E-18, 0.1192800384817525E+01, 0.1166495871019403E+01, 0.2552222839336001E-01, 0.2630451380147252E-01, 0.1136517859624050E+01, 0.1157326992574803E+01, 0.4848643531876122E-02, 0.4713095445958055E-02, 0.1170203406278252E+01, 0.1169203983266179E+01, 0.3087619670750762E-02, 0.5848066547299594E-02, 0.6177683213554945E+00, 0.6178354891793567E+00, 0.2500816796475141E-02, 0.3020451850239120E-02, 0.5089873548304448E+00, 0.5114881716302697E+00, 0.1826193617023393E-15, 0.7722354114894537E-15, 0.1203661659999391E+00, 0.1203660755137067E+00, 0.1412182528886294E-07, 0.9048958315991394E-07, 0.1878457941299617E-01, 0.1878437172085910E-01, 0.3956520722700361E-16, 0.2218173128942313E-06, 0.2033579915109003E-22, 0.3350576054907334E-11, 0.2652482201353177E-18, 0.2950599175525191E-18}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 2.0335799151090034E-023, + dmin1: 1.8784357595683275E-002, + dmin2: 0.12036607551035594, + dn: 2.0335799151090034E-023, + dn1: 1.8784357595683275E-002, + dn2: 0.12036607551035594, + tau: 3.3505364896797715E-012, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1297600320758988E+01, 0.1297600320762339E+01, 0.2652482201353177E-18, 0.2950599175525191E-18, 0.1192800384817525E+01, 0.1166495871019403E+01, 0.2552222839336001E-01, 0.2630451380147252E-01, 0.1136517859624050E+01, 0.1157326992574803E+01, 0.4848643531876122E-02, 0.4713095445958055E-02, 0.1170203406278252E+01, 0.1169203983266179E+01, 0.3087619670750762E-02, 0.5848066547299594E-02, 0.6177683213554945E+00, 0.6178354891793567E+00, 0.2500816796475141E-02, 0.3020451850239120E-02, 0.5089873548304448E+00, 0.5114881716302697E+00, 0.1826193617023393E-15, 0.7722354114894537E-15, 0.1203661659999391E+00, 0.1203660755137067E+00, 0.1412182528886294E-07, 0.9048958315991394E-07, 0.1878457941299617E-01, 0.1878437172085910E-01, 0.3956520722700361E-16, 0.2218173128942313E-06, 0.2033579915109003E-22, 0.3350576054907334E-11, 0.2652482201353177E-18, 0.2950599175525191E-18}, + tauOut: 2.0335799151089990E-023, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1297600320758988E+01, 0.1297600320758988E+01, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1192800384817525E+01, 0.1218322613210885E+01, 0.2552222839336001E-01, 0.2380852827644004E-01, 0.1136517859624050E+01, 0.1117557974879486E+01, 0.4848643531876122E-02, 0.5077051306839188E-02, 0.1170203406278252E+01, 0.1168213974642164E+01, 0.3087619670750762E-02, 0.1632777609571200E-02, 0.6177683213554945E+00, 0.6186363605423986E+00, 0.2500816796475141E-02, 0.2057564358223963E-02, 0.5089873548304448E+00, 0.5069297904722210E+00, 0.1826193617023393E-15, 0.4336141378669131E-16, 0.1203661659999391E+00, 0.1203661801217644E+00, 0.1412182528886294E-07, 0.2203879431304952E-08, 0.1878457941299617E-01, 0.1878457720911678E-01, 0.3956520722700361E-16, 0.4283248425464200E-37, 0.1183377192742860E+01}, + i0: 1, + n0: 8, + pp: 1, + n0in: 9, + dmin: 2.0335799151089993E-023, + dmin1: 1.8784577209116738E-002, + dmin2: 0.12036616599993906, + dn: 2.0335799151089993E-023, + dn1: 1.8784577209116738E-002, + dn2: 0.12036616599993906, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1297600320758988E+01, 0.1297600320758988E+01, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1192800384817525E+01, 0.1218322613210885E+01, 0.2552222839336001E-01, 0.2380852827644004E-01, 0.1136517859624050E+01, 0.1117557974879486E+01, 0.4848643531876122E-02, 0.5077051306839188E-02, 0.1170203406278252E+01, 0.1168213974642164E+01, 0.3087619670750762E-02, 0.1632777609571200E-02, 0.6177683213554945E+00, 0.6186363605423986E+00, 0.2500816796475141E-02, 0.2057564358223963E-02, 0.5089873548304448E+00, 0.5069297904722210E+00, 0.1826193617023393E-15, 0.4336141378669131E-16, 0.1203661659999391E+00, 0.1203661801217644E+00, 0.1412182528886294E-07, 0.2203879431304952E-08, 0.1878457941299617E-01, 0.1878457720911678E-01, 0.3956520722700361E-16, 0.4283248425464200E-37, 0.1183377192742860E+01}, + tauOut: 1.8784576682472597E-002, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1278815744076516E+01, 0.1297600320758988E+01, 0.2322916695987584E-18, 0.2438256017573345E-18, 0.1223346564804853E+01, 0.1218322613210885E+01, 0.2174969171530204E-01, 0.2380852827644004E-01, 0.1082100757788551E+01, 0.1117557974879486E+01, 0.5481081353963683E-02, 0.5077051306839188E-02, 0.1145581094215299E+01, 0.1168213974642164E+01, 0.8817320773368219E-03, 0.1632777609571200E-02, 0.6010276161408131E+00, 0.6186363605423986E+00, 0.1735428857154564E-02, 0.2057564358223963E-02, 0.4864097849325938E+00, 0.5069297904722210E+00, 0.1073014545319338E-16, 0.4336141378669131E-16, 0.1015816056431712E+00, 0.1203661801217644E+00, 0.4075436992240071E-09, 0.2203879431304952E-08, 0.1191004794787176E-09, 0.1878457720911678E-01, 0.2322916695987584E-18, 0.2438256017573345E-18}, + i0: 1, + n0: 8, + pp: 0, + n0in: 8, + dmin: 1.1910047947871760E-010, + dmin1: 0.10158160343929173, + dmin2: 0.48640978493259379, + dn: 1.1910047947871760E-010, + dn1: 0.10158160343929173, + dn2: 0.48640978493259379, + tau: 1.8784576682472597E-002, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.1278815744076516E+01, 0.1297600320758988E+01, 0.2322916695987584E-18, 0.2438256017573345E-18, 0.1223346564804853E+01, 0.1218322613210885E+01, 0.2174969171530204E-01, 0.2380852827644004E-01, 0.1082100757788551E+01, 0.1117557974879486E+01, 0.5481081353963683E-02, 0.5077051306839188E-02, 0.1145581094215299E+01, 0.1168213974642164E+01, 0.8817320773368219E-03, 0.1632777609571200E-02, 0.6010276161408131E+00, 0.6186363605423986E+00, 0.1735428857154564E-02, 0.2057564358223963E-02, 0.4864097849325938E+00, 0.5069297904722210E+00, 0.1073014545319338E-16, 0.4336141378669131E-16, 0.1015816056431712E+00, 0.1203661801217644E+00, 0.4075436992240071E-09, 0.2203879431304952E-08, 0.1191004794787176E-09, 0.1878457720911678E-01, 0.2322916695987584E-18, 0.2438256017573345E-18}, + tauOut: 1.1910047900088848E-010, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1278815744076516E+01, 0.1278815743957415E+01, 0.2322916695987584E-18, 0.2222159192042978E-18, 0.1223346564804853E+01, 0.1245096256401054E+01, 0.2174969171530204E-01, 0.1890244048666934E-01, 0.1082100757788551E+01, 0.1068679398536745E+01, 0.5481081353963683E-02, 0.5875497537946494E-02, 0.1145581094215299E+01, 0.1140587328635589E+01, 0.8817320773368219E-03, 0.4646249482278370E-03, 0.6010276161408131E+00, 0.6022984199306394E+00, 0.1735428857154564E-02, 0.1401513849681988E-02, 0.4864097849325938E+00, 0.4850082709638114E+00, 0.1073014545319338E-16, 0.2247354260070927E-17, 0.1015816056431712E+00, 0.1015816059316144E+00, 0.4075436992240071E-09, 0.4778291260603437E-18, 0.1191004794787176E-09, 0.0000000000000000E+00, 0.2322916695987584E-18, 0.2222159192042978E-18, 0.1183377192742860E+01}, + i0: 1, + n0: 8, + pp: 1, + n0in: 8, + dmin: 0.0000000000000000, + dmin1: 0.10158160552407068, + dmin2: 0.48500827096381138, + dn: 0.0000000000000000, + dn1: 0.10158160552407068, + dn2: 0.48500827096381138, + tau: 1.1910047900088848E-010, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1278815744076516E+01, 0.1278815743957415E+01, 0.2322916695987584E-18, 0.2222159192042978E-18, 0.1223346564804853E+01, 0.1245096256401054E+01, 0.2174969171530204E-01, 0.1890244048666934E-01, 0.1082100757788551E+01, 0.1068679398536745E+01, 0.5481081353963683E-02, 0.5875497537946494E-02, 0.1145581094215299E+01, 0.1140587328635589E+01, 0.8817320773368219E-03, 0.4646249482278370E-03, 0.6010276161408131E+00, 0.6022984199306394E+00, 0.1735428857154564E-02, 0.1401513849681988E-02, 0.4864097849325938E+00, 0.4850082709638114E+00, 0.1073014545319338E-16, 0.2247354260070927E-17, 0.1015816056431712E+00, 0.1015816059316144E+00, 0.4075436992240071E-09, 0.4778291260603437E-18, 0.1191004794787176E-09, 0.0000000000000000E+00, 0.2322916695987584E-18, 0.2222159192042978E-18, 0.1183377192742860E+01}, + tauOut: -0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1278815743957415E+01, 0.1278815743957415E+01, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1263998696887723E+01, 0.1245096256401054E+01, 0.1598154237018549E-01, 0.1890244048666934E-01, 0.1058573353704506E+01, 0.1068679398536745E+01, 0.6330707284251229E-02, 0.5875497537946494E-02, 0.1134721246299565E+01, 0.1140587328635589E+01, 0.2466181655543824E-03, 0.4646249482278370E-03, 0.6034533156147670E+00, 0.6022984199306394E+00, 0.1126426504548419E-02, 0.1401513849681988E-02, 0.4838818444592630E+00, 0.4850082709638114E+00, 0.4717884282068346E-18, 0.2247354260070927E-17, 0.1015816059316144E+00, 0.1015816059316144E+00, 0.0000000000000000E+00, 0.4778291260603437E-18}, + i0: 1, + n0: 7, + pp: 0, + n0in: 8, + dmin: 0.0000000000000000, + dmin1: 0.10158160593161437, + dmin2: 0.48388184445926297, + dn: 0.0000000000000000, + dn1: 0.10158160593161437, + dn2: 0.48388184445926297, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.1278815743957415E+01, 0.1278815743957415E+01, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1263998696887723E+01, 0.1245096256401054E+01, 0.1598154237018549E-01, 0.1890244048666934E-01, 0.1058573353704506E+01, 0.1068679398536745E+01, 0.6330707284251229E-02, 0.5875497537946494E-02, 0.1134721246299565E+01, 0.1140587328635589E+01, 0.2466181655543824E-03, 0.4646249482278370E-03, 0.6034533156147670E+00, 0.6022984199306394E+00, 0.1126426504548419E-02, 0.1401513849681988E-02, 0.4838818444592630E+00, 0.4850082709638114E+00, 0.4717884282068346E-18, 0.2247354260070927E-17, 0.1015816059316144E+00, 0.1015816059316144E+00, 0.0000000000000000E+00, 0.4778291260603437E-18}, + tauOut: -0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1278815743957415E+01, 0.1278815743957415E+01, 0.2163565864913247E-18, 0.2138497627045302E-18, 0.1263998696887723E+01, 0.1279980239257909E+01, 0.1598154237018549E-01, 0.1321710631563048E-01, 0.1058573353704506E+01, 0.1051686954673127E+01, 0.6330707284251229E-02, 0.6830538334266978E-02, 0.1134721246299565E+01, 0.1128137326130852E+01, 0.2466181655543824E-03, 0.1319188242844840E-03, 0.6034533156147670E+00, 0.6044478232950309E+00, 0.1126426504548419E-02, 0.9017442261557238E-03, 0.4838818444592630E+00, 0.4829801002331072E+00, 0.4717884282068346E-18, 0.9922774494036444E-19, 0.1015816059316144E+00, 0.1015816059316144E+00, 0.0000000000000000E+00, 0.2138497627045302E-18, 0.1202161769544433E+01}, + i0: 1, + n0: 7, + pp: 1, + n0in: 7, + dmin: 0.10158160593161437, + dmin1: 0.48298010023310722, + dmin2: 0.60332139679048247, + dn: 0.10158160593161437, + dn1: 0.48298010023310722, + dn2: 0.60332139679048247, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.1278815743957415E+01, 0.1278815743957415E+01, 0.2163565864913247E-18, 0.2138497627045302E-18, 0.1263998696887723E+01, 0.1279980239257909E+01, 0.1598154237018549E-01, 0.1321710631563048E-01, 0.1058573353704506E+01, 0.1051686954673127E+01, 0.6330707284251229E-02, 0.6830538334266978E-02, 0.1134721246299565E+01, 0.1128137326130852E+01, 0.2466181655543824E-03, 0.1319188242844840E-03, 0.6034533156147670E+00, 0.6044478232950309E+00, 0.1126426504548419E-02, 0.9017442261557238E-03, 0.4838818444592630E+00, 0.4829801002331072E+00, 0.4717884282068346E-18, 0.9922774494036444E-19, 0.1015816059316144E+00, 0.1015816059316144E+00, 0.0000000000000000E+00, 0.2138497627045302E-18, 0.1202161769544433E+01}, + tauOut: 0.10158160593161437, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1177234138025801E+01, 0.1278815743957415E+01, 0.2325140442247288E-18, 0.2138497627045302E-18, 0.1191615739641925E+01, 0.1279980239257909E+01, 0.1166505092896250E-01, 0.1321710631563048E-01, 0.9452708361468171E+00, 0.1051686954673127E+01, 0.8151933771558135E-02, 0.6830538334266978E-02, 0.1018535705251965E+01, 0.1128137326130852E+01, 0.7828694249915420E-04, 0.1319188242844840E-03, 0.5036896746470730E+00, 0.6044478232950309E+00, 0.8646683437346259E-03, 0.9017442261557238E-03, 0.3805338259577582E+00, 0.4829801002331072E+00, 0.2648835135390502E-19, 0.9922774494036444E-19, 0.0000000000000000E+00, 0.1015816059316144E+00, 0.2325140442247288E-18, 0.2138497627045302E-18}, + i0: 1, + n0: 7, + pp: 0, + n0in: 7, + dmin: 0.0000000000000000, + dmin1: 0.38053382595775820, + dmin2: 0.50278793042091730, + dn: 0.0000000000000000, + dn1: 0.38053382595775820, + dn2: 0.50278793042091730, + tau: 0.10158160593161437, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1177234138025801E+01, 0.1278815743957415E+01, 0.2325140442247288E-18, 0.2138497627045302E-18, 0.1191615739641925E+01, 0.1279980239257909E+01, 0.1166505092896250E-01, 0.1321710631563048E-01, 0.9452708361468171E+00, 0.1051686954673127E+01, 0.8151933771558135E-02, 0.6830538334266978E-02, 0.1018535705251965E+01, 0.1128137326130852E+01, 0.7828694249915420E-04, 0.1319188242844840E-03, 0.5036896746470730E+00, 0.6044478232950309E+00, 0.8646683437346259E-03, 0.9017442261557238E-03, 0.3805338259577582E+00, 0.4829801002331072E+00, 0.2648835135390502E-19, 0.9922774494036444E-19, 0.0000000000000000E+00, 0.1015816059316144E+00, 0.2325140442247288E-18, 0.2138497627045302E-18}, + tauOut: -0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1177234138025801E+01, 0.1177234138025801E+01, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1191615739641925E+01, 0.1203280790570888E+01, 0.1166505092896250E-01, 0.9163806595868684E-02, 0.9452708361468171E+00, 0.9442589633225065E+00, 0.8151933771558135E-02, 0.8793176380307672E-02, 0.1018535705251965E+01, 0.1009820815814156E+01, 0.7828694249915420E-04, 0.3904883319791864E-04, 0.5036896746470730E+00, 0.5045152941576099E+00, 0.8646683437346259E-03, 0.6521815232088979E-03, 0.3805338259577582E+00, 0.3798816444345493E+00, 0.2648835135390502E-19, 0.0000000000000000E+00, 0.1303743375476047E+01}, + i0: 1, + n0: 6, + pp: 1, + n0in: 7, + dmin: 0.0000000000000000, + dmin1: 0.37988164443454930, + dmin2: 0.50365062581387521, + dn: 0.0000000000000000, + dn1: 0.37988164443454930, + dn2: 0.50365062581387521, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.1177234138025801E+01, 0.1177234138025801E+01, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1191615739641925E+01, 0.1203280790570888E+01, 0.1166505092896250E-01, 0.9163806595868684E-02, 0.9452708361468171E+00, 0.9442589633225065E+00, 0.8151933771558135E-02, 0.8793176380307672E-02, 0.1018535705251965E+01, 0.1009820815814156E+01, 0.7828694249915420E-04, 0.3904883319791864E-04, 0.5036896746470730E+00, 0.5045152941576099E+00, 0.8646683437346259E-03, 0.6521815232088979E-03, 0.3805338259577582E+00, 0.3798816444345493E+00, 0.2648835135390502E-19, 0.0000000000000000E+00, 0.1303743375476047E+01}, + tauOut: -0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1177234138025801E+01, 0.1177234138025801E+01, 0.2405618249359890E-18, 0.2353545363971710E-18, 0.1212444597166756E+01, 0.1203280790570888E+01, 0.7136826323052847E-02, 0.9163806595868684E-02, 0.9459153133797613E+00, 0.9442589633225065E+00, 0.9387238392656353E-02, 0.8793176380307672E-02, 0.1000472626254697E+01, 0.1009820815814156E+01, 0.1969142688202247E-04, 0.3904883319791864E-04, 0.5051477842539368E+00, 0.5045152941576099E+00, 0.4904540754787929E-03, 0.6521815232088979E-03, 0.3793911903590705E+00, 0.3798816444345493E+00, 0.2405618249359890E-18, 0.2353545363971710E-18}, + i0: 1, + n0: 6, + pp: 0, + n0in: 6, + dmin: 0.37939119035907048, + dmin1: 0.50449560273072791, + dmin2: 0.93712213699945368, + dn: 0.37939119035907048, + dn1: 0.50449560273072791, + dn2: 1.0004335774214996, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.1177234138025801E+01, 0.1177234138025801E+01, 0.2405618249359890E-18, 0.2353545363971710E-18, 0.1212444597166756E+01, 0.1203280790570888E+01, 0.7136826323052847E-02, 0.9163806595868684E-02, 0.9459153133797613E+00, 0.9442589633225065E+00, 0.9387238392656353E-02, 0.8793176380307672E-02, 0.1000472626254697E+01, 0.1009820815814156E+01, 0.1969142688202247E-04, 0.3904883319791864E-04, 0.5051477842539368E+00, 0.5045152941576099E+00, 0.4904540754787929E-03, 0.6521815232088979E-03, 0.3793911903590705E+00, 0.3798816444345493E+00, 0.2405618249359890E-18, 0.2353545363971710E-18}, + tauOut: 0.37791671367087804, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1177234138025801E+01, 0.7993174243549228E+00, 0.2405618249359890E-18, 0.3648961927279404E-18, 0.1212444597166756E+01, 0.8416647098189309E+00, 0.7136826323052847E-02, 0.8020810697124018E-02, 0.9459153133797613E+00, 0.5693650274044155E+00, 0.9387238392656353E-02, 0.1649499810480807E-01, 0.1000472626254697E+01, 0.6060806059058935E+00, 0.1969142688202247E-04, 0.1641214148963635E-04, 0.5051477842539368E+00, 0.1277051125170478E+00, 0.4904540754787929E-03, 0.1457059563590431E-02, 0.3793911903590705E+00, 0.1741712460201494E-04, 0.2405618249359890E-18, 0.3648961927279404E-18, 0.1303743375476047E+01}, + i0: 1, + n0: 6, + pp: 1, + n0in: 6, + dmin: 1.7417124602014944E-005, + dmin1: 0.12721465844156904, + dmin2: 0.55997778901175921, + dn: 1.7417124602014944E-005, + dn1: 0.12721465844156904, + dn2: 0.60606091447901145, + tau: 0.37791671367087804, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1177234138025801E+01, 0.7993174243549228E+00, 0.2405618249359890E-18, 0.3648961927279404E-18, 0.1212444597166756E+01, 0.8416647098189309E+00, 0.7136826323052847E-02, 0.8020810697124018E-02, 0.9459153133797613E+00, 0.5693650274044155E+00, 0.9387238392656353E-02, 0.1649499810480807E-01, 0.1000472626254697E+01, 0.6060806059058935E+00, 0.1969142688202247E-04, 0.1641214148963635E-04, 0.5051477842539368E+00, 0.1277051125170478E+00, 0.4904540754787929E-03, 0.1457059563590431E-02, 0.3793911903590705E+00, 0.1741712460201494E-04, 0.2405618249359890E-18, 0.3648961927279404E-18, 0.1303743375476047E+01}, + tauOut: 1.7220607103034587E-005, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.7993002037478197E+00, 0.7993174243549228E+00, 0.3842364192156412E-18, 0.3648961927279404E-18, 0.8496682999089519E+00, 0.8416647098189309E+00, 0.5374766956544110E-02, 0.8020810697124018E-02, 0.5804680379455763E+00, 0.5693650274044155E+00, 0.1722282329473577E-01, 0.1649499810480807E-01, 0.5888569741455443E+00, 0.6060806059058935E+00, 0.3559292778388127E-05, 0.1641214148963635E-04, 0.1291413921807568E+00, 0.1277051125170478E+00, 0.1965116493098606E-06, 0.1457059563590431E-02, 0.5849670496393478E-11, 0.1741712460201494E-04, 0.3842364192156412E-18, 0.3648961927279404E-18}, + i0: 1, + n0: 6, + pp: 0, + n0in: 6, + dmin: 5.8496704963934779E-012, + dmin1: 0.12768433261716639, + dmin2: 0.56397303984076830, + dn: 5.8496704963934779E-012, + dn1: 0.12768433261716639, + dn2: 0.58884056200405466, + tau: 1.7220607103034587E-005, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.7993002037478197E+00, 0.7993174243549228E+00, 0.3842364192156412E-18, 0.3648961927279404E-18, 0.8496682999089519E+00, 0.8416647098189309E+00, 0.5374766956544110E-02, 0.8020810697124018E-02, 0.5804680379455763E+00, 0.5693650274044155E+00, 0.1722282329473577E-01, 0.1649499810480807E-01, 0.5888569741455443E+00, 0.6060806059058935E+00, 0.3559292778388127E-05, 0.1641214148963635E-04, 0.1291413921807568E+00, 0.1277051125170478E+00, 0.1965116493098606E-06, 0.1457059563590431E-02, 0.5849670496393478E-11, 0.1741712460201494E-04, 0.3842364192156412E-18, 0.3648961927279404E-18}, + tauOut: 5.8496615949827599E-012, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.7993002037478197E+00, 0.7993002037419701E+00, 0.3842364192156412E-18, 0.4084491703488284E-18, 0.8496682999089519E+00, 0.8550430668596465E+00, 0.5374766956544110E-02, 0.3648799166500929E-02, 0.5804680379455763E+00, 0.5940420620679615E+00, 0.1722282329473577E-01, 0.1707249411982080E-01, 0.5888569741455443E+00, 0.5717880393126522E+00, 0.3559292778388127E-05, 0.8038853438286423E-06, 0.1291413921807568E+00, 0.1291407848012127E+00, 0.1965116493098606E-06, 0.8901358303923820E-17, 0.5849670496393478E-11, 0.5241368559131172E-22, 0.3842364192156412E-18, 0.4084491703488284E-18, 0.1303743375476047E+01}, + i0: 1, + n0: 6, + pp: 1, + n0in: 6, + dmin: 5.2413685591311719E-023, + dmin1: 0.12914058828956335, + dmin2: 0.57178448001987381, + dn: 5.2413685591311719E-023, + dn1: 0.12914058828956335, + dn2: 0.57178448001987381, + tau: 5.8496615949827599E-012, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.7993002037478197E+00, 0.7993002037419701E+00, 0.3842364192156412E-18, 0.4084491703488284E-18, 0.8496682999089519E+00, 0.8550430668596465E+00, 0.5374766956544110E-02, 0.3648799166500929E-02, 0.5804680379455763E+00, 0.5940420620679615E+00, 0.1722282329473577E-01, 0.1707249411982080E-01, 0.5888569741455443E+00, 0.5717880393126522E+00, 0.3559292778388127E-05, 0.8038853438286423E-06, 0.1291413921807568E+00, 0.1291407848012127E+00, 0.1965116493098606E-06, 0.8901358303923820E-17, 0.5849670496393478E-11, 0.5241368559131172E-22, 0.3842364192156412E-18, 0.4084491703488284E-18, 0.1303743375476047E+01}, + tauOut: 5.2413685591311714E-023, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.7993002037419701E+00, 0.7993002037419701E+00, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.8586918660261474E+00, 0.8550430668596465E+00, 0.2524235138002424E-02, 0.3648799166500929E-02, 0.6085903210497798E+00, 0.5940420620679615E+00, 0.1604009725641142E-01, 0.1707249411982080E-01, 0.5557487459415846E+00, 0.5717880393126522E+00, 0.1868009328861996E-06, 0.8038853438286423E-06, 0.1291405980002798E+00, 0.1291407848012127E+00, 0.3612752323451872E-38, 0.8901358303923820E-17}, + i0: 1, + n0: 5, + pp: 0, + n0in: 6, + dmin: 5.2413685591311719E-023, + dmin1: 0.12914059800027977, + dmin2: 0.55574794205624078, + dn: 5.2413685591311719E-023, + dn1: 0.12914059800027977, + dn2: 0.55574794205624078, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.7993002037419701E+00, 0.7993002037419701E+00, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.8586918660261474E+00, 0.8550430668596465E+00, 0.2524235138002424E-02, 0.3648799166500929E-02, 0.6085903210497798E+00, 0.5940420620679615E+00, 0.1604009725641142E-01, 0.1707249411982080E-01, 0.5557487459415846E+00, 0.5717880393126522E+00, 0.1868009328861996E-06, 0.8038853438286423E-06, 0.1291405980002798E+00, 0.1291407848012127E+00, 0.3612752323451872E-38, 0.8901358303923820E-17}, + tauOut: 0.12914051019182277, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.7993002037419701E+00, 0.6701596935501473E+00, 0.4369342452764876E-18, 0.5598544436768911E-18, 0.8586918660261474E+00, 0.7320755909723271E+00, 0.2524235138002424E-02, 0.2098451433139096E-02, 0.6085903210497798E+00, 0.4933914566812295E+00, 0.1604009725641142E-01, 0.1806732527351204E-01, 0.5557487459415846E+00, 0.4085410972771827E+00, 0.1868009328861996E-06, 0.5904812108429529E-07, 0.1291405980002798E+00, 0.2876033591836524E-07, 0.3612752323451872E-38, 0.5598544436768911E-18, 0.1681677309759878E+01}, + i0: 1, + n0: 5, + pp: 1, + n0in: 5, + dmin: 2.8760335918365243E-008, + dmin1: 0.40854091047624980, + dmin2: 0.47735135942481804, + dn: 2.8760335918365243E-008, + dn1: 0.40854091047624980, + dn2: 0.47735135942481804, + tau: 0.12914051019182277, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.7993002037419701E+00, 0.6701596935501473E+00, 0.4369342452764876E-18, 0.5598544436768911E-18, 0.8586918660261474E+00, 0.7320755909723271E+00, 0.2524235138002424E-02, 0.2098451433139096E-02, 0.6085903210497798E+00, 0.4933914566812295E+00, 0.1604009725641142E-01, 0.1806732527351204E-01, 0.5557487459415846E+00, 0.4085410972771827E+00, 0.1868009328861996E-06, 0.5904812108429529E-07, 0.1291405980002798E+00, 0.2876033591836524E-07, 0.3612752323451872E-38, 0.5598544436768911E-18, 0.1681677309759878E+01}, + tauOut: 2.8760330654564486E-008, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.6701596647898166E+00, 0.6701596935501473E+00, 0.6115792910959321E-18, 0.5598544436768911E-18, 0.7341740136451356E+00, 0.7320755909723271E+00, 0.1410235162411720E-02, 0.2098451433139096E-02, 0.5100485180319990E+00, 0.4933914566812295E+00, 0.1447165246275905E-01, 0.1806732527351204E-01, 0.3940694751022140E+00, 0.4085410972771827E+00, 0.4309503539425748E-14, 0.5904812108429529E-07, 0.9542972193014773E-15, 0.2876033591836524E-07, 0.6115792910959321E-18, 0.5598544436768911E-18}, + i0: 1, + n0: 5, + pp: 0, + n0in: 5, + dmin: 9.5429721930147733E-016, + dmin1: 0.39406941605409296, + dmin2: 0.49198119275848701, + dn: 9.5429721930147733E-016, + dn1: 0.39406941605409296, + dn2: 0.49198119275848701, + tau: 2.8760330654564486E-008, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.6701596647898166E+00, 0.6701596935501473E+00, 0.6115792910959321E-18, 0.5598544436768911E-18, 0.7341740136451356E+00, 0.7320755909723271E+00, 0.1410235162411720E-02, 0.2098451433139096E-02, 0.5100485180319990E+00, 0.4933914566812295E+00, 0.1447165246275905E-01, 0.1806732527351204E-01, 0.3940694751022140E+00, 0.4085410972771827E+00, 0.4309503539425748E-14, 0.5904812108429529E-07, 0.9542972193014773E-15, 0.2876033591836524E-07, 0.6115792910959321E-18, 0.5598544436768911E-18}, + tauOut: 9.5429721930146451E-016, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.6701596647898166E+00, 0.6701596647898156E+00, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.7341740136451356E+00, 0.7355842488075462E+00, 0.1410235162411720E-02, 0.9778463253267723E-03, 0.5100485180319990E+00, 0.5235423241694304E+00, 0.1447165246275905E-01, 0.1089278980244500E-01, 0.3940694751022140E+00, 0.3831766852997724E+00, 0.4309503539425748E-14, 0.1073277003016631E-28, 0.1810817848712033E+01}, + i0: 1, + n0: 4, + pp: 1, + n0in: 5, + dmin: 1.9721522630525295E-030, + dmin1: 0.38317668529976806, + dmin2: 0.50907067170667131, + dn: 1.9721522630525295E-030, + dn1: 0.38317668529976806, + dn2: 0.50907067170667131, + tau: 9.5429721930146451E-016, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.6701596647898166E+00, 0.6701596647898156E+00, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.7341740136451356E+00, 0.7355842488075462E+00, 0.1410235162411720E-02, 0.9778463253267723E-03, 0.5100485180319990E+00, 0.5235423241694304E+00, 0.1447165246275905E-01, 0.1089278980244500E-01, 0.3940694751022140E+00, 0.3831766852997724E+00, 0.4309503539425748E-14, 0.1073277003016631E-28, 0.1810817848712033E+01}, + tauOut: 0.31895966905528556, + ttypeOut: -8, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.3511999957345300E+00, 0.6701596647898156E+00, 0.1403302870260262E-17, 0.6699979816704878E-18, 0.4176024260775874E+00, 0.7355842488075462E+00, 0.1225912269357841E-02, 0.9778463253267723E-03, 0.2142495326472319E+00, 0.5235423241694304E+00, 0.1948131712866055E-01, 0.1089278980244500E-01, 0.4473569911582631E-01, 0.3831766852997724E+00, 0.1403302870260262E-17, 0.6699979816704878E-18}, + i0: 1, + n0: 4, + pp: 0, + n0in: 4, + dmin: 4.4735699115826311E-002, + dmin1: 0.20335674284478694, + dmin2: 0.35119999573453003, + dn: 4.4735699115826311E-002, + dn1: 0.20335674284478694, + dn2: 0.41662457975226058, + tau: 0.31895966905528556, + ttype: -8, + g: 0.0000000000000000, + zOut: []float64{0.3511999957345300E+00, 0.6701596647898156E+00, 0.1403302870260262E-17, 0.6699979816704878E-18, 0.4176024260775874E+00, 0.7355842488075462E+00, 0.1225912269357841E-02, 0.9778463253267723E-03, 0.2142495326472319E+00, 0.5235423241694304E+00, 0.1948131712866055E-01, 0.1089278980244500E-01, 0.4473569911582631E-01, 0.3831766852997724E+00, 0.1403302870260262E-17, 0.6699979816704878E-18}, + tauOut: 3.9897804510299034E-002, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.3511999957345300E+00, 0.3113021912242310E+00, 0.1403302870260262E-17, 0.1882488140663987E-17, 0.4176024260775874E+00, 0.3789305338366462E+00, 0.1225912269357841E-02, 0.6931379430343076E-03, 0.2142495326472319E+00, 0.1931399073225591E+00, 0.1948131712866055E-01, 0.4512326600593524E-02, 0.4473569911582631E-01, 0.3255680049337531E-03, 0.1403302870260262E-17, 0.1882488140663987E-17, 0.1810817848712033E+01}, + i0: 1, + n0: 4, + pp: 1, + n0in: 4, + dmin: 3.2556800493375310E-004, + dmin1: 0.17365859019389857, + dmin2: 0.31130219122423097, + dn: 3.2556800493375310E-004, + dn1: 0.17365859019389857, + dn2: 0.37770462156728835, + tau: 3.9897804510299034E-002, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.3511999957345300E+00, 0.3113021912242310E+00, 0.1403302870260262E-17, 0.1882488140663987E-17, 0.4176024260775874E+00, 0.3789305338366462E+00, 0.1225912269357841E-02, 0.6931379430343076E-03, 0.2142495326472319E+00, 0.1931399073225591E+00, 0.1948131712866055E-01, 0.4512326600593524E-02, 0.4473569911582631E-01, 0.3255680049337531E-03, 0.1403302870260262E-17, 0.1882488140663987E-17, 0.1810817848712033E+01}, + tauOut: 3.1797943619548145E-004, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.3109842117880355E+00, 0.3113021912242310E+00, 0.2293789231233262E-17, 0.1882488140663987E-17, 0.3793056923434850E+00, 0.3789305338366462E+00, 0.3529411785314453E-03, 0.6931379430343076E-03, 0.1969813133084257E+00, 0.1931399073225591E+00, 0.7457911333267062E-05, 0.4512326600593524E-02, 0.1306574050045526E-06, 0.3255680049337531E-03, 0.2293789231233262E-17, 0.1882488140663987E-17}, + i0: 1, + n0: 4, + pp: 0, + n0in: 4, + dmin: 1.3065740500455263E-007, + dmin1: 0.19246898670783216, + dmin2: 0.31098421178803548, + dn: 1.3065740500455263E-007, + dn1: 0.19246898670783216, + dn2: 0.37861255440045072, + tau: 3.1797943619548145E-004, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.3109842117880355E+00, 0.3113021912242310E+00, 0.2293789231233262E-17, 0.1882488140663987E-17, 0.3793056923434850E+00, 0.3789305338366462E+00, 0.3529411785314453E-03, 0.6931379430343076E-03, 0.1969813133084257E+00, 0.1931399073225591E+00, 0.7457911333267062E-05, 0.4512326600593524E-02, 0.1306574050045526E-06, 0.3255680049337531E-03, 0.2293789231233262E-17, 0.1882488140663987E-17}, + tauOut: 1.3065240973281283E-007, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.3109842117880355E+00, 0.3109840811356258E+00, 0.2293789231233262E-17, 0.2797722987188916E-17, 0.3793056923434850E+00, 0.3796585028696068E+00, 0.3529411785314453E-03, 0.1831193463132450E-03, 0.1969813133084257E+00, 0.1968055212210360E+00, 0.7457911333267062E-05, 0.4951239861123181E-11, 0.1306574050045526E-06, 0.4403187866809611E-13, 0.2293789231233262E-17, 0.2797722987188916E-17, 0.1810817848712033E+01}, + i0: 1, + n0: 4, + pp: 1, + n0in: 4, + dmin: 4.4031878668096113E-014, + dmin1: 0.19679806330970273, + dmin2: 0.31098408113562576, + dn: 4.4031878668096113E-014, + dn1: 0.19679806330970273, + dn2: 0.37930556169107532, + tau: 1.3065240973281283E-007, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.3109842117880355E+00, 0.3109840811356258E+00, 0.2293789231233262E-17, 0.2797722987188916E-17, 0.3793056923434850E+00, 0.3796585028696068E+00, 0.3529411785314453E-03, 0.1831193463132450E-03, 0.1969813133084257E+00, 0.1968055212210360E+00, 0.7457911333267062E-05, 0.4951239861123181E-11, 0.1306574050045526E-06, 0.4403187866809611E-13, 0.2293789231233262E-17, 0.2797722987188916E-17, 0.1810817848712033E+01}, + tauOut: 4.4031878666982759E-014, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.3109840811355817E+00, 0.3109840811356258E+00, 0.3415542419024794E-17, 0.2797722987188916E-17, 0.3798416222158761E+00, 0.3796585028696068E+00, 0.9487875021856221E-04, 0.1831193463132450E-03, 0.1967106424757246E+00, 0.1968055212210360E+00, 0.1108289770587888E-23, 0.4951239861123181E-11, 0.5067642455139780E-26, 0.4403187866809611E-13, 0.3415542419024794E-17, 0.2797722987188916E-17}, + i0: 1, + n0: 4, + pp: 0, + n0in: 4, + dmin: 5.0676424551397798E-027, + dmin1: 0.19671064247077341, + dmin2: 0.31098408113558174, + dn: 5.0676424551397798E-027, + dn1: 0.19671064247077341, + dn2: 0.37965850286956282, + tau: 4.4031878666982759E-014, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.3109840811355817E+00, 0.3109840811356258E+00, 0.3415542419024794E-17, 0.2797722987188916E-17, 0.3798416222158761E+00, 0.3796585028696068E+00, 0.9487875021856221E-04, 0.1831193463132450E-03, 0.1967106424757246E+00, 0.1968055212210360E+00, 0.1108289770587888E-23, 0.4951239861123181E-11, 0.5067642455139780E-26, 0.4403187866809611E-13, 0.3415542419024794E-17, 0.2797722987188916E-17}, + tauOut: 5.0676424551397798E-027, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.3109840811355817E+00, 0.3109840811355817E+00, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.3798416222158761E+00, 0.3799365009660947E+00, 0.9487875021856221E-04, 0.4912310311151891E-04, 0.1967106424757246E+00, 0.1966615193726131E+00, 0.1108289770587888E-23, 0.2855879641297252E-49, 0.2169993432366266E+01}, + i0: 1, + n0: 3, + pp: 1, + n0in: 4, + dmin: 5.0676424551397798E-027, + dmin1: 0.19666151937261311, + dmin2: 0.31098408113558174, + dn: 5.0676424551397798E-027, + dn1: 0.19666151937261311, + dn2: 0.37984162221587608, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.3109840811355817E+00, 0.3109840811355817E+00, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.3798416222158761E+00, 0.3799365009660947E+00, 0.9487875021856221E-04, 0.4912310311151891E-04, 0.1967106424757246E+00, 0.1966615193726131E+00, 0.1108289770587888E-23, 0.2855879641297252E-49, 0.2169993432366266E+01}, + tauOut: 9.8330759686306557E-002, + ttypeOut: -9, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2126533214492752E+00, 0.3109840811355817E+00, 0.7453545812882342E-17, 0.4171805735046273E-17, 0.2816548643828996E+00, 0.3799365009660947E+00, 0.3429951091160839E-04, 0.4912310311151891E-04, 0.9829646017539498E-01, 0.1966615193726131E+00, 0.3799365009660947E+00, 0.2855879641297252E-49}, + i0: 1, + n0: 3, + pp: 0, + n0in: 3, + dmin: 9.8296460175394978E-002, + dmin1: 0.21265332144927518, + dmin2: 0.21265332144927518, + dn: 9.8296460175394978E-002, + dn1: 0.28160574127978810, + dn2: 0.21265332144927518, + tau: 9.8330759686306557E-002, + ttype: -9, + g: 0.0000000000000000, + zOut: []float64{0.2126533214492752E+00, 0.3109840811355817E+00, 0.7453545812882342E-17, 0.4171805735046273E-17, 0.2816548643828996E+00, 0.3799365009660947E+00, 0.3429951091160839E-04, 0.4912310311151891E-04, 0.9829646017539498E-01, 0.1966615193726131E+00, 0.3799365009660947E+00, 0.2855879641297252E-49}, + tauOut: 9.7172513485343004E-002, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2126533214492752E+00, 0.1154808079639322E+00, 0.7453545812882342E-17, 0.1817901582187390E-16, 0.2816548643828996E+00, 0.1845166504084682E+00, 0.3429951091160839E-04, 0.1827217490071947E-04, 0.9829646017539498E-01, 0.1105674515151256E-02, 0.3799365009660947E+00, 0.2816548643828996E+00, 0.2169993432366266E+01}, + i0: 1, + n0: 3, + pp: 1, + n0in: 3, + dmin: 1.1056745151512559E-003, + dmin1: 0.11548080796393217, + dmin2: 0.11548080796393217, + dn: 1.1056745151512559E-003, + dn1: 0.18448235089755655, + dn2: 0.11548080796393217, + tau: 9.7172513485343004E-002, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2126533214492752E+00, 0.1154808079639322E+00, 0.7453545812882342E-17, 0.1817901582187390E-16, 0.2816548643828996E+00, 0.1845166504084682E+00, 0.3429951091160839E-04, 0.1827217490071947E-04, 0.9829646017539498E-01, 0.1105674515151256E-02, 0.3799365009660947E+00, 0.2816548643828996E+00, 0.2169993432366266E+01}, + tauOut: 1.0942861809085330E-003, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1143865217830237E+00, 0.1154808079639322E+00, 0.2932453102768040E-16, 0.1817901582187390E-16, 0.1834406364024603E+00, 0.1845166504084682E+00, 0.1101341475930520E-06, 0.1827217490071947E-04, 0.1127820009512990E-04, 0.1105674515151256E-02, 0.1845166504084682E+00, 0.2816548643828996E+00}, + i0: 1, + n0: 3, + pp: 0, + n0in: 3, + dmin: 1.1278200095129901E-005, + dmin1: 0.11438652178302365, + dmin2: 0.11438652178302365, + dn: 1.1278200095129901E-005, + dn1: 0.18342236422755959, + dn2: 0.11438652178302365, + tau: 1.0942861809085330E-003, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1143865217830237E+00, 0.1154808079639322E+00, 0.2932453102768040E-16, 0.1817901582187390E-16, 0.1834406364024603E+00, 0.1845166504084682E+00, 0.1101341475930520E-06, 0.1827217490071947E-04, 0.1127820009512990E-04, 0.1105674515151256E-02, 0.1845166504084682E+00, 0.2816548643828996E+00}, + tauOut: 1.1269238360546607E-005, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1143865217830237E+00, 0.1143752525446631E+00, 0.2932453102768040E-16, 0.4703212027287794E-16, 0.1834406364024603E+00, 0.1834294772982473E+00, 0.1101341475930520E-06, 0.6771621290952006E-11, 0.1127820009512990E-04, 0.8954962962003413E-08, 0.1845166504084682E+00, 0.1834406364024603E+00, 0.2169993432366266E+01}, + i0: 1, + n0: 3, + pp: 1, + n0in: 3, + dmin: 8.9549629620034135E-009, + dmin1: 0.11437525254466312, + dmin2: 0.11437525254466312, + dn: 8.9549629620034135E-009, + dn1: 0.18342936716409974, + dn2: 0.11437525254466312, + tau: 1.1269238360546607E-005, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1143865217830237E+00, 0.1143752525446631E+00, 0.2932453102768040E-16, 0.4703212027287794E-16, 0.1834406364024603E+00, 0.1834294772982473E+00, 0.1101341475930520E-06, 0.6771621290952006E-11, 0.1127820009512990E-04, 0.8954962962003413E-08, 0.1845166504084682E+00, 0.1834406364024603E+00, 0.2169993432366266E+01}, + tauOut: 8.9549072084035346E-009, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1143752435897560E+00, 0.1143752525446631E+00, 0.7542783706608855E-16, 0.4703212027287794E-16, 0.1834294683501117E+00, 0.1834294772982473E+00, 0.3305882004599510E-18, 0.6771621290952006E-11, 0.5575326929115112E-13, 0.8954962962003413E-08, 0.1834294772982473E+00, 0.1834406364024603E+00}, + i0: 1, + n0: 3, + pp: 0, + n0in: 3, + dmin: 5.5753269291151117E-014, + dmin1: 0.11437524358975594, + dmin2: 0.11437524358975594, + dn: 5.5753269291151117E-014, + dn1: 0.18342946834334006, + dn2: 0.11437524358975594, + tau: 8.9549072084035346E-009, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1143752435897560E+00, 0.1143752525446631E+00, 0.7542783706608855E-16, 0.4703212027287794E-16, 0.1834294683501117E+00, 0.1834294772982473E+00, 0.3305882004599510E-18, 0.6771621290952006E-11, 0.5575326929115112E-13, 0.8954962962003413E-08, 0.1834294772982473E+00, 0.1834406364024603E+00}, + tauOut: 5.5753269214454873E-014, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1648283185136998E+01, 0.1396221235720571E+01, 0.1712714336271993E+00, 0.2520619494164272E+00, 0.1510753432847732E+01, 0.1119977945086946E+01, 0.3792800633372563E+00, 0.5620469213879850E+00, 0.1328441621586708E+01, 0.1019485448443405E+01, 0.1388998759717073E+00, 0.6882362364805590E+00, 0.4466938077796418E+00, 0.2681061628164644E+00, 0.7093206047768255E+00, 0.3174875209348847E+00, 0.6843112870203156E+00, 0.9979892152967577E+00, 0.6490582981441884E+00, 0.3956426765003833E+00, 0.5085572738629487E+00, 0.1122623886995757E+01, 0.9750235054014829E-02, 0.3499168501137979E-01, 0.1364886053450573E+00, 0.1417066070690837E+00, 0.2301225778544498E-01, 0.4532233329988395E-02, 0.1646009972289452E+01, 0.6930161671496210E+00, 0.2362515608142310E+00, 0.9760060629252760E+00, 0.5818602562677768E+00, 0.3984323866837953E+00, 0.1797665269485310E-01, 0.4196794303982125E+00, 0.5600419521166516E+00, 0.2492354636952108E-01, 0.2195137569256029E+00, 0.5530950584419837E+00, 0.4184071984843414E+00, 0.2222708575473020E+00, 0.2727864547293006E+00, 0.4156500978626423E+00, 0.6774373914466536E-01, 0.2745959086613283E+00, 0.1050967099374242E+00, 0.6593428521263771E-01, 0.2040338718098096E+00, 0.1079809097801335E+00, 0.1271971985482246E+00, 0.2011496719671002E+00, 0.4444741998443960E-01, 0.1290210252363728E+00, 0.5776327498150620E+00, 0.4262359329629137E-01, 0.3402556968467140E+00, 0.6023491555328507E+00, 0.1086565805630269E+00, 0.3155392911289253E+00, 0.9382999256694983E+00, 0.1171677238805356E+00, 0.7901625299559836E+00, 0.9297887823519896E+00, 0.6095853796269167E+00, 0.7973955560628040E+00, 0.8018125008387630E+00, 0.6023523535200964E+00, 0.2443177602187348E-01, 0.8114406374558937E+00, 0.2277830378453201E+00, 0.1480363940474286E-01, 0.6969081780841352E+00, 0.3759308106650992E+00, 0.8012406122589412E-01, 0.5487604052643561E+00, 0.9781022865072954E-01, 0.1017549972519246E+00, 0.2961248981181939E-03, 0.7617929262469909E-01, 0.8408398800007548E-04, 0.3802088861182694E-03, 0.0000000000000000E+00, 0.0000000000000000E+00}, + i0: 1, + n0: 21, + pp: 0, + n0in: 21, + dmin: -0.0000000000000000, + dmin1: 0.0000000000000000, + dmin2: 0.0000000000000000, + dn: 0.0000000000000000, + dn1: 0.0000000000000000, + dn2: 0.0000000000000000, + tau: 0.0000000000000000, + ttype: 0, + g: 0.0000000000000000, + zOut: []float64{0.1648283185136998E+01, 0.1396221235720571E+01, 0.1712714336271993E+00, 0.2520619494164272E+00, 0.1510753432847732E+01, 0.1119977945086946E+01, 0.3792800633372563E+00, 0.5620469213879850E+00, 0.1328441621586708E+01, 0.1019485448443405E+01, 0.1388998759717073E+00, 0.6882362364805590E+00, 0.4466938077796418E+00, 0.2681061628164644E+00, 0.7093206047768255E+00, 0.3174875209348847E+00, 0.6843112870203156E+00, 0.9979892152967577E+00, 0.6490582981441884E+00, 0.3956426765003833E+00, 0.5085572738629487E+00, 0.1122623886995757E+01, 0.9750235054014829E-02, 0.3499168501137979E-01, 0.1364886053450573E+00, 0.1417066070690837E+00, 0.2301225778544498E-01, 0.4532233329988395E-02, 0.1646009972289452E+01, 0.6930161671496210E+00, 0.2362515608142310E+00, 0.9760060629252760E+00, 0.5818602562677768E+00, 0.3984323866837953E+00, 0.1797665269485310E-01, 0.4196794303982125E+00, 0.5600419521166516E+00, 0.2492354636952108E-01, 0.2195137569256029E+00, 0.5530950584419837E+00, 0.4184071984843414E+00, 0.2222708575473020E+00, 0.2727864547293006E+00, 0.4156500978626423E+00, 0.6774373914466536E-01, 0.2745959086613283E+00, 0.1050967099374242E+00, 0.6593428521263771E-01, 0.2040338718098096E+00, 0.1079809097801335E+00, 0.1271971985482246E+00, 0.2011496719671002E+00, 0.4444741998443960E-01, 0.1290210252363728E+00, 0.5776327498150620E+00, 0.4262359329629137E-01, 0.3402556968467140E+00, 0.6023491555328507E+00, 0.1086565805630269E+00, 0.3155392911289253E+00, 0.9382999256694983E+00, 0.1171677238805356E+00, 0.7901625299559836E+00, 0.9297887823519896E+00, 0.6095853796269167E+00, 0.7973955560628040E+00, 0.8018125008387630E+00, 0.6023523535200964E+00, 0.2443177602187348E-01, 0.8114406374558937E+00, 0.2277830378453201E+00, 0.1480363940474286E-01, 0.6969081780841352E+00, 0.3759308106650992E+00, 0.8012406122589412E-01, 0.5487604052643561E+00, 0.9781022865072954E-01, 0.1017549972519246E+00, 0.2961248981181939E-03, 0.7617929262469909E-01, 0.8408398800007548E-04, 0.3802088861182694E-03, 0.0000000000000000E+00, 0.0000000000000000E+00}, + tauOut: 0.0000000000000000, + ttypeOut: -1, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1648283185136998E+01, 0.1819554618764197E+01, 0.1712714336271993E+00, 0.1422045283129674E+00, 0.1510753432847732E+01, 0.1747828967872021E+01, 0.3792800633372563E+00, 0.2882727267008810E+00, 0.1328441621586708E+01, 0.1179068770857534E+01, 0.1388998759717073E+00, 0.5262264257308433E-01, 0.4466938077796418E+00, 0.1103391769983383E+01, 0.7093206047768255E+00, 0.4399127392187891E+00, 0.6843112870203156E+00, 0.8934568459457148E+00, 0.6490582981441884E+00, 0.3694451726238032E+00, 0.5085572738629487E+00, 0.1488623362931603E+00, 0.9750235054014829E-02, 0.8939776288934402E-02, 0.1364886053450573E+00, 0.1505610868415679E+00, 0.2301225778544498E-01, 0.2515816443301624E+00, 0.1646009972289452E+01, 0.1630679888773521E+01, 0.2362515608142310E+00, 0.8429943526342391E-01, 0.5818602562677768E+00, 0.5155374736992060E+00, 0.1797665269485310E-01, 0.1952851185677853E-01, 0.5600419521166516E+00, 0.7600271971854760E+00, 0.2195137569256029E+00, 0.1208458544696003E+00, 0.4184071984843414E+00, 0.5703477987440417E+00, 0.2727864547293006E+00, 0.3240053608004366E-01, 0.6774373914466536E-01, 0.1404399130020459E+00, 0.1050967099374242E+00, 0.1526865702536626E+00, 0.2040338718098096E+00, 0.1785445001043715E+00, 0.1271971985482246E+00, 0.3166486394939177E-01, 0.4444741998443960E-01, 0.5904153058501098E+00, 0.5776327498150620E+00, 0.3328891237445398E+00, 0.3402556968467140E+00, 0.1160231536652011E+00, 0.1086565805630269E+00, 0.8787251358464724E+00, 0.9382999256694983E+00, 0.8497373197790092E+00, 0.7901625299559836E+00, 0.5668475593321608E+00, 0.6095853796269167E+00, 0.8445503211335190E+00, 0.8018125008387630E+00, 0.2319542476253924E-01, 0.2443177602187348E-01, 0.2290193891046544E+00, 0.2277830378453201E+00, 0.6931459494493321E+00, 0.6969081780841352E+00, 0.8388628986069724E-01, 0.8012406122589412E-01, 0.9342352322344821E-01, 0.9781022865072954E-01, 0.4682830325399513E-02, 0.2961248981181939E-03, 0.5317160915449039E-05, 0.8408398800007548E-04, 0.7876682708462645E-04, 0.0000000000000000E+00, 0.8939776288934402E-02, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + n0in: 21, + dmin: 7.8766827084626452E-005, + dmin1: 1.2363512593342330E-003, + dmin2: 1.2363512593342330E-003, + dn: 7.8766827084626452E-005, + dn1: 4.3867054272813191E-003, + dn2: 3.7622286348031123E-003, + tau: 0.0000000000000000, + ttype: -1, + g: 0.0000000000000000, + zOut: []float64{0.1648283185136998E+01, 0.1819554618764197E+01, 0.1712714336271993E+00, 0.1422045283129674E+00, 0.1510753432847732E+01, 0.1747828967872021E+01, 0.3792800633372563E+00, 0.2882727267008810E+00, 0.1328441621586708E+01, 0.1179068770857534E+01, 0.1388998759717073E+00, 0.5262264257308433E-01, 0.4466938077796418E+00, 0.1103391769983383E+01, 0.7093206047768255E+00, 0.4399127392187891E+00, 0.6843112870203156E+00, 0.8934568459457148E+00, 0.6490582981441884E+00, 0.3694451726238032E+00, 0.5085572738629487E+00, 0.1488623362931603E+00, 0.9750235054014829E-02, 0.8939776288934402E-02, 0.1364886053450573E+00, 0.1505610868415679E+00, 0.2301225778544498E-01, 0.2515816443301624E+00, 0.1646009972289452E+01, 0.1630679888773521E+01, 0.2362515608142310E+00, 0.8429943526342391E-01, 0.5818602562677768E+00, 0.5155374736992060E+00, 0.1797665269485310E-01, 0.1952851185677853E-01, 0.5600419521166516E+00, 0.7600271971854760E+00, 0.2195137569256029E+00, 0.1208458544696003E+00, 0.4184071984843414E+00, 0.5703477987440417E+00, 0.2727864547293006E+00, 0.3240053608004366E-01, 0.6774373914466536E-01, 0.1404399130020459E+00, 0.1050967099374242E+00, 0.1526865702536626E+00, 0.2040338718098096E+00, 0.1785445001043715E+00, 0.1271971985482246E+00, 0.3166486394939177E-01, 0.4444741998443960E-01, 0.5904153058501098E+00, 0.5776327498150620E+00, 0.3328891237445398E+00, 0.3402556968467140E+00, 0.1160231536652011E+00, 0.1086565805630269E+00, 0.8787251358464724E+00, 0.9382999256694983E+00, 0.8497373197790092E+00, 0.7901625299559836E+00, 0.5668475593321608E+00, 0.6095853796269167E+00, 0.8445503211335190E+00, 0.8018125008387630E+00, 0.2319542476253924E-01, 0.2443177602187348E-01, 0.2290193891046544E+00, 0.2277830378453201E+00, 0.6931459494493321E+00, 0.6969081780841352E+00, 0.8388628986069724E-01, 0.8012406122589412E-01, 0.9342352322344821E-01, 0.9781022865072954E-01, 0.4682830325399513E-02, 0.2961248981181939E-03, 0.5317160915449039E-05, 0.8408398800007548E-04, 0.7876682708462645E-04, 0.0000000000000000E+00, 0.8939776288934402E-02, 0.1037537856266618 - 321}, + tauOut: 0.0000000000000000, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1961759147077164E+01, 0.1819554618764197E+01, 0.1266970995487882E+00, 0.1422045283129674E+00, 0.1909404595024114E+01, 0.1747828967872021E+01, 0.1780101349021133E+00, 0.2882727267008810E+00, 0.1053681278528505E+01, 0.1179068770857534E+01, 0.5510526941411123E-01, 0.5262264257308433E-01, 0.1488199239788061E+01, 0.1103391769983383E+01, 0.2641064704009213E+00, 0.4399127392187891E+00, 0.9987955481685968E+00, 0.8934568459457148E+00, 0.5506279200968747E-01, 0.3694451726238032E+00, 0.1027393205724072E+00, 0.1488623362931603E+00, 0.1310094739466220E-01, 0.8939776288934402E-02, 0.3890417837770681E+00, 0.1505610868415679E+00, 0.1054511738587064E+01, 0.2515816443301624E+00, 0.6604675854498806E+00, 0.1630679888773521E+01, 0.6580113672099847E-01, 0.8429943526342391E-01, 0.4692648488349861E+00, 0.5155374736992060E+00, 0.3162862116895929E-01, 0.1952851185677853E-01, 0.8492444304861170E+00, 0.7600271971854760E+00, 0.8115939841327705E-01, 0.1208458544696003E+00, 0.5215889364108083E+00, 0.5703477987440417E+00, 0.8723974284448969E-02, 0.3240053608004366E-01, 0.2844025089712595E+00, 0.1404399130020459E+00, 0.9585480612390133E-01, 0.1526865702536626E+00, 0.1143545579298620E+00, 0.1785445001043715E+00, 0.1634864466429828E+00, 0.3166486394939177E-01, 0.7598179829516669E+00, 0.5904153058501098E+00, 0.5083170815153470E-01, 0.3328891237445398E+00, 0.9439165813601388E+00, 0.1160231536652011E+00, 0.7910503496831139E+00, 0.8787251358464724E+00, 0.6255345294280562E+00, 0.8497373197790092E+00, 0.7653155273545736E+00, 0.5668475593321608E+00, 0.1024302185414846E+00, 0.8445503211335190E+00, 0.5186166821452450E-01, 0.2319542476253924E-01, 0.8703036703394620E+00, 0.2290193891046544E+00, 0.6681052144545734E-01, 0.6931459494493321E+00, 0.1104992916386881E+00, 0.8388628986069724E-01, 0.3959179295799719E-02, 0.9342352322344821E-01, 0.7289681905152429E-03, 0.4682830325399513E-02, 0.5745324691222600E-06, 0.5317160915449039E-05, 0.7819229461550419E-04, 0.7876682708462645E-04, 0.8723974284448969E-02, 0.8939776288934402E-02}, + i0: 1, + n0: 21, + pp: 0, + n0in: 21, + dmin: 7.8192294615504193E-005, + dmin1: 7.2365102959979382E-004, + dmin2: 1.7075768415239889E-002, + dn: 7.8192294615504193E-005, + dn1: 7.2365102959979382E-004, + dn2: 1.7075768415239889E-002, + tau: 0.0000000000000000, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1961759147077164E+01, 0.1819554618764197E+01, 0.1266970995487882E+00, 0.1422045283129674E+00, 0.1909404595024114E+01, 0.1747828967872021E+01, 0.1780101349021133E+00, 0.2882727267008810E+00, 0.1053681278528505E+01, 0.1179068770857534E+01, 0.5510526941411123E-01, 0.5262264257308433E-01, 0.1488199239788061E+01, 0.1103391769983383E+01, 0.2641064704009213E+00, 0.4399127392187891E+00, 0.9987955481685968E+00, 0.8934568459457148E+00, 0.5506279200968747E-01, 0.3694451726238032E+00, 0.1027393205724072E+00, 0.1488623362931603E+00, 0.1310094739466220E-01, 0.8939776288934402E-02, 0.3890417837770681E+00, 0.1505610868415679E+00, 0.1054511738587064E+01, 0.2515816443301624E+00, 0.6604675854498806E+00, 0.1630679888773521E+01, 0.6580113672099847E-01, 0.8429943526342391E-01, 0.4692648488349861E+00, 0.5155374736992060E+00, 0.3162862116895929E-01, 0.1952851185677853E-01, 0.8492444304861170E+00, 0.7600271971854760E+00, 0.8115939841327705E-01, 0.1208458544696003E+00, 0.5215889364108083E+00, 0.5703477987440417E+00, 0.8723974284448969E-02, 0.3240053608004366E-01, 0.2844025089712595E+00, 0.1404399130020459E+00, 0.9585480612390133E-01, 0.1526865702536626E+00, 0.1143545579298620E+00, 0.1785445001043715E+00, 0.1634864466429828E+00, 0.3166486394939177E-01, 0.7598179829516669E+00, 0.5904153058501098E+00, 0.5083170815153470E-01, 0.3328891237445398E+00, 0.9439165813601388E+00, 0.1160231536652011E+00, 0.7910503496831139E+00, 0.8787251358464724E+00, 0.6255345294280562E+00, 0.8497373197790092E+00, 0.7653155273545736E+00, 0.5668475593321608E+00, 0.1024302185414846E+00, 0.8445503211335190E+00, 0.5186166821452450E-01, 0.2319542476253924E-01, 0.8703036703394620E+00, 0.2290193891046544E+00, 0.6681052144545734E-01, 0.6931459494493321E+00, 0.1104992916386881E+00, 0.8388628986069724E-01, 0.3959179295799719E-02, 0.9342352322344821E-01, 0.7289681905152429E-03, 0.4682830325399513E-02, 0.5745324691222600E-06, 0.5317160915449039E-05, 0.7819229461550419E-04, 0.7876682708462645E-04, 0.8723974284448969E-02, 0.8939776288934402E-02}, + tauOut: 7.8083356181667918E-005, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1961759147077164E+01, 0.2088378163269771E+01, 0.1266970995487882E+00, 0.1158391848322702E+00, 0.1909404595024114E+01, 0.1971497461737776E+01, 0.1780101349021133E+00, 0.9513882222772962E-01, 0.1053681278528505E+01, 0.1013569642358705E+01, 0.5510526941411123E-01, 0.8090970429970110E-01, 0.1488199239788061E+01, 0.1671317922533099E+01, 0.2641064704009213E+00, 0.1578325483874163E+00, 0.9987955481685968E+00, 0.8959477084346864E+00, 0.5506279200968747E-01, 0.6314111623521673E-02, 0.1027393205724072E+00, 0.1094480729873660E+00, 0.1310094739466220E-01, 0.4656834793406785E-01, 0.3890417837770681E+00, 0.1396907091073883E+01, 0.1054511738587064E+01, 0.4985806330739840E+00, 0.6604675854498806E+00, 0.2276100057407134E+00, 0.6580113672099847E-01, 0.1356625794022653E+00, 0.4692648488349861E+00, 0.3651528072454984E+00, 0.3162862116895929E-01, 0.7355942454424362E-01, 0.8492444304861170E+00, 0.8567663209989688E+00, 0.8115939841327705E-01, 0.4940885660487250E-01, 0.5215889364108083E+00, 0.4808259707342031E+00, 0.8723974284448969E-02, 0.5160120970399038E-02, 0.2844025089712595E+00, 0.3750191107685802E+00, 0.9585480612390133E-01, 0.2922900104287094E-01, 0.1143545579298620E+00, 0.2485339201737921E+00, 0.1634864466429828E+00, 0.4998108187459615E+00, 0.7598179829516669E+00, 0.3107607890010585E+00, 0.5083170815153470E-01, 0.1543981540828483E+00, 0.9439165813601388E+00, 0.1580490693604223E+01, 0.7910503496831139E+00, 0.3130858727896049E+00, 0.6255345294280562E+00, 0.1077686100636843E+01, 0.7653155273545736E+00, 0.7274051012980143E-01, 0.1024302185414846E+00, 0.8147329327002600E-01, 0.5186166821452450E-01, 0.5539901283655780E+00, 0.8703036703394620E+00, 0.3830459800631597E+00, 0.6681052144545734E-01, 0.1927318305890360E-01, 0.1104992916386881E+00, 0.9510720451940254E-01, 0.3959179295799719E-02, 0.3034592154998885E-04, 0.7289681905152429E-03, 0.6211134452527084E-03, 0.5745324691222600E-06, 0.7232819130731082E-07, 0.7819229461550419E-04, 0.3661024252896476E-07, 0.8723974284448969E-02, 0.5160120970399038E-02, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + n0in: 21, + dmin: 3.6610242528964756E-008, + dmin1: 6.2053891278358614E-004, + dmin2: 2.9611625055501498E-002, + dn: 3.6610242528964756E-008, + dn1: 6.2053891278358614E-004, + dn2: 9.1148025223602810E-002, + tau: 7.8083356181667918E-005, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.1961759147077164E+01, 0.2088378163269771E+01, 0.1266970995487882E+00, 0.1158391848322702E+00, 0.1909404595024114E+01, 0.1971497461737776E+01, 0.1780101349021133E+00, 0.9513882222772962E-01, 0.1053681278528505E+01, 0.1013569642358705E+01, 0.5510526941411123E-01, 0.8090970429970110E-01, 0.1488199239788061E+01, 0.1671317922533099E+01, 0.2641064704009213E+00, 0.1578325483874163E+00, 0.9987955481685968E+00, 0.8959477084346864E+00, 0.5506279200968747E-01, 0.6314111623521673E-02, 0.1027393205724072E+00, 0.1094480729873660E+00, 0.1310094739466220E-01, 0.4656834793406785E-01, 0.3890417837770681E+00, 0.1396907091073883E+01, 0.1054511738587064E+01, 0.4985806330739840E+00, 0.6604675854498806E+00, 0.2276100057407134E+00, 0.6580113672099847E-01, 0.1356625794022653E+00, 0.4692648488349861E+00, 0.3651528072454984E+00, 0.3162862116895929E-01, 0.7355942454424362E-01, 0.8492444304861170E+00, 0.8567663209989688E+00, 0.8115939841327705E-01, 0.4940885660487250E-01, 0.5215889364108083E+00, 0.4808259707342031E+00, 0.8723974284448969E-02, 0.5160120970399038E-02, 0.2844025089712595E+00, 0.3750191107685802E+00, 0.9585480612390133E-01, 0.2922900104287094E-01, 0.1143545579298620E+00, 0.2485339201737921E+00, 0.1634864466429828E+00, 0.4998108187459615E+00, 0.7598179829516669E+00, 0.3107607890010585E+00, 0.5083170815153470E-01, 0.1543981540828483E+00, 0.9439165813601388E+00, 0.1580490693604223E+01, 0.7910503496831139E+00, 0.3130858727896049E+00, 0.6255345294280562E+00, 0.1077686100636843E+01, 0.7653155273545736E+00, 0.7274051012980143E-01, 0.1024302185414846E+00, 0.8147329327002600E-01, 0.5186166821452450E-01, 0.5539901283655780E+00, 0.8703036703394620E+00, 0.3830459800631597E+00, 0.6681052144545734E-01, 0.1927318305890360E-01, 0.1104992916386881E+00, 0.9510720451940254E-01, 0.3959179295799719E-02, 0.3034592154998885E-04, 0.7289681905152429E-03, 0.6211134452527084E-03, 0.5745324691222600E-06, 0.7232819130731082E-07, 0.7819229461550419E-04, 0.3661024252896476E-07, 0.8723974284448969E-02, 0.5160120970399038E-02, 0.1037537856266618 - 321}, + tauOut: 3.6605973538398975E-008, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2204217311496068E+01, 0.2088378163269771E+01, 0.1036089580076783E+00, 0.1158391848322702E+00, 0.1963027289351853E+01, 0.1971497461737776E+01, 0.4912301654839819E-01, 0.9513882222772962E-01, 0.1045356293504034E+01, 0.1013569642358705E+01, 0.1293586117415210E+00, 0.8090970429970110E-01, 0.1699791822573021E+01, 0.1671317922533099E+01, 0.8319236989271818E-01, 0.1578325483874163E+00, 0.8190694135595162E+00, 0.8959477084346864E+00, 0.8437225690290790E-03, 0.6314111623521673E-02, 0.1551726617464312E+00, 0.1094480729873660E+00, 0.4192211096758560E+00, 0.4656834793406785E-01, 0.1476266577866037E+01, 0.1396907091073883E+01, 0.7687090018675194E-01, 0.4985806330739840E+00, 0.2864016483502532E+00, 0.2276100057407134E+00, 0.1729653861709652E+00, 0.1356625794022653E+00, 0.2657468090128033E+00, 0.3651528072454984E+00, 0.2371551996266359E+00, 0.7355942454424362E-01, 0.6690199413712319E+00, 0.8567663209989688E+00, 0.3551024412099299E-01, 0.4940885660487250E-01, 0.4504758109776356E+00, 0.4808259707342031E+00, 0.4295777776785939E-02, 0.5160120970399038E-02, 0.3999522974286917E+00, 0.3750191107685802E+00, 0.1816316160365039E-01, 0.2922900104287094E-01, 0.7301815407101296E+00, 0.2485339201737921E+00, 0.2127164214993764E+00, 0.4998108187459615E+00, 0.2524424849785568E+00, 0.3107607890010585E+00, 0.9666552191416621E+00, 0.1543981540828483E+00, 0.9269213106461920E+00, 0.1580490693604223E+01, 0.3640096408786760E+00, 0.3130858727896049E+00, 0.7864169332819952E+00, 0.1077686100636843E+01, 0.7535963003344312E-02, 0.7274051012980143E-01, 0.6279274220262862E+00, 0.8147329327002600E-01, 0.3379430237022286E+00, 0.5539901283655780E+00, 0.6437610281386123E-01, 0.3830459800631597E+00, 0.2847358698029713E-01, 0.1927318305890360E-01, 0.6666392685468185E-01, 0.9510720451940254E-01, 0.2827355178816361E-06, 0.3034592154998885E-04, 0.6208664319525956E-03, 0.6211134452527084E-03, 0.4264931214133004E-11, 0.7232819130731082E-07, 0.4059351646211308E-14, 0.3661024252896476E-07, 0.8437225690290790E-03, 0.5160120970399038E-02}, + i0: 1, + n0: 21, + pp: 0, + n0in: 21, + dmin: 4.0593516462113082E-015, + dmin1: 6.2079410376128833E-004, + dmin2: 4.5102919754957636E-002, + dn: 4.0593516462113082E-015, + dn1: 6.2079410376128833E-004, + dn2: 6.6633580933131861E-002, + tau: 3.6605973538398975E-008, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2204217311496068E+01, 0.2088378163269771E+01, 0.1036089580076783E+00, 0.1158391848322702E+00, 0.1963027289351853E+01, 0.1971497461737776E+01, 0.4912301654839819E-01, 0.9513882222772962E-01, 0.1045356293504034E+01, 0.1013569642358705E+01, 0.1293586117415210E+00, 0.8090970429970110E-01, 0.1699791822573021E+01, 0.1671317922533099E+01, 0.8319236989271818E-01, 0.1578325483874163E+00, 0.8190694135595162E+00, 0.8959477084346864E+00, 0.8437225690290790E-03, 0.6314111623521673E-02, 0.1551726617464312E+00, 0.1094480729873660E+00, 0.4192211096758560E+00, 0.4656834793406785E-01, 0.1476266577866037E+01, 0.1396907091073883E+01, 0.7687090018675194E-01, 0.4985806330739840E+00, 0.2864016483502532E+00, 0.2276100057407134E+00, 0.1729653861709652E+00, 0.1356625794022653E+00, 0.2657468090128033E+00, 0.3651528072454984E+00, 0.2371551996266359E+00, 0.7355942454424362E-01, 0.6690199413712319E+00, 0.8567663209989688E+00, 0.3551024412099299E-01, 0.4940885660487250E-01, 0.4504758109776356E+00, 0.4808259707342031E+00, 0.4295777776785939E-02, 0.5160120970399038E-02, 0.3999522974286917E+00, 0.3750191107685802E+00, 0.1816316160365039E-01, 0.2922900104287094E-01, 0.7301815407101296E+00, 0.2485339201737921E+00, 0.2127164214993764E+00, 0.4998108187459615E+00, 0.2524424849785568E+00, 0.3107607890010585E+00, 0.9666552191416621E+00, 0.1543981540828483E+00, 0.9269213106461920E+00, 0.1580490693604223E+01, 0.3640096408786760E+00, 0.3130858727896049E+00, 0.7864169332819952E+00, 0.1077686100636843E+01, 0.7535963003344312E-02, 0.7274051012980143E-01, 0.6279274220262862E+00, 0.8147329327002600E-01, 0.3379430237022286E+00, 0.5539901283655780E+00, 0.6437610281386123E-01, 0.3830459800631597E+00, 0.2847358698029713E-01, 0.1927318305890360E-01, 0.6666392685468185E-01, 0.9510720451940254E-01, 0.2827355178816361E-06, 0.3034592154998885E-04, 0.6208664319525956E-03, 0.6211134452527084E-03, 0.4264931214133004E-11, 0.7232819130731082E-07, 0.4059351646211308E-14, 0.3661024252896476E-07, 0.8437225690290790E-03, 0.5160120970399038E-02}, + tauOut: 4.0593516183260787E-015, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2204217311496068E+01, 0.2307826269503742E+01, 0.1036089580076783E+00, 0.8812934261040264E-01, 0.1963027289351853E+01, 0.1924020963289845E+01, 0.4912301654839819E-01, 0.2668944646890268E-01, 0.1045356293504034E+01, 0.1148025458776649E+01, 0.1293586117415210E+00, 0.1915312145184878E+00, 0.1699791822573021E+01, 0.1591452977947247E+01, 0.8319236989271818E-01, 0.4281642408847453E-01, 0.8190694135595162E+00, 0.7770967120400667E+00, 0.8437225690290790E-03, 0.1684766835109566E-03, 0.1551726617464312E+00, 0.5742252947387723E+00, 0.4192211096758560E+00, 0.1077768810640642E+01, 0.1476266577866037E+01, 0.4753686674121431E+00, 0.7687090018675194E-01, 0.4631342794110950E-01, 0.2864016483502532E+00, 0.4130536065801048E+00, 0.1729653861709652E+00, 0.1112809541240190E+00, 0.2657468090128033E+00, 0.3916210545154161E+00, 0.2371551996266359E+00, 0.4051405202062471E+00, 0.6690199413712319E+00, 0.2993896652859737E+00, 0.3551024412099299E-01, 0.5343038813025977E-01, 0.4504758109776356E+00, 0.4013412006241577E+00, 0.4295777776785939E-02, 0.4280911574482486E-02, 0.3999522974286917E+00, 0.4138345474578556E+00, 0.1816316160365039E-01, 0.3204760309498118E-01, 0.7301815407101296E+00, 0.9108503591145208E+00, 0.2127164214993764E+00, 0.5895442813598011E-01, 0.2524424849785568E+00, 0.1160143275984235E+01, 0.9666552191416621E+00, 0.7723298847804961E+00, 0.9269213106461920E+00, 0.5186010667443678E+00, 0.3640096408786760E+00, 0.5519914319921668E+00, 0.7864169332819952E+00, 0.2419614642931688E+00, 0.7535963003344312E-02, 0.1955698951896722E-01, 0.6279274220262862E+00, 0.9463134562095434E+00, 0.3379430237022286E+00, 0.2298969194226957E-01, 0.6437610281386123E-01, 0.6985999785188474E-01, 0.2847358698029713E-01, 0.2717093011896993E-01, 0.6666392685468185E-01, 0.3949327947122574E-01, 0.2827355178816361E-06, 0.4444831994804014E-08, 0.6208664319525956E-03, 0.6208619913814727E-03, 0.4264931214133004E-11, 0.2788519153273688E-22, 0.4059351646211308E-14, 0.3786532345060857E-28, 0.8437225690290790E-03, 0.1684766835109566E-03, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + n0in: 21, + dmin: 3.7865323450608567E-029, + dmin1: 6.2086198711654151E-004, + dmin2: 3.9492996735707858E-002, + dn: 3.7865323450608567E-029, + dn1: 6.2086198711654151E-004, + dn2: 3.9492996735707858E-002, + tau: 4.0593516183260787E-015, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2204217311496068E+01, 0.2307826269503742E+01, 0.1036089580076783E+00, 0.8812934261040264E-01, 0.1963027289351853E+01, 0.1924020963289845E+01, 0.4912301654839819E-01, 0.2668944646890268E-01, 0.1045356293504034E+01, 0.1148025458776649E+01, 0.1293586117415210E+00, 0.1915312145184878E+00, 0.1699791822573021E+01, 0.1591452977947247E+01, 0.8319236989271818E-01, 0.4281642408847453E-01, 0.8190694135595162E+00, 0.7770967120400667E+00, 0.8437225690290790E-03, 0.1684766835109566E-03, 0.1551726617464312E+00, 0.5742252947387723E+00, 0.4192211096758560E+00, 0.1077768810640642E+01, 0.1476266577866037E+01, 0.4753686674121431E+00, 0.7687090018675194E-01, 0.4631342794110950E-01, 0.2864016483502532E+00, 0.4130536065801048E+00, 0.1729653861709652E+00, 0.1112809541240190E+00, 0.2657468090128033E+00, 0.3916210545154161E+00, 0.2371551996266359E+00, 0.4051405202062471E+00, 0.6690199413712319E+00, 0.2993896652859737E+00, 0.3551024412099299E-01, 0.5343038813025977E-01, 0.4504758109776356E+00, 0.4013412006241577E+00, 0.4295777776785939E-02, 0.4280911574482486E-02, 0.3999522974286917E+00, 0.4138345474578556E+00, 0.1816316160365039E-01, 0.3204760309498118E-01, 0.7301815407101296E+00, 0.9108503591145208E+00, 0.2127164214993764E+00, 0.5895442813598011E-01, 0.2524424849785568E+00, 0.1160143275984235E+01, 0.9666552191416621E+00, 0.7723298847804961E+00, 0.9269213106461920E+00, 0.5186010667443678E+00, 0.3640096408786760E+00, 0.5519914319921668E+00, 0.7864169332819952E+00, 0.2419614642931688E+00, 0.7535963003344312E-02, 0.1955698951896722E-01, 0.6279274220262862E+00, 0.9463134562095434E+00, 0.3379430237022286E+00, 0.2298969194226957E-01, 0.6437610281386123E-01, 0.6985999785188474E-01, 0.2847358698029713E-01, 0.2717093011896993E-01, 0.6666392685468185E-01, 0.3949327947122574E-01, 0.2827355178816361E-06, 0.4444831994804014E-08, 0.6208664319525956E-03, 0.6208619913814727E-03, 0.4264931214133004E-11, 0.2788519153273688E-22, 0.4059351646211308E-14, 0.3786532345060857E-28, 0.8437225690290790E-03, 0.1684766835109566E-03, 0.1037537856266618 - 321}, + tauOut: 3.7865323450608567E-029, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2395955612114145E+01, 0.2307826269503742E+01, 0.7077038564739886E-01, 0.8812934261040264E-01, 0.1879940024111348E+01, 0.1924020963289845E+01, 0.1629847954401656E-01, 0.2668944646890268E-01, 0.1323258193751120E+01, 0.1148025458776649E+01, 0.2303502998543534E+00, 0.1915312145184878E+00, 0.1403919102181368E+01, 0.1591452977947247E+01, 0.2369972908607684E-01, 0.4281642408847453E-01, 0.7535654596375009E+00, 0.7770967120400667E+00, 0.1283811140869274E-03, 0.1684766835109566E-03, 0.1651865724265327E+01, 0.5742252947387723E+00, 0.3101568824672333E+00, 0.1077768810640642E+01, 0.2115252128860193E+00, 0.4753686674121431E+00, 0.9043805314343908E-01, 0.4631342794110950E-01, 0.4338965075606848E+00, 0.4130536065801048E+00, 0.1004386157577793E+00, 0.1112809541240190E+00, 0.6963229589638840E+00, 0.3916210545154161E+00, 0.1741934301847783E+00, 0.4051405202062471E+00, 0.1786266232314551E+00, 0.2993896652859737E+00, 0.1200482645536405E+00, 0.5343038813025977E-01, 0.2855738476449996E+00, 0.4013412006241577E+00, 0.6203611145567293E-02, 0.4280911574482486E-02, 0.4396785394072695E+00, 0.4138345474578556E+00, 0.6639071087521134E-01, 0.3204760309498118E-01, 0.9034140763752896E+00, 0.9108503591145208E+00, 0.7570790092830114E-01, 0.5895442813598011E-01, 0.1856765259836430E+01, 0.1160143275984235E+01, 0.2157144528657351E+00, 0.7723298847804961E+00, 0.8548780458707995E+00, 0.5186010667443678E+00, 0.1562335771835849E+00, 0.5519914319921668E+00, 0.1052848766285511E+00, 0.2419614642931688E+00, 0.1757806338135458E+00, 0.1955698951896722E-01, 0.7935225143382671E+00, 0.9463134562095434E+00, 0.2023962522401480E-02, 0.2298969194226957E-01, 0.9500696544845319E-01, 0.6985999785188474E-01, 0.1129463646814219E-01, 0.2717093011896993E-01, 0.2819864744791555E-01, 0.3949327947122574E-01, 0.9786381594178541E-10, 0.4444831994804014E-08, 0.6208618935176568E-03, 0.6208619913814727E-03, 0.1700670967075909E-47, 0.2788519153273688E-22}, + i0: 1, + n0: 20, + pp: 0, + n0in: 21, + dmin: 3.7865323450608567E-029, + dmin1: 6.2086189351765679E-004, + dmin2: 2.8198643003083550E-002, + dn: 3.7865323450608567E-029, + dn1: 6.2086189351765679E-004, + dn2: 2.8198643003083550E-002, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2395955612114145E+01, 0.2307826269503742E+01, 0.7077038564739886E-01, 0.8812934261040264E-01, 0.1879940024111348E+01, 0.1924020963289845E+01, 0.1629847954401656E-01, 0.2668944646890268E-01, 0.1323258193751120E+01, 0.1148025458776649E+01, 0.2303502998543534E+00, 0.1915312145184878E+00, 0.1403919102181368E+01, 0.1591452977947247E+01, 0.2369972908607684E-01, 0.4281642408847453E-01, 0.7535654596375009E+00, 0.7770967120400667E+00, 0.1283811140869274E-03, 0.1684766835109566E-03, 0.1651865724265327E+01, 0.5742252947387723E+00, 0.3101568824672333E+00, 0.1077768810640642E+01, 0.2115252128860193E+00, 0.4753686674121431E+00, 0.9043805314343908E-01, 0.4631342794110950E-01, 0.4338965075606848E+00, 0.4130536065801048E+00, 0.1004386157577793E+00, 0.1112809541240190E+00, 0.6963229589638840E+00, 0.3916210545154161E+00, 0.1741934301847783E+00, 0.4051405202062471E+00, 0.1786266232314551E+00, 0.2993896652859737E+00, 0.1200482645536405E+00, 0.5343038813025977E-01, 0.2855738476449996E+00, 0.4013412006241577E+00, 0.6203611145567293E-02, 0.4280911574482486E-02, 0.4396785394072695E+00, 0.4138345474578556E+00, 0.6639071087521134E-01, 0.3204760309498118E-01, 0.9034140763752896E+00, 0.9108503591145208E+00, 0.7570790092830114E-01, 0.5895442813598011E-01, 0.1856765259836430E+01, 0.1160143275984235E+01, 0.2157144528657351E+00, 0.7723298847804961E+00, 0.8548780458707995E+00, 0.5186010667443678E+00, 0.1562335771835849E+00, 0.5519914319921668E+00, 0.1052848766285511E+00, 0.2419614642931688E+00, 0.1757806338135458E+00, 0.1955698951896722E-01, 0.7935225143382671E+00, 0.9463134562095434E+00, 0.2023962522401480E-02, 0.2298969194226957E-01, 0.9500696544845319E-01, 0.6985999785188474E-01, 0.1129463646814219E-01, 0.2717093011896993E-01, 0.2819864744791555E-01, 0.3949327947122574E-01, 0.9786381594178541E-10, 0.4444831994804014E-08, 0.6208618935176568E-03, 0.6208619913814727E-03, 0.1700670967075909E-47, 0.2788519153273688E-22}, + tauOut: 0.0000000000000000, + ttypeOut: -7, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2395955612114145E+01, 0.2466725997761544E+01, 0.7077038564739886E-01, 0.5393549207373363E-01, 0.1879940024111348E+01, 0.1842303011581631E+01, 0.1629847954401656E-01, 0.1170659574821484E-01, 0.1323258193751120E+01, 0.1541901897857258E+01, 0.2303502998543534E+00, 0.2097365510789915E+00, 0.1403919102181368E+01, 0.1217882280188454E+01, 0.2369972908607684E-01, 0.1466422291592108E-01, 0.7535654596375009E+00, 0.7390296178356669E+00, 0.1283811140869274E-03, 0.2869551596920546E-03, 0.1651865724265327E+01, 0.1961735651572868E+01, 0.3101568824672333E+00, 0.3344283443049241E-01, 0.2115252128860193E+00, 0.2685204315989660E+00, 0.9043805314343908E-01, 0.1461369444993732E+00, 0.4338965075606848E+00, 0.3881981788190908E+00, 0.1004386157577793E+00, 0.1801598202532681E+00, 0.6963229589638840E+00, 0.6903565688953941E+00, 0.1741934301847783E+00, 0.4507175802324546E-01, 0.1786266232314551E+00, 0.2536031297618502E+00, 0.1200482645536405E+00, 0.1351822623162481E+00, 0.2855738476449996E+00, 0.1565951964743188E+00, 0.6203611145567293E-02, 0.1741812487831326E-01, 0.4396785394072695E+00, 0.4886511254041676E+00, 0.6639071087521134E-01, 0.1227425859208231E+00, 0.9034140763752896E+00, 0.8563793913827676E+00, 0.7570790092830114E-01, 0.1641466407918003E+00, 0.1856765259836430E+01, 0.1908333071910365E+01, 0.2157144528657351E+00, 0.9663383852973971E-01, 0.8548780458707995E+00, 0.9144777845246447E+00, 0.1562335771835849E+00, 0.1798735100772441E-01, 0.1052848766285511E+00, 0.2630781594343725E+00, 0.1757806338135458E+00, 0.5302070335887964E+00, 0.7935225143382671E+00, 0.2653394432718723E+00, 0.2023962522401480E-02, 0.7246963929058098E-03, 0.9500696544845319E-01, 0.1055769055236896E+00, 0.1129463646814219E-01, 0.3016696409481782E-02, 0.2819864744791555E-01, 0.2518195113629758E-01, 0.9786381594178541E-10, 0.2412835834031154E-11, 0.6208618935176568E-03, 0.6208618911048210E-03, 0.1700670967075909E-47, 0.2869551596920546E-03, 0.7811996215926567E-04}, + i0: 1, + n0: 20, + pp: 1, + n0in: 20, + dmin: 6.2086189110482101E-004, + dmin1: 2.5181951038433764E-002, + dmin2: 8.7297525620826724E-002, + dn: 6.2086189110482101E-004, + dn1: 2.5181951038433764E-002, + dn2: 9.4282269055547374E-002, + tau: 0.0000000000000000, + ttype: -7, + g: 0.0000000000000000, + zOut: []float64{0.2395955612114145E+01, 0.2466725997761544E+01, 0.7077038564739886E-01, 0.5393549207373363E-01, 0.1879940024111348E+01, 0.1842303011581631E+01, 0.1629847954401656E-01, 0.1170659574821484E-01, 0.1323258193751120E+01, 0.1541901897857258E+01, 0.2303502998543534E+00, 0.2097365510789915E+00, 0.1403919102181368E+01, 0.1217882280188454E+01, 0.2369972908607684E-01, 0.1466422291592108E-01, 0.7535654596375009E+00, 0.7390296178356669E+00, 0.1283811140869274E-03, 0.2869551596920546E-03, 0.1651865724265327E+01, 0.1961735651572868E+01, 0.3101568824672333E+00, 0.3344283443049241E-01, 0.2115252128860193E+00, 0.2685204315989660E+00, 0.9043805314343908E-01, 0.1461369444993732E+00, 0.4338965075606848E+00, 0.3881981788190908E+00, 0.1004386157577793E+00, 0.1801598202532681E+00, 0.6963229589638840E+00, 0.6903565688953941E+00, 0.1741934301847783E+00, 0.4507175802324546E-01, 0.1786266232314551E+00, 0.2536031297618502E+00, 0.1200482645536405E+00, 0.1351822623162481E+00, 0.2855738476449996E+00, 0.1565951964743188E+00, 0.6203611145567293E-02, 0.1741812487831326E-01, 0.4396785394072695E+00, 0.4886511254041676E+00, 0.6639071087521134E-01, 0.1227425859208231E+00, 0.9034140763752896E+00, 0.8563793913827676E+00, 0.7570790092830114E-01, 0.1641466407918003E+00, 0.1856765259836430E+01, 0.1908333071910365E+01, 0.2157144528657351E+00, 0.9663383852973971E-01, 0.8548780458707995E+00, 0.9144777845246447E+00, 0.1562335771835849E+00, 0.1798735100772441E-01, 0.1052848766285511E+00, 0.2630781594343725E+00, 0.1757806338135458E+00, 0.5302070335887964E+00, 0.7935225143382671E+00, 0.2653394432718723E+00, 0.2023962522401480E-02, 0.7246963929058098E-03, 0.9500696544845319E-01, 0.1055769055236896E+00, 0.1129463646814219E-01, 0.3016696409481782E-02, 0.2819864744791555E-01, 0.2518195113629758E-01, 0.9786381594178541E-10, 0.2412835834031154E-11, 0.6208618935176568E-03, 0.6208618911048210E-03, 0.1700670967075909E-47, 0.2869551596920546E-03, 0.7811996215926567E-04}, + tauOut: 6.2086189103875732E-004, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2520040627944239E+01, 0.2466725997761544E+01, 0.3943012599746679E-01, 0.5393549207373363E-01, 0.1813958619441340E+01, 0.1842303011581631E+01, 0.9950845630193767E-02, 0.1170659574821484E-01, 0.1741066741415017E+01, 0.1541901897857258E+01, 0.1467114516582776E+00, 0.2097365510789915E+00, 0.1085214189555058E+01, 0.1217882280188454E+01, 0.9986318978978259E-02, 0.1466422291592108E-01, 0.7287093921253419E+00, 0.7390296178356669E+00, 0.7725029665513934E-03, 0.2869551596920546E-03, 0.1993785121145770E+01, 0.1961735651572868E+01, 0.4504038193447841E-02, 0.3344283443049241E-01, 0.4095324760138526E+00, 0.2685204315989660E+00, 0.1385240464077977E+00, 0.1461369444993732E+00, 0.4292130907735224E+00, 0.3881981788190908E+00, 0.2897733504323247E+00, 0.1801598202532681E+00, 0.4450341145952761E+00, 0.6903565688953941E+00, 0.2568418582687495E-01, 0.4507175802324546E-01, 0.3624803443601846E+00, 0.2536031297618502E+00, 0.5840011260368079E-01, 0.1351822623162481E+00, 0.1149923468579125E+00, 0.1565951964743188E+00, 0.7401698075381481E-01, 0.1741812487831326E-01, 0.5367558686801371E+00, 0.4886511254041676E+00, 0.1958324578473516E+00, 0.1227425859208231E+00, 0.8240727124361776E+00, 0.8563793913827676E+00, 0.3801199318200257E+00, 0.1641466407918003E+00, 0.1624226116729040E+01, 0.1908333071910365E+01, 0.5440714051978934E-01, 0.9663383852973971E-01, 0.8774371331215411E+00, 0.9144777845246447E+00, 0.5393069221241477E-02, 0.1798735100772441E-01, 0.7872712619108886E+00, 0.2630781594343725E+00, 0.1786993199393658E+00, 0.5302070335887964E+00, 0.8674395783437358E-01, 0.2653394432718723E+00, 0.8820349511059155E-03, 0.7246963929058098E-03, 0.1070907050910267E+00, 0.1055769055236896E+00, 0.7093640994523618E-03, 0.3016696409481782E-02, 0.2385172514821930E-01, 0.2518195113629758E-01, 0.6280626703238275E-13, 0.2412835834031154E-11, 0.3257377007015450E-14, 0.6208618911048210E-03, 0.7725029665513934E-03, 0.2869551596920546E-03}, + i0: 1, + n0: 20, + pp: 0, + n0in: 20, + dmin: 3.2573770070154495E-015, + dmin1: 2.3851725145806461E-002, + dmin2: 8.6019261441467765E-002, + dn: 3.2573770070154495E-015, + dn1: 2.3851725145806461E-002, + dn2: 0.10407400868154487, + tau: 6.2086189103875732E-004, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2520040627944239E+01, 0.2466725997761544E+01, 0.3943012599746679E-01, 0.5393549207373363E-01, 0.1813958619441340E+01, 0.1842303011581631E+01, 0.9950845630193767E-02, 0.1170659574821484E-01, 0.1741066741415017E+01, 0.1541901897857258E+01, 0.1467114516582776E+00, 0.2097365510789915E+00, 0.1085214189555058E+01, 0.1217882280188454E+01, 0.9986318978978259E-02, 0.1466422291592108E-01, 0.7287093921253419E+00, 0.7390296178356669E+00, 0.7725029665513934E-03, 0.2869551596920546E-03, 0.1993785121145770E+01, 0.1961735651572868E+01, 0.4504038193447841E-02, 0.3344283443049241E-01, 0.4095324760138526E+00, 0.2685204315989660E+00, 0.1385240464077977E+00, 0.1461369444993732E+00, 0.4292130907735224E+00, 0.3881981788190908E+00, 0.2897733504323247E+00, 0.1801598202532681E+00, 0.4450341145952761E+00, 0.6903565688953941E+00, 0.2568418582687495E-01, 0.4507175802324546E-01, 0.3624803443601846E+00, 0.2536031297618502E+00, 0.5840011260368079E-01, 0.1351822623162481E+00, 0.1149923468579125E+00, 0.1565951964743188E+00, 0.7401698075381481E-01, 0.1741812487831326E-01, 0.5367558686801371E+00, 0.4886511254041676E+00, 0.1958324578473516E+00, 0.1227425859208231E+00, 0.8240727124361776E+00, 0.8563793913827676E+00, 0.3801199318200257E+00, 0.1641466407918003E+00, 0.1624226116729040E+01, 0.1908333071910365E+01, 0.5440714051978934E-01, 0.9663383852973971E-01, 0.8774371331215411E+00, 0.9144777845246447E+00, 0.5393069221241477E-02, 0.1798735100772441E-01, 0.7872712619108886E+00, 0.2630781594343725E+00, 0.1786993199393658E+00, 0.5302070335887964E+00, 0.8674395783437358E-01, 0.2653394432718723E+00, 0.8820349511059155E-03, 0.7246963929058098E-03, 0.1070907050910267E+00, 0.1055769055236896E+00, 0.7093640994523618E-03, 0.3016696409481782E-02, 0.2385172514821930E-01, 0.2518195113629758E-01, 0.6280626703238275E-13, 0.2412835834031154E-11, 0.3257377007015450E-14, 0.6208618911048210E-03, 0.7725029665513934E-03, 0.2869551596920546E-03}, + tauOut: 3.2573770070067200E-015, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2520040627944239E+01, 0.2559470753941703E+01, 0.3943012599746679E-01, 0.2794508075882943E-01, 0.1813958619441340E+01, 0.1795964384312701E+01, 0.9950845630193767E-02, 0.9646675917972324E-02, 0.1741066741415017E+01, 0.1878131517155319E+01, 0.1467114516582776E+00, 0.8477220453173254E-01, 0.1085214189555058E+01, 0.1010428304002300E+01, 0.9986318978978259E-02, 0.7202019583097946E-02, 0.7287093921253419E+00, 0.7222798755087921E+00, 0.7725029665513934E-03, 0.2132421202606784E-02, 0.1993785121145770E+01, 0.1996156738136608E+01, 0.4504038193447841E-02, 0.9240506410060376E-03, 0.4095324760138526E+00, 0.5471324717806409E+00, 0.1385240464077977E+00, 0.1086689918286978E+00, 0.4292130907735224E+00, 0.6103174493771462E+00, 0.2897733504323247E+00, 0.2112982785836522E+00, 0.4450341145952761E+00, 0.2594200218384955E+00, 0.2568418582687495E-01, 0.3588779484774172E-01, 0.3624803443601846E+00, 0.3849926621161204E+00, 0.5840011260368079E-01, 0.1744336104525046E-01, 0.1149923468579125E+00, 0.1715659665664736E+00, 0.7401698075381481E-01, 0.2315671901408358E+00, 0.5367558686801371E+00, 0.5010211363866497E+00, 0.1958324578473516E+00, 0.3221025481782661E+00, 0.8240727124361776E+00, 0.8820900960779340E+00, 0.3801199318200257E+00, 0.6999293195746292E+00, 0.1624226116729040E+01, 0.9787039376741966E+00, 0.5440714051978934E-01, 0.4877761656142095E-01, 0.8774371331215411E+00, 0.8340525857813585E+00, 0.5393069221241477E-02, 0.5090576402208483E-02, 0.7872712619108886E+00, 0.9608800054480426E+00, 0.1786993199393658E+00, 0.1613217694817542E-01, 0.8674395783437358E-01, 0.7149381583730083E-01, 0.8820349511059155E-03, 0.1321201613351008E-02, 0.1070907050910267E+00, 0.1064788675771248E+00, 0.7093640994523618E-03, 0.1589006148839502E-03, 0.2385172514821930E-01, 0.2369282453339490E-01, 0.6280626703238275E-13, 0.8634837515442557E-26, 0.3257377007015450E-14, 0.9466330862652142E-28, 0.7725029665513934E-03, 0.9240506410060376E-03, 0.7811996215926567E-04}, + i0: 1, + n0: 20, + pp: 1, + n0in: 20, + dmin: 9.4663308626521417E-029, + dmin1: 2.3692824533332088E-002, + dmin2: 7.0611780886194908E-002, + dn: 9.4663308626521417E-029, + dn1: 2.3692824533332088E-002, + dn2: 0.10576950347767239, + tau: 3.2573770070067200E-015, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2520040627944239E+01, 0.2559470753941703E+01, 0.3943012599746679E-01, 0.2794508075882943E-01, 0.1813958619441340E+01, 0.1795964384312701E+01, 0.9950845630193767E-02, 0.9646675917972324E-02, 0.1741066741415017E+01, 0.1878131517155319E+01, 0.1467114516582776E+00, 0.8477220453173254E-01, 0.1085214189555058E+01, 0.1010428304002300E+01, 0.9986318978978259E-02, 0.7202019583097946E-02, 0.7287093921253419E+00, 0.7222798755087921E+00, 0.7725029665513934E-03, 0.2132421202606784E-02, 0.1993785121145770E+01, 0.1996156738136608E+01, 0.4504038193447841E-02, 0.9240506410060376E-03, 0.4095324760138526E+00, 0.5471324717806409E+00, 0.1385240464077977E+00, 0.1086689918286978E+00, 0.4292130907735224E+00, 0.6103174493771462E+00, 0.2897733504323247E+00, 0.2112982785836522E+00, 0.4450341145952761E+00, 0.2594200218384955E+00, 0.2568418582687495E-01, 0.3588779484774172E-01, 0.3624803443601846E+00, 0.3849926621161204E+00, 0.5840011260368079E-01, 0.1744336104525046E-01, 0.1149923468579125E+00, 0.1715659665664736E+00, 0.7401698075381481E-01, 0.2315671901408358E+00, 0.5367558686801371E+00, 0.5010211363866497E+00, 0.1958324578473516E+00, 0.3221025481782661E+00, 0.8240727124361776E+00, 0.8820900960779340E+00, 0.3801199318200257E+00, 0.6999293195746292E+00, 0.1624226116729040E+01, 0.9787039376741966E+00, 0.5440714051978934E-01, 0.4877761656142095E-01, 0.8774371331215411E+00, 0.8340525857813585E+00, 0.5393069221241477E-02, 0.5090576402208483E-02, 0.7872712619108886E+00, 0.9608800054480426E+00, 0.1786993199393658E+00, 0.1613217694817542E-01, 0.8674395783437358E-01, 0.7149381583730083E-01, 0.8820349511059155E-03, 0.1321201613351008E-02, 0.1070907050910267E+00, 0.1064788675771248E+00, 0.7093640994523618E-03, 0.1589006148839502E-03, 0.2385172514821930E-01, 0.2369282453339490E-01, 0.6280626703238275E-13, 0.8634837515442557E-26, 0.3257377007015450E-14, 0.9466330862652142E-28, 0.7725029665513934E-03, 0.9240506410060376E-03, 0.7811996215926567E-04}, + tauOut: 9.4663308626521417E-029, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2587415834700532E+01, 0.2559470753941703E+01, 0.1939710234687058E-01, 0.2794508075882943E-01, 0.1786213957883803E+01, 0.1795964384312701E+01, 0.1014308840067055E-01, 0.9646675917972324E-02, 0.1952760633286381E+01, 0.1878131517155319E+01, 0.4386417535844126E-01, 0.8477220453173254E-01, 0.9737661482269571E+00, 0.1010428304002300E+01, 0.5342015449359675E-02, 0.7202019583097946E-02, 0.7190702812620393E+00, 0.7222798755087921E+00, 0.5919653562455767E-02, 0.2132421202606784E-02, 0.1991161135215158E+01, 0.1996156738136608E+01, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.6555475524103290E+00, 0.5471324717806409E+00, 0.1011712753337584E+00, 0.1086689918286978E+00, 0.7204444526270400E+00, 0.6103174493771462E+00, 0.7608498315828412E-01, 0.2112982785836522E+00, 0.2192228335279531E+00, 0.2594200218384955E+00, 0.6302508481237896E-01, 0.3588779484774172E-01, 0.3394109383489919E+00, 0.3849926621161204E+00, 0.8817297145618809E-02, 0.1744336104525046E-01, 0.3943158595616905E+00, 0.1715659665664736E+00, 0.2942312715577539E+00, 0.2315671901408358E+00, 0.5288924130071619E+00, 0.5010211363866497E+00, 0.5372046576619481E+00, 0.3221025481782661E+00, 0.1044814757990615E+01, 0.8820900960779340E+00, 0.6556411803358774E+00, 0.6999293195746292E+00, 0.3718403738997403E+00, 0.9787039376741966E+00, 0.1094101127175453E+00, 0.4877761656142095E-01, 0.7297330494660218E+00, 0.8340525857813585E+00, 0.6703044469024726E-02, 0.5090576402208483E-02, 0.9703091379271934E+00, 0.9608800054480426E+00, 0.1188642714683105E-02, 0.1613217694817542E-01, 0.7162637473596872E-01, 0.7149381583730083E-01, 0.1964081696850700E-02, 0.1321201613351008E-02, 0.1046736864951580E+00, 0.1064788675771248E+00, 0.3596705640885345E-04, 0.1589006148839502E-03, 0.2365685747698604E-01, 0.2369282453339490E-01, 0.3455244592226135E-52, 0.8634837515442557E-26}, + i0: 1, + n0: 19, + pp: 0, + n0in: 20, + dmin: 9.4663308626521417E-029, + dmin1: 2.3656857476986041E-002, + dmin2: 7.0305173122617720E-002, + dn: 9.4663308626521417E-029, + dn1: 2.3656857476986041E-002, + dn2: 0.10451478588027406, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2587415834700532E+01, 0.2559470753941703E+01, 0.1939710234687058E-01, 0.2794508075882943E-01, 0.1786213957883803E+01, 0.1795964384312701E+01, 0.1014308840067055E-01, 0.9646675917972324E-02, 0.1952760633286381E+01, 0.1878131517155319E+01, 0.4386417535844126E-01, 0.8477220453173254E-01, 0.9737661482269571E+00, 0.1010428304002300E+01, 0.5342015449359675E-02, 0.7202019583097946E-02, 0.7190702812620393E+00, 0.7222798755087921E+00, 0.5919653562455767E-02, 0.2132421202606784E-02, 0.1991161135215158E+01, 0.1996156738136608E+01, 0.2539111990097616E-03, 0.9240506410060376E-03, 0.6555475524103290E+00, 0.5471324717806409E+00, 0.1011712753337584E+00, 0.1086689918286978E+00, 0.7204444526270400E+00, 0.6103174493771462E+00, 0.7608498315828412E-01, 0.2112982785836522E+00, 0.2192228335279531E+00, 0.2594200218384955E+00, 0.6302508481237896E-01, 0.3588779484774172E-01, 0.3394109383489919E+00, 0.3849926621161204E+00, 0.8817297145618809E-02, 0.1744336104525046E-01, 0.3943158595616905E+00, 0.1715659665664736E+00, 0.2942312715577539E+00, 0.2315671901408358E+00, 0.5288924130071619E+00, 0.5010211363866497E+00, 0.5372046576619481E+00, 0.3221025481782661E+00, 0.1044814757990615E+01, 0.8820900960779340E+00, 0.6556411803358774E+00, 0.6999293195746292E+00, 0.3718403738997403E+00, 0.9787039376741966E+00, 0.1094101127175453E+00, 0.4877761656142095E-01, 0.7297330494660218E+00, 0.8340525857813585E+00, 0.6703044469024726E-02, 0.5090576402208483E-02, 0.9703091379271934E+00, 0.9608800054480426E+00, 0.1188642714683105E-02, 0.1613217694817542E-01, 0.7162637473596872E-01, 0.7149381583730083E-01, 0.1964081696850700E-02, 0.1321201613351008E-02, 0.1046736864951580E+00, 0.1064788675771248E+00, 0.3596705640885345E-04, 0.1589006148839502E-03, 0.2365685747698604E-01, 0.2369282453339490E-01, 0.3455244592226135E-52, 0.8634837515442557E-26}, + tauOut: 1.1828428738493020E-002, + ttypeOut: -9, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2587415834700532E+01, 0.2594984508308910E+01, 0.1939710234687058E-01, 0.1335166928493912E-01, 0.1786213957883803E+01, 0.1771176948261041E+01, 0.1014308840067055E-01, 0.1118297285215907E-01, 0.1952760633286381E+01, 0.1973613407054170E+01, 0.4386417535844126E-01, 0.2164225725832272E-01, 0.9737661482269571E+00, 0.9456374776795010E+00, 0.5342015449359675E-02, 0.4062111160297227E-02, 0.7190702812620393E+00, 0.7090993949257048E+00, 0.5919653562455767E-02, 0.1662247097070905E-01, 0.1991161135215158E+01, 0.1962964146704966E+01, 0.2539111990097616E-03, 0.8479567256479229E-04, 0.6555475524103290E+00, 0.7448056033330296E+00, 0.1011712753337584E+00, 0.9786215859981671E-01, 0.7204444526270400E+00, 0.6868388484470145E+00, 0.7608498315828412E-01, 0.2428454015756268E-01, 0.2192228335279531E+00, 0.2461349494442763E+00, 0.6302508481237896E-01, 0.8690924724014965E-01, 0.3394109383489919E+00, 0.2494905595159681E+00, 0.8817297145618809E-02, 0.1393559784278329E-01, 0.3943158595616905E+00, 0.6627831045381681E+00, 0.2942312715577539E+00, 0.2347927793131975E+00, 0.5288924130071619E+00, 0.8194758626174196E+00, 0.5372046576619481E+00, 0.6849248159595133E+00, 0.1044814757990615E+01, 0.1003702693628486E+01, 0.6556411803358774E+00, 0.2428944977310168E+00, 0.3718403738997403E+00, 0.2265275601477758E+00, 0.1094101127175453E+00, 0.3524523689025369E+00, 0.7297330494660218E+00, 0.3721552962940165E+00, 0.6703044469024726E-02, 0.1747664312451059E-01, 0.9703091379271934E+00, 0.9421927087788731E+00, 0.1188642714683105E-02, 0.9036173567869616E-04, 0.7162637473596872E-01, 0.6167166595864771E-01, 0.1964081696850700E-02, 0.3333583884775863E-02, 0.1046736864951580E+00, 0.8954764092829798E-01, 0.3596705640885345E-04, 0.9501841907954501E-05, 0.2365685747698604E-01, 0.1181892689658507E-01, 0.3455244592226135E-52, 0.8479567256479229E-04, 0.6989818532012803E-03}, + i0: 1, + n0: 19, + pp: 1, + n0in: 19, + dmin: 1.1818926896585069E-002, + dmin1: 5.9707584261797009E-002, + dmin2: 5.9707584261797009E-002, + dn: 1.1818926896585069E-002, + dn1: 8.9511673871889130E-002, + dn2: 5.9707584261797009E-002, + tau: 1.1828428738493020E-002, + ttype: -9, + g: 0.0000000000000000, + zOut: []float64{0.2587415834700532E+01, 0.2594984508308910E+01, 0.1939710234687058E-01, 0.1335166928493912E-01, 0.1786213957883803E+01, 0.1771176948261041E+01, 0.1014308840067055E-01, 0.1118297285215907E-01, 0.1952760633286381E+01, 0.1973613407054170E+01, 0.4386417535844126E-01, 0.2164225725832272E-01, 0.9737661482269571E+00, 0.9456374776795010E+00, 0.5342015449359675E-02, 0.4062111160297227E-02, 0.7190702812620393E+00, 0.7090993949257048E+00, 0.5919653562455767E-02, 0.1662247097070905E-01, 0.1991161135215158E+01, 0.1962964146704966E+01, 0.2539111990097616E-03, 0.8479567256479229E-04, 0.6555475524103290E+00, 0.7448056033330296E+00, 0.1011712753337584E+00, 0.9786215859981671E-01, 0.7204444526270400E+00, 0.6868388484470145E+00, 0.7608498315828412E-01, 0.2428454015756268E-01, 0.2192228335279531E+00, 0.2461349494442763E+00, 0.6302508481237896E-01, 0.8690924724014965E-01, 0.3394109383489919E+00, 0.2494905595159681E+00, 0.8817297145618809E-02, 0.1393559784278329E-01, 0.3943158595616905E+00, 0.6627831045381681E+00, 0.2942312715577539E+00, 0.2347927793131975E+00, 0.5288924130071619E+00, 0.8194758626174196E+00, 0.5372046576619481E+00, 0.6849248159595133E+00, 0.1044814757990615E+01, 0.1003702693628486E+01, 0.6556411803358774E+00, 0.2428944977310168E+00, 0.3718403738997403E+00, 0.2265275601477758E+00, 0.1094101127175453E+00, 0.3524523689025369E+00, 0.7297330494660218E+00, 0.3721552962940165E+00, 0.6703044469024726E-02, 0.1747664312451059E-01, 0.9703091379271934E+00, 0.9421927087788731E+00, 0.1188642714683105E-02, 0.9036173567869616E-04, 0.7162637473596872E-01, 0.6167166595864771E-01, 0.1964081696850700E-02, 0.3333583884775863E-02, 0.1046736864951580E+00, 0.8954764092829798E-01, 0.3596705640885345E-04, 0.9501841907954501E-05, 0.2365685747698604E-01, 0.1181892689658507E-01, 0.3455244592226135E-52, 0.8479567256479229E-04, 0.6989818532012803E-03}, + tauOut: 1.1689473904977585E-002, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2596646703688871E+01, 0.2594984508308910E+01, 0.9107195378059658E-02, 0.1335166928493912E-01, 0.1761563251830163E+01, 0.1771176948261041E+01, 0.1252913577120413E-01, 0.1118297285215907E-01, 0.1971037054636311E+01, 0.1973613407054170E+01, 0.1038322923301279E-01, 0.2164225725832272E-01, 0.9276268857018078E+00, 0.9456374776795010E+00, 0.3105171497598932E-02, 0.4062111160297227E-02, 0.7109272204938374E+00, 0.7090993949257048E+00, 0.4589684232723624E-01, 0.1662247097070905E-01, 0.1905462626145317E+01, 0.1962964146704966E+01, 0.3314486004504485E-04, 0.8479567256479229E-04, 0.8309451431678238E+00, 0.7448056033330296E+00, 0.8089045693556918E-01, 0.9786215859981671E-01, 0.6185434577640304E+00, 0.6868388484470145E+00, 0.9663466631053550E-02, 0.2428454015756268E-01, 0.3116912561483949E+00, 0.2461349494442763E+00, 0.6956575230565126E-01, 0.8690924724014965E-01, 0.1821709311481225E+00, 0.2494905595159681E+00, 0.5070116699532772E-01, 0.1393559784278329E-01, 0.8351852429510604E+00, 0.6627831045381681E+00, 0.2303764547900405E+00, 0.2347927793131975E+00, 0.1262334749881915E+01, 0.8194758626174196E+00, 0.5445947541061251E+00, 0.6849248159595133E+00, 0.6903129633483998E+00, 0.1003702693628486E+01, 0.7970630839299049E-01, 0.2428944977310168E+00, 0.4875841467523446E+00, 0.2265275601477758E+00, 0.2690141110044630E+00, 0.3524523689025369E+00, 0.1089283545090865E+00, 0.3721552962940165E+00, 0.1511669372043137E+00, 0.1747664312451059E-01, 0.7794266594052606E+00, 0.9421927087788731E+00, 0.7149818024536710E-05, 0.9036173567869616E-04, 0.5330862612042146E-01, 0.6167166595864771E-01, 0.5599742376476567E-02, 0.3333583884775863E-02, 0.7226792648875177E-01, 0.8954764092829798E-01, 0.1553961492315709E-05, 0.9501841907954501E-05, 0.1278990301151681E-03, 0.1181892689658507E-01, 0.7149818024536710E-05, 0.8479567256479229E-04}, + i0: 1, + n0: 19, + pp: 0, + n0in: 19, + dmin: 1.2789903011516807E-004, + dmin1: 4.9975042235645591E-002, + dmin2: 4.9975042235645591E-002, + dn: 1.2789903011516807E-004, + dn1: 7.2258424646843816E-002, + dn2: 4.9975042235645591E-002, + tau: 1.1689473904977585E-002, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2596646703688871E+01, 0.2594984508308910E+01, 0.9107195378059658E-02, 0.1335166928493912E-01, 0.1761563251830163E+01, 0.1771176948261041E+01, 0.1252913577120413E-01, 0.1118297285215907E-01, 0.1971037054636311E+01, 0.1973613407054170E+01, 0.1038322923301279E-01, 0.2164225725832272E-01, 0.9276268857018078E+00, 0.9456374776795010E+00, 0.3105171497598932E-02, 0.4062111160297227E-02, 0.7109272204938374E+00, 0.7090993949257048E+00, 0.4589684232723624E-01, 0.1662247097070905E-01, 0.1905462626145317E+01, 0.1962964146704966E+01, 0.3314486004504485E-04, 0.8479567256479229E-04, 0.8309451431678238E+00, 0.7448056033330296E+00, 0.8089045693556918E-01, 0.9786215859981671E-01, 0.6185434577640304E+00, 0.6868388484470145E+00, 0.9663466631053550E-02, 0.2428454015756268E-01, 0.3116912561483949E+00, 0.2461349494442763E+00, 0.6956575230565126E-01, 0.8690924724014965E-01, 0.1821709311481225E+00, 0.2494905595159681E+00, 0.5070116699532772E-01, 0.1393559784278329E-01, 0.8351852429510604E+00, 0.6627831045381681E+00, 0.2303764547900405E+00, 0.2347927793131975E+00, 0.1262334749881915E+01, 0.8194758626174196E+00, 0.5445947541061251E+00, 0.6849248159595133E+00, 0.6903129633483998E+00, 0.1003702693628486E+01, 0.7970630839299049E-01, 0.2428944977310168E+00, 0.4875841467523446E+00, 0.2265275601477758E+00, 0.2690141110044630E+00, 0.3524523689025369E+00, 0.1089283545090865E+00, 0.3721552962940165E+00, 0.1511669372043137E+00, 0.1747664312451059E-01, 0.7794266594052606E+00, 0.9421927087788731E+00, 0.7149818024536710E-05, 0.9036173567869616E-04, 0.5330862612042146E-01, 0.6167166595864771E-01, 0.5599742376476567E-02, 0.3333583884775863E-02, 0.7226792648875177E-01, 0.8954764092829798E-01, 0.1553961492315709E-05, 0.9501841907954501E-05, 0.1278990301151681E-03, 0.1181892689658507E-01, 0.7149818024536710E-05, 0.8479567256479229E-04}, + tauOut: 1.1689473904977585E-002, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2596646703688871E+01, 0.2605626003858251E+01, 0.9107195378059658E-02, 0.6157023564192275E-02, 0.1761563251830163E+01, 0.1767807468828494E+01, 0.1252913577120413E-01, 0.1396950250695455E-01, 0.1971037054636311E+01, 0.1967322886153689E+01, 0.1038322923301279E-01, 0.4895872794820515E-02, 0.9276268857018078E+00, 0.9257082891959054E+00, 0.3105171497598932E-02, 0.2384715539127593E-02, 0.7109272204938374E+00, 0.7543114520732653E+00, 0.4589684232723624E-01, 0.1159397984377132E+00, 0.1905462626145317E+01, 0.1789428077358968E+01, 0.3314486004504485E-04, 0.1539126429493388E-04, 0.8309451431678238E+00, 0.9116923136304173E+00, 0.8089045693556918E-01, 0.5488064578914756E-01, 0.6185434577640304E+00, 0.5731983833972557E+00, 0.9663466631053550E-02, 0.5254756712901782E-02, 0.3116912561483949E+00, 0.3758743565324636E+00, 0.6956575230565126E-01, 0.3371567560620648E-01, 0.1821709311481225E+00, 0.1990285273285630E+00, 0.5070116699532772E-01, 0.2127577741907859E+00, 0.8351852429510604E+00, 0.8526760283416343E+00, 0.2303764547900405E+00, 0.3410582621885915E+00, 0.1262334749881915E+01, 0.1465743346590768E+01, 0.5445947541061251E+00, 0.2564847518533230E+00, 0.6903129633483998E+00, 0.5134066246793865E+00, 0.7970630839299049E-01, 0.7569737222001199E-01, 0.4875841467523446E+00, 0.6807729903281149E+00, 0.2690141110044630E+00, 0.4304410555024735E-01, 0.1089283545090865E+00, 0.2169232909544721E+00, 0.1511669372043137E+00, 0.5431576312495270E+00, 0.7794266594052606E+00, 0.2361482827650774E+00, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.5330862612042146E-01, 0.5877885927277143E-01, 0.5599742376476567E-02, 0.6884818375619963E-02, 0.7226792648875177E-01, 0.6525676686594341E-01, 0.1553961492315709E-05, 0.3045663725752605E-08, 0.1278990301151681E-03, 0.7757707209639971E-09, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.6989818532012803E-03}, + i0: 1, + n0: 19, + pp: 1, + n0in: 19, + dmin: 7.7577072096399712E-010, + dmin1: 5.3179116896294863E-002, + dmin2: 5.3179116896294863E-002, + dn: 7.7577072096399712E-010, + dn1: 6.5255212904451090E-002, + dn2: 5.3179116896294863E-002, + tau: 1.2789520868072135E-004, + ttype: -15, + g: 0.0000000000000000, + zOut: []float64{0.2596646703688871E+01, 0.2605626003858251E+01, 0.9107195378059658E-02, 0.6157023564192275E-02, 0.1761563251830163E+01, 0.1767807468828494E+01, 0.1252913577120413E-01, 0.1396950250695455E-01, 0.1971037054636311E+01, 0.1967322886153689E+01, 0.1038322923301279E-01, 0.4895872794820515E-02, 0.9276268857018078E+00, 0.9257082891959054E+00, 0.3105171497598932E-02, 0.2384715539127593E-02, 0.7109272204938374E+00, 0.7543114520732653E+00, 0.4589684232723624E-01, 0.1159397984377132E+00, 0.1905462626145317E+01, 0.1789428077358968E+01, 0.3314486004504485E-04, 0.1539126429493388E-04, 0.8309451431678238E+00, 0.9116923136304173E+00, 0.8089045693556918E-01, 0.5488064578914756E-01, 0.6185434577640304E+00, 0.5731983833972557E+00, 0.9663466631053550E-02, 0.5254756712901782E-02, 0.3116912561483949E+00, 0.3758743565324636E+00, 0.6956575230565126E-01, 0.3371567560620648E-01, 0.1821709311481225E+00, 0.1990285273285630E+00, 0.5070116699532772E-01, 0.2127577741907859E+00, 0.8351852429510604E+00, 0.8526760283416343E+00, 0.2303764547900405E+00, 0.3410582621885915E+00, 0.1262334749881915E+01, 0.1465743346590768E+01, 0.5445947541061251E+00, 0.2564847518533230E+00, 0.6903129633483998E+00, 0.5134066246793865E+00, 0.7970630839299049E-01, 0.7569737222001199E-01, 0.4875841467523446E+00, 0.6807729903281149E+00, 0.2690141110044630E+00, 0.4304410555024735E-01, 0.1089283545090865E+00, 0.2169232909544721E+00, 0.1511669372043137E+00, 0.5431576312495270E+00, 0.7794266594052606E+00, 0.2361482827650774E+00, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.5330862612042146E-01, 0.5877885927277143E-01, 0.5599742376476567E-02, 0.6884818375619963E-02, 0.7226792648875177E-01, 0.6525676686594341E-01, 0.1553961492315709E-05, 0.3045663725752605E-08, 0.1278990301151681E-03, 0.7757707209639971E-09, 0.7149818024536710E-05, 0.1614015445872399E-05, 0.6989818532012803E-03}, + tauOut: 1.2789520868072135E-004, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2611783026646672E+01, 0.2605626003858251E+01, 0.4167433562238479E-02, 0.6157023564192275E-02, 0.1777609536997439E+01, 0.1767807468828494E+01, 0.1546038171944878E-01, 0.1396950250695455E-01, 0.1956758376453290E+01, 0.1967322886153689E+01, 0.2316152103168096E-02, 0.4895872794820515E-02, 0.9257768518560943E+00, 0.9257082891959054E+00, 0.1943036529261404E-02, 0.2384715539127593E-02, 0.8683082132059464E+00, 0.7543114520732653E+00, 0.2389312083572061E+00, 0.1159397984377132E+00, 0.1550512259490286E+01, 0.1789428077358968E+01, 0.9049975109102588E-05, 0.1539126429493388E-04, 0.9665639086686850E+00, 0.9116923136304173E+00, 0.3254569838994440E-01, 0.5488064578914756E-01, 0.5459074409444424E+00, 0.5731983833972557E+00, 0.3618064437406363E-02, 0.5254756712901782E-02, 0.4059719669254931E+00, 0.3758743565324636E+00, 0.1652917395900484E-01, 0.3371567560620648E-01, 0.3952571267845734E+00, 0.1990285273285630E+00, 0.4589757947481138E+00, 0.2127577741907859E+00, 0.7347584950063413E+00, 0.8526760283416343E+00, 0.6803648845168142E+00, 0.3410582621885915E+00, 0.1041863213151506E+01, 0.1465743346590768E+01, 0.1263898840735783E+00, 0.2564847518533230E+00, 0.4627141120500496E+00, 0.5134066246793865E+00, 0.1113705527974558E+00, 0.7569737222001199E-01, 0.6124465423051357E+00, 0.6807729903281149E+00, 0.1524585149425051E-01, 0.4304410555024735E-01, 0.7448350699339780E+00, 0.2169232909544721E+00, 0.1722069046798406E+00, 0.5431576312495270E+00, 0.6394299132491200E-01, 0.2361482827650774E+00, 0.1483665133446019E-05, 0.1614015445872399E-05, 0.6566219320748727E-01, 0.5877885927277143E-01, 0.6842308575232983E-02, 0.6884818375619963E-02, 0.5841446056060346E-01, 0.6525676686594341E-01, 0.4044780558898965E-16, 0.3045663725752605E-08, 0.1013559914197710E-18, 0.7757707209639971E-09, 0.1483665133446019E-05, 0.1614015445872399E-05}, + i0: 1, + n0: 19, + pp: 0, + n0in: 19, + dmin: 1.0135599141977102E-019, + dmin1: 5.8414457514939733E-002, + dmin2: 5.8777374831867304E-002, + dn: 1.0135599141977102E-019, + dn1: 5.8414457514939733E-002, + dn2: 5.8777374831867304E-002, + tau: 7.7577068041483555E-010, + ttype: -15, + g: 0.0000000000000000, + zOut: []float64{0.2611783026646672E+01, 0.2605626003858251E+01, 0.4167433562238479E-02, 0.6157023564192275E-02, 0.1777609536997439E+01, 0.1767807468828494E+01, 0.1546038171944878E-01, 0.1396950250695455E-01, 0.1956758376453290E+01, 0.1967322886153689E+01, 0.2316152103168096E-02, 0.4895872794820515E-02, 0.9257768518560943E+00, 0.9257082891959054E+00, 0.1943036529261404E-02, 0.2384715539127593E-02, 0.8683082132059464E+00, 0.7543114520732653E+00, 0.2389312083572061E+00, 0.1159397984377132E+00, 0.1550512259490286E+01, 0.1789428077358968E+01, 0.9049975109102588E-05, 0.1539126429493388E-04, 0.9665639086686850E+00, 0.9116923136304173E+00, 0.3254569838994440E-01, 0.5488064578914756E-01, 0.5459074409444424E+00, 0.5731983833972557E+00, 0.3618064437406363E-02, 0.5254756712901782E-02, 0.4059719669254931E+00, 0.3758743565324636E+00, 0.1652917395900484E-01, 0.3371567560620648E-01, 0.3952571267845734E+00, 0.1990285273285630E+00, 0.4589757947481138E+00, 0.2127577741907859E+00, 0.7347584950063413E+00, 0.8526760283416343E+00, 0.6803648845168142E+00, 0.3410582621885915E+00, 0.1041863213151506E+01, 0.1465743346590768E+01, 0.1263898840735783E+00, 0.2564847518533230E+00, 0.4627141120500496E+00, 0.5134066246793865E+00, 0.1113705527974558E+00, 0.7569737222001199E-01, 0.6124465423051357E+00, 0.6807729903281149E+00, 0.1524585149425051E-01, 0.4304410555024735E-01, 0.7448350699339780E+00, 0.2169232909544721E+00, 0.1722069046798406E+00, 0.5431576312495270E+00, 0.6394299132491200E-01, 0.2361482827650774E+00, 0.1483665133446019E-05, 0.1614015445872399E-05, 0.6566219320748727E-01, 0.5877885927277143E-01, 0.6842308575232983E-02, 0.6884818375619963E-02, 0.5841446056060346E-01, 0.6525676686594341E-01, 0.4044780558898965E-16, 0.3045663725752605E-08, 0.1013559914197710E-18, 0.7757707209639971E-09, 0.1483665133446019E-05, 0.1614015445872399E-05}, + tauOut: 1.0135599141977091E-019, + ttypeOut: -2, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2611783026646672E+01, 0.2615950460208911E+01, 0.4167433562238479E-02, 0.2831884532112553E-02, 0.1777609536997439E+01, 0.1790238034184775E+01, 0.1546038171944878E-01, 0.1689844079671380E-01, 0.1956758376453290E+01, 0.1942176087759744E+01, 0.2316152103168096E-02, 0.1104039956008399E-02, 0.9257768518560943E+00, 0.9266158484293474E+00, 0.1943036529261404E-02, 0.1820770257466081E-02, 0.8683082132059464E+00, 0.1105418651305687E+01, 0.2389312083572061E+00, 0.3351361651941490E+00, 0.1550512259490286E+01, 0.1215385144271246E+01, 0.9049975109102588E-05, 0.7197207696703830E-05, 0.9665639086686850E+00, 0.9991024098509327E+00, 0.3254569838994440E-01, 0.1778290067827487E-01, 0.5459074409444424E+00, 0.5317426047035739E+00, 0.3618064437406363E-02, 0.2762300261676148E-02, 0.4059719669254931E+00, 0.4197388406228219E+00, 0.1652917395900484E-01, 0.1556509232613395E-01, 0.3952571267845734E+00, 0.8386678292065533E+00, 0.4589757947481138E+00, 0.4021095747913879E+00, 0.7347584950063413E+00, 0.1013013804731768E+01, 0.6803648845168142E+00, 0.6997408538631263E+00, 0.1041863213151506E+01, 0.4685122433619579E+00, 0.1263898840735783E+00, 0.1248257304047288E+00, 0.4627141120500496E+00, 0.4492589344427766E+00, 0.1113705527974558E+00, 0.1518244930621437E+00, 0.6124465423051357E+00, 0.4758679007372426E+00, 0.1524585149425051E-01, 0.2386301922514691E-01, 0.7448350699339780E+00, 0.8931789553886716E+00, 0.1722069046798406E+00, 0.1232835205710967E-01, 0.6394299132491200E-01, 0.5161612293293578E-01, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6566219320748727E-01, 0.7250261437426894E-01, 0.6842308575232983E-02, 0.5512763475647510E-02, 0.5841446056060346E-01, 0.5290169708495600E-01, 0.4044780558898965E-16, 0.7749519698096867E-34, 0.2434478048112329E-01}, + i0: 1, + n0: 18, + pp: 1, + n0in: 19, + dmin: 1.0135599141977093E-019, + dmin1: 5.1614639267802333E-002, + dmin2: 5.1614639267802333E-002, + dn: 1.0135599141977093E-019, + dn1: 5.2901697084955956E-002, + dn2: 6.5660305799035965E-002, + tau: 0.0000000000000000, + ttype: -2, + g: 0.0000000000000000, + zOut: []float64{0.2611783026646672E+01, 0.2615950460208911E+01, 0.4167433562238479E-02, 0.2831884532112553E-02, 0.1777609536997439E+01, 0.1790238034184775E+01, 0.1546038171944878E-01, 0.1689844079671380E-01, 0.1956758376453290E+01, 0.1942176087759744E+01, 0.2316152103168096E-02, 0.1104039956008399E-02, 0.9257768518560943E+00, 0.9266158484293474E+00, 0.1943036529261404E-02, 0.1820770257466081E-02, 0.8683082132059464E+00, 0.1105418651305687E+01, 0.2389312083572061E+00, 0.3351361651941490E+00, 0.1550512259490286E+01, 0.1215385144271246E+01, 0.9049975109102588E-05, 0.7197207696703830E-05, 0.9665639086686850E+00, 0.9991024098509327E+00, 0.3254569838994440E-01, 0.1778290067827487E-01, 0.5459074409444424E+00, 0.5317426047035739E+00, 0.3618064437406363E-02, 0.2762300261676148E-02, 0.4059719669254931E+00, 0.4197388406228219E+00, 0.1652917395900484E-01, 0.1556509232613395E-01, 0.3952571267845734E+00, 0.8386678292065533E+00, 0.4589757947481138E+00, 0.4021095747913879E+00, 0.7347584950063413E+00, 0.1013013804731768E+01, 0.6803648845168142E+00, 0.6997408538631263E+00, 0.1041863213151506E+01, 0.4685122433619579E+00, 0.1263898840735783E+00, 0.1248257304047288E+00, 0.4627141120500496E+00, 0.4492589344427766E+00, 0.1113705527974558E+00, 0.1518244930621437E+00, 0.6124465423051357E+00, 0.4758679007372426E+00, 0.1524585149425051E-01, 0.2386301922514691E-01, 0.7448350699339780E+00, 0.8931789553886716E+00, 0.1722069046798406E+00, 0.1232835205710967E-01, 0.6394299132491200E-01, 0.5161612293293578E-01, 0.1483665133446019E-05, 0.1887408451311279E-05, 0.6566219320748727E-01, 0.7250261437426894E-01, 0.6842308575232983E-02, 0.5512763475647510E-02, 0.5841446056060346E-01, 0.5290169708495600E-01, 0.4044780558898965E-16, 0.7749519698096867E-34, 0.2434478048112329E-01}, + tauOut: 1.2903659816950583E-002, + ttypeOut: -9, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2605878684924073E+01, 0.2615950460208911E+01, 0.1945503997226627E-02, 0.2831884532112553E-02, 0.1792287311167312E+01, 0.1790238034184775E+01, 0.1831165540887852E-01, 0.1689844079671380E-01, 0.1912064812489923E+01, 0.1942176087759744E+01, 0.5350346462390188E-03, 0.1104039956008399E-02, 0.9149979242236238E+00, 0.9266158484293474E+00, 0.2199691768758329E-02, 0.1820770257466081E-02, 0.1425451464914127E+01, 0.1105418651305687E+01, 0.2857477273065492E+00, 0.3351361651941490E+00, 0.9167409543554429E+00, 0.1215385144271246E+01, 0.7843816205451699E-05, 0.7197207696703830E-05, 0.1003973806896052E+01, 0.9991024098509327E+00, 0.9418498631040351E-02, 0.1778290067827487E-01, 0.5121827465172590E+00, 0.5317426047035739E+00, 0.2263732461064059E-02, 0.2762300261676148E-02, 0.4201365406709412E+00, 0.4197388406228219E+00, 0.3107071375346623E-01, 0.1556509232613395E-01, 0.1196803030427524E+01, 0.8386678292065533E+00, 0.3403588894097180E+00, 0.4021095747913879E+00, 0.1359492109368225E+01, 0.1013013804731768E+01, 0.2411467892724848E+00, 0.6997408538631263E+00, 0.3392875246772514E+00, 0.4685122433619579E+00, 0.1652848117124708E+00, 0.1248257304047288E+00, 0.4228949559754990E+00, 0.4492589344427766E+00, 0.1708424320817961E+00, 0.1518244930621437E+00, 0.3159848280636428E+00, 0.4758679007372426E+00, 0.6745243660763246E-01, 0.2386301922514691E-01, 0.8251512110211983E+00, 0.8931789553886716E+00, 0.7711819686391232E-03, 0.1232835205710967E-01, 0.3794316855579739E-01, 0.5161612293293578E-01, 0.3606500256058598E-05, 0.1887408451311279E-05, 0.6510811153270980E-01, 0.7250261437426894E-01, 0.4479235177066975E-02, 0.5512763475647510E-02, 0.3551880209093845E-01, 0.5290169708495600E-01, 0.7843816205451699E-05, 0.7197207696703830E-05}, + i0: 1, + n0: 18, + pp: 0, + n0in: 18, + dmin: 3.5518802090938446E-002, + dmin1: 3.7941281147346073E-002, + dmin2: 3.7941281147346073E-002, + dn: 3.5518802090938446E-002, + dn1: 5.9595348057062299E-002, + dn2: 3.7941281147346073E-002, + tau: 1.2903659816950583E-002, + ttype: -9, + g: 0.0000000000000000, + zOut: []float64{0.2605878684924073E+01, 0.2615950460208911E+01, 0.1945503997226627E-02, 0.2831884532112553E-02, 0.1792287311167312E+01, 0.1790238034184775E+01, 0.1831165540887852E-01, 0.1689844079671380E-01, 0.1912064812489923E+01, 0.1942176087759744E+01, 0.5350346462390188E-03, 0.1104039956008399E-02, 0.9149979242236238E+00, 0.9266158484293474E+00, 0.2199691768758329E-02, 0.1820770257466081E-02, 0.1425451464914127E+01, 0.1105418651305687E+01, 0.2857477273065492E+00, 0.3351361651941490E+00, 0.9167409543554429E+00, 0.1215385144271246E+01, 0.7843816205451699E-05, 0.7197207696703830E-05, 0.1003973806896052E+01, 0.9991024098509327E+00, 0.9418498631040351E-02, 0.1778290067827487E-01, 0.5121827465172590E+00, 0.5317426047035739E+00, 0.2263732461064059E-02, 0.2762300261676148E-02, 0.4201365406709412E+00, 0.4197388406228219E+00, 0.3107071375346623E-01, 0.1556509232613395E-01, 0.1196803030427524E+01, 0.8386678292065533E+00, 0.3403588894097180E+00, 0.4021095747913879E+00, 0.1359492109368225E+01, 0.1013013804731768E+01, 0.2411467892724848E+00, 0.6997408538631263E+00, 0.3392875246772514E+00, 0.4685122433619579E+00, 0.1652848117124708E+00, 0.1248257304047288E+00, 0.4228949559754990E+00, 0.4492589344427766E+00, 0.1708424320817961E+00, 0.1518244930621437E+00, 0.3159848280636428E+00, 0.4758679007372426E+00, 0.6745243660763246E-01, 0.2386301922514691E-01, 0.8251512110211983E+00, 0.8931789553886716E+00, 0.7711819686391232E-03, 0.1232835205710967E-01, 0.3794316855579739E-01, 0.5161612293293578E-01, 0.3606500256058598E-05, 0.1887408451311279E-05, 0.6510811153270980E-01, 0.7250261437426894E-01, 0.4479235177066975E-02, 0.5512763475647510E-02, 0.3551880209093845E-01, 0.5290169708495600E-01, 0.7843816205451699E-05, 0.7197207696703830E-05}, + tauOut: 2.4222106054237202E-002, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.2605878684924073E+01, 0.2583602082867062E+01, 0.1945503997226627E-02, 0.1349628161076996E-02, 0.1792287311167312E+01, 0.1785027232360876E+01, 0.1831165540887852E-01, 0.1961486711855321E-01, 0.1912064812489923E+01, 0.1868762873963372E+01, 0.5350346462390188E-03, 0.2619677421449130E-03, 0.9149979242236238E+00, 0.8927135421960001E+00, 0.2199691768758329E-02, 0.3512385223173503E-02, 0.1425451464914127E+01, 0.1683464700943265E+01, 0.2857477273065492E+00, 0.1556056649653108E+00, 0.9167409543554429E+00, 0.7369210271521004E+00, 0.7843816205451699E-05, 0.1068633642713914E-04, 0.1003973806896052E+01, 0.9891595131364276E+00, 0.9418498631040351E-02, 0.4876860034049891E-02, 0.5121827465172590E+00, 0.4853475128900360E+00, 0.2263732461064059E-02, 0.1959578858316830E-02, 0.4201365406709412E+00, 0.4250255695118534E+00, 0.3107071375346623E-01, 0.8749008776201990E-01, 0.1196803030427524E+01, 0.1425449726020986E+01, 0.3403588894097180E+00, 0.3246099922425689E+00, 0.1359492109368225E+01, 0.1251806800343904E+01, 0.2411467892724848E+00, 0.6536000379104072E-01, 0.3392875246772514E+00, 0.4149902265444443E+00, 0.1652848117124708E+00, 0.1684331550518530E+00, 0.4228949559754990E+00, 0.4010821269512049E+00, 0.1708424320817961E+00, 0.1345949193440586E+00, 0.3159848280636428E+00, 0.2246202392729794E+00, 0.6745243660763246E-01, 0.2477891570824889E+00, 0.8251512110211983E+00, 0.5539111298531113E+00, 0.7711819686391232E-03, 0.5282632149136541E-04, 0.3794316855579739E-01, 0.1367184268032488E-01, 0.3606500256058598E-05, 0.1717489195894037E-04, 0.6510811153270980E-01, 0.4534806576358064E-01, 0.4479235177066975E-02, 0.3508353996892708E-02, 0.3551880209093845E-01, 0.7788342039808532E-02, 0.7843816205451699E-05, 0.1068633642713914E-04, 0.2434478048112329E-01}, + i0: 1, + n0: 18, + pp: 1, + n0in: 18, + dmin: 7.7883420398085317E-003, + dmin1: 1.3668236180068825E-002, + dmin2: 1.3668236180068825E-002, + dn: 7.7883420398085317E-003, + dn1: 4.0868830586513666E-002, + dn2: 1.3668236180068825E-002, + tau: 2.4222106054237202E-002, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.2605878684924073E+01, 0.2583602082867062E+01, 0.1945503997226627E-02, 0.1349628161076996E-02, 0.1792287311167312E+01, 0.1785027232360876E+01, 0.1831165540887852E-01, 0.1961486711855321E-01, 0.1912064812489923E+01, 0.1868762873963372E+01, 0.5350346462390188E-03, 0.2619677421449130E-03, 0.9149979242236238E+00, 0.8927135421960001E+00, 0.2199691768758329E-02, 0.3512385223173503E-02, 0.1425451464914127E+01, 0.1683464700943265E+01, 0.2857477273065492E+00, 0.1556056649653108E+00, 0.9167409543554429E+00, 0.7369210271521004E+00, 0.7843816205451699E-05, 0.1068633642713914E-04, 0.1003973806896052E+01, 0.9891595131364276E+00, 0.9418498631040351E-02, 0.4876860034049891E-02, 0.5121827465172590E+00, 0.4853475128900360E+00, 0.2263732461064059E-02, 0.1959578858316830E-02, 0.4201365406709412E+00, 0.4250255695118534E+00, 0.3107071375346623E-01, 0.8749008776201990E-01, 0.1196803030427524E+01, 0.1425449726020986E+01, 0.3403588894097180E+00, 0.3246099922425689E+00, 0.1359492109368225E+01, 0.1251806800343904E+01, 0.2411467892724848E+00, 0.6536000379104072E-01, 0.3392875246772514E+00, 0.4149902265444443E+00, 0.1652848117124708E+00, 0.1684331550518530E+00, 0.4228949559754990E+00, 0.4010821269512049E+00, 0.1708424320817961E+00, 0.1345949193440586E+00, 0.3159848280636428E+00, 0.2246202392729794E+00, 0.6745243660763246E-01, 0.2477891570824889E+00, 0.8251512110211983E+00, 0.5539111298531113E+00, 0.7711819686391232E-03, 0.5282632149136541E-04, 0.3794316855579739E-01, 0.1367184268032488E-01, 0.3606500256058598E-05, 0.1717489195894037E-04, 0.6510811153270980E-01, 0.4534806576358064E-01, 0.4479235177066975E-02, 0.3508353996892708E-02, 0.3551880209093845E-01, 0.7788342039808532E-02, 0.7843816205451699E-05, 0.1068633642713914E-04, 0.2434478048112329E-01}, + tauOut: 5.1484099711571517E-003, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + + { + z: []float64{0.1845045664413523E+01, 0.1845045673681623E+01, 0.9284324334305927E-09, 0.1331924177594376E-08, 0.1286110617891388E+01, 0.1286109423357647E+01, 0.8600075793510468E-06, 0.1206062196852843E-05, 0.9228692597002398E+00, 0.9170877606119078E+00, 0.7344017075309068E-02, 0.5782369695935185E-02, 0.1164764979181097E+01, 0.1172109006845551E+01, 0.1416795225784663E-10, 0.1087898982148097E-10, 0.1516899526939413E+01, 0.1516899536394917E+01, 0.1175479719901021E-09, 0.1158688024893155E-08, 0.1569402316257081E+00, 0.1538882419371820E+00, 0.4821181617659422E-02, 0.3052000406097992E-02, 0.2431018491557045E+00, 0.2479152225121892E+00, 0.8755391955186837E-05, 0.7818861198543554E-05, 0.2722314297289909E+00, 0.2722202019375114E+00, 0.1357252989661879E-04, 0.1999378345859679E-04, 0.1847873189363651E+00, 0.1848009020627515E+00, 0.2027258571663375E-18, 0.3534048617228375E-11, 0.4750110334503861E-13, 0.1060007138617788E-07, 0.1416795225784663E-10, 0.1087898982148097E-10}, + i0: 1, + n0: 10, + pp: 0, + n0in: 10, + dmin: 4.7501103345038606E-014, + dmin1: 0.15388823121961009, + dmin2: 0.15388823121961009, + dn: 4.7501103345038606E-014, + dn1: 0.18478731893283101, + dn2: 0.27221143594553232, + tau: 1.0600023884871808E-008, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1845045664413523E+01, 0.1845045673681623E+01, 0.9284324334305927E-09, 0.1331924177594376E-08, 0.1286110617891388E+01, 0.1286109423357647E+01, 0.8600075793510468E-06, 0.1206062196852843E-05, 0.9228692597002398E+00, 0.9170877606119078E+00, 0.7344017075309068E-02, 0.5782369695935185E-02, 0.1164764979181097E+01, 0.1172109006845551E+01, 0.1416795225784663E-10, 0.1087898982148097E-10, 0.1516899526939413E+01, 0.1516899536394917E+01, 0.1175479719901021E-09, 0.1158688024893155E-08, 0.1569402316257081E+00, 0.1538882419371820E+00, 0.4821181617659422E-02, 0.3052000406097992E-02, 0.2431018491557045E+00, 0.2479152225121892E+00, 0.8755391955186837E-05, 0.7818861198543554E-05, 0.2722314297289909E+00, 0.2722202019375114E+00, 0.1357252989661879E-04, 0.1999378345859679E-04, 0.1847873189363651E+00, 0.1848009020627515E+00, 0.2027258571663375E-18, 0.3534048617228375E-11, 0.4750110334503861E-13, 0.1060007138617788E-07, 0.1416795225784663E-10, 0.1087898982148097E-10}, + tauOut: 4.7501103294055340E-014, + ttypeOut: -4, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1845045664413523E+01, 0.1845045665341908E+01, 0.9284324334305927E-09, 0.6471746651368383E-09, 0.1286110617891388E+01, 0.1286111477251745E+01, 0.8600075793510468E-06, 0.6171117917307419E-06, 0.9228692597002398E+00, 0.9302126596637096E+00, 0.7344017075309068E-02, 0.9195804644198721E-02, 0.1164764979181097E+01, 0.1155569174551018E+01, 0.1416795225784663E-10, 0.1859807318413278E-10, 0.1516899526939413E+01, 0.1516899527038316E+01, 0.1175479719901021E-09, 0.1216165317638265E-10, 0.1569402316257081E+00, 0.1617614132311584E+00, 0.4821181617659422E-02, 0.7245474325163344E-02, 0.2431018491557045E+00, 0.2358651302224488E+00, 0.8755391955186837E-05, 0.1010532106865606E-04, 0.2722314297289909E+00, 0.2722348969377714E+00, 0.1357252989661879E-04, 0.9212747663842461E-05, 0.1847873189363651E+00, 0.1847781061886537E+00, 0.2027258571663375E-18, 0.5211495068651724E-31, 0.8046649468928653E+00}, + i0: 1, + n0: 9, + pp: 1, + n0in: 10, + dmin: 5.0983266199979805E-023, + dmin1: 0.15694023161349893, + dmin2: 0.15694023161349893, + dn: 5.0983266199979805E-023, + dn1: 0.18477810618865373, + dn2: 0.27222132440787472, + tau: 4.7501103294055340E-014, + ttype: -4, + g: 0.0000000000000000, + zOut: []float64{0.1845045664413523E+01, 0.1845045665341908E+01, 0.9284324334305927E-09, 0.6471746651368383E-09, 0.1286110617891388E+01, 0.1286111477251745E+01, 0.8600075793510468E-06, 0.6171117917307419E-06, 0.9228692597002398E+00, 0.9302126596637096E+00, 0.7344017075309068E-02, 0.9195804644198721E-02, 0.1164764979181097E+01, 0.1155569174551018E+01, 0.1416795225784663E-10, 0.1859807318413278E-10, 0.1516899526939413E+01, 0.1516899527038316E+01, 0.1175479719901021E-09, 0.1216165317638265E-10, 0.1569402316257081E+00, 0.1617614132311584E+00, 0.4821181617659422E-02, 0.7245474325163344E-02, 0.2431018491557045E+00, 0.2358651302224488E+00, 0.8755391955186837E-05, 0.1010532106865606E-04, 0.2722314297289909E+00, 0.2722348969377714E+00, 0.1357252989661879E-04, 0.9212747663842461E-05, 0.1847873189363651E+00, 0.1847781061886537E+00, 0.2027258571663375E-18, 0.5211495068651724E-31, 0.8046649468928653E+00}, + tauOut: 3.9235057903374733E-002, + ttypeOut: -9, + gOut: 0.0000000000000000, + }, + { + z: []float64{0.1805810608085708E+01, 0.1845045665341908E+01, 0.4609225136302542E-09, 0.6471746651368383E-09, 0.1246877035999240E+01, 0.1286111477251745E+01, 0.4603863769418564E-06, 0.6171117917307419E-06, 0.9001729460181566E+00, 0.9302126596637096E+00, 0.1180482975969687E-01, 0.9195804644198721E-02, 0.1104529286906545E+01, 0.1155569174551018E+01, 0.2554156666668993E-10, 0.1859807318413278E-10, 0.1477664469121561E+01, 0.1516899527038316E+01, 0.1331348385339719E-11, 0.1216165317638265E-10, 0.1297718296516156E+00, 0.1617614132311584E+00, 0.1316891924708087E-01, 0.7245474325163344E-02, 0.1834712583930619E+00, 0.2358651302224488E+00, 0.1499428882618218E-04, 0.1010532106865606E-04, 0.2329940574932343E+00, 0.2722348969377714E+00, 0.7306255294378852E-05, 0.9212747663842461E-05, 0.1455357420299846E+00, 0.1847781061886537E+00, 0.1331348385339719E-11, 0.1216165317638265E-10}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 0.12252635532645229, + dmin1: 0.12252635532645229, + dmin2: 0.12252635532645229, + dn: 0.14553574202998462, + dn1: 0.23298484474557046, + dn2: 0.18346115307199323, + tau: 3.9235057903374733E-002, + ttype: -9, + g: 0.0000000000000000, + zOut: []float64{0.1805810608085708E+01, 0.1845045665341908E+01, 0.4609225136302542E-09, 0.6471746651368383E-09, 0.1246877035999240E+01, 0.1286111477251745E+01, 0.4603863769418564E-06, 0.6171117917307419E-06, 0.9001729460181566E+00, 0.9302126596637096E+00, 0.1180482975969687E-01, 0.9195804644198721E-02, 0.1104529286906545E+01, 0.1155569174551018E+01, 0.2554156666668993E-10, 0.1859807318413278E-10, 0.1477664469121561E+01, 0.1516899527038316E+01, 0.1331348385339719E-11, 0.1216165317638265E-10, 0.1297718296516156E+00, 0.1617614132311584E+00, 0.1316891924708087E-01, 0.7245474325163344E-02, 0.1834712583930619E+00, 0.2358651302224488E+00, 0.1499428882618218E-04, 0.1010532106865606E-04, 0.2329940574932343E+00, 0.2722348969377714E+00, 0.7306255294378852E-05, 0.9212747663842461E-05, 0.1455357420299846E+00, 0.1847781061886537E+00, 0.1331348385339719E-11, 0.1216165317638265E-10}, + tauOut: 3.0631588831613071E-002, + ttypeOut: -6, + gOut: 0.25000000000000000, + }, + { + z: []float64{0.1805810608085708E+01, 0.1775179019715018E+01, 0.4609225136302542E-09, 0.3237497126982006E-09, 0.1246877035999240E+01, 0.1216245907230254E+01, 0.4603863769418564E-06, 0.3407430674789675E-06, 0.9001729460181566E+00, 0.8813458462031728E+00, 0.1180482975969687E-01, 0.1479416990810367E-01, 0.1104529286906545E+01, 0.1059103528192370E+01, 0.2554156666668993E-10, 0.3563567162644001E-10, 0.1477664469121561E+01, 0.1447032880255644E+01, 0.1331348385339719E-11, 0.1193970905752580E-12, 0.1297718296516156E+00, 0.1123091600669640E+00, 0.1316891924708087E-01, 0.2151309995104528E-01, 0.1834712583930619E+00, 0.1313415638992297E+00, 0.1499428882618218E-04, 0.2659919745982362E-04, 0.2329940574932343E+00, 0.2023431757194558E+00, 0.7306255294378852E-05, 0.5255039029347846E-05, 0.1455357420299846E+00, 0.1148988981593422E+00, 0.1331348385339719E-11, 0.1193970905752580E-12, 0.8046649468928653E+00}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 9.9140240819883152E-002, + dmin1: 9.9140240819883152E-002, + dmin2: 9.9140240819883152E-002, + dn: 0.11489889815934221, + dn1: 0.20233586946416143, + dn2: 0.13132656961040354, + tau: 3.0631588831613071E-002, + ttype: -6, + g: 0.25000000000000000, + zOut: []float64{0.1805810608085708E+01, 0.1775179019715018E+01, 0.4609225136302542E-09, 0.3237497126982006E-09, 0.1246877035999240E+01, 0.1216245907230254E+01, 0.4603863769418564E-06, 0.3407430674789675E-06, 0.9001729460181566E+00, 0.8813458462031728E+00, 0.1180482975969687E-01, 0.1479416990810367E-01, 0.1104529286906545E+01, 0.1059103528192370E+01, 0.2554156666668993E-10, 0.3563567162644001E-10, 0.1477664469121561E+01, 0.1447032880255644E+01, 0.1331348385339719E-11, 0.1193970905752580E-12, 0.1297718296516156E+00, 0.1123091600669640E+00, 0.1316891924708087E-01, 0.2151309995104528E-01, 0.1834712583930619E+00, 0.1313415638992297E+00, 0.1499428882618218E-04, 0.2659919745982362E-04, 0.2329940574932343E+00, 0.2023431757194558E+00, 0.7306255294378852E-05, 0.5255039029347846E-05, 0.1455357420299846E+00, 0.1148988981593422E+00, 0.1331348385339719E-11, 0.1193970905752580E-12, 0.8046649468928653E+00}, + tauOut: 4.9545335349736611E-002, + ttypeOut: -6, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1725633684689031E+01, 0.1775179019715018E+01, 0.2281824158451768E-09, 0.3237497126982006E-09, 0.1166700912395402E+01, 0.1216245907230254E+01, 0.2574031475886406E-06, 0.3407430674789675E-06, 0.8465944233583922E+00, 0.8813458462031728E+00, 0.1850774953630535E-01, 0.1479416990810367E-01, 0.9910504433419636E+00, 0.1059103528192370E+01, 0.5203164874187830E-10, 0.3563567162644001E-10, 0.1397487544853995E+01, 0.1447032880255644E+01, 0.9595353465813834E-14, 0.1193970905752580E-12, 0.8427692466826309E-01, 0.1123091600669640E+00, 0.3352713928531350E-01, 0.2151309995104528E-01, 0.4829568846163943E-01, 0.1313415638992297E+00, 0.1114419580100731E-03, 0.2659919745982362E-04, 0.1526916534507385E+00, 0.2023431757194558E+00, 0.3954362799871079E-05, 0.5255039029347846E-05, 0.6534960844680572E-01, 0.1148988981593422E+00, 0.9595353465813834E-14, 0.1193970905752580E-12}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 4.8269089264179610E-002, + dmin1: 4.8269089264179610E-002, + dmin2: 4.8269089264179610E-002, + dn: 6.5349608446805721E-002, + dn1: 0.15268639841170917, + dn2: 4.8269089264179610E-002, + tau: 4.9545335349736611E-002, + ttype: -6, + g: 0.49975000000000003, + zOut: []float64{0.1725633684689031E+01, 0.1775179019715018E+01, 0.2281824158451768E-09, 0.3237497126982006E-09, 0.1166700912395402E+01, 0.1216245907230254E+01, 0.2574031475886406E-06, 0.3407430674789675E-06, 0.8465944233583922E+00, 0.8813458462031728E+00, 0.1850774953630535E-01, 0.1479416990810367E-01, 0.9910504433419636E+00, 0.1059103528192370E+01, 0.5203164874187830E-10, 0.3563567162644001E-10, 0.1397487544853995E+01, 0.1447032880255644E+01, 0.9595353465813834E-14, 0.1193970905752580E-12, 0.8427692466826309E-01, 0.1123091600669640E+00, 0.3352713928531350E-01, 0.2151309995104528E-01, 0.4829568846163943E-01, 0.1313415638992297E+00, 0.1114419580100731E-03, 0.2659919745982362E-04, 0.1526916534507385E+00, 0.2023431757194558E+00, 0.3954362799871079E-05, 0.5255039029347846E-05, 0.6534960844680572E-01, 0.1148988981593422E+00, 0.9595353465813834E-14, 0.1193970905752580E-12}, + tauOut: 1.2037453975339630E-002, + ttypeOut: -5, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1725633684689031E+01, 0.1713596230941874E+01, 0.2281824158451768E-09, 0.1553578538234923E-09, 0.1166700912395402E+01, 0.1154663715667853E+01, 0.2574031475886406E-06, 0.1887268702969492E-06, 0.8465944233583922E+00, 0.8530645301924875E+00, 0.1850774953630535E-01, 0.2150143715280096E-01, 0.9910504433419636E+00, 0.9575115522658546E+00, 0.5203164874187830E-10, 0.7594016059954953E-10, 0.1397487544853995E+01, 0.1385450090802725E+01, 0.9595353465813834E-14, 0.5836853211617396E-15, 0.8427692466826309E-01, 0.1057666099782364E+00, 0.3352713928531350E-01, 0.1530933320323569E-01, 0.4829568846163943E-01, 0.2106034324107419E-01, 0.1114419580100731E-03, 0.8079762346493418E-03, 0.1526916534507385E+00, 0.1398501776035494E+00, 0.3954362799871079E-05, 0.1847806452993955E-05, 0.6534960844680572E-01, 0.5331030666501309E-01, 0.9595353465813834E-14, 0.5836853211617396E-15, 0.8046649468928653E+00}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 2.0948901283064113E-002, + dmin1: 2.0948901283064113E-002, + dmin2: 2.0948901283064113E-002, + dn: 5.3310306665013088E-002, + dn1: 0.13984622324074955, + dn2: 2.0948901283064113E-002, + tau: 1.2037453975339630E-002, + ttype: -5, + g: 0.49975000000000003, + zOut: []float64{0.1725633684689031E+01, 0.1713596230941874E+01, 0.2281824158451768E-09, 0.1553578538234923E-09, 0.1166700912395402E+01, 0.1154663715667853E+01, 0.2574031475886406E-06, 0.1887268702969492E-06, 0.8465944233583922E+00, 0.8530645301924875E+00, 0.1850774953630535E-01, 0.2150143715280096E-01, 0.9910504433419636E+00, 0.9575115522658546E+00, 0.5203164874187830E-10, 0.7594016059954953E-10, 0.1397487544853995E+01, 0.1385450090802725E+01, 0.9595353465813834E-14, 0.5836853211617396E-15, 0.8427692466826309E-01, 0.1057666099782364E+00, 0.3352713928531350E-01, 0.1530933320323569E-01, 0.4829568846163943E-01, 0.2106034324107419E-01, 0.1114419580100731E-03, 0.8079762346493418E-03, 0.1526916534507385E+00, 0.1398501776035494E+00, 0.3954362799871079E-05, 0.1847806452993955E-05, 0.6534960844680572E-01, 0.5331030666501309E-01, 0.9595353465813834E-14, 0.5836853211617396E-15, 0.8046649468928653E+00}, + tauOut: 1.1070386405955311E-002, + ttypeOut: -5, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1702525844691276E+01, 0.1713596230941874E+01, 0.1053646717395619E-09, 0.1553578538234923E-09, 0.1143593517883403E+01, 0.1154663715667853E+01, 0.1407809649380857E-06, 0.1887268702969492E-06, 0.8634954401583683E+00, 0.8530645301924875E+00, 0.2384248197112572E-01, 0.2150143715280096E-01, 0.9225986839647138E+00, 0.9575115522658546E+00, 0.1140379931457212E-09, 0.7594016059954953E-10, 0.1374379704282732E+01, 0.1385450090802725E+01, 0.4491802194179927E-16, 0.5836853211617396E-15, 0.1100055567755167E+00, 0.1057666099782364E+00, 0.2930941140637693E-02, 0.1530933320323569E-01, 0.7866991929130526E-02, 0.2106034324107419E-01, 0.1436325611276508E-01, 0.8079762346493418E-03, 0.1144183828912820E+00, 0.1398501776035494E+00, 0.8609379557504958E-06, 0.1847806452993955E-05, 0.4223905932110202E-01, 0.5331030666501309E-01, 0.4491802194179927E-16, 0.5836853211617396E-15}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 7.0590156944811844E-003, + dmin1: 7.0590156944811844E-003, + dmin2: 7.0590156944811844E-003, + dn: 4.2239059321102022E-002, + dn1: 0.11441653508482905, + dn2: 7.0590156944811844E-003, + tau: 1.1070386405955311E-002, + ttype: -5, + g: 0.49975000000000003, + zOut: []float64{0.1702525844691276E+01, 0.1713596230941874E+01, 0.1053646717395619E-09, 0.1553578538234923E-09, 0.1143593517883403E+01, 0.1154663715667853E+01, 0.1407809649380857E-06, 0.1887268702969492E-06, 0.8634954401583683E+00, 0.8530645301924875E+00, 0.2384248197112572E-01, 0.2150143715280096E-01, 0.9225986839647138E+00, 0.9575115522658546E+00, 0.1140379931457212E-09, 0.7594016059954953E-10, 0.1374379704282732E+01, 0.1385450090802725E+01, 0.4491802194179927E-16, 0.5836853211617396E-15, 0.1100055567755167E+00, 0.1057666099782364E+00, 0.2930941140637693E-02, 0.1530933320323569E-01, 0.7866991929130526E-02, 0.2106034324107419E-01, 0.1436325611276508E-01, 0.8079762346493418E-03, 0.1144183828912820E+00, 0.1398501776035494E+00, 0.8609379557504958E-06, 0.1847806452993955E-05, 0.4223905932110202E-01, 0.5331030666501309E-01, 0.4491802194179927E-16, 0.5836853211617396E-15}, + tauOut: 5.5670727120955849E-003, + ttypeOut: -5, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1702525844691276E+01, 0.1696958772084545E+01, 0.1053646717395619E-09, 0.7100605954454643E-10, 0.1143593517883403E+01, 0.1138026585881266E+01, 0.1407809649380857E-06, 0.1068197551738174E-06, 0.8634954401583683E+00, 0.8817707425976433E+00, 0.2384248197112572E-01, 0.2494644177488929E-01, 0.9225986839647138E+00, 0.8920851695917670E+00, 0.1140379931457212E-09, 0.1756911880603681E-09, 0.1374379704282732E+01, 0.1368812631394945E+01, 0.4491802194179927E-16, 0.3609867340226789E-17, 0.1100055567755167E+00, 0.1073694252040588E+00, 0.2930941140637693E-02, 0.2147509894397918E-03, 0.7866991929130526E-02, 0.1644842434036023E-01, 0.1436325611276508E-01, 0.9991355423895336E-01, 0.1144183828912820E+00, 0.8938616878188867E-02, 0.8609379557504958E-06, 0.4068326216494222E-05, 0.4223905932110202E-01, 0.3666791828278994E-01, 0.4491802194179927E-16, 0.3609867340226789E-17, 0.8046649468928653E+00}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 2.0851682275951503E-003, + dmin1: 2.0851682275951503E-003, + dmin2: 2.0851682275951503E-003, + dn: 3.6667918282789938E-002, + dn1: 8.9377559402331157E-003, + dn2: 2.0851682275951503E-003, + tau: 5.5670727120955849E-003, + ttype: -5, + g: 0.49975000000000003, + zOut: []float64{0.1702525844691276E+01, 0.1696958772084545E+01, 0.1053646717395619E-09, 0.7100605954454643E-10, 0.1143593517883403E+01, 0.1138026585881266E+01, 0.1407809649380857E-06, 0.1068197551738174E-06, 0.8634954401583683E+00, 0.8817707425976433E+00, 0.2384248197112572E-01, 0.2494644177488929E-01, 0.9225986839647138E+00, 0.8920851695917670E+00, 0.1140379931457212E-09, 0.1756911880603681E-09, 0.1374379704282732E+01, 0.1368812631394945E+01, 0.4491802194179927E-16, 0.3609867340226789E-17, 0.1100055567755167E+00, 0.1073694252040588E+00, 0.2930941140637693E-02, 0.2147509894397918E-03, 0.7866991929130526E-02, 0.1644842434036023E-01, 0.1436325611276508E-01, 0.9991355423895336E-01, 0.1144183828912820E+00, 0.8938616878188867E-02, 0.8609379557504958E-06, 0.4068326216494222E-05, 0.4223905932110202E-01, 0.3666791828278994E-01, 0.4491802194179927E-16, 0.3609867340226789E-17, 0.8046649468928653E+00}, + tauOut: 1.1659821590613959E-003, + ttypeOut: -5, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1695792789996490E+01, 0.1696958772084545E+01, 0.4765133098633433E-10, 0.7100605954454643E-10, 0.1136860710494309E+01, 0.1138026585881266E+01, 0.8285142935651389E-07, 0.1068197551738174E-06, 0.9055511193620417E+00, 0.8817707425976433E+00, 0.2457547703893446E-01, 0.2494644177488929E-01, 0.8663437105694624E+00, 0.8920851695917670E+00, 0.2775899617066991E-09, 0.1756911880603681E-09, 0.1367646648958294E+01, 0.1368812631394945E+01, 0.2833987723936393E-18, 0.3609867340226789E-17, 0.1064181940344372E+00, 0.1073694252040588E+00, 0.3319277717374952E-04, 0.2147509894397918E-03, 0.1151628036430784E+00, 0.1644842434036023E-01, 0.7755012504281143E-02, 0.9991355423895336E-01, 0.2169054106282214E-04, 0.8938616878188867E-02, 0.6877516463147774E-02, 0.4068326216494222E-05, 0.2862441966058077E-01, 0.3666791828278994E-01, 0.2833987723936393E-18, 0.3609867340226789E-17}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 1.7622214846327918E-005, + dmin1: 1.7622214846327918E-005, + dmin2: 1.5249249404125084E-002, + dn: 2.8624419660580765E-002, + dn1: 1.7622214846327918E-005, + dn2: 1.5249249404125084E-002, + tau: 1.1659821590613959E-003, + ttype: -5, + g: 0.49975000000000003, + zOut: []float64{0.1695792789996490E+01, 0.1696958772084545E+01, 0.4765133098633433E-10, 0.7100605954454643E-10, 0.1136860710494309E+01, 0.1138026585881266E+01, 0.8285142935651389E-07, 0.1068197551738174E-06, 0.9055511193620417E+00, 0.8817707425976433E+00, 0.2457547703893446E-01, 0.2494644177488929E-01, 0.8663437105694624E+00, 0.8920851695917670E+00, 0.2775899617066991E-09, 0.1756911880603681E-09, 0.1367646648958294E+01, 0.1368812631394945E+01, 0.2833987723936393E-18, 0.3609867340226789E-17, 0.1064181940344372E+00, 0.1073694252040588E+00, 0.3319277717374952E-04, 0.2147509894397918E-03, 0.1151628036430784E+00, 0.1644842434036023E-01, 0.7755012504281143E-02, 0.9991355423895336E-01, 0.2169054106282214E-04, 0.8938616878188867E-02, 0.6877516463147774E-02, 0.4068326216494222E-05, 0.2862441966058077E-01, 0.3666791828278994E-01, 0.2833987723936393E-18, 0.3609867340226789E-17}, + tauOut: 1.2076215031173109E-005, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1695792789996490E+01, 0.1695780713829110E+01, 0.4765133098633433E-10, 0.3194571418305606E-10, 0.1136860710494309E+01, 0.1136848717098761E+01, 0.8285142935651389E-07, 0.6599488873594650E-07, 0.9055511193620417E+00, 0.9301144541910563E+00, 0.2457547703893446E-01, 0.2289052693567938E-01, 0.8663437105694624E+00, 0.8434411076963417E+00, 0.2775899617066991E-09, 0.4501143914475995E-09, 0.1367646648958294E+01, 0.1367634572293148E+01, 0.2833987723936393E-18, 0.2205178646452290E-19, 0.1064181940344372E+00, 0.1064393105965798E+00, 0.3319277717374952E-04, 0.3591317210346347E-04, 0.1151628036430784E+00, 0.1228698267602250E+00, 0.7755012504281143E-02, 0.1369013219942635E-05, 0.2169054106282214E-04, 0.6885761775959480E-02, 0.6877516463147774E-02, 0.2859014352646020E-01, 0.2862441966058077E-01, 0.2219991908939190E-04, 0.2833987723936393E-18, 0.2205178646452290E-19, 0.8046649468928653E+00}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 8.2453128117063980E-006, + dmin1: 8.2453128117063980E-006, + dmin2: 0.10640611781940604, + dn: 2.2199919089391903E-005, + dn1: 8.2453128117063980E-006, + dn2: 0.11511481425594380, + tau: 1.2076215031173109E-005, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.1695792789996490E+01, 0.1695780713829110E+01, 0.4765133098633433E-10, 0.3194571418305606E-10, 0.1136860710494309E+01, 0.1136848717098761E+01, 0.8285142935651389E-07, 0.6599488873594650E-07, 0.9055511193620417E+00, 0.9301144541910563E+00, 0.2457547703893446E-01, 0.2289052693567938E-01, 0.8663437105694624E+00, 0.8434411076963417E+00, 0.2775899617066991E-09, 0.4501143914475995E-09, 0.1367646648958294E+01, 0.1367634572293148E+01, 0.2833987723936393E-18, 0.2205178646452290E-19, 0.1064181940344372E+00, 0.1064393105965798E+00, 0.3319277717374952E-04, 0.3591317210346347E-04, 0.1151628036430784E+00, 0.1228698267602250E+00, 0.7755012504281143E-02, 0.1369013219942635E-05, 0.2169054106282214E-04, 0.6885761775959480E-02, 0.6877516463147774E-02, 0.2859014352646020E-01, 0.2862441966058077E-01, 0.2219991908939190E-04, 0.2833987723936393E-18, 0.2205178646452290E-19, 0.8046649468928653E+00}, + tauOut: 3.2770273787704380E-006, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1695777436833677E+01, 0.1695780713829110E+01, 0.2141639781080129E-10, 0.3194571418305606E-10, 0.1136845506044855E+01, 0.1136848717098761E+01, 0.5399396803668456E-07, 0.6599488873594650E-07, 0.9530016501053890E+00, 0.9301144541910563E+00, 0.2025894854667596E-01, 0.2289052693567938E-01, 0.8231788825724013E+00, 0.8434411076963417E+00, 0.7478228806194929E-09, 0.4501143914475995E-09, 0.1367631294517947E+01, 0.1367634572293148E+01, 0.1716235185693175E-20, 0.2205178646452290E-19, 0.1064719467413045E+00, 0.1064393105965798E+00, 0.4144420544393849E-04, 0.3591317210346347E-04, 0.1228264745406222E+00, 0.1228698267602250E+00, 0.7674810284932935E-07, 0.1369013219942635E-05, 0.3547255152693805E-01, 0.6885761775959480E-02, 0.1789267604726782E-04, 0.2859014352646020E-01, 0.1030215663353646E-05, 0.2219991908939190E-04, 0.1716235185693175E-20, 0.2205178646452290E-19}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 1.0302156633536465E-006, + dmin1: 6.8824080004778604E-003, + dmin2: 0.10643603356920101, + dn: 1.0302156633536465E-006, + dn1: 6.8824080004778604E-003, + dn2: 0.12282510552740224, + tau: 3.2770273787704380E-006, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.1695777436833677E+01, 0.1695780713829110E+01, 0.2141639781080129E-10, 0.3194571418305606E-10, 0.1136845506044855E+01, 0.1136848717098761E+01, 0.5399396803668456E-07, 0.6599488873594650E-07, 0.9530016501053890E+00, 0.9301144541910563E+00, 0.2025894854667596E-01, 0.2289052693567938E-01, 0.8231788825724013E+00, 0.8434411076963417E+00, 0.7478228806194929E-09, 0.4501143914475995E-09, 0.1367631294517947E+01, 0.1367634572293148E+01, 0.1716235185693175E-20, 0.2205178646452290E-19, 0.1064719467413045E+00, 0.1064393105965798E+00, 0.4144420544393849E-04, 0.3591317210346347E-04, 0.1228264745406222E+00, 0.1228698267602250E+00, 0.7674810284932935E-07, 0.1369013219942635E-05, 0.3547255152693805E-01, 0.6885761775959480E-02, 0.1789267604726782E-04, 0.2859014352646020E-01, 0.1030215663353646E-05, 0.2219991908939190E-04, 0.1716235185693175E-20, 0.2205178646452290E-19}, + tauOut: 1.0296962592568820E-006, + ttypeOut: -2, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1695777436833677E+01, 0.1695776407158834E+01, 0.2141639781080129E-10, 0.1435751523850387E-10, 0.1136845506044855E+01, 0.1136844530328206E+01, 0.5399396803668456E-07, 0.4526242530264241E-07, 0.9530016501053890E+00, 0.9732595236933804E+00, 0.2025894854667596E-01, 0.1713493494875720E-01, 0.8231788825724013E+00, 0.8060429186752077E+00, 0.7478228806194929E-09, 0.1268848035998799E-08, 0.1367631294517947E+01, 0.1367630263552839E+01, 0.1716235185693175E-20, 0.1336113320657127E-21, 0.1064719467413045E+00, 0.1065123612504892E+00, 0.4144420544393849E-04, 0.4779206455525695E-04, 0.1228264745406222E+00, 0.1227777295279105E+00, 0.7674810284932935E-07, 0.2217381803186623E-07, 0.3547255152693805E-01, 0.3548939233290803E-01, 0.1789267604726782E-04, 0.5194035150079302E-09, 0.1030215663353646E-05, 0.5817566277343568E-15, 0.1716235185693175E-20, 0.1336113320657127E-21, 0.8046649468928653E+00}, + i0: 1, + n0: 9, + pp: 1, + n0in: 9, + dmin: 5.8175662773435680E-016, + dmin1: 3.5471499656860764E-002, + dmin2: 0.10647091704504522, + dn: 5.8175662773435680E-016, + dn1: 3.5471499656860764E-002, + dn2: 0.12277765277980766, + tau: 1.0296962592568820E-006, + ttype: -2, + g: 0.49975000000000003, + zOut: []float64{0.1695777436833677E+01, 0.1695776407158834E+01, 0.2141639781080129E-10, 0.1435751523850387E-10, 0.1136845506044855E+01, 0.1136844530328206E+01, 0.5399396803668456E-07, 0.4526242530264241E-07, 0.9530016501053890E+00, 0.9732595236933804E+00, 0.2025894854667596E-01, 0.1713493494875720E-01, 0.8231788825724013E+00, 0.8060429186752077E+00, 0.7478228806194929E-09, 0.1268848035998799E-08, 0.1367631294517947E+01, 0.1367630263552839E+01, 0.1716235185693175E-20, 0.1336113320657127E-21, 0.1064719467413045E+00, 0.1065123612504892E+00, 0.4144420544393849E-04, 0.4779206455525695E-04, 0.1228264745406222E+00, 0.1227777295279105E+00, 0.7674810284932935E-07, 0.2217381803186623E-07, 0.3547255152693805E-01, 0.3548939233290803E-01, 0.1789267604726782E-04, 0.5194035150079302E-09, 0.1030215663353646E-05, 0.5817566277343568E-15, 0.1716235185693175E-20, 0.1336113320657127E-21, 0.8046649468928653E+00}, + tauOut: 5.8175661922007790E-016, + ttypeOut: -2, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1695776407173191E+01, 0.1695776407158834E+01, 0.9625244577618415E-11, 0.1435751523850387E-10, 0.1136844575581005E+01, 0.1136844530328206E+01, 0.3874943632355666E-07, 0.4526242530264241E-07, 0.9903944198927007E+00, 0.9732595236933804E+00, 0.1394544708652782E-01, 0.1713493494875720E-01, 0.7920974728575274E+00, 0.8060429186752077E+00, 0.2190784636165185E-08, 0.1268848035998799E-08, 0.1367630261362054E+01, 0.1367630263552839E+01, 0.1040577915698430E-22, 0.1336113320657127E-21, 0.1065601533150438E+00, 0.1065123612504892E+00, 0.5506562249584694E-04, 0.4779206455525695E-04, 0.1227226860792321E+00, 0.1227777295279105E+00, 0.6412305277798032E-08, 0.2217381803186623E-07, 0.3548938644000568E-01, 0.3548939233290803E-01, 0.8514276171981532E-23, 0.5194035150079302E-09, 0.2761013168273541E-29, 0.5817566277343568E-15, 0.1040577915698430E-22, 0.1336113320657127E-21}, + i0: 1, + n0: 9, + pp: 0, + n0in: 9, + dmin: 2.7610131682735413E-030, + dmin1: 3.5489385920602169E-002, + dmin2: 0.10651236125048857, + dn: 2.7610131682735413E-030, + dn1: 3.5489385920602169E-002, + dn2: 0.12272266390541409, + tau: 5.8175661922007790E-016, + ttype: -2, + g: 0.49975000000000003, + zOut: []float64{0.1695776407173191E+01, 0.1695776407158834E+01, 0.9625244577618415E-11, 0.1435751523850387E-10, 0.1136844575581005E+01, 0.1136844530328206E+01, 0.3874943632355666E-07, 0.4526242530264241E-07, 0.9903944198927007E+00, 0.9732595236933804E+00, 0.1394544708652782E-01, 0.1713493494875720E-01, 0.7920974728575274E+00, 0.8060429186752077E+00, 0.2190784636165185E-08, 0.1268848035998799E-08, 0.1367630261362054E+01, 0.1367630263552839E+01, 0.1040577915698430E-22, 0.1336113320657127E-21, 0.1065601533150438E+00, 0.1065123612504892E+00, 0.5506562249584694E-04, 0.4779206455525695E-04, 0.1227226860792321E+00, 0.1227777295279105E+00, 0.6412305277798032E-08, 0.2217381803186623E-07, 0.3548938644000568E-01, 0.3548939233290803E-01, 0.8514276171981532E-23, 0.5194035150079302E-09, 0.2761013168273541E-29, 0.5817566277343568E-15, 0.1040577915698430E-22, 0.1336113320657127E-21}, + tauOut: 2.7610131682735413E-030, + ttypeOut: -2, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1695776407173191E+01, 0.1695776407182817E+01, 0.9625244577618415E-11, 0.6452741670633652E-11, 0.1136844575581005E+01, 0.1136844614323989E+01, 0.3874943632355666E-07, 0.3375767015588020E-07, 0.9903944198927007E+00, 0.1004339833221559E+01, 0.1394544708652782E-01, 0.1099842207759001E-01, 0.7920974728575274E+00, 0.7810990529707220E+00, 0.2190784636165185E-08, 0.3835855840755795E-08, 0.1367630261362054E+01, 0.1367630257526198E+01, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.1065601533150438E+00, 0.1066152189375397E+00, 0.5506562249584694E-04, 0.6338495733216447E-04, 0.1227226860792321E+00, 0.1226593075342052E+00, 0.6412305277798032E-08, 0.1855291575909163E-08, 0.3548938644000568E-01, 0.3548938458471410E-01, 0.8514276171981532E-23, 0.6623960630549781E-51, 0.9539342071687115E+00}, + i0: 1, + n0: 8, + pp: 1, + n0in: 9, + dmin: 2.7610131682735413E-030, + dmin1: 3.5489384584714102E-002, + dmin2: 0.10656015331504384, + dn: 2.7610131682735413E-030, + dn1: 3.5489384584714102E-002, + dn2: 0.12265930112189996, + tau: 0.0000000000000000, + ttype: -2, + g: 0.49975000000000003, + zOut: []float64{0.1695776407173191E+01, 0.1695776407182817E+01, 0.9625244577618415E-11, 0.6452741670633652E-11, 0.1136844575581005E+01, 0.1136844614323989E+01, 0.3874943632355666E-07, 0.3375767015588020E-07, 0.9903944198927007E+00, 0.1004339833221559E+01, 0.1394544708652782E-01, 0.1099842207759001E-01, 0.7920974728575274E+00, 0.7810990529707220E+00, 0.2190784636165185E-08, 0.3835855840755795E-08, 0.1367630261362054E+01, 0.1367630257526198E+01, 0.1040577915698430E-22, 0.8107757314001177E-24, 0.1065601533150438E+00, 0.1066152189375397E+00, 0.5506562249584694E-04, 0.6338495733216447E-04, 0.1227226860792321E+00, 0.1226593075342052E+00, 0.6412305277798032E-08, 0.1855291575909163E-08, 0.3548938644000568E-01, 0.3548938458471410E-01, 0.8514276171981532E-23, 0.6623960630549781E-51, 0.9539342071687115E+00}, + tauOut: 1.7744692292357051E-002, + ttypeOut: -9, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1678031714896912E+01, 0.1695776407182817E+01, 0.4371648372768990E-11, 0.6452741670633652E-11, 0.1119099955784930E+01, 0.1136844614323989E+01, 0.3029592900888367E-07, 0.3375767015588020E-07, 0.9975935327108624E+00, 0.1004339833221559E+01, 0.8611580555893368E-02, 0.1099842207759001E-01, 0.7547427839583274E+00, 0.7810990529707220E+00, 0.6950755439903452E-08, 0.3835855840755795E-08, 0.1349885558283086E+01, 0.1367630257526198E+01, 0.6403582257922030E-25, 0.8107757314001177E-24, 0.8893391160251481E-01, 0.1066152189375397E+00, 0.8742171388117141E-04, 0.6338495733216447E-04, 0.1048271953832586E+00, 0.1226593075342052E+00, 0.6281113981299557E-09, 0.1855291575909163E-08, 0.1774469166424565E-01, 0.3548938458471410E-01, 0.6403582257922030E-25, 0.8107757314001177E-24}, + i0: 1, + n0: 8, + pp: 0, + n0in: 8, + dmin: 1.7744691664245655E-002, + dmin1: 8.8870526645182649E-002, + dmin2: 8.8870526645182649E-002, + dn: 1.7744691664245655E-002, + dn1: 0.10482719352796703, + dn2: 8.8870526645182649E-002, + tau: 1.7744692292357051E-002, + ttype: -9, + g: 0.49975000000000003, + zOut: []float64{0.1678031714896912E+01, 0.1695776407182817E+01, 0.4371648372768990E-11, 0.6452741670633652E-11, 0.1119099955784930E+01, 0.1136844614323989E+01, 0.3029592900888367E-07, 0.3375767015588020E-07, 0.9975935327108624E+00, 0.1004339833221559E+01, 0.8611580555893368E-02, 0.1099842207759001E-01, 0.7547427839583274E+00, 0.7810990529707220E+00, 0.6950755439903452E-08, 0.3835855840755795E-08, 0.1349885558283086E+01, 0.1367630257526198E+01, 0.6403582257922030E-25, 0.8107757314001177E-24, 0.8893391160251481E-01, 0.1066152189375397E+00, 0.8742171388117141E-04, 0.6338495733216447E-04, 0.1048271953832586E+00, 0.1226593075342052E+00, 0.6281113981299557E-09, 0.1855291575909163E-08, 0.1774469166424565E-01, 0.3548938458471410E-01, 0.6403582257922030E-25, 0.8107757314001177E-24}, + tauOut: 1.7743283373674822E-002, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1678031714896912E+01, 0.1660288431527609E+01, 0.4371648372768990E-11, 0.2946663608425970E-11, 0.1119099955784930E+01, 0.1101356702704238E+01, 0.3029592900888367E-07, 0.2744162973950316E-07, 0.9975935327108624E+00, 0.9884618024514511E+00, 0.8611580555893368E-02, 0.6575396506892930E-02, 0.7547427839583274E+00, 0.7304241110285150E+00, 0.6950755439903452E-08, 0.1284558415558242E-07, 0.1349885558283086E+01, 0.1332142262063827E+01, 0.6403582257922030E-25, 0.4275036042946169E-26, 0.8893391160251481E-01, 0.7127804994272115E-01, 0.8742171388117141E-04, 0.1285693574547170E-03, 0.1048271953832586E+00, 0.8695534328024046E-01, 0.6281113981299557E-09, 0.1281766326273249E-09, 0.1774469166424565E-01, 0.1408162394200135E-05, 0.6403582257922030E-25, 0.4275036042946169E-26, 0.9539342071687115E+00}, + i0: 1, + n0: 8, + pp: 1, + n0in: 8, + dmin: 1.4081623942001353E-006, + dmin1: 7.1190628228839981E-002, + dmin2: 7.1190628228839981E-002, + dn: 1.4081623942001353E-006, + dn1: 8.6955342652129064E-002, + dn2: 7.1190628228839981E-002, + tau: 1.7743283373674822E-002, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.1678031714896912E+01, 0.1660288431527609E+01, 0.4371648372768990E-11, 0.2946663608425970E-11, 0.1119099955784930E+01, 0.1101356702704238E+01, 0.3029592900888367E-07, 0.2744162973950316E-07, 0.9975935327108624E+00, 0.9884618024514511E+00, 0.8611580555893368E-02, 0.6575396506892930E-02, 0.7547427839583274E+00, 0.7304241110285150E+00, 0.6950755439903452E-08, 0.1284558415558242E-07, 0.1349885558283086E+01, 0.1332142262063827E+01, 0.6403582257922030E-25, 0.4275036042946169E-26, 0.8893391160251481E-01, 0.7127804994272115E-01, 0.8742171388117141E-04, 0.1285693574547170E-03, 0.1048271953832586E+00, 0.8695534328024046E-01, 0.6281113981299557E-09, 0.1281766326273249E-09, 0.1774469166424565E-01, 0.1408162394200135E-05, 0.6403582257922030E-25, 0.4275036042946169E-26, 0.9539342071687115E+00}, + tauOut: 1.4081069428512511E-006, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1660287023423613E+01, 0.1660288431527609E+01, 0.1954678721190348E-11, 0.2946663608425970E-11, 0.1101355322036970E+01, 0.1101356702704238E+01, 0.2462874809952034E-07, 0.2744162973950316E-07, 0.9950357662226532E+00, 0.9884618024514511E+00, 0.4826789459478154E-02, 0.6575396506892930E-02, 0.7255959263076781E+00, 0.7304241110285150E+00, 0.2358357443050565E-07, 0.1284558415558242E-07, 0.1332140830373310E+01, 0.1332142262063827E+01, -0.9894235909416862E+00, 0.4275036042946169E-26, 0.7140521119323301E-01, 0.7127804994272115E-01, 0.1565683011922014E-03, 0.1285693574547170E-03, 0.8679736700028205E-01, 0.8695534328024046E-01, 0.2079481441878513E-14, 0.1281766326273249E-09, 0.5544926940271698E-10, 0.1408162394200135E-05, 0.1565683011922014E-03, 0.1285693574547170E-03}, + i0: 6, + n0: 8, + pp: 0, + n0in: 8, + dmin: 5.5449269402716976E-011, + dmin1: 7.1276641835778295E-002, + dmin2: 7.1276641835778295E-002, + dn: 5.5449269402716976E-011, + dn1: 8.6797366872105416E-002, + dn2: 7.1276641835778295E-002, + tau: 1.4081069428512511E-006, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.1660287023423613E+01, 0.1660288431527609E+01, 0.1954678721190348E-11, 0.2946663608425970E-11, 0.1101355322036970E+01, 0.1101356702704238E+01, 0.2462874809952034E-07, 0.2744162973950316E-07, 0.9950357662226532E+00, 0.9884618024514511E+00, 0.4826789459478154E-02, 0.6575396506892930E-02, 0.7255959263076781E+00, 0.7304241110285150E+00, 0.2358357443050565E-07, 0.1284558415558242E-07, 0.1332140830373310E+01, 0.1332142262063827E+01, -0.9894235909416862E+00, 0.4275036042946169E-26, 0.7140521119323301E-01, 0.7127804994272115E-01, 0.1565683011922014E-03, 0.1285693574547170E-03, 0.8679736700028205E-01, 0.8695534328024046E-01, 0.2079481441878513E-14, 0.1281766326273249E-09, 0.5544926940271698E-10, 0.1408162394200135E-05, 0.1565683011922014E-03, 0.1285693574547170E-03}, + tauOut: 5.5449260598506680E-011, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1660287023423613E+01, 0.1660288431527609E+01, 0.1954678721190348E-11, 0.2946663608425970E-11, 0.1101355322036970E+01, 0.1101356702704238E+01, 0.2462874809952034E-07, 0.2744162973950316E-07, 0.9950357662226532E+00, 0.9884618024514511E+00, 0.4826789459478154E-02, 0.6575396506892930E-02, 0.7255959263076781E+00, 0.7304241110285150E+00, 0.2358357443050565E-07, 0.1284558415558242E-07, 0.1332140830373310E+01, 0.1332142262063827E+01, -0.9894235909416862E+00, 0.4275036042946169E-26, 0.7140521119323301E-01, 0.7156177943897596E-01, 0.1565683011922014E-03, 0.1899018778701386E-03, 0.8679736700028205E-01, 0.8660746506696473E-01, 0.2079481441878513E-14, 0.1331360138522907E-23, 0.5544926940271698E-10, 0.8804208964992894E-17, 0.1565683011922014E-03, 0.8679736700028205E-01, 0.9539342071687115E+00}, + i0: 6, + n0: 8, + pp: 1, + n0in: 8, + dmin: 8.8042089649928937E-018, + dmin1: 7.1405211137783753E-002, + dmin2: 7.1405211137783753E-002, + dn: 8.8042089649928937E-018, + dn1: 8.6607465066962652E-002, + dn2: 7.1405211137783753E-002, + tau: 5.5449260598506680E-011, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.1660287023423613E+01, 0.1660288431527609E+01, 0.1954678721190348E-11, 0.2946663608425970E-11, 0.1101355322036970E+01, 0.1101356702704238E+01, 0.2462874809952034E-07, 0.2744162973950316E-07, 0.9950357662226532E+00, 0.9884618024514511E+00, 0.4826789459478154E-02, 0.6575396506892930E-02, 0.7255959263076781E+00, 0.7304241110285150E+00, 0.2358357443050565E-07, 0.1284558415558242E-07, 0.1332140830373310E+01, 0.1332142262063827E+01, -0.9894235909416862E+00, 0.4275036042946169E-26, 0.7140521119323301E-01, 0.7156177943897596E-01, 0.1565683011922014E-03, 0.1899018778701386E-03, 0.8679736700028205E-01, 0.8660746506696473E-01, 0.2079481441878513E-14, 0.1331360138522907E-23, 0.5544926940271698E-10, 0.8804208964992894E-17, 0.1565683011922014E-03, 0.8679736700028205E-01, 0.9539342071687115E+00}, + tauOut: 8.8042089649574750E-018, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1660287023423613E+01, 0.1660288431527609E+01, 0.1954678721190348E-11, 0.2946663608425970E-11, 0.1101355322036970E+01, 0.1101356702704238E+01, 0.2462874809952034E-07, 0.2744162973950316E-07, 0.9950357662226532E+00, 0.9884618024514511E+00, 0.4826789459478154E-02, 0.6575396506892930E-02, 0.7255959263076781E+00, 0.7304241110285150E+00, 0.2358357443050565E-07, 0.1284558415558242E-07, 0.1332140830373310E+01, 0.1332142262063827E+01, -0.9894235909416862E+00, 0.4275036042946169E-26}, + i0: 1, + n0: 5, + pp: 0, + n0in: 5, + dmin: -0.60723548073666500, + dmin1: 7.1561779438975959E-002, + dmin2: 7.1561779438975959E-002, + dn: 8.8042089649928937E-018, + dn1: 8.6378245068883266E-002, + dn2: 7.1561779438975959E-002, + tau: 0.0000000000000000, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.1660287023423613E+01, 0.1660288431527609E+01, 0.1954678721190348E-11, 0.2946663608425970E-11, 0.1101355322036970E+01, 0.1101356702704238E+01, 0.2462874809952034E-07, 0.2744162973950316E-07, 0.9950357662226532E+00, 0.9884618024514511E+00, 0.4826789459478154E-02, 0.6575396506892930E-02, 0.7255959263076781E+00, 0.7304241110285150E+00, 0.2358357443050565E-07, 0.1284558415558242E-07, 0.1332140830373310E+01, 0.1332142262063827E+01, -0.9894235909416862E+00, 0.4275036042946169E-26}, + tauOut: 0.60723548073666500, + ttypeOut: -1, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.1660287023423613E+01, 0.1053051542688903E+01, 0.1954678721190348E-11, 0.2044340400431280E-11, 0.1101355322036970E+01, 0.4941198659270088E+00, 0.2462874809952034E-07, 0.4959623550114665E-07, 0.9950357662226532E+00, 0.3926270253492309E+00, 0.4826789459478154E-02, 0.8920167341580701E-02, 0.7255959263076781E+00, 0.1094403018130068E+00, 0.2358357443050565E-07, 0.2870664819501689E-06, 0.1332140830373310E+01, 0.7249050625701626E+00, -0.9894235909416862E+00, 0.2044340400431280E-11, 0.1077066053646038E+01}, + i0: 1, + n0: 5, + pp: 1, + n0in: 5, + dmin: 0.10944027822943236, + dmin1: 0.10944027822943236, + dmin2: 0.38780023588975276, + dn: 0.72490506257016263, + dn1: 0.10944027822943236, + dn2: 0.38780023588975276, + tau: 0.60723548073666500, + ttype: -1, + g: 0.49975000000000003, + zOut: []float64{0.1660287023423613E+01, 0.1053051542688903E+01, 0.1954678721190348E-11, 0.2044340400431280E-11, 0.1101355322036970E+01, 0.4941198659270088E+00, 0.2462874809952034E-07, 0.4959623550114665E-07, 0.9950357662226532E+00, 0.3926270253492309E+00, 0.4826789459478154E-02, 0.8920167341580701E-02, 0.7255959263076781E+00, 0.1094403018130068E+00, 0.2358357443050565E-07, 0.2870664819501689E-06, 0.1332140830373310E+01, 0.7249050625701626E+00, -0.9894235909416862E+00, 0.2044340400431280E-11, 0.1077066053646038E+01}, + tauOut: 9.0381042476589277E-002, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9626705002143580E+00, 0.1053051542688903E+01, 0.1049319787347115E-11, 0.2044340400431280E-11, 0.4037388730456057E+00, 0.4941198659270088E+00, 0.4823122991958101E-07, 0.4959623550114665E-07, 0.3111661019829924E+00, 0.3926270253492309E+00, 0.3137314122148422E-02, 0.8920167341580701E-02, 0.1592223228075105E-01, 0.1094403018130068E+00, 0.1306952080528672E-04, 0.2870664819501689E-06, 0.6345109505727681E+00, 0.7249050625701626E+00, 0.1049319787347115E-11, 0.2044340400431280E-11}, + i0: 1, + n0: 5, + pp: 0, + n0in: 5, + dmin: 1.5921945214269095E-002, + dmin1: 1.5921945214269095E-002, + dmin2: 0.30224593464141175, + dn: 0.63451095057276807, + dn1: 1.5921945214269095E-002, + dn2: 0.30224593464141175, + tau: 9.0381042476589277E-002, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.9626705002143580E+00, 0.1053051542688903E+01, 0.1049319787347115E-11, 0.2044340400431280E-11, 0.4037388730456057E+00, 0.4941198659270088E+00, 0.4823122991958101E-07, 0.4959623550114665E-07, 0.3111661019829924E+00, 0.3926270253492309E+00, 0.3137314122148422E-02, 0.8920167341580701E-02, 0.1592223228075105E-01, 0.1094403018130068E+00, 0.1306952080528672E-04, 0.2870664819501689E-06, 0.6345109505727681E+00, 0.7249050625701626E+00, 0.1049319787347115E-11, 0.2044340400431280E-11}, + tauOut: 1.4134050686447828E-002, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9626705002143580E+00, 0.9485364495289594E+00, 0.1049319787347115E-11, 0.4466366986934060E-12, 0.4037388730456057E+00, 0.3896048705899411E+00, 0.4823122991958101E-07, 0.3852088344069326E-07, 0.3111661019829924E+00, 0.3001693268978096E+00, 0.3137314122148422E-02, 0.1664162181618706E-03, 0.1592223228075105E-01, 0.1634834896946635E-02, 0.1306952080528672E-04, 0.5072533064458891E-02, 0.6345109505727681E+00, 0.6153043668218613E+00, 0.1049319787347115E-11, 0.4466366986934060E-12, 0.1077066053646038E+01}, + i0: 1, + n0: 5, + pp: 1, + n0in: 5, + dmin: 1.6217653761413479E-003, + dmin1: 1.6217653761413479E-003, + dmin2: 0.29703201277566116, + dn: 0.61530436682186129, + dn1: 1.6217653761413479E-003, + dn2: 0.29703201277566116, + tau: 1.4134050686447828E-002, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.9626705002143580E+00, 0.9485364495289594E+00, 0.1049319787347115E-11, 0.4466366986934060E-12, 0.4037388730456057E+00, 0.3896048705899411E+00, 0.4823122991958101E-07, 0.3852088344069326E-07, 0.3111661019829924E+00, 0.3001693268978096E+00, 0.3137314122148422E-02, 0.1664162181618706E-03, 0.1592223228075105E-01, 0.1634834896946635E-02, 0.1306952080528672E-04, 0.5072533064458891E-02, 0.6345109505727681E+00, 0.6153043668218613E+00, 0.1049319787347115E-11, 0.4466366986934060E-12, 0.1077066053646038E+01}, + tauOut: 1.5809617416939919E-003, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9469554877877121E+00, 0.9485364495289594E+00, 0.1837592531426069E-12, 0.4466366986934060E-12, 0.3880239473689468E+00, 0.3896048705899411E+00, 0.2979915990315817E-07, 0.3852088344069326E-07, 0.2987547515751175E+00, 0.3001693268978096E+00, 0.9106567826436868E-06, 0.1664162181618706E-03, 0.5125495562928890E-02, 0.1634834896946635E-02, 0.6089463364253304E+00, 0.5072533064458891E-02, 0.4777068654836977E-02, 0.6153043668218613E+00, 0.1837592531426069E-12, 0.4466366986934060E-12}, + i0: 1, + n0: 5, + pp: 0, + n0in: 5, + dmin: 5.2962498469998932E-005, + dmin1: 5.2962498469998932E-005, + dmin2: 0.29858833535695567, + dn: 4.7770686548369769E-003, + dn1: 5.2962498469998932E-005, + dn2: 0.29858833535695567, + tau: 1.5809617416939919E-003, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.9469554877877121E+00, 0.9485364495289594E+00, 0.1837592531426069E-12, 0.4466366986934060E-12, 0.3880239473689468E+00, 0.3896048705899411E+00, 0.2979915990315817E-07, 0.3852088344069326E-07, 0.2987547515751175E+00, 0.3001693268978096E+00, 0.9106567826436868E-06, 0.1664162181618706E-03, 0.5125495562928890E-02, 0.1634834896946635E-02, 0.6089463364253304E+00, 0.5072533064458891E-02, 0.4777068654836977E-02, 0.6153043668218613E+00, 0.1837592531426069E-12, 0.4466366986934060E-12}, + tauOut: 4.7621670852039755E-005, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9469554877877121E+00, 0.9469159823779022E+00, 0.1837592531426069E-12, 0.7530022947855128E-13, 0.3880239473689468E+00, 0.3879844717580378E+00, 0.2979915990315817E-07, 0.2294586835827609E-07, 0.2987547515751175E+00, 0.2987161338760382E+00, 0.9106567826436868E-06, 0.1562542751952015E-07, 0.5125495562928890E-02, 0.6140323109528382E+00, 0.6089463364253304E+00, 0.4737500623869755E-02, 0.4777068654836977E-02, 0.6262097360996939E-07, 0.1837592531426069E-12, 0.7530022947855128E-13, 0.1077066053646038E+01}, + i0: 1, + n0: 5, + pp: 1, + n0in: 5, + dmin: 6.2620973609969386E-008, + dmin1: 5.0859745275077589E-003, + dmin2: 0.29871522321925559, + dn: 6.2620973609969386E-008, + dn1: 5.0859745275077589E-003, + dn2: 0.29871522321925559, + tau: 3.9505409993611756E-005, + ttype: -15, + g: 0.49975000000000003, + zOut: []float64{0.9469554877877121E+00, 0.9469159823779022E+00, 0.1837592531426069E-12, 0.7530022947855128E-13, 0.3880239473689468E+00, 0.3879844717580378E+00, 0.2979915990315817E-07, 0.2294586835827609E-07, 0.2987547515751175E+00, 0.2987161338760382E+00, 0.9106567826436868E-06, 0.1562542751952015E-07, 0.5125495562928890E-02, 0.6140323109528382E+00, 0.6089463364253304E+00, 0.4737500623869755E-02, 0.4777068654836977E-02, 0.6262097360996939E-07, 0.1837592531426069E-12, 0.7530022947855128E-13, 0.1077066053646038E+01}, + tauOut: 6.2141437994562936E-008, + ttypeOut: -2, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9469159202365395E+00, 0.9469159823779022E+00, 0.3085312975855001E-13, 0.7530022947855128E-13, 0.3879844325624373E+00, 0.3879844717580378E+00, 0.1766643326162244E-07, 0.2294586835827609E-07, 0.2987160696935945E+00, 0.2987161338760382E+00, 0.3211918722443868E-07, 0.1562542751952015E-07, 0.6187697173160828E+00, 0.6140323109528382E+00, 0.4794463808464251E-09, 0.4737500623869755E-02, 0.8923456002485611E-13, 0.6262097360996939E-07, 0.3085312975855001E-13, 0.7530022947855128E-13}, + i0: 1, + n0: 5, + pp: 0, + n0in: 5, + dmin: 8.9234560024856112E-014, + dmin1: 0.29871605406816698, + dmin2: 0.29871605406816698, + dn: 8.9234560024856112E-014, + dn1: 0.61403221669221297, + dn2: 0.29871605406816698, + tau: 6.2141437994562936E-008, + ttype: -2, + g: 0.49975000000000003, + zOut: []float64{0.9469159202365395E+00, 0.9469159823779022E+00, 0.3085312975855001E-13, 0.7530022947855128E-13, 0.3879844325624373E+00, 0.3879844717580378E+00, 0.1766643326162244E-07, 0.2294586835827609E-07, 0.2987160696935945E+00, 0.2987161338760382E+00, 0.3211918722443868E-07, 0.1562542751952015E-07, 0.6187697173160828E+00, 0.6140323109528382E+00, 0.4794463808464251E-09, 0.4737500623869755E-02, 0.8923456002485611E-13, 0.6262097360996939E-07, 0.3085312975855001E-13, 0.7530022947855128E-13}, + tauOut: 8.9232014685788963E-014, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9469159202365395E+00, 0.9469159202364811E+00, 0.3085312975855001E-13, 0.1264160184270297E-13, 0.3879844325624373E+00, 0.3879844502287687E+00, 0.1766643326162244E-07, 0.1360169848638109E-07, 0.2987160696935945E+00, 0.2987160882109940E+00, 0.3211918722443868E-07, 0.6653267495003571E-07, 0.6187697173160828E+00, 0.6187696512627651E+00, 0.4794463808464251E-09, 0.6914234847011291E-22, 0.8923456002485611E-13, 0.2545269924803487E-17, 0.3085312975855001E-13, 0.1264160184270297E-13, 0.1077066053646038E+01}, + i0: 1, + n0: 5, + pp: 1, + n0in: 5, + dmin: 2.5452699248034865E-018, + dmin1: 0.29871605609180679, + dmin2: 0.29871605609180679, + dn: 2.5452699248034865E-018, + dn1: 0.61876965078331869, + dn2: 0.29871605609180679, + tau: 8.9232014685788963E-014, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.9469159202365395E+00, 0.9469159202364811E+00, 0.3085312975855001E-13, 0.1264160184270297E-13, 0.3879844325624373E+00, 0.3879844502287687E+00, 0.1766643326162244E-07, 0.1360169848638109E-07, 0.2987160696935945E+00, 0.2987160882109940E+00, 0.3211918722443868E-07, 0.6653267495003571E-07, 0.6187697173160828E+00, 0.6187696512627651E+00, 0.4794463808464251E-09, 0.6914234847011291E-22, 0.8923456002485611E-13, 0.2545269924803487E-17, 0.3085312975855001E-13, 0.1264160184270297E-13, 0.1077066053646038E+01}, + tauOut: 2.5452699247759164E-018, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9469159202364937E+00, 0.9469159202364811E+00, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.3879844638304620E+00, 0.3879844502287687E+00, 0.1047218779010850E-07, 0.1360169848638109E-07, 0.2987161442714811E+00, 0.2987160882109940E+00, 0.1378177941363543E-06, 0.6653267495003571E-07, 0.6187695134449710E+00, 0.6187696512627651E+00, 0.2844127518685707E-39, 0.6914234847011291E-22}, + i0: 1, + n0: 4, + pp: 0, + n0in: 5, + dmin: 2.5452699248034865E-018, + dmin1: 0.29871607773880621, + dmin2: 0.29871607773880621, + dn: 2.5452699248034865E-018, + dn1: 0.61876951344497100, + dn2: 0.29871607773880621, + tau: 0.0000000000000000, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.9469159202364937E+00, 0.9469159202364811E+00, 0.5179704803914515E-14, 0.1264160184270297E-13, 0.3879844638304620E+00, 0.3879844502287687E+00, 0.1047218779010850E-07, 0.1360169848638109E-07, 0.2987161442714811E+00, 0.2987160882109940E+00, 0.1378177941363543E-06, 0.6653267495003571E-07, 0.6187695134449710E+00, 0.6187696512627651E+00, 0.2844127518685707E-39, 0.6914234847011291E-22}, + tauOut: 7.4679019434701552E-002, + ttypeOut: -9, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.9469159202364937E+00, 0.8722369008017974E+00, 0.5179704803914515E-14, 0.2304012808102351E-14, 0.3879844638304620E+00, 0.3133054548679459E+00, 0.1047218779010850E-07, 0.9984542273822185E-08, 0.2987161442714811E+00, 0.2240372526700314E+00, 0.1378177941363543E-06, 0.3806395963416417E-06, 0.6187695134449710E+00, 0.5440901133706730E+00, 0.2844127518685707E-39, 0.2304012808102351E-14, 0.1702794694134603E+01}, + i0: 1, + n0: 4, + pp: 1, + n0in: 4, + dmin: 0.22403711485223726, + dmin1: 0.22403711485223726, + dmin2: 0.31330544439575814, + dn: 0.54409011337067303, + dn1: 0.22403711485223726, + dn2: 0.31330544439575814, + tau: 7.4679019434701552E-002, + ttype: -9, + g: 0.49975000000000003, + zOut: []float64{0.9469159202364937E+00, 0.8722369008017974E+00, 0.5179704803914515E-14, 0.2304012808102351E-14, 0.3879844638304620E+00, 0.3133054548679459E+00, 0.1047218779010850E-07, 0.9984542273822185E-08, 0.2987161442714811E+00, 0.2240372526700314E+00, 0.1378177941363543E-06, 0.3806395963416417E-06, 0.6187695134449710E+00, 0.5440901133706730E+00, 0.2844127518685707E-39, 0.2304012808102351E-14, 0.1702794694134603E+01}, + tauOut: 0.22392121955733330, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6483156812444665E+00, 0.8722369008017974E+00, 0.1113438717814820E-14, 0.2304012808102351E-14, 0.8938424529515379E-01, 0.3133054548679459E+00, 0.2502576838690600E-07, 0.9984542273822185E-08, 0.1163887265260836E-03, 0.2240372526700314E+00, 0.1779401212715201E-02, 0.3806395963416417E-06, 0.3183894926006245E+00, 0.5440901133706730E+00, 0.1113438717814820E-14, 0.2304012808102351E-14}, + i0: 1, + n0: 4, + pp: 0, + n0in: 4, + dmin: 1.1600808692974196E-004, + dmin1: 1.1600808692974196E-004, + dmin2: 8.9384235310611515E-002, + dn: 0.31838949260062449, + dn1: 1.1600808692974196E-004, + dn2: 8.9384235310611515E-002, + tau: 0.22392121955733330, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.6483156812444665E+00, 0.8722369008017974E+00, 0.1113438717814820E-14, 0.2304012808102351E-14, 0.8938424529515379E-01, 0.3133054548679459E+00, 0.2502576838690600E-07, 0.9984542273822185E-08, 0.1163887265260836E-03, 0.2240372526700314E+00, 0.1779401212715201E-02, 0.3806395963416417E-06, 0.3183894926006245E+00, 0.5440901133706730E+00, 0.1113438717814820E-14, 0.2304012808102351E-14}, + tauOut: 1.1589031543524988E-004, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6483156812444665E+00, 0.6482265310101248E+00, 0.1113438717814820E-14, 0.1535325610927932E-15, 0.8938424529515379E-01, 0.8929512008657929E-01, 0.2502576838690600E-07, 0.3261899765703413E-10, 0.1163887265260836E-03, 0.1806639672279546E-02, 0.1779401212715201E-02, 0.3135891777105103E+00, 0.3183894926006245E+00, 0.4711164655771408E-02, 0.1113438717814820E-14, 0.1535325610927932E-15, 0.1702794694134603E+01}, + i0: 1, + n0: 4, + pp: 1, + n0in: 4, + dmin: 2.7238459564345061E-005, + dmin1: 2.7238459564345061E-005, + dmin2: 8.9295095060810903E-002, + dn: 4.7111646557714080E-003, + dn1: 2.7238459564345061E-005, + dn2: 8.9295095060810903E-002, + tau: 8.9150234342740890E-005, + ttype: -15, + g: 0.49975000000000003, + zOut: []float64{0.6483156812444665E+00, 0.6482265310101248E+00, 0.1113438717814820E-14, 0.1535325610927932E-15, 0.8938424529515379E-01, 0.8929512008657929E-01, 0.2502576838690600E-07, 0.3261899765703413E-10, 0.1163887265260836E-03, 0.1806639672279546E-02, 0.1779401212715201E-02, 0.3135891777105103E+00, 0.3183894926006245E+00, 0.4711164655771408E-02, 0.1113438717814820E-14, 0.1535325610927932E-15, 0.1702794694134603E+01}, + tauOut: 2.5005145741075717E-005, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6482015258643838E+00, 0.6482265310101248E+00, 0.2115037983241246E-16, 0.1535325610927932E-15, 0.8927011497345719E-01, 0.8929512008657929E-01, 0.6601400172354812E-12, 0.3261899765703413E-10, 0.3153708122363886E+00, 0.1806639672279546E-02, 0.4684549720964035E-02, 0.3135891777105103E+00, 0.1609789066298190E-05, 0.4711164655771408E-02, 0.2115037983241246E-16, 0.1535325610927932E-15}, + i0: 1, + n0: 4, + pp: 0, + n0in: 4, + dmin: 1.6097890662981897E-006, + dmin1: 1.7816345258783307E-003, + dmin2: 8.9270114940838197E-002, + dn: 1.6097890662981897E-006, + dn1: 1.7816345258783307E-003, + dn2: 8.9270114940838197E-002, + tau: 2.5005145741075717E-005, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.6482015258643838E+00, 0.6482265310101248E+00, 0.2115037983241246E-16, 0.1535325610927932E-15, 0.8927011497345719E-01, 0.8929512008657929E-01, 0.6601400172354812E-12, 0.3261899765703413E-10, 0.3153708122363886E+00, 0.1806639672279546E-02, 0.4684549720964035E-02, 0.3135891777105103E+00, 0.1609789066298190E-05, 0.4711164655771408E-02, 0.2115037983241246E-16, 0.1535325610927932E-15}, + tauOut: 1.5862205428611591E-006, + ttypeOut: -2, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6482015258643838E+00, 0.6481999396438409E+00, 0.2115037983241246E-16, 0.2912830939801045E-17, 0.8927011497345719E-01, 0.8926852875357447E-01, 0.6601400172354812E-12, 0.2332164496627946E-11, 0.3153708122363886E+00, 0.3200537757344777E+00, 0.4684549720964035E-02, 0.2356209328895529E-07, 0.1609789066298190E-05, 0.6430148075154844E-11, 0.2115037983241246E-16, 0.2912830939801045E-17, 0.1702794694134603E+01}, + i0: 1, + n0: 4, + pp: 1, + n0in: 4, + dmin: 6.4301480751548441E-012, + dmin1: 8.9268528752914328E-002, + dmin2: 8.9268528752914328E-002, + dn: 6.4301480751548441E-012, + dn1: 0.31536922601351364, + dn2: 8.9268528752914328E-002, + tau: 1.5862205428611591E-006, + ttype: -2, + g: 0.49975000000000003, + zOut: []float64{0.6482015258643838E+00, 0.6481999396438409E+00, 0.2115037983241246E-16, 0.2912830939801045E-17, 0.8927011497345719E-01, 0.8926852875357447E-01, 0.6601400172354812E-12, 0.2332164496627946E-11, 0.3153708122363886E+00, 0.3200537757344777E+00, 0.4684549720964035E-02, 0.2356209328895529E-07, 0.1609789066298190E-05, 0.6430148075154844E-11, 0.2115037983241246E-16, 0.2912830939801045E-17, 0.1702794694134603E+01}, + tauOut: 6.4283598105616478E-012, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6481999396374125E+00, 0.6481999396438409E+00, 0.4011480356653261E-18, 0.2912830939801045E-17, 0.8926852874947827E-01, 0.8926852875357447E-01, 0.8361491594360282E-11, 0.2332164496627946E-11, 0.3200537992817811E+00, 0.3200537757344777E+00, 0.4733821287189426E-18, 0.2356209328895529E-07, 0.1787791211067534E-14, 0.6430148075154844E-11, 0.4011480356653261E-18, 0.2912830939801045E-17}, + i0: 1, + n0: 4, + pp: 0, + n0in: 4, + dmin: 1.7877912110675335E-015, + dmin1: 8.9268528747146109E-002, + dmin2: 8.9268528747146109E-002, + dn: 1.7877912110675335E-015, + dn1: 0.32005377571968785, + dn2: 8.9268528747146109E-002, + tau: 6.4283598105616478E-012, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.6481999396374125E+00, 0.6481999396438409E+00, 0.4011480356653261E-18, 0.2912830939801045E-17, 0.8926852874947827E-01, 0.8926852875357447E-01, 0.8361491594360282E-11, 0.2332164496627946E-11, 0.3200537992817811E+00, 0.3200537757344777E+00, 0.4733821287189426E-18, 0.2356209328895529E-07, 0.1787791211067534E-14, 0.6430148075154844E-11, 0.4011480356653261E-18, 0.2912830939801045E-17}, + tauOut: 1.7877912088395813E-015, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6481999396374125E+00, 0.6481999396374107E+00, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.8926852874947827E-01, 0.8926852875783797E-01, 0.8361491594360282E-11, 0.2997839428604580E-10, 0.3200537992817811E+00, 0.3200537992518009E+00, 0.4733821287189426E-18, 0.2644269217171004E-32, 0.2001510674733695E+01}, + i0: 1, + n0: 3, + pp: 1, + n0in: 4, + dmin: 2.2279522444840209E-024, + dmin1: 8.9268528749476481E-002, + dmin2: 8.9268528749476481E-002, + dn: 2.2279522444840209E-024, + dn1: 0.32005379925180094, + dn2: 8.9268528749476481E-002, + tau: 1.7877912088395813E-015, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.6481999396374125E+00, 0.6481999396374107E+00, 0.4011480356653261E-18, 0.5524513774965514E-19, 0.8926852874947827E-01, 0.8926852875783797E-01, 0.8361491594360282E-11, 0.2997839428604580E-10, 0.3200537992817811E+00, 0.3200537992518009E+00, 0.4733821287189426E-18, 0.2644269217171004E-32, 0.2001510674733695E+01}, + tauOut: 2.2317132187369120E-002, + ttypeOut: -9, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6258828074500417E+00, 0.6481999396374107E+00, 0.7879513719234823E-20, 0.5524513774965514E-19, 0.6695139660044724E-01, 0.8926852875783797E-01, 0.1433084218388560E-09, 0.2997839428604580E-10, 0.2977366669211234E+00, 0.3200537992518009E+00, 0.8926852875783797E-01, 0.2644269217171004E-32}, + i0: 1, + n0: 3, + pp: 0, + n0in: 3, + dmin: 6.6951396570468849E-002, + dmin1: 6.6951396570468849E-002, + dmin2: 0.62588280745004166, + dn: 0.29773666692112338, + dn1: 6.6951396570468849E-002, + dn2: 0.62588280745004166, + tau: 2.2317132187369120E-002, + ttype: -9, + g: 0.49975000000000003, + zOut: []float64{0.6258828074500417E+00, 0.6481999396374107E+00, 0.7879513719234823E-20, 0.5524513774965514E-19, 0.6695139660044724E-01, 0.8926852875783797E-01, 0.1433084218388560E-09, 0.2997839428604580E-10, 0.2977366669211234E+00, 0.3200537992518009E+00, 0.8926852875783797E-01, 0.2644269217171004E-32}, + tauOut: 6.6950732596142107E-002, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.6258828074500417E+00, 0.5589320748538995E+00, 0.7879513719234823E-20, 0.9438435755776795E-21, 0.6695139660044724E-01, 0.6641476135588615E-06, 0.1433084218388560E-09, 0.6424501268835132E-04, 0.2977366669211234E+00, 0.2307216893122929E+00, 0.8926852875783797E-01, 0.6695139660044724E-01, 0.2001510674733695E+01}, + i0: 1, + n0: 3, + pp: 1, + n0in: 3, + dmin: 6.6400430513702258E-007, + dmin1: 6.6400430513702258E-007, + dmin2: 0.55893207485389951, + dn: 0.23072168931229292, + dn1: 6.6400430513702258E-007, + dn2: 0.55893207485389951, + tau: 6.6950732596142107E-002, + ttype: -4, + g: 0.49975000000000003, + zOut: []float64{0.6258828074500417E+00, 0.5589320748538995E+00, 0.7879513719234823E-20, 0.9438435755776795E-21, 0.6695139660044724E-01, 0.6641476135588615E-06, 0.1433084218388560E-09, 0.6424501268835132E-04, 0.2977366669211234E+00, 0.2307216893122929E+00, 0.8926852875783797E-01, 0.6695139660044724E-01, 0.2001510674733695E+01}, + tauOut: 6.6398937736467640E-007, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + { + z: []float64{0.5589315065851642E+00, 0.5589320748538995E+00, 0.1121517486324177E-26, 0.9438435755776795E-21, 0.6434089156657428E-04, 0.6641476135588615E-06, 0.2303778747300831E+00, 0.6424501268835132E-04, 0.3432463134744483E-03, 0.2307216893122929E+00, 0.6641476135588615E-06, 0.6695139660044724E-01}, + i0: 1, + n0: 3, + pp: 0, + n0in: 3, + dmin: 9.5878878222950548E-008, + dmin1: 9.5878878222950548E-008, + dmin2: 0.55893150658516422, + dn: 3.4324631347444829E-004, + dn1: 9.5878878222950548E-008, + dn2: 0.55893150658516422, + tau: 5.6826873533591094E-007, + ttype: -15, + g: 0.49975000000000003, + zOut: []float64{0.5589315065851642E+00, 0.5589320748538995E+00, 0.1121517486324177E-26, 0.9438435755776795E-21, 0.6434089156657428E-04, 0.6641476135588615E-06, 0.2303778747300831E+00, 0.6424501268835132E-04, 0.3432463134744483E-03, 0.2307216893122929E+00, 0.6641476135588615E-06, 0.6695139660044724E-01}, + tauOut: 9.4211902206835373E-008, + ttypeOut: -4, + gOut: 0.49975000000000003, + }, + } { + z := make([]float64, len(test.z)) + copy(z, test.z) + + // Print for fortran input + //printDlasq4FortranInput(test) + + i0 := test.i0 - 1 // zero index + n0 := test.n0 - 1 // zero index + n0in := test.n0in - 1 + + tauOut, ttypeOut, gOut := impl.Dlasq4(i0, n0, z, test.pp, n0in, test.dmin, test.dmin1, test.dmin2, test.dn, test.dn1, test.dn2, test.tau, test.ttype, test.g) + + if !floats.EqualApprox(z, test.zOut, dTol) { + t.Errorf("Z mismatch") + } + if !floats.EqualWithinAbsOrRel(tauOut, test.tauOut, dTol, dTol) { + t.Errorf("Case %d, wrong tau. Want %v, got %v", cas, test.tauOut, tauOut) + } + if ttypeOut != test.ttypeOut { + t.Errorf("Wrong ttype. Want %v, got %v", test.ttypeOut, ttypeOut) + } + if !floats.EqualWithinAbsOrRel(gOut, test.gOut, dTol, dTol) { + t.Errorf("Wrong g. Want %v, got %v", test.gOut, gOut) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq5.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq5.go new file mode 100644 index 00000000..235b9b9e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasq5.go @@ -0,0 +1,1992 @@ +// 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 testlapack + +import ( + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dlasq5er interface { + Dlasq5(i0, n0 int, z []float64, pp int, tau, sigma float64) (i0Out, n0Out, ppOut int, tauOut, sigmaOut, dmin, dmin1, dmin2, dn, dnm1, dnm2 float64) +} + +func Dlasq5Test(t *testing.T, impl Dlasq5er) { + dTol := 1e-14 + for _, test := range []struct { + z []float64 + i0, n0, pp int + tau, sigma float64 + + i0Out, n0Out, ppOut int + tauOut, sigmaOut float64 + dminOut, dmin1Out, dmin2Out float64 + dnOut, dnm1Out, dnm2Out float64 + }{ + { + z: []float64{0.1914365246180821E+01, 0.1564384297703890E+01, 0.2493389162143899E+00, 0.3499809484769305E+00, 0.1315996513131545E+01, 0.1363862112490627E+01, 0.9898466611970759E-01, 0.2014733168553078E+00, 0.6023973979587287E+00, 0.6465544792741794E+00, 0.2210033410638781E-02, 0.5482758480425683E-01, 0.9861857233678967E-01, 0.2428190810745492E-01, 0.4756321484454819E+00, 0.7654669763997353E-01, 0.2588748143677115E+00, 0.6127784069508770E+00, 0.1078611376690004E+00, 0.1217285558623164E+00, 0.6442896492255246E+00, 0.2293835804898155E+00, 0.6203230486639705E+00, 0.5227672064047094E+00, 0.3695660678607585E+00, 0.7645233184745865E+00, 0.5378838054252265E+00, 0.2253657980501426E+00, 0.3562533181264623E+00, 0.8820486722335483E+00, 0.2222132496436145E-01, 0.1208845131814035E-01, 0.1275094303021685E+01, 0.6548746852163357E+00, 0.1647324354821218E+00, 0.6424409427697111E+00, 0.1007530576543866E+01, 0.3269551736546701E+00, 0.3453881601783118E+00, 0.8453078383713172E+00, 0.2679391719153404E+00, 0.4116714838778281E+00, 0.7328677736683723E+00, 0.2016558482158241E+00, 0.8360828138307410E+00, 0.9737579452195326E+00, 0.4813660709592822E+00, 0.5951926422795808E+00, 0.6495370513676459E+00, 0.6761876248148171E+00, 0.2325475880222648E+00, 0.4547154975121112E+00, 0.1993624802893807E+00, 0.3321819367342255E+00, 0.3782318916911257E+00, 0.9972813157741996E-01, 0.9830449403503746E+00, 0.7561080996844842E+00, 0.4429733864040367E+00, 0.6051687323570161E+00, 0.1173279550602403E+01, 0.7195724480316686E+00, 0.5035524069144587E+00, 0.8966804889747714E+00, 0.3058980395058521E+00, 0.6588832353928662E+00, 0.3014634433415453E+00, 0.1505672110274446E+00, 0.1289422237567578E+01, 0.6124645310993601E+00, 0.7583364305799440E+00, 0.9784211498097629E+00, 0.4977814779461571E+00, 0.9993813577491869E+00, 0.2841468847862598E+00, 0.2567365507769143E+00, 0.9257539794205765E+00, 0.5509268385614666E+00, 0.5231355605450990E-04, 0.6589740256453697E+00, 0.2117869221381033E-04, 0.7349224826832024E-04, 0.0000000000000000E+00, 0.0000000000000000E+00}, + i0: 1, + n0: 21, + pp: 0, + tau: 0.0000000000000000, + sigma: 0.0000000000000000, + i0Out: 1, + n0Out: 21, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 0.0000000000000000, + dminOut: 2.1175426017541180E-005, + dmin1Out: 4.4311601260836921E-002, + dmin2Out: 4.4311601260836921E-002, + dnOut: 2.1175426017541180E-005, + dnm1Out: 0.33915960483100382, + dnm2Out: 0.16428924199195991, + }, + { + z: []float64{0.1914365246180821E+01, 0.2163704162395211E+01, 0.2493389162143899E+00, 0.1516515751224039E+00, 0.1315996513131545E+01, 0.1263329604128848E+01, 0.9898466611970759E-01, 0.4719916727467415E-01, 0.6023973979587287E+00, 0.5574082640946934E+00, 0.2210033410638781E-02, 0.3910066531356214E-03, 0.9861857233678967E-01, 0.5738597141291359E+00, 0.4756321484454819E+00, 0.2145632131068746E+00, 0.2588748143677115E+00, 0.1521727389298373E+00, 0.1078611376690004E+00, 0.4566771620366771E+00, 0.6442896492255246E+00, 0.8079355358528180E+00, 0.6203230486639705E+00, 0.2837483186776231E+00, 0.3695660678607585E+00, 0.6237015546083620E+00, 0.5378838054252265E+00, 0.3072349091217998E+00, 0.3562533181264623E+00, 0.7123973396902394E-01, 0.2222132496436145E-01, 0.3977314805803597E+00, 0.1275094303021685E+01, 0.1042095257923447E+01, 0.1647324354821218E+00, 0.1592685164190333E+00, 0.1007530576543866E+01, 0.1193650220303144E+01, 0.3453881601783118E+00, 0.7752942700755104E-01, 0.2679391719153404E+00, 0.9232775185761617E+00, 0.7328677736683723E+00, 0.6636554427529671E+00, 0.8360828138307410E+00, 0.6537934420370561E+00, 0.4813660709592822E+00, 0.4782322339990674E+00, 0.6495370513676459E+00, 0.4038524053908432E+00, 0.2325475880222648E+00, 0.1147975431483785E+00, 0.1993624802893807E+00, 0.4627968288321279E+00, 0.3782318916911257E+00, 0.8034172324482011E+00, 0.9830449403503746E+00, 0.6226010943062101E+00, 0.4429733864040367E+00, 0.8347746582554776E+00, 0.1173279550602403E+01, 0.8420572992613844E+00, 0.5035524069144587E+00, 0.1829278057427913E+00, 0.3058980395058521E+00, 0.4244336771046062E+00, 0.3014634433415453E+00, 0.9158407747236312E+00, 0.1289422237567578E+01, 0.1131917893423890E+01, 0.7583364305799440E+00, 0.3334922359541972E+00, 0.4977814779461571E+00, 0.4484361267782198E+00, 0.2841468847862598E+00, 0.5865943745895725E+00, 0.9257539794205765E+00, 0.3392119183870583E+00, 0.5231355605450990E-04, 0.3266196269153995E-08, 0.2117869221381033E-04, 0.2117542601754118E-04, 0.0000000000000000E+00, 0.3910066531356214E-03, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + tau: 0.0000000000000000, + sigma: 0.0000000000000000, + i0Out: 1, + n0Out: 21, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 0.0000000000000000, + dminOut: 2.1175425069176302E-005, + dmin1Out: 2.9944624525135358E-002, + dmin2Out: 2.9944624525135358E-002, + dnOut: 2.1175425069176302E-005, + dnm1Out: 7.2928780948497918E-002, + dnm2Out: 0.16065460645225654, + }, + { + z: []float64{0.2315355737517615E+01, 0.2163704162395211E+01, 0.8274578340618610E-01, 0.1516515751224039E+00, 0.1227782987997336E+01, 0.1263329604128848E+01, 0.2142822156235013E-01, 0.4719916727467415E-01, 0.5363710491854788E+00, 0.5574082640946934E+00, 0.4183353417969536E-03, 0.3910066531356214E-03, 0.7880045918942136E+00, 0.5738597141291359E+00, 0.4143462125464707E-01, 0.2145632131068746E+00, 0.5674152797118673E+00, 0.1521727389298373E+00, 0.6502569120260687E+00, 0.4566771620366771E+00, 0.4414269425043723E+00, 0.8079355358528180E+00, 0.4009140594652070E+00, 0.2837483186776231E+00, 0.5300224042649548E+00, 0.6237015546083620E+00, 0.4129510944388858E-01, 0.3072349091217998E+00, 0.4276761051054951E+00, 0.7123973396902394E-01, 0.9691308092544145E+00, 0.3977314805803597E+00, 0.2322329650880660E+00, 0.1042095257923447E+01, 0.8186215063776209E+00, 0.1592685164190333E+00, 0.4525581409330741E+00, 0.1193650220303144E+01, 0.1581701233715052E+00, 0.7752942700755104E-01, 0.1428762837957623E+01, 0.9232775185761617E+00, 0.3036848136842134E+00, 0.6636554427529671E+00, 0.8283408623519102E+00, 0.6537934420370561E+00, 0.2331591338951825E+00, 0.4782322339990674E+00, 0.2854908146440392E+00, 0.4038524053908432E+00, 0.1860933389154074E+00, 0.1147975431483785E+00, 0.1080120722364922E+01, 0.4627968288321279E+00, 0.4631042046962229E+00, 0.8034172324482011E+00, 0.9942715478654648E+00, 0.6226010943062101E+00, 0.7069779837626068E+00, 0.8347746582554776E+00, 0.3180071212415688E+00, 0.8420572992613844E+00, 0.2441477440283845E+00, 0.1829278057427913E+00, 0.1096126707799853E+01, 0.4244336771046062E+00, 0.9457451890006905E+00, 0.9158407747236312E+00, 0.5196649403773971E+00, 0.1131917893423890E+01, 0.2877815203259632E+00, 0.3334922359541972E+00, 0.7472489810418290E+00, 0.4484361267782198E+00, 0.2662831374385604E+00, 0.5865943745895725E+00, 0.7292878421469419E-01, 0.3392119183870583E+00, 0.9483648767903632E-12, 0.3266196269153995E-08, 0.2117542506917630E-04, 0.2117542601754118E-04, 0.4183353417969536E-03, 0.3910066531356214E-03}, + i0: 1, + n0: 21, + pp: 0, + tau: 2.1175313795360271E-005, + sigma: 0.0000000000000000, + i0Out: 1, + n0Out: 21, + ppOut: 0, + tauOut: 2.1175313795360271E-005, + sigmaOut: 0.0000000000000000, + dminOut: 1.1127325659669794E-010, + dmin1Out: 3.1433071595911154E-002, + dmin2Out: 3.1433071595911154E-002, + dnOut: 1.1127325659669794E-010, + dnm1Out: 3.5896964560873705E-002, + dnm2Out: 0.25842281720128102, + }, + { + z: []float64{0.2315355737517615E+01, 0.2398080345610006E+01, 0.8274578340618610E-01, 0.4236466279397526E-01, 0.1227782987997336E+01, 0.1206825371451915E+01, 0.2142822156235013E-01, 0.9523728911788614E-02, 0.5363710491854788E+00, 0.5272444803016919E+00, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.7880045918942136E+00, 0.8287928057414093E+00, 0.4143462125464707E-01, 0.2836732781232222E-01, 0.5674152797118673E+00, 0.1189283688611819E+01, 0.6502569120260687E+00, 0.2413561400585997E+00, 0.4414269425043723E+00, 0.6009636865971842E+00, 0.4009140594652070E+00, 0.3535878097802652E+00, 0.5300224042649548E+00, 0.2177085286147829E+00, 0.4129510944388858E-01, 0.8112190955144877E-01, 0.4276761051054951E+00, 0.1315663829494665E+01, 0.9691308092544145E+00, 0.1710650671895379E+00, 0.2322329650880660E+00, 0.8797682289623537E+00, 0.8186215063776209E+00, 0.4211038940233675E+00, 0.4525581409330741E+00, 0.1896031949674164E+00, 0.1581701233715052E+00, 0.1191897606932286E+01, 0.1428762837957623E+01, 0.5405288693957555E+00, 0.3036848136842134E+00, 0.4653859482687157E+00, 0.8283408623519102E+00, 0.5960928726645816E+00, 0.2331591338951825E+00, 0.1116684901463164E+00, 0.2854908146440392E+00, 0.3598944880993349E+00, 0.1860933389154074E+00, 0.5585061130503639E+00, 0.1080120722364922E+01, 0.9846976386969850E+00, 0.4631042046962229E+00, 0.4676068229793028E+00, 0.9942715478654648E+00, 0.1233621533334973E+01, 0.7069779837626068E+00, 0.1822471700779458E+00, 0.3180071212415688E+00, 0.3798865198782122E+00, 0.2441477440283845E+00, 0.7044652781161848E+00, 0.1096126707799853E+01, 0.1337385443370563E+01, 0.9457451890006905E+00, 0.3674861422265960E+00, 0.5196649403773971E+00, 0.4399391431629689E+00, 0.2877815203259632E+00, 0.4888049885267526E+00, 0.7472489810418290E+00, 0.5247059546398414E+00, 0.2662831374385604E+00, 0.3701064434002514E-01, 0.7292878421469419E-01, 0.3589696456182207E-01, 0.9483648767903632E-12, 0.5594353069081231E-15, 0.2117542506917630E-04, 0.1112732565966979E-09, 0.4183353417969536E-03, 0.6252320936560726E-03, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + tau: 2.1175313795360271E-005, + sigma: 2.1175313795360271E-005, + i0Out: 1, + n0Out: 21, + ppOut: 1, + tauOut: 2.1175313795360271E-005, + sigmaOut: 2.1175313795360271E-005, + dminOut: -2.1175202522103674E-005, + dmin1Out: 2.9116497146097618E-002, + dmin2Out: 4.9396687496051764E-002, + dnOut: -2.1175202522103674E-005, + dnm1Out: 2.9116497146097618E-002, + dnm2Out: 0.15954393093937583, + }, + { + z: []float64{0.2440423833090186E+01, 0.2398080345610006E+01, 0.2094994698033050E-01, 0.4236466279397526E-01, 0.1195377978069578E+01, 0.1206825371451915E+01, 0.4200624064314086E-02, 0.9523728911788614E-02, 0.5236479130172386E+00, 0.5272444803016919E+00, 0.9895730475750664E-03, 0.6252320936560726E-03, 0.8561493851923613E+00, 0.8287928057414093E+00, 0.3940527300515336E-01, 0.2836732781232222E-01, 0.1391213380351470E+01, 0.1189283688611819E+01, 0.1042588274099539E+00, 0.2413561400585997E+00, 0.8502714936537001E+00, 0.6009636865971842E+00, 0.9053470847599347E-01, 0.3535878097802652E+00, 0.2082745543764428E+00, 0.2177085286147829E+00, 0.5124445590385125E+00, 0.8112190955144877E-01, 0.9742631623318954E+00, 0.1315663829494665E+01, 0.1544732645319877E+00, 0.1710650671895379E+00, 0.1146377683139938E+01, 0.8797682289623537E+00, 0.6964776521238716E-01, 0.4211038940233675E+00, 0.1311831861373520E+01, 0.1896031949674164E+00, 0.4911110065859084E+00, 0.1191897606932286E+01, 0.5147826357647675E+00, 0.5405288693957555E+00, 0.5388939477127089E+00, 0.4653859482687157E+00, 0.1688462397843937E+00, 0.5960928726645816E+00, 0.2380205454936569E+00, 0.1116684901463164E+00, 0.6803588803422466E+00, 0.3598944880993349E+00, 0.8083375797812383E+00, 0.5585061130503639E+00, 0.6439457065812542E+00, 0.9846976386969850E+00, 0.8958050967125053E+00, 0.4676068229793028E+00, 0.5200424313866183E+00, 0.1233621533334973E+01, 0.1331299890548604E+00, 0.1822471700779458E+00, 0.9512006336257413E+00, 0.3798865198782122E+00, 0.9904762202705547E+00, 0.7044652781161848E+00, 0.7143741900128092E+00, 0.1337385443370563E+01, 0.2263121215682984E+00, 0.3674861422265960E+00, 0.7024108348076278E+00, 0.4399391431629689E+00, 0.3651408483866702E+00, 0.4888049885267526E+00, 0.1965545752794010E+00, 0.5247059546398414E+00, 0.6759292101929097E-02, 0.3701064434002514E-01, 0.2911649714609818E-01, 0.3589696456182207E-01, 0.2137969692662087E-23, 0.5594353069081231E-15, -0.2117520252210367E-04, 0.1112732565966979E-09, 0.9895730475750664E-03, 0.6252320936560726E-03, 0.1037537856266618 - 321}, + i0: 1, + n0: 21, + pp: 1, + tau: 1.1127325659669789E-010, + sigma: 2.1175313795360271E-005, + i0Out: 1, + n0Out: 21, + ppOut: 1, + tauOut: 1.1127325659669789E-010, + sigmaOut: 2.1175313795360271E-005, + dminOut: -2.0808762284537102E-024, + dmin1Out: 2.9139336744737766E-002, + dmin2Out: 4.9426557292086552E-002, + dnOut: -2.0808762284537102E-024, + dnm1Out: 2.9139336744737766E-002, + dnm2Out: 0.15959234211062134, + }, + { + z: []float64{0.2440445008292708E+01, 0.2398080345610006E+01, 0.2094976520226600E-01, 0.4236466279397526E-01, 0.1195399335050165E+01, 0.1206825371451915E+01, 0.4200549016048655E-02, 0.9523728911788614E-02, 0.5236691632680260E+00, 0.5272444803016919E+00, 0.9895328911616120E-03, 0.6252320936560726E-03, 0.8561706005512968E+00, 0.8287928057414093E+00, 0.3940429656773515E-01, 0.2836732781232222E-01, 0.1391235531991410E+01, 0.1189283688611819E+01, 0.1042571673718422E+00, 0.2413561400585997E+00, 0.8502943288943339E+00, 0.6009636865971842E+00, 0.9053227710395735E-01, 0.3535878097802652E+00, 0.2082981609510011E+00, 0.2177085286147829E+00, 0.5123864833424303E+00, 0.8112190955144877E-01, 0.9743424132304999E+00, 0.1315663829494665E+01, 0.1544607000116935E+00, 0.1710650671895379E+00, 0.1146411422862754E+01, 0.8797682289623537E+00, 0.6964571542795012E-01, 0.4211038940233675E+00, 0.1311855086360479E+01, 0.1896031949674164E+00, 0.4911023119923957E+00, 0.1191897606932286E+01, 0.5148125055608023E+00, 0.5405288693957555E+00, 0.5388626806938843E+00, 0.4653859482687157E+00, 0.1688986820057405E+00, 0.5960928726645816E+00, 0.2379466412690434E+00, 0.1116684901463164E+00, 0.6804539597693821E+00, 0.3598944880993349E+00, 0.8082246312519304E+00, 0.5585061130503639E+00, 0.6440798303130841E+00, 0.9846976386969850E+00, 0.8956185534970393E+00, 0.4676068229793028E+00, 0.5202501498046066E+00, 0.1233621533334973E+01, 0.1330768347199243E+00, 0.1822471700779458E+00, 0.9512749631631994E+00, 0.3798865198782122E+00, 0.9903988276741268E+00, 0.7044652781161848E+00, 0.7144727578117591E+00, 0.1337385443370563E+01, 0.2262808998212762E+00, 0.3674861422265960E+00, 0.7024632317571722E+00, 0.4399391431629689E+00, 0.3651136124179467E+00, 0.4888049885267526E+00, 0.1966029864506465E+00, 0.5247059546398414E+00, 0.6757627705811050E-02, 0.3701064434002514E-01, 0.2913933674473832E-01, 0.3589696456182207E-01, 0.2136293938333395E-23, 0.5594353069081231E-15, 0.0000000000000000E+00, 0.1112732565966979E-09, 0.9895328911616120E-03, 0.6252320936560726E-03}, + i0: 1, + n0: 21, + pp: 0, + tau: -0.0000000000000000, + sigma: 2.1175425068616867E-005, + i0Out: 1, + n0Out: 21, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 2.1175425068616867E-005, + dminOut: 0.0000000000000000, + dmin1Out: 2.7016889331018056E-002, + dmin2Out: 5.3061698118516694E-002, + dnOut: 0.0000000000000000, + dnm1Out: 2.7016889331018056E-002, + dnm2Out: 8.6018658784156071E-002, + }, + { + z: []float64{0.2440445008292708E+01, 0.2461394773494974E+01, 0.2094976520226600E-01, 0.1017444891892999E-01, 0.1195399335050165E+01, 0.1189425435147283E+01, 0.4200549016048655E-02, 0.1849378635683999E-02, 0.5236691632680260E+00, 0.5228093175235037E+00, 0.9895328911616120E-03, 0.1620493249248586E-02, 0.8561706005512968E+00, 0.8939544038697832E+00, 0.3940429656773515E-01, 0.6132377362967349E-01, 0.1391235531991410E+01, 0.1434168925733579E+01, 0.1042571673718422E+00, 0.6181229879703373E-01, 0.8502943288943339E+00, 0.8790143072012576E+00, 0.9053227710395735E-01, 0.2145324219750511E-01, 0.2082981609510011E+00, 0.6992314020959263E+00, 0.5123864833424303E+00, 0.7139837844669097E+00, 0.9743424132304999E+00, 0.4148193287752837E+00, 0.1544607000116935E+00, 0.4268738185358478E+00, 0.1146411422862754E+01, 0.7891833197548568E+00, 0.6964571542795012E-01, 0.1157716892137957E+00, 0.1311855086360479E+01, 0.1687185709139079E+01, 0.4911023119923957E+00, 0.1498504938454686E+00, 0.5148125055608023E+00, 0.9038246924092180E+00, 0.5388626806938843E+00, 0.1006978425303630E+00, 0.1688986820057405E+00, 0.3061474807444209E+00, 0.2379466412690434E+00, 0.5288684194677825E+00, 0.6804539597693821E+00, 0.9598101715535300E+00, 0.8082246312519304E+00, 0.5423584775195998E+00, 0.6440798303130841E+00, 0.9973399062905237E+00, 0.8956185534970393E+00, 0.4671884516860899E+00, 0.5202501498046066E+00, 0.1861385328384410E+00, 0.1330768347199243E+00, 0.6800991665489665E+00, 0.9512749631631994E+00, 0.1261574624288360E+01, 0.9903988276741268E+00, 0.5608966509936130E+00, 0.7144727578117591E+00, 0.3798570066394223E+00, 0.2262808998212762E+00, 0.4184574968871406E+00, 0.7024632317571722E+00, 0.6491193472879784E+00, 0.3651136124179467E+00, 0.1105843276664904E+00, 0.1966029864506465E+00, 0.9277628648996712E-01, 0.6757627705811050E-02, 0.2122447413720272E-02, 0.2913933674473832E-01, 0.2701688933101806E-01, 0.2136293938333395E-23, 0.0000000000000000E+00, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + tau: -0.0000000000000000, + sigma: 2.1175425068616867E-005, + i0Out: 1, + n0Out: 20, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 2.1175425068616867E-005, + dminOut: 2.5763383633962696E-002, + dmin1Out: 4.3622798915905092E-002, + dmin2Out: 7.4536672467372611E-002, + dnOut: 2.5763383633962696E-002, + dnm1Out: 4.3622798915905092E-002, + dnm2Out: 9.8141518071882677E-002, + }, + { + z: []float64{0.2471569222413904E+01, 0.2461394773494974E+01, 0.4896382518051712E-02, 0.1017444891892999E-01, 0.1186378431264915E+01, 0.1189425435147283E+01, 0.8149780515932184E-03, 0.1849378635683999E-02, 0.5236148327211592E+00, 0.5228093175235037E+00, 0.2766627272719901E-02, 0.1620493249248586E-02, 0.9525115502267366E+00, 0.8939544038697832E+00, 0.9233342160256496E-01, 0.6132377362967349E-01, 0.1403647802928048E+01, 0.1434168925733579E+01, 0.3870906568602875E-01, 0.6181229879703373E-01, 0.8617584837127339E+00, 0.8790143072012576E+00, 0.1740717486950262E-01, 0.2145324219750511E-01, 0.1395808011693333E+01, 0.6992314020959263E+00, 0.2121884039551361E+00, 0.7139837844669097E+00, 0.6295047433559955E+00, 0.4148193287752837E+00, 0.5351535485381410E+00, 0.4268738185358478E+00, 0.3698014604305115E+00, 0.7891833197548568E+00, 0.5281978587564573E+00, 0.1157716892137957E+00, 0.1308838344228090E+01, 0.1687185709139079E+01, 0.1034799882693896E+00, 0.1498504938454686E+00, 0.9010425466701916E+00, 0.9038246924092180E+00, 0.3421413441684364E-01, 0.1006978425303630E+00, 0.8008017657953598E+00, 0.3061474807444209E+00, 0.6338813300623194E+00, 0.5288684194677825E+00, 0.8682873190108105E+00, 0.9598101715535300E+00, 0.6229686202966810E+00, 0.5423584775195998E+00, 0.8415597376799326E+00, 0.9973399062905237E+00, 0.1033340463692495E+00, 0.4671884516860899E+00, 0.7629036530181579E+00, 0.1861385328384410E+00, 0.1124645093942705E+01, 0.6800991665489665E+00, 0.6978261813392677E+00, 0.1261574624288360E+01, 0.3053203341720497E+00, 0.5608966509936130E+00, 0.4929941693545132E+00, 0.3798570066394223E+00, 0.5509778292160957E+00, 0.4184574968871406E+00, 0.2087258457383731E+00, 0.6491193472879784E+00, 0.4915348757406203E-01, 0.1105843276664904E+00, 0.4574524632962537E-01, 0.9277628648996712E-01, 0.1253505697055357E-02, 0.2122447413720272E-02, 0.2576338363396270E-01, 0.2701688933101806E-01, 0.8149780515932184E-03, 0.1620493249248586E-02}, + i0: 1, + n0: 20, + pp: 0, + tau: 2.0080554394878082E-002, + sigma: 2.1175425068616867E-005, + i0Out: 1, + n0Out: 20, + ppOut: 0, + tauOut: 2.0080554394878082E-002, + sigmaOut: 2.1175425068616867E-005, + dminOut: -2.1187919252575148E-003, + dmin1Out: -2.1187919252575148E-003, + dmin2Out: 3.1777270007152948E-002, + dnOut: 4.3005217031728403E-002, + dnm1Out: -2.1187919252575148E-003, + dnm2Out: 3.1777270007152948E-002, + }, + { + z: []float64{0.2471569222413904E+01, 0.2456385050537078E+01, 0.4896382518051712E-02, 0.2364842030515144E-02, 0.1186378431264915E+01, 0.1164748012891115E+01, 0.8149780515932184E-03, 0.3663750368606913E-03, 0.5236148327211592E+00, 0.5059345305621403E+00, 0.2766627272719901E-02, 0.5208666879309463E-02, 0.9525115502267366E+00, 0.1019555750555114E+01, 0.9233342160256496E-01, 0.1271177219084926E+00, 0.1403647802928048E+01, 0.1295158592310706E+01, 0.3870906568602875E-01, 0.2575581550365553E-01, 0.8617584837127339E+00, 0.8333292886837029E+00, 0.1740717486950262E-01, 0.2915663048658400E-01, 0.1395808011693333E+01, 0.1558759230767007E+01, 0.2121884039551361E+00, 0.8569226352498945E-01, 0.6295047433559955E+00, 0.1058885473974269E+01, 0.5351535485381410E+00, 0.1868951540728986E+00, 0.3698014604305115E+00, 0.6910236107191923E+00, 0.5281978587564573E+00, 0.1000437033056103E+01, 0.1308838344228090E+01, 0.3918007450464985E+00, 0.1034799882693896E+00, 0.2379777816619179E+00, 0.9010425466701916E+00, 0.6771983450302391E+00, 0.3421413441684364E-01, 0.4045895778871807E-01, 0.8008017657953598E+00, 0.1374143583674083E+01, 0.6338813300623194E+00, 0.4005339232303680E+00, 0.8682873190108105E+00, 0.1070641461682245E+01, 0.6229686202966810E+00, 0.4896740201485869E+00, 0.8415597376799326E+00, 0.4351392095057171E+00, 0.1033340463692495E+00, 0.1811694274708021E+00, 0.7629036530181579E+00, 0.1686298765095183E+01, 0.1124645093942705E+01, 0.4654019842229331E+00, 0.6978261813392677E+00, 0.5176639768935063E+00, 0.3053203341720497E+00, 0.2907699806261721E+00, 0.4929941693545132E+00, 0.7331214635495586E+00, 0.5509778292160957E+00, 0.1568680213363420E+00, 0.2087258457383731E+00, 0.8093075758121498E-01, 0.4915348757406203E-01, 0.2778348386000479E-01, 0.4574524632962537E-01, -0.8652862282021575E-03, 0.1253505697055357E-02, -0.3732238779264379E-01, 0.2576338363396270E-01, 0.4300521703172840E-01, 0.8149780515932184E-03, 0.3663750368606913E-03}, + i0: 1, + n0: 20, + pp: 0, + tau: 5.0201385987195205E-003, + sigma: 2.1175425068616867E-005, + i0Out: 1, + n0Out: 20, + ppOut: 0, + tauOut: 5.0201385987195205E-003, + sigmaOut: 2.1175425068616867E-005, + dminOut: 1.8576185384092288E-002, + dmin1Out: 1.8576185384092288E-002, + dmin2Out: 5.2365600435162571E-002, + dnOut: 1.9114649409197451E-002, + dnm1Out: 1.8576185384092288E-002, + dnm2Out: 5.2365600435162571E-002, + }, + { + z: []float64{0.2471569222413904E+01, 0.2471445466333236E+01, 0.4896382518051712E-02, 0.2350431231346416E-02, 0.1186378431264915E+01, 0.1179822839486443E+01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.5236148327211592E+00, 0.5209996276036221E+00, 0.2766627272719901E-02, 0.5058054349403302E-02, 0.9525115502267366E+00, 0.1034766778881179E+01, 0.9233342160256496E-01, 0.1252490967185870E+00, 0.1403647802928048E+01, 0.1312087633296770E+01, 0.3870906568602875E-01, 0.2542350442532051E-01, 0.8617584837127339E+00, 0.8487220155581966E+00, 0.1740717486950262E-01, 0.2862783537884150E-01, 0.1395808011693333E+01, 0.1574348441670908E+01, 0.2121884039551361E+00, 0.8484373804386666E-01, 0.6295047433559955E+00, 0.1074794415251550E+01, 0.5351535485381410E+00, 0.1841287608083240E+00, 0.3698014604305115E+00, 0.7088504197799252E+00, 0.5281978587564573E+00, 0.9752771411128711E+00, 0.1308838344228090E+01, 0.4320210527858890E+00, 0.1034799882693896E+00, 0.2158225196628609E+00, 0.9010425466701916E+00, 0.7144140228254550E+00, 0.3421413441684364E-01, 0.3835134583138245E-01, 0.8008017657953598E+00, 0.1391311611427577E+01, 0.6338813300623194E+00, 0.3955915526975877E+00, 0.8682873190108105E+00, 0.1090644248011184E+01, 0.6229686202966810E+00, 0.4806932321292802E+00, 0.8415597376799326E+00, 0.4591804133211825E+00, 0.1033340463692495E+00, 0.1716839812178710E+00, 0.7629036530181579E+00, 0.1710844627144272E+01, 0.1124645093942705E+01, 0.4587247601659613E+00, 0.6978261813392677E+00, 0.5394016167466366E+00, 0.3053203341720497E+00, 0.2790520826393697E+00, 0.4929941693545132E+00, 0.7598997773325197E+00, 0.5509778292160957E+00, 0.1513401067044909E+00, 0.2087258457383731E+00, 0.1015190880092246E+00, 0.4915348757406203E-01, 0.2214892234681356E-01, 0.4574524632962537E-01, 0.1982969108114764E-01, 0.1253505697055357E-02, 0.1628595626045726E-02, 0.2576338363396270E-01, 0.1911464940919745E-01, 0.8149780515932184E-03, 0.3616937915375072E-03, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + tau: 5.4769133315280185E-003, + sigma: 5.0413140237881371E-003, + i0Out: 1, + n0Out: 20, + ppOut: 1, + tauOut: 5.4769133315280185E-003, + sigmaOut: 5.0413140237881371E-003, + dminOut: 9.5622848228283271E-003, + dmin1Out: 9.5622848228283271E-003, + dmin2Out: 6.9533978479808370E-002, + dnOut: 1.0856003705186750E-002, + dnm1Out: 9.5622848228283271E-003, + dnm2Out: 6.9533978479808370E-002, + }, + { + z: []float64{0.2468318984233055E+01, 0.2471445466333236E+01, 0.1123474100024551E-02, 0.2350431231346416E-02, 0.1173584145846428E+01, 0.1179822839486443E+01, 0.1605699355811189E-03, 0.3616937915375072E-03, 0.5204201986859162E+00, 0.5209996276036221E+00, 0.1005707814522541E-01, 0.5058054349403302E-02, 0.1144481884123012E+01, 0.1034766778881179E+01, 0.1435914304680996E+00, 0.1252490967185870E+00, 0.1188442793922463E+01, 0.1312087633296770E+01, 0.1815610143690141E-01, 0.2542350442532051E-01, 0.8537168361686087E+00, 0.8487220155581966E+00, 0.5279290053521807E-01, 0.2862783537884150E-01, 0.1600922365848029E+01, 0.1574348441670908E+01, 0.5696064828871891E-01, 0.8484373804386666E-01, 0.1196485614439627E+01, 0.1074794415251550E+01, 0.1090859328498209E+00, 0.1841287608083240E+00, 0.1569564714711448E+01, 0.7088504197799252E+00, 0.2684440171930437E+00, 0.9752771411128711E+00, 0.3739226419241781E+00, 0.4320210527858890E+00, 0.4123490187575627E+00, 0.2158225196628609E+00, 0.3349394365677468E+00, 0.7144140228254550E+00, 0.1593084209965356E+00, 0.3835134583138245E-01, 0.1622117829797102E+01, 0.1391311611427577E+01, 0.2659792301064862E+00, 0.3955915526975877E+00, 0.1299881336702450E+01, 0.1090644248011184E+01, 0.1698038973078534E+00, 0.4806932321292802E+00, 0.4555835838996722E+00, 0.4591804133211825E+00, 0.6447216871142054E+00, 0.1716839812178710E+00, 0.1519370786864500E+01, 0.1710844627144272E+01, 0.1628548339973444E+00, 0.4587247601659613E+00, 0.6501219520571339E+00, 0.5394016167466366E+00, 0.3261720586281595E+00, 0.2790520826393697E+00, 0.5795909120773233E+00, 0.7598997773325197E+00, 0.2650819619788820E-01, 0.1513401067044909E+00, 0.9168290082662192E-01, 0.1015190880092246E+00, 0.4790492926791300E-02, 0.2214892234681356E-01, 0.1119088044887405E-01, 0.1982969108114764E-01, 0.2781732372482683E-02, 0.1628595626045726E-02, 0.1085600370518675E-01, 0.1911464940919745E-01, 0.1605699355811189E-03, 0.3616937915375072E-03}, + i0: 1, + n0: 20, + pp: 0, + tau: 5.1216063611655054E-003, + sigma: 1.0518227355316156E-002, + i0Out: 1, + n0Out: 20, + ppOut: 0, + tauOut: 5.1216063611655054E-003, + sigmaOut: 1.0518227355316156E-002, + dminOut: 2.0601312480394186E-003, + dmin1Out: 5.4371870398960158E-003, + dmin2Out: 8.0023511442426670E-002, + dnOut: 2.0601312480394186E-003, + dnm1Out: 5.4371870398960158E-003, + dnm2Out: 8.0023511442426670E-002, + }, + { + z: []float64{0.2468318984233055E+01, 0.2464320851971913E+01, 0.1123474100024551E-02, 0.5350323562789559E-03, 0.1173584145846428E+01, 0.1168088077064565E+01, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.5204201986859162E+00, 0.5252841314829605E+00, 0.1005707814522541E-01, 0.2191222436498315E-01, 0.1144481884123012E+01, 0.1261039483864963E+01, 0.1435914304680996E+00, 0.1353250258951489E+00, 0.1188442793922463E+01, 0.1066152263103050E+01, 0.1815610143690141E-01, 0.1453842008528346E-01, 0.8537168361686087E+00, 0.8868497102573779E+00, 0.5279290053521807E-01, 0.9530062900995111E-01, 0.1600922365848029E+01, 0.1557460778765631E+01, 0.5696064828871891E-01, 0.4375878814786067E-01, 0.1196485614439627E+01, 0.1256691152780422E+01, 0.1090859328498209E+00, 0.1362446379077657E+00, 0.1569564714711448E+01, 0.1696642487635560E+01, 0.2684440171930437E+00, 0.5916231430550117E-01, 0.3739226419241781E+00, 0.7219877400150740E+00, 0.4123490187575627E+00, 0.1912940350054112E+00, 0.3349394365677468E+00, 0.2978322161977056E+00, 0.1593084209965356E+00, 0.8676597630518320E+00, 0.1622117829797102E+01, 0.1015315690490590E+01, 0.2659792301064862E+00, 0.3405260456467969E+00, 0.1299881336702450E+01, 0.1124037582002341E+01, 0.1698038973078534E+00, 0.6882320425428856E-01, 0.4555835838996722E+00, 0.1026360460398424E+01, 0.6447216871142054E+00, 0.9544125430154021E+00, 0.1519370786864500E+01, 0.7226914714852769E+00, 0.1628548339973444E+00, 0.1465016632377001E+00, 0.6501219520571339E+00, 0.8246707410864278E+00, 0.3261720586281595E+00, 0.2292385937027206E+00, 0.5795909120773233E+00, 0.3717389082113253E+00, 0.2650819619788820E-01, 0.6537783023029759E-02, 0.9168290082662192E-01, 0.8481400436921797E-01, 0.4790492926791300E-02, 0.6320870478125323E-03, 0.1119088044887405E-01, 0.8218919412378699E-02, 0.2781732372482683E-02, 0.3674266095981827E-02, 0.1085600370518675E-01, 0.2060131248039419E-02, 0.1605699355811189E-03, 0.7153898701552432E-04, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + tau: 1.2817878169164906E-003, + sigma: 1.5639833716481661E-002, + i0Out: 1, + n0Out: 20, + ppOut: 1, + tauOut: 1.2817878169164906E-003, + sigmaOut: 1.5639833716481661E-002, + dminOut: 6.0731361153288982E-005, + dmin1Out: 6.8738708636769136E-003, + dmin2Out: 8.1489512892123819E-002, + dnOut: 6.0731361153288982E-005, + dnm1Out: 6.8738708636769136E-003, + dnm2Out: 8.1489512892123819E-002, + }, + { + z: []float64{0.2463574096511276E+01, 0.2464320851971913E+01, 0.2536822079344948E-03, 0.5350323562789559E-03, 0.1166624146026729E+01, 0.1168088077064565E+01, 0.3221114082852138E-04, 0.7153898701552432E-04, 0.5458823568901986E+00, 0.5252841314829605E+00, 0.5061929508212644E-01, 0.2191222436498315E-01, 0.1344463426861069E+01, 0.1261039483864963E+01, 0.1073120173669855E+00, 0.1353250258951489E+00, 0.9720968780044319E+00, 0.1066152263103050E+01, 0.1326348631702415E-01, 0.1453842008528346E-01, 0.9676050651333883E+00, 0.8868497102573779E+00, 0.1533962535161303E+00, 0.9530062900995111E-01, 0.1446541525580445E+01, 0.1557460778765631E+01, 0.3801569533217738E-01, 0.4375878814786067E-01, 0.1353638307539094E+01, 0.1256691152780422E+01, 0.1707682473962209E+00, 0.1362446379077657E+00, 0.1583754766727924E+01, 0.1696642487635560E+01, 0.2697037855661164E-01, 0.5916231430550117E-01, 0.8850296086469572E+00, 0.7219877400150740E+00, 0.6437471225190403E-01, 0.1912940350054112E+00, 0.1099835479180717E+01, 0.2978322161977056E+00, 0.8009821360646626E+00, 0.8676597630518320E+00, 0.5535778122558079E+00, 0.1015315690490590E+01, 0.6914368034330997E+00, 0.3405260456467969E+00, 0.5001421950066134E+00, 0.1124037582002341E+01, 0.1412346654806686E+00, 0.6882320425428856E-01, 0.1838256550116241E+01, 0.1026360460398424E+01, 0.3752173792456719E+00, 0.9544125430154021E+00, 0.4926939676603885E+00, 0.7226914714852769E+00, 0.2452143584512202E+00, 0.1465016632377001E+00, 0.8074131885210117E+00, 0.8246707410864278E+00, 0.1055431169003394E+00, 0.2292385937027206E+00, 0.2714517865170992E+00, 0.3717389082113253E+00, 0.2042703660177667E-02, 0.6537783023029759E-02, 0.8212159993993635E-01, 0.8481400436921797E-01, 0.6326073178529442E-04, 0.6320870478125323E-03, 0.1054813695965874E-01, 0.8218919412378699E-02, 0.7176120699696391E-03, 0.3674266095981827E-02, 0.6073136115328898E-04, 0.2060131248039419E-02, 0.3221114082852138E-04, 0.7153898701552432E-04}, + i0: 1, + n0: 20, + pp: 0, + tau: 5.6837241251038845E-005, + sigma: 1.6921621533398150E-002, + i0Out: 1, + n0Out: 20, + ppOut: 0, + tauOut: 5.6837241251038845E-005, + sigmaOut: 1.6921621533398150E-002, + dminOut: 3.1568086081919418E-009, + dmin1Out: 1.0483100129151506E-002, + dmin2Out: 8.1316774559040517E-002, + dnOut: 3.1568086081919418E-009, + dnm1Out: 1.0483100129151506E-002, + dnm2Out: 8.1316774559040517E-002, + }, + { + z: []float64{0.2463574096511276E+01, 0.2463770941477959E+01, 0.2536822079344948E-03, 0.1201214707955848E-03, 0.1166624146026729E+01, 0.1166479398455512E+01, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.5458823568901986E+00, 0.5964297407456295E+00, 0.5061929508212644E-01, 0.1141052940222717E+00, 0.1344463426861069E+01, 0.1337613312964532E+01, 0.1073120173669855E+00, 0.7798791776646297E-01, 0.9720968780044319E+00, 0.9073156093137420E+00, 0.1326348631702415E-01, 0.1414482062243694E-01, 0.9676050651333883E+00, 0.1106799660785830E+01, 0.1533962535161303E+00, 0.2004825791345134E+00, 0.1446541525580445E+01, 0.1284017804536858E+01, 0.3801569533217738E-01, 0.4007693764646178E-01, 0.1353638307539094E+01, 0.1484272780047602E+01, 0.1707682473962209E+00, 0.1822138285193538E+00, 0.1583754766727924E+01, 0.1428454479523931E+01, 0.2697037855661164E-01, 0.1671007646458111E-01, 0.8850296086469572E+00, 0.9326374071930291E+00, 0.6437471225190403E-01, 0.7591545433480534E-01, 0.1099835479180717E+01, 0.1824845323669324E+01, 0.8009821360646626E+00, 0.2429827519008994E+00, 0.5535778122558079E+00, 0.1001975026546757E+01, 0.6914368034330997E+00, 0.3451350696526060E+00, 0.5001421950066134E+00, 0.2961849535934249E+00, 0.1412346654806686E+00, 0.8765656248686587E+00, 0.1838256550116241E+01, 0.1336851467252003E+01, 0.3752173792456719E+00, 0.1382856239786244E+00, 0.4926939676603885E+00, 0.5995658648917332E+00, 0.2452143584512202E+00, 0.3302211126778973E+00, 0.8074131885210117E+00, 0.5826783555022028E+00, 0.1055431169003394E+00, 0.4916926700063749E-01, 0.2714517865170992E+00, 0.2242683859353883E+00, 0.2042703660177667E-02, 0.7479881396448043E-03, 0.8212159993993635E-01, 0.8138003529082581E-01, 0.6326073178529442E-04, 0.8199589256196194E-05, 0.1054813695965874E-01, 0.1120071219912114E-01, 0.7176120699696391E-03, 0.3890963093641941E-05, 0.6073136115328898E-04, 0.3156808608191942E-08, 0.3221114082852138E-04, 0.1507398544447245E-04, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + tau: 3.1557121791797713E-009, + sigma: 1.6978458774649190E-002, + i0Out: 1, + n0Out: 20, + ppOut: 1, + tauOut: 3.1557121791797713E-009, + sigmaOut: 1.6978458774649190E-002, + dminOut: 6.9684975813366743E-017, + dmin1Out: 1.1199576261102989E-002, + dmin2Out: 8.1067607231828140E-002, + dnOut: 6.9684975813366743E-017, + dnm1Out: 1.1199576261102989E-002, + dnm2Out: 8.1067607231828140E-002, + }, + { + z: []float64{0.2463891059793043E+01, 0.2463770941477959E+01, 0.5686908130061341E-04, 0.1201214707955848E-03, 0.1166437600203943E+01, 0.1166479398455512E+01, 0.7707718980490818E-05, 0.1507398544447245E-04, 0.7105273238932086E+00, 0.5964297407456295E+00, 0.2148105431436762E+00, 0.1141052940222717E+00, 0.1200790684431606E+01, 0.1337613312964532E+01, 0.5892755169139442E-01, 0.7798791776646297E-01, 0.8625328750890724E+00, 0.9073156093137420E+00, 0.1815059242254727E-01, 0.1414482062243694E-01, 0.1289131644342084E+01, 0.1106799660785830E+01, 0.1996872873596725E+00, 0.2004825791345134E+00, 0.1124407451667935E+01, 0.1284017804536858E+01, 0.5290351604133232E-01, 0.4007693764646178E-01, 0.1613583089369911E+01, 0.1484272780047602E+01, 0.1613081850537457E+00, 0.1822138285193538E+00, 0.1283856367779054E+01, 0.1428454479523931E+01, 0.1213877407087503E-01, 0.1671007646458111E-01, 0.9964140843012472E+00, 0.9326374071930291E+00, 0.1390325207358455E+00, 0.7591545433480534E-01, 0.1928795551678665E+01, 0.1824845323669324E+01, 0.1262252233392066E+00, 0.2429827519008994E+00, 0.1220884869704444E+01, 0.1001975026546757E+01, 0.8372928285471114E-01, 0.3451350696526060E+00, 0.1089021292451660E+01, 0.2961849535934249E+00, 0.1076046951396362E+01, 0.8765656248686587E+00, 0.3990901366785531E+00, 0.1336851467252003E+01, 0.2077509116934600E+00, 0.1382856239786244E+00, 0.7220360627204584E+00, 0.5995658648917332E+00, 0.2664862668525171E+00, 0.3302211126778973E+00, 0.3653613524946110E+00, 0.5826783555022028E+00, 0.3018138637972599E-01, 0.4916926700063749E-01, 0.1948349845395949E+00, 0.2242683859353883E+00, 0.3124249032854923E-03, 0.7479881396448043E-03, 0.8107580682108434E-01, 0.8138003529082581E-01, 0.1132782305976083E-05, 0.8199589256196194E-05, 0.1120346722419663E-01, 0.1120071219912114E-01, 0.1096359327194516E-11, 0.3890963093641941E-05, 0.6968497581336674E-16, 0.3156808608191942E-08, 0.7707718980490818E-05, 0.1507398544447245E-04}, + i0: 1, + n0: 20, + pp: 0, + tau: 6.9684975806547287E-017, + sigma: 1.6978461930361368E-002, + i0Out: 1, + n0Out: 20, + ppOut: 0, + tauOut: 6.9684975806547287E-017, + sigmaOut: 1.6978461930361368E-002, + dminOut: 6.1629758220391547E-032, + dmin1Out: 1.1203310405167735E-002, + dmin2Out: 8.0927116373146771E-002, + dnOut: 6.1629758220391547E-032, + dnm1Out: 1.1203310405167735E-002, + dnm2Out: 8.0927116373146771E-002, + }, + { + z: []float64{0.2463891059793043E+01, 0.2463947928874343E+01, 0.5686908130061341E-04, 0.2692193042748079E-04, 0.1166437600203943E+01, 0.1166418385992496E+01, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.7105273238932086E+00, 0.9253331718563164E+00, 0.2148105431436762E+00, 0.2787563517334627E+00, 0.1200790684431606E+01, 0.9809618843895378E+00, 0.5892755169139442E-01, 0.5181337969514327E-01, 0.8625328750890724E+00, 0.8288700878164763E+00, 0.1815059242254727E-01, 0.2822939734392020E-01, 0.1289131644342084E+01, 0.1460589534357837E+01, 0.1996872873596725E+00, 0.1537255119449346E+00, 0.1124407451667935E+01, 0.1023585455764333E+01, 0.5290351604133232E-01, 0.8339725654733963E-01, 0.1613583089369911E+01, 0.1691494017876317E+01, 0.1613081850537457E+00, 0.1224340957564512E+00, 0.1283856367779054E+01, 0.1173561046093478E+01, 0.1213877407087503E-01, 0.1030644761994533E-01, 0.9964140843012472E+00, 0.1125140157417147E+01, 0.1390325207358455E+00, 0.2383394688796517E+00, 0.1928795551678665E+01, 0.1816681306138221E+01, 0.1262252233392066E+00, 0.8482856339700598E-01, 0.1220884869704444E+01, 0.1219785589162149E+01, 0.8372928285471114E-01, 0.7475327847832687E-01, 0.1089021292451660E+01, 0.2090314965369696E+01, 0.1076046951396362E+01, 0.2054425921547012E+00, 0.3990901366785531E+00, 0.4013984562173118E+00, 0.2077509116934600E+00, 0.3737026089221466E+00, 0.7220360627204584E+00, 0.6148197206508288E+00, 0.2664862668525171E+00, 0.1583615157552351E+00, 0.3653613524946110E+00, 0.2371812231191019E+00, 0.3018138637972599E-01, 0.2479281399828426E-01, 0.1948349845395949E+00, 0.1703545954445960E+00, 0.3124249032854923E-03, 0.1486904479375115E-03, 0.8107580682108434E-01, 0.8092824915545274E-01, 0.1132782305976083E-05, 0.1568190288260776E-06, 0.1120346722419663E-01, 0.1120331040626409E-01, 0.1096359327194516E-11, 0.6819392699821255E-26, 0.6968497581336674E-16, 0.6162975822039155E-31, 0.7707718980490818E-05, 0.4695180568393632E-05, 0.2117542506861687E-04}, + i0: 1, + n0: 20, + pp: 1, + tau: 6.1629758220391547E-032, + sigma: 1.6978461930361441E-002, + i0Out: 1, + n0Out: 20, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 1.6978461930361441E-002, + dminOut: 6.1629758220391547E-032, + dmin1Out: 1.1203288675083998E-002, + dmin2Out: 8.0846453894262649E-002, + dnOut: 6.1629758220391547E-032, + dnm1Out: 1.1203288675083998E-002, + dnm2Out: 8.0846453894262649E-002, + }, + { + z: []float64{0.2463974850804771E+01, 0.2463947928874343E+01, 0.1274454348702788E-04, 0.2692193042748079E-04, 0.1166410336629578E+01, 0.1166418385992496E+01, 0.3724766654883956E-05, 0.4695180568393632E-05, 0.1204085798823124E+01, 0.9253331718563164E+00, 0.2271012218143261E+00, 0.2787563517334627E+00, 0.8056740422703550E+00, 0.9809618843895378E+00, 0.5330513126246473E-01, 0.5181337969514327E-01, 0.8037943538979316E+00, 0.8288700878164763E+00, 0.5129615818002433E-01, 0.2822939734392020E-01, 0.1563018888122747E+01, 0.1460589534357837E+01, 0.1006713350698832E+00, 0.1537255119449346E+00, 0.1006311377241790E+01, 0.1023585455764333E+01, 0.1401812239704283E+00, 0.8339725654733963E-01, 0.1673746889662340E+01, 0.1691494017876317E+01, 0.8584564749956700E-01, 0.1224340957564512E+00, 0.1098021846213856E+01, 0.1173561046093478E+01, 0.1056099032774466E-01, 0.1030644761994533E-01, 0.1352918635969054E+01, 0.1125140157417147E+01, 0.3200390963041470E+00, 0.2383394688796517E+00, 0.1581470773231080E+01, 0.1816681306138221E+01, 0.6542811978092533E-01, 0.8482856339700598E-01, 0.1229110747859551E+01, 0.1219785589162149E+01, 0.1271308521106110E+00, 0.7475327847832687E-01, 0.2168626705413786E+01, 0.2090314965369696E+01, 0.3802606466401751E-01, 0.2054425921547012E+00, 0.7370750004754409E+00, 0.4013984562173118E+00, 0.3117182559112661E+00, 0.3737026089221466E+00, 0.4614629804947978E+00, 0.6148197206508288E+00, 0.8139413038408401E-01, 0.1583615157552351E+00, 0.1805799067333021E+00, 0.2371812231191019E+00, 0.2338892446571373E-01, 0.2479281399828426E-01, 0.1471143614268198E+00, 0.1703545954445960E+00, 0.8179526119010886E-04, 0.1486904479375115E-03, 0.8084661071329148E-01, 0.8092824915545274E-01, 0.2173118009582292E-07, 0.1568190288260776E-06, 0.1120328867508400E-01, 0.1120331040626409E-01, 0.3751376363572422E-55, 0.6819392699821255E-26}, + i0: 1, + n0: 19, + pp: 0, + tau: 1.1203284285913290E-002, + sigma: 1.6978461930361441E-002, + i0Out: 1, + n0Out: 19, + ppOut: 0, + tauOut: 1.1203284285913290E-002, + sigmaOut: 1.6978461930361441E-002, + dminOut: 8.9043085058082561E-010, + dmin1Out: 6.9585227169791292E-002, + dmin2Out: 0.11373841371027797, + dnOut: 8.9043085058082561E-010, + dnm1Out: 6.9585227169791292E-002, + dnm2Out: 0.11373841371027797, + }, + { + z: []float64{0.2463974850804771E+01, 0.2452784311062345E+01, 0.1274454348702788E-04, 0.6060609239813679E-05, 0.1166410336629578E+01, 0.1155204716501079E+01, 0.3724766654883956E-05, 0.3882375624867434E-05, 0.1204085798823124E+01, 0.1419979853975912E+01, 0.2271012218143261E+00, 0.1288536304732592E+00, 0.8056740422703550E+00, 0.7189222587736472E+00, 0.5330513126246473E-01, 0.5959804835594534E-01, 0.8037943538979316E+00, 0.7842891794360973E+00, 0.5129615818002433E-01, 0.1022287011292917E+00, 0.1563018888122747E+01, 0.1550258237777425E+01, 0.1006713350698832E+00, 0.6534828028921505E-01, 0.1006311377241790E+01, 0.1069941036637090E+01, 0.1401812239704283E+00, 0.2192904838448094E+00, 0.1673746889662340E+01, 0.1529098769031184E+01, 0.8584564749956700E-01, 0.6164441320989392E-01, 0.1098021846213856E+01, 0.1035735139045794E+01, 0.1056099032774466E-01, 0.1379518767882891E-01, 0.1352918635969054E+01, 0.1647959260308459E+01, 0.3200390963041470E+00, 0.3071268139247320E+00, 0.1581470773231080E+01, 0.1328568794801360E+01, 0.6542811978092533E-01, 0.6053010243026304E-01, 0.1229110747859551E+01, 0.1284508213253985E+01, 0.1271308521106110E+00, 0.2146341752620367E+00, 0.2168626705413786E+01, 0.1980815310529854E+01, 0.3802606466401751E-01, 0.1414976019284330E-01, 0.7370750004754409E+00, 0.1023440211907950E+01, 0.3117182559112661E+00, 0.1405518698344743E+00, 0.4614629804947978E+00, 0.3911019567584944E+00, 0.8139413038408401E-01, 0.3758136265851575E-01, 0.1805799067333021E+00, 0.1551841842545868E+00, 0.2338892446571373E-01, 0.2217266343062855E-01, 0.1471143614268198E+00, 0.1138202089714681E+00, 0.8179526119010886E-04, 0.5809925758690545E-04, 0.8084661071329148E-01, 0.6958524890097138E-01, 0.2173118009582292E-07, 0.3498739858072780E-08, 0.1120328867508400E-01, 0.8904308505808256E-09, 0.3751376363572422E-55, 0.3882375624867434E-05, 0.1697846193036144E-01}, + i0: 1, + n0: 19, + pp: 1, + tau: 8.9043080564395014E-010, + sigma: 2.8181746216274728E-002, + i0Out: 1, + n0Out: 19, + ppOut: 1, + tauOut: 8.9043080564395014E-010, + sigmaOut: 2.8181746216274728E-002, + dminOut: 1.3962105636374437E-019, + dmin1Out: 6.9544122471813200E-002, + dmin2Out: 9.8247027562672340E-002, + dnOut: 1.3962105636374437E-019, + dnm1Out: 6.9544122471813200E-002, + dnm2Out: 9.8247027562672340E-002, + }, + { + z: []float64{0.2452790370781154E+01, 0.2452784311062345E+01, 0.2854399814229969E-05, 0.6060609239813679E-05, 0.1155205743586459E+01, 0.1155204716501079E+01, 0.4772219324121025E-05, 0.3882375624867434E-05, 0.1548828711339416E+01, 0.1419979853975912E+01, 0.5981019230390531E-01, 0.1288536304732592E+00, 0.7187101139352565E+00, 0.7189222587736472E+00, 0.6503610222645050E-01, 0.5959804835594534E-01, 0.8214817774485077E+00, 0.7842891794360973E+00, 0.1929207566298143E+00, 0.1022287011292917E+00, 0.1422685760546395E+01, 0.1550258237777425E+01, 0.4914564318703864E-01, 0.6534828028921505E-01, 0.1240085876404429E+01, 0.1069941036637090E+01, 0.2703980549150243E+00, 0.2192904838448094E+00, 0.1320345126435623E+01, 0.1529098769031184E+01, 0.4835651195207321E-01, 0.6164441320989392E-01, 0.1001173813882118E+01, 0.1035735139045794E+01, 0.2270725319399537E-01, 0.1379518767882891E-01, 0.1932378820148765E+01, 0.1647959260308459E+01, 0.2111589595024383E+00, 0.3071268139247320E+00, 0.1177939936838754E+01, 0.1328568794801360E+01, 0.6600626338337756E-01, 0.6053010243026304E-01, 0.1433136124242214E+01, 0.1284508213253985E+01, 0.2966575563411978E+00, 0.2146341752620367E+00, 0.1698307513491068E+01, 0.1980815310529854E+01, 0.8526979628348903E-02, 0.1414976019284330E-01, 0.1155465101223645E+01, 0.1023440211907950E+01, 0.4757401262929915E-01, 0.1405518698344743E+00, 0.3811093058972801E+00, 0.3911019567584944E+00, 0.1530278326215801E-01, 0.3758136265851575E-01, 0.1620540635326265E+00, 0.1551841842545868E+00, 0.1557318051836492E-01, 0.2217266343062855E-01, 0.9830512682025924E-01, 0.1138202089714681E+00, 0.4112553872737890E-04, 0.5809925758690545E-04, 0.6954412597055305E-01, 0.6958524890097138E-01, 0.4479725446695418E-16, 0.3498739858072780E-08, 0.1396210563637444E-18, 0.8904308505808256E-09, 0.2854399814229969E-05, 0.3882375624867434E-05}, + i0: 1, + n0: 19, + pp: 0, + tau: 1.3962105636374427E-019, + sigma: 2.8181747106705537E-002, + i0Out: 1, + n0Out: 19, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 2.8181747106705537E-002, + dminOut: 1.3962105636374430E-019, + dmin1Out: 6.9512134440652351E-002, + dmin2Out: 8.9358776708560295E-002, + dnOut: 1.3962105636374430E-019, + dnm1Out: 6.9512134440652351E-002, + dnm2Out: 8.9358776708560295E-002, + }, + { + z: []float64{0.2452790370781154E+01, 0.2452793225180968E+01, 0.2854399814229969E-05, 0.1344352644992036E-05, 0.1155205743586459E+01, 0.1155209171453138E+01, 0.4772219324121025E-05, 0.6398278760815103E-05, 0.1548828711339416E+01, 0.1608632505364561E+01, 0.5981019230390531E-01, 0.2672219415054498E-01, 0.7187101139352565E+00, 0.7570240220111620E+00, 0.6503610222645050E-01, 0.7057368234283014E-01, 0.8214817774485077E+00, 0.9438288517354918E+00, 0.1929207566298143E+00, 0.2908001941945216E+00, 0.1422685760546395E+01, 0.1181031209538913E+01, 0.4914564318703864E-01, 0.5160305461093759E-01, 0.1240085876404429E+01, 0.1458880876708516E+01, 0.2703980549150243E+00, 0.2447209773632920E+00, 0.1320345126435623E+01, 0.1123980661024405E+01, 0.4835651195207321E-01, 0.4307304847484577E-01, 0.1001173813882118E+01, 0.9808080186012680E+00, 0.2270725319399537E-01, 0.4473761868138884E-01, 0.1932378820148765E+01, 0.2098800160969815E+01, 0.2111589595024383E+00, 0.1185117935689049E+00, 0.1177939936838754E+01, 0.1125434406653226E+01, 0.6600626338337756E-01, 0.8405284210411720E-01, 0.1433136124242214E+01, 0.1645740838479294E+01, 0.2966575563411978E+00, 0.3061331074057168E+00, 0.1698307513491068E+01, 0.1400701385713701E+01, 0.8526979628348903E-02, 0.7034066989504621E-02, 0.1155465101223645E+01, 0.1196005046863439E+01, 0.4757401262929915E-01, 0.1515955052150448E-01, 0.3811093058972801E+00, 0.3812525386379337E+00, 0.1530278326215801E-01, 0.6504555274179689E-02, 0.1620540635326265E+00, 0.1711226887768117E+00, 0.1557318051836492E-01, 0.8946350111698947E-02, 0.9830512682025924E-01, 0.8939990224728768E-01, 0.4112553872737890E-04, 0.3199152990069927E-04, 0.6954412597055305E-01, 0.6951213444065239E-01, 0.4479725446695418E-16, 0.8997910999570377E-34, 0.2818174710670554E-01}, + i0: 1, + n0: 18, + pp: 1, + tau: 6.8088572105595116E-002, + sigma: 2.8181747106705537E-002, + i0Out: 1, + n0Out: 18, + ppOut: 1, + tauOut: 6.8088572105595116E-002, + sigmaOut: 2.8181747106705537E-002, + dminOut: 1.2643548659038301E-003, + dmin1Out: 1.3935943135754067E-002, + dmin2Out: 9.9495800084882416E-002, + dnOut: 1.2643548659038301E-003, + dnm1Out: 1.3935943135754067E-002, + dnm2Out: 9.9495800084882416E-002, + }, + { + z: []float64{0.2384705997428018E+01, 0.2452793225180968E+01, 0.6512368848977837E-06, 0.1344352644992036E-05, 0.1087126346389419E+01, 0.1155209171453138E+01, 0.9467601652019932E-05, 0.6398278760815103E-05, 0.1567256659807859E+01, 0.1608632505364561E+01, 0.1290748567965171E-01, 0.2672219415054498E-01, 0.7466016465687454E+00, 0.7570240220111620E+00, 0.8921689079377818E-01, 0.7057368234283014E-01, 0.1077323583030640E+01, 0.9438288517354918E+00, 0.3187938243378626E+00, 0.2908001941945216E+00, 0.8457518677063927E+00, 0.1181031209538913E+01, 0.8901276181133644E-01, 0.5160305461093759E-01, 0.1546500520154876E+01, 0.1458880876708516E+01, 0.1778606876095877E+00, 0.2447209773632920E+00, 0.9211044497840675E+00, 0.1123980661024405E+01, 0.4586493023634136E-01, 0.4307304847484577E-01, 0.9115921349407204E+00, 0.9808080186012680E+00, 0.1030014605117353E+00, 0.4473761868138884E-01, 0.2046221921921390E+01, 0.2098800160969815E+01, 0.6518220171905387E-01, 0.1185117935689049E+00, 0.1076216474932694E+01, 0.1125434406653226E+01, 0.1285328723941422E+00, 0.8405284210411720E-01, 0.1755252501385274E+01, 0.1645740838479294E+01, 0.2442959445536252E+00, 0.3061331074057168E+00, 0.1095350936043985E+01, 0.1400701385713701E+01, 0.7680442260639305E-02, 0.7034066989504621E-02, 0.1135395583018709E+01, 0.1196005046863439E+01, 0.5090399511302622E-02, 0.1515955052150448E-01, 0.3145781222952156E+00, 0.3812525386379337E+00, 0.3538316586334169E-02, 0.6504555274179689E-02, 0.1084421501965814E+00, 0.1711226887768117E+00, 0.7375387005938499E-02, 0.8946350111698947E-02, 0.1396793466565477E-01, 0.8939990224728768E-01, 0.1592074691534444E-03, 0.3199152990069927E-04, 0.1264354865903830E-02, 0.6951213444065239E-01, 0.6512368848977837E-06, 0.1344352644992036E-05}, + i0: 1, + n0: 18, + pp: 0, + tau: 1.2463174543591322E-003, + sigma: 9.6270319212300656E-002, + i0Out: 1, + n0Out: 18, + ppOut: 0, + tauOut: 1.2463174543591322E-003, + sigmaOut: 9.6270319212300656E-002, + dminOut: 1.2236274461701734E-006, + dmin1Out: 1.1812799375517376E-002, + dmin2Out: 0.10597947881780349, + dnOut: 1.2236274461701734E-006, + dnm1Out: 1.1812799375517376E-002, + dnm2Out: 0.10597947881780349, + }, + { + z: []float64{0.2384705997428018E+01, 0.2383460331210544E+01, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.1087126346389419E+01, 0.1085889199499347E+01, 0.9467601652019932E-05, 0.1366452649899944E-04, 0.1567256659807859E+01, 0.1578904163506652E+01, 0.1290748567965171E-01, 0.6103442048115082E-02, 0.7466016465687454E+00, 0.8284687778600495E+00, 0.8921689079377818E-01, 0.1160157908485996E+00, 0.1077323583030640E+01, 0.1278855299065544E+01, 0.3187938243378626E+00, 0.2108295383723412E+00, 0.8457518677063927E+00, 0.7226887736910288E+00, 0.8901276181133644E-01, 0.1904807262171572E+00, 0.1546500520154876E+01, 0.1532634164092948E+01, 0.1778606876095877E+00, 0.1068932656188067E+00, 0.9211044497840675E+00, 0.8588297969472432E+00, 0.4586493023634136E-01, 0.4868264913684867E-01, 0.9115921349407204E+00, 0.9646646288612479E+00, 0.1030014605117353E+00, 0.2184840619043245E+00, 0.2046221921921390E+01, 0.1891673744281760E+01, 0.6518220171905387E-01, 0.3708364593761750E-01, 0.1076216474932694E+01, 0.1166419383934860E+01, 0.1285328723941422E+00, 0.1934189785315259E+00, 0.1755252501385274E+01, 0.1804883149953014E+01, 0.2442959445536252E+00, 0.1482587897978486E+00, 0.1095350936043985E+01, 0.9535262710524167E+00, 0.7680442260639305E-02, 0.9145359161143373E-02, 0.1135395583018709E+01, 0.1130094305914509E+01, 0.5090399511302622E-02, 0.1416986451145964E-02, 0.3145781222952156E+00, 0.3154531349760448E+00, 0.3538316586334169E-02, 0.1216353924418735E-02, 0.1084421501965814E+00, 0.1133548658237420E+00, 0.7375387005938499E-02, 0.9088178357782586E-03, 0.1396793466565477E-01, 0.1197200684467082E-01, 0.1592074691534444E-03, 0.1681378409852773E-04, 0.1264354865903830E-02, 0.1223627446170173E-05, 0.6512368848977837E-06, 0.2970373645586866E-06, 0.2818174710670554E-01}, + i0: 1, + n0: 18, + pp: 1, + tau: 1.2218877946904154E-006, + sigma: 9.7516636666659787E-002, + i0Out: 1, + n0Out: 18, + ppOut: 1, + tauOut: 1.2218877946904154E-006, + sigmaOut: 9.7516636666659787E-002, + dminOut: 9.5986727915820745E-012, + dmin1Out: 1.1875197612370336E-002, + dmin2Out: 0.11291768719739126, + dnOut: 9.5986727915820745E-012, + dnm1Out: 1.1875197612370336E-002, + dnm2Out: 0.11291768719739126, + }, + { + z: []float64{0.2383459406360114E+01, 0.2383460331210544E+01, 0.1353283656358167E-06, 0.2970373645586866E-06, 0.1085901506809686E+01, 0.1085889199499347E+01, 0.1986826396898849E-04, 0.1366452649899944E-04, 0.1584986515403004E+01, 0.1578904163506652E+01, 0.3190255011763210E-02, 0.6103442048115082E-02, 0.9412930918090910E+00, 0.8284687778600495E+00, 0.1576208411525267E+00, 0.1160157908485996E+00, 0.1332062774397564E+01, 0.1278855299065544E+01, 0.1143821023097510E+00, 0.2108295383723412E+00, 0.7987861757106404E+00, 0.7226887736910288E+00, 0.3654761154847582E+00, 0.1904807262171572E+00, 0.1274050092339202E+01, 0.1532634164092948E+01, 0.7205613198290631E-01, 0.1068932656188067E+00, 0.8354550922133908E+00, 0.8588297969472432E+00, 0.5621179414582513E-01, 0.4868264913684867E-01, 0.1126935674731953E+01, 0.9646646288612479E+00, 0.3667472533840468E+00, 0.2184840619043245E+00, 0.1562008914947536E+01, 0.1891673744281760E+01, 0.2769195683500124E-01, 0.3708364593761750E-01, 0.1332145183743590E+01, 0.1166419383934860E+01, 0.2620575140703801E+00, 0.1934189785315259E+00, 0.1691083203792688E+01, 0.1804883149953014E+01, 0.8359650824372877E-01, 0.1482587897978486E+00, 0.8790739000820365E+00, 0.9535262710524167E+00, 0.1175682535061811E-01, 0.9145359161143373E-02, 0.1119753245127243E+01, 0.1130094305914509E+01, 0.3991886785572840E-03, 0.1416986451145964E-02, 0.3162690783341116E+00, 0.3154531349760448E+00, 0.4359567385560517E-03, 0.1216353924418735E-02, 0.1138265050331695E+00, 0.1133548658237420E+00, 0.9558734450579545E-04, 0.9088178357782586E-03, 0.1189201139646886E-01, 0.1197200684467082E-01, 0.1730052806966466E-08, 0.1681378409852773E-04, 0.9598672791582074E-11, 0.1223627446170173E-05, 0.1353283656358167E-06, 0.2970373645586866E-06}, + i0: 1, + n0: 18, + pp: 0, + tau: 9.5986713933289272E-012, + sigma: 9.7517858554454467E-002, + i0Out: 1, + n0Out: 18, + ppOut: 0, + tauOut: 9.5986713933289272E-012, + sigmaOut: 9.7517858554454467E-002, + dminOut: 6.6174125886815435E-022, + dmin1Out: 1.1882019541390456E-002, + dmin2Out: 0.11366976186212303, + dnOut: 6.6174125886815435E-022, + dnm1Out: 1.1882019541390456E-002, + dnm2Out: 0.11366976186212303, + }, + { + z: []float64{0.2383459406360114E+01, 0.2383459541678881E+01, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.1085901506809686E+01, 0.1085921313408604E+01, 0.1986826396898849E-04, 0.2899927470478232E-04, 0.1584986515403004E+01, 0.1588147771130463E+01, 0.3190255011763210E-02, 0.1890859942802736E-02, 0.9412930918090910E+00, 0.1097023073009216E+01, 0.1576208411525267E+00, 0.1913914667196325E+00, 0.1332062774397564E+01, 0.1255053409978084E+01, 0.1143821023097510E+00, 0.7279916643176543E-01, 0.7987861757106404E+00, 0.1091463124754034E+01, 0.3654761154847582E+00, 0.4266153094141972E+00, 0.1274050092339202E+01, 0.9194909148983121E+00, 0.7205613198290631E-01, 0.6547064404326042E-01, 0.8354550922133908E+00, 0.8261962423063568E+00, 0.5621179414582513E-01, 0.7667315937770838E-01, 0.1126935674731953E+01, 0.1417009768728692E+01, 0.3667472533840468E+00, 0.4042756034295816E+00, 0.1562008914947536E+01, 0.1185425268343357E+01, 0.2769195683500124E-01, 0.3111938635974581E-01, 0.1332145183743590E+01, 0.1563083311444625E+01, 0.2620575140703801E+00, 0.2835172362390010E+00, 0.1691083203792688E+01, 0.1491162475787817E+01, 0.8359650824372877E-01, 0.4928202642453804E-01, 0.8790739000820365E+00, 0.8415486989985177E+00, 0.1175682535061811E-01, 0.1564347179719430E-01, 0.1119753245127243E+01, 0.1104508961999007E+01, 0.3991886785572840E-03, 0.1143051254380294E-03, 0.3162690783341116E+00, 0.3165907299376309E+00, 0.4359567385560517E-03, 0.1567431614478116E-03, 0.1138265050331695E+00, 0.1137653492066288E+00, 0.9558734450579545E-04, 0.9991845479738400E-05, 0.1189201139646886E-01, 0.1188202127144326E-01, 0.1730052806966466E-08, 0.1397591405272086E-17, 0.9598672791582074E-11, 0.6617412588681544E-21, 0.1353283656358167E-06, 0.6165545233233256E-07, 0.2818174710670554E-01}, + i0: 1, + n0: 18, + pp: 1, + tau: 6.6174125886815426E-022, + sigma: 9.7517858564053150E-002, + i0Out: 1, + n0Out: 18, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 9.7517858564053150E-002, + dminOut: 6.6174125886815426E-022, + dmin1Out: 1.1880977265773463E-002, + dmin2Out: 0.11370904624558997, + dnOut: 6.6174125886815426E-022, + dnm1Out: 1.1880977265773463E-002, + dnm2Out: 0.11370904624558997, + }, + { + z: []float64{0.2383459603334333E+01, 0.2383459541678881E+01, 0.2809066689524106E-07, 0.6165545233233256E-07, 0.1085950284592642E+01, 0.1085921313408604E+01, 0.4240998334843304E-04, 0.2899927470478232E-04, 0.1589996221089918E+01, 0.1588147771130463E+01, 0.1304604978030436E-02, 0.1890859942802736E-02, 0.1287109934750819E+01, 0.1097023073009216E+01, 0.1866247058326724E+00, 0.1913914667196325E+00, 0.1141227870577177E+01, 0.1255053409978084E+01, 0.6962466280543776E-01, 0.7279916643176543E-01, 0.1448453771362794E+01, 0.1091463124754034E+01, 0.2708190685256155E+00, 0.4266153094141972E+00, 0.7141424904159570E+00, 0.9194909148983121E+00, 0.7574342769943966E-01, 0.6547064404326042E-01, 0.8271259739846255E+00, 0.8261962423063568E+00, 0.1313543755784947E+00, 0.7667315937770838E-01, 0.1689930996579779E+01, 0.1417009768728692E+01, 0.2835846650840220E+00, 0.4042756034295816E+00, 0.9329599896190804E+00, 0.1185425268343357E+01, 0.5213749144931325E-01, 0.3111938635974581E-01, 0.1794463056234313E+01, 0.1563083311444625E+01, 0.2355970842920850E+00, 0.2835172362390010E+00, 0.1304847417920270E+01, 0.1491162475787817E+01, 0.3178396542921673E-01, 0.4928202642453804E-01, 0.8254082053664953E+00, 0.8415486989985177E+00, 0.2093310277804656E-01, 0.1564347179719430E-01, 0.1083690164346398E+01, 0.1104508961999007E+01, 0.3339325601415243E-04, 0.1143051254380294E-03, 0.3167140798430647E+00, 0.3165907299376309E+00, 0.5630296103885627E-04, 0.1567431614478116E-03, 0.1137190380910697E+00, 0.1137653492066288E+00, 0.1044005669799533E-05, 0.9991845479738400E-05, 0.1188097726577346E-01, 0.1188202127144326E-01, 0.7784240935906335E-37, 0.1397591405272086E-17}, + i0: 1, + n0: 17, + pp: 0, + tau: 1.1880832155707781E-002, + sigma: 9.7517858564053150E-002, + i0Out: 1, + n0Out: 17, + ppOut: 0, + tauOut: 1.1880832155707781E-002, + sigmaOut: 9.7517858564053150E-002, + dminOut: 2.3287035572430725E-008, + dmin1Out: 0.10181720511285566, + dmin2Out: 0.30482311636216664, + dnOut: 2.3287035572430725E-008, + dnm1Out: 0.10181720511285566, + dnm2Out: 0.30482311636216664, + }, + { + z: []float64{0.2383459603334333E+01, 0.2371578799269292E+01, 0.2809066689524106E-07, 0.1286276792433928E-07, 0.1085950284592642E+01, 0.1074111849557515E+01, 0.4240998334843304E-04, 0.6277904232066118E-04, 0.1589996221089918E+01, 0.1579357214869920E+01, 0.1304604978030436E-02, 0.1063198377376995E-02, 0.1287109934750819E+01, 0.1460790610050406E+01, 0.1866247058326724E+00, 0.1457986614708343E+00, 0.1141227870577177E+01, 0.1053173039756072E+01, 0.6962466280543776E-01, 0.9575644420574685E-01, 0.1448453771362794E+01, 0.1611635563526955E+01, 0.2708190685256155E+00, 0.1200044280642223E+00, 0.7141424904159570E+00, 0.6580006578954666E+00, 0.7574342769943966E-01, 0.9521169265880262E-01, 0.8271259739846255E+00, 0.8513878247486099E+00, 0.1313543755784947E+00, 0.2607270439790754E+00, 0.1689930996579779E+01, 0.1700907785529018E+01, 0.2835846650840220E+00, 0.1555482010511415E+00, 0.9329599896190804E+00, 0.8176684478615445E+00, 0.5213749144931325E-01, 0.1144214412274440E+00, 0.1794463056234313E+01, 0.1903757867143247E+01, 0.2355970842920850E+00, 0.1614796988702029E+00, 0.1304847417920270E+01, 0.1163270852323576E+01, 0.3178396542921673E-01, 0.2255256874351997E-01, 0.8254082053664953E+00, 0.8119079072453143E+00, 0.2093310277804656E-01, 0.2794035799797570E-01, 0.1083690164346398E+01, 0.1043902367448729E+01, 0.3339325601415243E-04, 0.1013132519024162E-04, 0.3167140798430647E+00, 0.3048794193232055E+00, 0.5630296103885627E-04, 0.2100082250625822E-04, 0.1137190380910697E+00, 0.1018182491185255E+00, 0.1044005669799533E-05, 0.1218230301111122E-06, 0.1188097726577346E-01, 0.2328703557243073E-07, 0.7784240935906335E-37, 0.1286276792433928E-07, 0.9751785856405315E-01}, + i0: 1, + n0: 17, + pp: 1, + tau: 2.3287007705477136E-008, + sigma: 0.10939869071976092, + i0Out: 1, + n0Out: 17, + ppOut: 1, + tauOut: 2.3287007705477136E-008, + sigmaOut: 0.10939869071976092, + dminOut: 2.6961654281145418E-018, + dmin1Out: 0.10181121275944585, + dmin2Out: 0.30487633314418217, + dnOut: 2.6961654281145418E-018, + dnm1Out: 0.10181121275944585, + dnm2Out: 0.30487633314418217, + }, + { + z: []float64{0.2371578788845052E+01, 0.2371578799269292E+01, 0.5825676764620370E-08, 0.1286276792433928E-07, 0.1074174599487151E+01, 0.1074111849557515E+01, 0.9230392664199863E-04, 0.6277904232066118E-04, 0.1580328086033647E+01, 0.1579357214869920E+01, 0.9827770701659698E-03, 0.1063198377376995E-02, 0.1605606471164067E+01, 0.1460790610050406E+01, 0.9563440497488795E-01, 0.1457986614708343E+00, 0.1053295055699924E+01, 0.1053173039756072E+01, 0.1465159169633776E+00, 0.9575644420574685E-01, 0.1585124051340792E+01, 0.1611635563526955E+01, 0.4981502397231050E-01, 0.1200044280642223E+00, 0.7033973032949510E+00, 0.6580006578954666E+00, 0.1152436546510613E+00, 0.9521169265880262E-01, 0.9968711907896164E+00, 0.8513878247486099E+00, 0.4448645553200346E+00, 0.2607270439790754E+00, 0.1411591407973117E+01, 0.1700907785529018E+01, 0.9010174998427344E-01, 0.1555482010511415E+00, 0.8419881158177074E+00, 0.8176684478615445E+00, 0.2587099684834221E+00, 0.1144214412274440E+00, 0.1806527574243020E+01, 0.1903757867143247E+01, 0.1039810460775319E+00, 0.1614796988702029E+00, 0.1081842351702556E+01, 0.1163270852323576E+01, 0.1692539477932339E-01, 0.2255256874351997E-01, 0.8229228471769590E+00, 0.8119079072453143E+00, 0.3544318396494814E-01, 0.2794035799797570E-01, 0.1008469291521964E+01, 0.1043902367448729E+01, 0.3062892015595061E-05, 0.1013132519024162E-04, 0.3048973339666884E+00, 0.3048794193232055E+00, 0.7013072071892081E-05, 0.2100082250625822E-04, 0.1018113345824760E+00, 0.1018182491185255E+00, 0.2786425742647189E-13, 0.1218230301111122E-06, 0.2696165428114542E-17, 0.2328703557243073E-07, 0.5825676764620370E-08, 0.1286276792433928E-07}, + i0: 1, + n0: 17, + pp: 0, + tau: 2.6961654281138038E-018, + sigma: 0.10939871400676864, + i0Out: 1, + n0Out: 17, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 0.10939871400676864, + dminOut: 2.6961654281138038E-018, + dmin1Out: 0.10180899282350273, + dmin2Out: 0.30489636738914000, + dnOut: 2.6961654281138038E-018, + dnm1Out: 0.10180899282350273, + dnm2Out: 0.30489636738914000, + }, + { + z: []float64{0.2371578788845052E+01, 0.2371578794670729E+01, 0.5825676764620370E-08, 0.2638661645752538E-08, 0.1074174599487151E+01, 0.1074266900775131E+01, 0.9230392664199863E-04, 0.1357860766428602E-03, 0.1580328086033647E+01, 0.1581175077027170E+01, 0.9827770701659698E-03, 0.9979623676695663E-03, 0.1605606471164067E+01, 0.1700242913771285E+01, 0.9563440497488795E-01, 0.5924520849284005E-01, 0.1053295055699924E+01, 0.1140565764170461E+01, 0.1465159169633776E+00, 0.2036234219705987E+00, 0.1585124051340792E+01, 0.1431315653342504E+01, 0.4981502397231050E-01, 0.2448080089382756E-01, 0.7033973032949510E+00, 0.7941601570521848E+00, 0.1152436546510613E+00, 0.1446598374682775E+00, 0.9968711907896164E+00, 0.1297075908641373E+01, 0.4448645553200346E+00, 0.4841405038964208E+00, 0.1411591407973117E+01, 0.1017552654060970E+01, 0.9010174998427344E-01, 0.7455594793877945E-01, 0.8419881158177074E+00, 0.1026142136362350E+01, 0.2587099684834221E+00, 0.4554599945126984E+00, 0.1806527574243020E+01, 0.1455048625807853E+01, 0.1039810460775319E+00, 0.7731088667813635E-01, 0.1081842351702556E+01, 0.1021456859803743E+01, 0.1692539477932339E-01, 0.1363571444815687E-01, 0.8229228471769590E+00, 0.8447303166937503E+00, 0.3544318396494814E-01, 0.4231334180394086E-01, 0.1008469291521964E+01, 0.9661590126100381E+00, 0.3062892015595061E-05, 0.9665775484099522E-06, 0.3048973339666884E+00, 0.3049033804612119E+00, 0.7013072071892081E-05, 0.2341758973227438E-05, 0.1018113345824760E+00, 0.1018089928235306E+00, 0.2786425742647189E-13, 0.7379175991216932E-30, 0.1093987140067686E+00}, + i0: 1, + n0: 16, + pp: 1, + tau: 0.10180650470263587, + sigma: 0.10939871400676864, + i0Out: 1, + n0Out: 16, + ppOut: 1, + tauOut: 0.10180650470263587, + sigmaOut: 0.10939871400676864, + dminOut: 1.3142485785350155E-006, + dmin1Out: 0.20309651253108729, + dmin2Out: 0.57610166617362735, + dnOut: 1.3142485785350155E-006, + dnm1Out: 0.20309651253108729, + dnm2Out: 0.81137144083676127, + }, + { + z: []float64{0.2269772292606755E+01, 0.2371578794670729E+01, 0.1248859578385863E-08, 0.2638661645752538E-08, 0.9725961809002787E+00, 0.1074266900775131E+01, 0.2207509801202943E-03, 0.1357860766428602E-03, 0.1480145783712083E+01, 0.1581175077027170E+01, 0.1146359002276934E-02, 0.9979623676695663E-03, 0.1656535258559212E+01, 0.1700242913771285E+01, 0.4079180092843103E-01, 0.5924520849284005E-01, 0.1201590880509993E+01, 0.1140565764170461E+01, 0.2425529321011353E+00, 0.2036234219705987E+00, 0.1111437017432560E+01, 0.1431315653342504E+01, 0.1749237822536809E-01, 0.2448080089382756E-01, 0.8195211115924584E+00, 0.7941601570521848E+00, 0.2289566278084960E+00, 0.1446598374682775E+00, 0.1450453280026662E+01, 0.1297075908641373E+01, 0.3396444831847066E+00, 0.4841405038964208E+00, 0.6506576141124067E+00, 0.1017552654060970E+01, 0.1175810411452473E+00, 0.7455594793877945E-01, 0.1262214585027166E+01, 0.1026142136362350E+01, 0.5250426092262996E+00, 0.4554599945126984E+00, 0.9055103985570538E+00, 0.1455048625807853E+01, 0.8721019179982008E-01, 0.7731088667813635E-01, 0.8460758777494440E+00, 0.1021456859803743E+01, 0.1361402882064932E-01, 0.1363571444815687E-01, 0.7716231249744060E+00, 0.8447303166937503E+00, 0.5298106707064092E-01, 0.4231334180394086E-01, 0.8113724074143097E+00, 0.9661590126100381E+00, 0.3632274887524200E-06, 0.9665775484099522E-06, 0.2030988542900605E+00, 0.3049033804612119E+00, 0.1173872316183806E-05, 0.2341758973227438E-05, 0.1314248578535016E-05, 0.1018089928235306E+00, 0.1248859578385863E-08, 0.2638661645752538E-08}, + i0: 1, + n0: 16, + pp: 0, + tau: 1.3142409824136984E-006, + sigma: 0.21120521870940451, + i0Out: 1, + n0Out: 16, + ppOut: 0, + tauOut: 1.3142409824136984E-006, + sigmaOut: 0.21120521870940451, + dminOut: 8.4118841991824567E-018, + dmin1Out: 0.20309744276965425, + dmin2Out: 0.50018599148866161, + dnOut: 8.4118841991824567E-018, + dnm1Out: 0.20309744276965425, + dnm2Out: 0.75834178007645303, + }, + { + z: []float64{0.2269772292606755E+01, 0.2269770979614632E+01, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.9725961809002787E+00, 0.9728156171042807E+00, 0.2207509801202943E-03, 0.3358741643642203E-03, 0.1480145783712083E+01, 0.1480954954309013E+01, 0.1146359002276934E-02, 0.1282269997958535E-02, 0.1656535258559212E+01, 0.1696043475248702E+01, 0.4079180092843103E-01, 0.2889964597634762E-01, 0.1201590880509993E+01, 0.1415242852393798E+01, 0.2425529321011353E+00, 0.1904848393814713E+00, 0.1111437017432560E+01, 0.9384432420354740E+00, 0.1749237822536809E-01, 0.1527569554079381E-01, 0.8195211115924584E+00, 0.1033200729619178E+01, 0.2289566278084960E+00, 0.3214195289148511E+00, 0.1450453280026662E+01, 0.1468676920055535E+01, 0.3396444831847066E+00, 0.1504703083827628E+00, 0.6506576141124067E+00, 0.6177670326339089E+00, 0.1175810411452473E+00, 0.2402402478867145E+00, 0.1262214585027166E+01, 0.1547015632125768E+01, 0.5250426092262996E+00, 0.3073217441808570E+00, 0.9055103985570538E+00, 0.6853975319350345E+00, 0.8721019179982008E-01, 0.1076549537133787E+00, 0.8460758777494440E+00, 0.7520336386157322E+00, 0.1361402882064932E-01, 0.1396865635082151E-01, 0.7716231249744060E+00, 0.8106342214532430E+00, 0.5298106707064092E-01, 0.5302931309687425E-01, 0.8113724074143097E+00, 0.7583421433039418E+00, 0.3632274887524200E-06, 0.9727942389020712E-07, 0.2030988542900605E+00, 0.2030986166419704E+00, 0.1173872316183806E-05, 0.7596112905317353E-11, 0.1314248578535016E-05, 0.8411884199182457E-17, 0.1248859578385863E-08, 0.5351359530665278E-09, 0.1093987140067686E+00}, + i0: 1, + n0: 16, + pp: 1, + tau: 8.4118841988678429E-018, + sigma: 0.21120653295038691, + i0Out: 1, + n0Out: 16, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 0.21120653295038691, + dminOut: 8.4118841988678429E-018, + dmin1Out: 0.20309858884628909, + dmin2Out: 0.53283137411117854, + dnOut: 8.4118841988678429E-018, + dnm1Out: 0.20309858884628909, + dnm2Out: 0.71080515929391042, + }, + { + z: []float64{0.2269770980149768E+01, 0.2269770979614632E+01, 0.2293573303077261E-09, 0.5351359530665278E-09, 0.9731514910392876E+00, 0.9728156171042807E+00, 0.5111377954200868E-03, 0.3358741643642203E-03, 0.1481726086511552E+01, 0.1480954954309013E+01, 0.1467737987028945E-02, 0.1282269997958535E-02, 0.1723475383238021E+01, 0.1696043475248702E+01, 0.2373112943910766E-01, 0.2889964597634762E-01, 0.1581996562336162E+01, 0.1415242852393798E+01, 0.1129959536471923E+00, 0.1904848393814713E+00, 0.8407229839290754E+00, 0.9384432420354740E+00, 0.1877296098701645E-01, 0.1527569554079381E-01, 0.1335847297547013E+01, 0.1033200729619178E+01, 0.3533797947109679E+00, 0.3214195289148511E+00, 0.1265767433727330E+01, 0.1468676920055535E+01, 0.7343813202351114E-01, 0.1504703083827628E+00, 0.7845691484971122E+00, 0.6177670326339089E+00, 0.4737063898809231E+00, 0.2402402478867145E+00, 0.1380630986425702E+01, 0.1547015632125768E+01, 0.1525661578238559E+00, 0.3073217441808570E+00, 0.6404863278245572E+00, 0.6853975319350345E+00, 0.1264041760751794E+00, 0.1076549537133787E+00, 0.6395981188913744E+00, 0.7520336386157322E+00, 0.1770404028911661E-01, 0.1396865635082151E-01, 0.8459594942610007E+00, 0.8106342214532430E+00, 0.4753698401003136E-01, 0.5302931309687425E-01, 0.7108052565733343E+00, 0.7583421433039418E+00, 0.2779568135873871E-07, 0.9727942389020712E-07, 0.2030985888538852E+00, 0.2030986166419704E+00, 0.3146138162949754E-27, 0.7596112905317353E-11, 0.8411884198867843E-17, 0.8411884199182457E-17, 0.2293573303077261E-09, 0.5351359530665278E-09}, + i0: 1, + n0: 16, + pp: 0, + tau: 8.4118841988678429E-018, + sigma: 0.21120653295038691, + i0Out: 1, + n0Out: 16, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 0.21120653295038691, + dminOut: 8.4118841988678429E-018, + dmin1Out: 0.20309858045029386, + dmin2Out: 0.51860540644834729, + dnOut: 8.4118841988678429E-018, + dnm1Out: 0.20309858045029386, + dnm2Out: 0.67176795876146822, + }, + { + z: []float64{0.2269770980149768E+01, 0.2269770980379126E+01, 0.2293573303077261E-09, 0.9833566024906726E-10, 0.9731514910392876E+00, 0.9736626287363720E+00, 0.5111377954200868E-03, 0.7778528033461282E-03, 0.1481726086511552E+01, 0.1482415971695234E+01, 0.1467737987028945E-02, 0.1706410574351102E-02, 0.1723475383238021E+01, 0.1745500102102777E+01, 0.2373112943910766E-01, 0.2150819994097728E-01, 0.1581996562336162E+01, 0.1673484316042377E+01, 0.1129959536471923E+00, 0.5676676764251993E-01, 0.8407229839290754E+00, 0.8027291772735718E+00, 0.1877296098701645E-01, 0.3124068479314146E-01, 0.1335847297547013E+01, 0.1657986407464839E+01, 0.3533797947109679E+00, 0.2697830536296953E+00, 0.1265767433727330E+01, 0.1069422512121146E+01, 0.7343813202351114E-01, 0.5387701498318342E-01, 0.7845691484971122E+00, 0.1204398523394852E+01, 0.4737063898809231E+00, 0.5430210247136315E+00, 0.1380630986425702E+01, 0.9901761195359265E+00, 0.1525661578238559E+00, 0.9868601781741700E-01, 0.6404863278245572E+00, 0.6682044860823195E+00, 0.1264041760751794E+00, 0.1209927124430272E+00, 0.6395981188913744E+00, 0.5363094467374639E+00, 0.1770404028911661E-01, 0.2792585709699239E-01, 0.8459594942610007E+00, 0.8655706211740396E+00, 0.4753698401003136E-01, 0.3903729781186600E-01, 0.7108052565733343E+00, 0.6717679865571495E+00, 0.2779568135873871E-07, 0.8403591378512072E-08, 0.2030985888538852E+00, 0.2030985804502939E+00, 0.3146138162949754E-27, 0.1303059324279677E-43, 0.2112065329503869E+00}, + i0: 1, + n0: 15, + pp: 1, + tau: 0.10154929022514693, + sigma: 0.21120653295038691, + i0Out: 1, + n0Out: 15, + ppOut: 1, + tauOut: 0.10154929022514693, + sigmaOut: 0.21120653295038691, + dminOut: 0.10154928703201281, + dmin1Out: 0.32391205918605420, + dmin2Out: 0.32391205918605420, + dnOut: 0.10154928703201281, + dnm1Out: 0.53450854002684800, + dnm2Out: 0.69531980574199759, + }, + { + z: []float64{0.2168221690252314E+01, 0.2269770980379126E+01, 0.4415865678637858E-10, 0.9833566024906726E-10, 0.8728911912704126E+00, 0.9736626287363720E+00, 0.1321013925721922E-02, 0.7778528033461282E-03, 0.1381252078118717E+01, 0.1482415971695234E+01, 0.2156405683614187E-02, 0.1706410574351102E-02, 0.1663302606134993E+01, 0.1745500102102777E+01, 0.2163985983955575E-01, 0.2150819994097728E-01, 0.1607061933620194E+01, 0.1673484316042377E+01, 0.2835506195054301E-01, 0.5676676764251993E-01, 0.7040655098910235E+00, 0.8027291772735718E+00, 0.7356791380810462E-01, 0.3124068479314146E-01, 0.1752652257061283E+01, 0.1657986407464839E+01, 0.1646145547572216E+00, 0.2697830536296953E+00, 0.8571356821219610E+00, 0.1069422512121146E+01, 0.7570493055431493E-01, 0.5387701498318342E-01, 0.1570165327329021E+01, 0.1204398523394852E+01, 0.3424393862982660E+00, 0.5430210247136315E+00, 0.6448734608299306E+00, 0.9901761195359265E+00, 0.1022564019526126E+00, 0.9868601781741700E-01, 0.5853915063475871E+00, 0.6682044860823195E+00, 0.1108480973262629E+00, 0.1209927124430272E+00, 0.3518379162830466E+00, 0.5363094467374639E+00, 0.6870152520689508E-01, 0.2792585709699239E-01, 0.7343571035538636E+00, 0.8655706211740396E+00, 0.3571015630515456E-01, 0.3903729781186600E-01, 0.5345085484304394E+00, 0.6717679865571495E+00, 0.3193134112956561E-08, 0.8403591378512072E-08, 0.1015492870320128E+00, 0.2030985804502939E+00, 0.4415865678637858E-10, 0.9833566024906726E-10}, + i0: 1, + n0: 15, + pp: 0, + tau: 0.10154100618138810, + sigma: 0.31275582317553385, + i0Out: 1, + n0Out: 15, + ppOut: 0, + tauOut: 0.10154100618138810, + sigmaOut: 0.31275582317553385, + dminOut: 8.2800215414347011E-006, + dmin1Out: 0.16866357962181588, + dmin2Out: 0.16866357962181588, + dnOut: 8.2800215414347011E-006, + dnm1Out: 0.39110725789187228, + dnm2Out: 0.42026820370851276, + }, + { + z: []float64{0.2168221690252314E+01, 0.2066680684115085E+01, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.8728911912704126E+00, 0.7726711989960955E+00, 0.1321013925721922E-02, 0.2361487308570419E-02, 0.1381252078118717E+01, 0.1279505990312372E+01, 0.2156405683614187E-02, 0.2803234389363145E-02, 0.1663302606134993E+01, 0.1580598225403798E+01, 0.2163985983955575E-01, 0.2200217261925751E-01, 0.1607061933620194E+01, 0.1511873816770092E+01, 0.2835506195054301E-01, 0.1320468740761088E-01, 0.7040655098910235E+00, 0.6628877301101292E+00, 0.7356791380810462E-01, 0.1945110224949301E+00, 0.1752652257061283E+01, 0.1621214783142186E+01, 0.1646145547572216E+00, 0.8703165684534678E-01, 0.8571356821219610E+00, 0.7442679496495411E+00, 0.7570493055431493E-01, 0.1597129865933493E+00, 0.1570165327329021E+01, 0.1651350720852550E+01, 0.3424393862982660E+00, 0.1337269360034139E+00, 0.6448734608299306E+00, 0.5118619205977412E+00, 0.1022564019526126E+00, 0.1169456581236225E+00, 0.5853915063475871E+00, 0.4777529393688394E+00, 0.1108480973262629E+00, 0.8163333047984263E-01, 0.3518379162830466E+00, 0.2373651048287110E+00, 0.6870152520689508E-01, 0.2125478936639627E+00, 0.7343571035538636E+00, 0.4559783600136673E+00, 0.3571015630515456E-01, 0.4186028435717903E-01, 0.5345085484304394E+00, 0.3911072610850064E+00, 0.3193134112956561E-08, 0.8290832843879624E-09, 0.1015492870320128E+00, 0.8280021541434701E-05, 0.4415865678637858E-10, 0.1865101988102620E-10, 0.2112065329503869E+00}, + i0: 1, + n0: 15, + pp: 1, + tau: 8.2795951083136037E-006, + sigma: 0.41429682935692197, + i0Out: 1, + n0Out: 15, + ppOut: 1, + tauOut: 8.2795951083136037E-006, + sigmaOut: 0.41429682935692197, + dminOut: 4.2641220534843968E-010, + dmin1Out: 0.19554701532405336, + dmin2Out: 0.19554701532405336, + dnOut: 4.2641220534843968E-010, + dnm1Out: 0.32821333105682254, + dnm2Out: 0.21848306981706411, + }, + { + z: []float64{0.2066672404538628E+01, 0.2066680684115085E+01, 0.6973096395115281E-11, 0.1865101988102620E-10, 0.7750244067025847E+00, 0.7726711989960955E+00, 0.3898634844569491E-02, 0.2361487308570419E-02, 0.1278402310262057E+01, 0.1279505990312372E+01, 0.3465878671879142E-02, 0.2803234389363145E-02, 0.1599126239756068E+01, 0.1580598225403798E+01, 0.2080167773382635E-01, 0.2200217261925751E-01, 0.1504268546848768E+01, 0.1511873816770092E+01, 0.5818924606767697E-02, 0.1320468740761088E-01, 0.8515715484031834E+00, 0.6628877301101292E+00, 0.3703084558710277E+00, 0.1945110224949301E+00, 0.1337929704521397E+01, 0.1621214783142186E+01, 0.4841425717359337E-01, 0.8703165684534678E-01, 0.8555583994741887E+00, 0.7442679496495411E+00, 0.3082690272254148E+00, 0.1597129865933493E+00, 0.1476800350035441E+01, 0.1651350720852550E+01, 0.4635002036444261E-01, 0.1337269360034139E+00, 0.5824492787618127E+00, 0.5118619205977412E+00, 0.9592445892242578E-01, 0.1169456581236225E+00, 0.4634535313311479E+00, 0.4777529393688394E+00, 0.4180980990954932E-01, 0.8163333047984263E-01, 0.4080949089880160E+00, 0.2373651048287110E+00, 0.2374870106014949E+00, 0.2125478936639627E+00, 0.2603433541742431E+00, 0.4559783600136673E+00, 0.6288565043307552E-01, 0.4186028435717903E-01, 0.3282133318859058E+00, 0.3911072610850064E+00, 0.2091574834858362E-13, 0.8290832843879624E-09, 0.4264122053484397E-09, 0.8280021541434701E-05, 0.6973096395115281E-11, 0.1865101988102620E-10}, + i0: 1, + n0: 15, + pp: 0, + tau: 4.2641207498271701E-010, + sigma: 0.41430510895203027, + i0Out: 1, + n0Out: 15, + ppOut: 0, + tauOut: 4.2641207498271701E-010, + sigmaOut: 0.41430510895203027, + dminOut: 1.3036568472020817E-016, + dmin1Out: 0.15841174212052453, + dmin2Out: 0.15841174212052453, + dnOut: 1.3036568472020817E-016, + dnm1Out: 0.23494558610432464, + dnm2Out: 0.15841174212052453, + }, + { + z: []float64{0.2066672404538628E+01, 0.2066672404119188E+01, 0.6973096395115281E-11, 0.2614986238618434E-11, 0.7750244067025847E+00, 0.7789230411181270E+00, 0.3898634844569491E-02, 0.6398608757305904E-02, 0.1278402310262057E+01, 0.1275469579750218E+01, 0.3465878671879142E-02, 0.4345362379476143E-02, 0.1599126239756068E+01, 0.1615582554684006E+01, 0.2080167773382635E-01, 0.1936843737632438E-01, 0.1504268546848768E+01, 0.1490719033652799E+01, 0.5818924606767697E-02, 0.3324054047451484E-02, 0.8515715484031834E+00, 0.1218555949800348E+01, 0.3703084558710277E+00, 0.4065850919906259E+00, 0.1337929704521397E+01, 0.9797588692779520E+00, 0.4841425717359337E-01, 0.4227695780870786E-01, 0.8555583994741887E+00, 0.1121550468464483E+01, 0.3082690272254148E+00, 0.4059129037098644E+00, 0.1476800350035441E+01, 0.1117237466263607E+01, 0.4635002036444261E-01, 0.2416365074306882E-01, 0.5824492787618127E+00, 0.6542100865147574E+00, 0.9592445892242578E-01, 0.6795451513972497E-01, 0.4634535313311479E+00, 0.4373088256745602E+00, 0.4180980990954932E-01, 0.3901675330591518E-01, 0.4080949089880160E+00, 0.6065651658571838E+00, 0.2374870106014949E+00, 0.1019316116273065E+00, 0.2603433541742431E+00, 0.2212973925536000E+00, 0.6288565043307552E-01, 0.9326774535516916E-01, 0.3282133318859058E+00, 0.2349455861043456E+00, 0.2091574834858362E-13, 0.3796083394336032E-22, 0.4264122053484397E-09, 0.1303656847202082E-15, 0.6973096395115281E-11, 0.2614986238618434E-11, 0.2112065329503869E+00}, + i0: 1, + n0: 15, + pp: 1, + tau: 1.3036568471812905E-016, + sigma: 0.41430510937844234, + i0Out: 1, + n0Out: 15, + ppOut: 1, + tauOut: 1.3036568471812905E-016, + sigmaOut: 0.41430510937844234, + dminOut: 2.0791168714198411E-027, + dmin1Out: 0.15670572686712736, + dmin2Out: 0.18680490956440032, + dnOut: 2.0791168714198411E-027, + dnm1Out: 0.15670572686712736, + dnm2Out: 0.18680490956440032, + }, + { + z: []float64{0.2066672404121803E+01, 0.2066672404119188E+01, 0.9855809897129084E-12, 0.2614986238618434E-11, 0.7853216498744473E+00, 0.7789230411181270E+00, 0.1039221422709001E-01, 0.6398608757305904E-02, 0.1269422727902604E+01, 0.1275469579750218E+01, 0.5530302475095172E-02, 0.4345362379476143E-02, 0.1629420689585235E+01, 0.1615582554684006E+01, 0.1771973219288664E-01, 0.1936843737632438E-01, 0.1476323355507364E+01, 0.1490719033652799E+01, 0.2743671176012720E-02, 0.3324054047451484E-02, 0.1622397370614960E+01, 0.1218555949800348E+01, 0.2455350071499520E+00, 0.4065850919906259E+00, 0.7765008199367077E+00, 0.9797588692779520E+00, 0.6106335063429082E-01, 0.4227695780870786E-01, 0.1466400021540057E+01, 0.1121550468464483E+01, 0.3092615230516922E+00, 0.4059129037098644E+00, 0.8321395939549830E+00, 0.1117237466263607E+01, 0.1899693772291602E-01, 0.2416365074306882E-01, 0.7031676639315663E+00, 0.6542100865147574E+00, 0.4226176876348708E-01, 0.6795451513972497E-01, 0.4340638102169883E+00, 0.4373088256745602E+00, 0.5452240634477346E-01, 0.3901675330591518E-01, 0.6539743711397168E+00, 0.6065651658571838E+00, 0.3449248298919955E-01, 0.1019316116273065E+00, 0.2800726549195695E+00, 0.2212973925536000E+00, 0.7823985923721809E-01, 0.9326774535516916E-01, 0.1567057268671274E+00, 0.2349455861043456E+00, 0.3158014839988858E-37, 0.3796083394336032E-22}, + i0: 1, + n0: 14, + pp: 0, + tau: 5.2226904068357879E-002, + sigma: 0.41430510937844245, + i0Out: 1, + n0Out: 14, + ppOut: 0, + tauOut: 5.2226904068357879E-002, + sigmaOut: 0.41430510937844245, + dminOut: 6.1979733096699005E-002, + dmin1Out: 0.21025182606004778, + dmin2Out: 0.35454858327394784, + dnOut: 6.1979733096699005E-002, + dnm1Out: 0.21025182606004778, + dnm2Out: 0.51458348500658069, + }, + { + z: []float64{0.2066672404121803E+01, 0.2014445500054431E+01, 0.9855809897129084E-12, 0.3842238913414725E-12, 0.7853216498744473E+00, 0.7434869600327952E+00, 0.1039221422709001E-01, 0.1774357001838869E-01, 0.1269422727902604E+01, 0.1204982556290953E+01, 0.5530302475095172E-02, 0.7478273627729330E-02, 0.1629420689585235E+01, 0.1587435244082034E+01, 0.1771973219288664E-01, 0.1647944669694028E-01, 0.1476323355507364E+01, 0.1410360675918078E+01, 0.2743671176012720E-02, 0.3156160674217245E-02, 0.1622397370614960E+01, 0.1812549313022337E+01, 0.2455350071499520E+00, 0.1051878329628395E+00, 0.7765008199367077E+00, 0.6801494335398012E+00, 0.6106335063429082E-01, 0.1316523902981273E+00, 0.1466400021540057E+01, 0.1591782250225264E+01, 0.3092615230516922E+00, 0.1616733433116970E+00, 0.8321395939549830E+00, 0.6372362842978442E+00, 0.1899693772291602E-01, 0.2096244776016672E-01, 0.7031676639315663E+00, 0.6722400808665288E+00, 0.4226176876348708E-01, 0.2728832287468248E-01, 0.4340638102169883E+00, 0.4090709896187213E+00, 0.5452240634477346E-01, 0.8716398206477828E-01, 0.6539743711397168E+00, 0.5490759679957803E+00, 0.3449248298919955E-01, 0.1759392479116377E-01, 0.2800726549195695E+00, 0.2884916852972659E+00, 0.7823985923721809E-01, 0.4249908970207047E-01, 0.1567057268671274E+00, 0.6197973309669901E-01, 0.3158014839988858E-37, 0.3842238913414725E-12, 0.4143051093784424E+00}, + i0: 1, + n0: 14, + pp: 1, + tau: 4.3992746597899146E-002, + sigma: 0.46653201344680034, + i0Out: 1, + n0Out: 14, + ppOut: 1, + tauOut: 4.3992746597899146E-002, + sigmaOut: 0.46653201344680034, + dminOut: 8.3978432207528000E-003, + dmin1Out: 0.23219513064786862, + dmin2Out: 0.34734604130905122, + dnOut: 8.3978432207528000E-003, + dnm1Out: 0.23219513064786862, + dnm2Out: 0.39493697562207530, + }, + { + z: []float64{0.1970452753456916E+01, 0.2014445500054431E+01, 0.1449745254963753E-12, 0.3842238913414725E-12, 0.7172377834531399E+00, 0.7434869600327952E+00, 0.2980976860358389E-01, 0.1774357001838869E-01, 0.1138658314717199E+01, 0.1204982556290953E+01, 0.1042566937606312E-01, 0.7478273627729330E-02, 0.1549496274805013E+01, 0.1587435244082034E+01, 0.1499968987352189E-01, 0.1647944669694028E-01, 0.1354524400120875E+01, 0.1410360675918078E+01, 0.4223398900256122E-02, 0.3156160674217245E-02, 0.1869521000487022E+01, 0.1812549313022337E+01, 0.3826832915293116E-01, 0.1051878329628395E+00, 0.7295407480870981E+00, 0.6801494335398012E+00, 0.2872518617030954E+00, 0.1316523902981273E+00, 0.1422210985235967E+01, 0.1591782250225264E+01, 0.7243940711431240E-01, 0.1616733433116970E+00, 0.5417665783457993E+00, 0.6372362842978442E+00, 0.2601082853889214E-01, 0.2096244776016672E-01, 0.6295248286044199E+00, 0.6722400808665288E+00, 0.1773220171177086E-01, 0.2728832287468248E-01, 0.4345100233738295E+00, 0.4090709896187213E+00, 0.1101462457758059E+00, 0.8716398206477828E-01, 0.4125309004132391E+00, 0.5490759679957803E+00, 0.1230380805149813E-01, 0.1759392479116377E-01, 0.2746942203499391E+00, 0.2884916852972659E+00, 0.9589143278047064E-02, 0.4249908970207047E-01, 0.8397843220752800E-02, 0.6197973309669901E-01, 0.1449745254963753E-12, 0.3842238913414725E-12}, + i0: 1, + n0: 14, + pp: 0, + tau: 8.0121275381568099E-003, + sigma: 0.51052476004469949, + i0Out: 1, + n0Out: 14, + ppOut: 0, + tauOut: 8.0121275381568099E-003, + sigmaOut: 0.51052476004469949, + dminOut: 8.3015533671799979E-005, + dmin1Out: 0.25644350373773794, + dmin2Out: 0.31779880038403513, + dnOut: 8.3015533671799979E-005, + dnm1Out: 0.25644350373773794, + dnm2Out: 0.31779880038403513, + }, + { + z: []float64{0.1970452753456916E+01, 0.1962440625918904E+01, 0.1449745254963753E-12, 0.5298565773193886E-13, 0.7172377834531399E+00, 0.7390354245185139E+00, 0.2980976860358389E-01, 0.4592897681783073E-01, 0.1138658314717199E+01, 0.1095142879737275E+01, 0.1042566937606312E-01, 0.1475107600976594E-01, 0.1549496274805013E+01, 0.1541732761130612E+01, 0.1499968987352189E-01, 0.1317831886314191E-01, 0.1354524400120875E+01, 0.1337557352619832E+01, 0.4223398900256122E-02, 0.5903098601340335E-02, 0.1869521000487022E+01, 0.1893874103500456E+01, 0.3826832915293116E-01, 0.1474137347708128E-01, 0.7295407480870981E+00, 0.9940391087749554E+00, 0.2872518617030954E+00, 0.4109825756725979E+00, 0.1422210985235967E+01, 0.1075655689139524E+01, 0.7243940711431240E-01, 0.3648495529374628E-01, 0.5417665783457993E+00, 0.5232803240527883E+00, 0.2601082853889214E-01, 0.3129195122603765E-01, 0.6295248286044199E+00, 0.6079529515519964E+00, 0.1773220171177086E-01, 0.1267338099203561E-01, 0.4345100233738295E+00, 0.5239707606194429E+00, 0.1101462457758059E+00, 0.8671997249104711E-01, 0.4125309004132391E+00, 0.3301026084355332E+00, 0.1230380805149813E-01, 0.1023858907404432E-01, 0.2746942203499391E+00, 0.2660326470157850E+00, 0.9589143278047064E-02, 0.3027001489241909E-03, 0.8397843220752800E-02, 0.8301553367179998E-04, 0.1449745254963753E-12, 0.5298565773193886E-13, 0.4143051093784424E+00}, + i0: 1, + n0: 14, + pp: 1, + tau: 8.2898056486573887E-005, + sigma: 0.51853688758285632, + i0Out: 1, + n0Out: 14, + ppOut: 1, + tauOut: 8.2898056486573887E-005, + sigmaOut: 0.51853688758285632, + dminOut: 1.9676836973621424E-008, + dmin1Out: 0.25663722751477031, + dmin2Out: 0.28224921557690585, + dnOut: 1.9676836973621424E-008, + dnm1Out: 0.25663722751477031, + dnm2Out: 0.28224921557690585, + }, + { + z: []float64{0.1962357727862470E+01, 0.1962440625918904E+01, 0.1995470932711637E-13, 0.5298565773193886E-13, 0.7848815032798381E+00, 0.7390354245185139E+00, 0.6408456783027588E-01, 0.4592897681783073E-01, 0.1045726489860278E+01, 0.1095142879737275E+01, 0.2174776805091989E-01, 0.1475107600976594E-01, 0.1533080413886347E+01, 0.1541732761130612E+01, 0.1149760777771624E-01, 0.1317831886314191E-01, 0.1331879945386970E+01, 0.1337557352619832E+01, 0.8393943921304423E-02, 0.5903098601340335E-02, 0.1900138634999746E+01, 0.1893874103500456E+01, 0.7711806645770664E-02, 0.1474137347708128E-01, 0.1397226979745296E+01, 0.9940391087749554E+00, 0.3163950825942626E+00, 0.4109825756725979E+00, 0.7956626637825215E+00, 0.1075655689139524E+01, 0.2399491656225486E-01, 0.3648495529374628E-01, 0.5304944606600845E+00, 0.5232803240527883E+00, 0.3586094769777509E-01, 0.3129195122603765E-01, 0.5846824867897703E+00, 0.6079529515519964E+00, 0.1135741402906866E-01, 0.1267338099203561E-01, 0.5992504210249349E+00, 0.5239707606194429E+00, 0.4777049480214081E-01, 0.8671997249104711E-01, 0.2924878046509502E+00, 0.3301026084355332E+00, 0.9312521444528056E-02, 0.1023858907404432E-01, 0.2569399276636945E+00, 0.2660326470157850E+00, 0.9780034825247492E-07, 0.3027001489241909E-03, 0.1967683697362142E-07, 0.8301553367179998E-04, 0.1995470932711637E-13, 0.5298565773193886E-13}, + i0: 1, + n0: 14, + pp: 0, + tau: 1.9676827722764296E-008, + sigma: 0.51861978563934286, + i0Out: 1, + n0Out: 14, + ppOut: 0, + tauOut: 1.9676827722764296E-008, + sigmaOut: 0.51861978563934286, + dminOut: 1.5032959860012969E-015, + dmin1Out: 0.24838793989138258, + dmin2Out: 0.27047787997045275, + dnOut: 1.5032959860012969E-015, + dnm1Out: 0.24838793989138258, + dnm2Out: 0.27047787997045275, + }, + { + z: []float64{0.1962357727862470E+01, 0.1962357708185662E+01, 0.1995470932711637E-13, 0.7981257539768321E-14, 0.7848815032798381E+00, 0.8489660514332782E+00, 0.6408456783027588E-01, 0.7893711422056097E-01, 0.1045726489860278E+01, 0.9885371240138099E+00, 0.2174776805091989E-01, 0.3372769361380378E-01, 0.1533080413886347E+01, 0.1510850308373431E+01, 0.1149760777771624E-01, 0.1013563894066502E-01, 0.1331879945386970E+01, 0.1330138230690781E+01, 0.8393943921304423E-02, 0.1199097716077874E-01, 0.1900138634999746E+01, 0.1895859444807910E+01, 0.7711806645770664E-02, 0.5683514322519618E-02, 0.1397226979745296E+01, 0.1707938528340212E+01, 0.3163950825942626E+00, 0.1473962616612956E+00, 0.7956626637825215E+00, 0.6722612990066530E+00, 0.2399491656225486E-01, 0.1893485515094503E-01, 0.5304944606600845E+00, 0.5474205335300870E+00, 0.3586094769777509E-01, 0.3830193935796279E-01, 0.5846824867897703E+00, 0.5577379417840483E+00, 0.1135741402906866E-01, 0.1220274725600271E-01, 0.5992504210249349E+00, 0.6348181488942451E+00, 0.4777049480214081E-01, 0.2200990500366971E-01, 0.2924878046509502E+00, 0.2797904014149808E+00, 0.9312521444528056E-02, 0.8551968095484232E-02, 0.2569399276636945E+00, 0.2483880376917308E+00, 0.9780034825247492E-07, 0.7747561140265878E-14, 0.1967683697362142E-07, 0.1503295986001297E-14, 0.1995470932711637E-13, 0.7981257539768321E-14, 0.4143051093784424E+00}, + i0: 1, + n0: 14, + pp: 1, + tau: 1.5032959860012393E-015, + sigma: 0.51861980531617058, + i0Out: 1, + n0Out: 14, + ppOut: 1, + tauOut: 1.5032959860012393E-015, + sigmaOut: 0.51861980531617058, + dminOut: 9.2691156363468887E-030, + dmin1Out: 0.24076768543540897, + dmin2Out: 0.27020241256687788, + dnOut: 9.2691156363468887E-030, + dnm1Out: 0.24076768543540897, + dnm2Out: 0.27020241256687788, + }, + { + z: []float64{0.1962357708185669E+01, 0.1962357708185662E+01, 0.3452895805257589E-14, 0.7981257539768321E-14, 0.9279031656538340E+00, 0.8489660514332782E+00, 0.8409527066820451E-01, 0.7893711422056097E-01, 0.9381695469594078E+00, 0.9885371240138099E+00, 0.5431587122209677E-01, 0.3372769361380378E-01, 0.1466670076091998E+01, 0.1510850308373431E+01, 0.9192115573380727E-02, 0.1013563894066502E-01, 0.1332937092278178E+01, 0.1330138230690781E+01, 0.1705497388769041E-01, 0.1199097716077874E-01, 0.1884487985242738E+01, 0.1895859444807910E+01, 0.5151050664063701E-02, 0.5683514322519618E-02, 0.1850183739337442E+01, 0.1707938528340212E+01, 0.5355619565040129E-01, 0.1473962616612956E+00, 0.6376399585071952E+00, 0.6722612990066530E+00, 0.1625577000116482E-01, 0.1893485515094503E-01, 0.5694667028868834E+00, 0.5474205335300870E+00, 0.3751307094084999E-01, 0.3830193935796279E-01, 0.5324276180991995E+00, 0.5577379417840483E+00, 0.1454944326918194E-01, 0.1220274725600271E-01, 0.6422786106287314E+00, 0.6348181488942451E+00, 0.9587988848101409E-02, 0.2200990500366971E-01, 0.2787543806623621E+00, 0.2797904014149808E+00, 0.7620352256320365E-02, 0.8551968095484232E-02, 0.2407676854354167E+00, 0.2483880376917308E+00, 0.4837392336267432E-28, 0.7747561140265878E-14}, + i0: 1, + n0: 13, + pp: 0, + tau: 0.19361025134591583, + sigma: 0.51861980531617213, + i0Out: 1, + n0Out: 13, + ppOut: 0, + tauOut: 0.19361025134591583, + sigmaOut: 0.51861980531617213, + dminOut: 2.5949209826162500E-002, + dmin1Out: 7.8890170839591350E-002, + dmin2Out: 0.28791033268116917, + dnOut: 2.5949209826162500E-002, + dnm1Out: 7.8890170839591350E-002, + dnm2Out: 0.41777236268627749, + }, + { + z: []float64{0.1962357708185669E+01, 0.1768747456839757E+01, 0.3452895805257589E-14, 0.1811424766142649E-14, 0.9279031656538340E+00, 0.8183881849761209E+00, 0.8409527066820451E-01, 0.9640366690596863E-01, 0.9381695469594078E+00, 0.7024714999296202E+00, 0.5431587122209677E-01, 0.1134045480653624E+00, 0.1466670076091998E+01, 0.1168847392254101E+01, 0.9192115573380727E-02, 0.1048255904531585E-01, 0.1332937092278178E+01, 0.1145899255774637E+01, 0.1705497388769041E-01, 0.2804774784346500E-01, 0.1884487985242738E+01, 0.1667981036717421E+01, 0.5151050664063701E-02, 0.5713728135608638E-02, 0.1850183739337442E+01, 0.1704415955506319E+01, 0.5355619565040129E-01, 0.2003593680404179E-01, 0.6376399585071952E+00, 0.4402495403584025E+00, 0.1625577000116482E-01, 0.2102698332839761E-01, 0.5694667028868834E+00, 0.3923425391534199E+00, 0.3751307094084999E-01, 0.5090703407211448E-01, 0.5324276180991995E+00, 0.3024597759503511E+00, 0.1454944326918194E-01, 0.3089599659653809E-01, 0.6422786106287314E+00, 0.4273603515343789E+00, 0.9587988848101409E-02, 0.6253958476854957E-02, 0.2787543806623621E+00, 0.8651052309591171E-01, 0.7620352256320365E-02, 0.2120822426333837E-01, 0.2407676854354167E+00, 0.2594920982616250E-01, 0.4837392336267432E-28, 0.1811424766142649E-14, 0.5186198053161721E+00}, + i0: 1, + n0: 13, + pp: 1, + tau: 1.8780556192507153E-002, + sigma: 0.71223005666208794, + i0Out: 1, + n0Out: 13, + ppOut: 1, + tauOut: 1.8780556192507153E-002, + sigmaOut: 0.71223005666208794, + dminOut: 8.7653100724300811E-004, + dmin1Out: 6.6256164803006098E-002, + dmin2Out: 0.24571773655185866, + dnOut: 8.7653100724300811E-004, + dnm1Out: 6.6256164803006098E-002, + dnm2Out: 0.36084635920253871, + }, + { + z: []float64{0.1749966900647251E+01, 0.1768747456839757E+01, 0.8471295234418270E-15, 0.1811424766142649E-14, 0.8960112956895816E+00, 0.8183881849761209E+00, 0.7558032897122403E-01, 0.9640366690596863E-01, 0.7215151628312513E+00, 0.7024714999296202E+00, 0.1837142406762631E+00, 0.1134045480653624E+00, 0.9768351544306461E+00, 0.1168847392254101E+01, 0.1229681032071614E-01, 0.1048255904531585E-01, 0.1142869637104878E+01, 0.1145899255774637E+01, 0.4093477506677201E-01, 0.2804774784346500E-01, 0.1613979433593750E+01, 0.1667981036717421E+01, 0.6033886923870183E-02, 0.5713728135608638E-02, 0.1699637449193983E+01, 0.1704415955506319E+01, 0.5189819730562233E-02, 0.2003593680404179E-01, 0.4373061477637308E+00, 0.4402495403584025E+00, 0.1886499897608887E-01, 0.2102698332839761E-01, 0.4056040180569384E+00, 0.3923425391534199E+00, 0.3796148320598534E-01, 0.5090703407211448E-01, 0.2766137331483968E+00, 0.3024597759503511E+00, 0.4773343613933298E-01, 0.3089599659653809E-01, 0.3671003176793937E+00, 0.4273603515343789E+00, 0.1473802100398464E-02, 0.6253958476854957E-02, 0.8746438906634448E-01, 0.8651052309591171E-01, 0.6292122626412339E-02, 0.2120822426333837E-01, 0.8765310072430081E-03, 0.2594920982616250E-01, 0.8471295234418270E-15, 0.1811424766142649E-14}, + i0: 1, + n0: 13, + pp: 0, + tau: 8.1622622999092049E-004, + sigma: 0.73101061285459512, + i0Out: 1, + n0Out: 13, + ppOut: 0, + tauOut: 8.1622622999092049E-004, + sigmaOut: 0.73101061285459512, + dminOut: 6.9556311345050133E-007, + dmin1Out: 8.6231166987816729E-002, + dmin2Out: 0.25114202935985525, + dnOut: 6.9556311345050133E-007, + dnm1Out: 8.6231166987816729E-002, + dnm2Out: 0.30765445605457048, + }, + { + z: []float64{0.1749966900647251E+01, 0.1749150674417261E+01, 0.8471295234418270E-15, 0.4339463906783712E-15, 0.8960112956895816E+00, 0.9707753984308143E+00, 0.7558032897122403E-01, 0.5617401661873561E-01, 0.7215151628312513E+00, 0.8482391606587878E+00, 0.1837142406762631E+00, 0.2115659556707206E+00, 0.9768351544306461E+00, 0.7767497828506508E+00, 0.1229681032071614E-01, 0.1809289356632693E-01, 0.1142869637104878E+01, 0.1164895292375332E+01, 0.4093477506677201E-01, 0.5671572845129930E-01, 0.1613979433593750E+01, 0.1562481365836330E+01, 0.6033886923870183E-02, 0.6563547191183529E-02, 0.1699637449193983E+01, 0.1697447495503371E+01, 0.5189819730562233E-02, 0.1337031089310571E-02, 0.4373061477637308E+00, 0.4540178894205181E+00, 0.1886499897608887E-01, 0.1685334336738995E-01, 0.4056040180569384E+00, 0.4258959316655428E+00, 0.3796148320598534E-01, 0.2465547755855056E-01, 0.2766137331483968E+00, 0.2988754654991882E+00, 0.4773343613933298E-01, 0.5862963539483231E-01, 0.3671003176793937E+00, 0.3091282581549689E+00, 0.1473802100398464E-02, 0.4169958485368410E-03, 0.8746438906634448E-01, 0.9252328961422907E-01, 0.6292122626412339E-02, 0.5960921413863723E-04, 0.8765310072430081E-03, 0.6955631134505013E-06, 0.8471295234418270E-15, 0.4339463906783712E-15, 0.5186198053161721E+00}, + i0: 1, + n0: 13, + pp: 1, + tau: 6.9511331676175615E-007, + sigma: 0.73182683908458601, + i0Out: 1, + n0Out: 13, + ppOut: 1, + tauOut: 6.9511331676175615E-007, + sigmaOut: 0.73182683908458601, + dminOut: 1.2278907249223888E-012, + dmin1Out: 9.2372077429255559E-002, + dmin2Out: 0.25591158693238830, + dnOut: 1.2278907249223888E-012, + dnm1Out: 9.2372077429255559E-002, + dnm2Out: 0.25591158693238830, + }, + { + z: []float64{0.1749149979303945E+01, 0.1749150674417261E+01, 0.2408395422307052E-15, 0.4339463906783712E-15, 0.1026948719936233E+01, 0.9707753984308143E+00, 0.4639861736277134E-01, 0.5617401661873561E-01, 0.1013405803853420E+01, 0.8482391606587878E+00, 0.1621599259654447E+00, 0.2115659556707206E+00, 0.6326820553382161E+00, 0.7767497828506508E+00, 0.3331266686486833E-01, 0.1809289356632693E-01, 0.1188297658848447E+01, 0.1164895292375332E+01, 0.7457497555020480E-01, 0.5671572845129930E-01, 0.1494469242363992E+01, 0.1562481365836330E+01, 0.7455005714048079E-02, 0.6563547191183529E-02, 0.1691328825765317E+01, 0.1697447495503371E+01, 0.3589107121045615E-03, 0.1337031089310571E-02, 0.4705116269624868E+00, 0.4540178894205181E+00, 0.1525524548983380E-01, 0.1685334336738995E-01, 0.4352954686209429E+00, 0.4258959316655428E+00, 0.1692854133253905E-01, 0.2465547755855056E-01, 0.3405758644481647E+00, 0.2988754654991882E+00, 0.5321597610926388E-01, 0.5862963539483231E-01, 0.2563285827809251E+00, 0.3091282581549689E+00, 0.1505170716567330E-03, 0.4169958485368410E-03, 0.9243168664339420E-01, 0.9252328961422907E-01, 0.4485687980202113E-09, 0.5960921413863723E-04, 0.1227890724922389E-11, 0.6955631134505013E-06, 0.2408395422307052E-15, 0.4339463906783712E-15}, + i0: 1, + n0: 13, + pp: 0, + tau: 1.2278907189544363E-012, + sigma: 0.73182753419790281, + i0Out: 1, + n0Out: 13, + ppOut: 0, + tauOut: 1.2278907189544363E-012, + sigmaOut: 0.73182753419790281, + dminOut: 4.9598525010503808E-024, + dmin1Out: 9.2368632133320736E-002, + dmin2Out: 0.22049265431403467, + dnOut: 4.9598525010503808E-024, + dnm1Out: 9.2368632133320736E-002, + dnm2Out: 0.22049265431403467, + }, + { + z: []float64{0.1749149979303945E+01, 0.1749149979302717E+01, 0.2408395422307052E-15, 0.1414000300319855E-15, 0.1026948719936233E+01, 0.1073347337297776E+01, 0.4639861736277134E-01, 0.4380746706334982E-01, 0.1013405803853420E+01, 0.1131758262754287E+01, 0.1621599259654447E+00, 0.9065158049178278E-01, 0.6326820553382161E+00, 0.5753431417100738E+00, 0.3331266686486833E-01, 0.6880305191066147E-01, 0.1188297658848447E+01, 0.1194069582486762E+01, 0.7457497555020480E-01, 0.9333627524262254E-01, 0.1494469242363992E+01, 0.1408587972834190E+01, 0.7455005714048079E-02, 0.8951422490882578E-02, 0.1691328825765317E+01, 0.1682736313985311E+01, 0.3589107121045615E-03, 0.1003553923945662E-03, 0.4705116269624868E+00, 0.4856665170586981E+00, 0.1525524548983380E-01, 0.1367304312976171E-01, 0.4352954686209429E+00, 0.4385509668224923E+00, 0.1692854133253905E-01, 0.1314659648329904E-01, 0.3405758644481647E+00, 0.3806452440729016E+00, 0.5321597610926388E-01, 0.3583592846566260E-01, 0.2563285827809251E+00, 0.2206431713856914E+00, 0.1505170716567330E-03, 0.6305450884558253E-04, 0.9243168664339420E-01, 0.9236863258188953E-01, 0.4485687980202113E-09, 0.5962992535266723E-20, 0.1227890724922389E-11, 0.4959852501050381E-23, 0.2408395422307052E-15, 0.1414000300319855E-15, 0.5186198053161721E+00}, + i0: 1, + n0: 13, + pp: 1, + tau: 4.9598525010503808E-024, + sigma: 0.73182753419913071, + i0Out: 1, + n0Out: 13, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 0.73182753419913071, + dminOut: 4.9598525010503808E-024, + dmin1Out: 9.2339683204333278E-002, + dmin2Out: 0.20112464802017624, + dnOut: 4.9598525010503808E-024, + dnm1Out: 9.2339683204333278E-002, + dnm2Out: 0.20112464802017624, + }, + { + z: []float64{0.1749149979302717E+01, 0.1749149979302717E+01, 0.8676862906242004E-16, 0.1414000300319855E-15, 0.1117154804361126E+01, 0.1073347337297776E+01, 0.4438011869593646E-01, 0.4380746706334982E-01, 0.1178029724550133E+01, 0.1131758262754287E+01, 0.4427372589519608E-01, 0.9065158049178278E-01, 0.5998724677255393E+00, 0.5753431417100738E+00, 0.1369551627869799E+00, 0.6880305191066147E-01, 0.1150450694942405E+01, 0.1194069582486762E+01, 0.1142789997988411E+00, 0.9333627524262254E-01, 0.1303260395526232E+01, 0.1408587972834190E+01, 0.1155784656615063E-01, 0.8951422490882578E-02, 0.1671278822811555E+01, 0.1682736313985311E+01, 0.2916285016424428E-04, 0.1003553923945662E-03, 0.4993103973382956E+00, 0.4856665170586981E+00, 0.1200921574220688E-01, 0.1367304312976171E-01, 0.4396883475635844E+00, 0.4385509668224923E+00, 0.1138121911768345E-01, 0.1314659648329904E-01, 0.4050999534208807E+00, 0.3806452440729016E+00, 0.1951852336551518E-01, 0.3583592846566260E-01, 0.2011877025290218E+00, 0.2206431713856914E+00, 0.2894937755625969E-04, 0.6305450884558253E-04, 0.9233968320433328E-01, 0.9236863258188953E-01, 0.3202909346606844E-42, 0.5962992535266723E-20}, + i0: 1, + n0: 12, + pp: 0, + tau: 9.2159326345418235E-002, + sigma: 0.73182753419913071, + i0Out: 1, + n0Out: 12, + ppOut: 0, + tauOut: 9.2159326345418235E-002, + sigmaOut: 0.73182753419913071, + dminOut: 1.5272797578758102E-004, + dmin1Out: 9.6724015270930774E-002, + dmin2Out: 0.29962742013672317, + dnOut: 1.5272797578758102E-004, + dnm1Out: 9.6724015270930774E-002, + dnm2Out: 0.29962742013672317, + }, + { + z: []float64{0.1749149979302717E+01, 0.1656990652957299E+01, 0.8676862906242004E-16, 0.5850002270797901E-16, 0.1117154804361126E+01, 0.1069375596711644E+01, 0.4438011869593646E-01, 0.4888936980013561E-01, 0.1178029724550133E+01, 0.1081254754299776E+01, 0.4427372589519608E-01, 0.2456274906772994E-01, 0.5998724677255393E+00, 0.6201055550993710E+00, 0.1369551627869799E+00, 0.2540860356894923E+00, 0.1150450694942405E+01, 0.9184843327063353E+00, 0.1142789997988411E+00, 0.1621533314992303E+00, 0.1303260395526232E+01, 0.1060505584247734E+01, 0.1155784656615063E-01, 0.1821431635083262E-01, 0.1671278822811555E+01, 0.1560934342965469E+01, 0.2916285016424428E-04, 0.9328588590960435E-05, 0.4993103973382956E+00, 0.4191509581464933E+00, 0.1200921574220688E-01, 0.1259763844648080E-01, 0.4396883475635844E+00, 0.3463126018893689E+00, 0.1138121911768345E-01, 0.1331320693873929E-01, 0.4050999534208807E+00, 0.3191459435022383E+00, 0.1951852336551518E-01, 0.1230436091267282E-01, 0.2011877025290218E+00, 0.9675296464848704E-01, 0.2894937755625969E-04, 0.2762888312745317E-04, 0.9233968320433328E-01, 0.1527279757875810E-03, 0.3202909346606844E-42, 0.5850002270797901E-16, 0.7318275341991307E+00}, + i0: 1, + n0: 12, + pp: 1, + tau: 1.5267965277267402E-004, + sigma: 0.82398686054454895, + i0Out: 1, + n0Out: 12, + ppOut: 1, + tauOut: 1.5267965277267402E-004, + sigmaOut: 0.82398686054454895, + dminOut: 2.8998364833248812E-009, + dmin1Out: 9.2869952038417761E-002, + dmin2Out: 0.30683160095299705, + dnOut: 2.8998364833248812E-009, + dnm1Out: 9.2869952038417761E-002, + dnm2Out: 0.30683160095299705, + }, + { + z: []float64{0.1656837973304527E+01, 0.1656990652957299E+01, 0.3775776370348287E-16, 0.5850002270797901E-16, 0.1118112286859007E+01, 0.1069375596711644E+01, 0.4727777715386321E-01, 0.4888936980013561E-01, 0.1058387046560870E+01, 0.1081254754299776E+01, 0.1439123541326830E-01, 0.2456274906772994E-01, 0.8596476757228223E+00, 0.6201055550993710E+00, 0.2714763844897646E+00, 0.2540860356894923E+00, 0.8090086000630283E+00, 0.9184843327063353E+00, 0.2125620340079330E+00, 0.1621533314992303E+00, 0.8660051869378607E+00, 0.1060505584247734E+01, 0.3283046378299830E-01, 0.1821431635083262E-01, 0.1527960528118289E+01, 0.1560934342965469E+01, 0.2559023465659061E-05, 0.9328588590960435E-05, 0.4315933579167358E+00, 0.4191509581464933E+00, 0.1010840613748274E-01, 0.1259763844648080E-01, 0.3493647230378528E+00, 0.3463126018893689E+00, 0.1216166289646864E-01, 0.1331320693873929E-01, 0.3191359618656699E+00, 0.3191459435022383E+00, 0.3730332957296599E-02, 0.1230436091267282E-01, 0.9289758092154521E-01, 0.9675296464848704E-01, 0.4542317842367971E-07, 0.2762888312745317E-04, 0.2899836483324881E-08, 0.1527279757875810E-03, 0.3775776370348287E-16, 0.5850002270797901E-16}, + i0: 1, + n0: 12, + pp: 0, + tau: 2.8998350258011044E-009, + sigma: 0.82413954019732161, + i0Out: 1, + n0Out: 12, + ppOut: 0, + tauOut: 2.8998350258011044E-009, + sigmaOut: 0.82413954019732161, + dminOut: 2.2456987483859239E-017, + dmin1Out: 9.1786476970678488E-002, + dmin2Out: 0.30815750788579249, + dnOut: 2.2456987483859239E-017, + dnm1Out: 9.1786476970678488E-002, + dnm2Out: 0.30815750788579249, + }, + { + z: []float64{0.1656837973304527E+01, 0.1656837970404692E+01, 0.3775776370348287E-16, 0.2548071704976161E-16, 0.1118112286859007E+01, 0.1165390061113035E+01, 0.4727777715386321E-01, 0.4293685745187325E-01, 0.1058387046560870E+01, 0.1029841421622430E+01, 0.1439123541326830E-01, 0.1201290976848257E-01, 0.8596476757228223E+00, 0.1119111147544269E+01, 0.2714763844897646E+00, 0.1962510428460807E+00, 0.8090086000630283E+00, 0.8253195883250457E+00, 0.2125620340079330E+00, 0.2230406579474441E+00, 0.8660051869378607E+00, 0.6757949898735797E+00, 0.3283046378299830E-01, 0.7422909836846008E-01, 0.1527960528118289E+01, 0.1453733985873459E+01, 0.2559023465659061E-05, 0.7597383986781573E-06, 0.4315933579167358E+00, 0.4417010014159849E+00, 0.1010840613748274E-01, 0.7995273950601426E-02, 0.3493647230378528E+00, 0.3535311090838850E+00, 0.1216166289646864E-01, 0.1097845108004235E-01, 0.3191359618656699E+00, 0.3118878408430891E+00, 0.3730332957296599E-02, 0.1111101051031713E-02, 0.9289758092154521E-01, 0.9178652239385691E-01, 0.4542317842367971E-07, 0.1435066789177947E-14, 0.2899836483324881E-08, 0.2245698748385924E-16, 0.3775776370348287E-16, 0.2548071704976161E-16, 0.7318275341991307E+00}, + i0: 1, + n0: 12, + pp: 1, + tau: 2.2456987483858885E-017, + sigma: 0.82413954309715665, + i0Out: 1, + n0Out: 12, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 0.82413954309715665, + dminOut: 2.2456987483858888E-017, + dmin1Out: 9.1450429866798411E-002, + dmin2Out: 0.30232944966555197, + dnOut: 2.2456987483858888E-017, + dnm1Out: 9.1450429866798411E-002, + dnm2Out: 0.30232944966555197, + }, + { + z: []float64{0.1656837970404692E+01, 0.1656837970404692E+01, 0.1792267857826344E-16, 0.2548071704976161E-16, 0.1208326918564908E+01, 0.1165390061113035E+01, 0.3659452888027460E-01, 0.4293685745187325E-01, 0.1005259802510638E+01, 0.1029841421622430E+01, 0.1337343958524596E-01, 0.1201290976848257E-01, 0.1301988750805104E+01, 0.1119111147544269E+01, 0.1244018658302015E+00, 0.1962510428460807E+00, 0.9239583804422884E+00, 0.8253195883250457E+00, 0.1631347930486186E+00, 0.2230406579474441E+00, 0.5868892951934211E+00, 0.6757949898735797E+00, 0.1838666404767374E+00, 0.7422909836846008E-01, 0.1269868105135121E+01, 0.1453733985873459E+01, 0.2642614694812039E-06, 0.7597383986781573E-06, 0.4496960111051168E+00, 0.4417010014159849E+00, 0.6285530663790794E-02, 0.7995273950601426E-02, 0.3582240295001366E+00, 0.3535311090838850E+00, 0.9558391177537082E-02, 0.1097845108004235E-01, 0.3034405507165837E+00, 0.3118878408430891E+00, 0.3360925270585024E-03, 0.1111101051031713E-02, 0.9145042986679984E-01, 0.9178652239385691E-01, 0.3524015903480299E-30, 0.1435066789177947E-14}, + i0: 1, + n0: 11, + pp: 0, + tau: 9.1173077708044642E-002, + sigma: 0.82413954309715665, + i0Out: 1, + n0Out: 11, + ppOut: 0, + tauOut: 9.1173077708044642E-002, + sigmaOut: 0.82413954309715665, + dminOut: 1.2510327751137640E-004, + dmin1Out: 0.20154260650453434, + dmin2Out: 0.26087886618071221, + dnOut: 1.2510327751137640E-004, + dnm1Out: 0.20154260650453434, + dnm2Out: 0.26087886618071221, + }, + { + z: []float64{0.1656837970404692E+01, 0.1565664892696647E+01, 0.1792267857826344E-16, 0.1383211380667930E-16, 0.1208326918564908E+01, 0.1153748369737138E+01, 0.3659452888027460E-01, 0.3188477647299814E-01, 0.1005259802510638E+01, 0.8955753879148407E+00, 0.1337343958524596E-01, 0.1944232516271161E-01, 0.1301988750805104E+01, 0.1315775213764550E+01, 0.1244018658302015E+00, 0.8735697805677015E-01, 0.9239583804422884E+00, 0.9085631177260922E+00, 0.1631347930486186E+00, 0.1053774491236745E+00, 0.5868892951934211E+00, 0.5742054088384394E+00, 0.1838666404767374E+00, 0.4066251880351924E+00, 0.1269868105135121E+01, 0.7720701036533529E+00, 0.2642614694812039E-06, 0.1539203864417861E-06, 0.4496960111051168E+00, 0.3648083101404764E+00, 0.6285530663790794E-02, 0.6172085611379779E-02, 0.3582240295001366E+00, 0.2704372573582493E+00, 0.9558391177537082E-02, 0.1072486650400470E-01, 0.3034405507165837E+00, 0.2018786990315928E+00, 0.3360925270585024E-03, 0.1522488812438262E-03, 0.9145042986679984E-01, 0.1251032775113764E-03, 0.3524015903480299E-30, 0.1383211380667930E-16, 0.8241395430971566E+00}, + i0: 1, + n0: 11, + pp: 1, + tau: 1.2498058228587147E-004, + sigma: 0.91531262080520126, + i0Out: 1, + n0Out: 11, + ppOut: 1, + tauOut: 1.2498058228587147E-004, + sigmaOut: 0.91531262080520126, + dminOut: 2.4554386425680716E-008, + dmin1Out: 0.19392428663386141, + dmin2Out: 0.26581143244488259, + dnOut: 2.4554386425680716E-008, + dnm1Out: 0.19392428663386141, + dnm2Out: 0.26581143244488259, + }, + { + z: []float64{0.1565539912114361E+01, 0.1565664892696647E+01, 0.1019378594629470E-16, 0.1383211380667930E-16, 0.1185508165627851E+01, 0.1153748369737138E+01, 0.2408690373149840E-01, 0.3188477647299814E-01, 0.8908058287637680E+00, 0.8955753879148407E+00, 0.2871751477260568E-01, 0.1944232516271161E-01, 0.1374289696466428E+01, 0.1315775213764550E+01, 0.5775298217141787E-01, 0.8735697805677015E-01, 0.9560626040960629E+00, 0.9085631177260922E+00, 0.6328905763825028E-01, 0.1053774491236745E+00, 0.9174165586530958E+00, 0.5742054088384394E+00, 0.3422034931823232E+00, 0.4066251880351924E+00, 0.4297417838091302E+00, 0.7720701036533529E+00, 0.1306631986684747E-06, 0.1539203864417861E-06, 0.3708552845063717E+00, 0.3648083101404764E+00, 0.4500844331080801E-02, 0.6172085611379779E-02, 0.2765362989488873E+00, 0.2704372573582493E+00, 0.7829431815445537E-02, 0.1072486650400470E-01, 0.1940765355151052E+00, 0.2018786990315928E+00, 0.9814083907923291E-07, 0.1522488812438262E-03, 0.2455438642568072E-07, 0.1251032775113764E-03, 0.1019378594629470E-16, 0.1383211380667930E-16}, + i0: 1, + n0: 11, + pp: 0, + tau: 2.4554370888251911E-008, + sigma: 0.91543760138748709, + i0Out: 1, + n0Out: 11, + ppOut: 0, + tauOut: 2.4554370888251911E-008, + sigmaOut: 0.91543760138748709, + dminOut: 2.7649302792337775E-015, + dmin1Out: 0.18866996369915248, + dmin2Out: 0.27322036360404983, + dnOut: 2.7649302792337775E-015, + dnm1Out: 0.18866996369915248, + dnm2Out: 0.27322036360404983, + }, + { + z: []float64{0.1565539912114361E+01, 0.1565539887559990E+01, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.1185508165627851E+01, 0.1209595044804978E+01, 0.2408690373149840E-01, 0.1773879145177052E-01, 0.8908058287637680E+00, 0.9017845275302323E+00, 0.2871751477260568E-01, 0.4376453959373496E-01, 0.1374289696466428E+01, 0.1388278114489740E+01, 0.5775298217141787E-01, 0.3977262621431848E-01, 0.9560626040960629E+00, 0.9795790109656241E+00, 0.6328905763825028E-01, 0.5927283946360358E-01, 0.9174165586530958E+00, 0.1200347187817445E+01, 0.3422034931823232E+00, 0.1225138368952072E+00, 0.4297417838091302E+00, 0.3072280530227507E+00, 0.1306631986684747E-06, 0.1577236754259593E-06, 0.3708552845063717E+00, 0.3753559465594062E+00, 0.4500844331080801E-02, 0.3315910790466669E-02, 0.2765362989488873E+00, 0.2810497954194954E+00, 0.7829431815445537E-02, 0.5406547261581845E-02, 0.1940765355151052E+00, 0.1886700618399915E+00, 0.9814083907923291E-07, 0.1277249852674422E-13, 0.2455438642568072E-07, 0.2764930279233778E-14, 0.1019378594629470E-16, 0.7719264500395369E-17, 0.8241395430971566E+00}, + i0: 1, + n0: 11, + pp: 1, + tau: 2.7649302792335523E-015, + sigma: 0.91543762594185796, + i0Out: 1, + n0Out: 11, + ppOut: 1, + tauOut: 2.7649302792335523E-015, + sigmaOut: 0.91543762594185796, + dminOut: 3.4709879829724519E-029, + dmin1Out: 0.18507826404867261, + dmin2Out: 0.27717487004787600, + dnOut: 3.4709879829724519E-029, + dnm1Out: 0.18507826404867261, + dnm2Out: 0.27858872904535659, + }, + { + z: []float64{0.1565539887559988E+01, 0.1565539887559990E+01, 0.5964194309842799E-17, 0.7719264500395369E-17, 0.1227333836256746E+01, 0.1209595044804978E+01, 0.1303359134714337E-01, 0.1773879145177052E-01, 0.9325154757768211E+00, 0.9017845275302323E+00, 0.6515425651042277E-01, 0.4376453959373496E-01, 0.1362896484193633E+01, 0.1388278114489740E+01, 0.2858649229958118E-01, 0.3977262621431848E-01, 0.1010265358129644E+01, 0.9795790109656241E+00, 0.7042504782685149E-01, 0.5927283946360358E-01, 0.1252435976885798E+01, 0.1200347187817445E+01, 0.3005318297487194E-01, 0.1225138368952072E+00, 0.2771750277715515E+00, 0.3072280530227507E+00, 0.2135925446109612E-06, 0.1577236754259593E-06, 0.3786716437573254E+00, 0.3753559465594062E+00, 0.2461066374135985E-02, 0.3315910790466669E-02, 0.2839952763069384E+00, 0.2810497954194954E+00, 0.3591797791316158E-02, 0.5406547261581845E-02, 0.1850782640486854E+00, 0.1886700618399915E+00, 0.1908115364037247E-27, 0.1277249852674422E-13}, + i0: 1, + n0: 10, + pp: 0, + tau: 9.2539132024336307E-002, + sigma: 0.91543762594186073, + i0Out: 1, + n0Out: 10, + ppOut: 0, + tauOut: 9.2539132024336307E-002, + sigmaOut: 0.91543762594186073, + dminOut: 8.9088074504151571E-002, + dmin1Out: 0.17705256406949207, + dmin2Out: 0.17705256406949207, + dnOut: 8.9088074504151571E-002, + dnm1Out: 0.18903428744201686, + dnm2Out: 0.28613205491191551, + }, + { + z: []float64{0.1565539887559988E+01, 0.1473000755535651E+01, 0.5964194309842799E-17, 0.4969486576955697E-17, 0.1227333836256746E+01, 0.1147828295579553E+01, 0.1303359134714337E-01, 0.1058871408116432E-01, 0.9325154757768211E+00, 0.8945418861817434E+00, 0.6515425651042277E-01, 0.9926701980086396E-01, 0.1362896484193633E+01, 0.1199676824668014E+01, 0.2858649229958118E-01, 0.2407310226126826E-01, 0.1010265358129644E+01, 0.9640781716708908E+00, 0.7042504782685149E-01, 0.9148932748822959E-01, 0.1252435976885798E+01, 0.1098460700348104E+01, 0.3005318297487194E-01, 0.7583331677723075E-02, 0.2771750277715515E+00, 0.1770527776620367E+00, 0.2135925446109612E-06, 0.4568210735249311E-06, 0.3786716437573254E+00, 0.2885931212860515E+00, 0.2461066374135985E-02, 0.2421856840585221E-02, 0.2839952763069384E+00, 0.1926260852333330E+00, 0.3591797791316158E-02, 0.3451057520197492E-02, 0.1850782640486854E+00, 0.8908807450415157E-01, 0.1908115364037247E-27, 0.4969486576955697E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + tau: 7.5387921832037685E-002, + sigma: 1.0079767579661971, + i0Out: 1, + n0Out: 10, + ppOut: 1, + tauOut: 7.5387921832037685E-002, + sigmaOut: 1.0079767579661971, + dminOut: 1.1106216559126303E-002, + dmin1Out: 0.10021441433509834, + dmin2Out: 0.10021441433509834, + dnOut: 1.1106216559126303E-002, + dnm1Out: 0.11507463320059727, + dnm2Out: 0.21320388392650824, + }, + { + z: []float64{0.1397612833703614E+01, 0.1473000755535651E+01, 0.4081328655531061E-17, 0.4969486576955697E-17, 0.1083029087828680E+01, 0.1147828295579553E+01, 0.8745885380967966E-02, 0.1058871408116432E-01, 0.9096750987696016E+00, 0.8945418861817434E+00, 0.1309130515609722E+00, 0.9926701980086396E-01, 0.1017448953536272E+01, 0.1199676824668014E+01, 0.2281033592282574E-01, 0.2407310226126826E-01, 0.9573692414042568E+00, 0.9640781716708908E+00, 0.1049724875218357E+00, 0.9148932748822959E-01, 0.9256836226719531E+00, 0.1098460700348104E+01, 0.1450441494900679E-02, 0.7583331677723075E-02, 0.1002148711561719E+00, 0.1770527776620367E+00, 0.1315527505616969E-05, 0.4568210735249311E-06, 0.2156257407670935E+00, 0.2885931212860515E+00, 0.2163530200698068E-02, 0.2421856840585221E-02, 0.1185256907207948E+00, 0.1926260852333330E+00, 0.2593936112987583E-02, 0.3451057520197492E-02, 0.1110621655912630E-01, 0.8908807450415157E-01, 0.4081328655531061E-17, 0.4969486576955697E-17}, + i0: 1, + n0: 10, + pp: 0, + tau: 9.2006637361187298E-003, + sigma: 1.0833646797982348, + i0Out: 1, + n0Out: 10, + ppOut: 0, + tauOut: 9.2006637361187298E-003, + sigmaOut: 1.0833646797982348, + dminOut: 1.6452860548183366E-003, + dmin1Out: 9.0837695870445614E-002, + dmin2Out: 9.0837695870445614E-002, + dnOut: 1.6452860548183366E-003, + dnm1Out: 0.10809563217808144, + dnm2Out: 0.20642195434625446, + }, + { + z: []float64{0.1397612833703614E+01, 0.1388412169967495E+01, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.1083029087828680E+01, 0.1082574309473529E+01, 0.8745885380967966E-02, 0.7349069784991225E-02, 0.9096750987696016E+00, 0.1024038416809464E+01, 0.1309130515609722E+00, 0.1300706547025319E+00, 0.1017448953536272E+01, 0.9009879710204475E+00, 0.2281033592282574E-01, 0.2423774201322422E-01, 0.9573692414042568E+00, 0.1028903323176749E+01, 0.1049724875218357E+00, 0.9444163542020824E-01, 0.9256836226719531E+00, 0.8234917650105269E+00, 0.1450441494900679E-02, 0.1765115496075164E-03, 0.1002148711561719E+00, 0.9083901139795122E-01, 0.1315527505616969E-05, 0.3122684720284652E-05, 0.2156257407670935E+00, 0.2085854845469525E+00, 0.2163530200698068E-02, 0.1229394806594584E-02, 0.1185256907207948E+00, 0.1106895682910690E+00, 0.2593936112987583E-02, 0.2602667681892373E-03, 0.1110621655912630E-01, 0.1645286054818337E-02, 0.4081328655531061E-17, 0.3183635051997810E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + tau: 1.5594219393746818E-003, + sigma: 1.0925653435343534, + i0Out: 1, + n0Out: 10, + ppOut: 1, + tauOut: 1.5594219393746818E-003, + sigmaOut: 1.0925653435343534, + dminOut: 8.1926049685687600E-005, + dmin1Out: 8.9258234858565516E-002, + dmin2Out: 8.9258234858565516E-002, + dnOut: 8.1926049685687600E-005, + dnm1Out: 0.10847668953277810, + dnm2Out: 0.20701876553386761, + }, + { + z: []float64{0.1386852748028120E+01, 0.1388412169967495E+01, 0.2485138759635906E-17, 0.3183635051997810E-17, 0.1088363957319145E+01, 0.1082574309473529E+01, 0.6914717946174950E-02, 0.7349069784991225E-02, 0.1145634931626446E+01, 0.1024038416809464E+01, 0.1022944500333619E+00, 0.1300706547025319E+00, 0.8213718410609353E+00, 0.9009879710204475E+00, 0.3036175828902931E-01, 0.2423774201322422E-01, 0.1091423778368554E+01, 0.1028903323176749E+01, 0.7125729765473905E-01, 0.9444163542020824E-01, 0.7508515569660207E+00, 0.8234917650105269E+00, 0.2135460001102832E-04, 0.1765115496075164E-03, 0.8926135754328580E-01, 0.9083901139795122E-01, 0.7297073710223142E-05, 0.3122684720284652E-05, 0.2082481603404622E+00, 0.2085854845469525E+00, 0.6534568189162364E-03, 0.1229394806594584E-02, 0.1087369563009673E+00, 0.1106895682910690E+00, 0.3938065757966957E-05, 0.2602667681892373E-03, 0.8192604968568760E-04, 0.1645286054818337E-02, 0.2485138759635906E-17, 0.3183635051997810E-17}, + i0: 1, + n0: 10, + pp: 0, + tau: 8.1416944590412474E-005, + sigma: 1.0941247654737283, + i0Out: 1, + n0Out: 10, + ppOut: 0, + tauOut: 8.1416944590412474E-005, + sigmaOut: 1.0941247654737283, + dminOut: 5.0612658152462498E-007, + dmin1Out: 8.9177229293753768E-002, + dmin2Out: 8.9177229293753768E-002, + dnOut: 5.0612658152462498E-007, + dnm1Out: 0.10831524323681536, + dnm2Out: 0.20814970454128662, + }, + { + z: []float64{0.1386852748028120E+01, 0.1386771331083530E+01, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.1088363957319145E+01, 0.1095197258320730E+01, 0.6914717946174950E-02, 0.7233164949324962E-02, 0.1145634931626446E+01, 0.1240614799765893E+01, 0.1022944500333619E+00, 0.6772592167212049E-01, 0.8213718410609353E+00, 0.7839262607332537E+00, 0.3036175828902931E-01, 0.4227125255215914E-01, 0.1091423778368554E+01, 0.1120328406526543E+01, 0.7125729765473905E-01, 0.4775711530437247E-01, 0.7508515569660207E+00, 0.7030343793170689E+00, 0.2135460001102832E-04, 0.2711304941630149E-05, 0.8926135754328580E-01, 0.8918452636746399E-01, 0.7297073710223142E-05, 0.1703885458517271E-04, 0.2082481603404622E+00, 0.2088031613602029E+00, 0.6534568189162364E-03, 0.3402961195615630E-03, 0.1087369563009673E+00, 0.1083191813025733E+00, 0.3938065757966957E-05, 0.2978513750500819E-08, 0.8192604968568760E-04, 0.5061265815246250E-06, 0.2485138759635906E-17, 0.1950383162890474E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + tau: 5.0604049633765406E-007, + sigma: 1.0942061824183187, + i0Out: 1, + n0Out: 10, + ppOut: 1, + tauOut: 5.0604049633765406E-007, + sigmaOut: 1.0942061824183187, + dminOut: 8.6071246971392626E-011, + dmin1Out: 8.9183660885577137E-002, + dmin2Out: 8.9183660885577137E-002, + dnOut: 8.6071246971392626E-011, + dnm1Out: 0.10814239569959758, + dnm2Out: 0.20876277035564564, + }, + { + z: []float64{0.1386770825043033E+01, 0.1386771331083530E+01, 0.1540308069724697E-17, 0.1950383162890474E-17, 0.1102429917229558E+01, 0.1095197258320730E+01, 0.8139811288713328E-02, 0.7233164949324962E-02, 0.1300200404108803E+01, 0.1240614799765893E+01, 0.4083380405309871E-01, 0.6772592167212049E-01, 0.7853632031918177E+00, 0.7839262607332537E+00, 0.6030036143936175E-01, 0.4227125255215914E-01, 0.1107784654351057E+01, 0.1120328406526543E+01, 0.3030814137396716E-01, 0.4775711530437247E-01, 0.6727284432075471E+00, 0.7030343793170689E+00, 0.3594413905024206E-06, 0.2711304941630149E-05, 0.8920069974016231E-01, 0.8918452636746399E-01, 0.3988496406087022E-04, 0.1703885458517271E-04, 0.2091030664752072E+00, 0.2088031613602029E+00, 0.1762795624794033E-03, 0.3402961195615630E-03, 0.1081423986781113E+00, 0.1083191813025733E+00, 0.1393999949133917E-13, 0.2978513750500819E-08, 0.8607124697139263E-10, 0.5061265815246250E-06, 0.1540308069724697E-17, 0.1950383162890474E-17}, + i0: 1, + n0: 10, + pp: 0, + tau: 8.6071215292546838E-011, + sigma: 1.0942066884588149, + i0Out: 1, + n0Out: 10, + ppOut: 0, + tauOut: 8.6071215292546838E-011, + sigmaOut: 1.0942066884588149, + dminOut: 3.1678834699165494E-017, + dmin1Out: 8.9200650586607991E-002, + dmin2Out: 8.9200650586607991E-002, + dnOut: 3.1678834699165494E-017, + dnm1Out: 0.10805126770967630, + dnm2Out: 0.20900961033533805, + }, + { + z: []float64{0.1386770825043033E+01, 0.1386770824956962E+01, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.1102429917229558E+01, 0.1110569728432201E+01, 0.8139811288713328E-02, 0.9529690622753703E-02, 0.1300200404108803E+01, 0.1331504517453077E+01, 0.4083380405309871E-01, 0.2408506071837550E-01, 0.7853632031918177E+00, 0.8215785038267327E+00, 0.6030036143936175E-01, 0.8130667336500198E-01, 0.1107784654351057E+01, 0.1056786122273951E+01, 0.3030814137396716E-01, 0.1929354325655847E-01, 0.6727284432075471E+00, 0.6534352593063080E+00, 0.3594413905024206E-06, 0.4906748310831983E-07, 0.8920069974016231E-01, 0.8924053555066887E-01, 0.3988496406087022E-04, 0.9345605379795243E-04, 0.2091030664752072E+00, 0.2091858898978174E+00, 0.1762795624794033E-03, 0.9113088236382798E-04, 0.1081423986781113E+00, 0.1080512677096902E+00, 0.1393999949133917E-13, 0.1110429488179469E-22, 0.8607124697139263E-10, 0.3167883469916549E-16, 0.1540308069724697E-17, 0.1224486171222500E-17, 0.9154376259418607E+00}, + i0: 1, + n0: 10, + pp: 1, + tau: 3.1678834698836348E-017, + sigma: 1.0942066885448862, + i0Out: 1, + n0Out: 10, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 1.0942066885448862, + dminOut: 3.1678834699165494E-017, + dmin1Out: 8.9240528714785800E-002, + dmin2Out: 8.9240528714785800E-002, + dnOut: 3.1678834699165494E-017, + dnm1Out: 0.10800416691102718, + dnm2Out: 0.20896705170504334, + }, + { + z: []float64{0.1386770824956962E+01, 0.1386770824956962E+01, 0.9806070694382835E-18, 0.1224486171222500E-17, 0.1120099419054954E+01, 0.1110569728432201E+01, 0.1132830345080667E-01, 0.9529690622753703E-02, 0.1344261274720646E+01, 0.1331504517453077E+01, 0.1472018016266302E-01, 0.2408506071837550E-01, 0.8881649970290716E+00, 0.8215785038267327E+00, 0.9674301998819117E-01, 0.8130667336500198E-01, 0.9793366455423188E+00, 0.1056786122273951E+01, 0.1287308250760436E-01, 0.1929354325655847E-01, 0.6405622258661866E+00, 0.6534352593063080E+00, 0.6835883063177366E-08, 0.4906748310831983E-07, 0.8933398476858376E-01, 0.8924053555066887E-01, 0.2188381927740679E-03, 0.9345605379795243E-04, 0.2090581825874072E+00, 0.2091858898978174E+00, 0.4710079866305792E-04, 0.9113088236382798E-04, 0.1080041669110272E+00, 0.1080512677096902E+00, 0.3257014354834561E-38, 0.1110429488179469E-22}, + i0: 1, + n0: 9, + pp: 0, + tau: 2.2310132178696450E-002, + sigma: 1.0942066885448862, + i0Out: 1, + n0Out: 9, + ppOut: 0, + tauOut: 2.2310132178696450E-002, + sigmaOut: 1.0942066885448862, + dminOut: 6.7023851586769906E-002, + dmin1Out: 6.7023851586769906E-002, + dmin2Out: 6.7023851586769906E-002, + dnOut: 8.5666701693601133E-002, + dnm1Out: 0.18606768031923254, + dnm2Out: 6.7023851586769906E-002, + }, + { + z: []float64{0.1386770824956962E+01, 0.1364460692778266E+01, 0.9806070694382835E-18, 0.8049901434408684E-18, 0.1120099419054954E+01, 0.1109117590327065E+01, 0.1132830345080667E-01, 0.1373001363427395E-01, 0.1344261274720646E+01, 0.1322941309070339E+01, 0.1472018016266302E-01, 0.9882485852396858E-02, 0.8881649970290716E+00, 0.9527153989861693E+00, 0.9674301998819117E-01, 0.9944626147083412E-01, 0.9793366455423188E+00, 0.8704533344003925E+00, 0.1287308250760436E-01, 0.9473236598617136E-02, 0.6405622258661866E+00, 0.6087788639247561E+00, 0.6835883063177366E-08, 0.1003117403762534E-08, 0.8933398476858376E-01, 0.6724268977954398E-01, 0.2188381927740679E-03, 0.6803700894781421E-03, 0.2090581825874072E+00, 0.1861147811178956E+00, 0.4710079866305792E-04, 0.2733303872960605E-04, 0.1080041669110272E+00, 0.8566670169360113E-01, 0.3257014354834561E-38, 0.8049901434408684E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + tau: 6.4730147312741043E-002, + sigma: 1.1165168207235825, + i0Out: 1, + n0Out: 9, + ppOut: 1, + tauOut: 6.4730147312741043E-002, + sigmaOut: 1.1165168207235825, + dminOut: 2.5125423409859404E-003, + dmin1Out: 2.5125423409859404E-003, + dmin2Out: 2.5125423409859404E-003, + dnOut: 2.0907912921905053E-002, + dnm1Out: 8.1725879285544201E-002, + dnm2Out: 2.5125423409859404E-003, + }, + { + z: []float64{0.1299730545465525E+01, 0.1364460692778266E+01, 0.6869337119490330E-18, 0.8049901434408684E-18, 0.1058117456648598E+01, 0.1109117590327065E+01, 0.1716633828952343E-01, 0.1373001363427395E-01, 0.1250927309320471E+01, 0.1322941309070339E+01, 0.7526573591998700E-02, 0.9882485852396858E-02, 0.9799049395522637E+00, 0.9527153989861693E+00, 0.8833849733474472E-01, 0.9944626147083412E-01, 0.7268579263515238E+00, 0.8704533344003925E+00, 0.7934296380510910E-02, 0.9473236598617136E-02, 0.5361144212346215E+00, 0.6087788639247561E+00, 0.1258170079408221E-09, 0.1003117403762534E-08, 0.3192912430464083E-02, 0.6724268977954398E-01, 0.3965875451961033E-01, 0.6803700894781421E-03, 0.8175321232427381E-01, 0.1861147811178956E+00, 0.2864145895504550E-04, 0.2733303872960605E-04, 0.2090791292190505E-01, 0.8566670169360113E-01, 0.6869337119490330E-18, 0.8049901434408684E-18}, + i0: 1, + n0: 9, + pp: 0, + tau: 2.3478378904869292E-003, + sigma: 1.1812469680363236, + i0Out: 1, + n0Out: 9, + ppOut: 0, + tauOut: 2.3478378904869292E-003, + sigmaOut: 1.1812469680363236, + dminOut: -6.4213352031532861E-004, + dmin1Out: -6.4213352031532861E-004, + dmin2Out: 8.4507453921550072E-004, + dnOut: 1.9536180783236046E-002, + dnm1Out: -6.4213352031532861E-004, + dnm2Out: 8.4507453921550072E-004, + }, + { + z: []float64{0.1299730545465525E+01, 0.1297382707575038E+01, 0.6869337119490330E-18, 0.5602483738451179E-18, 0.1058117456648598E+01, 0.1072935957047634E+01, 0.1716633828952343E-01, 0.2001409424891253E-01, 0.1250927309320471E+01, 0.1236091950773070E+01, 0.7526573591998700E-02, 0.5966648869520194E-02, 0.9799049395522637E+00, 0.1059928950127001E+01, 0.8833849733474472E-01, 0.6057909540261972E-01, 0.7268579263515238E+00, 0.6718652894389281E+00, 0.7934296380510910E-02, 0.6331166051893822E-02, 0.5361144212346215E+00, 0.5274354174180577E+00, 0.1258170079408221E-09, 0.7616528495272331E-12, 0.3192912430464083E-02, 0.4050382905882583E-01, 0.3965875451961033E-01, 0.8004750795410222E-01, 0.8175321232427381E-01, -0.6134920613602832E-03, 0.2864145895504550E-04, -0.9761057518179271E-03, 0.2090791292190505E-01, 0.1953618078323605E-01, 0.6869337119490330E-18, 0.5602483738451179E-18}, + i0: 1, + n0: 9, + pp: 0, + tau: 5.8695947262173229E-004, + sigma: 1.1812469680363236, + i0Out: 1, + n0Out: 9, + ppOut: 0, + tauOut: 5.8695947262173229E-004, + sigmaOut: 1.1812469680363236, + dminOut: 2.6059529570832572E-003, + dmin1Out: 2.6059529570832572E-003, + dmin2Out: 2.6059529570832572E-003, + dnOut: 2.0187357299561493E-002, + dnm1Out: 4.4537716273149721E-003, + dnm2Out: 2.6059529570832572E-003, + }, + { + z: []float64{0.1299730545465525E+01, 0.1299143585992903E+01, 0.6869337119490330E-18, 0.5594890049187079E-18, 0.1058117456648598E+01, 0.1074696835465499E+01, 0.1716633828952343E-01, 0.1998130138542489E-01, 0.1250927309320471E+01, 0.1237885622054423E+01, 0.7526573591998700E-02, 0.5958003315736791E-02, 0.9799049395522637E+00, 0.1061698474098650E+01, 0.8833849733474472E-01, 0.6047812873071532E-01, 0.7268579263515238E+00, 0.6737271345286977E+00, 0.7934296380510910E-02, 0.6313669873066943E-02, 0.5361144212346215E+00, 0.5292137920147498E+00, 0.1258170079408221E-09, 0.7590933847144573E-12, 0.3192912430464083E-02, 0.4226470747669359E-01, 0.3965875451961033E-01, 0.7671248122433710E-01, 0.8175321232427381E-01, 0.4482413086270017E-02, 0.2864145895504550E-04, 0.1335961497218277E-03, 0.2090791292190505E-01, 0.2018735729956149E-01, 0.6869337119490330E-18, 0.5594890049187079E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + tau: 4.9324499328963489E-004, + sigma: 1.1818339275089453, + i0Out: 1, + n0Out: 9, + ppOut: 1, + tauOut: 4.9324499328963489E-004, + sigmaOut: 1.1818339275089453, + dminOut: 1.0870277779300500E-003, + dmin1Out: 1.0870277779300500E-003, + dmin2Out: 4.1771462483342674E-002, + dnOut: 1.7484624889890960E-002, + dnm1Out: 1.0870277779300500E-003, + dnm2Out: 4.1771462483342674E-002, + }, + { + z: []float64{0.1298650340999613E+01, 0.1299143585992903E+01, 0.4630045856693428E-18, 0.5594890049187079E-18, 0.1094184891857634E+01, 0.1074696835465499E+01, 0.2260547177996662E-01, 0.1998130138542489E-01, 0.1220744908596903E+01, 0.1237885622054423E+01, 0.5181756634367578E-02, 0.5958003315736791E-02, 0.1116501601201708E+01, 0.1061698474098650E+01, 0.3649413160495897E-01, 0.6047812873071532E-01, 0.6430534278035160E+00, 0.6737271345286977E+00, 0.5195962000339362E-02, 0.6313669873066943E-02, 0.5235245850218799E+00, 0.5292137920147498E+00, 0.6128243213469890E-13, 0.7590933847144573E-12, 0.1184839437076798E+00, 0.4226470747669359E-01, 0.2902140315050332E-02, 0.7671248122433710E-01, 0.1220623927651878E-02, 0.4482413086270017E-02, 0.2209487416380896E-02, 0.1335961497218277E-03, 0.1748462488989096E-01, 0.2018735729956149E-01, 0.4630045856693428E-18, 0.5594890049187079E-18}, + i0: 1, + n0: 9, + pp: 0, + tau: 8.6238530354903250E-004, + sigma: 1.1823271725022351, + i0Out: 1, + n0Out: 9, + ppOut: 0, + tauOut: 8.6238530354903250E-004, + sigmaOut: 1.1823271725022351, + dminOut: 3.2884671240747138E-004, + dmin1Out: 3.2884671240747138E-004, + dmin2Out: 0.11762155840411674, + dnOut: 1.4027859154437344E-003, + dnm1Out: 3.2884671240747138E-004, + dnm2Out: 0.11762155840411674, + }, + { + z: []float64{0.1298650340999613E+01, 0.1297787955696064E+01, 0.4630045856693428E-18, 0.3903662538064461E-18, 0.1094184891857634E+01, 0.1115927978334052E+01, 0.2260547177996662E-01, 0.2472875948770642E-01, 0.1220744908596903E+01, 0.1200335520440015E+01, 0.5181756634367578E-02, 0.4819852017032840E-02, 0.1116501601201708E+01, 0.1147313495486085E+01, 0.3649413160495897E-01, 0.2045445862496274E-01, 0.6430534278035160E+00, 0.6269325458753436E+00, 0.5195962000339362E-02, 0.4338925882718484E-02, 0.5235245850218799E+00, 0.5183232738356738E+00, 0.6128243213469890E-13, 0.1400860159256393E-13, 0.1184839437076798E+00, 0.1205236987191671E+00, 0.2902140315050332E-02, 0.2939191169537379E-04, 0.1220623927651878E-02, 0.2538334128788367E-02, 0.2209487416380896E-02, 0.1521945367089819E-01, 0.1748462488989096E-01, 0.1402785915443734E-02, 0.4630045856693428E-18, 0.3903662538064461E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + tau: 1.8442717265434725E-004, + sigma: 1.1831895578057841, + i0Out: 1, + n0Out: 9, + ppOut: 1, + tauOut: 1.8442717265434725E-004, + sigmaOut: 1.1831895578057841, + dminOut: 3.4295817345512611E-006, + dmin1Out: 2.3532871395603098E-003, + dmin2Out: 0.12033927154650945, + dnOut: 3.4295817345512611E-006, + dnm1Out: 2.3532871395603098E-003, + dnm2Out: 0.12033927154650945, + }, + { + z: []float64{0.1297603528523410E+01, 0.1297787955696064E+01, 0.3357116521683426E-18, 0.3903662538064461E-18, 0.1140472310649104E+01, 0.1115927978334052E+01, 0.2602676813137004E-01, 0.2472875948770642E-01, 0.1178944177153024E+01, 0.1200335520440015E+01, 0.4690536984322235E-02, 0.4819852017032840E-02, 0.1162892989954071E+01, 0.1147313495486085E+01, 0.1102729651913737E-01, 0.2045445862496274E-01, 0.6200597480662705E+00, 0.6269325458753436E+00, 0.3627015421456806E-02, 0.4338925882718484E-02, 0.5145118312415766E+00, 0.5183232738356738E+00, 0.3281495925457712E-14, 0.1400860159256393E-13, 0.1203686634582048E+00, 0.1205236987191671E+00, 0.6198165737098726E-06, 0.2939191169537379E-04, 0.1757274081045850E-01, 0.2538334128788367E-02, 0.1214929161054836E-02, 0.1521945367089819E-01, 0.3429581734551261E-05, 0.1402785915443734E-02, 0.3357116521683426E-18, 0.3903662538064461E-18}, + i0: 1, + n0: 9, + pp: 0, + tau: 3.2077610710809750E-006, + sigma: 1.1833739849784384, + i0Out: 1, + n0Out: 9, + ppOut: 0, + tauOut: 3.2077610710809750E-006, + sigmaOut: 1.1833739849784384, + dminOut: 3.3505760549073344E-012, + dmin1Out: 1.7569442559804263E-002, + dmin2Out: 0.12036545569713296, + dnOut: 3.3505760549073344E-012, + dnm1Out: 1.7569442559804263E-002, + dnm2Out: 0.12036545569713296, + }, + { + z: []float64{0.1297603528523410E+01, 0.1297600320762339E+01, 0.3357116521683426E-18, 0.2950599175525191E-18, 0.1140472310649104E+01, 0.1166495871019403E+01, 0.2602676813137004E-01, 0.2630451380147252E-01, 0.1178944177153024E+01, 0.1157326992574803E+01, 0.4690536984322235E-02, 0.4713095445958055E-02, 0.1162892989954071E+01, 0.1169203983266179E+01, 0.1102729651913737E-01, 0.5848066547299594E-02, 0.6200597480662705E+00, 0.6178354891793567E+00, 0.3627015421456806E-02, 0.3020451850239120E-02, 0.5145118312415766E+00, 0.5114881716302697E+00, 0.3281495925457712E-14, 0.7722354114894537E-15, 0.1203686634582048E+00, 0.1203660755137067E+00, 0.6198165737098726E-06, 0.9048958315991394E-07, 0.1757274081045850E-01, 0.1878437172085910E-01, 0.1214929161054836E-02, 0.2218173128942313E-06, 0.3429581734551261E-05, 0.3350576054907334E-11, 0.3357116521683426E-18, 0.2950599175525191E-18, 0.1094206688544886E+01}, + i0: 1, + n0: 9, + pp: 1, + tau: 3.3505364896797715E-012, + sigma: 1.1833771927395094, + i0Out: 1, + n0Out: 9, + ppOut: 1, + tauOut: 3.3505364896797715E-012, + sigmaOut: 1.1833771927395094, + dminOut: 2.0335799151090034E-023, + dmin1Out: 1.8784357595683275E-002, + dmin2Out: 0.12036607551035594, + dnOut: 2.0335799151090034E-023, + dnm1Out: 1.8784357595683275E-002, + dnm2Out: 0.12036607551035594, + }, + { + z: []float64{0.1297600320758988E+01, 0.1297600320762339E+01, 0.2652482201353177E-18, 0.2950599175525191E-18, 0.1192800384817525E+01, 0.1166495871019403E+01, 0.2552222839336001E-01, 0.2630451380147252E-01, 0.1136517859624050E+01, 0.1157326992574803E+01, 0.4848643531876122E-02, 0.4713095445958055E-02, 0.1170203406278252E+01, 0.1169203983266179E+01, 0.3087619670750762E-02, 0.5848066547299594E-02, 0.6177683213554945E+00, 0.6178354891793567E+00, 0.2500816796475141E-02, 0.3020451850239120E-02, 0.5089873548304448E+00, 0.5114881716302697E+00, 0.1826193617023393E-15, 0.7722354114894537E-15, 0.1203661659999391E+00, 0.1203660755137067E+00, 0.1412182528886294E-07, 0.9048958315991394E-07, 0.1878457941299617E-01, 0.1878437172085910E-01, 0.3956520722700361E-16, 0.2218173128942313E-06, 0.2033579915109003E-22, 0.3350576054907334E-11, 0.2652482201353177E-18, 0.2950599175525191E-18}, + i0: 1, + n0: 9, + pp: 0, + tau: 2.0335799151089990E-023, + sigma: 1.1833771927428600, + i0Out: 1, + n0Out: 9, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 1.1833771927428600, + dminOut: 2.0335799151089993E-023, + dmin1Out: 1.8784577209116738E-002, + dmin2Out: 0.12036616599993906, + dnOut: 2.0335799151089993E-023, + dnm1Out: 1.8784577209116738E-002, + dnm2Out: 0.12036616599993906, + }, + { + z: []float64{0.1297600320758988E+01, 0.1297600320758988E+01, 0.2652482201353177E-18, 0.2438256017573345E-18, 0.1192800384817525E+01, 0.1218322613210885E+01, 0.2552222839336001E-01, 0.2380852827644004E-01, 0.1136517859624050E+01, 0.1117557974879486E+01, 0.4848643531876122E-02, 0.5077051306839188E-02, 0.1170203406278252E+01, 0.1168213974642164E+01, 0.3087619670750762E-02, 0.1632777609571200E-02, 0.6177683213554945E+00, 0.6186363605423986E+00, 0.2500816796475141E-02, 0.2057564358223963E-02, 0.5089873548304448E+00, 0.5069297904722210E+00, 0.1826193617023393E-15, 0.4336141378669131E-16, 0.1203661659999391E+00, 0.1203661801217644E+00, 0.1412182528886294E-07, 0.2203879431304952E-08, 0.1878457941299617E-01, 0.1878457720911678E-01, 0.3956520722700361E-16, 0.4283248425464200E-37, 0.1183377192742860E+01}, + i0: 1, + n0: 8, + pp: 1, + tau: 1.8784576682472597E-002, + sigma: 1.1833771927428600, + i0Out: 1, + n0Out: 8, + ppOut: 1, + tauOut: 1.8784576682472597E-002, + sigmaOut: 1.1833771927428600, + dminOut: 1.1910047947871760E-010, + dmin1Out: 0.10158160343929173, + dmin2Out: 0.48640978493259379, + dnOut: 1.1910047947871760E-010, + dnm1Out: 0.10158160343929173, + dnm2Out: 0.48640978493259379, + }, + { + z: []float64{0.1278815744076516E+01, 0.1297600320758988E+01, 0.2322916695987584E-18, 0.2438256017573345E-18, 0.1223346564804853E+01, 0.1218322613210885E+01, 0.2174969171530204E-01, 0.2380852827644004E-01, 0.1082100757788551E+01, 0.1117557974879486E+01, 0.5481081353963683E-02, 0.5077051306839188E-02, 0.1145581094215299E+01, 0.1168213974642164E+01, 0.8817320773368219E-03, 0.1632777609571200E-02, 0.6010276161408131E+00, 0.6186363605423986E+00, 0.1735428857154564E-02, 0.2057564358223963E-02, 0.4864097849325938E+00, 0.5069297904722210E+00, 0.1073014545319338E-16, 0.4336141378669131E-16, 0.1015816056431712E+00, 0.1203661801217644E+00, 0.4075436992240071E-09, 0.2203879431304952E-08, 0.1191004794787176E-09, 0.1878457720911678E-01, 0.2322916695987584E-18, 0.2438256017573345E-18}, + i0: 1, + n0: 8, + pp: 0, + tau: 1.1910047900088848E-010, + sigma: 1.2021617694253326, + i0Out: 1, + n0Out: 8, + ppOut: 0, + tauOut: 1.1910047900088848E-010, + sigmaOut: 1.2021617694253326, + dminOut: 0.0000000000000000, + dmin1Out: 0.10158160552407068, + dmin2Out: 0.48500827096381138, + dnOut: 0.0000000000000000, + dnm1Out: 0.10158160552407068, + dnm2Out: 0.48500827096381138, + }, + { + z: []float64{0.1278815744076516E+01, 0.1278815743957415E+01, 0.2322916695987584E-18, 0.2222159192042978E-18, 0.1223346564804853E+01, 0.1245096256401054E+01, 0.2174969171530204E-01, 0.1890244048666934E-01, 0.1082100757788551E+01, 0.1068679398536745E+01, 0.5481081353963683E-02, 0.5875497537946494E-02, 0.1145581094215299E+01, 0.1140587328635589E+01, 0.8817320773368219E-03, 0.4646249482278370E-03, 0.6010276161408131E+00, 0.6022984199306394E+00, 0.1735428857154564E-02, 0.1401513849681988E-02, 0.4864097849325938E+00, 0.4850082709638114E+00, 0.1073014545319338E-16, 0.2247354260070927E-17, 0.1015816056431712E+00, 0.1015816059316144E+00, 0.4075436992240071E-09, 0.4778291260603437E-18, 0.1191004794787176E-09, 0.0000000000000000E+00, 0.2322916695987584E-18, 0.2222159192042978E-18, 0.1183377192742860E+01}, + i0: 1, + n0: 8, + pp: 1, + tau: -0.0000000000000000, + sigma: 1.2021617695444331, + i0Out: 1, + n0Out: 8, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 1.2021617695444331, + dminOut: 0.0000000000000000, + dmin1Out: 0.10158160593161437, + dmin2Out: 0.48388184445926297, + dnOut: 0.0000000000000000, + dnm1Out: 0.10158160593161437, + dnm2Out: 0.48388184445926297, + }, + { + z: []float64{0.1278815743957415E+01, 0.1278815743957415E+01, 0.2163565864913247E-18, 0.2222159192042978E-18, 0.1263998696887723E+01, 0.1245096256401054E+01, 0.1598154237018549E-01, 0.1890244048666934E-01, 0.1058573353704506E+01, 0.1068679398536745E+01, 0.6330707284251229E-02, 0.5875497537946494E-02, 0.1134721246299565E+01, 0.1140587328635589E+01, 0.2466181655543824E-03, 0.4646249482278370E-03, 0.6034533156147670E+00, 0.6022984199306394E+00, 0.1126426504548419E-02, 0.1401513849681988E-02, 0.4838818444592630E+00, 0.4850082709638114E+00, 0.4717884282068346E-18, 0.2247354260070927E-17, 0.1015816059316144E+00, 0.1015816059316144E+00, 0.0000000000000000E+00, 0.4778291260603437E-18}, + i0: 1, + n0: 7, + pp: 0, + tau: -0.0000000000000000, + sigma: 1.2021617695444331, + i0Out: 1, + n0Out: 7, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 1.2021617695444331, + dminOut: 0.10158160593161437, + dmin1Out: 0.48298010023310722, + dmin2Out: 0.60332139679048247, + dnOut: 0.10158160593161437, + dnm1Out: 0.48298010023310722, + dnm2Out: 0.60332139679048247, + }, + { + z: []float64{0.1278815743957415E+01, 0.1278815743957415E+01, 0.2163565864913247E-18, 0.2138497627045302E-18, 0.1263998696887723E+01, 0.1279980239257909E+01, 0.1598154237018549E-01, 0.1321710631563048E-01, 0.1058573353704506E+01, 0.1051686954673127E+01, 0.6330707284251229E-02, 0.6830538334266978E-02, 0.1134721246299565E+01, 0.1128137326130852E+01, 0.2466181655543824E-03, 0.1319188242844840E-03, 0.6034533156147670E+00, 0.6044478232950309E+00, 0.1126426504548419E-02, 0.9017442261557238E-03, 0.4838818444592630E+00, 0.4829801002331072E+00, 0.4717884282068346E-18, 0.9922774494036444E-19, 0.1015816059316144E+00, 0.1015816059316144E+00, 0.0000000000000000E+00, 0.2138497627045302E-18, 0.1202161769544433E+01}, + i0: 1, + n0: 7, + pp: 1, + tau: 0.10158160593161437, + sigma: 1.2021617695444331, + i0Out: 1, + n0Out: 7, + ppOut: 1, + tauOut: 0.10158160593161437, + sigmaOut: 1.2021617695444331, + dminOut: 0.0000000000000000, + dmin1Out: 0.38053382595775820, + dmin2Out: 0.50278793042091730, + dnOut: 0.0000000000000000, + dnm1Out: 0.38053382595775820, + dnm2Out: 0.50278793042091730, + }, + { + z: []float64{0.1177234138025801E+01, 0.1278815743957415E+01, 0.2325140442247288E-18, 0.2138497627045302E-18, 0.1191615739641925E+01, 0.1279980239257909E+01, 0.1166505092896250E-01, 0.1321710631563048E-01, 0.9452708361468171E+00, 0.1051686954673127E+01, 0.8151933771558135E-02, 0.6830538334266978E-02, 0.1018535705251965E+01, 0.1128137326130852E+01, 0.7828694249915420E-04, 0.1319188242844840E-03, 0.5036896746470730E+00, 0.6044478232950309E+00, 0.8646683437346259E-03, 0.9017442261557238E-03, 0.3805338259577582E+00, 0.4829801002331072E+00, 0.2648835135390502E-19, 0.9922774494036444E-19, 0.0000000000000000E+00, 0.1015816059316144E+00, 0.2325140442247288E-18, 0.2138497627045302E-18}, + i0: 1, + n0: 7, + pp: 0, + tau: -0.0000000000000000, + sigma: 1.3037433754760475, + i0Out: 1, + n0Out: 7, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 1.3037433754760475, + dminOut: 0.0000000000000000, + dmin1Out: 0.37988164443454930, + dmin2Out: 0.50365062581387521, + dnOut: 0.0000000000000000, + dnm1Out: 0.37988164443454930, + dnm2Out: 0.50365062581387521, + }, + { + z: []float64{0.1177234138025801E+01, 0.1177234138025801E+01, 0.2325140442247288E-18, 0.2353545363971710E-18, 0.1191615739641925E+01, 0.1203280790570888E+01, 0.1166505092896250E-01, 0.9163806595868684E-02, 0.9452708361468171E+00, 0.9442589633225065E+00, 0.8151933771558135E-02, 0.8793176380307672E-02, 0.1018535705251965E+01, 0.1009820815814156E+01, 0.7828694249915420E-04, 0.3904883319791864E-04, 0.5036896746470730E+00, 0.5045152941576099E+00, 0.8646683437346259E-03, 0.6521815232088979E-03, 0.3805338259577582E+00, 0.3798816444345493E+00, 0.2648835135390502E-19, 0.0000000000000000E+00, 0.1303743375476047E+01}, + i0: 1, + n0: 6, + pp: 1, + tau: -0.0000000000000000, + sigma: 1.3037433754760475, + i0Out: 1, + n0Out: 6, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 1.3037433754760475, + dminOut: 0.37939119035907048, + dmin1Out: 0.50449560273072791, + dmin2Out: 0.93712213699945368, + dnOut: 0.37939119035907048, + dnm1Out: 0.50449560273072791, + dnm2Out: 1.0004335774214996, + }, + { + z: []float64{0.1177234138025801E+01, 0.1177234138025801E+01, 0.2405618249359890E-18, 0.2353545363971710E-18, 0.1212444597166756E+01, 0.1203280790570888E+01, 0.7136826323052847E-02, 0.9163806595868684E-02, 0.9459153133797613E+00, 0.9442589633225065E+00, 0.9387238392656353E-02, 0.8793176380307672E-02, 0.1000472626254697E+01, 0.1009820815814156E+01, 0.1969142688202247E-04, 0.3904883319791864E-04, 0.5051477842539368E+00, 0.5045152941576099E+00, 0.4904540754787929E-03, 0.6521815232088979E-03, 0.3793911903590705E+00, 0.3798816444345493E+00, 0.2405618249359890E-18, 0.2353545363971710E-18}, + i0: 1, + n0: 6, + pp: 0, + tau: 0.37791671367087804, + sigma: 1.3037433754760475, + i0Out: 1, + n0Out: 6, + ppOut: 0, + tauOut: 0.37791671367087804, + sigmaOut: 1.3037433754760475, + dminOut: 1.7417124602014944E-005, + dmin1Out: 0.12721465844156904, + dmin2Out: 0.55997778901175921, + dnOut: 1.7417124602014944E-005, + dnm1Out: 0.12721465844156904, + dnm2Out: 0.60606091447901145, + }, + { + z: []float64{0.1177234138025801E+01, 0.7993174243549228E+00, 0.2405618249359890E-18, 0.3648961927279404E-18, 0.1212444597166756E+01, 0.8416647098189309E+00, 0.7136826323052847E-02, 0.8020810697124018E-02, 0.9459153133797613E+00, 0.5693650274044155E+00, 0.9387238392656353E-02, 0.1649499810480807E-01, 0.1000472626254697E+01, 0.6060806059058935E+00, 0.1969142688202247E-04, 0.1641214148963635E-04, 0.5051477842539368E+00, 0.1277051125170478E+00, 0.4904540754787929E-03, 0.1457059563590431E-02, 0.3793911903590705E+00, 0.1741712460201494E-04, 0.2405618249359890E-18, 0.3648961927279404E-18, 0.1303743375476047E+01}, + i0: 1, + n0: 6, + pp: 1, + tau: 1.7220607103034587E-005, + sigma: 1.6816600891469256, + i0Out: 1, + n0Out: 6, + ppOut: 1, + tauOut: 1.7220607103034587E-005, + sigmaOut: 1.6816600891469256, + dminOut: 5.8496704963934779E-012, + dmin1Out: 0.12768433261716639, + dmin2Out: 0.56397303984076830, + dnOut: 5.8496704963934779E-012, + dnm1Out: 0.12768433261716639, + dnm2Out: 0.58884056200405466, + }, + { + z: []float64{0.7993002037478197E+00, 0.7993174243549228E+00, 0.3842364192156412E-18, 0.3648961927279404E-18, 0.8496682999089519E+00, 0.8416647098189309E+00, 0.5374766956544110E-02, 0.8020810697124018E-02, 0.5804680379455763E+00, 0.5693650274044155E+00, 0.1722282329473577E-01, 0.1649499810480807E-01, 0.5888569741455443E+00, 0.6060806059058935E+00, 0.3559292778388127E-05, 0.1641214148963635E-04, 0.1291413921807568E+00, 0.1277051125170478E+00, 0.1965116493098606E-06, 0.1457059563590431E-02, 0.5849670496393478E-11, 0.1741712460201494E-04, 0.3842364192156412E-18, 0.3648961927279404E-18}, + i0: 1, + n0: 6, + pp: 0, + tau: 5.8496615949827599E-012, + sigma: 1.6816773097540285, + i0Out: 1, + n0Out: 6, + ppOut: 0, + tauOut: 5.8496615949827599E-012, + sigmaOut: 1.6816773097540285, + dminOut: 5.2413685591311719E-023, + dmin1Out: 0.12914058828956335, + dmin2Out: 0.57178448001987381, + dnOut: 5.2413685591311719E-023, + dnm1Out: 0.12914058828956335, + dnm2Out: 0.57178448001987381, + }, + { + z: []float64{0.7993002037478197E+00, 0.7993002037419701E+00, 0.3842364192156412E-18, 0.4084491703488284E-18, 0.8496682999089519E+00, 0.8550430668596465E+00, 0.5374766956544110E-02, 0.3648799166500929E-02, 0.5804680379455763E+00, 0.5940420620679615E+00, 0.1722282329473577E-01, 0.1707249411982080E-01, 0.5888569741455443E+00, 0.5717880393126522E+00, 0.3559292778388127E-05, 0.8038853438286423E-06, 0.1291413921807568E+00, 0.1291407848012127E+00, 0.1965116493098606E-06, 0.8901358303923820E-17, 0.5849670496393478E-11, 0.5241368559131172E-22, 0.3842364192156412E-18, 0.4084491703488284E-18, 0.1303743375476047E+01}, + i0: 1, + n0: 6, + pp: 1, + tau: 5.2413685591311714E-023, + sigma: 1.6816773097598783, + i0Out: 1, + n0Out: 6, + ppOut: 1, + tauOut: 0.0000000000000000, + sigmaOut: 1.6816773097598783, + dminOut: 5.2413685591311719E-023, + dmin1Out: 0.12914059800027977, + dmin2Out: 0.55574794205624078, + dnOut: 5.2413685591311719E-023, + dnm1Out: 0.12914059800027977, + dnm2Out: 0.55574794205624078, + }, + { + z: []float64{0.7993002037419701E+00, 0.7993002037419701E+00, 0.4369342452764876E-18, 0.4084491703488284E-18, 0.8586918660261474E+00, 0.8550430668596465E+00, 0.2524235138002424E-02, 0.3648799166500929E-02, 0.6085903210497798E+00, 0.5940420620679615E+00, 0.1604009725641142E-01, 0.1707249411982080E-01, 0.5557487459415846E+00, 0.5717880393126522E+00, 0.1868009328861996E-06, 0.8038853438286423E-06, 0.1291405980002798E+00, 0.1291407848012127E+00, 0.3612752323451872E-38, 0.8901358303923820E-17}, + i0: 1, + n0: 5, + pp: 0, + tau: 0.12914051019182277, + sigma: 1.6816773097598783, + i0Out: 1, + n0Out: 5, + ppOut: 0, + tauOut: 0.12914051019182277, + sigmaOut: 1.6816773097598783, + dminOut: 2.8760335918365243E-008, + dmin1Out: 0.40854091047624980, + dmin2Out: 0.47735135942481804, + dnOut: 2.8760335918365243E-008, + dnm1Out: 0.40854091047624980, + dnm2Out: 0.47735135942481804, + }, + { + z: []float64{0.7993002037419701E+00, 0.6701596935501473E+00, 0.4369342452764876E-18, 0.5598544436768911E-18, 0.8586918660261474E+00, 0.7320755909723271E+00, 0.2524235138002424E-02, 0.2098451433139096E-02, 0.6085903210497798E+00, 0.4933914566812295E+00, 0.1604009725641142E-01, 0.1806732527351204E-01, 0.5557487459415846E+00, 0.4085410972771827E+00, 0.1868009328861996E-06, 0.5904812108429529E-07, 0.1291405980002798E+00, 0.2876033591836524E-07, 0.3612752323451872E-38, 0.5598544436768911E-18, 0.1681677309759878E+01}, + i0: 1, + n0: 5, + pp: 1, + tau: 2.8760330654564486E-008, + sigma: 1.8108178199517009, + i0Out: 1, + n0Out: 5, + ppOut: 1, + tauOut: 2.8760330654564486E-008, + sigmaOut: 1.8108178199517009, + dminOut: 9.5429721930147733E-016, + dmin1Out: 0.39406941605409296, + dmin2Out: 0.49198119275848701, + dnOut: 9.5429721930147733E-016, + dnm1Out: 0.39406941605409296, + dnm2Out: 0.49198119275848701, + }, + { + z: []float64{0.6701596647898166E+00, 0.6701596935501473E+00, 0.6115792910959321E-18, 0.5598544436768911E-18, 0.7341740136451356E+00, 0.7320755909723271E+00, 0.1410235162411720E-02, 0.2098451433139096E-02, 0.5100485180319990E+00, 0.4933914566812295E+00, 0.1447165246275905E-01, 0.1806732527351204E-01, 0.3940694751022140E+00, 0.4085410972771827E+00, 0.4309503539425748E-14, 0.5904812108429529E-07, 0.9542972193014773E-15, 0.2876033591836524E-07, 0.6115792910959321E-18, 0.5598544436768911E-18}, + i0: 1, + n0: 5, + pp: 0, + tau: 9.5429721930146451E-016, + sigma: 1.8108178487120317, + i0Out: 1, + n0Out: 5, + ppOut: 0, + tauOut: 9.5429721930146451E-016, + sigmaOut: 1.8108178487120317, + dminOut: 1.9721522630525295E-030, + dmin1Out: 0.38317668529976806, + dmin2Out: 0.50907067170667131, + dnOut: 1.9721522630525295E-030, + dnm1Out: 0.38317668529976806, + dnm2Out: 0.50907067170667131, + }, + { + z: []float64{0.6701596647898166E+00, 0.6701596647898156E+00, 0.6115792910959321E-18, 0.6699979816704878E-18, 0.7341740136451356E+00, 0.7355842488075462E+00, 0.1410235162411720E-02, 0.9778463253267723E-03, 0.5100485180319990E+00, 0.5235423241694304E+00, 0.1447165246275905E-01, 0.1089278980244500E-01, 0.3940694751022140E+00, 0.3831766852997724E+00, 0.4309503539425748E-14, 0.1073277003016631E-28, 0.1810817848712033E+01}, + i0: 1, + n0: 4, + pp: 1, + tau: 0.31895966905528556, + sigma: 1.8108178487120326, + i0Out: 1, + n0Out: 4, + ppOut: 1, + tauOut: 0.31895966905528556, + sigmaOut: 1.8108178487120326, + dminOut: 4.4735699115826311E-002, + dmin1Out: 0.20335674284478694, + dmin2Out: 0.35119999573453003, + dnOut: 4.4735699115826311E-002, + dnm1Out: 0.20335674284478694, + dnm2Out: 0.41662457975226058, + }, + { + z: []float64{0.3511999957345300E+00, 0.6701596647898156E+00, 0.1403302870260262E-17, 0.6699979816704878E-18, 0.4176024260775874E+00, 0.7355842488075462E+00, 0.1225912269357841E-02, 0.9778463253267723E-03, 0.2142495326472319E+00, 0.5235423241694304E+00, 0.1948131712866055E-01, 0.1089278980244500E-01, 0.4473569911582631E-01, 0.3831766852997724E+00, 0.1403302870260262E-17, 0.6699979816704878E-18}, + i0: 1, + n0: 4, + pp: 0, + tau: 3.9897804510299034E-002, + sigma: 2.1297775177673182, + i0Out: 1, + n0Out: 4, + ppOut: 0, + tauOut: 3.9897804510299034E-002, + sigmaOut: 2.1297775177673182, + dminOut: 3.2556800493375310E-004, + dmin1Out: 0.17365859019389857, + dmin2Out: 0.31130219122423097, + dnOut: 3.2556800493375310E-004, + dnm1Out: 0.17365859019389857, + dnm2Out: 0.37770462156728835, + }, + { + z: []float64{0.3511999957345300E+00, 0.3113021912242310E+00, 0.1403302870260262E-17, 0.1882488140663987E-17, 0.4176024260775874E+00, 0.3789305338366462E+00, 0.1225912269357841E-02, 0.6931379430343076E-03, 0.2142495326472319E+00, 0.1931399073225591E+00, 0.1948131712866055E-01, 0.4512326600593524E-02, 0.4473569911582631E-01, 0.3255680049337531E-03, 0.1403302870260262E-17, 0.1882488140663987E-17, 0.1810817848712033E+01}, + i0: 1, + n0: 4, + pp: 1, + tau: 3.1797943619548145E-004, + sigma: 2.1696753222776173, + i0Out: 1, + n0Out: 4, + ppOut: 1, + tauOut: 3.1797943619548145E-004, + sigmaOut: 2.1696753222776173, + dminOut: 1.3065740500455263E-007, + dmin1Out: 0.19246898670783216, + dmin2Out: 0.31098421178803548, + dnOut: 1.3065740500455263E-007, + dnm1Out: 0.19246898670783216, + dnm2Out: 0.37861255440045072, + }, + { + z: []float64{0.3109842117880355E+00, 0.3113021912242310E+00, 0.2293789231233262E-17, 0.1882488140663987E-17, 0.3793056923434850E+00, 0.3789305338366462E+00, 0.3529411785314453E-03, 0.6931379430343076E-03, 0.1969813133084257E+00, 0.1931399073225591E+00, 0.7457911333267062E-05, 0.4512326600593524E-02, 0.1306574050045526E-06, 0.3255680049337531E-03, 0.2293789231233262E-17, 0.1882488140663987E-17}, + i0: 1, + n0: 4, + pp: 0, + tau: 1.3065240973281283E-007, + sigma: 2.1699933017138124, + i0Out: 1, + n0Out: 4, + ppOut: 0, + tauOut: 1.3065240973281283E-007, + sigmaOut: 2.1699933017138124, + dminOut: 4.4031878668096113E-014, + dmin1Out: 0.19679806330970273, + dmin2Out: 0.31098408113562576, + dnOut: 4.4031878668096113E-014, + dnm1Out: 0.19679806330970273, + dnm2Out: 0.37930556169107532, + }, + { + z: []float64{0.3109842117880355E+00, 0.3109840811356258E+00, 0.2293789231233262E-17, 0.2797722987188916E-17, 0.3793056923434850E+00, 0.3796585028696068E+00, 0.3529411785314453E-03, 0.1831193463132450E-03, 0.1969813133084257E+00, 0.1968055212210360E+00, 0.7457911333267062E-05, 0.4951239861123181E-11, 0.1306574050045526E-06, 0.4403187866809611E-13, 0.2293789231233262E-17, 0.2797722987188916E-17, 0.1810817848712033E+01}, + i0: 1, + n0: 4, + pp: 1, + tau: 4.4031878666982759E-014, + sigma: 2.1699934323662222, + i0Out: 1, + n0Out: 4, + ppOut: 1, + tauOut: 4.4031878666982759E-014, + sigmaOut: 2.1699934323662222, + dminOut: 5.0676424551397798E-027, + dmin1Out: 0.19671064247077341, + dmin2Out: 0.31098408113558174, + dnOut: 5.0676424551397798E-027, + dnm1Out: 0.19671064247077341, + dnm2Out: 0.37965850286956282, + }, + { + z: []float64{0.3109840811355817E+00, 0.3109840811356258E+00, 0.3415542419024794E-17, 0.2797722987188916E-17, 0.3798416222158761E+00, 0.3796585028696068E+00, 0.9487875021856221E-04, 0.1831193463132450E-03, 0.1967106424757246E+00, 0.1968055212210360E+00, 0.1108289770587888E-23, 0.4951239861123181E-11, 0.5067642455139780E-26, 0.4403187866809611E-13, 0.3415542419024794E-17, 0.2797722987188916E-17}, + i0: 1, + n0: 4, + pp: 0, + tau: 5.0676424551397798E-027, + sigma: 2.1699934323662662, + i0Out: 1, + n0Out: 4, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 2.1699934323662662, + dminOut: 5.0676424551397798E-027, + dmin1Out: 0.19666151937261311, + dmin2Out: 0.31098408113558174, + dnOut: 5.0676424551397798E-027, + dnm1Out: 0.19666151937261311, + dnm2Out: 0.37984162221587608, + }, + { + z: []float64{0.3109840811355817E+00, 0.3109840811355817E+00, 0.3415542419024794E-17, 0.4171805735046273E-17, 0.3798416222158761E+00, 0.3799365009660947E+00, 0.9487875021856221E-04, 0.4912310311151891E-04, 0.1967106424757246E+00, 0.1966615193726131E+00, 0.1108289770587888E-23, 0.2855879641297252E-49, 0.2169993432366266E+01}, + i0: 1, + n0: 3, + pp: 1, + tau: 9.8330759686306557E-002, + sigma: 2.1699934323662662, + i0Out: 1, + n0Out: 3, + ppOut: 1, + tauOut: 9.8330759686306557E-002, + sigmaOut: 2.1699934323662662, + dminOut: 9.8296460175394978E-002, + dmin1Out: 0.21265332144927518, + dmin2Out: 0.21265332144927518, + dnOut: 9.8296460175394978E-002, + dnm1Out: 0.28160574127978810, + dnm2Out: 0.21265332144927518, + }, + { + z: []float64{0.2126533214492752E+00, 0.3109840811355817E+00, 0.7453545812882342E-17, 0.4171805735046273E-17, 0.2816548643828996E+00, 0.3799365009660947E+00, 0.3429951091160839E-04, 0.4912310311151891E-04, 0.9829646017539498E-01, 0.1966615193726131E+00, 0.3799365009660947E+00, 0.2855879641297252E-49}, + i0: 1, + n0: 3, + pp: 0, + tau: 9.7172513485343004E-002, + sigma: 2.2683241920525727, + i0Out: 1, + n0Out: 3, + ppOut: 0, + tauOut: 9.7172513485343004E-002, + sigmaOut: 2.2683241920525727, + dminOut: 1.1056745151512559E-003, + dmin1Out: 0.11548080796393217, + dmin2Out: 0.11548080796393217, + dnOut: 1.1056745151512559E-003, + dnm1Out: 0.18448235089755655, + dnm2Out: 0.11548080796393217, + }, + { + z: []float64{0.2126533214492752E+00, 0.1154808079639322E+00, 0.7453545812882342E-17, 0.1817901582187390E-16, 0.2816548643828996E+00, 0.1845166504084682E+00, 0.3429951091160839E-04, 0.1827217490071947E-04, 0.9829646017539498E-01, 0.1105674515151256E-02, 0.3799365009660947E+00, 0.2816548643828996E+00, 0.2169993432366266E+01}, + i0: 1, + n0: 3, + pp: 1, + tau: 1.0942861809085330E-003, + sigma: 2.3654967055379159, + i0Out: 1, + n0Out: 3, + ppOut: 1, + tauOut: 1.0942861809085330E-003, + sigmaOut: 2.3654967055379159, + dminOut: 1.1278200095129901E-005, + dmin1Out: 0.11438652178302365, + dmin2Out: 0.11438652178302365, + dnOut: 1.1278200095129901E-005, + dnm1Out: 0.18342236422755959, + dnm2Out: 0.11438652178302365, + }, + { + z: []float64{0.1143865217830237E+00, 0.1154808079639322E+00, 0.2932453102768040E-16, 0.1817901582187390E-16, 0.1834406364024603E+00, 0.1845166504084682E+00, 0.1101341475930520E-06, 0.1827217490071947E-04, 0.1127820009512990E-04, 0.1105674515151256E-02, 0.1845166504084682E+00, 0.2816548643828996E+00}, + i0: 1, + n0: 3, + pp: 0, + tau: 1.1269238360546607E-005, + sigma: 2.3665909917188244, + i0Out: 1, + n0Out: 3, + ppOut: 0, + tauOut: 1.1269238360546607E-005, + sigmaOut: 2.3665909917188244, + dminOut: 8.9549629620034135E-009, + dmin1Out: 0.11437525254466312, + dmin2Out: 0.11437525254466312, + dnOut: 8.9549629620034135E-009, + dnm1Out: 0.18342936716409974, + dnm2Out: 0.11437525254466312, + }, + { + z: []float64{0.1143865217830237E+00, 0.1143752525446631E+00, 0.2932453102768040E-16, 0.4703212027287794E-16, 0.1834406364024603E+00, 0.1834294772982473E+00, 0.1101341475930520E-06, 0.6771621290952006E-11, 0.1127820009512990E-04, 0.8954962962003413E-08, 0.1845166504084682E+00, 0.1834406364024603E+00, 0.2169993432366266E+01}, + i0: 1, + n0: 3, + pp: 1, + tau: 8.9549072084035346E-009, + sigma: 2.3666022609571851, + i0Out: 1, + n0Out: 3, + ppOut: 1, + tauOut: 8.9549072084035346E-009, + sigmaOut: 2.3666022609571851, + dminOut: 5.5753269291151117E-014, + dmin1Out: 0.11437524358975594, + dmin2Out: 0.11437524358975594, + dnOut: 5.5753269291151117E-014, + dnm1Out: 0.18342946834334006, + dnm2Out: 0.11437524358975594, + }, + { + z: []float64{0.1143752435897560E+00, 0.1143752525446631E+00, 0.7542783706608855E-16, 0.4703212027287794E-16, 0.1834294683501117E+00, 0.1834294772982473E+00, 0.3305882004599510E-18, 0.6771621290952006E-11, 0.5575326929115112E-13, 0.8954962962003413E-08, 0.1834294772982473E+00, 0.1834406364024603E+00}, + i0: 1, + n0: 3, + pp: 0, + tau: 5.5753269214454873E-014, + sigma: 2.3666022699120921, + i0Out: 1, + n0Out: 3, + ppOut: 0, + tauOut: 5.5753269214454873E-014, + sigmaOut: 2.3666022699120921, + dminOut: 7.6696244203643861E-023, + dmin1Out: 0.11437524358970023, + dmin2Out: 0.11437524358970023, + dnOut: 7.6696244203643861E-023, + dnm1Out: 0.18342946835005580, + dnm2Out: 0.11437524358970023, + }, + { + z: []float64{0.1648283185136998E+01, 0.1396221235720571E+01, 0.1712714336271993E+00, 0.2520619494164272E+00, 0.1510753432847732E+01, 0.1119977945086946E+01, 0.3792800633372563E+00, 0.5620469213879850E+00, 0.1328441621586708E+01, 0.1019485448443405E+01, 0.1388998759717073E+00, 0.6882362364805590E+00, 0.4466938077796418E+00, 0.2681061628164644E+00, 0.7093206047768255E+00, 0.3174875209348847E+00, 0.6843112870203156E+00, 0.9979892152967577E+00, 0.6490582981441884E+00, 0.3956426765003833E+00, 0.5085572738629487E+00, 0.1122623886995757E+01, 0.9750235054014829E-02, 0.3499168501137979E-01, 0.1364886053450573E+00, 0.1417066070690837E+00, 0.2301225778544498E-01, 0.4532233329988395E-02, 0.1646009972289452E+01, 0.6930161671496210E+00, 0.2362515608142310E+00, 0.9760060629252760E+00, 0.5818602562677768E+00, 0.3984323866837953E+00, 0.1797665269485310E-01, 0.4196794303982125E+00, 0.5600419521166516E+00, 0.2492354636952108E-01, 0.2195137569256029E+00, 0.5530950584419837E+00, 0.4184071984843414E+00, 0.2222708575473020E+00, 0.2727864547293006E+00, 0.4156500978626423E+00, 0.6774373914466536E-01, 0.2745959086613283E+00, 0.1050967099374242E+00, 0.6593428521263771E-01, 0.2040338718098096E+00, 0.1079809097801335E+00, 0.1271971985482246E+00, 0.2011496719671002E+00, 0.4444741998443960E-01, 0.1290210252363728E+00, 0.5776327498150620E+00, 0.4262359329629137E-01, 0.3402556968467140E+00, 0.6023491555328507E+00, 0.1086565805630269E+00, 0.3155392911289253E+00, 0.9382999256694983E+00, 0.1171677238805356E+00, 0.7901625299559836E+00, 0.9297887823519896E+00, 0.6095853796269167E+00, 0.7973955560628040E+00, 0.8018125008387630E+00, 0.6023523535200964E+00, 0.2443177602187348E-01, 0.8114406374558937E+00, 0.2277830378453201E+00, 0.1480363940474286E-01, 0.6969081780841352E+00, 0.3759308106650992E+00, 0.8012406122589412E-01, 0.5487604052643561E+00, 0.9781022865072954E-01, 0.1017549972519246E+00, 0.2961248981181939E-03, 0.7617929262469909E-01, 0.8408398800007548E-04, 0.3802088861182694E-03, 0.0000000000000000E+00, 0.0000000000000000E+00}, + i0: 1, + n0: 21, + pp: 0, + tau: 0.0000000000000000, + sigma: 0.0000000000000000, + i0Out: 1, + n0Out: 21, + ppOut: 0, + tauOut: 0.0000000000000000, + sigmaOut: 0.0000000000000000, + dminOut: 7.8766827084626452E-005, + dmin1Out: 1.2363512593342330E-003, + dmin2Out: 1.2363512593342330E-003, + dnOut: 7.8766827084626452E-005, + dnm1Out: 4.3867054272813191E-003, + dnm2Out: 3.7622286348031123E-003, + }, + } { + // TODO(btracey): Check other outputs + i0 := test.i0 - 1 + n0 := test.n0 - 1 + z := make([]float64, len(test.z)) + copy(z, test.z) + + i0Out, n0Out, ppOut, tauOut, sigmaOut, dminOut, dmin1Out, dmin2Out, dnOut, dnm1Out, dnm2Out := impl.Dlasq5(i0, n0, z, test.pp, test.tau, test.sigma) + + if i0Out != test.i0Out-1 { + t.Errorf("Wrong i0. Want %v, got %v", test.n0Out, n0Out) + } + if n0Out != test.n0Out-1 { + t.Errorf("Wrong n0. Want %v, got %v", test.n0Out, n0Out) + } + if ppOut != test.ppOut { + t.Errorf("Wrong pp. Want %v, got %v", test.ppOut, ppOut) + } + if !floats.EqualWithinAbsOrRel(tauOut, test.tauOut, dTol, dTol) { + t.Errorf("Wrong tau. Want %v, got %v", test.tauOut, tauOut) + } + if !floats.EqualWithinAbsOrRel(sigmaOut, test.sigmaOut, dTol, dTol) { + t.Errorf("Wrong tau. Want %v, got %v", test.sigmaOut, sigmaOut) + } + + if !floats.EqualWithinAbsOrRel(dminOut, test.dminOut, dTol, dTol) { + t.Errorf("Wrong dmin. Want %v, got %v", test.dminOut, dminOut) + } + if !floats.EqualWithinAbsOrRel(dmin1Out, test.dmin1Out, dTol, dTol) { + t.Errorf("Wrong dmin1. Want %v, got %v", test.dmin1Out, dmin1Out) + } + if !floats.EqualWithinAbsOrRel(dmin2Out, test.dmin2Out, dTol, dTol) { + t.Errorf("Wrong dmin2. Want %v, got %v", test.dmin2Out, dmin2Out) + } + if !floats.EqualWithinAbsOrRel(dnOut, test.dnOut, dTol, dTol) { + t.Errorf("Wrong dn. Want %v, got %v", test.dnOut, dnOut) + } + if !floats.EqualWithinAbsOrRel(dnm1Out, test.dnm1Out, dTol, dTol) { + t.Errorf("Wrong dnm1. Want %v, got %v", test.dnm1Out, dnm1Out) + } + if !floats.EqualWithinAbsOrRel(dnm2Out, test.dnm2Out, dTol, dTol) { + t.Errorf("Wrong dnm2. Want %v, got %v", test.dnm2Out, dnm2Out) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasr.go new file mode 100644 index 00000000..87a26059 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasr.go @@ -0,0 +1,148 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dlasrer interface { + Dlasr(side blas.Side, pivot lapack.Pivot, direct lapack.Direct, m, n int, c, s, a []float64, lda int) +} + +func DlasrTest(t *testing.T, impl Dlasrer) { + rnd := rand.New(rand.NewSource(1)) + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, pivot := range []lapack.Pivot{lapack.Variable, lapack.Top, lapack.Bottom} { + for _, direct := range []lapack.Direct{lapack.Forward, lapack.Backward} { + for _, test := range []struct { + m, n, lda int + }{ + {5, 5, 0}, + {5, 10, 0}, + {10, 5, 0}, + + {5, 5, 20}, + {5, 10, 20}, + {10, 5, 20}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + var s, c []float64 + if side == blas.Left { + s = make([]float64, m-1) + c = make([]float64, m-1) + } else { + s = make([]float64, n-1) + c = make([]float64, n-1) + } + for k := range s { + theta := rnd.Float64() * 2 * math.Pi + s[k] = math.Sin(theta) + c[k] = math.Cos(theta) + } + aCopy := make([]float64, len(a)) + copy(a, aCopy) + impl.Dlasr(side, pivot, direct, m, n, c, s, a, lda) + + pSize := m + if side == blas.Right { + pSize = n + } + p := blas64.General{ + Rows: pSize, + Cols: pSize, + Stride: pSize, + Data: make([]float64, pSize*pSize), + } + pk := blas64.General{ + Rows: pSize, + Cols: pSize, + Stride: pSize, + Data: make([]float64, pSize*pSize), + } + ptmp := blas64.General{ + Rows: pSize, + Cols: pSize, + Stride: pSize, + Data: make([]float64, pSize*pSize), + } + for i := 0; i < pSize; i++ { + p.Data[i*p.Stride+i] = 1 + ptmp.Data[i*p.Stride+i] = 1 + } + // Compare to direct computation. + for k := range s { + for i := range p.Data { + pk.Data[i] = 0 + } + for i := 0; i < pSize; i++ { + pk.Data[i*p.Stride+i] = 1 + } + if pivot == lapack.Variable { + pk.Data[k*p.Stride+k] = c[k] + pk.Data[k*p.Stride+k+1] = s[k] + pk.Data[(k+1)*p.Stride+k] = -s[k] + pk.Data[(k+1)*p.Stride+k+1] = c[k] + } else if pivot == lapack.Top { + pk.Data[0] = c[k] + pk.Data[k+1] = s[k] + pk.Data[(k+1)*p.Stride] = -s[k] + pk.Data[(k+1)*p.Stride+k+1] = c[k] + } else { + pk.Data[(pSize-1-k)*p.Stride+pSize-k-1] = c[k] + pk.Data[(pSize-1-k)*p.Stride+pSize-1] = s[k] + pk.Data[(pSize-1)*p.Stride+pSize-1-k] = -s[k] + pk.Data[(pSize-1)*p.Stride+pSize-1] = c[k] + } + if direct == lapack.Forward { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, pk, ptmp, 0, p) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, ptmp, pk, 0, p) + } + copy(ptmp.Data, p.Data) + } + + aMat := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + copy(a, aCopy) + newA := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, m*lda), + } + if side == blas.Left { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, p, aMat, 0, newA) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aMat, p, 0, newA) + } + if !floats.EqualApprox(newA.Data, a, 1e-12) { + t.Errorf("A update mismatch") + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasrt.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasrt.go new file mode 100644 index 00000000..80b1404b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasrt.go @@ -0,0 +1,80 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dlasrter interface { + Dlasrt(s lapack.Sort, n int, d []float64) +} + +func DlasrtTest(t *testing.T, impl Dlasrter) { + for ti, test := range []struct { + data []float64 + wantInc []float64 + wantDec []float64 + }{ + { + data: nil, + wantInc: nil, + wantDec: nil, + }, + { + data: []float64{}, + wantInc: []float64{}, + wantDec: []float64{}, + }, + { + data: []float64{1}, + wantInc: []float64{1}, + wantDec: []float64{1}, + }, + { + data: []float64{1, 2}, + wantInc: []float64{1, 2}, + wantDec: []float64{2, 1}, + }, + { + data: []float64{1, 2, -3}, + wantInc: []float64{-3, 1, 2}, + wantDec: []float64{2, 1, -3}, + }, + { + data: []float64{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}, + wantInc: []float64{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}, + wantDec: []float64{5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5}, + }, + { + data: []float64{5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5}, + wantInc: []float64{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}, + wantDec: []float64{5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5}, + }, + { + data: []float64{-2, 4, -1, 2, -4, 0, 3, 5, -5, 1, -3}, + wantInc: []float64{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5}, + wantDec: []float64{5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5}, + }, + } { + n := len(test.data) + ds := make([]float64, n) + + copy(ds, test.data) + impl.Dlasrt(lapack.SortIncreasing, n, ds) + if !floats.Equal(ds, test.wantInc) { + t.Errorf("Case #%v: unexpected result of SortIncreasing", ti) + } + + copy(ds, test.data) + impl.Dlasrt(lapack.SortDecreasing, n, ds) + if !floats.Equal(ds, test.wantDec) { + t.Errorf("Case #%v: unexpected result of SortIncreasing", ti) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasv2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasv2.go new file mode 100644 index 00000000..85184e62 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasv2.go @@ -0,0 +1,48 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dlasv2er interface { + Dlasv2(f, g, h float64) (ssmin, ssmax, snr, csr, snl, csl float64) +} + +func Dlasv2Test(t *testing.T, impl Dlasv2er) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < 100; i++ { + f := rnd.NormFloat64() + g := rnd.NormFloat64() + h := rnd.NormFloat64() + + ssmin, ssmax, snr, csr, snl, csl := impl.Dlasv2(f, g, h) + + // tmp = + // [ csl snl] [f g] + // [-snl csl] [0 h] + tmp11 := csl * f + tmp12 := csl*g + snl*h + tmp21 := -snl * f + tmp22 := -snl*g + csl*h + // lhs = + // [tmp11 tmp12] [csr -snr] + // [tmp21 tmp22] [snr csr] + ans11 := tmp11*csr + tmp12*snr + ans12 := tmp11*-snr + tmp12*csr + ans21 := tmp21*csr + tmp22*snr + ans22 := tmp21*-snr + tmp22*csr + + lhs := []float64{ans11, ans12, ans21, ans22} + rhs := []float64{ssmax, 0, 0, ssmin} + if !floats.EqualApprox(rhs, lhs, 1e-12) { + t.Errorf("SVD mismatch. f = %v, g = %v, h = %v.\nLHS: %v\nRHS: %v", f, g, h, lhs, rhs) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaswp.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaswp.go new file mode 100644 index 00000000..9d8e08d7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlaswp.go @@ -0,0 +1,130 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlaswper interface { + Dlaswp(n int, a []float64, lda, k1, k2 int, ipiv []int, incX int) +} + +func DlaswpTest(t *testing.T, impl Dlaswper) { + for ti, test := range []struct { + k1, k2 int + ipiv []int + incX int + + want blas64.General + }{ + { + k1: 0, + k2: 2, + ipiv: []int{0, 1, 2}, + incX: 1, + want: blas64.General{ + Rows: 4, + Cols: 3, + Stride: 3, + Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + }, + }, + }, + { + k1: 0, + k2: 2, + ipiv: []int{0, 1, 2}, + incX: -1, + want: blas64.General{ + Rows: 4, + Cols: 3, + Stride: 3, + Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + }, + }, + }, + { + k1: 0, + k2: 2, + ipiv: []int{1, 2, 3}, + incX: 1, + want: blas64.General{ + Rows: 5, + Cols: 3, + Stride: 3, + Data: []float64{ + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + 1, 2, 3, + 13, 14, 15, + }, + }, + }, + { + k1: 0, + k2: 2, + ipiv: []int{1, 2, 3}, + incX: -1, + want: blas64.General{ + Rows: 5, + Cols: 3, + Stride: 3, + Data: []float64{ + 10, 11, 12, + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 13, 14, 15, + }, + }, + }, + } { + m := test.want.Rows + n := test.want.Cols + k1 := test.k1 + k2 := test.k2 + if len(test.ipiv) != k2+1 { + panic("bad length of ipiv") + } + incX := test.incX + for _, extra := range []int{0, 11} { + a := zeros(m, n, n+extra) + c := 1 + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Data[i*a.Stride+j] = float64(c) + c++ + } + } + + ipiv := make([]int, len(test.ipiv)) + copy(ipiv, test.ipiv) + + impl.Dlaswp(n, a.Data, a.Stride, k1, k2, ipiv, incX) + + prefix := fmt.Sprintf("Case %v (m=%v,n=%v,k1=%v,k2=%v,extra=%v)", ti, m, n, k1, k2, extra) + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A", prefix) + } + + if !equalApproxGeneral(a, test.want, 0) { + t.Errorf("%v: unexpected A\n%v\n%v", prefix, a, test.want) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasy2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasy2.go new file mode 100644 index 00000000..7ed5ed8c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlasy2.go @@ -0,0 +1,104 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlasy2er interface { + Dlasy2(tranl, tranr bool, isgn, n1, n2 int, tl []float64, ldtl int, tr []float64, ldtr int, b []float64, ldb int, x []float64, ldx int) (scale, xnorm float64, ok bool) +} + +func Dlasy2Test(t *testing.T, impl Dlasy2er) { + rnd := rand.New(rand.NewSource(1)) + for _, tranl := range []bool{true, false} { + for _, tranr := range []bool{true, false} { + for _, isgn := range []int{1, -1} { + for _, n1 := range []int{0, 1, 2} { + for _, n2 := range []int{0, 1, 2} { + for _, extra := range []int{0, 1, 2, 13} { + for cas := 0; cas < 1000; cas++ { + testDlasy2(t, impl, tranl, tranr, isgn, n1, n2, extra, rnd) + } + } + } + } + } + } + } +} + +func testDlasy2(t *testing.T, impl Dlasy2er, tranl, tranr bool, isgn, n1, n2, extra int, rnd *rand.Rand) { + const tol = 1e-11 + + tl := randomGeneral(n1, n1, n1+extra, rnd) + tr := randomGeneral(n2, n2, n2+extra, rnd) + b := randomGeneral(n1, n2, n2+extra, rnd) + x := randomGeneral(n1, n2, n2+extra, rnd) + + scale, xnorm, ok := impl.Dlasy2(tranl, tranr, isgn, n1, n2, tl.Data, tl.Stride, tr.Data, tr.Stride, b.Data, b.Stride, x.Data, x.Stride) + if scale > 1 { + t.Errorf("invalid value of scale, want <= 1, got %v", scale) + } + if n1 == 0 || n2 == 0 { + return + } + + prefix := fmt.Sprintf("Case n1=%v, n2=%v, isgn=%v", n1, n2, isgn) + + // Check any invalid modifications of x. + if !generalOutsideAllNaN(x) { + t.Errorf("%v: out-of-range write to x\n%v", prefix, x.Data) + } + + var xnormWant float64 + for i := 0; i < n1; i++ { + var rowsum float64 + for j := 0; j < n2; j++ { + rowsum += math.Abs(x.Data[i*x.Stride+j]) + } + if rowsum > xnormWant { + xnormWant = rowsum + } + } + if xnormWant != xnorm { + t.Errorf("%v: unexpected xnorm: want %v, got %v", prefix, xnormWant, xnorm) + } + + // Multiply b by scale to get the wanted right-hand side. + for i := 0; i < n1; i++ { + for j := 0; j < n2; j++ { + b.Data[i*b.Stride+j] *= scale + } + } + // Compute the wanted left-hand side. + lhsWant := randomGeneral(n1, n2, n2, rnd) + if tranl { + blas64.Gemm(blas.Trans, blas.NoTrans, 1, tl, x, 0, lhsWant) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tl, x, 0, lhsWant) + } + if tranr { + blas64.Gemm(blas.NoTrans, blas.Trans, float64(isgn), x, tr, 1, lhsWant) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, float64(isgn), x, tr, 1, lhsWant) + } + // Compare them. + for i := 0; i < n1; i++ { + for j := 0; j < n2; j++ { + diff := lhsWant.Data[i*lhsWant.Stride+j] - b.Data[i*b.Stride+j] + if math.Abs(diff) > tol && ok { + t.Errorf("%v: unexpected result, diff[%v,%v]=%v", prefix, i, j, diff) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlatrd.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlatrd.go new file mode 100644 index 00000000..f4d3cddc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlatrd.go @@ -0,0 +1,245 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlatrder interface { + Dlatrd(uplo blas.Uplo, n, nb int, a []float64, lda int, e, tau, w []float64, ldw int) +} + +func DlatrdTest(t *testing.T, impl Dlatrder) { + rnd := rand.New(rand.NewSource(1)) + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, test := range []struct { + n, nb, lda, ldw int + }{ + {5, 2, 0, 0}, + {5, 5, 0, 0}, + + {5, 3, 10, 11}, + {5, 5, 10, 11}, + } { + n := test.n + nb := test.nb + lda := test.lda + if lda == 0 { + lda = n + } + ldw := test.ldw + if ldw == 0 { + ldw = nb + } + + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + + e := make([]float64, n-1) + for i := range e { + e[i] = math.NaN() + } + tau := make([]float64, n-1) + for i := range tau { + tau[i] = math.NaN() + } + w := make([]float64, n*ldw) + for i := range w { + w[i] = math.NaN() + } + + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + impl.Dlatrd(uplo, n, nb, a, lda, e, tau, w, ldw) + + // Construct Q. + ldq := n + q := blas64.General{ + Rows: n, + Cols: n, + Stride: ldq, + Data: make([]float64, n*ldq), + } + for i := 0; i < n; i++ { + q.Data[i*ldq+i] = 1 + } + if uplo == blas.Upper { + for i := n - 1; i >= n-nb; i-- { + if i == 0 { + continue + } + h := blas64.General{ + Rows: n, Cols: n, Stride: n, Data: make([]float64, n*n), + } + for j := 0; j < n; j++ { + h.Data[j*n+j] = 1 + } + v := blas64.Vector{ + Inc: 1, + Data: make([]float64, n), + } + for j := 0; j < i-1; j++ { + v.Data[j] = a[j*lda+i] + } + v.Data[i-1] = 1 + + blas64.Ger(-tau[i-1], v, v, h) + + qTmp := blas64.General{ + Rows: n, Cols: n, Stride: n, Data: make([]float64, n*n), + } + copy(qTmp.Data, q.Data) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qTmp, h, 0, q) + } + } else { + for i := 0; i < nb; i++ { + if i == n-1 { + continue + } + h := blas64.General{ + Rows: n, Cols: n, Stride: n, Data: make([]float64, n*n), + } + for j := 0; j < n; j++ { + h.Data[j*n+j] = 1 + } + v := blas64.Vector{ + Inc: 1, + Data: make([]float64, n), + } + v.Data[i+1] = 1 + for j := i + 2; j < n; j++ { + v.Data[j] = a[j*lda+i] + } + blas64.Ger(-tau[i], v, v, h) + + qTmp := blas64.General{ + Rows: n, Cols: n, Stride: n, Data: make([]float64, n*n), + } + copy(qTmp.Data, q.Data) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qTmp, h, 0, q) + } + } + errStr := fmt.Sprintf("isUpper = %v, n = %v, nb = %v", uplo == blas.Upper, n, nb) + if !isOrthonormal(q) { + t.Errorf("Q not orthonormal. %s", errStr) + } + aGen := genFromSym(blas64.Symmetric{N: n, Stride: lda, Uplo: uplo, Data: aCopy}) + if !dlatrdCheckDecomposition(t, uplo, n, nb, e, tau, a, lda, aGen, q) { + t.Errorf("Decomposition mismatch. %s", errStr) + } + } + } +} + +// dlatrdCheckDecomposition checks that the first nb rows have been successfully +// reduced. +func dlatrdCheckDecomposition(t *testing.T, uplo blas.Uplo, n, nb int, e, tau, a []float64, lda int, aGen, q blas64.General) bool { + // Compute Q^T * A * Q. + tmp := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + + ans := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, aGen, 0, tmp) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmp, q, 0, ans) + + // Compare with T. + if uplo == blas.Upper { + for i := n - 1; i >= n-nb; i-- { + for j := 0; j < n; j++ { + v := ans.Data[i*ans.Stride+j] + switch { + case i == j: + if math.Abs(v-a[i*lda+j]) > 1e-10 { + return false + } + case i == j-1: + if math.Abs(a[i*lda+j]-1) > 1e-10 { + return false + } + if math.Abs(v-e[i]) > 1e-10 { + return false + } + case i == j+1: + default: + if math.Abs(v) > 1e-10 { + return false + } + } + } + } + } else { + for i := 0; i < nb; i++ { + for j := 0; j < n; j++ { + v := ans.Data[i*ans.Stride+j] + switch { + case i == j: + if math.Abs(v-a[i*lda+j]) > 1e-10 { + return false + } + case i == j-1: + case i == j+1: + if math.Abs(a[i*lda+j]-1) > 1e-10 { + return false + } + if math.Abs(v-e[i-1]) > 1e-10 { + return false + } + default: + if math.Abs(v) > 1e-10 { + return false + } + } + } + } + } + return true +} + +// genFromSym constructs a (symmetric) general matrix from the data in the +// symmetric. +// TODO(btracey): Replace other constructions of this with a call to this function. +func genFromSym(a blas64.Symmetric) blas64.General { + n := a.N + lda := a.Stride + uplo := a.Uplo + b := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := a.Data[i*lda+j] + if uplo == blas.Lower { + v = a.Data[j*lda+i] + } + b.Data[i*n+j] = v + b.Data[j*n+i] = v + } + } + return b +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dlatrs.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlatrs.go new file mode 100644 index 00000000..d2d77897 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dlatrs.go @@ -0,0 +1,141 @@ +// 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 testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dlatrser interface { + Dlatrs(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, normin bool, n int, a []float64, lda int, x []float64, cnorm []float64) (scale float64) +} + +func DlatrsTest(t *testing.T, impl Dlatrser) { + rnd := rand.New(rand.NewSource(1)) + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, trans := range []blas.Transpose{blas.Trans, blas.NoTrans} { + for _, n := range []int{0, 1, 2, 3, 4, 5, 6, 7, 10, 20, 50, 100} { + for _, lda := range []int{n, 2*n + 1} { + lda = max(1, lda) + imats := []int{7, 11, 12, 13, 14, 15, 16, 17, 18} + if n < 6 { + imats = append(imats, 19) + } + for _, imat := range imats { + testDlatrs(t, impl, imat, uplo, trans, n, lda, rnd) + } + } + } + } + } +} + +func testDlatrs(t *testing.T, impl Dlatrser, imat int, uplo blas.Uplo, trans blas.Transpose, n, lda int, rnd *rand.Rand) { + const tol = 1e-14 + + a := nanSlice(n * lda) + b := nanSlice(n) + work := make([]float64, 3*n) + + // Generate triangular test matrix and right hand side. + diag := dlattr(imat, uplo, trans, n, a, lda, b, work, rnd) + if imat <= 10 { + // b has not been generated. + dlarnv(b, 3, rnd) + } + + cnorm := nanSlice(n) + x := make([]float64, n) + + // Call Dlatrs with normin=false. + copy(x, b) + scale := impl.Dlatrs(uplo, trans, diag, false, n, a, lda, x, cnorm) + prefix := fmt.Sprintf("Case imat=%v (n=%v,lda=%v,trans=%v,uplo=%v,diag=%v", imat, n, lda, trans, uplo, diag) + for i, v := range cnorm { + if math.IsNaN(v) { + t.Errorf("%v: cnorm[%v] not computed (scale=%v,normin=false)", prefix, i, scale) + } + } + resid, hasNaN := dlatrsResidual(uplo, trans, diag, n, a, lda, scale, cnorm, x, b, work[:n]) + if hasNaN { + t.Errorf("%v: unexpected NaN (scale=%v,normin=false)", prefix, scale) + } else if resid > tol { + t.Errorf("%v: residual %v too large (scale=%v,normin=false)", prefix, resid, scale) + } + + // Call Dlatrs with normin=true because cnorm has been filled. + copy(x, b) + scale = impl.Dlatrs(uplo, trans, diag, true, n, a, lda, x, cnorm) + resid, hasNaN = dlatrsResidual(uplo, trans, diag, n, a, lda, scale, cnorm, x, b, work[:n]) + if hasNaN { + t.Errorf("%v: unexpected NaN (scale=%v,normin=true)", prefix, scale) + } else if resid > tol { + t.Errorf("%v: residual %v too large (scale=%v,normin=true)", prefix, resid, scale) + } +} + +// dlatrsResidual returns norm(trans(A)*x-scale*b) / (norm(trans(A))*norm(x)*eps) +// and whether NaN has been encountered in the process. +func dlatrsResidual(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, a []float64, lda int, scale float64, cnorm []float64, x, b, work []float64) (resid float64, hasNaN bool) { + if n == 0 { + return 0, false + } + + // Compute the norm of the triangular matrix A using the column norms + // already computed by Dlatrs. + var tnorm float64 + if diag == blas.NonUnit { + for j := 0; j < n; j++ { + tnorm = math.Max(tnorm, math.Abs(a[j*lda+j])+cnorm[j]) + } + } else { + for j := 0; j < n; j++ { + tnorm = math.Max(tnorm, 1+cnorm[j]) + } + } + + eps := dlamchE + smlnum := dlamchS + bi := blas64.Implementation() + + // Compute norm(trans(A)*x-scale*b) / (norm(trans(A))*norm(x)*eps) + copy(work, x) + ix := bi.Idamax(n, work, 1) + xnorm := math.Max(1, math.Abs(work[ix])) + xscal := 1 / xnorm / float64(n) + bi.Dscal(n, xscal, work, 1) + bi.Dtrmv(uplo, trans, diag, n, a, lda, work, 1) + bi.Daxpy(n, -scale*xscal, b, 1, work, 1) + for _, v := range work { + if math.IsNaN(v) { + return 1 / eps, true + } + } + ix = bi.Idamax(n, work, 1) + resid = math.Abs(work[ix]) + ix = bi.Idamax(n, x, 1) + xnorm = math.Abs(x[ix]) + if resid*smlnum <= xnorm { + if xnorm > 0 { + resid /= xnorm + } + } else if resid > 0 { + resid = 1 / eps + } + if resid*smlnum <= tnorm { + if tnorm > 0 { + resid /= tnorm + } + } else if resid > 0 { + resid = 1 / eps + } + return resid, false +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/doc.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/doc.go new file mode 100644 index 00000000..76da5d18 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package testlapack implements a set of testing routines for Lapack functions. +package testlapack // import "gonum.org/v1/gonum/lapack/testlapack" diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorg2l.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorg2l.go new file mode 100644 index 00000000..e1f2f155 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorg2l.go @@ -0,0 +1,75 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +type Dorg2ler interface { + Dorg2l(m, n, k int, a []float64, lda int, tau, work []float64) + Dgeql2er +} + +func Dorg2lTest(t *testing.T, impl Dorg2ler) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, k, lda int + }{ + {5, 4, 3, 0}, + {5, 4, 4, 0}, + {3, 3, 2, 0}, + {5, 5, 5, 0}, + } { + m := test.m + n := test.n + k := test.k + lda := test.lda + if lda == 0 { + lda = n + } + + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + tau := nanSlice(max(m, n)) + work := make([]float64, n) + impl.Dgeql2(m, n, a, lda, tau, work) + + aCopy := make([]float64, len(a)) + copy(aCopy, a) + impl.Dorg2l(m, n, k, a, lda, tau[n-k:], work) + if !hasOrthonormalColumns(m, n, a, lda) { + t.Errorf("Q is not orthonormal. m = %v, n = %v, k = %v", m, n, k) + } + } +} + +// hasOrthornormalColumns checks that the columns of a are orthonormal. +func hasOrthonormalColumns(m, n int, a []float64, lda int) bool { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dot := blas64.Dot(m, + blas64.Vector{Inc: lda, Data: a[i:]}, + blas64.Vector{Inc: lda, Data: a[j:]}, + ) + if i == j { + if math.Abs(dot-1) > 1e-10 { + return false + } + } else { + if math.Abs(dot) > 1e-10 { + return false + } + } + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorg2r.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorg2r.go new file mode 100644 index 00000000..beeca34d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorg2r.go @@ -0,0 +1,79 @@ +// 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 testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dorg2rer interface { + Dgeqrfer + Dorg2r(m, n, k int, a []float64, lda int, tau []float64, work []float64) +} + +func Dorg2rTest(t *testing.T, impl Dorg2rer) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, k, lda int + }{ + {3, 3, 0, 0}, + {4, 3, 0, 0}, + {3, 3, 2, 0}, + {4, 3, 2, 0}, + + {5, 5, 0, 20}, + {5, 5, 3, 20}, + {10, 5, 0, 20}, + {10, 5, 2, 20}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = test.n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + k := min(m, n) + tau := make([]float64, k) + work := make([]float64, 1) + impl.Dgeqrf(m, n, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgeqrf(m, n, a, lda, tau, work, len(work)) + + k = test.k + if k == 0 { + k = n + } + q := constructQK("QR", m, n, k, a, lda, tau) + + impl.Dorg2r(m, n, k, a, lda, tau, work) + + // Check that the first n columns match. + same := true + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + if !floats.EqualWithinAbsOrRel(q.Data[i*q.Stride+j], a[i*lda+j], 1e-12, 1e-12) { + same = false + break + } + } + } + if !same { + fmt.Println() + fmt.Println("a =") + printRowise(a, m, n, lda, false) + fmt.Println("q =") + printRowise(q.Data, q.Rows, q.Cols, q.Stride, false) + t.Errorf("Q mismatch") + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgbr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgbr.go new file mode 100644 index 00000000..3f43fb94 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgbr.go @@ -0,0 +1,156 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dorgbrer interface { + Dorgbr(vect lapack.DecompUpdate, m, n, k int, a []float64, lda int, tau, work []float64, lwork int) + Dgebrder +} + +func DorgbrTest(t *testing.T, impl Dorgbrer) { + rnd := rand.New(rand.NewSource(1)) + for _, vect := range []lapack.DecompUpdate{lapack.ApplyQ, lapack.ApplyP} { + for _, test := range []struct { + m, n, k, lda int + }{ + {5, 5, 5, 0}, + {5, 5, 3, 0}, + {5, 3, 5, 0}, + {3, 5, 5, 0}, + {3, 4, 5, 0}, + {3, 5, 4, 0}, + {4, 3, 5, 0}, + {4, 5, 3, 0}, + {5, 3, 4, 0}, + {5, 4, 3, 0}, + + {5, 5, 5, 10}, + {5, 5, 3, 10}, + {5, 3, 5, 10}, + {3, 5, 5, 10}, + {3, 4, 5, 10}, + {3, 5, 4, 10}, + {4, 3, 5, 10}, + {4, 5, 3, 10}, + {5, 3, 4, 10}, + {5, 4, 3, 10}, + } { + m := test.m + n := test.n + k := test.k + lda := test.lda + // Filter out bad tests + if vect == lapack.ApplyQ { + if m < n || n < min(m, k) || m < min(m, k) { + continue + } + } else { + if n < m || m < min(n, k) || n < min(n, k) { + continue + } + } + // Sizes for Dorgbr. + var ma, na int + if vect == lapack.ApplyQ { + if m >= k { + ma = m + na = k + } else { + ma = m + na = m + } + } else { + if n >= k { + ma = k + na = n + } else { + ma = n + na = n + } + } + // a eventually needs to store either P or Q, so it must be + // sufficiently big. + var a []float64 + if vect == lapack.ApplyQ { + lda = max(m, lda) + a = make([]float64, m*lda) + } else { + lda = max(n, lda) + a = make([]float64, n*lda) + } + for i := range a { + a[i] = rnd.NormFloat64() + } + + nTau := min(ma, na) + tauP := make([]float64, nTau) + tauQ := make([]float64, nTau) + d := make([]float64, nTau) + e := make([]float64, nTau) + lwork := -1 + work := make([]float64, 1) + impl.Dgebrd(ma, na, a, lda, d, e, tauQ, tauP, work, lwork) + work = make([]float64, int(work[0])) + lwork = len(work) + impl.Dgebrd(ma, na, a, lda, d, e, tauQ, tauP, work, lwork) + + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + var tau []float64 + if vect == lapack.ApplyQ { + tau = tauQ + } else { + tau = tauP + } + + impl.Dorgbr(vect, m, n, k, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + lwork = len(work) + impl.Dorgbr(vect, m, n, k, a, lda, tau, work, lwork) + + var ans blas64.General + var nRows, nCols int + equal := true + if vect == lapack.ApplyQ { + nRows = m + nCols = m + if m >= k { + nCols = n + } + ans = constructQPBidiagonal(vect, ma, na, min(m, k), aCopy, lda, tau) + } else { + nRows = n + if k < n { + nRows = m + } + nCols = n + ansTmp := constructQPBidiagonal(vect, ma, na, min(k, n), aCopy, lda, tau) + // Dorgbr actually computes P^T + ans = transposeGeneral(ansTmp) + } + for i := 0; i < nRows; i++ { + for j := 0; j < nCols; j++ { + if !floats.EqualWithinAbsOrRel(a[i*lda+j], ans.Data[i*ans.Stride+j], 1e-8, 1e-8) { + equal = false + } + } + } + if !equal { + applyQ := vect == lapack.ApplyQ + t.Errorf("Extracted matrix mismatch. applyQ: %v, m = %v, n = %v, k = %v", applyQ, m, n, k) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorghr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorghr.go new file mode 100644 index 00000000..7311d015 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorghr.go @@ -0,0 +1,99 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dorghrer interface { + Dorghr(n, ilo, ihi int, a []float64, lda int, tau, work []float64, lwork int) + + Dgehrder +} + +func DorghrTest(t *testing.T, impl Dorghrer) { + rnd := rand.New(rand.NewSource(1)) + + for _, n := range []int{1, 2, 3, 4, 5, 6, 7, 8, 23, 34} { + for _, extra := range []int{0, 1, 13} { + for _, optwork := range []bool{true, false} { + for cas := 0; cas < 100; cas++ { + ilo := rnd.Intn(n) + ihi := rnd.Intn(n) + if ilo > ihi { + ilo, ihi = ihi, ilo + } + testDorghr(t, impl, n, ilo, ihi, extra, optwork, rnd) + } + } + } + } + testDorghr(t, impl, 0, 0, -1, 0, false, rnd) + testDorghr(t, impl, 0, 0, -1, 0, true, rnd) +} + +func testDorghr(t *testing.T, impl Dorghrer, n, ilo, ihi, extra int, optwork bool, rnd *rand.Rand) { + const tol = 1e-14 + + // Construct the matrix A with elementary reflectors and scalar factors tau. + a := randomGeneral(n, n, n+extra, rnd) + var tau []float64 + if n > 1 { + tau = nanSlice(n - 1) + } + work := nanSlice(max(1, n)) // Minimum work for Dgehrd. + impl.Dgehrd(n, ilo, ihi, a.Data, a.Stride, tau, work, len(work)) + + // Extract Q for later comparison. + q := eye(n, n) + qCopy := cloneGeneral(q) + for j := ilo; j < ihi; j++ { + h := eye(n, n) + v := blas64.Vector{ + Inc: 1, + Data: make([]float64, n), + } + v.Data[j+1] = 1 + for i := j + 2; i < ihi+1; i++ { + v.Data[i] = a.Data[i*a.Stride+j] + } + blas64.Ger(-tau[j], v, v, h) + copy(qCopy.Data, q.Data) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qCopy, h, 0, q) + } + + if optwork { + work = nanSlice(1) + impl.Dorghr(n, ilo, ihi, a.Data, a.Stride, tau, work, -1) + work = nanSlice(int(work[0])) + } else { + work = nanSlice(max(1, ihi-ilo)) + } + impl.Dorghr(n, ilo, ihi, a.Data, a.Stride, tau, work, len(work)) + + prefix := fmt.Sprintf("Case n=%v, ilo=%v, ihi=%v, extra=%v, optwork=%v", n, ilo, ihi, extra, optwork) + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A\n%v", prefix, a.Data) + } + if !isOrthonormal(a) { + t.Errorf("%v: A is not orthogonal\n%v", prefix, a.Data) + } + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + aij := a.Data[i*a.Stride+j] + qij := q.Data[i*q.Stride+j] + if math.Abs(aij-qij) > tol { + t.Errorf("%v: unexpected value of A[%v,%v]. want %v, got %v", prefix, i, j, qij, aij) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgl2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgl2.go new file mode 100644 index 00000000..5ae3fcb1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgl2.go @@ -0,0 +1,65 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dorgl2er interface { + Dgelqfer + Dorgl2(m, n, k int, a []float64, lda int, tau []float64, work []float64) +} + +func Dorgl2Test(t *testing.T, impl Dorgl2er) { + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, n, lda int + }{ + {3, 3, 0}, + {3, 4, 0}, + + {5, 5, 20}, + {5, 10, 20}, + } { + m := test.m + n := test.n + lda := test.lda + if lda == 0 { + lda = test.n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + k := min(m, n) + tau := make([]float64, k) + work := make([]float64, 1) + impl.Dgelqf(m, n, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgelqf(m, n, a, lda, tau, work, len(work)) + + q := constructQ("LQ", m, n, a, lda, tau) + + impl.Dorgl2(m, n, k, a, lda, tau, work) + + // Check that the first m rows match. + same := true + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + if !floats.EqualWithinAbsOrRel(q.Data[i*q.Stride+j], a[i*lda+j], 1e-12, 1e-12) { + same = false + break + } + } + } + if !same { + t.Errorf("Q mismatch") + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorglq.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorglq.go new file mode 100644 index 00000000..3d8bb105 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorglq.go @@ -0,0 +1,83 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dorglqer interface { + Dorgl2er + Dorglq(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) +} + +func DorglqTest(t *testing.T, impl Dorglqer) { + rnd := rand.New(rand.NewSource(1)) + // TODO(btracey): Base tests off of nb and nx. + for _, test := range []struct{ m, n, k, lda int }{ + {10, 10, 10, 0}, + {10, 10, 10, 20}, + {10, 30, 10, 0}, + {20, 30, 10, 0}, + + {100, 100, 100, 0}, + {100, 100, 50, 0}, + {100, 130, 100, 0}, + {100, 130, 50, 0}, + {100, 100, 100, 150}, + {100, 100, 50, 150}, + {100, 130, 100, 150}, + {100, 130, 50, 150}, + + {200, 200, 200, 0}, + {200, 200, 150, 0}, + {200, 230, 200, 0}, + {200, 230, 150, 0}, + {200, 200, 200, 250}, + {200, 200, 150, 250}, + {200, 230, 200, 250}, + {200, 230, 150, 250}, + } { + m := test.m + n := test.n + k := test.k + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + work := make([]float64, 1) + tau := make([]float64, m) + for i := range tau { + tau[i] = math.NaN() + } + // Compute LQ factorization. + impl.Dgelqf(m, n, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgelqf(m, n, a, lda, tau, work, len(work)) + + aUnblocked := make([]float64, len(a)) + copy(aUnblocked, a) + for i := range work { + work[i] = math.NaN() + } + impl.Dorgl2(m, n, k, aUnblocked, lda, tau, work) + // make sure work isn't used before initialized + for i := range work { + work[i] = math.NaN() + } + impl.Dorglq(m, n, k, a, lda, tau, work, len(work)) + if !floats.EqualApprox(a, aUnblocked, 1e-10) { + t.Errorf("Q Mismatch. m = %d, n = %d, k = %d, lda = %d", m, n, k, lda) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgql.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgql.go new file mode 100644 index 00000000..4cf9b22a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgql.go @@ -0,0 +1,130 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dorgqler interface { + Dorgql(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) + + Dlarfger +} + +func DorgqlTest(t *testing.T, impl Dorgqler) { + const tol = 1e-14 + + type Dorg2ler interface { + Dorg2l(m, n, k int, a []float64, lda int, tau, work []float64) + } + dorg2ler, hasDorg2l := impl.(Dorg2ler) + + rnd := rand.New(rand.NewSource(1)) + for _, m := range []int{0, 1, 2, 3, 4, 5, 7, 10, 15, 30, 50, 150} { + for _, extra := range []int{0, 11} { + for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { + var k int + if m >= 129 { + // For large matrices make sure that k + // is large enough to trigger blocked + // path. + k = 129 + rnd.Intn(m-129+1) + } else { + k = rnd.Intn(m + 1) + } + n := k + rnd.Intn(m-k+1) + if m == 0 || n == 0 { + m = 0 + n = 0 + k = 0 + } + + // Generate k elementary reflectors in the last + // k columns of A. + a := nanGeneral(m, n, n+extra) + tau := make([]float64, k) + for l := 0; l < k; l++ { + jj := m - k + l + v := randomSlice(jj, rnd) + _, tau[l] = impl.Dlarfg(len(v)+1, rnd.NormFloat64(), v, 1) + j := n - k + l + for i := 0; i < jj; i++ { + a.Data[i*a.Stride+j] = v[i] + } + } + aCopy := cloneGeneral(a) + + // Compute the full matrix Q by forming the + // Householder reflectors explicitly. + q := eye(m, m) + qCopy := eye(m, m) + for l := 0; l < k; l++ { + h := eye(m, m) + jj := m - k + l + j := n - k + l + v := blas64.Vector{1, make([]float64, m)} + for i := 0; i < jj; i++ { + v.Data[i] = a.Data[i*a.Stride+j] + } + v.Data[jj] = 1 + blas64.Ger(-tau[l], v, v, h) + copy(qCopy.Data, q.Data) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, h, qCopy, 0, q) + } + // View the last n columns of Q as 'want'. + want := blas64.General{ + Rows: m, + Cols: n, + Stride: q.Stride, + Data: q.Data[m-n:], + } + + var lwork int + switch wl { + case minimumWork: + lwork = max(1, n) + case mediumWork: + work := make([]float64, 1) + impl.Dorgql(m, n, k, nil, a.Stride, nil, work, -1) + lwork = (int(work[0]) + n) / 2 + lwork = max(1, lwork) + case optimumWork: + work := make([]float64, 1) + impl.Dorgql(m, n, k, nil, a.Stride, nil, work, -1) + lwork = int(work[0]) + } + work := make([]float64, lwork) + + // Compute the last n columns of Q by a call to + // Dorgql. + impl.Dorgql(m, n, k, a.Data, a.Stride, tau, work, len(work)) + + prefix := fmt.Sprintf("Case m=%v,n=%v,k=%v,wl=%v", m, n, k, wl) + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A", prefix) + } + if !equalApproxGeneral(want, a, tol) { + t.Errorf("%v: unexpected Q", prefix) + } + + // Compute the last n columns of Q by a call to + // Dorg2l and check that we get the same result. + if !hasDorg2l { + continue + } + dorg2ler.Dorg2l(m, n, k, aCopy.Data, aCopy.Stride, tau, work) + if !equalApproxGeneral(aCopy, a, tol) { + t.Errorf("%v: mismatch between Dorgql and Dorg2l", prefix) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgqr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgqr.go new file mode 100644 index 00000000..57306c05 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgqr.go @@ -0,0 +1,83 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dorgqrer interface { + Dorg2rer + Dorgqr(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) +} + +func DorgqrTest(t *testing.T, impl Dorgqrer) { + rnd := rand.New(rand.NewSource(1)) + // TODO(btracey): Base tests off of nb and nx. + for _, test := range []struct{ m, n, k, lda int }{ + {10, 10, 10, 0}, + {10, 10, 10, 20}, + {30, 10, 10, 0}, + {30, 20, 10, 20}, + + {100, 100, 100, 0}, + {100, 100, 50, 0}, + {130, 100, 100, 0}, + {130, 100, 50, 0}, + {100, 100, 100, 150}, + {100, 100, 50, 150}, + {130, 100, 100, 150}, + {130, 100, 50, 150}, + + {200, 200, 200, 0}, + {200, 200, 150, 0}, + {230, 200, 200, 0}, + {230, 200, 150, 0}, + {200, 200, 200, 250}, + {200, 200, 150, 250}, + {230, 200, 200, 250}, + {230, 200, 150, 250}, + } { + m := test.m + n := test.n + k := test.k + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, m*lda) + for i := range a { + a[i] = rnd.Float64() + } + work := make([]float64, 1) + tau := make([]float64, n) + for i := range tau { + tau[i] = math.NaN() + } + // Compute QR factorization. + impl.Dgeqrf(m, n, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgeqrf(m, n, a, lda, tau, work, len(work)) + + aUnblocked := make([]float64, len(a)) + copy(aUnblocked, a) + for i := range work { + work[i] = math.NaN() + } + impl.Dorg2r(m, n, k, aUnblocked, lda, tau, work) + // make sure work isn't used before initialized + for i := range work { + work[i] = math.NaN() + } + impl.Dorgqr(m, n, k, a, lda, tau, work, len(work)) + if !floats.EqualApprox(a, aUnblocked, 1e-10) { + t.Errorf("Q Mismatch. m = %d, n = %d, k = %d, lda = %d", m, n, k, lda) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgtr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgtr.go new file mode 100644 index 00000000..4f49d1a4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorgtr.go @@ -0,0 +1,136 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dorgtrer interface { + Dorgtr(uplo blas.Uplo, n int, a []float64, lda int, tau, work []float64, lwork int) + Dsytrder +} + +func DorgtrTest(t *testing.T, impl Dorgtrer) { + rnd := rand.New(rand.NewSource(1)) + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { + for _, test := range []struct { + n, lda int + }{ + {1, 0}, + {2, 0}, + {3, 0}, + {6, 0}, + {33, 0}, + {100, 0}, + + {1, 3}, + {2, 5}, + {3, 7}, + {6, 10}, + {33, 50}, + {100, 120}, + } { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + d := make([]float64, n) + e := make([]float64, n-1) + tau := make([]float64, n-1) + work := make([]float64, 1) + impl.Dsytrd(uplo, n, a, lda, d, e, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dsytrd(uplo, n, a, lda, d, e, tau, work, len(work)) + + var lwork int + switch wl { + case minimumWork: + lwork = max(1, n-1) + case mediumWork: + work := make([]float64, 1) + impl.Dorgtr(uplo, n, a, lda, tau, work, -1) + lwork = (int(work[0]) + n - 1) / 2 + lwork = max(1, lwork) + case optimumWork: + work := make([]float64, 1) + impl.Dorgtr(uplo, n, a, lda, tau, work, -1) + lwork = int(work[0]) + } + work = nanSlice(lwork) + + impl.Dorgtr(uplo, n, a, lda, tau, work, len(work)) + + q := blas64.General{ + Rows: n, + Cols: n, + Stride: lda, + Data: a, + } + tri := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + for i := 0; i < n; i++ { + tri.Data[i*tri.Stride+i] = d[i] + if i != n-1 { + tri.Data[i*tri.Stride+i+1] = e[i] + tri.Data[(i+1)*tri.Stride+i] = e[i] + } + } + + aMat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + if uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := aCopy[i*lda+j] + aMat.Data[i*aMat.Stride+j] = v + aMat.Data[j*aMat.Stride+i] = v + } + } + } else { + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + v := aCopy[i*lda+j] + aMat.Data[i*aMat.Stride+j] = v + aMat.Data[j*aMat.Stride+i] = v + } + } + } + + tmp := blas64.General{Rows: n, Cols: n, Stride: n, Data: make([]float64, n*n)} + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, aMat, q, 0, tmp) + + ans := blas64.General{Rows: n, Cols: n, Stride: n, Data: make([]float64, n*n)} + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, tmp, 0, ans) + + if !floats.EqualApprox(ans.Data, tri.Data, 1e-13) { + t.Errorf("Recombination mismatch. n = %v, isUpper = %v", n, uplo == blas.Upper) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorm2r.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorm2r.go new file mode 100644 index 00000000..5e23415d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorm2r.go @@ -0,0 +1,139 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dorm2rer interface { + Dgeqrfer + Dorm2r(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) +} + +func Dorm2rTest(t *testing.T, impl Dorm2rer) { + rnd := rand.New(rand.NewSource(1)) + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, test := range []struct { + common, adim, cdim, lda, ldc int + }{ + {3, 4, 5, 0, 0}, + {3, 5, 4, 0, 0}, + {4, 3, 5, 0, 0}, + {4, 5, 3, 0, 0}, + {5, 3, 4, 0, 0}, + {5, 4, 3, 0, 0}, + {3, 4, 5, 6, 20}, + {3, 5, 4, 6, 20}, + {4, 3, 5, 6, 20}, + {4, 5, 3, 6, 20}, + {5, 3, 4, 6, 20}, + {5, 4, 3, 6, 20}, + {3, 4, 5, 20, 6}, + {3, 5, 4, 20, 6}, + {4, 3, 5, 20, 6}, + {4, 5, 3, 20, 6}, + {5, 3, 4, 20, 6}, + {5, 4, 3, 20, 6}, + } { + var ma, na, mc, nc int + if side == blas.Left { + ma = test.common + na = test.adim + mc = test.common + nc = test.cdim + } else { + ma = test.common + na = test.adim + mc = test.cdim + nc = test.common + } + + // Generate a random matrix + lda := test.lda + if lda == 0 { + lda = na + } + a := make([]float64, ma*lda) + for i := range a { + a[i] = rnd.Float64() + } + ldc := test.ldc + if ldc == 0 { + ldc = nc + } + // Compute random C matrix + c := make([]float64, mc*ldc) + for i := range c { + c[i] = rnd.Float64() + } + + // Compute QR + k := min(ma, na) + tau := make([]float64, k) + work := make([]float64, 1) + impl.Dgeqrf(ma, na, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgeqrf(ma, na, a, lda, tau, work, len(work)) + + // Build Q from result + q := constructQ("QR", ma, na, a, lda, tau) + + cMat := blas64.General{ + Rows: mc, + Cols: nc, + Stride: ldc, + Data: make([]float64, len(c)), + } + copy(cMat.Data, c) + cMatCopy := blas64.General{ + Rows: cMat.Rows, + Cols: cMat.Cols, + Stride: cMat.Stride, + Data: make([]float64, len(cMat.Data)), + } + copy(cMatCopy.Data, cMat.Data) + switch { + default: + panic("bad test") + case side == blas.Left && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, cMatCopy, 0, cMat) + case side == blas.Left && trans == blas.Trans: + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, cMatCopy, 0, cMat) + case side == blas.Right && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, cMatCopy, q, 0, cMat) + case side == blas.Right && trans == blas.Trans: + blas64.Gemm(blas.NoTrans, blas.Trans, 1, cMatCopy, q, 0, cMat) + } + // Do Dorm2r ard compare + if side == blas.Left { + work = make([]float64, nc) + } else { + work = make([]float64, mc) + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + tauCopy := make([]float64, len(tau)) + copy(tauCopy, tau) + impl.Dorm2r(side, trans, mc, nc, k, a, lda, tau, c, ldc, work) + if !floats.Equal(a, aCopy) { + t.Errorf("a changed in call") + } + if !floats.Equal(tau, tauCopy) { + t.Errorf("tau changed in call") + } + if !floats.EqualApprox(cMat.Data, c, 1e-14) { + t.Errorf("Multiplication mismatch.\n Want %v \n got %v.", cMat.Data, c) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dormbr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormbr.go new file mode 100644 index 00000000..0a44faf5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormbr.go @@ -0,0 +1,164 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dormbrer interface { + Dormbr(vect lapack.DecompUpdate, side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) + Dgebrder +} + +func DormbrTest(t *testing.T, impl Dormbrer) { + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + for _, vect := range []lapack.DecompUpdate{lapack.ApplyQ, lapack.ApplyP} { + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { + for _, test := range []struct { + m, n, k, lda, ldc int + }{ + {3, 4, 5, 0, 0}, + {3, 5, 4, 0, 0}, + {4, 3, 5, 0, 0}, + {4, 5, 3, 0, 0}, + {5, 3, 4, 0, 0}, + {5, 4, 3, 0, 0}, + + {3, 4, 5, 10, 12}, + {3, 5, 4, 10, 12}, + {4, 3, 5, 10, 12}, + {4, 5, 3, 10, 12}, + {5, 3, 4, 10, 12}, + {5, 4, 3, 10, 12}, + + {150, 140, 130, 0, 0}, + } { + m := test.m + n := test.n + k := test.k + ldc := test.ldc + if ldc == 0 { + ldc = n + } + nq := n + nw := m + if side == blas.Left { + nq = m + nw = n + } + + // Compute a decomposition. + var ma, na int + var a []float64 + if vect == lapack.ApplyQ { + ma = nq + na = k + } else { + ma = k + na = nq + } + lda := test.lda + if lda == 0 { + lda = na + } + a = make([]float64, ma*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + nTau := min(nq, k) + tauP := make([]float64, nTau) + tauQ := make([]float64, nTau) + d := make([]float64, nTau) + e := make([]float64, nTau) + + work := make([]float64, 1) + impl.Dgebrd(ma, na, a, lda, d, e, tauQ, tauP, work, -1) + work = make([]float64, int(work[0])) + impl.Dgebrd(ma, na, a, lda, d, e, tauQ, tauP, work, len(work)) + + // Apply and compare update. + c := make([]float64, m*ldc) + for i := range c { + c[i] = rnd.NormFloat64() + } + cCopy := make([]float64, len(c)) + copy(cCopy, c) + + var lwork int + switch wl { + case minimumWork: + lwork = nw + case optimumWork: + impl.Dormbr(vect, side, trans, m, n, k, a, lda, tauQ, c, ldc, work, -1) + lwork = int(work[0]) + case mediumWork: + work := make([]float64, 1) + impl.Dormbr(vect, side, trans, m, n, k, a, lda, tauQ, c, ldc, work, -1) + lwork = (int(work[0]) + nw) / 2 + } + lwork = max(1, lwork) + work = make([]float64, lwork) + + if vect == lapack.ApplyQ { + impl.Dormbr(vect, side, trans, m, n, k, a, lda, tauQ, c, ldc, work, lwork) + } else { + impl.Dormbr(vect, side, trans, m, n, k, a, lda, tauP, c, ldc, work, lwork) + } + + // Check that the multiplication was correct. + cOrig := blas64.General{ + Rows: m, + Cols: n, + Stride: ldc, + Data: make([]float64, len(cCopy)), + } + copy(cOrig.Data, cCopy) + cAns := blas64.General{ + Rows: m, + Cols: n, + Stride: ldc, + Data: make([]float64, len(cCopy)), + } + copy(cAns.Data, cCopy) + nb := min(ma, na) + var mulMat blas64.General + if vect == lapack.ApplyQ { + mulMat = constructQPBidiagonal(lapack.ApplyQ, ma, na, nb, a, lda, tauQ) + } else { + mulMat = constructQPBidiagonal(lapack.ApplyP, ma, na, nb, a, lda, tauP) + } + + mulTrans := trans + + if side == blas.Left { + bi.Dgemm(mulTrans, blas.NoTrans, m, n, m, 1, mulMat.Data, mulMat.Stride, cOrig.Data, cOrig.Stride, 0, cAns.Data, cAns.Stride) + } else { + bi.Dgemm(blas.NoTrans, mulTrans, m, n, n, 1, cOrig.Data, cOrig.Stride, mulMat.Data, mulMat.Stride, 0, cAns.Data, cAns.Stride) + } + + if !floats.EqualApprox(cAns.Data, c, 1e-13) { + isApplyQ := vect == lapack.ApplyQ + isLeft := side == blas.Left + isTrans := trans == blas.Trans + + t.Errorf("C mismatch. isApplyQ: %v, isLeft: %v, isTrans: %v, m = %v, n = %v, k = %v, lda = %v, ldc = %v", + isApplyQ, isLeft, isTrans, m, n, k, lda, ldc) + } + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dormhr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormhr.go new file mode 100644 index 00000000..7b908aa1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormhr.go @@ -0,0 +1,132 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dormhrer interface { + Dormhr(side blas.Side, trans blas.Transpose, m, n, ilo, ihi int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) + + Dgehrder +} + +func DormhrTest(t *testing.T, impl Dormhrer) { + rnd := rand.New(rand.NewSource(1)) + + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, m := range []int{1, 2, 3, 4, 5, 8, 9, 10, 23} { + for _, n := range []int{1, 2, 3, 4, 5, 8, 9, 10, 23} { + for _, extra := range []int{0, 1, 13} { + for cas := 0; cas < 10; cas++ { + nq := m + if side == blas.Right { + nq = n + } + ilo := rnd.Intn(nq) + ihi := rnd.Intn(nq) + if ilo > ihi { + ilo, ihi = ihi, ilo + } + testDormhr(t, impl, side, trans, m, n, ilo, ihi, extra, true, rnd) + testDormhr(t, impl, side, trans, m, n, ilo, ihi, extra, false, rnd) + } + } + } + } + } + } + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + testDormhr(t, impl, side, trans, 0, 0, 0, -1, 0, true, rnd) + testDormhr(t, impl, side, trans, 0, 0, 0, -1, 0, false, rnd) + } + } +} + +func testDormhr(t *testing.T, impl Dormhrer, side blas.Side, trans blas.Transpose, m, n, ilo, ihi, extra int, optwork bool, rnd *rand.Rand) { + const tol = 1e-14 + + var nq, nw int + switch side { + case blas.Left: + nq = m + nw = n + case blas.Right: + nq = n + nw = m + } + + // Compute the elementary reflectors and tau. + a := randomGeneral(nq, nq, nq+extra, rnd) + var tau []float64 + if nq > 1 { + tau = nanSlice(nq - 1) + } + work := nanSlice(max(1, nq)) // Minimum work for Dgehrd. + impl.Dgehrd(nq, ilo, ihi, a.Data, a.Stride, tau, work, len(work)) + + // Construct Q from the elementary reflectors in a and from tau. + q := eye(nq, nq) + qCopy := eye(nq, nq) + for j := ilo; j < ihi; j++ { + h := eye(nq, nq) + v := blas64.Vector{ + Inc: 1, + Data: make([]float64, nq), + } + v.Data[j+1] = 1 + for i := j + 2; i < ihi+1; i++ { + v.Data[i] = a.Data[i*a.Stride+j] + } + blas64.Ger(-tau[j], v, v, h) + copy(qCopy.Data, q.Data) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qCopy, h, 0, q) + } + + c := randomGeneral(m, n, n+extra, rnd) + + // Compute the product of Q and C explicitly. + qc := randomGeneral(m, n, n+extra, rnd) + if side == blas.Left { + blas64.Gemm(trans, blas.NoTrans, 1, q, c, 0, qc) + } else { + blas64.Gemm(blas.NoTrans, trans, 1, c, q, 0, qc) + } + + // Compute the product of Q and C using Dormhr. + if optwork { + work = nanSlice(1) + impl.Dormhr(side, trans, m, n, ilo, ihi, nil, a.Stride, nil, nil, c.Stride, work, -1) + work = nanSlice(int(work[0])) + } else { + work = nanSlice(max(1, nw)) + } + impl.Dormhr(side, trans, m, n, ilo, ihi, a.Data, a.Stride, tau, c.Data, c.Stride, work, len(work)) + + // Compare the two answers. + prefix := fmt.Sprintf("Case side=%v, trans=%v, m=%v, n=%v, ilo=%v, ihi=%v, extra=%v, optwork=%v", + side, trans, m, n, ilo, ihi, extra, optwork) + if !generalOutsideAllNaN(c) { + t.Errorf("%v: out-of-range write to C\n%v", prefix, c.Data) + } + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + cij := c.Data[i*c.Stride+j] + qcij := qc.Data[i*qc.Stride+j] + if math.Abs(cij-qcij) > tol { + t.Errorf("%v: unexpected value of the QC product at [%v,%v]: want %v, got %v", prefix, i, j, qcij, cij) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dorml2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorml2.go new file mode 100644 index 00000000..909c56e4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dorml2.go @@ -0,0 +1,144 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dorml2er interface { + Dgelqfer + Dorml2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) +} + +func Dorml2Test(t *testing.T, impl Dorml2er) { + rnd := rand.New(rand.NewSource(1)) + // TODO(btracey): This test is not complete, because it + // doesn't test individual values of m, n, and k, instead only testing + // a specific subset of possible k values. + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, test := range []struct { + common, adim, cdim, lda, ldc int + }{ + {3, 4, 5, 0, 0}, + {3, 5, 4, 0, 0}, + {4, 3, 5, 0, 0}, + {4, 5, 3, 0, 0}, + {5, 3, 4, 0, 0}, + {5, 4, 3, 0, 0}, + + {3, 4, 5, 6, 20}, + {3, 5, 4, 6, 20}, + {4, 3, 5, 6, 20}, + {4, 5, 3, 6, 20}, + {5, 3, 4, 6, 20}, + {5, 4, 3, 6, 20}, + {3, 4, 5, 20, 6}, + {3, 5, 4, 20, 6}, + {4, 3, 5, 20, 6}, + {4, 5, 3, 20, 6}, + {5, 3, 4, 20, 6}, + {5, 4, 3, 20, 6}, + } { + var ma, na, mc, nc int + if side == blas.Left { + ma = test.adim + na = test.common + mc = test.common + nc = test.cdim + } else { + ma = test.adim + na = test.common + mc = test.cdim + nc = test.common + } + // Generate a random matrix + lda := test.lda + if lda == 0 { + lda = na + } + a := make([]float64, ma*lda) + for i := range a { + a[i] = rnd.Float64() + } + ldc := test.ldc + if ldc == 0 { + ldc = nc + } + // Compute random C matrix + c := make([]float64, mc*ldc) + for i := range c { + c[i] = rnd.Float64() + } + + // Compute LQ + k := min(ma, na) + tau := make([]float64, k) + work := make([]float64, 1) + impl.Dgelqf(ma, na, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgelqf(ma, na, a, lda, tau, work, len(work)) + + // Build Q from result + q := constructQ("LQ", ma, na, a, lda, tau) + + cMat := blas64.General{ + Rows: mc, + Cols: nc, + Stride: ldc, + Data: make([]float64, len(c)), + } + copy(cMat.Data, c) + cMatCopy := blas64.General{ + Rows: cMat.Rows, + Cols: cMat.Cols, + Stride: cMat.Stride, + Data: make([]float64, len(cMat.Data)), + } + copy(cMatCopy.Data, cMat.Data) + switch { + default: + panic("bad test") + case side == blas.Left && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, cMatCopy, 0, cMat) + case side == blas.Left && trans == blas.Trans: + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, cMatCopy, 0, cMat) + case side == blas.Right && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, cMatCopy, q, 0, cMat) + case side == blas.Right && trans == blas.Trans: + blas64.Gemm(blas.NoTrans, blas.Trans, 1, cMatCopy, q, 0, cMat) + } + // Do Dorm2r ard compare + if side == blas.Left { + work = make([]float64, nc) + } else { + work = make([]float64, mc) + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + tauCopy := make([]float64, len(tau)) + copy(tauCopy, tau) + impl.Dorml2(side, trans, mc, nc, k, a, lda, tau, c, ldc, work) + if !floats.Equal(a, aCopy) { + t.Errorf("a changed in call") + } + if !floats.Equal(tau, tauCopy) { + t.Errorf("tau changed in call") + } + if !floats.EqualApprox(cMat.Data, c, 1e-14) { + isLeft := side == blas.Left + isTrans := trans == blas.Trans + t.Errorf("Multiplication mismatch. IsLeft = %v. IsTrans = %v", isLeft, isTrans) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dormlq.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormlq.go new file mode 100644 index 00000000..19302e21 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormlq.go @@ -0,0 +1,130 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dormlqer interface { + Dorml2er + Dormlq(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) +} + +func DormlqTest(t *testing.T, impl Dormlqer) { + rnd := rand.New(rand.NewSource(1)) + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { + for _, test := range []struct { + common, adim, cdim, lda, ldc int + }{ + {0, 0, 0, 0, 0}, + {6, 7, 8, 0, 0}, + {6, 8, 7, 0, 0}, + {7, 6, 8, 0, 0}, + {7, 8, 6, 0, 0}, + {8, 6, 7, 0, 0}, + {8, 7, 6, 0, 0}, + {100, 200, 300, 0, 0}, + {100, 300, 200, 0, 0}, + {200, 100, 300, 0, 0}, + {200, 300, 100, 0, 0}, + {300, 100, 200, 0, 0}, + {300, 200, 100, 0, 0}, + {100, 200, 300, 400, 500}, + {100, 300, 200, 400, 500}, + {200, 100, 300, 400, 500}, + {200, 300, 100, 400, 500}, + {300, 100, 200, 400, 500}, + {300, 200, 100, 400, 500}, + {100, 200, 300, 500, 400}, + {100, 300, 200, 500, 400}, + {200, 100, 300, 500, 400}, + {200, 300, 100, 500, 400}, + {300, 100, 200, 500, 400}, + {300, 200, 100, 500, 400}, + } { + var ma, na, mc, nc int + if side == blas.Left { + ma = test.adim + na = test.common + mc = test.common + nc = test.cdim + } else { + ma = test.adim + na = test.common + mc = test.cdim + nc = test.common + } + // Generate a random matrix + lda := test.lda + if lda == 0 { + lda = na + } + a := make([]float64, ma*lda) + for i := range a { + a[i] = rnd.Float64() + } + // Compute random C matrix + ldc := test.ldc + if ldc == 0 { + ldc = nc + } + c := make([]float64, mc*ldc) + for i := range c { + c[i] = rnd.Float64() + } + + // Compute LQ + k := min(ma, na) + tau := make([]float64, k) + work := make([]float64, 1) + impl.Dgelqf(ma, na, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgelqf(ma, na, a, lda, tau, work, len(work)) + + cCopy := make([]float64, len(c)) + copy(cCopy, c) + ans := make([]float64, len(c)) + copy(ans, cCopy) + + var nw int + if side == blas.Left { + nw = nc + } else { + nw = mc + } + work = make([]float64, max(1, nw)) + impl.Dorml2(side, trans, mc, nc, k, a, lda, tau, ans, ldc, work) + + var lwork int + switch wl { + case minimumWork: + lwork = nw + case optimumWork: + impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, -1) + lwork = int(work[0]) + case mediumWork: + work := make([]float64, 1) + impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, -1) + lwork = (int(work[0]) + nw) / 2 + } + lwork = max(1, lwork) + work = make([]float64, lwork) + + impl.Dormlq(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, lwork) + if !floats.EqualApprox(c, ans, 1e-13) { + t.Errorf("Dormqr and Dorm2r results mismatch") + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dormqr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormqr.go new file mode 100644 index 00000000..cfacd81b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormqr.go @@ -0,0 +1,154 @@ +// 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 testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dormqrer interface { + Dorm2rer + Dormqr(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64, lwork int) +} + +func DormqrTest(t *testing.T, impl Dormqrer) { + rnd := rand.New(rand.NewSource(1)) + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, test := range []struct { + common, adim, cdim, lda, ldc int + }{ + {6, 7, 8, 0, 0}, + {6, 8, 7, 0, 0}, + {7, 6, 8, 0, 0}, + {7, 8, 6, 0, 0}, + {8, 6, 7, 0, 0}, + {8, 7, 6, 0, 0}, + {100, 200, 300, 0, 0}, + {100, 300, 200, 0, 0}, + {200, 100, 300, 0, 0}, + {200, 300, 100, 0, 0}, + {300, 100, 200, 0, 0}, + {300, 200, 100, 0, 0}, + {100, 200, 300, 400, 500}, + {100, 300, 200, 400, 500}, + {200, 100, 300, 400, 500}, + {200, 300, 100, 400, 500}, + {300, 100, 200, 400, 500}, + {300, 200, 100, 400, 500}, + {100, 200, 300, 500, 400}, + {100, 300, 200, 500, 400}, + {200, 100, 300, 500, 400}, + {200, 300, 100, 500, 400}, + {300, 100, 200, 500, 400}, + {300, 200, 100, 500, 400}, + } { + var ma, na, mc, nc int + if side == blas.Left { + ma = test.common + na = test.adim + mc = test.common + nc = test.cdim + } else { + ma = test.common + na = test.adim + mc = test.cdim + nc = test.common + } + // Generate a random matrix + lda := test.lda + if lda == 0 { + lda = na + } + a := make([]float64, ma*lda) + for i := range a { + a[i] = rnd.Float64() + } + // Compute random C matrix + ldc := test.ldc + if ldc == 0 { + ldc = nc + } + c := make([]float64, mc*ldc) + for i := range c { + c[i] = rnd.Float64() + } + + // Compute QR + k := min(ma, na) + tau := make([]float64, k) + work := make([]float64, 1) + impl.Dgeqrf(ma, na, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgeqrf(ma, na, a, lda, tau, work, len(work)) + + cCopy := make([]float64, len(c)) + copy(cCopy, c) + ans := make([]float64, len(c)) + copy(ans, cCopy) + + if side == blas.Left { + work = make([]float64, nc) + } else { + work = make([]float64, mc) + } + impl.Dorm2r(side, trans, mc, nc, k, a, lda, tau, ans, ldc, work) + + // Make sure Dorm2r and Dormqr match with small work + for i := range work { + work[i] = rnd.Float64() + } + copy(c, cCopy) + impl.Dormqr(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, len(work)) + if !floats.EqualApprox(c, ans, 1e-12) { + t.Errorf("Dormqr and Dorm2r mismatch for small work") + } + + // Try with the optimum amount of work + copy(c, cCopy) + impl.Dormqr(side, trans, mc, nc, k, nil, lda, nil, nil, ldc, work, -1) + work = make([]float64, int(work[0])) + for i := range work { + work[i] = rnd.Float64() + } + impl.Dormqr(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, len(work)) + if !floats.EqualApprox(c, ans, 1e-12) { + t.Errorf("Dormqr and Dorm2r mismatch for full work") + fmt.Println("ccopy") + for i := 0; i < mc; i++ { + fmt.Println(cCopy[i*ldc : (i+1)*ldc]) + } + fmt.Println("ans =") + for i := 0; i < mc; i++ { + fmt.Println(ans[i*ldc : (i+1)*ldc]) + } + fmt.Println("c =") + for i := 0; i < mc; i++ { + fmt.Println(c[i*ldc : (i+1)*ldc]) + } + } + + // Try with amount of work that is less than + // optimal but still long enough to use the + // blocked code. + copy(c, cCopy) + if side == blas.Left { + work = make([]float64, 3*nc) + } else { + work = make([]float64, 3*mc) + } + impl.Dormqr(side, trans, mc, nc, k, a, lda, tau, c, ldc, work, len(work)) + if !floats.EqualApprox(c, ans, 1e-12) { + t.Errorf("Dormqr and Dorm2r mismatch for medium work") + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dormr2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormr2.go new file mode 100644 index 00000000..94a13488 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dormr2.go @@ -0,0 +1,137 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dormr2er interface { + Dgerqf(m, n int, a []float64, lda int, tau, work []float64, lwork int) + Dormr2(side blas.Side, trans blas.Transpose, m, n, k int, a []float64, lda int, tau, c []float64, ldc int, work []float64) +} + +func Dormr2Test(t *testing.T, impl Dormr2er) { + rnd := rand.New(rand.NewSource(1)) + for _, side := range []blas.Side{blas.Left, blas.Right} { + for _, trans := range []blas.Transpose{blas.NoTrans, blas.Trans} { + for _, test := range []struct { + common, adim, cdim, lda, ldc int + }{ + {3, 4, 5, 0, 0}, + {3, 5, 4, 0, 0}, + {4, 3, 5, 0, 0}, + {4, 5, 3, 0, 0}, + {5, 3, 4, 0, 0}, + {5, 4, 3, 0, 0}, + {3, 4, 5, 6, 20}, + {3, 5, 4, 6, 20}, + {4, 3, 5, 6, 20}, + {4, 5, 3, 6, 20}, + {5, 3, 4, 6, 20}, + {5, 4, 3, 6, 20}, + {3, 4, 5, 20, 6}, + {3, 5, 4, 20, 6}, + {4, 3, 5, 20, 6}, + {4, 5, 3, 20, 6}, + {5, 3, 4, 20, 6}, + {5, 4, 3, 20, 6}, + } { + ma := test.adim + na := test.common + var mc, nc int + if side == blas.Left { + mc = test.common + nc = test.cdim + } else { + mc = test.cdim + nc = test.common + } + + // Generate a random matrix + lda := test.lda + if lda == 0 { + lda = na + } + a := make([]float64, ma*lda) + for i := range a { + a[i] = rnd.Float64() + } + ldc := test.ldc + if ldc == 0 { + ldc = nc + } + // Compute random C matrix + c := make([]float64, mc*ldc) + for i := range c { + c[i] = rnd.Float64() + } + + // Compute RQ + k := min(ma, na) + tau := make([]float64, k) + work := make([]float64, 1) + impl.Dgerqf(ma, na, a, lda, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dgerqf(ma, na, a, lda, tau, work, len(work)) + + // Build Q from result + q := constructQ("RQ", ma, na, a, lda, tau) + + cMat := blas64.General{ + Rows: mc, + Cols: nc, + Stride: ldc, + Data: make([]float64, len(c)), + } + copy(cMat.Data, c) + cMatCopy := blas64.General{ + Rows: cMat.Rows, + Cols: cMat.Cols, + Stride: cMat.Stride, + Data: make([]float64, len(cMat.Data)), + } + copy(cMatCopy.Data, cMat.Data) + switch { + default: + panic("bad test") + case side == blas.Left && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, q, cMatCopy, 0, cMat) + case side == blas.Left && trans == blas.Trans: + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, cMatCopy, 0, cMat) + case side == blas.Right && trans == blas.NoTrans: + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, cMatCopy, q, 0, cMat) + case side == blas.Right && trans == blas.Trans: + blas64.Gemm(blas.NoTrans, blas.Trans, 1, cMatCopy, q, 0, cMat) + } + // Do Dorm2r ard compare + if side == blas.Left { + work = make([]float64, nc) + } else { + work = make([]float64, mc) + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + tauCopy := make([]float64, len(tau)) + copy(tauCopy, tau) + impl.Dormr2(side, trans, mc, nc, k, a[(ma-k)*lda:], lda, tau, c, ldc, work) + if !floats.Equal(a, aCopy) { + t.Errorf("a changed in call") + } + if !floats.Equal(tau, tauCopy) { + t.Errorf("tau changed in call") + } + if !floats.EqualApprox(cMat.Data, c, 1e-14) { + t.Errorf("Multiplication mismatch.\n Want %v \n got %v.", cMat.Data, c) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dpbtf2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpbtf2.go new file mode 100644 index 00000000..7f5498b8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpbtf2.go @@ -0,0 +1,47 @@ +package testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" +) + +type Dpbtf2er interface { + Dpbtf2(ul blas.Uplo, n, kd int, ab []float64, ldab int) (ok bool) + Dpotrfer +} + +func Dpbtf2Test(t *testing.T, impl Dpbtf2er) { + // Test random symmetric banded matrices against the full version. + rnd := rand.New(rand.NewSource(1)) + + for _, n := range []int{5, 10, 20} { + for _, kb := range []int{0, 1, 3, n - 1} { + for _, ldoff := range []int{0, 4} { + for _, ul := range []blas.Uplo{blas.Upper, blas.Lower} { + ldab := kb + 1 + ldoff + sym, band := randSymBand(ul, n, ldab, kb, rnd) + + // Compute the Cholesky decomposition of the symmetric matrix. + ok := impl.Dpotrf(ul, sym.N, sym.Data, sym.Stride) + if !ok { + panic("bad test: symmetric cholesky decomp failed") + } + + // Compute the Cholesky decomposition of the banded matrix. + ok = impl.Dpbtf2(band.Uplo, band.N, band.K, band.Data, band.Stride) + if !ok { + t.Errorf("SymBand cholesky decomp failed") + } + + // Compare the result to the Symmetric decomposition. + sb := symBandToSym(ul, band.Data, n, kb, ldab) + if !equalApproxSymmetric(sym, sb, 1e-10) { + t.Errorf("chol mismatch banded and sym. n = %v, kb = %v, ldoff = %v", n, kb, ldoff) + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dpocon.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpocon.go new file mode 100644 index 00000000..87b6cca0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpocon.go @@ -0,0 +1,157 @@ +// 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 testlapack + +import ( + "log" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dpoconer interface { + Dpotrfer + Dgeconer + Dlansy(norm lapack.MatrixNorm, uplo blas.Uplo, n int, a []float64, lda int, work []float64) float64 + Dpocon(uplo blas.Uplo, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 +} + +func DpoconTest(t *testing.T, impl Dpoconer) { + for _, test := range []struct { + a []float64 + n int + cond float64 + uplo blas.Uplo + }{ + { + a: []float64{ + 89, 59, 77, + 0, 107, 59, + 0, 0, 89, + }, + uplo: blas.Upper, + n: 3, + cond: 0.050052137643379, + }, + { + a: []float64{ + 89, 0, 0, + 59, 107, 0, + 77, 59, 89, + }, + uplo: blas.Lower, + n: 3, + cond: 0.050052137643379, + }, + // Dgecon does not match Dpocon for this case. https://github.com/xianyi/OpenBLAS/issues/664. + { + a: []float64{ + 2.9995576045549965, -2.0898894566158663, 3.965560740124006, + 0, 1.9634729526261008, -2.8681002706874104, + 0, 0, 5.502416670471008, + }, + uplo: blas.Upper, + n: 3, + cond: 0.024054837369015203, + }, + } { + n := test.n + a := make([]float64, len(test.a)) + copy(a, test.a) + lda := n + uplo := test.uplo + work := make([]float64, 3*n) + anorm := impl.Dlansy(lapack.MaxColumnSum, uplo, n, a, lda, work) + // Compute cholesky decomposition + ok := impl.Dpotrf(uplo, n, a, lda) + if !ok { + t.Errorf("Bad test, matrix not positive definite") + continue + } + iwork := make([]int, n) + cond := impl.Dpocon(uplo, n, a, lda, anorm, work, iwork) + // Error if not the same order, otherwise log the difference. + if !floats.EqualWithinAbsOrRel(cond, test.cond, 1e0, 1e0) { + t.Errorf("Cond mismatch. Want %v, got %v.", test.cond, cond) + } else if !floats.EqualWithinAbsOrRel(cond, test.cond, 1e-14, 1e-14) { + log.Printf("Dpocon cond mismatch. Want %v, got %v.", test.cond, cond) + } + } + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + // Randomized tests compared against Dgecon. + for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} { + for _, test := range []struct { + n, lda int + }{ + {3, 0}, + {3, 5}, + } { + for trial := 0; trial < 100; trial++ { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + + // Multiply a by itself to make it symmetric positive definite. + aCopy := make([]float64, len(a)) + copy(aCopy, a) + bi.Dgemm(blas.Trans, blas.NoTrans, n, n, n, 1, aCopy, lda, aCopy, lda, 0, a, lda) + + aDat := make([]float64, len(aCopy)) + copy(aDat, a) + + aDense := make([]float64, len(a)) + if uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := a[i*lda+j] + aDense[i*lda+j] = v + aDense[j*lda+i] = v + } + } + } else { + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + v := a[i*lda+j] + aDense[i*lda+j] = v + aDense[j*lda+i] = v + } + } + } + work := make([]float64, 4*n) + iwork := make([]int, n) + + anorm := impl.Dlansy(lapack.MaxColumnSum, uplo, n, a, lda, work) + ok := impl.Dpotrf(uplo, n, a, lda) + if !ok { + t.Errorf("Bad test, matrix not positive definite") + continue + } + got := impl.Dpocon(uplo, n, a, lda, anorm, work, iwork) + + denseNorm := impl.Dlange(lapack.MaxColumnSum, n, n, aDense, lda, work) + ipiv := make([]int, n) + impl.Dgetrf(n, n, aDense, lda, ipiv) + want := impl.Dgecon(lapack.MaxColumnSum, n, aDense, lda, denseNorm, work, iwork) + // Error if not the same order, otherwise log the difference. + if !floats.EqualWithinAbsOrRel(want, got, 1e0, 1e0) { + t.Errorf("Dpocon and Dgecon mismatch. Dpocon %v, Dgecon %v.", got, want) + } else if !floats.EqualWithinAbsOrRel(want, got, 1e-14, 1e-14) { + log.Printf("Dpocon and Dgecon mismatch. Dpocon %v, Dgecon %v.", got, want) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dpotf2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpotf2.go new file mode 100644 index 00000000..d6e1691c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpotf2.go @@ -0,0 +1,117 @@ +// 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 testlapack + +import ( + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" +) + +type Dpotf2er interface { + Dpotf2(ul blas.Uplo, n int, a []float64, lda int) (ok bool) +} + +func Dpotf2Test(t *testing.T, impl Dpotf2er) { + for _, test := range []struct { + a [][]float64 + pos bool + U [][]float64 + }{ + { + a: [][]float64{ + {23, 37, 34, 32}, + {108, 71, 48, 48}, + {109, 109, 67, 58}, + {106, 107, 106, 63}, + }, + pos: true, + U: [][]float64{ + {4.795831523312719, 7.715033320111766, 7.089490077940543, 6.672461249826393}, + {0, 3.387958215439679, -1.976308959006481, -1.026654004678691}, + {0, 0, 3.582364210034111, 2.419258947036024}, + {0, 0, 0, 3.401680257083044}, + }, + }, + { + a: [][]float64{ + {8, 2}, + {2, 4}, + }, + pos: true, + U: [][]float64{ + {2.82842712474619, 0.707106781186547}, + {0, 1.870828693386971}, + }, + }, + } { + testDpotf2(t, impl, test.pos, test.a, test.U, len(test.a[0]), blas.Upper) + testDpotf2(t, impl, test.pos, test.a, test.U, len(test.a[0])+5, blas.Upper) + aT := transpose(test.a) + L := transpose(test.U) + testDpotf2(t, impl, test.pos, aT, L, len(test.a[0]), blas.Lower) + testDpotf2(t, impl, test.pos, aT, L, len(test.a[0])+5, blas.Lower) + } +} + +func testDpotf2(t *testing.T, impl Dpotf2er, testPos bool, a, ans [][]float64, stride int, ul blas.Uplo) { + aFlat := flattenTri(a, stride, ul) + ansFlat := flattenTri(ans, stride, ul) + pos := impl.Dpotf2(ul, len(a[0]), aFlat, stride) + if pos != testPos { + t.Errorf("Positive definite mismatch: Want %v, Got %v", testPos, pos) + return + } + if testPos && !floats.EqualApprox(ansFlat, aFlat, 1e-14) { + t.Errorf("Result mismatch: Want %v, Got %v", ansFlat, aFlat) + } +} + +// flattenTri with a certain stride. stride must be >= dimension. Puts repeatable +// nonce values in non-accessed places +func flattenTri(a [][]float64, stride int, ul blas.Uplo) []float64 { + m := len(a) + n := len(a[0]) + if stride < n { + panic("bad stride") + } + upper := ul == blas.Upper + v := make([]float64, m*stride) + count := 1000.0 + for i := 0; i < m; i++ { + for j := 0; j < stride; j++ { + if j >= n || (upper && j < i) || (!upper && j > i) { + // not accessed, so give a unique crazy number + v[i*stride+j] = count + count++ + continue + } + v[i*stride+j] = a[i][j] + } + } + return v +} + +func transpose(a [][]float64) [][]float64 { + m := len(a) + n := len(a[0]) + if m != n { + panic("not square") + } + aNew := make([][]float64, m) + for i := 0; i < m; i++ { + aNew[i] = make([]float64, n) + } + for i := 0; i < m; i++ { + if len(a[i]) != n { + panic("bad n size") + } + for j := 0; j < n; j++ { + aNew[j][i] = a[i][j] + } + } + return aNew +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dpotrf.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpotrf.go new file mode 100644 index 00000000..d4318228 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dpotrf.go @@ -0,0 +1,135 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dpotrfer interface { + Dpotrf(ul blas.Uplo, n int, a []float64, lda int) (ok bool) +} + +func DpotrfTest(t *testing.T, impl Dpotrfer) { + const tol = 1e-13 + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for tc, test := range []struct { + n int + lda int + }{ + {1, 0}, + {2, 0}, + {3, 0}, + {10, 0}, + {30, 0}, + {63, 0}, + {65, 0}, + {127, 0}, + {129, 0}, + {500, 0}, + {1, 10}, + {2, 10}, + {3, 10}, + {10, 20}, + {30, 50}, + {63, 100}, + {65, 100}, + {127, 200}, + {129, 200}, + {500, 600}, + } { + n := test.n + + // Random diagonal matrix D with positive entries. + d := make([]float64, n) + Dlatm1(d, 4, 10000, false, 1, rnd) + + // Construct a positive definite matrix A as + // A = U * D * U^T + // where U is a random orthogonal matrix. + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + Dlagsy(n, 0, d, a, lda, rnd, make([]float64, 2*n)) + + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + ok := impl.Dpotrf(uplo, n, a, lda) + if !ok { + t.Errorf("Case %v: unexpected failure for positive definite matrix", tc) + continue + } + + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + a[i*lda+j] = 0 + } + } + case blas.Lower: + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + a[i*lda+j] = 0 + } + } + default: + panic("bad uplo") + } + + ans := make([]float64, len(a)) + switch uplo { + case blas.Upper: + // Multiply U^T * U. + bi.Dsyrk(uplo, blas.Trans, n, n, 1, a, lda, 0, ans, lda) + case blas.Lower: + // Multiply L * L^T. + bi.Dsyrk(uplo, blas.NoTrans, n, n, 1, a, lda, 0, ans, lda) + } + + match := true + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + if !floats.EqualWithinAbsOrRel(ans[i*lda+j], aCopy[i*lda+j], tol, tol) { + match = false + } + } + } + case blas.Lower: + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + if !floats.EqualWithinAbsOrRel(ans[i*lda+j], aCopy[i*lda+j], tol, tol) { + match = false + } + } + } + } + if !match { + t.Errorf("Case %v (uplo=%v,n=%v,lda=%v): unexpected result", tc, uplo, n, lda) + } + + // Make one element of D negative so that A is not + // positive definite, and check that Dpotrf fails. + d[0] *= -1 + Dlagsy(n, 0, d, a, lda, rnd, make([]float64, 2*n)) + ok = impl.Dpotrf(uplo, n, a, lda) + if ok { + t.Errorf("Case %v: unexpected success for not positive definite matrix", tc) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/drscl.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/drscl.go new file mode 100644 index 00000000..df87db40 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/drscl.go @@ -0,0 +1,52 @@ +// 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 testlapack + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Drscler interface { + Drscl(n int, a float64, x []float64, incX int) +} + +func DrsclTest(t *testing.T, impl Drscler) { + for _, test := range []struct { + x []float64 + a float64 + }{ + { + x: []float64{1, 2, 3, 4, 5}, + a: 4, + }, + { + x: []float64{1, 2, 3, 4, 5}, + a: math.MaxFloat64, + }, + { + x: []float64{1, 2, 3, 4, 5}, + a: 1e-307, + }, + } { + xcopy := make([]float64, len(test.x)) + copy(xcopy, test.x) + + // Cannot test the scaling directly because of floating point scaling issues + // (the purpose of Drscl). Instead, check that scaling and scaling back + // yeilds approximately x. If overflow or underflow occurs then the scaling + // won't match. + impl.Drscl(len(test.x), test.a, xcopy, 1) + if floats.Equal(xcopy, test.x) { + t.Errorf("x unchanged during call to drscl. a = %v, x = %v.", test.a, test.x) + } + impl.Drscl(len(test.x), 1/test.a, xcopy, 1) + if !floats.EqualApprox(xcopy, test.x, 1e-14) { + t.Errorf("x not equal after scaling and unscaling. a = %v, x = %v.", test.a, test.x) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dsteqr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsteqr.go new file mode 100644 index 00000000..1fffdb1e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsteqr.go @@ -0,0 +1,171 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dsteqrer interface { + Dsteqr(compz lapack.EVComp, n int, d, e, z []float64, ldz int, work []float64) (ok bool) + Dorgtrer +} + +func DsteqrTest(t *testing.T, impl Dsteqrer) { + rnd := rand.New(rand.NewSource(1)) + for _, compz := range []lapack.EVComp{lapack.OriginalEV, lapack.TridiagEV} { + for _, test := range []struct { + n, lda int + }{ + {1, 0}, + {4, 0}, + {8, 0}, + {10, 0}, + + {2, 10}, + {8, 10}, + {10, 20}, + } { + for cas := 0; cas < 100; cas++ { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + d := make([]float64, n) + for i := range d { + d[i] = rnd.Float64() + } + e := make([]float64, n-1) + for i := range e { + e[i] = rnd.Float64() + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.Float64() + } + dCopy := make([]float64, len(d)) + copy(dCopy, d) + eCopy := make([]float64, len(e)) + copy(eCopy, e) + aCopy := make([]float64, len(a)) + copy(aCopy, a) + if compz == lapack.OriginalEV { + // Compute triangular decomposition and orthonormal matrix. + uplo := blas.Upper + tau := make([]float64, n) + work := make([]float64, 1) + impl.Dsytrd(blas.Upper, n, a, lda, d, e, tau, work, -1) + work = make([]float64, int(work[0])) + impl.Dsytrd(uplo, n, a, lda, d, e, tau, work, len(work)) + impl.Dorgtr(uplo, n, a, lda, tau, work, len(work)) + } else { + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = 0 + if i == j { + a[i*lda+j] = 1 + } + } + } + } + work := make([]float64, 2*n) + + aDecomp := make([]float64, len(a)) + copy(aDecomp, a) + dDecomp := make([]float64, len(d)) + copy(dDecomp, d) + eDecomp := make([]float64, len(e)) + copy(eDecomp, e) + impl.Dsteqr(compz, n, d, e, a, lda, work) + dAns := make([]float64, len(d)) + copy(dAns, d) + + var truth blas64.General + if compz == lapack.OriginalEV { + truth = blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := aCopy[i*lda+j] + truth.Data[i*truth.Stride+j] = v + truth.Data[j*truth.Stride+i] = v + } + } + } else { + truth = blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + for i := 0; i < n; i++ { + truth.Data[i*truth.Stride+i] = dCopy[i] + if i != n-1 { + truth.Data[(i+1)*truth.Stride+i] = eCopy[i] + truth.Data[i*truth.Stride+i+1] = eCopy[i] + } + } + } + + V := blas64.General{ + Rows: n, + Cols: n, + Stride: lda, + Data: a, + } + if !eigenDecompCorrect(d, truth, V) { + t.Errorf("Eigen reconstruction mismatch. fromFull = %v, n = %v", + compz == lapack.OriginalEV, n) + } + + // Compare eigenvalues when not computing eigenvectors. + for i := range work { + work[i] = rnd.Float64() + } + impl.Dsteqr(lapack.None, n, dDecomp, eDecomp, aDecomp, lda, work) + if !floats.EqualApprox(d, dAns, 1e-8) { + t.Errorf("Eigenvalue mismatch when eigenvectors not computed") + } + } + } + } +} + +// eigenDecompCorrect returns whether the eigen decomposition is correct. +// It checks if +// A * v ≈ λ * v +// where the eigenvalues λ are stored in values, and the eigenvectors are stored +// in the columns of v. +func eigenDecompCorrect(values []float64, A, V blas64.General) bool { + n := A.Rows + for i := 0; i < n; i++ { + lambda := values[i] + vector := make([]float64, n) + ans2 := make([]float64, n) + for j := range vector { + v := V.Data[j*V.Stride+i] + vector[j] = v + ans2[j] = lambda * v + } + v := blas64.Vector{Inc: 1, Data: vector} + ans1 := blas64.Vector{Inc: 1, Data: make([]float64, n)} + blas64.Gemv(blas.NoTrans, 1, A, v, 0, ans1) + if !floats.EqualApprox(ans1.Data, ans2, 1e-8) { + return false + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dsterf.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsterf.go new file mode 100644 index 00000000..66b4a9e1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsterf.go @@ -0,0 +1,126 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type Dsterfer interface { + Dgetrfer + Dsterf(n int, d, e []float64) (ok bool) +} + +func DsterfTest(t *testing.T, impl Dsterfer) { + // Hand coded tests. + for cas, test := range []struct { + d []float64 + e []float64 + n int + + ans []float64 + }{ + // Computed from Fortran code. + { + d: []float64{1, 3, 4, 6}, + e: []float64{2, 4, 5}, + n: 4, + ans: []float64{11.046227528488854, 4.795922173417400, -2.546379458290125, 0.704229756383872}, + }, + } { + n := test.n + d := make([]float64, len(test.d)) + copy(d, test.d) + e := make([]float64, len(test.e)) + copy(e, test.e) + ok := impl.Dsterf(n, d, e) + if !ok { + t.Errorf("Case %d, Eigenvalue decomposition failed", cas) + continue + } + ans := make([]float64, len(test.ans)) + copy(ans, test.ans) + sort.Float64s(ans) + if !floats.EqualApprox(ans, d, 1e-10) { + t.Errorf("eigenvalue mismatch") + } + } + + rnd := rand.New(rand.NewSource(1)) + // Probabilistic tests. + for _, n := range []int{4, 6, 10} { + for cas := 0; cas < 10; cas++ { + d := make([]float64, n) + for i := range d { + d[i] = rnd.NormFloat64() + } + dCopy := make([]float64, len(d)) + copy(dCopy, d) + e := make([]float64, n-1) + for i := range e { + e[i] = rnd.NormFloat64() + } + eCopy := make([]float64, len(e)) + copy(eCopy, e) + + ok := impl.Dsterf(n, d, e) + if !ok { + t.Errorf("Eigenvalue decomposition failed") + continue + } + + // Test that the eigenvalues are sorted. + if !sort.Float64sAreSorted(d) { + t.Errorf("Values are not sorted") + } + + // Construct original tridagional matrix. + lda := n + a := make([]float64, n*lda) + for i := 0; i < n; i++ { + a[i*lda+i] = dCopy[i] + if i != n-1 { + a[i*lda+i+1] = eCopy[i] + a[(i+1)*lda+i] = eCopy[i] + } + } + + asub := make([]float64, len(a)) + ipiv := make([]int, n) + + // Test that they are actually eigenvalues by computing the + // determinant of A - λI. + // TODO(btracey): Replace this test with a more numerically stable + // test. + for _, lambda := range d { + copy(asub, a) + for i := 0; i < n; i++ { + asub[i*lda+i] -= lambda + } + + // Compute LU. + ok := impl.Dgetrf(n, n, asub, lda, ipiv) + if !ok { + // Definitely singular. + continue + } + // Compute determinant. + var logdet float64 + for i := 0; i < n; i++ { + v := asub[i*lda+i] + logdet += math.Log(math.Abs(v)) + } + if math.Exp(logdet) > 2 { + t.Errorf("Incorrect singular value. n = %d, cas = %d, det = %v", n, cas, math.Exp(logdet)) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dsyev.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsyev.go new file mode 100644 index 00000000..e70088c9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsyev.go @@ -0,0 +1,115 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dsyever interface { + Dsyev(jobz lapack.EVJob, uplo blas.Uplo, n int, a []float64, lda int, w, work []float64, lwork int) (ok bool) +} + +func DsyevTest(t *testing.T, impl Dsyever) { + rnd := rand.New(rand.NewSource(1)) + for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} { + for _, test := range []struct { + n, lda int + }{ + {1, 0}, + {2, 0}, + {5, 0}, + {10, 0}, + {100, 0}, + + {1, 5}, + {2, 5}, + {5, 10}, + {10, 20}, + {100, 110}, + } { + for cas := 0; cas < 10; cas++ { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + w := make([]float64, n) + for i := range w { + w[i] = rnd.NormFloat64() + } + + work := make([]float64, 1) + impl.Dsyev(lapack.ComputeEV, uplo, n, a, lda, w, work, -1) + work = make([]float64, int(work[0])) + impl.Dsyev(lapack.ComputeEV, uplo, n, a, lda, w, work, len(work)) + + // Check that the decomposition is correct + orig := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + if uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := aCopy[i*lda+j] + orig.Data[i*orig.Stride+j] = v + orig.Data[j*orig.Stride+i] = v + } + } + } else { + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + v := aCopy[i*lda+j] + orig.Data[i*orig.Stride+j] = v + orig.Data[j*orig.Stride+i] = v + } + } + } + + V := blas64.General{ + Rows: n, + Cols: n, + Stride: lda, + Data: a, + } + + if !eigenDecompCorrect(w, orig, V) { + t.Errorf("Decomposition mismatch") + } + + // Check that the decomposition is correct when the eigenvectors + // are not computed. + wAns := make([]float64, len(w)) + copy(wAns, w) + copy(a, aCopy) + for i := range w { + w[i] = rnd.Float64() + } + for i := range work { + work[i] = rnd.Float64() + } + impl.Dsyev(lapack.None, uplo, n, a, lda, w, work, len(work)) + if !floats.EqualApprox(w, wAns, 1e-8) { + t.Errorf("Eigenvalue mismatch when vectors not computed") + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dsytd2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsytd2.go new file mode 100644 index 00000000..af71cf1f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsytd2.go @@ -0,0 +1,205 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dsytd2er interface { + Dsytd2(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau []float64) +} + +func Dsytd2Test(t *testing.T, impl Dsytd2er) { + rnd := rand.New(rand.NewSource(1)) + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, test := range []struct { + n, lda int + }{ + {3, 0}, + {4, 0}, + {5, 0}, + + {3, 10}, + {4, 10}, + {5, 10}, + } { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.NormFloat64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + + d := make([]float64, n) + for i := range d { + d[i] = math.NaN() + } + e := make([]float64, n-1) + for i := range e { + e[i] = math.NaN() + } + tau := make([]float64, n-1) + for i := range tau { + tau[i] = math.NaN() + } + + impl.Dsytd2(uplo, n, a, lda, d, e, tau) + + // Construct Q + qMat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + qCopy := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, len(qMat.Data)), + } + // Set Q to I. + for i := 0; i < n; i++ { + qMat.Data[i*qMat.Stride+i] = 1 + } + for i := 0; i < n-1; i++ { + hMat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + // Set H to I. + for i := 0; i < n; i++ { + hMat.Data[i*hMat.Stride+i] = 1 + } + var vi blas64.Vector + if uplo == blas.Upper { + vi = blas64.Vector{ + Inc: 1, + Data: make([]float64, n), + } + for j := 0; j < i; j++ { + vi.Data[j] = a[j*lda+i+1] + } + vi.Data[i] = 1 + } else { + vi = blas64.Vector{ + Inc: 1, + Data: make([]float64, n), + } + vi.Data[i+1] = 1 + for j := i + 2; j < n; j++ { + vi.Data[j] = a[j*lda+i] + } + } + blas64.Ger(-tau[i], vi, vi, hMat) + copy(qCopy.Data, qMat.Data) + + // Multiply q by the new h. + if uplo == blas.Upper { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, hMat, qCopy, 0, qMat) + } else { + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qCopy, hMat, 0, qMat) + } + } + // Check that Q is orthonormal + othonormal := true + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dot := blas64.Dot(n, + blas64.Vector{Inc: 1, Data: qMat.Data[i*qMat.Stride:]}, + blas64.Vector{Inc: 1, Data: qMat.Data[j*qMat.Stride:]}, + ) + if i == j { + if math.Abs(dot-1) > 1e-10 { + othonormal = false + } + } else { + if math.Abs(dot) > 1e-10 { + othonormal = false + } + } + } + } + if !othonormal { + t.Errorf("Q not orthonormal") + } + + // Compute Q^T * A * Q. + aMat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, len(a)), + } + + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + v := aCopy[i*lda+j] + if uplo == blas.Lower { + v = aCopy[j*lda+i] + } + aMat.Data[i*aMat.Stride+j] = v + aMat.Data[j*aMat.Stride+i] = v + } + } + + tmp := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + + ans := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + + blas64.Gemm(blas.Trans, blas.NoTrans, 1, qMat, aMat, 0, tmp) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmp, qMat, 0, ans) + + // Compare with T. + tMat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + for i := 0; i < n-1; i++ { + tMat.Data[i*tMat.Stride+i] = d[i] + tMat.Data[i*tMat.Stride+i+1] = e[i] + tMat.Data[(i+1)*tMat.Stride+i] = e[i] + } + tMat.Data[(n-1)*tMat.Stride+n-1] = d[n-1] + + same := true + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if math.Abs(ans.Data[i*ans.Stride+j]-tMat.Data[i*tMat.Stride+j]) > 1e-10 { + same = false + } + } + } + if !same { + t.Errorf("Matrix answer mismatch") + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dsytrd.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsytrd.go new file mode 100644 index 00000000..74e2beba --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dsytrd.go @@ -0,0 +1,160 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dsytrder interface { + Dsytrd(uplo blas.Uplo, n int, a []float64, lda int, d, e, tau, work []float64, lwork int) + + Dorgqr(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) + Dorgql(m, n, k int, a []float64, lda int, tau, work []float64, lwork int) +} + +func DsytrdTest(t *testing.T, impl Dsytrder) { + const tol = 1e-13 + rnd := rand.New(rand.NewSource(1)) + for tc, test := range []struct { + n, lda int + }{ + {1, 0}, + {2, 0}, + {3, 0}, + {4, 0}, + {10, 0}, + {50, 0}, + {100, 0}, + {150, 0}, + {300, 0}, + + {1, 3}, + {2, 3}, + {3, 7}, + {4, 9}, + {10, 20}, + {50, 70}, + {100, 120}, + {150, 170}, + {300, 320}, + } { + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, wl := range []worklen{minimumWork, mediumWork, optimumWork} { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := randomGeneral(n, n, lda, rnd) + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + a.Data[i*a.Stride+j] = a.Data[j*a.Stride+i] + } + } + aCopy := cloneGeneral(a) + + d := nanSlice(n) + e := nanSlice(n - 1) + tau := nanSlice(n - 1) + + var lwork int + switch wl { + case minimumWork: + lwork = 1 + case mediumWork: + work := make([]float64, 1) + impl.Dsytrd(uplo, n, a.Data, a.Stride, d, e, tau, work, -1) + lwork = (int(work[0]) + 1) / 2 + lwork = max(1, lwork) + case optimumWork: + work := make([]float64, 1) + impl.Dsytrd(uplo, n, a.Data, a.Stride, d, e, tau, work, -1) + lwork = int(work[0]) + } + work := make([]float64, lwork) + + impl.Dsytrd(uplo, n, a.Data, a.Stride, d, e, tau, work, lwork) + + prefix := fmt.Sprintf("Case #%v: uplo=%v,n=%v,lda=%v,work=%v", + tc, uplo, n, lda, wl) + + if !generalOutsideAllNaN(a) { + t.Errorf("%v: out-of-range write to A", prefix) + } + + // Extract Q by doing what Dorgtr does. + q := cloneGeneral(a) + if uplo == blas.Upper { + for j := 0; j < n-1; j++ { + for i := 0; i < j; i++ { + q.Data[i*q.Stride+j] = q.Data[i*q.Stride+j+1] + } + q.Data[(n-1)*q.Stride+j] = 0 + } + for i := 0; i < n-1; i++ { + q.Data[i*q.Stride+n-1] = 0 + } + q.Data[(n-1)*q.Stride+n-1] = 1 + if n > 1 { + work = make([]float64, n-1) + impl.Dorgql(n-1, n-1, n-1, q.Data, q.Stride, tau, work, len(work)) + } + } else { + for j := n - 1; j > 0; j-- { + q.Data[j] = 0 + for i := j + 1; i < n; i++ { + q.Data[i*q.Stride+j] = q.Data[i*q.Stride+j-1] + } + } + q.Data[0] = 1 + for i := 1; i < n; i++ { + q.Data[i*q.Stride] = 0 + } + if n > 1 { + work = make([]float64, n-1) + impl.Dorgqr(n-1, n-1, n-1, q.Data[q.Stride+1:], q.Stride, tau, work, len(work)) + } + } + if !isOrthonormal(q) { + t.Errorf("%v: Q not orthogonal", prefix) + } + + // Contruct symmetric tridiagonal T from d and e. + tMat := zeros(n, n, n) + for i := 0; i < n; i++ { + tMat.Data[i*tMat.Stride+i] = d[i] + } + if uplo == blas.Upper { + for j := 1; j < n; j++ { + tMat.Data[(j-1)*tMat.Stride+j] = e[j-1] + tMat.Data[j*tMat.Stride+j-1] = e[j-1] + } + } else { + for j := 0; j < n-1; j++ { + tMat.Data[(j+1)*tMat.Stride+j] = e[j] + tMat.Data[j*tMat.Stride+j+1] = e[j] + } + } + + // Compute Q^T * A * Q. + tmp := zeros(n, n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, aCopy, 0, tmp) + got := zeros(n, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmp, q, 0, got) + + // Compare with T. + if !equalApproxGeneral(got, tMat, tol) { + t.Errorf("%v: Q^T*A*Q != T", prefix) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dtgsja.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtgsja.go new file mode 100644 index 00000000..af4cec80 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtgsja.go @@ -0,0 +1,165 @@ +// 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 testlapack + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dtgsjaer interface { + Dlanger + Dtgsja(jobU, jobV, jobQ lapack.GSVDJob, m, p, n, k, l int, a []float64, lda int, b []float64, ldb int, tola, tolb float64, alpha, beta, u []float64, ldu int, v []float64, ldv int, q []float64, ldq int, work []float64) (cycles int, ok bool) +} + +func DtgsjaTest(t *testing.T, impl Dtgsjaer) { + rnd := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + m, p, n, k, l, lda, ldb, ldu, ldv, ldq int + + ok bool + }{ + {m: 5, p: 5, n: 5, k: 2, l: 2, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 5, k: 4, l: 1, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 10, k: 2, l: 2, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 10, k: 4, l: 1, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 10, k: 4, l: 2, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 5, n: 5, k: 2, l: 2, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 5, n: 5, k: 4, l: 1, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 10, n: 10, k: 5, l: 3, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 10, p: 10, n: 10, k: 6, l: 4, lda: 0, ldb: 0, ldu: 0, ldv: 0, ldq: 0, ok: true}, + {m: 5, p: 5, n: 5, k: 2, l: 2, lda: 10, ldb: 10, ldu: 10, ldv: 10, ldq: 10, ok: true}, + {m: 5, p: 5, n: 5, k: 4, l: 1, lda: 10, ldb: 10, ldu: 10, ldv: 10, ldq: 10, ok: true}, + {m: 5, p: 5, n: 10, k: 2, l: 2, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20, ok: true}, + {m: 5, p: 5, n: 10, k: 4, l: 1, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20, ok: true}, + {m: 5, p: 5, n: 10, k: 4, l: 2, lda: 20, ldb: 20, ldu: 10, ldv: 10, ldq: 20, ok: true}, + {m: 10, p: 5, n: 5, k: 2, l: 2, lda: 10, ldb: 10, ldu: 20, ldv: 10, ldq: 10, ok: true}, + {m: 10, p: 5, n: 5, k: 4, l: 1, lda: 10, ldb: 10, ldu: 20, ldv: 10, ldq: 10, ok: true}, + {m: 10, p: 10, n: 10, k: 5, l: 3, lda: 20, ldb: 20, ldu: 20, ldv: 20, ldq: 20, ok: true}, + {m: 10, p: 10, n: 10, k: 6, l: 4, lda: 20, ldb: 20, ldu: 20, ldv: 20, ldq: 20, ok: true}, + } { + m := test.m + p := test.p + n := test.n + k := test.k + l := test.l + lda := test.lda + if lda == 0 { + lda = n + } + ldb := test.ldb + if ldb == 0 { + ldb = n + } + ldu := test.ldu + if ldu == 0 { + ldu = m + } + ldv := test.ldv + if ldv == 0 { + ldv = p + } + ldq := test.ldq + if ldq == 0 { + ldq = n + } + + a := blockedUpperTriGeneral(m, n, k, l, lda, true, rnd) + aCopy := cloneGeneral(a) + b := blockedUpperTriGeneral(p, n, k, l, ldb, false, rnd) + bCopy := cloneGeneral(b) + + tola := float64(max(m, n)) * impl.Dlange(lapack.NormFrob, m, n, a.Data, a.Stride, nil) * dlamchE + tolb := float64(max(p, n)) * impl.Dlange(lapack.NormFrob, p, n, b.Data, b.Stride, nil) * dlamchE + + alpha := make([]float64, n) + beta := make([]float64, n) + + work := make([]float64, 2*n) + + u := nanGeneral(m, m, ldu) + v := nanGeneral(p, p, ldv) + q := nanGeneral(n, n, ldq) + + _, ok := impl.Dtgsja(lapack.GSVDUnit, lapack.GSVDUnit, lapack.GSVDUnit, + m, p, n, k, l, + a.Data, a.Stride, + b.Data, b.Stride, + tola, tolb, + alpha, beta, + u.Data, u.Stride, + v.Data, v.Stride, + q.Data, q.Stride, + work) + + if !ok { + if test.ok { + t.Errorf("test %d unexpectedly did not converge", cas) + } + continue + } + + // Check orthogonality of U, V and Q. + if !isOrthonormal(u) { + t.Errorf("test %d: U is not orthogonal\n%+v", cas, u) + } + if !isOrthonormal(v) { + t.Errorf("test %d: V is not orthogonal\n%+v", cas, v) + } + if !isOrthonormal(q) { + t.Errorf("test %d: Q is not orthogonal\n%+v", cas, q) + } + + // Check C^2 + S^2 = I. + var elements []float64 + if m-k-l >= 0 { + elements = alpha[k : k+l] + } else { + elements = alpha[k:m] + } + for i := range elements { + i += k + d := alpha[i]*alpha[i] + beta[i]*beta[i] + if !floats.EqualWithinAbsOrRel(d, 1, 1e-14, 1e-14) { + t.Errorf("test %d: alpha_%d^2 + beta_%d^2 != 1: got: %v", cas, i, i, d) + } + } + + zeroR, d1, d2 := constructGSVDresults(n, p, m, k, l, a, b, alpha, beta) + + // Check U^T*A*Q = D1*[ 0 R ]. + uTmp := nanGeneral(m, n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, u, aCopy, 0, uTmp) + uAns := nanGeneral(m, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, uTmp, q, 0, uAns) + + d10r := nanGeneral(m, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, d1, zeroR, 0, d10r) + + if !equalApproxGeneral(uAns, d10r, 1e-14) { + t.Errorf("test %d: U^T*A*Q != D1*[ 0 R ]\nU^T*A*Q:\n%+v\nD1*[ 0 R ]:\n%+v", + cas, uAns, d10r) + } + + // Check V^T*B*Q = D2*[ 0 R ]. + vTmp := nanGeneral(p, n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, v, bCopy, 0, vTmp) + vAns := nanGeneral(p, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, vTmp, q, 0, vAns) + + d20r := nanGeneral(p, n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, d2, zeroR, 0, d20r) + + if !equalApproxGeneral(vAns, d20r, 1e-14) { + t.Errorf("test %d: V^T*B*Q != D2*[ 0 R ]\nV^T*B*Q:\n%+v\nD2*[ 0 R ]:\n%+v", + cas, vAns, d20r) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrcon.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrcon.go new file mode 100644 index 00000000..1e490ca9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrcon.go @@ -0,0 +1,184 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dtrconer interface { + Dgeconer + Dtrcon(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int, work []float64, iwork []int) float64 +} + +func DtrconTest(t *testing.T, impl Dtrconer) { + rnd := rand.New(rand.NewSource(1)) + // Hand crafted tests. + for _, test := range []struct { + a []float64 + n int + uplo blas.Uplo + diag blas.Diag + condOne float64 + condInf float64 + }{ + { + a: []float64{ + 8, 5, 6, + 0, 7, 8, + 0, 0, 6, + }, + n: 3, + uplo: blas.Upper, + diag: blas.Unit, + condOne: 1.0 / 645, + condInf: 1.0 / 480, + }, + { + a: []float64{ + 8, 5, 6, + 0, 7, 8, + 0, 0, 6, + }, + n: 3, + uplo: blas.Upper, + diag: blas.NonUnit, + condOne: 0.137704918032787, + condInf: 0.157894736842105, + }, + { + a: []float64{ + 8, 0, 0, + 5, 7, 0, + 6, 8, 6, + }, + n: 3, + uplo: blas.Lower, + diag: blas.Unit, + condOne: 1.0 / 480, + condInf: 1.0 / 645, + }, + { + a: []float64{ + 8, 0, 0, + 5, 7, 0, + 6, 8, 6, + }, + n: 3, + uplo: blas.Lower, + diag: blas.NonUnit, + condOne: 0.157894736842105, + condInf: 0.137704918032787, + }, + } { + lda := test.n + work := make([]float64, 3*test.n) + for i := range work { + work[i] = rnd.Float64() + } + iwork := make([]int, test.n) + for i := range iwork { + iwork[i] = int(rnd.Int31()) + } + aCopy := make([]float64, len(test.a)) + copy(aCopy, test.a) + condOne := impl.Dtrcon(lapack.MaxColumnSum, test.uplo, test.diag, test.n, test.a, lda, work, iwork) + if math.Abs(condOne-test.condOne) > 1e-14 { + t.Errorf("One norm mismatch. Want %v, got %v.", test.condOne, condOne) + } + if !floats.Equal(aCopy, test.a) { + t.Errorf("a modified during call") + } + condInf := impl.Dtrcon(lapack.MaxRowSum, test.uplo, test.diag, test.n, test.a, lda, work, iwork) + if math.Abs(condInf-test.condInf) > 1e-14 { + t.Errorf("Inf norm mismatch. Want %v, got %v.", test.condInf, condInf) + } + if !floats.Equal(aCopy, test.a) { + t.Errorf("a modified during call") + } + } + + // Dtrcon does not match the Dgecon output in many cases. See + // https://github.com/xianyi/OpenBLAS/issues/636 + // TODO(btracey): Uncomment this when the mismatch between Dgecon and Dtrcon + // is understood. + /* + // Randomized tests against Dgecon. + for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} { + for _, diag := range []blas.Diag{blas.NonUnit, blas.Unit} { + for _, test := range []struct { + n, lda int + }{ + {3, 0}, + {4, 9}, + } { + for trial := 0; trial < 1; trial++ { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + if trial == 0 { + for i := range a { + a[i] = float64(i + 2) + } + } else { + for i := range a { + a[i] = rnd.NormFloat64() + } + } + + aDense := make([]float64, len(a)) + if uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + aDense[i*lda+j] = a[i*lda+j] + } + } + } else { + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + aDense[i*lda+j] = a[i*lda+j] + } + } + } + if diag == blas.Unit { + for i := 0; i < n; i++ { + aDense[i*lda+i] = 1 + } + } + + ipiv := make([]int, n) + work := make([]float64, 4*n) + denseOne := impl.Dlange(lapack.MaxColumnSum, n, n, aDense, lda, work) + denseInf := impl.Dlange(lapack.MaxRowSum, n, n, aDense, lda, work) + + aDenseLU := make([]float64, len(aDense)) + copy(aDenseLU, aDense) + impl.Dgetrf(n, n, aDenseLU, lda, ipiv) + iwork := make([]int, n) + want := impl.Dgecon(lapack.MaxColumnSum, n, aDenseLU, lda, denseOne, work, iwork) + got := impl.Dtrcon(lapack.MaxColumnSum, uplo, diag, n, a, lda, work, iwork) + if math.Abs(want-got) > 1e-14 { + t.Errorf("One norm mismatch. Upper = %v, unit = %v, want %v, got %v", uplo == blas.Upper, diag == blas.Unit, want, got) + } + want = impl.Dgecon(lapack.MaxRowSum, n, aDenseLU, lda, denseInf, work, iwork) + got = impl.Dtrcon(lapack.MaxRowSum, uplo, diag, n, a, lda, work, iwork) + if math.Abs(want-got) > 1e-14 { + t.Errorf("Inf norm mismatch. Upper = %v, unit = %v, want %v, got %v", uplo == blas.Upper, diag == blas.Unit, want, got) + } + } + } + } + } + */ +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrevc3.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrevc3.go new file mode 100644 index 00000000..60c51241 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrevc3.go @@ -0,0 +1,221 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +type Dtrevc3er interface { + Dtrevc3(side lapack.EVSide, howmny lapack.HowMany, selected []bool, n int, t []float64, ldt int, vl []float64, ldvl int, vr []float64, ldvr int, mm int, work []float64, lwork int) int +} + +func Dtrevc3Test(t *testing.T, impl Dtrevc3er) { + rnd := rand.New(rand.NewSource(1)) + for _, side := range []lapack.EVSide{lapack.RightEV, lapack.LeftEV, lapack.RightLeftEV} { + for _, howmny := range []lapack.HowMany{lapack.AllEV, lapack.AllEVMulQ, lapack.SelectedEV} { + for _, n := range []int{0, 1, 2, 3, 4, 5, 10, 34, 100} { + for _, extra := range []int{0, 11} { + for _, optwork := range []bool{true, false} { + for cas := 0; cas < 10; cas++ { + tmat := randomSchurCanonical(n, n+extra, rnd) + testDtrevc3(t, impl, side, howmny, tmat, optwork, rnd) + } + } + } + } + } + } +} + +func testDtrevc3(t *testing.T, impl Dtrevc3er, side lapack.EVSide, howmny lapack.HowMany, tmat blas64.General, optwork bool, rnd *rand.Rand) { + const tol = 1e-14 + + n := tmat.Rows + extra := tmat.Stride - tmat.Cols + right := side != lapack.LeftEV + left := side != lapack.RightEV + + var selected, selectedWant []bool + var mWant int // How many columns will the eigenvectors occupy. + if howmny == lapack.SelectedEV { + selected = make([]bool, n) + selectedWant = make([]bool, n) + // Dtrevc3 will compute only selected eigenvectors. Pick them + // randomly disregarding whether they are real or complex. + for i := range selected { + if rnd.Float64() < 0.5 { + selected[i] = true + } + } + // Dtrevc3 will modify (standardize) the slice selected based on + // whether the corresponding eigenvalues are real or complex. Do + // the same process here to fill selectedWant. + for i := 0; i < n; { + if i == n-1 || tmat.Data[(i+1)*tmat.Stride+i] == 0 { + // Real eigenvalue. + if selected[i] { + selectedWant[i] = true + mWant++ // Real eigenvectors occupy one column. + } + i++ + } else { + // Complex eigenvalue. + if selected[i] || selected[i+1] { + // Dtrevc3 will modify selected so that + // only the first element of the pair is + // true. + selectedWant[i] = true + mWant += 2 // Complex eigenvectors occupy two columns. + } + i += 2 + } + } + } else { + // All eigenvectors occupy n columns. + mWant = n + } + + var vr blas64.General + if right { + if howmny == lapack.AllEVMulQ { + vr = eye(n, n+extra) + } else { + // VR will be overwritten. + vr = nanGeneral(n, mWant, n+extra) + } + } + + var vl blas64.General + if left { + if howmny == lapack.AllEVMulQ { + vl = eye(n, n+extra) + } else { + // VL will be overwritten. + vl = nanGeneral(n, mWant, n+extra) + } + } + + work := make([]float64, max(1, 3*n)) + if optwork { + impl.Dtrevc3(side, howmny, nil, n, nil, 1, nil, 1, nil, 1, mWant, work, -1) + work = make([]float64, int(work[0])) + } + + m := impl.Dtrevc3(side, howmny, selected, n, tmat.Data, tmat.Stride, + vl.Data, vl.Stride, vr.Data, vr.Stride, mWant, work, len(work)) + + prefix := fmt.Sprintf("Case side=%v, howmny=%v, n=%v, extra=%v, optwk=%v", + side, howmny, n, extra, optwork) + + if !generalOutsideAllNaN(tmat) { + t.Errorf("%v: out-of-range write to T", prefix) + } + if !generalOutsideAllNaN(vl) { + t.Errorf("%v: out-of-range write to VL", prefix) + } + if !generalOutsideAllNaN(vr) { + t.Errorf("%v: out-of-range write to VR", prefix) + } + + if m != mWant { + t.Errorf("%v: unexpected value of m. Want %v, got %v", prefix, mWant, m) + } + + if howmny == lapack.SelectedEV { + for i := range selected { + if selected[i] != selectedWant[i] { + t.Errorf("%v: unexpected selected[%v]", prefix, i) + } + } + } + + // Check that the columns of VR and VL are actually eigenvectors and + // that the magnitude of their largest element is 1. + var k int + for j := 0; j < n; { + re := tmat.Data[j*tmat.Stride+j] + if j == n-1 || tmat.Data[(j+1)*tmat.Stride+j] == 0 { + if howmny == lapack.SelectedEV && !selected[j] { + j++ + continue + } + if right { + ev := columnOf(vr, k) + norm := floats.Norm(ev, math.Inf(1)) + if math.Abs(norm-1) > tol { + t.Errorf("%v: magnitude of largest element of VR[:,%v] not 1", prefix, k) + } + if !isRightEigenvectorOf(tmat, ev, nil, complex(re, 0), tol) { + t.Errorf("%v: VR[:,%v] is not real right eigenvector", prefix, k) + } + } + if left { + ev := columnOf(vl, k) + norm := floats.Norm(ev, math.Inf(1)) + if math.Abs(norm-1) > tol { + t.Errorf("%v: magnitude of largest element of VL[:,%v] not 1", prefix, k) + } + if !isLeftEigenvectorOf(tmat, ev, nil, complex(re, 0), tol) { + t.Errorf("%v: VL[:,%v] is not real left eigenvector", prefix, k) + } + } + k++ + j++ + continue + } + if howmny == lapack.SelectedEV && !selected[j] { + j += 2 + continue + } + im := math.Sqrt(math.Abs(tmat.Data[(j+1)*tmat.Stride+j])) * + math.Sqrt(math.Abs(tmat.Data[j*tmat.Stride+j+1])) + if right { + evre := columnOf(vr, k) + evim := columnOf(vr, k+1) + var evmax float64 + for i, v := range evre { + evmax = math.Max(evmax, math.Abs(v)+math.Abs(evim[i])) + } + if math.Abs(evmax-1) > tol { + t.Errorf("%v: magnitude of largest element of VR[:,%v] not 1", prefix, k) + } + if !isRightEigenvectorOf(tmat, evre, evim, complex(re, im), tol) { + t.Errorf("%v: VR[:,%v:%v] is not complex right eigenvector", prefix, k, k+1) + } + floats.Scale(-1, evim) + if !isRightEigenvectorOf(tmat, evre, evim, complex(re, -im), tol) { + t.Errorf("%v: VR[:,%v:%v] is not complex right eigenvector", prefix, k, k+1) + } + } + if left { + evre := columnOf(vl, k) + evim := columnOf(vl, k+1) + var evmax float64 + for i, v := range evre { + evmax = math.Max(evmax, math.Abs(v)+math.Abs(evim[i])) + } + if math.Abs(evmax-1) > tol { + t.Errorf("%v: magnitude of largest element of VL[:,%v] not 1", prefix, k) + } + if !isLeftEigenvectorOf(tmat, evre, evim, complex(re, im), tol) { + t.Errorf("%v: VL[:,%v:%v] is not complex left eigenvector", prefix, k, k+1) + } + floats.Scale(-1, evim) + if !isLeftEigenvectorOf(tmat, evre, evim, complex(re, -im), tol) { + t.Errorf("%v: VL[:,%v:%v] is not complex left eigenvector", prefix, k, k+1) + } + } + k += 2 + j += 2 + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrexc.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrexc.go new file mode 100644 index 00000000..855805fb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrexc.go @@ -0,0 +1,219 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "fmt" + "math/cmplx" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" +) + +type Dtrexcer interface { + Dtrexc(compq lapack.EVComp, n int, t []float64, ldt int, q []float64, ldq int, ifst, ilst int, work []float64) (ifstOut, ilstOut int, ok bool) +} + +func DtrexcTest(t *testing.T, impl Dtrexcer) { + rnd := rand.New(rand.NewSource(1)) + + for _, compq := range []lapack.EVComp{lapack.None, lapack.UpdateSchur} { + for _, n := range []int{1, 2, 3, 4, 5, 6, 10, 18, 31, 53} { + for _, extra := range []int{0, 1, 11} { + for cas := 0; cas < 100; cas++ { + tmat := randomSchurCanonical(n, n+extra, rnd) + ifst := rnd.Intn(n) + ilst := rnd.Intn(n) + testDtrexc(t, impl, compq, tmat, ifst, ilst, extra, rnd) + } + } + } + } + + for _, compq := range []lapack.EVComp{lapack.None, lapack.UpdateSchur} { + for _, extra := range []int{0, 1, 11} { + tmat := randomSchurCanonical(0, extra, rnd) + testDtrexc(t, impl, compq, tmat, 0, 0, extra, rnd) + } + } +} + +func testDtrexc(t *testing.T, impl Dtrexcer, compq lapack.EVComp, tmat blas64.General, ifst, ilst, extra int, rnd *rand.Rand) { + const tol = 1e-13 + + n := tmat.Rows + fstSize, fstFirst := schurBlockSize(tmat, ifst) + lstSize, lstFirst := schurBlockSize(tmat, ilst) + + tmatCopy := cloneGeneral(tmat) + + var wantq bool + var q, qCopy blas64.General + if compq == lapack.UpdateSchur { + wantq = true + q = eye(n, n+extra) + qCopy = cloneGeneral(q) + } + + work := nanSlice(n) + + ifstGot, ilstGot, ok := impl.Dtrexc(compq, n, tmat.Data, tmat.Stride, q.Data, q.Stride, ifst, ilst, work) + + prefix := fmt.Sprintf("Case compq=%v, n=%v, ifst=%v, nbf=%v, ilst=%v, nbl=%v, extra=%v", + compq, n, ifst, fstSize, ilst, lstSize, extra) + + if !generalOutsideAllNaN(tmat) { + t.Errorf("%v: out-of-range write to T", prefix) + } + if wantq && !generalOutsideAllNaN(q) { + t.Errorf("%v: out-of-range write to Q", prefix) + } + + if !ok { + t.Logf("%v: Dtrexc returned ok=false", prefix) + } + + // Check that the index of the first block was correctly updated (if + // necessary). + ifstWant := ifst + if !fstFirst { + ifstWant = ifst - 1 + } + if ifstWant != ifstGot { + t.Errorf("%v: unexpected ifst index. Want %v, got %v ", prefix, ifstWant, ifstGot) + } + + // Check that the index of the last block is as expected when ok=true. + // When ok=false, we don't know at which block the algorithm failed, so + // we don't check. + ilstWant := ilst + if !lstFirst { + ilstWant-- + } + if ok { + if ifstWant < ilstWant { + // If the blocks are swapped backwards, these + // adjustments are not necessary, the first row of the + // last block will end up at ifst. + switch { + case fstSize == 2 && lstSize == 1: + ilstWant-- + case fstSize == 1 && lstSize == 2: + ilstWant++ + } + } + if ilstWant != ilstGot { + t.Errorf("%v: unexpected ilst index. Want %v, got %v", prefix, ilstWant, ilstGot) + } + } + + if n <= 1 || ifstGot == ilstGot { + // Too small matrix or no swapping. + // Check that T was not modified. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if tmat.Data[i*tmat.Stride+j] != tmatCopy.Data[i*tmatCopy.Stride+j] { + t.Errorf("%v: unexpected modification at T[%v,%v]", prefix, i, j) + } + } + } + if !wantq { + return + } + // Check that Q was not modified. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if q.Data[i*q.Stride+j] != qCopy.Data[i*qCopy.Stride+j] { + t.Errorf("%v: unexpected modification at Q[%v,%v]", prefix, i, j) + } + } + } + return + } + + if !isSchurCanonicalGeneral(tmat) { + t.Errorf("%v: T is not in Schur canonical form", prefix) + } + + // Check that T was not modified except above the second subdiagonal in + // rows and columns [modMin,modMax]. + modMin := min(ifstGot, ilstGot) + modMax := max(ifstGot, ilstGot) + fstSize + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if modMin <= i && i < modMax && j+1 >= i { + continue + } + if modMin <= j && j < modMax && j+1 >= i { + continue + } + diff := tmat.Data[i*tmat.Stride+j] - tmatCopy.Data[i*tmatCopy.Stride+j] + if diff != 0 { + t.Errorf("%v: unexpected modification at T[%v,%v]", prefix, i, j) + } + } + } + + // Check that the block at ifstGot was delivered to ilstGot correctly. + if fstSize == 1 { + // 1×1 blocks are swapped exactly. + got := tmat.Data[ilstGot*tmat.Stride+ilstGot] + want := tmatCopy.Data[ifstGot*tmatCopy.Stride+ifstGot] + if want != got { + t.Errorf("%v: unexpected 1×1 block at T[%v,%v]. Want %v, got %v", + prefix, want, got, ilstGot, ilstGot) + } + } else { + // Check that the swapped 2×2 block is in Schur canonical form. + a, b, c, d := extract2x2Block(tmat.Data[ilstGot*tmat.Stride+ilstGot:], tmat.Stride) + if !isSchurCanonical(a, b, c, d) { + t.Errorf("%v: 2×2 block at T[%v,%v] not in Schur canonical form", prefix, ilstGot, ilstGot) + } + ev1Got, ev2Got := schurBlockEigenvalues(a, b, c, d) + + // Check that the swapped 2×2 block has the same eigenvalues. + // The block was originally located at T[ifstGot,ifstGot]. + a, b, c, d = extract2x2Block(tmatCopy.Data[ifstGot*tmatCopy.Stride+ifstGot:], tmatCopy.Stride) + ev1Want, ev2Want := schurBlockEigenvalues(a, b, c, d) + if cmplx.Abs(ev1Got-ev1Want) > tol { + t.Errorf("%v: unexpected first eigenvalue of 2×2 block at T[%v,%v]. Want %v, got %v", + prefix, ilstGot, ilstGot, ev1Want, ev1Got) + } + if cmplx.Abs(ev2Got-ev2Want) > tol { + t.Errorf("%v: unexpected second eigenvalue of 2×2 block at T[%v,%v]. Want %v, got %v", + prefix, ilstGot, ilstGot, ev2Want, ev2Got) + } + } + + if !wantq { + return + } + + if !isOrthonormal(q) { + t.Errorf("%v: Q is not orthogonal", prefix) + } + // Check that Q is unchanged outside of columns [modMin,modMax]. + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if modMin <= j && j < modMax { + continue + } + if q.Data[i*q.Stride+j]-qCopy.Data[i*qCopy.Stride+j] != 0 { + t.Errorf("%v: unexpected modification of Q[%v,%v]", prefix, i, j) + } + } + } + // Check that Q^T TOrig Q == T. + tq := eye(n, n) + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmatCopy, q, 0, tq) + qtq := eye(n, n) + blas64.Gemm(blas.Trans, blas.NoTrans, 1, q, tq, 0, qtq) + if !equalApproxGeneral(qtq, tmat, tol) { + t.Errorf("%v: Q^T (initial T) Q and (final T) are not equal", prefix) + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrti2.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrti2.go new file mode 100644 index 00000000..acb8b5e9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrti2.go @@ -0,0 +1,163 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +type Dtrti2er interface { + Dtrti2(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) +} + +func Dtrti2Test(t *testing.T, impl Dtrti2er) { + const tol = 1e-14 + for _, test := range []struct { + a []float64 + n int + uplo blas.Uplo + diag blas.Diag + ans []float64 + }{ + { + a: []float64{ + 2, 3, 4, + 0, 5, 6, + 8, 0, 8}, + n: 3, + uplo: blas.Upper, + diag: blas.NonUnit, + ans: []float64{ + 0.5, -0.3, -0.025, + 0, 0.2, -0.15, + 8, 0, 0.125, + }, + }, + { + a: []float64{ + 5, 3, 4, + 0, 7, 6, + 10, 0, 8}, + n: 3, + uplo: blas.Upper, + diag: blas.Unit, + ans: []float64{ + 5, -3, 14, + 0, 7, -6, + 10, 0, 8, + }, + }, + { + a: []float64{ + 2, 0, 0, + 3, 5, 0, + 4, 6, 8}, + n: 3, + uplo: blas.Lower, + diag: blas.NonUnit, + ans: []float64{ + 0.5, 0, 0, + -0.3, 0.2, 0, + -0.025, -0.15, 0.125, + }, + }, + { + a: []float64{ + 1, 0, 0, + 3, 1, 0, + 4, 6, 1}, + n: 3, + uplo: blas.Lower, + diag: blas.Unit, + ans: []float64{ + 1, 0, 0, + -3, 1, 0, + 14, -6, 1, + }, + }, + } { + impl.Dtrti2(test.uplo, test.diag, test.n, test.a, test.n) + if !floats.EqualApprox(test.ans, test.a, tol) { + t.Errorf("Matrix inverse mismatch. Want %v, got %v.", test.ans, test.a) + } + } + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, diag := range []blas.Diag{blas.NonUnit, blas.Unit} { + for _, test := range []struct { + n, lda int + }{ + {1, 0}, + {2, 0}, + {3, 0}, + {1, 5}, + {2, 5}, + {3, 5}, + } { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.Float64() + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + impl.Dtrti2(uplo, diag, n, a, lda) + if uplo == blas.Upper { + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + aCopy[i*lda+j] = 0 + a[i*lda+j] = 0 + } + } + } else { + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + aCopy[i*lda+j] = 0 + a[i*lda+j] = 0 + } + } + } + if diag == blas.Unit { + for i := 0; i < n; i++ { + a[i*lda+i] = 1 + aCopy[i*lda+i] = 1 + } + } + ans := make([]float64, len(a)) + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, n, n, 1, a, lda, aCopy, lda, 0, ans, lda) + iseye := true + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if i == j { + if math.Abs(ans[i*lda+i]-1) > tol { + iseye = false + break + } + } else { + if math.Abs(ans[i*lda+j]) > tol { + iseye = false + break + } + } + } + } + if !iseye { + t.Errorf("inv(A) * A != I. Upper = %v, unit = %v, ans = %v", uplo == blas.Upper, diag == blas.Unit, ans) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrtri.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrtri.go new file mode 100644 index 00000000..1224b7b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/dtrtri.go @@ -0,0 +1,95 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +type Dtrtrier interface { + Dtrconer + Dtrtri(uplo blas.Uplo, diag blas.Diag, n int, a []float64, lda int) bool +} + +func DtrtriTest(t *testing.T, impl Dtrtrier) { + const tol = 1e-6 + rnd := rand.New(rand.NewSource(1)) + bi := blas64.Implementation() + for _, uplo := range []blas.Uplo{blas.Upper, blas.Lower} { + for _, diag := range []blas.Diag{blas.NonUnit, blas.Unit} { + for _, test := range []struct { + n, lda int + }{ + {3, 0}, + {70, 0}, + {200, 0}, + {3, 5}, + {70, 92}, + {200, 205}, + } { + n := test.n + lda := test.lda + if lda == 0 { + lda = n + } + a := make([]float64, n*lda) + for i := range a { + a[i] = rnd.Float64() + 1 // This keeps the matrices well conditioned. + } + aCopy := make([]float64, len(a)) + copy(aCopy, a) + impl.Dtrtri(uplo, diag, n, a, lda) + if uplo == blas.Upper { + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + aCopy[i*lda+j] = 0 + a[i*lda+j] = 0 + } + } + } else { + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + aCopy[i*lda+j] = 0 + a[i*lda+j] = 0 + } + } + } + if diag == blas.Unit { + for i := 0; i < n; i++ { + a[i*lda+i] = 1 + aCopy[i*lda+i] = 1 + } + } + ans := make([]float64, len(a)) + bi.Dgemm(blas.NoTrans, blas.NoTrans, n, n, n, 1, a, lda, aCopy, lda, 0, ans, lda) + iseye := true + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if i == j { + if math.Abs(ans[i*lda+i]-1) > tol { + iseye = false + break + } + } else { + if math.Abs(ans[i*lda+j]) > tol { + iseye = false + break + } + } + } + } + if !iseye { + t.Errorf("inv(A) * A != I. Upper = %v, unit = %v, n = %v, lda = %v", + uplo == blas.Upper, diag == blas.Unit, n, lda) + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/fortran.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/fortran.go new file mode 100644 index 00000000..45ea6d07 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/fortran.go @@ -0,0 +1,33 @@ +// 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 testlapack + +import ( + "fmt" + "strings" +) + +// This file implements types for helping to convert to Fortran testing capabilities. + +// fortran64 is a float64 type that prints as a double precision constant in +// Fortran format. +type fortran64 float64 + +func (f fortran64) String() string { + // Replace exponent with D + s := fmt.Sprintf("%0.16E", f) + s = strings.Replace(s, "E", "D", 1) + return s +} + +// printFortranArray prints a Go slice as an array that can be copied into a +// fortran script. +func printFortranArray(z []float64, name string) { + fmt.Printf("%s(1:%d) = (/%v, &\n", name, len(z), fortran64(z[0])) + for i := 1; i < len(z)-1; i++ { + fmt.Printf("%v, &\n", fortran64(z[i])) + } + fmt.Printf("%s/)\n", fortran64(z[len(z)-1])) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/general.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/general.go new file mode 100644 index 00000000..f2376a7d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/general.go @@ -0,0 +1,1516 @@ +// 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 testlapack + +import ( + "fmt" + "math" + "math/cmplx" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" +) + +const ( + // dlamchE is the machine epsilon. For IEEE this is 2^{-53}. + dlamchE = 1.0 / (1 << 53) + dlamchB = 2 + dlamchP = dlamchB * dlamchE + // dlamchS is the smallest normal number. For IEEE this is 2^{-1022}. + dlamchS = 1.0 / (1 << 256) / (1 << 256) / (1 << 256) / (1 << 254) +) + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +// worklen describes how much workspace a test should use. +type worklen int + +const ( + minimumWork worklen = iota + mediumWork + optimumWork +) + +// nanSlice allocates a new slice of length n filled with NaN. +func nanSlice(n int) []float64 { + s := make([]float64, n) + for i := range s { + s[i] = math.NaN() + } + return s +} + +// randomSlice allocates a new slice of length n filled with random values. +func randomSlice(n int, rnd *rand.Rand) []float64 { + s := make([]float64, n) + for i := range s { + s[i] = rnd.NormFloat64() + } + return s +} + +// nanGeneral allocates a new r×c general matrix filled with NaN values. +func nanGeneral(r, c, stride int) blas64.General { + if r < 0 || c < 0 { + panic("bad matrix size") + } + if r == 0 || c == 0 { + return blas64.General{Stride: max(1, stride)} + } + if stride < c { + panic("bad stride") + } + return blas64.General{ + Rows: r, + Cols: c, + Stride: stride, + Data: nanSlice((r-1)*stride + c), + } +} + +// randomGeneral allocates a new r×c general matrix filled with random +// numbers. Out-of-range elements are filled with NaN values. +func randomGeneral(r, c, stride int, rnd *rand.Rand) blas64.General { + ans := nanGeneral(r, c, stride) + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + ans.Data[i*ans.Stride+j] = rnd.NormFloat64() + } + } + return ans +} + +// randomHessenberg allocates a new n×n Hessenberg matrix filled with zeros +// under the first subdiagonal and with random numbers elsewhere. Out-of-range +// elements are filled with NaN values. +func randomHessenberg(n, stride int, rnd *rand.Rand) blas64.General { + ans := nanGeneral(n, n, stride) + for i := 0; i < n; i++ { + for j := 0; j < i-1; j++ { + ans.Data[i*ans.Stride+j] = 0 + } + for j := max(0, i-1); j < n; j++ { + ans.Data[i*ans.Stride+j] = rnd.NormFloat64() + } + } + return ans +} + +// randomSchurCanonical returns a random, general matrix in Schur canonical +// form, that is, block upper triangular with 1×1 and 2×2 diagonal blocks where +// each 2×2 diagonal block has its diagonal elements equal and its off-diagonal +// elements of opposite sign. +func randomSchurCanonical(n, stride int, rnd *rand.Rand) blas64.General { + t := randomGeneral(n, n, stride, rnd) + // Zero out the lower triangle. + for i := 0; i < t.Rows; i++ { + for j := 0; j < i; j++ { + t.Data[i*t.Stride+j] = 0 + } + } + // Randomly create 2×2 diagonal blocks. + for i := 0; i < t.Rows; { + if i == t.Rows-1 || rnd.Float64() < 0.5 { + // 1×1 block. + i++ + continue + } + // 2×2 block. + // Diagonal elements equal. + t.Data[(i+1)*t.Stride+i+1] = t.Data[i*t.Stride+i] + // Off-diagonal elements of opposite sign. + c := rnd.NormFloat64() + if math.Signbit(c) == math.Signbit(t.Data[i*t.Stride+i+1]) { + c *= -1 + } + t.Data[(i+1)*t.Stride+i] = c + i += 2 + } + return t +} + +// blockedUpperTriGeneral returns a normal random, general matrix in the form +// +// c-k-l k l +// A = k [ 0 A12 A13 ] if r-k-l >= 0; +// l [ 0 0 A23 ] +// r-k-l [ 0 0 0 ] +// +// c-k-l k l +// A = k [ 0 A12 A13 ] if r-k-l < 0; +// r-k [ 0 0 A23 ] +// +// where the k×k matrix A12 and l×l matrix is non-singular +// upper triangular. A23 is l×l upper triangular if r-k-l >= 0, +// otherwise A23 is (r-k)×l upper trapezoidal. +func blockedUpperTriGeneral(r, c, k, l, stride int, kblock bool, rnd *rand.Rand) blas64.General { + t := l + if kblock { + t += k + } + ans := zeros(r, c, stride) + for i := 0; i < min(r, t); i++ { + var v float64 + for v == 0 { + v = rnd.NormFloat64() + } + ans.Data[i*ans.Stride+i+(c-t)] = v + } + for i := 0; i < min(r, t); i++ { + for j := i + (c - t) + 1; j < c; j++ { + ans.Data[i*ans.Stride+j] = rnd.NormFloat64() + } + } + return ans +} + +// nanTriangular allocates a new r×c triangular matrix filled with NaN values. +func nanTriangular(uplo blas.Uplo, n, stride int) blas64.Triangular { + if n < 0 { + panic("bad matrix size") + } + if n == 0 { + return blas64.Triangular{ + Stride: max(1, stride), + Uplo: uplo, + Diag: blas.NonUnit, + } + } + if stride < n { + panic("bad stride") + } + return blas64.Triangular{ + N: n, + Stride: stride, + Data: nanSlice((n-1)*stride + n), + Uplo: uplo, + Diag: blas.NonUnit, + } +} + +// generalOutsideAllNaN returns whether all out-of-range elements have NaN +// values. +func generalOutsideAllNaN(a blas64.General) bool { + // Check after last column. + for i := 0; i < a.Rows-1; i++ { + for _, v := range a.Data[i*a.Stride+a.Cols : i*a.Stride+a.Stride] { + if !math.IsNaN(v) { + return false + } + } + } + // Check after last element. + last := (a.Rows-1)*a.Stride + a.Cols + if a.Rows == 0 || a.Cols == 0 { + last = 0 + } + for _, v := range a.Data[last:] { + if !math.IsNaN(v) { + return false + } + } + return true +} + +// triangularOutsideAllNaN returns whether all out-of-triangle elements have NaN +// values. +func triangularOutsideAllNaN(a blas64.Triangular) bool { + if a.Uplo == blas.Upper { + // Check below diagonal. + for i := 0; i < a.N; i++ { + for _, v := range a.Data[i*a.Stride : i*a.Stride+i] { + if !math.IsNaN(v) { + return false + } + } + } + // Check after last column. + for i := 0; i < a.N-1; i++ { + for _, v := range a.Data[i*a.Stride+a.N : i*a.Stride+a.Stride] { + if !math.IsNaN(v) { + return false + } + } + } + } else { + // Check above diagonal. + for i := 0; i < a.N-1; i++ { + for _, v := range a.Data[i*a.Stride+i+1 : i*a.Stride+a.Stride] { + if !math.IsNaN(v) { + return false + } + } + } + } + // Check after last element. + for _, v := range a.Data[max(0, a.N-1)*a.Stride+a.N:] { + if !math.IsNaN(v) { + return false + } + } + return true +} + +// transposeGeneral returns a new general matrix that is the transpose of the +// input. Nothing is done with data outside the {rows, cols} limit of the general. +func transposeGeneral(a blas64.General) blas64.General { + ans := blas64.General{ + Rows: a.Cols, + Cols: a.Rows, + Stride: a.Rows, + Data: make([]float64, a.Cols*a.Rows), + } + for i := 0; i < a.Rows; i++ { + for j := 0; j < a.Cols; j++ { + ans.Data[j*ans.Stride+i] = a.Data[i*a.Stride+j] + } + } + return ans +} + +// columnNorms returns the column norms of a. +func columnNorms(m, n int, a []float64, lda int) []float64 { + bi := blas64.Implementation() + norms := make([]float64, n) + for j := 0; j < n; j++ { + norms[j] = bi.Dnrm2(m, a[j:], lda) + } + return norms +} + +// extractVMat collects the single reflectors from a into a matrix. +func extractVMat(m, n int, a []float64, lda int, direct lapack.Direct, store lapack.StoreV) blas64.General { + k := min(m, n) + switch { + default: + panic("not implemented") + case direct == lapack.Forward && store == lapack.ColumnWise: + v := blas64.General{ + Rows: m, + Cols: k, + Stride: k, + Data: make([]float64, m*k), + } + for i := 0; i < k; i++ { + for j := 0; j < i; j++ { + v.Data[j*v.Stride+i] = 0 + } + v.Data[i*v.Stride+i] = 1 + for j := i + 1; j < m; j++ { + v.Data[j*v.Stride+i] = a[j*lda+i] + } + } + return v + case direct == lapack.Forward && store == lapack.RowWise: + v := blas64.General{ + Rows: k, + Cols: n, + Stride: n, + Data: make([]float64, k*n), + } + for i := 0; i < k; i++ { + for j := 0; j < i; j++ { + v.Data[i*v.Stride+j] = 0 + } + v.Data[i*v.Stride+i] = 1 + for j := i + 1; j < n; j++ { + v.Data[i*v.Stride+j] = a[i*lda+j] + } + } + return v + } +} + +// constructBidiagonal constructs a bidiagonal matrix with the given diagonal +// and off-diagonal elements. +func constructBidiagonal(uplo blas.Uplo, n int, d, e []float64) blas64.General { + bMat := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: make([]float64, n*n), + } + + for i := 0; i < n-1; i++ { + bMat.Data[i*bMat.Stride+i] = d[i] + if uplo == blas.Upper { + bMat.Data[i*bMat.Stride+i+1] = e[i] + } else { + bMat.Data[(i+1)*bMat.Stride+i] = e[i] + } + } + bMat.Data[(n-1)*bMat.Stride+n-1] = d[n-1] + return bMat +} + +// constructVMat transforms the v matrix based on the storage. +func constructVMat(vMat blas64.General, store lapack.StoreV, direct lapack.Direct) blas64.General { + m := vMat.Rows + k := vMat.Cols + switch { + default: + panic("not implemented") + case store == lapack.ColumnWise && direct == lapack.Forward: + ldv := k + v := make([]float64, m*k) + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + if j > i { + v[i*ldv+j] = 0 + } else if j == i { + v[i*ldv+i] = 1 + } else { + v[i*ldv+j] = vMat.Data[i*vMat.Stride+j] + } + } + } + return blas64.General{ + Rows: m, + Cols: k, + Stride: k, + Data: v, + } + case store == lapack.RowWise && direct == lapack.Forward: + ldv := m + v := make([]float64, m*k) + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + if j > i { + v[j*ldv+i] = 0 + } else if j == i { + v[j*ldv+i] = 1 + } else { + v[j*ldv+i] = vMat.Data[i*vMat.Stride+j] + } + } + } + return blas64.General{ + Rows: k, + Cols: m, + Stride: m, + Data: v, + } + case store == lapack.ColumnWise && direct == lapack.Backward: + rowsv := m + ldv := k + v := make([]float64, m*k) + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + vrow := rowsv - i - 1 + vcol := k - j - 1 + if j > i { + v[vrow*ldv+vcol] = 0 + } else if j == i { + v[vrow*ldv+vcol] = 1 + } else { + v[vrow*ldv+vcol] = vMat.Data[i*vMat.Stride+j] + } + } + } + return blas64.General{ + Rows: rowsv, + Cols: ldv, + Stride: ldv, + Data: v, + } + case store == lapack.RowWise && direct == lapack.Backward: + rowsv := k + ldv := m + v := make([]float64, m*k) + for i := 0; i < m; i++ { + for j := 0; j < k; j++ { + vcol := ldv - i - 1 + vrow := k - j - 1 + if j > i { + v[vrow*ldv+vcol] = 0 + } else if j == i { + v[vrow*ldv+vcol] = 1 + } else { + v[vrow*ldv+vcol] = vMat.Data[i*vMat.Stride+j] + } + } + } + return blas64.General{ + Rows: rowsv, + Cols: ldv, + Stride: ldv, + Data: v, + } + } +} + +func constructH(tau []float64, v blas64.General, store lapack.StoreV, direct lapack.Direct) blas64.General { + m := v.Rows + k := v.Cols + if store == lapack.RowWise { + m, k = k, m + } + h := blas64.General{ + Rows: m, + Cols: m, + Stride: m, + Data: make([]float64, m*m), + } + for i := 0; i < m; i++ { + h.Data[i*m+i] = 1 + } + for i := 0; i < k; i++ { + vecData := make([]float64, m) + if store == lapack.ColumnWise { + for j := 0; j < m; j++ { + vecData[j] = v.Data[j*v.Cols+i] + } + } else { + for j := 0; j < m; j++ { + vecData[j] = v.Data[i*v.Cols+j] + } + } + vec := blas64.Vector{ + Inc: 1, + Data: vecData, + } + + hi := blas64.General{ + Rows: m, + Cols: m, + Stride: m, + Data: make([]float64, m*m), + } + for i := 0; i < m; i++ { + hi.Data[i*m+i] = 1 + } + // hi = I - tau * v * v^T + blas64.Ger(-tau[i], vec, vec, hi) + + hcopy := blas64.General{ + Rows: m, + Cols: m, + Stride: m, + Data: make([]float64, m*m), + } + copy(hcopy.Data, h.Data) + if direct == lapack.Forward { + // H = H * H_I in forward mode + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, hcopy, hi, 0, h) + } else { + // H = H_I * H in backward mode + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, hi, hcopy, 0, h) + } + } + return h +} + +// constructQ constructs the Q matrix from the result of dgeqrf and dgeqr2. +func constructQ(kind string, m, n int, a []float64, lda int, tau []float64) blas64.General { + k := min(m, n) + return constructQK(kind, m, n, k, a, lda, tau) +} + +// constructQK constructs the Q matrix from the result of dgeqrf and dgeqr2 using +// the first k reflectors. +func constructQK(kind string, m, n, k int, a []float64, lda int, tau []float64) blas64.General { + var sz int + switch kind { + case "QR": + sz = m + case "LQ", "RQ": + sz = n + } + + q := blas64.General{ + Rows: sz, + Cols: sz, + Stride: sz, + Data: make([]float64, sz*sz), + } + for i := 0; i < sz; i++ { + q.Data[i*sz+i] = 1 + } + qCopy := blas64.General{ + Rows: q.Rows, + Cols: q.Cols, + Stride: q.Stride, + Data: make([]float64, len(q.Data)), + } + for i := 0; i < k; i++ { + h := blas64.General{ + Rows: sz, + Cols: sz, + Stride: sz, + Data: make([]float64, sz*sz), + } + for j := 0; j < sz; j++ { + h.Data[j*sz+j] = 1 + } + vVec := blas64.Vector{ + Inc: 1, + Data: make([]float64, sz), + } + switch kind { + case "QR": + vVec.Data[i] = 1 + for j := i + 1; j < sz; j++ { + vVec.Data[j] = a[lda*j+i] + } + case "LQ": + vVec.Data[i] = 1 + for j := i + 1; j < sz; j++ { + vVec.Data[j] = a[i*lda+j] + } + case "RQ": + for j := 0; j < n-k+i; j++ { + vVec.Data[j] = a[(m-k+i)*lda+j] + } + vVec.Data[n-k+i] = 1 + } + blas64.Ger(-tau[i], vVec, vVec, h) + copy(qCopy.Data, q.Data) + // Multiply q by the new h. + switch kind { + case "QR", "RQ": + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qCopy, h, 0, q) + case "LQ": + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, h, qCopy, 0, q) + } + } + return q +} + +// checkBidiagonal checks the bidiagonal decomposition from dlabrd and dgebd2. +// The input to this function is the answer returned from the routines, stored +// in a, d, e, tauP, and tauQ. The data of original A matrix (before +// decomposition) is input in aCopy. +// +// checkBidiagonal constructs the V and U matrices, and from them constructs Q +// and P. Using these constructions, it checks that Q^T * A * P and checks that +// the result is bidiagonal. +func checkBidiagonal(t *testing.T, m, n, nb int, a []float64, lda int, d, e, tauP, tauQ, aCopy []float64) { + // Check the answer. + // Construct V and U. + qMat := constructQPBidiagonal(lapack.ApplyQ, m, n, nb, a, lda, tauQ) + pMat := constructQPBidiagonal(lapack.ApplyP, m, n, nb, a, lda, tauP) + + // Compute Q^T * A * P. + aMat := blas64.General{ + Rows: m, + Cols: n, + Stride: lda, + Data: make([]float64, len(aCopy)), + } + copy(aMat.Data, aCopy) + + tmp1 := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + blas64.Gemm(blas.Trans, blas.NoTrans, 1, qMat, aMat, 0, tmp1) + tmp2 := blas64.General{ + Rows: m, + Cols: n, + Stride: n, + Data: make([]float64, m*n), + } + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, tmp1, pMat, 0, tmp2) + + // Check that the first nb rows and cols of tm2 are upper bidiagonal + // if m >= n, and lower bidiagonal otherwise. + correctDiag := true + matchD := true + matchE := true + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + if i >= nb && j >= nb { + continue + } + v := tmp2.Data[i*tmp2.Stride+j] + if i == j { + if math.Abs(d[i]-v) > 1e-12 { + matchD = false + } + continue + } + if m >= n && i == j-1 { + if math.Abs(e[j-1]-v) > 1e-12 { + matchE = false + } + continue + } + if m < n && i-1 == j { + if math.Abs(e[i-1]-v) > 1e-12 { + matchE = false + } + continue + } + if math.Abs(v) > 1e-12 { + correctDiag = false + } + } + } + if !correctDiag { + t.Errorf("Updated A not bi-diagonal") + } + if !matchD { + fmt.Println("d = ", d) + t.Errorf("D Mismatch") + } + if !matchE { + t.Errorf("E mismatch") + } +} + +// constructQPBidiagonal constructs Q or P from the Bidiagonal decomposition +// computed by dlabrd and bgebd2. +func constructQPBidiagonal(vect lapack.DecompUpdate, m, n, nb int, a []float64, lda int, tau []float64) blas64.General { + sz := n + if vect == lapack.ApplyQ { + sz = m + } + + var ldv int + var v blas64.General + if vect == lapack.ApplyQ { + ldv = nb + v = blas64.General{ + Rows: m, + Cols: nb, + Stride: ldv, + Data: make([]float64, m*ldv), + } + } else { + ldv = n + v = blas64.General{ + Rows: nb, + Cols: n, + Stride: ldv, + Data: make([]float64, m*ldv), + } + } + + if vect == lapack.ApplyQ { + if m >= n { + for i := 0; i < m; i++ { + for j := 0; j <= min(nb-1, i); j++ { + if i == j { + v.Data[i*ldv+j] = 1 + continue + } + v.Data[i*ldv+j] = a[i*lda+j] + } + } + } else { + for i := 1; i < m; i++ { + for j := 0; j <= min(nb-1, i-1); j++ { + if i-1 == j { + v.Data[i*ldv+j] = 1 + continue + } + v.Data[i*ldv+j] = a[i*lda+j] + } + } + } + } else { + if m < n { + for i := 0; i < nb; i++ { + for j := i; j < n; j++ { + if i == j { + v.Data[i*ldv+j] = 1 + continue + } + v.Data[i*ldv+j] = a[i*lda+j] + } + } + } else { + for i := 0; i < nb; i++ { + for j := i + 1; j < n; j++ { + if j-1 == i { + v.Data[i*ldv+j] = 1 + continue + } + v.Data[i*ldv+j] = a[i*lda+j] + } + } + } + } + + // The variable name is a computation of Q, but the algorithm is mostly the + // same for computing P (just with different data). + qMat := blas64.General{ + Rows: sz, + Cols: sz, + Stride: sz, + Data: make([]float64, sz*sz), + } + hMat := blas64.General{ + Rows: sz, + Cols: sz, + Stride: sz, + Data: make([]float64, sz*sz), + } + // set Q to I + for i := 0; i < sz; i++ { + qMat.Data[i*qMat.Stride+i] = 1 + } + for i := 0; i < nb; i++ { + qCopy := blas64.General{Rows: qMat.Rows, Cols: qMat.Cols, Stride: qMat.Stride, Data: make([]float64, len(qMat.Data))} + copy(qCopy.Data, qMat.Data) + + // Set g and h to I + for i := 0; i < sz; i++ { + for j := 0; j < sz; j++ { + if i == j { + hMat.Data[i*sz+j] = 1 + } else { + hMat.Data[i*sz+j] = 0 + } + } + } + var vi blas64.Vector + // H -= tauQ[i] * v[i] * v[i]^t + if vect == lapack.ApplyQ { + vi = blas64.Vector{ + Inc: v.Stride, + Data: v.Data[i:], + } + } else { + vi = blas64.Vector{ + Inc: 1, + Data: v.Data[i*v.Stride:], + } + } + blas64.Ger(-tau[i], vi, vi, hMat) + // Q = Q * G[1] + blas64.Gemm(blas.NoTrans, blas.NoTrans, 1, qCopy, hMat, 0, qMat) + } + return qMat +} + +// printRowise prints the matrix with one row per line. This is useful for debugging. +// If beyond is true, it prints beyond the final column to lda. If false, only +// the columns are printed. +func printRowise(a []float64, m, n, lda int, beyond bool) { + for i := 0; i < m; i++ { + end := n + if beyond { + end = lda + } + fmt.Println(a[i*lda : i*lda+end]) + } +} + +// isOrthonormal checks that a general matrix is orthonormal. +func isOrthonormal(q blas64.General) bool { + n := q.Rows + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dot := blas64.Dot(n, + blas64.Vector{Inc: 1, Data: q.Data[i*q.Stride:]}, + blas64.Vector{Inc: 1, Data: q.Data[j*q.Stride:]}, + ) + if math.IsNaN(dot) { + return false + } + if i == j { + if math.Abs(dot-1) > 1e-10 { + return false + } + } else { + if math.Abs(dot) > 1e-10 { + return false + } + } + } + } + return true +} + +// copyMatrix copies an m×n matrix src of stride n into an m×n matrix dst of stride ld. +func copyMatrix(m, n int, dst []float64, ld int, src []float64) { + for i := 0; i < m; i++ { + copy(dst[i*ld:i*ld+n], src[i*n:i*n+n]) + } +} + +func copyGeneral(dst, src blas64.General) { + r := min(dst.Rows, src.Rows) + c := min(dst.Cols, src.Cols) + for i := 0; i < r; i++ { + copy(dst.Data[i*dst.Stride:i*dst.Stride+c], src.Data[i*src.Stride:i*src.Stride+c]) + } +} + +// cloneGeneral allocates and returns an exact copy of the given general matrix. +func cloneGeneral(a blas64.General) blas64.General { + c := a + c.Data = make([]float64, len(a.Data)) + copy(c.Data, a.Data) + return c +} + +// equalApprox returns whether the matrices A and B of order n are approximately +// equal within given tolerance. +func equalApprox(m, n int, a []float64, lda int, b []float64, tol float64) bool { + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + diff := a[i*lda+j] - b[i*n+j] + if math.IsNaN(diff) || math.Abs(diff) > tol { + return false + } + } + } + return true +} + +// equalApproxGeneral returns whether the general matrices a and b are +// approximately equal within given tolerance. +func equalApproxGeneral(a, b blas64.General, tol float64) bool { + if a.Rows != b.Rows || a.Cols != b.Cols { + panic("bad input") + } + for i := 0; i < a.Rows; i++ { + for j := 0; j < a.Cols; j++ { + diff := a.Data[i*a.Stride+j] - b.Data[i*b.Stride+j] + if math.IsNaN(diff) || math.Abs(diff) > tol { + return false + } + } + } + return true +} + +// equalApproxTriangular returns whether the triangular matrices A and B of +// order n are approximately equal within given tolerance. +func equalApproxTriangular(upper bool, n int, a []float64, lda int, b []float64, tol float64) bool { + if upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + diff := a[i*lda+j] - b[i*n+j] + if math.IsNaN(diff) || math.Abs(diff) > tol { + return false + } + } + } + return true + } + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + diff := a[i*lda+j] - b[i*n+j] + if math.IsNaN(diff) || math.Abs(diff) > tol { + return false + } + } + } + return true +} + +func equalApproxSymmetric(a, b blas64.Symmetric, tol float64) bool { + if a.Uplo != b.Uplo { + return false + } + if a.N != b.N { + return false + } + if a.Uplo == blas.Upper { + for i := 0; i < a.N; i++ { + for j := i; j < a.N; j++ { + if !floats.EqualWithinAbsOrRel(a.Data[i*a.Stride+j], b.Data[i*b.Stride+j], tol, tol) { + return false + } + } + } + return true + } + for i := 0; i < a.N; i++ { + for j := 0; j <= i; j++ { + if !floats.EqualWithinAbsOrRel(a.Data[i*a.Stride+j], b.Data[i*b.Stride+j], tol, tol) { + return false + } + } + } + return true +} + +// randSymBand creates a random symmetric banded matrix, and returns both the +// random matrix and the equivalent Symmetric matrix for testing. rnder +// specifies the random number +func randSymBand(ul blas.Uplo, n, ldab, kb int, rnd *rand.Rand) (blas64.Symmetric, blas64.SymmetricBand) { + // A matrix is positive definite if and only if it has a Cholesky + // decomposition. Generate a random banded lower triangular matrix + // to construct the random symmetric matrix. + a := make([]float64, n*n) + for i := 0; i < n; i++ { + for j := max(0, i-kb); j <= i; j++ { + a[i*n+j] = rnd.NormFloat64() + } + a[i*n+i] = math.Abs(a[i*n+i]) + // Add an extra amound to the diagonal in order to improve the condition number. + a[i*n+i] += 1.5 * rnd.Float64() + } + agen := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: a, + } + + // Construct the SymDense from a*a^T + c := make([]float64, n*n) + cgen := blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: c, + } + blas64.Gemm(blas.NoTrans, blas.Trans, 1, agen, agen, 0, cgen) + sym := blas64.Symmetric{ + N: n, + Stride: n, + Data: c, + Uplo: ul, + } + + b := symToSymBand(ul, c, n, n, kb, ldab) + band := blas64.SymmetricBand{ + N: n, + K: kb, + Stride: ldab, + Data: b, + Uplo: ul, + } + + return sym, band +} + +// symToSymBand takes the data in a Symmetric matrix and returns a +// SymmetricBanded matrix. +func symToSymBand(ul blas.Uplo, a []float64, n, lda, kb, ldab int) []float64 { + if ul == blas.Upper { + band := make([]float64, (n-1)*ldab+kb+1) + for i := 0; i < n; i++ { + for j := i; j < min(i+kb+1, n); j++ { + band[i*ldab+j-i] = a[i*lda+j] + } + } + return band + } + band := make([]float64, (n-1)*ldab+kb+1) + for i := 0; i < n; i++ { + for j := max(0, i-kb); j <= i; j++ { + band[i*ldab+j-i+kb] = a[i*lda+j] + } + } + return band +} + +// symBandToSym takes a banded symmetric matrix and returns the same data as +// a Symmetric matrix. +func symBandToSym(ul blas.Uplo, band []float64, n, kb, ldab int) blas64.Symmetric { + sym := make([]float64, n*n) + if ul == blas.Upper { + for i := 0; i < n; i++ { + for j := 0; j < min(kb+1+i, n)-i; j++ { + sym[i*n+i+j] = band[i*ldab+j] + } + } + } else { + for i := 0; i < n; i++ { + for j := kb - min(i, kb); j < kb+1; j++ { + sym[i*n+i-kb+j] = band[i*ldab+j] + } + } + } + return blas64.Symmetric{ + N: n, + Stride: n, + Data: sym, + Uplo: ul, + } +} + +// eye returns an identity matrix of given order and stride. +func eye(n, stride int) blas64.General { + ans := nanGeneral(n, n, stride) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + ans.Data[i*ans.Stride+j] = 0 + } + ans.Data[i*ans.Stride+i] = 1 + } + return ans +} + +// zeros returns an m×n matrix with given stride filled with zeros. +func zeros(m, n, stride int) blas64.General { + a := nanGeneral(m, n, stride) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Data[i*a.Stride+j] = 0 + } + } + return a +} + +// extract2x2Block returns the elements of T at [0,0], [0,1], [1,0], and [1,1]. +func extract2x2Block(t []float64, ldt int) (a, b, c, d float64) { + return t[0], t[1], t[ldt], t[ldt+1] +} + +// isSchurCanonical returns whether the 2×2 matrix [a b; c d] is in Schur +// canonical form. +func isSchurCanonical(a, b, c, d float64) bool { + return c == 0 || (a == d && math.Signbit(b) != math.Signbit(c)) +} + +// isSchurCanonicalGeneral returns whether T is block upper triangular with 1×1 +// and 2×2 diagonal blocks, each 2×2 block in Schur canonical form. The function +// checks only along the diagonal and the first subdiagonal, otherwise the lower +// triangle is not accessed. +func isSchurCanonicalGeneral(t blas64.General) bool { + if t.Rows != t.Cols { + panic("invalid matrix") + } + for i := 0; i < t.Rows-1; { + if t.Data[(i+1)*t.Stride+i] == 0 { + // 1×1 block. + i++ + continue + } + // 2×2 block. + a, b, c, d := extract2x2Block(t.Data[i*t.Stride+i:], t.Stride) + if !isSchurCanonical(a, b, c, d) { + return false + } + i += 2 + } + return true +} + +// schurBlockEigenvalues returns the two eigenvalues of the 2×2 matrix [a b; c d] +// that must be in Schur canonical form. +func schurBlockEigenvalues(a, b, c, d float64) (ev1, ev2 complex128) { + if !isSchurCanonical(a, b, c, d) { + panic("block not in Schur canonical form") + } + if c == 0 { + return complex(a, 0), complex(d, 0) + } + im := math.Sqrt(-b * c) + return complex(a, im), complex(a, -im) +} + +// schurBlockSize returns the size of the diagonal block at i-th row in the +// upper quasi-triangular matrix t in Schur canonical form, and whether i points +// to the first row of the block. For zero-sized matrices the function returns 0 +// and true. +func schurBlockSize(t blas64.General, i int) (size int, first bool) { + if t.Rows != t.Cols { + panic("matrix not square") + } + if t.Rows == 0 { + return 0, true + } + if i < 0 || t.Rows <= i { + panic("index out of range") + } + + first = true + if i > 0 && t.Data[i*t.Stride+i-1] != 0 { + // There is a non-zero element to the left, therefore i must + // point to the second row in a 2×2 diagonal block. + first = false + i-- + } + size = 1 + if i+1 < t.Rows && t.Data[(i+1)*t.Stride+i] != 0 { + // There is a non-zero element below, this must be a 2×2 + // diagonal block. + size = 2 + } + return size, first +} + +// containsComplex returns whether z is approximately equal to one of the complex +// numbers in v. If z is found, its index in v will be also returned. +func containsComplex(v []complex128, z complex128, tol float64) (found bool, index int) { + for i := range v { + if cmplx.Abs(v[i]-z) < tol { + return true, i + } + } + return false, -1 +} + +// isAllNaN returns whether x contains only NaN values. +func isAllNaN(x []float64) bool { + for _, v := range x { + if !math.IsNaN(v) { + return false + } + } + return true +} + +// isUpperHessenberg returns whether h contains only zeros below the +// subdiagonal. +func isUpperHessenberg(h blas64.General) bool { + if h.Rows != h.Cols { + panic("matrix not square") + } + n := h.Rows + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if i > j+1 && h.Data[i*h.Stride+j] != 0 { + return false + } + } + } + return true +} + +// isUpperTriangular returns whether a contains only zeros below the diagonal. +func isUpperTriangular(a blas64.General) bool { + n := a.Rows + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + if a.Data[i*a.Stride+j] != 0 { + return false + } + } + } + return true +} + +// unbalancedSparseGeneral returns an m×n dense matrix with a random sparse +// structure consisting of nz nonzero elements. The matrix will be unbalanced by +// multiplying each element randomly by its row or column index. +func unbalancedSparseGeneral(m, n, stride int, nonzeros int, rnd *rand.Rand) blas64.General { + a := zeros(m, n, stride) + for k := 0; k < nonzeros; k++ { + i := rnd.Intn(n) + j := rnd.Intn(n) + if rnd.Float64() < 0.5 { + a.Data[i*stride+j] = float64(i+1) * rnd.NormFloat64() + } else { + a.Data[i*stride+j] = float64(j+1) * rnd.NormFloat64() + } + } + return a +} + +// columnOf returns a copy of the j-th column of a. +func columnOf(a blas64.General, j int) []float64 { + if j < 0 || a.Cols <= j { + panic("bad column index") + } + col := make([]float64, a.Rows) + for i := range col { + col[i] = a.Data[i*a.Stride+j] + } + return col +} + +// isRightEigenvectorOf returns whether the vector xRe+i*xIm, where i is the +// imaginary unit, is the right eigenvector of A corresponding to the eigenvalue +// lambda. +// +// A right eigenvector corresponding to a complex eigenvalue λ is a complex +// non-zero vector x such that +// A x = λ x. +func isRightEigenvectorOf(a blas64.General, xRe, xIm []float64, lambda complex128, tol float64) bool { + if a.Rows != a.Cols { + panic("matrix not square") + } + + if imag(lambda) != 0 && xIm == nil { + // Complex eigenvalue of a real matrix cannot have a real + // eigenvector. + return false + } + + n := a.Rows + + // Compute A real(x) and store the result into xReAns. + xReAns := make([]float64, n) + blas64.Gemv(blas.NoTrans, 1, a, blas64.Vector{1, xRe}, 0, blas64.Vector{1, xReAns}) + + if imag(lambda) == 0 && xIm == nil { + // Real eigenvalue and eigenvector. + + // Compute λx and store the result into lambdax. + lambdax := make([]float64, n) + floats.AddScaled(lambdax, real(lambda), xRe) + + // This is expressed as the inverse to catch the case + // xReAns_i = Inf and lambdax_i = Inf of the same sign. + return !(floats.Distance(xReAns, lambdax, math.Inf(1)) > tol) + } + + // Complex eigenvector, and real or complex eigenvalue. + + // Compute A imag(x) and store the result into xImAns. + xImAns := make([]float64, n) + blas64.Gemv(blas.NoTrans, 1, a, blas64.Vector{1, xIm}, 0, blas64.Vector{1, xImAns}) + + // Compute λx and store the result into lambdax. + lambdax := make([]complex128, n) + for i := range lambdax { + lambdax[i] = lambda * complex(xRe[i], xIm[i]) + } + + for i, v := range lambdax { + ax := complex(xReAns[i], xImAns[i]) + if cmplx.Abs(v-ax) > tol { + return false + } + } + return true +} + +// isLeftEigenvectorOf returns whether the vector yRe+i*yIm, where i is the +// imaginary unit, is the left eigenvector of A corresponding to the eigenvalue +// lambda. +// +// A left eigenvector corresponding to a complex eigenvalue λ is a complex +// non-zero vector y such that +// y^H A = λ y^H, +// which is equivalent for real A to +// A^T y = conj(λ) y, +func isLeftEigenvectorOf(a blas64.General, yRe, yIm []float64, lambda complex128, tol float64) bool { + if a.Rows != a.Cols { + panic("matrix not square") + } + + if imag(lambda) != 0 && yIm == nil { + // Complex eigenvalue of a real matrix cannot have a real + // eigenvector. + return false + } + + n := a.Rows + + // Compute A^T real(y) and store the result into yReAns. + yReAns := make([]float64, n) + blas64.Gemv(blas.Trans, 1, a, blas64.Vector{1, yRe}, 0, blas64.Vector{1, yReAns}) + + if imag(lambda) == 0 && yIm == nil { + // Real eigenvalue and eigenvector. + + // Compute λy and store the result into lambday. + lambday := make([]float64, n) + floats.AddScaled(lambday, real(lambda), yRe) + + // This is expressed as the inverse to catch the case + // yReAns_i = Inf and lambday_i = Inf of the same sign. + return !(floats.Distance(yReAns, lambday, math.Inf(1)) > tol) + } + + // Complex eigenvector, and real or complex eigenvalue. + + // Compute A^T imag(y) and store the result into yImAns. + yImAns := make([]float64, n) + blas64.Gemv(blas.Trans, 1, a, blas64.Vector{1, yIm}, 0, blas64.Vector{1, yImAns}) + + // Compute conj(λ)y and store the result into lambday. + lambda = cmplx.Conj(lambda) + lambday := make([]complex128, n) + for i := range lambday { + lambday[i] = lambda * complex(yRe[i], yIm[i]) + } + + for i, v := range lambday { + ay := complex(yReAns[i], yImAns[i]) + if cmplx.Abs(v-ay) > tol { + return false + } + } + return true +} + +// rootsOfUnity returns the n complex numbers whose n-th power is equal to 1. +func rootsOfUnity(n int) []complex128 { + w := make([]complex128, n) + for i := 0; i < n; i++ { + angle := math.Pi * float64(2*i) / float64(n) + w[i] = complex(math.Cos(angle), math.Sin(angle)) + } + return w +} + +// randomOrthogonal returns an n×n random orthogonal matrix. +func randomOrthogonal(n int, rnd *rand.Rand) blas64.General { + q := eye(n, n) + x := make([]float64, n) + v := make([]float64, n) + for j := 0; j < n-1; j++ { + // x represents the j-th column of a random matrix. + for i := 0; i < j; i++ { + x[i] = 0 + } + for i := j; i < n; i++ { + x[i] = rnd.NormFloat64() + } + // Compute v that represents the elementary reflector that + // annihilates the subdiagonal elements of x. + reflector(v, x, j) + // Compute Q * H_j and store the result into Q. + applyReflector(q, q, v) + } + if !isOrthonormal(q) { + panic("Q not orthogonal") + } + return q +} + +// reflector generates a Householder reflector v that zeros out subdiagonal +// entries in the j-th column of a matrix. +func reflector(v, col []float64, j int) { + n := len(col) + if len(v) != n { + panic("slice length mismatch") + } + if j < 0 || n <= j { + panic("invalid column index") + } + + for i := range v { + v[i] = 0 + } + if j == n-1 { + return + } + s := floats.Norm(col[j:], 2) + if s == 0 { + return + } + v[j] = col[j] + math.Copysign(s, col[j]) + copy(v[j+1:], col[j+1:]) + s = floats.Norm(v[j:], 2) + floats.Scale(1/s, v[j:]) +} + +// applyReflector computes Q*H where H is a Householder matrix represented by +// the Householder reflector v. +func applyReflector(qh blas64.General, q blas64.General, v []float64) { + n := len(v) + if qh.Rows != n || qh.Cols != n { + panic("bad size of qh") + } + if q.Rows != n || q.Cols != n { + panic("bad size of q") + } + qv := make([]float64, n) + blas64.Gemv(blas.NoTrans, 1, q, blas64.Vector{1, v}, 0, blas64.Vector{1, qv}) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + qh.Data[i*qh.Stride+j] = q.Data[i*q.Stride+j] + } + } + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + qh.Data[i*qh.Stride+j] -= 2 * qv[i] * v[j] + } + } + var norm2 float64 + for _, vi := range v { + norm2 += vi * vi + } + norm2inv := 1 / norm2 + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + qh.Data[i*qh.Stride+j] *= norm2inv + } + } +} + +// constructGSVDresults returns the matrices [ 0 R ], D1 and D2 described +// in the documentation of Dtgsja and Dggsvd3, and the result matrix in +// the documentation for Dggsvp3. +func constructGSVDresults(n, p, m, k, l int, a, b blas64.General, alpha, beta []float64) (zeroR, d1, d2 blas64.General) { + // [ 0 R ] + zeroR = zeros(k+l, n, n) + dst := zeroR + dst.Rows = min(m, k+l) + dst.Cols = k + l + dst.Data = zeroR.Data[n-k-l:] + src := a + src.Rows = min(m, k+l) + src.Cols = k + l + src.Data = a.Data[n-k-l:] + copyGeneral(dst, src) + if m < k+l { + // [ 0 R ] + dst.Rows = k + l - m + dst.Cols = k + l - m + dst.Data = zeroR.Data[m*zeroR.Stride+n-(k+l-m):] + src = b + src.Rows = k + l - m + src.Cols = k + l - m + src.Data = b.Data[(m-k)*b.Stride+n+m-k-l:] + copyGeneral(dst, src) + } + + // D1 + d1 = zeros(m, k+l, k+l) + for i := 0; i < k; i++ { + d1.Data[i*d1.Stride+i] = 1 + } + for i := k; i < min(m, k+l); i++ { + d1.Data[i*d1.Stride+i] = alpha[i] + } + + // D2 + d2 = zeros(p, k+l, k+l) + for i := 0; i < min(l, m-k); i++ { + d2.Data[i*d2.Stride+i+k] = beta[k+i] + } + for i := m - k; i < l; i++ { + d2.Data[i*d2.Stride+i+k] = 1 + } + + return zeroR, d1, d2 +} + +func constructGSVPresults(n, p, m, k, l int, a, b blas64.General) (zeroA, zeroB blas64.General) { + zeroA = zeros(m, n, n) + dst := zeroA + dst.Rows = min(m, k+l) + dst.Cols = k + l + dst.Data = zeroA.Data[n-k-l:] + src := a + dst.Rows = min(m, k+l) + src.Cols = k + l + src.Data = a.Data[n-k-l:] + copyGeneral(dst, src) + + zeroB = zeros(p, n, n) + dst = zeroB + dst.Rows = l + dst.Cols = l + dst.Data = zeroB.Data[n-l:] + src = b + dst.Rows = l + src.Cols = l + src.Data = b.Data[n-l:] + copyGeneral(dst, src) + + return zeroA, zeroB +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/iladlc.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/iladlc.go new file mode 100644 index 00000000..b8a5b2b3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/iladlc.go @@ -0,0 +1,83 @@ +// 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 testlapack + +import "testing" + +type Iladlcer interface { + Iladlc(m, n int, a []float64, lda int) int +} + +func IladlcTest(t *testing.T, impl Iladlcer) { + for i, test := range []struct { + a []float64 + m, n, lda int + ans int + }{ + { + a: []float64{0, 0, 0, 0}, + m: 1, + n: 1, + lda: 2, + ans: -1, + }, + { + a: []float64{0, 0, 0, 0}, + m: 2, + n: 2, + lda: 2, + ans: -1, + }, + { + a: []float64{0, 0, 0, 0}, + m: 4, + n: 1, + lda: 1, + ans: -1, + }, + { + a: []float64{0, 0, 0, 0}, + m: 1, + n: 4, + lda: 4, + ans: -1, + }, + { + a: []float64{ + 1, 2, 3, 4, + 5, 6, 7, 8, + }, + m: 2, + n: 4, + lda: 4, + ans: 3, + }, + { + a: []float64{ + 1, 2, 3, 0, + 0, 0, 0, 0, + }, + m: 2, + n: 4, + lda: 4, + ans: 2, + }, + { + a: []float64{ + 0, 0, 3, 4, + 0, 0, 0, 0, + }, + m: 2, + n: 2, + lda: 4, + ans: -1, + }, + } { + ans := impl.Iladlc(test.m, test.n, test.a, test.lda) + if ans != test.ans { + t.Errorf("Column mismatch case %v. Want: %v, got: %v", i, test.ans, ans) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/iladlr.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/iladlr.go new file mode 100644 index 00000000..bd74d28c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/iladlr.go @@ -0,0 +1,83 @@ +// 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 testlapack + +import "testing" + +type Iladlrer interface { + Iladlr(m, n int, a []float64, lda int) int +} + +func IladlrTest(t *testing.T, impl Iladlrer) { + for i, test := range []struct { + a []float64 + m, n, lda int + ans int + }{ + { + a: []float64{0, 0, 0, 0}, + m: 1, + n: 1, + lda: 2, + ans: -1, + }, + { + a: []float64{0, 0, 0, 0}, + m: 2, + n: 2, + lda: 2, + ans: -1, + }, + { + a: []float64{0, 0, 0, 0}, + m: 4, + n: 1, + lda: 1, + ans: -1, + }, + { + a: []float64{0, 0, 0, 0}, + m: 1, + n: 4, + lda: 4, + ans: -1, + }, + { + a: []float64{ + 1, 2, 3, 4, + 5, 6, 7, 8, + }, + m: 2, + n: 4, + lda: 4, + ans: 1, + }, + { + a: []float64{ + 1, 2, 3, 0, + 0, 0, 0, 0, + }, + m: 2, + n: 4, + lda: 4, + ans: 0, + }, + { + a: []float64{ + 0, 0, 3, 4, + 0, 0, 0, 0, + }, + m: 2, + n: 2, + lda: 4, + ans: -1, + }, + } { + ans := impl.Iladlr(test.m, test.n, test.a, test.lda) + if ans != test.ans { + t.Errorf("Column mismatch case %v. Want: %v, got: %v", i, test.ans, ans) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/matgen.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/matgen.go new file mode 100644 index 00000000..b47d9270 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/matgen.go @@ -0,0 +1,655 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +// Dlatm1 computes the entries of dst as specified by mode, cond and rsign. +// +// mode describes how dst will be computed: +// |mode| == 1: dst[0] = 1 and dst[1:n] = 1/cond +// |mode| == 2: dst[:n-1] = 1/cond and dst[n-1] = 1 +// |mode| == 3: dst[i] = cond^{-i/(n-1)}, i=0,...,n-1 +// |mode| == 4: dst[i] = 1 - i*(1-1/cond)/(n-1) +// |mode| == 5: dst[i] = random number in the range (1/cond, 1) such that +// their logarithms are uniformly distributed +// |mode| == 6: dst[i] = random number from the distribution given by dist +// If mode is negative, the order of the elements of dst will be reversed. +// For other values of mode Dlatm1 will panic. +// +// If rsign is true and mode is not ±6, each entry of dst will be multiplied by 1 +// or -1 with probability 0.5 +// +// dist specifies the type of distribution to be used when mode == ±6: +// dist == 1: Uniform[0,1) +// dist == 2: Uniform[-1,1) +// dist == 3: Normal(0,1) +// For other values of dist Dlatm1 will panic. +// +// rnd is used as a source of random numbers. +func Dlatm1(dst []float64, mode int, cond float64, rsign bool, dist int, rnd *rand.Rand) { + amode := mode + if amode < 0 { + amode = -amode + } + if amode < 1 || 6 < amode { + panic("testlapack: invalid mode") + } + if cond < 1 { + panic("testlapack: cond < 1") + } + if amode == 6 && (dist < 1 || 3 < dist) { + panic("testlapack: invalid dist") + } + + n := len(dst) + if n == 0 { + return + } + + switch amode { + case 1: + dst[0] = 1 + for i := 1; i < n; i++ { + dst[i] = 1 / cond + } + case 2: + for i := 0; i < n-1; i++ { + dst[i] = 1 + } + dst[n-1] = 1 / cond + case 3: + dst[0] = 1 + if n > 1 { + alpha := math.Pow(cond, -1/float64(n-1)) + for i := 1; i < n; i++ { + dst[i] = math.Pow(alpha, float64(i)) + } + } + case 4: + dst[0] = 1 + if n > 1 { + condInv := 1 / cond + alpha := (1 - condInv) / float64(n-1) + for i := 1; i < n; i++ { + dst[i] = float64(n-i-1)*alpha + condInv + } + } + case 5: + alpha := math.Log(1 / cond) + for i := range dst { + dst[i] = math.Exp(alpha * rnd.Float64()) + } + case 6: + switch dist { + case 1: + for i := range dst { + dst[i] = rnd.Float64() + } + case 2: + for i := range dst { + dst[i] = 2*rnd.Float64() - 1 + } + case 3: + for i := range dst { + dst[i] = rnd.NormFloat64() + } + } + } + + if rsign && amode != 6 { + for i, v := range dst { + if rnd.Float64() < 0.5 { + dst[i] = -v + } + } + } + + if mode < 0 { + for i := 0; i < n/2; i++ { + dst[i], dst[n-i-1] = dst[n-i-1], dst[i] + } + } +} + +// Dlagsy generates an n×n symmetric matrix A, by pre- and post- multiplying a +// real diagonal matrix D with a random orthogonal matrix: +// A = U * D * U^T. +// +// work must have length at least 2*n, otherwise Dlagsy will panic. +// +// The parameter k is unused but it must satisfy +// 0 <= k <= n-1. +func Dlagsy(n, k int, d []float64, a []float64, lda int, rnd *rand.Rand, work []float64) { + checkMatrix(n, n, a, lda) + if k < 0 || max(0, n-1) < k { + panic("testlapack: invalid value of k") + } + if len(d) != n { + panic("testlapack: bad length of d") + } + if len(work) < 2*n { + panic("testlapack: insufficient work length") + } + + // Initialize lower triangle of A to diagonal matrix. + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + a[i*lda+j] = 0 + } + } + for i := 0; i < n; i++ { + a[i*lda+i] = d[i] + } + + bi := blas64.Implementation() + + // Generate lower triangle of symmetric matrix. + for i := n - 2; i >= 0; i-- { + for j := 0; j < n-i; j++ { + work[j] = rnd.NormFloat64() + } + wn := bi.Dnrm2(n-i, work[:n-i], 1) + wa := math.Copysign(wn, work[0]) + var tau float64 + if wn != 0 { + wb := work[0] + wa + bi.Dscal(n-i-1, 1/wb, work[1:n-i], 1) + work[0] = 1 + tau = wb / wa + } + + // Apply random reflection to A[i:n,i:n] from the left and the + // right. + // + // Compute y := tau * A * u. + bi.Dsymv(blas.Lower, n-i, tau, a[i*lda+i:], lda, work[:n-i], 1, 0, work[n:2*n-i], 1) + + // Compute v := y - 1/2 * tau * ( y, u ) * u. + alpha := -0.5 * tau * bi.Ddot(n-i, work[n:2*n-i], 1, work[:n-i], 1) + bi.Daxpy(n-i, alpha, work[:n-i], 1, work[n:2*n-i], 1) + + // Apply the transformation as a rank-2 update to A[i:n,i:n]. + bi.Dsyr2(blas.Lower, n-i, -1, work[:n-i], 1, work[n:2*n-i], 1, a[i*lda+i:], lda) + } + + // Store full symmetric matrix. + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + a[j*lda+i] = a[i*lda+j] + } + } +} + +// Dlagge generates a real general m×n matrix A, by pre- and post-multiplying +// a real diagonal matrix D with random orthogonal matrices: +// A = U*D*V. +// +// d must have length min(m,n), and work must have length m+n, otherwise Dlagge +// will panic. +// +// The parameters ku and kl are unused but they must satisfy +// 0 <= kl <= m-1, +// 0 <= ku <= n-1. +func Dlagge(m, n, kl, ku int, d []float64, a []float64, lda int, rnd *rand.Rand, work []float64) { + checkMatrix(m, n, a, lda) + if kl < 0 || max(0, m-1) < kl { + panic("testlapack: invalid value of kl") + } + if ku < 0 || max(0, n-1) < ku { + panic("testlapack: invalid value of ku") + } + if len(d) != min(m, n) { + panic("testlapack: bad length of d") + } + if len(work) < m+n { + panic("testlapack: insufficient work length") + } + + // Initialize A to diagonal matrix. + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a[i*lda+j] = 0 + } + } + for i := 0; i < min(m, n); i++ { + a[i*lda+i] = d[i] + } + + // Quick exit if the user wants a diagonal matrix. + // if kl == 0 && ku == 0 { + // return + // } + + bi := blas64.Implementation() + + // Pre- and post-multiply A by random orthogonal matrices. + for i := min(m, n) - 1; i >= 0; i-- { + if i < m-1 { + for j := 0; j < m-i; j++ { + work[j] = rnd.NormFloat64() + } + wn := bi.Dnrm2(m-i, work[:m-i], 1) + wa := math.Copysign(wn, work[0]) + var tau float64 + if wn != 0 { + wb := work[0] + wa + bi.Dscal(m-i-1, 1/wb, work[1:m-i], 1) + work[0] = 1 + tau = wb / wa + } + + // Multiply A[i:m,i:n] by random reflection from the left. + bi.Dgemv(blas.Trans, m-i, n-i, + 1, a[i*lda+i:], lda, work[:m-i], 1, + 0, work[m:m+n-i], 1) + bi.Dger(m-i, n-i, + -tau, work[:m-i], 1, work[m:m+n-i], 1, + a[i*lda+i:], lda) + } + if i < n-1 { + for j := 0; j < n-i; j++ { + work[j] = rnd.NormFloat64() + } + wn := bi.Dnrm2(n-i, work[:n-i], 1) + wa := math.Copysign(wn, work[0]) + var tau float64 + if wn != 0 { + wb := work[0] + wa + bi.Dscal(n-i-1, 1/wb, work[1:n-i], 1) + work[0] = 1 + tau = wb / wa + } + + // Multiply A[i:m,i:n] by random reflection from the right. + bi.Dgemv(blas.NoTrans, m-i, n-i, + 1, a[i*lda+i:], lda, work[:n-i], 1, + 0, work[n:n+m-i], 1) + bi.Dger(m-i, n-i, + -tau, work[n:n+m-i], 1, work[:n-i], 1, + a[i*lda+i:], lda) + } + } + + // TODO(vladimir-ch): Reduce number of subdiagonals to kl and number of + // superdiagonals to ku. +} + +// dlarnv fills dst with random numbers from a uniform or normal distribution +// specified by dist: +// dist=1: uniform(0,1), +// dist=2: uniform(-1,1), +// dist=3: normal(0,1). +// For other values of dist dlarnv will panic. +func dlarnv(dst []float64, dist int, rnd *rand.Rand) { + switch dist { + default: + panic("testlapack: invalid dist") + case 1: + for i := range dst { + dst[i] = rnd.Float64() + } + case 2: + for i := range dst { + dst[i] = 2*rnd.Float64() - 1 + } + case 3: + for i := range dst { + dst[i] = rnd.NormFloat64() + } + } +} + +// dlattr generates an n×n triangular test matrix A with its properties uniquely +// determined by imat and uplo, and returns whether A has unit diagonal. If diag +// is blas.Unit, the diagonal elements are set so that A[k,k]=k. +// +// trans specifies whether the matrix A or its transpose will be used. +// +// If imat is greater than 10, dlattr also generates the right hand side of the +// linear system A*x=b, or A^T*x=b. Valid values of imat are 7, and all between 11 +// and 19, inclusive. +// +// b mush have length n, and work must have length 3*n, and dlattr will panic +// otherwise. +func dlattr(imat int, uplo blas.Uplo, trans blas.Transpose, n int, a []float64, lda int, b, work []float64, rnd *rand.Rand) (diag blas.Diag) { + checkMatrix(n, n, a, lda) + if len(b) != n { + panic("testlapack: bad length of b") + } + if len(work) < 3*n { + panic("testlapack: insufficient length of work") + } + if uplo != blas.Upper && uplo != blas.Lower { + panic("testlapack: bad uplo") + } + if trans != blas.Trans && trans != blas.NoTrans { + panic("testlapack: bad trans") + } + + if n == 0 { + return blas.NonUnit + } + + ulp := dlamchE * dlamchB + smlnum := dlamchS + bignum := (1 - ulp) / smlnum + + bi := blas64.Implementation() + + switch imat { + default: + // TODO(vladimir-ch): Implement the remaining cases. + panic("testlapack: invalid or unimplemented imat") + case 7: + // Identity matrix. The diagonal is set to NaN. + diag = blas.Unit + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + a[i*lda+i] = math.NaN() + for j := i + 1; j < n; j++ { + a[i*lda+j] = 0 + } + } + case blas.Lower: + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + a[i*lda+j] = 0 + } + a[i*lda+i] = math.NaN() + } + } + case 11: + // Generate a triangular matrix with elements between -1 and 1, + // give the diagonal norm 2 to make it well-conditioned, and + // make the right hand side large so that it requires scaling. + diag = blas.NonUnit + switch uplo { + case blas.Upper: + for i := 0; i < n-1; i++ { + dlarnv(a[i*lda+i:i*lda+n], 2, rnd) + } + case blas.Lower: + for i := 1; i < n; i++ { + dlarnv(a[i*lda:i*lda+i+1], 2, rnd) + } + } + for i := 0; i < n; i++ { + a[i*lda+i] = math.Copysign(2, a[i*lda+i]) + } + // Set the right hand side so that the largest value is bignum. + dlarnv(b, 2, rnd) + imax := bi.Idamax(n, b, 1) + bscal := bignum / math.Max(1, b[imax]) + bi.Dscal(n, bscal, b, 1) + case 12: + // Make the first diagonal element in the solve small to cause + // immediate overflow when dividing by T[j,j]. The off-diagonal + // elements are small (cnorm[j] < 1). + diag = blas.NonUnit + tscal := 1 / math.Max(1, float64(n-1)) + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + dlarnv(a[i*lda+i:i*lda+n], 2, rnd) + bi.Dscal(n-i-1, tscal, a[i*lda+i+1:], 1) + a[i*lda+i] = math.Copysign(1, a[i*lda+i]) + } + a[(n-1)*lda+n-1] *= smlnum + case blas.Lower: + for i := 0; i < n; i++ { + dlarnv(a[i*lda:i*lda+i+1], 2, rnd) + bi.Dscal(i, tscal, a[i*lda:], 1) + a[i*lda+i] = math.Copysign(1, a[i*lda+i]) + } + a[0] *= smlnum + } + dlarnv(b, 2, rnd) + case 13: + // Make the first diagonal element in the solve small to cause + // immediate overflow when dividing by T[j,j]. The off-diagonal + // elements are O(1) (cnorm[j] > 1). + diag = blas.NonUnit + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + dlarnv(a[i*lda+i:i*lda+n], 2, rnd) + a[i*lda+i] = math.Copysign(1, a[i*lda+i]) + } + a[(n-1)*lda+n-1] *= smlnum + case blas.Lower: + for i := 0; i < n; i++ { + dlarnv(a[i*lda:i*lda+i+1], 2, rnd) + a[i*lda+i] = math.Copysign(1, a[i*lda+i]) + } + a[0] *= smlnum + } + dlarnv(b, 2, rnd) + case 14: + // T is diagonal with small numbers on the diagonal to + // make the growth factor underflow, but a small right hand side + // chosen so that the solution does not overflow. + diag = blas.NonUnit + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + a[i*lda+j] = 0 + } + if (n-1-i)&0x2 == 0 { + a[i*lda+i] = smlnum + } else { + a[i*lda+i] = 1 + } + } + case blas.Lower: + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + a[i*lda+j] = 0 + } + if i&0x2 == 0 { + a[i*lda+i] = smlnum + } else { + a[i*lda+i] = 1 + } + } + } + // Set the right hand side alternately zero and small. + switch uplo { + case blas.Upper: + b[0] = 0 + for i := n - 1; i > 0; i -= 2 { + b[i] = 0 + b[i-1] = smlnum + } + case blas.Lower: + for i := 0; i < n-1; i += 2 { + b[i] = 0 + b[i+1] = smlnum + } + b[n-1] = 0 + } + case 15: + // Make the diagonal elements small to cause gradual overflow + // when dividing by T[j,j]. To control the amount of scaling + // needed, the matrix is bidiagonal. + diag = blas.NonUnit + texp := 1 / math.Max(1, float64(n-1)) + tscal := math.Pow(smlnum, texp) + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + a[i*lda+i] = tscal + if i < n-1 { + a[i*lda+i+1] = -1 + } + for j := i + 2; j < n; j++ { + a[i*lda+j] = 0 + } + } + case blas.Lower: + for i := 0; i < n; i++ { + for j := 0; j < i-1; j++ { + a[i*lda+j] = 0 + } + if i > 0 { + a[i*lda+i-1] = -1 + } + a[i*lda+i] = tscal + } + } + dlarnv(b, 2, rnd) + case 16: + // One zero diagonal element. + diag = blas.NonUnit + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + dlarnv(a[i*lda+i:i*lda+n], 2, rnd) + a[i*lda+i] = math.Copysign(2, a[i*lda+i]) + } + case blas.Lower: + for i := 0; i < n; i++ { + dlarnv(a[i*lda:i*lda+i+1], 2, rnd) + a[i*lda+i] = math.Copysign(2, a[i*lda+i]) + } + } + iy := n / 2 + a[iy*lda+iy] = 0 + dlarnv(b, 2, rnd) + bi.Dscal(n, 2, b, 1) + case 17: + // Make the offdiagonal elements large to cause overflow when + // adding a column of T. In the non-transposed case, the matrix + // is constructed to cause overflow when adding a column in + // every other step. + diag = blas.NonUnit + tscal := (1 - ulp) / (dlamchS / ulp) + texp := 1.0 + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + a[i*lda+j] = 0 + } + } + for j := n - 1; j >= 1; j -= 2 { + a[j] = -tscal / float64(n+1) + a[j*lda+j] = 1 + b[j] = texp * (1 - ulp) + a[j-1] = -tscal / float64(n+1) / float64(n+2) + a[(j-1)*lda+j-1] = 1 + b[j-1] = texp * float64(n*n+n-1) + texp *= 2 + } + b[0] = float64(n+1) / float64(n+2) * tscal + case blas.Lower: + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + a[i*lda+j] = 0 + } + } + for j := 0; j < n-1; j += 2 { + a[(n-1)*lda+j] = -tscal / float64(n+1) + a[j*lda+j] = 1 + b[j] = texp * (1 - ulp) + a[(n-1)*lda+j+1] = -tscal / float64(n+1) / float64(n+2) + a[(j+1)*lda+j+1] = 1 + b[j+1] = texp * float64(n*n+n-1) + texp *= 2 + } + b[n-1] = float64(n+1) / float64(n+2) * tscal + } + case 18: + // Generate a unit triangular matrix with elements between -1 + // and 1, and make the right hand side large so that it requires + // scaling. The diagonal is set to NaN. + diag = blas.Unit + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + a[i*lda+i] = math.NaN() + dlarnv(a[i*lda+i+1:i*lda+n], 2, rnd) + } + case blas.Lower: + for i := 0; i < n; i++ { + dlarnv(a[i*lda:i*lda+i], 2, rnd) + a[i*lda+i] = math.NaN() + } + } + // Set the right hand side so that the largest value is bignum. + dlarnv(b, 2, rnd) + iy := bi.Idamax(n, b, 1) + bnorm := math.Abs(b[iy]) + bscal := bignum / math.Max(1, bnorm) + bi.Dscal(n, bscal, b, 1) + case 19: + // Generate a triangular matrix with elements between + // bignum/(n-1) and bignum so that at least one of the column + // norms will exceed bignum. + // Dlatrs cannot handle this case for (typically) n>5. + diag = blas.NonUnit + tleft := bignum / math.Max(1, float64(n-1)) + tscal := bignum * (float64(n-1) / math.Max(1, float64(n))) + switch uplo { + case blas.Upper: + for i := 0; i < n; i++ { + dlarnv(a[i*lda+i:i*lda+n], 2, rnd) + for j := i; j < n; j++ { + aij := a[i*lda+j] + a[i*lda+j] = math.Copysign(tleft, aij) + tscal*aij + } + } + case blas.Lower: + for i := 0; i < n; i++ { + dlarnv(a[i*lda:i*lda+i+1], 2, rnd) + for j := 0; j <= i; j++ { + aij := a[i*lda+j] + a[i*lda+j] = math.Copysign(tleft, aij) + tscal*aij + } + } + } + dlarnv(b, 2, rnd) + bi.Dscal(n, 2, b, 1) + } + + // Flip the matrix if the transpose will be used. + if trans == blas.Trans { + switch uplo { + case blas.Upper: + for j := 0; j < n/2; j++ { + bi.Dswap(n-2*j-1, a[j*lda+j:], 1, a[(j+1)*lda+n-j-1:], -lda) + } + case blas.Lower: + for j := 0; j < n/2; j++ { + bi.Dswap(n-2*j-1, a[j*lda+j:], lda, a[(n-j-1)*lda+j+1:], -1) + } + } + } + + return diag +} + +func checkMatrix(m, n int, a []float64, lda int) { + if m < 0 { + panic("testlapack: m < 0") + } + if n < 0 { + panic("testlapack: n < 0") + } + if lda < max(1, n) { + panic("testlapack: lda < max(1, n)") + } + if len(a) < (m-1)*lda+n { + panic("testlapack: insufficient matrix slice length") + } +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/matgen_test.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/matgen_test.go new file mode 100644 index 00000000..1bb86d3c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/matgen_test.go @@ -0,0 +1,90 @@ +// 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 testlapack + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +func TestDlagsy(t *testing.T) { + const tol = 1e-14 + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{0, 1, 2, 3, 4, 5, 10, 50} { + for _, lda := range []int{0, 2*n + 1} { + if lda == 0 { + lda = max(1, n) + } + d := make([]float64, n) + for i := range d { + d[i] = 1 + } + a := blas64.General{ + Rows: n, + Cols: n, + Stride: lda, + Data: nanSlice(n * lda), + } + work := make([]float64, a.Rows+a.Cols) + + Dlagsy(a.Rows, 0, d, a.Data, a.Stride, rnd, work) + + isIdentity := true + identityLoop: + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + aij := a.Data[i*a.Stride+j] + if math.IsNaN(aij) { + isIdentity = false + } + if i == j && math.Abs(aij-1) > tol { + isIdentity = false + } + if i != j && math.Abs(aij) > tol { + isIdentity = false + } + if !isIdentity { + break identityLoop + } + } + } + if !isIdentity { + t.Errorf("Case n=%v,lda=%v: unexpected result", n, lda) + } + } + } +} + +func TestDlagge(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{0, 1, 2, 3, 4, 5, 10, 50} { + for _, lda := range []int{0, 2*n + 1} { + if lda == 0 { + lda = max(1, n) + } + d := make([]float64, n) + for i := range d { + d[i] = 1 + } + a := blas64.General{ + Rows: n, + Cols: n, + Stride: lda, + Data: nanSlice(n * lda), + } + work := make([]float64, a.Rows+a.Cols) + + Dlagge(a.Rows, a.Cols, 0, 0, d, a.Data, a.Stride, rnd, work) + + if !isOrthonormal(a) { + t.Errorf("Case n=%v,lda=%v: unexpected result", n, lda) + } + } + } + +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/test_matrices.go b/vendor/gonum.org/v1/gonum/lapack/testlapack/test_matrices.go new file mode 100644 index 00000000..6be490b2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/lapack/testlapack/test_matrices.go @@ -0,0 +1,615 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testlapack + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/blas/blas64" +) + +// A123 is the non-symmetric singular matrix +// [ 1 2 3 ] +// A = [ 4 5 6 ] +// [ 7 8 9 ] +// It has three distinct real eigenvalues. +type A123 struct{} + +func (A123) Matrix() blas64.General { + return blas64.General{ + Rows: 3, + Cols: 3, + Stride: 3, + Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }, + } +} + +func (A123) Eigenvalues() []complex128 { + return []complex128{16.116843969807043, -1.116843969807043, 0} +} + +func (A123) LeftEV() blas64.General { + return blas64.General{ + Rows: 3, + Cols: 3, + Stride: 3, + Data: []float64{ + -0.464547273387671, -0.570795531228578, -0.677043789069485, + -0.882905959653586, -0.239520420054206, 0.403865119545174, + 0.408248290463862, -0.816496580927726, 0.408248290463863, + }, + } +} + +func (A123) RightEV() blas64.General { + return blas64.General{ + Rows: 3, + Cols: 3, + Stride: 3, + Data: []float64{ + -0.231970687246286, -0.785830238742067, 0.408248290463864, + -0.525322093301234, -0.086751339256628, -0.816496580927726, + -0.818673499356181, 0.612327560228810, 0.408248290463863, + }, + } +} + +// AntisymRandom is a anti-symmetric random matrix. All its eigenvalues are +// imaginary with one zero if the order is odd. +type AntisymRandom struct { + mat blas64.General +} + +func NewAntisymRandom(n int, rnd *rand.Rand) AntisymRandom { + a := zeros(n, n, n) + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + r := rnd.NormFloat64() + a.Data[i*a.Stride+j] = r + a.Data[j*a.Stride+i] = -r + } + } + return AntisymRandom{a} +} + +func (a AntisymRandom) Matrix() blas64.General { + return cloneGeneral(a.mat) +} + +func (AntisymRandom) Eigenvalues() []complex128 { + return nil +} + +// Circulant is a generally non-symmetric matrix given by +// A[i,j] = 1 + (j-i+n)%n. +// For example, for n=5, +// [ 1 2 3 4 5 ] +// [ 5 1 2 3 4 ] +// A = [ 4 5 1 2 3 ] +// [ 3 4 5 1 2 ] +// [ 2 3 4 5 1 ] +// It has real and complex eigenvalues, some possibly repeated. +type Circulant int + +func (c Circulant) Matrix() blas64.General { + n := int(c) + a := zeros(n, n, n) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + a.Data[i*a.Stride+j] = float64(1 + (j-i+n)%n) + } + } + return a +} + +func (c Circulant) Eigenvalues() []complex128 { + n := int(c) + w := rootsOfUnity(n) + ev := make([]complex128, n) + for k := 0; k < n; k++ { + ev[k] = complex(float64(n), 0) + } + for i := n - 1; i > 0; i-- { + for k := 0; k < n; k++ { + ev[k] = ev[k]*w[k] + complex(float64(i), 0) + } + } + return ev +} + +// Clement is a generally non-symmetric matrix given by +// A[i,j] = i+1, if j == i+1, +// = n-i, if j == i-1, +// = 0, otherwise. +// For example, for n=5, +// [ . 1 . . . ] +// [ 4 . 2 . . ] +// A = [ . 3 . 3 . ] +// [ . . 2 . 4 ] +// [ . . . 1 . ] +// It has n distinct real eigenvalues. +type Clement int + +func (c Clement) Matrix() blas64.General { + n := int(c) + a := zeros(n, n, n) + for i := 0; i < n; i++ { + if i < n-1 { + a.Data[i*a.Stride+i+1] = float64(i + 1) + } + if i > 0 { + a.Data[i*a.Stride+i-1] = float64(n - i) + } + } + return a +} + +func (c Clement) Eigenvalues() []complex128 { + n := int(c) + ev := make([]complex128, n) + for i := range ev { + ev[i] = complex(float64(-n+2*i+1), 0) + } + return ev +} + +// Creation is a singular non-symmetric matrix given by +// A[i,j] = i, if j == i-1, +// = 0, otherwise. +// For example, for n=5, +// [ . . . . . ] +// [ 1 . . . . ] +// A = [ . 2 . . . ] +// [ . . 3 . . ] +// [ . . . 4 . ] +// Zero is its only eigenvalue. +type Creation int + +func (c Creation) Matrix() blas64.General { + n := int(c) + a := zeros(n, n, n) + for i := 1; i < n; i++ { + a.Data[i*a.Stride+i-1] = float64(i) + } + return a +} + +func (c Creation) Eigenvalues() []complex128 { + return make([]complex128, int(c)) +} + +// Diagonal is a diagonal matrix given by +// A[i,j] = i+1, if i == j, +// = 0, otherwise. +// For example, for n=5, +// [ 1 . . . . ] +// [ . 2 . . . ] +// A = [ . . 3 . . ] +// [ . . . 4 . ] +// [ . . . . 5 ] +// It has n real eigenvalues {1,...,n}. +type Diagonal int + +func (d Diagonal) Matrix() blas64.General { + n := int(d) + a := zeros(n, n, n) + for i := 0; i < n; i++ { + a.Data[i*a.Stride+i] = float64(i) + } + return a +} + +func (d Diagonal) Eigenvalues() []complex128 { + n := int(d) + ev := make([]complex128, n) + for i := range ev { + ev[i] = complex(float64(i), 0) + } + return ev +} + +// Downshift is a non-singular upper Hessenberg matrix given by +// A[i,j] = 1, if (i-j+n)%n == 1, +// = 0, otherwise. +// For example, for n=5, +// [ . . . . 1 ] +// [ 1 . . . . ] +// A = [ . 1 . . . ] +// [ . . 1 . . ] +// [ . . . 1 . ] +// Its eigenvalues are the complex roots of unity. +type Downshift int + +func (d Downshift) Matrix() blas64.General { + n := int(d) + a := zeros(n, n, n) + a.Data[n-1] = 1 + for i := 1; i < n; i++ { + a.Data[i*a.Stride+i-1] = 1 + } + return a +} + +func (d Downshift) Eigenvalues() []complex128 { + return rootsOfUnity(int(d)) +} + +// Fibonacci is an upper Hessenberg matrix with 3 distinct real eigenvalues. For +// example, for n=5, +// [ . 1 . . . ] +// [ 1 1 . . . ] +// A = [ . 1 1 . . ] +// [ . . 1 1 . ] +// [ . . . 1 1 ] +type Fibonacci int + +func (f Fibonacci) Matrix() blas64.General { + n := int(f) + a := zeros(n, n, n) + if n > 1 { + a.Data[1] = 1 + } + for i := 1; i < n; i++ { + a.Data[i*a.Stride+i-1] = 1 + a.Data[i*a.Stride+i] = 1 + } + return a +} + +func (f Fibonacci) Eigenvalues() []complex128 { + n := int(f) + ev := make([]complex128, n) + if n == 0 || n == 1 { + return ev + } + phi := 0.5 * (1 + math.Sqrt(5)) + ev[0] = complex(phi, 0) + for i := 1; i < n-1; i++ { + ev[i] = 1 + 0i + } + ev[n-1] = complex(1-phi, 0) + return ev +} + +// Gear is a singular non-symmetric matrix with real eigenvalues. For example, +// for n=5, +// [ . 1 . . 1 ] +// [ 1 . 1 . . ] +// A = [ . 1 . 1 . ] +// [ . . 1 . 1 ] +// [-1 . . 1 . ] +type Gear int + +func (g Gear) Matrix() blas64.General { + n := int(g) + a := zeros(n, n, n) + if n == 1 { + return a + } + for i := 0; i < n-1; i++ { + a.Data[i*a.Stride+i+1] = 1 + } + for i := 1; i < n; i++ { + a.Data[i*a.Stride+i-1] = 1 + } + a.Data[n-1] = 1 + a.Data[(n-1)*a.Stride] = -1 + return a +} + +func (g Gear) Eigenvalues() []complex128 { + n := int(g) + ev := make([]complex128, n) + if n == 0 || n == 1 { + return ev + } + if n == 2 { + ev[0] = complex(0, 1) + ev[1] = complex(0, -1) + return ev + } + w := 0 + ev[w] = math.Pi / 2 + w++ + phi := (n - 1) / 2 + for p := 1; p <= phi; p++ { + ev[w] = complex(float64(2*p)*math.Pi/float64(n), 0) + w++ + } + phi = n / 2 + for p := 1; p <= phi; p++ { + ev[w] = complex(float64(2*p-1)*math.Pi/float64(n), 0) + w++ + } + for i, v := range ev { + ev[i] = complex(2*math.Cos(real(v)), 0) + } + return ev +} + +// Grcar is an upper Hessenberg matrix given by +// A[i,j] = -1 if i == j+1, +// = 1 if i <= j and j <= i+k, +// = 0 otherwise. +// For example, for n=5 and k=2, +// [ 1 1 1 . . ] +// [ -1 1 1 1 . ] +// A = [ . -1 1 1 1 ] +// [ . . -1 1 1 ] +// [ . . . -1 1 ] +// The matrix has sensitive eigenvalues but they are not given explicitly. +type Grcar struct { + N int + K int +} + +func (g Grcar) Matrix() blas64.General { + n := g.N + a := zeros(n, n, n) + for k := 0; k <= g.K; k++ { + for i := 0; i < n-k; i++ { + a.Data[i*a.Stride+i+k] = 1 + } + } + for i := 1; i < n; i++ { + a.Data[i*a.Stride+i-1] = -1 + } + return a +} + +func (Grcar) Eigenvalues() []complex128 { + return nil +} + +// Hanowa is a non-symmetric non-singular matrix of even order given by +// A[i,j] = alpha if i == j, +// = -i-1 if i < n/2 and j == i + n/2, +// = i+1-n/2 if i >= n/2 and j == i - n/2, +// = 0 otherwise. +// The matrix has complex eigenvalues. +type Hanowa struct { + N int // Order of the matrix, must be even. + Alpha float64 +} + +func (h Hanowa) Matrix() blas64.General { + if h.N&0x1 != 0 { + panic("lapack: matrix order must be even") + } + n := h.N + a := zeros(n, n, n) + for i := 0; i < n; i++ { + a.Data[i*a.Stride+i] = h.Alpha + } + for i := 0; i < n/2; i++ { + a.Data[i*a.Stride+i+n/2] = float64(-i - 1) + } + for i := n / 2; i < n; i++ { + a.Data[i*a.Stride+i-n/2] = float64(i + 1 - n/2) + } + return a +} + +func (h Hanowa) Eigenvalues() []complex128 { + if h.N&0x1 != 0 { + panic("lapack: matrix order must be even") + } + n := int(h.N) + ev := make([]complex128, n) + for i := 0; i < n/2; i++ { + ev[2*i] = complex(h.Alpha, float64(-i-1)) + ev[2*i+1] = complex(h.Alpha, float64(i+1)) + } + return ev +} + +// Lesp is a tridiagonal, generally non-symmetric matrix given by +// A[i,j] = -2*i-5 if i == j, +// = 1/(i+1) if i == j-1, +// = j+1 if i == j+1. +// For example, for n=5, +// [ -5 2 . . . ] +// [ 1/2 -7 3 . . ] +// A = [ . 1/3 -9 4 . ] +// [ . . 1/4 -11 5 ] +// [ . . . 1/5 -13 ]. +// The matrix has sensitive eigenvalues but they are not given explicitly. +type Lesp int + +func (l Lesp) Matrix() blas64.General { + n := int(l) + a := zeros(n, n, n) + for i := 0; i < n; i++ { + a.Data[i*a.Stride+i] = float64(-2*i - 5) + } + for i := 0; i < n-1; i++ { + a.Data[i*a.Stride+i+1] = float64(i + 2) + } + for i := 1; i < n; i++ { + a.Data[i*a.Stride+i-1] = 1 / float64(i+1) + } + return a +} + +func (Lesp) Eigenvalues() []complex128 { + return nil +} + +// Rutis is the 4×4 non-symmetric matrix +// [ 4 -5 0 3 ] +// A = [ 0 4 -3 -5 ] +// [ 5 -3 4 0 ] +// [ 3 0 5 4 ] +// It has two distinct real eigenvalues and a pair of complex eigenvalues. +type Rutis struct{} + +func (Rutis) Matrix() blas64.General { + return blas64.General{ + Rows: 4, + Cols: 4, + Stride: 4, + Data: []float64{ + 4, -5, 0, 3, + 0, 4, -3, -5, + 5, -3, 4, 0, + 3, 0, 5, 4, + }, + } +} + +func (Rutis) Eigenvalues() []complex128 { + return []complex128{12, 1 + 5i, 1 - 5i, 2} +} + +// Tris is a tridiagonal matrix given by +// A[i,j] = x if i == j-1, +// = y if i == j, +// = z if i == j+1. +// If x*z is negative, the matrix has complex eigenvalues. +type Tris struct { + N int + X, Y, Z float64 +} + +func (t Tris) Matrix() blas64.General { + n := t.N + a := zeros(n, n, n) + for i := 1; i < n; i++ { + a.Data[i*a.Stride+i-1] = t.X + } + for i := 0; i < n; i++ { + a.Data[i*a.Stride+i] = t.Y + } + for i := 0; i < n-1; i++ { + a.Data[i*a.Stride+i+1] = t.Z + } + return a +} + +func (t Tris) Eigenvalues() []complex128 { + n := int(t.N) + ev := make([]complex128, n) + for i := range ev { + angle := float64(i+1) * math.Pi / float64(n+1) + arg := t.X * t.Z + if arg >= 0 { + ev[i] = complex(t.Y+2*math.Sqrt(arg)*math.Cos(angle), 0) + } else { + ev[i] = complex(t.Y, 2*math.Sqrt(-arg)*math.Cos(angle)) + } + } + return ev +} + +// Wilk4 is a 4×4 lower triangular matrix with 4 distinct real eigenvalues. +type Wilk4 struct{} + +func (Wilk4) Matrix() blas64.General { + return blas64.General{ + Rows: 4, + Cols: 4, + Stride: 4, + Data: []float64{ + 0.9143e-4, 0.0, 0.0, 0.0, + 0.8762, 0.7156e-4, 0.0, 0.0, + 0.7943, 0.8143, 0.9504e-4, 0.0, + 0.8017, 0.6123, 0.7165, 0.7123e-4, + }, + } +} + +func (Wilk4) Eigenvalues() []complex128 { + return []complex128{ + 0.9504e-4, 0.9143e-4, 0.7156e-4, 0.7123e-4, + } +} + +// Wilk12 is a 12×12 lower Hessenberg matrix with 12 distinct real eigenvalues. +type Wilk12 struct{} + +func (Wilk12) Matrix() blas64.General { + return blas64.General{ + Rows: 12, + Cols: 12, + Stride: 12, + Data: []float64{ + 12, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 11, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 10, 10, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 8, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 8, 8, 8, 7, 0, 0, 0, 0, 0, 0, + 7, 7, 7, 7, 7, 7, 6, 0, 0, 0, 0, 0, + 6, 6, 6, 6, 6, 6, 6, 5, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 4, 0, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + }, + } +} + +func (Wilk12) Eigenvalues() []complex128 { + return []complex128{ + 32.2288915015722210, + 20.1989886458770691, + 12.3110774008685340, + 6.9615330855671154, + 3.5118559485807528, + 1.5539887091319704, + 0.6435053190136506, + 0.2847497205488856, + 0.1436465181918488, + 0.0812276683076552, + 0.0495074140194613, + 0.0310280683208907, + } +} + +// Wilk20 is a 20×20 lower Hessenberg matrix. If the parameter is 0, the matrix +// has 20 distinct real eigenvalues. If the parameter is 1e-10, the matrix has 6 +// real eigenvalues and 7 pairs of complex eigenvalues. +type Wilk20 float64 + +func (w Wilk20) Matrix() blas64.General { + a := zeros(20, 20, 20) + for i := 0; i < 20; i++ { + a.Data[i*a.Stride+i] = float64(i + 1) + } + for i := 0; i < 19; i++ { + a.Data[i*a.Stride+i+1] = 20 + } + a.Data[19*a.Stride] = float64(w) + return a +} + +func (w Wilk20) Eigenvalues() []complex128 { + if float64(w) == 0 { + ev := make([]complex128, 20) + for i := range ev { + ev[i] = complex(float64(i+1), 0) + } + return ev + } + return nil +} + +// Zero is a matrix with all elements equal to zero. +type Zero int + +func (z Zero) Matrix() blas64.General { + n := int(z) + return zeros(n, n, n) +} + +func (z Zero) Eigenvalues() []complex128 { + n := int(z) + return make([]complex128, n) +} diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/testdata/dlahr2data.json.gz b/vendor/gonum.org/v1/gonum/lapack/testlapack/testdata/dlahr2data.json.gz new file mode 100644 index 00000000..7652126a Binary files /dev/null and b/vendor/gonum.org/v1/gonum/lapack/testlapack/testdata/dlahr2data.json.gz differ diff --git a/vendor/gonum.org/v1/gonum/lapack/testlapack/testdata/dlaqr5data.json.gz b/vendor/gonum.org/v1/gonum/lapack/testlapack/testdata/dlaqr5data.json.gz new file mode 100644 index 00000000..9e629480 Binary files /dev/null and b/vendor/gonum.org/v1/gonum/lapack/testlapack/testdata/dlaqr5data.json.gz differ diff --git a/vendor/gonum.org/v1/gonum/mat/README.md b/vendor/gonum.org/v1/gonum/mat/README.md new file mode 100644 index 00000000..151e8a27 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/README.md @@ -0,0 +1,3 @@ +# Gonum matrix [![GoDoc](https://godoc.org/gonum.org/v1/gonum/matrix?status.svg)](https://godoc.org/gonum.org/v1/gonum/matrix) + +Package matrix is a matrix package for the Go language. diff --git a/vendor/gonum.org/v1/gonum/mat/band.go b/vendor/gonum.org/v1/gonum/mat/band.go new file mode 100644 index 00000000..296040ea --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/band.go @@ -0,0 +1,228 @@ +// 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 mat + +import ( + "gonum.org/v1/gonum/blas/blas64" +) + +var ( + bandDense *BandDense + _ Matrix = bandDense + _ Banded = bandDense + _ RawBander = bandDense + + _ NonZeroDoer = bandDense + _ RowNonZeroDoer = bandDense + _ ColNonZeroDoer = bandDense +) + +// BandDense represents a band matrix in dense storage format. +type BandDense struct { + mat blas64.Band +} + +// Banded is a band matrix representation. +type Banded interface { + Matrix + // Bandwidth returns the lower and upper bandwidth values for + // the matrix. The total bandwidth of the matrix is kl+ku+1. + Bandwidth() (kl, ku int) + + // TBand is the equivalent of the T() method in the Matrix + // interface but guarantees the transpose is of banded type. + TBand() Banded +} + +// A RawBander can return a blas64.Band representation of the receiver. +// Changes to the blas64.Band.Data slice will be reflected in the original +// matrix, changes to the Rows, Cols, KL, KU and Stride fields will not. +type RawBander interface { + RawBand() blas64.Band +} + +// A MutableBanded can set elements of a band matrix. +type MutableBanded interface { + Banded + SetBand(i, j int, v float64) +} + +var ( + _ Matrix = TransposeBand{} + _ Banded = TransposeBand{} + _ UntransposeBander = TransposeBand{} +) + +// TransposeBand is a type for performing an implicit transpose of a band +// matrix. It implements the Banded interface, returning values from the +// transpose of the matrix within. +type TransposeBand struct { + Banded Banded +} + +// At returns the value of the element at row i and column j of the transposed +// matrix, that is, row j and column i of the Banded field. +func (t TransposeBand) At(i, j int) float64 { + return t.Banded.At(j, i) +} + +// Dims returns the dimensions of the transposed matrix. +func (t TransposeBand) Dims() (r, c int) { + c, r = t.Banded.Dims() + return r, c +} + +// T performs an implicit transpose by returning the Banded field. +func (t TransposeBand) T() Matrix { + return t.Banded +} + +// Bandwidth returns the lower and upper bandwidth values for +// the transposed matrix. +func (t TransposeBand) Bandwidth() (kl, ku int) { + kl, ku = t.Banded.Bandwidth() + return ku, kl +} + +// TBand performs an implicit transpose by returning the Banded field. +func (t TransposeBand) TBand() Banded { + return t.Banded +} + +// Untranspose returns the Banded field. +func (t TransposeBand) Untranspose() Matrix { + return t.Banded +} + +// UntransposeBand returns the Banded field. +func (t TransposeBand) UntransposeBand() Banded { + return t.Banded +} + +// NewBandDense creates a new Band matrix with r rows and c columns. If data == nil, +// a new slice is allocated for the backing slice. If len(data) == min(r, c+kl)*(kl+ku+1), +// data is used as the backing slice, and changes to the elements of the returned +// BandDense will be reflected in data. If neither of these is true, NewBandDense +// will panic. kl must be at least zero and less r, and ku must be at least zero and +// less than c, otherwise NewBandDense will panic. +// +// The data must be arranged in row-major order constructed by removing the zeros +// from the rows outside the band 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 +// 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 passed to NewBandDense as []float64{*, 1, 2, 3, 4, ...} with kl=1 and ku=2. +// Only the values in the band portion of the matrix are used. +func NewBandDense(r, c, kl, ku int, data []float64) *BandDense { + if r < 0 || c < 0 || kl < 0 || ku < 0 { + panic("mat: negative dimension") + } + if kl+1 > r || ku+1 > c { + panic("mat: band out of range") + } + bc := kl + ku + 1 + if data != nil && len(data) != min(r, c+kl)*bc { + panic(ErrShape) + } + if data == nil { + data = make([]float64, min(r, c+kl)*bc) + } + return &BandDense{ + mat: blas64.Band{ + Rows: r, + Cols: c, + KL: kl, + KU: ku, + Stride: bc, + Data: data, + }, + } +} + +// NewDiagonalRect is a convenience function that returns a diagonal matrix represented by a +// BandDense. The length of data must be min(r, c) otherwise NewDiagonalRect will panic. +func NewDiagonalRect(r, c int, data []float64) *BandDense { + return NewBandDense(r, c, 0, 0, data) +} + +// Dims returns the number of rows and columns in the matrix. +func (b *BandDense) Dims() (r, c int) { + return b.mat.Rows, b.mat.Cols +} + +// Bandwidth returns the upper and lower bandwidths of the matrix. +func (b *BandDense) Bandwidth() (kl, ku int) { + return b.mat.KL, b.mat.KU +} + +// T performs an implicit transpose by returning the receiver inside a Transpose. +func (b *BandDense) T() Matrix { + return Transpose{b} +} + +// TBand performs an implicit transpose by returning the receiver inside a TransposeBand. +func (b *BandDense) TBand() Banded { + return TransposeBand{b} +} + +// RawBand returns the underlying blas64.Band used by the receiver. +// Changes to elements in the receiver following the call will be reflected +// in returned blas64.Band. +func (b *BandDense) RawBand() blas64.Band { + return b.mat +} + +// DoNonZero calls the function fn for each of the non-zero elements of b. The function fn +// takes a row/column index and the element value of b at (i, j). +func (b *BandDense) DoNonZero(fn func(i, j int, v float64)) { + for i := 0; i < min(b.mat.Rows, b.mat.Cols+b.mat.KL); i++ { + for j := max(0, i-b.mat.KL); j < min(b.mat.Cols, i+b.mat.KU+1); j++ { + v := b.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + } +} + +// DoRowNonZero calls the function fn for each of the non-zero elements of row i of b. The function fn +// takes a row/column index and the element value of b at (i, j). +func (b *BandDense) DoRowNonZero(i int, fn func(i, j int, v float64)) { + if i < 0 || b.mat.Rows <= i { + panic(ErrRowAccess) + } + for j := max(0, i-b.mat.KL); j < min(b.mat.Cols, i+b.mat.KU+1); j++ { + v := b.at(i, j) + if v != 0 { + fn(i, j, v) + } + } +} + +// DoColNonZero calls the function fn for each of the non-zero elements of column j of b. The function fn +// takes a row/column index and the element value of b at (i, j). +func (b *BandDense) DoColNonZero(j int, fn func(i, j int, v float64)) { + if j < 0 || b.mat.Cols <= j { + panic(ErrColAccess) + } + for i := 0; i < min(b.mat.Rows, b.mat.Cols+b.mat.KL); i++ { + if i-b.mat.KL <= j && j < i+b.mat.KU+1 { + v := b.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/band_test.go b/vendor/gonum.org/v1/gonum/mat/band_test.go new file mode 100644 index 00000000..f24d7f5c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/band_test.go @@ -0,0 +1,377 @@ +// 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 mat + +import ( + "reflect" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +func TestNewBand(t *testing.T) { + for i, test := range []struct { + data []float64 + r, c int + kl, ku int + mat *BandDense + dense *Dense + }{ + { + data: []float64{ + -1, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, -1, + 19, 20, -1, -1, + }, + r: 6, c: 6, + kl: 1, ku: 2, + mat: &BandDense{ + mat: blas64.Band{ + Rows: 6, + Cols: 6, + KL: 1, + KU: 2, + Stride: 4, + Data: []float64{ + -1, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, -1, + 19, 20, -1, -1, + }, + }, + }, + dense: NewDense(6, 6, []float64{ + 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, + }), + }, + { + data: []float64{ + -1, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, -1, + 19, 20, -1, -1, + 21, -1, -1, -1, + }, + r: 10, c: 6, + kl: 1, ku: 2, + mat: &BandDense{ + mat: blas64.Band{ + Rows: 10, + Cols: 6, + KL: 1, + KU: 2, + Stride: 4, + Data: []float64{ + -1, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, -1, + 19, 20, -1, -1, + 21, -1, -1, -1, + }, + }, + }, + dense: NewDense(10, 6, []float64{ + 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, + 0, 0, 0, 0, 0, 21, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + }), + }, + { + data: []float64{ + -1, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, 19, + 20, 21, 22, 23, + }, + r: 6, c: 10, + kl: 1, ku: 2, + mat: &BandDense{ + mat: blas64.Band{ + Rows: 6, + Cols: 10, + KL: 1, + KU: 2, + Stride: 4, + Data: []float64{ + -1, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, 19, + 20, 21, 22, 23, + }, + }, + }, + dense: NewDense(6, 10, []float64{ + 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, + 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, + 0, 8, 9, 10, 11, 0, 0, 0, 0, 0, + 0, 0, 12, 13, 14, 15, 0, 0, 0, 0, + 0, 0, 0, 16, 17, 18, 19, 0, 0, 0, + 0, 0, 0, 0, 20, 21, 22, 23, 0, 0, + }), + }, + } { + band := NewBandDense(test.r, test.c, test.kl, test.ku, test.data) + rows, cols := band.Dims() + + if rows != test.r { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.r) + } + if cols != test.c { + t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.c) + } + if !reflect.DeepEqual(band, test.mat) { + t.Errorf("unexpected value via reflect for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.mat) { + t.Errorf("unexpected value via mat.Equal for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.dense) { + t.Errorf("unexpected value via mat.Equal(band, dense) for test %d:\ngot:\n% v\nwant:\n% v", i, Formatted(band), Formatted(test.dense)) + } + } +} + +func TestNewDiagonalRect(t *testing.T) { + for i, test := range []struct { + data []float64 + r, c int + mat *BandDense + dense *Dense + }{ + { + data: []float64{1, 2, 3, 4, 5, 6}, + r: 6, c: 6, + mat: &BandDense{ + mat: blas64.Band{ + Rows: 6, + Cols: 6, + Stride: 1, + Data: []float64{1, 2, 3, 4, 5, 6}, + }, + }, + dense: NewDense(6, 6, []float64{ + 1, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 6, + }), + }, + { + data: []float64{1, 2, 3, 4, 5, 6}, + r: 7, c: 6, + mat: &BandDense{ + mat: blas64.Band{ + Rows: 7, + Cols: 6, + Stride: 1, + Data: []float64{1, 2, 3, 4, 5, 6}, + }, + }, + dense: NewDense(7, 6, []float64{ + 1, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 0, 0, + }), + }, + { + data: []float64{1, 2, 3, 4, 5, 6}, + r: 6, c: 7, + mat: &BandDense{ + mat: blas64.Band{ + Rows: 6, + Cols: 7, + Stride: 1, + Data: []float64{1, 2, 3, 4, 5, 6}, + }, + }, + dense: NewDense(6, 7, []float64{ + 1, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, + 0, 0, 0, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 6, 0, + }), + }, + } { + band := NewDiagonalRect(test.r, test.c, test.data) + rows, cols := band.Dims() + + if rows != test.r { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.r) + } + if cols != test.c { + t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.c) + } + if !reflect.DeepEqual(band, test.mat) { + t.Errorf("unexpected value via reflect for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.mat) { + t.Errorf("unexpected value via mat.Equal for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.dense) { + t.Errorf("unexpected value via mat.Equal(band, dense) for test %d:\ngot:\n% v\nwant:\n% v", i, Formatted(band), Formatted(test.dense)) + } + } +} + +func TestBandAtSet(t *testing.T) { + // 2 3 4 0 0 0 + // 5 6 7 8 0 0 + // 0 9 10 11 12 0 + // 0 0 13 14 15 16 + // 0 0 0 17 18 19 + // 0 0 0 0 21 22 + band := NewBandDense(6, 6, 1, 2, []float64{ + -1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16, + 17, 18, 19, -1, + 21, 22, -1, -1, + }) + + rows, cols := band.Dims() + kl, ku := band.Bandwidth() + + // Explicitly test all indexes. + want := bandImplicit{rows, cols, kl, ku, func(i, j int) float64 { + return float64(i*(kl+ku) + j + kl + 1) + }} + for i := 0; i < 6; i++ { + for j := 0; j < 6; j++ { + if band.At(i, j) != want.At(i, j) { + t.Errorf("unexpected value for band.At(%d, %d): got:%v want:%v", i, j, band.At(i, j), want.At(i, j)) + } + } + } + // Do that same thing via a call to Equal. + if !Equal(band, want) { + t.Errorf("unexpected value via mat.Equal:\ngot:\n% v\nwant:\n% v", Formatted(band), Formatted(want)) + } + + // Check At out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { band.At(row, 0) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { band.At(0, col) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + // Check Set out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { band.SetBand(row, 0, 1.2) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { band.SetBand(0, col, 1.2) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + for _, st := range []struct { + row, col int + }{ + {row: 0, col: 3}, + {row: 0, col: 4}, + {row: 0, col: 5}, + {row: 1, col: 4}, + {row: 1, col: 5}, + {row: 2, col: 5}, + {row: 2, col: 0}, + {row: 3, col: 1}, + {row: 4, col: 2}, + {row: 5, col: 3}, + } { + panicked, message := panics(func() { band.SetBand(st.row, st.col, 1.2) }) + if !panicked || message != ErrBandSet.Error() { + t.Errorf("expected panic for %+v %s", st, message) + } + } + + for _, st := range []struct { + row, col int + orig, new float64 + }{ + {row: 1, col: 2, orig: 7, new: 15}, + {row: 2, col: 3, orig: 11, new: 15}, + } { + if e := band.At(st.row, st.col); e != st.orig { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", st.row, st.col, e, st.orig) + } + band.SetBand(st.row, st.col, st.new) + if e := band.At(st.row, st.col); e != st.new { + t.Errorf("unexpected value for At(%d, %d) after SetBand(%[1]d, %d, %v): got: %v want: %[3]v", st.row, st.col, st.new, e) + } + } +} + +// bandImplicit is an implicit band matrix returning val(i, j) +// for the value at (i, j). +type bandImplicit struct { + r, c, kl, ku int + val func(i, j int) float64 +} + +func (b bandImplicit) Dims() (r, c int) { + return b.r, b.c +} + +func (b bandImplicit) T() Matrix { + return Transpose{b} +} + +func (b bandImplicit) At(i, j int) float64 { + if i < 0 || b.r <= i { + panic("row") + } + if j < 0 || b.c <= j { + panic("col") + } + if j < i-b.kl || i+b.ku < j { + return 0 + } + return b.val(i, j) +} diff --git a/vendor/gonum.org/v1/gonum/mat/cblas_test.go b/vendor/gonum.org/v1/gonum/mat/cblas_test.go new file mode 100644 index 00000000..7371e8ba --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/cblas_test.go @@ -0,0 +1,16 @@ +// 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. + +//+build cblas + +package mat + +import ( + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/netlib/blas" +) + +func init() { + blas64.Use(blas.Implementation{}) +} diff --git a/vendor/gonum.org/v1/gonum/mat/cholesky.go b/vendor/gonum.org/v1/gonum/mat/cholesky.go new file mode 100644 index 00000000..fa4e91c6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/cholesky.go @@ -0,0 +1,479 @@ +// 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. + +package mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack/lapack64" +) + +const ( + badTriangle = "mat: invalid triangle" + badCholesky = "mat: invalid Cholesky factorization" +) + +// Cholesky is a type for creating and using the Cholesky factorization of a +// symmetric positive definite matrix. +// +// Cholesky methods may only be called on a value that has been successfully +// initialized by a call to Factorize that has returned true. Calls to methods +// of an unsuccessful Cholesky factorization will panic. +type Cholesky struct { + // The chol pointer must never be retained as a pointer outside the Cholesky + // struct, either by returning chol outside the struct or by setting it to + // a pointer coming from outside. The same prohibition applies to the data + // slice within chol. + chol *TriDense + cond float64 +} + +// updateCond updates the condition number of the Cholesky decomposition. If +// norm > 0, then that norm is used as the norm of the original matrix A, otherwise +// the norm is estimated from the decomposition. +func (c *Cholesky) updateCond(norm float64) { + n := c.chol.mat.N + work := getFloats(3*n, false) + defer putFloats(work) + if norm < 0 { + // This is an approximation. By the definition of a norm, + // |AB| <= |A| |B|. + // Since A = U^T*U, we get for the condition number κ that + // κ(A) := |A| |A^-1| = |U^T*U| |A^-1| <= |U^T| |U| |A^-1|, + // so this will overestimate the condition number somewhat. + // The norm of the original factorized matrix cannot be stored + // because of update possibilities. + unorm := lapack64.Lantr(CondNorm, c.chol.mat, work) + lnorm := lapack64.Lantr(CondNormTrans, c.chol.mat, work) + norm = unorm * lnorm + } + sym := c.chol.asSymBlas() + iwork := getInts(n, false) + v := lapack64.Pocon(sym, norm, work, iwork) + putInts(iwork) + c.cond = 1 / v +} + +// Cond returns the condition number of the factorized matrix. +func (c *Cholesky) Cond() float64 { + return c.cond +} + +// Factorize calculates the Cholesky decomposition of the matrix A and returns +// whether the matrix is positive definite. If Factorize returns false, the +// factorization must not be used. +func (c *Cholesky) Factorize(a Symmetric) (ok bool) { + n := a.Symmetric() + if c.isZero() { + c.chol = NewTriDense(n, Upper, nil) + } else { + c.chol = NewTriDense(n, Upper, use(c.chol.mat.Data, n*n)) + } + copySymIntoTriangle(c.chol, a) + + sym := c.chol.asSymBlas() + work := getFloats(c.chol.mat.N, false) + norm := lapack64.Lansy(CondNorm, sym, work) + putFloats(work) + _, ok = lapack64.Potrf(sym) + if ok { + c.updateCond(norm) + } else { + c.Reset() + } + return ok +} + +// Reset resets the factorization so that it can be reused as the receiver of a +// dimensionally restricted operation. +func (c *Cholesky) Reset() { + if !c.isZero() { + c.chol.Reset() + } + c.cond = math.Inf(1) +} + +// SetFromU sets the Cholesky decomposition from the given triangular matrix. +// SetFromU panics if t is not upper triangular. Note that t is copied into, +// not stored inside, the receiver. +func (c *Cholesky) SetFromU(t *TriDense) { + n, kind := t.Triangle() + if kind != Upper { + panic("cholesky: matrix must be upper triangular") + } + if c.isZero() { + c.chol = NewTriDense(n, Upper, nil) + } else { + c.chol = NewTriDense(n, Upper, use(c.chol.mat.Data, n*n)) + } + c.chol.Copy(t) + c.updateCond(-1) +} + +// Clone makes a copy of the input Cholesky into the receiver, overwriting the +// previous value of the receiver. Clone does not place any restrictions on receiver +// shape. Clone panics if the input Cholesky is not the result of a valid decomposition. +func (c *Cholesky) Clone(chol *Cholesky) { + if !chol.valid() { + panic(badCholesky) + } + n := chol.Size() + if c.isZero() { + c.chol = NewTriDense(n, Upper, nil) + } else { + c.chol = NewTriDense(n, Upper, use(c.chol.mat.Data, n*n)) + } + c.chol.Copy(chol.chol) + c.cond = chol.cond +} + +// Size returns the dimension of the factorized matrix. +func (c *Cholesky) Size() int { + if !c.valid() { + panic(badCholesky) + } + return c.chol.mat.N +} + +// Det returns the determinant of the matrix that has been factorized. +func (c *Cholesky) Det() float64 { + if !c.valid() { + panic(badCholesky) + } + return math.Exp(c.LogDet()) +} + +// LogDet returns the log of the determinant of the matrix that has been factorized. +func (c *Cholesky) LogDet() float64 { + if !c.valid() { + panic(badCholesky) + } + var det float64 + for i := 0; i < c.chol.mat.N; i++ { + det += 2 * math.Log(c.chol.mat.Data[i*c.chol.mat.Stride+i]) + } + return det +} + +// Solve finds the matrix m that solves A * m = b where A is represented +// by the Cholesky decomposition, placing the result in m. +func (c *Cholesky) Solve(m *Dense, b Matrix) error { + if !c.valid() { + panic(badCholesky) + } + n := c.chol.mat.N + bm, bn := b.Dims() + if n != bm { + panic(ErrShape) + } + + m.reuseAs(bm, bn) + if b != m { + m.Copy(b) + } + blas64.Trsm(blas.Left, blas.Trans, 1, c.chol.mat, m.mat) + blas64.Trsm(blas.Left, blas.NoTrans, 1, c.chol.mat, m.mat) + if c.cond > ConditionTolerance { + return Condition(c.cond) + } + return nil +} + +// SolveChol finds the matrix m that solves A * m = B where A and B are represented +// by their Cholesky decompositions a and b, placing the result in the receiver. +func (a *Cholesky) SolveChol(m *Dense, b *Cholesky) error { + if !a.valid() || !b.valid() { + panic(badCholesky) + } + bn := b.chol.mat.N + if a.chol.mat.N != bn { + panic(ErrShape) + } + + m.reuseAsZeroed(bn, bn) + m.Copy(b.chol.T()) + blas64.Trsm(blas.Left, blas.Trans, 1, a.chol.mat, m.mat) + blas64.Trsm(blas.Left, blas.NoTrans, 1, a.chol.mat, m.mat) + blas64.Trmm(blas.Right, blas.NoTrans, 1, b.chol.mat, m.mat) + if a.cond > ConditionTolerance { + return Condition(a.cond) + } + return nil +} + +// SolveVec finds the vector v that solves A * v = b where A is represented +// by the Cholesky decomposition, placing the result in v. +func (c *Cholesky) SolveVec(v, b *VecDense) error { + if !c.valid() { + panic(badCholesky) + } + n := c.chol.mat.N + vn := b.Len() + if vn != n { + panic(ErrShape) + } + if v != b { + v.checkOverlap(b.mat) + } + v.reuseAs(n) + if v != b { + v.CopyVec(b) + } + blas64.Trsv(blas.Trans, c.chol.mat, v.mat) + blas64.Trsv(blas.NoTrans, c.chol.mat, v.mat) + if c.cond > ConditionTolerance { + return Condition(c.cond) + } + return nil + +} + +// UTo extracts the n×n upper triangular matrix U from a Cholesky +// decomposition into dst and returns the result. If dst is nil a new +// TriDense is allocated. +// A = U^T * U. +func (c *Cholesky) UTo(dst *TriDense) *TriDense { + if !c.valid() { + panic(badCholesky) + } + n := c.chol.mat.N + if dst == nil { + dst = NewTriDense(n, Upper, make([]float64, n*n)) + } else { + dst.reuseAs(n, Upper) + } + dst.Copy(c.chol) + return dst +} + +// LTo extracts the n×n lower triangular matrix L from a Cholesky +// decomposition into dst and returns the result. If dst is nil a new +// TriDense is allocated. +// A = L * L^T. +func (c *Cholesky) LTo(dst *TriDense) *TriDense { + if !c.valid() { + panic(badCholesky) + } + n := c.chol.mat.N + if dst == nil { + dst = NewTriDense(n, Lower, make([]float64, n*n)) + } else { + dst.reuseAs(n, Lower) + } + dst.Copy(c.chol.TTri()) + return dst +} + +// To reconstructs the original positive definite matrix given its +// Cholesky decomposition into dst and returns the result. If dst is nil +// a new SymDense is allocated. +func (c *Cholesky) To(dst *SymDense) *SymDense { + if !c.valid() { + panic(badCholesky) + } + n := c.chol.mat.N + if dst == nil { + dst = NewSymDense(n, make([]float64, n*n)) + } else { + dst.reuseAs(n) + } + dst.SymOuterK(1, c.chol.T()) + return dst +} + +// InverseTo computes the inverse of the matrix represented by its Cholesky +// factorization and stores the result into s. If the factorized +// matrix is ill-conditioned, a Condition error will be returned. +// Note that matrix inversion is numerically unstable, and should generally be +// avoided where possible, for example by using the Solve routines. +func (c *Cholesky) InverseTo(s *SymDense) error { + if !c.valid() { + panic(badCholesky) + } + // TODO(btracey): Replace this code with a direct call to Dpotri when it + // is available. + s.reuseAs(c.chol.mat.N) + // If: + // chol(A) = U^T * U + // Then: + // chol(A^-1) = S * S^T + // where S = U^-1 + var t TriDense + err := t.InverseTri(c.chol) + s.SymOuterK(1, &t) + return err +} + +// SymRankOne performs a rank-1 update of the original matrix A and refactorizes +// its Cholesky factorization, storing the result into the receiver. That is, if +// in the original Cholesky factorization +// U^T * U = A, +// in the updated factorization +// U'^T * U' = A + alpha * x * x^T = A'. +// +// Note that when alpha is negative, the updating problem may be ill-conditioned +// and the results may be inaccurate, or the updated matrix A' may not be +// positive definite and not have a Cholesky factorization. SymRankOne returns +// whether the updated matrix A' is positive definite. +// +// SymRankOne updates a Cholesky factorization in O(n²) time. The Cholesky +// factorization computation from scratch is O(n³). +func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x *VecDense) (ok bool) { + if !orig.valid() { + panic(badCholesky) + } + n := orig.Size() + if x.Len() != n { + panic(ErrShape) + } + if orig != c { + if c.isZero() { + c.chol = NewTriDense(n, Upper, nil) + } else if c.chol.mat.N != n { + panic(ErrShape) + } + c.chol.Copy(orig.chol) + } + + if alpha == 0 { + return true + } + + // Algorithms for updating and downdating the Cholesky factorization are + // described, for example, in + // - J. J. Dongarra, J. R. Bunch, C. B. Moler, G. W. Stewart: LINPACK + // Users' Guide. SIAM (1979), pages 10.10--10.14 + // or + // - P. E. Gill, G. H. Golub, W. Murray, and M. A. Saunders: Methods for + // modifying matrix factorizations. Mathematics of Computation 28(126) + // (1974), Method C3 on page 521 + // + // The implementation is based on LINPACK code + // http://www.netlib.org/linpack/dchud.f + // http://www.netlib.org/linpack/dchdd.f + // and + // https://icl.cs.utk.edu/lapack-forum/viewtopic.php?f=2&t=2646 + // + // According to http://icl.cs.utk.edu/lapack-forum/archives/lapack/msg00301.html + // LINPACK is released under BSD license. + // + // See also: + // - M. A. Saunders: Large-scale Linear Programming Using the Cholesky + // Factorization. Technical Report Stanford University (1972) + // http://i.stanford.edu/pub/cstr/reports/cs/tr/72/252/CS-TR-72-252.pdf + // - Matthias Seeger: Low rank updates for the Cholesky decomposition. + // EPFL Technical Report 161468 (2004) + // http://infoscience.epfl.ch/record/161468 + + work := getFloats(n, false) + defer putFloats(work) + blas64.Copy(n, x.RawVector(), blas64.Vector{1, work}) + + if alpha > 0 { + // Compute rank-1 update. + if alpha != 1 { + blas64.Scal(n, math.Sqrt(alpha), blas64.Vector{1, work}) + } + umat := c.chol.mat + stride := umat.Stride + for i := 0; i < n; i++ { + // Compute parameters of the Givens matrix that zeroes + // the i-th element of x. + c, s, r, _ := blas64.Rotg(umat.Data[i*stride+i], work[i]) + if r < 0 { + // Multiply by -1 to have positive diagonal + // elemnts. + r *= -1 + c *= -1 + s *= -1 + } + umat.Data[i*stride+i] = r + if i < n-1 { + // Multiply the extended factorization matrix by + // the Givens matrix from the left. Only + // the i-th row and x are modified. + blas64.Rot(n-i-1, + blas64.Vector{1, umat.Data[i*stride+i+1 : i*stride+n]}, + blas64.Vector{1, work[i+1 : n]}, + c, s) + } + } + c.updateCond(-1) + return true + } + + // Compute rank-1 downdate. + alpha = math.Sqrt(-alpha) + if alpha != 1 { + blas64.Scal(n, alpha, blas64.Vector{1, work}) + } + // Solve U^T * p = x storing the result into work. + ok = lapack64.Trtrs(blas.Trans, c.chol.RawTriangular(), blas64.General{ + Rows: n, + Cols: 1, + Stride: 1, + Data: work, + }) + if !ok { + // The original matrix is singular. Should not happen, because + // the factorization is valid. + panic(badCholesky) + } + norm := blas64.Nrm2(n, blas64.Vector{1, work}) + if norm >= 1 { + // The updated matrix is not positive definite. + return false + } + norm = math.Sqrt((1 + norm) * (1 - norm)) + cos := getFloats(n, false) + defer putFloats(cos) + sin := getFloats(n, false) + defer putFloats(sin) + for i := n - 1; i >= 0; i-- { + // Compute parameters of Givens matrices that zero elements of p + // backwards. + cos[i], sin[i], norm, _ = blas64.Rotg(norm, work[i]) + if norm < 0 { + norm *= -1 + cos[i] *= -1 + sin[i] *= -1 + } + } + umat := c.chol.mat + stride := umat.Stride + for i := n - 1; i >= 0; i-- { + // Apply Givens matrices to U. + // TODO(vladimir-ch): Use workspace to avoid modifying the + // receiver in case an invalid factorization is created. + blas64.Rot(n-i, blas64.Vector{1, work[i:n]}, blas64.Vector{1, umat.Data[i*stride+i : i*stride+n]}, cos[i], sin[i]) + if umat.Data[i*stride+i] == 0 { + // The matrix is singular (may rarely happen due to + // floating-point effects?). + ok = false + } else if umat.Data[i*stride+i] < 0 { + // Diagonal elements should be positive. If it happens + // that on the i-th row the diagonal is negative, + // multiply U from the left by an identity matrix that + // has -1 on the i-th row. + blas64.Scal(n-i, -1, blas64.Vector{1, umat.Data[i*stride+i : i*stride+n]}) + } + } + if ok { + c.updateCond(-1) + } else { + c.Reset() + } + return ok +} + +func (c *Cholesky) isZero() bool { + return c.chol == nil +} + +func (c *Cholesky) valid() bool { + return !c.isZero() && !c.chol.IsZero() +} diff --git a/vendor/gonum.org/v1/gonum/mat/cholesky_example_test.go b/vendor/gonum.org/v1/gonum/mat/cholesky_example_test.go new file mode 100644 index 00000000..8f75d79b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/cholesky_example_test.go @@ -0,0 +1,121 @@ +// 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 mat_test + +import ( + "fmt" + + "gonum.org/v1/gonum/mat" +) + +func ExampleCholesky() { + // Construct a symmetric positive definite matrix. + tmp := mat.NewDense(4, 4, []float64{ + 2, 6, 8, -4, + 1, 8, 7, -2, + 2, 2, 1, 7, + 8, -2, -2, 1, + }) + var a mat.SymDense + a.SymOuterK(1, tmp) + + fmt.Printf("a = %0.4v\n", mat.Formatted(&a, mat.Prefix(" "))) + + // Compute the cholesky factorization. + var chol mat.Cholesky + if ok := chol.Factorize(&a); !ok { + fmt.Println("a matrix is not positive semi-definite.") + } + + // Find the determinant. + fmt.Printf("\nThe determinant of a is %0.4g\n\n", chol.Det()) + + // Use the factorization to solve the system of equations a * x = b. + b := mat.NewVecDense(4, []float64{1, 2, 3, 4}) + var x mat.VecDense + if err := chol.SolveVec(&x, b); err != nil { + fmt.Println("Matrix is near singular: ", err) + } + fmt.Println("Solve a * x = b") + fmt.Printf("x = %0.4v\n", mat.Formatted(&x, mat.Prefix(" "))) + + // Extract the factorization and check that it equals the original matrix. + t := chol.LTo(nil) + var test mat.Dense + test.Mul(t, t.T()) + fmt.Println() + fmt.Printf("L * L^T = %0.4v\n", mat.Formatted(&a, mat.Prefix(" "))) + + // Output: + // a = ⎡120 114 -4 -16⎤ + // ⎢114 118 11 -24⎥ + // ⎢ -4 11 58 17⎥ + // ⎣-16 -24 17 73⎦ + // + // The determinant of a is 1.543e+06 + // + // Solve a * x = b + // x = ⎡ -0.239⎤ + // ⎢ 0.2732⎥ + // ⎢-0.04681⎥ + // ⎣ 0.1031⎦ + // + // L * L^T = ⎡120 114 -4 -16⎤ + // ⎢114 118 11 -24⎥ + // ⎢ -4 11 58 17⎥ + // ⎣-16 -24 17 73⎦ +} + +func ExampleCholesky_SymRankOne() { + a := mat.NewSymDense(4, []float64{ + 1, 1, 1, 1, + 0, 2, 3, 4, + 0, 0, 6, 10, + 0, 0, 0, 20, + }) + fmt.Printf("A = %0.4v\n", mat.Formatted(a, mat.Prefix(" "))) + + // Compute the Cholesky factorization. + var chol mat.Cholesky + if ok := chol.Factorize(a); !ok { + fmt.Println("matrix a is not positive definite.") + } + + x := mat.NewVecDense(4, []float64{0, 0, 0, 1}) + fmt.Printf("\nx = %0.4v\n", mat.Formatted(x, mat.Prefix(" "))) + + // Rank-1 update the factorization. + chol.SymRankOne(&chol, 1, x) + // Rank-1 update the matrix a. + a.SymRankOne(a, 1, x) + + au := chol.To(nil) + + // Print the matrix that was updated directly. + fmt.Printf("\nA' = %0.4v\n", mat.Formatted(a, mat.Prefix(" "))) + // Print the matrix recovered from the factorization. + fmt.Printf("\nU'^T * U' = %0.4v\n", mat.Formatted(au, mat.Prefix(" "))) + + // Output: + // A = ⎡ 1 1 1 1⎤ + // ⎢ 1 2 3 4⎥ + // ⎢ 1 3 6 10⎥ + // ⎣ 1 4 10 20⎦ + // + // x = ⎡0⎤ + // ⎢0⎥ + // ⎢0⎥ + // ⎣1⎦ + // + // A' = ⎡ 1 1 1 1⎤ + // ⎢ 1 2 3 4⎥ + // ⎢ 1 3 6 10⎥ + // ⎣ 1 4 10 21⎦ + // + // U'^T * U' = ⎡ 1 1 1 1⎤ + // ⎢ 1 2 3 4⎥ + // ⎢ 1 3 6 10⎥ + // ⎣ 1 4 10 21⎦ +} diff --git a/vendor/gonum.org/v1/gonum/mat/cholesky_test.go b/vendor/gonum.org/v1/gonum/mat/cholesky_test.go new file mode 100644 index 00000000..6a5c853d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/cholesky_test.go @@ -0,0 +1,453 @@ +// 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. + +package mat + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/testblas" +) + +func TestCholesky(t *testing.T) { + for _, test := range []struct { + a *SymDense + + cond float64 + want *TriDense + posdef bool + }{ + { + a: NewSymDense(3, []float64{ + 4, 1, 1, + 0, 2, 3, + 0, 0, 6, + }), + cond: 37, + want: NewTriDense(3, true, []float64{ + 2, 0.5, 0.5, + 0, 1.3228756555322954, 2.0788046015507495, + 0, 0, 1.195228609334394, + }), + posdef: true, + }, + } { + _, n := test.a.Dims() + for _, chol := range []*Cholesky{ + {}, + {chol: NewTriDense(n-1, true, nil)}, + {chol: NewTriDense(n, true, nil)}, + {chol: NewTriDense(n+1, true, nil)}, + } { + ok := chol.Factorize(test.a) + if ok != test.posdef { + t.Errorf("unexpected return from Cholesky factorization: got: ok=%t want: ok=%t", ok, test.posdef) + } + fc := DenseCopyOf(chol.chol) + if !Equal(fc, test.want) { + t.Error("incorrect Cholesky factorization") + } + if math.Abs(test.cond-chol.cond) > 1e-13 { + t.Errorf("Condition number mismatch: Want %v, got %v", test.cond, chol.cond) + } + U := chol.UTo(nil) + aCopy := DenseCopyOf(test.a) + var a Dense + a.Mul(U.TTri(), U) + if !EqualApprox(&a, aCopy, 1e-14) { + t.Error("unexpected Cholesky factor product") + } + + L := chol.LTo(nil) + a.Mul(L, L.TTri()) + if !EqualApprox(&a, aCopy, 1e-14) { + t.Error("unexpected Cholesky factor product") + } + } + } +} + +func TestCholeskySolve(t *testing.T) { + for _, test := range []struct { + a *SymDense + b *Dense + ans *Dense + }{ + { + a: NewSymDense(2, []float64{ + 1, 0, + 0, 1, + }), + b: NewDense(2, 1, []float64{5, 6}), + ans: NewDense(2, 1, []float64{5, 6}), + }, + { + a: NewSymDense(3, []float64{ + 53, 59, 37, + 0, 83, 71, + 37, 71, 101, + }), + b: NewDense(3, 1, []float64{5, 6, 7}), + ans: NewDense(3, 1, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}), + }, + } { + var chol Cholesky + ok := chol.Factorize(test.a) + if !ok { + t.Fatal("unexpected Cholesky factorization failure: not positive definite") + } + + var x Dense + chol.Solve(&x, test.b) + if !EqualApprox(&x, test.ans, 1e-12) { + t.Error("incorrect Cholesky solve solution") + } + + var ans Dense + ans.Mul(test.a, &x) + if !EqualApprox(&ans, test.b, 1e-12) { + t.Error("incorrect Cholesky solve solution product") + } + } +} + +func TestCholeskySolveChol(t *testing.T) { + for _, test := range []struct { + a, b *SymDense + }{ + { + a: NewSymDense(2, []float64{ + 1, 0, + 0, 1, + }), + b: NewSymDense(2, []float64{ + 1, 0, + 0, 1, + }), + }, + { + a: NewSymDense(2, []float64{ + 1, 0, + 0, 1, + }), + b: NewSymDense(2, []float64{ + 2, 0, + 0, 2, + }), + }, + { + a: NewSymDense(3, []float64{ + 53, 59, 37, + 59, 83, 71, + 37, 71, 101, + }), + b: NewSymDense(3, []float64{ + 2, -1, 0, + -1, 2, -1, + 0, -1, 2, + }), + }, + } { + var chola, cholb Cholesky + ok := chola.Factorize(test.a) + if !ok { + t.Fatal("unexpected Cholesky factorization failure for a: not positive definite") + } + ok = cholb.Factorize(test.b) + if !ok { + t.Fatal("unexpected Cholesky factorization failure for b: not positive definite") + } + + var x Dense + chola.SolveChol(&x, &cholb) + + var ans Dense + ans.Mul(test.a, &x) + if !EqualApprox(&ans, test.b, 1e-12) { + var y Dense + y.Solve(test.a, test.b) + t.Errorf("incorrect Cholesky solve solution product\ngot solution:\n%.4v\nwant solution\n%.4v", + Formatted(&x), Formatted(&y)) + } + } +} + +func TestCholeskySolveVec(t *testing.T) { + for _, test := range []struct { + a *SymDense + b *VecDense + ans *VecDense + }{ + { + a: NewSymDense(2, []float64{ + 1, 0, + 0, 1, + }), + b: NewVecDense(2, []float64{5, 6}), + ans: NewVecDense(2, []float64{5, 6}), + }, + { + a: NewSymDense(3, []float64{ + 53, 59, 37, + 0, 83, 71, + 0, 0, 101, + }), + b: NewVecDense(3, []float64{5, 6, 7}), + ans: NewVecDense(3, []float64{0.20745069393718094, -0.17421475529583694, 0.11577794010226464}), + }, + } { + var chol Cholesky + ok := chol.Factorize(test.a) + if !ok { + t.Fatal("unexpected Cholesky factorization failure: not positive definite") + } + + var x VecDense + chol.SolveVec(&x, test.b) + if !EqualApprox(&x, test.ans, 1e-12) { + t.Error("incorrect Cholesky solve solution") + } + + var ans VecDense + ans.MulVec(test.a, &x) + if !EqualApprox(&ans, test.b, 1e-12) { + t.Error("incorrect Cholesky solve solution product") + } + } +} + +func TestCholeskyTo(t *testing.T) { + for _, test := range []*SymDense{ + NewSymDense(3, []float64{ + 53, 59, 37, + 0, 83, 71, + 0, 0, 101, + }), + } { + var chol Cholesky + ok := chol.Factorize(test) + if !ok { + t.Fatal("unexpected Cholesky factorization failure: not positive definite") + } + s := chol.To(nil) + + if !EqualApprox(s, test, 1e-12) { + t.Errorf("Cholesky reconstruction not equal to original matrix.\nWant:\n% v\nGot:\n% v\n", Formatted(test), Formatted(s)) + } + } +} + +func TestCloneCholesky(t *testing.T) { + for _, test := range []*SymDense{ + NewSymDense(3, []float64{ + 53, 59, 37, + 0, 83, 71, + 0, 0, 101, + }), + } { + var chol Cholesky + ok := chol.Factorize(test) + if !ok { + panic("bad test") + } + var chol2 Cholesky + chol2.Clone(&chol) + + if chol.cond != chol2.cond { + t.Errorf("condition number mismatch from zero") + } + if !Equal(chol.chol, chol2.chol) { + t.Errorf("chol mismatch from zero") + } + + // Corrupt chol2 and try again + chol2.cond = math.NaN() + chol2.chol = NewTriDense(2, Upper, nil) + chol2.Clone(&chol) + if chol.cond != chol2.cond { + t.Errorf("condition number mismatch from non-zero") + } + if !Equal(chol.chol, chol2.chol) { + t.Errorf("chol mismatch from non-zero") + } + } +} + +func TestCholeskyInverseTo(t *testing.T) { + for _, n := range []int{1, 3, 5, 9} { + data := make([]float64, n*n) + for i := range data { + data[i] = rand.NormFloat64() + } + var s SymDense + s.SymOuterK(1, NewDense(n, n, data)) + + var chol Cholesky + ok := chol.Factorize(&s) + if !ok { + t.Errorf("Bad test, cholesky decomposition failed") + } + + var sInv SymDense + chol.InverseTo(&sInv) + + var ans Dense + ans.Mul(&sInv, &s) + if !equalApprox(eye(n), &ans, 1e-8, false) { + var diff Dense + diff.Sub(eye(n), &ans) + t.Errorf("SymDense times Cholesky inverse not identity. Norm diff = %v", Norm(&diff, 2)) + } + } +} + +func TestCholeskySymRankOne(t *testing.T) { + rand.Seed(1) + for _, n := range []int{1, 2, 3, 4, 5, 7, 10, 20, 50, 100} { + for k := 0; k < 10; k++ { + data := make([]float64, n*n) + for i := range data { + data[i] = rand.NormFloat64() + } + + var a SymDense + a.SymOuterK(1, NewDense(n, n, data)) + + xdata := make([]float64, n) + for i := range xdata { + xdata[i] = rand.NormFloat64() + } + x := NewVecDense(n, xdata) + + var chol Cholesky + ok := chol.Factorize(&a) + if !ok { + t.Errorf("Bad random test, Cholesky factorization failed") + continue + } + + alpha := rand.Float64() + ok = chol.SymRankOne(&chol, alpha, x) + if !ok { + t.Errorf("n=%v, alpha=%v: unexpected failure", n, alpha) + continue + } + a.SymRankOne(&a, alpha, x) + + var achol SymDense + chol.To(&achol) + if !EqualApprox(&achol, &a, 1e-13) { + t.Errorf("n=%v, alpha=%v: mismatch between updated matrix and from Cholesky:\nupdated:\n%v\nfrom Cholesky:\n%v", + n, alpha, Formatted(&a), Formatted(&achol)) + } + } + } + + for i, test := range []struct { + a *SymDense + alpha float64 + x []float64 + + wantOk bool + }{ + { + // Update (to positive definite matrix). + a: NewSymDense(4, []float64{ + 1, 1, 1, 1, + 0, 2, 3, 4, + 0, 0, 6, 10, + 0, 0, 0, 20, + }), + alpha: 1, + x: []float64{0, 0, 0, 1}, + wantOk: true, + }, + { + // Downdate to singular matrix. + a: NewSymDense(4, []float64{ + 1, 1, 1, 1, + 0, 2, 3, 4, + 0, 0, 6, 10, + 0, 0, 0, 20, + }), + alpha: -1, + x: []float64{0, 0, 0, 1}, + wantOk: false, + }, + { + // Downdate to positive definite matrix. + a: NewSymDense(4, []float64{ + 1, 1, 1, 1, + 0, 2, 3, 4, + 0, 0, 6, 10, + 0, 0, 0, 20, + }), + alpha: -1 / 2, + x: []float64{0, 0, 0, 1}, + wantOk: true, + }, + } { + var chol Cholesky + ok := chol.Factorize(test.a) + if !ok { + t.Errorf("Case %v: bad test, Cholesky factorization failed", i) + continue + } + + x := NewVecDense(len(test.x), test.x) + ok = chol.SymRankOne(&chol, test.alpha, x) + if !ok { + if test.wantOk { + t.Errorf("Case %v: unexpected failure from SymRankOne", i) + } + continue + } + if ok && !test.wantOk { + t.Errorf("Case %v: expected a failure from SymRankOne", i) + } + + a := test.a + a.SymRankOne(a, test.alpha, x) + + var achol SymDense + chol.To(&achol) + if !EqualApprox(&achol, a, 1e-13) { + t.Errorf("Case %v: mismatch between updated matrix and from Cholesky:\nupdated:\n%v\nfrom Cholesky:\n%v", + i, Formatted(a), Formatted(&achol)) + } + } +} + +func BenchmarkCholeskySmall(b *testing.B) { + benchmarkCholesky(b, 2) +} + +func BenchmarkCholeskyMedium(b *testing.B) { + benchmarkCholesky(b, testblas.MediumMat) +} + +func BenchmarkCholeskyLarge(b *testing.B) { + benchmarkCholesky(b, testblas.LargeMat) +} + +func benchmarkCholesky(b *testing.B, n int) { + base := make([]float64, n*n) + for i := range base { + base[i] = rand.Float64() + } + bm := NewDense(n, n, base) + bm.Mul(bm.T(), bm) + am := NewSymDense(n, bm.mat.Data) + + var chol Cholesky + b.ResetTimer() + for i := 0; i < b.N; i++ { + ok := chol.Factorize(am) + if !ok { + panic("not pos def") + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/cmatrix.go b/vendor/gonum.org/v1/gonum/mat/cmatrix.go new file mode 100644 index 00000000..a2894237 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/cmatrix.go @@ -0,0 +1,71 @@ +// 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. + +package mat + +// CMatrix is the basic matrix interface type for complex matrices. +type CMatrix interface { + // Dims returns the dimensions of a Matrix. + Dims() (r, c int) + + // At returns the value of a matrix element at row i, column j. + // It will panic if i or j are out of bounds for the matrix. + At(i, j int) complex128 + + // H returns the conjugate transpose of the Matrix. Whether H + // returns a copy of the underlying data is implementation dependent. + // This method may be implemented using the Conjugate type, which + // provides an implicit matrix conjugate transpose. + H() CMatrix +} + +var ( + _ CMatrix = Conjugate{} + _ Unconjugator = Conjugate{} +) + +// Conjugate is a type for performing an implicit matrix conjugate transpose. +// It implements the Matrix interface, returning values from the conjugate +// transpose of the matrix within. +type Conjugate struct { + CMatrix CMatrix +} + +// At returns the value of the element at row i and column j of the transposed +// matrix, that is, row j and column i of the Matrix field. +func (t Conjugate) At(i, j int) complex128 { + z := t.CMatrix.At(j, i) + return complex(real(z), -imag(z)) +} + +// Dims returns the dimensions of the transposed matrix. The number of rows returned +// is the number of columns in the Matrix field, and the number of columns is +// the number of rows in the Matrix field. +func (t Conjugate) Dims() (r, c int) { + c, r = t.CMatrix.Dims() + return r, c +} + +// H performs an implicit conjugate transpose by returning the Matrix field. +func (t Conjugate) H() CMatrix { + return t.CMatrix +} + +// Unconjugate returns the Matrix field. +func (t Conjugate) Unconjugate() CMatrix { + return t.CMatrix +} + +// Unconjugator is a type that can undo an implicit conjugate transpose. +type Unconjugator interface { + // Note: This interface is needed to unify all of the Conjugate types. In + // the cmat128 methods, we need to test if the Matrix has been implicitly + // transposed. If this is checked by testing for the specific Conjugate type + // then the behavior will be different if the user uses H() or HTri() for a + // triangular matrix. + + // Unconjugate returns the underlying Matrix stored for the implicit + // conjugate transpose. + Unconjugate() CMatrix +} diff --git a/vendor/gonum.org/v1/gonum/mat/consts.go b/vendor/gonum.org/v1/gonum/mat/consts.go new file mode 100644 index 00000000..a7025fff --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/consts.go @@ -0,0 +1,54 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mat + +// TriKind represents the triangularity of the matrix. +type TriKind bool + +const ( + // Upper specifies an upper triangular matrix. + Upper TriKind = true + // Lower specifies a lower triangular matrix. + Lower TriKind = false +) + +// SVDKind specifies the treatment of singular vectors during an SVD +// factorization. +type SVDKind int + +const ( + // SVDNone specifies that no singular vectors should be computed during + // the decomposition. + SVDNone SVDKind = iota + 1 + // SVDThin computes the thin singular vectors, that is, it computes + // A = U~ * Σ * V~^T + // where U~ is of size m×min(m,n), Σ is a diagonal matrix of size min(m,n)×min(m,n) + // and V~ is of size n×min(m,n). + SVDThin + // SVDFull computes the full singular value decomposition, + // A = U * Σ * V^T + // where U is of size m×m, Σ is an m×n diagonal matrix, and V is an n×n matrix. + SVDFull +) + +// GSVDKind specifies the treatment of singular vectors during a GSVD +// factorization. +type GSVDKind int + +const ( + // GSVDU specifies that the U singular vectors should be computed during + // the decomposition. + GSVDU GSVDKind = 1 << iota + // GSVDV specifies that the V singular vectors should be computed during + // the decomposition. + GSVDV + // GSVDQ specifies that the Q singular vectors should be computed during + // the decomposition. + GSVDQ + + // GSVDNone specifies that no singular vector should be computed during + // the decomposition. + GSVDNone +) diff --git a/vendor/gonum.org/v1/gonum/mat/dense.go b/vendor/gonum.org/v1/gonum/mat/dense.go new file mode 100644 index 00000000..1fab99c2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/dense.go @@ -0,0 +1,534 @@ +// 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. + +package mat + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +var ( + dense *Dense + + _ Matrix = dense + _ Mutable = dense + + _ Cloner = dense + _ RowViewer = dense + _ ColViewer = dense + _ RawRowViewer = dense + _ Grower = dense + + _ RawMatrixSetter = dense + _ RawMatrixer = dense + + _ Reseter = dense +) + +// Dense is a dense matrix representation. +type Dense struct { + mat blas64.General + + capRows, capCols int +} + +// NewDense creates a new Dense matrix with r rows and c columns. If data == nil, +// a new slice is allocated for the backing slice. If len(data) == r*c, data is +// used as the backing slice, and changes to the elements of the returned Dense +// will be reflected in data. If neither of these is true, NewDense will panic. +// +// The data must be arranged in row-major order, i.e. the (i*c + j)-th +// element in the data slice is the {i, j}-th element in the matrix. +func NewDense(r, c int, data []float64) *Dense { + if data != nil && r*c != len(data) { + panic(ErrShape) + } + if data == nil { + data = make([]float64, r*c) + } + return &Dense{ + mat: blas64.General{ + Rows: r, + Cols: c, + Stride: c, + Data: data, + }, + capRows: r, + capCols: c, + } +} + +// reuseAs resizes an empty matrix to a r×c matrix, +// or checks that a non-empty matrix is r×c. +// +// reuseAs must be kept in sync with reuseAsZeroed. +func (m *Dense) reuseAs(r, c int) { + if m.mat.Rows > m.capRows || m.mat.Cols > m.capCols { + // Panic as a string, not a mat.Error. + panic("mat: caps not correctly set") + } + if m.IsZero() { + m.mat = blas64.General{ + Rows: r, + Cols: c, + Stride: c, + Data: use(m.mat.Data, r*c), + } + m.capRows = r + m.capCols = c + return + } + if r != m.mat.Rows || c != m.mat.Cols { + panic(ErrShape) + } +} + +// reuseAsZeroed resizes an empty matrix to a r×c matrix, +// or checks that a non-empty matrix is r×c. It zeroes +// all the elements of the matrix. +// +// reuseAsZeroed must be kept in sync with reuseAs. +func (m *Dense) reuseAsZeroed(r, c int) { + if m.mat.Rows > m.capRows || m.mat.Cols > m.capCols { + // Panic as a string, not a mat.Error. + panic("mat: caps not correctly set") + } + if m.IsZero() { + m.mat = blas64.General{ + Rows: r, + Cols: c, + Stride: c, + Data: useZeroed(m.mat.Data, r*c), + } + m.capRows = r + m.capCols = c + return + } + if r != m.mat.Rows || c != m.mat.Cols { + panic(ErrShape) + } + for i := 0; i < r; i++ { + zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]) + } +} + +// untranspose untransposes a matrix if applicable. If a is an Untransposer, then +// untranspose returns the underlying matrix and true. If it is not, then it returns +// the input matrix and false. +func untranspose(a Matrix) (Matrix, bool) { + if ut, ok := a.(Untransposer); ok { + return ut.Untranspose(), true + } + return a, false +} + +// isolatedWorkspace returns a new dense matrix w with the size of a and +// returns a callback to defer which performs cleanup at the return of the call. +// This should be used when a method receiver is the same pointer as an input argument. +func (m *Dense) isolatedWorkspace(a Matrix) (w *Dense, restore func()) { + r, c := a.Dims() + w = getWorkspace(r, c, false) + return w, func() { + m.Copy(w) + putWorkspace(w) + } +} + +// Reset zeros the dimensions of the matrix so that it can be reused as the +// receiver of a dimensionally restricted operation. +// +// See the Reseter interface for more information. +func (m *Dense) Reset() { + // Row, Cols and Stride must be zeroed in unison. + m.mat.Rows, m.mat.Cols, m.mat.Stride = 0, 0, 0 + m.capRows, m.capCols = 0, 0 + m.mat.Data = m.mat.Data[:0] +} + +// IsZero returns whether the receiver is zero-sized. Zero-sized matrices can be the +// receiver for size-restricted operations. Dense matrices can be zeroed using Reset. +func (m *Dense) IsZero() bool { + // It must be the case that m.Dims() returns + // zeros in this case. See comment in Reset(). + return m.mat.Stride == 0 +} + +// asTriDense returns a TriDense with the given size and side. The backing data +// of the TriDense is the same as the receiver. +func (m *Dense) asTriDense(n int, diag blas.Diag, uplo blas.Uplo) *TriDense { + return &TriDense{ + mat: blas64.Triangular{ + N: n, + Stride: m.mat.Stride, + Data: m.mat.Data, + Uplo: uplo, + Diag: diag, + }, + cap: n, + } +} + +// DenseCopyOf returns a newly allocated copy of the elements of a. +func DenseCopyOf(a Matrix) *Dense { + d := &Dense{} + d.Clone(a) + return d +} + +// SetRawMatrix sets the underlying blas64.General used by the receiver. +// Changes to elements in the receiver following the call will be reflected +// in b. +func (m *Dense) SetRawMatrix(b blas64.General) { + m.capRows, m.capCols = b.Rows, b.Cols + m.mat = b +} + +// RawMatrix returns the underlying blas64.General used by the receiver. +// Changes to elements in the receiver following the call will be reflected +// in returned blas64.General. +func (m *Dense) RawMatrix() blas64.General { return m.mat } + +// Dims returns the number of rows and columns in the matrix. +func (m *Dense) Dims() (r, c int) { return m.mat.Rows, m.mat.Cols } + +// Caps returns the number of rows and columns in the backing matrix. +func (m *Dense) Caps() (r, c int) { return m.capRows, m.capCols } + +// T performs an implicit transpose by returning the receiver inside a Transpose. +func (m *Dense) T() Matrix { + return Transpose{m} +} + +// ColView returns a VecDense reflecting the column j, backed by the matrix data. +// +// See ColViewer for more information. +func (m *Dense) ColView(j int) *VecDense { + if j >= m.mat.Cols || j < 0 { + panic(ErrColAccess) + } + return &VecDense{ + mat: blas64.Vector{ + Inc: m.mat.Stride, + Data: m.mat.Data[j : (m.mat.Rows-1)*m.mat.Stride+j+1], + }, + n: m.mat.Rows, + } +} + +// SetCol sets the values in the specified column of the matrix to the values +// in src. len(src) must equal the number of rows in the receiver. +func (m *Dense) SetCol(j int, src []float64) { + if j >= m.mat.Cols || j < 0 { + panic(ErrColAccess) + } + if len(src) != m.mat.Rows { + panic(ErrColLength) + } + + blas64.Copy(m.mat.Rows, + blas64.Vector{Inc: 1, Data: src}, + blas64.Vector{Inc: m.mat.Stride, Data: m.mat.Data[j:]}, + ) +} + +// SetRow sets the values in the specified rows of the matrix to the values +// in src. len(src) must equal the number of columns in the receiver. +func (m *Dense) SetRow(i int, src []float64) { + if i >= m.mat.Rows || i < 0 { + panic(ErrRowAccess) + } + if len(src) != m.mat.Cols { + panic(ErrRowLength) + } + + copy(m.rawRowView(i), src) +} + +// RowView returns row i of the matrix data represented as a column vector, +// backed by the matrix data. +// +// See RowViewer for more information. +func (m *Dense) RowView(i int) *VecDense { + if i >= m.mat.Rows || i < 0 { + panic(ErrRowAccess) + } + return &VecDense{ + mat: blas64.Vector{ + Inc: 1, + Data: m.rawRowView(i), + }, + n: m.mat.Cols, + } +} + +// RawRowView returns a slice backed by the same array as backing the +// receiver. +func (m *Dense) RawRowView(i int) []float64 { + if i >= m.mat.Rows || i < 0 { + panic(ErrRowAccess) + } + return m.rawRowView(i) +} + +func (m *Dense) rawRowView(i int) []float64 { + return m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+m.mat.Cols] +} + +// Slice returns a new Matrix that shares backing data with the receiver. +// The returned matrix starts at {i,j} of the receiver and extends k-i rows +// and l-j columns. The final row in the resulting matrix is k-1 and the +// final column is l-1. +// Slice panics with ErrIndexOutOfRange if the slice is outside the capacity +// of the receiver. +func (m *Dense) Slice(i, k, j, l int) Matrix { + mr, mc := m.Caps() + if i < 0 || mr <= i || j < 0 || mc <= j || k <= i || mr < k || l <= j || mc < l { + panic(ErrIndexOutOfRange) + } + t := *m + t.mat.Data = t.mat.Data[i*t.mat.Stride+j : (k-1)*t.mat.Stride+l] + t.mat.Rows = k - i + t.mat.Cols = l - j + t.capRows -= i + t.capCols -= j + return &t +} + +// Grow returns the receiver expanded by r rows and c columns. If the dimensions +// of the expanded matrix are outside the capacities of the receiver a new +// allocation is made, otherwise not. Note the receiver itself is not modified +// during the call to Grow. +func (m *Dense) Grow(r, c int) Matrix { + if r < 0 || c < 0 { + panic(ErrIndexOutOfRange) + } + if r == 0 && c == 0 { + return m + } + + r += m.mat.Rows + c += m.mat.Cols + + var t Dense + switch { + case m.mat.Rows == 0 || m.mat.Cols == 0: + t.mat = blas64.General{ + Rows: r, + Cols: c, + Stride: c, + // We zero because we don't know how the matrix will be used. + // In other places, the mat is immediately filled with a result; + // this is not the case here. + Data: useZeroed(m.mat.Data, r*c), + } + case r > m.capRows || c > m.capCols: + cr := max(r, m.capRows) + cc := max(c, m.capCols) + t.mat = blas64.General{ + Rows: r, + Cols: c, + Stride: cc, + Data: make([]float64, cr*cc), + } + t.capRows = cr + t.capCols = cc + // Copy the complete matrix over to the new matrix. + // Including elements not currently visible. Use a temporary structure + // to avoid modifying the receiver. + var tmp Dense + tmp.mat = blas64.General{ + Rows: m.mat.Rows, + Cols: m.mat.Cols, + Stride: m.mat.Stride, + Data: m.mat.Data, + } + tmp.capRows = m.capRows + tmp.capCols = m.capCols + t.Copy(&tmp) + return &t + default: + t.mat = blas64.General{ + Data: m.mat.Data[:(r-1)*m.mat.Stride+c], + Rows: r, + Cols: c, + Stride: m.mat.Stride, + } + } + t.capRows = r + t.capCols = c + return &t +} + +// Clone makes a copy of a into the receiver, overwriting the previous value of +// the receiver. The clone operation does not make any restriction on shape and +// will not cause shadowing. +// +// See the Cloner interface for more information. +func (m *Dense) Clone(a Matrix) { + r, c := a.Dims() + mat := blas64.General{ + Rows: r, + Cols: c, + Stride: c, + } + m.capRows, m.capCols = r, c + + aU, trans := untranspose(a) + switch aU := aU.(type) { + case RawMatrixer: + amat := aU.RawMatrix() + mat.Data = make([]float64, r*c) + if trans { + for i := 0; i < r; i++ { + blas64.Copy(c, + blas64.Vector{Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]}, + blas64.Vector{Inc: 1, Data: mat.Data[i*c : (i+1)*c]}) + } + } else { + for i := 0; i < r; i++ { + copy(mat.Data[i*c:(i+1)*c], amat.Data[i*amat.Stride:i*amat.Stride+c]) + } + } + case *VecDense: + amat := aU.mat + mat.Data = make([]float64, aU.n) + blas64.Copy(aU.n, + blas64.Vector{Inc: amat.Inc, Data: amat.Data}, + blas64.Vector{Inc: 1, Data: mat.Data}) + default: + mat.Data = make([]float64, r*c) + w := *m + w.mat = mat + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + w.set(i, j, a.At(i, j)) + } + } + *m = w + return + } + m.mat = mat +} + +// Copy makes a copy of elements of a into the receiver. It is similar to the +// built-in copy; it copies as much as the overlap between the two matrices and +// returns the number of rows and columns it copied. If a aliases the receiver +// and is a transposed Dense or VecDense, with a non-unitary increment, Copy will +// panic. +// +// See the Copier interface for more information. +func (m *Dense) Copy(a Matrix) (r, c int) { + r, c = a.Dims() + if a == m { + return r, c + } + r = min(r, m.mat.Rows) + c = min(c, m.mat.Cols) + if r == 0 || c == 0 { + return 0, 0 + } + + aU, trans := untranspose(a) + switch aU := aU.(type) { + case RawMatrixer: + amat := aU.RawMatrix() + if trans { + if amat.Stride != 1 { + m.checkOverlap(amat) + } + for i := 0; i < r; i++ { + blas64.Copy(c, + blas64.Vector{Inc: amat.Stride, Data: amat.Data[i : i+(c-1)*amat.Stride+1]}, + blas64.Vector{Inc: 1, Data: m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]}) + } + } else { + switch o := offset(m.mat.Data, amat.Data); { + case o < 0: + for i := r - 1; i >= 0; i-- { + copy(m.mat.Data[i*m.mat.Stride:i*m.mat.Stride+c], amat.Data[i*amat.Stride:i*amat.Stride+c]) + } + case o > 0: + for i := 0; i < r; i++ { + copy(m.mat.Data[i*m.mat.Stride:i*m.mat.Stride+c], amat.Data[i*amat.Stride:i*amat.Stride+c]) + } + default: + // Nothing to do. + } + } + case *VecDense: + var n, stride int + amat := aU.mat + if trans { + if amat.Inc != 1 { + m.checkOverlap(aU.asGeneral()) + } + n = c + stride = 1 + } else { + n = r + stride = m.mat.Stride + } + if amat.Inc == 1 && stride == 1 { + copy(m.mat.Data, amat.Data[:n]) + break + } + switch o := offset(m.mat.Data, amat.Data); { + case o < 0: + blas64.Copy(n, + blas64.Vector{Inc: -amat.Inc, Data: amat.Data}, + blas64.Vector{Inc: -stride, Data: m.mat.Data}) + case o > 0: + blas64.Copy(n, + blas64.Vector{Inc: amat.Inc, Data: amat.Data}, + blas64.Vector{Inc: stride, Data: m.mat.Data}) + default: + // Nothing to do. + } + default: + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + m.set(i, j, a.At(i, j)) + } + } + } + + return r, c +} + +// Stack appends the rows of b onto the rows of a, placing the result into the +// receiver with b placed in the greater indexed rows. Stack will panic if the +// two input matrices do not have the same number of columns or the constructed +// stacked matrix is not the same shape as the receiver. +func (m *Dense) Stack(a, b Matrix) { + ar, ac := a.Dims() + br, bc := b.Dims() + if ac != bc || m == a || m == b { + panic(ErrShape) + } + + m.reuseAs(ar+br, ac) + + m.Copy(a) + w := m.Slice(ar, ar+br, 0, bc).(*Dense) + w.Copy(b) +} + +// Augment creates the augmented matrix of a and b, where b is placed in the +// greater indexed columns. Augment will panic if the two input matrices do +// not have the same number of rows or the constructed augmented matrix is +// not the same shape as the receiver. +func (m *Dense) Augment(a, b Matrix) { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br || m == a || m == b { + panic(ErrShape) + } + + m.reuseAs(ar, ac+bc) + + m.Copy(a) + w := m.Slice(0, br, ac, ac+bc).(*Dense) + w.Copy(b) +} diff --git a/vendor/gonum.org/v1/gonum/mat/dense_arithmetic.go b/vendor/gonum.org/v1/gonum/mat/dense_arithmetic.go new file mode 100644 index 00000000..db18e735 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/dense_arithmetic.go @@ -0,0 +1,719 @@ +// 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. + +package mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack/lapack64" +) + +// Add adds a and b element-wise, placing the result in the receiver. Add +// will panic if the two matrices do not have the same shape. +func (m *Dense) Add(a, b Matrix) { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br || ac != bc { + panic(ErrShape) + } + + aU, _ := untranspose(a) + bU, _ := untranspose(b) + m.reuseAs(ar, ac) + + if arm, ok := a.(RawMatrixer); ok { + if brm, ok := b.(RawMatrixer); ok { + amat, bmat := arm.RawMatrix(), brm.RawMatrix() + if m != aU { + m.checkOverlap(amat) + } + if m != bU { + m.checkOverlap(bmat) + } + for ja, jb, jm := 0, 0, 0; ja < ar*amat.Stride; ja, jb, jm = ja+amat.Stride, jb+bmat.Stride, jm+m.mat.Stride { + for i, v := range amat.Data[ja : ja+ac] { + m.mat.Data[i+jm] = v + bmat.Data[i+jb] + } + } + return + } + } + + var restore func() + if m == aU { + m, restore = m.isolatedWorkspace(aU) + defer restore() + } else if m == bU { + m, restore = m.isolatedWorkspace(bU) + defer restore() + } + + for r := 0; r < ar; r++ { + for c := 0; c < ac; c++ { + m.set(r, c, a.At(r, c)+b.At(r, c)) + } + } +} + +// Sub subtracts the matrix b from a, placing the result in the receiver. Sub +// will panic if the two matrices do not have the same shape. +func (m *Dense) Sub(a, b Matrix) { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br || ac != bc { + panic(ErrShape) + } + + aU, _ := untranspose(a) + bU, _ := untranspose(b) + m.reuseAs(ar, ac) + + if arm, ok := a.(RawMatrixer); ok { + if brm, ok := b.(RawMatrixer); ok { + amat, bmat := arm.RawMatrix(), brm.RawMatrix() + if m != aU { + m.checkOverlap(amat) + } + if m != bU { + m.checkOverlap(bmat) + } + for ja, jb, jm := 0, 0, 0; ja < ar*amat.Stride; ja, jb, jm = ja+amat.Stride, jb+bmat.Stride, jm+m.mat.Stride { + for i, v := range amat.Data[ja : ja+ac] { + m.mat.Data[i+jm] = v - bmat.Data[i+jb] + } + } + return + } + } + + var restore func() + if m == aU { + m, restore = m.isolatedWorkspace(aU) + defer restore() + } else if m == bU { + m, restore = m.isolatedWorkspace(bU) + defer restore() + } + + for r := 0; r < ar; r++ { + for c := 0; c < ac; c++ { + m.set(r, c, a.At(r, c)-b.At(r, c)) + } + } +} + +// MulElem performs element-wise multiplication of a and b, placing the result +// in the receiver. MulElem will panic if the two matrices do not have the same +// shape. +func (m *Dense) MulElem(a, b Matrix) { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br || ac != bc { + panic(ErrShape) + } + + aU, _ := untranspose(a) + bU, _ := untranspose(b) + m.reuseAs(ar, ac) + + if arm, ok := a.(RawMatrixer); ok { + if brm, ok := b.(RawMatrixer); ok { + amat, bmat := arm.RawMatrix(), brm.RawMatrix() + if m != aU { + m.checkOverlap(amat) + } + if m != bU { + m.checkOverlap(bmat) + } + for ja, jb, jm := 0, 0, 0; ja < ar*amat.Stride; ja, jb, jm = ja+amat.Stride, jb+bmat.Stride, jm+m.mat.Stride { + for i, v := range amat.Data[ja : ja+ac] { + m.mat.Data[i+jm] = v * bmat.Data[i+jb] + } + } + return + } + } + + var restore func() + if m == aU { + m, restore = m.isolatedWorkspace(aU) + defer restore() + } else if m == bU { + m, restore = m.isolatedWorkspace(bU) + defer restore() + } + + for r := 0; r < ar; r++ { + for c := 0; c < ac; c++ { + m.set(r, c, a.At(r, c)*b.At(r, c)) + } + } +} + +// DivElem performs element-wise division of a by b, placing the result +// in the receiver. DivElem will panic if the two matrices do not have the same +// shape. +func (m *Dense) DivElem(a, b Matrix) { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br || ac != bc { + panic(ErrShape) + } + + aU, _ := untranspose(a) + bU, _ := untranspose(b) + m.reuseAs(ar, ac) + + if arm, ok := a.(RawMatrixer); ok { + if brm, ok := b.(RawMatrixer); ok { + amat, bmat := arm.RawMatrix(), brm.RawMatrix() + if m != aU { + m.checkOverlap(amat) + } + if m != bU { + m.checkOverlap(bmat) + } + for ja, jb, jm := 0, 0, 0; ja < ar*amat.Stride; ja, jb, jm = ja+amat.Stride, jb+bmat.Stride, jm+m.mat.Stride { + for i, v := range amat.Data[ja : ja+ac] { + m.mat.Data[i+jm] = v / bmat.Data[i+jb] + } + } + return + } + } + + var restore func() + if m == aU { + m, restore = m.isolatedWorkspace(aU) + defer restore() + } else if m == bU { + m, restore = m.isolatedWorkspace(bU) + defer restore() + } + + for r := 0; r < ar; r++ { + for c := 0; c < ac; c++ { + m.set(r, c, a.At(r, c)/b.At(r, c)) + } + } +} + +// Inverse computes the inverse of the matrix a, storing the result into the +// receiver. If a is ill-conditioned, a Condition error will be returned. +// Note that matrix inversion is numerically unstable, and should generally +// be avoided where possible, for example by using the Solve routines. +func (m *Dense) Inverse(a Matrix) error { + // TODO(btracey): Special case for RawTriangular, etc. + r, c := a.Dims() + if r != c { + panic(ErrSquare) + } + m.reuseAs(a.Dims()) + aU, aTrans := untranspose(a) + switch rm := aU.(type) { + case RawMatrixer: + if m != aU || aTrans { + if m == aU || m.checkOverlap(rm.RawMatrix()) { + tmp := getWorkspace(r, c, false) + tmp.Copy(a) + m.Copy(tmp) + putWorkspace(tmp) + break + } + m.Copy(a) + } + default: + m.Copy(a) + } + ipiv := getInts(r, false) + defer putInts(ipiv) + ok := lapack64.Getrf(m.mat, ipiv) + if !ok { + return Condition(math.Inf(1)) + } + work := getFloats(4*r, false) // must be at least 4*r for cond. + lapack64.Getri(m.mat, ipiv, work, -1) + if int(work[0]) > 4*r { + l := int(work[0]) + putFloats(work) + work = getFloats(l, false) + } else { + work = work[:4*r] + } + defer putFloats(work) + lapack64.Getri(m.mat, ipiv, work, len(work)) + norm := lapack64.Lange(CondNorm, m.mat, work) + rcond := lapack64.Gecon(CondNorm, m.mat, norm, work, ipiv) // reuse ipiv + if rcond == 0 { + return Condition(math.Inf(1)) + } + cond := 1 / rcond + if cond > ConditionTolerance { + return Condition(cond) + } + return nil +} + +// Mul takes the matrix product of a and b, placing the result in the receiver. +// If the number of columns in a does not equal the number of rows in b, Mul will panic. +func (m *Dense) Mul(a, b Matrix) { + ar, ac := a.Dims() + br, bc := b.Dims() + + if ac != br { + panic(ErrShape) + } + + aU, aTrans := untranspose(a) + bU, bTrans := untranspose(b) + m.reuseAs(ar, bc) + var restore func() + if m == aU { + m, restore = m.isolatedWorkspace(aU) + defer restore() + } else if m == bU { + m, restore = m.isolatedWorkspace(bU) + defer restore() + } + aT := blas.NoTrans + if aTrans { + aT = blas.Trans + } + bT := blas.NoTrans + if bTrans { + bT = blas.Trans + } + + // Some of the cases do not have a transpose option, so create + // temporary memory. + // C = A^T * B = (B^T * A)^T + // C^T = B^T * A. + if aUrm, ok := aU.(RawMatrixer); ok { + amat := aUrm.RawMatrix() + if restore == nil { + m.checkOverlap(amat) + } + if bUrm, ok := bU.(RawMatrixer); ok { + bmat := bUrm.RawMatrix() + if restore == nil { + m.checkOverlap(bmat) + } + blas64.Gemm(aT, bT, 1, amat, bmat, 0, m.mat) + return + } + if bU, ok := bU.(RawSymmetricer); ok { + bmat := bU.RawSymmetric() + if aTrans { + c := getWorkspace(ac, ar, false) + blas64.Symm(blas.Left, 1, bmat, amat, 0, c.mat) + strictCopy(m, c.T()) + putWorkspace(c) + return + } + blas64.Symm(blas.Right, 1, bmat, amat, 0, m.mat) + return + } + if bU, ok := bU.(RawTriangular); ok { + // Trmm updates in place, so copy aU first. + bmat := bU.RawTriangular() + if aTrans { + c := getWorkspace(ac, ar, false) + var tmp Dense + tmp.SetRawMatrix(amat) + c.Copy(&tmp) + bT := blas.Trans + if bTrans { + bT = blas.NoTrans + } + blas64.Trmm(blas.Left, bT, 1, bmat, c.mat) + strictCopy(m, c.T()) + putWorkspace(c) + return + } + m.Copy(a) + blas64.Trmm(blas.Right, bT, 1, bmat, m.mat) + return + } + if bU, ok := bU.(*VecDense); ok { + m.checkOverlap(bU.asGeneral()) + bvec := bU.RawVector() + if bTrans { + // {ar,1} x {1,bc}, which is not a vector. + // Instead, construct B as a General. + bmat := blas64.General{ + Rows: bc, + Cols: 1, + Stride: bvec.Inc, + Data: bvec.Data, + } + blas64.Gemm(aT, bT, 1, amat, bmat, 0, m.mat) + return + } + cvec := blas64.Vector{ + Inc: m.mat.Stride, + Data: m.mat.Data, + } + blas64.Gemv(aT, 1, amat, bvec, 0, cvec) + return + } + } + if bUrm, ok := bU.(RawMatrixer); ok { + bmat := bUrm.RawMatrix() + if restore == nil { + m.checkOverlap(bmat) + } + if aU, ok := aU.(RawSymmetricer); ok { + amat := aU.RawSymmetric() + if bTrans { + c := getWorkspace(bc, br, false) + blas64.Symm(blas.Right, 1, amat, bmat, 0, c.mat) + strictCopy(m, c.T()) + putWorkspace(c) + return + } + blas64.Symm(blas.Left, 1, amat, bmat, 0, m.mat) + return + } + if aU, ok := aU.(RawTriangular); ok { + // Trmm updates in place, so copy bU first. + amat := aU.RawTriangular() + if bTrans { + c := getWorkspace(bc, br, false) + var tmp Dense + tmp.SetRawMatrix(bmat) + c.Copy(&tmp) + aT := blas.Trans + if aTrans { + aT = blas.NoTrans + } + blas64.Trmm(blas.Right, aT, 1, amat, c.mat) + strictCopy(m, c.T()) + putWorkspace(c) + return + } + m.Copy(b) + blas64.Trmm(blas.Left, aT, 1, amat, m.mat) + return + } + if aU, ok := aU.(*VecDense); ok { + m.checkOverlap(aU.asGeneral()) + avec := aU.RawVector() + if aTrans { + // {1,ac} x {ac, bc} + // Transpose B so that the vector is on the right. + cvec := blas64.Vector{ + Inc: 1, + Data: m.mat.Data, + } + bT := blas.Trans + if bTrans { + bT = blas.NoTrans + } + blas64.Gemv(bT, 1, bmat, avec, 0, cvec) + return + } + // {ar,1} x {1,bc} which is not a vector result. + // Instead, construct A as a General. + amat := blas64.General{ + Rows: ar, + Cols: 1, + Stride: avec.Inc, + Data: avec.Data, + } + blas64.Gemm(aT, bT, 1, amat, bmat, 0, m.mat) + return + } + } + + row := getFloats(ac, false) + defer putFloats(row) + for r := 0; r < ar; r++ { + for i := range row { + row[i] = a.At(r, i) + } + for c := 0; c < bc; c++ { + var v float64 + for i, e := range row { + v += e * b.At(i, c) + } + m.mat.Data[r*m.mat.Stride+c] = v + } + } +} + +// strictCopy copies a into m panicking if the shape of a and m differ. +func strictCopy(m *Dense, a Matrix) { + r, c := m.Copy(a) + if r != m.mat.Rows || c != m.mat.Cols { + // Panic with a string since this + // is not a user-facing panic. + panic(ErrShape.Error()) + } +} + +// Exp calculates the exponential of the matrix a, e^a, placing the result +// in the receiver. Exp will panic with matrix.ErrShape if a is not square. +// +// Exp uses the scaling and squaring method described in section 3 of +// http://www.cs.cornell.edu/cv/researchpdf/19ways+.pdf. +func (m *Dense) Exp(a Matrix) { + r, c := a.Dims() + if r != c { + panic(ErrShape) + } + + var w *Dense + if m.IsZero() { + m.reuseAsZeroed(r, r) + w = m + } else { + w = getWorkspace(r, r, true) + } + for i := 0; i < r*r; i += r + 1 { + w.mat.Data[i] = 1 + } + + const ( + terms = 10 + scaling = 4 + ) + + small := getWorkspace(r, r, false) + small.Scale(math.Pow(2, -scaling), a) + power := getWorkspace(r, r, false) + power.Copy(small) + + var ( + tmp = getWorkspace(r, r, false) + factI = 1. + ) + for i := 1.; i < terms; i++ { + factI *= i + + // This is OK to do because power and tmp are + // new Dense values so all rows are contiguous. + // TODO(kortschak) Make this explicit in the NewDense doc comment. + for j, v := range power.mat.Data { + tmp.mat.Data[j] = v / factI + } + + w.Add(w, tmp) + if i < terms-1 { + tmp.Mul(power, small) + tmp, power = power, tmp + } + } + putWorkspace(small) + putWorkspace(power) + for i := 0; i < scaling; i++ { + tmp.Mul(w, w) + tmp, w = w, tmp + } + putWorkspace(tmp) + + if w != m { + m.Copy(w) + putWorkspace(w) + } +} + +// Pow calculates the integral power of the matrix a to n, placing the result +// in the receiver. Pow will panic if n is negative or if a is not square. +func (m *Dense) Pow(a Matrix, n int) { + if n < 0 { + panic("matrix: illegal power") + } + r, c := a.Dims() + if r != c { + panic(ErrShape) + } + + m.reuseAs(r, c) + + // Take possible fast paths. + switch n { + case 0: + for i := 0; i < r; i++ { + zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]) + m.mat.Data[i*m.mat.Stride+i] = 1 + } + return + case 1: + m.Copy(a) + return + case 2: + m.Mul(a, a) + return + } + + // Perform iterative exponentiation by squaring in work space. + w := getWorkspace(r, r, false) + w.Copy(a) + s := getWorkspace(r, r, false) + s.Copy(a) + x := getWorkspace(r, r, false) + for n--; n > 0; n >>= 1 { + if n&1 != 0 { + x.Mul(w, s) + w, x = x, w + } + if n != 1 { + x.Mul(s, s) + s, x = x, s + } + } + m.Copy(w) + putWorkspace(w) + putWorkspace(s) + putWorkspace(x) +} + +// Scale multiplies the elements of a by f, placing the result in the receiver. +// +// See the Scaler interface for more information. +func (m *Dense) Scale(f float64, a Matrix) { + ar, ac := a.Dims() + + m.reuseAs(ar, ac) + + aU, aTrans := untranspose(a) + if rm, ok := aU.(RawMatrixer); ok { + amat := rm.RawMatrix() + if m == aU || m.checkOverlap(amat) { + var restore func() + m, restore = m.isolatedWorkspace(a) + defer restore() + } + if !aTrans { + for ja, jm := 0, 0; ja < ar*amat.Stride; ja, jm = ja+amat.Stride, jm+m.mat.Stride { + for i, v := range amat.Data[ja : ja+ac] { + m.mat.Data[i+jm] = v * f + } + } + } else { + for ja, jm := 0, 0; ja < ac*amat.Stride; ja, jm = ja+amat.Stride, jm+1 { + for i, v := range amat.Data[ja : ja+ar] { + m.mat.Data[i*m.mat.Stride+jm] = v * f + } + } + } + return + } + + for r := 0; r < ar; r++ { + for c := 0; c < ac; c++ { + m.set(r, c, f*a.At(r, c)) + } + } +} + +// Apply applies the function fn to each of the elements of a, placing the +// resulting matrix in the receiver. The function fn takes a row/column +// index and element value and returns some function of that tuple. +func (m *Dense) Apply(fn func(i, j int, v float64) float64, a Matrix) { + ar, ac := a.Dims() + + m.reuseAs(ar, ac) + + aU, aTrans := untranspose(a) + if rm, ok := aU.(RawMatrixer); ok { + amat := rm.RawMatrix() + if m == aU || m.checkOverlap(amat) { + var restore func() + m, restore = m.isolatedWorkspace(a) + defer restore() + } + if !aTrans { + for j, ja, jm := 0, 0, 0; ja < ar*amat.Stride; j, ja, jm = j+1, ja+amat.Stride, jm+m.mat.Stride { + for i, v := range amat.Data[ja : ja+ac] { + m.mat.Data[i+jm] = fn(j, i, v) + } + } + } else { + for j, ja, jm := 0, 0, 0; ja < ac*amat.Stride; j, ja, jm = j+1, ja+amat.Stride, jm+1 { + for i, v := range amat.Data[ja : ja+ar] { + m.mat.Data[i*m.mat.Stride+jm] = fn(i, j, v) + } + } + } + return + } + + for r := 0; r < ar; r++ { + for c := 0; c < ac; c++ { + m.set(r, c, fn(r, c, a.At(r, c))) + } + } +} + +// RankOne performs a rank-one update to the matrix a and stores the result +// in the receiver. If a is zero, see Outer. +// m = a + alpha * x * y' +func (m *Dense) RankOne(a Matrix, alpha float64, x, y *VecDense) { + ar, ac := a.Dims() + if x.Len() != ar { + panic(ErrShape) + } + if y.Len() != ac { + panic(ErrShape) + } + + m.checkOverlap(x.asGeneral()) + m.checkOverlap(y.asGeneral()) + + var w Dense + if m == a { + w = *m + } + w.reuseAs(ar, ac) + + // Copy over to the new memory if necessary + if m != a { + w.Copy(a) + } + blas64.Ger(alpha, x.mat, y.mat, w.mat) + *m = w +} + +// Outer calculates the outer product of x and y, and stores the result +// in the receiver. +// m = alpha * x * y' +// In order to update an existing matrix, see RankOne. +func (m *Dense) Outer(alpha float64, x, y *VecDense) { + r := x.Len() + c := y.Len() + + // Copied from reuseAs with use replaced by useZeroed + // and a final zero of the matrix elements if we pass + // the shape checks. + // TODO(kortschak): Factor out into reuseZeroedAs if + // we find another case that needs it. + if m.mat.Rows > m.capRows || m.mat.Cols > m.capCols { + // Panic as a string, not a mat.Error. + panic("mat: caps not correctly set") + } + if m.IsZero() { + m.mat = blas64.General{ + Rows: r, + Cols: c, + Stride: c, + Data: useZeroed(m.mat.Data, r*c), + } + m.capRows = r + m.capCols = c + } else if r != m.mat.Rows || c != m.mat.Cols { + panic(ErrShape) + } else { + m.checkOverlap(x.asGeneral()) + m.checkOverlap(y.asGeneral()) + for i := 0; i < r; i++ { + zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+c]) + } + } + + blas64.Ger(alpha, x.mat, y.mat, m.mat) +} diff --git a/vendor/gonum.org/v1/gonum/mat/dense_test.go b/vendor/gonum.org/v1/gonum/mat/dense_test.go new file mode 100644 index 00000000..34b37cc3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/dense_test.go @@ -0,0 +1,2005 @@ +// 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. + +package mat + +import ( + "fmt" + "math" + "math/rand" + "reflect" + "testing" + + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +func asBasicMatrix(d *Dense) Matrix { return (*basicMatrix)(d) } +func asBasicSymmetric(s *SymDense) Matrix { return (*basicSymmetric)(s) } +func asBasicTriangular(t *TriDense) Triangular { return (*basicTriangular)(t) } + +func TestNewDense(t *testing.T) { + for i, test := range []struct { + a []float64 + rows, cols int + min, max float64 + fro float64 + mat *Dense + }{ + { + []float64{ + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + }, + 3, 3, + 0, 0, + 0, + &Dense{ + mat: blas64.General{ + Rows: 3, Cols: 3, + Stride: 3, + Data: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + capRows: 3, capCols: 3, + }, + }, + { + []float64{ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + }, + 3, 3, + 1, 1, + 3, + &Dense{ + mat: blas64.General{ + Rows: 3, Cols: 3, + Stride: 3, + Data: []float64{1, 1, 1, 1, 1, 1, 1, 1, 1}, + }, + capRows: 3, capCols: 3, + }, + }, + { + []float64{ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, + }, + 3, 3, + 0, 1, + 1.7320508075688772, + &Dense{ + mat: blas64.General{ + Rows: 3, Cols: 3, + Stride: 3, + Data: []float64{1, 0, 0, 0, 1, 0, 0, 0, 1}, + }, + capRows: 3, capCols: 3, + }, + }, + { + []float64{ + -1, 0, 0, + 0, -1, 0, + 0, 0, -1, + }, + 3, 3, + -1, 0, + 1.7320508075688772, + &Dense{ + mat: blas64.General{ + Rows: 3, Cols: 3, + Stride: 3, + Data: []float64{-1, 0, 0, 0, -1, 0, 0, 0, -1}, + }, + capRows: 3, capCols: 3, + }, + }, + { + []float64{ + 1, 2, 3, + 4, 5, 6, + }, + 2, 3, + 1, 6, + 9.539392014169458, + &Dense{ + mat: blas64.General{ + Rows: 2, Cols: 3, + Stride: 3, + Data: []float64{1, 2, 3, 4, 5, 6}, + }, + capRows: 2, capCols: 3, + }, + }, + { + []float64{ + 1, 2, + 3, 4, + 5, 6, + }, + 3, 2, + 1, 6, + 9.539392014169458, + &Dense{ + mat: blas64.General{ + Rows: 3, Cols: 2, + Stride: 2, + Data: []float64{1, 2, 3, 4, 5, 6}, + }, + capRows: 3, capCols: 2, + }, + }, + } { + m := NewDense(test.rows, test.cols, test.a) + rows, cols := m.Dims() + if rows != test.rows { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.rows) + } + if cols != test.cols { + t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.cols) + } + if min := Min(m); min != test.min { + t.Errorf("unexpected min for test %d: got: %v want: %v", i, min, test.min) + } + if max := Max(m); max != test.max { + t.Errorf("unexpected max for test %d: got: %v want: %v", i, max, test.max) + } + if fro := Norm(m, 2); math.Abs(Norm(m, 2)-test.fro) > 1e-14 { + t.Errorf("unexpected Frobenius norm for test %d: got: %v want: %v", i, fro, test.fro) + } + if !reflect.DeepEqual(m, test.mat) { + t.Errorf("unexpected matrix for test %d", i) + } + if !Equal(m, test.mat) { + t.Errorf("matrix does not equal expected matrix for test %d", i) + } + } +} + +func TestAtSet(t *testing.T) { + for test, af := range [][][]float64{ + {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, // even + {{1, 2}, {4, 5}, {7, 8}}, // wide + {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, //skinny + } { + m := NewDense(flatten(af)) + rows, cols := m.Dims() + for i := 0; i < rows; i++ { + for j := 0; j < cols; j++ { + if m.At(i, j) != af[i][j] { + t.Errorf("unexpected value for At(%d, %d) for test %d: got: %v want: %v", + i, j, test, m.At(i, j), af[i][j]) + } + + v := float64(i * j) + m.Set(i, j, v) + if m.At(i, j) != v { + t.Errorf("unexpected value for At(%d, %d) after Set(%[1]d, %d, %v) for test %d: got: %v want: %[3]v", + i, j, v, test, m.At(i, j)) + } + } + } + // Check access out of bounds fails + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { m.At(row, 0) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { m.At(0, col) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + // Check Set out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { m.Set(row, 0, 1.2) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { m.Set(0, col, 1.2) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + } +} + +func TestSetRowColumn(t *testing.T) { + for _, as := range [][][]float64{ + {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}, + {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}, + } { + for ri, row := range as { + a := NewDense(flatten(as)) + m := &Dense{} + m.Clone(a) + a.SetRow(ri, make([]float64, a.mat.Cols)) + m.Sub(m, a) + nt := Norm(m, 2) + nr := floats.Norm(row, 2) + if math.Abs(nt-nr) > 1e-14 { + t.Errorf("Row %d norm mismatch, want: %g, got: %g", ri, nr, nt) + } + } + + for ci := range as[0] { + a := NewDense(flatten(as)) + m := &Dense{} + m.Clone(a) + a.SetCol(ci, make([]float64, a.mat.Rows)) + col := make([]float64, a.mat.Rows) + for j := range col { + col[j] = float64(ci + 1 + j*a.mat.Cols) + } + m.Sub(m, a) + nt := Norm(m, 2) + nc := floats.Norm(col, 2) + if math.Abs(nt-nc) > 1e-14 { + t.Errorf("Column %d norm mismatch, want: %g, got: %g", ci, nc, nt) + } + } + } +} + +func TestRowColView(t *testing.T) { + for _, test := range []struct { + mat [][]float64 + }{ + { + mat: [][]float64{ + {1, 2, 3, 4, 5}, + {6, 7, 8, 9, 10}, + {11, 12, 13, 14, 15}, + {16, 17, 18, 19, 20}, + {21, 22, 23, 24, 25}, + }, + }, + { + mat: [][]float64{ + {1, 2, 3, 4}, + {6, 7, 8, 9}, + {11, 12, 13, 14}, + {16, 17, 18, 19}, + {21, 22, 23, 24}, + }, + }, + { + mat: [][]float64{ + {1, 2, 3, 4, 5}, + {6, 7, 8, 9, 10}, + {11, 12, 13, 14, 15}, + {16, 17, 18, 19, 20}, + }, + }, + } { + // This over cautious approach to building a matrix data + // slice is to ensure that changes to flatten in the future + // do not mask a regression to the issue identified in + // gonum/matrix#110. + rows, cols, flat := flatten(test.mat) + m := NewDense(rows, cols, flat[:len(flat):len(flat)]) + + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { m.At(row, 0) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access rows=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { m.At(0, col) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access cols=%d c=%d", cols, col) + } + } + + for i := 0; i < rows; i++ { + vr := m.RowView(i) + if vr.Len() != cols { + t.Errorf("unexpected number of columns: got: %d want: %d", vr.Len(), cols) + } + for j := 0; j < cols; j++ { + if got := vr.At(j, 0); got != test.mat[i][j] { + t.Errorf("unexpected value for row.At(%d, 0): got: %v want: %v", + j, got, test.mat[i][j]) + } + } + } + for j := 0; j < cols; j++ { + vc := m.ColView(j) + if vc.Len() != rows { + t.Errorf("unexpected number of rows: got: %d want: %d", vc.Len(), rows) + } + for i := 0; i < rows; i++ { + if got := vc.At(i, 0); got != test.mat[i][j] { + t.Errorf("unexpected value for col.At(%d, 0): got: %v want: %v", + i, got, test.mat[i][j]) + } + } + } + m = m.Slice(1, rows-1, 1, cols-1).(*Dense) + for i := 1; i < rows-1; i++ { + vr := m.RowView(i - 1) + if vr.Len() != cols-2 { + t.Errorf("unexpected number of columns: got: %d want: %d", vr.Len(), cols-2) + } + for j := 1; j < cols-1; j++ { + if got := vr.At(j-1, 0); got != test.mat[i][j] { + t.Errorf("unexpected value for row.At(%d, 0): got: %v want: %v", + j-1, got, test.mat[i][j]) + } + } + } + for j := 1; j < cols-1; j++ { + vc := m.ColView(j - 1) + if vc.Len() != rows-2 { + t.Errorf("unexpected number of rows: got: %d want: %d", vc.Len(), rows-2) + } + for i := 1; i < rows-1; i++ { + if got := vc.At(i-1, 0); got != test.mat[i][j] { + t.Errorf("unexpected value for col.At(%d, 0): got: %v want: %v", + i-1, got, test.mat[i][j]) + } + } + } + } +} + +func TestGrow(t *testing.T) { + m := &Dense{} + m = m.Grow(10, 10).(*Dense) + rows, cols := m.Dims() + capRows, capCols := m.Caps() + if rows != 10 { + t.Errorf("unexpected value for rows: got: %d want: 10", rows) + } + if cols != 10 { + t.Errorf("unexpected value for cols: got: %d want: 10", cols) + } + if capRows != 10 { + t.Errorf("unexpected value for capRows: got: %d want: 10", capRows) + } + if capCols != 10 { + t.Errorf("unexpected value for capCols: got: %d want: 10", capCols) + } + + // Test grow within caps is in-place. + m.Set(1, 1, 1) + v := m.Slice(1, 5, 1, 5).(*Dense) + if v.At(0, 0) != m.At(1, 1) { + t.Errorf("unexpected viewed element value: got: %v want: %v", v.At(0, 0), m.At(1, 1)) + } + v = v.Grow(5, 5).(*Dense) + if !Equal(v, m.Slice(1, 10, 1, 10)) { + t.Error("unexpected view value after grow") + } + + // Test grow bigger than caps copies. + v = v.Grow(5, 5).(*Dense) + if !Equal(v.Slice(0, 9, 0, 9), m.Slice(1, 10, 1, 10)) { + t.Error("unexpected mismatched common view value after grow") + } + v.Set(0, 0, 0) + if Equal(v.Slice(0, 9, 0, 9), m.Slice(1, 10, 1, 10)) { + t.Error("unexpected matching view value after grow past capacity") + } + + // Test grow uses existing data slice when matrix is zero size. + v.Reset() + p, l := &v.mat.Data[:1][0], cap(v.mat.Data) + *p = 1 // This element is at position (-1, -1) relative to v and so should not be visible. + v = v.Grow(5, 5).(*Dense) + if &v.mat.Data[:1][0] != p { + t.Error("grow unexpectedly copied slice within cap limit") + } + if cap(v.mat.Data) != l { + t.Errorf("unexpected change in data slice capacity: got: %d want: %d", cap(v.mat.Data), l) + } + if v.At(0, 0) != 0 { + t.Errorf("unexpected value for At(0, 0): got: %v want: 0", v.At(0, 0)) + } +} + +func TestAdd(t *testing.T) { + for i, test := range []struct { + a, b, r [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{2, 2, 2}, {2, 2, 2}, {2, 2, 2}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{2, 0, 0}, {0, 2, 0}, {0, 0, 2}}, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-2, 0, 0}, {0, -2, 0}, {0, 0, -2}}, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{2, 4, 6}, {8, 10, 12}}, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + r := NewDense(flatten(test.r)) + + var temp Dense + temp.Add(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from Add for test %d %v Add %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + zero(temp.mat.Data) + temp.Add(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from Add for test %d %v Add %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + // These probably warrant a better check and failure. They should never happen in the wild though. + temp.mat.Data = nil + panicked, message := panics(func() { temp.Add(a, b) }) + if !panicked || message != "runtime error: index out of range" { + t.Error("exected runtime panic for nil data slice") + } + + a.Add(a, b) + if !Equal(a, r) { + t.Errorf("unexpected result from Add for test %d %v Add %v: got: %v want: %v", + i, test.a, test.b, unflatten(a.mat.Rows, a.mat.Cols, a.mat.Data), test.r) + } + } + + panicked, message := panics(func() { + m := NewDense(10, 10, nil) + a := NewDense(5, 5, nil) + m.Slice(1, 6, 1, 6).(*Dense).Add(a, m.Slice(2, 7, 2, 7)) + }) + if !panicked { + t.Error("expected panic for overlapping matrices") + } + if message != regionOverlap { + t.Errorf("unexpected panic message: got: %q want: %q", message, regionOverlap) + } + + method := func(receiver, a, b Matrix) { + type Adder interface { + Add(a, b Matrix) + } + rd := receiver.(Adder) + rd.Add(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Add(a, b) + } + testTwoInput(t, "Add", &Dense{}, method, denseComparison, legalTypesAll, legalSizeSameRectangular, 1e-14) +} + +func TestSub(t *testing.T) { + for i, test := range []struct { + a, b, r [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{0, 0, 0}, {0, 0, 0}}, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + r := NewDense(flatten(test.r)) + + var temp Dense + temp.Sub(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from Sub for test %d %v Sub %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + zero(temp.mat.Data) + temp.Sub(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from Sub for test %d %v Sub %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + // These probably warrant a better check and failure. They should never happen in the wild though. + temp.mat.Data = nil + panicked, message := panics(func() { temp.Sub(a, b) }) + if !panicked || message != "runtime error: index out of range" { + t.Error("exected runtime panic for nil data slice") + } + + a.Sub(a, b) + if !Equal(a, r) { + t.Errorf("unexpected result from Sub for test %d %v Sub %v: got: %v want: %v", + i, test.a, test.b, unflatten(a.mat.Rows, a.mat.Cols, a.mat.Data), test.r) + } + } + + panicked, message := panics(func() { + m := NewDense(10, 10, nil) + a := NewDense(5, 5, nil) + m.Slice(1, 6, 1, 6).(*Dense).Sub(a, m.Slice(2, 7, 2, 7)) + }) + if !panicked { + t.Error("expected panic for overlapping matrices") + } + if message != regionOverlap { + t.Errorf("unexpected panic message: got: %q want: %q", message, regionOverlap) + } + + method := func(receiver, a, b Matrix) { + type Suber interface { + Sub(a, b Matrix) + } + rd := receiver.(Suber) + rd.Sub(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Sub(a, b) + } + testTwoInput(t, "Sub", &Dense{}, method, denseComparison, legalTypesAll, legalSizeSameRectangular, 1e-14) +} + +func TestMulElem(t *testing.T) { + for i, test := range []struct { + a, b, r [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 4, 9}, {16, 25, 36}}, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + r := NewDense(flatten(test.r)) + + var temp Dense + temp.MulElem(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from MulElem for test %d %v MulElem %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + zero(temp.mat.Data) + temp.MulElem(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from MulElem for test %d %v MulElem %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + // These probably warrant a better check and failure. They should never happen in the wild though. + temp.mat.Data = nil + panicked, message := panics(func() { temp.MulElem(a, b) }) + if !panicked || message != "runtime error: index out of range" { + t.Error("exected runtime panic for nil data slice") + } + + a.MulElem(a, b) + if !Equal(a, r) { + t.Errorf("unexpected result from MulElem for test %d %v MulElem %v: got: %v want: %v", + i, test.a, test.b, unflatten(a.mat.Rows, a.mat.Cols, a.mat.Data), test.r) + } + } + + panicked, message := panics(func() { + m := NewDense(10, 10, nil) + a := NewDense(5, 5, nil) + m.Slice(1, 6, 1, 6).(*Dense).MulElem(a, m.Slice(2, 7, 2, 7)) + }) + if !panicked { + t.Error("expected panic for overlapping matrices") + } + if message != regionOverlap { + t.Errorf("unexpected panic message: got: %q want: %q", message, regionOverlap) + } + + method := func(receiver, a, b Matrix) { + type ElemMuler interface { + MulElem(a, b Matrix) + } + rd := receiver.(ElemMuler) + rd.MulElem(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.MulElem(a, b) + } + testTwoInput(t, "MulElem", &Dense{}, method, denseComparison, legalTypesAll, legalSizeSameRectangular, 1e-14) +} + +// A comparison that treats NaNs as equal, for testing. +func (m *Dense) same(b Matrix) bool { + br, bc := b.Dims() + if br != m.mat.Rows || bc != m.mat.Cols { + return false + } + for r := 0; r < br; r++ { + for c := 0; c < bc; c++ { + if av, bv := m.At(r, c), b.At(r, c); av != bv && !(math.IsNaN(av) && math.IsNaN(bv)) { + return false + } + } + } + return true +} + +func TestDivElem(t *testing.T) { + for i, test := range []struct { + a, b, r [][]float64 + }{ + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{math.Inf(1), math.NaN(), math.NaN()}, {math.NaN(), math.Inf(1), math.NaN()}, {math.NaN(), math.NaN(), math.Inf(1)}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, math.NaN(), math.NaN()}, {math.NaN(), 1, math.NaN()}, {math.NaN(), math.NaN(), 1}}, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{1, math.NaN(), math.NaN()}, {math.NaN(), 1, math.NaN()}, {math.NaN(), math.NaN(), 1}}, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 1, 1}, {1, 1, 1}}, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + r := NewDense(flatten(test.r)) + + var temp Dense + temp.DivElem(a, b) + if !temp.same(r) { + t.Errorf("unexpected result from DivElem for test %d %v DivElem %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + zero(temp.mat.Data) + temp.DivElem(a, b) + if !temp.same(r) { + t.Errorf("unexpected result from DivElem for test %d %v DivElem %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + // These probably warrant a better check and failure. They should never happen in the wild though. + temp.mat.Data = nil + panicked, message := panics(func() { temp.DivElem(a, b) }) + if !panicked || message != "runtime error: index out of range" { + t.Error("exected runtime panic for nil data slice") + } + + a.DivElem(a, b) + if !a.same(r) { + t.Errorf("unexpected result from DivElem for test %d %v DivElem %v: got: %v want: %v", + i, test.a, test.b, unflatten(a.mat.Rows, a.mat.Cols, a.mat.Data), test.r) + } + } + + panicked, message := panics(func() { + m := NewDense(10, 10, nil) + a := NewDense(5, 5, nil) + m.Slice(1, 6, 1, 6).(*Dense).DivElem(a, m.Slice(2, 7, 2, 7)) + }) + if !panicked { + t.Error("expected panic for overlapping matrices") + } + if message != regionOverlap { + t.Errorf("unexpected panic message: got: %q want: %q", message, regionOverlap) + } + + method := func(receiver, a, b Matrix) { + type ElemDiver interface { + DivElem(a, b Matrix) + } + rd := receiver.(ElemDiver) + rd.DivElem(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.DivElem(a, b) + } + testTwoInput(t, "DivElem", &Dense{}, method, denseComparison, legalTypesAll, legalSizeSameRectangular, 1e-14) +} + +func TestMul(t *testing.T) { + for i, test := range []struct { + a, b, r [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{3, 3, 3}, {3, 3, 3}, {3, 3, 3}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 2}, {3, 4}, {5, 6}}, + [][]float64{{22, 28}, {49, 64}}, + }, + { + [][]float64{{0, 1, 1}, {0, 1, 1}, {0, 1, 1}}, + [][]float64{{0, 1, 1}, {0, 1, 1}, {0, 1, 1}}, + [][]float64{{0, 2, 2}, {0, 2, 2}, {0, 2, 2}}, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + r := NewDense(flatten(test.r)) + + var temp Dense + temp.Mul(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from Mul for test %d %v Mul %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + zero(temp.mat.Data) + temp.Mul(a, b) + if !Equal(&temp, r) { + t.Errorf("unexpected result from Mul for test %d %v Mul %v: got: %v want: %v", + i, test.a, test.b, unflatten(temp.mat.Rows, temp.mat.Cols, temp.mat.Data), test.r) + } + + // These probably warrant a better check and failure. They should never happen in the wild though. + temp.mat.Data = nil + panicked, message := panics(func() { temp.Mul(a, b) }) + if !panicked || message != "blas: index of c out of range" { + if message != "" { + t.Errorf("expected runtime panic for nil data slice: got %q", message) + } else { + t.Error("expected runtime panic for nil data slice") + } + } + } + + panicked, message := panics(func() { + m := NewDense(10, 10, nil) + a := NewDense(5, 5, nil) + m.Slice(1, 6, 1, 6).(*Dense).Mul(a, m.Slice(2, 7, 2, 7)) + }) + if !panicked { + t.Error("expected panic for overlapping matrices") + } + if message != regionOverlap { + t.Errorf("unexpected panic message: got: %q want: %q", message, regionOverlap) + } + + method := func(receiver, a, b Matrix) { + type Muler interface { + Mul(a, b Matrix) + } + rd := receiver.(Muler) + rd.Mul(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Mul(a, b) + } + legalSizeMul := func(ar, ac, br, bc int) bool { + return ac == br + } + testTwoInput(t, "Mul", &Dense{}, method, denseComparison, legalTypesAll, legalSizeMul, 1e-14) +} + +func randDense(size int, rho float64, rnd func() float64) (*Dense, error) { + if size == 0 { + return nil, ErrZeroLength + } + d := &Dense{ + mat: blas64.General{ + Rows: size, Cols: size, Stride: size, + Data: make([]float64, size*size), + }, + capRows: size, capCols: size, + } + for i := 0; i < size; i++ { + for j := 0; j < size; j++ { + if rand.Float64() < rho { + d.Set(i, j, rnd()) + } + } + } + return d, nil +} + +func TestExp(t *testing.T) { + for i, test := range []struct { + a [][]float64 + want [][]float64 + mod func(*Dense) + }{ + { + a: [][]float64{{-49, 24}, {-64, 31}}, + want: [][]float64{{-0.7357587581474017, 0.5518190996594223}, {-1.4715175990917921, 1.103638240717339}}, + }, + { + a: [][]float64{{-49, 24}, {-64, 31}}, + want: [][]float64{{-0.7357587581474017, 0.5518190996594223}, {-1.4715175990917921, 1.103638240717339}}, + mod: func(a *Dense) { + d := make([]float64, 100) + for i := range d { + d[i] = math.NaN() + } + *a = *NewDense(10, 10, d).Slice(1, 3, 1, 3).(*Dense) + }, + }, + { + a: [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + want: [][]float64{{2.71828182845905, 0, 0}, {0, 2.71828182845905, 0}, {0, 0, 2.71828182845905}}, + }, + } { + var got Dense + if test.mod != nil { + test.mod(&got) + } + got.Exp(NewDense(flatten(test.a))) + if !EqualApprox(&got, NewDense(flatten(test.want)), 1e-12) { + t.Errorf("unexpected result for Exp test %d", i) + } + } +} + +func TestPow(t *testing.T) { + for i, test := range []struct { + a [][]float64 + n int + mod func(*Dense) + want [][]float64 + }{ + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 0, + want: [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 0, + want: [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + mod: func(a *Dense) { + d := make([]float64, 100) + for i := range d { + d[i] = math.NaN() + } + *a = *NewDense(10, 10, d).Slice(1, 4, 1, 4).(*Dense) + }, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 1, + want: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 1, + want: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + mod: func(a *Dense) { + d := make([]float64, 100) + for i := range d { + d[i] = math.NaN() + } + *a = *NewDense(10, 10, d).Slice(1, 4, 1, 4).(*Dense) + }, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 2, + want: [][]float64{{30, 36, 42}, {66, 81, 96}, {102, 126, 150}}, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 2, + want: [][]float64{{30, 36, 42}, {66, 81, 96}, {102, 126, 150}}, + mod: func(a *Dense) { + d := make([]float64, 100) + for i := range d { + d[i] = math.NaN() + } + *a = *NewDense(10, 10, d).Slice(1, 4, 1, 4).(*Dense) + }, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 3, + want: [][]float64{{468, 576, 684}, {1062, 1305, 1548}, {1656, 2034, 2412}}, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + n: 3, + want: [][]float64{{468, 576, 684}, {1062, 1305, 1548}, {1656, 2034, 2412}}, + mod: func(a *Dense) { + d := make([]float64, 100) + for i := range d { + d[i] = math.NaN() + } + *a = *NewDense(10, 10, d).Slice(1, 4, 1, 4).(*Dense) + }, + }, + } { + var got Dense + if test.mod != nil { + test.mod(&got) + } + got.Pow(NewDense(flatten(test.a)), test.n) + if !EqualApprox(&got, NewDense(flatten(test.want)), 1e-12) { + t.Errorf("unexpected result for Pow test %d", i) + } + } +} + +func TestScale(t *testing.T) { + for _, f := range []float64{0.5, 1, 3} { + method := func(receiver, a Matrix) { + type Scaler interface { + Scale(f float64, a Matrix) + } + rd := receiver.(Scaler) + rd.Scale(f, a) + } + denseComparison := func(receiver, a *Dense) { + receiver.Scale(f, a) + } + testOneInput(t, "Scale", &Dense{}, method, denseComparison, isAnyType, isAnySize, 1e-14) + } +} + +func TestPowN(t *testing.T) { + for i, test := range []struct { + a [][]float64 + mod func(*Dense) + }{ + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, + mod: func(a *Dense) { + d := make([]float64, 100) + for i := range d { + d[i] = math.NaN() + } + *a = *NewDense(10, 10, d).Slice(1, 4, 1, 4).(*Dense) + }, + }, + } { + for n := 1; n <= 14; n++ { + var got, want Dense + if test.mod != nil { + test.mod(&got) + } + got.Pow(NewDense(flatten(test.a)), n) + want.iterativePow(NewDense(flatten(test.a)), n) + if !Equal(&got, &want) { + t.Errorf("unexpected result for iterative Pow test %d", i) + } + } + } +} + +func (m *Dense) iterativePow(a Matrix, n int) { + m.Clone(a) + for i := 1; i < n; i++ { + m.Mul(m, a) + } +} + +func TestCloneT(t *testing.T) { + for i, test := range []struct { + a, want [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 4}, {2, 5}, {3, 6}}, + }, + } { + a := NewDense(flatten(test.a)) + want := NewDense(flatten(test.want)) + + var got, gotT Dense + + for j := 0; j < 2; j++ { + got.Clone(a.T()) + if !Equal(&got, want) { + t.Errorf("expected transpose for test %d iteration %d: %v transpose = %v", + i, j, test.a, test.want) + } + gotT.Clone(got.T()) + if !Equal(&gotT, a) { + t.Errorf("expected transpose for test %d iteration %d: %v transpose = %v", + i, j, test.a, test.want) + } + + zero(got.mat.Data) + } + } +} + +func TestCopyT(t *testing.T) { + for i, test := range []struct { + a, want [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 4}, {2, 5}, {3, 6}}, + }, + } { + a := NewDense(flatten(test.a)) + want := NewDense(flatten(test.want)) + + ar, ac := a.Dims() + got := NewDense(ac, ar, nil) + rr := NewDense(ar, ac, nil) + + for j := 0; j < 2; j++ { + got.Copy(a.T()) + if !Equal(got, want) { + t.Errorf("expected transpose for test %d iteration %d: %v transpose = %v", + i, j, test.a, test.want) + } + rr.Copy(got.T()) + if !Equal(rr, a) { + t.Errorf("expected transpose for test %d iteration %d: %v transpose = %v", + i, j, test.a, test.want) + } + + zero(got.mat.Data) + } + } +} + +func TestCopyDenseAlias(t *testing.T) { + for _, trans := range []bool{false, true} { + for di := 0; di < 2; di++ { + for dj := 0; dj < 2; dj++ { + for si := 0; si < 2; si++ { + for sj := 0; sj < 2; sj++ { + a := NewDense(3, 3, []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }) + src := a.Slice(si, si+2, sj, sj+2) + want := DenseCopyOf(src) + got := a.Slice(di, di+2, dj, dj+2).(*Dense) + + if trans { + panicked, _ := panics(func() { got.Copy(src.T()) }) + if !panicked { + t.Errorf("expected panic for transpose aliased copy with offsets dst(%d,%d) src(%d,%d):\ngot:\n%v\nwant:\n%v", + di, dj, si, sj, Formatted(got), Formatted(want), + ) + } + continue + } + + got.Copy(src) + if !Equal(got, want) { + t.Errorf("unexpected aliased copy result with offsets dst(%d,%d) src(%d,%d):\ngot:\n%v\nwant:\n%v", + di, dj, si, sj, Formatted(got), Formatted(want), + ) + } + } + } + } + } + } +} + +func TestCopyVecDenseAlias(t *testing.T) { + for _, horiz := range []bool{false, true} { + for do := 0; do < 2; do++ { + for di := 0; di < 3; di++ { + for si := 0; si < 3; si++ { + a := NewDense(3, 3, []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }) + var src *VecDense + var want *Dense + if horiz { + src = a.RowView(si) + want = DenseCopyOf(a.Slice(si, si+1, 0, 2)) + } else { + src = a.ColView(si) + want = DenseCopyOf(a.Slice(0, 2, si, si+1)) + } + + var got *Dense + if horiz { + got = a.Slice(di, di+1, do, do+2).(*Dense) + got.Copy(src.T()) + } else { + got = a.Slice(do, do+2, di, di+1).(*Dense) + got.Copy(src) + } + + if !Equal(got, want) { + t.Errorf("unexpected aliased copy result with offsets dst(%d) src(%d):\ngot:\n%v\nwant:\n%v", + di, si, Formatted(got), Formatted(want), + ) + } + } + } + } + } +} + +func identity(r, c int, v float64) float64 { return v } + +func TestApply(t *testing.T) { + for i, test := range []struct { + a, want [][]float64 + fn func(r, c int, v float64) float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + identity, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + identity, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + identity, + }, + { + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + [][]float64{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}}, + identity, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{1, 2, 3}, {4, 5, 6}}, + identity, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{2, 4, 6}, {8, 10, 12}}, + func(r, c int, v float64) float64 { return v * 2 }, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{0, 2, 0}, {0, 5, 0}}, + func(r, c int, v float64) float64 { + if c == 1 { + return v + } + return 0 + }, + }, + { + [][]float64{{1, 2, 3}, {4, 5, 6}}, + [][]float64{{0, 0, 0}, {4, 5, 6}}, + func(r, c int, v float64) float64 { + if r == 1 { + return v + } + return 0 + }, + }, + } { + a := NewDense(flatten(test.a)) + want := NewDense(flatten(test.want)) + + var got Dense + + for j := 0; j < 2; j++ { + got.Apply(test.fn, a) + if !Equal(&got, want) { + t.Errorf("unexpected result for test %d iteration %d: got: %v want: %v", i, j, got.mat.Data, want.mat.Data) + } + } + } + + for _, fn := range []func(r, c int, v float64) float64{ + identity, + func(r, c int, v float64) float64 { + if r < c { + return v + } + return -v + }, + func(r, c int, v float64) float64 { + if r%2 == 0 && c%2 == 0 { + return v + } + return -v + }, + func(_, _ int, v float64) float64 { return v * v }, + func(_, _ int, v float64) float64 { return -v }, + } { + method := func(receiver, x Matrix) { + type Applier interface { + Apply(func(r, c int, v float64) float64, Matrix) + } + rd := receiver.(Applier) + rd.Apply(fn, x) + } + denseComparison := func(receiver, x *Dense) { + receiver.Apply(fn, x) + } + testOneInput(t, "Apply", &Dense{}, method, denseComparison, isAnyType, isAnySize, 0) + } +} + +func TestClone(t *testing.T) { + for i, test := range []struct { + a [][]float64 + i, j int + v float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + 1, 1, + 1, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + 0, 0, + 0, + }, + } { + a := NewDense(flatten(test.a)) + b := *a + a.Clone(a) + a.Set(test.i, test.j, test.v) + + if Equal(&b, a) { + t.Errorf("unexpected mirror of write to cloned matrix for test %d: %v cloned and altered = %v", + i, a, &b) + } + } +} + +// TODO(kortschak) Roll this into testOneInput when it exists. +func TestCopyPanic(t *testing.T) { + for _, a := range []*Dense{ + {}, + {mat: blas64.General{Rows: 1}}, + {mat: blas64.General{Cols: 1}}, + } { + var rows, cols int + m := NewDense(1, 1, nil) + panicked, message := panics(func() { rows, cols = m.Copy(a) }) + if panicked { + t.Errorf("unexpected panic: %v", message) + } + if rows != 0 { + t.Errorf("unexpected rows: got: %d want: 0", rows) + } + if cols != 0 { + t.Errorf("unexpected cols: got: %d want: 0", cols) + } + } +} + +func TestStack(t *testing.T) { + for i, test := range []struct { + a, b, e [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{0, 1, 0}, {0, 0, 1}, {1, 0, 0}}, + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}}, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + + var s Dense + s.Stack(a, b) + + if !Equal(&s, NewDense(flatten(test.e))) { + t.Errorf("unexpected result for Stack test %d: %v stack %v = %v", i, a, b, s) + } + } + + method := func(receiver, a, b Matrix) { + type Stacker interface { + Stack(a, b Matrix) + } + rd := receiver.(Stacker) + rd.Stack(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Stack(a, b) + } + testTwoInput(t, "Stack", &Dense{}, method, denseComparison, legalTypesAll, legalSizeSameWidth, 0) +} + +func TestAugment(t *testing.T) { + for i, test := range []struct { + a, b, e [][]float64 + }{ + { + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + [][]float64{{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}}, + }, + { + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}, + [][]float64{{1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}}, + }, + { + [][]float64{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + [][]float64{{0, 1, 0}, {0, 0, 1}, {1, 0, 0}}, + [][]float64{{1, 0, 0, 0, 1, 0}, {0, 1, 0, 0, 0, 1}, {0, 0, 1, 1, 0, 0}}, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + + var s Dense + s.Augment(a, b) + + if !Equal(&s, NewDense(flatten(test.e))) { + t.Errorf("unexpected result for Augment test %d: %v augment %v = %v", i, a, b, s) + } + } + + method := func(receiver, a, b Matrix) { + type Augmenter interface { + Augment(a, b Matrix) + } + rd := receiver.(Augmenter) + rd.Augment(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Augment(a, b) + } + testTwoInput(t, "Augment", &Dense{}, method, denseComparison, legalTypesAll, legalSizeSameHeight, 0) +} + +func TestRankOne(t *testing.T) { + for i, test := range []struct { + x []float64 + y []float64 + m [][]float64 + alpha float64 + }{ + { + x: []float64{5}, + y: []float64{10}, + m: [][]float64{{2}}, + alpha: -3, + }, + { + x: []float64{5, 6, 1}, + y: []float64{10}, + m: [][]float64{{2}, {-3}, {5}}, + alpha: -3, + }, + + { + x: []float64{5}, + y: []float64{10, 15, 8}, + m: [][]float64{{2, -3, 5}}, + alpha: -3, + }, + { + x: []float64{1, 5}, + y: []float64{10, 15}, + m: [][]float64{ + {2, -3}, + {4, -1}, + }, + alpha: -3, + }, + { + x: []float64{2, 3, 9}, + y: []float64{8, 9}, + m: [][]float64{ + {2, 3}, + {4, 5}, + {6, 7}, + }, + alpha: -3, + }, + { + x: []float64{2, 3}, + y: []float64{8, 9, 9}, + m: [][]float64{ + {2, 3, 6}, + {4, 5, 7}, + }, + alpha: -3, + }, + } { + want := &Dense{} + xm := NewDense(len(test.x), 1, test.x) + ym := NewDense(1, len(test.y), test.y) + + want.Mul(xm, ym) + want.Scale(test.alpha, want) + want.Add(want, NewDense(flatten(test.m))) + + a := NewDense(flatten(test.m)) + m := &Dense{} + // Check with a new matrix + m.RankOne(a, test.alpha, NewVecDense(len(test.x), test.x), NewVecDense(len(test.y), test.y)) + if !Equal(m, want) { + t.Errorf("unexpected result for RankOne test %d iteration 0: got: %+v want: %+v", i, m, want) + } + // Check with the same matrix + a.RankOne(a, test.alpha, NewVecDense(len(test.x), test.x), NewVecDense(len(test.y), test.y)) + if !Equal(a, want) { + t.Errorf("unexpected result for Outer test %d iteration 1: got: %+v want: %+v", i, m, want) + } + } +} + +func TestOuter(t *testing.T) { + for i, test := range []struct { + x []float64 + y []float64 + }{ + { + x: []float64{5}, + y: []float64{10}, + }, + { + x: []float64{5, 6, 1}, + y: []float64{10}, + }, + + { + x: []float64{5}, + y: []float64{10, 15, 8}, + }, + { + x: []float64{1, 5}, + y: []float64{10, 15}, + }, + { + x: []float64{2, 3, 9}, + y: []float64{8, 9}, + }, + { + x: []float64{2, 3}, + y: []float64{8, 9, 9}, + }, + } { + for _, f := range []float64{0.5, 1, 3} { + want := &Dense{} + xm := NewDense(len(test.x), 1, test.x) + ym := NewDense(1, len(test.y), test.y) + + want.Mul(xm, ym) + want.Scale(f, want) + + var m Dense + for j := 0; j < 2; j++ { + // Check with a new matrix - and then again. + m.Outer(f, NewVecDense(len(test.x), test.x), NewVecDense(len(test.y), test.y)) + if !Equal(&m, want) { + t.Errorf("unexpected result for Outer test %d iteration %d scale %v: got: %+v want: %+v", i, j, f, m, want) + } + } + } + } +} + +func TestInverse(t *testing.T) { + for i, test := range []struct { + a Matrix + want Matrix // nil indicates that a is singular. + tol float64 + }{ + { + a: NewDense(3, 3, []float64{ + 8, 1, 6, + 3, 5, 7, + 4, 9, 2, + }), + want: NewDense(3, 3, []float64{ + 0.147222222222222, -0.144444444444444, 0.063888888888889, + -0.061111111111111, 0.022222222222222, 0.105555555555556, + -0.019444444444444, 0.188888888888889, -0.102777777777778, + }), + tol: 1e-14, + }, + { + a: NewDense(3, 3, []float64{ + 8, 1, 6, + 3, 5, 7, + 4, 9, 2, + }).T(), + want: NewDense(3, 3, []float64{ + 0.147222222222222, -0.144444444444444, 0.063888888888889, + -0.061111111111111, 0.022222222222222, 0.105555555555556, + -0.019444444444444, 0.188888888888889, -0.102777777777778, + }).T(), + tol: 1e-14, + }, + + // This case does not fail, but we do not guarantee that. The success + // is because the receiver and the input are aligned in the call to + // inverse. If there was a misalignment, the result would likely be + // incorrect and no shadowing panic would occur. + { + a: asBasicMatrix(NewDense(3, 3, []float64{ + 8, 1, 6, + 3, 5, 7, + 4, 9, 2, + })), + want: NewDense(3, 3, []float64{ + 0.147222222222222, -0.144444444444444, 0.063888888888889, + -0.061111111111111, 0.022222222222222, 0.105555555555556, + -0.019444444444444, 0.188888888888889, -0.102777777777778, + }), + tol: 1e-14, + }, + + // The following case fails as it does not follow the shadowing rules. + // Specifically, the test extracts the underlying *Dense, and uses + // it as a receiver with the basicMatrix as input. The basicMatrix type + // allows shadowing of the input data without providing the Raw method + // required for detection of shadowing. + // + // We specifically state we do not check this case. + // + // { + // a: asBasicMatrix(NewDense(3, 3, []float64{ + // 8, 1, 6, + // 3, 5, 7, + // 4, 9, 2, + // })).T(), + // want: NewDense(3, 3, []float64{ + // 0.147222222222222, -0.144444444444444, 0.063888888888889, + // -0.061111111111111, 0.022222222222222, 0.105555555555556, + // -0.019444444444444, 0.188888888888889, -0.102777777777778, + // }).T(), + // tol: 1e-14, + // }, + + { + a: NewDense(4, 4, []float64{ + 5, 2, 8, 7, + 4, 5, 8, 2, + 8, 5, 3, 2, + 8, 7, 7, 5, + }), + want: NewDense(4, 4, []float64{ + 0.100548446069470, 0.021937842778793, 0.334552102376599, -0.283363802559415, + -0.226691042047532, -0.067641681901280, -0.281535648994515, 0.457038391224863, + 0.080438756855576, 0.217550274223035, 0.067641681901280, -0.226691042047532, + 0.043875685557587, -0.244972577696527, -0.235831809872029, 0.330895795246801, + }), + tol: 1e-14, + }, + + // Tests with singular matrix. + { + a: NewDense(1, 1, []float64{ + 0, + }), + }, + { + a: NewDense(2, 2, []float64{ + 0, 0, + 0, 0, + }), + }, + { + a: NewDense(2, 2, []float64{ + 0, 0, + 0, 1, + }), + }, + { + a: NewDense(3, 3, []float64{ + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + }), + }, + { + a: NewDense(4, 4, []float64{ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }), + }, + { + a: NewDense(4, 4, []float64{ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 20, 20, + 0, 0, 20, 20, + }), + }, + { + a: NewDense(4, 4, []float64{ + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1, + 0, 0, 0, 0, + }), + }, + { + a: NewDense(4, 4, []float64{ + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + }), + }, + { + a: NewDense(5, 5, []float64{ + 0, 1, 0, 0, 0, + 4, 0, 2, 0, 0, + 0, 3, 0, 3, 0, + 0, 0, 2, 0, 4, + 0, 0, 0, 1, 0, + }), + }, + { + a: NewDense(5, 5, []float64{ + 4, -1, -1, -1, -1, + -1, 4, -1, -1, -1, + -1, -1, 4, -1, -1, + -1, -1, -1, 4, -1, + -1, -1, -1, -1, 4, + }), + }, + { + a: NewDense(5, 5, []float64{ + 2, -1, 0, 0, -1, + -1, 2, -1, 0, 0, + 0, -1, 2, -1, 0, + 0, 0, -1, 2, -1, + -1, 0, 0, -1, 2, + }), + }, + { + a: NewDense(5, 5, []float64{ + 1, 2, 3, 5, 8, + 2, 3, 5, 8, 13, + 3, 5, 8, 13, 21, + 5, 8, 13, 21, 34, + 8, 13, 21, 34, 55, + }), + }, + { + a: NewDense(8, 8, []float64{ + 611, 196, -192, 407, -8, -52, -49, 29, + 196, 899, 113, -192, -71, -43, -8, -44, + -192, 113, 899, 196, 61, 49, 8, 52, + 407, -192, 196, 611, 8, 44, 59, -23, + -8, -71, 61, 8, 411, -599, 208, 208, + -52, -43, 49, 44, -599, 411, 208, 208, + -49, -8, 8, 59, 208, 208, 99, -911, + 29, -44, 52, -23, 208, 208, -911, 99, + }), + }, + } { + var got Dense + err := got.Inverse(test.a) + if test.want == nil { + if err == nil { + t.Errorf("Case %d: expected error for singular matrix", i) + } + continue + } + if err != nil { + t.Errorf("Case %d: unexpected error: %v", i, err) + continue + } + if !equalApprox(&got, test.want, test.tol, false) { + t.Errorf("Case %d, inverse mismatch.", i) + } + var m Dense + m.Mul(&got, test.a) + r, _ := test.a.Dims() + d := make([]float64, r*r) + for i := 0; i < r*r; i += r + 1 { + d[i] = 1 + } + eye := NewDense(r, r, d) + if !equalApprox(eye, &m, 1e-14, false) { + t.Errorf("Case %d, A^-1 * A != I", i) + } + + var tmp Dense + tmp.Clone(test.a) + aU, transposed := untranspose(test.a) + if transposed { + switch aU := aU.(type) { + case *Dense: + err = aU.Inverse(test.a) + case *basicMatrix: + err = (*Dense)(aU).Inverse(test.a) + default: + continue + } + m.Mul(aU, &tmp) + } else { + switch a := test.a.(type) { + case *Dense: + err = a.Inverse(test.a) + m.Mul(a, &tmp) + case *basicMatrix: + err = (*Dense)(a).Inverse(test.a) + m.Mul(a, &tmp) + default: + continue + } + } + if err != nil { + t.Errorf("Error computing inverse: %v", err) + } + if !equalApprox(eye, &m, 1e-14, false) { + t.Errorf("Case %d, A^-1 * A != I", i) + fmt.Println(Formatted(&m)) + } + } +} + +var ( + wd *Dense +) + +func BenchmarkMulDense100Half(b *testing.B) { denseMulBench(b, 100, 0.5) } +func BenchmarkMulDense100Tenth(b *testing.B) { denseMulBench(b, 100, 0.1) } +func BenchmarkMulDense1000Half(b *testing.B) { denseMulBench(b, 1000, 0.5) } +func BenchmarkMulDense1000Tenth(b *testing.B) { denseMulBench(b, 1000, 0.1) } +func BenchmarkMulDense1000Hundredth(b *testing.B) { denseMulBench(b, 1000, 0.01) } +func BenchmarkMulDense1000Thousandth(b *testing.B) { denseMulBench(b, 1000, 0.001) } +func denseMulBench(b *testing.B, size int, rho float64) { + b.StopTimer() + a, _ := randDense(size, rho, rand.NormFloat64) + d, _ := randDense(size, rho, rand.NormFloat64) + b.StartTimer() + for i := 0; i < b.N; i++ { + var n Dense + n.Mul(a, d) + wd = &n + } +} + +func BenchmarkPreMulDense100Half(b *testing.B) { densePreMulBench(b, 100, 0.5) } +func BenchmarkPreMulDense100Tenth(b *testing.B) { densePreMulBench(b, 100, 0.1) } +func BenchmarkPreMulDense1000Half(b *testing.B) { densePreMulBench(b, 1000, 0.5) } +func BenchmarkPreMulDense1000Tenth(b *testing.B) { densePreMulBench(b, 1000, 0.1) } +func BenchmarkPreMulDense1000Hundredth(b *testing.B) { densePreMulBench(b, 1000, 0.01) } +func BenchmarkPreMulDense1000Thousandth(b *testing.B) { densePreMulBench(b, 1000, 0.001) } +func densePreMulBench(b *testing.B, size int, rho float64) { + b.StopTimer() + a, _ := randDense(size, rho, rand.NormFloat64) + d, _ := randDense(size, rho, rand.NormFloat64) + wd = NewDense(size, size, nil) + b.StartTimer() + for i := 0; i < b.N; i++ { + wd.Mul(a, d) + } +} + +func BenchmarkRow10(b *testing.B) { rowBench(b, 10) } +func BenchmarkRow100(b *testing.B) { rowBench(b, 100) } +func BenchmarkRow1000(b *testing.B) { rowBench(b, 1000) } + +func rowBench(b *testing.B, size int) { + a, _ := randDense(size, 1, rand.NormFloat64) + _, c := a.Dims() + dst := make([]float64, c) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + Row(dst, 0, a) + } +} + +func BenchmarkExp10(b *testing.B) { expBench(b, 10) } +func BenchmarkExp100(b *testing.B) { expBench(b, 100) } +func BenchmarkExp1000(b *testing.B) { expBench(b, 1000) } + +func expBench(b *testing.B, size int) { + a, _ := randDense(size, 1, rand.NormFloat64) + + b.ResetTimer() + var m Dense + for i := 0; i < b.N; i++ { + m.Exp(a) + } +} + +func BenchmarkPow10_3(b *testing.B) { powBench(b, 10, 3) } +func BenchmarkPow100_3(b *testing.B) { powBench(b, 100, 3) } +func BenchmarkPow1000_3(b *testing.B) { powBench(b, 1000, 3) } +func BenchmarkPow10_4(b *testing.B) { powBench(b, 10, 4) } +func BenchmarkPow100_4(b *testing.B) { powBench(b, 100, 4) } +func BenchmarkPow1000_4(b *testing.B) { powBench(b, 1000, 4) } +func BenchmarkPow10_5(b *testing.B) { powBench(b, 10, 5) } +func BenchmarkPow100_5(b *testing.B) { powBench(b, 100, 5) } +func BenchmarkPow1000_5(b *testing.B) { powBench(b, 1000, 5) } +func BenchmarkPow10_6(b *testing.B) { powBench(b, 10, 6) } +func BenchmarkPow100_6(b *testing.B) { powBench(b, 100, 6) } +func BenchmarkPow1000_6(b *testing.B) { powBench(b, 1000, 6) } +func BenchmarkPow10_7(b *testing.B) { powBench(b, 10, 7) } +func BenchmarkPow100_7(b *testing.B) { powBench(b, 100, 7) } +func BenchmarkPow1000_7(b *testing.B) { powBench(b, 1000, 7) } +func BenchmarkPow10_8(b *testing.B) { powBench(b, 10, 8) } +func BenchmarkPow100_8(b *testing.B) { powBench(b, 100, 8) } +func BenchmarkPow1000_8(b *testing.B) { powBench(b, 1000, 8) } +func BenchmarkPow10_9(b *testing.B) { powBench(b, 10, 9) } +func BenchmarkPow100_9(b *testing.B) { powBench(b, 100, 9) } +func BenchmarkPow1000_9(b *testing.B) { powBench(b, 1000, 9) } + +func powBench(b *testing.B, size, n int) { + a, _ := randDense(size, 1, rand.NormFloat64) + + b.ResetTimer() + var m Dense + for i := 0; i < b.N; i++ { + m.Pow(a, n) + } +} + +func BenchmarkMulTransDense100Half(b *testing.B) { denseMulTransBench(b, 100, 0.5) } +func BenchmarkMulTransDense100Tenth(b *testing.B) { denseMulTransBench(b, 100, 0.1) } +func BenchmarkMulTransDense1000Half(b *testing.B) { denseMulTransBench(b, 1000, 0.5) } +func BenchmarkMulTransDense1000Tenth(b *testing.B) { denseMulTransBench(b, 1000, 0.1) } +func BenchmarkMulTransDense1000Hundredth(b *testing.B) { denseMulTransBench(b, 1000, 0.01) } +func BenchmarkMulTransDense1000Thousandth(b *testing.B) { denseMulTransBench(b, 1000, 0.001) } +func denseMulTransBench(b *testing.B, size int, rho float64) { + b.StopTimer() + a, _ := randDense(size, rho, rand.NormFloat64) + d, _ := randDense(size, rho, rand.NormFloat64) + b.StartTimer() + for i := 0; i < b.N; i++ { + var n Dense + n.Mul(a, d.T()) + wd = &n + } +} + +func BenchmarkMulTransDenseSym100Half(b *testing.B) { denseMulTransSymBench(b, 100, 0.5) } +func BenchmarkMulTransDenseSym100Tenth(b *testing.B) { denseMulTransSymBench(b, 100, 0.1) } +func BenchmarkMulTransDenseSym1000Half(b *testing.B) { denseMulTransSymBench(b, 1000, 0.5) } +func BenchmarkMulTransDenseSym1000Tenth(b *testing.B) { denseMulTransSymBench(b, 1000, 0.1) } +func BenchmarkMulTransDenseSym1000Hundredth(b *testing.B) { denseMulTransSymBench(b, 1000, 0.01) } +func BenchmarkMulTransDenseSym1000Thousandth(b *testing.B) { denseMulTransSymBench(b, 1000, 0.001) } +func denseMulTransSymBench(b *testing.B, size int, rho float64) { + b.StopTimer() + a, _ := randDense(size, rho, rand.NormFloat64) + b.StartTimer() + for i := 0; i < b.N; i++ { + var n Dense + n.Mul(a, a.T()) + wd = &n + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/doc.go b/vendor/gonum.org/v1/gonum/mat/doc.go new file mode 100644 index 00000000..eecb742c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/doc.go @@ -0,0 +1,173 @@ +// 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 mat provides implementations of float64 and complex128 matrix +// structures and linear algebra operations on them. +// +// Overview +// +// This section provides a quick overview of the mat package. The following +// sections provide more in depth commentary. +// +// mat provides: +// - Interfaces for Matrix classes (Matrix, Symmetric, Triangular) +// - Concrete implementations (Dense, SymDense, TriDense) +// - Methods and functions for using matrix data (Add, Trace, SymRankOne) +// - Types for constructing and using matrix factorizations (QR, LU) +// - The complementary types for complex matrices, CMatrix, CSymDense, etc. +// +// A matrix may be constructed through the corresponding New function. If no +// backing array is provided the matrix will be initialized to all zeros. +// // Allocate a zeroed real matrix of size 3×5 +// zero := mat.NewDense(3, 5, nil) +// If a backing data slice is provided, the matrix will have those elements. +// Matrices are all stored in row-major format. +// // Generate a 6×6 matrix of random values. +// data := make([]float64, 36) +// for i := range data { +// data[i] = rand.NormFloat64() +// } +// a := mat.NewDense(6, 6, data) +// Operations involving matrix data are implemented as functions when the values +// of the matrix remain unchanged +// tr := mat.Trace(a) +// and are implemented as methods when the operation modifies the receiver. +// zero.Copy(a) +// +// Receivers must be the correct size for the matrix operations, otherwise the +// operation will panic. As a special case for convenience, a zero-value matrix +// will be modified to have the correct size, allocating data if necessary. +// var c mat.Dense // construct a new zero-sized matrix +// c.Mul(a, a) // c is automatically adjusted to be 6×6 +// +// Zero-value of a matrix +// +// A zero-value matrix is either the Go language definition of a zero-value or +// is a zero-sized matrix with zero-length stride. Matrix implementations may have +// a Reset method to revert the receiver into a zero-valued matrix and an IsZero +// method that returns whether the matrix is zero-valued. +// So the following will all result in a zero-value matrix. +// - var a mat.Dense +// - a := NewDense(0, 0, make([]float64, 0, 100)) +// - a.Reset() +// A zero-value matrix can not be sliced even if it does have an adequately sized +// backing data slice, but can be expanded using its Grow method if it exists. +// +// The Matrix Interfaces +// +// The Matrix interface is the common link between the concrete types of real +// matrices, The Matrix interface is defined by three functions: Dims, which +// returns the dimensions of the Matrix, At, which returns the element in the +// specified location, and T for returning a Transpose (discussed later). All of +// the concrete types can perform these behaviors and so implement the interface. +// Methods and functions are designed to use this interface, so in particular the method +// func (m *Dense) Mul(a, b Matrix) +// constructs a *Dense from the result of a multiplication with any Matrix types, +// not just *Dense. Where more restrictive requirements must be met, there are also the +// Symmetric and Triangular interfaces. For example, in +// func (s *SymDense) AddSym(a, b Symmetric) +// the Symmetric interface guarantees a symmetric result. +// +// The CMatrix interface plays the same role for complex matrices. The difference +// is that the CMatrix type has the H method instead T, for returning the conjugate +// transpose. +// +// (Conjugate) Transposes +// +// The T method is used for transposition on real matrices, and H is used for +// conjugate transposition on complex matrices. For example, c.Mul(a.T(), b) computes +// c = a^T * b. The mat types implement this method implicitly — +// see the Transpose and Conjugate types for more details. Note that some +// operations have a transpose as part of their definition, as in *SymDense.SymOuterK. +// +// Matrix Factorization +// +// Matrix factorizations, such as the LU decomposition, typically have their own +// specific data storage, and so are each implemented as a specific type. The +// factorization can be computed through a call to Factorize +// var lu mat.LU +// lu.Factorize(a) +// The elements of the factorization can be extracted through methods on the +// factorized type, i.e. *LU.UTo. The factorization types can also be used directly, +// as in *Dense.SolveCholesky. Some factorizations can be updated directly, +// without needing to update the original matrix and refactorize, +// as in *LU.RankOne. +// +// BLAS and LAPACK +// +// BLAS and LAPACK are the standard APIs for linear algebra routines. Many +// operations in mat are implemented using calls to the wrapper functions +// in gonum/blas/blas64 and gonum/lapack/lapack64 and their complex equivalents. +// By default, blas64 and lapack64 call the native Go implementations of the +// routines. Alternatively, it is possible to use C-based implementations of the +// APIs through the respective cgo packages and "Use" functions. The Go +// implementation of LAPACK (used by default) makes calls +// through blas64, so if a cgo BLAS implementation is registered, the lapack64 +// calls will be partially executed in Go and partially executed in C. +// +// Type Switching +// +// The Matrix abstraction enables efficiency as well as interoperability. Go's +// type reflection capabilities are used to choose the most efficient routine +// given the specific concrete types. For example, in +// c.Mul(a, b) +// if a and b both implement RawMatrixer, that is, they can be represented as a +// blas64.General, blas64.Gemm (general matrix multiplication) is called, while +// instead if b is a RawSymmetricer blas64.Symm is used (general-symmetric +// multiplication), and if b is a *VecDense blas64.Gemv is used. +// +// There are many possible type combinations and special cases. No specific guarantees +// are made about the performance of any method, and in particular, note that an +// abstract matrix type may be copied into a concrete type of the corresponding +// value. If there are specific special cases that are needed, please submit a +// pull-request or file an issue. +// +// Invariants +// +// Matrix input arguments to functions are never directly modified. If an operation +// changes Matrix data, the mutated matrix will be the receiver of a function. +// +// For convenience, a matrix may be used as both a receiver and as an input, e.g. +// a.Pow(a, 6) +// v.SolveVec(a.T(), v) +// though in many cases this will cause an allocation (see Element Aliasing). +// An exception to this rule is Copy, which does not allow a.Copy(a.T()). +// +// Element Aliasing +// +// Most methods in mat modify receiver data. It is forbidden for the modified +// data region of the receiver to overlap the used data area of the input +// arguments. The exception to this rule is when the method receiver is equal to one +// of the input arguments, as in the a.Pow(a, 6) call above, or its implicit transpose. +// +// This prohibition is to help avoid subtle mistakes when the method needs to read +// from and write to the same data region. There are ways to make mistakes using the +// mat API, and mat functions will detect and complain about those. +// There are many ways to make mistakes by excursion from the mat API via +// interaction with raw matrix values. +// +// If you need to read the rest of this section to understand the behavior of +// your program, you are being clever. Don't be clever. If you must be clever, +// blas64 and lapack64 may be used to call the behavior directly. +// +// mat will use the following rules to detect overlap between the receiver and one +// of the inputs: +// - the input implements one of the Raw methods, and +// - the Raw type matches that of the receiver or +// one is a RawMatrixer and the other is a RawVectorer, and +// - the address ranges of the backing data slices overlap, and +// - the strides differ or there is an overlap in the used data elements. +// If such an overlap is detected, the method will panic. +// +// The following cases will not panic: +// - the data slices do not overlap, +// - there is pointer identity between the receiver and input values after +// the value has been untransposed if necessary. +// +// mat will not attempt to detect element overlap if the input does not implement a +// Raw method, or if the Raw method differs from that of the receiver except when a +// conversion has occurred through a mat API function. Method behavior is undefined +// if there is undetected overlap. +// +package mat // import "gonum.org/v1/gonum/mat" diff --git a/vendor/gonum.org/v1/gonum/mat/eigen.go b/vendor/gonum.org/v1/gonum/mat/eigen.go new file mode 100644 index 00000000..0c677a8a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/eigen.go @@ -0,0 +1,260 @@ +// 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. + +package mat + +import ( + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/lapack64" +) + +const ( + badFact = "mat: use without successful factorization" + badNoVect = "mat: eigenvectors not computed" +) + +// EigenSym is a type for creating and manipulating the Eigen decomposition of +// symmetric matrices. +type EigenSym struct { + vectorsComputed bool + + values []float64 + vectors *Dense +} + +// Factorize computes the eigenvalue decomposition of the symmetric matrix a. +// The Eigen decomposition is defined as +// A = P * D * P^-1 +// where D is a diagonal matrix containing the eigenvalues of the matrix, and +// P is a matrix of the eigenvectors of A. If the vectors input argument is +// false, the eigenvectors are not computed. +// +// Factorize returns whether the decomposition succeeded. If the decomposition +// failed, methods that require a successful factorization will panic. +func (e *EigenSym) Factorize(a Symmetric, vectors bool) (ok bool) { + n := a.Symmetric() + sd := NewSymDense(n, nil) + sd.CopySym(a) + + jobz := lapack.EVJob(lapack.None) + if vectors { + jobz = lapack.ComputeEV + } + w := make([]float64, n) + work := []float64{0} + lapack64.Syev(jobz, sd.mat, w, work, -1) + + work = getFloats(int(work[0]), false) + ok = lapack64.Syev(jobz, sd.mat, w, work, len(work)) + putFloats(work) + if !ok { + e.vectorsComputed = false + e.values = nil + e.vectors = nil + return false + } + e.vectorsComputed = vectors + e.values = w + e.vectors = NewDense(n, n, sd.mat.Data) + return true +} + +// succFact returns whether the receiver contains a successful factorization. +func (e *EigenSym) succFact() bool { + return len(e.values) != 0 +} + +// Values extracts the eigenvalues of the factorized matrix. If dst is +// non-nil, the values are stored in-place into dst. In this case +// dst must have length n, otherwise Values will panic. If dst is +// nil, then a new slice will be allocated of the proper length and filled +// with the eigenvalues. +// +// Values panics if the Eigen decomposition was not successful. +func (e *EigenSym) Values(dst []float64) []float64 { + if !e.succFact() { + panic(badFact) + } + if dst == nil { + dst = make([]float64, len(e.values)) + } + if len(dst) != len(e.values) { + panic(ErrSliceLengthMismatch) + } + copy(dst, e.values) + return dst +} + +// EigenvectorsSym extracts the eigenvectors of the factorized matrix and stores +// them in the receiver. Each eigenvector is a column corresponding to the +// respective eigenvalue returned by e.Values. +// +// EigenvectorsSym panics if the factorization was not successful or if the +// decomposition did not compute the eigenvectors. +func (m *Dense) EigenvectorsSym(e *EigenSym) { + if !e.succFact() { + panic(badFact) + } + if !e.vectorsComputed { + panic(badNoVect) + } + m.reuseAs(len(e.values), len(e.values)) + m.Copy(e.vectors) +} + +// Eigen is a type for creating and using the eigenvalue decomposition of a dense matrix. +type Eigen struct { + n int // The size of the factorized matrix. + + right bool // have the right eigenvectors been computed + left bool // have the left eigenvectors been computed + + values []complex128 + rVectors *Dense + lVectors *Dense +} + +// succFact returns whether the receiver contains a successful factorization. +func (e *Eigen) succFact() bool { + return len(e.values) != 0 +} + +// Factorize computes the eigenvalues of the square matrix a, and optionally +// the eigenvectors. +// +// A right eigenvalue/eigenvector combination is defined by +// A * x_r = λ * x_r +// where x_r is the column vector called an eigenvector, and λ is the corresponding +// eigenvector. +// +// Similarly, a left eigenvalue/eigenvector combination is defined by +// x_l * A = λ * x_l +// The eigenvalues, but not the eigenvectors, are the same for both decompositions. +// +// Typically eigenvectors refer to right eigenvectors. +// +// In all cases, Eigen computes the eigenvalues of the matrix. If right and left +// are true, then the right and left eigenvectors will be computed, respectively. +// Eigen panics if the input matrix is not square. +// +// Factorize returns whether the decomposition succeeded. If the decomposition +// failed, methods that require a successful factorization will panic. +func (e *Eigen) Factorize(a Matrix, left, right bool) (ok bool) { + // TODO(btracey): Change implementation to store VecDenses as a *CMat when + // #308 is resolved. + + // Copy a because it is modified during the Lapack call. + r, c := a.Dims() + if r != c { + panic(ErrShape) + } + var sd Dense + sd.Clone(a) + + var vl, vr Dense + var jobvl lapack.LeftEVJob = lapack.None + var jobvr lapack.RightEVJob = lapack.None + if left { + vl = *NewDense(r, r, nil) + jobvl = lapack.ComputeLeftEV + } + if right { + vr = *NewDense(c, c, nil) + jobvr = lapack.ComputeRightEV + } + + wr := getFloats(c, false) + defer putFloats(wr) + wi := getFloats(c, false) + defer putFloats(wi) + + work := []float64{0} + lapack64.Geev(jobvl, jobvr, sd.mat, wr, wi, vl.mat, vr.mat, work, -1) + work = getFloats(int(work[0]), false) + first := lapack64.Geev(jobvl, jobvr, sd.mat, wr, wi, vl.mat, vr.mat, work, len(work)) + putFloats(work) + + if first != 0 { + e.values = nil + return false + } + e.n = r + e.right = right + e.left = left + e.lVectors = &vl + e.rVectors = &vr + values := make([]complex128, r) + for i, v := range wr { + values[i] = complex(v, wi[i]) + } + e.values = values + return true +} + +// Values extracts the eigenvalues of the factorized matrix. If dst is +// non-nil, the values are stored in-place into dst. In this case +// dst must have length n, otherwise Values will panic. If dst is +// nil, then a new slice will be allocated of the proper length and +// filed with the eigenvalues. +// +// Values panics if the Eigen decomposition was not successful. +func (e *Eigen) Values(dst []complex128) []complex128 { + if !e.succFact() { + panic(badFact) + } + if dst == nil { + dst = make([]complex128, e.n) + } + if len(dst) != e.n { + panic(ErrSliceLengthMismatch) + } + copy(dst, e.values) + return dst +} + +// Vectors returns the right eigenvectors of the decomposition. Vectors +// will panic if the right eigenvectors were not computed during the factorization, +// or if the factorization was not successful. +// +// The returned matrix will contain the right eigenvectors of the decomposition +// in the columns of the n×n matrix in the same order as their eigenvalues. +// If the j-th eigenvalue is real, then +// u_j = VL[:,j], +// v_j = VR[:,j], +// and if it is not real, then j and j+1 form a complex conjugate pair and the +// eigenvectors can be recovered as +// u_j = VL[:,j] + i*VL[:,j+1], +// u_{j+1} = VL[:,j] - i*VL[:,j+1], +// v_j = VR[:,j] + i*VR[:,j+1], +// v_{j+1} = VR[:,j] - i*VR[:,j+1], +// where i is the imaginary unit. The computed eigenvectors are normalized to +// have Euclidean norm equal to 1 and largest component real. +// +// BUG: This signature and behavior will change when issue #308 is resolved. +func (e *Eigen) Vectors() *Dense { + if !e.succFact() { + panic(badFact) + } + if !e.right { + panic(badNoVect) + } + return DenseCopyOf(e.rVectors) +} + +// LeftVectors returns the left eigenvectors of the decomposition. LeftVectors +// will panic if the left eigenvectors were not computed during the factorization. +// or if the factorization was not successful. +// +// See the documentation in lapack64.Geev for the format of the vectors. +// +// BUG: This signature and behavior will change when issue #308 is resolved. +func (e *Eigen) LeftVectors() *Dense { + if !e.succFact() { + panic(badFact) + } + if !e.left { + panic(badNoVect) + } + return DenseCopyOf(e.lVectors) +} diff --git a/vendor/gonum.org/v1/gonum/mat/eigen_test.go b/vendor/gonum.org/v1/gonum/mat/eigen_test.go new file mode 100644 index 00000000..1980fbe4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/eigen_test.go @@ -0,0 +1,164 @@ +// 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. + +package mat + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestEigen(t *testing.T) { + for i, test := range []struct { + a *Dense + + values []complex128 + left *Dense + right *Dense + }{ + { + a: NewDense(3, 3, []float64{ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, + }), + values: []complex128{1, 1, 1}, + left: NewDense(3, 3, []float64{ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, + }), + right: NewDense(3, 3, []float64{ + 1, 0, 0, + 0, 1, 0, + 0, 0, 1, + }), + }, + } { + var e1, e2, e3, e4 Eigen + ok := e1.Factorize(test.a, true, true) + if !ok { + panic("bad factorization") + } + e2.Factorize(test.a, false, true) + e3.Factorize(test.a, true, false) + e4.Factorize(test.a, false, false) + + v1 := e1.Values(nil) + if !cmplxEqual(v1, test.values) { + t.Errorf("eigenvector mismatch. Case %v", i) + } + if !Equal(e1.LeftVectors(), test.left) { + t.Errorf("left eigenvector mismatch. Case %v", i) + } + if !Equal(e1.Vectors(), test.right) { + t.Errorf("right eigenvector mismatch. Case %v", i) + } + + // Check that the eigenvectors and values are the same in all combinations. + if !cmplxEqual(v1, e2.Values(nil)) { + t.Errorf("eigenvector mismatch. Case %v", i) + } + if !cmplxEqual(v1, e3.Values(nil)) { + t.Errorf("eigenvector mismatch. Case %v", i) + } + if !cmplxEqual(v1, e4.Values(nil)) { + t.Errorf("eigenvector mismatch. Case %v", i) + } + if !Equal(e1.Vectors(), e2.Vectors()) { + t.Errorf("right eigenvector mismatch. Case %v", i) + } + if !Equal(e1.LeftVectors(), e3.LeftVectors()) { + t.Errorf("right eigenvector mismatch. Case %v", i) + } + + // TODO(btracey): Also add in a test for correctness when #308 is + // resolved and we have a CMat.Mul(). + } +} + +func cmplxEqual(v1, v2 []complex128) bool { + for i, v := range v1 { + if v != v2[i] { + return false + } + } + return true +} + +func TestSymEigen(t *testing.T) { + // Hand coded tests with results from lapack. + for _, test := range []struct { + mat *SymDense + + values []float64 + vectors *Dense + }{ + { + mat: NewSymDense(3, []float64{8, 2, 4, 2, 6, 10, 4, 10, 5}), + values: []float64{-4.707679201365891, 6.294580208480216, 17.413098992885672}, + vectors: NewDense(3, 3, []float64{ + -0.127343483135656, -0.902414161226903, -0.411621572466779, + -0.664177720955769, 0.385801900032553, -0.640331827193739, + 0.736648893495999, 0.191847792659746, -0.648492738712395, + }), + }, + } { + var es EigenSym + ok := es.Factorize(test.mat, true) + if !ok { + t.Errorf("bad factorization") + } + if !floats.EqualApprox(test.values, es.values, 1e-14) { + t.Errorf("Eigenvalue mismatch") + } + if !EqualApprox(test.vectors, es.vectors, 1e-14) { + t.Errorf("Eigenvector mismatch") + } + + var es2 EigenSym + es2.Factorize(test.mat, false) + if !floats.EqualApprox(es2.values, es.values, 1e-14) { + t.Errorf("Eigenvalue mismatch when no vectors computed") + } + } + + // Randomized tests + rnd := rand.New(rand.NewSource(1)) + for _, n := range []int{3, 5, 10, 70} { + for cas := 0; cas < 10; cas++ { + a := make([]float64, n*n) + for i := range a { + a[i] = rnd.NormFloat64() + } + s := NewSymDense(n, a) + var es EigenSym + ok := es.Factorize(s, true) + if !ok { + t.Errorf("Bad test") + } + + // Check that the eigenvectors are orthonormal. + if !isOrthonormal(es.vectors, 1e-8) { + t.Errorf("Eigenvectors not orthonormal") + } + + // Check that the eigenvalues are actually eigenvalues. + for i := 0; i < n; i++ { + v := NewVecDense(n, Col(nil, i, es.vectors)) + var m VecDense + m.MulVec(s, v) + + var scal VecDense + scal.ScaleVec(es.values[i], v) + + if !EqualApprox(&m, &scal, 1e-8) { + t.Errorf("Eigenvalue does not match") + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/errors.go b/vendor/gonum.org/v1/gonum/mat/errors.go new file mode 100644 index 00000000..38bd7d5a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/errors.go @@ -0,0 +1,148 @@ +// 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. + +package mat + +import ( + "fmt" + "runtime" + + "gonum.org/v1/gonum/lapack" +) + +// Condition is the condition number of a matrix. The condition +// number is defined as |A| * |A^-1|. +// +// One important use of Condition is during linear solve routines (finding x such +// that A * x = b). The condition number of A indicates the accuracy of +// the computed solution. A Condition error will be returned if the condition +// number of A is sufficiently large. If A is exactly singular to working precision, +// Condition == ∞, and the solve algorithm may have completed early. If Condition +// is large and finite the solve algorithm will be performed, but the computed +// solution may be innacurate. Due to the nature of finite precision arithmetic, +// the value of Condition is only an approximate test of singularity. +type Condition float64 + +func (c Condition) Error() string { + return fmt.Sprintf("matrix singular or near-singular with condition number %.4e", c) +} + +// ConditionTolerance is the tolerance limit of the condition number. If the +// condition number is above this value, the matrix is considered singular. +const ConditionTolerance = 1e16 + +const ( + // CondNorm is the matrix norm used for computing the condition number by routines + // in the matrix packages. + CondNorm = lapack.MaxRowSum + + // CondNormTrans is the norm used to compute on A^T to get the same result as + // computing CondNorm on A. + CondNormTrans = lapack.MaxColumnSum +) + +const stackTraceBufferSize = 1 << 20 + +// Maybe will recover a panic with a type mat.Error from fn, and return this error +// as the Err field of an ErrorStack. The stack trace for the panicking function will be +// recovered and placed in the StackTrace field. Any other error is re-panicked. +func Maybe(fn func()) (err error) { + defer func() { + if r := recover(); r != nil { + if e, ok := r.(Error); ok { + if e.string == "" { + panic("mat: invalid error") + } + buf := make([]byte, stackTraceBufferSize) + n := runtime.Stack(buf, false) + err = ErrorStack{Err: e, StackTrace: string(buf[:n])} + return + } + panic(r) + } + }() + fn() + return +} + +// MaybeFloat will recover a panic with a type mat.Error from fn, and return this error +// as the Err field of an ErrorStack. The stack trace for the panicking function will be +// recovered and placed in the StackTrace field. Any other error is re-panicked. +func MaybeFloat(fn func() float64) (f float64, err error) { + defer func() { + if r := recover(); r != nil { + if e, ok := r.(Error); ok { + if e.string == "" { + panic("mat: invalid error") + } + buf := make([]byte, stackTraceBufferSize) + n := runtime.Stack(buf, false) + err = ErrorStack{Err: e, StackTrace: string(buf[:n])} + return + } + panic(r) + } + }() + return fn(), nil +} + +// MaybeComplex will recover a panic with a type mat.Error from fn, and return this error +// as the Err field of an ErrorStack. The stack trace for the panicking function will be +// recovered and placed in the StackTrace field. Any other error is re-panicked. +func MaybeComplex(fn func() complex128) (f complex128, err error) { + defer func() { + if r := recover(); r != nil { + if e, ok := r.(Error); ok { + if e.string == "" { + panic("mat: invalid error") + } + buf := make([]byte, stackTraceBufferSize) + n := runtime.Stack(buf, false) + err = ErrorStack{Err: e, StackTrace: string(buf[:n])} + return + } + panic(r) + } + }() + return fn(), nil +} + +// Error represents matrix handling errors. These errors can be recovered by Maybe wrappers. +type Error struct{ string } + +func (err Error) Error() string { return err.string } + +var ( + ErrIndexOutOfRange = Error{"matrix: index out of range"} + ErrRowAccess = Error{"matrix: row index out of range"} + ErrColAccess = Error{"matrix: column index out of range"} + ErrVectorAccess = Error{"matrix: vector index out of range"} + ErrZeroLength = Error{"matrix: zero length in matrix definition"} + ErrRowLength = Error{"matrix: row length mismatch"} + ErrColLength = Error{"matrix: col length mismatch"} + ErrSquare = Error{"matrix: expect square matrix"} + ErrNormOrder = Error{"matrix: invalid norm order for matrix"} + ErrSingular = Error{"matrix: matrix is singular"} + ErrShape = Error{"matrix: dimension mismatch"} + ErrIllegalStride = Error{"matrix: illegal stride"} + ErrPivot = Error{"matrix: malformed pivot list"} + ErrTriangle = Error{"matrix: triangular storage mismatch"} + ErrTriangleSet = Error{"matrix: triangular set out of bounds"} + ErrBandSet = Error{"matrix: band set out of bounds"} + ErrSliceLengthMismatch = Error{"matrix: input slice length mismatch"} + ErrNotPSD = Error{"matrix: input not positive symmetric definite"} + ErrFailedEigen = Error{"matrix: eigendecomposition not successful"} +) + +// ErrorStack represents matrix handling errors that have been recovered by Maybe wrappers. +type ErrorStack struct { + Err error + + // StackTrace is the stack trace + // recovered by Maybe, MaybeFloat + // or MaybeComplex. + StackTrace string +} + +func (err ErrorStack) Error() string { return err.Err.Error() } diff --git a/vendor/gonum.org/v1/gonum/mat/errors_test.go b/vendor/gonum.org/v1/gonum/mat/errors_test.go new file mode 100644 index 00000000..7a1a7dd7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/errors_test.go @@ -0,0 +1,56 @@ +// 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. + +package mat + +import "testing" + +func leaksPanic(fn func()) (panicked bool) { + defer func() { + r := recover() + panicked = r != nil + }() + Maybe(fn) + return +} + +func TestMaybe(t *testing.T) { + for i, test := range []struct { + fn func() + panics bool + errors bool + }{ + { + fn: func() {}, + panics: false, + errors: false, + }, + { + fn: func() { panic("panic") }, + panics: true, + errors: false, + }, + { + fn: func() { panic(Error{"panic"}) }, + panics: false, + errors: true, + }, + } { + panicked := leaksPanic(test.fn) + if panicked != test.panics { + t.Errorf("unexpected panic state for test %d: got: panicked=%t want: panicked=%t", + i, panicked, test.panics) + } + if test.errors { + err := Maybe(test.fn) + stack, ok := err.(ErrorStack) + if !ok { + t.Errorf("unexpected error type: got:%T want:%T", stack, ErrorStack{}) + } + if stack.StackTrace == "" { + t.Error("expected non-empty stack trace") + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/fao_data_test.go b/vendor/gonum.org/v1/gonum/mat/fao_data_test.go new file mode 100644 index 00000000..e32e1676 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/fao_data_test.go @@ -0,0 +1,122 @@ +// 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 mat_test + +import "gonum.org/v1/gonum/mat" + +// FAO is a dataset extracted from Food and Agriculture Organization of the +// United Nations "FAO Statistical Pocketbook: World Food and Agriculture 2015". +// pp49-52. +var FAO = struct { + Africa *mat.Dense + Asia *mat.Dense + LatinAmericaCaribbean *mat.Dense + Oceania *mat.Dense +}{ + Africa: mat.NewDense(21, 3, []float64{ + // 1990, 2000, 2014 + 35.3, 38, 30.7, // Employment in agriculture (%) + 9.2, 20.3, 25.2, // Employment in agriculture, female (%) + 3163, 14718, 20667, // Energy consump, power irrigation (mln kWh) + + 2597, 2717, 2903, // Dietary energy supply (kcal/pc/day) + 113, 116, 123, // Average dietary energy supply adequacy (%) + 58, 55, 52, // Dietary en supp, cereals/roots/tubers (%) + 18.6, 15, 10.8, // Prevalence of undernourishment (%) + 8832, 10241, 13915, // GDP per capita (US$, PPP) + -0.4, -0.2, 50.7, // Cereal import dependency ratio (%) + 78.5, 83, 88.7, // Improved water source (% pop) + + // Production indices (2004-06=100) + 73, 90, 121, // Net food + 72, 89, 123, // Net crops + 82, 92, 123, // Cereals + 51, 77, 141, // Vegetable oils + 74, 94, 119, // Roots and tubers + 58, 86, 127, // Fruit and vegetables + 86, 93, 132, // Sugar + 76, 92, 115, // Livestock + 83, 89, 114, // Milk + 74, 91, 118, // Meat + 72, 92, 119, // Fish + }), + + Asia: mat.NewDense(21, 3, []float64{ + // 1990, 2000, 2014 + 30.9, 24.5, 27.6, // Employment in agriculture (%) + 40.9, 29.4, 31.1, // Employment in agriculture, female (%) + 7614, 38316, 82411, // Energy consump, power irrigation (mln kWh) + + 2320, 2402, 2581, // Dietary energy supply (kcal/pc/day) + 107, 110, 117, // Average dietary energy supply adequacy (%) + 66, 65, 63, // Dietary en supp, cereals/roots/tubers (%) + 27.6, 25.7, 19.8, // Prevalence of undernourishment (%) + 3315, 3421, 4575, // GDP per capita (US$, PPP) + 25.9, 28.1, 42, // Cereal import dependency ratio (%) + 55.5, 61.1, 68.7, // Improved water source (% pop) + + // Production indices (2004-06=100) + 60, 82, 129, // Net food + 59, 82, 127, // Net crops + 66, 79, 131, // Cereals + 58, 79, 128, // Vegetable oils + 50, 80, 133, // Roots and tubers + 58, 82, 124, // Fruit and vegetables + 76, 94, 114, // Sugar + 65, 84, 126, // Livestock + 59, 77, 125, // Milk + 67, 87, 127, // Meat + 65, 90, 119, // Fish + }), + + LatinAmericaCaribbean: mat.NewDense(14, 3, []float64{ + // 1990, 2000, 2014 + 19.5, 14.2, 15.8, // Employment in agriculture (%) + 13.7, 6.2, 7.6, // Employment in agriculture, female (%) + + 2669, 2787, 3069, // Dietary energy supply (kcal/pc/day) + 117, 120, 129, // Average dietary energy supply adequacy (%) + 42, 41, 40, // Dietary en supp, cereals/roots/tubers (%) + 14.7, 12.1, 5.5, // Prevalence of undernourishment (%) + 9837, 10976, 13915, // GDP per capita (US$, PPP) + 13, 12, 49.7, // Cereal import dependency ratio (%) + 85.1, 89.8, 94, // Improved water source (% pop) + + // Production indices (2004-06=100) + 60, 83, 129, // Net food + 64, 83, 131, // Net crops + 62, 88, 139, // Cereals + 58, 84, 123, // Livestock + 82, 107, 71, // Fish + }), + + Oceania: mat.NewDense(21, 3, []float64{ + // 1990, 2000, 2014 + 6.2, 17.1, 3.8, // Employment in agriculture (%) + 4.5, 3.9, 4.4, // Employment in agriculture, female (%) + 415, 1028, 8667, // Energy consump, power irrigation (mln kWh) + + 2454, 2436, 2542, // Dietary energy supply (kcal/pc/day) + 113, 112, 114, // Average dietary energy supply adequacy (%) + 49, 50, 48, // Dietary en supp, cereals/roots/tubers (%) + 15.7, 16.1, 14.2, // Prevalence of undernourishment (%) + 2269, 2536, 3110, // GDP per capita (US$, PPP) + 95.2, 95.9, 95.4, // Cereal import dependency ratio (%) + 49.7, 53.2, 55.5, // Improved water source (% pop) + + // Production indices (2004-06=100) + 72, 99, 116, // Net food + 69, 105, 126, // Net crops + 77, 113, 117, // Cereals + 41, 122, 215, // Vegetable oils + 80, 90, 110, // Roots and tubers + 66, 88, 104, // Fruit and vegetables + 70, 104, 71, // Sugar + 79, 97, 107, // Livestock + 56, 92, 113, // Milk + 79, 96, 105, // Meat + 51, 78, 85, // Fish + }), +} diff --git a/vendor/gonum.org/v1/gonum/mat/format.go b/vendor/gonum.org/v1/gonum/mat/format.go new file mode 100644 index 00000000..8ab70ed3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/format.go @@ -0,0 +1,238 @@ +// 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. + +package mat + +import ( + "fmt" + "strconv" +) + +// Formatted returns a fmt.Formatter for the matrix m using the given options. +func Formatted(m Matrix, options ...FormatOption) fmt.Formatter { + f := formatter{ + matrix: m, + dot: '.', + } + for _, o := range options { + o(&f) + } + return f +} + +type formatter struct { + matrix Matrix + prefix string + margin int + dot byte + squeeze bool +} + +// FormatOption is a functional option for matrix formatting. +type FormatOption func(*formatter) + +// Prefix sets the formatted prefix to the string p. Prefix is a string that is prepended to +// each line of output. +func Prefix(p string) FormatOption { + return func(f *formatter) { f.prefix = p } +} + +// Excerpt sets the maximum number of rows and columns to print at the margins of the matrix +// to m. If m is zero or less all elements are printed. +func Excerpt(m int) FormatOption { + return func(f *formatter) { f.margin = m } +} + +// DotByte sets the dot character to b. The dot character is used to replace zero elements +// if the result is printed with the fmt ' ' verb flag. Without a DotByte option, the default +// dot character is '.'. +func DotByte(b byte) FormatOption { + return func(f *formatter) { f.dot = b } +} + +// Squeeze sets the printing behaviour to minimise column width for each individual column. +func Squeeze() FormatOption { + return func(f *formatter) { f.squeeze = true } +} + +// Format satisfies the fmt.Formatter interface. +func (f formatter) Format(fs fmt.State, c rune) { + if c == 'v' && fs.Flag('#') { + fmt.Fprintf(fs, "%#v", f.matrix) + return + } + format(f.matrix, f.prefix, f.margin, f.dot, f.squeeze, fs, c) +} + +// format prints a pretty representation of m to the fs io.Writer. The format character c +// specifies the numerical representation of of elements; valid values are those for float64 +// specified in the fmt package, with their associated flags. In addition to this, a space +// preceding a verb indicates that zero values should be represented by the dot character. +// The printed range of the matrix can be limited by specifying a positive value for margin; +// If margin is greater than zero, only the first and last margin rows/columns of the matrix +// are output. If squeeze is true, column widths are determined on a per-column basis. +// +// format will not provide Go syntax output. +func format(m Matrix, prefix string, margin int, dot byte, squeeze bool, fs fmt.State, c rune) { + rows, cols := m.Dims() + + var printed int + if margin <= 0 { + printed = rows + if cols > printed { + printed = cols + } + } else { + printed = margin + } + + prec, pOk := fs.Precision() + if !pOk { + prec = -1 + } + + var ( + maxWidth int + widths widther + buf, pad []byte + ) + if squeeze { + widths = make(columnWidth, cols) + } else { + widths = new(uniformWidth) + } + switch c { + case 'v', 'e', 'E', 'f', 'F', 'g', 'G': + if c == 'v' { + buf, maxWidth = maxCellWidth(m, 'g', printed, prec, widths) + } else { + buf, maxWidth = maxCellWidth(m, c, printed, prec, widths) + } + default: + fmt.Fprintf(fs, "%%!%c(%T=Dims(%d, %d))", c, m, rows, cols) + return + } + width, _ := fs.Width() + width = max(width, maxWidth) + pad = make([]byte, max(width, 2)) + for i := range pad { + pad[i] = ' ' + } + + first := true + if rows > 2*printed || cols > 2*printed { + first = false + fmt.Fprintf(fs, "Dims(%d, %d)\n", rows, cols) + } + + skipZero := fs.Flag(' ') + for i := 0; i < rows; i++ { + if !first { + fmt.Fprint(fs, prefix) + } + first = false + var el string + switch { + case rows == 1: + fmt.Fprint(fs, "[") + el = "]" + case i == 0: + fmt.Fprint(fs, "⎡") + el = "⎤\n" + case i < rows-1: + fmt.Fprint(fs, "⎢") + el = "⎥\n" + default: + fmt.Fprint(fs, "⎣") + el = "⎦" + } + + for j := 0; j < cols; j++ { + if j >= printed && j < cols-printed { + j = cols - printed - 1 + if i == 0 || i == rows-1 { + fmt.Fprint(fs, "... ... ") + } else { + fmt.Fprint(fs, " ") + } + continue + } + + v := m.At(i, j) + if v == 0 && skipZero { + buf = buf[:1] + buf[0] = dot + } else { + if c == 'v' { + buf = strconv.AppendFloat(buf[:0], v, 'g', prec, 64) + } else { + buf = strconv.AppendFloat(buf[:0], v, byte(c), prec, 64) + } + } + if fs.Flag('-') { + fs.Write(buf) + fs.Write(pad[:widths.width(j)-len(buf)]) + } else { + fs.Write(pad[:widths.width(j)-len(buf)]) + fs.Write(buf) + } + + if j < cols-1 { + fs.Write(pad[:2]) + } + } + + fmt.Fprint(fs, el) + + if i >= printed-1 && i < rows-printed && 2*printed < rows { + i = rows - printed - 1 + fmt.Fprintf(fs, "%s .\n%[1]s .\n%[1]s .\n", prefix) + continue + } + } +} + +func maxCellWidth(m Matrix, c rune, printed, prec int, w widther) ([]byte, int) { + var ( + buf = make([]byte, 0, 64) + rows, cols = m.Dims() + max int + ) + for i := 0; i < rows; i++ { + if i >= printed-1 && i < rows-printed && 2*printed < rows { + i = rows - printed - 1 + continue + } + for j := 0; j < cols; j++ { + if j >= printed && j < cols-printed { + continue + } + + buf = strconv.AppendFloat(buf, m.At(i, j), byte(c), prec, 64) + if len(buf) > max { + max = len(buf) + } + if len(buf) > w.width(j) { + w.setWidth(j, len(buf)) + } + buf = buf[:0] + } + } + return buf, max +} + +type widther interface { + width(i int) int + setWidth(i, w int) +} + +type uniformWidth int + +func (u *uniformWidth) width(_ int) int { return int(*u) } +func (u *uniformWidth) setWidth(_, w int) { *u = uniformWidth(w) } + +type columnWidth []int + +func (c columnWidth) width(i int) int { return c[i] } +func (c columnWidth) setWidth(i, w int) { c[i] = w } diff --git a/vendor/gonum.org/v1/gonum/mat/format_example_test.go b/vendor/gonum.org/v1/gonum/mat/format_example_test.go new file mode 100644 index 00000000..59f26c70 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/format_example_test.go @@ -0,0 +1,112 @@ +// 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 mat_test + +import ( + "fmt" + + "gonum.org/v1/gonum/mat" +) + +func ExampleFormatted() { + a := mat.NewDense(3, 3, []float64{1, 2, 3, 0, 4, 5, 0, 0, 6}) + + // Create a matrix formatting value with a prefix and calculating each column + // width individually... + fa := mat.Formatted(a, mat.Prefix(" "), mat.Squeeze()) + + // and then print with and without zero value elements. + fmt.Printf("with all values:\na = %v\n\n", fa) + fmt.Printf("with only non-zero values:\na = % v\n\n", fa) + + // Modify the matrix... + a.Set(0, 2, 0) + + // and print it without zero value elements. + fmt.Printf("after modification with only non-zero values:\na = % v\n\n", fa) + + // Modify the matrix again... + a.Set(0, 2, 123.456) + + // and print it using scientific notation for large exponents. + fmt.Printf("after modification with scientific notation:\na = %.2g\n\n", fa) + // See golang.org/pkg/fmt/ floating-point verbs for a comprehensive list. + + // Output: + // with all values: + // a = ⎡1 2 3⎤ + // ⎢0 4 5⎥ + // ⎣0 0 6⎦ + // + // with only non-zero values: + // a = ⎡1 2 3⎤ + // ⎢. 4 5⎥ + // ⎣. . 6⎦ + // + // after modification with only non-zero values: + // a = ⎡1 2 .⎤ + // ⎢. 4 5⎥ + // ⎣. . 6⎦ + // + // after modification with scientific notation: + // a = ⎡1 2 1.2e+02⎤ + // ⎢0 4 5⎥ + // ⎣0 0 6⎦ +} + +func ExampleExcerpt() { + // Excerpt allows diagnostic display of very large + // matrices and vectors. + + // The big matrix is too large to properly print... + big := mat.NewDense(100, 100, nil) + for i := 0; i < 100; i++ { + big.Set(i, i, 1) + } + + // so only print corner excerpts of the matrix. + fmt.Printf("excerpt big identity matrix: %v\n\n", + mat.Formatted(big, mat.Prefix(" "), mat.Excerpt(3))) + + // The long vector is also too large, ... + long := mat.NewVecDense(100, nil) + for i := 0; i < 100; i++ { + long.SetVec(i, float64(i)) + } + + // ... so print end excerpts of the vector, + fmt.Printf("excerpt long column vector: %v\n\n", + mat.Formatted(long, mat.Prefix(" "), mat.Excerpt(3))) + // or its transpose. + fmt.Printf("excerpt long row vector: %v\n", + mat.Formatted(long.T(), mat.Prefix(" "), mat.Excerpt(3))) + + // Output: + // excerpt big identity matrix: Dims(100, 100) + // ⎡1 0 0 ... ... 0 0 0⎤ + // ⎢0 1 0 0 0 0⎥ + // ⎢0 0 1 0 0 0⎥ + // . + // . + // . + // ⎢0 0 0 1 0 0⎥ + // ⎢0 0 0 0 1 0⎥ + // ⎣0 0 0 ... ... 0 0 1⎦ + // + // excerpt long column vector: Dims(100, 1) + // ⎡ 0⎤ + // ⎢ 1⎥ + // ⎢ 2⎥ + // . + // . + // . + // ⎢97⎥ + // ⎢98⎥ + // ⎣99⎦ + // + // excerpt long row vector: Dims(1, 100) + // [ 0 1 2 ... ... 97 98 99] + +} diff --git a/vendor/gonum.org/v1/gonum/mat/format_test.go b/vendor/gonum.org/v1/gonum/mat/format_test.go new file mode 100644 index 00000000..2b725571 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/format_test.go @@ -0,0 +1,150 @@ +// 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. + +package mat + +import ( + "fmt" + "math" + "testing" +) + +func TestFormat(t *testing.T) { + type rp struct { + format string + output string + } + sqrt := func(_, _ int, v float64) float64 { return math.Sqrt(v) } + for i, test := range []struct { + m fmt.Formatter + rep []rp + }{ + // Dense matrix representation + { + Formatted(NewDense(3, 3, []float64{0, 0, 0, 0, 0, 0, 0, 0, 0})), + []rp{ + {"%v", "⎡0 0 0⎤\n⎢0 0 0⎥\n⎣0 0 0⎦"}, + {"% f", "⎡. . .⎤\n⎢. . .⎥\n⎣. . .⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{0, 0, 0, 0, 0, 0, 0, 0, 0}}, capRows:3, capCols:3}"}, + {"%s", "%!s(*mat.Dense=Dims(3, 3))"}, + }, + }, + { + Formatted(NewDense(3, 3, []float64{1, 1, 1, 1, 1, 1, 1, 1, 1})), + []rp{ + {"%v", "⎡1 1 1⎤\n⎢1 1 1⎥\n⎣1 1 1⎦"}, + {"% f", "⎡1 1 1⎤\n⎢1 1 1⎥\n⎣1 1 1⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 1, 1, 1, 1, 1, 1, 1, 1}}, capRows:3, capCols:3}"}, + }, + }, + { + Formatted(NewDense(3, 3, []float64{1, 1, 1, 1, 1, 1, 1, 1, 1}), Prefix("\t")), + []rp{ + {"%v", "⎡1 1 1⎤\n\t⎢1 1 1⎥\n\t⎣1 1 1⎦"}, + {"% f", "⎡1 1 1⎤\n\t⎢1 1 1⎥\n\t⎣1 1 1⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 1, 1, 1, 1, 1, 1, 1, 1}}, capRows:3, capCols:3}"}, + }, + }, + { + Formatted(NewDense(3, 3, []float64{1, 0, 0, 0, 1, 0, 0, 0, 1})), + []rp{ + {"%v", "⎡1 0 0⎤\n⎢0 1 0⎥\n⎣0 0 1⎦"}, + {"% f", "⎡1 . .⎤\n⎢. 1 .⎥\n⎣. . 1⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:3, Stride:3, Data:[]float64{1, 0, 0, 0, 1, 0, 0, 0, 1}}, capRows:3, capCols:3}"}, + }, + }, + { + Formatted(NewDense(2, 3, []float64{1, 2, 3, 4, 5, 6})), + []rp{ + {"%v", "⎡1 2 3⎤\n⎣4 5 6⎦"}, + {"% f", "⎡1 2 3⎤\n⎣4 5 6⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{1, 2, 3, 4, 5, 6}}, capRows:2, capCols:3}"}, + }, + }, + { + Formatted(NewDense(3, 2, []float64{1, 2, 3, 4, 5, 6})), + []rp{ + {"%v", "⎡1 2⎤\n⎢3 4⎥\n⎣5 6⎦"}, + {"% f", "⎡1 2⎤\n⎢3 4⎥\n⎣5 6⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:2, Stride:2, Data:[]float64{1, 2, 3, 4, 5, 6}}, capRows:3, capCols:2}"}, + }, + }, + { + func() fmt.Formatter { + m := NewDense(2, 3, []float64{0, 1, 2, 3, 4, 5}) + m.Apply(sqrt, m) + return Formatted(m) + }(), + []rp{ + {"%v", "⎡ 0 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, + {"%.2f", "⎡0.00 1.00 1.41⎤\n⎣1.73 2.00 2.24⎦"}, + {"% f", "⎡ . 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:2, capCols:3}"}, + }, + }, + { + func() fmt.Formatter { + m := NewDense(3, 2, []float64{0, 1, 2, 3, 4, 5}) + m.Apply(sqrt, m) + return Formatted(m) + }(), + []rp{ + {"%v", "⎡ 0 1⎤\n⎢1.4142135623730951 1.7320508075688772⎥\n⎣ 2 2.23606797749979⎦"}, + {"%.2f", "⎡0.00 1.00⎤\n⎢1.41 1.73⎥\n⎣2.00 2.24⎦"}, + {"% f", "⎡ . 1⎤\n⎢1.4142135623730951 1.7320508075688772⎥\n⎣ 2 2.23606797749979⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:3, Cols:2, Stride:2, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:3, capCols:2}"}, + }, + }, + { + func() fmt.Formatter { + m := NewDense(2, 3, []float64{0, 1, 2, 3, 4, 5}) + m.Apply(sqrt, m) + return Formatted(m, Squeeze()) + }(), + []rp{ + {"%v", "⎡ 0 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, + {"%.2f", "⎡0.00 1.00 1.41⎤\n⎣1.73 2.00 2.24⎦"}, + {"% f", "⎡ . 1 1.4142135623730951⎤\n⎣1.7320508075688772 2 2.23606797749979⎦"}, + {"%#v", "&mat.Dense{mat:blas64.General{Rows:2, Cols:3, Stride:3, Data:[]float64{0, 1, 1.4142135623730951, 1.7320508075688772, 2, 2.23606797749979}}, capRows:2, capCols:3}"}, + }, + }, + { + func() fmt.Formatter { + m := NewDense(1, 10, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + return Formatted(m, Excerpt(3)) + }(), + []rp{ + {"%v", "Dims(1, 10)\n[ 1 2 3 ... ... 8 9 10]"}, + }, + }, + { + func() fmt.Formatter { + m := NewDense(10, 1, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) + return Formatted(m, Excerpt(3)) + }(), + []rp{ + {"%v", "Dims(10, 1)\n⎡ 1⎤\n⎢ 2⎥\n⎢ 3⎥\n .\n .\n .\n⎢ 8⎥\n⎢ 9⎥\n⎣10⎦"}, + }, + }, + { + func() fmt.Formatter { + m := NewDense(10, 10, nil) + for i := 0; i < 10; i++ { + m.Set(i, i, 1) + } + return Formatted(m, Excerpt(3)) + }(), + []rp{ + {"%v", "Dims(10, 10)\n⎡1 0 0 ... ... 0 0 0⎤\n⎢0 1 0 0 0 0⎥\n⎢0 0 1 0 0 0⎥\n .\n .\n .\n⎢0 0 0 1 0 0⎥\n⎢0 0 0 0 1 0⎥\n⎣0 0 0 ... ... 0 0 1⎦"}, + }, + }, + } { + for j, rp := range test.rep { + got := fmt.Sprintf(rp.format, test.m) + if got != rp.output { + t.Errorf("unexpected format result test %d part %d:\ngot:\n%s\nwant:\n%s", i, j, got, rp.output) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/gsvd.go b/vendor/gonum.org/v1/gonum/mat/gsvd.go new file mode 100644 index 00000000..663a0729 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/gsvd.go @@ -0,0 +1,371 @@ +// 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 mat + +import ( + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/lapack64" +) + +// GSVD is a type for creating and using the Generalized Singular Value Decomposition +// (GSVD) of a matrix. +// +// The factorization is a linear transformation of the data sets from the given +// variable×sample spaces to reduced and diagonalized "eigenvariable"×"eigensample" +// spaces. +type GSVD struct { + kind GSVDKind + + r, p, c, k, l int + s1, s2 []float64 + a, b, u, v, q blas64.General + + work []float64 + iwork []int +} + +// Factorize computes the generalized singular value decomposition (GSVD) of the input +// the r×c matrix A and the p×c matrix B. The singular values of A and B are computed +// in all cases, while the singular vectors are optionally computed depending on the +// input kind. +// +// The full singular value decomposition (kind == GSVDU|GSVDV|GSVDQ) deconstructs A and B as +// A = U * Σ₁ * [ 0 R ] * Q^T +// +// B = V * Σ₂ * [ 0 R ] * Q^T +// where Σ₁ and Σ₂ are r×(k+l) and p×(k+l) diagonal matrices of singular values, and +// U, V and Q are r×r, p×p and c×c orthogonal matrices of singular vectors. k+l is the +// effective numerical rank of the matrix [ A^T B^T ]^T. +// +// It is frequently not necessary to compute the full GSVD. Computation time and +// storage costs can be reduced using the appropriate kind. Either only the singular +// values can be computed (kind == SVDNone), or in conjunction with specific singular +// vectors (kind bit set according to matrix.GSVDU, matrix.GSVDV and matrix.GSVDQ). +// +// Factorize returns whether the decomposition succeeded. If the decomposition +// failed, routines that require a successful factorization will panic. +func (gsvd *GSVD) Factorize(a, b Matrix, kind GSVDKind) (ok bool) { + r, c := a.Dims() + gsvd.r, gsvd.c = r, c + p, c := b.Dims() + gsvd.p = p + if gsvd.c != c { + panic(ErrShape) + } + var jobU, jobV, jobQ lapack.GSVDJob + switch { + default: + panic("gsvd: bad input kind") + case kind == GSVDNone: + jobU = lapack.GSVDNone + jobV = lapack.GSVDNone + jobQ = lapack.GSVDNone + case (GSVDU|GSVDV|GSVDQ)&kind != 0: + if GSVDU&kind != 0 { + jobU = lapack.GSVDU + gsvd.u = blas64.General{ + Rows: r, + Cols: r, + Stride: r, + Data: use(gsvd.u.Data, r*r), + } + } + if GSVDV&kind != 0 { + jobV = lapack.GSVDV + gsvd.v = blas64.General{ + Rows: p, + Cols: p, + Stride: p, + Data: use(gsvd.v.Data, p*p), + } + } + if GSVDQ&kind != 0 { + jobQ = lapack.GSVDQ + gsvd.q = blas64.General{ + Rows: c, + Cols: c, + Stride: c, + Data: use(gsvd.q.Data, c*c), + } + } + } + + // A and B are destroyed on call, so copy the matrices. + aCopy := DenseCopyOf(a) + bCopy := DenseCopyOf(b) + + gsvd.s1 = use(gsvd.s1, c) + gsvd.s2 = use(gsvd.s2, c) + + gsvd.iwork = useInt(gsvd.iwork, c) + + gsvd.work = use(gsvd.work, 1) + lapack64.Ggsvd3(jobU, jobV, jobQ, aCopy.mat, bCopy.mat, gsvd.s1, gsvd.s2, gsvd.u, gsvd.v, gsvd.q, gsvd.work, -1, gsvd.iwork) + gsvd.work = use(gsvd.work, int(gsvd.work[0])) + gsvd.k, gsvd.l, ok = lapack64.Ggsvd3(jobU, jobV, jobQ, aCopy.mat, bCopy.mat, gsvd.s1, gsvd.s2, gsvd.u, gsvd.v, gsvd.q, gsvd.work, len(gsvd.work), gsvd.iwork) + if ok { + gsvd.a = aCopy.mat + gsvd.b = bCopy.mat + gsvd.kind = kind + } + return ok +} + +// Kind returns the matrix.GSVDKind of the decomposition. If no decomposition has been +// computed, Kind returns 0. +func (gsvd *GSVD) Kind() GSVDKind { + return gsvd.kind +} + +// Rank returns the k and l terms of the rank of [ A^T B^T ]^T. +func (gsvd *GSVD) Rank() (k, l int) { + return gsvd.k, gsvd.l +} + +// GeneralizedValues returns the generalized singular values of the factorized matrices. +// If the input slice is non-nil, the values will be stored in-place into the slice. +// In this case, the slice must have length min(r,c)-k, and GeneralizedValues will +// panic with matrix.ErrSliceLengthMismatch otherwise. If the input slice is nil, +// a new slice of the appropriate length will be allocated and returned. +// +// GeneralizedValues will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) GeneralizedValues(v []float64) []float64 { + if gsvd.kind == 0 { + panic("gsvd: no decomposition computed") + } + r := gsvd.r + c := gsvd.c + k := gsvd.k + d := min(r, c) + if v == nil { + v = make([]float64, d-k) + } + if len(v) != d-k { + panic(ErrSliceLengthMismatch) + } + floats.DivTo(v, gsvd.s1[k:d], gsvd.s2[k:d]) + return v +} + +// ValuesA returns the singular values of the factorized A matrix. +// If the input slice is non-nil, the values will be stored in-place into the slice. +// In this case, the slice must have length min(r,c)-k, and ValuesA will panic with +// matrix.ErrSliceLengthMismatch otherwise. If the input slice is nil, +// a new slice of the appropriate length will be allocated and returned. +// +// ValuesA will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) ValuesA(s []float64) []float64 { + if gsvd.kind == 0 { + panic("gsvd: no decomposition computed") + } + r := gsvd.r + c := gsvd.c + k := gsvd.k + d := min(r, c) + if s == nil { + s = make([]float64, d-k) + } + if len(s) != d-k { + panic(ErrSliceLengthMismatch) + } + copy(s, gsvd.s1[k:min(r, c)]) + return s +} + +// ValuesB returns the singular values of the factorized B matrix. +// If the input slice is non-nil, the values will be stored in-place into the slice. +// In this case, the slice must have length min(r,c)-k, and ValuesB will panic with +// matrix.ErrSliceLengthMismatch otherwise. If the input slice is nil, +// a new slice of the appropriate length will be allocated and returned. +// +// ValuesB will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) ValuesB(s []float64) []float64 { + if gsvd.kind == 0 { + panic("gsvd: no decomposition computed") + } + r := gsvd.r + c := gsvd.c + k := gsvd.k + d := min(r, c) + if s == nil { + s = make([]float64, d-k) + } + if len(s) != d-k { + panic(ErrSliceLengthMismatch) + } + copy(s, gsvd.s2[k:d]) + return s +} + +// ZeroRTo extracts the matrix [ 0 R ] from the singular value decomposition, storing +// the result in-place into dst. [ 0 R ] is size (k+l)×c. +// If dst is nil, a new matrix is allocated. The resulting ZeroR matrix is returned. +// +// ZeroRTo will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) ZeroRTo(dst *Dense) *Dense { + if gsvd.kind == 0 { + panic("gsvd: no decomposition computed") + } + r := gsvd.r + c := gsvd.c + k := gsvd.k + l := gsvd.l + h := min(k+l, r) + if dst == nil { + dst = NewDense(k+l, c, nil) + } else { + dst.reuseAsZeroed(k+l, c) + } + a := Dense{ + mat: gsvd.a, + capRows: r, + capCols: c, + } + dst.Slice(0, h, c-k-l, c).(*Dense). + Copy(a.Slice(0, h, c-k-l, c)) + if r < k+l { + b := Dense{ + mat: gsvd.b, + capRows: gsvd.p, + capCols: c, + } + dst.Slice(r, k+l, c+r-k-l, c).(*Dense). + Copy(b.Slice(r-k, l, c+r-k-l, c)) + } + return dst +} + +// SigmaATo extracts the matrix Σ₁ from the singular value decomposition, storing +// the result in-place into dst. Σ₁ is size r×(k+l). +// If dst is nil, a new matrix is allocated. The resulting SigmaA matrix is returned. +// +// SigmaATo will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) SigmaATo(dst *Dense) *Dense { + if gsvd.kind == 0 { + panic("gsvd: no decomposition computed") + } + r := gsvd.r + k := gsvd.k + l := gsvd.l + if dst == nil { + dst = NewDense(r, k+l, nil) + } else { + dst.reuseAsZeroed(r, k+l) + } + for i := 0; i < k; i++ { + dst.set(i, i, 1) + } + for i := k; i < min(r, k+l); i++ { + dst.set(i, i, gsvd.s1[i]) + } + return dst +} + +// SigmaBTo extracts the matrix Σ₂ from the singular value decomposition, storing +// the result in-place into dst. Σ₂ is size p×(k+l). +// If dst is nil, a new matrix is allocated. The resulting SigmaB matrix is returned. +// +// SigmaBTo will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) SigmaBTo(dst *Dense) *Dense { + if gsvd.kind == 0 { + panic("gsvd: no decomposition computed") + } + r := gsvd.r + p := gsvd.p + k := gsvd.k + l := gsvd.l + if dst == nil { + dst = NewDense(p, k+l, nil) + } else { + dst.reuseAsZeroed(p, k+l) + } + for i := 0; i < min(l, r-k); i++ { + dst.set(i, i+k, gsvd.s2[k+i]) + } + for i := r - k; i < l; i++ { + dst.set(i, i+k, 1) + } + return dst +} + +// UTo extracts the matrix U from the singular value decomposition, storing +// the result in-place into dst. U is size r×r. +// If dst is nil, a new matrix is allocated. The resulting U matrix is returned. +// +// UTo will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) UTo(dst *Dense) *Dense { + if gsvd.kind&GSVDU == 0 { + panic("mat: improper GSVD kind") + } + r := gsvd.u.Rows + c := gsvd.u.Cols + if dst == nil { + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(r, c) + } + + tmp := &Dense{ + mat: gsvd.u, + capRows: r, + capCols: c, + } + dst.Copy(tmp) + return dst +} + +// VTo extracts the matrix V from the singular value decomposition, storing +// the result in-place into dst. V is size p×p. +// If dst is nil, a new matrix is allocated. The resulting V matrix is returned. +// +// VTo will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) VTo(dst *Dense) *Dense { + if gsvd.kind&GSVDV == 0 { + panic("mat: improper GSVD kind") + } + r := gsvd.v.Rows + c := gsvd.v.Cols + if dst == nil { + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(r, c) + } + + tmp := &Dense{ + mat: gsvd.v, + capRows: r, + capCols: c, + } + dst.Copy(tmp) + return dst +} + +// QTo extracts the matrix Q from the singular value decomposition, storing +// the result in-place into dst. Q is size c×c. +// If dst is nil, a new matrix is allocated. The resulting Q matrix is returned. +// +// QTo will panic if the receiver does not contain a successful factorization. +func (gsvd *GSVD) QTo(dst *Dense) *Dense { + if gsvd.kind&GSVDQ == 0 { + panic("mat: improper GSVD kind") + } + r := gsvd.q.Rows + c := gsvd.q.Cols + if dst == nil { + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(r, c) + } + + tmp := &Dense{ + mat: gsvd.q, + capRows: r, + capCols: c, + } + dst.Copy(tmp) + return dst +} diff --git a/vendor/gonum.org/v1/gonum/mat/gsvd_example_test.go b/vendor/gonum.org/v1/gonum/mat/gsvd_example_test.go new file mode 100644 index 00000000..48898ccc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/gsvd_example_test.go @@ -0,0 +1,85 @@ +// 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 mat_test + +import ( + "fmt" + "log" + "math" + + "gonum.org/v1/gonum/mat" +) + +func ExampleGSVD() { + // Perform a GSVD factorization on food production/consumption data for the + // three years 1990, 2000 and 2014, for Africa and Latin America/Caribbean. + // + // See Lee et al. doi:10.1371/journal.pone.0030098 and + // Alter at al. doi:10.1073/pnas.0530258100 for more details. + var gsvd mat.GSVD + ok := gsvd.Factorize(FAO.Africa, FAO.LatinAmericaCaribbean, mat.GSVDU|mat.GSVDV|mat.GSVDQ) + if !ok { + log.Fatal("GSVD factorization failed") + } + + u := gsvd.UTo(nil) + v := gsvd.VTo(nil) + + s1 := gsvd.ValuesA(nil) + s2 := gsvd.ValuesB(nil) + + fmt.Printf("Africa\n\ts1 = %.4f\n\n\tU = %.4f\n\n", + s1, mat.Formatted(u, mat.Prefix("\t "), mat.Excerpt(2))) + fmt.Printf("Latin America/Caribbean\n\ts2 = %.4f\n\n\tV = %.4f\n", + s2, mat.Formatted(v, mat.Prefix("\t "), mat.Excerpt(2))) + + var q mat.Dense + q.Mul(gsvd.ZeroRTo(nil), gsvd.QTo(nil)) + fmt.Printf("\nCommon basis vectors\n\n\tQ^T = %.4f\n", + mat.Formatted(q.T(), mat.Prefix("\t "))) + + // Calculate the antisymmetric angular distances for each eigenvariable. + fmt.Println("\nSignificance:") + for i := 0; i < 3; i++ { + fmt.Printf("\teigenvar_%d: %+.4f\n", i, math.Atan(s1[i]/s2[i])-math.Pi/4) + } + + // Output: + // + // Africa + // s1 = [1.0000 0.9344 0.5118] + // + // U = Dims(21, 21) + // ⎡-0.0005 0.0142 ... ... -0.0060 -0.0055⎤ + // ⎢-0.0010 0.0019 0.0071 0.0075⎥ + // . + // . + // . + // ⎢-0.0007 -0.0024 0.9999 -0.0001⎥ + // ⎣-0.0010 -0.0016 ... ... -0.0001 0.9999⎦ + // + // Latin America/Caribbean + // s2 = [0.0047 0.3563 0.8591] + // + // V = Dims(14, 14) + // ⎡ 0.1362 0.0008 ... ... 0.0700 0.2636⎤ + // ⎢ 0.1830 -0.0040 0.2908 0.7834⎥ + // . + // . + // . + // ⎢-0.2598 -0.0324 0.9339 -0.2170⎥ + // ⎣-0.8386 0.1494 ... ... -0.1639 0.4121⎦ + // + // Common basis vectors + // + // Q^T = ⎡ -8172.4084 -4524.2933 4813.9616⎤ + // ⎢ 22581.8020 12397.1070 -16364.8933⎥ + // ⎣ -8910.8462 -10902.1488 15762.8719⎦ + // + // Significance: + // eigenvar_0: +0.7807 + // eigenvar_1: +0.4211 + // eigenvar_2: -0.2482 +} diff --git a/vendor/gonum.org/v1/gonum/mat/gsvd_test.go b/vendor/gonum.org/v1/gonum/mat/gsvd_test.go new file mode 100644 index 00000000..6e8ef0f5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/gsvd_test.go @@ -0,0 +1,117 @@ +// 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 mat + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestGSVD(t *testing.T) { + const tol = 1e-10 + rnd := rand.New(rand.NewSource(1)) + for _, test := range []struct { + m, p, n int + }{ + {5, 3, 5}, + {5, 3, 3}, + {3, 3, 5}, + {5, 5, 5}, + {5, 5, 3}, + {3, 5, 5}, + {150, 150, 150}, + {200, 150, 150}, + {150, 150, 200}, + {150, 200, 150}, + {200, 200, 150}, + {150, 200, 200}, + } { + m := test.m + p := test.p + n := test.n + for trial := 0; trial < 10; trial++ { + a := NewDense(m, n, nil) + for i := range a.mat.Data { + a.mat.Data[i] = rnd.NormFloat64() + } + aCopy := DenseCopyOf(a) + + b := NewDense(p, n, nil) + for i := range b.mat.Data { + b.mat.Data[i] = rnd.NormFloat64() + } + bCopy := DenseCopyOf(b) + + // Test Full decomposition. + var gsvd GSVD + ok := gsvd.Factorize(a, b, GSVDU|GSVDV|GSVDQ) + if !ok { + t.Errorf("GSVD factorization failed") + } + if !Equal(a, aCopy) { + t.Errorf("A changed during call to GSVD.Factorize with GSVDU|GSVDV|GSVDQ") + } + if !Equal(b, bCopy) { + t.Errorf("B changed during call to GSVD.Factorize with GSVDU|GSVDV|GSVDQ") + } + c, s, sigma1, sigma2, zeroR, u, v, q := extractGSVD(&gsvd) + var ansU, ansV, d1R, d2R Dense + ansU.Product(u.T(), a, q) + ansV.Product(v.T(), b, q) + d1R.Mul(sigma1, zeroR) + d2R.Mul(sigma2, zeroR) + if !EqualApprox(&ansU, &d1R, tol) { + t.Errorf("Answer mismatch with GSVDU|GSVDV|GSVDQ\nU^T * A * Q:\n% 0.2f\nΣ₁ * [ 0 R ]:\n% 0.2f", + Formatted(&ansU), Formatted(&d1R)) + } + if !EqualApprox(&ansV, &d2R, tol) { + t.Errorf("Answer mismatch with GSVDU|GSVDV|GSVDQ\nV^T * B *Q:\n% 0.2f\nΣ₂ * [ 0 R ]:\n% 0.2f", + Formatted(&d2R), Formatted(&ansV)) + } + + // Check C^2 + S^2 = I. + for i := range c { + d := c[i]*c[i] + s[i]*s[i] + if !floats.EqualWithinAbsOrRel(d, 1, 1e-14, 1e-14) { + t.Errorf("c_%d^2 + s_%d^2 != 1: got: %v", i, i, d) + } + } + + // Test None decomposition. + ok = gsvd.Factorize(a, b, GSVDNone) + if !ok { + t.Errorf("GSVD factorization failed") + } + if !Equal(a, aCopy) { + t.Errorf("A changed during call to GSVD with GSVDNone") + } + if !Equal(b, bCopy) { + t.Errorf("B changed during call to GSVD with GSVDNone") + } + cNone := gsvd.ValuesA(nil) + if !floats.EqualApprox(c, cNone, tol) { + t.Errorf("Singular value mismatch between GSVDU|GSVDV|GSVDQ and GSVDNone decomposition") + } + sNone := gsvd.ValuesB(nil) + if !floats.EqualApprox(s, sNone, tol) { + t.Errorf("Singular value mismatch between GSVDU|GSVDV|GSVDQ and GSVDNone decomposition") + } + } + } +} + +func extractGSVD(gsvd *GSVD) (c, s []float64, s1, s2, zR, u, v, q *Dense) { + s1 = gsvd.SigmaATo(nil) + s2 = gsvd.SigmaBTo(nil) + zR = gsvd.ZeroRTo(nil) + u = gsvd.UTo(nil) + v = gsvd.VTo(nil) + q = gsvd.QTo(nil) + c = gsvd.ValuesA(nil) + s = gsvd.ValuesB(nil) + return c, s, s1, s2, zR, u, v, q +} diff --git a/vendor/gonum.org/v1/gonum/mat/hogsvd.go b/vendor/gonum.org/v1/gonum/mat/hogsvd.go new file mode 100644 index 00000000..2d3c0403 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/hogsvd.go @@ -0,0 +1,213 @@ +// 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 mat + +import ( + "errors" + + "gonum.org/v1/gonum/blas/blas64" +) + +// HOGSVD is a type for creating and using the Higher Order Generalized Singular Value +// Decomposition (HOGSVD) of a set of matrices. +// +// The factorization is a linear transformation of the data sets from the given +// variable×sample spaces to reduced and diagonalized "eigenvariable"×"eigensample" +// spaces. +type HOGSVD struct { + n int + v *Dense + b []Dense + + err error +} + +// Factorize computes the higher order generalized singular value decomposition (HOGSVD) +// of the n input r_i×c column tall matrices in m. HOGSV extends the GSVD case from 2 to n +// input matrices. +// +// M_0 = U_0 * Σ_0 * V^T +// M_1 = U_1 * Σ_1 * V^T +// . +// . +// . +// M_{n-1} = U_{n-1} * Σ_{n-1} * V^T +// +// where U_i are r_i×c matrices of singular vectors, Σ are c×c matrices singular values, and V +// is a c×c matrix of singular vectors. +// +// Factorize returns whether the decomposition succeeded. If the decomposition +// failed, routines that require a successful factorization will panic. +func (gsvd *HOGSVD) Factorize(m ...Matrix) (ok bool) { + // Factorize performs the HOGSVD factorisation + // essentially as described by Ponnapalli et al. + // https://doi.org/10.1371/journal.pone.0028072 + + if len(m) < 2 { + panic("hogsvd: too few matrices") + } + gsvd.n = 0 + + r, c := m[0].Dims() + a := make([]Cholesky, len(m)) + var ts SymDense + for i, d := range m { + rd, cd := d.Dims() + if rd < cd { + gsvd.err = ErrShape + return false + } + if rd > r { + r = rd + } + if cd != c { + panic(ErrShape) + } + ts.Reset() + ts.SymOuterK(1, d.T()) + ok = a[i].Factorize(&ts) + if !ok { + gsvd.err = errors.New("hogsvd: cholesky decomposition failed") + return false + } + } + + s := getWorkspace(c, c, true) + defer putWorkspace(s) + sij := getWorkspace(c, c, false) + defer putWorkspace(sij) + for i, ai := range a { + for _, aj := range a[i+1:] { + gsvd.err = ai.SolveChol(sij, &aj) + if gsvd.err != nil { + return false + } + s.Add(s, sij) + + gsvd.err = aj.SolveChol(sij, &ai) + if gsvd.err != nil { + return false + } + s.Add(s, sij) + } + } + s.Scale(1/float64(len(m)*(len(m)-1)), s) + + var eig Eigen + ok = eig.Factorize(s.T(), false, true) + if !ok { + gsvd.err = errors.New("hogsvd: eigen decomposition failed") + return false + } + v := eig.Vectors() + for j := 0; j < c; j++ { + cv := v.ColView(j) + cv.ScaleVec(1/blas64.Nrm2(c, cv.mat), cv) + } + + b := make([]Dense, len(m)) + biT := getWorkspace(c, r, false) + defer putWorkspace(biT) + for i, d := range m { + // All calls to reset will leave a zeroed + // matrix with capacity to store the result + // without additional allocation. + biT.Reset() + gsvd.err = biT.Solve(v, d.T()) + if gsvd.err != nil { + return false + } + b[i].Clone(biT.T()) + } + + gsvd.n = len(m) + gsvd.v = v + gsvd.b = b + return true +} + +// Err returns the reason for a factorization failure. +func (gsvd *HOGSVD) Err() error { + return gsvd.err +} + +// Len returns the number of matrices that have been factorized. If Len returns +// zero, the factorization was not successful. +func (gsvd *HOGSVD) Len() int { + return gsvd.n +} + +// UTo extracts the matrix U_n from the singular value decomposition, storing +// the result in-place into dst. U_n is size r×c. +// If dst is nil, a new matrix is allocated. The resulting U matrix is returned. +// +// UTo will panic if the receiver does not contain a successful factorization. +func (gsvd *HOGSVD) UTo(dst *Dense, n int) *Dense { + if gsvd.n == 0 { + panic("hogsvd: unsuccessful factorization") + } + if n < 0 || gsvd.n <= n { + panic("hogsvd: invalid index") + } + + if dst == nil { + r, c := gsvd.b[n].Dims() + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(gsvd.b[n].Dims()) + } + dst.Copy(&gsvd.b[n]) + for j, f := range gsvd.Values(nil, n) { + v := dst.ColView(j) + v.ScaleVec(1/f, v) + } + return dst +} + +// Values returns the nth set of singular values of the factorized system. +// If the input slice is non-nil, the values will be stored in-place into the slice. +// In this case, the slice must have length c, and Values will panic with +// matrix.ErrSliceLengthMismatch otherwise. If the input slice is nil, +// a new slice of the appropriate length will be allocated and returned. +// +// Values will panic if the receiver does not contain a successful factorization. +func (gsvd *HOGSVD) Values(s []float64, n int) []float64 { + if gsvd.n == 0 { + panic("hogsvd: unsuccessful factorization") + } + if n < 0 || gsvd.n <= n { + panic("hogsvd: invalid index") + } + + r, c := gsvd.b[n].Dims() + if s == nil { + s = make([]float64, c) + } else if len(s) != c { + panic(ErrSliceLengthMismatch) + } + for j := 0; j < c; j++ { + s[j] = blas64.Nrm2(r, gsvd.b[n].ColView(j).mat) + } + return s +} + +// VTo extracts the matrix V from the singular value decomposition, storing +// the result in-place into dst. V is size c×c. +// If dst is nil, a new matrix is allocated. The resulting V matrix is returned. +// +// VTo will panic if the receiver does not contain a successful factorization. +func (gsvd *HOGSVD) VTo(dst *Dense) *Dense { + if gsvd.n == 0 { + panic("hogsvd: unsuccessful factorization") + } + if dst == nil { + r, c := gsvd.v.Dims() + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(gsvd.v.Dims()) + } + dst.Copy(gsvd.v) + return dst +} diff --git a/vendor/gonum.org/v1/gonum/mat/hogsvd_example_test.go b/vendor/gonum.org/v1/gonum/mat/hogsvd_example_test.go new file mode 100644 index 00000000..a1651448 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/hogsvd_example_test.go @@ -0,0 +1,134 @@ +// 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 mat_test + +import ( + "fmt" + "log" + + "gonum.org/v1/gonum/mat" +) + +func ExampleHOGSVD() { + // Perform an HOGSVD factorization on food production/consumption data for the + // three years 1990, 2000 and 2014. + // + // See Ponnapalli et al. doi:10.1371/journal.pone.0028072 and + // Alter at al. doi:10.1073/pnas.0530258100 for more details. + var gsvd mat.HOGSVD + ok := gsvd.Factorize(FAO.Africa, FAO.Asia, FAO.LatinAmericaCaribbean, FAO.Oceania) + if !ok { + log.Fatalf("HOGSVD factorization failed: %v", gsvd.Err()) + } + + for i, n := range []string{"Africa", "Asia", "Latin America/Caribbean", "Oceania"} { + u := gsvd.UTo(nil, i) + s := gsvd.Values(nil, i) + fmt.Printf("%s\n\ts_%d = %.4f\n\n\tU_%[2]d = %.4[4]f\n", + n, i, s, mat.Formatted(u, mat.Prefix("\t "))) + } + + v := gsvd.VTo(nil) + fmt.Printf("\nCommon basis vectors\n\n\tV^T = %.4f", + mat.Formatted(v.T(), mat.Prefix("\t "))) + + // Output: + // + // Africa + // s_0 = [45507.3278 18541.9293 21503.0778] + // + // U_0 = ⎡-0.0005 -0.0039 -0.0019⎤ + // ⎢-0.0010 -0.0007 -0.0012⎥ + // ⎢-1.0000 -0.0507 -0.9964⎥ + // ⎢-0.0022 -0.2906 -0.0415⎥ + // ⎢ 0.0001 -0.0127 -0.0016⎥ + // ⎢ 0.0003 -0.0067 -0.0010⎥ + // ⎢ 0.0003 -0.0022 -0.0003⎥ + // ⎢-0.0086 -0.9550 0.0734⎥ + // ⎢ 0.0017 0.0002 0.0059⎥ + // ⎢-0.0002 -0.0088 -0.0014⎥ + // ⎢-0.0006 -0.0078 -0.0001⎥ + // ⎢-0.0005 -0.0076 0.0003⎥ + // ⎢ 0.0001 -0.0090 0.0008⎥ + // ⎢-0.0005 -0.0050 0.0029⎥ + // ⎢-0.0011 -0.0078 -0.0012⎥ + // ⎢-0.0014 -0.0058 -0.0002⎥ + // ⎢ 0.0007 -0.0095 0.0020⎥ + // ⎢-0.0008 -0.0081 -0.0009⎥ + // ⎢ 0.0004 -0.0092 0.0006⎥ + // ⎢-0.0007 -0.0079 -0.0006⎥ + // ⎣-0.0011 -0.0076 -0.0010⎦ + // Asia + // s_1 = [77228.2804 8413.7024 14711.1879] + // + // U_1 = ⎡ 0.0005 -0.0080 0.0011⎤ + // ⎢ 0.0008 -0.0108 0.0016⎥ + // ⎢-0.9998 0.0612 0.9949⎥ + // ⎢ 0.0007 -0.5734 -0.0468⎥ + // ⎢ 0.0001 -0.0265 -0.0022⎥ + // ⎢ 0.0001 -0.0165 -0.0019⎥ + // ⎢ 0.0000 -0.0070 -0.0013⎥ + // ⎢ 0.0196 -0.8148 0.0893⎥ + // ⎢ 0.0002 -0.0063 0.0012⎥ + // ⎢-0.0001 -0.0135 -0.0013⎥ + // ⎢-0.0004 -0.0135 0.0019⎥ + // ⎢-0.0005 -0.0132 0.0014⎥ + // ⎢ 0.0003 -0.0155 0.0045⎥ + // ⎢-0.0003 -0.0130 0.0025⎥ + // ⎢-0.0007 -0.0105 0.0016⎥ + // ⎢-0.0006 -0.0129 0.0007⎥ + // ⎢-0.0006 -0.0178 -0.0023⎥ + // ⎢-0.0003 -0.0149 0.0016⎥ + // ⎢-0.0001 -0.0134 0.0030⎥ + // ⎢-0.0004 -0.0154 0.0010⎥ + // ⎣-0.0009 -0.0147 -0.0019⎦ + // Latin America/Caribbean + // s_2 = [274.1364 20736.3116 729.6947] + // + // U_2 = ⎡ 0.1060 -0.0021 0.0174⎤ + // ⎢ 0.1415 -0.0016 0.0289⎥ + // ⎢ 0.2350 -0.2669 -0.9212⎥ + // ⎢ 0.0290 -0.0118 -0.0429⎥ + // ⎢ 0.0226 -0.0043 -0.0213⎥ + // ⎢ 0.0117 -0.0016 -0.0197⎥ + // ⎢-0.6263 -0.9635 0.2234⎥ + // ⎢ 0.2334 -0.0013 0.1275⎥ + // ⎢-0.0358 -0.0085 -0.0498⎥ + // ⎢-0.1238 -0.0054 0.0313⎥ + // ⎢-0.0421 -0.0059 0.0528⎥ + // ⎢-0.1471 -0.0056 0.0350⎥ + // ⎢-0.2158 -0.0052 -0.0044⎥ + // ⎣-0.6154 -0.0078 -0.2717⎦ + // Oceania + // s_3 = [8954.1914 6942.6316 17233.0561] + // + // U_3 = ⎡-0.0080 -0.0012 -0.0040⎤ + // ⎢ 0.0004 -0.0014 0.0001⎥ + // ⎢ 0.9973 -0.0315 0.9991⎥ + // ⎢ 0.0473 -0.7426 -0.0359⎥ + // ⎢ 0.0018 -0.0342 -0.0020⎥ + // ⎢-0.0005 -0.0148 -0.0016⎥ + // ⎢-0.0004 -0.0047 -0.0007⎥ + // ⎢-0.0246 -0.6642 -0.0138⎥ + // ⎢ 0.0003 -0.0287 -0.0023⎥ + // ⎢-0.0011 -0.0148 -0.0014⎥ + // ⎢-0.0108 -0.0198 -0.0039⎥ + // ⎢-0.0149 -0.0183 -0.0048⎥ + // ⎢-0.0178 -0.0208 -0.0075⎥ + // ⎢-0.0266 -0.0063 -0.0016⎥ + // ⎢-0.0012 -0.0234 -0.0006⎥ + // ⎢-0.0084 -0.0184 -0.0030⎥ + // ⎢-0.0232 -0.0191 -0.0124⎥ + // ⎢-0.0072 -0.0226 -0.0035⎥ + // ⎢-0.0150 -0.0144 -0.0045⎥ + // ⎢-0.0068 -0.0227 -0.0034⎥ + // ⎣-0.0127 -0.0136 -0.0049⎦ + // + // Common basis vectors + // + // V^T = ⎡-0.0897 -0.4460 -0.8905⎤ + // ⎢-0.4911 -0.5432 -0.6810⎥ + // ⎣ 0.0644 0.2841 0.9566⎦ +} diff --git a/vendor/gonum.org/v1/gonum/mat/hogsvd_test.go b/vendor/gonum.org/v1/gonum/mat/hogsvd_test.go new file mode 100644 index 00000000..5838b61b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/hogsvd_test.go @@ -0,0 +1,87 @@ +// 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 mat + +import ( + "math/rand" + "testing" +) + +func TestHOGSVD(t *testing.T) { + const tol = 1e-10 + rnd := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + r, c int + }{ + {5, 3}, + {5, 5}, + {150, 150}, + {200, 150}, + + // Calculating A_i*A_j^T and A_j*A_i^T fails for wide matrices. + {3, 5}, + } { + r := test.r + c := test.c + for n := 3; n < 6; n++ { + data := make([]Matrix, n) + dataCopy := make([]*Dense, n) + for trial := 0; trial < 10; trial++ { + for i := range data { + d := NewDense(r, c, nil) + for j := range d.mat.Data { + d.mat.Data[j] = rnd.Float64() + } + data[i] = d + dataCopy[i] = DenseCopyOf(d) + } + + var gsvd HOGSVD + ok := gsvd.Factorize(data...) + if r >= c { + if !ok { + t.Errorf("HOGSVD factorization failed for %d %d×%d matrices: %v", n, r, c, gsvd.Err()) + continue + } + } else { + if ok { + t.Errorf("HOGSVD factorization unexpectedly succeeded for for %d %d×%d matrices", n, r, c) + } + continue + } + for i := range data { + if !Equal(data[i], dataCopy[i]) { + t.Errorf("A changed during call to HOGSVD.Factorize") + } + } + u, s, v := extractHOGSVD(&gsvd) + for i, want := range data { + var got Dense + sigma := NewDense(c, c, nil) + for j := 0; j < c; j++ { + sigma.Set(j, j, s[i][j]) + } + + got.Product(u[i], sigma, v.T()) + if !EqualApprox(&got, want, tol) { + t.Errorf("test %d n=%d trial %d: unexpected answer\nU_%[4]d * S_%[4]d * V^T:\n% 0.2f\nD_%d:\n% 0.2f", + cas, n, trial, i, Formatted(&got, Excerpt(5)), i, Formatted(want, Excerpt(5))) + } + } + } + } + } +} + +func extractHOGSVD(gsvd *HOGSVD) (u []*Dense, s [][]float64, v *Dense) { + u = make([]*Dense, gsvd.Len()) + s = make([][]float64, gsvd.Len()) + for i := 0; i < gsvd.Len(); i++ { + u[i] = gsvd.UTo(nil, i) + s[i] = gsvd.Values(nil, i) + } + v = gsvd.VTo(nil) + return u, s, v +} diff --git a/vendor/gonum.org/v1/gonum/mat/index_bound_checks.go b/vendor/gonum.org/v1/gonum/mat/index_bound_checks.go new file mode 100644 index 00000000..9633b21b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/index_bound_checks.go @@ -0,0 +1,227 @@ +// 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. + +// This file must be kept in sync with index_no_bound_checks.go. + +//+build bounds + +package mat + +// At returns the element at row i, column j. +func (m *Dense) At(i, j int) float64 { + return m.at(i, j) +} + +func (m *Dense) at(i, j int) float64 { + if uint(i) >= uint(m.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(m.mat.Cols) { + panic(ErrColAccess) + } + return m.mat.Data[i*m.mat.Stride+j] +} + +// Set sets the element at row i, column j to the value v. +func (m *Dense) Set(i, j int, v float64) { + m.set(i, j, v) +} + +func (m *Dense) set(i, j int, v float64) { + if uint(i) >= uint(m.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(m.mat.Cols) { + panic(ErrColAccess) + } + m.mat.Data[i*m.mat.Stride+j] = v +} + +// At returns the element at row i. +// It panics if i is out of bounds or if j is not zero. +func (v *VecDense) At(i, j int) float64 { + if j != 0 { + panic(ErrColAccess) + } + return v.at(i) +} + +func (v *VecDense) at(i int) float64 { + if uint(i) >= uint(v.n) { + panic(ErrRowAccess) + } + return v.mat.Data[i*v.mat.Inc] +} + +// SetVec sets the element at row i to the value val. +// It panics if i is out of bounds. +func (v *VecDense) SetVec(i int, val float64) { + v.setVec(i, val) +} + +func (v *VecDense) setVec(i int, val float64) { + if uint(i) >= uint(v.n) { + panic(ErrVectorAccess) + } + v.mat.Data[i*v.mat.Inc] = val +} + +// At returns the element at row i and column j. +func (t *SymDense) At(i, j int) float64 { + return t.at(i, j) +} + +func (t *SymDense) at(i, j int) float64 { + if uint(i) >= uint(t.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(t.mat.N) { + panic(ErrColAccess) + } + if i > j { + i, j = j, i + } + return t.mat.Data[i*t.mat.Stride+j] +} + +// SetSym sets the elements at (i,j) and (j,i) to the value v. +func (t *SymDense) SetSym(i, j int, v float64) { + t.set(i, j, v) +} + +func (t *SymDense) set(i, j int, v float64) { + if uint(i) >= uint(t.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(t.mat.N) { + panic(ErrColAccess) + } + if i > j { + i, j = j, i + } + t.mat.Data[i*t.mat.Stride+j] = v +} + +// At returns the element at row i, column j. +func (t *TriDense) At(i, j int) float64 { + return t.at(i, j) +} + +func (t *TriDense) at(i, j int) float64 { + if uint(i) >= uint(t.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(t.mat.N) { + panic(ErrColAccess) + } + isUpper := t.isUpper() + if (isUpper && i > j) || (!isUpper && i < j) { + return 0 + } + return t.mat.Data[i*t.mat.Stride+j] +} + +// SetTri sets the element of the triangular matrix at row i, column j to the value v. +// It panics if the location is outside the appropriate half of the matrix. +func (t *TriDense) SetTri(i, j int, v float64) { + t.set(i, j, v) +} + +func (t *TriDense) set(i, j int, v float64) { + if uint(i) >= uint(t.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(t.mat.N) { + panic(ErrColAccess) + } + isUpper := t.isUpper() + if (isUpper && i > j) || (!isUpper && i < j) { + panic(ErrTriangleSet) + } + t.mat.Data[i*t.mat.Stride+j] = v +} + +// At returns the element at row i, column j. +func (b *BandDense) At(i, j int) float64 { + return b.at(i, j) +} + +func (b *BandDense) at(i, j int) float64 { + if uint(i) >= uint(b.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(b.mat.Cols) { + panic(ErrColAccess) + } + pj := j + b.mat.KL - i + if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj { + return 0 + } + return b.mat.Data[i*b.mat.Stride+pj] +} + +// SetBand sets the element at row i, column j to the value v. +// It panics if the location is outside the appropriate region of the matrix. +func (b *BandDense) SetBand(i, j int, v float64) { + b.set(i, j, v) +} + +func (b *BandDense) set(i, j int, v float64) { + if uint(i) >= uint(b.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(b.mat.Cols) { + panic(ErrColAccess) + } + pj := j + b.mat.KL - i + if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj { + panic(ErrBandSet) + } + b.mat.Data[i*b.mat.Stride+pj] = v +} + +// At returns the element at row i, column j. +func (s *SymBandDense) At(i, j int) float64 { + return s.at(i, j) +} + +func (s *SymBandDense) at(i, j int) float64 { + if uint(i) >= uint(s.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(s.mat.N) { + panic(ErrColAccess) + } + if i > j { + i, j = j, i + } + pj := j - i + if s.mat.K+1 <= pj { + return 0 + } + return s.mat.Data[i*s.mat.Stride+pj] +} + +// SetSymBand sets the element at row i, column j to the value v. +// It panics if the location is outside the appropriate region of the matrix. +func (s *SymBandDense) SetSymBand(i, j int, v float64) { + s.set(i, j, v) +} + +func (s *SymBandDense) set(i, j int, v float64) { + if uint(i) >= uint(s.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(s.mat.N) { + panic(ErrColAccess) + } + if i > j { + i, j = j, i + } + pj := j - i + if s.mat.K+1 <= pj { + panic(ErrBandSet) + } + s.mat.Data[i*s.mat.Stride+pj] = v +} diff --git a/vendor/gonum.org/v1/gonum/mat/index_no_bound_checks.go b/vendor/gonum.org/v1/gonum/mat/index_no_bound_checks.go new file mode 100644 index 00000000..2aa378cb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/index_no_bound_checks.go @@ -0,0 +1,228 @@ +// 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. + +// This file must be kept in sync with index_bound_checks.go. + +//+build !bounds + +package mat + +// At returns the element at row i, column j. +func (m *Dense) At(i, j int) float64 { + if uint(i) >= uint(m.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(m.mat.Cols) { + panic(ErrColAccess) + } + return m.at(i, j) +} + +func (m *Dense) at(i, j int) float64 { + return m.mat.Data[i*m.mat.Stride+j] +} + +// Set sets the element at row i, column j to the value v. +func (m *Dense) Set(i, j int, v float64) { + if uint(i) >= uint(m.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(m.mat.Cols) { + panic(ErrColAccess) + } + m.set(i, j, v) +} + +func (m *Dense) set(i, j int, v float64) { + m.mat.Data[i*m.mat.Stride+j] = v +} + +// At returns the element at row i. +// It panics if i is out of bounds or if j is not zero. +func (v *VecDense) At(i, j int) float64 { + if uint(i) >= uint(v.n) { + panic(ErrRowAccess) + } + if j != 0 { + panic(ErrColAccess) + } + return v.at(i) +} + +func (v *VecDense) at(i int) float64 { + return v.mat.Data[i*v.mat.Inc] +} + +// SetVec sets the element at row i to the value val. +// It panics if i is out of bounds. +func (v *VecDense) SetVec(i int, val float64) { + if uint(i) >= uint(v.n) { + panic(ErrVectorAccess) + } + v.setVec(i, val) +} + +func (v *VecDense) setVec(i int, val float64) { + v.mat.Data[i*v.mat.Inc] = val +} + +// At returns the element at row i and column j. +func (s *SymDense) At(i, j int) float64 { + if uint(i) >= uint(s.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(s.mat.N) { + panic(ErrColAccess) + } + return s.at(i, j) +} + +func (s *SymDense) at(i, j int) float64 { + if i > j { + i, j = j, i + } + return s.mat.Data[i*s.mat.Stride+j] +} + +// SetSym sets the elements at (i,j) and (j,i) to the value v. +func (s *SymDense) SetSym(i, j int, v float64) { + if uint(i) >= uint(s.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(s.mat.N) { + panic(ErrColAccess) + } + s.set(i, j, v) +} + +func (s *SymDense) set(i, j int, v float64) { + if i > j { + i, j = j, i + } + s.mat.Data[i*s.mat.Stride+j] = v +} + +// At returns the element at row i, column j. +func (t *TriDense) At(i, j int) float64 { + if uint(i) >= uint(t.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(t.mat.N) { + panic(ErrColAccess) + } + return t.at(i, j) +} + +func (t *TriDense) at(i, j int) float64 { + isUpper := t.triKind() + if (isUpper && i > j) || (!isUpper && i < j) { + return 0 + } + return t.mat.Data[i*t.mat.Stride+j] +} + +// SetTri sets the element at row i, column j to the value v. +// It panics if the location is outside the appropriate half of the matrix. +func (t *TriDense) SetTri(i, j int, v float64) { + if uint(i) >= uint(t.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(t.mat.N) { + panic(ErrColAccess) + } + isUpper := t.isUpper() + if (isUpper && i > j) || (!isUpper && i < j) { + panic(ErrTriangleSet) + } + t.set(i, j, v) +} + +func (t *TriDense) set(i, j int, v float64) { + t.mat.Data[i*t.mat.Stride+j] = v +} + +// At returns the element at row i, column j. +func (b *BandDense) At(i, j int) float64 { + if uint(i) >= uint(b.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(b.mat.Cols) { + panic(ErrColAccess) + } + return b.at(i, j) +} + +func (b *BandDense) at(i, j int) float64 { + pj := j + b.mat.KL - i + if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj { + return 0 + } + return b.mat.Data[i*b.mat.Stride+pj] +} + +// SetBand sets the element at row i, column j to the value v. +// It panics if the location is outside the appropriate region of the matrix. +func (b *BandDense) SetBand(i, j int, v float64) { + if uint(i) >= uint(b.mat.Rows) { + panic(ErrRowAccess) + } + if uint(j) >= uint(b.mat.Cols) { + panic(ErrColAccess) + } + pj := j + b.mat.KL - i + if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj { + panic(ErrBandSet) + } + b.set(i, j, v) +} + +func (b *BandDense) set(i, j int, v float64) { + pj := j + b.mat.KL - i + b.mat.Data[i*b.mat.Stride+pj] = v +} + +// At returns the element at row i, column j. +func (s *SymBandDense) At(i, j int) float64 { + if uint(i) >= uint(s.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(s.mat.N) { + panic(ErrColAccess) + } + return s.at(i, j) +} + +func (s *SymBandDense) at(i, j int) float64 { + if i > j { + i, j = j, i + } + pj := j - i + if s.mat.K+1 <= pj { + return 0 + } + return s.mat.Data[i*s.mat.Stride+pj] +} + +// SetSymBand sets the element at row i, column j to the value v. +// It panics if the location is outside the appropriate region of the matrix. +func (s *SymBandDense) SetSymBand(i, j int, v float64) { + if uint(i) >= uint(s.mat.N) { + panic(ErrRowAccess) + } + if uint(j) >= uint(s.mat.N) { + panic(ErrColAccess) + } + s.set(i, j, v) +} + +func (s *SymBandDense) set(i, j int, v float64) { + if i > j { + i, j = j, i + } + pj := j - i + if s.mat.K+1 <= pj { + panic(ErrBandSet) + } + s.mat.Data[i*s.mat.Stride+pj] = v +} diff --git a/vendor/gonum.org/v1/gonum/mat/inner.go b/vendor/gonum.org/v1/gonum/mat/inner.go new file mode 100644 index 00000000..1acc615e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/inner.go @@ -0,0 +1,102 @@ +// 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 mat + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/internal/asm/f64" +) + +// Inner computes the generalized inner product +// x^T A y +// between vectors x and y with matrix A. This is only a true inner product if +// A is symmetric positive definite, though the operation works for any matrix A. +// +// Inner panics if x.Len != m or y.Len != n when A is an m x n matrix. +func Inner(x *VecDense, A Matrix, y *VecDense) float64 { + m, n := A.Dims() + if x.Len() != m { + panic(ErrShape) + } + if y.Len() != n { + panic(ErrShape) + } + if m == 0 || n == 0 { + return 0 + } + + var sum float64 + + switch b := A.(type) { + case RawSymmetricer: + bmat := b.RawSymmetric() + if bmat.Uplo != blas.Upper { + // Panic as a string not a mat.Error. + panic(badSymTriangle) + } + for i := 0; i < x.Len(); i++ { + xi := x.at(i) + if xi != 0 { + if y.mat.Inc == 1 { + sum += xi * f64.DotUnitary( + bmat.Data[i*bmat.Stride+i:i*bmat.Stride+n], + y.mat.Data[i:], + ) + } else { + sum += xi * f64.DotInc( + bmat.Data[i*bmat.Stride+i:i*bmat.Stride+n], + y.mat.Data[i*y.mat.Inc:], uintptr(n-i), + 1, uintptr(y.mat.Inc), + 0, 0, + ) + } + } + yi := y.at(i) + if i != n-1 && yi != 0 { + if x.mat.Inc == 1 { + sum += yi * f64.DotUnitary( + bmat.Data[i*bmat.Stride+i+1:i*bmat.Stride+n], + x.mat.Data[i+1:], + ) + } else { + sum += yi * f64.DotInc( + bmat.Data[i*bmat.Stride+i+1:i*bmat.Stride+n], + x.mat.Data[(i+1)*x.mat.Inc:], uintptr(n-i-1), + 1, uintptr(x.mat.Inc), + 0, 0, + ) + } + } + } + case RawMatrixer: + bmat := b.RawMatrix() + for i := 0; i < x.Len(); i++ { + xi := x.at(i) + if xi != 0 { + if y.mat.Inc == 1 { + sum += xi * f64.DotUnitary( + bmat.Data[i*bmat.Stride:i*bmat.Stride+n], + y.mat.Data, + ) + } else { + sum += xi * f64.DotInc( + bmat.Data[i*bmat.Stride:i*bmat.Stride+n], + y.mat.Data, uintptr(n), + 1, uintptr(y.mat.Inc), + 0, 0, + ) + } + } + } + default: + for i := 0; i < x.Len(); i++ { + xi := x.at(i) + for j := 0; j < y.Len(); j++ { + sum += xi * A.At(i, j) * y.at(j) + } + } + } + return sum +} diff --git a/vendor/gonum.org/v1/gonum/mat/inner_test.go b/vendor/gonum.org/v1/gonum/mat/inner_test.go new file mode 100644 index 00000000..05a76b72 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/inner_test.go @@ -0,0 +1,181 @@ +// 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 mat + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/blas/testblas" +) + +func TestInner(t *testing.T) { + for i, test := range []struct { + x []float64 + y []float64 + m [][]float64 + }{ + { + x: []float64{5}, + y: []float64{10}, + m: [][]float64{{2}}, + }, + { + x: []float64{5, 6, 1}, + y: []float64{10}, + m: [][]float64{{2}, {-3}, {5}}, + }, + { + x: []float64{5}, + y: []float64{10, 15}, + m: [][]float64{{2, -3}}, + }, + { + x: []float64{1, 5}, + y: []float64{10, 15}, + m: [][]float64{ + {2, -3}, + {4, -1}, + }, + }, + { + x: []float64{2, 3, 9}, + y: []float64{8, 9}, + m: [][]float64{ + {2, 3}, + {4, 5}, + {6, 7}, + }, + }, + { + x: []float64{2, 3}, + y: []float64{8, 9, 9}, + m: [][]float64{ + {2, 3, 6}, + {4, 5, 7}, + }, + }, + } { + for _, inc := range []struct{ x, y int }{ + {1, 1}, + {1, 2}, + {2, 1}, + {2, 2}, + } { + x := NewDense(1, len(test.x), test.x) + m := NewDense(flatten(test.m)) + mWant := NewDense(flatten(test.m)) + y := NewDense(len(test.y), 1, test.y) + + var tmp, cell Dense + tmp.Mul(mWant, y) + cell.Mul(x, &tmp) + + rm, cm := cell.Dims() + if rm != 1 { + t.Errorf("Test %d result doesn't have 1 row", i) + } + if cm != 1 { + t.Errorf("Test %d result doesn't have 1 column", i) + } + + want := cell.At(0, 0) + got := Inner(makeVecDenseInc(inc.x, test.x), m, makeVecDenseInc(inc.y, test.y)) + if got != want { + t.Errorf("Test %v: want %v, got %v", i, want, got) + } + } + } +} + +func TestInnerSym(t *testing.T) { + for _, inc := range []struct{ x, y int }{ + {1, 1}, + {1, 2}, + {2, 1}, + {2, 2}, + } { + n := 10 + xData := make([]float64, n) + yData := make([]float64, n) + data := make([]float64, n*n) + for i := 0; i < n; i++ { + xData[i] = float64(i) + yData[i] = float64(i) + for j := i; j < n; j++ { + data[i*n+j] = float64(i*n + j) + data[j*n+i] = data[i*n+j] + } + } + x := makeVecDenseInc(inc.x, xData) + y := makeVecDenseInc(inc.y, yData) + m := NewDense(n, n, data) + ans := Inner(x, m, y) + sym := NewSymDense(n, data) + // Poison the lower half of data to ensure it is not used. + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + data[i*n+j] = math.NaN() + } + } + + if math.Abs(Inner(x, sym, y)-ans) > 1e-14 { + t.Error("inner different symmetric and dense") + } + } +} + +func makeVecDenseInc(inc int, f []float64) *VecDense { + v := &VecDense{ + n: len(f), + mat: blas64.Vector{ + Inc: inc, + Data: make([]float64, (len(f)-1)*inc+1), + }, + } + + // Contaminate backing data in all positions... + const base = 100 + for i := range v.mat.Data { + v.mat.Data[i] = float64(i + base) + } + + // then write real elements. + for i := range f { + v.mat.Data[i*inc] = f[i] + } + return v +} + +func benchmarkInner(b *testing.B, m, n int) { + x := NewVecDense(m, nil) + randomSlice(x.mat.Data) + y := NewVecDense(n, nil) + randomSlice(y.mat.Data) + data := make([]float64, m*n) + randomSlice(data) + mat := &Dense{mat: blas64.General{Rows: m, Cols: n, Stride: n, Data: data}, capRows: m, capCols: n} + b.ResetTimer() + for i := 0; i < b.N; i++ { + Inner(x, mat, y) + } +} + +func BenchmarkInnerSmSm(b *testing.B) { + benchmarkInner(b, testblas.SmallMat, testblas.SmallMat) +} + +func BenchmarkInnerMedMed(b *testing.B) { + benchmarkInner(b, testblas.MediumMat, testblas.MediumMat) +} + +func BenchmarkInnerLgLg(b *testing.B) { + benchmarkInner(b, testblas.LargeMat, testblas.LargeMat) +} + +func BenchmarkInnerLgSm(b *testing.B) { + benchmarkInner(b, testblas.LargeMat, testblas.SmallMat) +} diff --git a/vendor/gonum.org/v1/gonum/mat/io.go b/vendor/gonum.org/v1/gonum/mat/io.go new file mode 100644 index 00000000..db429bfa --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/io.go @@ -0,0 +1,360 @@ +// 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 mat + +import ( + "encoding/binary" + "errors" + "io" + "math" +) + +const ( + // maxLen is the biggest slice/array len one can create on a 32/64b platform. + maxLen = int64(int(^uint(0) >> 1)) +) + +var ( + sizeInt64 = binary.Size(int64(0)) + sizeFloat64 = binary.Size(float64(0)) + + errTooBig = errors.New("mat: resulting data slice too big") + errTooSmall = errors.New("mat: input slice too small") + errBadBuffer = errors.New("mat: data buffer size mismatch") + errBadSize = errors.New("mat: invalid dimension") +) + +// MarshalBinary encodes the receiver into a binary form and returns the result. +// +// Dense is little-endian encoded as follows: +// 0 - 7 number of rows (int64) +// 8 - 15 number of columns (int64) +// 16 - .. matrix data elements (float64) +// [0,0] [0,1] ... [0,ncols-1] +// [1,0] [1,1] ... [1,ncols-1] +// ... +// [nrows-1,0] ... [nrows-1,ncols-1] +func (m Dense) MarshalBinary() ([]byte, error) { + bufLen := int64(m.mat.Rows)*int64(m.mat.Cols)*int64(sizeFloat64) + 2*int64(sizeInt64) + if bufLen <= 0 { + // bufLen is too big and has wrapped around. + return nil, errTooBig + } + + p := 0 + buf := make([]byte, bufLen) + binary.LittleEndian.PutUint64(buf[p:p+sizeInt64], uint64(m.mat.Rows)) + p += sizeInt64 + binary.LittleEndian.PutUint64(buf[p:p+sizeInt64], uint64(m.mat.Cols)) + p += sizeInt64 + + r, c := m.Dims() + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + binary.LittleEndian.PutUint64(buf[p:p+sizeFloat64], math.Float64bits(m.at(i, j))) + p += sizeFloat64 + } + } + + return buf, nil +} + +// MarshalBinaryTo encodes the receiver into a binary form and writes it into w. +// MarshalBinaryTo returns the number of bytes written into w and an error, if any. +// +// See MarshalBinary for the on-disk layout. +func (m Dense) MarshalBinaryTo(w io.Writer) (int, error) { + var n int + var buf [8]byte + binary.LittleEndian.PutUint64(buf[:], uint64(m.mat.Rows)) + nn, err := w.Write(buf[:]) + n += nn + if err != nil { + return n, err + } + binary.LittleEndian.PutUint64(buf[:], uint64(m.mat.Cols)) + nn, err = w.Write(buf[:]) + n += nn + if err != nil { + return n, err + } + + r, c := m.Dims() + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + binary.LittleEndian.PutUint64(buf[:], math.Float64bits(m.at(i, j))) + nn, err = w.Write(buf[:]) + n += nn + if err != nil { + return n, err + } + } + } + + return n, nil +} + +// UnmarshalBinary decodes the binary form into the receiver. +// It panics if the receiver is a non-zero Dense matrix. +// +// See MarshalBinary for the on-disk layout. +// +// Limited checks on the validity of the binary input are performed: +// - matrix.ErrShape is returned if the number of rows or columns is negative, +// - an error is returned if the resulting Dense matrix is too +// big for the current architecture (e.g. a 16GB matrix written by a +// 64b application and read back from a 32b application.) +// UnmarshalBinary does not limit the size of the unmarshaled matrix, and so +// it should not be used on untrusted data. +func (m *Dense) UnmarshalBinary(data []byte) error { + if !m.IsZero() { + panic("mat: unmarshal into non-zero matrix") + } + + if len(data) < 2*sizeInt64 { + return errTooSmall + } + + p := 0 + rows := int64(binary.LittleEndian.Uint64(data[p : p+sizeInt64])) + p += sizeInt64 + cols := int64(binary.LittleEndian.Uint64(data[p : p+sizeInt64])) + p += sizeInt64 + if rows < 0 || cols < 0 { + return errBadSize + } + + size := rows * cols + if int(size) < 0 || size > maxLen { + return errTooBig + } + + if len(data) != int(size)*sizeFloat64+2*sizeInt64 { + return errBadBuffer + } + + m.reuseAs(int(rows), int(cols)) + for i := range m.mat.Data { + m.mat.Data[i] = math.Float64frombits(binary.LittleEndian.Uint64(data[p : p+sizeFloat64])) + p += sizeFloat64 + } + + return nil +} + +// UnmarshalBinaryFrom decodes the binary form into the receiver and returns +// the number of bytes read and an error if any. +// It panics if the receiver is a non-zero Dense matrix. +// +// See MarshalBinary for the on-disk layout. +// +// Limited checks on the validity of the binary input are performed: +// - matrix.ErrShape is returned if the number of rows or columns is negative, +// - an error is returned if the resulting Dense matrix is too +// big for the current architecture (e.g. a 16GB matrix written by a +// 64b application and read back from a 32b application.) +// UnmarshalBinary does not limit the size of the unmarshaled matrix, and so +// it should not be used on untrusted data. +func (m *Dense) UnmarshalBinaryFrom(r io.Reader) (int, error) { + if !m.IsZero() { + panic("mat: unmarshal into non-zero matrix") + } + + var ( + n int + buf [8]byte + ) + nn, err := readFull(r, buf[:]) + n += nn + if err != nil { + return n, err + } + rows := int64(binary.LittleEndian.Uint64(buf[:])) + + nn, err = readFull(r, buf[:]) + n += nn + if err != nil { + return n, err + } + cols := int64(binary.LittleEndian.Uint64(buf[:])) + if rows < 0 || cols < 0 { + return n, errBadSize + } + + size := rows * cols + if int(size) < 0 || size > maxLen { + return n, errTooBig + } + + m.reuseAs(int(rows), int(cols)) + for i := range m.mat.Data { + nn, err = readFull(r, buf[:]) + n += nn + if err != nil { + return n, err + } + m.mat.Data[i] = math.Float64frombits(binary.LittleEndian.Uint64(buf[:])) + } + + return n, nil +} + +// MarshalBinary encodes the receiver into a binary form and returns the result. +// +// VecDense is little-endian encoded as follows: +// 0 - 7 number of elements (int64) +// 8 - .. vector's data elements (float64) +func (v VecDense) MarshalBinary() ([]byte, error) { + bufLen := int64(sizeInt64) + int64(v.n)*int64(sizeFloat64) + if bufLen <= 0 { + // bufLen is too big and has wrapped around. + return nil, errTooBig + } + + p := 0 + buf := make([]byte, bufLen) + binary.LittleEndian.PutUint64(buf[p:p+sizeInt64], uint64(v.n)) + p += sizeInt64 + + for i := 0; i < v.n; i++ { + binary.LittleEndian.PutUint64(buf[p:p+sizeFloat64], math.Float64bits(v.at(i))) + p += sizeFloat64 + } + + return buf, nil +} + +// MarshalBinaryTo encodes the receiver into a binary form, writes it to w and +// returns the number of bytes written and an error if any. +// +// See MarshalBainry for the on-disk format. +func (v VecDense) MarshalBinaryTo(w io.Writer) (int, error) { + var ( + n int + buf [8]byte + ) + + binary.LittleEndian.PutUint64(buf[:], uint64(v.n)) + nn, err := w.Write(buf[:]) + n += nn + if err != nil { + return n, err + } + + for i := 0; i < v.n; i++ { + binary.LittleEndian.PutUint64(buf[:], math.Float64bits(v.at(i))) + nn, err = w.Write(buf[:]) + n += nn + if err != nil { + return n, err + } + } + + return n, nil +} + +// UnmarshalBinary decodes the binary form into the receiver. +// It panics if the receiver is a non-zero VecDense. +// +// See MarshalBinary for the on-disk layout. +// +// Limited checks on the validity of the binary input are performed: +// - matrix.ErrShape is returned if the number of rows is negative, +// - an error is returned if the resulting VecDense is too +// big for the current architecture (e.g. a 16GB vector written by a +// 64b application and read back from a 32b application.) +// UnmarshalBinary does not limit the size of the unmarshaled vector, and so +// it should not be used on untrusted data. +func (v *VecDense) UnmarshalBinary(data []byte) error { + if !v.IsZero() { + panic("mat: unmarshal into non-zero vector") + } + + p := 0 + n := int64(binary.LittleEndian.Uint64(data[p : p+sizeInt64])) + p += sizeInt64 + if n < 0 { + return errBadSize + } + if n > maxLen { + return errTooBig + } + if len(data) != int(n)*sizeFloat64+sizeInt64 { + return errBadBuffer + } + + v.reuseAs(int(n)) + for i := range v.mat.Data { + v.mat.Data[i] = math.Float64frombits(binary.LittleEndian.Uint64(data[p : p+sizeFloat64])) + p += sizeFloat64 + } + + return nil +} + +// UnmarshalBinaryFrom decodes the binary form into the receiver, from the +// io.Reader and returns the number of bytes read and an error if any. +// It panics if the receiver is a non-zero VecDense. +// +// See MarshalBinary for the on-disk layout. +// See UnmarshalBinary for the list of sanity checks performed on the input. +func (v *VecDense) UnmarshalBinaryFrom(r io.Reader) (int, error) { + if !v.IsZero() { + panic("mat: unmarshal into non-zero vector") + } + + var ( + n int + buf [8]byte + ) + nn, err := readFull(r, buf[:]) + n += nn + if err != nil { + return n, err + } + sz := int64(binary.LittleEndian.Uint64(buf[:])) + if sz < 0 { + return n, errBadSize + } + if sz > maxLen { + return n, errTooBig + } + + v.reuseAs(int(sz)) + for i := range v.mat.Data { + nn, err = readFull(r, buf[:]) + n += nn + if err != nil { + return n, err + } + v.mat.Data[i] = math.Float64frombits(binary.LittleEndian.Uint64(buf[:])) + } + + if n != sizeInt64+int(sz)*sizeFloat64 { + return n, io.ErrUnexpectedEOF + } + + return n, nil +} + +// readFull reads from r into buf until it has read len(buf). +// It returns the number of bytes copied and an error if fewer bytes were read. +// If an EOF happens after reading fewer than len(buf) bytes, io.ErrUnexpectedEOF is returned. +func readFull(r io.Reader, buf []byte) (int, error) { + var n int + var err error + for n < len(buf) && err == nil { + var nn int + nn, err = r.Read(buf[n:]) + n += nn + } + if n == len(buf) { + return n, nil + } + if err == io.EOF { + return n, io.ErrUnexpectedEOF + } + return n, err +} diff --git a/vendor/gonum.org/v1/gonum/mat/io_test.go b/vendor/gonum.org/v1/gonum/mat/io_test.go new file mode 100644 index 00000000..e2dd639d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/io_test.go @@ -0,0 +1,731 @@ +// 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 mat + +import ( + "bytes" + "encoding" + "io" + "io/ioutil" + "math" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +var ( + _ encoding.BinaryMarshaler = (*Dense)(nil) + _ encoding.BinaryUnmarshaler = (*Dense)(nil) + _ encoding.BinaryMarshaler = (*VecDense)(nil) + _ encoding.BinaryUnmarshaler = (*VecDense)(nil) +) + +var denseData = []struct { + raw []byte + want *Dense + eq func(got, want Matrix) bool +}{ + { + raw: []byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), + want: NewDense(0, 0, []float64{}), + eq: Equal, + }, + { + raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"), + want: NewDense(2, 2, []float64{1, 2, 3, 4}), + eq: Equal, + }, + { + raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"), + want: NewDense(2, 3, []float64{1, 2, 3, 4, 5, 6}), + eq: Equal, + }, + { + raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"), + want: NewDense(3, 2, []float64{1, 2, 3, 4, 5, 6}), + eq: Equal, + }, + { + raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"), + want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}), + eq: Equal, + }, + { + raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@"), + want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).Slice(0, 2, 0, 2).(*Dense), + eq: Equal, + }, + { + raw: []byte("\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"), + want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).Slice(1, 3, 1, 3).(*Dense), + eq: Equal, + }, + { + raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"), + want: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).Slice(0, 3, 1, 3).(*Dense), + eq: Equal, + }, + { + raw: []byte("\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\xf0\u007f\x01\x00\x00\x00\x00\x00\xf8\u007f"), + want: NewDense(1, 4, []float64{0, math.Inf(-1), math.Inf(+1), math.NaN()}), + eq: func(got, want Matrix) bool { + for _, v := range []bool{ + got.At(0, 0) == 0, + math.IsInf(got.At(0, 1), -1), + math.IsInf(got.At(0, 2), +1), + math.IsNaN(got.At(0, 3)), + } { + if !v { + return false + } + } + return true + }, + }, +} + +func TestDenseMarshal(t *testing.T) { + for i, test := range denseData { + buf, err := test.want.MarshalBinary() + if err != nil { + t.Errorf("error encoding test-%d: %v\n", i, err) + continue + } + + nrows, ncols := test.want.Dims() + sz := nrows*ncols*sizeFloat64 + 2*sizeInt64 + if len(buf) != sz { + t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, len(buf)) + } + + if !bytes.Equal(buf, test.raw) { + t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n", + i, + string(buf), + string(test.raw), + ) + continue + } + } +} + +func TestDenseMarshalTo(t *testing.T) { + for i, test := range denseData { + buf := new(bytes.Buffer) + n, err := test.want.MarshalBinaryTo(buf) + if err != nil { + t.Errorf("error encoding test-%d: %v\n", i, err) + continue + } + + nrows, ncols := test.want.Dims() + sz := nrows*ncols*sizeFloat64 + 2*sizeInt64 + if n != sz { + t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, n) + } + + if !bytes.Equal(buf.Bytes(), test.raw) { + t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n", + i, + string(buf.Bytes()), + string(test.raw), + ) + continue + } + } +} + +func TestDenseUnmarshal(t *testing.T) { + for i, test := range denseData { + var v Dense + err := v.UnmarshalBinary(test.raw) + if err != nil { + t.Errorf("error decoding test-%d: %v\n", i, err) + continue + } + if !test.eq(&v, test.want) { + t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n", + i, + &v, + test.want, + ) + } + } +} + +func TestDenseUnmarshalFrom(t *testing.T) { + for i, test := range denseData { + var v Dense + buf := bytes.NewReader(test.raw) + n, err := v.UnmarshalBinaryFrom(buf) + if err != nil { + t.Errorf("error decoding test-%d: %v\n", i, err) + continue + } + if n != len(test.raw) { + t.Errorf("error decoding test-%d: lengths differ.\n got=%d\nwant=%d\n", + i, n, len(test.raw), + ) + } + if !test.eq(&v, test.want) { + t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n", + i, + &v, + test.want, + ) + } + } +} + +func TestDenseUnmarshalFromError(t *testing.T) { + test := denseData[1] + for i, tt := range []struct { + beg int + end int + }{ + { + beg: 0, + end: len(test.raw) - 1, + }, + { + beg: 0, + end: len(test.raw) - sizeFloat64, + }, + { + beg: 0, + end: 0, + }, + { + beg: 0, + end: 1, + }, + { + beg: 0, + end: sizeInt64, + }, + { + beg: 0, + end: sizeInt64 - 1, + }, + { + beg: 0, + end: sizeInt64 + 1, + }, + { + beg: 0, + end: 2*sizeInt64 - 1, + }, + { + beg: 0, + end: 2 * sizeInt64, + }, + { + beg: 0, + end: 2*sizeInt64 + 1, + }, + { + beg: 0, + end: 2*sizeInt64 + sizeFloat64 - 1, + }, + { + beg: 0, + end: 2*sizeInt64 + sizeFloat64, + }, + { + beg: 0, + end: 2*sizeInt64 + sizeFloat64 + 1, + }, + } { + buf := bytes.NewReader(test.raw[tt.beg:tt.end]) + var m Dense + _, err := m.UnmarshalBinaryFrom(buf) + if err != io.ErrUnexpectedEOF { + t.Errorf("test #%d: error decoding. got=%v. want=%v\n", i, err, io.ErrUnexpectedEOF) + } + } +} + +func TestDenseIORoundTrip(t *testing.T) { + for i, test := range denseData { + buf, err := test.want.MarshalBinary() + if err != nil { + t.Errorf("error encoding test #%d: %v\n", i, err) + } + + var got Dense + err = got.UnmarshalBinary(buf) + if err != nil { + t.Errorf("error decoding test #%d: %v\n", i, err) + } + + if !test.eq(&got, test.want) { + t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &got, test.want) + } + + wbuf := new(bytes.Buffer) + _, err = test.want.MarshalBinaryTo(wbuf) + if err != nil { + t.Errorf("error encoding test #%d: %v\n", i, err) + } + + if !bytes.Equal(buf, wbuf.Bytes()) { + t.Errorf("r/w test #%d encoding via MarshalBinary and MarshalBinaryTo differ:\nwith-stream: %q\n no-stream: %q\n", + i, wbuf.Bytes(), buf, + ) + } + + var wgot Dense + _, err = wgot.UnmarshalBinaryFrom(wbuf) + if err != nil { + t.Errorf("error decoding test #%d: %v\n", i, err) + } + + if !test.eq(&wgot, test.want) { + t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &wgot, test.want) + } + } +} + +var vectorData = []struct { + raw []byte + want *VecDense + eq func(got, want Matrix) bool +}{ + { + raw: []byte("\x00\x00\x00\x00\x00\x00\x00\x00"), + want: NewVecDense(0, []float64{}), + eq: Equal, + }, + { + raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"), + want: NewVecDense(4, []float64{1, 2, 3, 4}), + eq: Equal, + }, + { + raw: []byte("\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@"), + want: NewVecDense(6, []float64{1, 2, 3, 4, 5, 6}), + eq: Equal, + }, + { + raw: []byte("\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @\x00\x00\x00\x00\x00\x00\"@"), + want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}), + eq: Equal, + }, + { + raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@"), + want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 3), + eq: Equal, + }, + { + raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@"), + want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(1, 4), + eq: Equal, + }, + { + raw: []byte("\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x10@\x00\x00\x00\x00\x00\x00\x14@\x00\x00\x00\x00\x00\x00\x18@\x00\x00\x00\x00\x00\x00\x1c@\x00\x00\x00\x00\x00\x00 @"), + want: NewVecDense(9, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}).SliceVec(0, 8), + eq: Equal, + }, + { + raw: []byte("\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b@\x00\x00\x00\x00\x00\x00\x18@"), + want: &VecDense{ + mat: blas64.Vector{ + Data: []float64{0, 1, 2, 3, 4, 5, 6}, + Inc: 3, + }, + n: 3, + }, + eq: Equal, + }, + { + raw: []byte("\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xff\x00\x00\x00\x00\x00\x00\xf0\u007f\x01\x00\x00\x00\x00\x00\xf8\u007f"), + want: NewVecDense(4, []float64{0, math.Inf(-1), math.Inf(+1), math.NaN()}), + eq: func(got, want Matrix) bool { + for _, v := range []bool{ + got.At(0, 0) == 0, + math.IsInf(got.At(1, 0), -1), + math.IsInf(got.At(2, 0), +1), + math.IsNaN(got.At(3, 0)), + } { + if !v { + return false + } + } + return true + }, + }, +} + +func TestVecDenseMarshal(t *testing.T) { + for i, test := range vectorData { + buf, err := test.want.MarshalBinary() + if err != nil { + t.Errorf("error encoding test-%d: %v\n", i, err) + continue + } + + nrows, ncols := test.want.Dims() + sz := nrows*ncols*sizeFloat64 + sizeInt64 + if len(buf) != sz { + t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, len(buf)) + } + + if !bytes.Equal(buf, test.raw) { + t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n", + i, + string(buf), + string(test.raw), + ) + continue + } + } +} + +func TestVecDenseMarshalTo(t *testing.T) { + for i, test := range vectorData { + buf := new(bytes.Buffer) + n, err := test.want.MarshalBinaryTo(buf) + if err != nil { + t.Errorf("error encoding test-%d: %v\n", i, err) + continue + } + + nrows, ncols := test.want.Dims() + sz := nrows*ncols*sizeFloat64 + sizeInt64 + if n != sz { + t.Errorf("encoded size test-%d: want=%d got=%d\n", i, sz, n) + } + + if !bytes.Equal(buf.Bytes(), test.raw) { + t.Errorf("error encoding test-%d: bytes mismatch.\n got=%q\nwant=%q\n", + i, + string(buf.Bytes()), + string(test.raw), + ) + continue + } + } +} + +func TestVecDenseUnmarshal(t *testing.T) { + for i, test := range vectorData { + var v VecDense + err := v.UnmarshalBinary(test.raw) + if err != nil { + t.Errorf("error decoding test-%d: %v\n", i, err) + continue + } + if !test.eq(&v, test.want) { + t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n", + i, + &v, + test.want, + ) + } + } +} + +func TestVecDenseUnmarshalFrom(t *testing.T) { + for i, test := range vectorData { + var v VecDense + buf := bytes.NewReader(test.raw) + n, err := v.UnmarshalBinaryFrom(buf) + if err != nil { + t.Errorf("error decoding test-%d: %v\n", i, err) + continue + } + if n != len(test.raw) { + t.Errorf("error decoding test-%d: lengths differ.\n got=%d\nwant=%d\n", + i, + n, + len(test.raw), + ) + } + if !test.eq(&v, test.want) { + t.Errorf("error decoding test-%d: values differ.\n got=%v\nwant=%v\n", + i, + &v, + test.want, + ) + } + } +} + +func TestVecDenseUnmarshalFromError(t *testing.T) { + test := vectorData[1] + for i, tt := range []struct { + beg int + end int + }{ + { + beg: 0, + end: len(test.raw) - 1, + }, + { + beg: 0, + end: len(test.raw) - sizeFloat64, + }, + { + beg: 0, + end: 0, + }, + { + beg: 0, + end: 1, + }, + { + beg: 0, + end: sizeInt64, + }, + { + beg: 0, + end: sizeInt64 - 1, + }, + { + beg: 0, + end: sizeInt64 + 1, + }, + { + beg: 0, + end: sizeInt64 + sizeFloat64 - 1, + }, + { + beg: 0, + end: sizeInt64 + sizeFloat64, + }, + { + beg: 0, + end: sizeInt64 + sizeFloat64 + 1, + }, + } { + buf := bytes.NewReader(test.raw[tt.beg:tt.end]) + var v VecDense + _, err := v.UnmarshalBinaryFrom(buf) + if err != io.ErrUnexpectedEOF { + t.Errorf("test #%d: error decoding. got=%v. want=%v\n", i, err, io.ErrUnexpectedEOF) + } + } +} + +func TestVecDenseIORoundTrip(t *testing.T) { + for i, test := range vectorData { + buf, err := test.want.MarshalBinary() + if err != nil { + t.Errorf("error encoding test #%d: %v\n", i, err) + } + + var got VecDense + err = got.UnmarshalBinary(buf) + if err != nil { + t.Errorf("error decoding test #%d: %v\n", i, err) + } + if !test.eq(&got, test.want) { + t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &got, test.want) + } + + wbuf := new(bytes.Buffer) + _, err = test.want.MarshalBinaryTo(wbuf) + if err != nil { + t.Errorf("error encoding test #%d: %v\n", i, err) + } + + if !bytes.Equal(buf, wbuf.Bytes()) { + t.Errorf("test #%d encoding via MarshalBinary and MarshalBinaryTo differ:\nwith-stream: %q\n no-stream: %q\n", + i, wbuf.Bytes(), buf, + ) + } + + var wgot VecDense + _, err = wgot.UnmarshalBinaryFrom(wbuf) + if err != nil { + t.Errorf("error decoding test #%d: %v\n", i, err) + } + + if !test.eq(&wgot, test.want) { + t.Errorf("r/w test #%d failed\n got=%#v\nwant=%#v\n", i, &wgot, test.want) + } + } +} + +func BenchmarkMarshalDense10(b *testing.B) { marshalBinaryBenchDense(b, 10) } +func BenchmarkMarshalDense100(b *testing.B) { marshalBinaryBenchDense(b, 100) } +func BenchmarkMarshalDense1000(b *testing.B) { marshalBinaryBenchDense(b, 1000) } +func BenchmarkMarshalDense10000(b *testing.B) { marshalBinaryBenchDense(b, 10000) } + +func marshalBinaryBenchDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + m := NewDense(1, size, data) + b.ResetTimer() + + for n := 0; n < b.N; n++ { + m.MarshalBinary() + } +} + +func BenchmarkUnmarshalDense10(b *testing.B) { unmarshalBinaryBenchDense(b, 10) } +func BenchmarkUnmarshalDense100(b *testing.B) { unmarshalBinaryBenchDense(b, 100) } +func BenchmarkUnmarshalDense1000(b *testing.B) { unmarshalBinaryBenchDense(b, 1000) } +func BenchmarkUnmarshalDense10000(b *testing.B) { unmarshalBinaryBenchDense(b, 10000) } + +func unmarshalBinaryBenchDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + buf, err := NewDense(1, size, data).MarshalBinary() + if err != nil { + b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err) + } + b.ResetTimer() + + for n := 0; n < b.N; n++ { + var m Dense + m.UnmarshalBinary(buf) + } +} + +func BenchmarkMarshalToDense10(b *testing.B) { marshalBinaryToBenchDense(b, 10) } +func BenchmarkMarshalToDense100(b *testing.B) { marshalBinaryToBenchDense(b, 100) } +func BenchmarkMarshalToDense1000(b *testing.B) { marshalBinaryToBenchDense(b, 1000) } +func BenchmarkMarshalToDense10000(b *testing.B) { marshalBinaryToBenchDense(b, 10000) } + +func marshalBinaryToBenchDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + m := NewDense(1, size, data) + w := ioutil.Discard + b.ResetTimer() + + for n := 0; n < b.N; n++ { + m.MarshalBinaryTo(w) + } +} + +type readerTest struct { + buf []byte + pos int +} + +func (r *readerTest) Read(data []byte) (int, error) { + n := copy(data, r.buf[r.pos:r.pos+len(data)]) + r.pos += n + return n, nil +} + +func (r *readerTest) reset() { + r.pos = 0 +} + +func BenchmarkUnmarshalFromDense10(b *testing.B) { unmarshalBinaryFromBenchDense(b, 10) } +func BenchmarkUnmarshalFromDense100(b *testing.B) { unmarshalBinaryFromBenchDense(b, 100) } +func BenchmarkUnmarshalFromDense1000(b *testing.B) { unmarshalBinaryFromBenchDense(b, 1000) } +func BenchmarkUnmarshalFromDense10000(b *testing.B) { unmarshalBinaryFromBenchDense(b, 10000) } + +func unmarshalBinaryFromBenchDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + buf, err := NewDense(1, size, data).MarshalBinary() + if err != nil { + b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err) + } + r := &readerTest{buf: buf} + b.ResetTimer() + + for n := 0; n < b.N; n++ { + var m Dense + m.UnmarshalBinaryFrom(r) + r.reset() + } +} + +func BenchmarkMarshalVecDense10(b *testing.B) { marshalBinaryBenchVecDense(b, 10) } +func BenchmarkMarshalVecDense100(b *testing.B) { marshalBinaryBenchVecDense(b, 100) } +func BenchmarkMarshalVecDense1000(b *testing.B) { marshalBinaryBenchVecDense(b, 1000) } +func BenchmarkMarshalVecDense10000(b *testing.B) { marshalBinaryBenchVecDense(b, 10000) } + +func marshalBinaryBenchVecDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + vec := NewVecDense(size, data) + b.ResetTimer() + + for n := 0; n < b.N; n++ { + vec.MarshalBinary() + } +} + +func BenchmarkUnmarshalVecDense10(b *testing.B) { unmarshalBinaryBenchVecDense(b, 10) } +func BenchmarkUnmarshalVecDense100(b *testing.B) { unmarshalBinaryBenchVecDense(b, 100) } +func BenchmarkUnmarshalVecDense1000(b *testing.B) { unmarshalBinaryBenchVecDense(b, 1000) } +func BenchmarkUnmarshalVecDense10000(b *testing.B) { unmarshalBinaryBenchVecDense(b, 10000) } + +func unmarshalBinaryBenchVecDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + buf, err := NewVecDense(size, data).MarshalBinary() + if err != nil { + b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err) + } + b.ResetTimer() + + for n := 0; n < b.N; n++ { + var vec VecDense + vec.UnmarshalBinary(buf) + } +} + +func BenchmarkMarshalToVecDense10(b *testing.B) { marshalBinaryToBenchVecDense(b, 10) } +func BenchmarkMarshalToVecDense100(b *testing.B) { marshalBinaryToBenchVecDense(b, 100) } +func BenchmarkMarshalToVecDense1000(b *testing.B) { marshalBinaryToBenchVecDense(b, 1000) } +func BenchmarkMarshalToVecDense10000(b *testing.B) { marshalBinaryToBenchVecDense(b, 10000) } + +func marshalBinaryToBenchVecDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + vec := NewVecDense(size, data) + w := ioutil.Discard + b.ResetTimer() + + for n := 0; n < b.N; n++ { + vec.MarshalBinaryTo(w) + } +} + +func BenchmarkUnmarshalFromVecDense10(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 10) } +func BenchmarkUnmarshalFromVecDense100(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 100) } +func BenchmarkUnmarshalFromVecDense1000(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 1000) } +func BenchmarkUnmarshalFromVecDense10000(b *testing.B) { unmarshalBinaryFromBenchVecDense(b, 10000) } + +func unmarshalBinaryFromBenchVecDense(b *testing.B, size int) { + data := make([]float64, size) + for i := range data { + data[i] = float64(i) + } + buf, err := NewVecDense(size, data).MarshalBinary() + if err != nil { + b.Fatalf("error creating binary buffer (size=%d): %v\n", size, err) + } + r := &readerTest{buf: buf} + b.ResetTimer() + + for n := 0; n < b.N; n++ { + var vec VecDense + vec.UnmarshalBinaryFrom(r) + r.reset() + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/list_test.go b/vendor/gonum.org/v1/gonum/mat/list_test.go new file mode 100644 index 00000000..5f0cdafa --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/list_test.go @@ -0,0 +1,1151 @@ +// 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 mat + +import ( + "fmt" + "math" + "math/rand" + "reflect" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +// legalSizeSameRectangular returns whether the two matrices have the same rectangular shape. +func legalSizeSameRectangular(ar, ac, br, bc int) bool { + if ar != br { + return false + } + if ac != bc { + return false + } + return true +} + +// legalSizeSameSquare returns whether the two matrices have the same square shape. +func legalSizeSameSquare(ar, ac, br, bc int) bool { + if ar != br { + return false + } + if ac != bc { + return false + } + if ar != ac { + return false + } + return true +} + +// legalSizeSameHeight returns whether the two matrices have the same number of rows. +func legalSizeSameHeight(ar, _, br, _ int) bool { + return ar == br +} + +// legalSizeSameWidth returns whether the two matrices have the same number of columns. +func legalSizeSameWidth(_, ac, _, bc int) bool { + return ac == bc +} + +// legalSizeSolve returns whether the two matrices can be used in a linear solve. +func legalSizeSolve(ar, ac, br, bc int) bool { + return ar == br +} + +// legalSizeSameVec returns whether the two matrices are column vectors of the +// same dimension. +func legalSizeSameVec(ar, ac, br, bc int) bool { + return ac == 1 && bc == 1 && ar == br +} + +// isAnySize returns true for all matrix sizes. +func isAnySize(ar, ac int) bool { + return true +} + +// isAnySize2 returns true for all matrix sizes. +func isAnySize2(ar, ac, br, bc int) bool { + return true +} + +// isAnyVecDense returns true for any column vector sizes. +func isAnyVecDense(ar, ac int) bool { + return ac == 1 +} + +// isSquare returns whether the input matrix is square. +func isSquare(r, c int) bool { + return r == c +} + +// sameAnswerFloat returns whether the two inputs are both NaN or are equal. +func sameAnswerFloat(a, b interface{}) bool { + if math.IsNaN(a.(float64)) { + return math.IsNaN(b.(float64)) + } + return a.(float64) == b.(float64) +} + +// sameAnswerFloatApproxTol returns a function that determines whether its two +// inputs are both NaN or within tol of each other. +func sameAnswerFloatApproxTol(tol float64) func(a, b interface{}) bool { + return func(a, b interface{}) bool { + if math.IsNaN(a.(float64)) { + return math.IsNaN(b.(float64)) + } + return floats.EqualWithinAbsOrRel(a.(float64), b.(float64), tol, tol) + } +} + +func sameAnswerF64SliceOfSlice(a, b interface{}) bool { + for i, v := range a.([][]float64) { + if same := floats.Same(v, b.([][]float64)[i]); !same { + return false + } + } + return true +} + +// sameAnswerBool returns whether the two inputs have the same value. +func sameAnswerBool(a, b interface{}) bool { + return a.(bool) == b.(bool) +} + +// isAnyType returns true for all Matrix types. +func isAnyType(Matrix) bool { + return true +} + +// legalTypesAll returns true for all Matrix types. +func legalTypesAll(a, b Matrix) bool { + return true +} + +// legalTypeSym returns whether a is a Symmetric. +func legalTypeSym(a Matrix) bool { + _, ok := a.(Symmetric) + return ok +} + +// legalTypesSym returns whether both input arguments are Symmetric. +func legalTypesSym(a, b Matrix) bool { + if _, ok := a.(Symmetric); !ok { + return false + } + if _, ok := b.(Symmetric); !ok { + return false + } + return true +} + +// legalTypeVec returns whether v is a *VecDense. +func legalTypeVec(v Matrix) bool { + _, ok := v.(*VecDense) + return ok +} + +// legalTypesVecVec returns whether both inputs are *VecDense. +func legalTypesVecVec(a, b Matrix) bool { + if _, ok := a.(*VecDense); !ok { + return false + } + if _, ok := b.(*VecDense); !ok { + return false + } + return true +} + +// legalTypesNotVecVec returns whether the first input is an arbitrary Matrix +// and the second input is a *VecDense. +func legalTypesNotVecVec(a, b Matrix) bool { + _, ok := b.(*VecDense) + return ok +} + +// legalDims returns whether {m,n} is a valid dimension of the given matrix type. +func legalDims(a Matrix, m, n int) bool { + switch t := a.(type) { + default: + panic("legal dims type not coded") + case Untransposer: + return legalDims(t.Untranspose(), n, m) + case *Dense, *basicMatrix: + if m < 0 || n < 0 { + return false + } + return true + case *SymDense, *TriDense, *basicSymmetric, *basicTriangular: + if m < 0 || n < 0 || m != n { + return false + } + return true + case *VecDense: + if m < 0 || n < 0 { + return false + } + return n == 1 + } +} + +// returnAs returns the matrix a with the type of t. Used for making a concrete +// type and changing to the basic form. +func returnAs(a, t Matrix) Matrix { + switch mat := a.(type) { + default: + panic("unknown type for a") + case *Dense: + switch t.(type) { + default: + panic("bad type") + case *Dense: + return mat + case *basicMatrix: + return asBasicMatrix(mat) + } + case *SymDense: + switch t.(type) { + default: + panic("bad type") + case *SymDense: + return mat + case *basicSymmetric: + return asBasicSymmetric(mat) + } + case *TriDense: + switch t.(type) { + default: + panic("bad type") + case *TriDense: + return mat + case *basicTriangular: + return asBasicTriangular(mat) + } + } +} + +// retranspose returns the matrix m inside an Untransposer of the type +// of a. +func retranspose(a, m Matrix) Matrix { + switch a.(type) { + case TransposeTri: + return TransposeTri{m.(Triangular)} + case Transpose: + return Transpose{m} + case Untransposer: + panic("unknown transposer type") + default: + panic("a is not an untransposer") + } +} + +// makeRandOf returns a new randomly filled m×n matrix of the underlying matrix type. +func makeRandOf(a Matrix, m, n int) Matrix { + var rMatrix Matrix + switch t := a.(type) { + default: + panic("unknown type for make rand of") + case Untransposer: + rMatrix = retranspose(a, makeRandOf(t.Untranspose(), n, m)) + case *Dense, *basicMatrix: + mat := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + mat.Set(i, j, rand.NormFloat64()) + } + } + rMatrix = returnAs(mat, t) + case *VecDense: + if m == 0 && n == 0 { + return &VecDense{} + } + if n != 1 { + panic(fmt.Sprintf("bad vector size: m = %v, n = %v", m, n)) + } + length := m + inc := 1 + if t.mat.Inc != 0 { + inc = t.mat.Inc + } + mat := &VecDense{ + mat: blas64.Vector{ + Inc: inc, + Data: make([]float64, inc*(length-1)+1), + }, + n: length, + } + for i := 0; i < length; i++ { + mat.SetVec(i, rand.NormFloat64()) + } + return mat + case *SymDense, *basicSymmetric: + if m != n { + panic("bad size") + } + mat := NewSymDense(n, nil) + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + mat.SetSym(i, j, rand.NormFloat64()) + } + } + rMatrix = returnAs(mat, t) + case *TriDense, *basicTriangular: + if m != n { + panic("bad size") + } + + // This is necessary because we are making + // a triangle from the zero value, which + // always returns upper as true. + var triKind TriKind + switch t := t.(type) { + case *TriDense: + triKind = t.triKind() + case *basicTriangular: + triKind = (*TriDense)(t).triKind() + } + + mat := NewTriDense(n, triKind, nil) + if triKind == Upper { + for i := 0; i < m; i++ { + for j := i; j < n; j++ { + mat.SetTri(i, j, rand.NormFloat64()) + } + } + } else { + for i := 0; i < m; i++ { + for j := 0; j <= i; j++ { + mat.SetTri(i, j, rand.NormFloat64()) + } + } + } + rMatrix = returnAs(mat, t) + } + if mr, mc := rMatrix.Dims(); mr != m || mc != n { + panic(fmt.Sprintf("makeRandOf for %T returns wrong size: %d×%d != %d×%d", a, m, n, mr, mc)) + } + return rMatrix +} + +// makeCopyOf returns a copy of the matrix. +func makeCopyOf(a Matrix) Matrix { + switch t := a.(type) { + default: + panic("unknown type in makeCopyOf") + case Untransposer: + return retranspose(a, makeCopyOf(t.Untranspose())) + case *Dense, *basicMatrix: + var m Dense + m.Clone(a) + return returnAs(&m, t) + case *SymDense, *basicSymmetric: + n := t.(Symmetric).Symmetric() + m := NewSymDense(n, nil) + m.CopySym(t.(Symmetric)) + return returnAs(m, t) + case *TriDense, *basicTriangular: + n, upper := t.(Triangular).Triangle() + m := NewTriDense(n, upper, nil) + if upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + m.SetTri(i, j, t.At(i, j)) + } + } + } else { + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + m.SetTri(i, j, t.At(i, j)) + } + } + } + return returnAs(m, t) + case *VecDense: + m := &VecDense{ + mat: blas64.Vector{ + Inc: t.mat.Inc, + Data: make([]float64, t.mat.Inc*(t.n-1)+1), + }, + n: t.n, + } + copy(m.mat.Data, t.mat.Data) + return m + } +} + +// sameType returns true if a and b have the same underlying type. +func sameType(a, b Matrix) bool { + return reflect.ValueOf(a).Type() == reflect.ValueOf(b).Type() +} + +// maybeSame returns true if the two matrices could be represented by the same +// pointer. +func maybeSame(receiver, a Matrix) bool { + rr, rc := receiver.Dims() + u, trans := a.(Untransposer) + if trans { + a = u.Untranspose() + } + if !sameType(receiver, a) { + return false + } + ar, ac := a.Dims() + if rr != ar || rc != ac { + return false + } + if _, ok := a.(Triangular); ok { + // They are both triangular types. The TriType needs to match + _, aKind := a.(Triangular).Triangle() + _, rKind := receiver.(Triangular).Triangle() + if aKind != rKind { + return false + } + } + return true +} + +// equalApprox returns whether the elements of a and b are the same to within +// the tolerance. If ignoreNaN is true the test is relaxed such that NaN == NaN. +func equalApprox(a, b Matrix, tol float64, ignoreNaN bool) bool { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br { + return false + } + if ac != bc { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if !floats.EqualWithinAbsOrRel(a.At(i, j), b.At(i, j), tol, tol) { + if ignoreNaN && math.IsNaN(a.At(i, j)) && math.IsNaN(b.At(i, j)) { + continue + } + return false + } + } + } + return true +} + +// equal returns true if the matrices have equal entries. +func equal(a, b Matrix) bool { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br { + return false + } + if ac != bc { + return false + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.At(i, j) != b.At(i, j) { + return false + } + } + } + return true +} + +// isDiagonal returns whether a is a diagonal matrix. +func isDiagonal(a Matrix) bool { + r, c := a.Dims() + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + if a.At(i, j) != 0 && i != j { + return false + } + } + } + return true +} + +// equalDiagonal returns whether a and b are equal on the diagonal. +func equalDiagonal(a, b Matrix) bool { + ar, ac := a.Dims() + br, bc := a.Dims() + if min(ar, ac) != min(br, bc) { + return false + } + for i := 0; i < min(ar, ac); i++ { + if a.At(i, i) != b.At(i, i) { + return false + } + } + return true +} + +// underlyingData extracts the underlying data of the matrix a. +func underlyingData(a Matrix) []float64 { + switch t := a.(type) { + default: + panic("matrix type not implemented for extracting underlying data") + case Untransposer: + return underlyingData(t.Untranspose()) + case *Dense: + return t.mat.Data + case *SymDense: + return t.mat.Data + case *TriDense: + return t.mat.Data + case *VecDense: + return t.mat.Data + } +} + +// testMatrices is a list of matrix types to test. +// The TriDense types have actual sizes because the return from Triangular is +// only valid when n == 0. +var testMatrices = []Matrix{ + &Dense{}, + &SymDense{}, + NewTriDense(3, true, nil), + NewTriDense(3, false, nil), + NewVecDense(0, nil), + &VecDense{mat: blas64.Vector{Inc: 10}}, + &basicMatrix{}, + &basicSymmetric{}, + &basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Upper}}, + &basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Lower}}, + + Transpose{&Dense{}}, + Transpose{NewTriDense(3, true, nil)}, + TransposeTri{NewTriDense(3, true, nil)}, + Transpose{NewTriDense(3, false, nil)}, + TransposeTri{NewTriDense(3, false, nil)}, + Transpose{NewVecDense(0, nil)}, + Transpose{&VecDense{mat: blas64.Vector{Inc: 10}}}, + Transpose{&basicMatrix{}}, + Transpose{&basicSymmetric{}}, + Transpose{&basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Upper}}}, + Transpose{&basicTriangular{cap: 3, mat: blas64.Triangular{N: 3, Stride: 3, Uplo: blas.Lower}}}, +} + +var sizes = []struct { + ar, ac int +}{ + {1, 1}, + {1, 3}, + {3, 1}, + + {6, 6}, + {6, 11}, + {11, 6}, +} + +func testOneInputFunc(t *testing.T, + // name is the name of the function being tested. + name string, + + // f is the function being tested. + f func(a Matrix) interface{}, + + // denseComparison performs the same operation, but using Dense matrices for + // comparison. + denseComparison func(a *Dense) interface{}, + + // sameAnswer compares the result from two different evaluations of the function + // and returns true if they are the same. The specific function being tested + // determines the definition of "same". It may mean identical or it may mean + // approximately equal. + sameAnswer func(a, b interface{}) bool, + + // legalType returns true if the type of the input is a legal type for the + // input of the function. + legalType func(a Matrix) bool, + + // legalSize returns true if the size is valid for the function. + legalSize func(r, c int) bool, +) { + for _, aMat := range testMatrices { + for _, test := range sizes { + // Skip the test if the argument would not be assignable to the + // method's corresponding input parameter or it is not possible + // to construct an argument of the requested size. + if !legalType(aMat) { + continue + } + if !legalDims(aMat, test.ar, test.ac) { + continue + } + a := makeRandOf(aMat, test.ar, test.ac) + + // Compute the true answer if the sizes are legal. + dimsOK := legalSize(test.ar, test.ac) + var want interface{} + if dimsOK { + var aDense Dense + aDense.Clone(a) + want = denseComparison(&aDense) + } + aCopy := makeCopyOf(a) + // Test the method for a zero-value of the receiver. + aType, aTrans := untranspose(a) + errStr := fmt.Sprintf("%v(%T), size: %#v, atrans %t", name, aType, test, aTrans) + var got interface{} + panicked, err := panics(func() { got = f(a) }) + if !dimsOK && !panicked { + t.Errorf("Did not panic with illegal size: %s", errStr) + continue + } + if dimsOK && panicked { + t.Errorf("Panicked with legal size: %s: %v", errStr, err) + continue + } + if !equal(a, aCopy) { + t.Errorf("First input argument changed in call: %s", errStr) + } + if !dimsOK { + continue + } + if !sameAnswer(want, got) { + t.Errorf("Answer mismatch: %s", errStr) + } + } + } +} + +var sizePairs = []struct { + ar, ac, br, bc int +}{ + {1, 1, 1, 1}, + {6, 6, 6, 6}, + {7, 7, 7, 7}, + + {1, 1, 1, 5}, + {1, 1, 5, 1}, + {1, 5, 1, 1}, + {5, 1, 1, 1}, + + {5, 5, 5, 1}, + {5, 5, 1, 5}, + {5, 1, 5, 5}, + {1, 5, 5, 5}, + + {6, 6, 6, 11}, + {6, 6, 11, 6}, + {6, 11, 6, 6}, + {11, 6, 6, 6}, + {11, 11, 11, 6}, + {11, 11, 6, 11}, + {11, 6, 11, 11}, + {6, 11, 11, 11}, + + {1, 1, 5, 5}, + {1, 5, 1, 5}, + {1, 5, 5, 1}, + {5, 1, 1, 5}, + {5, 1, 5, 1}, + {5, 5, 1, 1}, + {6, 6, 11, 11}, + {6, 11, 6, 11}, + {6, 11, 11, 6}, + {11, 6, 6, 11}, + {11, 6, 11, 6}, + {11, 11, 6, 6}, + + {1, 1, 17, 11}, + {1, 1, 11, 17}, + {1, 11, 1, 17}, + {1, 17, 1, 11}, + {1, 11, 17, 1}, + {1, 17, 11, 1}, + {11, 1, 1, 17}, + {17, 1, 1, 11}, + {11, 1, 17, 1}, + {17, 1, 11, 1}, + {11, 17, 1, 1}, + {17, 11, 1, 1}, + + {6, 6, 1, 11}, + {6, 6, 11, 1}, + {6, 11, 6, 1}, + {6, 1, 6, 11}, + {6, 11, 1, 6}, + {6, 1, 11, 6}, + {11, 6, 6, 1}, + {1, 6, 6, 11}, + {11, 6, 1, 6}, + {1, 6, 11, 6}, + {11, 1, 6, 6}, + {1, 11, 6, 6}, + + {6, 6, 17, 1}, + {6, 6, 1, 17}, + {6, 1, 6, 17}, + {6, 17, 6, 1}, + {6, 1, 17, 6}, + {6, 17, 1, 6}, + {1, 6, 6, 17}, + {17, 6, 6, 1}, + {1, 6, 17, 6}, + {17, 6, 1, 6}, + {1, 17, 6, 6}, + {17, 1, 6, 6}, + + {6, 6, 17, 11}, + {6, 6, 11, 17}, + {6, 11, 6, 17}, + {6, 17, 6, 11}, + {6, 11, 17, 6}, + {6, 17, 11, 6}, + {11, 6, 6, 17}, + {17, 6, 6, 11}, + {11, 6, 17, 6}, + {17, 6, 11, 6}, + {11, 17, 6, 6}, + {17, 11, 6, 6}, +} + +func testTwoInputFunc(t *testing.T, + // name is the name of the function being tested. + name string, + + // f is the function being tested. + f func(a, b Matrix) interface{}, + + // denseComparison performs the same operation, but using Dense matrices for + // comparison. + denseComparison func(a, b *Dense) interface{}, + + // sameAnswer compares the result from two different evaluations of the function + // and returns true if they are the same. The specific function being tested + // determines the definition of "same". It may mean identical or it may mean + // approximately equal. + sameAnswer func(a, b interface{}) bool, + + // legalType returns true if the types of the inputs are legal for the + // input of the function. + legalType func(a, b Matrix) bool, + + // legalSize returns true if the sizes are valid for the function. + legalSize func(ar, ac, br, bc int) bool, +) { + for _, aMat := range testMatrices { + for _, bMat := range testMatrices { + // Loop over all of the size combinations (bigger, smaller, etc.). + for _, test := range sizePairs { + // Skip the test if the argument would not be assignable to the + // method's corresponding input parameter or it is not possible + // to construct an argument of the requested size. + if !legalType(aMat, bMat) { + continue + } + if !legalDims(aMat, test.ar, test.ac) { + continue + } + if !legalDims(bMat, test.br, test.bc) { + continue + } + a := makeRandOf(aMat, test.ar, test.ac) + b := makeRandOf(bMat, test.br, test.bc) + + // Compute the true answer if the sizes are legal. + dimsOK := legalSize(test.ar, test.ac, test.br, test.bc) + var want interface{} + if dimsOK { + var aDense, bDense Dense + aDense.Clone(a) + bDense.Clone(b) + want = denseComparison(&aDense, &bDense) + } + aCopy := makeCopyOf(a) + bCopy := makeCopyOf(b) + // Test the method for a zero-value of the receiver. + aType, aTrans := untranspose(a) + bType, bTrans := untranspose(b) + errStr := fmt.Sprintf("%v(%T, %T), size: %#v, atrans %t, btrans %t", name, aType, bType, test, aTrans, bTrans) + var got interface{} + panicked, err := panics(func() { got = f(a, b) }) + if !dimsOK && !panicked { + t.Errorf("Did not panic with illegal size: %s", errStr) + continue + } + if dimsOK && panicked { + t.Errorf("Panicked with legal size: %s: %v", errStr, err) + continue + } + if !equal(a, aCopy) { + t.Errorf("First input argument changed in call: %s", errStr) + } + if !equal(b, bCopy) { + t.Errorf("First input argument changed in call: %s", errStr) + } + if !dimsOK { + continue + } + if !sameAnswer(want, got) { + t.Errorf("Answer mismatch: %s", errStr) + } + } + } + } +} + +// testOneInput tests a method that has one matrix input argument +func testOneInput(t *testing.T, + // name is the name of the method being tested. + name string, + + // receiver is a value of the receiver type. + receiver Matrix, + + // method is the generalized receiver.Method(a). + method func(receiver, a Matrix), + + // denseComparison performs the same operation as method, but with dense + // matrices for comparison with the result. + denseComparison func(receiver, a *Dense), + + // legalTypes returns whether the concrete types in Matrix are valid for + // the method. + legalType func(a Matrix) bool, + + // legalSize returns whether the matrix sizes are valid for the method. + legalSize func(ar, ac int) bool, + + // tol is the tolerance for equality when comparing method results. + tol float64, +) { + for _, aMat := range testMatrices { + for _, test := range sizes { + // Skip the test if the argument would not be assignable to the + // method's corresponding input parameter or it is not possible + // to construct an argument of the requested size. + if !legalType(aMat) { + continue + } + if !legalDims(aMat, test.ar, test.ac) { + continue + } + a := makeRandOf(aMat, test.ar, test.ac) + + // Compute the true answer if the sizes are legal. + dimsOK := legalSize(test.ar, test.ac) + var want Dense + if dimsOK { + var aDense Dense + aDense.Clone(a) + denseComparison(&want, &aDense) + } + aCopy := makeCopyOf(a) + + // Test the method for a zero-value of the receiver. + aType, aTrans := untranspose(a) + errStr := fmt.Sprintf("%T.%s(%T), size: %#v, atrans %v", receiver, name, aType, test, aTrans) + zero := makeRandOf(receiver, 0, 0) + panicked, err := panics(func() { method(zero, a) }) + if !dimsOK && !panicked { + t.Errorf("Did not panic with illegal size: %s", errStr) + continue + } + if dimsOK && panicked { + t.Errorf("Panicked with legal size: %s: %v", errStr, err) + continue + } + if !equal(a, aCopy) { + t.Errorf("First input argument changed in call: %s", errStr) + } + if !dimsOK { + continue + } + if !equalApprox(zero, &want, tol, false) { + t.Errorf("Answer mismatch with zero receiver: %s.\nGot:\n% v\nWant:\n% v\n", errStr, Formatted(zero), Formatted(&want)) + continue + } + + // Test the method with a non-zero-value of the receiver. + // The receiver has been overwritten in place so use its size + // to construct a new random matrix. + rr, rc := zero.Dims() + neverZero := makeRandOf(receiver, rr, rc) + panicked, _ = panics(func() { method(neverZero, a) }) + if panicked { + t.Errorf("Panicked with non-zero receiver: %s", errStr) + } + if !equalApprox(neverZero, &want, tol, false) { + t.Errorf("Answer mismatch non-zero receiver: %s", errStr) + } + + // Test with an incorrectly sized matrix. + switch receiver.(type) { + default: + panic("matrix type not coded for incorrect receiver size") + case *Dense: + wrongSize := makeRandOf(receiver, rr+1, rc) + panicked, _ = panics(func() { method(wrongSize, a) }) + if !panicked { + t.Errorf("Did not panic with wrong number of rows: %s", errStr) + } + wrongSize = makeRandOf(receiver, rr, rc+1) + panicked, _ = panics(func() { method(wrongSize, a) }) + if !panicked { + t.Errorf("Did not panic with wrong number of columns: %s", errStr) + } + case *TriDense, *SymDense: + // Add to the square size. + wrongSize := makeRandOf(receiver, rr+1, rc+1) + panicked, _ = panics(func() { method(wrongSize, a) }) + if !panicked { + t.Errorf("Did not panic with wrong size: %s", errStr) + } + case *VecDense: + // Add to the column length. + wrongSize := makeRandOf(receiver, rr+1, rc) + panicked, _ = panics(func() { method(wrongSize, a) }) + if !panicked { + t.Errorf("Did not panic with wrong number of rows: %s", errStr) + } + } + + // The receiver and the input may share a matrix pointer + // if the type and size of the receiver and one of the + // arguments match. Test the method works properly + // when this is the case. + aMaybeSame := maybeSame(neverZero, a) + if aMaybeSame { + aSame := makeCopyOf(a) + receiver = aSame + u, ok := aSame.(Untransposer) + if ok { + receiver = u.Untranspose() + } + preData := underlyingData(receiver) + panicked, err = panics(func() { method(receiver, aSame) }) + if panicked { + t.Errorf("Panics when a maybeSame: %s: %v", errStr, err) + } else { + if !equalApprox(receiver, &want, tol, false) { + t.Errorf("Wrong answer when a maybeSame: %s", errStr) + } + postData := underlyingData(receiver) + if !floats.Equal(preData, postData) { + t.Errorf("Original data slice not modified when a maybeSame: %s", errStr) + } + } + } + } + } +} + +// testTwoInput tests a method that has two input arguments. +func testTwoInput(t *testing.T, + // name is the name of the method being tested. + name string, + + // receiver is a value of the receiver type. + receiver Matrix, + + // method is the generalized receiver.Method(a, b). + method func(receiver, a, b Matrix), + + // denseComparison performs the same operation as method, but with dense + // matrices for comparison with the result. + denseComparison func(receiver, a, b *Dense), + + // legalTypes returns whether the concrete types in Matrix are valid for + // the method. + legalTypes func(a, b Matrix) bool, + + // legalSize returns whether the matrix sizes are valid for the method. + legalSize func(ar, ac, br, bc int) bool, + + // tol is the tolerance for equality when comparing method results. + tol float64, +) { + for _, aMat := range testMatrices { + for _, bMat := range testMatrices { + // Loop over all of the size combinations (bigger, smaller, etc.). + for _, test := range sizePairs { + // Skip the test if any argument would not be assignable to the + // method's corresponding input parameter or it is not possible + // to construct an argument of the requested size. + if !legalTypes(aMat, bMat) { + continue + } + if !legalDims(aMat, test.ar, test.ac) { + continue + } + if !legalDims(bMat, test.br, test.bc) { + continue + } + a := makeRandOf(aMat, test.ar, test.ac) + b := makeRandOf(bMat, test.br, test.bc) + + // Compute the true answer if the sizes are legal. + dimsOK := legalSize(test.ar, test.ac, test.br, test.bc) + var want Dense + if dimsOK { + var aDense, bDense Dense + aDense.Clone(a) + bDense.Clone(b) + denseComparison(&want, &aDense, &bDense) + } + aCopy := makeCopyOf(a) + bCopy := makeCopyOf(b) + + // Test the method for a zero-value of the receiver. + aType, aTrans := untranspose(a) + bType, bTrans := untranspose(b) + errStr := fmt.Sprintf("%T.%s(%T, %T), sizes: %#v, atrans %v, btrans %v", receiver, name, aType, bType, test, aTrans, bTrans) + zero := makeRandOf(receiver, 0, 0) + panicked, err := panics(func() { method(zero, a, b) }) + if !dimsOK && !panicked { + t.Errorf("Did not panic with illegal size: %s", errStr) + continue + } + if dimsOK && panicked { + t.Errorf("Panicked with legal size: %s: %v", errStr, err) + continue + } + if !equal(a, aCopy) { + t.Errorf("First input argument changed in call: %s", errStr) + } + if !equal(b, bCopy) { + t.Errorf("Second input argument changed in call: %s", errStr) + } + if !dimsOK { + continue + } + wasZero, zero := zero, nil // Nil-out zero so we detect illegal use. + // NaN equality is allowed because of 0/0 in DivElem test. + if !equalApprox(wasZero, &want, tol, true) { + t.Errorf("Answer mismatch with zero receiver: %s", errStr) + continue + } + + // Test the method with a non-zero-value of the receiver. + // The receiver has been overwritten in place so use its size + // to construct a new random matrix. + rr, rc := wasZero.Dims() + neverZero := makeRandOf(receiver, rr, rc) + panicked, message := panics(func() { method(neverZero, a, b) }) + if panicked { + t.Errorf("Panicked with non-zero receiver: %s: %s", errStr, message) + } + // NaN equality is allowed because of 0/0 in DivElem test. + if !equalApprox(neverZero, &want, tol, true) { + t.Errorf("Answer mismatch non-zero receiver: %s", errStr) + } + + // Test with an incorrectly sized matrix. + switch receiver.(type) { + default: + panic("matrix type not coded for incorrect receiver size") + case *Dense: + wrongSize := makeRandOf(receiver, rr+1, rc) + panicked, _ = panics(func() { method(wrongSize, a, b) }) + if !panicked { + t.Errorf("Did not panic with wrong number of rows: %s", errStr) + } + wrongSize = makeRandOf(receiver, rr, rc+1) + panicked, _ = panics(func() { method(wrongSize, a, b) }) + if !panicked { + t.Errorf("Did not panic with wrong number of columns: %s", errStr) + } + case *TriDense, *SymDense: + // Add to the square size. + wrongSize := makeRandOf(receiver, rr+1, rc+1) + panicked, _ = panics(func() { method(wrongSize, a, b) }) + if !panicked { + t.Errorf("Did not panic with wrong size: %s", errStr) + } + case *VecDense: + // Add to the column length. + wrongSize := makeRandOf(receiver, rr+1, rc) + panicked, _ = panics(func() { method(wrongSize, a, b) }) + if !panicked { + t.Errorf("Did not panic with wrong number of rows: %s", errStr) + } + } + + // The receiver and an input may share a matrix pointer + // if the type and size of the receiver and one of the + // arguments match. Test the method works properly + // when this is the case. + aMaybeSame := maybeSame(neverZero, a) + bMaybeSame := maybeSame(neverZero, b) + if aMaybeSame { + aSame := makeCopyOf(a) + receiver = aSame + u, ok := aSame.(Untransposer) + if ok { + receiver = u.Untranspose() + } + preData := underlyingData(receiver) + panicked, err = panics(func() { method(receiver, aSame, b) }) + if panicked { + t.Errorf("Panics when a maybeSame: %s: %v", errStr, err) + } else { + if !equalApprox(receiver, &want, tol, false) { + t.Errorf("Wrong answer when a maybeSame: %s", errStr) + } + postData := underlyingData(receiver) + if !floats.Equal(preData, postData) { + t.Errorf("Original data slice not modified when a maybeSame: %s", errStr) + } + } + } + if bMaybeSame { + bSame := makeCopyOf(b) + receiver = bSame + u, ok := bSame.(Untransposer) + if ok { + receiver = u.Untranspose() + } + preData := underlyingData(receiver) + panicked, err = panics(func() { method(receiver, a, bSame) }) + if panicked { + t.Errorf("Panics when b maybeSame: %s: %v", errStr, err) + } else { + if !equalApprox(receiver, &want, tol, false) { + t.Errorf("Wrong answer when b maybeSame: %s", errStr) + } + postData := underlyingData(receiver) + if !floats.Equal(preData, postData) { + t.Errorf("Original data slice not modified when b maybeSame: %s", errStr) + } + } + } + if aMaybeSame && bMaybeSame { + aSame := makeCopyOf(a) + receiver = aSame + u, ok := aSame.(Untransposer) + if ok { + receiver = u.Untranspose() + } + // Ensure that b is the correct transpose type if applicable. + // The receiver is always a concrete type so use it. + bSame := receiver + u, ok = b.(Untransposer) + if ok { + bSame = retranspose(b, receiver) + } + // Compute the real answer for this case. It is different + // from the initial answer since now a and b have the + // same data. + zero = makeRandOf(wasZero, 0, 0) + method(zero, aSame, bSame) + wasZero, zero = zero, nil // Nil-out zero so we detect illegal use. + preData := underlyingData(receiver) + panicked, err = panics(func() { method(receiver, aSame, bSame) }) + if panicked { + t.Errorf("Panics when both maybeSame: %s: %v", errStr, err) + } else { + if !equalApprox(receiver, wasZero, tol, false) { + t.Errorf("Wrong answer when both maybeSame: %s", errStr) + } + postData := underlyingData(receiver) + if !floats.Equal(preData, postData) { + t.Errorf("Original data slice not modified when both maybeSame: %s", errStr) + } + } + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/lq.go b/vendor/gonum.org/v1/gonum/mat/lq.go new file mode 100644 index 00000000..54c49336 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/lq.go @@ -0,0 +1,225 @@ +// 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. + +package mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/lapack64" +) + +// LQ is a type for creating and using the LQ factorization of a matrix. +type LQ struct { + lq *Dense + tau []float64 + cond float64 +} + +func (lq *LQ) updateCond(norm lapack.MatrixNorm) { + // Since A = L*Q, and Q is orthogonal, we get for the condition number κ + // κ(A) := |A| |A^-1| = |L*Q| |(L*Q)^-1| = |L| |Q^T * L^-1| + // = |L| |L^-1| = κ(L), + // where we used that fact that Q^-1 = Q^T. However, this assumes that + // the matrix norm is invariant under orthogonal transformations which + // is not the case for CondNorm. Hopefully the error is negligible: κ + // is only a qualitative measure anyway. + m := lq.lq.mat.Rows + work := getFloats(3*m, false) + iwork := getInts(m, false) + l := lq.lq.asTriDense(m, blas.NonUnit, blas.Lower) + v := lapack64.Trcon(norm, l.mat, work, iwork) + lq.cond = 1 / v + putFloats(work) + putInts(iwork) +} + +// Factorize computes the LQ factorization of an m×n matrix a where n <= m. The LQ +// factorization always exists even if A is singular. +// +// The LQ decomposition is a factorization of the matrix A such that A = L * Q. +// The matrix Q is an orthonormal n×n matrix, and L is an m×n upper triangular matrix. +// L and Q can be extracted from the LTo and QTo methods. +func (lq *LQ) Factorize(a Matrix) { + lq.factorize(a, CondNorm) +} + +func (lq *LQ) factorize(a Matrix, norm lapack.MatrixNorm) { + m, n := a.Dims() + if m > n { + panic(ErrShape) + } + k := min(m, n) + if lq.lq == nil { + lq.lq = &Dense{} + } + lq.lq.Clone(a) + work := []float64{0} + lq.tau = make([]float64, k) + lapack64.Gelqf(lq.lq.mat, lq.tau, work, -1) + work = getFloats(int(work[0]), false) + lapack64.Gelqf(lq.lq.mat, lq.tau, work, len(work)) + putFloats(work) + lq.updateCond(norm) +} + +// Cond returns the condition number for the factorized matrix. +// Cond will panic if the receiver does not contain a successful factorization. +func (lq *LQ) Cond() float64 { + if lq.lq == nil || lq.lq.IsZero() { + panic("lq: no decomposition computed") + } + return lq.cond +} + +// TODO(btracey): Add in the "Reduced" forms for extracting the m×m orthogonal +// and upper triangular matrices. + +// LTo extracts the m×n lower trapezoidal matrix from a LQ decomposition. +// If dst is nil, a new matrix is allocated. The resulting L matrix is returned. +func (lq *LQ) LTo(dst *Dense) *Dense { + r, c := lq.lq.Dims() + if dst == nil { + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(r, c) + } + + // Disguise the LQ as a lower triangular. + t := &TriDense{ + mat: blas64.Triangular{ + N: r, + Stride: lq.lq.mat.Stride, + Data: lq.lq.mat.Data, + Uplo: blas.Lower, + Diag: blas.NonUnit, + }, + cap: lq.lq.capCols, + } + dst.Copy(t) + + if r == c { + return dst + } + // Zero right of the triangular. + for i := 0; i < r; i++ { + zero(dst.mat.Data[i*dst.mat.Stride+r : i*dst.mat.Stride+c]) + } + + return dst +} + +// QTo extracts the n×n orthonormal matrix Q from an LQ decomposition. +// If dst is nil, a new matrix is allocated. The resulting Q matrix is returned. +func (lq *LQ) QTo(dst *Dense) *Dense { + _, c := lq.lq.Dims() + if dst == nil { + dst = NewDense(c, c, nil) + } else { + dst.reuseAsZeroed(c, c) + } + q := dst.mat + + // Set Q = I. + ldq := q.Stride + for i := 0; i < c; i++ { + q.Data[i*ldq+i] = 1 + } + + // Construct Q from the elementary reflectors. + work := []float64{0} + lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, q, work, -1) + work = getFloats(int(work[0]), false) + lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, q, work, len(work)) + putFloats(work) + + return dst +} + +// Solve finds a minimum-norm solution to a system of linear equations defined +// by the matrices A and b, where A is an m×n matrix represented in its LQ factorized +// form. If A is singular or near-singular a Condition error is returned. Please +// see the documentation for Condition for more information. +// +// The minimization problem solved depends on the input parameters. +// If trans == false, find the minimum norm solution of A * X = b. +// If trans == true, find X such that ||A*X - b||_2 is minimized. +// The solution matrix, X, is stored in place into m. +func (lq *LQ) Solve(m *Dense, trans bool, b Matrix) error { + r, c := lq.lq.Dims() + br, bc := b.Dims() + + // The LQ solve algorithm stores the result in-place into the right hand side. + // The storage for the answer must be large enough to hold both b and x. + // However, this method's receiver must be the size of x. Copy b, and then + // copy the result into m at the end. + if trans { + if c != br { + panic(ErrShape) + } + m.reuseAs(r, bc) + } else { + if r != br { + panic(ErrShape) + } + m.reuseAs(c, bc) + } + // Do not need to worry about overlap between m and b because x has its own + // independent storage. + x := getWorkspace(max(r, c), bc, false) + x.Copy(b) + t := lq.lq.asTriDense(lq.lq.mat.Rows, blas.NonUnit, blas.Lower).mat + if trans { + work := []float64{0} + lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, x.mat, work, -1) + work = getFloats(int(work[0]), false) + lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, x.mat, work, len(work)) + putFloats(work) + + ok := lapack64.Trtrs(blas.Trans, t, x.mat) + if !ok { + return Condition(math.Inf(1)) + } + } else { + ok := lapack64.Trtrs(blas.NoTrans, t, x.mat) + if !ok { + return Condition(math.Inf(1)) + } + for i := r; i < c; i++ { + zero(x.mat.Data[i*x.mat.Stride : i*x.mat.Stride+bc]) + } + work := []float64{0} + lapack64.Ormlq(blas.Left, blas.Trans, lq.lq.mat, lq.tau, x.mat, work, -1) + work = getFloats(int(work[0]), false) + lapack64.Ormlq(blas.Left, blas.Trans, lq.lq.mat, lq.tau, x.mat, work, len(work)) + putFloats(work) + } + // M was set above to be the correct size for the result. + m.Copy(x) + putWorkspace(x) + if lq.cond > ConditionTolerance { + return Condition(lq.cond) + } + return nil +} + +// SolveVec finds a minimum-norm solution to a system of linear equations. +// Please see LQ.Solve for the full documentation. +func (lq *LQ) SolveVec(v *VecDense, trans bool, b *VecDense) error { + if v != b { + v.checkOverlap(b.mat) + } + r, c := lq.lq.Dims() + // The Solve implementation is non-trivial, so rather than duplicate the code, + // instead recast the VecDenses as Dense and call the matrix code. + if trans { + v.reuseAs(r) + } else { + v.reuseAs(c) + } + return lq.Solve(v.asDense(), trans, b.asDense()) +} diff --git a/vendor/gonum.org/v1/gonum/mat/lq_test.go b/vendor/gonum.org/v1/gonum/mat/lq_test.go new file mode 100644 index 00000000..9902b62a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/lq_test.go @@ -0,0 +1,179 @@ +// 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. + +package mat + +import ( + "math/rand" + "testing" +) + +func TestLQ(t *testing.T) { + for _, test := range []struct { + m, n int + }{ + {5, 5}, + {5, 10}, + } { + m := test.m + n := test.n + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.NormFloat64()) + } + } + var want Dense + want.Clone(a) + + var lq LQ + lq.Factorize(a) + q := lq.QTo(nil) + + if !isOrthonormal(q, 1e-10) { + t.Errorf("Q is not orthonormal: m = %v, n = %v", m, n) + } + + l := lq.LTo(nil) + + var got Dense + got.Mul(l, q) + if !EqualApprox(&got, &want, 1e-12) { + t.Errorf("LQ does not equal original matrix. \nWant: %v\nGot: %v", want, got) + } + } +} + +func TestSolveLQ(t *testing.T) { + for _, trans := range []bool{false, true} { + for _, test := range []struct { + m, n, bc int + }{ + {5, 5, 1}, + {5, 10, 1}, + {5, 5, 3}, + {5, 10, 3}, + } { + m := test.m + n := test.n + bc := test.bc + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.Float64()) + } + } + br := m + if trans { + br = n + } + b := NewDense(br, bc, nil) + for i := 0; i < br; i++ { + for j := 0; j < bc; j++ { + b.Set(i, j, rand.Float64()) + } + } + var x Dense + lq := &LQ{} + lq.Factorize(a) + lq.Solve(&x, trans, b) + + // Test that the normal equations hold. + // A^T * A * x = A^T * b if !trans + // A * A^T * x = A * b if trans + var lhs Dense + var rhs Dense + if trans { + var tmp Dense + tmp.Mul(a, a.T()) + lhs.Mul(&tmp, &x) + rhs.Mul(a, b) + } else { + var tmp Dense + tmp.Mul(a.T(), a) + lhs.Mul(&tmp, &x) + rhs.Mul(a.T(), b) + } + if !EqualApprox(&lhs, &rhs, 1e-10) { + t.Errorf("Normal equations do not hold.\nLHS: %v\n, RHS: %v\n", lhs, rhs) + } + } + } + // TODO(btracey): Add in testOneInput when it exists. +} + +func TestSolveLQVec(t *testing.T) { + for _, trans := range []bool{false, true} { + for _, test := range []struct { + m, n int + }{ + {5, 5}, + {5, 10}, + } { + m := test.m + n := test.n + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.Float64()) + } + } + br := m + if trans { + br = n + } + b := NewVecDense(br, nil) + for i := 0; i < br; i++ { + b.SetVec(i, rand.Float64()) + } + var x VecDense + lq := &LQ{} + lq.Factorize(a) + lq.SolveVec(&x, trans, b) + + // Test that the normal equations hold. + // A^T * A * x = A^T * b if !trans + // A * A^T * x = A * b if trans + var lhs Dense + var rhs Dense + if trans { + var tmp Dense + tmp.Mul(a, a.T()) + lhs.Mul(&tmp, &x) + rhs.Mul(a, b) + } else { + var tmp Dense + tmp.Mul(a.T(), a) + lhs.Mul(&tmp, &x) + rhs.Mul(a.T(), b) + } + if !EqualApprox(&lhs, &rhs, 1e-10) { + t.Errorf("Normal equations do not hold.\nLHS: %v\n, RHS: %v\n", lhs, rhs) + } + } + } + // TODO(btracey): Add in testOneInput when it exists. +} + +func TestSolveLQCond(t *testing.T) { + for _, test := range []*Dense{ + NewDense(2, 2, []float64{1, 0, 0, 1e-20}), + NewDense(2, 3, []float64{1, 0, 0, 0, 1e-20, 0}), + } { + m, _ := test.Dims() + var lq LQ + lq.Factorize(test) + b := NewDense(m, 2, nil) + var x Dense + if err := lq.Solve(&x, false, b); err == nil { + t.Error("No error for near-singular matrix in matrix solve.") + } + + bvec := NewVecDense(m, nil) + var xvec VecDense + if err := lq.SolveVec(&xvec, false, bvec); err == nil { + t.Error("No error for near-singular matrix in matrix solve.") + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/lu.go b/vendor/gonum.org/v1/gonum/mat/lu.go new file mode 100644 index 00000000..ff0df0cf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/lu.go @@ -0,0 +1,373 @@ +// 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. + +package mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/lapack64" +) + +const badSliceLength = "mat: improper slice length" + +// LU is a type for creating and using the LU factorization of a matrix. +type LU struct { + lu *Dense + pivot []int + cond float64 +} + +// updateCond updates the stored condition number of the matrix. anorm is the +// norm of the original matrix. If anorm is negative it will be estimated. +func (lu *LU) updateCond(anorm float64, norm lapack.MatrixNorm) { + n := lu.lu.mat.Cols + work := getFloats(4*n, false) + defer putFloats(work) + iwork := getInts(n, false) + defer putInts(iwork) + if anorm < 0 { + // This is an approximation. By the definition of a norm, + // |AB| <= |A| |B|. + // Since A = L*U, we get for the condition number κ that + // κ(A) := |A| |A^-1| = |L*U| |A^-1| <= |L| |U| |A^-1|, + // so this will overestimate the condition number somewhat. + // The norm of the original factorized matrix cannot be stored + // because of update possibilities. + u := lu.lu.asTriDense(n, blas.NonUnit, blas.Upper) + l := lu.lu.asTriDense(n, blas.Unit, blas.Lower) + unorm := lapack64.Lantr(norm, u.mat, work) + lnorm := lapack64.Lantr(norm, l.mat, work) + anorm = unorm * lnorm + } + v := lapack64.Gecon(norm, lu.lu.mat, anorm, work, iwork) + lu.cond = 1 / v +} + +// Factorize computes the LU factorization of the square matrix a and stores the +// result. The LU decomposition will complete regardless of the singularity of a. +// +// The LU factorization is computed with pivoting, and so really the decomposition +// is a PLU decomposition where P is a permutation matrix. The individual matrix +// factors can be extracted from the factorization using the Permutation method +// on Dense, and the LU LTo and UTo methods. +func (lu *LU) Factorize(a Matrix) { + lu.factorize(a, CondNorm) +} + +func (lu *LU) factorize(a Matrix, norm lapack.MatrixNorm) { + r, c := a.Dims() + if r != c { + panic(ErrSquare) + } + if lu.lu == nil { + lu.lu = NewDense(r, r, nil) + } else { + lu.lu.Reset() + lu.lu.reuseAs(r, r) + } + lu.lu.Copy(a) + if cap(lu.pivot) < r { + lu.pivot = make([]int, r) + } + lu.pivot = lu.pivot[:r] + work := getFloats(r, false) + anorm := lapack64.Lange(norm, lu.lu.mat, work) + putFloats(work) + lapack64.Getrf(lu.lu.mat, lu.pivot) + lu.updateCond(anorm, norm) +} + +// Cond returns the condition number for the factorized matrix. +// Cond will panic if the receiver does not contain a successful factorization. +func (lu *LU) Cond() float64 { + if lu.lu == nil || lu.lu.IsZero() { + panic("lu: no decomposition computed") + } + return lu.cond +} + +// Reset resets the factorization so that it can be reused as the receiver of a +// dimensionally restricted operation. +func (lu *LU) Reset() { + if lu.lu != nil { + lu.lu.Reset() + } + lu.pivot = lu.pivot[:0] +} + +func (lu *LU) isZero() bool { + return len(lu.pivot) == 0 +} + +// Det returns the determinant of the matrix that has been factorized. In many +// expressions, using LogDet will be more numerically stable. +func (lu *LU) Det() float64 { + det, sign := lu.LogDet() + return math.Exp(det) * sign +} + +// LogDet returns the log of the determinant and the sign of the determinant +// for the matrix that has been factorized. Numerical stability in product and +// division expressions is generally improved by working in log space. +func (lu *LU) LogDet() (det float64, sign float64) { + _, n := lu.lu.Dims() + logDiag := getFloats(n, false) + defer putFloats(logDiag) + sign = 1.0 + for i := 0; i < n; i++ { + v := lu.lu.at(i, i) + if v < 0 { + sign *= -1 + } + if lu.pivot[i] != i { + sign *= -1 + } + logDiag[i] = math.Log(math.Abs(v)) + } + return floats.Sum(logDiag), sign +} + +// Pivot returns pivot indices that enable the construction of the permutation +// matrix P (see Dense.Permutation). If swaps == nil, then new memory will be +// allocated, otherwise the length of the input must be equal to the size of the +// factorized matrix. +func (lu *LU) Pivot(swaps []int) []int { + _, n := lu.lu.Dims() + if swaps == nil { + swaps = make([]int, n) + } + if len(swaps) != n { + panic(badSliceLength) + } + // Perform the inverse of the row swaps in order to find the final + // row swap position. + for i := range swaps { + swaps[i] = i + } + for i := n - 1; i >= 0; i-- { + v := lu.pivot[i] + swaps[i], swaps[v] = swaps[v], swaps[i] + } + return swaps +} + +// RankOne updates an LU factorization as if a rank-one update had been applied to +// the original matrix A, storing the result into the receiver. That is, if in +// the original LU decomposition P * L * U = A, in the updated decomposition +// P * L * U = A + alpha * x * y^T. +func (lu *LU) RankOne(orig *LU, alpha float64, x, y *VecDense) { + // RankOne uses algorithm a1 on page 28 of "Multiple-Rank Updates to Matrix + // Factorizations for Nonlinear Analysis and Circuit Design" by Linzhong Deng. + // http://web.stanford.edu/group/SOL/dissertations/Linzhong-Deng-thesis.pdf + _, n := orig.lu.Dims() + if x.Len() != n { + panic(ErrShape) + } + if y.Len() != n { + panic(ErrShape) + } + if orig != lu { + if lu.isZero() { + if cap(lu.pivot) < n { + lu.pivot = make([]int, n) + } + lu.pivot = lu.pivot[:n] + if lu.lu == nil { + lu.lu = NewDense(n, n, nil) + } else { + lu.lu.reuseAs(n, n) + } + } else if len(lu.pivot) != n { + panic(ErrShape) + } + copy(lu.pivot, orig.pivot) + lu.lu.Copy(orig.lu) + } + + xs := getFloats(n, false) + defer putFloats(xs) + ys := getFloats(n, false) + defer putFloats(ys) + for i := 0; i < n; i++ { + xs[i] = x.at(i) + ys[i] = y.at(i) + } + + // Adjust for the pivoting in the LU factorization + for i, v := range lu.pivot { + xs[i], xs[v] = xs[v], xs[i] + } + + lum := lu.lu.mat + omega := alpha + for j := 0; j < n; j++ { + ujj := lum.Data[j*lum.Stride+j] + ys[j] /= ujj + theta := 1 + xs[j]*ys[j]*omega + beta := omega * ys[j] / theta + gamma := omega * xs[j] + omega -= beta * gamma + lum.Data[j*lum.Stride+j] *= theta + for i := j + 1; i < n; i++ { + xs[i] -= lum.Data[i*lum.Stride+j] * xs[j] + tmp := ys[i] + ys[i] -= lum.Data[j*lum.Stride+i] * ys[j] + lum.Data[i*lum.Stride+j] += beta * xs[i] + lum.Data[j*lum.Stride+i] += gamma * tmp + } + } + lu.updateCond(-1, CondNorm) +} + +// LTo extracts the lower triangular matrix from an LU factorization. +// If dst is nil, a new matrix is allocated. The resulting L matrix is returned. +func (lu *LU) LTo(dst *TriDense) *TriDense { + _, n := lu.lu.Dims() + if dst == nil { + dst = NewTriDense(n, Lower, nil) + } else { + dst.reuseAs(n, Lower) + } + // Extract the lower triangular elements. + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + dst.mat.Data[i*dst.mat.Stride+j] = lu.lu.mat.Data[i*lu.lu.mat.Stride+j] + } + } + // Set ones on the diagonal. + for i := 0; i < n; i++ { + dst.mat.Data[i*dst.mat.Stride+i] = 1 + } + return dst +} + +// UTo extracts the upper triangular matrix from an LU factorization. +// If dst is nil, a new matrix is allocated. The resulting U matrix is returned. +func (lu *LU) UTo(dst *TriDense) *TriDense { + _, n := lu.lu.Dims() + if dst == nil { + dst = NewTriDense(n, Upper, nil) + } else { + dst.reuseAs(n, Upper) + } + // Extract the upper triangular elements. + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + dst.mat.Data[i*dst.mat.Stride+j] = lu.lu.mat.Data[i*lu.lu.mat.Stride+j] + } + } + return dst +} + +// Permutation constructs an r×r permutation matrix with the given row swaps. +// A permutation matrix has exactly one element equal to one in each row and column +// and all other elements equal to zero. swaps[i] specifies the row with which +// i will be swapped, which is equivalent to the non-zero column of row i. +func (m *Dense) Permutation(r int, swaps []int) { + m.reuseAs(r, r) + for i := 0; i < r; i++ { + zero(m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+r]) + v := swaps[i] + if v < 0 || v >= r { + panic(ErrRowAccess) + } + m.mat.Data[i*m.mat.Stride+v] = 1 + } +} + +// Solve solves a system of linear equations using the LU decomposition of a matrix. +// It computes +// A * x = b if trans == false +// A^T * x = b if trans == true +// In both cases, A is represented in LU factorized form, and the matrix x is +// stored into m. +// +// If A is singular or near-singular a Condition error is returned. Please see +// the documentation for Condition for more information. +func (lu *LU) Solve(m *Dense, trans bool, b Matrix) error { + _, n := lu.lu.Dims() + br, bc := b.Dims() + if br != n { + panic(ErrShape) + } + // TODO(btracey): Should test the condition number instead of testing that + // the determinant is exactly zero. + if lu.Det() == 0 { + return Condition(math.Inf(1)) + } + + m.reuseAs(n, bc) + bU, _ := untranspose(b) + var restore func() + if m == bU { + m, restore = m.isolatedWorkspace(bU) + defer restore() + } else if rm, ok := bU.(RawMatrixer); ok { + m.checkOverlap(rm.RawMatrix()) + } + + m.Copy(b) + t := blas.NoTrans + if trans { + t = blas.Trans + } + lapack64.Getrs(t, lu.lu.mat, m.mat, lu.pivot) + if lu.cond > ConditionTolerance { + return Condition(lu.cond) + } + return nil +} + +// SolveVec solves a system of linear equations using the LU decomposition of a matrix. +// It computes +// A * x = b if trans == false +// A^T * x = b if trans == true +// In both cases, A is represented in LU factorized form, and the matrix x is +// stored into v. +// +// If A is singular or near-singular a Condition error is returned. Please see +// the documentation for Condition for more information. +func (lu *LU) SolveVec(v *VecDense, trans bool, b *VecDense) error { + _, n := lu.lu.Dims() + bn := b.Len() + if bn != n { + panic(ErrShape) + } + if v != b { + v.checkOverlap(b.mat) + } + // TODO(btracey): Should test the condition number instead of testing that + // the determinant is exactly zero. + if lu.Det() == 0 { + return Condition(math.Inf(1)) + } + + v.reuseAs(n) + var restore func() + if v == b { + v, restore = v.isolatedWorkspace(b) + defer restore() + } + v.CopyVec(b) + vMat := blas64.General{ + Rows: n, + Cols: 1, + Stride: v.mat.Inc, + Data: v.mat.Data, + } + t := blas.NoTrans + if trans { + t = blas.Trans + } + lapack64.Getrs(t, lu.lu.mat, vMat, lu.pivot) + if lu.cond > ConditionTolerance { + return Condition(lu.cond) + } + return nil +} diff --git a/vendor/gonum.org/v1/gonum/mat/lu_test.go b/vendor/gonum.org/v1/gonum/mat/lu_test.go new file mode 100644 index 00000000..c210670f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/lu_test.go @@ -0,0 +1,189 @@ +// 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. + +package mat + +import ( + "math/rand" + "testing" +) + +func TestLUD(t *testing.T) { + for _, n := range []int{1, 5, 10, 11, 50} { + a := NewDense(n, n, nil) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.NormFloat64()) + } + } + var want Dense + want.Clone(a) + + var lu LU + lu.Factorize(a) + + l := lu.LTo(nil) + u := lu.UTo(nil) + var p Dense + pivot := lu.Pivot(nil) + p.Permutation(n, pivot) + var got Dense + got.Product(&p, l, u) + if !EqualApprox(&got, &want, 1e-12) { + t.Errorf("PLU does not equal original matrix.\nWant: %v\n Got: %v", want, got) + } + } +} + +func TestLURankOne(t *testing.T) { + for _, pivoting := range []bool{true} { + for _, n := range []int{3, 10, 50} { + // Construct a random LU factorization + lu := &LU{} + lu.lu = NewDense(n, n, nil) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + lu.lu.Set(i, j, rand.Float64()) + } + } + lu.pivot = make([]int, n) + for i := range lu.pivot { + lu.pivot[i] = i + } + if pivoting { + // For each row, randomly swap with itself or a row after (like is done) + // in the actual LU factorization. + for i := range lu.pivot { + idx := i + rand.Intn(n-i) + lu.pivot[i], lu.pivot[idx] = lu.pivot[idx], lu.pivot[i] + } + } + // Apply a rank one update. Ensure the update magnitude is larger than + // the equal tolerance. + alpha := rand.Float64() + 1 + x := NewVecDense(n, nil) + y := NewVecDense(n, nil) + for i := 0; i < n; i++ { + x.setVec(i, rand.Float64()+1) + y.setVec(i, rand.Float64()+1) + } + a := luReconstruct(lu) + a.RankOne(a, alpha, x, y) + + var luNew LU + luNew.RankOne(lu, alpha, x, y) + lu.RankOne(lu, alpha, x, y) + + aR1New := luReconstruct(&luNew) + aR1 := luReconstruct(lu) + + if !Equal(aR1, aR1New) { + t.Error("Different answer when new receiver") + } + if !EqualApprox(aR1, a, 1e-10) { + t.Errorf("Rank one mismatch, pivot %v.\nWant: %v\nGot:%v\n", pivoting, a, aR1) + } + } + } +} + +// luReconstruct reconstructs the original A matrix from an LU decomposition. +func luReconstruct(lu *LU) *Dense { + var L, U TriDense + lu.LTo(&L) + lu.UTo(&U) + var P Dense + pivot := lu.Pivot(nil) + P.Permutation(len(pivot), pivot) + + var a Dense + a.Mul(&L, &U) + a.Mul(&P, &a) + return &a +} + +func TestSolveLU(t *testing.T) { + for _, test := range []struct { + n, bc int + }{ + {5, 5}, + {5, 10}, + {10, 5}, + } { + n := test.n + bc := test.bc + a := NewDense(n, n, nil) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.NormFloat64()) + } + } + b := NewDense(n, bc, nil) + for i := 0; i < n; i++ { + for j := 0; j < bc; j++ { + b.Set(i, j, rand.NormFloat64()) + } + } + var lu LU + lu.Factorize(a) + var x Dense + if err := lu.Solve(&x, false, b); err != nil { + continue + } + var got Dense + got.Mul(a, &x) + if !EqualApprox(&got, b, 1e-12) { + t.Errorf("Solve mismatch for non-singular matrix. n = %v, bc = %v.\nWant: %v\nGot: %v", n, bc, b, got) + } + } + // TODO(btracey): Add testOneInput test when such a function exists. +} + +func TestSolveLUCond(t *testing.T) { + for _, test := range []*Dense{ + NewDense(2, 2, []float64{1, 0, 0, 1e-20}), + } { + m, _ := test.Dims() + var lu LU + lu.Factorize(test) + b := NewDense(m, 2, nil) + var x Dense + if err := lu.Solve(&x, false, b); err == nil { + t.Error("No error for near-singular matrix in matrix solve.") + } + + bvec := NewVecDense(m, nil) + var xvec VecDense + if err := lu.SolveVec(&xvec, false, bvec); err == nil { + t.Error("No error for near-singular matrix in matrix solve.") + } + } +} + +func TestSolveLUVec(t *testing.T) { + for _, n := range []int{5, 10} { + a := NewDense(n, n, nil) + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.NormFloat64()) + } + } + b := NewVecDense(n, nil) + for i := 0; i < n; i++ { + b.SetVec(i, rand.NormFloat64()) + } + var lu LU + lu.Factorize(a) + var x VecDense + if err := lu.SolveVec(&x, false, b); err != nil { + continue + } + var got VecDense + got.MulVec(a, &x) + if !EqualApprox(&got, b, 1e-12) { + t.Errorf("Solve mismatch n = %v.\nWant: %v\nGot: %v", n, b, got) + } + } + // TODO(btracey): Add testOneInput test when such a function exists. +} diff --git a/vendor/gonum.org/v1/gonum/mat/matrix.go b/vendor/gonum.org/v1/gonum/mat/matrix.go new file mode 100644 index 00000000..6ba51eaf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/matrix.go @@ -0,0 +1,881 @@ +// 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. + +package mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/lapack64" +) + +// Matrix is the basic matrix interface type. +type Matrix interface { + // Dims returns the dimensions of a Matrix. + Dims() (r, c int) + + // At returns the value of a matrix element at row i, column j. + // It will panic if i or j are out of bounds for the matrix. + At(i, j int) float64 + + // T returns the transpose of the Matrix. Whether T returns a copy of the + // underlying data is implementation dependent. + // This method may be implemented using the Transpose type, which + // provides an implicit matrix transpose. + T() Matrix +} + +var ( + _ Matrix = Transpose{} + _ Untransposer = Transpose{} +) + +// Transpose is a type for performing an implicit matrix transpose. It implements +// the Matrix interface, returning values from the transpose of the matrix within. +type Transpose struct { + Matrix Matrix +} + +// At returns the value of the element at row i and column j of the transposed +// matrix, that is, row j and column i of the Matrix field. +func (t Transpose) At(i, j int) float64 { + return t.Matrix.At(j, i) +} + +// Dims returns the dimensions of the transposed matrix. The number of rows returned +// is the number of columns in the Matrix field, and the number of columns is +// the number of rows in the Matrix field. +func (t Transpose) Dims() (r, c int) { + c, r = t.Matrix.Dims() + return r, c +} + +// T performs an implicit transpose by returning the Matrix field. +func (t Transpose) T() Matrix { + return t.Matrix +} + +// Untranspose returns the Matrix field. +func (t Transpose) Untranspose() Matrix { + return t.Matrix +} + +// Untransposer is a type that can undo an implicit transpose. +type Untransposer interface { + // Note: This interface is needed to unify all of the Transpose types. In + // the mat methods, we need to test if the Matrix has been implicitly + // transposed. If this is checked by testing for the specific Transpose type + // then the behavior will be different if the user uses T() or TTri() for a + // triangular matrix. + + // Untranspose returns the underlying Matrix stored for the implicit transpose. + Untranspose() Matrix +} + +// UntransposeBander is a type that can undo an implicit band transpose. +type UntransposeBander interface { + // Untranspose returns the underlying Banded stored for the implicit transpose. + UntransposeBand() Banded +} + +// UntransposeTrier is a type that can undo an implicit triangular transpose. +type UntransposeTrier interface { + // Untranspose returns the underlying Triangular stored for the implicit transpose. + UntransposeTri() Triangular +} + +// Mutable is a matrix interface type that allows elements to be altered. +type Mutable interface { + // Set alters the matrix element at row i, column j to v. + // It will panic if i or j are out of bounds for the matrix. + Set(i, j int, v float64) + + Matrix +} + +// A RowViewer can return a VecDense reflecting a row that is backed by the matrix +// data. The VecDense returned will have length equal to the number of columns. +type RowViewer interface { + RowView(i int) *VecDense +} + +// A RawRowViewer can return a slice of float64 reflecting a row that is backed by the matrix +// data. +type RawRowViewer interface { + RawRowView(i int) []float64 +} + +// A ColViewer can return a VecDense reflecting a column that is backed by the matrix +// data. The VecDense returned will have length equal to the number of rows. +type ColViewer interface { + ColView(j int) *VecDense +} + +// A RawColViewer can return a slice of float64 reflecting a column that is backed by the matrix +// data. +type RawColViewer interface { + RawColView(j int) []float64 +} + +// A Cloner can make a copy of a into the receiver, overwriting the previous value of the +// receiver. The clone operation does not make any restriction on shape and will not cause +// shadowing. +type Cloner interface { + Clone(a Matrix) +} + +// A Reseter can reset the matrix so that it can be reused as the receiver of a dimensionally +// restricted operation. This is commonly used when the matrix is being used as a workspace +// or temporary matrix. +// +// If the matrix is a view, using the reset matrix may result in data corruption in elements +// outside the view. +type Reseter interface { + Reset() +} + +// A Copier can make a copy of elements of a into the receiver. The submatrix copied +// starts at row and column 0 and has dimensions equal to the minimum dimensions of +// the two matrices. The number of row and columns copied is returned. +// Copy will copy from a source that aliases the receiver unless the source is transposed; +// an aliasing transpose copy will panic with the exception for a special case when +// the source data has a unitary increment or stride. +type Copier interface { + Copy(a Matrix) (r, c int) +} + +// A Grower can grow the size of the represented matrix by the given number of rows and columns. +// Growing beyond the size given by the Caps method will result in the allocation of a new +// matrix and copying of the elements. If Grow is called with negative increments it will +// panic with ErrIndexOutOfRange. +type Grower interface { + Caps() (r, c int) + Grow(r, c int) Matrix +} + +// A BandWidther represents a banded matrix and can return the left and right half-bandwidths, k1 and +// k2. +type BandWidther interface { + BandWidth() (k1, k2 int) +} + +// A RawMatrixSetter can set the underlying blas64.General used by the receiver. There is no restriction +// on the shape of the receiver. Changes to the receiver's elements will be reflected in the blas64.General.Data. +type RawMatrixSetter interface { + SetRawMatrix(a blas64.General) +} + +// A RawMatrixer can return a blas64.General representation of the receiver. Changes to the blas64.General.Data +// slice will be reflected in the original matrix, changes to the Rows, Cols and Stride fields will not. +type RawMatrixer interface { + RawMatrix() blas64.General +} + +// A RawVectorer can return a blas64.Vector representation of the receiver. Changes to the blas64.Vector.Data +// slice will be reflected in the original matrix, changes to the Inc field will not. +type RawVectorer interface { + RawVector() blas64.Vector +} + +// A NonZeroDoer can call a function for each non-zero element of the receiver. +// The parameters of the function are the element indices and its value. +type NonZeroDoer interface { + DoNonZero(func(i, j int, v float64)) +} + +// A RowNonZeroDoer can call a function for each non-zero element of a row of the receiver. +// The parameters of the function are the element indices and its value. +type RowNonZeroDoer interface { + DoRowNonZero(i int, fn func(i, j int, v float64)) +} + +// A ColNonZeroDoer can call a function for each non-zero element of a column of the receiver. +// The parameters of the function are the element indices and its value. +type ColNonZeroDoer interface { + DoColNonZero(j int, fn func(i, j int, v float64)) +} + +// TODO(btracey): Consider adding CopyCol/CopyRow if the behavior seems useful. +// TODO(btracey): Add in fast paths to Row/Col for the other concrete types +// (TriDense, etc.) as well as relevant interfaces (RowColer, RawRowViewer, etc.) + +// Col copies the elements in the jth column of the matrix into the slice dst. +// The length of the provided slice must equal the number of rows, unless the +// slice is nil in which case a new slice is first allocated. +func Col(dst []float64, j int, a Matrix) []float64 { + r, c := a.Dims() + if j < 0 || j >= c { + panic(ErrColAccess) + } + if dst == nil { + dst = make([]float64, r) + } else { + if len(dst) != r { + panic(ErrColLength) + } + } + aU, aTrans := untranspose(a) + if rm, ok := aU.(RawMatrixer); ok { + m := rm.RawMatrix() + if aTrans { + copy(dst, m.Data[j*m.Stride:j*m.Stride+m.Cols]) + return dst + } + blas64.Copy(r, + blas64.Vector{Inc: m.Stride, Data: m.Data[j:]}, + blas64.Vector{Inc: 1, Data: dst}, + ) + return dst + } + for i := 0; i < r; i++ { + dst[i] = a.At(i, j) + } + return dst +} + +// Row copies the elements in the jth column of the matrix into the slice dst. +// The length of the provided slice must equal the number of columns, unless the +// slice is nil in which case a new slice is first allocated. +func Row(dst []float64, i int, a Matrix) []float64 { + r, c := a.Dims() + if i < 0 || i >= r { + panic(ErrColAccess) + } + if dst == nil { + dst = make([]float64, c) + } else { + if len(dst) != c { + panic(ErrRowLength) + } + } + aU, aTrans := untranspose(a) + if rm, ok := aU.(RawMatrixer); ok { + m := rm.RawMatrix() + if aTrans { + blas64.Copy(c, + blas64.Vector{Inc: m.Stride, Data: m.Data[i:]}, + blas64.Vector{Inc: 1, Data: dst}, + ) + return dst + } + copy(dst, m.Data[i*m.Stride:i*m.Stride+m.Cols]) + return dst + } + for j := 0; j < c; j++ { + dst[j] = a.At(i, j) + } + return dst +} + +// Cond returns the condition number of the given matrix under the given norm. +// The condition number must be based on the 1-norm, 2-norm or ∞-norm. +// Cond will panic with matrix.ErrShape if the matrix has zero size. +// +// BUG(btracey): The computation of the 1-norm and ∞-norm for non-square matrices +// is innacurate, although is typically the right order of magnitude. See +// https://github.com/xianyi/OpenBLAS/issues/636. While the value returned will +// change with the resolution of this bug, the result from Cond will match the +// condition number used internally. +func Cond(a Matrix, norm float64) float64 { + m, n := a.Dims() + if m == 0 || n == 0 { + panic(ErrShape) + } + var lnorm lapack.MatrixNorm + switch norm { + default: + panic("mat: bad norm value") + case 1: + lnorm = lapack.MaxColumnSum + case 2: + var svd SVD + ok := svd.Factorize(a, SVDNone) + if !ok { + return math.Inf(1) + } + return svd.Cond() + case math.Inf(1): + lnorm = lapack.MaxRowSum + } + + if m == n { + // Use the LU decomposition to compute the condition number. + var lu LU + lu.factorize(a, lnorm) + return lu.Cond() + } + if m > n { + // Use the QR factorization to compute the condition number. + var qr QR + qr.factorize(a, lnorm) + return qr.Cond() + } + // Use the LQ factorization to compute the condition number. + var lq LQ + lq.factorize(a, lnorm) + return lq.Cond() +} + +// Det returns the determinant of the matrix a. In many expressions using LogDet +// will be more numerically stable. +func Det(a Matrix) float64 { + det, sign := LogDet(a) + return math.Exp(det) * sign +} + +// Dot returns the sum of the element-wise product of a and b. +// Dot panics if the matrix sizes are unequal. +func Dot(a, b *VecDense) float64 { + la := a.Len() + lb := b.Len() + if la != lb { + panic(ErrShape) + } + return blas64.Dot(la, a.mat, b.mat) +} + +// Equal returns whether the matrices a and b have the same size +// and are element-wise equal. +func Equal(a, b Matrix) bool { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br || ac != bc { + return false + } + aU, aTrans := untranspose(a) + bU, bTrans := untranspose(b) + if rma, ok := aU.(RawMatrixer); ok { + if rmb, ok := bU.(RawMatrixer); ok { + ra := rma.RawMatrix() + rb := rmb.RawMatrix() + if aTrans == bTrans { + for i := 0; i < ra.Rows; i++ { + for j := 0; j < ra.Cols; j++ { + if ra.Data[i*ra.Stride+j] != rb.Data[i*rb.Stride+j] { + return false + } + } + } + return true + } + for i := 0; i < ra.Rows; i++ { + for j := 0; j < ra.Cols; j++ { + if ra.Data[i*ra.Stride+j] != rb.Data[j*rb.Stride+i] { + return false + } + } + } + return true + } + } + if rma, ok := aU.(RawSymmetricer); ok { + if rmb, ok := bU.(RawSymmetricer); ok { + ra := rma.RawSymmetric() + rb := rmb.RawSymmetric() + // Symmetric matrices are always upper and equal to their transpose. + for i := 0; i < ra.N; i++ { + for j := i; j < ra.N; j++ { + if ra.Data[i*ra.Stride+j] != rb.Data[i*rb.Stride+j] { + return false + } + } + } + return true + } + } + if ra, ok := aU.(*VecDense); ok { + if rb, ok := bU.(*VecDense); ok { + // If the raw vectors are the same length they must either both be + // transposed or both not transposed (or have length 1). + for i := 0; i < ra.n; i++ { + if ra.mat.Data[i*ra.mat.Inc] != rb.mat.Data[i*rb.mat.Inc] { + return false + } + } + return true + } + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if a.At(i, j) != b.At(i, j) { + return false + } + } + } + return true +} + +// EqualApprox returns whether the matrices a and b have the same size and contain all equal +// elements with tolerance for element-wise equality specified by epsilon. Matrices +// with non-equal shapes are not equal. +func EqualApprox(a, b Matrix, epsilon float64) bool { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br || ac != bc { + return false + } + aU, aTrans := untranspose(a) + bU, bTrans := untranspose(b) + if rma, ok := aU.(RawMatrixer); ok { + if rmb, ok := bU.(RawMatrixer); ok { + ra := rma.RawMatrix() + rb := rmb.RawMatrix() + if aTrans == bTrans { + for i := 0; i < ra.Rows; i++ { + for j := 0; j < ra.Cols; j++ { + if !floats.EqualWithinAbsOrRel(ra.Data[i*ra.Stride+j], rb.Data[i*rb.Stride+j], epsilon, epsilon) { + return false + } + } + } + return true + } + for i := 0; i < ra.Rows; i++ { + for j := 0; j < ra.Cols; j++ { + if !floats.EqualWithinAbsOrRel(ra.Data[i*ra.Stride+j], rb.Data[j*rb.Stride+i], epsilon, epsilon) { + return false + } + } + } + return true + } + } + if rma, ok := aU.(RawSymmetricer); ok { + if rmb, ok := bU.(RawSymmetricer); ok { + ra := rma.RawSymmetric() + rb := rmb.RawSymmetric() + // Symmetric matrices are always upper and equal to their transpose. + for i := 0; i < ra.N; i++ { + for j := i; j < ra.N; j++ { + if !floats.EqualWithinAbsOrRel(ra.Data[i*ra.Stride+j], rb.Data[i*rb.Stride+j], epsilon, epsilon) { + return false + } + } + } + return true + } + } + if ra, ok := aU.(*VecDense); ok { + if rb, ok := bU.(*VecDense); ok { + // If the raw vectors are the same length they must either both be + // transposed or both not transposed (or have length 1). + for i := 0; i < ra.n; i++ { + if !floats.EqualWithinAbsOrRel(ra.mat.Data[i*ra.mat.Inc], rb.mat.Data[i*rb.mat.Inc], epsilon, epsilon) { + return false + } + } + return true + } + } + for i := 0; i < ar; i++ { + for j := 0; j < ac; j++ { + if !floats.EqualWithinAbsOrRel(a.At(i, j), b.At(i, j), epsilon, epsilon) { + return false + } + } + } + return true +} + +// LogDet returns the log of the determinant and the sign of the determinant +// for the matrix that has been factorized. Numerical stability in product and +// division expressions is generally improved by working in log space. +func LogDet(a Matrix) (det float64, sign float64) { + // TODO(btracey): Add specialized routines for TriDense, etc. + var lu LU + lu.Factorize(a) + return lu.LogDet() +} + +// Max returns the largest element value of the matrix A. +// Max will panic with matrix.ErrShape if the matrix has zero size. +func Max(a Matrix) float64 { + r, c := a.Dims() + if r == 0 || c == 0 { + panic(ErrShape) + } + // Max(A) = Max(A^T) + aU, _ := untranspose(a) + switch m := aU.(type) { + case RawMatrixer: + rm := m.RawMatrix() + max := math.Inf(-1) + for i := 0; i < rm.Rows; i++ { + for _, v := range rm.Data[i*rm.Stride : i*rm.Stride+rm.Cols] { + if v > max { + max = v + } + } + } + return max + case RawTriangular: + rm := m.RawTriangular() + // The max of a triangular is at least 0 unless the size is 1. + if rm.N == 1 { + return rm.Data[0] + } + max := 0.0 + if rm.Uplo == blas.Upper { + for i := 0; i < rm.N; i++ { + for _, v := range rm.Data[i*rm.Stride+i : i*rm.Stride+rm.N] { + if v > max { + max = v + } + } + } + return max + } + for i := 0; i < rm.N; i++ { + for _, v := range rm.Data[i*rm.Stride : i*rm.Stride+i+1] { + if v > max { + max = v + } + } + } + return max + case RawSymmetricer: + rm := m.RawSymmetric() + if rm.Uplo != blas.Upper { + panic(badSymTriangle) + } + max := math.Inf(-1) + for i := 0; i < rm.N; i++ { + for _, v := range rm.Data[i*rm.Stride+i : i*rm.Stride+rm.N] { + if v > max { + max = v + } + } + } + return max + default: + r, c := aU.Dims() + max := math.Inf(-1) + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + v := aU.At(i, j) + if v > max { + max = v + } + } + } + return max + } +} + +// Min returns the smallest element value of the matrix A. +// Min will panic with matrix.ErrShape if the matrix has zero size. +func Min(a Matrix) float64 { + r, c := a.Dims() + if r == 0 || c == 0 { + panic(ErrShape) + } + // Min(A) = Min(A^T) + aU, _ := untranspose(a) + switch m := aU.(type) { + case RawMatrixer: + rm := m.RawMatrix() + min := math.Inf(1) + for i := 0; i < rm.Rows; i++ { + for _, v := range rm.Data[i*rm.Stride : i*rm.Stride+rm.Cols] { + if v < min { + min = v + } + } + } + return min + case RawTriangular: + rm := m.RawTriangular() + // The min of a triangular is at most 0 unless the size is 1. + if rm.N == 1 { + return rm.Data[0] + } + min := 0.0 + if rm.Uplo == blas.Upper { + for i := 0; i < rm.N; i++ { + for _, v := range rm.Data[i*rm.Stride+i : i*rm.Stride+rm.N] { + if v < min { + min = v + } + } + } + return min + } + for i := 0; i < rm.N; i++ { + for _, v := range rm.Data[i*rm.Stride : i*rm.Stride+i+1] { + if v < min { + min = v + } + } + } + return min + case RawSymmetricer: + rm := m.RawSymmetric() + if rm.Uplo != blas.Upper { + panic(badSymTriangle) + } + min := math.Inf(1) + for i := 0; i < rm.N; i++ { + for _, v := range rm.Data[i*rm.Stride+i : i*rm.Stride+rm.N] { + if v < min { + min = v + } + } + } + return min + default: + r, c := aU.Dims() + min := math.Inf(1) + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + v := aU.At(i, j) + if v < min { + min = v + } + } + } + return min + } +} + +// Norm returns the specified (induced) norm of the matrix a. See +// https://en.wikipedia.org/wiki/Matrix_norm for the definition of an induced norm. +// +// Valid norms are: +// 1 - The maximum absolute column sum +// 2 - Frobenius norm, the square root of the sum of the squares of the elements. +// Inf - The maximum absolute row sum. +// Norm will panic with ErrNormOrder if an illegal norm order is specified and +// with matrix.ErrShape if the matrix has zero size. +func Norm(a Matrix, norm float64) float64 { + r, c := a.Dims() + if r == 0 || c == 0 { + panic(ErrShape) + } + aU, aTrans := untranspose(a) + var work []float64 + switch rma := aU.(type) { + case RawMatrixer: + rm := rma.RawMatrix() + n := normLapack(norm, aTrans) + if n == lapack.MaxColumnSum { + work = getFloats(rm.Cols, false) + defer putFloats(work) + } + return lapack64.Lange(n, rm, work) + case RawTriangular: + rm := rma.RawTriangular() + n := normLapack(norm, aTrans) + if n == lapack.MaxRowSum || n == lapack.MaxColumnSum { + work = getFloats(rm.N, false) + defer putFloats(work) + } + return lapack64.Lantr(n, rm, work) + case RawSymmetricer: + rm := rma.RawSymmetric() + n := normLapack(norm, aTrans) + if n == lapack.MaxRowSum || n == lapack.MaxColumnSum { + work = getFloats(rm.N, false) + defer putFloats(work) + } + return lapack64.Lansy(n, rm, work) + case *VecDense: + rv := rma.RawVector() + switch norm { + default: + panic("unreachable") + case 1: + if aTrans { + imax := blas64.Iamax(rma.n, rv) + return math.Abs(rma.At(imax, 0)) + } + return blas64.Asum(rma.n, rv) + case 2: + return blas64.Nrm2(rma.n, rv) + case math.Inf(1): + if aTrans { + return blas64.Asum(rma.n, rv) + } + imax := blas64.Iamax(rma.n, rv) + return math.Abs(rma.At(imax, 0)) + } + } + switch norm { + default: + panic("unreachable") + case 1: + var max float64 + for j := 0; j < c; j++ { + var sum float64 + for i := 0; i < r; i++ { + sum += math.Abs(a.At(i, j)) + } + if sum > max { + max = sum + } + } + return max + case 2: + var sum float64 + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + v := a.At(i, j) + sum += v * v + } + } + return math.Sqrt(sum) + case math.Inf(1): + var max float64 + for i := 0; i < r; i++ { + var sum float64 + for j := 0; j < c; j++ { + sum += math.Abs(a.At(i, j)) + } + if sum > max { + max = sum + } + } + return max + } +} + +// normLapack converts the float64 norm input in Norm to a lapack.MatrixNorm. +func normLapack(norm float64, aTrans bool) lapack.MatrixNorm { + switch norm { + case 1: + n := lapack.MaxColumnSum + if aTrans { + n = lapack.MaxRowSum + } + return n + case 2: + return lapack.NormFrob + case math.Inf(1): + n := lapack.MaxRowSum + if aTrans { + n = lapack.MaxColumnSum + } + return n + default: + panic(ErrNormOrder) + } +} + +// Sum returns the sum of the elements of the matrix. +func Sum(a Matrix) float64 { + // TODO(btracey): Add a fast path for the other supported matrix types. + + r, c := a.Dims() + var sum float64 + aU, _ := untranspose(a) + if rma, ok := aU.(RawMatrixer); ok { + rm := rma.RawMatrix() + for i := 0; i < rm.Rows; i++ { + for _, v := range rm.Data[i*rm.Stride : i*rm.Stride+rm.Cols] { + sum += v + } + } + return sum + } + for i := 0; i < r; i++ { + for j := 0; j < c; j++ { + sum += a.At(i, j) + } + } + return sum +} + +// Trace returns the trace of the matrix. Trace will panic if the +// matrix is not square. +func Trace(a Matrix) float64 { + r, c := a.Dims() + if r != c { + panic(ErrSquare) + } + + aU, _ := untranspose(a) + switch m := aU.(type) { + case RawMatrixer: + rm := m.RawMatrix() + var t float64 + for i := 0; i < r; i++ { + t += rm.Data[i*rm.Stride+i] + } + return t + case RawTriangular: + rm := m.RawTriangular() + var t float64 + for i := 0; i < r; i++ { + t += rm.Data[i*rm.Stride+i] + } + return t + case RawSymmetricer: + rm := m.RawSymmetric() + var t float64 + for i := 0; i < r; i++ { + t += rm.Data[i*rm.Stride+i] + } + return t + default: + var t float64 + for i := 0; i < r; i++ { + t += a.At(i, i) + } + return t + } +} + +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 +} + +// use returns a float64 slice with l elements, using f if it +// has the necessary capacity, otherwise creating a new slice. +func use(f []float64, l int) []float64 { + if l <= cap(f) { + return f[:l] + } + return make([]float64, l) +} + +// useZeroed returns a float64 slice with l elements, using f if it +// has the necessary capacity, otherwise creating a new slice. The +// elements of the returned slice are guaranteed to be zero. +func useZeroed(f []float64, l int) []float64 { + if l <= cap(f) { + f = f[:l] + zero(f) + return f + } + return make([]float64, l) +} + +// zero zeros the given slice's elements. +func zero(f []float64) { + for i := range f { + f[i] = 0 + } +} + +// useInt returns an int slice with l elements, using i if it +// has the necessary capacity, otherwise creating a new slice. +func useInt(i []int, l int) []int { + if l <= cap(i) { + return i[:l] + } + return make([]int, l) +} diff --git a/vendor/gonum.org/v1/gonum/mat/matrix_test.go b/vendor/gonum.org/v1/gonum/mat/matrix_test.go new file mode 100644 index 00000000..7a576529 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/matrix_test.go @@ -0,0 +1,624 @@ +// 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. + +package mat + +import ( + "fmt" + "math" + "reflect" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +func panics(fn func()) (panicked bool, message string) { + defer func() { + r := recover() + panicked = r != nil + message = fmt.Sprint(r) + }() + fn() + return +} + +func flatten(f [][]float64) (r, c int, d []float64) { + r = len(f) + if r == 0 { + panic("bad test: no row") + } + c = len(f[0]) + d = make([]float64, 0, r*c) + for _, row := range f { + if len(row) != c { + panic("bad test: ragged input") + } + d = append(d, row...) + } + return r, c, d +} + +func unflatten(r, c int, d []float64) [][]float64 { + m := make([][]float64, r) + for i := 0; i < r; i++ { + m[i] = d[i*c : (i+1)*c] + } + return m +} + +// eye returns a new identity matrix of size n×n. +func eye(n int) *Dense { + d := make([]float64, n*n) + for i := 0; i < n*n; i += n + 1 { + d[i] = 1 + } + return NewDense(n, n, d) +} + +func TestCol(t *testing.T) { + for id, af := range [][][]float64{ + { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + }, + { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + {10, 11, 12}, + }, + { + {1, 2, 3, 4}, + {5, 6, 7, 8}, + {9, 10, 11, 12}, + }, + } { + a := NewDense(flatten(af)) + col := make([]float64, a.mat.Rows) + for j := range af[0] { + for i := range col { + col[i] = float64(i*a.mat.Cols + j + 1) + } + + if got := Col(nil, j, a); !reflect.DeepEqual(got, col) { + t.Errorf("test %d: unexpected values returned for dense col %d: got: %v want: %v", + id, j, got, col) + } + + got := make([]float64, a.mat.Rows) + if Col(got, j, a); !reflect.DeepEqual(got, col) { + t.Errorf("test %d: unexpected values filled for dense col %d: got: %v want: %v", + id, j, got, col) + } + } + } + + denseComparison := func(a *Dense) interface{} { + r, c := a.Dims() + ans := make([][]float64, c) + for j := range ans { + ans[j] = make([]float64, r) + for i := range ans[j] { + ans[j][i] = a.At(i, j) + } + } + return ans + } + + f := func(a Matrix) interface{} { + _, c := a.Dims() + ans := make([][]float64, c) + for j := range ans { + ans[j] = Col(nil, j, a) + } + return ans + } + testOneInputFunc(t, "Col", f, denseComparison, sameAnswerF64SliceOfSlice, isAnyType, isAnySize) + + f = func(a Matrix) interface{} { + r, c := a.Dims() + ans := make([][]float64, c) + for j := range ans { + ans[j] = make([]float64, r) + Col(ans[j], j, a) + } + return ans + } + testOneInputFunc(t, "Col", f, denseComparison, sameAnswerF64SliceOfSlice, isAnyType, isAnySize) +} + +func TestRow(t *testing.T) { + for id, af := range [][][]float64{ + { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + }, + { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + {10, 11, 12}, + }, + { + {1, 2, 3, 4}, + {5, 6, 7, 8}, + {9, 10, 11, 12}, + }, + } { + a := NewDense(flatten(af)) + for i, row := range af { + if got := Row(nil, i, a); !reflect.DeepEqual(got, row) { + t.Errorf("test %d: unexpected values returned for dense row %d: got: %v want: %v", + id, i, got, row) + } + + got := make([]float64, len(row)) + if Row(got, i, a); !reflect.DeepEqual(got, row) { + t.Errorf("test %d: unexpected values filled for dense row %d: got: %v want: %v", + id, i, got, row) + } + } + } + + denseComparison := func(a *Dense) interface{} { + r, c := a.Dims() + ans := make([][]float64, r) + for i := range ans { + ans[i] = make([]float64, c) + for j := range ans[i] { + ans[i][j] = a.At(i, j) + } + } + return ans + } + + f := func(a Matrix) interface{} { + r, _ := a.Dims() + ans := make([][]float64, r) + for i := range ans { + ans[i] = Row(nil, i, a) + } + return ans + } + testOneInputFunc(t, "Row", f, denseComparison, sameAnswerF64SliceOfSlice, isAnyType, isAnySize) + + f = func(a Matrix) interface{} { + r, c := a.Dims() + ans := make([][]float64, r) + for i := range ans { + ans[i] = make([]float64, c) + Row(ans[i], i, a) + } + return ans + } + testOneInputFunc(t, "Row", f, denseComparison, sameAnswerF64SliceOfSlice, isAnyType, isAnySize) +} + +func TestCond(t *testing.T) { + for i, test := range []struct { + a *Dense + condOne float64 + condTwo float64 + condInf float64 + }{ + { + a: NewDense(3, 3, []float64{ + 8, 1, 6, + 3, 5, 7, + 4, 9, 2, + }), + condOne: 16.0 / 3.0, + condTwo: 4.330127018922192, + condInf: 16.0 / 3.0, + }, + { + a: NewDense(4, 4, []float64{ + 2, 9, 3, 2, + 10, 9, 9, 3, + 1, 1, 5, 2, + 8, 4, 10, 2, + }), + condOne: 1 / 0.024740155174938, + condTwo: 34.521576567075087, + condInf: 1 / 0.012034465570035, + }, + { + a: NewDense(3, 3, []float64{ + 5, 6, 7, + 8, -2, 1, + 7, 7, 7}), + condOne: 30.769230769230749, + condTwo: 21.662689498448440, + condInf: 31.153846153846136, + }, + } { + orig := DenseCopyOf(test.a) + condOne := Cond(test.a, 1) + if !floats.EqualWithinAbsOrRel(test.condOne, condOne, 1e-13, 1e-13) { + t.Errorf("Case %d: one norm mismatch. Want %v, got %v", i, test.condOne, condOne) + } + if !Equal(test.a, orig) { + t.Errorf("Case %d: unexpected mutation of input matrix for one norm. Want %v, got %v", i, orig, test.a) + } + condTwo := Cond(test.a, 2) + if !floats.EqualWithinAbsOrRel(test.condTwo, condTwo, 1e-13, 1e-13) { + t.Errorf("Case %d: two norm mismatch. Want %v, got %v", i, test.condTwo, condTwo) + } + if !Equal(test.a, orig) { + t.Errorf("Case %d: unexpected mutation of input matrix for two norm. Want %v, got %v", i, orig, test.a) + } + condInf := Cond(test.a, math.Inf(1)) + if !floats.EqualWithinAbsOrRel(test.condInf, condInf, 1e-13, 1e-13) { + t.Errorf("Case %d: inf norm mismatch. Want %v, got %v", i, test.condInf, condInf) + } + if !Equal(test.a, orig) { + t.Errorf("Case %d: unexpected mutation of input matrix for inf norm. Want %v, got %v", i, orig, test.a) + } + } + + for _, test := range []struct { + name string + norm float64 + }{ + { + name: "CondOne", + norm: 1, + }, + { + name: "CondTwo", + norm: 2, + }, + { + name: "CondInf", + norm: math.Inf(1), + }, + } { + f := func(a Matrix) interface{} { + return Cond(a, test.norm) + } + denseComparison := func(a *Dense) interface{} { + return Cond(a, test.norm) + } + testOneInputFunc(t, test.name, f, denseComparison, sameAnswerFloatApproxTol(1e-12), isAnyType, isAnySize) + } +} + +func TestDet(t *testing.T) { + for c, test := range []struct { + a *Dense + ans float64 + }{ + { + a: NewDense(2, 2, []float64{1, 0, 0, 1}), + ans: 1, + }, + { + a: NewDense(2, 2, []float64{1, 0, 0, -1}), + ans: -1, + }, + { + a: NewDense(3, 3, []float64{ + 1, 2, 0, + 0, 1, 2, + 0, 2, 1, + }), + ans: -3, + }, + { + a: NewDense(3, 3, []float64{ + 1, 2, 3, + 5, 7, 9, + 6, 9, 12, + }), + ans: 0, + }, + } { + a := DenseCopyOf(test.a) + det := Det(a) + if !Equal(a, test.a) { + t.Errorf("Input matrix changed during Det. Case %d.", c) + } + if !floats.EqualWithinAbsOrRel(det, test.ans, 1e-14, 1e-14) { + t.Errorf("Det mismatch case %d. Got %v, want %v", c, det, test.ans) + } + } + // Perform the normal list test to ensure it works for all types. + f := func(a Matrix) interface{} { + return Det(a) + } + denseComparison := func(a *Dense) interface{} { + return Det(a) + } + testOneInputFunc(t, "Det", f, denseComparison, sameAnswerFloatApproxTol(1e-12), isAnyType, isSquare) + + // Check that it gives approximately the same answer as Cholesky + // Ensure the input matrices are wider than tall so they are full rank + isWide := func(ar, ac int) bool { + return ar <= ac + } + f = func(a Matrix) interface{} { + ar, ac := a.Dims() + if !isWide(ar, ac) { + panic(ErrShape) + } + var tmp Dense + tmp.Mul(a, a.T()) + return Det(&tmp) + } + denseComparison = func(a *Dense) interface{} { + ar, ac := a.Dims() + if !isWide(ar, ac) { + panic(ErrShape) + } + var tmp SymDense + tmp.SymOuterK(1, a) + var chol Cholesky + ok := chol.Factorize(&tmp) + if !ok { + panic("bad chol test") + } + return chol.Det() + } + testOneInputFunc(t, "DetVsChol", f, denseComparison, sameAnswerFloatApproxTol(1e-10), isAnyType, isWide) +} + +func TestDot(t *testing.T) { + f := func(a, b Matrix) interface{} { + return Dot(a.(*VecDense), b.(*VecDense)) + } + denseComparison := func(a, b *Dense) interface{} { + ra, ca := a.Dims() + rb, cb := b.Dims() + if ra != rb || ca != cb { + panic(ErrShape) + } + var sum float64 + for i := 0; i < ra; i++ { + for j := 0; j < ca; j++ { + sum += a.At(i, j) * b.At(i, j) + } + } + return sum + } + testTwoInputFunc(t, "Dot", f, denseComparison, sameAnswerFloatApproxTol(1e-12), legalTypesVecVec, legalSizeSameVec) +} + +func TestEqual(t *testing.T) { + f := func(a, b Matrix) interface{} { + return Equal(a, b) + } + denseComparison := func(a, b *Dense) interface{} { + return Equal(a, b) + } + testTwoInputFunc(t, "Equal", f, denseComparison, sameAnswerBool, legalTypesAll, isAnySize2) +} + +func TestMax(t *testing.T) { + // A direct test of Max with *Dense arguments is in TestNewDense. + f := func(a Matrix) interface{} { + return Max(a) + } + denseComparison := func(a *Dense) interface{} { + return Max(a) + } + testOneInputFunc(t, "Max", f, denseComparison, sameAnswerFloat, isAnyType, isAnySize) +} + +func TestMin(t *testing.T) { + // A direct test of Min with *Dense arguments is in TestNewDense. + f := func(a Matrix) interface{} { + return Min(a) + } + denseComparison := func(a *Dense) interface{} { + return Min(a) + } + testOneInputFunc(t, "Min", f, denseComparison, sameAnswerFloat, isAnyType, isAnySize) +} + +func TestNorm(t *testing.T) { + for i, test := range []struct { + a [][]float64 + ord float64 + norm float64 + }{ + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}, + ord: 1, + norm: 30, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}, + ord: 2, + norm: 25.495097567963924, + }, + { + a: [][]float64{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}, + ord: math.Inf(1), + norm: 33, + }, + { + a: [][]float64{{1, -2, -2}, {-4, 5, 6}}, + ord: 1, + norm: 8, + }, + { + a: [][]float64{{1, -2, -2}, {-4, 5, 6}}, + ord: math.Inf(1), + norm: 15, + }, + } { + a := NewDense(flatten(test.a)) + if math.Abs(Norm(a, test.ord)-test.norm) > 1e-14 { + t.Errorf("Mismatch test %d: %v norm = %f", i, test.a, test.norm) + } + } + + for _, test := range []struct { + name string + norm float64 + }{ + {"NormOne", 1}, + {"NormTwo", 2}, + {"NormInf", math.Inf(1)}, + } { + f := func(a Matrix) interface{} { + return Norm(a, test.norm) + } + denseComparison := func(a *Dense) interface{} { + return Norm(a, test.norm) + } + testOneInputFunc(t, test.name, f, denseComparison, sameAnswerFloatApproxTol(1e-12), isAnyType, isAnySize) + } +} + +func TestNormZero(t *testing.T) { + for _, a := range []Matrix{ + &Dense{}, + &SymDense{}, + &SymDense{mat: blas64.Symmetric{Uplo: blas.Upper}}, + &TriDense{}, + &TriDense{mat: blas64.Triangular{Uplo: blas.Upper, Diag: blas.NonUnit}}, + &VecDense{}, + } { + for _, norm := range []float64{1, 2, math.Inf(1)} { + panicked, message := panics(func() { Norm(a, norm) }) + if !panicked { + t.Errorf("expected panic for Norm(&%T{}, %v)", a, norm) + } + if message != ErrShape.Error() { + t.Errorf("unexpected panic string for Norm(&%T{}, %v): got:%s want:%s", + a, norm, message, ErrShape.Error()) + } + } + } +} + +func TestSum(t *testing.T) { + f := func(a Matrix) interface{} { + return Sum(a) + } + denseComparison := func(a *Dense) interface{} { + return Sum(a) + } + testOneInputFunc(t, "Sum", f, denseComparison, sameAnswerFloatApproxTol(1e-12), isAnyType, isAnySize) +} + +func TestTrace(t *testing.T) { + for _, test := range []struct { + a *Dense + trace float64 + }{ + { + a: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}), + trace: 15, + }, + } { + trace := Trace(test.a) + if trace != test.trace { + t.Errorf("Trace mismatch. Want %v, got %v", test.trace, trace) + } + } + f := func(a Matrix) interface{} { + return Trace(a) + } + denseComparison := func(a *Dense) interface{} { + return Trace(a) + } + testOneInputFunc(t, "Trace", f, denseComparison, sameAnswerFloat, isAnyType, isSquare) +} + +func TestDoer(t *testing.T) { + type MatrixDoer interface { + Matrix + NonZeroDoer + RowNonZeroDoer + ColNonZeroDoer + } + ones := func(n int) []float64 { + data := make([]float64, n) + for i := range data { + data[i] = 1 + } + return data + } + for i, m := range []MatrixDoer{ + NewTriDense(3, Lower, ones(3*3)), + NewTriDense(3, Upper, ones(3*3)), + NewBandDense(6, 6, 1, 1, ones(3*6)), + NewBandDense(6, 10, 1, 1, ones(3*6)), + NewBandDense(10, 6, 1, 1, ones(7*3)), + NewSymBandDense(3, 0, ones(3)), + NewSymBandDense(3, 1, ones(3*(1+1))), + NewSymBandDense(6, 1, ones(6*(1+1))), + NewSymBandDense(6, 2, ones(6*(2+1))), + } { + r, c := m.Dims() + + want := Sum(m) + + // got and fn sum the accessed elements in + // the Doer that is being operated on. + // fn also tests that the accessed elements + // are within the writable areas of the + // matrix to check that only valid elements + // are operated on. + var got float64 + fn := func(i, j int, v float64) { + got += v + switch m := m.(type) { + case MutableTriangular: + m.SetTri(i, j, v) + case MutableBanded: + m.SetBand(i, j, v) + case MutableSymBanded: + m.SetSymBand(i, j, v) + default: + panic("bad test: need mutable type") + } + } + + panicked, message := panics(func() { m.DoNonZero(fn) }) + if panicked { + t.Errorf("unexpected panic for Doer test %d: %q", i, message) + continue + } + if got != want { + t.Errorf("unexpected Doer sum: got:%f want:%f", got, want) + } + + // Reset got for testing with DoRowNonZero. + got = 0 + panicked, message = panics(func() { + for i := 0; i < r; i++ { + m.DoRowNonZero(i, fn) + } + }) + if panicked { + t.Errorf("unexpected panic for RowDoer test %d: %q", i, message) + continue + } + if got != want { + t.Errorf("unexpected RowDoer sum: got:%f want:%f", got, want) + } + + // Reset got for testing with DoColNonZero. + got = 0 + panicked, message = panics(func() { + for j := 0; j < c; j++ { + m.DoColNonZero(j, fn) + } + }) + if panicked { + t.Errorf("unexpected panic for ColDoer test %d: %q", i, message) + continue + } + if got != want { + t.Errorf("unexpected ColDoer sum: got:%f want:%f", got, want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/mul_test.go b/vendor/gonum.org/v1/gonum/mat/mul_test.go new file mode 100644 index 00000000..57ec17f2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/mul_test.go @@ -0,0 +1,283 @@ +// 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 mat + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +// TODO: Need to add tests where one is overwritten. +func TestMulTypes(t *testing.T) { + for _, test := range []struct { + ar int + ac int + br int + bc int + Panics bool + }{ + { + ar: 5, + ac: 5, + br: 5, + bc: 5, + Panics: false, + }, + { + ar: 10, + ac: 5, + br: 5, + bc: 3, + Panics: false, + }, + { + ar: 10, + ac: 5, + br: 5, + bc: 8, + Panics: false, + }, + { + ar: 8, + ac: 10, + br: 10, + bc: 3, + Panics: false, + }, + { + ar: 8, + ac: 3, + br: 3, + bc: 10, + Panics: false, + }, + { + ar: 5, + ac: 8, + br: 8, + bc: 10, + Panics: false, + }, + { + ar: 5, + ac: 12, + br: 12, + bc: 8, + Panics: false, + }, + { + ar: 5, + ac: 7, + br: 8, + bc: 10, + Panics: true, + }, + } { + ar := test.ar + ac := test.ac + br := test.br + bc := test.bc + + // Generate random matrices + avec := make([]float64, ar*ac) + randomSlice(avec) + a := NewDense(ar, ac, avec) + + bvec := make([]float64, br*bc) + randomSlice(bvec) + + b := NewDense(br, bc, bvec) + + // Check that it panics if it is supposed to + if test.Panics { + c := NewDense(0, 0, nil) + fn := func() { + c.Mul(a, b) + } + pan, _ := panics(fn) + if !pan { + t.Errorf("Mul did not panic with dimension mismatch") + } + continue + } + + cvec := make([]float64, ar*bc) + + // Get correct matrix multiply answer from blas64.Gemm + blas64.Gemm(blas.NoTrans, blas.NoTrans, + 1, a.mat, b.mat, + 0, blas64.General{Rows: ar, Cols: bc, Stride: bc, Data: cvec}, + ) + + avecCopy := append([]float64{}, avec...) + bvecCopy := append([]float64{}, bvec...) + cvecCopy := append([]float64{}, cvec...) + + acomp := matComp{r: ar, c: ac, data: avecCopy} + bcomp := matComp{r: br, c: bc, data: bvecCopy} + ccomp := matComp{r: ar, c: bc, data: cvecCopy} + + // Do normal multiply with empty dense + d := NewDense(0, 0, nil) + + testMul(t, a, b, d, acomp, bcomp, ccomp, false, "zero receiver") + + // Normal multiply with existing receiver + c := NewDense(ar, bc, cvec) + randomSlice(cvec) + testMul(t, a, b, c, acomp, bcomp, ccomp, false, "existing receiver") + + // Cast a as a basic matrix + am := (*basicMatrix)(a) + bm := (*basicMatrix)(b) + d.Reset() + testMul(t, am, b, d, acomp, bcomp, ccomp, true, "a is basic, receiver is zero") + d.Reset() + testMul(t, a, bm, d, acomp, bcomp, ccomp, true, "b is basic, receiver is zero") + d.Reset() + testMul(t, am, bm, d, acomp, bcomp, ccomp, true, "both basic, receiver is zero") + randomSlice(cvec) + testMul(t, am, b, d, acomp, bcomp, ccomp, true, "a is basic, receiver is full") + randomSlice(cvec) + testMul(t, a, bm, d, acomp, bcomp, ccomp, true, "b is basic, receiver is full") + randomSlice(cvec) + testMul(t, am, bm, d, acomp, bcomp, ccomp, true, "both basic, receiver is full") + } +} + +func randomSlice(s []float64) { + for i := range s { + s[i] = rand.NormFloat64() + } +} + +type matComp struct { + r, c int + data []float64 +} + +func testMul(t *testing.T, a, b Matrix, c *Dense, acomp, bcomp, ccomp matComp, cvecApprox bool, name string) { + c.Mul(a, b) + var aDense *Dense + switch t := a.(type) { + case *Dense: + aDense = t + case *basicMatrix: + aDense = (*Dense)(t) + } + + var bDense *Dense + switch t := b.(type) { + case *Dense: + bDense = t + case *basicMatrix: + bDense = (*Dense)(t) + } + + if !denseEqual(aDense, acomp) { + t.Errorf("a changed unexpectedly for %v", name) + } + if !denseEqual(bDense, bcomp) { + t.Errorf("b changed unexpectedly for %v", name) + } + if cvecApprox { + if !denseEqualApprox(c, ccomp, 1e-14) { + t.Errorf("mul answer not within tol for %v", name) + } + return + } + + if !denseEqual(c, ccomp) { + t.Errorf("mul answer not equal for %v", name) + } +} + +type basicMatrix Dense + +func (m *basicMatrix) At(r, c int) float64 { + return (*Dense)(m).At(r, c) +} + +func (m *basicMatrix) Dims() (r, c int) { + return (*Dense)(m).Dims() +} + +func (m *basicMatrix) T() Matrix { + return Transpose{m} +} + +type basicSymmetric SymDense + +var _ Symmetric = &basicSymmetric{} + +func (m *basicSymmetric) At(r, c int) float64 { + return (*SymDense)(m).At(r, c) +} + +func (m *basicSymmetric) Dims() (r, c int) { + return (*SymDense)(m).Dims() +} + +func (m *basicSymmetric) T() Matrix { + return m +} + +func (m *basicSymmetric) Symmetric() int { + return (*SymDense)(m).Symmetric() +} + +type basicTriangular TriDense + +func (m *basicTriangular) At(r, c int) float64 { + return (*TriDense)(m).At(r, c) +} + +func (m *basicTriangular) Dims() (r, c int) { + return (*TriDense)(m).Dims() +} + +func (m *basicTriangular) T() Matrix { + return Transpose{m} +} + +func (m *basicTriangular) Triangle() (int, TriKind) { + return (*TriDense)(m).Triangle() +} + +func (m *basicTriangular) TTri() Triangular { + return TransposeTri{m} +} + +func denseEqual(a *Dense, acomp matComp) bool { + ar2, ac2 := a.Dims() + if ar2 != acomp.r { + return false + } + if ac2 != acomp.c { + return false + } + if !floats.Equal(a.mat.Data, acomp.data) { + return false + } + return true +} + +func denseEqualApprox(a *Dense, acomp matComp, tol float64) bool { + ar2, ac2 := a.Dims() + if ar2 != acomp.r { + return false + } + if ac2 != acomp.c { + return false + } + if !floats.EqualApprox(a.mat.Data, acomp.data, tol) { + return false + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/mat/offset.go b/vendor/gonum.org/v1/gonum/mat/offset.go new file mode 100644 index 00000000..01e7d34f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/offset.go @@ -0,0 +1,20 @@ +// 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. + +//+build !appengine + +package mat + +import "unsafe" + +// offset returns the number of float64 values b[0] is after a[0]. +func offset(a, b []float64) int { + if &a[0] == &b[0] { + return 0 + } + // This expression must be atomic with respect to GC moves. + // At this stage this is true, because the GC does not + // move. See https://golang.org/issue/12445. + return int(uintptr(unsafe.Pointer(&b[0]))-uintptr(unsafe.Pointer(&a[0]))) / int(unsafe.Sizeof(float64(0))) +} diff --git a/vendor/gonum.org/v1/gonum/mat/offset_appengine.go b/vendor/gonum.org/v1/gonum/mat/offset_appengine.go new file mode 100644 index 00000000..a4e7b27a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/offset_appengine.go @@ -0,0 +1,24 @@ +// 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. + +//+build appengine + +package mat + +import "reflect" + +var sizeOfFloat64 = int(reflect.TypeOf(float64(0)).Size()) + +// offset returns the number of float64 values b[0] is after a[0]. +func offset(a, b []float64) int { + va0 := reflect.ValueOf(a).Index(0) + vb0 := reflect.ValueOf(b).Index(0) + if va0.Addr() == vb0.Addr() { + return 0 + } + // This expression must be atomic with respect to GC moves. + // At this stage this is true, because the GC does not + // move. See https://golang.org/issue/12445. + return int(vb0.UnsafeAddr()-va0.UnsafeAddr()) / sizeOfFloat64 +} diff --git a/vendor/gonum.org/v1/gonum/mat/pool.go b/vendor/gonum.org/v1/gonum/mat/pool.go new file mode 100644 index 00000000..7adb3275 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/pool.go @@ -0,0 +1,236 @@ +// 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 mat + +import ( + "sync" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +var tab64 = [64]byte{ + 0x3f, 0x00, 0x3a, 0x01, 0x3b, 0x2f, 0x35, 0x02, + 0x3c, 0x27, 0x30, 0x1b, 0x36, 0x21, 0x2a, 0x03, + 0x3d, 0x33, 0x25, 0x28, 0x31, 0x12, 0x1c, 0x14, + 0x37, 0x1e, 0x22, 0x0b, 0x2b, 0x0e, 0x16, 0x04, + 0x3e, 0x39, 0x2e, 0x34, 0x26, 0x1a, 0x20, 0x29, + 0x32, 0x24, 0x11, 0x13, 0x1d, 0x0a, 0x0d, 0x15, + 0x38, 0x2d, 0x19, 0x1f, 0x23, 0x10, 0x09, 0x0c, + 0x2c, 0x18, 0x0f, 0x08, 0x17, 0x07, 0x06, 0x05, +} + +// bits returns the ceiling of base 2 log of v. +// Approach based on http://stackoverflow.com/a/11398748. +func bits(v uint64) byte { + if v == 0 { + return 0 + } + v <<= 2 + v-- + v |= v >> 1 + v |= v >> 2 + v |= v >> 4 + v |= v >> 8 + v |= v >> 16 + v |= v >> 32 + return tab64[((v-(v>>1))*0x07EDD5E59A4E28C2)>>58] - 1 +} + +var ( + // pool contains size stratified workspace Dense pools. + // Each pool element i returns sized matrices with a data + // slice capped at 1<= 2*len(w.mat.Data) { + t.Errorf("r: %d c: %d -> len: %d cap: %d", i, j, len(w.mat.Data), cap(w.mat.Data)) + } + w.Set(0, 0, math.NaN()) + work[l] = w + } + for _, w := range work { + putWorkspace(w) + } + } + } + } +} + +var benchmat *Dense + +func poolBenchmark(n, r, c int, clear bool) { + for i := 0; i < n; i++ { + benchmat = getWorkspace(r, c, clear) + putWorkspace(benchmat) + } +} + +func newBenchmark(n, r, c int) { + for i := 0; i < n; i++ { + benchmat = NewDense(r, c, nil) + } +} + +func BenchmarkPool10by10Uncleared(b *testing.B) { poolBenchmark(b.N, 10, 10, false) } +func BenchmarkPool10by10Cleared(b *testing.B) { poolBenchmark(b.N, 10, 10, true) } +func BenchmarkNew10by10(b *testing.B) { newBenchmark(b.N, 10, 10) } +func BenchmarkPool100by100Uncleared(b *testing.B) { poolBenchmark(b.N, 100, 100, false) } +func BenchmarkPool100by100Cleared(b *testing.B) { poolBenchmark(b.N, 100, 100, true) } +func BenchmarkNew100by100(b *testing.B) { newBenchmark(b.N, 100, 100) } + +func BenchmarkMulWorkspaceDense100Half(b *testing.B) { denseMulWorkspaceBench(b, 100, 0.5) } +func BenchmarkMulWorkspaceDense100Tenth(b *testing.B) { denseMulWorkspaceBench(b, 100, 0.1) } +func BenchmarkMulWorkspaceDense1000Half(b *testing.B) { denseMulWorkspaceBench(b, 1000, 0.5) } +func BenchmarkMulWorkspaceDense1000Tenth(b *testing.B) { denseMulWorkspaceBench(b, 1000, 0.1) } +func BenchmarkMulWorkspaceDense1000Hundredth(b *testing.B) { denseMulWorkspaceBench(b, 1000, 0.01) } +func BenchmarkMulWorkspaceDense1000Thousandth(b *testing.B) { denseMulWorkspaceBench(b, 1000, 0.001) } +func denseMulWorkspaceBench(b *testing.B, size int, rho float64) { + b.StopTimer() + a, _ := randDense(size, rho, rand.NormFloat64) + d, _ := randDense(size, rho, rand.NormFloat64) + b.StartTimer() + for i := 0; i < b.N; i++ { + a.Mul(a, d) + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/product.go b/vendor/gonum.org/v1/gonum/mat/product.go new file mode 100644 index 00000000..5a0343b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/product.go @@ -0,0 +1,193 @@ +// 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 mat + +import "fmt" + +// Product calculates the product of the given factors and places the result in +// the receiver. The order of multiplication operations is optimized to minimize +// the number of floating point operations on the basis that all matrix +// multiplications are general. +func (m *Dense) Product(factors ...Matrix) { + // The operation order optimisation is the naive O(n^3) dynamic + // programming approach and does not take into consideration + // finer-grained optimisations that might be available. + // + // TODO(kortschak) Consider using the O(nlogn) or O(mlogn) + // algorithms that are available. e.g. + // + // e.g. http://www.jofcis.com/publishedpapers/2014_10_10_4299_4306.pdf + // + // In the case that this is replaced, retain this code in + // tests to compare against. + + r, c := m.Dims() + switch len(factors) { + case 0: + if r != 0 || c != 0 { + panic(ErrShape) + } + return + case 1: + m.reuseAs(factors[0].Dims()) + m.Copy(factors[0]) + return + case 2: + // Don't do work that we know the answer to. + m.Mul(factors[0], factors[1]) + return + } + + p := newMultiplier(m, factors) + p.optimize() + result := p.multiply() + m.reuseAs(result.Dims()) + m.Copy(result) + putWorkspace(result) +} + +// debugProductWalk enables debugging output for Product. +const debugProductWalk = false + +// multiplier performs operation order optimisation and tree traversal. +type multiplier struct { + // factors is the ordered set of + // factors to multiply. + factors []Matrix + // dims is the chain of factor + // dimensions. + dims []int + + // table contains the dynamic + // programming costs and subchain + // division indices. + table table +} + +func newMultiplier(m *Dense, factors []Matrix) *multiplier { + // Check size early, but don't yet + // allocate data for m. + r, c := m.Dims() + fr, fc := factors[0].Dims() // newMultiplier is only called with len(factors) > 2. + if !m.IsZero() { + if fr != r { + panic(ErrShape) + } + if _, lc := factors[len(factors)-1].Dims(); lc != c { + panic(ErrShape) + } + } + + dims := make([]int, len(factors)+1) + dims[0] = r + dims[len(dims)-1] = c + pc := fc + for i, f := range factors[1:] { + cr, cc := f.Dims() + dims[i+1] = cr + if pc != cr { + panic(ErrShape) + } + pc = cc + } + + return &multiplier{ + factors: factors, + dims: dims, + table: newTable(len(factors)), + } +} + +// optimize determines an optimal matrix multiply operation order. +func (p *multiplier) optimize() { + if debugProductWalk { + fmt.Printf("chain dims: %v\n", p.dims) + } + const maxInt = int(^uint(0) >> 1) + for f := 1; f < len(p.factors); f++ { + for i := 0; i < len(p.factors)-f; i++ { + j := i + f + p.table.set(i, j, entry{cost: maxInt}) + for k := i; k < j; k++ { + cost := p.table.at(i, k).cost + p.table.at(k+1, j).cost + p.dims[i]*p.dims[k+1]*p.dims[j+1] + if cost < p.table.at(i, j).cost { + p.table.set(i, j, entry{cost: cost, k: k}) + } + } + } + } +} + +// multiply walks the optimal operation tree found by optimize, +// leaving the final result in the stack. It returns the +// product, which may be copied but should be returned to +// the workspace pool. +func (p *multiplier) multiply() *Dense { + result, _ := p.multiplySubchain(0, len(p.factors)-1) + if debugProductWalk { + r, c := result.Dims() + fmt.Printf("\tpop result (%d×%d) cost=%d\n", r, c, p.table.at(0, len(p.factors)-1).cost) + } + return result.(*Dense) +} + +func (p *multiplier) multiplySubchain(i, j int) (m Matrix, intermediate bool) { + if i == j { + return p.factors[i], false + } + + a, aTmp := p.multiplySubchain(i, p.table.at(i, j).k) + b, bTmp := p.multiplySubchain(p.table.at(i, j).k+1, j) + + ar, ac := a.Dims() + br, bc := b.Dims() + if ac != br { + // Panic with a string since this + // is not a user-facing panic. + panic(ErrShape.Error()) + } + + if debugProductWalk { + fmt.Printf("\tpush f[%d] (%d×%d)%s * f[%d] (%d×%d)%s\n", + i, ar, ac, result(aTmp), j, br, bc, result(bTmp)) + } + + r := getWorkspace(ar, bc, false) + r.Mul(a, b) + if aTmp { + putWorkspace(a.(*Dense)) + } + if bTmp { + putWorkspace(b.(*Dense)) + } + return r, true +} + +type entry struct { + k int // is the chain subdivision index. + cost int // cost is the cost of the operation. +} + +// table is a row major n×n dynamic programming table. +type table struct { + n int + entries []entry +} + +func newTable(n int) table { + return table{n: n, entries: make([]entry, n*n)} +} + +func (t table) at(i, j int) entry { return t.entries[i*t.n+j] } +func (t table) set(i, j int, e entry) { t.entries[i*t.n+j] = e } + +type result bool + +func (r result) String() string { + if r { + return " (popped result)" + } + return "" +} diff --git a/vendor/gonum.org/v1/gonum/mat/product_test.go b/vendor/gonum.org/v1/gonum/mat/product_test.go new file mode 100644 index 00000000..2ce0e575 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/product_test.go @@ -0,0 +1,251 @@ +// 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 mat + +import ( + "fmt" + "math/rand" + "testing" +) + +type dims struct{ r, c int } + +var productTests = []struct { + n int + factors []dims + product dims + panics bool +}{ + { + n: 1, + factors: []dims{{3, 4}}, + product: dims{3, 4}, + panics: false, + }, + { + n: 1, + factors: []dims{{2, 4}}, + product: dims{3, 4}, + panics: true, + }, + { + n: 3, + factors: []dims{{10, 30}, {30, 5}, {5, 60}}, + product: dims{10, 60}, + panics: false, + }, + { + n: 3, + factors: []dims{{100, 30}, {30, 5}, {5, 60}}, + product: dims{10, 60}, + panics: true, + }, + { + n: 7, + factors: []dims{{60, 5}, {5, 5}, {5, 4}, {4, 10}, {10, 22}, {22, 45}, {45, 10}}, + product: dims{60, 10}, + panics: false, + }, + { + n: 7, + factors: []dims{{60, 5}, {5, 5}, {5, 400}, {4, 10}, {10, 22}, {22, 45}, {45, 10}}, + product: dims{60, 10}, + panics: true, + }, + { + n: 3, + factors: []dims{{1, 1000}, {1000, 2}, {2, 2}}, + product: dims{1, 2}, + panics: false, + }, + + // Random chains. + { + n: 0, + product: dims{0, 0}, + panics: false, + }, + { + n: 2, + product: dims{60, 10}, + panics: false, + }, + { + n: 3, + product: dims{60, 10}, + panics: false, + }, + { + n: 4, + product: dims{60, 10}, + panics: false, + }, + { + n: 10, + product: dims{60, 10}, + panics: false, + }, +} + +func TestProduct(t *testing.T) { + for _, test := range productTests { + dimensions := test.factors + if dimensions == nil && test.n > 0 { + dimensions = make([]dims, test.n) + for i := range dimensions { + if i != 0 { + dimensions[i].r = dimensions[i-1].c + } + dimensions[i].c = rand.Intn(50) + 1 + } + dimensions[0].r = test.product.r + dimensions[test.n-1].c = test.product.c + } + factors := make([]Matrix, test.n) + for i, d := range dimensions { + data := make([]float64, d.r*d.c) + for i := range data { + data[i] = rand.Float64() + } + factors[i] = NewDense(d.r, d.c, data) + } + + want := &Dense{} + if !test.panics { + a := &Dense{} + for i, b := range factors { + if i == 0 { + want.Clone(b) + continue + } + a, want = want, &Dense{} + want.Mul(a, b) + } + } + + got := NewDense(test.product.r, test.product.c, nil) + panicked, message := panics(func() { + got.Product(factors...) + }) + if test.panics { + if !panicked { + t.Errorf("fail to panic with product chain dimensions: %+v result dimension: %+v", + dimensions, test.product) + } + continue + } else if panicked { + t.Errorf("unexpected panic %q with product chain dimensions: %+v result dimension: %+v", + message, dimensions, test.product) + continue + } + + if len(factors) > 0 { + p := newMultiplier(NewDense(test.product.r, test.product.c, nil), factors) + p.optimize() + gotCost := p.table.at(0, len(factors)-1).cost + expr, wantCost, ok := bestExpressionFor(dimensions) + if !ok { + t.Fatal("unexpected number of expressions in brute force expression search") + } + if gotCost != wantCost { + t.Errorf("unexpected cost for chain dimensions: %+v got: %v want: %v\n%s", + dimensions, got, want, expr) + } + } + + if !EqualApprox(got, want, 1e-14) { + t.Errorf("unexpected result from product chain dimensions: %+v", dimensions) + } + } +} + +// node is a subexpression node. +type node struct { + dims + left, right *node +} + +func (n *node) String() string { + if n.left == nil || n.right == nil { + rows, cols := n.shape() + return fmt.Sprintf("[%d×%d]", rows, cols) + } + rows, cols := n.shape() + return fmt.Sprintf("(%s * %s):[%d×%d]", n.left, n.right, rows, cols) +} + +// shape returns the dimensions of the result of the subexpression. +func (n *node) shape() (rows, cols int) { + if n.left == nil || n.right == nil { + return n.r, n.c + } + rows, _ = n.left.shape() + _, cols = n.right.shape() + return rows, cols +} + +// cost returns the cost to evaluate the subexpression. +func (n *node) cost() int { + if n.left == nil || n.right == nil { + return 0 + } + lr, lc := n.left.shape() + _, rc := n.right.shape() + return lr*lc*rc + n.left.cost() + n.right.cost() +} + +// expressionsFor returns a channel that can be used to iterate over all +// expressions of the given factor dimensions. +func expressionsFor(factors []dims) chan *node { + if len(factors) == 1 { + c := make(chan *node, 1) + c <- &node{dims: factors[0]} + close(c) + return c + } + c := make(chan *node) + go func() { + for i := 1; i < len(factors); i++ { + for left := range expressionsFor(factors[:i]) { + for right := range expressionsFor(factors[i:]) { + c <- &node{left: left, right: right} + } + } + } + close(c) + }() + return c +} + +// catalan returns the nth 0-based Catalan number. +func catalan(n int) int { + p := 1 + for k := n + 1; k < 2*n+1; k++ { + p *= k + } + for k := 2; k < n+2; k++ { + p /= k + } + return p +} + +// bestExpressonFor returns the lowest cost expression for the given expression +// factor dimensions, the cost of the expression and whether the number of +// expressions searched matches the Catalan number for the number of factors. +func bestExpressionFor(factors []dims) (exp *node, cost int, ok bool) { + const maxInt = int(^uint(0) >> 1) + min := maxInt + var best *node + var n int + for exp := range expressionsFor(factors) { + n++ + cost := exp.cost() + if cost < min { + min = cost + best = exp + } + } + return best, min, n == catalan(len(factors)-1) +} diff --git a/vendor/gonum.org/v1/gonum/mat/qr.go b/vendor/gonum.org/v1/gonum/mat/qr.go new file mode 100644 index 00000000..b89f8fb7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/qr.go @@ -0,0 +1,221 @@ +// 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. + +package mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/lapack64" +) + +// QR is a type for creating and using the QR factorization of a matrix. +type QR struct { + qr *Dense + tau []float64 + cond float64 +} + +func (qr *QR) updateCond(norm lapack.MatrixNorm) { + // Since A = Q*R, and Q is orthogonal, we get for the condition number κ + // κ(A) := |A| |A^-1| = |Q*R| |(Q*R)^-1| = |R| |R^-1 * Q^T| + // = |R| |R^-1| = κ(R), + // where we used that fact that Q^-1 = Q^T. However, this assumes that + // the matrix norm is invariant under orthogonal transformations which + // is not the case for CondNorm. Hopefully the error is negligible: κ + // is only a qualitative measure anyway. + n := qr.qr.mat.Cols + work := getFloats(3*n, false) + iwork := getInts(n, false) + r := qr.qr.asTriDense(n, blas.NonUnit, blas.Upper) + v := lapack64.Trcon(norm, r.mat, work, iwork) + putFloats(work) + putInts(iwork) + qr.cond = 1 / v +} + +// Factorize computes the QR factorization of an m×n matrix a where m >= n. The QR +// factorization always exists even if A is singular. +// +// The QR decomposition is a factorization of the matrix A such that A = Q * R. +// The matrix Q is an orthonormal m×m matrix, and R is an m×n upper triangular matrix. +// Q and R can be extracted using the QTo and RTo methods. +func (qr *QR) Factorize(a Matrix) { + qr.factorize(a, CondNorm) +} + +func (qr *QR) factorize(a Matrix, norm lapack.MatrixNorm) { + m, n := a.Dims() + if m < n { + panic(ErrShape) + } + k := min(m, n) + if qr.qr == nil { + qr.qr = &Dense{} + } + qr.qr.Clone(a) + work := []float64{0} + qr.tau = make([]float64, k) + lapack64.Geqrf(qr.qr.mat, qr.tau, work, -1) + + work = getFloats(int(work[0]), false) + lapack64.Geqrf(qr.qr.mat, qr.tau, work, len(work)) + putFloats(work) + qr.updateCond(norm) +} + +// Cond returns the condition number for the factorized matrix. +// Cond will panic if the receiver does not contain a successful factorization. +func (qr *QR) Cond() float64 { + if qr.qr == nil || qr.qr.IsZero() { + panic("qr: no decomposition computed") + } + return qr.cond +} + +// TODO(btracey): Add in the "Reduced" forms for extracting the n×n orthogonal +// and upper triangular matrices. + +// RTo extracts the m×n upper trapezoidal matrix from a QR decomposition. +// If dst is nil, a new matrix is allocated. The resulting dst matrix is returned. +func (qr *QR) RTo(dst *Dense) *Dense { + r, c := qr.qr.Dims() + if dst == nil { + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(r, c) + } + + // Disguise the QR as an upper triangular + t := &TriDense{ + mat: blas64.Triangular{ + N: c, + Stride: qr.qr.mat.Stride, + Data: qr.qr.mat.Data, + Uplo: blas.Upper, + Diag: blas.NonUnit, + }, + cap: qr.qr.capCols, + } + dst.Copy(t) + + // Zero below the triangular. + for i := r; i < c; i++ { + zero(dst.mat.Data[i*dst.mat.Stride : i*dst.mat.Stride+c]) + } + + return dst +} + +// QTo extracts the m×m orthonormal matrix Q from a QR decomposition. +// If dst is nil, a new matrix is allocated. The resulting Q matrix is returned. +func (qr *QR) QTo(dst *Dense) *Dense { + r, _ := qr.qr.Dims() + if dst == nil { + dst = NewDense(r, r, nil) + } else { + dst.reuseAsZeroed(r, r) + } + + // Set Q = I. + for i := 0; i < r*r; i += r + 1 { + dst.mat.Data[i] = 1 + } + + // Construct Q from the elementary reflectors. + work := []float64{0} + lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, dst.mat, work, -1) + work = getFloats(int(work[0]), false) + lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, dst.mat, work, len(work)) + putFloats(work) + + return dst +} + +// Solve finds a minimum-norm solution to a system of linear equations defined +// by the matrices A and b, where A is an m×n matrix represented in its QR factorized +// form. If A is singular or near-singular a Condition error is returned. Please +// see the documentation for Condition for more information. +// +// The minimization problem solved depends on the input parameters. +// If trans == false, find X such that ||A*X - b||_2 is minimized. +// If trans == true, find the minimum norm solution of A^T * X = b. +// The solution matrix, X, is stored in place into m. +func (qr *QR) Solve(m *Dense, trans bool, b Matrix) error { + r, c := qr.qr.Dims() + br, bc := b.Dims() + + // The QR solve algorithm stores the result in-place into the right hand side. + // The storage for the answer must be large enough to hold both b and x. + // However, this method's receiver must be the size of x. Copy b, and then + // copy the result into m at the end. + if trans { + if c != br { + panic(ErrShape) + } + m.reuseAs(r, bc) + } else { + if r != br { + panic(ErrShape) + } + m.reuseAs(c, bc) + } + // Do not need to worry about overlap between m and b because x has its own + // independent storage. + x := getWorkspace(max(r, c), bc, false) + x.Copy(b) + t := qr.qr.asTriDense(qr.qr.mat.Cols, blas.NonUnit, blas.Upper).mat + if trans { + ok := lapack64.Trtrs(blas.Trans, t, x.mat) + if !ok { + return Condition(math.Inf(1)) + } + for i := c; i < r; i++ { + zero(x.mat.Data[i*x.mat.Stride : i*x.mat.Stride+bc]) + } + work := []float64{0} + lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, x.mat, work, -1) + work = getFloats(int(work[0]), false) + lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, x.mat, work, len(work)) + putFloats(work) + } else { + work := []float64{0} + lapack64.Ormqr(blas.Left, blas.Trans, qr.qr.mat, qr.tau, x.mat, work, -1) + work = getFloats(int(work[0]), false) + lapack64.Ormqr(blas.Left, blas.Trans, qr.qr.mat, qr.tau, x.mat, work, len(work)) + putFloats(work) + + ok := lapack64.Trtrs(blas.NoTrans, t, x.mat) + if !ok { + return Condition(math.Inf(1)) + } + } + // M was set above to be the correct size for the result. + m.Copy(x) + putWorkspace(x) + if qr.cond > ConditionTolerance { + return Condition(qr.cond) + } + return nil +} + +// SolveVec finds a minimum-norm solution to a system of linear equations. +// Please see QR.Solve for the full documentation. +func (qr *QR) SolveVec(v *VecDense, trans bool, b *VecDense) error { + if v != b { + v.checkOverlap(b.mat) + } + r, c := qr.qr.Dims() + // The Solve implementation is non-trivial, so rather than duplicate the code, + // instead recast the VecDenses as Dense and call the matrix code. + if trans { + v.reuseAs(r) + } else { + v.reuseAs(c) + } + return qr.Solve(v.asDense(), trans, b.asDense()) +} diff --git a/vendor/gonum.org/v1/gonum/mat/qr_test.go b/vendor/gonum.org/v1/gonum/mat/qr_test.go new file mode 100644 index 00000000..71a2d6e6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/qr_test.go @@ -0,0 +1,205 @@ +// 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. + +package mat + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +func TestQR(t *testing.T) { + for _, test := range []struct { + m, n int + }{ + {5, 5}, + {10, 5}, + } { + m := test.m + n := test.n + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.NormFloat64()) + } + } + var want Dense + want.Clone(a) + + var qr QR + qr.Factorize(a) + q := qr.QTo(nil) + + if !isOrthonormal(q, 1e-10) { + t.Errorf("Q is not orthonormal: m = %v, n = %v", m, n) + } + + r := qr.RTo(nil) + + var got Dense + got.Mul(q, r) + if !EqualApprox(&got, &want, 1e-12) { + t.Errorf("QR does not equal original matrix. \nWant: %v\nGot: %v", want, got) + } + } +} + +func isOrthonormal(q *Dense, tol float64) bool { + m, n := q.Dims() + if m != n { + return false + } + for i := 0; i < m; i++ { + for j := i; j < m; j++ { + dot := blas64.Dot(m, + blas64.Vector{Inc: 1, Data: q.mat.Data[i*q.mat.Stride:]}, + blas64.Vector{Inc: 1, Data: q.mat.Data[j*q.mat.Stride:]}, + ) + // Dot product should be 1 if i == j and 0 otherwise. + if i == j && math.Abs(dot-1) > tol { + return false + } + if i != j && math.Abs(dot) > tol { + return false + } + } + } + return true +} + +func TestSolveQR(t *testing.T) { + for _, trans := range []bool{false, true} { + for _, test := range []struct { + m, n, bc int + }{ + {5, 5, 1}, + {10, 5, 1}, + {5, 5, 3}, + {10, 5, 3}, + } { + m := test.m + n := test.n + bc := test.bc + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.Float64()) + } + } + br := m + if trans { + br = n + } + b := NewDense(br, bc, nil) + for i := 0; i < br; i++ { + for j := 0; j < bc; j++ { + b.Set(i, j, rand.Float64()) + } + } + var x Dense + var qr QR + qr.Factorize(a) + qr.Solve(&x, trans, b) + + // Test that the normal equations hold. + // A^T * A * x = A^T * b if !trans + // A * A^T * x = A * b if trans + var lhs Dense + var rhs Dense + if trans { + var tmp Dense + tmp.Mul(a, a.T()) + lhs.Mul(&tmp, &x) + rhs.Mul(a, b) + } else { + var tmp Dense + tmp.Mul(a.T(), a) + lhs.Mul(&tmp, &x) + rhs.Mul(a.T(), b) + } + if !EqualApprox(&lhs, &rhs, 1e-10) { + t.Errorf("Normal equations do not hold.\nLHS: %v\n, RHS: %v\n", lhs, rhs) + } + } + } + // TODO(btracey): Add in testOneInput when it exists. +} + +func TestSolveQRVec(t *testing.T) { + for _, trans := range []bool{false, true} { + for _, test := range []struct { + m, n int + }{ + {5, 5}, + {10, 5}, + } { + m := test.m + n := test.n + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.Float64()) + } + } + br := m + if trans { + br = n + } + b := NewVecDense(br, nil) + for i := 0; i < br; i++ { + b.SetVec(i, rand.Float64()) + } + var x VecDense + var qr QR + qr.Factorize(a) + qr.SolveVec(&x, trans, b) + + // Test that the normal equations hold. + // A^T * A * x = A^T * b if !trans + // A * A^T * x = A * b if trans + var lhs Dense + var rhs Dense + if trans { + var tmp Dense + tmp.Mul(a, a.T()) + lhs.Mul(&tmp, &x) + rhs.Mul(a, b) + } else { + var tmp Dense + tmp.Mul(a.T(), a) + lhs.Mul(&tmp, &x) + rhs.Mul(a.T(), b) + } + if !EqualApprox(&lhs, &rhs, 1e-10) { + t.Errorf("Normal equations do not hold.\nLHS: %v\n, RHS: %v\n", lhs, rhs) + } + } + } + // TODO(btracey): Add in testOneInput when it exists. +} + +func TestSolveQRCond(t *testing.T) { + for _, test := range []*Dense{ + NewDense(2, 2, []float64{1, 0, 0, 1e-20}), + NewDense(3, 2, []float64{1, 0, 0, 1e-20, 0, 0}), + } { + m, _ := test.Dims() + var qr QR + qr.Factorize(test) + b := NewDense(m, 2, nil) + var x Dense + if err := qr.Solve(&x, false, b); err == nil { + t.Error("No error for near-singular matrix in matrix solve.") + } + + bvec := NewVecDense(m, nil) + var xvec VecDense + if err := qr.SolveVec(&xvec, false, bvec); err == nil { + t.Error("No error for near-singular matrix in matrix solve.") + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/shadow.go b/vendor/gonum.org/v1/gonum/mat/shadow.go new file mode 100644 index 00000000..91ed21f9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/shadow.go @@ -0,0 +1,280 @@ +// 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 mat + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +const ( + // regionOverlap is the panic string used for the general case + // of a matrix region overlap between a source and destination. + regionOverlap = "mat: bad region: overlap" + + // regionIdentity is the panic string used for the specific + // case of complete agreement between a source and a destination. + regionIdentity = "mat: bad region: identical" + + // mismatchedStrides is the panic string used for overlapping + // data slices with differing strides. + mismatchedStrides = "mat: bad region: different strides" +) + +// checkOverlap returns false if the receiver does not overlap data elements +// referenced by the parameter and panics otherwise. +// +// checkOverlap methods return a boolean to allow the check call to be added to a +// boolean expression, making use of short-circuit operators. + +func (m *Dense) checkOverlap(a blas64.General) bool { + mat := m.RawMatrix() + if cap(mat.Data) == 0 || cap(a.Data) == 0 { + return false + } + + off := offset(mat.Data[:1], a.Data[:1]) + + if off == 0 { + // At least one element overlaps. + if mat.Cols == a.Cols && mat.Rows == a.Rows && mat.Stride == a.Stride { + panic(regionIdentity) + } + panic(regionOverlap) + } + + if off > 0 && len(mat.Data) <= off { + // We know m is completely before a. + return false + } + if off < 0 && len(a.Data) <= -off { + // We know m is completely after a. + return false + } + + if mat.Stride != a.Stride { + // Too hard, so assume the worst. + panic(mismatchedStrides) + } + + if off < 0 { + off = -off + mat.Cols, a.Cols = a.Cols, mat.Cols + } + if rectanglesOverlap(off, mat.Cols, a.Cols, mat.Stride) { + panic(regionOverlap) + } + return false +} + +func (s *SymDense) checkOverlap(a blas64.Symmetric) bool { + mat := s.RawSymmetric() + if cap(mat.Data) == 0 || cap(a.Data) == 0 { + return false + } + + off := offset(mat.Data[:1], a.Data[:1]) + + if off == 0 { + // At least one element overlaps. + if mat.N == a.N && mat.Stride == a.Stride { + panic(regionIdentity) + } + panic(regionOverlap) + } + + if off > 0 && len(mat.Data) <= off { + // We know s is completely before a. + return false + } + if off < 0 && len(a.Data) <= -off { + // We know s is completely after a. + return false + } + + if mat.Stride != a.Stride { + // Too hard, so assume the worst. + panic(mismatchedStrides) + } + + if off < 0 { + off = -off + mat.N, a.N = a.N, mat.N + // If we created the matrix it will always + // be in the upper triangle, but don't trust + // that this is the case. + mat.Uplo, a.Uplo = a.Uplo, mat.Uplo + } + if trianglesOverlap(off, mat.N, a.N, mat.Stride, mat.Uplo == blas.Upper, a.Uplo == blas.Upper) { + panic(regionOverlap) + } + return false +} + +func (t *TriDense) checkOverlap(a blas64.Triangular) bool { + mat := t.RawTriangular() + if cap(mat.Data) == 0 || cap(a.Data) == 0 { + return false + } + + off := offset(mat.Data[:1], a.Data[:1]) + + if off == 0 { + // At least one element overlaps. + if mat.N == a.N && mat.Stride == a.Stride { + panic(regionIdentity) + } + panic(regionOverlap) + } + + if off > 0 && len(mat.Data) <= off { + // We know t is completely before a. + return false + } + if off < 0 && len(a.Data) <= -off { + // We know t is completely after a. + return false + } + + if mat.Stride != a.Stride { + // Too hard, so assume the worst. + panic(mismatchedStrides) + } + + if off < 0 { + off = -off + mat.N, a.N = a.N, mat.N + mat.Uplo, a.Uplo = a.Uplo, mat.Uplo + } + if trianglesOverlap(off, mat.N, a.N, mat.Stride, mat.Uplo == blas.Upper, a.Uplo == blas.Upper) { + panic(regionOverlap) + } + return false +} + +func (v *VecDense) checkOverlap(a blas64.Vector) bool { + mat := v.mat + if cap(mat.Data) == 0 || cap(a.Data) == 0 { + return false + } + + off := offset(mat.Data[:1], a.Data[:1]) + + if off == 0 { + // At least one element overlaps. + if mat.Inc == a.Inc && len(mat.Data) == len(a.Data) { + panic(regionIdentity) + } + panic(regionOverlap) + } + + if off > 0 && len(mat.Data) <= off { + // We know v is completely before a. + return false + } + if off < 0 && len(a.Data) <= -off { + // We know v is completely after a. + return false + } + + if mat.Inc != a.Inc { + // Too hard, so assume the worst. + panic(mismatchedStrides) + } + + if mat.Inc == 1 || off&mat.Inc == 0 { + panic(regionOverlap) + } + return false +} + +// rectanglesOverlap returns whether the strided rectangles a and b overlap +// when b is offset by off elements after a but has at least one element before +// the end of a. off must be positive. a and b have aCols and bCols respectively. +// +// rectanglesOverlap works by shifting both matrices left such that the left +// column of a is at 0. The column indexes are flattened by obtaining the shifted +// relative left and right column positions modulo the common stride. This allows +// direct comparison of the column offsets when the matrix backing data slices +// are known to overlap. +func rectanglesOverlap(off, aCols, bCols, stride int) bool { + if stride == 1 { + // Unit stride means overlapping data + // slices must overlap as matrices. + return true + } + + // Flatten the shifted matrix column positions + // so a starts at 0, modulo the common stride. + aTo := aCols + // The mod stride operations here make the from + // and to indexes comparable between a and b when + // the data slices of a and b overlap. + bFrom := off % stride + bTo := (bFrom + bCols) % stride + + if bTo == 0 || bFrom < bTo { + // b matrix is not wrapped: compare for + // simple overlap. + return bFrom < aTo + } + + // b strictly wraps and so must overlap with a. + return true +} + +// trianglesOverlap returns whether the strided triangles a and b overlap +// when b is offset by off elements after a but has at least one element before +// the end of a. off must be positive. a and b are aSize×aSize and bSize×bSize +// respectively. +func trianglesOverlap(off, aSize, bSize, stride int, aUpper, bUpper bool) bool { + if !rectanglesOverlap(off, aSize, bSize, stride) { + // Fast return if bounding rectangles do not overlap. + return false + } + + // Find location of b relative to a. + rowOffset := off / stride + colOffset := off % stride + if (off+bSize)%stride < colOffset { + // We have wrapped, so readjust offsets. + rowOffset++ + colOffset -= stride + } + + if aUpper { + // Check whether the upper left of b + // is in the triangle of a + if rowOffset >= 0 && rowOffset <= colOffset { + return true + } + // Check whether the upper right of b + // is in the triangle of a. + return bUpper && rowOffset < colOffset+bSize + } + + // Check whether the upper left of b + // is in the triangle of a + if colOffset >= 0 && rowOffset >= colOffset { + return true + } + if bUpper { + // Check whether the upper right corner of b + // is in a or the upper row of b spans a row + // of a. + return rowOffset > colOffset+bSize || colOffset < 0 + } + if colOffset < 0 { + // Check whether the lower left of a + // is in the triangle of b or below + // the diagonal of a. This requires a + // swap of reference origin. + return -rowOffset+aSize > -colOffset + } + // Check whether the lower left of b + // is in the triangle of a or below + // the diagonal of a. + return rowOffset+bSize > colOffset +} diff --git a/vendor/gonum.org/v1/gonum/mat/shadow_test.go b/vendor/gonum.org/v1/gonum/mat/shadow_test.go new file mode 100644 index 00000000..564d9e66 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/shadow_test.go @@ -0,0 +1,274 @@ +// 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 mat + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +func TestDenseOverlaps(t *testing.T) { + type view struct { + i, j, r, c int + *Dense + } + + rnd := rand.New(rand.NewSource(1)) + + for r := 1; r < 20; r++ { + for c := 1; c < 20; c++ { + m := NewDense(r, c, nil) + panicked, message := panics(func() { m.checkOverlap(m.RawMatrix()) }) + if !panicked { + t.Error("expected matrix overlap with self") + } + if message != regionIdentity { + t.Errorf("unexpected panic message for self overlap: got: %q want: %q", message, regionIdentity) + } + + for i := 0; i < 1000; i++ { + var views [2]view + for k := range views { + if r > 1 { + views[k].i = rnd.Intn(r - 1) + views[k].r = rnd.Intn(r-views[k].i-1) + 1 + } else { + views[k].r = 1 + } + if c > 1 { + views[k].j = rnd.Intn(c - 1) + views[k].c = rnd.Intn(c-views[k].j-1) + 1 + } else { + views[k].c = 1 + } + views[k].Dense = m.Slice(views[k].i, views[k].i+views[k].r, views[k].j, views[k].j+views[k].c).(*Dense) + + panicked, _ = panics(func() { m.checkOverlap(views[k].RawMatrix()) }) + if !panicked { + t.Errorf("expected matrix (%d×%d) overlap with view {rows=%d:%d, cols=%d:%d}", + r, c, views[k].i, views[k].i+views[k].r, views[k].j, views[k].j+views[k].c) + } + panicked, _ = panics(func() { views[k].checkOverlap(m.RawMatrix()) }) + if !panicked { + t.Errorf("expected view {rows=%d:%d, cols=%d:%d} overlap with parent (%d×%d)", + views[k].i, views[k].i+views[k].r, views[k].j, views[k].j+views[k].c, r, c) + } + } + + overlapRows := intervalsOverlap( + interval{views[0].i, views[0].i + views[0].r}, + interval{views[1].i, views[1].i + views[1].r}, + ) + overlapCols := intervalsOverlap( + interval{views[0].j, views[0].j + views[0].c}, + interval{views[1].j, views[1].j + views[1].c}, + ) + want := overlapRows && overlapCols + + for k, v := range views { + w := views[1-k] + got, _ := panics(func() { v.checkOverlap(w.RawMatrix()) }) + if got != want { + t.Errorf("unexpected result for overlap test for {rows=%d:%d, cols=%d:%d} with {rows=%d:%d, cols=%d:%d}: got: %t want: %t", + v.i, v.i+v.r, v.j, v.j+v.c, + w.i, w.i+w.r, w.j, w.j+w.c, + got, want) + } + } + } + } + } +} + +func TestTriDenseOverlaps(t *testing.T) { + type view struct { + i, j, n int + *TriDense + } + + rnd := rand.New(rand.NewSource(1)) + + for _, parentKind := range []TriKind{Upper, Lower} { + for n := 1; n < 20; n++ { + data := make([]float64, n*n) + for i := range data { + data[i] = float64(i + 1) + } + m := NewDense(n, n, data) + mt := denseAsTriDense(m, parentKind) + panicked, message := panics(func() { mt.checkOverlap(mt.RawTriangular()) }) + if !panicked { + t.Error("expected matrix overlap with self") + } + if message != regionIdentity { + t.Errorf("unexpected panic message for self overlap: got: %q want: %q", message, regionIdentity) + } + + for i := 0; i < 1000; i++ { + var views [2]view + for k := range views { + if n > 1 { + views[k].i = rnd.Intn(n - 1) + views[k].j = rnd.Intn(n - 1) + views[k].n = rnd.Intn(n-max(views[k].i, views[k].j)-1) + 1 + } else { + views[k].n = 1 + } + viewKind := []TriKind{Upper, Lower}[rnd.Intn(2)] + views[k].TriDense = denseAsTriDense( + m.Slice(views[k].i, views[k].i+views[k].n, views[k].j, views[k].j+views[k].n).(*Dense), + viewKind) + + wantPanick := overlapsParentTriangle(views[k].i, views[k].j, views[k].n, parentKind, viewKind) + + panicked, _ = panics(func() { mt.checkOverlap(views[k].RawTriangular()) }) + if panicked != wantPanick { + t.Errorf("unexpected (%d×%d)%s overlap with view {rows=%d:%d, cols=%d:%d}%s got:%t want:%t\n% v\n\n% v\n", + n, n, kindString(parentKind), + views[k].i, views[k].i+views[k].n, views[k].j, views[k].j+views[k].n, kindString(viewKind), + panicked, wantPanick, + Formatted(mt), Formatted(views[k].TriDense)) + } + panicked, _ = panics(func() { views[k].checkOverlap(mt.RawTriangular()) }) + if panicked != wantPanick { + t.Errorf("unexpected {rows=%d:%d, cols=%d:%d}%s overlap with parent (%d×%d)%s got:%t want:%t\n% v\n\n% v\n", + views[k].i, views[k].i+views[k].n, views[k].j, views[k].j+views[k].n, kindString(viewKind), + n, n, kindString(parentKind), + panicked, wantPanick, + Formatted(views[k].TriDense), Formatted(mt)) + } + } + + want := overlapSiblingTriangles( + views[0].i, views[0].j, views[0].n, views[0].mat.Uplo == blas.Upper, + views[1].i, views[1].j, views[1].n, views[1].mat.Uplo == blas.Upper, + ) + + for k, v := range views { + w := views[1-k] + got, _ := panics(func() { v.checkOverlap(w.RawTriangular()) }) + if got != want { + t.Errorf("unexpected result for overlap test for {rows=%d:%d, cols=%d:%d}%s with {rows=%d:%d, cols=%d:%d}%s: got:%t want:%t\n% v\n\n% v\n", + v.i, v.i+v.n, v.j, v.j+v.n, kindString(v.mat.Uplo == blas.Upper), + w.i, w.i+w.n, w.j, w.j+w.n, kindString(w.mat.Uplo == blas.Upper), + got, want, + Formatted(v.TriDense), Formatted(w.TriDense)) + } + } + } + } + } +} + +type interval struct{ from, to int } + +func intervalsOverlap(a, b interval) bool { + return a.to > b.from && b.to > a.from +} + +func overlapsParentTriangle(i, j, n int, parent, view TriKind) bool { + switch parent { + case Upper: + if i <= j { + return true + } + if view == Upper { + return i < j+n + } + + case Lower: + if i >= j { + return true + } + if view == Lower { + return i+n > j + } + } + + return false +} + +func overlapSiblingTriangles(ai, aj, an int, aKind TriKind, bi, bj, bn int, bKind TriKind) bool { + for i := max(ai, bi); i < min(ai+an, bi+bn); i++ { + var a, b interval + + if aKind == Upper { + a = interval{from: aj - ai + i, to: aj + an} + } else { + a = interval{from: aj, to: aj - ai + i + 1} + } + + if bKind == Upper { + b = interval{from: bj - bi + i, to: bj + bn} + } else { + b = interval{from: bj, to: bj - bi + i + 1} + } + + if intervalsOverlap(a, b) { + return true + } + } + return false +} + +func kindString(k TriKind) string { + if k == Upper { + return "U" + } + return "L" +} + +// See https://github.com/gonum/matrix/issues/359 for details. +func TestIssue359(t *testing.T) { + for xi := 0; xi < 2; xi++ { + for xj := 0; xj < 2; xj++ { + for yi := 0; yi < 2; yi++ { + for yj := 0; yj < 2; yj++ { + a := NewDense(3, 3, []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }) + x := a.Slice(xi, xi+2, xj, xj+2).(*Dense) + y := a.Slice(yi, yi+2, yj, yj+2).(*Dense) + + panicked, _ := panics(func() { x.checkOverlap(y.mat) }) + if !panicked { + t.Errorf("expected panic for aliased with offsets x(%d,%d) y(%d,%d):\nx:\n%v\ny:\n%v", + xi, xj, yi, yj, Formatted(x), Formatted(y), + ) + } + } + } + } + } +} + +// denseAsTriDense returns a triangular matrix derived from the +// square matrix m, with the orientation specified by kind. +func denseAsTriDense(m *Dense, kind TriKind) *TriDense { + r, c := m.Dims() + if r != c { + panic(ErrShape) + } + n := r + uplo := blas.Lower + if kind == Upper { + uplo = blas.Upper + } + return &TriDense{ + mat: blas64.Triangular{ + N: n, + Stride: m.mat.Stride, + Data: m.mat.Data, + Uplo: uplo, + Diag: blas.NonUnit, + }, + cap: n, + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/solve.go b/vendor/gonum.org/v1/gonum/mat/solve.go new file mode 100644 index 00000000..ef3d00ef --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/solve.go @@ -0,0 +1,127 @@ +// 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 mat + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack/lapack64" +) + +// Solve finds a minimum-norm solution to a system of linear equations defined +// by the matrices a and b. If A is singular or near-singular, a Condition error +// is returned. Please see the documentation for Condition for more information. +// +// The minimization problem solved depends on the input parameters: +// - if m >= n, find X such that ||A*X - B||_2 is minimized, +// - if m < n, find the minimum norm solution of A * X = B. +// The solution matrix, X, is stored in-place into the receiver. +func (m *Dense) Solve(a, b Matrix) error { + ar, ac := a.Dims() + br, bc := b.Dims() + if ar != br { + panic(ErrShape) + } + m.reuseAs(ac, bc) + + // TODO(btracey): Add special cases for SymDense, etc. + aU, aTrans := untranspose(a) + bU, bTrans := untranspose(b) + switch rma := aU.(type) { + case RawTriangular: + side := blas.Left + tA := blas.NoTrans + if aTrans { + tA = blas.Trans + } + + switch rm := bU.(type) { + case RawMatrixer: + if m != bU || bTrans { + if m == bU || m.checkOverlap(rm.RawMatrix()) { + tmp := getWorkspace(br, bc, false) + tmp.Copy(b) + m.Copy(tmp) + putWorkspace(tmp) + break + } + m.Copy(b) + } + default: + if m != bU { + m.Copy(b) + } else if bTrans { + // m and b share data so Copy cannot be used directly. + tmp := getWorkspace(br, bc, false) + tmp.Copy(b) + m.Copy(tmp) + putWorkspace(tmp) + } + } + + rm := rma.RawTriangular() + blas64.Trsm(side, tA, 1, rm, m.mat) + work := getFloats(3*rm.N, false) + iwork := getInts(rm.N, false) + cond := lapack64.Trcon(CondNorm, rm, work, iwork) + putFloats(work) + putInts(iwork) + if cond > ConditionTolerance { + return Condition(cond) + } + return nil + } + + switch { + case ar == ac: + if a == b { + // x = I. + if ar == 1 { + m.mat.Data[0] = 1 + return nil + } + for i := 0; i < ar; i++ { + v := m.mat.Data[i*m.mat.Stride : i*m.mat.Stride+ac] + zero(v) + v[i] = 1 + } + return nil + } + var lu LU + lu.Factorize(a) + return lu.Solve(m, false, b) + case ar > ac: + var qr QR + qr.Factorize(a) + return qr.Solve(m, false, b) + default: + var lq LQ + lq.Factorize(a) + return lq.Solve(m, false, b) + } +} + +// SolveVec finds a minimum-norm solution to a system of linear equations defined +// by the matrix a and the right-hand side vector b. If A is singular or +// near-singular, a Condition error is returned. Please see the documentation for +// Dense.Solve for more information. +func (v *VecDense) SolveVec(a Matrix, b *VecDense) error { + if v != b { + v.checkOverlap(b.mat) + } + _, c := a.Dims() + // The Solve implementation is non-trivial, so rather than duplicate the code, + // instead recast the VecDenses as Dense and call the matrix code. + v.reuseAs(c) + m := v.asDense() + // We conditionally create bm as m when b and v are identical + // to prevent the overlap detection code from identifying m + // and bm as overlapping but not identical. + bm := m + if v != b { + bm = b.asDense() + } + return m.Solve(a, bm) +} diff --git a/vendor/gonum.org/v1/gonum/mat/solve_test.go b/vendor/gonum.org/v1/gonum/mat/solve_test.go new file mode 100644 index 00000000..08ed5839 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/solve_test.go @@ -0,0 +1,296 @@ +// 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 mat + +import ( + "math/rand" + "testing" +) + +func TestSolve(t *testing.T) { + // Hand-coded cases. + for _, test := range []struct { + a [][]float64 + b [][]float64 + ans [][]float64 + shouldErr bool + }{ + { + a: [][]float64{{6}}, + b: [][]float64{{3}}, + ans: [][]float64{{0.5}}, + shouldErr: false, + }, + { + a: [][]float64{ + {1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + }, + b: [][]float64{ + {3}, + {2}, + {1}, + }, + ans: [][]float64{ + {3}, + {2}, + {1}, + }, + shouldErr: false, + }, + { + a: [][]float64{ + {0.8147, 0.9134, 0.5528}, + {0.9058, 0.6324, 0.8723}, + {0.1270, 0.0975, 0.7612}, + }, + b: [][]float64{ + {0.278}, + {0.547}, + {0.958}, + }, + ans: [][]float64{ + {-0.932687281002860}, + {0.303963920182067}, + {1.375216503507109}, + }, + shouldErr: false, + }, + { + a: [][]float64{ + {0.8147, 0.9134, 0.5528}, + {0.9058, 0.6324, 0.8723}, + }, + b: [][]float64{ + {0.278}, + {0.547}, + }, + ans: [][]float64{ + {0.25919787248965376}, + {-0.25560256266441034}, + {0.5432324059702451}, + }, + shouldErr: false, + }, + { + a: [][]float64{ + {0.8147, 0.9134, 0.9}, + {0.9058, 0.6324, 0.9}, + {0.1270, 0.0975, 0.1}, + {1.6, 2.8, -3.5}, + }, + b: [][]float64{ + {0.278}, + {0.547}, + {-0.958}, + {1.452}, + }, + ans: [][]float64{ + {0.820970340787782}, + {-0.218604626527306}, + {-0.212938815234215}, + }, + shouldErr: false, + }, + { + a: [][]float64{ + {0.8147, 0.9134, 0.231, -1.65}, + {0.9058, 0.6324, 0.9, 0.72}, + {0.1270, 0.0975, 0.1, 1.723}, + {1.6, 2.8, -3.5, 0.987}, + {7.231, 9.154, 1.823, 0.9}, + }, + b: [][]float64{ + {0.278, 8.635}, + {0.547, 9.125}, + {-0.958, -0.762}, + {1.452, 1.444}, + {1.999, -7.234}, + }, + ans: [][]float64{ + {1.863006789511373, 44.467887791812750}, + {-1.127270935407224, -34.073794226035126}, + {-0.527926457947330, -8.032133759788573}, + {-0.248621916204897, -2.366366415805275}, + }, + shouldErr: false, + }, + { + a: [][]float64{ + {0, 0}, + {0, 0}, + }, + b: [][]float64{ + {3}, + {2}, + }, + ans: nil, + shouldErr: true, + }, + { + a: [][]float64{ + {0, 0}, + {0, 0}, + {0, 0}, + }, + b: [][]float64{ + {3}, + {2}, + {1}, + }, + ans: nil, + shouldErr: true, + }, + { + a: [][]float64{ + {0, 0, 0}, + {0, 0, 0}, + }, + b: [][]float64{ + {3}, + {2}, + }, + ans: nil, + shouldErr: true, + }, + } { + a := NewDense(flatten(test.a)) + b := NewDense(flatten(test.b)) + + var ans *Dense + if test.ans != nil { + ans = NewDense(flatten(test.ans)) + } + + var x Dense + err := x.Solve(a, b) + if err != nil { + if !test.shouldErr { + t.Errorf("Unexpected solve error: %s", err) + } + continue + } + if err == nil && test.shouldErr { + t.Errorf("Did not error during solve.") + continue + } + if !EqualApprox(&x, ans, 1e-12) { + t.Errorf("Solve answer mismatch. Want %v, got %v", ans, x) + } + } + + // Random Cases. + for _, test := range []struct { + m, n, bc int + }{ + {5, 5, 1}, + {5, 10, 1}, + {10, 5, 1}, + {5, 5, 7}, + {5, 10, 7}, + {10, 5, 7}, + {5, 5, 12}, + {5, 10, 12}, + {10, 5, 12}, + } { + m := test.m + n := test.n + bc := test.bc + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.Float64()) + } + } + br := m + b := NewDense(br, bc, nil) + for i := 0; i < br; i++ { + for j := 0; j < bc; j++ { + b.Set(i, j, rand.Float64()) + } + } + var x Dense + x.Solve(a, b) + + // Test that the normal equations hold. + // A^T * A * x = A^T * b + var tmp, lhs, rhs Dense + tmp.Mul(a.T(), a) + lhs.Mul(&tmp, &x) + rhs.Mul(a.T(), b) + if !EqualApprox(&lhs, &rhs, 1e-10) { + t.Errorf("Normal equations do not hold.\nLHS: %v\n, RHS: %v\n", lhs, rhs) + } + } + + // Use testTwoInput. + method := func(receiver, a, b Matrix) { + type Solver interface { + Solve(a, b Matrix) error + } + rd := receiver.(Solver) + rd.Solve(a, b) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Solve(a, b) + } + testTwoInput(t, "Solve", &Dense{}, method, denseComparison, legalTypesAll, legalSizeSolve, 1e-7) +} + +func TestSolveVec(t *testing.T) { + for _, test := range []struct { + m, n int + }{ + {5, 5}, + {5, 10}, + {10, 5}, + {5, 5}, + {5, 10}, + {10, 5}, + {5, 5}, + {5, 10}, + {10, 5}, + } { + m := test.m + n := test.n + a := NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, rand.Float64()) + } + } + br := m + b := NewVecDense(br, nil) + for i := 0; i < br; i++ { + b.SetVec(i, rand.Float64()) + } + var x VecDense + x.SolveVec(a, b) + + // Test that the normal equations hold. + // A^T * A * x = A^T * b + var tmp, lhs, rhs Dense + tmp.Mul(a.T(), a) + lhs.Mul(&tmp, &x) + rhs.Mul(a.T(), b) + if !EqualApprox(&lhs, &rhs, 1e-10) { + t.Errorf("Normal equations do not hold.\nLHS: %v\n, RHS: %v\n", lhs, rhs) + } + } + + // Use testTwoInput + method := func(receiver, a, b Matrix) { + type SolveVecer interface { + SolveVec(a Matrix, b *VecDense) error + } + rd := receiver.(SolveVecer) + rd.SolveVec(a, b.(*VecDense)) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Solve(a, b) + } + testTwoInput(t, "SolveVec", &VecDense{}, method, denseComparison, legalTypesNotVecVec, legalSizeSolve, 1e-12) +} diff --git a/vendor/gonum.org/v1/gonum/mat/svd.go b/vendor/gonum.org/v1/gonum/mat/svd.go new file mode 100644 index 00000000..9d386d81 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/svd.go @@ -0,0 +1,190 @@ +// 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. + +package mat + +import ( + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack" + "gonum.org/v1/gonum/lapack/lapack64" +) + +// SVD is a type for creating and using the Singular Value Decomposition (SVD) +// of a matrix. +type SVD struct { + kind SVDKind + + s []float64 + u blas64.General + vt blas64.General +} + +// Factorize computes the singular value decomposition (SVD) of the input matrix +// A. The singular values of A are computed in all cases, while the singular +// vectors are optionally computed depending on the input kind. +// +// The full singular value decomposition (kind == SVDFull) deconstructs A as +// A = U * Σ * V^T +// where Σ is an m×n diagonal matrix of singular vectors, U is an m×m unitary +// matrix of left singular vectors, and V is an n×n matrix of right singular vectors. +// +// It is frequently not necessary to compute the full SVD. Computation time and +// storage costs can be reduced using the appropriate kind. Only the singular +// values can be computed (kind == SVDNone), or a "thin" representation of the +// singular vectors (kind = SVDThin). The thin representation can save a significant +// amount of memory if m >> n. See the documentation for the lapack.SVDKind values +// for more information. +// +// Factorize returns whether the decomposition succeeded. If the decomposition +// failed, routines that require a successful factorization will panic. +func (svd *SVD) Factorize(a Matrix, kind SVDKind) (ok bool) { + m, n := a.Dims() + var jobU, jobVT lapack.SVDJob + switch kind { + default: + panic("svd: bad input kind") + case SVDNone: + jobU = lapack.SVDNone + jobVT = lapack.SVDNone + case SVDFull: + // TODO(btracey): This code should be modified to have the smaller + // matrix written in-place into aCopy when the lapack/native/dgesvd + // implementation is complete. + svd.u = blas64.General{ + Rows: m, + Cols: m, + Stride: m, + Data: use(svd.u.Data, m*m), + } + svd.vt = blas64.General{ + Rows: n, + Cols: n, + Stride: n, + Data: use(svd.vt.Data, n*n), + } + jobU = lapack.SVDAll + jobVT = lapack.SVDAll + case SVDThin: + // TODO(btracey): This code should be modified to have the larger + // matrix written in-place into aCopy when the lapack/native/dgesvd + // implementation is complete. + svd.u = blas64.General{ + Rows: m, + Cols: min(m, n), + Stride: min(m, n), + Data: use(svd.u.Data, m*min(m, n)), + } + svd.vt = blas64.General{ + Rows: min(m, n), + Cols: n, + Stride: n, + Data: use(svd.vt.Data, min(m, n)*n), + } + jobU = lapack.SVDInPlace + jobVT = lapack.SVDInPlace + } + + // A is destroyed on call, so copy the matrix. + aCopy := DenseCopyOf(a) + svd.kind = kind + svd.s = use(svd.s, min(m, n)) + + work := []float64{0} + lapack64.Gesvd(jobU, jobVT, aCopy.mat, svd.u, svd.vt, svd.s, work, -1) + work = getFloats(int(work[0]), false) + ok = lapack64.Gesvd(jobU, jobVT, aCopy.mat, svd.u, svd.vt, svd.s, work, len(work)) + putFloats(work) + if !ok { + svd.kind = 0 + } + return ok +} + +// Kind returns the matrix.SVDKind of the decomposition. If no decomposition has been +// computed, Kind returns 0. +func (svd *SVD) Kind() SVDKind { + return svd.kind +} + +// Cond returns the 2-norm condition number for the factorized matrix. Cond will +// panic if the receiver does not contain a successful factorization. +func (svd *SVD) Cond() float64 { + if svd.kind == 0 { + panic("svd: no decomposition computed") + } + return svd.s[0] / svd.s[len(svd.s)-1] +} + +// Values returns the singular values of the factorized matrix in decreasing order. +// If the input slice is non-nil, the values will be stored in-place into the slice. +// In this case, the slice must have length min(m,n), and Values will panic with +// matrix.ErrSliceLengthMismatch otherwise. If the input slice is nil, +// a new slice of the appropriate length will be allocated and returned. +// +// Values will panic if the receiver does not contain a successful factorization. +func (svd *SVD) Values(s []float64) []float64 { + if svd.kind == 0 { + panic("svd: no decomposition computed") + } + if s == nil { + s = make([]float64, len(svd.s)) + } + if len(s) != len(svd.s) { + panic(ErrSliceLengthMismatch) + } + copy(s, svd.s) + return s +} + +// UTo extracts the matrix U from the singular value decomposition, storing +// the result in-place into dst. U is size m×m if svd.Kind() == SVDFull, +// of size m×min(m,n) if svd.Kind() == SVDThin, and UTo panics otherwise. +func (svd *SVD) UTo(dst *Dense) *Dense { + kind := svd.kind + if kind != SVDFull && kind != SVDThin { + panic("mat: improper SVD kind") + } + r := svd.u.Rows + c := svd.u.Cols + if dst == nil { + dst = NewDense(r, c, nil) + } else { + dst.reuseAs(r, c) + } + + tmp := &Dense{ + mat: svd.u, + capRows: r, + capCols: c, + } + dst.Copy(tmp) + + return dst +} + +// VTo extracts the matrix V from the singular value decomposition, storing +// the result in-place into dst. V is size n×n if svd.Kind() == SVDFull, +// of size n×min(m,n) if svd.Kind() == SVDThin, and VTo panics otherwise. +func (svd *SVD) VTo(dst *Dense) *Dense { + kind := svd.kind + if kind != SVDFull && kind != SVDThin { + panic("mat: improper SVD kind") + } + r := svd.vt.Rows + c := svd.vt.Cols + if dst == nil { + dst = NewDense(c, r, nil) + } else { + dst.reuseAs(c, r) + } + + tmp := &Dense{ + mat: svd.vt, + capRows: r, + capCols: c, + } + dst.Copy(tmp.T()) + + return dst +} diff --git a/vendor/gonum.org/v1/gonum/mat/svd_test.go b/vendor/gonum.org/v1/gonum/mat/svd_test.go new file mode 100644 index 00000000..54815c85 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/svd_test.go @@ -0,0 +1,172 @@ +// 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. + +package mat + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestSVD(t *testing.T) { + // Hand coded tests + for _, test := range []struct { + a *Dense + u *Dense + v *Dense + s []float64 + }{ + { + a: NewDense(4, 2, []float64{2, 4, 1, 3, 0, 0, 0, 0}), + u: NewDense(4, 2, []float64{ + -0.8174155604703632, -0.5760484367663209, + -0.5760484367663209, 0.8174155604703633, + 0, 0, + 0, 0, + }), + v: NewDense(2, 2, []float64{ + -0.4045535848337571, -0.9145142956773044, + -0.9145142956773044, 0.4045535848337571, + }), + s: []float64{5.464985704219041, 0.365966190626258}, + }, + { + // Issue #5. + a: NewDense(3, 11, []float64{ + 1, 1, 0, 1, 0, 0, 0, 0, 0, 11, 1, + 1, 0, 0, 0, 0, 0, 1, 0, 0, 12, 2, + 1, 1, 0, 0, 0, 0, 0, 0, 1, 13, 3, + }), + u: NewDense(3, 3, []float64{ + -0.5224167862273765, 0.7864430360363114, 0.3295270133658976, + -0.5739526766688285, -0.03852203026050301, -0.8179818935216693, + -0.6306021141833781, -0.6164603833618163, 0.4715056408282468, + }), + v: NewDense(11, 3, []float64{ + -0.08123293141915189, 0.08528085505260324, -0.013165501690885152, + -0.05423546426886932, 0.1102707844980355, 0.622210623111631, + 0, 0, 0, + -0.0245733326078166, 0.510179651760153, 0.25596360803140994, + 0, 0, 0, + 0, 0, 0, + -0.026997467150282436, -0.024989929445430496, -0.6353761248025164, + 0, 0, 0, + -0.029662131661052707, -0.3999088672621176, 0.3662470150802212, + -0.9798839760830571, 0.11328174160898856, -0.047702613241813366, + -0.16755466189153964, -0.7395268089170608, 0.08395240366704032, + }), + s: []float64{21.259500881097434, 1.5415021616856566, 1.2873979074613628}, + }, + } { + var svd SVD + ok := svd.Factorize(test.a, SVDThin) + if !ok { + t.Errorf("SVD failed") + } + s, u, v := extractSVD(&svd) + if !floats.EqualApprox(s, test.s, 1e-10) { + t.Errorf("Singular value mismatch. Got %v, want %v.", s, test.s) + } + if !EqualApprox(u, test.u, 1e-10) { + t.Errorf("U mismatch.\nGot:\n%v\nWant:\n%v", Formatted(u), Formatted(test.u)) + } + if !EqualApprox(v, test.v, 1e-10) { + t.Errorf("V mismatch.\nGot:\n%v\nWant:\n%v", Formatted(v), Formatted(test.v)) + } + m, n := test.a.Dims() + sigma := NewDense(min(m, n), min(m, n), nil) + for i := 0; i < min(m, n); i++ { + sigma.Set(i, i, s[i]) + } + + var ans Dense + ans.Product(u, sigma, v.T()) + if !EqualApprox(test.a, &ans, 1e-10) { + t.Errorf("A reconstruction mismatch.\nGot:\n%v\nWant:\n%v\n", Formatted(&ans), Formatted(test.a)) + } + } + + for _, test := range []struct { + m, n int + }{ + {5, 5}, + {5, 3}, + {3, 5}, + {150, 150}, + {200, 150}, + {150, 200}, + } { + m := test.m + n := test.n + for trial := 0; trial < 10; trial++ { + a := NewDense(m, n, nil) + for i := range a.mat.Data { + a.mat.Data[i] = rand.NormFloat64() + } + aCopy := DenseCopyOf(a) + + // Test Full decomposition. + var svd SVD + ok := svd.Factorize(a, SVDFull) + if !ok { + t.Errorf("SVD factorization failed") + } + if !Equal(a, aCopy) { + t.Errorf("A changed during call to SVD with full") + } + s, u, v := extractSVD(&svd) + sigma := NewDense(m, n, nil) + for i := 0; i < min(m, n); i++ { + sigma.Set(i, i, s[i]) + } + var ansFull Dense + ansFull.Product(u, sigma, v.T()) + if !EqualApprox(&ansFull, a, 1e-8) { + t.Errorf("Answer mismatch when SVDFull") + } + + // Test Thin decomposition. + ok = svd.Factorize(a, SVDThin) + if !ok { + t.Errorf("SVD factorization failed") + } + if !Equal(a, aCopy) { + t.Errorf("A changed during call to SVD with Thin") + } + sThin, u, v := extractSVD(&svd) + if !floats.EqualApprox(s, sThin, 1e-8) { + t.Errorf("Singular value mismatch between Full and Thin decomposition") + } + sigma = NewDense(min(m, n), min(m, n), nil) + for i := 0; i < min(m, n); i++ { + sigma.Set(i, i, sThin[i]) + } + ansFull.Reset() + ansFull.Product(u, sigma, v.T()) + if !EqualApprox(&ansFull, a, 1e-8) { + t.Errorf("Answer mismatch when SVDFull") + } + + // Test None decomposition. + ok = svd.Factorize(a, SVDNone) + if !ok { + t.Errorf("SVD factorization failed") + } + if !Equal(a, aCopy) { + t.Errorf("A changed during call to SVD with none") + } + sNone := make([]float64, min(m, n)) + svd.Values(sNone) + if !floats.EqualApprox(s, sNone, 1e-8) { + t.Errorf("Singular value mismatch between Full and None decomposition") + } + } + } +} + +func extractSVD(svd *SVD) (s []float64, u, v *Dense) { + return svd.Values(nil), svd.UTo(nil), svd.VTo(nil) +} diff --git a/vendor/gonum.org/v1/gonum/mat/symband.go b/vendor/gonum.org/v1/gonum/mat/symband.go new file mode 100644 index 00000000..986a3335 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/symband.go @@ -0,0 +1,175 @@ +// 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 mat + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +var ( + symBandDense *SymBandDense + _ Matrix = symBandDense + _ Symmetric = symBandDense + _ Banded = symBandDense + _ RawSymBander = symBandDense + _ MutableSymBanded = symBandDense + + _ NonZeroDoer = symBandDense + _ RowNonZeroDoer = symBandDense + _ ColNonZeroDoer = symBandDense +) + +// SymBandDense represents a symmetric band matrix in dense storage format. +type SymBandDense struct { + mat blas64.SymmetricBand +} + +// MutableSymBanded is a symmetric band matrix interface type that allows elements +// to be altered. +type MutableSymBanded interface { + Symmetric + Bandwidth() (kl, ku int) + SetSymBand(i, j int, v float64) +} + +// A RawSymBander can return a blas64.SymmetricBand representation of the receiver. +// Changes to the blas64.SymmetricBand.Data slice will be reflected in the original +// matrix, changes to the N, K, Stride and Uplo fields will not. +type RawSymBander interface { + RawSymBand() blas64.SymmetricBand +} + +// NewSymBandDense creates a new SymBand matrix with n rows and columns. If data == nil, +// a new slice is allocated for the backing slice. If len(data) == n*(k+1), +// data is used as the backing slice, and changes to the elements of the returned +// SymBandDense will be reflected in data. If neither of these is true, NewSymBandDense +// will panic. k must be at least zero and less than n, otherwise NewBandDense will panic. +// +// The data must be arranged in row-major order constructed by removing the zeros +// from the rows outside the band and aligning the diagonals. SymBandDense matrices +// are stored in the upper triangle. For example, the matrix +// 1 2 3 0 0 0 +// 2 4 5 6 0 0 +// 3 5 7 8 9 0 +// 0 6 8 10 11 12 +// 0 0 9 11 13 14 +// 0 0 0 12 14 15 +// becomes (* entries are never accessed) +// 1 2 3 +// 4 5 6 +// 7 8 9 +// 10 11 12 +// 13 14 * +// 15 * * +// which is passed to NewBandDense as []float64{1, 2, 3, 4, ...} with k=2. +// Only the values in the band portion of the matrix are used. +func NewSymBandDense(n, k int, data []float64) *SymBandDense { + if n < 0 || k < 0 { + panic("mat: negative dimension") + } + if k+1 > n { + panic("mat: band out of range") + } + bc := k + 1 + if data != nil && len(data) != n*bc { + panic(ErrShape) + } + if data == nil { + data = make([]float64, n*bc) + } + return &SymBandDense{ + mat: blas64.SymmetricBand{ + N: n, + K: k, + Stride: bc, + Uplo: blas.Upper, + Data: data, + }, + } +} + +// NewDiagonal is a convenience function that returns a diagonal matrix represented by a +// SymBandDense. The length of data must be n or data must be nil, otherwise NewDiagonal +// will panic. +func NewDiagonal(n int, data []float64) *SymBandDense { + return NewSymBandDense(n, 0, data) +} + +// Dims returns the number of rows and columns in the matrix. +func (s *SymBandDense) Dims() (r, c int) { + return s.mat.N, s.mat.N +} + +// Symmetric returns the size of the receiver. +func (s *SymBandDense) Symmetric() int { + return s.mat.N +} + +// Bandwidth returns the bandwidths of the matrix. +func (s *SymBandDense) Bandwidth() (kl, ku int) { + return s.mat.K, s.mat.K +} + +// T implements the Matrix interface. Symmetric matrices, by definition, are +// equal to their transpose, and this is a no-op. +func (s *SymBandDense) T() Matrix { + return s +} + +// TBand implements the Banded interface. +func (s *SymBandDense) TBand() Banded { + return s +} + +// RawSymBand returns the underlying blas64.SymBand used by the receiver. +// Changes to elements in the receiver following the call will be reflected +// in returned blas64.SymBand. +func (s *SymBandDense) RawSymBand() blas64.SymmetricBand { + return s.mat +} + +// DoNonZero calls the function fn for each of the non-zero elements of s. The function fn +// takes a row/column index and the element value of s at (i, j). +func (s *SymBandDense) DoNonZero(fn func(i, j int, v float64)) { + for i := 0; i < s.mat.N; i++ { + for j := max(0, i-s.mat.K); j < min(s.mat.N, i+s.mat.K+1); j++ { + v := s.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + } +} + +// DoRowNonZero calls the function fn for each of the non-zero elements of row i of s. The function fn +// takes a row/column index and the element value of s at (i, j). +func (s *SymBandDense) DoRowNonZero(i int, fn func(i, j int, v float64)) { + if i < 0 || s.mat.N <= i { + panic(ErrRowAccess) + } + for j := max(0, i-s.mat.K); j < min(s.mat.N, i+s.mat.K+1); j++ { + v := s.at(i, j) + if v != 0 { + fn(i, j, v) + } + } +} + +// DoColNonZero calls the function fn for each of the non-zero elements of column j of s. The function fn +// takes a row/column index and the element value of s at (i, j). +func (s *SymBandDense) DoColNonZero(j int, fn func(i, j int, v float64)) { + if j < 0 || s.mat.N <= j { + panic(ErrColAccess) + } + for i := 0; i < s.mat.N; i++ { + if i-s.mat.K <= j && j < i+s.mat.K+1 { + v := s.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/symband_test.go b/vendor/gonum.org/v1/gonum/mat/symband_test.go new file mode 100644 index 00000000..cf3e6808 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/symband_test.go @@ -0,0 +1,230 @@ +// 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 mat + +import ( + "reflect" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +func TestNewSymBand(t *testing.T) { + for i, test := range []struct { + data []float64 + n int + k int + mat *SymBandDense + dense *Dense + }{ + { + data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + 13, 14, -1, + 15, -1, -1, + }, + n: 6, + k: 2, + mat: &SymBandDense{ + mat: blas64.SymmetricBand{ + N: 6, + K: 2, + Stride: 3, + Uplo: blas.Upper, + Data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + 13, 14, -1, + 15, -1, -1, + }, + }, + }, + dense: NewDense(6, 6, []float64{ + 1, 2, 3, 0, 0, 0, + 2, 4, 5, 6, 0, 0, + 3, 5, 7, 8, 9, 0, + 0, 6, 8, 10, 11, 12, + 0, 0, 9, 11, 13, 14, + 0, 0, 0, 12, 14, 15, + }), + }, + } { + band := NewSymBandDense(test.n, test.k, test.data) + rows, cols := band.Dims() + + if rows != test.n { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n) + } + if cols != test.n { + t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.n) + } + if !reflect.DeepEqual(band, test.mat) { + t.Errorf("unexpected value via reflect for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.mat) { + t.Errorf("unexpected value via mat.Equal for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.dense) { + t.Errorf("unexpected value via mat.Equal(band, dense) for test %d:\ngot:\n% v\nwant:\n% v", i, Formatted(band), Formatted(test.dense)) + } + } +} + +func TestNewDiagonal(t *testing.T) { + for i, test := range []struct { + data []float64 + n int + mat *SymBandDense + dense *Dense + }{ + { + data: []float64{1, 2, 3, 4, 5, 6}, + n: 6, + mat: &SymBandDense{ + mat: blas64.SymmetricBand{ + N: 6, + Stride: 1, + Uplo: blas.Upper, + Data: []float64{1, 2, 3, 4, 5, 6}, + }, + }, + dense: NewDense(6, 6, []float64{ + 1, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 0, 0, 0, 6, + }), + }, + } { + band := NewDiagonal(test.n, test.data) + rows, cols := band.Dims() + + if rows != test.n { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n) + } + if cols != test.n { + t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.n) + } + if !reflect.DeepEqual(band, test.mat) { + t.Errorf("unexpected value via reflect for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.mat) { + t.Errorf("unexpected value via mat.Equal for test %d: got: %v want: %v", i, band, test.mat) + } + if !Equal(band, test.dense) { + t.Errorf("unexpected value via mat.Equal(band, dense) for test %d:\ngot:\n% v\nwant:\n% v", i, Formatted(band), Formatted(test.dense)) + } + } +} + +func TestSymBandAtSet(t *testing.T) { + // 1 2 3 0 0 0 + // 2 4 5 6 0 0 + // 3 5 7 8 9 0 + // 0 6 8 10 11 12 + // 0 0 9 11 13 14 + // 0 0 0 12 14 16 + band := NewSymBandDense(6, 2, []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10, 11, 12, + 13, 14, -1, + 16, -1, -1, + }) + + rows, cols := band.Dims() + kl, ku := band.Bandwidth() + + // Explicitly test all indexes. + want := bandImplicit{rows, cols, kl, ku, func(i, j int) float64 { + if i > j { + i, j = j, i + } + return float64(i*ku + j + 1) + }} + for i := 0; i < 6; i++ { + for j := 0; j < 6; j++ { + if band.At(i, j) != want.At(i, j) { + t.Errorf("unexpected value for band.At(%d, %d): got:%v want:%v", i, j, band.At(i, j), want.At(i, j)) + } + } + } + // Do that same thing via a call to Equal. + if !Equal(band, want) { + t.Errorf("unexpected value via mat.Equal:\ngot:\n% v\nwant:\n% v", Formatted(band), Formatted(want)) + } + + // Check At out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { band.At(row, 0) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { band.At(0, col) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + // Check Set out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { band.SetSymBand(row, 0, 1.2) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { band.SetSymBand(0, col, 1.2) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + for _, st := range []struct { + row, col int + }{ + {row: 0, col: 3}, + {row: 0, col: 4}, + {row: 0, col: 5}, + {row: 1, col: 4}, + {row: 1, col: 5}, + {row: 2, col: 5}, + {row: 3, col: 0}, + {row: 4, col: 1}, + {row: 5, col: 2}, + } { + panicked, message := panics(func() { band.SetSymBand(st.row, st.col, 1.2) }) + if !panicked || message != ErrBandSet.Error() { + t.Errorf("expected panic for %+v %s", st, message) + } + } + + for _, st := range []struct { + row, col int + orig, new float64 + }{ + {row: 1, col: 2, orig: 5, new: 15}, + {row: 2, col: 3, orig: 8, new: 15}, + } { + if e := band.At(st.row, st.col); e != st.orig { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", st.row, st.col, e, st.orig) + } + band.SetSymBand(st.row, st.col, st.new) + if e := band.At(st.row, st.col); e != st.new { + t.Errorf("unexpected value for At(%d, %d) after SetSymBand(%[1]d, %d, %v): got: %v want: %[3]v", st.row, st.col, st.new, e) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/symmetric.go b/vendor/gonum.org/v1/gonum/mat/symmetric.go new file mode 100644 index 00000000..98802d94 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/symmetric.go @@ -0,0 +1,502 @@ +// 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 mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +var ( + symDense *SymDense + + _ Matrix = symDense + _ Symmetric = symDense + _ RawSymmetricer = symDense + _ MutableSymmetric = symDense +) + +const ( + badSymTriangle = "mat: blas64.Symmetric not upper" + badSymCap = "mat: bad capacity for SymDense" +) + +// SymDense is a symmetric matrix that uses dense storage. SymDense +// matrices are stored in the upper triangle. +type SymDense struct { + mat blas64.Symmetric + cap int +} + +// Symmetric represents a symmetric matrix (where the element at {i, j} equals +// the element at {j, i}). Symmetric matrices are always square. +type Symmetric interface { + Matrix + // Symmetric returns the number of rows/columns in the matrix. + Symmetric() int +} + +// A RawSymmetricer can return a view of itself as a BLAS Symmetric matrix. +type RawSymmetricer interface { + RawSymmetric() blas64.Symmetric +} + +// A MutableSymmetric can set elements of a symmetric matrix. +type MutableSymmetric interface { + Symmetric + SetSym(i, j int, v float64) +} + +// NewSymDense creates a new Symmetric matrix with n rows and columns. If data == nil, +// a new slice is allocated for the backing slice. If len(data) == n*n, data is +// used as the backing slice, and changes to the elements of the returned SymDense +// will be reflected in data. If neither of these is true, NewSymDense will panic. +// +// The data must be arranged in row-major order, i.e. the (i*c + j)-th +// element in the data slice is the {i, j}-th element in the matrix. +// Only the values in the upper triangular portion of the matrix are used. +func NewSymDense(n int, data []float64) *SymDense { + if n < 0 { + panic("mat: negative dimension") + } + if data != nil && n*n != len(data) { + panic(ErrShape) + } + if data == nil { + data = make([]float64, n*n) + } + return &SymDense{ + mat: blas64.Symmetric{ + N: n, + Stride: n, + Data: data, + Uplo: blas.Upper, + }, + cap: n, + } +} + +// Dims returns the number of rows and columns in the matrix. +func (s *SymDense) Dims() (r, c int) { + return s.mat.N, s.mat.N +} + +// Caps returns the number of rows and columns in the backing matrix. +func (s *SymDense) Caps() (r, c int) { + return s.cap, s.cap +} + +// T implements the Matrix interface. Symmetric matrices, by definition, are +// equal to their transpose, and this is a no-op. +func (s *SymDense) T() Matrix { + return s +} + +func (s *SymDense) Symmetric() int { + return s.mat.N +} + +// RawSymmetric returns the matrix as a blas64.Symmetric. The returned +// value must be stored in upper triangular format. +func (s *SymDense) RawSymmetric() blas64.Symmetric { + return s.mat +} + +// SetRawSymmetric sets the underlying blas64.Symmetric used by the receiver. +// Changes to elements in the receiver following the call will be reflected +// in b. SetRawSymmetric will panic if b is not an upper-encoded symmetric +// matrix. +func (s *SymDense) SetRawSymmetric(b blas64.Symmetric) { + if b.Uplo != blas.Upper { + panic(badSymTriangle) + } + s.mat = b +} + +// Reset zeros the dimensions of the matrix so that it can be reused as the +// receiver of a dimensionally restricted operation. +// +// See the Reseter interface for more information. +func (s *SymDense) Reset() { + // N and Stride must be zeroed in unison. + s.mat.N, s.mat.Stride = 0, 0 + s.mat.Data = s.mat.Data[:0] +} + +// IsZero returns whether the receiver is zero-sized. Zero-sized matrices can be the +// receiver for size-restricted operations. SymDense matrices can be zeroed using Reset. +func (s *SymDense) IsZero() bool { + // It must be the case that m.Dims() returns + // zeros in this case. See comment in Reset(). + return s.mat.N == 0 +} + +// reuseAs resizes an empty matrix to a n×n matrix, +// or checks that a non-empty matrix is n×n. +func (s *SymDense) reuseAs(n int) { + if s.mat.N > s.cap { + panic(badSymCap) + } + if s.IsZero() { + s.mat = blas64.Symmetric{ + N: n, + Stride: n, + Data: use(s.mat.Data, n*n), + Uplo: blas.Upper, + } + s.cap = n + return + } + if s.mat.Uplo != blas.Upper { + panic(badSymTriangle) + } + if s.mat.N != n { + panic(ErrShape) + } +} + +func (s *SymDense) isolatedWorkspace(a Symmetric) (w *SymDense, restore func()) { + n := a.Symmetric() + w = getWorkspaceSym(n, false) + return w, func() { + s.CopySym(w) + putWorkspaceSym(w) + } +} + +func (s *SymDense) AddSym(a, b Symmetric) { + n := a.Symmetric() + if n != b.Symmetric() { + panic(ErrShape) + } + s.reuseAs(n) + + if a, ok := a.(RawSymmetricer); ok { + if b, ok := b.(RawSymmetricer); ok { + amat, bmat := a.RawSymmetric(), b.RawSymmetric() + if s != a { + s.checkOverlap(amat) + } + if s != b { + s.checkOverlap(bmat) + } + for i := 0; i < n; i++ { + btmp := bmat.Data[i*bmat.Stride+i : i*bmat.Stride+n] + stmp := s.mat.Data[i*s.mat.Stride+i : i*s.mat.Stride+n] + for j, v := range amat.Data[i*amat.Stride+i : i*amat.Stride+n] { + stmp[j] = v + btmp[j] + } + } + return + } + } + + for i := 0; i < n; i++ { + stmp := s.mat.Data[i*s.mat.Stride : i*s.mat.Stride+n] + for j := i; j < n; j++ { + stmp[j] = a.At(i, j) + b.At(i, j) + } + } +} + +func (s *SymDense) CopySym(a Symmetric) int { + n := a.Symmetric() + n = min(n, s.mat.N) + if n == 0 { + return 0 + } + switch a := a.(type) { + case RawSymmetricer: + amat := a.RawSymmetric() + if amat.Uplo != blas.Upper { + panic(badSymTriangle) + } + for i := 0; i < n; i++ { + copy(s.mat.Data[i*s.mat.Stride+i:i*s.mat.Stride+n], amat.Data[i*amat.Stride+i:i*amat.Stride+n]) + } + default: + for i := 0; i < n; i++ { + stmp := s.mat.Data[i*s.mat.Stride : i*s.mat.Stride+n] + for j := i; j < n; j++ { + stmp[j] = a.At(i, j) + } + } + } + return n +} + +// SymRankOne performs a symetric rank-one update to the matrix a and stores +// the result in the receiver +// s = a + alpha * x * x' +func (s *SymDense) SymRankOne(a Symmetric, alpha float64, x *VecDense) { + n := x.Len() + if a.Symmetric() != n { + panic(ErrShape) + } + s.reuseAs(n) + if s != a { + if rs, ok := a.(RawSymmetricer); ok { + s.checkOverlap(rs.RawSymmetric()) + } + s.CopySym(a) + } + blas64.Syr(alpha, x.mat, s.mat) +} + +// SymRankK performs a symmetric rank-k update to the matrix a and stores the +// result into the receiver. If a is zero, see SymOuterK. +// s = a + alpha * x * x' +func (s *SymDense) SymRankK(a Symmetric, alpha float64, x Matrix) { + n := a.Symmetric() + r, _ := x.Dims() + if r != n { + panic(ErrShape) + } + xMat, aTrans := untranspose(x) + var g blas64.General + if rm, ok := xMat.(RawMatrixer); ok { + g = rm.RawMatrix() + } else { + g = DenseCopyOf(x).mat + aTrans = false + } + if a != s { + if rs, ok := a.(RawSymmetricer); ok { + s.checkOverlap(rs.RawSymmetric()) + } + s.reuseAs(n) + s.CopySym(a) + } + t := blas.NoTrans + if aTrans { + t = blas.Trans + } + blas64.Syrk(t, alpha, g, 1, s.mat) +} + +// SymOuterK calculates the outer product of x with itself and stores +// the result into the receiver. It is equivalent to the matrix +// multiplication +// s = alpha * x * x'. +// In order to update an existing matrix, see SymRankOne. +func (s *SymDense) SymOuterK(alpha float64, x Matrix) { + n, _ := x.Dims() + switch { + case s.IsZero(): + s.mat = blas64.Symmetric{ + N: n, + Stride: n, + Data: useZeroed(s.mat.Data, n*n), + Uplo: blas.Upper, + } + s.cap = n + s.SymRankK(s, alpha, x) + case s.mat.Uplo != blas.Upper: + panic(badSymTriangle) + case s.mat.N == n: + if s == x { + w := getWorkspaceSym(n, true) + w.SymRankK(w, alpha, x) + s.CopySym(w) + putWorkspaceSym(w) + } else { + if rs, ok := x.(RawSymmetricer); ok { + s.checkOverlap(rs.RawSymmetric()) + } + // Only zero the upper triangle. + for i := 0; i < n; i++ { + ri := i * s.mat.Stride + zero(s.mat.Data[ri+i : ri+n]) + } + s.SymRankK(s, alpha, x) + } + default: + panic(ErrShape) + } +} + +// RankTwo performs a symmmetric rank-two update to the matrix a and stores +// the result in the receiver +// m = a + alpha * (x * y' + y * x') +func (s *SymDense) RankTwo(a Symmetric, alpha float64, x, y *VecDense) { + n := s.mat.N + if x.Len() != n { + panic(ErrShape) + } + if y.Len() != n { + panic(ErrShape) + } + var w SymDense + if s == a { + w = *s + } + w.reuseAs(n) + if s != a { + if rs, ok := a.(RawSymmetricer); ok { + s.checkOverlap(rs.RawSymmetric()) + } + w.CopySym(a) + } + blas64.Syr2(alpha, x.mat, y.mat, w.mat) + *s = w +} + +// ScaleSym multiplies the elements of a by f, placing the result in the receiver. +func (s *SymDense) ScaleSym(f float64, a Symmetric) { + n := a.Symmetric() + s.reuseAs(n) + if a, ok := a.(RawSymmetricer); ok { + amat := a.RawSymmetric() + if s != a { + s.checkOverlap(amat) + } + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + s.mat.Data[i*s.mat.Stride+j] = f * amat.Data[i*amat.Stride+j] + } + } + return + } + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + s.mat.Data[i*s.mat.Stride+j] = f * a.At(i, j) + } + } +} + +// SubsetSym extracts a subset of the rows and columns of the matrix a and stores +// the result in-place into the receiver. The resulting matrix size is +// len(set)×len(set). Specifically, at the conclusion of SubsetSym, +// s.At(i, j) equals a.At(set[i], set[j]). Note that the supplied set does not +// have to be a strict subset, dimension repeats are allowed. +func (s *SymDense) SubsetSym(a Symmetric, set []int) { + n := len(set) + na := a.Symmetric() + s.reuseAs(n) + var restore func() + if a == s { + s, restore = s.isolatedWorkspace(a) + defer restore() + } + + if a, ok := a.(RawSymmetricer); ok { + raw := a.RawSymmetric() + if s != a { + s.checkOverlap(raw) + } + for i := 0; i < n; i++ { + ssub := s.mat.Data[i*s.mat.Stride : i*s.mat.Stride+n] + r := set[i] + rsub := raw.Data[r*raw.Stride : r*raw.Stride+na] + for j := i; j < n; j++ { + c := set[j] + if r <= c { + ssub[j] = rsub[c] + } else { + ssub[j] = raw.Data[c*raw.Stride+r] + } + } + } + return + } + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + s.mat.Data[i*s.mat.Stride+j] = a.At(set[i], set[j]) + } + } +} + +// SliceSquare returns a new Matrix that shares backing data with the receiver. +// The returned matrix starts at {i,i} of the receiver and extends k-i rows +// and columns. The final row and column in the resulting matrix is k-1. +// SliceSquare panics with ErrIndexOutOfRange if the slice is outside the capacity +// of the receiver. +func (s *SymDense) SliceSquare(i, k int) Matrix { + sz := s.cap + if i < 0 || sz < i || k < i || sz < k { + panic(ErrIndexOutOfRange) + } + v := *s + v.mat.Data = s.mat.Data[i*s.mat.Stride+i : (k-1)*s.mat.Stride+k] + v.mat.N = k - i + v.cap = s.cap - i + return &v +} + +// GrowSquare returns the receiver expanded by n rows and n columns. If the +// dimensions of the expanded matrix are outside the capacity of the receiver +// a new allocation is made, otherwise not. Note that the receiver itself is +// not modified during the call to GrowSquare. +func (s *SymDense) GrowSquare(n int) Matrix { + if n < 0 { + panic(ErrIndexOutOfRange) + } + if n == 0 { + return s + } + var v SymDense + n += s.mat.N + if n > s.cap { + v.mat = blas64.Symmetric{ + N: n, + Stride: n, + Uplo: blas.Upper, + Data: make([]float64, n*n), + } + v.cap = n + // Copy elements, including those not currently visible. Use a temporary + // structure to avoid modifying the receiver. + var tmp SymDense + tmp.mat = blas64.Symmetric{ + N: s.cap, + Stride: s.mat.Stride, + Data: s.mat.Data, + Uplo: s.mat.Uplo, + } + tmp.cap = s.cap + v.CopySym(&tmp) + return &v + } + v.mat = blas64.Symmetric{ + N: n, + Stride: s.mat.Stride, + Uplo: blas.Upper, + Data: s.mat.Data[:(n-1)*s.mat.Stride+n], + } + v.cap = s.cap + return &v +} + +// PowPSD computes a^pow where a is a positive symmetric definite matrix. +// +// PowPSD returns an error if the matrix is not not positive symmetric definite +// or the Eigendecomposition is not successful. +func (s *SymDense) PowPSD(a Symmetric, pow float64) error { + dim := a.Symmetric() + s.reuseAs(dim) + + var eigen EigenSym + ok := eigen.Factorize(a, true) + if !ok { + return ErrFailedEigen + } + values := eigen.Values(nil) + for i, v := range values { + if v <= 0 { + return ErrNotPSD + } + values[i] = math.Pow(v, pow) + } + var u Dense + u.EigenvectorsSym(&eigen) + + s.SymOuterK(values[0], u.ColView(0)) + for i := 1; i < dim; i++ { + s.SymRankOne(s, values[i], u.ColView(i)) + } + return nil +} diff --git a/vendor/gonum.org/v1/gonum/mat/symmetric_example_test.go b/vendor/gonum.org/v1/gonum/mat/symmetric_example_test.go new file mode 100644 index 00000000..2616d6f4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/symmetric_example_test.go @@ -0,0 +1,54 @@ +// 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 mat_test + +import ( + "fmt" + + "gonum.org/v1/gonum/mat" +) + +func ExampleSymDense_SubsetSym() { + n := 5 + s := mat.NewSymDense(5, nil) + count := 1.0 + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + s.SetSym(i, j, count) + count++ + } + } + fmt.Println("Original matrix:") + fmt.Printf("%0.4v\n\n", mat.Formatted(s)) + + // Take the subset {0, 2, 4} + var sub mat.SymDense + sub.SubsetSym(s, []int{0, 2, 4}) + fmt.Println("Subset {0, 2, 4}") + fmt.Printf("%0.4v\n\n", mat.Formatted(&sub)) + + // Take the subset {0, 0, 4} + sub.SubsetSym(s, []int{0, 0, 4}) + fmt.Println("Subset {0, 0, 4}") + fmt.Printf("%0.4v\n\n", mat.Formatted(&sub)) + + // Output: + // Original matrix: + // ⎡ 1 2 3 4 5⎤ + // ⎢ 2 6 7 8 9⎥ + // ⎢ 3 7 10 11 12⎥ + // ⎢ 4 8 11 13 14⎥ + // ⎣ 5 9 12 14 15⎦ + // + // Subset {0, 2, 4} + // ⎡ 1 3 5⎤ + // ⎢ 3 10 12⎥ + // ⎣ 5 12 15⎦ + // + // Subset {0, 0, 4} + // ⎡ 1 1 5⎤ + // ⎢ 1 1 5⎥ + // ⎣ 5 5 15⎦ +} diff --git a/vendor/gonum.org/v1/gonum/mat/symmetric_test.go b/vendor/gonum.org/v1/gonum/mat/symmetric_test.go new file mode 100644 index 00000000..48210aa4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/symmetric_test.go @@ -0,0 +1,694 @@ +// 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 mat + +import ( + "fmt" + "math/rand" + "os" + "reflect" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/floats" +) + +func TestNewSymmetric(t *testing.T) { + for i, test := range []struct { + data []float64 + n int + mat *SymDense + }{ + { + data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }, + n: 3, + mat: &SymDense{ + mat: blas64.Symmetric{ + N: 3, + Stride: 3, + Uplo: blas.Upper, + Data: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + cap: 3, + }, + }, + } { + sym := NewSymDense(test.n, test.data) + rows, cols := sym.Dims() + + if rows != test.n { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n) + } + if cols != test.n { + t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.n) + } + if !reflect.DeepEqual(sym, test.mat) { + t.Errorf("unexpected data slice for test %d: got: %v want: %v", i, sym, test.mat) + } + + m := NewDense(test.n, test.n, test.data) + if !reflect.DeepEqual(sym.mat.Data, m.mat.Data) { + t.Errorf("unexpected data slice mismatch for test %d: got: %v want: %v", i, sym.mat.Data, m.mat.Data) + } + } + + panicked, message := panics(func() { NewSymDense(3, []float64{1, 2}) }) + if !panicked || message != ErrShape.Error() { + t.Error("expected panic for invalid data slice length") + } +} + +func TestSymAtSet(t *testing.T) { + sym := &SymDense{ + mat: blas64.Symmetric{ + N: 3, + Stride: 3, + Uplo: blas.Upper, + Data: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}, + }, + cap: 3, + } + rows, cols := sym.Dims() + + // Check At out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { sym.At(row, 0) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { sym.At(0, col) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + // Check Set out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { sym.SetSym(row, 0, 1.2) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { sym.SetSym(0, col, 1.2) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + for _, st := range []struct { + row, col int + orig, new float64 + }{ + {row: 1, col: 2, orig: 6, new: 15}, + {row: 2, col: 1, orig: 15, new: 12}, + } { + if e := sym.At(st.row, st.col); e != st.orig { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", st.row, st.col, e, st.orig) + } + if e := sym.At(st.col, st.row); e != st.orig { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", st.col, st.row, e, st.orig) + } + sym.SetSym(st.row, st.col, st.new) + if e := sym.At(st.row, st.col); e != st.new { + t.Errorf("unexpected value for At(%d, %d) after SetSym(%[1]d, %[2]d, %[4]v): got: %[3]v want: %v", st.row, st.col, e, st.new) + } + if e := sym.At(st.col, st.row); e != st.new { + t.Errorf("unexpected value for At(%d, %d) after SetSym(%[2]d, %[1]d, %[4]v): got: %[3]v want: %v", st.col, st.row, e, st.new) + } + } +} + +func TestSymAdd(t *testing.T) { + for _, test := range []struct { + n int + }{ + {n: 1}, + {n: 2}, + {n: 3}, + {n: 4}, + {n: 5}, + {n: 10}, + } { + n := test.n + a := NewSymDense(n, nil) + for i := range a.mat.Data { + a.mat.Data[i] = rand.Float64() + } + b := NewSymDense(n, nil) + for i := range a.mat.Data { + b.mat.Data[i] = rand.Float64() + } + var m Dense + m.Add(a, b) + + // Check with new receiver + var s SymDense + s.AddSym(a, b) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + want := m.At(i, j) + if got := s.At(i, j); got != want { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", i, j, got, want) + } + } + } + + // Check with equal receiver + s.CopySym(a) + s.AddSym(&s, b) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + want := m.At(i, j) + if got := s.At(i, j); got != want { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", i, j, got, want) + } + } + } + } + + method := func(receiver, a, b Matrix) { + type addSymer interface { + AddSym(a, b Symmetric) + } + rd := receiver.(addSymer) + rd.AddSym(a.(Symmetric), b.(Symmetric)) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Add(a, b) + } + testTwoInput(t, "AddSym", &SymDense{}, method, denseComparison, legalTypesSym, legalSizeSameSquare, 1e-14) +} + +func TestCopy(t *testing.T) { + for _, test := range []struct { + n int + }{ + {n: 1}, + {n: 2}, + {n: 3}, + {n: 4}, + {n: 5}, + {n: 10}, + } { + n := test.n + a := NewSymDense(n, nil) + for i := range a.mat.Data { + a.mat.Data[i] = rand.Float64() + } + s := NewSymDense(n, nil) + s.CopySym(a) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + want := a.At(i, j) + if got := s.At(i, j); got != want { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", i, j, got, want) + } + } + } + } +} + +// TODO(kortschak) Roll this into testOneInput when it exists. +// https://github.com/gonum/matrix/issues/171 +func TestSymCopyPanic(t *testing.T) { + var ( + a SymDense + n int + ) + m := NewSymDense(1, nil) + panicked, message := panics(func() { n = m.CopySym(&a) }) + if panicked { + t.Errorf("unexpected panic: %v", message) + } + if n != 0 { + t.Errorf("unexpected n: got: %d want: 0", n) + } +} + +func TestSymRankOne(t *testing.T) { + for _, test := range []struct { + n int + }{ + {n: 1}, + {n: 2}, + {n: 3}, + {n: 4}, + {n: 5}, + {n: 10}, + } { + n := test.n + alpha := 2.0 + a := NewSymDense(n, nil) + for i := range a.mat.Data { + a.mat.Data[i] = rand.Float64() + } + x := make([]float64, n) + for i := range x { + x[i] = rand.Float64() + } + + xMat := NewDense(n, 1, x) + var m Dense + m.Mul(xMat, xMat.T()) + m.Scale(alpha, &m) + m.Add(&m, a) + + // Check with new receiver + s := NewSymDense(n, nil) + s.SymRankOne(a, alpha, NewVecDense(len(x), x)) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + want := m.At(i, j) + if got := s.At(i, j); got != want { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", i, j, got, want) + } + } + } + + // Check with reused receiver + copy(s.mat.Data, a.mat.Data) + s.SymRankOne(s, alpha, NewVecDense(len(x), x)) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + want := m.At(i, j) + if got := s.At(i, j); got != want { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", i, j, got, want) + } + } + } + } + + alpha := 3.0 + method := func(receiver, a, b Matrix) { + type SymRankOner interface { + SymRankOne(a Symmetric, alpha float64, x *VecDense) + } + rd := receiver.(SymRankOner) + rd.SymRankOne(a.(Symmetric), alpha, b.(*VecDense)) + } + denseComparison := func(receiver, a, b *Dense) { + var tmp Dense + tmp.Mul(b, b.T()) + tmp.Scale(alpha, &tmp) + receiver.Add(a, &tmp) + } + legalTypes := func(a, b Matrix) bool { + _, ok := a.(Symmetric) + if !ok { + return false + } + _, ok = b.(*VecDense) + return ok + } + legalSize := func(ar, ac, br, bc int) bool { + if ar != ac { + return false + } + return br == ar + } + testTwoInput(t, "SymRankOne", &SymDense{}, method, denseComparison, legalTypes, legalSize, 1e-14) +} + +func TestIssue250SymRankOne(t *testing.T) { + x := NewVecDense(5, []float64{1, 2, 3, 4, 5}) + var s1, s2 SymDense + s1.SymRankOne(NewSymDense(5, nil), 1, x) + s2.SymRankOne(NewSymDense(5, nil), 1, x) + s2.SymRankOne(NewSymDense(5, nil), 1, x) + if !Equal(&s1, &s2) { + t.Error("unexpected result from repeat") + } +} + +func TestRankTwo(t *testing.T) { + for _, test := range []struct { + n int + }{ + {n: 1}, + {n: 2}, + {n: 3}, + {n: 4}, + {n: 5}, + {n: 10}, + } { + n := test.n + alpha := 2.0 + a := NewSymDense(n, nil) + for i := range a.mat.Data { + a.mat.Data[i] = rand.Float64() + } + x := make([]float64, n) + y := make([]float64, n) + for i := range x { + x[i] = rand.Float64() + y[i] = rand.Float64() + } + + xMat := NewDense(n, 1, x) + yMat := NewDense(n, 1, y) + var m Dense + m.Mul(xMat, yMat.T()) + var tmp Dense + tmp.Mul(yMat, xMat.T()) + m.Add(&m, &tmp) + m.Scale(alpha, &m) + m.Add(&m, a) + + // Check with new receiver + s := NewSymDense(n, nil) + s.RankTwo(a, alpha, NewVecDense(len(x), x), NewVecDense(len(y), y)) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + if !floats.EqualWithinAbsOrRel(s.At(i, j), m.At(i, j), 1e-14, 1e-14) { + t.Errorf("unexpected element value at (%d,%d): got: %f want: %f", i, j, m.At(i, j), s.At(i, j)) + } + } + } + + // Check with reused receiver + copy(s.mat.Data, a.mat.Data) + s.RankTwo(s, alpha, NewVecDense(len(x), x), NewVecDense(len(y), y)) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + if !floats.EqualWithinAbsOrRel(s.At(i, j), m.At(i, j), 1e-14, 1e-14) { + t.Errorf("unexpected element value at (%d,%d): got: %f want: %f", i, j, m.At(i, j), s.At(i, j)) + } + } + } + } +} + +func TestSymRankK(t *testing.T) { + alpha := 3.0 + method := func(receiver, a, b Matrix) { + type SymRankKer interface { + SymRankK(a Symmetric, alpha float64, x Matrix) + } + rd := receiver.(SymRankKer) + rd.SymRankK(a.(Symmetric), alpha, b) + } + denseComparison := func(receiver, a, b *Dense) { + var tmp Dense + tmp.Mul(b, b.T()) + tmp.Scale(alpha, &tmp) + receiver.Add(a, &tmp) + } + legalTypes := func(a, b Matrix) bool { + _, ok := a.(Symmetric) + return ok + } + legalSize := func(ar, ac, br, bc int) bool { + if ar != ac { + return false + } + return br == ar + } + testTwoInput(t, "SymRankK", &SymDense{}, method, denseComparison, legalTypes, legalSize, 1e-14) +} + +func TestSymOuterK(t *testing.T) { + for _, f := range []float64{0.5, 1, 3} { + method := func(receiver, x Matrix) { + type SymOuterKer interface { + SymOuterK(alpha float64, x Matrix) + } + rd := receiver.(SymOuterKer) + rd.SymOuterK(f, x) + } + denseComparison := func(receiver, x *Dense) { + receiver.Mul(x, x.T()) + receiver.Scale(f, receiver) + } + testOneInput(t, "SymOuterK", &SymDense{}, method, denseComparison, isAnyType, isAnySize, 1e-14) + } +} + +func TestIssue250SymOuterK(t *testing.T) { + x := NewVecDense(5, []float64{1, 2, 3, 4, 5}) + var s1, s2 SymDense + s1.SymOuterK(1, x) + s2.SymOuterK(1, x) + s2.SymOuterK(1, x) + if !Equal(&s1, &s2) { + t.Error("unexpected result from repeat") + } +} + +func TestScaleSym(t *testing.T) { + for _, f := range []float64{0.5, 1, 3} { + method := func(receiver, a Matrix) { + type ScaleSymer interface { + ScaleSym(f float64, a Symmetric) + } + rd := receiver.(ScaleSymer) + rd.ScaleSym(f, a.(Symmetric)) + } + denseComparison := func(receiver, a *Dense) { + receiver.Scale(f, a) + } + testOneInput(t, "ScaleSym", &SymDense{}, method, denseComparison, legalTypeSym, isSquare, 1e-14) + } +} + +func TestSubsetSym(t *testing.T) { + for _, test := range []struct { + a *SymDense + dims []int + ans *SymDense + }{ + { + a: NewSymDense(3, []float64{ + 1, 2, 3, + 0, 4, 5, + 0, 0, 6, + }), + dims: []int{0, 2}, + ans: NewSymDense(2, []float64{ + 1, 3, + 0, 6, + }), + }, + { + a: NewSymDense(3, []float64{ + 1, 2, 3, + 0, 4, 5, + 0, 0, 6, + }), + dims: []int{2, 0}, + ans: NewSymDense(2, []float64{ + 6, 3, + 0, 1, + }), + }, + { + a: NewSymDense(3, []float64{ + 1, 2, 3, + 0, 4, 5, + 0, 0, 6, + }), + dims: []int{1, 1, 1}, + ans: NewSymDense(3, []float64{ + 4, 4, 4, + 0, 4, 4, + 0, 0, 4, + }), + }, + } { + var s SymDense + s.SubsetSym(test.a, test.dims) + if !Equal(&s, test.ans) { + t.Errorf("SubsetSym mismatch dims %v\nGot:\n% v\nWant:\n% v\n", test.dims, s, test.ans) + } + } + + dims := []int{0, 2} + maxDim := dims[0] + for _, v := range dims { + if maxDim < v { + maxDim = v + } + } + method := func(receiver, a Matrix) { + type SubsetSymer interface { + SubsetSym(a Symmetric, set []int) + } + rd := receiver.(SubsetSymer) + rd.SubsetSym(a.(Symmetric), dims) + } + denseComparison := func(receiver, a *Dense) { + *receiver = *NewDense(len(dims), len(dims), nil) + sz := len(dims) + for i := 0; i < sz; i++ { + for j := 0; j < sz; j++ { + receiver.Set(i, j, a.At(dims[i], dims[j])) + } + } + } + legalSize := func(ar, ac int) bool { + return ar == ac && ar > maxDim + } + + testOneInput(t, "SubsetSym", &SymDense{}, method, denseComparison, legalTypeSym, legalSize, 0) +} + +func TestViewGrowSquare(t *testing.T) { + // n is the size of the original SymDense. + // The first view uses start1, span1. The second view uses start2, span2 on + // the first view. + for _, test := range []struct { + n, start1, span1, start2, span2 int + }{ + {10, 0, 10, 0, 10}, + {10, 0, 8, 0, 8}, + {10, 2, 8, 0, 6}, + {10, 2, 7, 4, 2}, + {10, 2, 6, 0, 5}, + } { + n := test.n + s := NewSymDense(n, nil) + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + s.SetSym(i, j, float64((i+1)*n+j+1)) + } + } + + // Take a subset and check the view matches. + start1 := test.start1 + span1 := test.span1 + v := s.SliceSquare(start1, start1+span1).(*SymDense) + for i := 0; i < span1; i++ { + for j := i; j < span1; j++ { + if v.At(i, j) != s.At(start1+i, start1+j) { + t.Errorf("View mismatch") + } + } + } + + start2 := test.start2 + span2 := test.span2 + v2 := v.SliceSquare(start2, start2+span2).(*SymDense) + + for i := 0; i < span2; i++ { + for j := i; j < span2; j++ { + if v2.At(i, j) != s.At(start1+start2+i, start1+start2+j) { + t.Errorf("Second view mismatch") + } + } + } + + // Check that a write to the view is reflected in the original. + v2.SetSym(0, 0, 1.2) + if s.At(start1+start2, start1+start2) != 1.2 { + t.Errorf("Write to view not reflected in original") + } + + // Grow the matrix back to the original view + gn := n - start1 - start2 + g := v2.GrowSquare(gn - v2.Symmetric()).(*SymDense) + g.SetSym(1, 1, 2.2) + + for i := 0; i < gn; i++ { + for j := 0; j < gn; j++ { + if g.At(i, j) != s.At(start1+start2+i, start1+start2+j) { + t.Errorf("Grow mismatch") + + fmt.Printf("g=\n% v\n", Formatted(g)) + fmt.Printf("s=\n% v\n", Formatted(s)) + os.Exit(1) + } + } + } + + // View g, then grow it and make sure all the elements were copied. + gv := g.SliceSquare(0, gn-1).(*SymDense) + + gg := gv.GrowSquare(2) + for i := 0; i < gn; i++ { + for j := 0; j < gn; j++ { + if g.At(i, j) != gg.At(i, j) { + t.Errorf("Expand mismatch") + } + } + } + } +} + +func TestPowPSD(t *testing.T) { + for cas, test := range []struct { + a *SymDense + pow float64 + ans *SymDense + }{ + // Comparison with Matlab. + { + a: NewSymDense(2, []float64{10, 5, 5, 12}), + pow: 0.5, + ans: NewSymDense(2, []float64{3.065533767740645, 0.776210486171016, 0.776210486171016, 3.376017962209052}), + }, + { + a: NewSymDense(2, []float64{11, -1, -1, 8}), + pow: 0.5, + ans: NewSymDense(2, []float64{3.312618742210524, -0.162963396980939, -0.162963396980939, 2.823728551267709}), + }, + { + a: NewSymDense(2, []float64{10, 5, 5, 12}), + pow: -0.5, + ans: NewSymDense(2, []float64{0.346372134547712, -0.079637515547296, -0.079637515547296, 0.314517128328794}), + }, + { + a: NewSymDense(3, []float64{15, -1, -3, -1, 8, 6, -3, 6, 14}), + pow: 0.6, + ans: NewSymDense(3, []float64{ + 5.051214323034288, -0.163162161893975, -0.612153996497505, + -0.163162161893976, 3.283474884617009, 1.432842761381493, + -0.612153996497505, 1.432842761381494, 4.695873060862573, + }), + }, + } { + var s SymDense + err := s.PowPSD(test.a, test.pow) + if err != nil { + panic("bad test") + } + if !EqualApprox(&s, test.ans, 1e-10) { + t.Errorf("Case %d, pow mismatch", cas) + fmt.Println(Formatted(&s)) + fmt.Println(Formatted(test.ans)) + } + } + + // Compare with Dense.Pow + rnd := rand.New(rand.NewSource(1)) + for dim := 2; dim < 10; dim++ { + for pow := 2; pow < 6; pow++ { + a := NewDense(dim, dim, nil) + for i := 0; i < dim; i++ { + for j := 0; j < dim; j++ { + a.Set(i, j, rnd.Float64()) + } + } + var mat SymDense + mat.SymOuterK(1, a) + + var sym SymDense + sym.PowPSD(&mat, float64(pow)) + + var dense Dense + dense.Pow(&mat, pow) + + if !EqualApprox(&sym, &dense, 1e-10) { + t.Errorf("Dim %d: pow mismatch", dim) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/triangular.go b/vendor/gonum.org/v1/gonum/mat/triangular.go new file mode 100644 index 00000000..19b15bba --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/triangular.go @@ -0,0 +1,540 @@ +// 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 mat + +import ( + "math" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/lapack/lapack64" +) + +var ( + triDense *TriDense + _ Matrix = triDense + _ Triangular = triDense + _ RawTriangular = triDense + _ MutableTriangular = triDense + + _ NonZeroDoer = triDense + _ RowNonZeroDoer = triDense + _ ColNonZeroDoer = triDense +) + +const badTriCap = "mat: bad capacity for TriDense" + +// TriDense represents an upper or lower triangular matrix in dense storage +// format. +type TriDense struct { + mat blas64.Triangular + cap int +} + +// Triangular represents a triangular matrix. Triangular matrices are always square. +type Triangular interface { + Matrix + // Triangular returns the number of rows/columns in the matrix and its + // orientation. + Triangle() (n int, kind TriKind) + + // TTri is the equivalent of the T() method in the Matrix interface but + // guarantees the transpose is of triangular type. + TTri() Triangular +} + +// A RawTriangular can return a view of itself as a BLAS Triangular matrix. +type RawTriangular interface { + RawTriangular() blas64.Triangular +} + +// A MutableTriangular can set elements of a triangular matrix. +type MutableTriangular interface { + Triangular + SetTri(i, j int, v float64) +} + +var ( + _ Matrix = TransposeTri{} + _ Triangular = TransposeTri{} + _ UntransposeTrier = TransposeTri{} +) + +// TransposeTri is a type for performing an implicit transpose of a Triangular +// matrix. It implements the Triangular interface, returning values from the +// transpose of the matrix within. +type TransposeTri struct { + Triangular Triangular +} + +// At returns the value of the element at row i and column j of the transposed +// matrix, that is, row j and column i of the Triangular field. +func (t TransposeTri) At(i, j int) float64 { + return t.Triangular.At(j, i) +} + +// Dims returns the dimensions of the transposed matrix. Triangular matrices are +// square and thus this is the same size as the original Triangular. +func (t TransposeTri) Dims() (r, c int) { + c, r = t.Triangular.Dims() + return r, c +} + +// T performs an implicit transpose by returning the Triangular field. +func (t TransposeTri) T() Matrix { + return t.Triangular +} + +// Triangle returns the number of rows/columns in the matrix and its orientation. +func (t TransposeTri) Triangle() (int, TriKind) { + n, upper := t.Triangular.Triangle() + return n, !upper +} + +// TTri performs an implicit transpose by returning the Triangular field. +func (t TransposeTri) TTri() Triangular { + return t.Triangular +} + +// Untranspose returns the Triangular field. +func (t TransposeTri) Untranspose() Matrix { + return t.Triangular +} + +func (t TransposeTri) UntransposeTri() Triangular { + return t.Triangular +} + +// NewTriDense creates a new Triangular matrix with n rows and columns. If data == nil, +// a new slice is allocated for the backing slice. If len(data) == n*n, data is +// used as the backing slice, and changes to the elements of the returned TriDense +// will be reflected in data. If neither of these is true, NewTriDense will panic. +// +// The data must be arranged in row-major order, i.e. the (i*c + j)-th +// element in the data slice is the {i, j}-th element in the matrix. +// Only the values in the triangular portion corresponding to kind are used. +func NewTriDense(n int, kind TriKind, data []float64) *TriDense { + if n < 0 { + panic("mat: negative dimension") + } + if data != nil && len(data) != n*n { + panic(ErrShape) + } + if data == nil { + data = make([]float64, n*n) + } + uplo := blas.Lower + if kind == Upper { + uplo = blas.Upper + } + return &TriDense{ + mat: blas64.Triangular{ + N: n, + Stride: n, + Data: data, + Uplo: uplo, + Diag: blas.NonUnit, + }, + cap: n, + } +} + +func (t *TriDense) Dims() (r, c int) { + return t.mat.N, t.mat.N +} + +// Triangle returns the dimension of t and its orientation. The returned +// orientation is only valid when n is not zero. +func (t *TriDense) Triangle() (n int, kind TriKind) { + return t.mat.N, TriKind(!t.IsZero()) && t.triKind() +} + +func (t *TriDense) isUpper() bool { + return isUpperUplo(t.mat.Uplo) +} + +func (t *TriDense) triKind() TriKind { + return TriKind(isUpperUplo(t.mat.Uplo)) +} + +func isUpperUplo(u blas.Uplo) bool { + switch u { + case blas.Upper: + return true + case blas.Lower: + return false + default: + panic(badTriangle) + } +} + +// asSymBlas returns the receiver restructured as a blas64.Symmetric with the +// same backing memory. Panics if the receiver is unit. +// This returns a blas64.Symmetric and not a *SymDense because SymDense can only +// be upper triangular. +func (t *TriDense) asSymBlas() blas64.Symmetric { + if t.mat.Diag == blas.Unit { + panic("mat: cannot convert unit TriDense into blas64.Symmetric") + } + return blas64.Symmetric{ + N: t.mat.N, + Stride: t.mat.Stride, + Data: t.mat.Data, + Uplo: t.mat.Uplo, + } +} + +// T performs an implicit transpose by returning the receiver inside a Transpose. +func (t *TriDense) T() Matrix { + return Transpose{t} +} + +// TTri performs an implicit transpose by returning the receiver inside a TransposeTri. +func (t *TriDense) TTri() Triangular { + return TransposeTri{t} +} + +func (t *TriDense) RawTriangular() blas64.Triangular { + return t.mat +} + +// Reset zeros the dimensions of the matrix so that it can be reused as the +// receiver of a dimensionally restricted operation. +// +// See the Reseter interface for more information. +func (t *TriDense) Reset() { + // N and Stride must be zeroed in unison. + t.mat.N, t.mat.Stride = 0, 0 + // Defensively zero Uplo to ensure + // it is set correctly later. + t.mat.Uplo = 0 + t.mat.Data = t.mat.Data[:0] +} + +// IsZero returns whether the receiver is zero-sized. Zero-sized matrices can be the +// receiver for size-restricted operations. TriDense matrices can be zeroed using Reset. +func (t *TriDense) IsZero() bool { + // It must be the case that t.Dims() returns + // zeros in this case. See comment in Reset(). + return t.mat.Stride == 0 +} + +// untranspose untransposes a matrix if applicable. If a is an Untransposer, then +// untranspose returns the underlying matrix and true. If it is not, then it returns +// the input matrix and false. +func untransposeTri(a Triangular) (Triangular, bool) { + if ut, ok := a.(UntransposeTrier); ok { + return ut.UntransposeTri(), true + } + return a, false +} + +// reuseAs resizes a zero receiver to an n×n triangular matrix with the given +// orientation. If the receiver is non-zero, reuseAs checks that the receiver +// is the correct size and orientation. +func (t *TriDense) reuseAs(n int, kind TriKind) { + ul := blas.Lower + if kind == Upper { + ul = blas.Upper + } + if t.mat.N > t.cap { + panic(badTriCap) + } + if t.IsZero() { + t.mat = blas64.Triangular{ + N: n, + Stride: n, + Diag: blas.NonUnit, + Data: use(t.mat.Data, n*n), + Uplo: ul, + } + t.cap = n + return + } + if t.mat.N != n { + panic(ErrShape) + } + if t.mat.Uplo != ul { + panic(ErrTriangle) + } +} + +// isolatedWorkspace returns a new TriDense matrix w with the size of a and +// returns a callback to defer which performs cleanup at the return of the call. +// This should be used when a method receiver is the same pointer as an input argument. +func (t *TriDense) isolatedWorkspace(a Triangular) (w *TriDense, restore func()) { + n, kind := a.Triangle() + if n == 0 { + panic("zero size") + } + w = getWorkspaceTri(n, kind, false) + return w, func() { + t.Copy(w) + putWorkspaceTri(w) + } +} + +// Copy makes a copy of elements of a into the receiver. It is similar to the +// built-in copy; it copies as much as the overlap between the two matrices and +// returns the number of rows and columns it copied. Only elements within the +// receiver's non-zero triangle are set. +// +// See the Copier interface for more information. +func (t *TriDense) Copy(a Matrix) (r, c int) { + r, c = a.Dims() + r = min(r, t.mat.N) + c = min(c, t.mat.N) + if r == 0 || c == 0 { + return 0, 0 + } + + switch a := a.(type) { + case RawMatrixer: + amat := a.RawMatrix() + if t.isUpper() { + for i := 0; i < r; i++ { + copy(t.mat.Data[i*t.mat.Stride+i:i*t.mat.Stride+c], amat.Data[i*amat.Stride+i:i*amat.Stride+c]) + } + } else { + for i := 0; i < r; i++ { + copy(t.mat.Data[i*t.mat.Stride:i*t.mat.Stride+i+1], amat.Data[i*amat.Stride:i*amat.Stride+i+1]) + } + } + case RawTriangular: + amat := a.RawTriangular() + aIsUpper := isUpperUplo(amat.Uplo) + tIsUpper := t.isUpper() + switch { + case tIsUpper && aIsUpper: + for i := 0; i < r; i++ { + copy(t.mat.Data[i*t.mat.Stride+i:i*t.mat.Stride+c], amat.Data[i*amat.Stride+i:i*amat.Stride+c]) + } + case !tIsUpper && !aIsUpper: + for i := 0; i < r; i++ { + copy(t.mat.Data[i*t.mat.Stride:i*t.mat.Stride+i+1], amat.Data[i*amat.Stride:i*amat.Stride+i+1]) + } + default: + for i := 0; i < r; i++ { + t.set(i, i, amat.Data[i*amat.Stride+i]) + } + } + default: + isUpper := t.isUpper() + for i := 0; i < r; i++ { + if isUpper { + for j := i; j < c; j++ { + t.set(i, j, a.At(i, j)) + } + } else { + for j := 0; j <= i; j++ { + t.set(i, j, a.At(i, j)) + } + } + } + } + + return r, c +} + +// InverseTri computes the inverse of the triangular matrix a, storing the result +// into the receiver. If a is ill-conditioned, a Condition error will be returned. +// Note that matrix inversion is numerically unstable, and should generally be +// avoided where possible, for example by using the Solve routines. +func (t *TriDense) InverseTri(a Triangular) error { + if rt, ok := a.(RawTriangular); ok { + t.checkOverlap(rt.RawTriangular()) + } + n, _ := a.Triangle() + t.reuseAs(a.Triangle()) + t.Copy(a) + work := getFloats(3*n, false) + iwork := getInts(n, false) + cond := lapack64.Trcon(CondNorm, t.mat, work, iwork) + putFloats(work) + putInts(iwork) + if math.IsInf(cond, 1) { + return Condition(cond) + } + ok := lapack64.Trtri(t.mat) + if !ok { + return Condition(math.Inf(1)) + } + if cond > ConditionTolerance { + return Condition(cond) + } + return nil +} + +// MulTri takes the product of triangular matrices a and b and places the result +// in the receiver. The size of a and b must match, and they both must have the +// same TriKind, or Mul will panic. +func (t *TriDense) MulTri(a, b Triangular) { + n, kind := a.Triangle() + nb, kindb := b.Triangle() + if n != nb { + panic(ErrShape) + } + if kind != kindb { + panic(ErrTriangle) + } + + aU, _ := untransposeTri(a) + bU, _ := untransposeTri(b) + t.reuseAs(n, kind) + var restore func() + if t == aU { + t, restore = t.isolatedWorkspace(aU) + defer restore() + } else if t == bU { + t, restore = t.isolatedWorkspace(bU) + defer restore() + } + + // TODO(btracey): Improve the set of fast-paths. + if kind == Upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + var v float64 + for k := i; k <= j; k++ { + v += a.At(i, k) * b.At(k, j) + } + t.SetTri(i, j, v) + } + } + return + } + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + var v float64 + for k := j; k <= i; k++ { + v += a.At(i, k) * b.At(k, j) + } + t.SetTri(i, j, v) + } + } +} + +// copySymIntoTriangle copies a symmetric matrix into a TriDense +func copySymIntoTriangle(t *TriDense, s Symmetric) { + n, upper := t.Triangle() + ns := s.Symmetric() + if n != ns { + panic("mat: triangle size mismatch") + } + ts := t.mat.Stride + if rs, ok := s.(RawSymmetricer); ok { + sd := rs.RawSymmetric() + ss := sd.Stride + if upper { + if sd.Uplo == blas.Upper { + for i := 0; i < n; i++ { + copy(t.mat.Data[i*ts+i:i*ts+n], sd.Data[i*ss+i:i*ss+n]) + } + return + } + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + t.mat.Data[i*ts+j] = sd.Data[j*ss+i] + } + } + return + } + if sd.Uplo == blas.Upper { + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + t.mat.Data[i*ts+j] = sd.Data[j*ss+i] + } + } + return + } + for i := 0; i < n; i++ { + copy(t.mat.Data[i*ts:i*ts+i+1], sd.Data[i*ss:i*ss+i+1]) + } + return + } + if upper { + for i := 0; i < n; i++ { + for j := i; j < n; j++ { + t.mat.Data[i*ts+j] = s.At(i, j) + } + } + return + } + for i := 0; i < n; i++ { + for j := 0; j <= i; j++ { + t.mat.Data[i*ts+j] = s.At(i, j) + } + } +} + +// DoNonZero calls the function fn for each of the non-zero elements of t. The function fn +// takes a row/column index and the element value of t at (i, j). +func (t *TriDense) DoNonZero(fn func(i, j int, v float64)) { + if t.isUpper() { + for i := 0; i < t.mat.N; i++ { + for j := i; j < t.mat.N; j++ { + v := t.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + } + return + } + for i := 0; i < t.mat.N; i++ { + for j := 0; j <= i; j++ { + v := t.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + } +} + +// DoRowNonZero calls the function fn for each of the non-zero elements of row i of t. The function fn +// takes a row/column index and the element value of t at (i, j). +func (t *TriDense) DoRowNonZero(i int, fn func(i, j int, v float64)) { + if i < 0 || t.mat.N <= i { + panic(ErrRowAccess) + } + if t.isUpper() { + for j := i; j < t.mat.N; j++ { + v := t.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + return + } + for j := 0; j <= i; j++ { + v := t.at(i, j) + if v != 0 { + fn(i, j, v) + } + } +} + +// DoColNonZero calls the function fn for each of the non-zero elements of column j of t. The function fn +// takes a row/column index and the element value of t at (i, j). +func (t *TriDense) DoColNonZero(j int, fn func(i, j int, v float64)) { + if j < 0 || t.mat.N <= j { + panic(ErrColAccess) + } + if t.isUpper() { + for i := 0; i <= j; i++ { + v := t.at(i, j) + if v != 0 { + fn(i, j, v) + } + } + return + } + for i := j; i < t.mat.N; i++ { + v := t.at(i, j) + if v != 0 { + fn(i, j, v) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/triangular_test.go b/vendor/gonum.org/v1/gonum/mat/triangular_test.go new file mode 100644 index 00000000..883322d7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/triangular_test.go @@ -0,0 +1,438 @@ +// 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 mat + +import ( + "math" + "math/rand" + "reflect" + "testing" + + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" +) + +func TestNewTriangular(t *testing.T) { + for i, test := range []struct { + data []float64 + n int + kind TriKind + mat *TriDense + }{ + { + data: []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }, + n: 3, + kind: Upper, + mat: &TriDense{ + mat: blas64.Triangular{ + N: 3, + Stride: 3, + Uplo: blas.Upper, + Data: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}, + Diag: blas.NonUnit, + }, + cap: 3, + }, + }, + } { + tri := NewTriDense(test.n, test.kind, test.data) + rows, cols := tri.Dims() + + if rows != test.n { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n) + } + if cols != test.n { + t.Errorf("unexpected number of cols for test %d: got: %d want: %d", i, cols, test.n) + } + if !reflect.DeepEqual(tri, test.mat) { + t.Errorf("unexpected data slice for test %d: got: %v want: %v", i, tri, test.mat) + } + } + + for _, kind := range []TriKind{Lower, Upper} { + panicked, message := panics(func() { NewTriDense(3, kind, []float64{1, 2}) }) + if !panicked || message != ErrShape.Error() { + t.Errorf("expected panic for invalid data slice length for upper=%t", kind) + } + } +} + +func TestTriAtSet(t *testing.T) { + tri := &TriDense{ + mat: blas64.Triangular{ + N: 3, + Stride: 3, + Uplo: blas.Upper, + Data: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}, + Diag: blas.NonUnit, + }, + cap: 3, + } + + rows, cols := tri.Dims() + + // Check At out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { tri.At(row, 0) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { tri.At(0, col) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + // Check Set out of bounds + for _, row := range []int{-1, rows, rows + 1} { + panicked, message := panics(func() { tri.SetTri(row, 0, 1.2) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access N=%d r=%d", rows, row) + } + } + for _, col := range []int{-1, cols, cols + 1} { + panicked, message := panics(func() { tri.SetTri(0, col, 1.2) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access N=%d c=%d", cols, col) + } + } + + for _, st := range []struct { + row, col int + uplo blas.Uplo + }{ + {row: 2, col: 1, uplo: blas.Upper}, + {row: 1, col: 2, uplo: blas.Lower}, + } { + tri.mat.Uplo = st.uplo + panicked, message := panics(func() { tri.SetTri(st.row, st.col, 1.2) }) + if !panicked || message != ErrTriangleSet.Error() { + t.Errorf("expected panic for %+v", st) + } + } + + for _, st := range []struct { + row, col int + uplo blas.Uplo + orig, new float64 + }{ + {row: 2, col: 1, uplo: blas.Lower, orig: 8, new: 15}, + {row: 1, col: 2, uplo: blas.Upper, orig: 6, new: 15}, + } { + tri.mat.Uplo = st.uplo + if e := tri.At(st.row, st.col); e != st.orig { + t.Errorf("unexpected value for At(%d, %d): got: %v want: %v", st.row, st.col, e, st.orig) + } + tri.SetTri(st.row, st.col, st.new) + if e := tri.At(st.row, st.col); e != st.new { + t.Errorf("unexpected value for At(%d, %d) after SetTri(%[1]d, %d, %v): got: %v want: %[3]v", st.row, st.col, st.new, e) + } + } +} + +func TestTriDenseCopy(t *testing.T) { + for i := 0; i < 100; i++ { + size := rand.Intn(100) + r, err := randDense(size, 0.9, rand.NormFloat64) + if size == 0 { + if err != ErrZeroLength { + t.Fatalf("expected error %v: got: %v", ErrZeroLength, err) + } + continue + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + u := NewTriDense(size, true, nil) + l := NewTriDense(size, false, nil) + + for _, typ := range []Matrix{r, (*basicMatrix)(r)} { + for j := range u.mat.Data { + u.mat.Data[j] = math.NaN() + l.mat.Data[j] = math.NaN() + } + u.Copy(typ) + l.Copy(typ) + for m := 0; m < size; m++ { + for n := 0; n < size; n++ { + want := typ.At(m, n) + switch { + case m < n: // Upper triangular matrix. + if got := u.At(m, n); got != want { + t.Errorf("unexpected upper value for At(%d, %d) for test %d: got: %v want: %v", m, n, i, got, want) + } + case m == n: // Diagonal matrix. + if got := u.At(m, n); got != want { + t.Errorf("unexpected upper value for At(%d, %d) for test %d: got: %v want: %v", m, n, i, got, want) + } + if got := l.At(m, n); got != want { + t.Errorf("unexpected diagonal value for At(%d, %d) for test %d: got: %v want: %v", m, n, i, got, want) + } + case m < n: // Lower triangular matrix. + if got := l.At(m, n); got != want { + t.Errorf("unexpected lower value for At(%d, %d) for test %d: got: %v want: %v", m, n, i, got, want) + } + } + } + } + } + } +} + +func TestTriTriDenseCopy(t *testing.T) { + for i := 0; i < 100; i++ { + size := rand.Intn(100) + r, err := randDense(size, 1, rand.NormFloat64) + if size == 0 { + if err != ErrZeroLength { + t.Fatalf("expected error %v: got: %v", ErrZeroLength, err) + } + continue + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + ur := NewTriDense(size, true, nil) + lr := NewTriDense(size, false, nil) + + ur.Copy(r) + lr.Copy(r) + + u := NewTriDense(size, true, nil) + u.Copy(ur) + if !equal(u, ur) { + t.Fatal("unexpected result for U triangle copy of U triangle: not equal") + } + + l := NewTriDense(size, false, nil) + l.Copy(lr) + if !equal(l, lr) { + t.Fatal("unexpected result for L triangle copy of L triangle: not equal") + } + + zero(u.mat.Data) + u.Copy(lr) + if !isDiagonal(u) { + t.Fatal("unexpected result for U triangle copy of L triangle: off diagonal non-zero element") + } + if !equalDiagonal(u, lr) { + t.Fatal("unexpected result for U triangle copy of L triangle: diagonal not equal") + } + + zero(l.mat.Data) + l.Copy(ur) + if !isDiagonal(l) { + t.Fatal("unexpected result for L triangle copy of U triangle: off diagonal non-zero element") + } + if !equalDiagonal(l, ur) { + t.Fatal("unexpected result for L triangle copy of U triangle: diagonal not equal") + } + } +} + +func TestTriInverse(t *testing.T) { + for _, kind := range []TriKind{Upper, Lower} { + for _, n := range []int{1, 3, 5, 9} { + data := make([]float64, n*n) + for i := range data { + data[i] = rand.NormFloat64() + } + a := NewTriDense(n, kind, data) + var tr TriDense + err := tr.InverseTri(a) + if err != nil { + t.Errorf("Bad test: %s", err) + } + var d Dense + d.Mul(a, &tr) + if !equalApprox(eye(n), &d, 1e-8, false) { + var diff Dense + diff.Sub(eye(n), &d) + t.Errorf("Tri times inverse is not identity. Norm of difference: %v", Norm(&diff, 2)) + } + } + } +} + +func TestTriMul(t *testing.T) { + method := func(receiver, a, b Matrix) { + type MulTrier interface { + MulTri(a, b Triangular) + } + receiver.(MulTrier).MulTri(a.(Triangular), b.(Triangular)) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Mul(a, b) + } + legalSizeTriMul := func(ar, ac, br, bc int) bool { + // Need both to be square and the sizes to be the same + return ar == ac && br == bc && ar == br + } + + // The legal types are triangles with the same TriKind. + // legalTypesTri returns whether both input arguments are Triangular. + legalTypes := func(a, b Matrix) bool { + at, ok := a.(Triangular) + if !ok { + return false + } + bt, ok := b.(Triangular) + if !ok { + return false + } + _, ak := at.Triangle() + _, bk := bt.Triangle() + return ak == bk + } + legalTypesLower := func(a, b Matrix) bool { + legal := legalTypes(a, b) + if !legal { + return false + } + _, kind := a.(Triangular).Triangle() + r := kind == Lower + return r + } + receiver := NewTriDense(3, Lower, nil) + testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesLower, legalSizeTriMul, 1e-14) + + legalTypesUpper := func(a, b Matrix) bool { + legal := legalTypes(a, b) + if !legal { + return false + } + _, kind := a.(Triangular).Triangle() + r := kind == Upper + return r + } + receiver = NewTriDense(3, Upper, nil) + testTwoInput(t, "TriMul", receiver, method, denseComparison, legalTypesUpper, legalSizeTriMul, 1e-14) +} + +func TestCopySymIntoTriangle(t *testing.T) { + nan := math.NaN() + for tc, test := range []struct { + n int + sUplo blas.Uplo + s []float64 + + tUplo TriKind + want []float64 + }{ + { + n: 3, + sUplo: blas.Upper, + s: []float64{ + 1, 2, 3, + nan, 4, 5, + nan, nan, 6, + }, + tUplo: Upper, + want: []float64{ + 1, 2, 3, + 0, 4, 5, + 0, 0, 6, + }, + }, + { + n: 3, + sUplo: blas.Lower, + s: []float64{ + 1, nan, nan, + 2, 3, nan, + 4, 5, 6, + }, + tUplo: Upper, + want: []float64{ + 1, 2, 4, + 0, 3, 5, + 0, 0, 6, + }, + }, + { + n: 3, + sUplo: blas.Upper, + s: []float64{ + 1, 2, 3, + nan, 4, 5, + nan, nan, 6, + }, + tUplo: Lower, + want: []float64{ + 1, 0, 0, + 2, 4, 0, + 3, 5, 6, + }, + }, + { + n: 3, + sUplo: blas.Lower, + s: []float64{ + 1, nan, nan, + 2, 3, nan, + 4, 5, 6, + }, + tUplo: Lower, + want: []float64{ + 1, 0, 0, + 2, 3, 0, + 4, 5, 6, + }, + }, + } { + n := test.n + s := NewSymDense(n, test.s) + // For the purpose of the test, break the assumption that + // symmetric is stored in the upper triangle (only when S is + // RawSymmetricer). + s.mat.Uplo = test.sUplo + + t1 := NewTriDense(n, test.tUplo, nil) + copySymIntoTriangle(t1, s) + + equal := true + loop1: + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if t1.At(i, j) != test.want[i*n+j] { + equal = false + break loop1 + } + } + } + if !equal { + t.Errorf("Case %v: unexpected T when S is RawSymmetricer", tc) + } + + if test.sUplo == blas.Lower { + continue + } + + sb := (basicSymmetric)(*s) + t2 := NewTriDense(n, test.tUplo, nil) + copySymIntoTriangle(t2, &sb) + equal = true + loop2: + for i := 0; i < n; i++ { + for j := 0; j < n; j++ { + if t1.At(i, j) != test.want[i*n+j] { + equal = false + break loop2 + } + } + } + if !equal { + t.Errorf("Case %v: unexpected T when S is not RawSymmetricer", tc) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/vector.go b/vendor/gonum.org/v1/gonum/mat/vector.go new file mode 100644 index 00000000..110581ad --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/vector.go @@ -0,0 +1,484 @@ +// 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. + +package mat + +import ( + "gonum.org/v1/gonum/blas" + "gonum.org/v1/gonum/blas/blas64" + "gonum.org/v1/gonum/internal/asm/f64" +) + +var ( + vector *VecDense + + _ Matrix = vector + _ Vector = vector + _ Reseter = vector +) + +// Vector is a column vector. +type Vector interface { + Matrix + Len() int +} + +// VecDense represents a column vector. +type VecDense struct { + mat blas64.Vector + n int + // A BLAS vector can have a negative increment, but allowing this + // in the mat type complicates a lot of code, and doesn't gain anything. + // VecDense must have positive increment in this package. +} + +// NewVecDense creates a new VecDense of length n. If data == nil, +// a new slice is allocated for the backing slice. If len(data) == n, data is +// used as the backing slice, and changes to the elements of the returned VecDense +// will be reflected in data. If neither of these is true, NewVecDense will panic. +func NewVecDense(n int, data []float64) *VecDense { + if len(data) != n && data != nil { + panic(ErrShape) + } + if data == nil { + data = make([]float64, n) + } + return &VecDense{ + mat: blas64.Vector{ + Inc: 1, + Data: data, + }, + n: n, + } +} + +// SliceVec returns a new VecDense that shares backing data with the receiver. +// The returned matrix starts at i of the receiver and extends k-i elements. +// SliceVec panics with ErrIndexOutOfRange if the slice is outside the capacity +// of the receiver. +func (v *VecDense) SliceVec(i, k int) *VecDense { + if i < 0 || k <= i || v.Cap() < k { + panic(ErrIndexOutOfRange) + } + return &VecDense{ + n: k - i, + mat: blas64.Vector{ + Inc: v.mat.Inc, + Data: v.mat.Data[i*v.mat.Inc : (k-1)*v.mat.Inc+1], + }, + } +} + +// Dims returns the number of rows and columns in the matrix. Columns is always 1 +// for a non-Reset vector. +func (v *VecDense) Dims() (r, c int) { + if v.IsZero() { + return 0, 0 + } + return v.n, 1 +} + +// Caps returns the number of rows and columns in the backing matrix. Columns is always 1 +// for a non-Reset vector. +func (v *VecDense) Caps() (r, c int) { + if v.IsZero() { + return 0, 0 + } + return v.Cap(), 1 +} + +// Len returns the length of the vector. +func (v *VecDense) Len() int { + return v.n +} + +// Cap returns the capacity of the vector. +func (v *VecDense) Cap() int { + if v.IsZero() { + return 0 + } + return (cap(v.mat.Data)-1)/v.mat.Inc + 1 +} + +// T performs an implicit transpose by returning the receiver inside a Transpose. +func (v *VecDense) T() Matrix { + return Transpose{v} +} + +// Reset zeros the length of the vector so that it can be reused as the +// receiver of a dimensionally restricted operation. +// +// See the Reseter interface for more information. +func (v *VecDense) Reset() { + // No change of Inc or n to 0 may be + // made unless both are set to 0. + v.mat.Inc = 0 + v.n = 0 + v.mat.Data = v.mat.Data[:0] +} + +// CloneVec makes a copy of a into the receiver, overwriting the previous value +// of the receiver. +func (v *VecDense) CloneVec(a *VecDense) { + if v == a { + return + } + v.n = a.n + v.mat = blas64.Vector{ + Inc: 1, + Data: use(v.mat.Data, v.n), + } + blas64.Copy(v.n, a.mat, v.mat) +} + +func (v *VecDense) RawVector() blas64.Vector { + return v.mat +} + +// CopyVec makes a copy of elements of a into the receiver. It is similar to the +// built-in copy; it copies as much as the overlap between the two vectors and +// returns the number of elements it copied. +func (v *VecDense) CopyVec(a *VecDense) int { + n := min(v.Len(), a.Len()) + if v != a { + blas64.Copy(n, a.mat, v.mat) + } + return n +} + +// ScaleVec scales the vector a by alpha, placing the result in the receiver. +func (v *VecDense) ScaleVec(alpha float64, a *VecDense) { + n := a.Len() + if v != a { + v.reuseAs(n) + if v.mat.Inc == 1 && a.mat.Inc == 1 { + f64.ScalUnitaryTo(v.mat.Data, alpha, a.mat.Data) + return + } + f64.ScalIncTo(v.mat.Data, uintptr(v.mat.Inc), + alpha, a.mat.Data, uintptr(n), uintptr(a.mat.Inc)) + return + } + if v.mat.Inc == 1 { + f64.ScalUnitary(alpha, v.mat.Data) + return + } + f64.ScalInc(alpha, v.mat.Data, uintptr(n), uintptr(v.mat.Inc)) +} + +// AddScaledVec adds the vectors a and alpha*b, placing the result in the receiver. +func (v *VecDense) AddScaledVec(a *VecDense, alpha float64, b *VecDense) { + if alpha == 1 { + v.AddVec(a, b) + return + } + if alpha == -1 { + v.SubVec(a, b) + return + } + + ar := a.Len() + br := b.Len() + + if ar != br { + panic(ErrShape) + } + + if v != a { + v.checkOverlap(a.mat) + } + if v != b { + v.checkOverlap(b.mat) + } + + v.reuseAs(ar) + + switch { + case alpha == 0: // v <- a + v.CopyVec(a) + case v == a && v == b: // v <- v + alpha * v = (alpha + 1) * v + blas64.Scal(ar, alpha+1, v.mat) + case v == a && v != b: // v <- v + alpha * b + if v.mat.Inc == 1 && b.mat.Inc == 1 { + // Fast path for a common case. + f64.AxpyUnitaryTo(v.mat.Data, alpha, b.mat.Data, a.mat.Data) + } else { + f64.AxpyInc(alpha, b.mat.Data, v.mat.Data, + uintptr(ar), uintptr(b.mat.Inc), uintptr(v.mat.Inc), 0, 0) + } + default: // v <- a + alpha * b or v <- a + alpha * v + if v.mat.Inc == 1 && a.mat.Inc == 1 && b.mat.Inc == 1 { + // Fast path for a common case. + f64.AxpyUnitaryTo(v.mat.Data, alpha, b.mat.Data, a.mat.Data) + } else { + f64.AxpyIncTo(v.mat.Data, uintptr(v.mat.Inc), 0, + alpha, b.mat.Data, a.mat.Data, + uintptr(ar), uintptr(b.mat.Inc), uintptr(a.mat.Inc), 0, 0) + } + } +} + +// AddVec adds the vectors a and b, placing the result in the receiver. +func (v *VecDense) AddVec(a, b *VecDense) { + ar := a.Len() + br := b.Len() + + if ar != br { + panic(ErrShape) + } + + if v != a { + v.checkOverlap(a.mat) + } + if v != b { + v.checkOverlap(b.mat) + } + + v.reuseAs(ar) + + if v.mat.Inc == 1 && a.mat.Inc == 1 && b.mat.Inc == 1 { + // Fast path for a common case. + f64.AxpyUnitaryTo(v.mat.Data, 1, b.mat.Data, a.mat.Data) + return + } + f64.AxpyIncTo(v.mat.Data, uintptr(v.mat.Inc), 0, + 1, b.mat.Data, a.mat.Data, + uintptr(ar), uintptr(b.mat.Inc), uintptr(a.mat.Inc), 0, 0) +} + +// SubVec subtracts the vector b from a, placing the result in the receiver. +func (v *VecDense) SubVec(a, b *VecDense) { + ar := a.Len() + br := b.Len() + + if ar != br { + panic(ErrShape) + } + + if v != a { + v.checkOverlap(a.mat) + } + if v != b { + v.checkOverlap(b.mat) + } + + v.reuseAs(ar) + + if v.mat.Inc == 1 && a.mat.Inc == 1 && b.mat.Inc == 1 { + // Fast path for a common case. + f64.AxpyUnitaryTo(v.mat.Data, -1, b.mat.Data, a.mat.Data) + return + } + f64.AxpyIncTo(v.mat.Data, uintptr(v.mat.Inc), 0, + -1, b.mat.Data, a.mat.Data, + uintptr(ar), uintptr(b.mat.Inc), uintptr(a.mat.Inc), 0, 0) +} + +// MulElemVec performs element-wise multiplication of a and b, placing the result +// in the receiver. +func (v *VecDense) MulElemVec(a, b *VecDense) { + ar := a.Len() + br := b.Len() + + if ar != br { + panic(ErrShape) + } + + if v != a { + v.checkOverlap(a.mat) + } + if v != b { + v.checkOverlap(b.mat) + } + + v.reuseAs(ar) + + amat, bmat := a.RawVector(), b.RawVector() + for i := 0; i < v.n; i++ { + v.mat.Data[i*v.mat.Inc] = amat.Data[i*amat.Inc] * bmat.Data[i*bmat.Inc] + } +} + +// DivElemVec performs element-wise division of a by b, placing the result +// in the receiver. +func (v *VecDense) DivElemVec(a, b *VecDense) { + ar := a.Len() + br := b.Len() + + if ar != br { + panic(ErrShape) + } + + if v != a { + v.checkOverlap(a.mat) + } + if v != b { + v.checkOverlap(b.mat) + } + + v.reuseAs(ar) + + amat, bmat := a.RawVector(), b.RawVector() + for i := 0; i < v.n; i++ { + v.mat.Data[i*v.mat.Inc] = amat.Data[i*amat.Inc] / bmat.Data[i*bmat.Inc] + } +} + +// MulVec computes a * b. The result is stored into the receiver. +// MulVec panics if the number of columns in a does not equal the number of rows in b. +func (v *VecDense) MulVec(a Matrix, b *VecDense) { + r, c := a.Dims() + br := b.Len() + if c != br { + panic(ErrShape) + } + + if v != b { + v.checkOverlap(b.mat) + } + + a, trans := untranspose(a) + ar, ac := a.Dims() + v.reuseAs(r) + var restore func() + if v == a { + v, restore = v.isolatedWorkspace(a.(*VecDense)) + defer restore() + } else if v == b { + v, restore = v.isolatedWorkspace(b) + defer restore() + } + + switch a := a.(type) { + case *VecDense: + if v != a { + v.checkOverlap(a.mat) + } + + if a.Len() == 1 { + // {1,1} x {1,n} + av := a.At(0, 0) + for i := 0; i < b.Len(); i++ { + v.mat.Data[i*v.mat.Inc] = av * b.mat.Data[i*b.mat.Inc] + } + return + } + if b.Len() == 1 { + // {1,n} x {1,1} + bv := b.At(0, 0) + for i := 0; i < a.Len(); i++ { + v.mat.Data[i*v.mat.Inc] = bv * a.mat.Data[i*a.mat.Inc] + } + return + } + // {n,1} x {1,n} + var sum float64 + for i := 0; i < c; i++ { + sum += a.At(i, 0) * b.At(i, 0) + } + v.SetVec(0, sum) + return + case RawSymmetricer: + amat := a.RawSymmetric() + blas64.Symv(1, amat, b.mat, 0, v.mat) + case RawTriangular: + v.CopyVec(b) + amat := a.RawTriangular() + ta := blas.NoTrans + if trans { + ta = blas.Trans + } + blas64.Trmv(ta, amat, v.mat) + case RawMatrixer: + amat := a.RawMatrix() + // We don't know that a is a *Dense, so make + // a temporary Dense to check overlap. + (&Dense{mat: amat}).checkOverlap(v.asGeneral()) + t := blas.NoTrans + if trans { + t = blas.Trans + } + blas64.Gemv(t, 1, amat, b.mat, 0, v.mat) + default: + if trans { + col := make([]float64, ar) + for c := 0; c < ac; c++ { + for i := range col { + col[i] = a.At(i, c) + } + var f float64 + for i, e := range col { + f += e * b.mat.Data[i*b.mat.Inc] + } + v.mat.Data[c*v.mat.Inc] = f + } + } else { + row := make([]float64, ac) + for r := 0; r < ar; r++ { + for i := range row { + row[i] = a.At(r, i) + } + var f float64 + for i, e := range row { + f += e * b.mat.Data[i*b.mat.Inc] + } + v.mat.Data[r*v.mat.Inc] = f + } + } + } +} + +// reuseAs resizes an empty vector to a r×1 vector, +// or checks that a non-empty matrix is r×1. +func (v *VecDense) reuseAs(r int) { + if v.IsZero() { + v.mat = blas64.Vector{ + Inc: 1, + Data: use(v.mat.Data, r), + } + v.n = r + return + } + if r != v.n { + panic(ErrShape) + } +} + +// IsZero returns whether the receiver is zero-sized. Zero-sized vectors can be the +// receiver for size-restricted operations. VecDenses can be zeroed using Reset. +func (v *VecDense) IsZero() bool { + // It must be the case that v.Dims() returns + // zeros in this case. See comment in Reset(). + return v.mat.Inc == 0 +} + +func (v *VecDense) isolatedWorkspace(a *VecDense) (n *VecDense, restore func()) { + l := a.Len() + n = getWorkspaceVec(l, false) + return n, func() { + v.CopyVec(n) + putWorkspaceVec(n) + } +} + +// asDense returns a Dense representation of the receiver with the same +// underlying data. +func (v *VecDense) asDense() *Dense { + return &Dense{ + mat: v.asGeneral(), + capRows: v.n, + capCols: 1, + } +} + +// asGeneral returns a blas64.General representation of the receiver with the +// same underlying data. +func (v *VecDense) asGeneral() blas64.General { + return blas64.General{ + Rows: v.n, + Cols: 1, + Stride: v.mat.Inc, + Data: v.mat.Data, + } +} diff --git a/vendor/gonum.org/v1/gonum/mat/vector_test.go b/vendor/gonum.org/v1/gonum/mat/vector_test.go new file mode 100644 index 00000000..4f39f71f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mat/vector_test.go @@ -0,0 +1,530 @@ +// 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 mat + +import ( + "math/rand" + "reflect" + "testing" + + "gonum.org/v1/gonum/blas/blas64" +) + +func TestNewVecDense(t *testing.T) { + for i, test := range []struct { + n int + data []float64 + vector *VecDense + }{ + { + n: 3, + data: []float64{4, 5, 6}, + vector: &VecDense{ + mat: blas64.Vector{ + Data: []float64{4, 5, 6}, + Inc: 1, + }, + n: 3, + }, + }, + { + n: 3, + data: nil, + vector: &VecDense{ + mat: blas64.Vector{ + Data: []float64{0, 0, 0}, + Inc: 1, + }, + n: 3, + }, + }, + } { + v := NewVecDense(test.n, test.data) + rows, cols := v.Dims() + if rows != test.n { + t.Errorf("unexpected number of rows for test %d: got: %d want: %d", i, rows, test.n) + } + if cols != 1 { + t.Errorf("unexpected number of cols for test %d: got: %d want: 1", i, cols) + } + if !reflect.DeepEqual(v, test.vector) { + t.Errorf("unexpected data slice for test %d: got: %v want: %v", i, v, test.vector) + } + } +} + +func TestCap(t *testing.T) { + for i, test := range []struct { + vector *VecDense + want int + }{ + {vector: NewVecDense(3, nil), want: 3}, + { + vector: &VecDense{ + mat: blas64.Vector{ + Data: make([]float64, 7, 10), + Inc: 3, + }, + n: 3, + }, + want: 4, + }, + { + vector: &VecDense{ + mat: blas64.Vector{ + Data: make([]float64, 10), + Inc: 3, + }, + n: 4, + }, + want: 4, + }, + { + vector: &VecDense{ + mat: blas64.Vector{ + Data: make([]float64, 11), + Inc: 3, + }, + n: 4, + }, + want: 4, + }, + { + vector: &VecDense{ + mat: blas64.Vector{ + Data: make([]float64, 12), + Inc: 3, + }, + n: 4, + }, + want: 4, + }, + { + vector: &VecDense{ + mat: blas64.Vector{ + Data: make([]float64, 13), + Inc: 3, + }, + n: 4, + }, + want: 5, + }, + } { + got := test.vector.Cap() + if got != test.want { + t.Errorf("unexpected capacty for test %d: got: %d want: %d", i, got, test.want) + } + } +} + +func TestVecDenseAtSet(t *testing.T) { + for i, test := range []struct { + vector *VecDense + }{ + { + vector: &VecDense{ + mat: blas64.Vector{ + Data: []float64{0, 1, 2}, + Inc: 1, + }, + n: 3, + }, + }, + { + vector: &VecDense{ + mat: blas64.Vector{ + Data: []float64{0, 10, 10, 1, 10, 10, 2}, + Inc: 3, + }, + n: 3, + }, + }, + } { + v := test.vector + n := test.vector.n + + for _, row := range []int{-1, n} { + panicked, message := panics(func() { v.At(row, 0) }) + if !panicked || message != ErrRowAccess.Error() { + t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row) + } + } + for _, col := range []int{-1, 1} { + panicked, message := panics(func() { v.At(0, col) }) + if !panicked || message != ErrColAccess.Error() { + t.Errorf("expected panic for invalid column access for test %d n=%d c=%d", i, n, col) + } + } + + for _, row := range []int{0, 1, n - 1} { + if e := v.At(row, 0); e != float64(row) { + t.Errorf("unexpected value for At(%d, 0) for test %d : got: %v want: %v", row, i, e, float64(row)) + } + } + + for _, row := range []int{-1, n} { + panicked, message := panics(func() { v.SetVec(row, 100) }) + if !panicked || message != ErrVectorAccess.Error() { + t.Errorf("expected panic for invalid row access for test %d n=%d r=%d", i, n, row) + } + } + + for inc, row := range []int{0, 2} { + v.SetVec(row, 100+float64(inc)) + if e := v.At(row, 0); e != 100+float64(inc) { + t.Errorf("unexpected value for At(%d, 0) after SetVec(%[1]d, %v) for test %d: got: %v want: %[2]v", row, 100+float64(inc), i, e) + } + } + } +} + +func TestVecDenseMul(t *testing.T) { + method := func(receiver, a, b Matrix) { + type mulVecer interface { + MulVec(a Matrix, b *VecDense) + } + rd := receiver.(mulVecer) + rd.MulVec(a, b.(*VecDense)) + } + denseComparison := func(receiver, a, b *Dense) { + receiver.Mul(a, b) + } + legalSizeMulVec := func(ar, ac, br, bc int) bool { + var legal bool + if bc != 1 { + legal = false + } else { + legal = ac == br + } + return legal + } + testTwoInput(t, "MulVec", &VecDense{}, method, denseComparison, legalTypesNotVecVec, legalSizeMulVec, 1e-14) +} + +func TestVecDenseScale(t *testing.T) { + for i, test := range []struct { + a *VecDense + alpha float64 + want *VecDense + }{ + { + a: NewVecDense(3, []float64{0, 1, 2}), + alpha: 0, + want: NewVecDense(3, []float64{0, 0, 0}), + }, + { + a: NewVecDense(3, []float64{0, 1, 2}), + alpha: 1, + want: NewVecDense(3, []float64{0, 1, 2}), + }, + { + a: NewVecDense(3, []float64{0, 1, 2}), + alpha: -2, + want: NewVecDense(3, []float64{0, -2, -4}), + }, + { + a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0), + alpha: 0, + want: NewVecDense(3, []float64{0, 0, 0}), + }, + { + a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0), + alpha: 1, + want: NewVecDense(3, []float64{0, 1, 2}), + }, + { + a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0), + alpha: -2, + want: NewVecDense(3, []float64{0, -2, -4}), + }, + { + a: NewDense(3, 3, []float64{ + 0, 1, 2, + 3, 4, 5, + 6, 7, 8, + }).ColView(1), + alpha: -2, + want: NewVecDense(3, []float64{-2, -8, -14}), + }, + } { + var v VecDense + v.ScaleVec(test.alpha, test.a) + if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) { + t.Errorf("test %d: unexpected result for v = alpha * a: got: %v want: %v", i, v.RawVector(), test.want.RawVector()) + } + + v.CopyVec(test.a) + v.ScaleVec(test.alpha, &v) + if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) { + t.Errorf("test %d: unexpected result for v = alpha * v: got: %v want: %v", i, v.RawVector(), test.want.RawVector()) + } + } + + for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} { + method := func(receiver, a Matrix) { + type scaleVecer interface { + ScaleVec(float64, *VecDense) + } + v := receiver.(scaleVecer) + v.ScaleVec(alpha, a.(*VecDense)) + } + denseComparison := func(receiver, a *Dense) { + receiver.Scale(alpha, a) + } + testOneInput(t, "ScaleVec", &VecDense{}, method, denseComparison, legalTypeVec, isAnyVecDense, 0) + } +} + +func TestVecDenseAddScaled(t *testing.T) { + for _, alpha := range []float64{0, 1, -1, 2.3, -2.3} { + method := func(receiver, a, b Matrix) { + type addScaledVecer interface { + AddScaledVec(*VecDense, float64, *VecDense) + } + v := receiver.(addScaledVecer) + v.AddScaledVec(a.(*VecDense), alpha, b.(*VecDense)) + } + denseComparison := func(receiver, a, b *Dense) { + var sb Dense + sb.Scale(alpha, b) + receiver.Add(a, &sb) + } + testTwoInput(t, "AddScaledVec", &VecDense{}, method, denseComparison, legalTypesVecVec, legalSizeSameVec, 1e-14) + } +} + +func TestVecDenseAdd(t *testing.T) { + for i, test := range []struct { + a, b *VecDense + want *VecDense + }{ + { + a: NewVecDense(3, []float64{0, 1, 2}), + b: NewVecDense(3, []float64{0, 2, 3}), + want: NewVecDense(3, []float64{0, 3, 5}), + }, + { + a: NewVecDense(3, []float64{0, 1, 2}), + b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0), + want: NewVecDense(3, []float64{0, 3, 5}), + }, + { + a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0), + b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0), + want: NewVecDense(3, []float64{0, 3, 5}), + }, + } { + var v VecDense + v.AddVec(test.a, test.b) + if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) { + t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector()) + } + } +} + +func TestVecDenseSub(t *testing.T) { + for i, test := range []struct { + a, b *VecDense + want *VecDense + }{ + { + a: NewVecDense(3, []float64{0, 1, 2}), + b: NewVecDense(3, []float64{0, 0.5, 1}), + want: NewVecDense(3, []float64{0, 0.5, 1}), + }, + { + a: NewVecDense(3, []float64{0, 1, 2}), + b: NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0), + want: NewVecDense(3, []float64{0, 0.5, 1}), + }, + { + a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0), + b: NewDense(3, 1, []float64{0, 0.5, 1}).ColView(0), + want: NewVecDense(3, []float64{0, 0.5, 1}), + }, + } { + var v VecDense + v.SubVec(test.a, test.b) + if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) { + t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector()) + } + } +} + +func TestVecDenseMulElem(t *testing.T) { + for i, test := range []struct { + a, b *VecDense + want *VecDense + }{ + { + a: NewVecDense(3, []float64{0, 1, 2}), + b: NewVecDense(3, []float64{0, 2, 3}), + want: NewVecDense(3, []float64{0, 2, 6}), + }, + { + a: NewVecDense(3, []float64{0, 1, 2}), + b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0), + want: NewVecDense(3, []float64{0, 2, 6}), + }, + { + a: NewDense(3, 1, []float64{0, 1, 2}).ColView(0), + b: NewDense(3, 1, []float64{0, 2, 3}).ColView(0), + want: NewVecDense(3, []float64{0, 2, 6}), + }, + } { + var v VecDense + v.MulElemVec(test.a, test.b) + if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) { + t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector()) + } + } +} + +func TestVecDenseDivElem(t *testing.T) { + for i, test := range []struct { + a, b *VecDense + want *VecDense + }{ + { + a: NewVecDense(3, []float64{0.5, 1, 2}), + b: NewVecDense(3, []float64{0.5, 0.5, 1}), + want: NewVecDense(3, []float64{1, 2, 2}), + }, + { + a: NewVecDense(3, []float64{0.5, 1, 2}), + b: NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0), + want: NewVecDense(3, []float64{1, 2, 2}), + }, + { + a: NewDense(3, 1, []float64{0.5, 1, 2}).ColView(0), + b: NewDense(3, 1, []float64{0.5, 0.5, 1}).ColView(0), + want: NewVecDense(3, []float64{1, 2, 2}), + }, + } { + var v VecDense + v.DivElemVec(test.a, test.b) + if !reflect.DeepEqual(v.RawVector(), test.want.RawVector()) { + t.Errorf("unexpected result for test %d: got: %v want: %v", i, v.RawVector(), test.want.RawVector()) + } + } +} + +func BenchmarkAddScaledVec10Inc1(b *testing.B) { addScaledVecBench(b, 10, 1) } +func BenchmarkAddScaledVec100Inc1(b *testing.B) { addScaledVecBench(b, 100, 1) } +func BenchmarkAddScaledVec1000Inc1(b *testing.B) { addScaledVecBench(b, 1000, 1) } +func BenchmarkAddScaledVec10000Inc1(b *testing.B) { addScaledVecBench(b, 10000, 1) } +func BenchmarkAddScaledVec100000Inc1(b *testing.B) { addScaledVecBench(b, 100000, 1) } +func BenchmarkAddScaledVec10Inc2(b *testing.B) { addScaledVecBench(b, 10, 2) } +func BenchmarkAddScaledVec100Inc2(b *testing.B) { addScaledVecBench(b, 100, 2) } +func BenchmarkAddScaledVec1000Inc2(b *testing.B) { addScaledVecBench(b, 1000, 2) } +func BenchmarkAddScaledVec10000Inc2(b *testing.B) { addScaledVecBench(b, 10000, 2) } +func BenchmarkAddScaledVec100000Inc2(b *testing.B) { addScaledVecBench(b, 100000, 2) } +func BenchmarkAddScaledVec10Inc20(b *testing.B) { addScaledVecBench(b, 10, 20) } +func BenchmarkAddScaledVec100Inc20(b *testing.B) { addScaledVecBench(b, 100, 20) } +func BenchmarkAddScaledVec1000Inc20(b *testing.B) { addScaledVecBench(b, 1000, 20) } +func BenchmarkAddScaledVec10000Inc20(b *testing.B) { addScaledVecBench(b, 10000, 20) } +func BenchmarkAddScaledVec100000Inc20(b *testing.B) { addScaledVecBench(b, 100000, 20) } +func addScaledVecBench(b *testing.B, size, inc int) { + x := randVecDense(size, inc, 1, rand.NormFloat64) + y := randVecDense(size, inc, 1, rand.NormFloat64) + b.ResetTimer() + var v VecDense + for i := 0; i < b.N; i++ { + v.AddScaledVec(y, 2, x) + } +} + +func BenchmarkScaleVec10Inc1(b *testing.B) { scaleVecBench(b, 10, 1) } +func BenchmarkScaleVec100Inc1(b *testing.B) { scaleVecBench(b, 100, 1) } +func BenchmarkScaleVec1000Inc1(b *testing.B) { scaleVecBench(b, 1000, 1) } +func BenchmarkScaleVec10000Inc1(b *testing.B) { scaleVecBench(b, 10000, 1) } +func BenchmarkScaleVec100000Inc1(b *testing.B) { scaleVecBench(b, 100000, 1) } +func BenchmarkScaleVec10Inc2(b *testing.B) { scaleVecBench(b, 10, 2) } +func BenchmarkScaleVec100Inc2(b *testing.B) { scaleVecBench(b, 100, 2) } +func BenchmarkScaleVec1000Inc2(b *testing.B) { scaleVecBench(b, 1000, 2) } +func BenchmarkScaleVec10000Inc2(b *testing.B) { scaleVecBench(b, 10000, 2) } +func BenchmarkScaleVec100000Inc2(b *testing.B) { scaleVecBench(b, 100000, 2) } +func BenchmarkScaleVec10Inc20(b *testing.B) { scaleVecBench(b, 10, 20) } +func BenchmarkScaleVec100Inc20(b *testing.B) { scaleVecBench(b, 100, 20) } +func BenchmarkScaleVec1000Inc20(b *testing.B) { scaleVecBench(b, 1000, 20) } +func BenchmarkScaleVec10000Inc20(b *testing.B) { scaleVecBench(b, 10000, 20) } +func BenchmarkScaleVec100000Inc20(b *testing.B) { scaleVecBench(b, 100000, 20) } +func scaleVecBench(b *testing.B, size, inc int) { + x := randVecDense(size, inc, 1, rand.NormFloat64) + b.ResetTimer() + var v VecDense + for i := 0; i < b.N; i++ { + v.ScaleVec(2, x) + } +} + +func BenchmarkAddVec10Inc1(b *testing.B) { addVecBench(b, 10, 1) } +func BenchmarkAddVec100Inc1(b *testing.B) { addVecBench(b, 100, 1) } +func BenchmarkAddVec1000Inc1(b *testing.B) { addVecBench(b, 1000, 1) } +func BenchmarkAddVec10000Inc1(b *testing.B) { addVecBench(b, 10000, 1) } +func BenchmarkAddVec100000Inc1(b *testing.B) { addVecBench(b, 100000, 1) } +func BenchmarkAddVec10Inc2(b *testing.B) { addVecBench(b, 10, 2) } +func BenchmarkAddVec100Inc2(b *testing.B) { addVecBench(b, 100, 2) } +func BenchmarkAddVec1000Inc2(b *testing.B) { addVecBench(b, 1000, 2) } +func BenchmarkAddVec10000Inc2(b *testing.B) { addVecBench(b, 10000, 2) } +func BenchmarkAddVec100000Inc2(b *testing.B) { addVecBench(b, 100000, 2) } +func BenchmarkAddVec10Inc20(b *testing.B) { addVecBench(b, 10, 20) } +func BenchmarkAddVec100Inc20(b *testing.B) { addVecBench(b, 100, 20) } +func BenchmarkAddVec1000Inc20(b *testing.B) { addVecBench(b, 1000, 20) } +func BenchmarkAddVec10000Inc20(b *testing.B) { addVecBench(b, 10000, 20) } +func BenchmarkAddVec100000Inc20(b *testing.B) { addVecBench(b, 100000, 20) } +func addVecBench(b *testing.B, size, inc int) { + x := randVecDense(size, inc, 1, rand.NormFloat64) + y := randVecDense(size, inc, 1, rand.NormFloat64) + b.ResetTimer() + var v VecDense + for i := 0; i < b.N; i++ { + v.AddVec(x, y) + } +} + +func BenchmarkSubVec10Inc1(b *testing.B) { subVecBench(b, 10, 1) } +func BenchmarkSubVec100Inc1(b *testing.B) { subVecBench(b, 100, 1) } +func BenchmarkSubVec1000Inc1(b *testing.B) { subVecBench(b, 1000, 1) } +func BenchmarkSubVec10000Inc1(b *testing.B) { subVecBench(b, 10000, 1) } +func BenchmarkSubVec100000Inc1(b *testing.B) { subVecBench(b, 100000, 1) } +func BenchmarkSubVec10Inc2(b *testing.B) { subVecBench(b, 10, 2) } +func BenchmarkSubVec100Inc2(b *testing.B) { subVecBench(b, 100, 2) } +func BenchmarkSubVec1000Inc2(b *testing.B) { subVecBench(b, 1000, 2) } +func BenchmarkSubVec10000Inc2(b *testing.B) { subVecBench(b, 10000, 2) } +func BenchmarkSubVec100000Inc2(b *testing.B) { subVecBench(b, 100000, 2) } +func BenchmarkSubVec10Inc20(b *testing.B) { subVecBench(b, 10, 20) } +func BenchmarkSubVec100Inc20(b *testing.B) { subVecBench(b, 100, 20) } +func BenchmarkSubVec1000Inc20(b *testing.B) { subVecBench(b, 1000, 20) } +func BenchmarkSubVec10000Inc20(b *testing.B) { subVecBench(b, 10000, 20) } +func BenchmarkSubVec100000Inc20(b *testing.B) { subVecBench(b, 100000, 20) } +func subVecBench(b *testing.B, size, inc int) { + x := randVecDense(size, inc, 1, rand.NormFloat64) + y := randVecDense(size, inc, 1, rand.NormFloat64) + b.ResetTimer() + var v VecDense + for i := 0; i < b.N; i++ { + v.SubVec(x, y) + } +} + +func randVecDense(size, inc int, rho float64, rnd func() float64) *VecDense { + if size <= 0 { + panic("bad vector size") + } + data := make([]float64, size*inc) + for i := range data { + if rand.Float64() < rho { + data[i] = rnd() + } + } + return &VecDense{ + mat: blas64.Vector{ + Inc: inc, + Data: data, + }, + n: size, + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/README.md b/vendor/gonum.org/v1/gonum/mathext/README.md new file mode 100644 index 00000000..b3bc6442 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/README.md @@ -0,0 +1,3 @@ +# mathext [![GoDoc](https://godoc.org/gonum.org/v1/gonum/mathext?status.svg)](https://godoc.org/gonum.org/v1/gonum/mathext) + +Package mathext implements basic elementary functions not included in the Go standard library. diff --git a/vendor/gonum.org/v1/gonum/mathext/airy.go b/vendor/gonum.org/v1/gonum/mathext/airy.go new file mode 100644 index 00000000..1022e938 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/airy.go @@ -0,0 +1,37 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import "gonum.org/v1/gonum/mathext/internal/amos" + +// AiryAi returns the value of the Airy function at z. The Airy function here, +// Ai(z), is one of the two linearly independent solutions to +// y'' - y*z = 0. +// See http://mathworld.wolfram.com/AiryFunctions.html for more detailed information. +func AiryAi(z complex128) complex128 { + // id specifies the order of the derivative to compute, + // 0 for the function itself and 1 for the derivative. + // kode specifies the scaling option. See the function + // documentation for the exact behavior. + id := 0 + kode := 1 + air, aii, _ := amos.Zairy(real(z), imag(z), id, kode) + return complex(air, aii) +} + +// AiryAiDeriv returns the value of the derivative of the Airy function at z. The +// Airy function here, Ai(z), is one of the two linearly independent solutions to +// y'' - y*z = 0. +// See http://mathworld.wolfram.com/AiryFunctions.html for more detailed information. +func AiryAiDeriv(z complex128) complex128 { + // id specifies the order of the derivative to compute, + // 0 for the function itself and 1 for the derivative. + // kode specifies the scaling option. See the function + // documentation for the exact behavior. + id := 1 + kode := 1 + air, aii, _ := amos.Zairy(real(z), imag(z), id, kode) + return complex(air, aii) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/airy_test.go b/vendor/gonum.org/v1/gonum/mathext/airy_test.go new file mode 100644 index 00000000..4359abd5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/airy_test.go @@ -0,0 +1,28 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "math" + "testing" +) + +func TestAiry(t *testing.T) { + for _, test := range []struct { + z, ans complex128 + }{ + // Results computed using Octave. + {5, 1.08344428136074e-04}, + {5i, 29.9014823980070 + 21.6778315987835i}, + } { + ans := AiryAi(test.z) + if math.Abs(real(ans)-real(test.ans)) > 1e-10 { + t.Errorf("Real part mismatch. Got %v, want %v", real(ans), real(test.ans)) + } + if math.Abs(imag(ans)-imag(test.ans)) > 1e-10 { + t.Errorf("Imaginary part mismatch. Got %v, want %v", imag(ans), imag(test.ans)) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/beta.go b/vendor/gonum.org/v1/gonum/mathext/beta.go new file mode 100644 index 00000000..03f53f09 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/beta.go @@ -0,0 +1,34 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import "gonum.org/v1/gonum/mathext/internal/gonum" + +// Beta returns the value of the complete beta function B(a, b). It is defined as +// Γ(a)Γ(b) / Γ(a+b) +// Special cases are: +// B(a,b) returns NaN if a or b is Inf +// B(a,b) returns NaN if a and b are 0 +// B(a,b) returns NaN if a or b is NaN +// B(a,b) returns NaN if a or b is < 0 +// B(a,b) returns +Inf if a xor b is 0. +// +// See http://mathworld.wolfram.com/BetaFunction.html for more detailed informations. +func Beta(a, b float64) float64 { + return gonum.Beta(a, b) +} + +// Lbeta returns the natural logarithm of the complete beta function B(a,b). +// Lbeta is defined as: +// Ln(Γ(a)Γ(b)/Γ(a+b)) +// Special cases are: +// Lbeta(a,b) returns NaN if a or b is Inf +// Lbeta(a,b) returns NaN if a and b are 0 +// Lbeta(a,b) returns NaN if a or b is NaN +// Lbeta(a,b) returns NaN if a or b is < 0 +// Lbeta(a,b) returns +Inf if a xor b is 0. +func Lbeta(a, b float64) float64 { + return gonum.Lbeta(a, b) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/beta_test.go b/vendor/gonum.org/v1/gonum/mathext/beta_test.go new file mode 100644 index 00000000..7e0cd4c8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/beta_test.go @@ -0,0 +1,177 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext_test + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mathext" +) + +var betaTests = []struct { + p, q float64 + want float64 +}{ + { + p: 1, + q: 2, + want: 0.5, // obtained from scipy.special.beta(1,2) (version=0.18.0) + }, + { + p: 10, + q: 20, + want: 4.9925087406346778e-09, // obtained from scipy.special.beta(10,20) (version=0.18.0) + }, + { + p: +0, + q: 10, + want: math.Inf(+1), + }, + { + p: -0, + q: 10, + want: math.Inf(+1), + }, + { + p: 0, + q: 0, + want: math.NaN(), + }, + { + p: 0, + q: math.Inf(-1), + want: math.NaN(), + }, + { + p: 10, + q: math.Inf(-1), + want: math.NaN(), + }, + { + p: 0, + q: math.Inf(+1), + want: math.NaN(), + }, + { + p: 10, + q: math.Inf(+1), + want: math.NaN(), + }, + { + p: math.NaN(), + q: 10, + want: math.NaN(), + }, + { + p: math.NaN(), + q: 0, + want: math.NaN(), + }, + { + p: -1, + q: 0, + want: math.NaN(), + }, + { + p: -1, + q: +1, + want: math.NaN(), + }, +} + +func TestBeta(t *testing.T) { + for i, test := range betaTests { + v := mathext.Beta(test.p, test.q) + testOK := func(x float64) bool { + return floats.EqualWithinAbsOrRel(x, test.want, 1e-15, 1e-15) || (math.IsNaN(test.want) && math.IsNaN(x)) + } + if !testOK(v) { + t.Errorf("test #%d: Beta(%v, %v)=%v. want=%v\n", + i, test.p, test.q, v, test.want, + ) + } + + u := mathext.Beta(test.q, test.p) + if !testOK(u) { + t.Errorf("test #%[1]d: Beta(%[2]v, %[3]v)=%[4]v != Beta(%[3]v, %[2]v)=%[5]v)\n", + i, test.p, test.q, v, u, + ) + } + + if math.IsInf(v, +1) || math.IsNaN(v) { + continue + } + + vv := mathext.Beta(test.p, test.q+1) + uu := mathext.Beta(test.p+1, test.q) + if !floats.EqualWithinAbsOrRel(v, vv+uu, 1e-15, 1e-15) { + t.Errorf( + "test #%[1]d: Beta(%[2]v, %[3]v)=%[4]v != Beta(%[2]v+1, %[3]v) + Beta(%[2]v, %[3]v+1) (=%[5]v + %[6]v = %[7]v)\n", + i, test.p, test.q, v, uu, vv, uu+vv, + ) + } + + vbeta2 := beta2(test.p, test.q) + if !floats.EqualWithinAbsOrRel(v, vbeta2, 1e-15, 1e-15) { + t.Errorf( + "test #%[1]d: Beta(%[2]v, %[3]v) != Γ(p)Γ(q) / Γ(p+q) (v=%[4]v u=%[5]v)\n", + i, test.p, test.q, v, vbeta2, + ) + } + } +} + +func beta2(x, y float64) float64 { + return math.Gamma(x) * math.Gamma(y) / math.Gamma(x+y) +} + +func BenchmarkBeta(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = mathext.Beta(10, 20) + } +} + +func BenchmarkBeta2(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = math.Gamma(10) * math.Gamma(20) / math.Gamma(10+20) + } +} + +func TestLbeta(t *testing.T) { + for i, test := range betaTests { + want := math.Log(test.want) + v := mathext.Lbeta(test.p, test.q) + + testOK := func(x float64) bool { + return floats.EqualWithinAbsOrRel(x, want, 1e-15, 1e-15) || (math.IsNaN(want) && math.IsNaN(x)) + } + if !testOK(v) { + t.Errorf("test #%d: Lbeta(%v, %v)=%v. want=%v\n", + i, test.p, test.q, v, want, + ) + } + + u := mathext.Lbeta(test.q, test.p) + if !testOK(u) { + t.Errorf("test #%[1]d: Lbeta(%[2]v, %[3]v)=%[4]v != Lbeta(%[3]v, %[2]v)=%[5]v)\n", + i, test.p, test.q, v, u, + ) + } + + if math.IsInf(v, +1) || math.IsNaN(v) { + continue + } + + vbeta2 := math.Log(beta2(test.p, test.q)) + if !floats.EqualWithinAbsOrRel(v, vbeta2, 1e-15, 1e-15) { + t.Errorf( + "test #%[1]d: Lbeta(%[2]v, %[3]v) != Log(Γ(p)Γ(q) / Γ(p+q)) (v=%[4]v u=%[5]v)\n", + i, test.p, test.q, v, vbeta2, + ) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/betainc.go b/vendor/gonum.org/v1/gonum/mathext/betainc.go new file mode 100644 index 00000000..77791ce9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/betainc.go @@ -0,0 +1,29 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import "gonum.org/v1/gonum/mathext/internal/cephes" + +// RegIncBeta returns the value of the regularized incomplete beta function +// I(x;a,b). It is defined as +// I(x;a,b) = B(x;a,b) / B(a,b) +// = Γ(a+b) / (Γ(a)*Γ(b)) * int_0^x u^(a-1) * (1-u)^(b-1) du. +// The domain of definition is 0 <= x <= 1, and the parameters a and b must be positive. +// For other values of x, a, and b RegIncBeta will panic. +func RegIncBeta(a, b float64, x float64) float64 { + return cephes.Incbet(a, b, x) +} + +// InvRegIncBeta computes the inverse of the regularized incomplete beta function. +// It returns the x for which +// y = I(x;a,b) +// The domain of definition is 0 <= y <= 1, and the parameters a and b must be +// positive. For other values of x, a, and b InvRegIncBeta will panic. +func InvRegIncBeta(a, b float64, y float64) float64 { + if y < 0 || y > 1 { + panic("mathext: parameter out of range") + } + return cephes.Incbi(a, b, y) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/betainc_test.go b/vendor/gonum.org/v1/gonum/mathext/betainc_test.go new file mode 100644 index 00000000..f1e0c950 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/betainc_test.go @@ -0,0 +1,75 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestIncBeta(t *testing.T) { + tol := 1e-14 + tol2 := 1e-10 + // Test against values from scipy + for i, test := range []struct { + a, b, x, ans float64 + }{ + {1, 1, 0.8, 0.8}, + {1, 5, 0.8, 0.99968000000000001}, + {10, 10, 0.8, 0.99842087945083291}, + {10, 10, 0.1, 3.929882327128003e-06}, + {10, 2, 0.4, 0.00073400320000000028}, + {0.1, 0.2, 0.6, 0.69285678232066683}, + {1, 10, 0.7489, 0.99999900352334858}, + } { + y := RegIncBeta(test.a, test.b, test.x) + if !floats.EqualWithinAbsOrRel(y, test.ans, tol, tol) { + t.Errorf("Incomplete beta mismatch. Case %v: Got %v, want %v", i, y, test.ans) + } + + yc := 1 - RegIncBeta(test.b, test.a, 1-test.x) + if !floats.EqualWithinAbsOrRel(y, yc, tol, tol) { + t.Errorf("Incomplete beta complementary mismatch. Case %v: Got %v, want %v", i, y, yc) + } + + x := InvRegIncBeta(test.a, test.b, y) + if !floats.EqualWithinAbsOrRel(x, test.x, tol2, tol2) { + t.Errorf("Inverse incomplete beta mismatch. Case %v: Got %v, want %v", i, x, test.x) + } + } + + // Confirm that Invincbeta and Incbeta agree. Sweep over a variety of + // a, b, and y values. + tol = 1e-6 + steps := 201 + ints := make([]float64, steps) + floats.Span(ints, 0, 1) + + sz := 51 + min := 1e-2 + max := 1e2 + as := make([]float64, sz) + floats.LogSpan(as, min, max) + bs := make([]float64, sz) + floats.LogSpan(bs, min, max) + + for _, a := range as { + for _, b := range bs { + for _, yr := range ints { + x := InvRegIncBeta(a, b, yr) + if x > 1-1e-6 { + // Numerical error too large + continue + } + y := RegIncBeta(a, b, x) + if !floats.EqualWithinAbsOrRel(yr, y, tol, tol) { + t.Errorf("Mismatch between inv inc beta and inc beta. a = %v, b = %v, x = %v, got %v, want %v.", a, b, x, y, yr) + break + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/digamma.go b/vendor/gonum.org/v1/gonum/mathext/digamma.go new file mode 100644 index 00000000..81132dd1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/digamma.go @@ -0,0 +1,28 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "math" +) + +// Digamma returns the logorithmic derivative of the gamma function at x. +// ψ(x) = d/dx (Ln (Γ(x)). +// Note that if x is a negative integer in [-7, 0] this function will return +// negative Inf. +func Digamma(x float64) float64 { + // This is adapted from + // http://web.science.mq.edu.au/~mjohnson/code/digamma.c + var result float64 + for ; x < 7.0; x++ { + result -= 1 / x + } + x -= 1.0 / 2.0 + xx := 1.0 / x + xx2 := xx * xx + xx4 := xx2 * xx2 + result += math.Log(x) + (1./24.)*xx2 - (7.0/960.0)*xx4 + (31.0/8064.0)*xx4*xx2 - (127.0/30720.0)*xx4*xx4 + return result +} diff --git a/vendor/gonum.org/v1/gonum/mathext/digamma_test.go b/vendor/gonum.org/v1/gonum/mathext/digamma_test.go new file mode 100644 index 00000000..0e113ed1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/digamma_test.go @@ -0,0 +1,27 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "math" + "testing" +) + +func TestDigamma(t *testing.T) { + for i, test := range []struct { + x, want float64 + }{ + // Results computed using WolframAlpha. + {-100.5, 4.615124601338064117341315601525112558522917517910505881343}, + {.5, -1.96351002602142347944097633299875556719315960466043}, + {10, 2.251752589066721107647456163885851537211808918028330369448}, + {math.Pow10(20), 46.05170185988091368035482909368728415202202143924212618733}, + } { + + if got := Digamma(test.x); math.Abs(got-test.want) > 1e-10 { + t.Errorf("test %d Digamma(%g) failed: got %g want %g", i, test.x, got, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/doc.go b/vendor/gonum.org/v1/gonum/mathext/doc.go new file mode 100644 index 00000000..b1c350ee --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/doc.go @@ -0,0 +1,7 @@ +// 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 mathext implements special math functions not implemented by the +// Go standard library. +package mathext // import "gonum.org/v1/gonum/mathext" diff --git a/vendor/gonum.org/v1/gonum/mathext/ell_carlson.go b/vendor/gonum.org/v1/gonum/mathext/ell_carlson.go new file mode 100644 index 00000000..159f0a9e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/ell_carlson.go @@ -0,0 +1,156 @@ +// 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 mathext + +import ( + "math" +) + +// EllipticRF computes the symmetric elliptic integral R_F(x,y,z): +// R_F(x,y,z) = (1/2)\int_{0}^{\infty}{1/s(t)} dt, +// s(t) = \sqrt{(t+x)(t+y)(t+z)}. +// +// The arguments x, y, z must satisfy the following conditions, otherwise the function returns math.NaN(): +// 0 ≤ x,y,z ≤ upper, +// lower ≤ x+y,y+z,z+x, +// where: +// lower = 5/(2^1022) = 1.112536929253601e-307, +// upper = (2^1022)/5 = 8.988465674311580e+306. +// +// The definition of the symmetric elliptic integral R_F can be found in NIST +// Digital Library of Mathematical Functions (http://dlmf.nist.gov/19.16.E1). +func EllipticRF(x, y, z float64) float64 { + // The original Fortran code was published as Algorithm 577 in ACM TOMS (http://doi.org/10.1145/355958.355970). + // This code is also available as a part of SLATEC Common Mathematical Library (http://netlib.org/slatec/index.html). Later, Carlson described + // an improved version in http://dx.doi.org/10.1007/BF02198293 (also available at https://arxiv.org/abs/math/9409227). + const ( + lower = 5.0 / (1 << 256) / (1 << 256) / (1 << 256) / (1 << 254) // 5*2^-1022 + upper = 1 / lower + tol = 1.2674918778210762260320167734407048051023273568443e-02 // (3ε)^(1/8) + ) + if x < 0 || y < 0 || z < 0 || math.IsNaN(x) || math.IsNaN(y) || math.IsNaN(z) { + return math.NaN() + } + if upper < x || upper < y || upper < z { + return math.NaN() + } + if x+y < lower || y+z < lower || z+x < lower { + return math.NaN() + } + + A0 := (x + y + z) / 3 + An := A0 + Q := math.Max(math.Max(math.Abs(A0-x), math.Abs(A0-y)), math.Abs(A0-z)) / tol + xn, yn, zn := x, y, z + mul := 1.0 + + for Q >= mul*math.Abs(An) { + xnsqrt, ynsqrt, znsqrt := math.Sqrt(xn), math.Sqrt(yn), math.Sqrt(zn) + lambda := xnsqrt*ynsqrt + ynsqrt*znsqrt + znsqrt*xnsqrt + An = (An + lambda) * 0.25 + xn = (xn + lambda) * 0.25 + yn = (yn + lambda) * 0.25 + zn = (zn + lambda) * 0.25 + mul *= 4 + } + + X := (A0 - x) / (mul * An) + Y := (A0 - y) / (mul * An) + Z := -(X + Y) + E2 := X*Y - Z*Z + E3 := X * Y * Z + + // http://dlmf.nist.gov/19.36.E1 + return (1 - 1/10.0*E2 + 1/14.0*E3 + 1/24.0*E2*E2 - 3/44.0*E2*E3 - 5/208.0*E2*E2*E2 + 3/104.0*E3*E3 + 1/16.0*E2*E2*E3) / math.Sqrt(An) +} + +// EllipticRD computes the symmetric elliptic integral R_D(x,y,z): +// R_D(x,y,z) = (1/2)\int_{0}^{\infty}{1/(s(t)(t+z))} dt, +// s(t) = \sqrt{(t+x)(t+y)(t+z)}. +// +// The arguments x, y, z must satisfy the following conditions, otherwise the function returns math.NaN(): +// 0 ≤ x,y ≤ upper, +// lower ≤ z ≤ upper, +// lower ≤ x+y, +// where: +// lower = (5/(2^1022))^(1/3) = 4.809554074311679e-103, +// upper = ((2^1022)/5)^(1/3) = 2.079194837087086e+102. +// +// The definition of the symmetric elliptic integral R_D can be found in NIST +// Digital Library of Mathematical Functions (http://dlmf.nist.gov/19.16.E5). +func EllipticRD(x, y, z float64) float64 { + // The original Fortran code was published as Algorithm 577 in ACM TOMS (http://doi.org/10.1145/355958.355970). + // This code is also available as a part of SLATEC Common Mathematical Library (http://netlib.org/slatec/index.html). Later, Carlson described + // an improved version in http://dx.doi.org/10.1007/BF02198293 (also available at https://arxiv.org/abs/math/9409227). + const ( + lower = 4.8095540743116787026618007863123676393525016818363e-103 // (5*2^-1022)^(1/3) + upper = 1 / lower + tol = 9.0351169339315770474760122547068324993857488849382e-03 // (ε/5)^(1/8) + ) + if x < 0 || y < 0 || math.IsNaN(x) || math.IsNaN(y) || math.IsNaN(z) { + return math.NaN() + } + if upper < x || upper < y || upper < z { + return math.NaN() + } + if x+y < lower || z < lower { + return math.NaN() + } + + A0 := (x + y + 3*z) / 5 + An := A0 + Q := math.Max(math.Max(math.Abs(A0-x), math.Abs(A0-y)), math.Abs(A0-z)) / tol + xn, yn, zn := x, y, z + mul, s := 1.0, 0.0 + + for Q >= mul*math.Abs(An) { + xnsqrt, ynsqrt, znsqrt := math.Sqrt(xn), math.Sqrt(yn), math.Sqrt(zn) + lambda := xnsqrt*ynsqrt + ynsqrt*znsqrt + znsqrt*xnsqrt + s += 1 / (mul * znsqrt * (zn + lambda)) + An = (An + lambda) * 0.25 + xn = (xn + lambda) * 0.25 + yn = (yn + lambda) * 0.25 + zn = (zn + lambda) * 0.25 + mul *= 4 + } + + X := (A0 - x) / (mul * An) + Y := (A0 - y) / (mul * An) + Z := -(X + Y) / 3 + E2 := X*Y - 6*Z*Z + E3 := (3*X*Y - 8*Z*Z) * Z + E4 := 3 * (X*Y - Z*Z) * Z * Z + E5 := X * Y * Z * Z * Z + + // http://dlmf.nist.gov/19.36.E2 + return (1-3/14.0*E2+1/6.0*E3+9/88.0*E2*E2-3/22.0*E4-9/52.0*E2*E3+3/26.0*E5-1/16.0*E2*E2*E2+3/40.0*E3*E3+3/20.0*E2*E4+45/272.0*E2*E2*E3-9/68.0*(E3*E4+E2*E5))/(mul*An*math.Sqrt(An)) + 3*s +} + +// EllipticF computes the Legendre's elliptic integral of the 1st kind F(phi,m), 0≤m<1: +// F(\phi,m) = \int_{0}^{\phi} 1 / \sqrt{1-m\sin^2(\theta)} d\theta +// +// Legendre's elliptic integrals can be expressed as symmetric elliptic integrals, in this case: +// F(\phi,m) = \sin\phi R_F(\cos^2\phi,1-m\sin^2\phi,1) +// +// The definition of F(phi,k) where k=sqrt(m) can be found in NIST Digital Library of Mathematical +// Functions (http://dlmf.nist.gov/19.2.E4). +func EllipticF(phi, m float64) float64 { + s, c := math.Sincos(phi) + return s * EllipticRF(c*c, 1-m*s*s, 1) +} + +// EllipticE computes the Legendre's elliptic integral of the 2nd kind E(phi,m), 0≤m<1: +// E(\phi,m) = \int_{0}^{\phi} \sqrt{1-m\sin^2(\theta)} d\theta +// +// Legendre's elliptic integrals can be expressed as symmetric elliptic integrals, in this case: +// E(\phi,m) = \sin\phi R_F(\cos^2\phi,1-m\sin^2\phi,1)-(m/3)\sin^3\phi R_D(\cos^2\phi,1-m\sin^2\phi,1) +// +// The definition of E(phi,k) where k=sqrt(m) can be found in NIST Digital Library of Mathematical +// Functions (http://dlmf.nist.gov/19.2.E5). +func EllipticE(phi, m float64) float64 { + s, c := math.Sincos(phi) + x, y := c*c, 1-m*s*s + return s * (EllipticRF(x, y, 1) - (m/3)*s*s*EllipticRD(x, y, 1)) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/ell_carlson_test.go b/vendor/gonum.org/v1/gonum/mathext/ell_carlson_test.go new file mode 100644 index 00000000..4018bc1c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/ell_carlson_test.go @@ -0,0 +1,103 @@ +// 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 mathext + +import ( + "math" + "math/rand" + "testing" +) + +// Testing EllipticF (and EllipticRF) using the addition theorems from http://dlmf.nist.gov/19.11.i +func TestEllipticF(t *testing.T) { + const tol = 1.0e-14 + rnd := rand.New(rand.NewSource(1)) + + // The following EllipticF(pi/3,m), m=0.1(0.1)0.9 was computed in Maxima 5.38.0 using Bigfloat arithmetic. + vF := [...]float64{ + 1.0631390181954904767742338285104637431858016483079, + 1.0803778062523490005579242592072579594037132891908, + 1.0991352230920430074586978843452269008747645822123, + 1.1196949183404746257742176145632376703505764745654, + 1.1424290580457772555013955266260457822322036529624, + 1.1678400583161860445148860686430780757517286094732, + 1.1966306515644649360767197589467723191317720122309, + 1.2298294422249382706933871574135731278765534034979, + 1.2690359140762658660446752406901433173504503955036, + } + phi := math.Pi / 3 + for m := 1; m <= 9; m++ { + mf := float64(m) / 10 + delta := math.Abs(EllipticF(phi, mf) - vF[m-1]) + if delta > tol { + t.Fatalf("EllipticF(pi/3,m) test fail for m=%v", mf) + } + } + + for test := 0; test < 100; test++ { + alpha := rnd.Float64() * math.Pi / 4 + beta := rnd.Float64() * math.Pi / 4 + for mi := 0; mi < 9999; mi++ { + m := float64(mi) / 10000 + Fa := EllipticF(alpha, m) + Fb := EllipticF(beta, m) + sina, cosa := math.Sincos(alpha) + sinb, cosb := math.Sincos(beta) + tan := (sina*math.Sqrt(1-m*sinb*sinb) + sinb*math.Sqrt(1-m*sina*sina)) / (cosa + cosb) + gamma := 2 * math.Atan(tan) + Fg := EllipticF(gamma, m) + delta := math.Abs(Fa + Fb - Fg) + if delta > tol { + t.Fatalf("EllipticF test fail for m=%v, alpha=%v, beta=%v", m, alpha, beta) + } + } + } +} + +// Testing EllipticE (and EllipticRF, EllipticRD) using the addition theorems from http://dlmf.nist.gov/19.11.i +func TestEllipticE(t *testing.T) { + const tol = 1.0e-14 + rnd := rand.New(rand.NewSource(1)) + + // The following EllipticE(pi/3,m), m=0.1(0.1)0.9 was computed in Maxima 5.38.0 using Bigfloat arithmetic. + vE := [...]float64{ + 1.0316510822817691068014397636905610074934300946730, + 1.0156973658341766636288643556414001451527597364432, + 9.9929636467826398814855428365155224243586391115108e-1, + 9.8240033979859736941287149003648737502960015189033e-1, + 9.6495145764299257550956863602992167490195750321518e-1, + 9.4687829659158090935158610908054896203271861698355e-1, + 9.2809053417715769009517654522979827392794124845027e-1, + 9.0847044378047233264777277954768245721857017157916e-1, + 8.8785835036531301307661603341327881634688308777383e-1, + } + phi := math.Pi / 3 + for m := 1; m <= 9; m++ { + mf := float64(m) / 10 + delta := math.Abs(EllipticE(phi, mf) - vE[m-1]) + if delta > tol { + t.Fatalf("EllipticE(pi/3,m) test fail for m=%v", mf) + } + } + + for test := 0; test < 100; test++ { + alpha := rnd.Float64() * math.Pi / 4 + beta := rnd.Float64() * math.Pi / 4 + for mi := 0; mi < 9999; mi++ { + m := float64(mi) / 10000 + Ea := EllipticE(alpha, m) + Eb := EllipticE(beta, m) + sina, cosa := math.Sincos(alpha) + sinb, cosb := math.Sincos(beta) + tan := (sina*math.Sqrt(1-m*sinb*sinb) + sinb*math.Sqrt(1-m*sina*sina)) / (cosa + cosb) + gamma := 2 * math.Atan(tan) + Eg := EllipticE(gamma, m) + delta := math.Abs(Ea + Eb - Eg - m*sina*sinb*math.Sin(gamma)) + if delta > tol { + t.Fatalf("EllipticE test fail for m=%v, alpha=%v, beta=%v", m, alpha, beta) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/ell_complete.go b/vendor/gonum.org/v1/gonum/mathext/ell_complete.go new file mode 100644 index 00000000..08586ec0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/ell_complete.go @@ -0,0 +1,157 @@ +// 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 mathext + +import ( + "math" +) + +// CompleteK computes the complete elliptic integral of the 1st kind, 0≤m≤1. +// It returns math.NaN() if m is not in [0,1]. +// +// K(m) = \int_{0}^{\pi/2} 1 / {\sqrt{1-m{\sin^2\theta}}} d\theta +// +// See: http://dx.doi.org/10.1016/j.cam.2014.12.038 for the computation method. +func CompleteK(m float64) float64 { + if m < 0 || 1 < m || math.IsNaN(m) { + return math.NaN() + } + + mc := 1 - m + + if mc > 0.592990 { + t := 2.45694208987494165*mc - 1.45694208987494165 + p := 3703.75266375099019 + t*(5462.47093231923466+t*(2744.82029097576810+t*(543.839017382099411+t*(36.2381612593459565+t*0.393188651542789784)))) + q := 2077.94377067058435 + t*(3398.00069767755460+t*(1959.05960044399275+t*(472.794455487539279+t*(43.5464368440078942+t)))) + return p / q + } + if mc > 0.350756 { + t := 4.12823963605439369*mc - 1.44800482178389491 + p := 4264.28203103974630 + t*(6341.90978213264024+t*(3214.59187442783167+t*(642.790566685354573+t*(43.2589626155454993+t*0.475223892294445943)))) + q := 2125.06914237062279 + t*(3479.95663350926514+t*(2006.03187933518870+t*(482.900172581418890+t*(44.1848041560412224+t)))) + return p / q + } + if mc > 0.206924 { + t := 6.95255575949719117*mc - 1.43865064797819679 + p := 4870.25402224986382 + t*(7307.18826377416591+t*(3738.29369283392307+t*(754.928587580583704+t*(51.3609902253065926+t*0.571948962277566451)))) + q := 2172.51745704102287 + t*(3565.04737778032566+t*(2056.13612019430497+t*(493.962405117599400+t*(44.9026847057686146+t)))) + return p / q + } + if mc > 0.121734 { + t := 11.7384669562155183*mc - 1.42897053644793990 + p := 5514.8512729127464 + t*(8350.4595896779631+t*(4313.60788246750934+t*(880.27903031894216+t*(60.598720224393536+t*0.68504458747933773)))) + q := 2218.41682813309737 + t*(3650.41829123846319+t*(2107.97379949034285+t*(505.74295207655096+t*(45.6911096775045314+t)))) + return p / q + } + if mc > 0.071412 { + t := 19.8720241643813839*mc - 1.41910098962680339 + p := 6188.8743957372448 + t*(9459.3331440432847+t*(4935.41351498551527+t*(1018.21910476032105+t*(70.981049144472361+t*0.81599895108245948)))) + q := 2260.73112539748448 + t*(3732.66955095581621+t*(2159.68721749761492+t*(517.86964191812384+t*(46.5298955058476510+t)))) + return p / q + } + if mc > 0.041770 { + t := 33.7359152553808785*mc - 1.40914918021725929 + p := 6879.5170681289562 + t*(10615.0836403687221+t*(5594.8381504799829+t*(1167.26108955935542+t*(82.452856129147838+t*0.96592719058503951)))) + q := 2296.88303450660439 + t*(3807.37745652028212+t*(2208.74949754945558+t*(529.79651353072921+t*(47.3844470709989137+t)))) + return p / q + } + if mc > 0.024360 { + t := 57.4382538770821367*mc - 1.39919586444572085 + p := 7570.6827538712100 + t*(11792.9392624454532+t*(6279.2661370014890+t*(1325.01058966228180+t*(94.886883830605940+t*1.13537029594409690)))) + q := 2324.04824540459984 + t*(3869.56755306385732+t*(2252.22250562615338+t*(540.85752251676412+t*(48.2089280211559345+t)))) + return p / q + } + if mc > 0.014165 { + t := 98.0872976949485042*mc - 1.38940657184894556 + p := 8247.2601660137746 + t*(12967.7060124572914+t*(6974.7495213178613+t*(1488.54008220335966+t*(108.098282908839979+t*1.32411616748380686)))) + q := 2340.47337508405427 + t*(3915.63324533769906+t*(2287.70677154700516+t*(550.45072377717361+t*(48.9575432570382154+t)))) + return p / q + } + if mc > 0.008213 { + t := 168.010752688172043*mc - 1.37987231182795699 + p := 8894.2961573611293 + t*(14113.7038749808951+t*(7666.5611739483371+t*(1654.60731579994159+t*(121.863474964652041+t*1.53112170837206117)))) + q := 2344.88618943372377 + t*(3942.81065054556536+t*(2313.28396270968662+t*(558.07615380622169+t*(49.5906602613891184+t)))) + return p / q + } + if mc > 0 { + t := 1.0 - 121.758188238159016*mc + p := -math.Log(mc*0.0625) * (34813.4518336350547 + t*(235.767716637974271+t*0.199792723884069485)) / (69483.5736412906324 + t*(614.265044703187382+t)) + q := -mc * (9382.53386835986099 + t*(51.6478985993381223+t*0.00410754154682816898)) / (37327.7262507318317 + t*(408.017247271148538+t)) + return p + q + } + + return math.Inf(1) +} + +// CompleteE computes the complete elliptic integral of the 2nd kind, 0≤m≤1. +// It returns math.NaN() if m is not in [0,1]. +// +// E(m) = \int_{0}^{\pi/2} {\sqrt{1-m{\sin^2\theta}}} d\theta +// +// See: http://dx.doi.org/10.1016/j.cam.2014.12.038 for the computation method. +func CompleteE(m float64) float64 { + if m < 0 || 1 < m || math.IsNaN(m) { + return math.NaN() + } + + mc := 1 - m + + if mc > 0.566638 { + t := 2.30753965506897236*mc - 1.30753965506897236 + p := 19702.2363352671642 + t*(31904.1559574281609+t*(18177.1879313824040+t*(4362.94760768571862+t*(409.975559128654710+t*10.3244775335024885)))) + q := 14241.2135819448616 + t*(20909.9899599927367+t*(10266.4884503526076+t*(1934.86289070792954+t*(117.162100771599098+t)))) + return p / q + } + if mc > 0.315153 { + t := 3.97638030101198879*mc - 1.25316818100483130 + p := 16317.0721393008221 + t*(26627.8852140835023+t*(15129.4009798463159+t*(3574.15857605556033+t*(326.113727011739428+t*7.93163724081373477)))) + q := 13047.1505096551210 + t*(19753.5762165922376+t*(9964.25173735060361+t*(1918.72232033637537+t*(117.670514069579649+t)))) + return p / q + } + if mc > 0.171355 { + t := 6.95419964116329852*mc - 1.19163687951153702 + p := 13577.3850240991520 + t*(22545.4744699553993+t*(12871.9137872656293+t*(3000.74575264868572+t*(263.964361648520708+t*6.08522443139677663)))) + q := 11717.3306408059832 + t*(18431.1264424290258+t*(9619.40382323874064+t*(1904.06010727307491+t*(118.690522739531267+t)))) + return p / q + } + if mc > 0.090670 { + t := 12.3938774245522712*mc - 1.12375286608415443 + p := 11307.9485341543712 + t*(19328.6173704569489+t*(11208.6068472959372+t*(2596.54874477084334+t*(219.253495956962613+t*4.66931143174036616)))) + q := 10307.6837501971393 + t*(16982.2450249024383+t*(9241.7604666150102+t*(1893.41905403040679+t*(120.498555754227847+t)))) + return p / q + } + if mc > 0.046453 { + t := 22.6157360291290680*mc - 1.05056878576113260 + p := 9383.1490856819874 + t*(16718.9730458676860+t*(9977.2498973537718+t*(2323.49987246555537+t*(188.618148076418837+t*3.59313532204509922)))) + q := 8877.1964704758383 + t*(15450.0537230364062+t*(8840.2771293410661+t*(1889.13672102820913+t*(123.422125687316355+t)))) + return p / q + } + if mc > 0.022912 { + t := 42.4790790535661187*mc - 0.973280659275306911 + p := 7719.1171817802054 + t*(14521.7363804934985+t*(9045.3996063894006+t*(2149.92068078627829+t*(169.386557799782496+t*2.78515570453129137)))) + q := 7479.7539074698012 + t*(13874.4978011497847+t*(8420.3848818926324+t*(1892.69753150329759+t*(127.802109608726363+t)))) + return p / q + } + if mc > 0.010809 { + t := 82.6241427745187144*mc - 0.893084359249772784 + p := 6261.6095608987273 + t*(12593.0874916293982+t*(8304.3265605809870+t*(2048.68391263416822+t*(159.371262600702237+t*2.18867046462858104)))) + q := 6156.4532048239501 + t*(12283.8373999680518+t*(7979.7435857665227+t*(1903.60556312663537+t*(133.911640385965187+t)))) + return p / q + } + if mc > 0.004841 { + t := 167.560321715817694*mc - 0.811159517426273458 + p := 4978.06146583586728 + t*(10831.7178150656694+t*(7664.6703673290453+t*(1995.66437151562090+t*(156.689647694892782+t*1.75859085945198570)))) + q := 4935.56743322938333 + t*(10694.5510113880077+t*(7506.8028283118051+t*(1918.38517009740321+t*(141.854303920116856+t)))) + return p / q + } + if mc > 0 { + t := 1.0 - 206.568890725056806*mc + p := -mc * math.Log(mc*0.0625) * (41566.6612602868736 + t*(154.034981522913482+t*0.0618072471798575991)) / (165964.442527585615 + t*(917.589668642251803+t)) + q := (132232.803956682877 + t*(353.375480007017643-t*1.40105837312528026)) / (132393.665743088043 + t*(192.112635228732532-t)) + return p + q + } + + return 1 +} diff --git a/vendor/gonum.org/v1/gonum/mathext/ell_complete_test.go b/vendor/gonum.org/v1/gonum/mathext/ell_complete_test.go new file mode 100644 index 00000000..54840c58 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/ell_complete_test.go @@ -0,0 +1,27 @@ +// 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 mathext + +import ( + "math" + "testing" +) + +// TestCompleteKE checks if the Legendre's relation for m=0.0001(0.0001)0.9999 +// is satisfied with accuracy 1e-14. +func TestCompleteKE(t *testing.T) { + const tol = 1.0e-14 + + for m := 1; m <= 9999; m++ { + mf := float64(m) / 10000 + mp := 1 - mf + K, Kp := CompleteK(mf), CompleteK(mp) + E, Ep := CompleteE(mf), CompleteE(mp) + legendre := math.Abs(E*Kp + Ep*K - K*Kp - math.Pi/2) + if legendre > tol { + t.Fatalf("legendre > tol: m=%v, legendre=%v, tol=%v", mf, legendre, tol) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/erf.go b/vendor/gonum.org/v1/gonum/mathext/erf.go new file mode 100644 index 00000000..cee4dbc2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/erf.go @@ -0,0 +1,91 @@ +// 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 mathext + +import "math" + +/* +Copyright (c) 2012 The Probab 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 Google Inc. nor the names of its +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 +OWNER 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. +*/ + +// NormalQuantile computes the quantile function (inverse CDF) of the standard +// normal. NormalQuantile panics if the input p is less than 0 or greater than 1. +func NormalQuantile(p float64) float64 { + switch { + case p < 0 || 1 < p: + panic("mathext: quantile out of bounds") + case p == 1: + return math.Inf(1) + case p == 0: + return math.Inf(-1) + } + // Compute rational approximation based on the value of p. + + dp := p - 0.5 + if math.Abs(dp) <= 0.425 { + z := 0.180625 - dp*dp + z1 := ((((((zQSA[0]*z+zQSA[1])*z+zQSA[2])*z+zQSA[3])*z+zQSA[4])*z+zQSA[5])*z+zQSA[6])*z + zQSA[7] + z2 := ((((((zQSB[0]*z+zQSB[1])*z+zQSB[2])*z+zQSB[3])*z+zQSB[4])*z+zQSB[5])*z+zQSB[6])*z + zQSB[7] + return dp * z1 / z2 + } + + if p < 0.5 { + r := math.Sqrt(-math.Log(p)) + if r <= 5.0 { + z := r - 1.6 + z1 := ((((((zQIA[0]*z+zQIA[1])*z+zQIA[2])*z+zQIA[3])*z+zQIA[4])*z+zQIA[5])*z+zQIA[6])*z + zQIA[7] + z2 := ((((((zQIB[0]*z+zQIB[1])*z+zQIB[2])*z+zQIB[3])*z+zQIB[4])*z+zQIB[5])*z+zQIB[6])*z + zQIB[7] + return -z1 / z2 + } + z := r - 5 + z1 := ((((((zQTA[0]*z+zQTA[1])*z+zQTA[2])*z+zQTA[3])*z+zQTA[4])*z+zQTA[5])*z+zQTA[6])*z + zQTA[7] + z2 := ((((((zQTB[0]*z+zQTB[1])*z+zQTB[2])*z+zQTB[3])*z+zQTB[4])*z+zQTB[5])*z+zQTB[6])*z + zQTB[7] + return -z1 / z2 + } + r := math.Sqrt(-math.Log(1 - p)) + if r <= 5.0 { + z := r - 1.6 + z1 := ((((((zQIA[0]*z+zQIA[1])*z+zQIA[2])*z+zQIA[3])*z+zQIA[4])*z+zQIA[5])*z+zQIA[6])*z + zQIA[7] + z2 := ((((((zQIB[0]*z+zQIB[1])*z+zQIB[2])*z+zQIB[3])*z+zQIB[4])*z+zQIB[5])*z+zQIB[6])*z + zQIB[7] + return z1 / z2 + } + + z := r - 5 + z1 := ((((((zQTA[0]*z+zQTA[1])*z+zQTA[2])*z+zQTA[3])*z+zQTA[4])*z+zQTA[5])*z+zQTA[6])*z + zQTA[7] + z2 := ((((((zQTB[0]*z+zQTB[1])*z+zQTB[2])*z+zQTB[3])*z+zQTB[4])*z+zQTB[5])*z+zQTB[6])*z + zQTB[7] + return z1 / z2 +} + +var ( + zQSA = [...]float64{2509.0809287301226727, 33430.575583588128105, 67265.770927008700853, 45921.953931549871457, 13731.693765509461125, 1971.5909503065514427, 133.14166789178437745, 3.387132872796366608} + zQSB = [...]float64{5226.495278852854561, 28729.085735721942674, 39307.89580009271061, 21213.794301586595867, 5394.1960214247511077, 687.1870074920579083, 42.313330701600911252, 1.0} + zQIA = [...]float64{7.7454501427834140764e-4, 0.0227238449892691845833, 0.24178072517745061177, 1.27045825245236838258, 3.64784832476320460504, 5.7694972214606914055, 4.6303378461565452959, 1.42343711074968357734} + zQIB = [...]float64{1.05075007164441684324e-9, 5.475938084995344946e-4, 0.0151986665636164571966, 0.14810397642748007459, 0.68976733498510000455, 1.6763848301838038494, 2.05319162663775882187, 1.0} + zQTA = [...]float64{2.01033439929228813265e-7, 2.71155556874348757815e-5, 0.0012426609473880784386, 0.026532189526576123093, 0.29656057182850489123, 1.7848265399172913358, 5.4637849111641143699, 6.6579046435011037772} + zQTB = [...]float64{2.04426310338993978564e-15, 1.4215117583164458887e-7, 1.8463183175100546818e-5, 7.868691311456132591e-4, 0.0148753612908506148525, 0.13692988092273580531, 0.59983220655588793769, 1.0} +) diff --git a/vendor/gonum.org/v1/gonum/mathext/erf_test.go b/vendor/gonum.org/v1/gonum/mathext/erf_test.go new file mode 100644 index 00000000..f698e51e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/erf_test.go @@ -0,0 +1,69 @@ +// 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 mathext + +import ( + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestNormalQuantile(t *testing.T) { + // Values from https://www.johndcook.com/blog/normal_cdf_inverse/ + p := []float64{ + 0.0000001, + 0.00001, + 0.001, + 0.05, + 0.15, + 0.25, + 0.35, + 0.45, + 0.55, + 0.65, + 0.75, + 0.85, + 0.95, + 0.999, + 0.99999, + 0.9999999, + } + ans := []float64{ + -5.199337582187471, + -4.264890793922602, + -3.090232306167813, + -1.6448536269514729, + -1.0364333894937896, + -0.6744897501960817, + -0.38532046640756773, + -0.12566134685507402, + 0.12566134685507402, + 0.38532046640756773, + 0.6744897501960817, + 1.0364333894937896, + 1.6448536269514729, + 3.090232306167813, + 4.264890793922602, + 5.199337582187471, + } + for i, v := range p { + got := NormalQuantile(v) + if !floats.EqualWithinAbsOrRel(got, ans[i], 1e-10, 1e-10) { + t.Errorf("Quantile mismatch. Case %d, want: %v, got: %v", i, ans[i], got) + } + } +} + +var nqtmp float64 + +func BenchmarkNormalQuantile(b *testing.B) { + ps := make([]float64, 1000) // ensure there are small values + floats.Span(ps, 0, 1) + for i := 0; i < b.N; i++ { + for _, v := range ps { + nqtmp = NormalQuantile(v) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/gamma_inc.go b/vendor/gonum.org/v1/gonum/mathext/gamma_inc.go new file mode 100644 index 00000000..db16dad9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/gamma_inc.go @@ -0,0 +1,50 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "gonum.org/v1/gonum/mathext/internal/cephes" +) + +// GammaInc computes the incomplete Gamma integral. +// GammaInc(a,x) = (1/ Γ(a)) \int_0^x e^{-t} t^{a-1} dt +// The input argument a must be positive and x must be non-negative or GammaInc +// will panic. +// +// See http://mathworld.wolfram.com/IncompleteGammaFunction.html +// or https://en.wikipedia.org/wiki/Incomplete_gamma_function for more detailed +// information. +func GammaInc(a, x float64) float64 { + return cephes.Igam(a, x) +} + +// GammaIncComp computes the complemented incomplete Gamma integral. +// GammaIncComp(a,x) = 1 - GammaInc(a,x) +// = (1/ Γ(a)) \int_0^\infty e^{-t} t^{a-1} dt +// The input argument a must be positive and x must be non-negative or +// GammaIncComp will panic. +func GammaIncComp(a, x float64) float64 { + return cephes.IgamC(a, x) +} + +// GammaIncInv computes the inverse of the incomplete Gamma integral. That is, +// it returns the x such that: +// GammaInc(a, x) = y +// The input argument a must be positive and y must be between 0 and 1 +// inclusive or GammaIncInv will panic. GammaIncInv should return a positive +// number, but can return NaN if there is a failure to converge. +func GammaIncInv(a, y float64) float64 { + return gammaIncInv(a, y) +} + +// GammaIncCompInv computes the inverse of the complemented incomplete Gamma +// integral. That is, it returns the x such that: +// GammaIncComp(a, x) = y +// The input argument a must be positive and y must be between 0 and 1 +// inclusive or GammaIncCompInv will panic. GammaIncCompInv should return a +// positive number, but can return 0 even with non-zero y due to underflow. +func GammaIncCompInv(a, y float64) float64 { + return cephes.IgamI(a, y) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/gamma_inc_inv.go b/vendor/gonum.org/v1/gonum/mathext/gamma_inc_inv.go new file mode 100644 index 00000000..650717b0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/gamma_inc_inv.go @@ -0,0 +1,56 @@ +// Derived from SciPy's special/c_misc/gammaincinv.c +// https://github.com/scipy/scipy/blob/master/scipy/special/c_misc/gammaincinv.c + +// 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 mathext + +import ( + "math" + + "gonum.org/v1/gonum/mathext/internal/cephes" +) + +const ( + allowedATol = 1e-306 + allowedRTol = 1e-6 +) + +func gammaInc(x float64, params []float64) float64 { + return cephes.Igam(params[0], x) - params[1] +} + +// gammaIncInv is the inverse of the incomplete Gamma integral. That is, it +// returns x such that: +// Igam(a, x) = y +// The input argument a must be positive and y must be between 0 and 1 +// inclusive or gammaIncInv will panic. gammaIncInv should return a +// positive number, but can return NaN if there is a failure to converge. +func gammaIncInv(a, y float64) float64 { + // For y not small, we just use + // IgamI(a, 1-y) + // (inverse of the complemented incomplete Gamma integral). For y small, + // however, 1-y is about 1, and we lose digits. + if a <= 0 || y <= 0 || y >= 0.25 { + return cephes.IgamI(a, 1-y) + } + + lo := 0.0 + flo := -y + hi := cephes.IgamI(a, 0.75) + fhi := 0.25 - y + + params := []float64{a, y} + + // Also, after we generate a small interval by bisection above, false + // position will do a large step from an interval of width ~1e-4 to ~1e-14 + // in one step (a=10, x=0.05, but similar for other values). + result, bestX, _, errEst := falsePosition(lo, hi, flo, fhi, 2*machEp, 2*machEp, 1e-2*a, gammaInc, params) + if result == fSolveMaxIterations && errEst > allowedATol+allowedRTol*math.Abs(bestX) { + bestX = math.NaN() + } + + return bestX +} diff --git a/vendor/gonum.org/v1/gonum/mathext/gamma_inc_test.go b/vendor/gonum.org/v1/gonum/mathext/gamma_inc_test.go new file mode 100644 index 00000000..03d5f014 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/gamma_inc_test.go @@ -0,0 +1,138 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "math" + "testing" +) + +func TestGammaInc(t *testing.T) { + for i, test := range []struct { + a, x, want float64 + }{ + // Results computed using scipy.special.gamminc + {0, 0, 0}, + {0.0001, 1, 0.99997805936186279}, + {0.001, 0.005, 0.99528424172333985}, + {0.01, 10, 0.99999995718295021}, + {0.1, 10, 0.99999944520142825}, + {0.25, 0.75, 0.89993651328449831}, + {0.5, 0.5, 0.68268949213708596}, + {0.5, 2, 0.95449973610364147}, + {0.75, 2.5, 0.95053039734695643}, + {1, 0.5, 0.39346934028736652}, + {1, 1, 0.63212055882855778}, + {1.5, 0.75, 0.31772966966378746}, + {2.5, 1, 0.15085496391539038}, + {3, 0.05, 2.0067493624397931e-05}, + {3, 20, 0.99999954448504946}, + {5, 50, 1}, + {7, 10, 0.86985857911751696}, + {10, 0.9, 4.2519575433351128e-08}, + {10, 5, 0.031828057306204811}, + {25, 10, 4.6949381426799868e-05}, + } { + if got := GammaInc(test.a, test.x); math.Abs(got-test.want) > 1e-10 { + t.Errorf("test %d GammaInc(%g, %g) failed: got %g want %g", i, test.a, test.x, got, test.want) + } + } +} + +func TestGammaIncComp(t *testing.T) { + for i, test := range []struct { + a, x, want float64 + }{ + // Results computed using scipy.special.gammincc + {0.00001, 0.075, 2.0866541002417804e-05}, + {0.0001, 1, 2.1940638138146658e-05}, + {0.001, 0.005, 0.0047157582766601536}, + {0.01, 0.9, 0.0026263432520514662}, + {0.25, 0.75, 0.10006348671550169}, + {0.5, 0.5, 0.31731050786291404}, + {0.75, 0.25, 0.65343980284081038}, + {0.9, 0.01, 0.98359881081593148}, + {1, 0, 1}, + {1, 0.075, 0.92774348632855297}, + {1, 1, 0.36787944117144233}, + {1, 10, 4.5399929762484861e-05}, + {1, math.Inf(1), 0}, + {3, 20, 4.5551495055892125e-07}, + {5, 10, 0.029252688076961127}, + {10, 3, 0.99889751186988451}, + {50, 25, 0.99999304669475242}, + {100, 10, 1}, + {500, 500, 0.49405285382921321}, + {500, 550, 0.014614408126291296}, + } { + if got := GammaIncComp(test.a, test.x); math.Abs(got-test.want) > 1e-10 { + t.Errorf("test %d GammaIncComp(%g, %g) failed: got %g want %g", i, test.a, test.x, got, test.want) + } + } +} + +func TestGammaIncInv(t *testing.T) { + for i, test := range []struct { + a, x, want float64 + }{ + // Results computed using scipy.special.gammincinv + {0.001, 0.99, 2.4259428385570885e-05}, + {0.01, 0.99, 0.26505255025157959}, + {0.1, 0.5, 0.00059339110446022798}, + {0.2, 0.8, 0.26354363204872067}, + {0.25, 0.5, 0.043673802352873381}, + {0.5, 0.25, 0.050765522133810789}, + {0.5, 0.5, 0.22746821155978625}, + {0.75, 0.25, 0.15340752707472377}, + {1, 0, 0}, + {1, 0.075, 0.077961541469711862}, + {1, 1, math.Inf(1)}, + {2.5, 0.99, 7.5431362346944937}, + {10, 0.5, 9.6687146147141299}, + {25, 0.01, 14.853341349420646}, + {25, 0.99, 38.076945624506337}, + {50, 0.75, 54.570620535040511}, + {100, 0.25, 93.08583383712174}, + {1000, 0.01, 927.90815979664251}, + {1000, 0.99, 1075.0328320864389}, + {10000, 0.5, 9999.6666686420485}, + } { + if got := GammaIncInv(test.a, test.x); math.Abs(got-test.want) > 1e-10 { + t.Errorf("test %d GammaIncInv(%g, %g) failed: got %g want %g", i, test.a, test.x, got, test.want) + } + } +} + +func TestGammaIncCompInv(t *testing.T) { + for i, test := range []struct { + a, x, want float64 + }{ + // Results computed using scipy.special.gamminccinv + {0.001, 0.01, 2.4259428385570885e-05}, + {0.01, 0.01, 0.26505255025158292}, + {0.03, 0.4, 2.316980536227699e-08}, + {0.1, 0.5, 0.00059339110446022798}, + {0.1, 0.75, 5.7917132949696076e-07}, + {0.25, 0.25, 0.26062600197823282}, + {0.5, 0.1, 1.3527717270477047}, + {0.5, 0.5, 0.22746821155978625}, + {0.75, 0.25, 1.0340914067758025}, + {1, 0, math.Inf(1)}, + {1, 0.5, 0.69314718055994529}, + {1, 1, 0}, + {3, 0.75, 1.727299417860519}, + {25, 0.4, 25.945791937289371}, + {25, 0.7, 22.156653488661991}, + {10, 0.5, 9.6687146147141299}, + {100, 0.25, 106.5510925269767}, + {1000, 0.01, 1075.0328320864389}, + {1000, 0.99, 927.90815979664251}, + {10000, 0.5, 9999.6666686420485}, + } { + if got := GammaIncCompInv(test.a, test.x); math.Abs(got-test.want) > 1e-10 { + t.Errorf("test %d GammaIncCompInv(%g, %g) failed: got %g want %g", i, test.a, test.x, got, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amos.go b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amos.go new file mode 100644 index 00000000..2bd74d43 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amos.go @@ -0,0 +1,2154 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package amos + +import ( + "math" + "math/cmplx" +) + +/* +The AMOS functions are included in SLATEC, and the SLATEC guide (http://www.netlib.org/slatec/guide) explicitly states: +"The Library is in the public domain and distributed by the Energy +Science and Technology Software Center." +Mention of AMOS's inclusion in SLATEC goes back at least to this 1985 technical report from Sandia National Labs: http://infoserve.sandia.gov/sand_doc/1985/851018.pdf +*/ + +// math.NaN() are for padding to keep indexing easy. +var imach = []int{-0, 5, 6, 0, 0, 32, 4, 2, 31, 2147483647, 2, 24, -125, 127, 53, -1021, 1023} + +var dmach = []float64{math.NaN(), 2.23E-308, 1.79E-308, 1.11E-16, 2.22E-16, 0.30103000998497009} + +func abs(a int) int { + if a >= 0 { + return a + } + return -a +} + +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 +} + +func Zairy(ZR, ZI float64, ID, KODE int) (AIR, AII float64, NZ int) { + // zairy is adapted from the original Netlib code by Donald Amos. + // http://www.netlib.no/netlib/amos/zairy.f + + // Original comment: + /* + C***BEGIN PROLOGUE ZAIRY + C***DATE WRITTEN 830501 (YYMMDD) + C***REVISION DATE 890801 (YYMMDD) + C***CATEGORY NO. B5K + C***KEYWORDS AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD + C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES + C***PURPOSE TO COMPUTE AIRY FUNCTIONS AI(Z) AND DAI(Z) FOR COMPLEX Z + C***DESCRIPTION + C + C ***A DOUBLE PRECISION ROUTINE*** + C ON KODE=1, ZAIRY COMPUTES THE COMPLEX AIRY FUNCTION AI(Z) OR + C ITS DERIVATIVE DAI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON + C KODE=2, A SCALING OPTION CEXP(ZTA)*AI(Z) OR CEXP(ZTA)* + C DAI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL DECAY IN + C -PI/31.0 FROM THE K BESSEL + C FUNCTIONS BY + C + C AI(Z)=C*SQRT(Z)*K(1/3,ZTA) , DAI(Z)=-C*Z*K(2/3,ZTA) + C C=1.0/(PI*SQRT(3.0)) + C ZTA=(2/3)*Z**(3/2) + C + C WITH THE POWER SERIES FOR CABS(Z)<=1.0. + C + C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- + C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES + C OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF + C THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR), + C THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR + C FLAG IERR=3 IS TRIGGERED WHERE UR=math.Max(dmach[4),1.0D-18) IS + C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. + C ALSO, if THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN + C ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT + C FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE + C LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA + C MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, + C AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE + C PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE + C PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT- + C ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG- + C NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN + C DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN + C EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, + C NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE + C PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER + C MACHINES. + C + C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX + C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT + C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- + C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE + C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), + C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF + C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY + C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN + C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY + C SEVERAL ORDERS OF MAGNITUDE. if ONE COMPONENT IS 10**K LARGER + C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, + C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS + C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER + C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY + C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER + C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE + C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, + C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, + C OR -PI/2+P. + C + C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ + C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF + C COMMERCE, 1955. + C + C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT + C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 + C + C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX + C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- + C 1018, MAY, 1985 + C + C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX + C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. + C MATH. SOFTWARE, 1986 + */ + var AI, CONE, CSQ, CY, S1, S2, TRM1, TRM2, Z, ZTA, Z3 complex128 + var AA, AD, AK, ALIM, ATRM, AZ, AZ3, BK, + CC, CK, COEF, CONEI, CONER, CSQI, CSQR, C1, C2, DIG, + DK, D1, D2, ELIM, FID, FNU, PTR, RL, R1M5, SFAC, STI, STR, + S1I, S1R, S2I, S2R, TOL, TRM1I, TRM1R, TRM2I, TRM2R, TTH, ZEROI, + ZEROR, ZTAI, ZTAR, Z3I, Z3R, ALAZ, BB float64 + var IERR, IFLAG, K, K1, K2, MR, NN int + var tmp complex128 + + // Extra element for padding. + CYR := []float64{math.NaN(), 0} + CYI := []float64{math.NaN(), 0} + + _ = AI + _ = CONE + _ = CSQ + _ = CY + _ = S1 + _ = S2 + _ = TRM1 + _ = TRM2 + _ = Z + _ = ZTA + _ = Z3 + + TTH = 6.66666666666666667E-01 + C1 = 3.55028053887817240E-01 + C2 = 2.58819403792806799E-01 + COEF = 1.83776298473930683E-01 + ZEROR = 0 + ZEROI = 0 + CONER = 1 + CONEI = 0 + + NZ = 0 + if ID < 0 || ID > 1 { + IERR = 1 + } + if KODE < 1 || KODE > 2 { + IERR = 1 + } + if IERR != 0 { + return + } + AZ = cmplx.Abs(complex(ZR, ZI)) + TOL = math.Max(dmach[4], 1.0E-18) + FID = float64(ID) + if AZ > 1.0E0 { + goto Seventy + } + + // POWER SERIES FOR CABS(Z)<=1. + S1R = CONER + S1I = CONEI + S2R = CONER + S2I = CONEI + if AZ < TOL { + goto OneSeventy + } + AA = AZ * AZ + if AA < TOL/AZ { + goto Forty + } + TRM1R = CONER + TRM1I = CONEI + TRM2R = CONER + TRM2I = CONEI + ATRM = 1.0E0 + STR = ZR*ZR - ZI*ZI + STI = ZR*ZI + ZI*ZR + Z3R = STR*ZR - STI*ZI + Z3I = STR*ZI + STI*ZR + AZ3 = AZ * AA + AK = 2.0E0 + FID + BK = 3.0E0 - FID - FID + CK = 4.0E0 - FID + DK = 3.0E0 + FID + FID + D1 = AK * DK + D2 = BK * CK + AD = math.Min(D1, D2) + AK = 24.0E0 + 9.0E0*FID + BK = 30.0E0 - 9.0E0*FID + for K = 1; K <= 25; K++ { + STR = (TRM1R*Z3R - TRM1I*Z3I) / D1 + TRM1I = (TRM1R*Z3I + TRM1I*Z3R) / D1 + TRM1R = STR + S1R = S1R + TRM1R + S1I = S1I + TRM1I + STR = (TRM2R*Z3R - TRM2I*Z3I) / D2 + TRM2I = (TRM2R*Z3I + TRM2I*Z3R) / D2 + TRM2R = STR + S2R = S2R + TRM2R + S2I = S2I + TRM2I + ATRM = ATRM * AZ3 / AD + D1 = D1 + AK + D2 = D2 + BK + AD = math.Min(D1, D2) + if ATRM < TOL*AD { + goto Forty + } + AK = AK + 18.0E0 + BK = BK + 18.0E0 + } +Forty: + if ID == 1 { + goto Fifty + } + AIR = S1R*C1 - C2*(ZR*S2R-ZI*S2I) + AII = S1I*C1 - C2*(ZR*S2I+ZI*S2R) + if KODE == 1 { + return + } + tmp = cmplx.Sqrt(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + ZTAR = TTH * (ZR*STR - ZI*STI) + ZTAI = TTH * (ZR*STI + ZI*STR) + tmp = cmplx.Exp(complex(ZTAR, ZTAI)) + STR = real(tmp) + STI = imag(tmp) + PTR = AIR*STR - AII*STI + AII = AIR*STI + AII*STR + AIR = PTR + return + +Fifty: + AIR = -S2R * C2 + AII = -S2I * C2 + if AZ <= TOL { + goto Sixty + } + STR = ZR*S1R - ZI*S1I + STI = ZR*S1I + ZI*S1R + CC = C1 / (1.0E0 + FID) + AIR = AIR + CC*(STR*ZR-STI*ZI) + AII = AII + CC*(STR*ZI+STI*ZR) + +Sixty: + if KODE == 1 { + return + } + tmp = cmplx.Sqrt(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + ZTAR = TTH * (ZR*STR - ZI*STI) + ZTAI = TTH * (ZR*STI + ZI*STR) + tmp = cmplx.Exp(complex(ZTAR, ZTAI)) + STR = real(tmp) + STI = imag(tmp) + PTR = STR*AIR - STI*AII + AII = STR*AII + STI*AIR + AIR = PTR + return + + // CASE FOR CABS(Z)>1.0. +Seventy: + FNU = (1.0E0 + FID) / 3.0E0 + + /* + SET PARAMETERS RELATED TO MACHINE CONSTANTS. + TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0D-18. + ELIM IS THE APPROXIMATE EXPONENTIAL OVER-&&UNDERFLOW LIMIT. + EXP(-ELIM)EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR + UNDERFLOW&&OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. + RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LA>=Z. + DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). + */ + K1 = imach[15] + K2 = imach[16] + R1M5 = dmach[5] + + K = min(abs(K1), abs(K2)) + ELIM = 2.303E0 * (float64(K)*R1M5 - 3.0E0) + K1 = imach[14] - 1 + AA = R1M5 * float64(K1) + DIG = math.Min(AA, 18.0E0) + AA = AA * 2.303E0 + ALIM = ELIM + math.Max(-AA, -41.45E0) + RL = 1.2E0*DIG + 3.0E0 + ALAZ = math.Log(AZ) + + // TEST FOR PROPER RANGE. + AA = 0.5E0 / TOL + BB = float64(float32(imach[9])) * 0.5E0 + AA = math.Min(AA, BB) + AA = math.Pow(AA, TTH) + if AZ > AA { + goto TwoSixty + } + AA = math.Sqrt(AA) + if AZ > AA { + IERR = 3 + } + tmp = cmplx.Sqrt(complex(ZR, ZI)) + CSQR = real(tmp) + CSQI = imag(tmp) + ZTAR = TTH * (ZR*CSQR - ZI*CSQI) + ZTAI = TTH * (ZR*CSQI + ZI*CSQR) + + // RE(ZTA)<=0 WHEN RE(Z)<0, ESPECIALLY WHEN IM(Z) IS SMALL. + IFLAG = 0 + SFAC = 1.0E0 + AK = ZTAI + if ZR >= 0.0E0 { + goto Eighty + } + BK = ZTAR + CK = -math.Abs(BK) + ZTAR = CK + ZTAI = AK + +Eighty: + if ZI != 0.0E0 { + goto Ninety + } + if ZR > 0.0E0 { + goto Ninety + } + ZTAR = 0.0E0 + ZTAI = AK +Ninety: + AA = ZTAR + if AA >= 0.0E0 && ZR > 0.0E0 { + goto OneTen + } + if KODE == 2 { + goto OneHundred + } + + // OVERFLOW TEST. + if AA > (-ALIM) { + goto OneHundred + } + AA = -AA + 0.25E0*ALAZ + IFLAG = 1 + SFAC = TOL + if AA > ELIM { + goto TwoSeventy + } + +OneHundred: + // CBKNU AND CACON return EXP(ZTA)*K(FNU,ZTA) ON KODE=2. + MR = 1 + if ZI < 0.0E0 { + MR = -1 + } + ZTAR, ZTAI, FNU, KODE, MR, _, CYR, CYI, NN, RL, TOL, ELIM, ALIM = Zacai(ZTAR, ZTAI, FNU, KODE, MR, 1, CYR, CYI, NN, RL, TOL, ELIM, ALIM) + if NN < 0 { + goto TwoEighty + } + NZ = NZ + NN + goto OneThirty + +OneTen: + if KODE == 2 { + goto OneTwenty + } + + // UNDERFLOW TEST. + if AA < ALIM { + goto OneTwenty + } + AA = -AA - 0.25E0*ALAZ + IFLAG = 2 + SFAC = 1.0E0 / TOL + if AA < (-ELIM) { + goto TwoTen + } +OneTwenty: + ZTAR, ZTAI, FNU, KODE, _, CYR, CYI, NZ, TOL, ELIM, ALIM = Zbknu(ZTAR, ZTAI, FNU, KODE, 1, CYR, CYI, NZ, TOL, ELIM, ALIM) + +OneThirty: + S1R = CYR[1] * COEF + S1I = CYI[1] * COEF + if IFLAG != 0 { + goto OneFifty + } + if ID == 1 { + goto OneFourty + } + AIR = CSQR*S1R - CSQI*S1I + AII = CSQR*S1I + CSQI*S1R + return +OneFourty: + AIR = -(ZR*S1R - ZI*S1I) + AII = -(ZR*S1I + ZI*S1R) + return +OneFifty: + S1R = S1R * SFAC + S1I = S1I * SFAC + if ID == 1 { + goto OneSixty + } + STR = S1R*CSQR - S1I*CSQI + S1I = S1R*CSQI + S1I*CSQR + S1R = STR + AIR = S1R / SFAC + AII = S1I / SFAC + return +OneSixty: + STR = -(S1R*ZR - S1I*ZI) + S1I = -(S1R*ZI + S1I*ZR) + S1R = STR + AIR = S1R / SFAC + AII = S1I / SFAC + return +OneSeventy: + AA = 1.0E+3 * dmach[1] + S1R = ZEROR + S1I = ZEROI + if ID == 1 { + goto OneNinety + } + if AZ <= AA { + goto OneEighty + } + S1R = C2 * ZR + S1I = C2 * ZI +OneEighty: + AIR = C1 - S1R + AII = -S1I + return +OneNinety: + AIR = -C2 + AII = 0.0E0 + AA = math.Sqrt(AA) + if AZ <= AA { + goto TwoHundred + } + S1R = 0.5E0 * (ZR*ZR - ZI*ZI) + S1I = ZR * ZI +TwoHundred: + AIR = AIR + C1*S1R + AII = AII + C1*S1I + return +TwoTen: + NZ = 1 + AIR = ZEROR + AII = ZEROI + return +TwoSeventy: + NZ = 0 + IERR = 2 + return +TwoEighty: + if NN == (-1) { + goto TwoSeventy + } + NZ = 0 + IERR = 5 + return +TwoSixty: + IERR = 4 + NZ = 0 + return +} + +// sbknu computes the k bessel function in the right half z plane. +func Zbknu(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL, ELIM, ALIM float64) (ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout, ELIMout, ALIMout float64) { + /* Old dimension comment. + DIMENSION YR(N), YI(N), CC(8), CSSR(3), CSRR(3), BRY(3), CYR(2), + * CYI(2) + */ + + // TODO(btracey): Find which of these are inputs/outputs/both and clean up + // the function call. + // YR and YI have length n (but n+1 with better indexing) + var AA, AK, ASCLE, A1, A2, BB, BK, CAZ, + CBI, CBR, CCHI, CCHR, CKI, CKR, COEFI, COEFR, CONEI, CONER, + CRSCR, CSCLR, CSHI, CSHR, CSI, CSR, CTWOR, + CZEROI, CZEROR, CZI, CZR, DNU, DNU2, DPI, ETEST, FC, FHS, + FI, FK, FKS, FMUI, FMUR, FPI, FR, G1, G2, HPI, PI, PR, PTI, + PTR, P1I, P1R, P2I, P2M, P2R, QI, QR, RAK, RCAZ, RTHPI, RZI, + RZR, R1, S, SMUI, SMUR, SPI, STI, STR, S1I, S1R, S2I, S2R, TM, + TTH, T1, T2, ELM, CELMR, ZDR, ZDI, AS, ALAS, HELIM float64 + + var I, IFLAG, INU, K, KFLAG, KK, KMAX, KODED, IDUM, J, IC, INUB, NW int + + var sinh, cosh complex128 + //var sin, cos float64 + + var tmp, p complex128 + var CSSR, CSRR, BRY [4]float64 + var CYR, CYI [3]float64 + + KMAX = 30 + CZEROR = 0 + CZEROI = 0 + CONER = 1 + CONEI = 0 + CTWOR = 2 + R1 = 2 + + DPI = 3.14159265358979324E0 + RTHPI = 1.25331413731550025E0 + SPI = 1.90985931710274403E0 + HPI = 1.57079632679489662E0 + FPI = 1.89769999331517738E0 + TTH = 6.66666666666666666E-01 + + CC := [9]float64{math.NaN(), 5.77215664901532861E-01, -4.20026350340952355E-02, + -4.21977345555443367E-02, 7.21894324666309954E-03, + -2.15241674114950973E-04, -2.01348547807882387E-05, + 1.13302723198169588E-06, 6.11609510448141582E-09} + + CAZ = cmplx.Abs(complex(ZR, ZI)) + CSCLR = 1.0E0 / TOL + CRSCR = TOL + CSSR[1] = CSCLR + CSSR[2] = 1.0E0 + CSSR[3] = CRSCR + CSRR[1] = CRSCR + CSRR[2] = 1.0E0 + CSRR[3] = CSCLR + BRY[1] = 1.0E+3 * dmach[1] / TOL + BRY[2] = 1.0E0 / BRY[1] + BRY[3] = dmach[2] + NZ = 0 + IFLAG = 0 + KODED = KODE + RCAZ = 1.0E0 / CAZ + STR = ZR * RCAZ + STI = -ZI * RCAZ + RZR = (STR + STR) * RCAZ + RZI = (STI + STI) * RCAZ + INU = int(float32(FNU + 0.5)) + DNU = FNU - float64(INU) + if math.Abs(DNU) == 0.5E0 { + goto OneTen + } + DNU2 = 0.0E0 + if math.Abs(DNU) > TOL { + DNU2 = DNU * DNU + } + if CAZ > R1 { + goto OneTen + } + + // SERIES FOR CABS(Z)<=R1. + FC = 1.0E0 + tmp = cmplx.Log(complex(RZR, RZI)) + SMUR = real(tmp) + SMUI = imag(tmp) + FMUR = SMUR * DNU + FMUI = SMUI * DNU + tmp = complex(FMUR, FMUI) + sinh = cmplx.Sinh(tmp) + cosh = cmplx.Cosh(tmp) + CSHR = real(sinh) + CSHI = imag(sinh) + CCHR = real(cosh) + CCHI = imag(cosh) + if DNU == 0.0E0 { + goto Ten + } + FC = DNU * DPI + FC = FC / math.Sin(FC) + SMUR = CSHR / DNU + SMUI = CSHI / DNU +Ten: + A2 = 1.0E0 + DNU + + // GAM(1-Z)*GAM(1+Z)=PI*Z/SIN(PI*Z), T1=1/GAM(1-DNU), T2=1/GAM(1+DNU). + T2 = math.Exp(-dgamln(A2, IDUM)) + T1 = 1.0E0 / (T2 * FC) + if math.Abs(DNU) > 0.1E0 { + goto Forty + } + + // SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU). + AK = 1.0E0 + S = CC[1] + for K = 2; K <= 8; K++ { + AK = AK * DNU2 + TM = CC[K] * AK + S = S + TM + if math.Abs(TM) < TOL { + goto Thirty + } + } +Thirty: + G1 = -S + goto Fifty +Forty: + G1 = (T1 - T2) / (DNU + DNU) +Fifty: + G2 = (T1 + T2) * 0.5E0 + FR = FC * (CCHR*G1 + SMUR*G2) + FI = FC * (CCHI*G1 + SMUI*G2) + tmp = cmplx.Exp(complex(FMUR, FMUI)) + STR = real(tmp) + STI = imag(tmp) + PR = 0.5E0 * STR / T2 + PI = 0.5E0 * STI / T2 + tmp = complex(0.5, 0) / complex(STR, STI) + PTR = real(tmp) + PTI = imag(tmp) + QR = PTR / T1 + QI = PTI / T1 + S1R = FR + S1I = FI + S2R = PR + S2I = PI + AK = 1.0E0 + A1 = 1.0E0 + CKR = CONER + CKI = CONEI + BK = 1.0E0 - DNU2 + if INU > 0 || N > 1 { + goto Eighty + } + + // GENERATE K(FNU,Z), 0.0E0 <= FNU < 0.5E0 AND N=1. + if CAZ < TOL { + goto Seventy + } + tmp = complex(ZR, ZI) * complex(ZR, ZI) + CZR = real(tmp) + CZI = imag(tmp) + CZR = 0.25E0 * CZR + CZI = 0.25E0 * CZI + T1 = 0.25E0 * CAZ * CAZ +Sixty: + FR = (FR*AK + PR + QR) / BK + FI = (FI*AK + PI + QI) / BK + STR = 1.0E0 / (AK - DNU) + PR = PR * STR + PI = PI * STR + STR = 1.0E0 / (AK + DNU) + QR = QR * STR + QI = QI * STR + STR = CKR*CZR - CKI*CZI + RAK = 1.0E0 / AK + CKI = (CKR*CZI + CKI*CZR) * RAK + CKR = STR * RAK + S1R = CKR*FR - CKI*FI + S1R + S1I = CKR*FI + CKI*FR + S1I + A1 = A1 * T1 * RAK + BK = BK + AK + AK + 1.0E0 + AK = AK + 1.0E0 + if A1 > TOL { + goto Sixty + } +Seventy: + YR[1] = S1R + YI[1] = S1I + if KODED == 1 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + tmp = cmplx.Exp(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = complex(S1R, S1I) * complex(STR, STI) + YR[1] = real(tmp) + YI[1] = imag(tmp) + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + + // GENERATE K(DNU,Z) AND K(DNU+1,Z) FOR FORWARD RECURRENCE. +Eighty: + if CAZ < TOL { + goto OneHundred + } + tmp = complex(ZR, ZI) * complex(ZR, ZI) + CZR = real(tmp) + CZI = imag(tmp) + CZR = 0.25E0 * CZR + CZI = 0.25E0 * CZI + T1 = 0.25E0 * CAZ * CAZ +Ninety: + FR = (FR*AK + PR + QR) / BK + FI = (FI*AK + PI + QI) / BK + STR = 1.0E0 / (AK - DNU) + PR = PR * STR + PI = PI * STR + STR = 1.0E0 / (AK + DNU) + QR = QR * STR + QI = QI * STR + STR = CKR*CZR - CKI*CZI + RAK = 1.0E0 / AK + CKI = (CKR*CZI + CKI*CZR) * RAK + CKR = STR * RAK + S1R = CKR*FR - CKI*FI + S1R + S1I = CKR*FI + CKI*FR + S1I + STR = PR - FR*AK + STI = PI - FI*AK + S2R = CKR*STR - CKI*STI + S2R + S2I = CKR*STI + CKI*STR + S2I + A1 = A1 * T1 * RAK + BK = BK + AK + AK + 1.0E0 + AK = AK + 1.0E0 + if A1 > TOL { + goto Ninety + } +OneHundred: + KFLAG = 2 + A1 = FNU + 1.0E0 + AK = A1 * math.Abs(SMUR) + if AK > ALIM { + KFLAG = 3 + } + STR = CSSR[KFLAG] + P2R = S2R * STR + P2I = S2I * STR + tmp = complex(P2R, P2I) * complex(RZR, RZI) + S2R = real(tmp) + S2I = imag(tmp) + S1R = S1R * STR + S1I = S1I * STR + if KODED == 1 { + goto TwoTen + } + tmp = cmplx.Exp(complex(ZR, ZI)) + FR = real(tmp) + FI = imag(tmp) + tmp = complex(S1R, S1I) * complex(FR, FI) + S1R = real(tmp) + S1I = imag(tmp) + tmp = complex(S2R, S2I) * complex(FR, FI) + S2R = real(tmp) + S2I = imag(tmp) + goto TwoTen + + // IFLAG=0 MEANS NO UNDERFLOW OCCURRED + // IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH + // KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD RECURSION +OneTen: + tmp = cmplx.Sqrt(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = complex(RTHPI, CZEROI) / complex(STR, STI) + COEFR = real(tmp) + COEFI = imag(tmp) + KFLAG = 2 + if KODED == 2 { + goto OneTwenty + } + if ZR > ALIM { + goto TwoNinety + } + + STR = math.Exp(-ZR) * CSSR[KFLAG] + //sin, cos = math.Sincos(ZI) + STI = -STR * math.Sin(ZI) + STR = STR * math.Cos(ZI) + tmp = complex(COEFR, COEFI) * complex(STR, STI) + COEFR = real(tmp) + COEFI = imag(tmp) +OneTwenty: + if math.Abs(DNU) == 0.5E0 { + goto ThreeHundred + } + // MILLER ALGORITHM FOR CABS(Z)>R1. + AK = math.Cos(DPI * DNU) + AK = math.Abs(AK) + if AK == CZEROR { + goto ThreeHundred + } + FHS = math.Abs(0.25E0 - DNU2) + if FHS == CZEROR { + goto ThreeHundred + } + + // COMPUTE R2=F(E). if CABS(Z)>=R2, USE FORWARD RECURRENCE TO + // DETERMINE THE BACKWARD INDEX K. R2=F(E) IS A STRAIGHT LINE ON + // 12<=E<=60. E IS COMPUTED FROM 2**(-E)=B**(1-I1MACH(14))= + // TOL WHERE B IS THE BASE OF THE ARITHMETIC. + T1 = float64(imach[14] - 1) + T1 = T1 * dmach[5] * 3.321928094E0 + T1 = math.Max(T1, 12.0E0) + T1 = math.Min(T1, 60.0E0) + T2 = TTH*T1 - 6.0E0 + if ZR != 0.0E0 { + goto OneThirty + } + T1 = HPI + goto OneFourty +OneThirty: + T1 = math.Atan(ZI / ZR) + T1 = math.Abs(T1) +OneFourty: + if T2 > CAZ { + goto OneSeventy + } + // FORWARD RECURRENCE LOOP WHEN CABS(Z)>=R2. + ETEST = AK / (DPI * CAZ * TOL) + FK = CONER + if ETEST < CONER { + goto OneEighty + } + FKS = CTWOR + CKR = CAZ + CAZ + CTWOR + P1R = CZEROR + P2R = CONER + for I = 1; I <= KMAX; I++ { + AK = FHS / FKS + CBR = CKR / (FK + CONER) + PTR = P2R + P2R = CBR*P2R - P1R*AK + P1R = PTR + CKR = CKR + CTWOR + FKS = FKS + FK + FK + CTWOR + FHS = FHS + FK + FK + FK = FK + CONER + STR = math.Abs(P2R) * FK + if ETEST < STR { + goto OneSixty + } + } + goto ThreeTen +OneSixty: + FK = FK + SPI*T1*math.Sqrt(T2/CAZ) + FHS = math.Abs(0.25 - DNU2) + goto OneEighty +OneSeventy: + // COMPUTE BACKWARD INDEX K FOR CABS(Z) 0 || N > 1 { + goto TwoHundred + } + ZDR = ZR + ZDI = ZI + if IFLAG == 1 { + goto TwoSeventy + } + goto TwoFourty +TwoHundred: + // COMPUTE P1/P2=(P1/CABS(P2)*CONJG(P2)/CABS(P2) FOR SCALING. + TM = cmplx.Abs(complex(P2R, P2I)) + PTR = 1.0E0 / TM + P1R = P1R * PTR + P1I = P1I * PTR + P2R = P2R * PTR + P2I = -P2I * PTR + tmp = complex(P1R, P1I) * complex(P2R, P2I) + PTR = real(tmp) + PTI = imag(tmp) + STR = DNU + 0.5E0 - PTR + STI = -PTI + tmp = complex(STR, STI) / complex(ZR, ZI) + STR = real(tmp) + STI = imag(tmp) + STR = STR + 1.0E0 + tmp = complex(STR, STI) * complex(S1R, S1I) + S2R = real(tmp) + S2I = imag(tmp) + + // FORWARD RECURSION ON THE THREE TERM RECURSION WITH RELATION WITH + // SCALING NEAR EXPONENT EXTREMES ON KFLAG=1 OR KFLAG=3 +TwoTen: + STR = DNU + 1.0E0 + CKR = STR * RZR + CKI = STR * RZI + if N == 1 { + INU = INU - 1 + } + if INU > 0 { + goto TwoTwenty + } + if N > 1 { + goto TwoFifteen + } + S1R = S2R + S1I = S2I +TwoFifteen: + ZDR = ZR + ZDI = ZI + if IFLAG == 1 { + goto TwoSeventy + } + goto TwoFourty +TwoTwenty: + INUB = 1 + if IFLAG == 1 { + goto TwoSixtyOne + } +TwoTwentyFive: + P1R = CSRR[KFLAG] + ASCLE = BRY[KFLAG] + for I = INUB; I <= INU; I++ { + STR = S2R + STI = S2I + S2R = CKR*STR - CKI*STI + S1R + S2I = CKR*STI + CKI*STR + S1I + S1R = STR + S1I = STI + CKR = CKR + RZR + CKI = CKI + RZI + if KFLAG >= 3 { + continue + } + P2R = S2R * P1R + P2I = S2I * P1R + STR = math.Abs(P2R) + STI = math.Abs(P2I) + P2M = math.Max(STR, STI) + if P2M <= ASCLE { + continue + } + KFLAG = KFLAG + 1 + ASCLE = BRY[KFLAG] + S1R = S1R * P1R + S1I = S1I * P1R + S2R = P2R + S2I = P2I + STR = CSSR[KFLAG] + S1R = S1R * STR + S1I = S1I * STR + S2R = S2R * STR + S2I = S2I * STR + P1R = CSRR[KFLAG] + } + if N != 1 { + goto TwoFourty + } + S1R = S2R + S1I = S2I +TwoFourty: + STR = CSRR[KFLAG] + YR[1] = S1R * STR + YI[1] = S1I * STR + if N == 1 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + YR[2] = S2R * STR + YI[2] = S2I * STR + if N == 2 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + KK = 2 +TwoFifty: + KK = KK + 1 + if KK > N { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + P1R = CSRR[KFLAG] + ASCLE = BRY[KFLAG] + for I = KK; I <= N; I++ { + P2R = S2R + P2I = S2I + S2R = CKR*P2R - CKI*P2I + S1R + S2I = CKI*P2R + CKR*P2I + S1I + S1R = P2R + S1I = P2I + CKR = CKR + RZR + CKI = CKI + RZI + P2R = S2R * P1R + P2I = S2I * P1R + YR[I] = P2R + YI[I] = P2I + if KFLAG >= 3 { + continue + } + STR = math.Abs(P2R) + STI = math.Abs(P2I) + P2M = math.Max(STR, STI) + if P2M <= ASCLE { + continue + } + KFLAG = KFLAG + 1 + ASCLE = BRY[KFLAG] + S1R = S1R * P1R + S1I = S1I * P1R + S2R = P2R + S2I = P2I + STR = CSSR[KFLAG] + S1R = S1R * STR + S1I = S1I * STR + S2R = S2R * STR + S2I = S2I * STR + P1R = CSRR[KFLAG] + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + + // IFLAG=1 CASES, FORWARD RECURRENCE ON SCALED VALUES ON UNDERFLOW. +TwoSixtyOne: + HELIM = 0.5E0 * ELIM + ELM = math.Exp(-ELIM) + CELMR = ELM + ASCLE = BRY[1] + ZDR = ZR + ZDI = ZI + IC = -1 + J = 2 + for I = 1; I <= INU; I++ { + STR = S2R + STI = S2I + S2R = STR*CKR - STI*CKI + S1R + S2I = STI*CKR + STR*CKI + S1I + S1R = STR + S1I = STI + CKR = CKR + RZR + CKI = CKI + RZI + AS = cmplx.Abs(complex(S2R, S2I)) + ALAS = math.Log(AS) + P2R = -ZDR + ALAS + if P2R < (-ELIM) { + goto TwoSixtyThree + } + tmp = cmplx.Log(complex(S2R, S2I)) + STR = real(tmp) + STI = imag(tmp) + P2R = -ZDR + STR + P2I = -ZDI + STI + P2M = math.Exp(P2R) / TOL + // sin, cos = math.Sincos(P2I) + P1R = P2M * math.Cos(P2I) + P1I = P2M * math.Sin(P2I) + p = complex(P1R, P1I) + NW = Zuchk(p, ASCLE, TOL) + if NW != 0 { + goto TwoSixtyThree + } + J = 3 - J + CYR[J] = P1R + CYI[J] = P1I + if IC == (I - 1) { + goto TwoSixtyFour + } + IC = I + continue + TwoSixtyThree: + if ALAS < HELIM { + continue + } + ZDR = ZDR - ELIM + S1R = S1R * CELMR + S1I = S1I * CELMR + S2R = S2R * CELMR + S2I = S2I * CELMR + } + if N != 1 { + goto TwoSeventy + } + S1R = S2R + S1I = S2I + goto TwoSeventy +TwoSixtyFour: + KFLAG = 1 + INUB = I + 1 + S2R = CYR[J] + S2I = CYI[J] + J = 3 - J + S1R = CYR[J] + S1I = CYI[J] + if INUB <= INU { + goto TwoTwentyFive + } + if N != 1 { + goto TwoFourty + } + S1R = S2R + S1I = S2I + goto TwoFourty +TwoSeventy: + YR[1] = S1R + YI[1] = S1I + if N == 1 { + goto TwoEighty + } + YR[2] = S2R + YI[2] = S2I +TwoEighty: + ASCLE = BRY[1] + ZDR, ZDI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM = Zkscl(ZDR, ZDI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM) + INU = N - NZ + if INU <= 0 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + KK = NZ + 1 + S1R = YR[KK] + S1I = YI[KK] + YR[KK] = S1R * CSRR[1] + YI[KK] = S1I * CSRR[1] + if INU == 1 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + KK = NZ + 2 + S2R = YR[KK] + S2I = YI[KK] + YR[KK] = S2R * CSRR[1] + YI[KK] = S2I * CSRR[1] + if INU == 2 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + T2 = FNU + float64(float32(KK-1)) + CKR = T2 * RZR + CKI = T2 * RZI + KFLAG = 1 + goto TwoFifty +TwoNinety: + + // SCALE BY math.Exp(Z), IFLAG = 1 CASES. + + KODED = 2 + IFLAG = 1 + KFLAG = 2 + goto OneTwenty + + // FNU=HALF ODD INTEGER CASE, DNU=-0.5 +ThreeHundred: + S1R = COEFR + S1I = COEFI + S2R = COEFR + S2I = COEFI + goto TwoTen + +ThreeTen: + NZ = -2 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM +} + +// SET K FUNCTIONS TO ZERO ON UNDERFLOW, CONTINUE RECURRENCE +// ON SCALED FUNCTIONS UNTIL TWO MEMBERS COME ON SCALE, THEN +// return WITH MIN(NZ+2,N) VALUES SCALED BY 1/TOL. +func Zkscl(ZRR, ZRI, FNU float64, N int, YR, YI []float64, NZ int, RZR, RZI, ASCLE, TOL, ELIM float64) ( + ZRRout, ZRIout, FNUout float64, Nout int, YRout, YIout []float64, NZout int, RZRout, RZIout, ASCLEout, TOLout, ELIMout float64) { + var ACS, AS, CKI, CKR, CSI, CSR, FN, STR, S1I, S1R, S2I, + S2R, ZEROI, ZEROR, ZDR, ZDI, CELMR, ELM, HELIM, ALAS float64 + + var I, IC, KK, NN, NW int + var tmp, c complex128 + var CYR, CYI [3]float64 + var sin, cos float64 + + // DIMENSION YR(N), YI(N), CYR(2), CYI(2) + ZEROR = 0 + ZEROI = 0 + NZ = 0 + IC = 0 + NN = min(2, N) + for I = 1; I <= NN; I++ { + S1R = YR[I] + S1I = YI[I] + CYR[I] = S1R + CYI[I] = S1I + AS = cmplx.Abs(complex(S1R, S1I)) + ACS = -ZRR + math.Log(AS) + NZ = NZ + 1 + YR[I] = ZEROR + YI[I] = ZEROI + if ACS < (-ELIM) { + continue + } + + tmp = cmplx.Log(complex(S1R, S1I)) + CSR = real(tmp) + CSI = imag(tmp) + CSR = CSR - ZRR + CSI = CSI - ZRI + STR = math.Exp(CSR) / TOL + // sin, cos = math.Sincos(CSI) + CSR = STR * math.Cos(CSI) + CSI = STR * math.Sin(CSI) + c = complex(CSR, CSI) + NW = Zuchk(c, ASCLE, TOL) + if NW != 0 { + continue + } + YR[I] = CSR + YI[I] = CSI + IC = I + NZ = NZ - 1 + } + if N == 1 { + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM + } + if IC > 1 { + goto Twenty + } + YR[1] = ZEROR + YI[1] = ZEROI + NZ = 2 +Twenty: + if N == 2 { + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM + } + if NZ == 0 { + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM + } + FN = FNU + 1.0E0 + CKR = FN * RZR + CKI = FN * RZI + S1R = CYR[1] + S1I = CYI[1] + S2R = CYR[2] + S2I = CYI[2] + HELIM = 0.5E0 * ELIM + ELM = math.Exp(-ELIM) + CELMR = ELM + ZDR = ZRR + ZDI = ZRI + + // FIND TWO CONSECUTIVE Y VALUES ON SCALE. SCALE RECURRENCE IF + // S2 GETS LARGER THAN EXP(ELIM/2) + for I = 3; I <= N; I++ { + KK = I + CSR = S2R + CSI = S2I + S2R = CKR*CSR - CKI*CSI + S1R + S2I = CKI*CSR + CKR*CSI + S1I + S1R = CSR + S1I = CSI + CKR = CKR + RZR + CKI = CKI + RZI + AS = cmplx.Abs(complex(S2R, S2I)) + ALAS = math.Log(AS) + ACS = -ZDR + ALAS + NZ = NZ + 1 + YR[I] = ZEROR + YI[I] = ZEROI + if ACS < (-ELIM) { + goto TwentyFive + } + tmp = cmplx.Log(complex(S2R, S2I)) + CSR = real(tmp) + CSI = imag(tmp) + CSR = CSR - ZDR + CSI = CSI - ZDI + STR = math.Exp(CSR) / TOL + sin, cos = math.Sincos(CSI) + CSR = STR * cos + CSI = STR * sin + c = complex(CSR, CSI) + NW = Zuchk(c, ASCLE, TOL) + if NW != 0 { + goto TwentyFive + } + YR[I] = CSR + YI[I] = CSI + NZ = NZ - 1 + if IC == KK-1 { + goto Forty + } + IC = KK + continue + TwentyFive: + if ALAS < HELIM { + continue + } + ZDR = ZDR - ELIM + S1R = S1R * CELMR + S1I = S1I * CELMR + S2R = S2R * CELMR + S2I = S2I * CELMR + } + NZ = N + if IC == N { + NZ = N - 1 + } + goto FourtyFive +Forty: + NZ = KK - 2 +FourtyFive: + for I = 1; I <= NZ; I++ { + YR[I] = ZEROR + YI[I] = ZEROI + } + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM +} + +// Zuchk tests whether the magnitude of the real or imaginary part would +// underflow when y is scaled by tol. +// +// y enters as a scaled quantity whose magnitude is greater than +// 1e3 + 3*dmach(1)/tol +// y is accepted if the underflow is at least one precision below the magnitude +// of the largest component. Otherwise an underflow is assumed as the phase angle +// does not have sufficient accuracy. +func Zuchk(y complex128, scale, tol float64) int { + absR := math.Abs(real(y)) + absI := math.Abs(imag(y)) + minAbs := math.Min(absR, absI) + if minAbs > scale { + return 0 + } + maxAbs := math.Max(absR, absI) + minAbs /= tol + if maxAbs < minAbs { + return 1 + } + return 0 +} + +// ZACAI APPLIES THE ANALYTIC CONTINUATION FORMULA +// +// K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN) +// MP=PI*MR*CMPLX(0.0,1.0) +// +// TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT +// HALF Z PLANE FOR USE WITH ZAIRY WHERE FNU=1/3 OR 2/3 AND N=1. +// ZACAI IS THE SAME AS ZACON WITH THE PARTS FOR LARGER ORDERS AND +// RECURRENCE REMOVED. A RECURSIVE CALL TO ZACON CAN RESULT if ZACON +// IS CALLED FROM ZAIRY. +func Zacai(ZR, ZI, FNU float64, KODE, MR, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, MRout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { + var ARG, ASCLE, AZ, CSGNR, CSGNI, CSPNR, + CSPNI, C1R, C1I, C2R, C2I, DFNU, FMR, PI, + SGN, YY, ZNR, ZNI float64 + var INU, IUF, NN, NW int + var zn, c1, c2, z complex128 + var y []complex128 + //var sin, cos float64 + + CYR := []float64{math.NaN(), 0, 0} + CYI := []float64{math.NaN(), 0, 0} + + PI = math.Pi + NZ = 0 + ZNR = -ZR + ZNI = -ZI + AZ = cmplx.Abs(complex(ZR, ZI)) + NN = N + DFNU = FNU + float64(float32(N-1)) + if AZ <= 2.0E0 { + goto Ten + } + if AZ*AZ*0.25 > DFNU+1.0E0 { + goto Twenty + } +Ten: + // POWER SERIES FOR THE I FUNCTION. + z = complex(ZNR, ZNI) + y = make([]complex128, len(YR)) + for i, v := range YR { + y[i] = complex(v, YI[i]) + } + NW = Zseri(z, FNU, KODE, NN, y[1:], TOL, ELIM, ALIM) + for i, v := range y { + YR[i] = real(v) + YI[i] = imag(v) + } + goto Forty +Twenty: + if AZ < RL { + goto Thirty + } + // ASYMPTOTIC EXPANSION FOR LARGE Z FOR THE I FUNCTION. + ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM, ALIM = Zasyi(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM, ALIM) + if NW < 0 { + goto Eighty + } + goto Forty +Thirty: + // MILLER ALGORITHM NORMALIZED BY THE SERIES FOR THE I FUNCTION + ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL = Zmlri(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL) + if NW < 0 { + goto Eighty + } +Forty: + // ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION. + ZNR, ZNI, FNU, KODE, _, CYR, CYI, NW, TOL, ELIM, ALIM = Zbknu(ZNR, ZNI, FNU, KODE, 1, CYR, CYI, NW, TOL, ELIM, ALIM) + if NW != 0 { + goto Eighty + } + FMR = float64(float32(MR)) + SGN = -math.Copysign(PI, FMR) + CSGNR = 0.0E0 + CSGNI = SGN + if KODE == 1 { + goto Fifty + } + YY = -ZNI + //sin, cos = math.Sincos(YY) + CSGNR = -CSGNI * math.Sin(YY) + CSGNI = CSGNI * math.Cos(YY) +Fifty: + // CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE + // WHEN FNU IS LARGE + INU = int(float32(FNU)) + ARG = (FNU - float64(float32(INU))) * SGN + //sin, cos = math.Sincos(ARG) + CSPNR = math.Cos(ARG) + CSPNI = math.Sin(ARG) + if INU%2 == 0 { + goto Sixty + } + CSPNR = -CSPNR + CSPNI = -CSPNI +Sixty: + C1R = CYR[1] + C1I = CYI[1] + C2R = YR[1] + C2I = YI[1] + if KODE == 1 { + goto Seventy + } + IUF = 0 + ASCLE = 1.0E+3 * dmach[1] / TOL + zn = complex(ZNR, ZNI) + c1 = complex(C1R, C1I) + c2 = complex(C2R, C2I) + c1, c2, NW, IUF = Zs1s2(zn, c1, c2, ASCLE, ALIM, IUF) + C1R = real(c1) + C1I = imag(c1) + C2R = real(c2) + C2I = imag(c2) + NZ = NZ + NW +Seventy: + YR[1] = CSPNR*C1R - CSPNI*C1I + CSGNR*C2R - CSGNI*C2I + YI[1] = CSPNR*C1I + CSPNI*C1R + CSGNR*C2I + CSGNI*C2R + return ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +Eighty: + NZ = -1 + if NW == -2 { + NZ = -2 + } + return ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +} + +// ZASYI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z)>=0.0 BY +// MEANS OF THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z) IN THE +// REGION CABS(Z)>MAX(RL,FNU*FNU/2). NZ=0 IS A NORMAL return. +// NZ<0 INDICATES AN OVERFLOW ON KODE=1. +func Zasyi(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { + var AA, AEZ, AK, AK1I, AK1R, ARG, ARM, ATOL, + AZ, BB, BK, CKI, CKR, CONEI, CONER, CS1I, CS1R, CS2I, CS2R, CZI, + CZR, DFNU, DKI, DKR, DNU2, EZI, EZR, FDN, PI, P1I, + P1R, RAZ, RTPI, RTR1, RZI, RZR, S, SGN, SQK, STI, STR, S2I, + S2R, TZI, TZR, ZEROI, ZEROR float64 + + var I, IB, IL, INU, J, JL, K, KODED, M, NN int + var tmp complex128 + // var sin, cos float64 + + PI = math.Pi + RTPI = 0.159154943091895336E0 + ZEROR = 0 + ZEROI = 0 + CONER = 1 + CONEI = 0 + + NZ = 0 + AZ = cmplx.Abs(complex(ZR, ZI)) + ARM = 1.0E3 * dmach[1] + RTR1 = math.Sqrt(ARM) + IL = min(2, N) + DFNU = FNU + float64(float32(N-IL)) + + // OVERFLOW TEST + RAZ = 1.0E0 / AZ + STR = ZR * RAZ + STI = -ZI * RAZ + AK1R = RTPI * STR * RAZ + AK1I = RTPI * STI * RAZ + tmp = cmplx.Sqrt(complex(AK1R, AK1I)) + AK1R = real(tmp) + AK1I = imag(tmp) + CZR = ZR + CZI = ZI + if KODE != 2 { + goto Ten + } + CZR = ZEROR + CZI = ZI +Ten: + if math.Abs(CZR) > ELIM { + goto OneHundred + } + DNU2 = DFNU + DFNU + KODED = 1 + if (math.Abs(CZR) > ALIM) && (N > 2) { + goto Twenty + } + KODED = 0 + tmp = cmplx.Exp(complex(CZR, CZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = complex(AK1R, AK1I) * complex(STR, STI) + AK1R = real(tmp) + AK1I = imag(tmp) +Twenty: + FDN = 0.0E0 + if DNU2 > RTR1 { + FDN = DNU2 * DNU2 + } + EZR = ZR * 8.0E0 + EZI = ZI * 8.0E0 + + // WHEN Z IS IMAGINARY, THE ERROR TEST MUST BE MADE RELATIVE TO THE + // FIRST RECIPROCAL POWER SINCE THIS IS THE LEADING TERM OF THE + // EXPANSION FOR THE IMAGINARY PART. + AEZ = 8.0E0 * AZ + S = TOL / AEZ + JL = int(float32(RL+RL)) + 2 + P1R = ZEROR + P1I = ZEROI + if ZI == 0.0E0 { + goto Thirty + } + + // CALCULATE EXP(PI*(0.5+FNU+N-IL)*I) TO MINIMIZE LOSSES OF + // SIGNIFICANCE WHEN FNU OR N IS LARGE + INU = int(float32(FNU)) + ARG = (FNU - float64(float32(INU))) * PI + INU = INU + N - IL + //sin, cos = math.Sincos(ARG) + AK = -math.Sin(ARG) + BK = math.Cos(ARG) + if ZI < 0.0E0 { + BK = -BK + } + P1R = AK + P1I = BK + if INU%2 == 0 { + goto Thirty + } + P1R = -P1R + P1I = -P1I +Thirty: + for K = 1; K <= IL; K++ { + SQK = FDN - 1.0E0 + ATOL = S * math.Abs(SQK) + SGN = 1.0E0 + CS1R = CONER + CS1I = CONEI + CS2R = CONER + CS2I = CONEI + CKR = CONER + CKI = CONEI + AK = 0.0E0 + AA = 1.0E0 + BB = AEZ + DKR = EZR + DKI = EZI + // TODO(btracey): This loop is executed tens of thousands of times. Why? + // is that really necessary? + for J = 1; J <= JL; J++ { + tmp = complex(CKR, CKI) / complex(DKR, DKI) + STR = real(tmp) + STI = imag(tmp) + CKR = STR * SQK + CKI = STI * SQK + CS2R = CS2R + CKR + CS2I = CS2I + CKI + SGN = -SGN + CS1R = CS1R + CKR*SGN + CS1I = CS1I + CKI*SGN + DKR = DKR + EZR + DKI = DKI + EZI + AA = AA * math.Abs(SQK) / BB + BB = BB + AEZ + AK = AK + 8.0E0 + SQK = SQK - AK + if AA <= ATOL { + goto Fifty + } + } + goto OneTen + Fifty: + S2R = CS1R + S2I = CS1I + if ZR+ZR >= ELIM { + goto Sixty + } + TZR = ZR + ZR + TZI = ZI + ZI + tmp = cmplx.Exp(complex(-TZR, -TZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = complex(STR, STI) * complex(P1R, P1I) + STR = real(tmp) + STI = imag(tmp) + tmp = complex(STR, STI) * complex(CS2R, CS2I) + STR = real(tmp) + STI = imag(tmp) + S2R = S2R + STR + S2I = S2I + STI + Sixty: + FDN = FDN + 8.0E0*DFNU + 4.0E0 + P1R = -P1R + P1I = -P1I + M = N - IL + K + YR[M] = S2R*AK1R - S2I*AK1I + YI[M] = S2R*AK1I + S2I*AK1R + } + if N <= 2 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM + } + NN = N + K = NN - 2 + AK = float64(float32(K)) + STR = ZR * RAZ + STI = -ZI * RAZ + RZR = (STR + STR) * RAZ + RZI = (STI + STI) * RAZ + IB = 3 + for I = IB; I <= NN; I++ { + YR[K] = (AK+FNU)*(RZR*YR[K+1]-RZI*YI[K+1]) + YR[K+2] + YI[K] = (AK+FNU)*(RZR*YI[K+1]+RZI*YR[K+1]) + YI[K+2] + AK = AK - 1.0E0 + K = K - 1 + } + if KODED == 0 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM + } + tmp = cmplx.Exp(complex(CZR, CZI)) + CKR = real(tmp) + CKI = imag(tmp) + for I = 1; I <= NN; I++ { + STR = YR[I]*CKR - YI[I]*CKI + YI[I] = YR[I]*CKI + YI[I]*CKR + YR[I] = STR + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +OneHundred: + NZ = -1 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +OneTen: + NZ = -2 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +} + +// ZMLRI COMPUTES THE I BESSEL FUNCTION FOR RE(Z)>=0.0 BY THE +// MILLER ALGORITHM NORMALIZED BY A NEUMANN SERIES. +func Zmlri(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout float64) { + var ACK, AK, AP, AT, AZ, BK, CKI, CKR, CNORMI, + CNORMR, CONEI, CONER, FKAP, FKK, FLAM, FNF, PTI, PTR, P1I, + P1R, P2I, P2R, RAZ, RHO, RHO2, RZI, RZR, SCLE, STI, STR, SUMI, + SUMR, TFNF, TST, ZEROI, ZEROR float64 + var I, IAZ, IDUM, IFNU, INU, ITIME, K, KK, KM, M int + var tmp complex128 + ZEROR = 0 + ZEROI = 0 + CONER = 1 + CONEI = 0 + + SCLE = dmach[1] / TOL + NZ = 0 + AZ = cmplx.Abs(complex(ZR, ZI)) + IAZ = int(float32(AZ)) + IFNU = int(float32(FNU)) + INU = IFNU + N - 1 + AT = float64(float32(IAZ)) + 1.0E0 + RAZ = 1.0E0 / AZ + STR = ZR * RAZ + STI = -ZI * RAZ + CKR = STR * AT * RAZ + CKI = STI * AT * RAZ + RZR = (STR + STR) * RAZ + RZI = (STI + STI) * RAZ + P1R = ZEROR + P1I = ZEROI + P2R = CONER + P2I = CONEI + ACK = (AT + 1.0E0) * RAZ + RHO = ACK + math.Sqrt(ACK*ACK-1.0E0) + RHO2 = RHO * RHO + TST = (RHO2 + RHO2) / ((RHO2 - 1.0E0) * (RHO - 1.0E0)) + TST = TST / TOL + + // COMPUTE RELATIVE TRUNCATION ERROR INDEX FOR SERIES. + //fmt.Println("before loop", P2R, P2I, CKR, CKI, RZR, RZI, TST, AK) + AK = AT + for I = 1; I <= 80; I++ { + PTR = P2R + PTI = P2I + P2R = P1R - (CKR*PTR - CKI*PTI) + P2I = P1I - (CKI*PTR + CKR*PTI) + P1R = PTR + P1I = PTI + CKR = CKR + RZR + CKI = CKI + RZI + AP = cmplx.Abs(complex(P2R, P2I)) + if AP > TST*AK*AK { + goto Twenty + } + AK = AK + 1.0E0 + } + goto OneTen +Twenty: + I = I + 1 + K = 0 + if INU < IAZ { + goto Forty + } + // COMPUTE RELATIVE TRUNCATION ERROR FOR RATIOS. + P1R = ZEROR + P1I = ZEROI + P2R = CONER + P2I = CONEI + AT = float64(float32(INU)) + 1.0E0 + STR = ZR * RAZ + STI = -ZI * RAZ + CKR = STR * AT * RAZ + CKI = STI * AT * RAZ + ACK = AT * RAZ + TST = math.Sqrt(ACK / TOL) + ITIME = 1 + for K = 1; K <= 80; K++ { + PTR = P2R + PTI = P2I + P2R = P1R - (CKR*PTR - CKI*PTI) + P2I = P1I - (CKR*PTI + CKI*PTR) + P1R = PTR + P1I = PTI + CKR = CKR + RZR + CKI = CKI + RZI + AP = cmplx.Abs(complex(P2R, P2I)) + if AP < TST { + continue + } + if ITIME == 2 { + goto Forty + } + ACK = cmplx.Abs(complex(CKR, CKI)) + FLAM = ACK + math.Sqrt(ACK*ACK-1.0E0) + FKAP = AP / cmplx.Abs(complex(P1R, P1I)) + RHO = math.Min(FLAM, FKAP) + TST = TST * math.Sqrt(RHO/(RHO*RHO-1.0E0)) + ITIME = 2 + } + goto OneTen +Forty: + // BACKWARD RECURRENCE AND SUM NORMALIZING RELATION. + K = K + 1 + KK = max(I+IAZ, K+INU) + FKK = float64(float32(KK)) + P1R = ZEROR + P1I = ZEROI + + // SCALE P2 AND SUM BY SCLE. + P2R = SCLE + P2I = ZEROI + FNF = FNU - float64(float32(IFNU)) + TFNF = FNF + FNF + BK = dgamln(FKK+TFNF+1.0E0, IDUM) - dgamln(FKK+1.0E0, IDUM) - dgamln(TFNF+1.0E0, IDUM) + BK = math.Exp(BK) + SUMR = ZEROR + SUMI = ZEROI + KM = KK - INU + for I = 1; I <= KM; I++ { + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) + P1R = PTR + P1I = PTI + AK = 1.0E0 - TFNF/(FKK+TFNF) + ACK = BK * AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0E0 + } + YR[N] = P2R + YI[N] = P2I + if N == 1 { + goto Seventy + } + for I = 2; I <= N; I++ { + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) + P1R = PTR + P1I = PTI + AK = 1.0E0 - TFNF/(FKK+TFNF) + ACK = BK * AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0E0 + M = N - I + 1 + YR[M] = P2R + YI[M] = P2I + } +Seventy: + if IFNU <= 0 { + goto Ninety + } + for I = 1; I <= IFNU; I++ { + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZR*PTI+RZI*PTR) + P1R = PTR + P1I = PTI + AK = 1.0E0 - TFNF/(FKK+TFNF) + ACK = BK * AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0E0 + } +Ninety: + PTR = ZR + PTI = ZI + if KODE == 2 { + PTR = ZEROR + } + tmp = cmplx.Log(complex(RZR, RZI)) + STR = real(tmp) + STI = imag(tmp) + P1R = -FNF*STR + PTR + P1I = -FNF*STI + PTI + AP = dgamln(1.0E0+FNF, IDUM) + PTR = P1R - AP + PTI = P1I + + // THE DIVISION CEXP(PT)/(SUM+P2) IS ALTERED TO AVOID OVERFLOW + // IN THE DENOMINATOR BY SQUARING LARGE QUANTITIES. + P2R = P2R + SUMR + P2I = P2I + SUMI + AP = cmplx.Abs(complex(P2R, P2I)) + P1R = 1.0E0 / AP + tmp = cmplx.Exp(complex(PTR, PTI)) + STR = real(tmp) + STI = imag(tmp) + CKR = STR * P1R + CKI = STI * P1R + PTR = P2R * P1R + PTI = -P2I * P1R + tmp = complex(CKR, CKI) * complex(PTR, PTI) + CNORMR = real(tmp) + CNORMI = imag(tmp) + for I = 1; I <= N; I++ { + STR = YR[I]*CNORMR - YI[I]*CNORMI + YI[I] = YR[I]*CNORMI + YI[I]*CNORMR + YR[I] = STR + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL +OneTen: + NZ = -2 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL +} + +// Zseri computes the I bessel function for real(z) >= 0 by means of the power +// series for large |z| in the region |z| <= 2*sqrt(fnu+1). +// +// nz = 0 is a normal return. nz > 0 means that the last nz components were set +// to zero due to underflow. nz < 0 means that underflow occurred, but the +// condition |z| <= 2*sqrt(fnu+1) was violated and the computation must be +// completed in another routine with n -= abs(nz). +func Zseri(z complex128, fnu float64, kode, n int, y []complex128, tol, elim, alim float64) (nz int) { + // TODO(btracey): The original fortran line is "ARM = 1.0D+3*D1MACH(1)". Evidently, in Fortran + // this is interpreted as one to the power of +3*D1MACH(1). While it is possible + // this was intentional, it seems unlikely. + arm := 1000 * dmach[1] + az := cmplx.Abs(z) + if az < arm { + for i := 0; i < n; i++ { + y[i] = 0 + } + if fnu == 0 { + y[0] = 1 + n-- + } + if az == 0 { + return 0 + } + return n + } + hz := 0.5 * z + var cz complex128 + var acz float64 + if az > math.Sqrt(arm) { + cz = hz * hz + acz = cmplx.Abs(cz) + } + NN := n + ck := cmplx.Log(hz) + var ak1 complex128 + for { + dfnu := fnu + float64(NN-1) + // Underflow test. + ak1 = ck * complex(dfnu, 0) + ak := dgamln(dfnu+1, 0) + ak1 -= complex(ak, 0) + if kode == 2 { + ak1 -= complex(real(z), 0) + } + if real(ak1) > -elim { + break + } + nz++ + y[NN-1] = 0 + if acz > dfnu { + // Return with nz < 0 if abs(Z*Z/4)>fnu+u-nz-1 complete the calculation + // in cbinu with n = n - abs(nz). + nz *= -1 + return nz + } + NN-- + if NN == 0 { + return nz + } + } + crscr := 1.0 + var flag int + var scale float64 + aa := real(ak1) + if aa <= -alim { + flag = 1 + crscr = tol + scale = arm / tol + aa -= math.Log(tol) + } + var w [2]complex128 + for { + coef := cmplx.Exp(complex(aa, imag(ak1))) + atol := tol * acz / (fnu + float64(NN)) + for i := 0; i < min(2, NN); i++ { + FNUP := fnu + float64(NN-i) + s1 := 1 + 0i + if acz >= tol*FNUP { + ak2 := 1 + 0i + ak := FNUP + 2 + S := FNUP + scl := 2.0 + first := true + for first || scl > atol { + ak2 = ak2 * cz * complex(1/S, 0) + scl *= acz / S + s1 += ak2 + S += ak + ak += 2 + first = false + } + } + s2 := s1 * coef + w[i] = s2 + if flag == 1 { + if Zuchk(s2, scale, tol) != 0 { + var full bool + var dfnu float64 + // This code is similar to the code that exists above. The + // code copying is here because the original Fortran used + // a goto to solve the loop-and-a-half problem. Removing the + // goto makes the behavior of the function and variable scoping + // much clearer, but requires copying this code due to Go's + // goto rules. + for { + if full { + dfnu = fnu + float64(NN-1) + // Underflow test. + ak1 = ck * complex(dfnu, 0) + ak1 -= complex(dgamln(dfnu+1, 0), 0) + if kode == 2 { + ak1 -= complex(real(z), 0) + } + if real(ak1) > -elim { + break + } + } else { + full = true + } + nz++ + y[NN-1] = 0 + if acz > dfnu { + // Return with nz < 0 if abs(Z*Z/4)>fnu+u-nz-1 complete the calculation + // in cbinu with n = n - abs(nz). + nz *= -1 + return nz + } + NN-- + if NN == 0 { + return nz + } + } + continue + } + } + y[NN-i-1] = s2 * complex(crscr, 0) + coef /= hz + coef *= complex(FNUP-1, 0) + } + break + } + if NN <= 2 { + return nz + } + rz := complex(2*real(z)/(az*az), -2*imag(z)/(az*az)) + if flag == 0 { + for i := NN - 3; i >= 0; i-- { + y[i] = complex(float64(i+1)+fnu, 0)*rz*y[i+1] + y[i+2] + } + return nz + } + + // exp(-alim)=exp(-elim)/tol=approximately one digit of precision above the + // underflow limit, which equals scale = dmach[1)*SS*1e3. + s1 := w[0] + s2 := w[1] + for K := NN - 3; K >= 0; K-- { + s1, s2 = s2, s1+complex(float64(K+1)+fnu, 0)*(rz*s2) + ck := s2 * complex(crscr, 0) + y[K] = ck + if cmplx.Abs(ck) > scale { + for ; K >= 0; K-- { + y[K] = complex(float64(K+1)+fnu, 0)*rz*y[K+1] + y[K+2] + } + return nz + } + } + return nz +} + +// Zs1s2 tests for a possible underflow resulting from the addition of the I and +// K functions in the analytic continuation formula where s1 == K function and +// s2 == I function. +// +// When kode == 1, the I and K functions are different orders of magnitude. +// +// When kode == 2, they may both be of the same order of magnitude, but the maximum +// must be at least one precision above the underflow limit. +func Zs1s2(zr, s1, s2 complex128, scale, lim float64, iuf int) (s1o, s2o complex128, nz, iufo int) { + if s1 == 0 || math.Log(cmplx.Abs(s1))-2*real(zr) < -lim { + if cmplx.Abs(s2) > scale { + return 0, s2, 0, iuf + } + return 0, 0, 1, 0 + } + // TODO(btracey): Written like this for numerical rounding reasons. + // Fix once we're sure other changes are correct. + s1 = cmplx.Exp(cmplx.Log(s1) - zr - zr) + if math.Max(cmplx.Abs(s1), cmplx.Abs(s2)) > scale { + return s1, s2, 0, iuf + 1 + } + return 0, 0, 1, 0 +} + +func dgamln(z float64, ierr int) float64 { + //return amoslib.DgamlnFort(z) + // Go implementation. + if z < 0 { + return 0 + } + a2, _ := math.Lgamma(z) + return a2 +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amos_test.go b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amos_test.go new file mode 100644 index 00000000..59cdfa4f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amos_test.go @@ -0,0 +1,521 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package amos + +import ( + "math" + "math/rand" + "strconv" + "testing" + + "gonum.org/v1/gonum/floats" +) + +type input struct { + x []float64 + is []int + kode int + id int + yr []float64 + yi []float64 + n int + tol float64 +} + +func randnum(rnd *rand.Rand) float64 { + r := 2e2 // Fortran has infinite loop if this is set higher than 2e3 + if rnd.Float64() > 0.99 { + return 0 + } + return rnd.Float64()*r - r/2 +} + +func randInput(rnd *rand.Rand) input { + x := make([]float64, 8) + for j := range x { + x[j] = randnum(rnd) + } + is := make([]int, 3) + for j := range is { + is[j] = rand.Intn(1000) + } + kode := rand.Intn(2) + 1 + id := rand.Intn(2) + n := rand.Intn(5) + 1 + yr := make([]float64, n+1) + yi := make([]float64, n+1) + for j := range yr { + yr[j] = randnum(rnd) + yi[j] = randnum(rnd) + } + tol := 1e-14 + + return input{ + x, is, kode, id, yr, yi, n, tol, + } +} + +const nInputs = 100000 + +func TestAiry(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zairytest(t, in.x, in.kode, in.id) + } +} + +func TestZacai(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zacaitest(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode) + } +} + +func TestZbknu(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zbknutest(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode) + } +} + +func TestZasyi(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zasyitest(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode) + } +} + +func TestZseri(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zseritest(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode) + } +} + +func TestZmlri(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zmlritest(t, in.x, in.is, in.tol, in.n, in.yr, in.yi, in.kode) + } +} + +func TestZkscl(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zkscltest(t, in.x, in.is, in.tol, in.n, in.yr, in.yi) + } +} + +func TestZuchk(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zuchktest(t, in.x, in.is, in.tol) + } +} + +func TestZs1s2(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for i := 0; i < nInputs; i++ { + in := randInput(rnd) + zs1s2test(t, in.x, in.is) + } +} + +func zs1s2test(t *testing.T, x []float64, is []int) { + + type data struct { + ZRR, ZRI, S1R, S1I, S2R, S2I float64 + NZ int + ASCLE, ALIM float64 + IUF int + } + + input := data{ + x[0], x[1], x[2], x[3], x[4], x[5], + is[0], + x[6], x[7], + is[1], + } + + zr := complex(input.ZRR, input.ZRI) + s1 := complex(input.S1R, input.S1I) + s2 := complex(input.S2R, input.S2I) + impl := func(input data) data { + s1, s2, nz, iuf := Zs1s2(zr, s1, s2, input.ASCLE, input.ALIM, input.IUF) + zrr := real(zr) + zri := imag(zr) + s1r := real(s1) + s1i := imag(s1) + s2r := real(s2) + s2i := imag(s2) + alim := input.ALIM + ascle := input.ASCLE + return data{zrr, zri, s1r, s1i, s2r, s2i, nz, ascle, alim, iuf} + } + + comp := func(input data) data { + zrr, zri, s1r, s1i, s2r, s2i, nz, ascle, alim, iuf := + zs1s2Orig(input.ZRR, input.ZRI, input.S1R, input.S1I, input.S2R, input.S2I, input.NZ, input.ASCLE, input.ALIM, input.IUF) + return data{zrr, zri, s1r, s1i, s2r, s2i, nz, ascle, alim, iuf} + } + + oi := impl(input) + oc := comp(input) + + sameF64(t, "zs1s2 zrr", oc.ZRR, oi.ZRR) + sameF64(t, "zs1s2 zri", oc.ZRI, oi.ZRI) + sameF64(t, "zs1s2 s1r", oc.S1R, oi.S1R) + sameF64(t, "zs1s2 s1i", oc.S1I, oi.S1I) + sameF64(t, "zs1s2 s2r", oc.S2R, oi.S2R) + sameF64(t, "zs1s2 s2i", oc.S2I, oi.S2I) + sameF64(t, "zs1s2 ascle", oc.ASCLE, oi.ASCLE) + sameF64(t, "zs1s2 alim", oc.ALIM, oi.ALIM) + sameInt(t, "iuf", oc.IUF, oi.IUF) + sameInt(t, "nz", oc.NZ, oi.NZ) +} + +func zuchktest(t *testing.T, x []float64, is []int, tol float64) { + YR := x[0] + YI := x[1] + NZ := is[0] + ASCLE := x[2] + TOL := tol + + YRfort, YIfort, NZfort, ASCLEfort, TOLfort := zuchkOrig(YR, YI, NZ, ASCLE, TOL) + y := complex(YR, YI) + NZamos := Zuchk(y, ASCLE, TOL) + YRamos := real(y) + YIamos := imag(y) + ASCLEamos := ASCLE + TOLamos := TOL + + sameF64(t, "zuchk yr", YRfort, YRamos) + sameF64(t, "zuchk yi", YIfort, YIamos) + sameInt(t, "zuchk nz", NZfort, NZamos) + sameF64(t, "zuchk ascle", ASCLEfort, ASCLEamos) + sameF64(t, "zuchk tol", TOLfort, TOLamos) +} + +func zkscltest(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64) { + ZRR := x[0] + ZRI := x[1] + FNU := x[2] + NZ := is[1] + ELIM := x[3] + ASCLE := x[4] + RZR := x[6] + RZI := x[7] + + yrfort := make([]float64, len(yr)) + copy(yrfort, yr) + yifort := make([]float64, len(yi)) + copy(yifort, yi) + ZRRfort, ZRIfort, FNUfort, Nfort, YRfort, YIfort, NZfort, RZRfort, RZIfort, ASCLEfort, TOLfort, ELIMfort := + zksclOrig(ZRR, ZRI, FNU, n, yrfort, yifort, NZ, RZR, RZI, ASCLE, tol, ELIM) + + yramos := make([]float64, len(yr)) + copy(yramos, yr) + yiamos := make([]float64, len(yi)) + copy(yiamos, yi) + ZRRamos, ZRIamos, FNUamos, Namos, YRamos, YIamos, NZamos, RZRamos, RZIamos, ASCLEamos, TOLamos, ELIMamos := + Zkscl(ZRR, ZRI, FNU, n, yramos, yiamos, NZ, RZR, RZI, ASCLE, tol, ELIM) + + sameF64(t, "zkscl zrr", ZRRfort, ZRRamos) + sameF64(t, "zkscl zri", ZRIfort, ZRIamos) + sameF64(t, "zkscl fnu", FNUfort, FNUamos) + sameInt(t, "zkscl n", Nfort, Namos) + sameInt(t, "zkscl nz", NZfort, NZamos) + sameF64(t, "zkscl rzr", RZRfort, RZRamos) + sameF64(t, "zkscl rzi", RZIfort, RZIamos) + sameF64(t, "zkscl ascle", ASCLEfort, ASCLEamos) + sameF64(t, "zkscl tol", TOLfort, TOLamos) + sameF64(t, "zkscl elim", ELIMfort, ELIMamos) + + sameF64SApprox(t, "zkscl yr", YRfort, YRamos, 1e-14) + sameF64SApprox(t, "zkscl yi", YIfort, YIamos, 1e-14) +} + +func zmlritest(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) { + ZR := x[0] + ZI := x[1] + FNU := x[2] + KODE := kode + NZ := is[1] + + yrfort := make([]float64, len(yr)) + copy(yrfort, yr) + yifort := make([]float64, len(yi)) + copy(yifort, yi) + ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, TOLfort := + zmlriOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, tol) + + yramos := make([]float64, len(yr)) + copy(yramos, yr) + yiamos := make([]float64, len(yi)) + copy(yiamos, yi) + ZRamos, ZIamos, FNUamos, KODEamos, Namos, YRamos, YIamos, NZamos, TOLamos := + Zmlri(ZR, ZI, FNU, KODE, n, yramos, yiamos, NZ, tol) + + sameF64(t, "zmlri zr", ZRfort, ZRamos) + sameF64(t, "zmlri zi", ZIfort, ZIamos) + sameF64(t, "zmlri fnu", FNUfort, FNUamos) + sameInt(t, "zmlri kode", KODEfort, KODEamos) + sameInt(t, "zmlri n", Nfort, Namos) + sameInt(t, "zmlri nz", NZfort, NZamos) + sameF64(t, "zmlri tol", TOLfort, TOLamos) + + sameF64S(t, "zmlri yr", YRfort, YRamos) + sameF64S(t, "zmlri yi", YIfort, YIamos) +} + +func zseritest(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) { + ZR := x[0] + ZI := x[1] + FNU := x[2] + KODE := kode + NZ := is[1] + ELIM := x[3] + ALIM := x[4] + + yrfort := make([]float64, len(yr)) + copy(yrfort, yr) + yifort := make([]float64, len(yi)) + copy(yifort, yi) + ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, TOLfort, ELIMfort, ALIMfort := + zseriOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, tol, ELIM, ALIM) + + yramos := make([]float64, len(yr)) + copy(yramos, yr) + yiamos := make([]float64, len(yi)) + copy(yiamos, yi) + y := make([]complex128, len(yramos)) + for i, v := range yramos { + y[i] = complex(v, yiamos[i]) + } + z := complex(ZR, ZI) + + NZamos := Zseri(z, FNU, KODE, n, y[1:], tol, ELIM, ALIM) + + ZRamos := real(z) + ZIamos := imag(z) + FNUamos := FNU + KODEamos := KODE + Namos := n + TOLamos := tol + ELIMamos := ELIM + ALIMamos := ALIM + YRamos := make([]float64, len(y)) + YIamos := make([]float64, len(y)) + for i, v := range y { + YRamos[i] = real(v) + YIamos[i] = imag(v) + } + + sameF64(t, "zseri zr", ZRfort, ZRamos) + sameF64(t, "zseri zi", ZIfort, ZIamos) + sameF64(t, "zseri fnu", FNUfort, FNUamos) + sameInt(t, "zseri kode", KODEfort, KODEamos) + sameInt(t, "zseri n", Nfort, Namos) + sameInt(t, "zseri nz", NZfort, NZamos) + sameF64(t, "zseri tol", TOLfort, TOLamos) + sameF64(t, "zseri elim", ELIMfort, ELIMamos) + sameF64(t, "zseri elim", ALIMfort, ALIMamos) + + sameF64SApprox(t, "zseri yr", YRfort, YRamos, 1e-10) + sameF64SApprox(t, "zseri yi", YIfort, YIamos, 1e-10) +} + +func zasyitest(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) { + ZR := x[0] + ZI := x[1] + FNU := x[2] + KODE := kode + NZ := is[1] + ELIM := x[3] + ALIM := x[4] + RL := x[5] + + yrfort := make([]float64, len(yr)) + copy(yrfort, yr) + yifort := make([]float64, len(yi)) + copy(yifort, yi) + ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, RLfort, TOLfort, ELIMfort, ALIMfort := + zasyiOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, RL, tol, ELIM, ALIM) + + yramos := make([]float64, len(yr)) + copy(yramos, yr) + yiamos := make([]float64, len(yi)) + copy(yiamos, yi) + ZRamos, ZIamos, FNUamos, KODEamos, Namos, YRamos, YIamos, NZamos, RLamos, TOLamos, ELIMamos, ALIMamos := + Zasyi(ZR, ZI, FNU, KODE, n, yramos, yiamos, NZ, RL, tol, ELIM, ALIM) + + sameF64(t, "zasyi zr", ZRfort, ZRamos) + sameF64(t, "zasyi zr", ZIfort, ZIamos) + sameF64(t, "zasyi fnu", FNUfort, FNUamos) + sameInt(t, "zasyi kode", KODEfort, KODEamos) + sameInt(t, "zasyi n", Nfort, Namos) + sameInt(t, "zasyi nz", NZfort, NZamos) + sameF64(t, "zasyi rl", RLfort, RLamos) + sameF64(t, "zasyi tol", TOLfort, TOLamos) + sameF64(t, "zasyi elim", ELIMfort, ELIMamos) + sameF64(t, "zasyi alim", ALIMfort, ALIMamos) + + sameF64SApprox(t, "zasyi yr", YRfort, YRamos, 1e-12) + sameF64SApprox(t, "zasyi yi", YIfort, YIamos, 1e-12) +} + +func zbknutest(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) { + ZR := x[0] + ZI := x[1] + FNU := x[2] + KODE := kode + NZ := is[1] + ELIM := x[3] + ALIM := x[4] + + yrfort := make([]float64, len(yr)) + copy(yrfort, yr) + yifort := make([]float64, len(yi)) + copy(yifort, yi) + ZRfort, ZIfort, FNUfort, KODEfort, Nfort, YRfort, YIfort, NZfort, TOLfort, ELIMfort, ALIMfort := + zbknuOrig(ZR, ZI, FNU, KODE, n, yrfort, yifort, NZ, tol, ELIM, ALIM) + + yramos := make([]float64, len(yr)) + copy(yramos, yr) + yiamos := make([]float64, len(yi)) + copy(yiamos, yi) + ZRamos, ZIamos, FNUamos, KODEamos, Namos, YRamos, YIamos, NZamos, TOLamos, ELIMamos, ALIMamos := + Zbknu(ZR, ZI, FNU, KODE, n, yramos, yiamos, NZ, tol, ELIM, ALIM) + + sameF64(t, "zbknu zr", ZRfort, ZRamos) + sameF64(t, "zbknu zr", ZIfort, ZIamos) + sameF64(t, "zbknu fnu", FNUfort, FNUamos) + sameInt(t, "zbknu kode", KODEfort, KODEamos) + sameInt(t, "zbknu n", Nfort, Namos) + sameInt(t, "zbknu nz", NZfort, NZamos) + sameF64(t, "zbknu tol", TOLfort, TOLamos) + sameF64(t, "zbknu elim", ELIMfort, ELIMamos) + sameF64(t, "zbknu alim", ALIMfort, ALIMamos) + + sameF64SApprox(t, "zbknu yr", YRfort, YRamos, 1e-12) + sameF64SApprox(t, "zbknu yi", YIfort, YIamos, 1e-12) +} + +func zairytest(t *testing.T, x []float64, kode, id int) { + ZR := x[0] + ZI := x[1] + KODE := kode + ID := id + + AIRfort, AIIfort, NZfort := zairyOrig(ZR, ZI, ID, KODE) + AIRamos, AIIamos, NZamos := Zairy(ZR, ZI, ID, KODE) + + sameF64Approx(t, "zairy air", AIRfort, AIRamos, 1e-12) + sameF64Approx(t, "zairy aii", AIIfort, AIIamos, 1e-12) + sameInt(t, "zairy nz", NZfort, NZamos) +} + +func zacaitest(t *testing.T, x []float64, is []int, tol float64, n int, yr, yi []float64, kode int) { + ZR := x[0] + ZI := x[1] + FNU := x[2] + KODE := kode + NZ := is[1] + MR := is[2] + ELIM := x[3] + ALIM := x[4] + RL := x[5] + + yrfort := make([]float64, len(yr)) + copy(yrfort, yr) + yifort := make([]float64, len(yi)) + copy(yifort, yi) + ZRfort, ZIfort, FNUfort, KODEfort, MRfort, Nfort, YRfort, YIfort, NZfort, RLfort, TOLfort, ELIMfort, ALIMfort := + zacaiOrig(ZR, ZI, FNU, KODE, MR, n, yrfort, yifort, NZ, RL, tol, ELIM, ALIM) + + yramos := make([]float64, len(yr)) + copy(yramos, yr) + yiamos := make([]float64, len(yi)) + copy(yiamos, yi) + ZRamos, ZIamos, FNUamos, KODEamos, MRamos, Namos, YRamos, YIamos, NZamos, RLamos, TOLamos, ELIMamos, ALIMamos := + Zacai(ZR, ZI, FNU, KODE, MR, n, yramos, yiamos, NZ, RL, tol, ELIM, ALIM) + + sameF64(t, "zacai zr", ZRfort, ZRamos) + sameF64(t, "zacai zi", ZIfort, ZIamos) + sameF64(t, "zacai fnu", FNUfort, FNUamos) + sameInt(t, "zacai kode", KODEfort, KODEamos) + sameInt(t, "zacai mr", MRfort, MRamos) + sameInt(t, "zacai n", Nfort, Namos) + sameInt(t, "zacai nz", NZfort, NZamos) + sameF64(t, "zacai rl", RLfort, RLamos) + sameF64(t, "zacai tol", TOLfort, TOLamos) + sameF64(t, "zacai elim", ELIMfort, ELIMamos) + sameF64(t, "zacai elim", ALIMfort, ALIMamos) + + sameF64SApprox(t, "zacai yr", YRfort, YRamos, 1e-12) + sameF64SApprox(t, "zacai yi", YIfort, YIamos, 1e-12) +} + +func sameF64(t *testing.T, str string, c, native float64) { + if math.IsNaN(c) && math.IsNaN(native) { + return + } + if c == native { + return + } + cb := math.Float64bits(c) + nb := math.Float64bits(native) + t.Errorf("Case %s: Float64 mismatch. c = %v, native = %v\n cb: %v, nb: %v\n", str, c, native, cb, nb) +} + +func sameF64Approx(t *testing.T, str string, c, native, tol float64) { + if math.IsNaN(c) && math.IsNaN(native) { + return + } + if floats.EqualWithinAbsOrRel(c, native, tol, tol) { + return + } + // Have a much looser tolerance for correctness when the values are large. + // Floating point noise makes the relative tolerance difference greater for + // higher values. + if c > 1e200 && floats.EqualWithinAbsOrRel(c, native, 10, 10) { + return + } + cb := math.Float64bits(c) + nb := math.Float64bits(native) + t.Errorf("Case %s: Float64 mismatch. c = %v, native = %v\n cb: %v, nb: %v\n", str, c, native, cb, nb) +} + +func sameInt(t *testing.T, str string, c, native int) { + if c != native { + t.Errorf("Case %s: Int mismatch. c = %v, native = %v.", str, c, native) + } +} + +func sameF64S(t *testing.T, str string, c, native []float64) { + if len(c) != len(native) { + panic(str) + } + for i, v := range c { + sameF64(t, str+"_idx_"+strconv.Itoa(i), v, native[i]) + } +} + +func sameF64SApprox(t *testing.T, str string, c, native []float64, tol float64) { + if len(c) != len(native) { + panic(str) + } + for i, v := range c { + sameF64Approx(t, str+"_idx_"+strconv.Itoa(i), v, native[i], tol) + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/Make.files b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/Make.files new file mode 100644 index 00000000..81c7c715 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/Make.files @@ -0,0 +1,5 @@ +$(CUR_SRCS) += d1mach.f zabs.f zasyi.f zbesk.f zbknu.f zexp.f zmlt.f zshch.f zuni1.f zunk2.f \ + dgamln.f zacai.f zbesh.f zbesy.f zbuni.f zkscl.f zrati.f zsqrt.f zuni2.f zuoik.f \ + i1mach.f zacon.f zbesi.f zbinu.f zbunk.f zlog.f zs1s2.f zuchk.f zunik.f zwrsk.f \ + xerror.f zairy.f zbesj.f zbiry.f zdiv.f zmlri.f zseri.f zunhj.f zunk1.f + diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/d1mach.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/d1mach.f new file mode 100644 index 00000000..0d344def --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/d1mach.f @@ -0,0 +1,97 @@ +*DECK D1MACH + DOUBLE PRECISION FUNCTION D1MACH(I) +C***BEGIN PROLOGUE D1MACH +C***DATE WRITTEN 750101 (YYMMDD) +C***REVISION DATE 890213 (YYMMDD) +C***CATEGORY NO. R1 +C***KEYWORDS LIBRARY=SLATEC,TYPE=DOUBLE PRECISION(R1MACH-S D1MACH-D), +C MACHINE CONSTANTS +C***AUTHOR FOX, P. A., (BELL LABS) +C HALL, A. D., (BELL LABS) +C SCHRYER, N. L., (BELL LABS) +C***PURPOSE Returns double precision machine dependent constants +C***DESCRIPTION +C +C D1MACH can be used to obtain machine-dependent parameters +C for the local machine environment. It is a function +C subprogram with one (input) argument, and can be called +C as follows, for example +C +C D = D1MACH(I) +C +C where I=1,...,5. The (output) value of D above is +C determined by the (input) value of I. The results for +C various values of I are discussed below. +C +C D1MACH( 1) = B**(EMIN-1), the smallest positive magnitude. +C D1MACH( 2) = B**EMAX*(1 - B**(-T)), the largest magnitude. +C D1MACH( 3) = B**(-T), the smallest relative spacing. +C D1MACH( 4) = B**(1-T), the largest relative spacing. +C D1MACH( 5) = LOG10(B) +C +C Assume double precision numbers are represented in the T-digit, +C base-B form +C +C sign (B**E)*( (X(1)/B) + ... + (X(T)/B**T) ) +C +C where 0 .LE. X(I) .LT. B for I=1,...,T, 0 .LT. X(1), and +C EMIN .LE. E .LE. EMAX. +C +C The values of B, T, EMIN and EMAX are provided in I1MACH as +C follows: +C I1MACH(10) = B, the base. +C I1MACH(14) = T, the number of base-B digits. +C I1MACH(15) = EMIN, the smallest exponent E. +C I1MACH(16) = EMAX, the largest exponent E. +C +C To alter this function for a particular environment, +C the desired set of DATA statements should be activated by +C removing the C from column 1. Also, the values of +C D1MACH(1) - D1MACH(4) should be checked for consistency +C with the local operating system. +C +C***REFERENCES FOX P.A., HALL A.D., SCHRYER N.L.,*FRAMEWORK FOR A +C PORTABLE LIBRARY*, ACM TRANSACTIONS ON MATHEMATICAL +C SOFTWARE, VOL. 4, NO. 2, JUNE 1978, PP. 177-188. +C***ROUTINES CALLED XERROR +C***END PROLOGUE D1MACH +C + INTEGER SMALL(4) + INTEGER LARGE(4) + INTEGER RIGHT(4) + INTEGER DIVER(4) + INTEGER LOG10(4) +C + DOUBLE PRECISION DMACH(5) + SAVE DMACH +C +C EQUIVALENCE (DMACH(1),SMALL(1)) +C EQUIVALENCE (DMACH(2),LARGE(1)) +C EQUIVALENCE (DMACH(3),RIGHT(1)) +C EQUIVALENCE (DMACH(4),DIVER(1)) +C EQUIVALENCE (DMACH(5),LOG10(1)) +C +C MACHINE CONSTANTS FOR THE IBM PC +C ASSUMES THAT ALL ARITHMETIC IS DONE IN DOUBLE PRECISION +C ON 8088, I.E., NOT IN 80 BIT FORM FOR THE 8087. +C + DATA DMACH(1) / 2.23D-308 / +C DATA SMALL(1),SMALL(2) / 2002288515, 1050897 / + DATA DMACH(2) / 1.79D-308 / +C DATA LARGE(1),LARGE(2) / 1487780761, 2146426097 / + DATA DMACH(3) / 1.11D-16 / +C DATA RIGHT(1),RIGHT(2) / -1209488034, 1017118298 / + DATA DMACH(4) / 2.22D-16 / +C DATA DIVER(1),DIVER(2) / -1209488034, 1018166874 / + DATA DMACH(5) / 0.3010299956639812 / +C DATA LOG10(1),LOG10(2) / 1352628735, 1070810131 / +C +C +C***FIRST EXECUTABLE STATEMENT D1MACH + IF (I .LT. 1 .OR. I .GT. 5) + 1 CALL XERROR ('D1MACH -- I OUT OF BOUNDS', 25, 1, 2) +C + D1MACH = DMACH(I) + RETURN +C + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/dgamln.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/dgamln.f new file mode 100644 index 00000000..792014be --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/dgamln.f @@ -0,0 +1,189 @@ + DOUBLE PRECISION FUNCTION DGAMLN(Z,IERR) +C***BEGIN PROLOGUE DGAMLN +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 830501 (YYMMDD) +C***CATEGORY NO. B5F +C***KEYWORDS GAMMA FUNCTION,LOGARITHM OF GAMMA FUNCTION +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE THE LOGARITHM OF THE GAMMA FUNCTION +C***DESCRIPTION +C +C **** A DOUBLE PRECISION ROUTINE **** +C DGAMLN COMPUTES THE NATURAL LOG OF THE GAMMA FUNCTION FOR +C Z.GT.0. THE ASYMPTOTIC EXPANSION IS USED TO GENERATE VALUES +C GREATER THAN ZMIN WHICH ARE ADJUSTED BY THE RECURSION +C G(Z+1)=Z*G(Z) FOR Z.LE.ZMIN. THE FUNCTION WAS MADE AS +C PORTABLE AS POSSIBLE BY COMPUTIMG ZMIN FROM THE NUMBER OF BASE +C 10 DIGITS IN A WORD, RLN=AMAX1(-ALOG10(R1MACH(4)),0.5E-18) +C LIMITED TO 18 DIGITS OF (RELATIVE) ACCURACY. +C +C SINCE INTEGER ARGUMENTS ARE COMMON, A TABLE LOOK UP ON 100 +C VALUES IS USED FOR SPEED OF EXECUTION. +C +C DESCRIPTION OF ARGUMENTS +C +C INPUT Z IS D0UBLE PRECISION +C Z - ARGUMENT, Z.GT.0.0D0 +C +C OUTPUT DGAMLN IS DOUBLE PRECISION +C DGAMLN - NATURAL LOG OF THE GAMMA FUNCTION AT Z.NE.0.0D0 +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN, COMPUTATION COMPLETED +C IERR=1, Z.LE.0.0D0, NO COMPUTATION +C +C +C***REFERENCES COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C BY D. E. AMOS, SAND83-0083, MAY, 1983. +C***ROUTINES CALLED I1MACH,D1MACH +C***END PROLOGUE DGAMLN + DOUBLE PRECISION CF, CON, FLN, FZ, GLN, RLN, S, TLG, TRM, TST, + * T1, WDTOL, Z, ZDMY, ZINC, ZM, ZMIN, ZP, ZSQ, D1MACH + INTEGER I, IERR, I1M, K, MZ, NZ, I1MACH + DIMENSION CF(22), GLN(100) +C LNGAMMA(N), N=1,100 + DATA GLN(1), GLN(2), GLN(3), GLN(4), GLN(5), GLN(6), GLN(7), + 1 GLN(8), GLN(9), GLN(10), GLN(11), GLN(12), GLN(13), GLN(14), + 2 GLN(15), GLN(16), GLN(17), GLN(18), GLN(19), GLN(20), + 3 GLN(21), GLN(22)/ + 4 0.00000000000000000D+00, 0.00000000000000000D+00, + 5 6.93147180559945309D-01, 1.79175946922805500D+00, + 6 3.17805383034794562D+00, 4.78749174278204599D+00, + 7 6.57925121201010100D+00, 8.52516136106541430D+00, + 8 1.06046029027452502D+01, 1.28018274800814696D+01, + 9 1.51044125730755153D+01, 1.75023078458738858D+01, + A 1.99872144956618861D+01, 2.25521638531234229D+01, + B 2.51912211827386815D+01, 2.78992713838408916D+01, + C 3.06718601060806728D+01, 3.35050734501368889D+01, + D 3.63954452080330536D+01, 3.93398841871994940D+01, + E 4.23356164607534850D+01, 4.53801388984769080D+01/ + DATA GLN(23), GLN(24), GLN(25), GLN(26), GLN(27), GLN(28), + 1 GLN(29), GLN(30), GLN(31), GLN(32), GLN(33), GLN(34), + 2 GLN(35), GLN(36), GLN(37), GLN(38), GLN(39), GLN(40), + 3 GLN(41), GLN(42), GLN(43), GLN(44)/ + 4 4.84711813518352239D+01, 5.16066755677643736D+01, + 5 5.47847293981123192D+01, 5.80036052229805199D+01, + 6 6.12617017610020020D+01, 6.45575386270063311D+01, + 7 6.78897431371815350D+01, 7.12570389671680090D+01, + 8 7.46582363488301644D+01, 7.80922235533153106D+01, + 9 8.15579594561150372D+01, 8.50544670175815174D+01, + A 8.85808275421976788D+01, 9.21361756036870925D+01, + B 9.57196945421432025D+01, 9.93306124547874269D+01, + C 1.02968198614513813D+02, 1.06631760260643459D+02, + D 1.10320639714757395D+02, 1.14034211781461703D+02, + E 1.17771881399745072D+02, 1.21533081515438634D+02/ + DATA GLN(45), GLN(46), GLN(47), GLN(48), GLN(49), GLN(50), + 1 GLN(51), GLN(52), GLN(53), GLN(54), GLN(55), GLN(56), + 2 GLN(57), GLN(58), GLN(59), GLN(60), GLN(61), GLN(62), + 3 GLN(63), GLN(64), GLN(65), GLN(66)/ + 4 1.25317271149356895D+02, 1.29123933639127215D+02, + 5 1.32952575035616310D+02, 1.36802722637326368D+02, + 6 1.40673923648234259D+02, 1.44565743946344886D+02, + 7 1.48477766951773032D+02, 1.52409592584497358D+02, + 8 1.56360836303078785D+02, 1.60331128216630907D+02, + 9 1.64320112263195181D+02, 1.68327445448427652D+02, + A 1.72352797139162802D+02, 1.76395848406997352D+02, + B 1.80456291417543771D+02, 1.84533828861449491D+02, + C 1.88628173423671591D+02, 1.92739047287844902D+02, + D 1.96866181672889994D+02, 2.01009316399281527D+02, + E 2.05168199482641199D+02, 2.09342586752536836D+02/ + DATA GLN(67), GLN(68), GLN(69), GLN(70), GLN(71), GLN(72), + 1 GLN(73), GLN(74), GLN(75), GLN(76), GLN(77), GLN(78), + 2 GLN(79), GLN(80), GLN(81), GLN(82), GLN(83), GLN(84), + 3 GLN(85), GLN(86), GLN(87), GLN(88)/ + 4 2.13532241494563261D+02, 2.17736934113954227D+02, + 5 2.21956441819130334D+02, 2.26190548323727593D+02, + 6 2.30439043565776952D+02, 2.34701723442818268D+02, + 7 2.38978389561834323D+02, 2.43268849002982714D+02, + 8 2.47572914096186884D+02, 2.51890402209723194D+02, + 9 2.56221135550009525D+02, 2.60564940971863209D+02, + A 2.64921649798552801D+02, 2.69291097651019823D+02, + B 2.73673124285693704D+02, 2.78067573440366143D+02, + C 2.82474292687630396D+02, 2.86893133295426994D+02, + D 2.91323950094270308D+02, 2.95766601350760624D+02, + E 3.00220948647014132D+02, 3.04686856765668715D+02/ + DATA GLN(89), GLN(90), GLN(91), GLN(92), GLN(93), GLN(94), + 1 GLN(95), GLN(96), GLN(97), GLN(98), GLN(99), GLN(100)/ + 2 3.09164193580146922D+02, 3.13652829949879062D+02, + 3 3.18152639620209327D+02, 3.22663499126726177D+02, + 4 3.27185287703775217D+02, 3.31717887196928473D+02, + 5 3.36261181979198477D+02, 3.40815058870799018D+02, + 6 3.45379407062266854D+02, 3.49954118040770237D+02, + 7 3.54539085519440809D+02, 3.59134205369575399D+02/ +C COEFFICIENTS OF ASYMPTOTIC EXPANSION + DATA CF(1), CF(2), CF(3), CF(4), CF(5), CF(6), CF(7), CF(8), + 1 CF(9), CF(10), CF(11), CF(12), CF(13), CF(14), CF(15), + 2 CF(16), CF(17), CF(18), CF(19), CF(20), CF(21), CF(22)/ + 3 8.33333333333333333D-02, -2.77777777777777778D-03, + 4 7.93650793650793651D-04, -5.95238095238095238D-04, + 5 8.41750841750841751D-04, -1.91752691752691753D-03, + 6 6.41025641025641026D-03, -2.95506535947712418D-02, + 7 1.79644372368830573D-01, -1.39243221690590112D+00, + 8 1.34028640441683920D+01, -1.56848284626002017D+02, + 9 2.19310333333333333D+03, -3.61087712537249894D+04, + A 6.91472268851313067D+05, -1.52382215394074162D+07, + B 3.82900751391414141D+08, -1.08822660357843911D+10, + C 3.47320283765002252D+11, -1.23696021422692745D+13, + D 4.88788064793079335D+14, -2.13203339609193739D+16/ +C +C LN(2*PI) + DATA CON / 1.83787706640934548D+00/ +C +C***FIRST EXECUTABLE STATEMENT DGAMLN + IERR=0 + IF (Z.LE.0.0D0) GO TO 70 + IF (Z.GT.101.0D0) GO TO 10 + NZ = INT(SNGL(Z)) + FZ = Z - FLOAT(NZ) + IF (FZ.GT.0.0D0) GO TO 10 + IF (NZ.GT.100) GO TO 10 + DGAMLN = GLN(NZ) + RETURN + 10 CONTINUE + WDTOL = D1MACH(4) + WDTOL = DMAX1(WDTOL,0.5D-18) + I1M = I1MACH(14) + RLN = D1MACH(5)*FLOAT(I1M) + FLN = DMIN1(RLN,20.0D0) + FLN = DMAX1(FLN,3.0D0) + FLN = FLN - 3.0D0 + ZM = 1.8000D0 + 0.3875D0*FLN + MZ = INT(SNGL(ZM)) + 1 + ZMIN = FLOAT(MZ) + ZDMY = Z + ZINC = 0.0D0 + IF (Z.GE.ZMIN) GO TO 20 + ZINC = ZMIN - FLOAT(NZ) + ZDMY = Z + ZINC + 20 CONTINUE + ZP = 1.0D0/ZDMY + T1 = CF(1)*ZP + S = T1 + IF (ZP.LT.WDTOL) GO TO 40 + ZSQ = ZP*ZP + TST = T1*WDTOL + DO 30 K=2,22 + ZP = ZP*ZSQ + TRM = CF(K)*ZP + IF (DABS(TRM).LT.TST) GO TO 40 + S = S + TRM + 30 CONTINUE + 40 CONTINUE + IF (ZINC.NE.0.0D0) GO TO 50 + TLG = DLOG(Z) + DGAMLN = Z*(TLG-1.0D0) + 0.5D0*(CON-TLG) + S + RETURN + 50 CONTINUE + ZP = 1.0D0 + NZ = INT(SNGL(ZINC)) + DO 60 I=1,NZ + ZP = ZP*(Z+FLOAT(I-1)) + 60 CONTINUE + TLG = DLOG(ZDMY) + DGAMLN = ZDMY*(TLG-1.0D0) - DLOG(ZP) + 0.5D0*(CON-TLG) + S + RETURN +C +C + 70 CONTINUE + IERR=1 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/fortran.go b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/fortran.go new file mode 100644 index 00000000..52e17e1f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/fortran.go @@ -0,0 +1,366 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build fortran +// TODO(jonlawlor): remove fortran build tag when gonum only supports go 1.7+. + +package amoslib + +/* +double mzabs_(double * ar, double * ai); +void zs1s2_(double * ZRR, double * ZRI, double * S1R, double * S1I, double * S2R, double * S2I, int* NZ, double *ASCLE, double * ALIM, int * IUF); +void zacai_(double * ZR, double * ZI, double * FNU, int * KODE, int * N, int * MR, double * YR, double * YI, int * NZ, double * RL, double * tol, double * elim, double * alim); +void zseri_(double * ZR, double * ZI, double * FNU, int * KODE, int * N, double * YR, double * YI, int * NZ, double * tol, double * elim, double * alim); +void zmlri_(double * ZR, double * ZI, double * FNU, int * KODE, int * N, double * YR, double * YI, int * NZ, double * tol); +void zbknu_(double * ZR, double * ZI, double * FNU, int * KODE, int * N, double * YR, double * YI, int * NZ, double * tol, double * elim, double * alim); +void zasyi_(double * ZR, double * ZI, double * FNU, int * KODE, int * N, double * YR, double * YI, int * NZ,double * RL, double * tol, double * elim, double * alim); +void zkscl_(double * ZRR, double * ZRI, double * FNU, int * N, double * YR, double * YI, int * NZ, double * RZR, double * RZI, double * ASCLE, double * tol, double * elim); +void zuchk_(double * YR, double * YI, int * NZ, double * ASCLE, double * TOL); +void zairy_(double * ZR, double * ZI, int * ID, int * KODE, double * AIR, double * AII, int * NZ, int * IERR); +void zlog_(double * ar, double * ai, double * br, double * bi, int * ierr); +void zexp_(double * ar, double * ai, double * br, double * bi); +void zsqrt_(double * ar, double * ai, double * br, double * bi); +void zdiv_(double * ar, double * ai, double * br, double * bi, double * cr, double * ci); +void zmlt_(double * ar, double * ai, double * br, double * bi, double * cr, double * ci); +double dgamln_(double *z, int * ierr); +void zshch_(double * zr, double * zi, double * cshr, double * cshi, double * cchr, double * cchi); +double mysqrt_(double * A); +double myexp_(double * A); +double mycos_(double * A); +double mysin_(double * A); +double mylog_(double * A); +double mytan_(double * A); +double myatan_(double * A); +double myabs_(double * A); +double mymin_(double * A, double * B); +double mymax_(double * A, double * B); +*/ +import "C" +import "unsafe" + +func MinFort(a, b float64) float64 { + ans := C.mymin_((*C.double)(&a), (*C.double)(&b)) + return float64(ans) +} + +func MaxFort(a, b float64) float64 { + ans := C.mymax_((*C.double)(&a), (*C.double)(&b)) + return float64(ans) +} + +func AbsFort(a float64) float64 { + ans := C.myabs_((*C.double)(&a)) + return float64(ans) +} + +func AtanFort(a float64) float64 { + ans := C.myatan_((*C.double)(&a)) + return float64(ans) +} + +func TanFort(a float64) float64 { + ans := C.mytan_((*C.double)(&a)) + return float64(ans) +} + +func LogFort(a float64) float64 { + ans := C.mylog_((*C.double)(&a)) + return float64(ans) +} + +func SinFort(a float64) float64 { + ans := C.mysin_((*C.double)(&a)) + return float64(ans) +} + +func CosFort(a float64) float64 { + ans := C.mycos_((*C.double)(&a)) + return float64(ans) +} + +func ExpFort(a float64) float64 { + ans := C.myexp_((*C.double)(&a)) + return float64(ans) +} + +func SqrtFort(a float64) float64 { + ans := C.mysqrt_((*C.double)(&a)) + return float64(ans) +} + +func DgamlnFort(a float64) float64 { + var ierr int + pierr := (*C.int)(unsafe.Pointer(&ierr)) + pa := (*C.double)(&a) + ans := C.dgamln_(pa, pierr) + return (float64)(ans) +} + +func ZmltFort(a, b complex128) complex128 { + ar := real(a) + ai := imag(a) + br := real(b) + bi := imag(b) + var cr, ci float64 + C.zmlt_( + (*C.double)(&ar), (*C.double)(&ai), + (*C.double)(&br), (*C.double)(&bi), + (*C.double)(&cr), (*C.double)(&ci), + ) + return complex(cr, ci) +} + +func ZdivFort(a, b complex128) complex128 { + ar := real(a) + ai := imag(a) + br := real(b) + bi := imag(b) + var cr, ci float64 + C.zdiv_( + (*C.double)(&ar), (*C.double)(&ai), + (*C.double)(&br), (*C.double)(&bi), + (*C.double)(&cr), (*C.double)(&ci), + ) + return complex(cr, ci) +} + +func ZabsFort(a complex128) float64 { + ar := real(a) + ai := imag(a) + return float64(C.mzabs_((*C.double)(&ar), (*C.double)(&ai))) +} + +func ZsqrtFort(a complex128) (b complex128) { + ar := real(a) + ai := imag(a) + + var br, bi float64 + + par := (*C.double)(&ar) + pai := (*C.double)(&ai) + pbr := (*C.double)(&br) + pbi := (*C.double)(&bi) + + C.zsqrt_(par, pai, pbr, pbi) + return complex(br, bi) +} + +func ZexpFort(a complex128) (b complex128) { + ar := real(a) + ai := imag(a) + + var br, bi float64 + + par := (*C.double)(&ar) + pai := (*C.double)(&ai) + pbr := (*C.double)(&br) + pbi := (*C.double)(&bi) + + C.zexp_(par, pai, pbr, pbi) + return complex(br, bi) +} + +func ZlogFort(a complex128) (b complex128) { + ar := real(a) + ai := imag(a) + var ierr int + var br, bi float64 + + par := (*C.double)(&ar) + pai := (*C.double)(&ai) + pbr := (*C.double)(&br) + pbi := (*C.double)(&bi) + pierr := (*C.int)(unsafe.Pointer(&ierr)) + C.zlog_(par, pai, pbr, pbi, pierr) + return complex(br, bi) +} + +func Zshch(ZR, ZI, CSHR, CSHI, CCHR, CCHI float64) (ZRout, ZIout, CSHRout, CSHIout, CCHRout, CCHIout float64) { + pzr := (*C.double)(&ZR) + pzi := (*C.double)(&ZI) + pcshr := (*C.double)(&CSHR) + pcshi := (*C.double)(&CSHI) + pcchr := (*C.double)(&CCHR) + pcchi := (*C.double)(&CCHI) + + C.zshch_(pzr, pzi, pcshr, pcshi, pcchr, pcchi) + return ZR, ZI, CSHR, CSHI, CCHR, CCHI +} + +func ZairyFort(ZR, ZI float64, ID, KODE int) (AIR, AII float64, NZ int) { + var IERR int + pzr := (*C.double)(&ZR) + pzi := (*C.double)(&ZI) + pid := (*C.int)(unsafe.Pointer(&ID)) + pkode := (*C.int)(unsafe.Pointer(&KODE)) + + pair := (*C.double)(&AIR) + paii := (*C.double)(&AII) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + pierr := (*C.int)(unsafe.Pointer(&IERR)) + C.zairy_(pzr, pzi, pid, pkode, pair, paii, pnz, pierr) + + NZ = int(*pnz) + return AIR, AII, NZ +} + +func ZksclFort(ZRR, ZRI, FNU float64, N int, YR, YI []float64, NZ int, RZR, RZI, ASCLE, TOL, ELIM float64) ( + ZRout, ZIout, FNUout float64, Nout int, YRout, YIout []float64, NZout int, RZRout, RZIout, ASCLEout, TOLout, ELIMout float64) { + + pzrr := (*C.double)(&ZRR) + pzri := (*C.double)(&ZRI) + pfnu := (*C.double)(&FNU) + pn := (*C.int)(unsafe.Pointer(&N)) + pyr := (*C.double)(&YR[0]) + pyi := (*C.double)(&YI[0]) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + przr := (*C.double)(&RZR) + przi := (*C.double)(&RZI) + pascle := (*C.double)(&ASCLE) + ptol := (*C.double)(&TOL) + pelim := (*C.double)(&ELIM) + + C.zkscl_(pzrr, pzri, pfnu, pn, pyr, pyi, pnz, przr, przi, pascle, ptol, pelim) + N = int(*pn) + NZ = int(*pnz) + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM +} + +func ZbknuFort(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout, ELIMout, ALIMout float64) { + + pzr := (*C.double)(&ZR) + pzi := (*C.double)(&ZI) + pfnu := (*C.double)(&FNU) + pkode := (*C.int)(unsafe.Pointer(&KODE)) + pn := (*C.int)(unsafe.Pointer(&N)) + pyr := (*C.double)(&YR[0]) + pyi := (*C.double)(&YI[0]) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + ptol := (*C.double)(&TOL) + pelim := (*C.double)(&ELIM) + palim := (*C.double)(&ALIM) + + C.zbknu_(pzr, pzi, pfnu, pkode, pn, pyr, pyi, pnz, ptol, pelim, palim) + KODE = int(*pkode) + N = int(*pn) + NZ = int(*pnz) + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM +} + +func ZasyiFort(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { + + pzr := (*C.double)(&ZR) + pzi := (*C.double)(&ZI) + pfnu := (*C.double)(&FNU) + pkode := (*C.int)(unsafe.Pointer(&KODE)) + pn := (*C.int)(unsafe.Pointer(&N)) + pyr := (*C.double)(&YR[0]) + pyi := (*C.double)(&YI[0]) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + prl := (*C.double)(&RL) + ptol := (*C.double)(&TOL) + pelim := (*C.double)(&ELIM) + palim := (*C.double)(&ALIM) + + C.zasyi_(pzr, pzi, pfnu, pkode, pn, pyr, pyi, pnz, prl, ptol, pelim, palim) + KODE = int(*pkode) + N = int(*pn) + NZ = int(*pnz) + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +} + +func ZuchkFort(YR, YI float64, NZ int, ASCLE, TOL float64) (YRout, YIout float64, NZout int, ASCLEout, TOLout float64) { + pyr := (*C.double)(&YR) + pyi := (*C.double)(&YI) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + pascle := (*C.double)(&ASCLE) + ptol := (*C.double)(&TOL) + + C.zuchk_(pyr, pyi, pnz, pascle, ptol) + return YR, YI, NZ, ASCLE, TOL +} + +func Zs1s2Fort(ZRR, ZRI, S1R, S1I, S2R, S2I float64, NZ int, ASCLE, ALIM float64, IUF int) ( + ZRRout, ZRIout, S1Rout, S1Iout, S2Rout, S2Iout float64, NZout int, ASCLEout, ALIMout float64, IUFout int) { + + pzrr := (*C.double)(&ZRR) + pzri := (*C.double)(&ZRI) + ps1r := (*C.double)(&S1R) + ps1i := (*C.double)(&S1I) + ps2r := (*C.double)(&S2R) + ps2i := (*C.double)(&S2I) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + pascle := (*C.double)(&ASCLE) + palim := (*C.double)(&ALIM) + piuf := (*C.int)(unsafe.Pointer(&IUF)) + + C.zs1s2_(pzrr, pzri, ps1r, ps1i, ps2r, ps2i, pnz, pascle, palim, piuf) + return ZRR, ZRI, S1R, S1I, S2R, S2I, NZ, ASCLE, ALIM, IUF +} + +func ZacaiFort(ZR, ZI, FNU float64, KODE, MR, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, MRout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { + pzr := (*C.double)(&ZR) + pzi := (*C.double)(&ZI) + pfnu := (*C.double)(&FNU) + pkode := (*C.int)(unsafe.Pointer(&KODE)) + pmr := (*C.int)(unsafe.Pointer(&MR)) + pn := (*C.int)(unsafe.Pointer(&N)) + pyr := (*C.double)(&YR[0]) + pyi := (*C.double)(&YI[0]) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + prl := (*C.double)(&RL) + ptol := (*C.double)(&TOL) + pelim := (*C.double)(&ELIM) + palim := (*C.double)(&ALIM) + + C.zacai_(pzr, pzi, pfnu, pkode, pmr, pn, pyr, pyi, pnz, prl, ptol, pelim, palim) + KODE = int(*pkode) + MR = int(*pmr) + N = int(*pn) + NZ = int(*pnz) + return ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +} + +func ZseriFort(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout, ELIMout, ALIMout float64) { + pzr := (*C.double)(&ZR) + pzi := (*C.double)(&ZI) + pfnu := (*C.double)(&FNU) + pkode := (*C.int)(unsafe.Pointer(&KODE)) + pn := (*C.int)(unsafe.Pointer(&N)) + pyr := (*C.double)(&YR[0]) + pyi := (*C.double)(&YI[0]) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + ptol := (*C.double)(&TOL) + pelim := (*C.double)(&ELIM) + palim := (*C.double)(&ALIM) + + C.zseri_(pzr, pzi, pfnu, pkode, pn, pyr, pyi, pnz, ptol, pelim, palim) + KODE = int(*pkode) + N = int(*pn) + NZ = int(*pnz) + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM +} + +func ZmlriFort(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout float64) { + pzr := (*C.double)(&ZR) + pzi := (*C.double)(&ZI) + pfnu := (*C.double)(&FNU) + pkode := (*C.int)(unsafe.Pointer(&KODE)) + pn := (*C.int)(unsafe.Pointer(&N)) + pyr := (*C.double)(&YR[0]) + pyi := (*C.double)(&YI[0]) + pnz := (*C.int)(unsafe.Pointer(&NZ)) + ptol := (*C.double)(&TOL) + + C.zmlri_(pzr, pzi, pfnu, pkode, pn, pyr, pyi, pnz, ptol) + KODE = int(*pkode) + N = int(*pn) + NZ = int(*pnz) + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/i1mach.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/i1mach.f new file mode 100644 index 00000000..b9683336 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/i1mach.f @@ -0,0 +1,113 @@ +*DECK I1MACH + INTEGER FUNCTION I1MACH(I) +C***BEGIN PROLOGUE I1MACH +C***DATE WRITTEN 750101 (YYMMDD) +C***REVISION DATE 890213 (YYMMDD) +C***CATEGORY NO. R1 +C***KEYWORDS LIBRARY=SLATEC,TYPE=INTEGER(I1MACH-I),MACHINE CONSTANTS +C***AUTHOR FOX, P. A., (BELL LABS) +C HALL, A. D., (BELL LABS) +C SCHRYER, N. L., (BELL LABS) +C***PURPOSE Returns integer machine dependent constants +C***DESCRIPTION +C +C I1MACH can be used to obtain machine-dependent parameters +C for the local machine environment. It is a function +C subroutine with one (input) argument, and can be called +C as follows, for example +C +C K = I1MACH(I) +C +C where I=1,...,16. The (output) value of K above is +C determined by the (input) value of I. The results for +C various values of I are discussed below. +C +C I/O unit numbers. +C I1MACH( 1) = the standard input unit. +C I1MACH( 2) = the standard output unit. +C I1MACH( 3) = the standard punch unit. +C I1MACH( 4) = the standard error message unit. +C +C Words. +C I1MACH( 5) = the number of bits per integer storage unit. +C I1MACH( 6) = the number of characters per integer storage unit. +C +C Integers. +C assume integers are represented in the S-digit, base-A form +C +C sign ( X(S-1)*A**(S-1) + ... + X(1)*A + X(0) ) +C +C where 0 .LE. X(I) .LT. A for I=0,...,S-1. +C I1MACH( 7) = A, the base. +C I1MACH( 8) = S, the number of base-A digits. +C I1MACH( 9) = A**S - 1, the largest magnitude. +C +C Floating-Point Numbers. +C Assume floating-point numbers are represented in the T-digit, +C base-B form +C sign (B**E)*( (X(1)/B) + ... + (X(T)/B**T) ) +C +C where 0 .LE. X(I) .LT. B for I=1,...,T, +C 0 .LT. X(1), and EMIN .LE. E .LE. EMAX. +C I1MACH(10) = B, the base. +C +C Single-Precision +C I1MACH(11) = T, the number of base-B digits. +C I1MACH(12) = EMIN, the smallest exponent E. +C I1MACH(13) = EMAX, the largest exponent E. +C +C Double-Precision +C I1MACH(14) = T, the number of base-B digits. +C I1MACH(15) = EMIN, the smallest exponent E. +C I1MACH(16) = EMAX, the largest exponent E. +C +C To alter this function for a particular environment, +C the desired set of DATA statements should be activated by +C removing the C from column 1. Also, the values of +C I1MACH(1) - I1MACH(4) should be checked for consistency +C with the local operating system. +C +C***REFERENCES FOX P.A., HALL A.D., SCHRYER N.L.,*FRAMEWORK FOR A +C PORTABLE LIBRARY*, ACM TRANSACTIONS ON MATHEMATICAL +C SOFTWARE, VOL. 4, NO. 2, JUNE 1978, PP. 177-188. +C***ROUTINES CALLED (NONE) +C***END PROLOGUE I1MACH +C + INTEGER IMACH(16),OUTPUT + SAVE IMACH + EQUIVALENCE (IMACH(4),OUTPUT) +C +C MACHINE CONSTANTS FOR THE IBM PC +C + DATA IMACH( 1) / 5 / + DATA IMACH( 2) / 6 / + DATA IMACH( 3) / 0 / + DATA IMACH( 4) / 0 / + DATA IMACH( 5) / 32 / + DATA IMACH( 6) / 4 / + DATA IMACH( 7) / 2 / + DATA IMACH( 8) / 31 / + DATA IMACH( 9) / 2147483647 / + DATA IMACH(10) / 2 / + DATA IMACH(11) / 24 / + DATA IMACH(12) / -125 / + DATA IMACH(13) / 127 / + DATA IMACH(14) / 53 / + DATA IMACH(15) / -1021 / + DATA IMACH(16) / 1023 / +C +C***FIRST EXECUTABLE STATEMENT I1MACH + IF (I .LT. 1 .OR. I .GT. 16) GO TO 10 +C + I1MACH = IMACH(I) + RETURN +C + 10 CONTINUE + WRITE (UNIT = OUTPUT, FMT = 9000) + 9000 FORMAT ('1ERROR 1 IN I1MACH - I OUT OF BOUNDS') +C +C CALL FDUMP +C +C + STOP + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myabs.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myabs.f new file mode 100644 index 00000000..5060195c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myabs.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYABS(A) + DOUBLE PRECISION A + MYABS = DABS(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myatan.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myatan.f new file mode 100644 index 00000000..0887fdae --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myatan.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYATAN(A) + DOUBLE PRECISION A + MYATAN = DATAN(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mycos.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mycos.f new file mode 100644 index 00000000..c39e46df --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mycos.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYCOS(A) + DOUBLE PRECISION A + MYCOS = DCOS(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myexp.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myexp.f new file mode 100644 index 00000000..44a2a80b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/myexp.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYEXP(A) + DOUBLE PRECISION A + MYEXP = DEXP(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mylog.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mylog.f new file mode 100644 index 00000000..ac7e3a34 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mylog.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYLOG(A) + DOUBLE PRECISION A + MYLOG = DLOG(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mymax.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mymax.f new file mode 100644 index 00000000..0438eb46 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mymax.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYMAX(A, B) + DOUBLE PRECISION A, B + MYMAX = DMAX1(A,B) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mymin.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mymin.f new file mode 100644 index 00000000..950606c6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mymin.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYMIN(A, B) + DOUBLE PRECISION A, B + MYMIN = DMIN1(A,B) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mysin.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mysin.f new file mode 100644 index 00000000..1663ed56 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mysin.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYSIN(A) + DOUBLE PRECISION A + MYSIN = DSIN(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mysqrt.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mysqrt.f new file mode 100644 index 00000000..a3998389 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mysqrt.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYSQRT(A) + DOUBLE PRECISION A + MYSQRT = SQRT(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mytan.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mytan.f new file mode 100644 index 00000000..239aa682 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/mytan.f @@ -0,0 +1,5 @@ + DOUBLE PRECISION FUNCTION MYTAN(A) + DOUBLE PRECISION A + MYTAN = DTAN(A) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/xerror.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/xerror.f new file mode 100644 index 00000000..baa55067 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/xerror.f @@ -0,0 +1,22 @@ + SUBROUTINE XERROR(MESS,NMESS,L1,L2) +C +C THIS IS A DUMMY XERROR ROUTINE TO PRINT ERROR MESSAGES WITH NMESS +C CHARACTERS. L1 AND L2 ARE DUMMY PARAMETERS TO MAKE THIS CALL +C COMPATIBLE WITH THE SLATEC XERROR ROUTINE. THIS IS A FORTRAN 77 +C ROUTINE. +C + CHARACTER*(*) MESS + NN=NMESS/70 + NR=NMESS-70*NN + IF(NR.NE.0) NN=NN+1 + K=1 + PRINT 900 + 900 FORMAT(/) + DO 10 I=1,NN + KMIN=MIN0(K+69,NMESS) + PRINT *, MESS(K:KMIN) + K=K+70 + 10 CONTINUE + PRINT 900 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zabs.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zabs.f new file mode 100644 index 00000000..23e00a64 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zabs.f @@ -0,0 +1,34 @@ + DOUBLE PRECISION FUNCTION MZABS(ZR, ZI) +C***BEGIN PROLOGUE ZABS +C***REFER TO ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY +C +C ZABS COMPUTES THE ABSOLUTE VALUE OR MAGNITUDE OF A DOUBLE +C PRECISION COMPLEX VARIABLE CMPLX(ZR,ZI) +C +C***ROUTINES CALLED (NONE) +C***END PROLOGUE ZABS + DOUBLE PRECISION ZR, ZI, U, V, Q, S + + MZABS = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + RETURN + END + +c U = DABS(ZR) +c V = DABS(ZI) +c S = U + V +C----------------------------------------------------------------------- +C S*1.0D0 MAKES AN UNNORMALIZED UNDERFLOW ON CDC MACHINES INTO A +C TRUE FLOATING ZERO +C----------------------------------------------------------------------- +c S = S*1.0D+0 +c IF (S.EQ.0.0D+0) GO TO 20 +c IF (U.GT.V) GO TO 10 +c Q = U/V +c ZABS = V*DSQRT(1.D+0+Q*Q) +c RETURN +c 10 Q = V/U +c ZABS = U*DSQRT(1.D+0+Q*Q) +c RETURN +c 20 ZABS = 0.0D+0 +c RETURN +c END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zacai.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zacai.f new file mode 100644 index 00000000..aa05a5c7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zacai.f @@ -0,0 +1,99 @@ + SUBROUTINE ZACAI(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, + * ELIM, ALIM) +C***BEGIN PROLOGUE ZACAI +C***REFER TO ZAIRY +C +C ZACAI APPLIES THE ANALYTIC CONTINUATION FORMULA +C +C K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN) +C MP=PI*MR*CMPLX(0.0,1.0) +C +C TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT +C HALF Z PLANE FOR USE WITH ZAIRY WHERE FNU=1/3 OR 2/3 AND N=1. +C ZACAI IS THE SAME AS ZACON WITH THE PARTS FOR LARGER ORDERS AND +C RECURRENCE REMOVED. A RECURSIVE CALL TO ZACON CAN RESULT IF ZACON +C IS CALLED FROM ZAIRY. +C +C***ROUTINES CALLED ZASYI,ZBKNU,ZMLRI,ZSERI,ZS1S2,D1MACH,ZABS +C***END PROLOGUE ZACAI +C COMPLEX CSGN,CSPN,C1,C2,Y,Z,ZN,CY + DOUBLE PRECISION ALIM, ARG, ASCLE, AZ, CSGNR, CSGNI, CSPNR, + * CSPNI, C1R, C1I, C2R, C2I, CYR, CYI, DFNU, ELIM, FMR, FNU, PI, + * RL, SGN, TOL, YY, YR, YI, ZR, ZI, ZNR, ZNI, D1MACH, ZABS + INTEGER INU, IUF, KODE, MR, N, NN, NW, NZ + DIMENSION YR(N), YI(N), CYR(2), CYI(2) + DATA PI / 3.14159265358979324D0 / + NZ = 0 + ZNR = -ZR + ZNI = -ZI + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + NN = N + DFNU = FNU + DBLE(FLOAT(N-1)) + IF (AZ.LE.2.0D0) GO TO 10 + IF (AZ*AZ*0.25D0.GT.DFNU+1.0D0) GO TO 20 + 10 CONTINUE +C----------------------------------------------------------------------- +C POWER SERIES FOR THE I FUNCTION +C----------------------------------------------------------------------- + CALL ZSERI(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL, ELIM, ALIM) + GO TO 40 + 20 CONTINUE + IF (AZ.LT.RL) GO TO 30 +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR LARGE Z FOR THE I FUNCTION +C----------------------------------------------------------------------- + CALL ZASYI(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM, + * ALIM) + IF (NW.LT.0) GO TO 80 + GO TO 40 + 30 CONTINUE +C----------------------------------------------------------------------- +C MILLER ALGORITHM NORMALIZED BY THE SERIES FOR THE I FUNCTION +C----------------------------------------------------------------------- + CALL ZMLRI(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL) + IF(NW.LT.0) GO TO 80 + 40 CONTINUE +C----------------------------------------------------------------------- +C ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION +C----------------------------------------------------------------------- + CALL ZBKNU(ZNR, ZNI, FNU, KODE, 1, CYR, CYI, NW, TOL, ELIM, ALIM) + IF (NW.NE.0) GO TO 80 + FMR = DBLE(FLOAT(MR)) + SGN = -DSIGN(PI,FMR) + CSGNR = 0.0D0 + CSGNI = SGN + IF (KODE.EQ.1) GO TO 50 + YY = -ZNI + CSGNR = -CSGNI*DSIN(YY) + CSGNI = CSGNI*DCOS(YY) + 50 CONTINUE +C----------------------------------------------------------------------- +C CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE +C WHEN FNU IS LARGE +C----------------------------------------------------------------------- + INU = INT(SNGL(FNU)) + ARG = (FNU-DBLE(FLOAT(INU)))*SGN + CSPNR = DCOS(ARG) + CSPNI = DSIN(ARG) + IF (MOD(INU,2).EQ.0) GO TO 60 + CSPNR = -CSPNR + CSPNI = -CSPNI + 60 CONTINUE + C1R = CYR(1) + C1I = CYI(1) + C2R = YR(1) + C2I = YI(1) + IF (KODE.EQ.1) GO TO 70 + IUF = 0 + ASCLE = 1.0D+3*D1MACH(1)/TOL + CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF) + NZ = NZ + NW + 70 CONTINUE + YR(1) = CSPNR*C1R - CSPNI*C1I + CSGNR*C2R - CSGNI*C2I + YI(1) = CSPNR*C1I + CSPNI*C1R + CSGNR*C2I + CSGNI*C2R + RETURN + 80 CONTINUE + NZ = -1 + IF(NW.EQ.(-2)) NZ=-2 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zacon.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zacon.f new file mode 100644 index 00000000..ba593590 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zacon.f @@ -0,0 +1,203 @@ + SUBROUTINE ZACON(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, FNUL, + * TOL, ELIM, ALIM) +C***BEGIN PROLOGUE ZACON +C***REFER TO ZBESK,ZBESH +C +C ZACON APPLIES THE ANALYTIC CONTINUATION FORMULA +C +C K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN) +C MP=PI*MR*CMPLX(0.0,1.0) +C +C TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT +C HALF Z PLANE +C +C***ROUTINES CALLED ZBINU,ZBKNU,ZS1S2,D1MACH,ZABS,ZMLT +C***END PROLOGUE ZACON +C COMPLEX CK,CONE,CSCL,CSCR,CSGN,CSPN,CY,CZERO,C1,C2,RZ,SC1,SC2,ST, +C *S1,S2,Y,Z,ZN + DOUBLE PRECISION ALIM, ARG, ASCLE, AS2, AZN, BRY, BSCLE, CKI, + * CKR, CONER, CPN, CSCL, CSCR, CSGNI, CSGNR, CSPNI, CSPNR, + * CSR, CSRR, CSSR, CYI, CYR, C1I, C1M, C1R, C2I, C2R, ELIM, FMR, + * FN, FNU, FNUL, PI, PTI, PTR, RAZN, RL, RZI, RZR, SC1I, SC1R, + * SC2I, SC2R, SGN, SPN, STI, STR, S1I, S1R, S2I, S2R, TOL, YI, YR, + * YY, ZEROR, ZI, ZNI, ZNR, ZR, D1MACH, ZABS + INTEGER I, INU, IUF, KFLAG, KODE, MR, N, NN, NW, NZ + DIMENSION YR(N), YI(N), CYR(2), CYI(2), CSSR(3), CSRR(3), BRY(3) + DATA PI / 3.14159265358979324D0 / + DATA ZEROR,CONER / 0.0D0,1.0D0 / + NZ = 0 + ZNR = -ZR + ZNI = -ZI + NN = N + CALL ZBINU(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, FNUL, TOL, + * ELIM, ALIM) + IF (NW.LT.0) GO TO 90 +C----------------------------------------------------------------------- +C ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION +C----------------------------------------------------------------------- + NN = MIN0(2,N) + CALL ZBKNU(ZNR, ZNI, FNU, KODE, NN, CYR, CYI, NW, TOL, ELIM, ALIM) + IF (NW.NE.0) GO TO 90 + S1R = CYR(1) + S1I = CYI(1) + FMR = DBLE(FLOAT(MR)) + SGN = -DSIGN(PI,FMR) + CSGNR = ZEROR + CSGNI = SGN + IF (KODE.EQ.1) GO TO 10 + YY = -ZNI + CPN = DCOS(YY) + SPN = DSIN(YY) + CALL ZMLT(CSGNR, CSGNI, CPN, SPN, CSGNR, CSGNI) + 10 CONTINUE +C----------------------------------------------------------------------- +C CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE +C WHEN FNU IS LARGE +C----------------------------------------------------------------------- + INU = INT(SNGL(FNU)) + ARG = (FNU-DBLE(FLOAT(INU)))*SGN + CPN = DCOS(ARG) + SPN = DSIN(ARG) + CSPNR = CPN + CSPNI = SPN + IF (MOD(INU,2).EQ.0) GO TO 20 + CSPNR = -CSPNR + CSPNI = -CSPNI + 20 CONTINUE + IUF = 0 + C1R = S1R + C1I = S1I + C2R = YR(1) + C2I = YI(1) + ASCLE = 1.0D+3*D1MACH(1)/TOL + IF (KODE.EQ.1) GO TO 30 + CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF) + NZ = NZ + NW + SC1R = C1R + SC1I = C1I + 30 CONTINUE + CALL ZMLT(CSPNR, CSPNI, C1R, C1I, STR, STI) + CALL ZMLT(CSGNR, CSGNI, C2R, C2I, PTR, PTI) + YR(1) = STR + PTR + YI(1) = STI + PTI + IF (N.EQ.1) RETURN + CSPNR = -CSPNR + CSPNI = -CSPNI + S2R = CYR(2) + S2I = CYI(2) + C1R = S2R + C1I = S2I + C2R = YR(2) + C2I = YI(2) + IF (KODE.EQ.1) GO TO 40 + CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF) + NZ = NZ + NW + SC2R = C1R + SC2I = C1I + 40 CONTINUE + CALL ZMLT(CSPNR, CSPNI, C1R, C1I, STR, STI) + CALL ZMLT(CSGNR, CSGNI, C2R, C2I, PTR, PTI) + YR(2) = STR + PTR + YI(2) = STI + PTI + IF (N.EQ.2) RETURN + CSPNR = -CSPNR + CSPNI = -CSPNI + AZN = ZABS(CMPLX(ZNR,ZNI,kind=KIND(1.0D0))) + RAZN = 1.0D0/AZN + STR = ZNR*RAZN + STI = -ZNI*RAZN + RZR = (STR+STR)*RAZN + RZI = (STI+STI)*RAZN + FN = FNU + 1.0D0 + CKR = FN*RZR + CKI = FN*RZI +C----------------------------------------------------------------------- +C SCALE NEAR EXPONENT EXTREMES DURING RECURRENCE ON K FUNCTIONS +C----------------------------------------------------------------------- + CSCL = 1.0D0/TOL + CSCR = TOL + CSSR(1) = CSCL + CSSR(2) = CONER + CSSR(3) = CSCR + CSRR(1) = CSCR + CSRR(2) = CONER + CSRR(3) = CSCL + BRY(1) = ASCLE + BRY(2) = 1.0D0/ASCLE + BRY(3) = D1MACH(2) + AS2 = ZABS(CMPLX(S2R,S2I,kind=KIND(1.0D0))) + KFLAG = 2 + IF (AS2.GT.BRY(1)) GO TO 50 + KFLAG = 1 + GO TO 60 + 50 CONTINUE + IF (AS2.LT.BRY(2)) GO TO 60 + KFLAG = 3 + 60 CONTINUE + BSCLE = BRY(KFLAG) + S1R = S1R*CSSR(KFLAG) + S1I = S1I*CSSR(KFLAG) + S2R = S2R*CSSR(KFLAG) + S2I = S2I*CSSR(KFLAG) + CSR = CSRR(KFLAG) + DO 80 I=3,N + STR = S2R + STI = S2I + S2R = CKR*STR - CKI*STI + S1R + S2I = CKR*STI + CKI*STR + S1I + S1R = STR + S1I = STI + C1R = S2R*CSR + C1I = S2I*CSR + STR = C1R + STI = C1I + C2R = YR(I) + C2I = YI(I) + IF (KODE.EQ.1) GO TO 70 + IF (IUF.LT.0) GO TO 70 + CALL ZS1S2(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF) + NZ = NZ + NW + SC1R = SC2R + SC1I = SC2I + SC2R = C1R + SC2I = C1I + IF (IUF.NE.3) GO TO 70 + IUF = -4 + S1R = SC1R*CSSR(KFLAG) + S1I = SC1I*CSSR(KFLAG) + S2R = SC2R*CSSR(KFLAG) + S2I = SC2I*CSSR(KFLAG) + STR = SC2R + STI = SC2I + 70 CONTINUE + PTR = CSPNR*C1R - CSPNI*C1I + PTI = CSPNR*C1I + CSPNI*C1R + YR(I) = PTR + CSGNR*C2R - CSGNI*C2I + YI(I) = PTI + CSGNR*C2I + CSGNI*C2R + CKR = CKR + RZR + CKI = CKI + RZI + CSPNR = -CSPNR + CSPNI = -CSPNI + IF (KFLAG.GE.3) GO TO 80 + PTR = DABS(C1R) + PTI = DABS(C1I) + C1M = DMAX1(PTR,PTI) + IF (C1M.LE.BSCLE) GO TO 80 + KFLAG = KFLAG + 1 + BSCLE = BRY(KFLAG) + S1R = S1R*CSR + S1I = S1I*CSR + S2R = STR + S2I = STI + S1R = S1R*CSSR(KFLAG) + S1I = S1I*CSSR(KFLAG) + S2R = S2R*CSSR(KFLAG) + S2I = S2I*CSSR(KFLAG) + CSR = CSRR(KFLAG) + 80 CONTINUE + RETURN + 90 CONTINUE + NZ = -1 + IF(NW.EQ.(-2)) NZ=-2 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zairy.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zairy.f new file mode 100644 index 00000000..6adab8f5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zairy.f @@ -0,0 +1,395 @@ + SUBROUTINE ZAIRY(ZR, ZI, ID, KODE, AIR, AII, NZ, IERR) +C***BEGIN PROLOGUE ZAIRY +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 890801 (YYMMDD) +C***CATEGORY NO. B5K +C***KEYWORDS AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE AIRY FUNCTIONS AI(Z) AND DAI(Z) FOR COMPLEX Z +C***DESCRIPTION +C +C ***A DOUBLE PRECISION ROUTINE*** +C ON KODE=1, ZAIRY COMPUTES THE COMPLEX AIRY FUNCTION AI(Z) OR +C ITS DERIVATIVE DAI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON +C KODE=2, A SCALING OPTION CEXP(ZTA)*AI(Z) OR CEXP(ZTA)* +C DAI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL DECAY IN +C -PI/3.LT.ARG(Z).LT.PI/3 AND THE EXPONENTIAL GROWTH IN +C PI/3.LT.ABS(ARG(Z)).LT.PI WHERE ZTA=(2/3)*Z*CSQRT(Z). +C +C WHILE THE AIRY FUNCTIONS AI(Z) AND DAI(Z)/DZ ARE ANALYTIC IN +C THE WHOLE Z PLANE, THE CORRESPONDING SCALED FUNCTIONS DEFINED +C FOR KODE=2 HAVE A CUT ALONG THE NEGATIVE REAL AXIS. +C DEFINTIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF +C MATHEMATICAL FUNCTIONS (REF. 1). +C +C INPUT ZR,ZI ARE DOUBLE PRECISION +C ZR,ZI - Z=CMPLX(ZR,ZI) +C ID - ORDER OF DERIVATIVE, ID=0 OR ID=1 +C KODE - A PARAMETER TO INDICATE THE SCALING OPTION +C KODE= 1 RETURNS +C AI=AI(Z) ON ID=0 OR +C AI=DAI(Z)/DZ ON ID=1 +C = 2 RETURNS +C AI=CEXP(ZTA)*AI(Z) ON ID=0 OR +C AI=CEXP(ZTA)*DAI(Z)/DZ ON ID=1 WHERE +C ZTA=(2/3)*Z*CSQRT(Z) +C +C OUTPUT AIR,AII ARE DOUBLE PRECISION +C AIR,AII- COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND +C KODE +C NZ - UNDERFLOW INDICATOR +C NZ= 0 , NORMAL RETURN +C NZ= 1 , AI=CMPLX(0.0D0,0.0D0) DUE TO UNDERFLOW IN +C -PI/3.LT.ARG(Z).LT.PI/3 ON KODE=1 +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +C IERR=1, INPUT ERROR - NO COMPUTATION +C IERR=2, OVERFLOW - NO COMPUTATION, REAL(ZTA) +C TOO LARGE ON KODE=1 +C IERR=3, CABS(Z) LARGE - COMPUTATION COMPLETED +C LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION +C PRODUCE LESS THAN HALF OF MACHINE ACCURACY +C IERR=4, CABS(Z) TOO LARGE - NO COMPUTATION +C COMPLETE LOSS OF ACCURACY BY ARGUMENT +C REDUCTION +C IERR=5, ERROR - NO COMPUTATION, +C ALGORITHM TERMINATION CONDITION NOT MET +C +C***LONG DESCRIPTION +C +C AI AND DAI ARE COMPUTED FOR CABS(Z).GT.1.0 FROM THE K BESSEL +C FUNCTIONS BY +C +C AI(Z)=C*SQRT(Z)*K(1/3,ZTA) , DAI(Z)=-C*Z*K(2/3,ZTA) +C C=1.0/(PI*SQRT(3.0)) +C ZTA=(2/3)*Z**(3/2) +C +C WITH THE POWER SERIES FOR CABS(Z).LE.1.0. +C +C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES +C OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF +C THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR), +C THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR +C FLAG IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS +C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +C ALSO, IF THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN +C ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT +C FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE +C LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA +C MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, +C AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE +C PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE +C PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT- +C ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG- +C NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN +C DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN +C EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, +C NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE +C PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER +C MACHINES. +C +C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT +C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), +C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF +C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +C OR -PI/2+P. +C +C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +C COMMERCE, 1955. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 +C +C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +C 1018, MAY, 1985 +C +C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +C MATH. SOFTWARE, 1986 +C +C***ROUTINES CALLED ZACAI,ZBKNU,ZEXP,ZSQRT,I1MACH,D1MACH +C***END PROLOGUE ZAIRY +C COMPLEX AI,CONE,CSQ,CY,S1,S2,TRM1,TRM2,Z,ZTA,Z3 + DOUBLE PRECISION AA, AD, AII, AIR, AK, ALIM, ATRM, AZ, AZ3, BK, + * CC, CK, COEF, CONEI, CONER, CSQI, CSQR, CYI, CYR, C1, C2, DIG, + * DK, D1, D2, ELIM, FID, FNU, PTR, RL, R1M5, SFAC, STI, STR, + * S1I, S1R, S2I, S2R, TOL, TRM1I, TRM1R, TRM2I, TRM2R, TTH, ZEROI, + * ZEROR, ZI, ZR, ZTAI, ZTAR, Z3I, Z3R, D1MACH, ZABS, ALAZ, BB + INTEGER ID, IERR, IFLAG, K, KODE, K1, K2, MR, NN, NZ, I1MACH + DIMENSION CYR(1), CYI(1) + DATA TTH, C1, C2, COEF /6.66666666666666667D-01, + * 3.55028053887817240D-01,2.58819403792806799D-01, + * 1.83776298473930683D-01/ + DATA ZEROR, ZEROI, CONER, CONEI /0.0D0,0.0D0,1.0D0,0.0D0/ +C***FIRST EXECUTABLE STATEMENT ZAIRY + IERR = 0 + NZ=0 + IF (ID.LT.0 .OR. ID.GT.1) IERR=1 + IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1 + IF (IERR.NE.0) RETURN + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + TOL = DMAX1(D1MACH(4),1.0D-18) + FID = DBLE(FLOAT(ID)) + IF (AZ.GT.1.0D0) GO TO 70 +C----------------------------------------------------------------------- +C POWER SERIES FOR CABS(Z).LE.1. +C----------------------------------------------------------------------- + S1R = CONER + S1I = CONEI + S2R = CONER + S2I = CONEI + IF (AZ.LT.TOL) GO TO 170 + AA = AZ*AZ + IF (AA.LT.TOL/AZ) GO TO 40 + TRM1R = CONER + TRM1I = CONEI + TRM2R = CONER + TRM2I = CONEI + ATRM = 1.0D0 + STR = ZR*ZR - ZI*ZI + STI = ZR*ZI + ZI*ZR + Z3R = STR*ZR - STI*ZI + Z3I = STR*ZI + STI*ZR + AZ3 = AZ*AA + AK = 2.0D0 + FID + BK = 3.0D0 - FID - FID + CK = 4.0D0 - FID + DK = 3.0D0 + FID + FID + D1 = AK*DK + D2 = BK*CK + AD = DMIN1(D1,D2) + AK = 24.0D0 + 9.0D0*FID + BK = 30.0D0 - 9.0D0*FID + DO 30 K=1,25 + STR = (TRM1R*Z3R-TRM1I*Z3I)/D1 + TRM1I = (TRM1R*Z3I+TRM1I*Z3R)/D1 + TRM1R = STR + S1R = S1R + TRM1R + S1I = S1I + TRM1I + STR = (TRM2R*Z3R-TRM2I*Z3I)/D2 + TRM2I = (TRM2R*Z3I+TRM2I*Z3R)/D2 + TRM2R = STR + S2R = S2R + TRM2R + S2I = S2I + TRM2I + ATRM = ATRM*AZ3/AD + D1 = D1 + AK + D2 = D2 + BK + AD = DMIN1(D1,D2) + IF (ATRM.LT.TOL*AD) GO TO 40 + AK = AK + 18.0D0 + BK = BK + 18.0D0 + 30 CONTINUE + 40 CONTINUE + IF (ID.EQ.1) THEN + GO TO 50 + END IF + AIR = S1R*C1 - C2*(ZR*S2R-ZI*S2I) + AII = S1I*C1 - C2*(ZR*S2I+ZI*S2R) + IF (KODE.EQ.1) RETURN + CALL ZSQRT(ZR, ZI, STR, STI) + ZTAR = TTH*(ZR*STR-ZI*STI) + ZTAI = TTH*(ZR*STI+ZI*STR) + CALL ZEXP(ZTAR, ZTAI, STR, STI) + PTR = AIR*STR - AII*STI + AII = AIR*STI + AII*STR + AIR = PTR + RETURN + 50 CONTINUE + AIR = -S2R*C2 + AII = -S2I*C2 + IF (AZ.LE.TOL) GO TO 60 + STR = ZR*S1R - ZI*S1I + STI = ZR*S1I + ZI*S1R + CC = C1/(1.0D0+FID) + AIR = AIR + CC*(STR*ZR-STI*ZI) + AII = AII + CC*(STR*ZI+STI*ZR) + 60 CONTINUE + IF (KODE.EQ.1) RETURN + CALL ZSQRT(ZR, ZI, STR, STI) + ZTAR = TTH*(ZR*STR-ZI*STI) + ZTAI = TTH*(ZR*STI+ZI*STR) + CALL ZEXP(ZTAR, ZTAI, STR, STI) + PTR = STR*AIR - STI*AII + AII = STR*AII + STI*AIR + AIR = PTR + RETURN +C----------------------------------------------------------------------- +C CASE FOR CABS(Z).GT.1.0 +C----------------------------------------------------------------------- + 70 CONTINUE + FNU = (1.0D0+FID)/3.0D0 +C----------------------------------------------------------------------- +C SET PARAMETERS RELATED TO MACHINE CONSTANTS. +C TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0D-18. +C ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. +C EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND +C EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR +C UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. +C RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. +C DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). +C----------------------------------------------------------------------- + K1 = I1MACH(15) + K2 = I1MACH(16) + R1M5 = D1MACH(5) + K = MIN0(IABS(K1),IABS(K2)) + ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0) + K1 = I1MACH(14) - 1 + AA = R1M5*DBLE(FLOAT(K1)) + DIG = DMIN1(AA,18.0D0) + AA = AA*2.303D0 + ALIM = ELIM + DMAX1(-AA,-41.45D0) + RL = 1.2D0*DIG + 3.0D0 + ALAZ = DLOG(AZ) +C-------------------------------------------------------------------------- +C TEST FOR PROPER RANGE +C----------------------------------------------------------------------- + AA=0.5D0/TOL + BB=DBLE(FLOAT(I1MACH(9)))*0.5D0 + AA=DMIN1(AA,BB) + AA=AA**TTH + IF (AZ.GT.AA) GO TO 260 + AA=DSQRT(AA) + IF (AZ.GT.AA) IERR=3 + CALL ZSQRT(ZR, ZI, CSQR, CSQI) + ZTAR = TTH*(ZR*CSQR-ZI*CSQI) + ZTAI = TTH*(ZR*CSQI+ZI*CSQR) +C----------------------------------------------------------------------- +C RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL +C----------------------------------------------------------------------- + IFLAG = 0 + SFAC = 1.0D0 + AK = ZTAI + IF (ZR.GE.0.0D0) GO TO 80 + BK = ZTAR + CK = -DABS(BK) + ZTAR = CK + ZTAI = AK + 80 CONTINUE + IF (ZI.NE.0.0D0) GO TO 90 + IF (ZR.GT.0.0D0) GO TO 90 + ZTAR = 0.0D0 + ZTAI = AK + 90 CONTINUE + AA = ZTAR + IF (AA.GE.0.0D0 .AND. ZR.GT.0.0D0) GO TO 110 + IF (KODE.EQ.2) GO TO 100 +C----------------------------------------------------------------------- +C OVERFLOW TEST +C----------------------------------------------------------------------- + IF (AA.GT.(-ALIM)) GO TO 100 + AA = -AA + 0.25D0*ALAZ + IFLAG = 1 + SFAC = TOL + IF (AA.GT.ELIM) GO TO 270 + 100 CONTINUE +C----------------------------------------------------------------------- +C CBKNU AND CACON RETURN EXP(ZTA)*K(FNU,ZTA) ON KODE=2 +C----------------------------------------------------------------------- + MR = 1 + IF (ZI.LT.0.0D0) MR = -1 + CALL ZACAI(ZTAR, ZTAI, FNU, KODE, MR, 1, CYR, CYI, NN, RL, TOL, + * ELIM, ALIM) + IF (NN.LT.0) GO TO 280 + NZ = NZ + NN + GO TO 130 + 110 CONTINUE + IF (KODE.EQ.2) GO TO 120 +C----------------------------------------------------------------------- +C UNDERFLOW TEST +C----------------------------------------------------------------------- + IF (AA.LT.ALIM) GO TO 120 + AA = -AA - 0.25D0*ALAZ + IFLAG = 2 + SFAC = 1.0D0/TOL + IF (AA.LT.(-ELIM)) GO TO 210 + 120 CONTINUE + CALL ZBKNU(ZTAR, ZTAI, FNU, KODE, 1, CYR, CYI, NZ, TOL, ELIM, + * ALIM) + 130 CONTINUE + S1R = CYR(1)*COEF + S1I = CYI(1)*COEF + IF (IFLAG.NE.0) GO TO 150 + IF (ID.EQ.1) GO TO 140 + AIR = CSQR*S1R - CSQI*S1I + AII = CSQR*S1I + CSQI*S1R + RETURN + 140 CONTINUE + AIR = -(ZR*S1R-ZI*S1I) + AII = -(ZR*S1I+ZI*S1R) + RETURN + 150 CONTINUE + S1R = S1R*SFAC + S1I = S1I*SFAC + IF (ID.EQ.1) GO TO 160 + STR = S1R*CSQR - S1I*CSQI + S1I = S1R*CSQI + S1I*CSQR + S1R = STR + AIR = S1R/SFAC + AII = S1I/SFAC + RETURN + 160 CONTINUE + STR = -(S1R*ZR-S1I*ZI) + S1I = -(S1R*ZI+S1I*ZR) + S1R = STR + AIR = S1R/SFAC + AII = S1I/SFAC + RETURN + 170 CONTINUE + AA = 1.0D+3*D1MACH(1) + S1R = ZEROR + S1I = ZEROI + IF (ID.EQ.1) GO TO 190 + IF (AZ.LE.AA) GO TO 180 + S1R = C2*ZR + S1I = C2*ZI + 180 CONTINUE + AIR = C1 - S1R + AII = -S1I + RETURN + 190 CONTINUE + AIR = -C2 + AII = 0.0D0 + AA = DSQRT(AA) + IF (AZ.LE.AA) GO TO 200 + S1R = 0.5D0*(ZR*ZR-ZI*ZI) + S1I = ZR*ZI + 200 CONTINUE + AIR = AIR + C1*S1R + AII = AII + C1*S1I + RETURN + 210 CONTINUE + NZ = 1 + AIR = ZEROR + AII = ZEROI + RETURN + 270 CONTINUE + NZ = 0 + IERR=2 + RETURN + 280 CONTINUE + IF(NN.EQ.(-1)) GO TO 270 + NZ=0 + IERR=5 + RETURN + 260 CONTINUE + IERR=4 + NZ=0 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zasyi.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zasyi.f new file mode 100644 index 00000000..139d7390 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zasyi.f @@ -0,0 +1,169 @@ + SUBROUTINE ZASYI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, + * ALIM) +C***BEGIN PROLOGUE ZASYI +C***REFER TO ZBESI,ZBESK +C +C ZASYI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY +C MEANS OF THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z) IN THE +C REGION CABS(Z).GT.MAX(RL,FNU*FNU/2). NZ=0 IS A NORMAL RETURN. +C NZ.LT.0 INDICATES AN OVERFLOW ON KODE=1. +C +C***ROUTINES CALLED D1MACH,ZABS,ZDIV,ZEXP,ZMLT,ZSQRT +C***END PROLOGUE ZASYI +C COMPLEX AK1,CK,CONE,CS1,CS2,CZ,CZERO,DK,EZ,P1,RZ,S2,Y,Z + DOUBLE PRECISION AA, AEZ, AK, AK1I, AK1R, ALIM, ARG, ARM, ATOL, + * AZ, BB, BK, CKI, CKR, CONEI, CONER, CS1I, CS1R, CS2I, CS2R, CZI, + * CZR, DFNU, DKI, DKR, DNU2, ELIM, EZI, EZR, FDN, FNU, PI, P1I, + * P1R, RAZ, RL, RTPI, RTR1, RZI, RZR, S, SGN, SQK, STI, STR, S2I, + * S2R, TOL, TZI, TZR, YI, YR, ZEROI, ZEROR, ZI, ZR, D1MACH, ZABS + INTEGER I, IB, IL, INU, J, JL, K, KODE, KODED, M, N, NN, NZ + DIMENSION YR(N), YI(N) + DATA PI, RTPI /3.14159265358979324D0 , 0.159154943091895336D0 / + DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 / +C + NZ = 0 + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + ARM = 1.0D+3*D1MACH(1) + RTR1 = DSQRT(ARM) + IL = MIN0(2,N) + DFNU = FNU + DBLE(FLOAT(N-IL)) +C----------------------------------------------------------------------- +C OVERFLOW TEST +C----------------------------------------------------------------------- + RAZ = 1.0D0/AZ + STR = ZR*RAZ + STI = -ZI*RAZ + AK1R = RTPI*STR*RAZ + AK1I = RTPI*STI*RAZ + CALL ZSQRT(AK1R, AK1I, AK1R, AK1I) + CZR = ZR + CZI = ZI + IF (KODE.NE.2) GO TO 10 + CZR = ZEROR + CZI = ZI + 10 CONTINUE + IF (DABS(CZR).GT.ELIM) GO TO 100 + DNU2 = DFNU + DFNU + KODED = 1 + IF ((DABS(CZR).GT.ALIM) .AND. (N.GT.2)) GO TO 20 + KODED = 0 + CALL ZEXP(CZR, CZI, STR, STI) + CALL ZMLT(AK1R, AK1I, STR, STI, AK1R, AK1I) + 20 CONTINUE + FDN = 0.0D0 + IF (DNU2.GT.RTR1) THEN + FDN = DNU2*DNU2 + END IF + EZR = ZR*8.0D0 + EZI = ZI*8.0D0 +C----------------------------------------------------------------------- +C WHEN Z IS IMAGINARY, THE ERROR TEST MUST BE MADE RELATIVE TO THE +C FIRST RECIPROCAL POWER SINCE THIS IS THE LEADING TERM OF THE +C EXPANSION FOR THE IMAGINARY PART. +C----------------------------------------------------------------------- + AEZ = 8.0D0*AZ + S = TOL/AEZ + JL = INT(SNGL(RL+RL)) + 2 + P1R = ZEROR + P1I = ZEROI + IF (ZI.EQ.0.0D0) GO TO 30 +C----------------------------------------------------------------------- +C CALCULATE EXP(PI*(0.5+FNU+N-IL)*I) TO MINIMIZE LOSSES OF +C SIGNIFICANCE WHEN FNU OR N IS LARGE +C----------------------------------------------------------------------- + INU = INT(SNGL(FNU)) + ARG = (FNU-DBLE(FLOAT(INU)))*PI + INU = INU + N - IL + AK = -DSIN(ARG) + BK = DCOS(ARG) + IF (ZI.LT.0.0D0) BK = -BK + P1R = AK + P1I = BK + IF (MOD(INU,2).EQ.0) GO TO 30 + P1R = -P1R + P1I = -P1I + 30 CONTINUE + DO 70 K=1,IL + SQK = FDN - 1.0D0 + ATOL = S*DABS(SQK) + SGN = 1.0D0 + CS1R = CONER + CS1I = CONEI + CS2R = CONER + CS2I = CONEI + CKR = CONER + CKI = CONEI + AK = 0.0D0 + AA = 1.0D0 + BB = AEZ + DKR = EZR + DKI = EZI + DO 40 J=1,JL + CALL ZDIV(CKR, CKI, DKR, DKI, STR, STI) + CKR = STR*SQK + CKI = STI*SQK + CS2R = CS2R + CKR + CS2I = CS2I + CKI + SGN = -SGN + CS1R = CS1R + CKR*SGN + CS1I = CS1I + CKI*SGN + DKR = DKR + EZR + DKI = DKI + EZI + AA = AA*DABS(SQK)/BB + BB = BB + AEZ + AK = AK + 8.0D0 + SQK = SQK - AK + IF (AA.LE.ATOL) THEN + GO TO 50 + END IF + 40 CONTINUE + GO TO 110 + 50 CONTINUE + S2R = CS1R + S2I = CS1I + IF (ZR+ZR.GE.ELIM) GO TO 60 + TZR = ZR + ZR + TZI = ZI + ZI + CALL ZEXP(-TZR, -TZI, STR, STI) + CALL ZMLT(STR, STI, P1R, P1I, STR, STI) + CALL ZMLT(STR, STI, CS2R, CS2I, STR, STI) + S2R = S2R + STR + S2I = S2I + STI + 60 CONTINUE + FDN = FDN + 8.0D0*DFNU + 4.0D0 + P1R = -P1R + P1I = -P1I + M = N - IL + K + YR(M) = S2R*AK1R - S2I*AK1I + YI(M) = S2R*AK1I + S2I*AK1R + 70 CONTINUE + IF (N.LE.2) RETURN + NN = N + K = NN - 2 + AK = DBLE(FLOAT(K)) + STR = ZR*RAZ + STI = -ZI*RAZ + RZR = (STR+STR)*RAZ + RZI = (STI+STI)*RAZ + IB = 3 + DO 80 I=IB,NN + YR(K) = (AK+FNU)*(RZR*YR(K+1)-RZI*YI(K+1)) + YR(K+2) + YI(K) = (AK+FNU)*(RZR*YI(K+1)+RZI*YR(K+1)) + YI(K+2) + AK = AK - 1.0D0 + K = K - 1 + 80 CONTINUE + IF (KODED.EQ.0) RETURN + CALL ZEXP(CZR, CZI, CKR, CKI) + DO 90 I=1,NN + STR = YR(I)*CKR - YI(I)*CKI + YI(I) = YR(I)*CKI + YI(I)*CKR + YR(I) = STR + 90 CONTINUE + RETURN + 100 CONTINUE + NZ = -1 + RETURN + 110 CONTINUE + NZ=-2 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesh.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesh.f new file mode 100644 index 00000000..a055ae46 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesh.f @@ -0,0 +1,348 @@ + SUBROUTINE ZBESH(ZR, ZI, FNU, KODE, M, N, CYR, CYI, NZ, IERR) +C***BEGIN PROLOGUE ZBESH +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 890801 (YYMMDD) +C***CATEGORY NO. B5K +C***KEYWORDS H-BESSEL FUNCTIONS,BESSEL FUNCTIONS OF COMPLEX ARGUMENT, +C BESSEL FUNCTIONS OF THIRD KIND,HANKEL FUNCTIONS +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE THE H-BESSEL FUNCTIONS OF A COMPLEX ARGUMENT +C***DESCRIPTION +C +C ***A DOUBLE PRECISION ROUTINE*** +C ON KODE=1, ZBESH COMPUTES AN N MEMBER SEQUENCE OF COMPLEX +C HANKEL (BESSEL) FUNCTIONS CY(J)=H(M,FNU+J-1,Z) FOR KINDS M=1 +C OR 2, REAL, NONNEGATIVE ORDERS FNU+J-1, J=1,...,N, AND COMPLEX +C Z.NE.CMPLX(0.0,0.0) IN THE CUT PLANE -PI.LT.ARG(Z).LE.PI. +C ON KODE=2, ZBESH RETURNS THE SCALED HANKEL FUNCTIONS +C +C CY(I)=EXP(-MM*Z*I)*H(M,FNU+J-1,Z) MM=3-2*M, I**2=-1. +C +C WHICH REMOVES THE EXPONENTIAL BEHAVIOR IN BOTH THE UPPER AND +C LOWER HALF PLANES. DEFINITIONS AND NOTATION ARE FOUND IN THE +C NBS HANDBOOK OF MATHEMATICAL FUNCTIONS (REF. 1). +C +C INPUT ZR,ZI,FNU ARE DOUBLE PRECISION +C ZR,ZI - Z=CMPLX(ZR,ZI), Z.NE.CMPLX(0.0D0,0.0D0), +C -PT.LT.ARG(Z).LE.PI +C FNU - ORDER OF INITIAL H FUNCTION, FNU.GE.0.0D0 +C KODE - A PARAMETER TO INDICATE THE SCALING OPTION +C KODE= 1 RETURNS +C CY(J)=H(M,FNU+J-1,Z), J=1,...,N +C = 2 RETURNS +C CY(J)=H(M,FNU+J-1,Z)*EXP(-I*Z*(3-2M)) +C J=1,...,N , I**2=-1 +C M - KIND OF HANKEL FUNCTION, M=1 OR 2 +C N - NUMBER OF MEMBERS IN THE SEQUENCE, N.GE.1 +C +C OUTPUT CYR,CYI ARE DOUBLE PRECISION +C CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS +C CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE +C CY(J)=H(M,FNU+J-1,Z) OR +C CY(J)=H(M,FNU+J-1,Z)*EXP(-I*Z*(3-2M)) J=1,...,N +C DEPENDING ON KODE, I**2=-1. +C NZ - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW, +C NZ= 0 , NORMAL RETURN +C NZ.GT.0 , FIRST NZ COMPONENTS OF CY SET TO ZERO DUE +C TO UNDERFLOW, CY(J)=CMPLX(0.0D0,0.0D0) +C J=1,...,NZ WHEN Y.GT.0.0 AND M=1 OR +C Y.LT.0.0 AND M=2. FOR THE COMPLMENTARY +C HALF PLANES, NZ STATES ONLY THE NUMBER +C OF UNDERFLOWS. +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +C IERR=1, INPUT ERROR - NO COMPUTATION +C IERR=2, OVERFLOW - NO COMPUTATION, FNU TOO +C LARGE OR CABS(Z) TOO SMALL OR BOTH +C IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE +C BUT LOSSES OF SIGNIFCANCE BY ARGUMENT +C REDUCTION PRODUCE LESS THAN HALF OF MACHINE +C ACCURACY +C IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA- +C TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI- +C CANCE BY ARGUMENT REDUCTION +C IERR=5, ERROR - NO COMPUTATION, +C ALGORITHM TERMINATION CONDITION NOT MET +C +C***LONG DESCRIPTION +C +C THE COMPUTATION IS CARRIED OUT BY THE RELATION +C +C H(M,FNU,Z)=(1/MP)*EXP(-MP*FNU)*K(FNU,Z*EXP(-MP)) +C MP=MM*HPI*I, MM=3-2*M, HPI=PI/2, I**2=-1 +C +C FOR M=1 OR 2 WHERE THE K BESSEL FUNCTION IS COMPUTED FOR THE +C RIGHT HALF PLANE RE(Z).GE.0.0. THE K FUNCTION IS CONTINUED +C TO THE LEFT HALF PLANE BY THE RELATION +C +C K(FNU,Z*EXP(MP)) = EXP(-MP*FNU)*K(FNU,Z)-MP*I(FNU,Z) +C MP=MR*PI*I, MR=+1 OR -1, RE(Z).GT.0, I**2=-1 +C +C WHERE I(FNU,Z) IS THE I BESSEL FUNCTION. +C +C EXPONENTIAL DECAY OF H(M,FNU,Z) OCCURS IN THE UPPER HALF Z +C PLANE FOR M=1 AND THE LOWER HALF Z PLANE FOR M=2. EXPONENTIAL +C GROWTH OCCURS IN THE COMPLEMENTARY HALF PLANES. SCALING +C BY EXP(-MM*Z*I) REMOVES THE EXPONENTIAL BEHAVIOR IN THE +C WHOLE Z PLANE FOR Z TO INFINITY. +C +C FOR NEGATIVE ORDERS,THE FORMULAE +C +C H(1,-FNU,Z) = H(1,FNU,Z)*CEXP( PI*FNU*I) +C H(2,-FNU,Z) = H(2,FNU,Z)*CEXP(-PI*FNU*I) +C I**2=-1 +C +C CAN BE USED. +C +C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS +C LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. +C CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN +C LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG +C IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS +C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +C IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS +C LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS +C MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE +C INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS +C RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3 +C ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION +C ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION +C ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN +C THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT +C TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS +C IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC. +C SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES. +C +C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT +C ROUNDOFF,1.0D-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), +C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF +C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +C OR -PI/2+P. +C +C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +C COMMERCE, 1955. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C BY D. E. AMOS, SAND83-0083, MAY, 1983. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 +C +C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +C 1018, MAY, 1985 +C +C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +C MATH. SOFTWARE, 1986 +C +C***ROUTINES CALLED ZACON,ZBKNU,ZBUNK,ZUOIK,ZABS,I1MACH,D1MACH +C***END PROLOGUE ZBESH +C +C COMPLEX CY,Z,ZN,ZT,CSGN + DOUBLE PRECISION AA, ALIM, ALN, ARG, AZ, CYI, CYR, DIG, ELIM, + * FMM, FN, FNU, FNUL, HPI, RHPI, RL, R1M5, SGN, STR, TOL, UFL, ZI, + * ZNI, ZNR, ZR, ZTI, D1MACH, ZABS, BB, ASCLE, RTOL, ATOL, STI, + * CSGNR, CSGNI + INTEGER I, IERR, INU, INUH, IR, K, KODE, K1, K2, M, + * MM, MR, N, NN, NUF, NW, NZ, I1MACH + DIMENSION CYR(N), CYI(N) +C + DATA HPI /1.57079632679489662D0/ +C +C***FIRST EXECUTABLE STATEMENT ZBESH + IERR = 0 + NZ=0 + IF (ZR.EQ.0.0D0 .AND. ZI.EQ.0.0D0) IERR=1 + IF (FNU.LT.0.0D0) IERR=1 + IF (M.LT.1 .OR. M.GT.2) IERR=1 + IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1 + IF (N.LT.1) IERR=1 + IF (IERR.NE.0) RETURN + NN = N +C----------------------------------------------------------------------- +C SET PARAMETERS RELATED TO MACHINE CONSTANTS. +C TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18. +C ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. +C EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND +C EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR +C UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. +C RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. +C DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). +C FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU +C----------------------------------------------------------------------- + TOL = DMAX1(D1MACH(4),1.0D-18) + K1 = I1MACH(15) + K2 = I1MACH(16) + R1M5 = D1MACH(5) + K = MIN0(IABS(K1),IABS(K2)) + ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0) + K1 = I1MACH(14) - 1 + AA = R1M5*DBLE(FLOAT(K1)) + DIG = DMIN1(AA,18.0D0) + AA = AA*2.303D0 + ALIM = ELIM + DMAX1(-AA,-41.45D0) + FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0) + RL = 1.2D0*DIG + 3.0D0 + FN = FNU + DBLE(FLOAT(NN-1)) + MM = 3 - M - M + FMM = DBLE(FLOAT(MM)) + ZNR = FMM*ZI + ZNI = -FMM*ZR +C----------------------------------------------------------------------- +C TEST FOR PROPER RANGE +C----------------------------------------------------------------------- + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + AA = 0.5D0/TOL + BB=DBLE(FLOAT(I1MACH(9)))*0.5D0 + AA = DMIN1(AA,BB) + IF (AZ.GT.AA) GO TO 260 + IF (FN.GT.AA) GO TO 260 + AA = DSQRT(AA) + IF (AZ.GT.AA) IERR=3 + IF (FN.GT.AA) IERR=3 +C----------------------------------------------------------------------- +C OVERFLOW TEST ON THE LAST MEMBER OF THE SEQUENCE +C----------------------------------------------------------------------- + UFL = D1MACH(1)*1.0D+3 + IF (AZ.LT.UFL) GO TO 230 + IF (FNU.GT.FNUL) GO TO 90 + IF (FN.LE.1.0D0) GO TO 70 + IF (FN.GT.2.0D0) GO TO 60 + IF (AZ.GT.TOL) GO TO 70 + ARG = 0.5D0*AZ + ALN = -FN*DLOG(ARG) + IF (ALN.GT.ELIM) GO TO 230 + GO TO 70 + 60 CONTINUE + CALL ZUOIK(ZNR, ZNI, FNU, KODE, 2, NN, CYR, CYI, NUF, TOL, ELIM, + * ALIM) + IF (NUF.LT.0) GO TO 230 + NZ = NZ + NUF + NN = NN - NUF +C----------------------------------------------------------------------- +C HERE NN=N OR NN=0 SINCE NUF=0,NN, OR -1 ON RETURN FROM CUOIK +C IF NUF=NN, THEN CY(I)=CZERO FOR ALL I +C----------------------------------------------------------------------- + IF (NN.EQ.0) GO TO 140 + 70 CONTINUE + IF ((ZNR.LT.0.0D0) .OR. (ZNR.EQ.0.0D0 .AND. ZNI.LT.0.0D0 .AND. + * M.EQ.2)) GO TO 80 +C----------------------------------------------------------------------- +C RIGHT HALF PLANE COMPUTATION, XN.GE.0. .AND. (XN.NE.0. .OR. +C YN.GE.0. .OR. M=1) +C----------------------------------------------------------------------- + CALL ZBKNU(ZNR, ZNI, FNU, KODE, NN, CYR, CYI, NZ, TOL, ELIM, ALIM) + GO TO 110 +C----------------------------------------------------------------------- +C LEFT HALF PLANE COMPUTATION +C----------------------------------------------------------------------- + 80 CONTINUE + MR = -MM + CALL ZACON(ZNR, ZNI, FNU, KODE, MR, NN, CYR, CYI, NW, RL, FNUL, + * TOL, ELIM, ALIM) + IF (NW.LT.0) GO TO 240 + NZ=NW + GO TO 110 + 90 CONTINUE +C----------------------------------------------------------------------- +C UNIFORM ASYMPTOTIC EXPANSIONS FOR FNU.GT.FNUL +C----------------------------------------------------------------------- + MR = 0 + IF ((ZNR.GE.0.0D0) .AND. (ZNR.NE.0.0D0 .OR. ZNI.GE.0.0D0 .OR. + * M.NE.2)) GO TO 100 + MR = -MM + IF (ZNR.NE.0.0D0 .OR. ZNI.GE.0.0D0) GO TO 100 + ZNR = -ZNR + ZNI = -ZNI + 100 CONTINUE + CALL ZBUNK(ZNR, ZNI, FNU, KODE, MR, NN, CYR, CYI, NW, TOL, ELIM, + * ALIM) + IF (NW.LT.0) GO TO 240 + NZ = NZ + NW + 110 CONTINUE +C----------------------------------------------------------------------- +C H(M,FNU,Z) = -FMM*(I/HPI)*(ZT**FNU)*K(FNU,-Z*ZT) +C +C ZT=EXP(-FMM*HPI*I) = CMPLX(0.0,-FMM), FMM=3-2*M, M=1,2 +C----------------------------------------------------------------------- + SGN = DSIGN(HPI,-FMM) +C----------------------------------------------------------------------- +C CALCULATE EXP(FNU*HPI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE +C WHEN FNU IS LARGE +C----------------------------------------------------------------------- + INU = INT(SNGL(FNU)) + INUH = INU/2 + IR = INU - 2*INUH + ARG = (FNU-DBLE(FLOAT(INU-IR)))*SGN + RHPI = 1.0D0/SGN +C ZNI = RHPI*DCOS(ARG) +C ZNR = -RHPI*DSIN(ARG) + CSGNI = RHPI*DCOS(ARG) + CSGNR = -RHPI*DSIN(ARG) + IF (MOD(INUH,2).EQ.0) GO TO 120 +C ZNR = -ZNR +C ZNI = -ZNI + CSGNR = -CSGNR + CSGNI = -CSGNI + 120 CONTINUE + ZTI = -FMM + RTOL = 1.0D0/TOL + ASCLE = UFL*RTOL + DO 130 I=1,NN +C STR = CYR(I)*ZNR - CYI(I)*ZNI +C CYI(I) = CYR(I)*ZNI + CYI(I)*ZNR +C CYR(I) = STR +C STR = -ZNI*ZTI +C ZNI = ZNR*ZTI +C ZNR = STR + AA = CYR(I) + BB = CYI(I) + ATOL = 1.0D0 + IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 135 + AA = AA*RTOL + BB = BB*RTOL + ATOL = TOL + 135 CONTINUE + STR = AA*CSGNR - BB*CSGNI + STI = AA*CSGNI + BB*CSGNR + CYR(I) = STR*ATOL + CYI(I) = STI*ATOL + STR = -CSGNI*ZTI + CSGNI = CSGNR*ZTI + CSGNR = STR + 130 CONTINUE + RETURN + 140 CONTINUE + IF (ZNR.LT.0.0D0) GO TO 230 + RETURN + 230 CONTINUE + NZ=0 + IERR=2 + RETURN + 240 CONTINUE + IF(NW.EQ.(-1)) GO TO 230 + NZ=0 + IERR=5 + RETURN + 260 CONTINUE + NZ=0 + IERR=4 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesi.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesi.f new file mode 100644 index 00000000..5f7c1407 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesi.f @@ -0,0 +1,269 @@ + SUBROUTINE ZBESI(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, IERR) +C***BEGIN PROLOGUE ZBESI +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 890801 (YYMMDD) +C***CATEGORY NO. B5K +C***KEYWORDS I-BESSEL FUNCTION,COMPLEX BESSEL FUNCTION, +C MODIFIED BESSEL FUNCTION OF THE FIRST KIND +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE I-BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C***DESCRIPTION +C +C ***A DOUBLE PRECISION ROUTINE*** +C ON KODE=1, ZBESI COMPUTES AN N MEMBER SEQUENCE OF COMPLEX +C BESSEL FUNCTIONS CY(J)=I(FNU+J-1,Z) FOR REAL, NONNEGATIVE +C ORDERS FNU+J-1, J=1,...,N AND COMPLEX Z IN THE CUT PLANE +C -PI.LT.ARG(Z).LE.PI. ON KODE=2, ZBESI RETURNS THE SCALED +C FUNCTIONS +C +C CY(J)=EXP(-ABS(X))*I(FNU+J-1,Z) J = 1,...,N , X=REAL(Z) +C +C WITH THE EXPONENTIAL GROWTH REMOVED IN BOTH THE LEFT AND +C RIGHT HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION +C ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS +C (REF. 1). +C +C INPUT ZR,ZI,FNU ARE DOUBLE PRECISION +C ZR,ZI - Z=CMPLX(ZR,ZI), -PI.LT.ARG(Z).LE.PI +C FNU - ORDER OF INITIAL I FUNCTION, FNU.GE.0.0D0 +C KODE - A PARAMETER TO INDICATE THE SCALING OPTION +C KODE= 1 RETURNS +C CY(J)=I(FNU+J-1,Z), J=1,...,N +C = 2 RETURNS +C CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X)), J=1,...,N +C N - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1 +C +C OUTPUT CYR,CYI ARE DOUBLE PRECISION +C CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS +C CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE +C CY(J)=I(FNU+J-1,Z) OR +C CY(J)=I(FNU+J-1,Z)*EXP(-ABS(X)) J=1,...,N +C DEPENDING ON KODE, X=REAL(Z) +C NZ - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW, +C NZ= 0 , NORMAL RETURN +C NZ.GT.0 , LAST NZ COMPONENTS OF CY SET TO ZERO +C TO UNDERFLOW, CY(J)=CMPLX(0.0D0,0.0D0) +C J = N-NZ+1,...,N +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +C IERR=1, INPUT ERROR - NO COMPUTATION +C IERR=2, OVERFLOW - NO COMPUTATION, REAL(Z) TOO +C LARGE ON KODE=1 +C IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE +C BUT LOSSES OF SIGNIFCANCE BY ARGUMENT +C REDUCTION PRODUCE LESS THAN HALF OF MACHINE +C ACCURACY +C IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA- +C TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI- +C CANCE BY ARGUMENT REDUCTION +C IERR=5, ERROR - NO COMPUTATION, +C ALGORITHM TERMINATION CONDITION NOT MET +C +C***LONG DESCRIPTION +C +C THE COMPUTATION IS CARRIED OUT BY THE POWER SERIES FOR +C SMALL CABS(Z), THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z), +C THE MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN AND A +C NEUMANN SERIES FOR IMTERMEDIATE MAGNITUDES, AND THE +C UNIFORM ASYMPTOTIC EXPANSIONS FOR I(FNU,Z) AND J(FNU,Z) +C FOR LARGE ORDERS. BACKWARD RECURRENCE IS USED TO GENERATE +C SEQUENCES OR REDUCE ORDERS WHEN NECESSARY. +C +C THE CALCULATIONS ABOVE ARE DONE IN THE RIGHT HALF PLANE AND +C CONTINUED INTO THE LEFT HALF PLANE BY THE FORMULA +C +C I(FNU,Z*EXP(M*PI)) = EXP(M*PI*FNU)*I(FNU,Z) REAL(Z).GT.0.0 +C M = +I OR -I, I**2=-1 +C +C FOR NEGATIVE ORDERS,THE FORMULA +C +C I(-FNU,Z) = I(FNU,Z) + (2/PI)*SIN(PI*FNU)*K(FNU,Z) +C +C CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE +C THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE +C INTEGER,THE MAGNITUDE OF I(-FNU,Z)=I(FNU,Z) IS A LARGE +C NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER, +C K(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF +C TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY +C UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN +C OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE, +C LARGE MEANS FNU.GT.CABS(Z). +C +C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS +C LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. +C CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN +C LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG +C IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS +C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +C IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS +C LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS +C MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE +C INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS +C RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3 +C ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION +C ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION +C ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN +C THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT +C TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS +C IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC. +C SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES. +C +C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT +C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), +C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF +C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +C OR -PI/2+P. +C +C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +C COMMERCE, 1955. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C BY D. E. AMOS, SAND83-0083, MAY, 1983. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 +C +C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +C 1018, MAY, 1985 +C +C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +C MATH. SOFTWARE, 1986 +C +C***ROUTINES CALLED ZBINU,I1MACH,D1MACH +C***END PROLOGUE ZBESI +C COMPLEX CONE,CSGN,CW,CY,CZERO,Z,ZN + DOUBLE PRECISION AA, ALIM, ARG, CONEI, CONER, CSGNI, CSGNR, CYI, + * CYR, DIG, ELIM, FNU, FNUL, PI, RL, R1M5, STR, TOL, ZI, ZNI, ZNR, + * ZR, D1MACH, AZ, BB, FN, ZABS, ASCLE, RTOL, ATOL, STI + INTEGER I, IERR, INU, K, KODE, K1,K2,N,NZ,NN, I1MACH + DIMENSION CYR(N), CYI(N) + DATA PI /3.14159265358979324D0/ + DATA CONER, CONEI /1.0D0,0.0D0/ +C +C***FIRST EXECUTABLE STATEMENT ZBESI + IERR = 0 + NZ=0 + IF (FNU.LT.0.0D0) IERR=1 + IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1 + IF (N.LT.1) IERR=1 + IF (IERR.NE.0) RETURN +C----------------------------------------------------------------------- +C SET PARAMETERS RELATED TO MACHINE CONSTANTS. +C TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18. +C ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. +C EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND +C EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR +C UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. +C RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. +C DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). +C FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU. +C----------------------------------------------------------------------- + TOL = DMAX1(D1MACH(4),1.0D-18) + K1 = I1MACH(15) + K2 = I1MACH(16) + R1M5 = D1MACH(5) + K = MIN0(IABS(K1),IABS(K2)) + ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0) + K1 = I1MACH(14) - 1 + AA = R1M5*DBLE(FLOAT(K1)) + DIG = DMIN1(AA,18.0D0) + AA = AA*2.303D0 + ALIM = ELIM + DMAX1(-AA,-41.45D0) + RL = 1.2D0*DIG + 3.0D0 + FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0) +C----------------------------------------------------------------------------- +C TEST FOR PROPER RANGE +C----------------------------------------------------------------------- + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + FN = FNU+DBLE(FLOAT(N-1)) + AA = 0.5D0/TOL + BB=DBLE(FLOAT(I1MACH(9)))*0.5D0 + AA = DMIN1(AA,BB) + IF (AZ.GT.AA) GO TO 260 + IF (FN.GT.AA) GO TO 260 + AA = DSQRT(AA) + IF (AZ.GT.AA) IERR=3 + IF (FN.GT.AA) IERR=3 + ZNR = ZR + ZNI = ZI + CSGNR = CONER + CSGNI = CONEI + IF (ZR.GE.0.0D0) GO TO 40 + ZNR = -ZR + ZNI = -ZI +C----------------------------------------------------------------------- +C CALCULATE CSGN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE +C WHEN FNU IS LARGE +C----------------------------------------------------------------------- + INU = INT(SNGL(FNU)) + ARG = (FNU-DBLE(FLOAT(INU)))*PI + IF (ZI.LT.0.0D0) ARG = -ARG + CSGNR = DCOS(ARG) + CSGNI = DSIN(ARG) + IF (MOD(INU,2).EQ.0) GO TO 40 + CSGNR = -CSGNR + CSGNI = -CSGNI + 40 CONTINUE + CALL ZBINU(ZNR, ZNI, FNU, KODE, N, CYR, CYI, NZ, RL, FNUL, TOL, + * ELIM, ALIM) + IF (NZ.LT.0) GO TO 120 + IF (ZR.GE.0.0D0) RETURN +C----------------------------------------------------------------------- +C ANALYTIC CONTINUATION TO THE LEFT HALF PLANE +C----------------------------------------------------------------------- + NN = N - NZ + IF (NN.EQ.0) RETURN + RTOL = 1.0D0/TOL + ASCLE = D1MACH(1)*RTOL*1.0D+3 + DO 50 I=1,NN +C STR = CYR(I)*CSGNR - CYI(I)*CSGNI +C CYI(I) = CYR(I)*CSGNI + CYI(I)*CSGNR +C CYR(I) = STR + AA = CYR(I) + BB = CYI(I) + ATOL = 1.0D0 + IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 55 + AA = AA*RTOL + BB = BB*RTOL + ATOL = TOL + 55 CONTINUE + STR = AA*CSGNR - BB*CSGNI + STI = AA*CSGNI + BB*CSGNR + CYR(I) = STR*ATOL + CYI(I) = STI*ATOL + CSGNR = -CSGNR + CSGNI = -CSGNI + 50 CONTINUE + RETURN + 120 CONTINUE + IF(NZ.EQ.(-2)) GO TO 130 + NZ = 0 + IERR=2 + RETURN + 130 CONTINUE + NZ=0 + IERR=5 + RETURN + 260 CONTINUE + NZ=0 + IERR=4 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesj.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesj.f new file mode 100644 index 00000000..1fb217f4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesj.f @@ -0,0 +1,266 @@ + SUBROUTINE ZBESJ(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, IERR) +C***BEGIN PROLOGUE ZBESJ +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 890801 (YYMMDD) +C***CATEGORY NO. B5K +C***KEYWORDS J-BESSEL FUNCTION,BESSEL FUNCTION OF COMPLEX ARGUMENT, +C BESSEL FUNCTION OF FIRST KIND +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE THE J-BESSEL FUNCTION OF A COMPLEX ARGUMENT +C***DESCRIPTION +C +C ***A DOUBLE PRECISION ROUTINE*** +C ON KODE=1, CBESJ COMPUTES AN N MEMBER SEQUENCE OF COMPLEX +C BESSEL FUNCTIONS CY(I)=J(FNU+I-1,Z) FOR REAL, NONNEGATIVE +C ORDERS FNU+I-1, I=1,...,N AND COMPLEX Z IN THE CUT PLANE +C -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESJ RETURNS THE SCALED +C FUNCTIONS +C +C CY(I)=EXP(-ABS(Y))*J(FNU+I-1,Z) I = 1,...,N , Y=AIMAG(Z) +C +C WHICH REMOVE THE EXPONENTIAL GROWTH IN BOTH THE UPPER AND +C LOWER HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION +C ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS +C (REF. 1). +C +C INPUT ZR,ZI,FNU ARE DOUBLE PRECISION +C ZR,ZI - Z=CMPLX(ZR,ZI), -PI.LT.ARG(Z).LE.PI +C FNU - ORDER OF INITIAL J FUNCTION, FNU.GE.0.0D0 +C KODE - A PARAMETER TO INDICATE THE SCALING OPTION +C KODE= 1 RETURNS +C CY(I)=J(FNU+I-1,Z), I=1,...,N +C = 2 RETURNS +C CY(I)=J(FNU+I-1,Z)EXP(-ABS(Y)), I=1,...,N +C N - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1 +C +C OUTPUT CYR,CYI ARE DOUBLE PRECISION +C CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS +C CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE +C CY(I)=J(FNU+I-1,Z) OR +C CY(I)=J(FNU+I-1,Z)EXP(-ABS(Y)) I=1,...,N +C DEPENDING ON KODE, Y=AIMAG(Z). +C NZ - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW, +C NZ= 0 , NORMAL RETURN +C NZ.GT.0 , LAST NZ COMPONENTS OF CY SET ZERO DUE +C TO UNDERFLOW, CY(I)=CMPLX(0.0D0,0.0D0), +C I = N-NZ+1,...,N +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +C IERR=1, INPUT ERROR - NO COMPUTATION +C IERR=2, OVERFLOW - NO COMPUTATION, AIMAG(Z) +C TOO LARGE ON KODE=1 +C IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE +C BUT LOSSES OF SIGNIFCANCE BY ARGUMENT +C REDUCTION PRODUCE LESS THAN HALF OF MACHINE +C ACCURACY +C IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA- +C TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI- +C CANCE BY ARGUMENT REDUCTION +C IERR=5, ERROR - NO COMPUTATION, +C ALGORITHM TERMINATION CONDITION NOT MET +C +C***LONG DESCRIPTION +C +C THE COMPUTATION IS CARRIED OUT BY THE FORMULA +C +C J(FNU,Z)=EXP( FNU*PI*I/2)*I(FNU,-I*Z) AIMAG(Z).GE.0.0 +C +C J(FNU,Z)=EXP(-FNU*PI*I/2)*I(FNU, I*Z) AIMAG(Z).LT.0.0 +C +C WHERE I**2 = -1 AND I(FNU,Z) IS THE I BESSEL FUNCTION. +C +C FOR NEGATIVE ORDERS,THE FORMULA +C +C J(-FNU,Z) = J(FNU,Z)*COS(PI*FNU) - Y(FNU,Z)*SIN(PI*FNU) +C +C CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE +C THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE +C INTEGER,THE MAGNITUDE OF J(-FNU,Z)=J(FNU,Z)*COS(PI*FNU) IS A +C LARGE NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER, +C Y(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF +C TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY +C UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN +C OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE, +C LARGE MEANS FNU.GT.CABS(Z). +C +C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS +C LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. +C CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN +C LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG +C IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS +C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +C IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS +C LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS +C MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE +C INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS +C RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3 +C ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION +C ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION +C ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN +C THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT +C TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS +C IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC. +C SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES. +C +C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT +C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), +C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF +C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +C OR -PI/2+P. +C +C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +C COMMERCE, 1955. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C BY D. E. AMOS, SAND83-0083, MAY, 1983. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 +C +C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +C 1018, MAY, 1985 +C +C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +C MATH. SOFTWARE, 1986 +C +C***ROUTINES CALLED ZBINU,I1MACH,D1MACH +C***END PROLOGUE ZBESJ +C +C COMPLEX CI,CSGN,CY,Z,ZN + DOUBLE PRECISION AA, ALIM, ARG, CII, CSGNI, CSGNR, CYI, CYR, DIG, + * ELIM, FNU, FNUL, HPI, RL, R1M5, STR, TOL, ZI, ZNI, ZNR, ZR, + * D1MACH, BB, FN, AZ, ZABS, ASCLE, RTOL, ATOL, STI + INTEGER I, IERR, INU, INUH, IR, K, KODE, K1, K2, N, NL, NZ, I1MACH + DIMENSION CYR(N), CYI(N) + DATA HPI /1.57079632679489662D0/ +C +C***FIRST EXECUTABLE STATEMENT ZBESJ + IERR = 0 + NZ=0 + IF (FNU.LT.0.0D0) IERR=1 + IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1 + IF (N.LT.1) IERR=1 + IF (IERR.NE.0) RETURN +C----------------------------------------------------------------------- +C SET PARAMETERS RELATED TO MACHINE CONSTANTS. +C TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18. +C ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. +C EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND +C EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR +C UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. +C RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. +C DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). +C FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU. +C----------------------------------------------------------------------- + TOL = DMAX1(D1MACH(4),1.0D-18) + K1 = I1MACH(15) + K2 = I1MACH(16) + R1M5 = D1MACH(5) + K = MIN0(IABS(K1),IABS(K2)) + ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0) + K1 = I1MACH(14) - 1 + AA = R1M5*DBLE(FLOAT(K1)) + DIG = DMIN1(AA,18.0D0) + AA = AA*2.303D0 + ALIM = ELIM + DMAX1(-AA,-41.45D0) + RL = 1.2D0*DIG + 3.0D0 + FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0) +C----------------------------------------------------------------------- +C TEST FOR PROPER RANGE +C----------------------------------------------------------------------- + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + FN = FNU+DBLE(FLOAT(N-1)) + AA = 0.5D0/TOL + BB=DBLE(FLOAT(I1MACH(9)))*0.5D0 + AA = DMIN1(AA,BB) + IF (AZ.GT.AA) GO TO 260 + IF (FN.GT.AA) GO TO 260 + AA = DSQRT(AA) + IF (AZ.GT.AA) IERR=3 + IF (FN.GT.AA) IERR=3 +C----------------------------------------------------------------------- +C CALCULATE CSGN=EXP(FNU*HPI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE +C WHEN FNU IS LARGE +C----------------------------------------------------------------------- + CII = 1.0D0 + INU = INT(SNGL(FNU)) + INUH = INU/2 + IR = INU - 2*INUH + ARG = (FNU-DBLE(FLOAT(INU-IR)))*HPI + CSGNR = DCOS(ARG) + CSGNI = DSIN(ARG) + IF (MOD(INUH,2).EQ.0) GO TO 40 + CSGNR = -CSGNR + CSGNI = -CSGNI + 40 CONTINUE +C----------------------------------------------------------------------- +C ZN IS IN THE RIGHT HALF PLANE +C----------------------------------------------------------------------- + ZNR = ZI + ZNI = -ZR + IF (ZI.GE.0.0D0) GO TO 50 + ZNR = -ZNR + ZNI = -ZNI + CSGNI = -CSGNI + CII = -CII + 50 CONTINUE + CALL ZBINU(ZNR, ZNI, FNU, KODE, N, CYR, CYI, NZ, RL, FNUL, TOL, + * ELIM, ALIM) + IF (NZ.LT.0) GO TO 130 + NL = N - NZ + IF (NL.EQ.0) RETURN + RTOL = 1.0D0/TOL + ASCLE = D1MACH(1)*RTOL*1.0D+3 + DO 60 I=1,NL +C STR = CYR(I)*CSGNR - CYI(I)*CSGNI +C CYI(I) = CYR(I)*CSGNI + CYI(I)*CSGNR +C CYR(I) = STR + AA = CYR(I) + BB = CYI(I) + ATOL = 1.0D0 + IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 55 + AA = AA*RTOL + BB = BB*RTOL + ATOL = TOL + 55 CONTINUE + STR = AA*CSGNR - BB*CSGNI + STI = AA*CSGNI + BB*CSGNR + CYR(I) = STR*ATOL + CYI(I) = STI*ATOL + STR = -CSGNI*CII + CSGNI = CSGNR*CII + CSGNR = STR + 60 CONTINUE + RETURN + 130 CONTINUE + IF(NZ.EQ.(-2)) GO TO 140 + NZ = 0 + IERR = 2 + RETURN + 140 CONTINUE + NZ=0 + IERR=5 + RETURN + 260 CONTINUE + NZ=0 + IERR=4 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesk.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesk.f new file mode 100644 index 00000000..c2228288 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesk.f @@ -0,0 +1,281 @@ + SUBROUTINE ZBESK(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, IERR) +C***BEGIN PROLOGUE ZBESK +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 890801 (YYMMDD) +C***CATEGORY NO. B5K +C***KEYWORDS K-BESSEL FUNCTION,COMPLEX BESSEL FUNCTION, +C MODIFIED BESSEL FUNCTION OF THE SECOND KIND, +C BESSEL FUNCTION OF THE THIRD KIND +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE K-BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C***DESCRIPTION +C +C ***A DOUBLE PRECISION ROUTINE*** +C +C ON KODE=1, CBESK COMPUTES AN N MEMBER SEQUENCE OF COMPLEX +C BESSEL FUNCTIONS CY(J)=K(FNU+J-1,Z) FOR REAL, NONNEGATIVE +C ORDERS FNU+J-1, J=1,...,N AND COMPLEX Z.NE.CMPLX(0.0,0.0) +C IN THE CUT PLANE -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESK +C RETURNS THE SCALED K FUNCTIONS, +C +C CY(J)=EXP(Z)*K(FNU+J-1,Z) , J=1,...,N, +C +C WHICH REMOVE THE EXPONENTIAL BEHAVIOR IN BOTH THE LEFT AND +C RIGHT HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND +C NOTATION ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL +C FUNCTIONS (REF. 1). +C +C INPUT ZR,ZI,FNU ARE DOUBLE PRECISION +C ZR,ZI - Z=CMPLX(ZR,ZI), Z.NE.CMPLX(0.0D0,0.0D0), +C -PI.LT.ARG(Z).LE.PI +C FNU - ORDER OF INITIAL K FUNCTION, FNU.GE.0.0D0 +C N - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1 +C KODE - A PARAMETER TO INDICATE THE SCALING OPTION +C KODE= 1 RETURNS +C CY(I)=K(FNU+I-1,Z), I=1,...,N +C = 2 RETURNS +C CY(I)=K(FNU+I-1,Z)*EXP(Z), I=1,...,N +C +C OUTPUT CYR,CYI ARE DOUBLE PRECISION +C CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS +C CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE +C CY(I)=K(FNU+I-1,Z), I=1,...,N OR +C CY(I)=K(FNU+I-1,Z)*EXP(Z), I=1,...,N +C DEPENDING ON KODE +C NZ - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW. +C NZ= 0 , NORMAL RETURN +C NZ.GT.0 , FIRST NZ COMPONENTS OF CY SET TO ZERO DUE +C TO UNDERFLOW, CY(I)=CMPLX(0.0D0,0.0D0), +C I=1,...,N WHEN X.GE.0.0. WHEN X.LT.0.0 +C NZ STATES ONLY THE NUMBER OF UNDERFLOWS +C IN THE SEQUENCE. +C +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +C IERR=1, INPUT ERROR - NO COMPUTATION +C IERR=2, OVERFLOW - NO COMPUTATION, FNU IS +C TOO LARGE OR CABS(Z) IS TOO SMALL OR BOTH +C IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE +C BUT LOSSES OF SIGNIFCANCE BY ARGUMENT +C REDUCTION PRODUCE LESS THAN HALF OF MACHINE +C ACCURACY +C IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA- +C TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI- +C CANCE BY ARGUMENT REDUCTION +C IERR=5, ERROR - NO COMPUTATION, +C ALGORITHM TERMINATION CONDITION NOT MET +C +C***LONG DESCRIPTION +C +C EQUATIONS OF THE REFERENCE ARE IMPLEMENTED FOR SMALL ORDERS +C DNU AND DNU+1.0 IN THE RIGHT HALF PLANE X.GE.0.0. FORWARD +C RECURRENCE GENERATES HIGHER ORDERS. K IS CONTINUED TO THE LEFT +C HALF PLANE BY THE RELATION +C +C K(FNU,Z*EXP(MP)) = EXP(-MP*FNU)*K(FNU,Z)-MP*I(FNU,Z) +C MP=MR*PI*I, MR=+1 OR -1, RE(Z).GT.0, I**2=-1 +C +C WHERE I(FNU,Z) IS THE I BESSEL FUNCTION. +C +C FOR LARGE ORDERS, FNU.GT.FNUL, THE K FUNCTION IS COMPUTED +C BY MEANS OF ITS UNIFORM ASYMPTOTIC EXPANSIONS. +C +C FOR NEGATIVE ORDERS, THE FORMULA +C +C K(-FNU,Z) = K(FNU,Z) +C +C CAN BE USED. +C +C CBESK ASSUMES THAT A SIGNIFICANT DIGIT SINH(X) FUNCTION IS +C AVAILABLE. +C +C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS +C LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. +C CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN +C LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG +C IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS +C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +C IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS +C LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS +C MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE +C INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS +C RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3 +C ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION +C ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION +C ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN +C THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT +C TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS +C IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC. +C SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES. +C +C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT +C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), +C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF +C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +C OR -PI/2+P. +C +C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +C COMMERCE, 1955. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C BY D. E. AMOS, SAND83-0083, MAY, 1983. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983. +C +C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +C 1018, MAY, 1985 +C +C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +C MATH. SOFTWARE, 1986 +C +C***ROUTINES CALLED ZACON,ZBKNU,ZBUNK,ZUOIK,ZABS,I1MACH,D1MACH +C***END PROLOGUE ZBESK +C +C COMPLEX CY,Z + DOUBLE PRECISION AA, ALIM, ALN, ARG, AZ, CYI, CYR, DIG, ELIM, FN, + * FNU, FNUL, RL, R1M5, TOL, UFL, ZI, ZR, D1MACH, ZABS, BB + INTEGER IERR, K, KODE, K1, K2, MR, N, NN, NUF, NW, NZ, I1MACH + DIMENSION CYR(N), CYI(N) +C***FIRST EXECUTABLE STATEMENT ZBESK + IERR = 0 + NZ=0 + IF (ZI.EQ.0.0E0 .AND. ZR.EQ.0.0E0) IERR=1 + IF (FNU.LT.0.0D0) IERR=1 + IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1 + IF (N.LT.1) IERR=1 + IF (IERR.NE.0) RETURN + NN = N +C----------------------------------------------------------------------- +C SET PARAMETERS RELATED TO MACHINE CONSTANTS. +C TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18. +C ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. +C EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND +C EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR +C UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. +C RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. +C DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). +C FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU +C----------------------------------------------------------------------- + TOL = DMAX1(D1MACH(4),1.0D-18) + K1 = I1MACH(15) + K2 = I1MACH(16) + R1M5 = D1MACH(5) + K = MIN0(IABS(K1),IABS(K2)) + ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0) + K1 = I1MACH(14) - 1 + AA = R1M5*DBLE(FLOAT(K1)) + DIG = DMIN1(AA,18.0D0) + AA = AA*2.303D0 + ALIM = ELIM + DMAX1(-AA,-41.45D0) + FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0) + RL = 1.2D0*DIG + 3.0D0 +C----------------------------------------------------------------------------- +C TEST FOR PROPER RANGE +C----------------------------------------------------------------------- + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + FN = FNU + DBLE(FLOAT(NN-1)) + AA = 0.5D0/TOL + BB=DBLE(FLOAT(I1MACH(9)))*0.5D0 + AA = DMIN1(AA,BB) + IF (AZ.GT.AA) GO TO 260 + IF (FN.GT.AA) GO TO 260 + AA = DSQRT(AA) + IF (AZ.GT.AA) IERR=3 + IF (FN.GT.AA) IERR=3 +C----------------------------------------------------------------------- +C OVERFLOW TEST ON THE LAST MEMBER OF THE SEQUENCE +C----------------------------------------------------------------------- +C UFL = DEXP(-ELIM) + UFL = D1MACH(1)*1.0D+3 + IF (AZ.LT.UFL) GO TO 180 + IF (FNU.GT.FNUL) GO TO 80 + IF (FN.LE.1.0D0) GO TO 60 + IF (FN.GT.2.0D0) GO TO 50 + IF (AZ.GT.TOL) GO TO 60 + ARG = 0.5D0*AZ + ALN = -FN*DLOG(ARG) + IF (ALN.GT.ELIM) GO TO 180 + GO TO 60 + 50 CONTINUE + CALL ZUOIK(ZR, ZI, FNU, KODE, 2, NN, CYR, CYI, NUF, TOL, ELIM, + * ALIM) + IF (NUF.LT.0) GO TO 180 + NZ = NZ + NUF + NN = NN - NUF +C----------------------------------------------------------------------- +C HERE NN=N OR NN=0 SINCE NUF=0,NN, OR -1 ON RETURN FROM CUOIK +C IF NUF=NN, THEN CY(I)=CZERO FOR ALL I +C----------------------------------------------------------------------- + IF (NN.EQ.0) GO TO 100 + 60 CONTINUE + IF (ZR.LT.0.0D0) GO TO 70 +C----------------------------------------------------------------------- +C RIGHT HALF PLANE COMPUTATION, REAL(Z).GE.0. +C----------------------------------------------------------------------- + CALL ZBKNU(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, TOL, ELIM, ALIM) + IF (NW.LT.0) GO TO 200 + NZ=NW + RETURN +C----------------------------------------------------------------------- +C LEFT HALF PLANE COMPUTATION +C PI/2.LT.ARG(Z).LE.PI AND -PI.LT.ARG(Z).LT.-PI/2. +C----------------------------------------------------------------------- + 70 CONTINUE + IF (NZ.NE.0) GO TO 180 + MR = 1 + IF (ZI.LT.0.0D0) MR = -1 + CALL ZACON(ZR, ZI, FNU, KODE, MR, NN, CYR, CYI, NW, RL, FNUL, + * TOL, ELIM, ALIM) + IF (NW.LT.0) GO TO 200 + NZ=NW + RETURN +C----------------------------------------------------------------------- +C UNIFORM ASYMPTOTIC EXPANSIONS FOR FNU.GT.FNUL +C----------------------------------------------------------------------- + 80 CONTINUE + MR = 0 + IF (ZR.GE.0.0D0) GO TO 90 + MR = 1 + IF (ZI.LT.0.0D0) MR = -1 + 90 CONTINUE + CALL ZBUNK(ZR, ZI, FNU, KODE, MR, NN, CYR, CYI, NW, TOL, ELIM, + * ALIM) + IF (NW.LT.0) GO TO 200 + NZ = NZ + NW + RETURN + 100 CONTINUE + IF (ZR.LT.0.0D0) GO TO 180 + RETURN + 180 CONTINUE + NZ = 0 + IERR=2 + RETURN + 200 CONTINUE + IF(NW.EQ.(-1)) GO TO 180 + NZ=0 + IERR=5 + RETURN + 260 CONTINUE + NZ=0 + IERR=4 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesy.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesy.f new file mode 100644 index 00000000..05ec40be --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbesy.f @@ -0,0 +1,244 @@ + SUBROUTINE ZBESY(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, CWRKR, CWRKI, + * IERR) +C***BEGIN PROLOGUE ZBESY +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 890801 (YYMMDD) +C***CATEGORY NO. B5K +C***KEYWORDS Y-BESSEL FUNCTION,BESSEL FUNCTION OF COMPLEX ARGUMENT, +C BESSEL FUNCTION OF SECOND KIND +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE THE Y-BESSEL FUNCTION OF A COMPLEX ARGUMENT +C***DESCRIPTION +C +C ***A DOUBLE PRECISION ROUTINE*** +C +C ON KODE=1, CBESY COMPUTES AN N MEMBER SEQUENCE OF COMPLEX +C BESSEL FUNCTIONS CY(I)=Y(FNU+I-1,Z) FOR REAL, NONNEGATIVE +C ORDERS FNU+I-1, I=1,...,N AND COMPLEX Z IN THE CUT PLANE +C -PI.LT.ARG(Z).LE.PI. ON KODE=2, CBESY RETURNS THE SCALED +C FUNCTIONS +C +C CY(I)=EXP(-ABS(Y))*Y(FNU+I-1,Z) I = 1,...,N , Y=AIMAG(Z) +C +C WHICH REMOVE THE EXPONENTIAL GROWTH IN BOTH THE UPPER AND +C LOWER HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION +C ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS +C (REF. 1). +C +C INPUT ZR,ZI,FNU ARE DOUBLE PRECISION +C ZR,ZI - Z=CMPLX(ZR,ZI), Z.NE.CMPLX(0.0D0,0.0D0), +C -PI.LT.ARG(Z).LE.PI +C FNU - ORDER OF INITIAL Y FUNCTION, FNU.GE.0.0D0 +C KODE - A PARAMETER TO INDICATE THE SCALING OPTION +C KODE= 1 RETURNS +C CY(I)=Y(FNU+I-1,Z), I=1,...,N +C = 2 RETURNS +C CY(I)=Y(FNU+I-1,Z)*EXP(-ABS(Y)), I=1,...,N +C WHERE Y=AIMAG(Z) +C N - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1 +C CWRKR, - DOUBLE PRECISION WORK VECTORS OF DIMENSION AT +C CWRKI AT LEAST N +C +C OUTPUT CYR,CYI ARE DOUBLE PRECISION +C CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS +C CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE +C CY(I)=Y(FNU+I-1,Z) OR +C CY(I)=Y(FNU+I-1,Z)*EXP(-ABS(Y)) I=1,...,N +C DEPENDING ON KODE. +C NZ - NZ=0 , A NORMAL RETURN +C NZ.GT.0 , NZ COMPONENTS OF CY SET TO ZERO DUE TO +C UNDERFLOW (GENERALLY ON KODE=2) +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +C IERR=1, INPUT ERROR - NO COMPUTATION +C IERR=2, OVERFLOW - NO COMPUTATION, FNU IS +C TOO LARGE OR CABS(Z) IS TOO SMALL OR BOTH +C IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE +C BUT LOSSES OF SIGNIFCANCE BY ARGUMENT +C REDUCTION PRODUCE LESS THAN HALF OF MACHINE +C ACCURACY +C IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA- +C TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI- +C CANCE BY ARGUMENT REDUCTION +C IERR=5, ERROR - NO COMPUTATION, +C ALGORITHM TERMINATION CONDITION NOT MET +C +C***LONG DESCRIPTION +C +C THE COMPUTATION IS CARRIED OUT BY THE FORMULA +C +C Y(FNU,Z)=0.5*(H(1,FNU,Z)-H(2,FNU,Z))/I +C +C WHERE I**2 = -1 AND THE HANKEL BESSEL FUNCTIONS H(1,FNU,Z) +C AND H(2,FNU,Z) ARE CALCULATED IN CBESH. +C +C FOR NEGATIVE ORDERS,THE FORMULA +C +C Y(-FNU,Z) = Y(FNU,Z)*COS(PI*FNU) + J(FNU,Z)*SIN(PI*FNU) +C +C CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO HALF ODD +C INTEGERS THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE +C POSITIVE HALF ODD INTEGER,THE MAGNITUDE OF Y(-FNU,Z)=J(FNU,Z)* +C SIN(PI*FNU) IS A LARGE NEGATIVE POWER OF TEN. BUT WHEN FNU IS +C NOT A HALF ODD INTEGER, Y(FNU,Z) DOMINATES IN MAGNITUDE WITH A +C LARGE POSITIVE POWER OF TEN AND THE MOST THAT THE SECOND TERM +C CAN BE REDUCED IS BY UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, +C WIDE CHANGES CAN OCCUR WITHIN UNIT ROUNDOFF OF A LARGE HALF +C ODD INTEGER. HERE, LARGE MEANS FNU.GT.CABS(Z). +C +C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS +C LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. +C CONSEQUENTLY, IF EITHER ONE EXCEEDS U1=SQRT(0.5/UR), THEN +C LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG +C IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS +C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +C IF EITHER IS LARGER THAN U2=0.5/UR, THEN ALL SIGNIFICANCE IS +C LOST AND IERR=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS +C MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE +C INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS +C RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3 +C ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION +C ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION +C ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN +C THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT +C TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS +C IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC. +C SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES. +C +C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT +C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), +C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF +C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +C OR -PI/2+P. +C +C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +C COMMERCE, 1955. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C BY D. E. AMOS, SAND83-0083, MAY, 1983. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 +C +C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +C 1018, MAY, 1985 +C +C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +C MATH. SOFTWARE, 1986 +C +C***ROUTINES CALLED ZBESH,I1MACH,D1MACH +C***END PROLOGUE ZBESY +C +C COMPLEX CWRK,CY,C1,C2,EX,HCI,Z,ZU,ZV + DOUBLE PRECISION CWRKI, CWRKR, CYI, CYR, C1I, C1R, C2I, C2R, + * ELIM, EXI, EXR, EY, FNU, HCII, STI, STR, TAY, ZI, ZR, DEXP, + * D1MACH, ASCLE, RTOL, ATOL, AA, BB, TOL + INTEGER I, IERR, K, KODE, K1, K2, N, NZ, NZ1, NZ2, I1MACH + DIMENSION CYR(N), CYI(N), CWRKR(N), CWRKI(N) +C***FIRST EXECUTABLE STATEMENT ZBESY + IERR = 0 + NZ=0 + IF (ZR.EQ.0.0D0 .AND. ZI.EQ.0.0D0) IERR=1 + IF (FNU.LT.0.0D0) IERR=1 + IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1 + IF (N.LT.1) IERR=1 + IF (IERR.NE.0) RETURN + HCII = 0.5D0 + CALL ZBESH(ZR, ZI, FNU, KODE, 1, N, CYR, CYI, NZ1, IERR) + IF (IERR.NE.0.AND.IERR.NE.3) GO TO 170 + CALL ZBESH(ZR, ZI, FNU, KODE, 2, N, CWRKR, CWRKI, NZ2, IERR) + IF (IERR.NE.0.AND.IERR.NE.3) GO TO 170 + NZ = MIN0(NZ1,NZ2) + IF (KODE.EQ.2) GO TO 60 + DO 50 I=1,N + STR = CWRKR(I) - CYR(I) + STI = CWRKI(I) - CYI(I) + CYR(I) = -STI*HCII + CYI(I) = STR*HCII + 50 CONTINUE + RETURN + 60 CONTINUE + TOL = DMAX1(D1MACH(4),1.0D-18) + K1 = I1MACH(15) + K2 = I1MACH(16) + K = MIN0(IABS(K1),IABS(K2)) + R1M5 = D1MACH(5) +C----------------------------------------------------------------------- +C ELIM IS THE APPROXIMATE EXPONENTIAL UNDER- AND OVERFLOW LIMIT +C----------------------------------------------------------------------- + ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0) + EXR = DCOS(ZR) + EXI = DSIN(ZR) + EY = 0.0D0 + TAY = DABS(ZI+ZI) + IF (TAY.LT.ELIM) EY = DEXP(-TAY) + IF (ZI.LT.0.0D0) GO TO 90 + C1R = EXR*EY + C1I = EXI*EY + C2R = EXR + C2I = -EXI + 70 CONTINUE + NZ = 0 + RTOL = 1.0D0/TOL + ASCLE = D1MACH(1)*RTOL*1.0D+3 + DO 80 I=1,N +C STR = C1R*CYR(I) - C1I*CYI(I) +C STI = C1R*CYI(I) + C1I*CYR(I) +C STR = -STR + C2R*CWRKR(I) - C2I*CWRKI(I) +C STI = -STI + C2R*CWRKI(I) + C2I*CWRKR(I) +C CYR(I) = -STI*HCII +C CYI(I) = STR*HCII + AA = CWRKR(I) + BB = CWRKI(I) + ATOL = 1.0D0 + IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 75 + AA = AA*RTOL + BB = BB*RTOL + ATOL = TOL + 75 CONTINUE + STR = (AA*C2R - BB*C2I)*ATOL + STI = (AA*C2I + BB*C2R)*ATOL + AA = CYR(I) + BB = CYI(I) + ATOL = 1.0D0 + IF (DMAX1(DABS(AA),DABS(BB)).GT.ASCLE) GO TO 85 + AA = AA*RTOL + BB = BB*RTOL + ATOL = TOL + 85 CONTINUE + STR = STR - (AA*C1R - BB*C1I)*ATOL + STI = STI - (AA*C1I + BB*C1R)*ATOL + CYR(I) = -STI*HCII + CYI(I) = STR*HCII + IF (STR.EQ.0.0D0 .AND. STI.EQ.0.0D0 .AND. EY.EQ.0.0D0) NZ = NZ + * + 1 + 80 CONTINUE + RETURN + 90 CONTINUE + C1R = EXR + C1I = EXI + C2R = EXR*EY + C2I = -EXI*EY + GO TO 70 + 170 CONTINUE + NZ = 0 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbinu.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbinu.f new file mode 100644 index 00000000..b740e707 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbinu.f @@ -0,0 +1,110 @@ + SUBROUTINE ZBINU(ZR, ZI, FNU, KODE, N, CYR, CYI, NZ, RL, FNUL, + * TOL, ELIM, ALIM) +C***BEGIN PROLOGUE ZBINU +C***REFER TO ZBESH,ZBESI,ZBESJ,ZBESK,ZAIRY,ZBIRY +C +C ZBINU COMPUTES THE I FUNCTION IN THE RIGHT HALF Z PLANE +C +C***ROUTINES CALLED ZABS,ZASYI,ZBUNI,ZMLRI,ZSERI,ZUOIK,ZWRSK +C***END PROLOGUE ZBINU + DOUBLE PRECISION ALIM, AZ, CWI, CWR, CYI, CYR, DFNU, ELIM, FNU, + * FNUL, RL, TOL, ZEROI, ZEROR, ZI, ZR, ZABS + INTEGER I, INW, KODE, N, NLAST, NN, NUI, NW, NZ + DIMENSION CYR(N), CYI(N), CWR(2), CWI(2) + DATA ZEROR,ZEROI / 0.0D0, 0.0D0 / +C + NZ = 0 + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + NN = N + DFNU = FNU + DBLE(FLOAT(N-1)) + IF (AZ.LE.2.0D0) GO TO 10 + IF (AZ*AZ*0.25D0.GT.DFNU+1.0D0) GO TO 20 + 10 CONTINUE +C----------------------------------------------------------------------- +C POWER SERIES +C----------------------------------------------------------------------- + CALL ZSERI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, TOL, ELIM, ALIM) + INW = IABS(NW) + NZ = NZ + INW + NN = NN - INW + IF (NN.EQ.0) RETURN + IF (NW.GE.0) GO TO 120 + DFNU = FNU + DBLE(FLOAT(NN-1)) + 20 CONTINUE + IF (AZ.LT.RL) GO TO 40 + IF (DFNU.LE.1.0D0) GO TO 30 + IF (AZ+AZ.LT.DFNU*DFNU) GO TO 50 +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR LARGE Z +C----------------------------------------------------------------------- + 30 CONTINUE + CALL ZASYI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, RL, TOL, ELIM, + * ALIM) + IF (NW.LT.0) GO TO 130 + GO TO 120 + 40 CONTINUE + IF (DFNU.LE.1.0D0) GO TO 70 + 50 CONTINUE +C----------------------------------------------------------------------- +C OVERFLOW AND UNDERFLOW TEST ON I SEQUENCE FOR MILLER ALGORITHM +C----------------------------------------------------------------------- + CALL ZUOIK(ZR, ZI, FNU, KODE, 1, NN, CYR, CYI, NW, TOL, ELIM, + * ALIM) + IF (NW.LT.0) GO TO 130 + NZ = NZ + NW + NN = NN - NW + IF (NN.EQ.0) RETURN + DFNU = FNU+DBLE(FLOAT(NN-1)) + IF (DFNU.GT.FNUL) GO TO 110 + IF (AZ.GT.FNUL) GO TO 110 + 60 CONTINUE + IF (AZ.GT.RL) GO TO 80 + 70 CONTINUE +C----------------------------------------------------------------------- +C MILLER ALGORITHM NORMALIZED BY THE SERIES +C----------------------------------------------------------------------- + CALL ZMLRI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, TOL) + IF(NW.LT.0) GO TO 130 + GO TO 120 + 80 CONTINUE +C----------------------------------------------------------------------- +C MILLER ALGORITHM NORMALIZED BY THE WRONSKIAN +C----------------------------------------------------------------------- +C----------------------------------------------------------------------- +C OVERFLOW TEST ON K FUNCTIONS USED IN WRONSKIAN +C----------------------------------------------------------------------- + CALL ZUOIK(ZR, ZI, FNU, KODE, 2, 2, CWR, CWI, NW, TOL, ELIM, + * ALIM) + IF (NW.GE.0) GO TO 100 + NZ = NN + DO 90 I=1,NN + CYR(I) = ZEROR + CYI(I) = ZEROI + 90 CONTINUE + RETURN + 100 CONTINUE + IF (NW.GT.0) GO TO 130 + CALL ZWRSK(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, CWR, CWI, TOL, + * ELIM, ALIM) + IF (NW.LT.0) GO TO 130 + GO TO 120 + 110 CONTINUE +C----------------------------------------------------------------------- +C INCREMENT FNU+NN-1 UP TO FNUL, COMPUTE AND RECUR BACKWARD +C----------------------------------------------------------------------- + NUI = INT(SNGL(FNUL-DFNU)) + 1 + NUI = MAX0(NUI,0) + CALL ZBUNI(ZR, ZI, FNU, KODE, NN, CYR, CYI, NW, NUI, NLAST, FNUL, + * TOL, ELIM, ALIM) + IF (NW.LT.0) GO TO 130 + NZ = NZ + NW + IF (NLAST.EQ.0) GO TO 120 + NN = NLAST + GO TO 60 + 120 CONTINUE + RETURN + 130 CONTINUE + NZ = -1 + IF(NW.EQ.(-2)) NZ=-2 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbiry.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbiry.f new file mode 100644 index 00000000..f042d824 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbiry.f @@ -0,0 +1,364 @@ + SUBROUTINE ZBIRY(ZR, ZI, ID, KODE, BIR, BII, IERR) +C***BEGIN PROLOGUE ZBIRY +C***DATE WRITTEN 830501 (YYMMDD) +C***REVISION DATE 890801 (YYMMDD) +C***CATEGORY NO. B5K +C***KEYWORDS AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD +C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +C***PURPOSE TO COMPUTE AIRY FUNCTIONS BI(Z) AND DBI(Z) FOR COMPLEX Z +C***DESCRIPTION +C +C ***A DOUBLE PRECISION ROUTINE*** +C ON KODE=1, CBIRY COMPUTES THE COMPLEX AIRY FUNCTION BI(Z) OR +C ITS DERIVATIVE DBI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON +C KODE=2, A SCALING OPTION CEXP(-AXZTA)*BI(Z) OR CEXP(-AXZTA)* +C DBI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL BEHAVIOR IN +C BOTH THE LEFT AND RIGHT HALF PLANES WHERE +C ZTA=(2/3)*Z*CSQRT(Z)=CMPLX(XZTA,YZTA) AND AXZTA=ABS(XZTA). +C DEFINTIONS AND NOTATION ARE FOUND IN THE NBS HANDBOOK OF +C MATHEMATICAL FUNCTIONS (REF. 1). +C +C INPUT ZR,ZI ARE DOUBLE PRECISION +C ZR,ZI - Z=CMPLX(ZR,ZI) +C ID - ORDER OF DERIVATIVE, ID=0 OR ID=1 +C KODE - A PARAMETER TO INDICATE THE SCALING OPTION +C KODE= 1 RETURNS +C BI=BI(Z) ON ID=0 OR +C BI=DBI(Z)/DZ ON ID=1 +C = 2 RETURNS +C BI=CEXP(-AXZTA)*BI(Z) ON ID=0 OR +C BI=CEXP(-AXZTA)*DBI(Z)/DZ ON ID=1 WHERE +C ZTA=(2/3)*Z*CSQRT(Z)=CMPLX(XZTA,YZTA) +C AND AXZTA=ABS(XZTA) +C +C OUTPUT BIR,BII ARE DOUBLE PRECISION +C BIR,BII- COMPLEX ANSWER DEPENDING ON THE CHOICES FOR ID AND +C KODE +C IERR - ERROR FLAG +C IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +C IERR=1, INPUT ERROR - NO COMPUTATION +C IERR=2, OVERFLOW - NO COMPUTATION, REAL(Z) +C TOO LARGE ON KODE=1 +C IERR=3, CABS(Z) LARGE - COMPUTATION COMPLETED +C LOSSES OF SIGNIFCANCE BY ARGUMENT REDUCTION +C PRODUCE LESS THAN HALF OF MACHINE ACCURACY +C IERR=4, CABS(Z) TOO LARGE - NO COMPUTATION +C COMPLETE LOSS OF ACCURACY BY ARGUMENT +C REDUCTION +C IERR=5, ERROR - NO COMPUTATION, +C ALGORITHM TERMINATION CONDITION NOT MET +C +C***LONG DESCRIPTION +C +C BI AND DBI ARE COMPUTED FOR CABS(Z).GT.1.0 FROM THE I BESSEL +C FUNCTIONS BY +C +C BI(Z)=C*SQRT(Z)*( I(-1/3,ZTA) + I(1/3,ZTA) ) +C DBI(Z)=C * Z * ( I(-2/3,ZTA) + I(2/3,ZTA) ) +C C=1.0/SQRT(3.0) +C ZTA=(2/3)*Z**(3/2) +C +C WITH THE POWER SERIES FOR CABS(Z).LE.1.0. +C +C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES +C OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF +C THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR), +C THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR +C FLAG IERR=3 IS TRIGGERED WHERE UR=DMAX1(D1MACH(4),1.0D-18) IS +C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +C ALSO, IF THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN +C ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT +C FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE +C LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA +C MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, +C AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE +C PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE +C PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT- +C ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG- +C NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN +C DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN +C EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, +C NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE +C PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER +C MACHINES. +C +C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT +C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), +C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF +C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +C SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +C OR -PI/2+P. +C +C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +C COMMERCE, 1955. +C +C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 +C +C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +C 1018, MAY, 1985 +C +C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +C MATH. SOFTWARE, 1986 +C +C***ROUTINES CALLED ZBINU,ZABS,ZDIV,ZSQRT,D1MACH,I1MACH +C***END PROLOGUE ZBIRY +C COMPLEX BI,CONE,CSQ,CY,S1,S2,TRM1,TRM2,Z,ZTA,Z3 + DOUBLE PRECISION AA, AD, AK, ALIM, ATRM, AZ, AZ3, BB, BII, BIR, + * BK, CC, CK, COEF, CONEI, CONER, CSQI, CSQR, CYI, CYR, C1, C2, + * DIG, DK, D1, D2, EAA, ELIM, FID, FMR, FNU, FNUL, PI, RL, R1M5, + * SFAC, STI, STR, S1I, S1R, S2I, S2R, TOL, TRM1I, TRM1R, TRM2I, + * TRM2R, TTH, ZI, ZR, ZTAI, ZTAR, Z3I, Z3R, D1MACH, ZABS + INTEGER ID, IERR, K, KODE, K1, K2, NZ, I1MACH + DIMENSION CYR(2), CYI(2) + DATA TTH, C1, C2, COEF, PI /6.66666666666666667D-01, + * 6.14926627446000736D-01,4.48288357353826359D-01, + * 5.77350269189625765D-01,3.14159265358979324D+00/ + DATA CONER, CONEI /1.0D0,0.0D0/ +C***FIRST EXECUTABLE STATEMENT ZBIRY + IERR = 0 + NZ=0 + IF (ID.LT.0 .OR. ID.GT.1) IERR=1 + IF (KODE.LT.1 .OR. KODE.GT.2) IERR=1 + IF (IERR.NE.0) RETURN + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + TOL = DMAX1(D1MACH(4),1.0D-18) + FID = DBLE(FLOAT(ID)) + IF (AZ.GT.1.0E0) GO TO 70 +C----------------------------------------------------------------------- +C POWER SERIES FOR CABS(Z).LE.1. +C----------------------------------------------------------------------- + S1R = CONER + S1I = CONEI + S2R = CONER + S2I = CONEI + IF (AZ.LT.TOL) GO TO 130 + AA = AZ*AZ + IF (AA.LT.TOL/AZ) GO TO 40 + TRM1R = CONER + TRM1I = CONEI + TRM2R = CONER + TRM2I = CONEI + ATRM = 1.0D0 + STR = ZR*ZR - ZI*ZI + STI = ZR*ZI + ZI*ZR + Z3R = STR*ZR - STI*ZI + Z3I = STR*ZI + STI*ZR + AZ3 = AZ*AA + AK = 2.0D0 + FID + BK = 3.0D0 - FID - FID + CK = 4.0D0 - FID + DK = 3.0D0 + FID + FID + D1 = AK*DK + D2 = BK*CK + AD = DMIN1(D1,D2) + AK = 24.0D0 + 9.0D0*FID + BK = 30.0D0 - 9.0D0*FID + DO 30 K=1,25 + STR = (TRM1R*Z3R-TRM1I*Z3I)/D1 + TRM1I = (TRM1R*Z3I+TRM1I*Z3R)/D1 + TRM1R = STR + S1R = S1R + TRM1R + S1I = S1I + TRM1I + STR = (TRM2R*Z3R-TRM2I*Z3I)/D2 + TRM2I = (TRM2R*Z3I+TRM2I*Z3R)/D2 + TRM2R = STR + S2R = S2R + TRM2R + S2I = S2I + TRM2I + ATRM = ATRM*AZ3/AD + D1 = D1 + AK + D2 = D2 + BK + AD = DMIN1(D1,D2) + IF (ATRM.LT.TOL*AD) GO TO 40 + AK = AK + 18.0D0 + BK = BK + 18.0D0 + 30 CONTINUE + 40 CONTINUE + IF (ID.EQ.1) GO TO 50 + BIR = C1*S1R + C2*(ZR*S2R-ZI*S2I) + BII = C1*S1I + C2*(ZR*S2I+ZI*S2R) + IF (KODE.EQ.1) RETURN + CALL ZSQRT(ZR, ZI, STR, STI) + ZTAR = TTH*(ZR*STR-ZI*STI) + ZTAI = TTH*(ZR*STI+ZI*STR) + AA = ZTAR + AA = -DABS(AA) + EAA = DEXP(AA) + BIR = BIR*EAA + BII = BII*EAA + RETURN + 50 CONTINUE + BIR = S2R*C2 + BII = S2I*C2 + IF (AZ.LE.TOL) GO TO 60 + CC = C1/(1.0D0+FID) + STR = S1R*ZR - S1I*ZI + STI = S1R*ZI + S1I*ZR + BIR = BIR + CC*(STR*ZR-STI*ZI) + BII = BII + CC*(STR*ZI+STI*ZR) + 60 CONTINUE + IF (KODE.EQ.1) RETURN + CALL ZSQRT(ZR, ZI, STR, STI) + ZTAR = TTH*(ZR*STR-ZI*STI) + ZTAI = TTH*(ZR*STI+ZI*STR) + AA = ZTAR + AA = -DABS(AA) + EAA = DEXP(AA) + BIR = BIR*EAA + BII = BII*EAA + RETURN +C----------------------------------------------------------------------- +C CASE FOR CABS(Z).GT.1.0 +C----------------------------------------------------------------------- + 70 CONTINUE + FNU = (1.0D0+FID)/3.0D0 +C----------------------------------------------------------------------- +C SET PARAMETERS RELATED TO MACHINE CONSTANTS. +C TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18. +C ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. +C EXP(-ELIM).LT.EXP(-ALIM)=EXP(-ELIM)/TOL AND +C EXP(ELIM).GT.EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR +C UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. +C RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. +C DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). +C FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU. +C----------------------------------------------------------------------- + K1 = I1MACH(15) + K2 = I1MACH(16) + R1M5 = D1MACH(5) + K = MIN0(IABS(K1),IABS(K2)) + ELIM = 2.303D0*(DBLE(FLOAT(K))*R1M5-3.0D0) + K1 = I1MACH(14) - 1 + AA = R1M5*DBLE(FLOAT(K1)) + DIG = DMIN1(AA,18.0D0) + AA = AA*2.303D0 + ALIM = ELIM + DMAX1(-AA,-41.45D0) + RL = 1.2D0*DIG + 3.0D0 + FNUL = 10.0D0 + 6.0D0*(DIG-3.0D0) +C----------------------------------------------------------------------- +C TEST FOR RANGE +C----------------------------------------------------------------------- + AA=0.5D0/TOL + BB=DBLE(FLOAT(I1MACH(9)))*0.5D0 + AA=DMIN1(AA,BB) + AA=AA**TTH + IF (AZ.GT.AA) GO TO 260 + AA=DSQRT(AA) + IF (AZ.GT.AA) IERR=3 + CALL ZSQRT(ZR, ZI, CSQR, CSQI) + ZTAR = TTH*(ZR*CSQR-ZI*CSQI) + ZTAI = TTH*(ZR*CSQI+ZI*CSQR) +C----------------------------------------------------------------------- +C RE(ZTA).LE.0 WHEN RE(Z).LT.0, ESPECIALLY WHEN IM(Z) IS SMALL +C----------------------------------------------------------------------- + SFAC = 1.0D0 + AK = ZTAI + IF (ZR.GE.0.0D0) GO TO 80 + BK = ZTAR + CK = -DABS(BK) + ZTAR = CK + ZTAI = AK + 80 CONTINUE + IF (ZI.NE.0.0D0 .OR. ZR.GT.0.0D0) GO TO 90 + ZTAR = 0.0D0 + ZTAI = AK + 90 CONTINUE + AA = ZTAR + IF (KODE.EQ.2) GO TO 100 +C----------------------------------------------------------------------- +C OVERFLOW TEST +C----------------------------------------------------------------------- + BB = DABS(AA) + IF (BB.LT.ALIM) GO TO 100 + BB = BB + 0.25D0*DLOG(AZ) + SFAC = TOL + IF (BB.GT.ELIM) GO TO 190 + 100 CONTINUE + FMR = 0.0D0 + IF (AA.GE.0.0D0 .AND. ZR.GT.0.0D0) GO TO 110 + FMR = PI + IF (ZI.LT.0.0D0) FMR = -PI + ZTAR = -ZTAR + ZTAI = -ZTAI + 110 CONTINUE +C----------------------------------------------------------------------- +C AA=FACTOR FOR ANALYTIC CONTINUATION OF I(FNU,ZTA) +C KODE=2 RETURNS EXP(-ABS(XZTA))*I(FNU,ZTA) FROM CBESI +C----------------------------------------------------------------------- + CALL ZBINU(ZTAR, ZTAI, FNU, KODE, 1, CYR, CYI, NZ, RL, FNUL, TOL, + * ELIM, ALIM) + IF (NZ.LT.0) GO TO 200 + AA = FMR*FNU + Z3R = SFAC + STR = DCOS(AA) + STI = DSIN(AA) + S1R = (STR*CYR(1)-STI*CYI(1))*Z3R + S1I = (STR*CYI(1)+STI*CYR(1))*Z3R + FNU = (2.0D0-FID)/3.0D0 + CALL ZBINU(ZTAR, ZTAI, FNU, KODE, 2, CYR, CYI, NZ, RL, FNUL, TOL, + * ELIM, ALIM) + CYR(1) = CYR(1)*Z3R + CYI(1) = CYI(1)*Z3R + CYR(2) = CYR(2)*Z3R + CYI(2) = CYI(2)*Z3R +C----------------------------------------------------------------------- +C BACKWARD RECUR ONE STEP FOR ORDERS -1/3 OR -2/3 +C----------------------------------------------------------------------- + CALL ZDIV(CYR(1), CYI(1), ZTAR, ZTAI, STR, STI) + S2R = (FNU+FNU)*STR + CYR(2) + S2I = (FNU+FNU)*STI + CYI(2) + AA = FMR*(FNU-1.0D0) + STR = DCOS(AA) + STI = DSIN(AA) + S1R = COEF*(S1R+S2R*STR-S2I*STI) + S1I = COEF*(S1I+S2R*STI+S2I*STR) + IF (ID.EQ.1) GO TO 120 + STR = CSQR*S1R - CSQI*S1I + S1I = CSQR*S1I + CSQI*S1R + S1R = STR + BIR = S1R/SFAC + BII = S1I/SFAC + RETURN + 120 CONTINUE + STR = ZR*S1R - ZI*S1I + S1I = ZR*S1I + ZI*S1R + S1R = STR + BIR = S1R/SFAC + BII = S1I/SFAC + RETURN + 130 CONTINUE + AA = C1*(1.0D0-FID) + FID*C2 + BIR = AA + BII = 0.0D0 + RETURN + 190 CONTINUE + IERR=2 + NZ=0 + RETURN + 200 CONTINUE + IF(NZ.EQ.(-1)) GO TO 190 + NZ=0 + IERR=5 + RETURN + 260 CONTINUE + IERR=4 + NZ=0 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbknu.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbknu.f new file mode 100644 index 00000000..ef932d40 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbknu.f @@ -0,0 +1,568 @@ + SUBROUTINE ZBKNU(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, + * ALIM) +C***BEGIN PROLOGUE ZBKNU +C***REFER TO ZBESI,ZBESK,ZAIRY,ZBESH +C +C ZBKNU COMPUTES THE K BESSEL FUNCTION IN THE RIGHT HALF Z PLANE. +C +C***ROUTINES CALLED DGAMLN,I1MACH,D1MACH,ZKSCL,ZSHCH,ZUCHK,ZABS,ZDIV, +C ZEXP,ZLOG,ZMLT,ZSQRT +C***END PROLOGUE ZBKNU +C + DOUBLE PRECISION AA, AK, ALIM, ASCLE, A1, A2, BB, BK, BRY, CAZ, + * CBI, CBR, CC, CCHI, CCHR, CKI, CKR, COEFI, COEFR, CONEI, CONER, + * CRSCR, CSCLR, CSHI, CSHR, CSI, CSR, CSRR, CSSR, CTWOR, + * CZEROI, CZEROR, CZI, CZR, DNU, DNU2, DPI, ELIM, ETEST, FC, FHS, + * FI, FK, FKS, FMUI, FMUR, FNU, FPI, FR, G1, G2, HPI, PI, PR, PTI, + * PTR, P1I, P1R, P2I, P2M, P2R, QI, QR, RAK, RCAZ, RTHPI, RZI, + * RZR, R1, S, SMUI, SMUR, SPI, STI, STR, S1I, S1R, S2I, S2R, TM, + * TOL, TTH, T1, T2, YI, YR, ZI, ZR, DGAMLN, D1MACH, ZABS, ELM, + * CELMR, ZDR, ZDI, AS, ALAS, HELIM, CYR, CYI + INTEGER I, IFLAG, INU, K, KFLAG, KK, KMAX, KODE, KODED, N, NZ, + * IDUM, I1MACH, J, IC, INUB, NW + DIMENSION YR(N), YI(N), CC(8), CSSR(3), CSRR(3), BRY(3), CYR(2), + * CYI(2) +C COMPLEX Z,Y,A,B,RZ,SMU,FU,FMU,F,FLRZ,CZ,S1,S2,CSH,CCH +C COMPLEX CK,P,Q,COEF,P1,P2,CBK,PT,CZERO,CONE,CTWO,ST,EZ,CS,DK +C + DATA KMAX / 30 / + DATA CZEROR,CZEROI,CONER,CONEI,CTWOR,R1/ + 1 0.0D0 , 0.0D0 , 1.0D0 , 0.0D0 , 2.0D0 , 2.0D0 / + DATA DPI, RTHPI, SPI ,HPI, FPI, TTH / + 1 3.14159265358979324D0, 1.25331413731550025D0, + 2 1.90985931710274403D0, 1.57079632679489662D0, + 3 1.89769999331517738D0, 6.66666666666666666D-01/ + DATA CC(1), CC(2), CC(3), CC(4), CC(5), CC(6), CC(7), CC(8)/ + 1 5.77215664901532861D-01, -4.20026350340952355D-02, + 2 -4.21977345555443367D-02, 7.21894324666309954D-03, + 3 -2.15241674114950973D-04, -2.01348547807882387D-05, + 4 1.13302723198169588D-06, 6.11609510448141582D-09/ +C + CAZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + CSCLR = 1.0D0/TOL + CRSCR = TOL + CSSR(1) = CSCLR + CSSR(2) = 1.0D0 + CSSR(3) = CRSCR + CSRR(1) = CRSCR + CSRR(2) = 1.0D0 + CSRR(3) = CSCLR + BRY(1) = 1.0D+3*D1MACH(1)/TOL + BRY(2) = 1.0D0/BRY(1) + BRY(3) = D1MACH(2) + NZ = 0 + IFLAG = 0 + KODED = KODE + RCAZ = 1.0D0/CAZ + STR = ZR*RCAZ + STI = -ZI*RCAZ + RZR = (STR+STR)*RCAZ + RZI = (STI+STI)*RCAZ + INU = INT(SNGL(FNU+0.5D0)) + DNU = FNU - DBLE(FLOAT(INU)) + IF (DABS(DNU).EQ.0.5D0) GO TO 110 + DNU2 = 0.0D0 + IF (DABS(DNU).GT.TOL) DNU2 = DNU*DNU + IF (CAZ.GT.R1) GO TO 110 +C----------------------------------------------------------------------- +C SERIES FOR CABS(Z).LE.R1 +C----------------------------------------------------------------------- + FC = 1.0D0 + CALL ZLOG(RZR, RZI, SMUR, SMUI, IDUM) + FMUR = SMUR*DNU + FMUI = SMUI*DNU + CALL ZSHCH(FMUR, FMUI, CSHR, CSHI, CCHR, CCHI) + IF (DNU.EQ.0.0D0) GO TO 10 + FC = DNU*DPI + FC = FC/DSIN(FC) + SMUR = CSHR/DNU + SMUI = CSHI/DNU + 10 CONTINUE + A2 = 1.0D0 + DNU +C----------------------------------------------------------------------- +C GAM(1-Z)*GAM(1+Z)=PI*Z/SIN(PI*Z), T1=1/GAM(1-DNU), T2=1/GAM(1+DNU) +C----------------------------------------------------------------------- + T2 = DEXP(-DGAMLN(A2,IDUM)) + T1 = 1.0D0/(T2*FC) + IF (DABS(DNU).GT.0.1D0) GO TO 40 +C----------------------------------------------------------------------- +C SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU) +C----------------------------------------------------------------------- + AK = 1.0D0 + S = CC(1) + DO 20 K=2,8 + AK = AK*DNU2 + TM = CC(K)*AK + S = S + TM + IF (DABS(TM).LT.TOL) GO TO 30 + 20 CONTINUE + 30 G1 = -S + GO TO 50 + 40 CONTINUE + G1 = (T1-T2)/(DNU+DNU) + 50 CONTINUE + G2 = (T1+T2)*0.5D0 + FR = FC*(CCHR*G1+SMUR*G2) + FI = FC*(CCHI*G1+SMUI*G2) + CALL ZEXP(FMUR, FMUI, STR, STI) + PR = 0.5D0*STR/T2 + PI = 0.5D0*STI/T2 + CALL ZDIV(0.5D0, 0.0D0, STR, STI, PTR, PTI) + QR = PTR/T1 + QI = PTI/T1 + S1R = FR + S1I = FI + S2R = PR + S2I = PI + AK = 1.0D0 + A1 = 1.0D0 + CKR = CONER + CKI = CONEI + BK = 1.0D0 - DNU2 + IF (INU.GT.0 .OR. N.GT.1) GO TO 80 +C----------------------------------------------------------------------- +C GENERATE K(FNU,Z), 0.0D0 .LE. FNU .LT. 0.5D0 AND N=1 +C----------------------------------------------------------------------- + IF (CAZ.LT.TOL) GO TO 70 + CALL ZMLT(ZR, ZI, ZR, ZI, CZR, CZI) + CZR = 0.25D0*CZR + CZI = 0.25D0*CZI + T1 = 0.25D0*CAZ*CAZ + 60 CONTINUE + FR = (FR*AK+PR+QR)/BK + FI = (FI*AK+PI+QI)/BK + STR = 1.0D0/(AK-DNU) + PR = PR*STR + PI = PI*STR + STR = 1.0D0/(AK+DNU) + QR = QR*STR + QI = QI*STR + STR = CKR*CZR - CKI*CZI + RAK = 1.0D0/AK + CKI = (CKR*CZI+CKI*CZR)*RAK + CKR = STR*RAK + S1R = CKR*FR - CKI*FI + S1R + S1I = CKR*FI + CKI*FR + S1I + A1 = A1*T1*RAK + BK = BK + AK + AK + 1.0D0 + AK = AK + 1.0D0 + IF (A1.GT.TOL) GO TO 60 + 70 CONTINUE + YR(1) = S1R + YI(1) = S1I + IF (KODED.EQ.1) RETURN + CALL ZEXP(ZR, ZI, STR, STI) + CALL ZMLT(S1R, S1I, STR, STI, YR(1), YI(1)) + RETURN +C----------------------------------------------------------------------- +C GENERATE K(DNU,Z) AND K(DNU+1,Z) FOR FORWARD RECURRENCE +C----------------------------------------------------------------------- + 80 CONTINUE + IF (CAZ.LT.TOL) GO TO 100 + CALL ZMLT(ZR, ZI, ZR, ZI, CZR, CZI) + CZR = 0.25D0*CZR + CZI = 0.25D0*CZI + T1 = 0.25D0*CAZ*CAZ + 90 CONTINUE + FR = (FR*AK+PR+QR)/BK + FI = (FI*AK+PI+QI)/BK + STR = 1.0D0/(AK-DNU) + PR = PR*STR + PI = PI*STR + STR = 1.0D0/(AK+DNU) + QR = QR*STR + QI = QI*STR + STR = CKR*CZR - CKI*CZI + RAK = 1.0D0/AK + CKI = (CKR*CZI+CKI*CZR)*RAK + CKR = STR*RAK + S1R = CKR*FR - CKI*FI + S1R + S1I = CKR*FI + CKI*FR + S1I + STR = PR - FR*AK + STI = PI - FI*AK + S2R = CKR*STR - CKI*STI + S2R + S2I = CKR*STI + CKI*STR + S2I + A1 = A1*T1*RAK + BK = BK + AK + AK + 1.0D0 + AK = AK + 1.0D0 + IF (A1.GT.TOL) GO TO 90 + 100 CONTINUE + KFLAG = 2 + A1 = FNU + 1.0D0 + AK = A1*DABS(SMUR) + IF (AK.GT.ALIM) KFLAG = 3 + STR = CSSR(KFLAG) + P2R = S2R*STR + P2I = S2I*STR + CALL ZMLT(P2R, P2I, RZR, RZI, S2R, S2I) + S1R = S1R*STR + S1I = S1I*STR + IF (KODED.EQ.1) GO TO 210 + CALL ZEXP(ZR, ZI, FR, FI) + CALL ZMLT(S1R, S1I, FR, FI, S1R, S1I) + CALL ZMLT(S2R, S2I, FR, FI, S2R, S2I) + GO TO 210 +C----------------------------------------------------------------------- +C IFLAG=0 MEANS NO UNDERFLOW OCCURRED +C IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH +C KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD +C RECURSION +C----------------------------------------------------------------------- + 110 CONTINUE + CALL ZSQRT(ZR, ZI, STR, STI) + CALL ZDIV(RTHPI, CZEROI, STR, STI, COEFR, COEFI) + KFLAG = 2 + IF (KODED.EQ.2) GO TO 120 + IF (ZR.GT.ALIM) GO TO 290 +C BLANK LINE + STR = DEXP(-ZR)*CSSR(KFLAG) + STI = -STR*DSIN(ZI) + STR = STR*DCOS(ZI) + CALL ZMLT(COEFR, COEFI, STR, STI, COEFR, COEFI) + 120 CONTINUE + IF (DABS(DNU).EQ.0.5D0) GO TO 300 +C----------------------------------------------------------------------- +C MILLER ALGORITHM FOR CABS(Z).GT.R1 +C----------------------------------------------------------------------- + AK = DCOS(DPI*DNU) + AK = DABS(AK) + IF (AK.EQ.CZEROR) GO TO 300 + FHS = DABS(0.25D0-DNU2) + IF (FHS.EQ.CZEROR) GO TO 300 +C----------------------------------------------------------------------- +C COMPUTE R2=F(E). IF CABS(Z).GE.R2, USE FORWARD RECURRENCE TO +C DETERMINE THE BACKWARD INDEX K. R2=F(E) IS A STRAIGHT LINE ON +C 12.LE.E.LE.60. E IS COMPUTED FROM 2**(-E)=B**(1-I1MACH(14))= +C TOL WHERE B IS THE BASE OF THE ARITHMETIC. +C----------------------------------------------------------------------- + T1 = DBLE(FLOAT(I1MACH(14)-1)) + T1 = T1*D1MACH(5)*3.321928094D0 + T1 = DMAX1(T1,12.0D0) + T1 = DMIN1(T1,60.0D0) + T2 = TTH*T1 - 6.0D0 + IF (ZR.NE.0.0D0) GO TO 130 + T1 = HPI + GO TO 140 + 130 CONTINUE + T1 = DATAN(ZI/ZR) + T1 = DABS(T1) + 140 CONTINUE + IF (T2.GT.CAZ) GO TO 170 +C----------------------------------------------------------------------- +C FORWARD RECURRENCE LOOP WHEN CABS(Z).GE.R2 +C----------------------------------------------------------------------- + ETEST = AK/(DPI*CAZ*TOL) + FK = CONER + IF (ETEST.LT.CONER) GO TO 180 + FKS = CTWOR + CKR = CAZ + CAZ + CTWOR + P1R = CZEROR + P2R = CONER + DO 150 I=1,KMAX + AK = FHS/FKS + CBR = CKR/(FK+CONER) + PTR = P2R + P2R = CBR*P2R - P1R*AK + P1R = PTR + CKR = CKR + CTWOR + FKS = FKS + FK + FK + CTWOR + FHS = FHS + FK + FK + FK = FK + CONER + STR = DABS(P2R)*FK + IF (ETEST.LT.STR) GO TO 160 + 150 CONTINUE + GO TO 310 + 160 CONTINUE + FK = FK + SPI*T1*DSQRT(T2/CAZ) + FHS = DABS(0.25D0-DNU2) + GO TO 180 + 170 CONTINUE +C----------------------------------------------------------------------- +C COMPUTE BACKWARD INDEX K FOR CABS(Z).LT.R2 +C----------------------------------------------------------------------- + A2 = DSQRT(CAZ) + AK = FPI*AK/(TOL*DSQRT(A2)) + AA = 3.0D0*T1/(1.0D0+CAZ) + BB = 14.7D0*T1/(28.0D0+CAZ) + AK = (DLOG(AK)+CAZ*DCOS(AA)/(1.0D0+0.008D0*CAZ))/DCOS(BB) + FK = 0.12125D0*AK*AK/CAZ + 1.5D0 + 180 CONTINUE +C----------------------------------------------------------------------- +C BACKWARD RECURRENCE LOOP FOR MILLER ALGORITHM +C----------------------------------------------------------------------- + K = INT(SNGL(FK)) + FK = DBLE(FLOAT(K)) + FKS = FK*FK + P1R = CZEROR + P1I = CZEROI + P2R = TOL + P2I = CZEROI + CSR = P2R + CSI = P2I + DO 190 I=1,K + A1 = FKS - FK + AK = (FKS+FK)/(A1+FHS) + RAK = 2.0D0/(FK+CONER) + CBR = (FK+ZR)*RAK + CBI = ZI*RAK + PTR = P2R + PTI = P2I + P2R = (PTR*CBR-PTI*CBI-P1R)*AK + P2I = (PTI*CBR+PTR*CBI-P1I)*AK + P1R = PTR + P1I = PTI + CSR = CSR + P2R + CSI = CSI + P2I + FKS = A1 - FK + CONER + FK = FK - CONER + 190 CONTINUE +C----------------------------------------------------------------------- +C COMPUTE (P2/CS)=(P2/CABS(CS))*(CONJG(CS)/CABS(CS)) FOR BETTER +C SCALING +C----------------------------------------------------------------------- + TM = ZABS(CMPLX(CSR,CSI,kind=KIND(1.0D0))) + PTR = 1.0D0/TM + S1R = P2R*PTR + S1I = P2I*PTR + CSR = CSR*PTR + CSI = -CSI*PTR + CALL ZMLT(COEFR, COEFI, S1R, S1I, STR, STI) + CALL ZMLT(STR, STI, CSR, CSI, S1R, S1I) + IF (INU.GT.0 .OR. N.GT.1) GO TO 200 + ZDR = ZR + ZDI = ZI + IF(IFLAG.EQ.1) GO TO 270 + GO TO 240 + 200 CONTINUE +C----------------------------------------------------------------------- +C COMPUTE P1/P2=(P1/CABS(P2)*CONJG(P2)/CABS(P2) FOR SCALING +C----------------------------------------------------------------------- + TM = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) + PTR = 1.0D0/TM + P1R = P1R*PTR + P1I = P1I*PTR + P2R = P2R*PTR + P2I = -P2I*PTR + CALL ZMLT(P1R, P1I, P2R, P2I, PTR, PTI) + STR = DNU + 0.5D0 - PTR + STI = -PTI + CALL ZDIV(STR, STI, ZR, ZI, STR, STI) + STR = STR + 1.0D0 + CALL ZMLT(STR, STI, S1R, S1I, S2R, S2I) +C----------------------------------------------------------------------- +C FORWARD RECURSION ON THE THREE TERM RECURSION WITH RELATION WITH +C SCALING NEAR EXPONENT EXTREMES ON KFLAG=1 OR KFLAG=3 +C----------------------------------------------------------------------- + 210 CONTINUE + STR = DNU + 1.0D0 + CKR = STR*RZR + CKI = STR*RZI + IF (N.EQ.1) INU = INU - 1 + IF (INU.GT.0) GO TO 220 + IF (N.GT.1) GO TO 215 + S1R = S2R + S1I = S2I + 215 CONTINUE + ZDR = ZR + ZDI = ZI + IF(IFLAG.EQ.1) GO TO 270 + GO TO 240 + 220 CONTINUE + INUB = 1 + IF(IFLAG.EQ.1) GO TO 261 + 225 CONTINUE + P1R = CSRR(KFLAG) + ASCLE = BRY(KFLAG) + DO 230 I=INUB,INU + STR = S2R + STI = S2I + S2R = CKR*STR - CKI*STI + S1R + S2I = CKR*STI + CKI*STR + S1I + S1R = STR + S1I = STI + CKR = CKR + RZR + CKI = CKI + RZI + IF (KFLAG.GE.3) GO TO 230 + P2R = S2R*P1R + P2I = S2I*P1R + STR = DABS(P2R) + STI = DABS(P2I) + P2M = DMAX1(STR,STI) + IF (P2M.LE.ASCLE) GO TO 230 + KFLAG = KFLAG + 1 + ASCLE = BRY(KFLAG) + S1R = S1R*P1R + S1I = S1I*P1R + S2R = P2R + S2I = P2I + STR = CSSR(KFLAG) + S1R = S1R*STR + S1I = S1I*STR + S2R = S2R*STR + S2I = S2I*STR + P1R = CSRR(KFLAG) + 230 CONTINUE + IF (N.NE.1) GO TO 240 + S1R = S2R + S1I = S2I + 240 CONTINUE + STR = CSRR(KFLAG) + YR(1) = S1R*STR + YI(1) = S1I*STR + IF (N.EQ.1) RETURN + YR(2) = S2R*STR + YI(2) = S2I*STR + IF (N.EQ.2) RETURN + KK = 2 + 250 CONTINUE + KK = KK + 1 + IF (KK.GT.N) RETURN + P1R = CSRR(KFLAG) + ASCLE = BRY(KFLAG) + DO 260 I=KK,N + P2R = S2R + P2I = S2I + S2R = CKR*P2R - CKI*P2I + S1R + S2I = CKI*P2R + CKR*P2I + S1I + S1R = P2R + S1I = P2I + CKR = CKR + RZR + CKI = CKI + RZI + P2R = S2R*P1R + P2I = S2I*P1R + YR(I) = P2R + YI(I) = P2I + IF (KFLAG.GE.3) GO TO 260 + STR = DABS(P2R) + STI = DABS(P2I) + P2M = DMAX1(STR,STI) + IF (P2M.LE.ASCLE) GO TO 260 + KFLAG = KFLAG + 1 + ASCLE = BRY(KFLAG) + S1R = S1R*P1R + S1I = S1I*P1R + S2R = P2R + S2I = P2I + STR = CSSR(KFLAG) + S1R = S1R*STR + S1I = S1I*STR + S2R = S2R*STR + S2I = S2I*STR + P1R = CSRR(KFLAG) + 260 CONTINUE + RETURN +C----------------------------------------------------------------------- +C IFLAG=1 CASES, FORWARD RECURRENCE ON SCALED VALUES ON UNDERFLOW +C----------------------------------------------------------------------- + 261 CONTINUE + HELIM = 0.5D0*ELIM + ELM = DEXP(-ELIM) + CELMR = ELM + ASCLE = BRY(1) + ZDR = ZR + ZDI = ZI + IC = -1 + J = 2 + DO 262 I=1,INU + STR = S2R + STI = S2I + S2R = STR*CKR-STI*CKI+S1R + S2I = STI*CKR+STR*CKI+S1I + S1R = STR + S1I = STI + CKR = CKR+RZR + CKI = CKI+RZI + AS = ZABS(CMPLX(S2R,S2I,kind=KIND(1.0D0))) + ALAS = DLOG(AS) + P2R = -ZDR+ALAS + IF(P2R.LT.(-ELIM)) GO TO 263 + CALL ZLOG(S2R,S2I,STR,STI,IDUM) + P2R = -ZDR+STR + P2I = -ZDI+STI + P2M = DEXP(P2R)/TOL + P1R = P2M*DCOS(P2I) + P1I = P2M*DSIN(P2I) + CALL ZUCHK(P1R,P1I,NW,ASCLE,TOL) + IF(NW.NE.0) GO TO 263 + J = 3 - J + CYR(J) = P1R + CYI(J) = P1I + IF(IC.EQ.(I-1)) GO TO 264 + IC = I + GO TO 262 + 263 CONTINUE + IF(ALAS.LT.HELIM) GO TO 262 + ZDR = ZDR-ELIM + S1R = S1R*CELMR + S1I = S1I*CELMR + S2R = S2R*CELMR + S2I = S2I*CELMR + 262 CONTINUE + IF(N.NE.1) GO TO 270 + S1R = S2R + S1I = S2I + GO TO 270 + 264 CONTINUE + KFLAG = 1 + INUB = I+1 + S2R = CYR(J) + S2I = CYI(J) + J = 3 - J + S1R = CYR(J) + S1I = CYI(J) + IF(INUB.LE.INU) GO TO 225 + IF(N.NE.1) GO TO 240 + S1R = S2R + S1I = S2I + GO TO 240 + 270 CONTINUE + YR(1) = S1R + YI(1) = S1I + IF(N.EQ.1) GO TO 280 + YR(2) = S2R + YI(2) = S2I + 280 CONTINUE + ASCLE = BRY(1) + CALL ZKSCL(ZDR,ZDI,FNU,N,YR,YI,NZ,RZR,RZI,ASCLE,TOL,ELIM) + INU = N - NZ + IF (INU.LE.0) RETURN + KK = NZ + 1 + S1R = YR(KK) + S1I = YI(KK) + YR(KK) = S1R*CSRR(1) + YI(KK) = S1I*CSRR(1) + IF (INU.EQ.1) RETURN + KK = NZ + 2 + S2R = YR(KK) + S2I = YI(KK) + YR(KK) = S2R*CSRR(1) + YI(KK) = S2I*CSRR(1) + IF (INU.EQ.2) RETURN + T2 = FNU + DBLE(FLOAT(KK-1)) + CKR = T2*RZR + CKI = T2*RZI + KFLAG = 1 + GO TO 250 + 290 CONTINUE +C----------------------------------------------------------------------- +C SCALE BY DEXP(Z), IFLAG = 1 CASES +C----------------------------------------------------------------------- + KODED = 2 + IFLAG = 1 + KFLAG = 2 + GO TO 120 +C----------------------------------------------------------------------- +C FNU=HALF ODD INTEGER CASE, DNU=-0.5 +C----------------------------------------------------------------------- + 300 CONTINUE + S1R = COEFR + S1I = COEFI + S2R = COEFR + S2I = COEFI + GO TO 210 +C +C + 310 CONTINUE + NZ=-2 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbuni.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbuni.f new file mode 100644 index 00000000..3811b89a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbuni.f @@ -0,0 +1,174 @@ + SUBROUTINE ZBUNI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, NUI, NLAST, + * FNUL, TOL, ELIM, ALIM) +C***BEGIN PROLOGUE ZBUNI +C***REFER TO ZBESI,ZBESK +C +C ZBUNI COMPUTES THE I BESSEL FUNCTION FOR LARGE CABS(Z).GT. +C FNUL AND FNU+N-1.LT.FNUL. THE ORDER IS INCREASED FROM +C FNU+N-1 GREATER THAN FNUL BY ADDING NUI AND COMPUTING +C ACCORDING TO THE UNIFORM ASYMPTOTIC EXPANSION FOR I(FNU,Z) +C ON IFORM=1 AND THE EXPANSION FOR J(FNU,Z) ON IFORM=2 +C +C***ROUTINES CALLED ZUNI1,ZUNI2,ZABS,D1MACH +C***END PROLOGUE ZBUNI +C COMPLEX CSCL,CSCR,CY,RZ,ST,S1,S2,Y,Z + DOUBLE PRECISION ALIM, AX, AY, CSCLR, CSCRR, CYI, CYR, DFNU, + * ELIM, FNU, FNUI, FNUL, GNU, RAZ, RZI, RZR, STI, STR, S1I, S1R, + * S2I, S2R, TOL, YI, YR, ZI, ZR, ZABS, ASCLE, BRY, C1R, C1I, C1M, + * D1MACH + INTEGER I, IFLAG, IFORM, K, KODE, N, NL, NLAST, NUI, NW, NZ + DIMENSION YR(N), YI(N), CYR(2), CYI(2), BRY(3) + NZ = 0 + AX = DABS(ZR)*1.7321D0 + AY = DABS(ZI) + IFORM = 1 + IF (AY.GT.AX) IFORM = 2 + IF (NUI.EQ.0) GO TO 60 + FNUI = DBLE(FLOAT(NUI)) + DFNU = FNU + DBLE(FLOAT(N-1)) + GNU = DFNU + FNUI + IF (IFORM.EQ.2) GO TO 10 +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR I(FNU,Z) FOR LARGE FNU APPLIED IN +C -PI/3.LE.ARG(Z).LE.PI/3 +C----------------------------------------------------------------------- + CALL ZUNI1(ZR, ZI, GNU, KODE, 2, CYR, CYI, NW, NLAST, FNUL, TOL, + * ELIM, ALIM) + GO TO 20 + 10 CONTINUE +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR J(FNU,Z*EXP(M*HPI)) FOR LARGE FNU +C APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I +C AND HPI=PI/2 +C----------------------------------------------------------------------- + CALL ZUNI2(ZR, ZI, GNU, KODE, 2, CYR, CYI, NW, NLAST, FNUL, TOL, + * ELIM, ALIM) + 20 CONTINUE + IF (NW.LT.0) GO TO 50 + IF (NW.NE.0) GO TO 90 + STR = ZABS(CMPLX(CYR(1),CYI(1),kind=KIND(1.0D0))) +C---------------------------------------------------------------------- +C SCALE BACKWARD RECURRENCE, BRY(3) IS DEFINED BUT NEVER USED +C---------------------------------------------------------------------- + BRY(1)=1.0D+3*D1MACH(1)/TOL + BRY(2) = 1.0D0/BRY(1) + BRY(3) = BRY(2) + IFLAG = 2 + ASCLE = BRY(2) + CSCLR = 1.0D0 + IF (STR.GT.BRY(1)) GO TO 21 + IFLAG = 1 + ASCLE = BRY(1) + CSCLR = 1.0D0/TOL + GO TO 25 + 21 CONTINUE + IF (STR.LT.BRY(2)) GO TO 25 + IFLAG = 3 + ASCLE=BRY(3) + CSCLR = TOL + 25 CONTINUE + CSCRR = 1.0D0/CSCLR + S1R = CYR(2)*CSCLR + S1I = CYI(2)*CSCLR + S2R = CYR(1)*CSCLR + S2I = CYI(1)*CSCLR + RAZ = 1.0D0/ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + STR = ZR*RAZ + STI = -ZI*RAZ + RZR = (STR+STR)*RAZ + RZI = (STI+STI)*RAZ + DO 30 I=1,NUI + STR = S2R + STI = S2I + S2R = (DFNU+FNUI)*(RZR*STR-RZI*STI) + S1R + S2I = (DFNU+FNUI)*(RZR*STI+RZI*STR) + S1I + S1R = STR + S1I = STI + FNUI = FNUI - 1.0D0 + IF (IFLAG.GE.3) GO TO 30 + STR = S2R*CSCRR + STI = S2I*CSCRR + C1R = DABS(STR) + C1I = DABS(STI) + C1M = DMAX1(C1R,C1I) + IF (C1M.LE.ASCLE) GO TO 30 + IFLAG = IFLAG+1 + ASCLE = BRY(IFLAG) + S1R = S1R*CSCRR + S1I = S1I*CSCRR + S2R = STR + S2I = STI + CSCLR = CSCLR*TOL + CSCRR = 1.0D0/CSCLR + S1R = S1R*CSCLR + S1I = S1I*CSCLR + S2R = S2R*CSCLR + S2I = S2I*CSCLR + 30 CONTINUE + YR(N) = S2R*CSCRR + YI(N) = S2I*CSCRR + IF (N.EQ.1) RETURN + NL = N - 1 + FNUI = DBLE(FLOAT(NL)) + K = NL + DO 40 I=1,NL + STR = S2R + STI = S2I + S2R = (FNU+FNUI)*(RZR*STR-RZI*STI) + S1R + S2I = (FNU+FNUI)*(RZR*STI+RZI*STR) + S1I + S1R = STR + S1I = STI + STR = S2R*CSCRR + STI = S2I*CSCRR + YR(K) = STR + YI(K) = STI + FNUI = FNUI - 1.0D0 + K = K - 1 + IF (IFLAG.GE.3) GO TO 40 + C1R = DABS(STR) + C1I = DABS(STI) + C1M = DMAX1(C1R,C1I) + IF (C1M.LE.ASCLE) GO TO 40 + IFLAG = IFLAG+1 + ASCLE = BRY(IFLAG) + S1R = S1R*CSCRR + S1I = S1I*CSCRR + S2R = STR + S2I = STI + CSCLR = CSCLR*TOL + CSCRR = 1.0D0/CSCLR + S1R = S1R*CSCLR + S1I = S1I*CSCLR + S2R = S2R*CSCLR + S2I = S2I*CSCLR + 40 CONTINUE + RETURN + 50 CONTINUE + NZ = -1 + IF(NW.EQ.(-2)) NZ=-2 + RETURN + 60 CONTINUE + IF (IFORM.EQ.2) GO TO 70 +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR I(FNU,Z) FOR LARGE FNU APPLIED IN +C -PI/3.LE.ARG(Z).LE.PI/3 +C----------------------------------------------------------------------- + CALL ZUNI1(ZR, ZI, FNU, KODE, N, YR, YI, NW, NLAST, FNUL, TOL, + * ELIM, ALIM) + GO TO 80 + 70 CONTINUE +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR J(FNU,Z*EXP(M*HPI)) FOR LARGE FNU +C APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I +C AND HPI=PI/2 +C----------------------------------------------------------------------- + CALL ZUNI2(ZR, ZI, FNU, KODE, N, YR, YI, NW, NLAST, FNUL, TOL, + * ELIM, ALIM) + 80 CONTINUE + IF (NW.LT.0) GO TO 50 + NZ = NW + RETURN + 90 CONTINUE + NLAST = N + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbunk.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbunk.f new file mode 100644 index 00000000..b20b79f3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zbunk.f @@ -0,0 +1,35 @@ + SUBROUTINE ZBUNK(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM, + * ALIM) +C***BEGIN PROLOGUE ZBUNK +C***REFER TO ZBESK,ZBESH +C +C ZBUNK COMPUTES THE K BESSEL FUNCTION FOR FNU.GT.FNUL. +C ACCORDING TO THE UNIFORM ASYMPTOTIC EXPANSION FOR K(FNU,Z) +C IN ZUNK1 AND THE EXPANSION FOR H(2,FNU,Z) IN ZUNK2 +C +C***ROUTINES CALLED ZUNK1,ZUNK2 +C***END PROLOGUE ZBUNK +C COMPLEX Y,Z + DOUBLE PRECISION ALIM, AX, AY, ELIM, FNU, TOL, YI, YR, ZI, ZR + INTEGER KODE, MR, N, NZ + DIMENSION YR(N), YI(N) + NZ = 0 + AX = DABS(ZR)*1.7321D0 + AY = DABS(ZI) + IF (AY.GT.AX) GO TO 10 +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR K(FNU,Z) FOR LARGE FNU APPLIED IN +C -PI/3.LE.ARG(Z).LE.PI/3 +C----------------------------------------------------------------------- + CALL ZUNK1(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM, ALIM) + GO TO 20 + 10 CONTINUE +C----------------------------------------------------------------------- +C ASYMPTOTIC EXPANSION FOR H(2,FNU,Z*EXP(M*HPI)) FOR LARGE FNU +C APPLIED IN PI/3.LT.ABS(ARG(Z)).LE.PI/2 WHERE M=+I OR -I +C AND HPI=PI/2 +C----------------------------------------------------------------------- + CALL ZUNK2(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM, ALIM) + 20 CONTINUE + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zdiv.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zdiv.f new file mode 100644 index 00000000..ac73b86d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zdiv.f @@ -0,0 +1,19 @@ + SUBROUTINE ZDIV(AR, AI, BR, BI, CR, CI) +C***BEGIN PROLOGUE ZDIV +C***REFER TO ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY +C +C DOUBLE PRECISION COMPLEX DIVIDE C=A/B. +C +C***ROUTINES CALLED ZABS +C***END PROLOGUE ZDIV + DOUBLE PRECISION AR, AI, BR, BI, CR, CI, BM, CA, CB, CC, CD + DOUBLE PRECISION ZABS + BM = 1.0D0/ZABS(CMPLX(BR,BI,kind=KIND(1.0D0))) + CC = BR*BM + CD = BI*BM + CA = (AR*CC+AI*CD)*BM + CB = (AI*CC-AR*CD)*BM + CR = CA + CI = CB + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zexp.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zexp.f new file mode 100644 index 00000000..fcb553c1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zexp.f @@ -0,0 +1,16 @@ + SUBROUTINE ZEXP(AR, AI, BR, BI) +C***BEGIN PROLOGUE ZEXP +C***REFER TO ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY +C +C DOUBLE PRECISION COMPLEX EXPONENTIAL FUNCTION B=EXP(A) +C +C***ROUTINES CALLED (NONE) +C***END PROLOGUE ZEXP + DOUBLE PRECISION AR, AI, BR, BI, ZM, CA, CB + ZM = DEXP(AR) + CA = ZM*DCOS(AI) + CB = ZM*DSIN(AI) + BR = CA + BI = CB + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zkscl.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zkscl.f new file mode 100644 index 00000000..eeda4715 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zkscl.f @@ -0,0 +1,121 @@ + SUBROUTINE ZKSCL(ZRR,ZRI,FNU,N,YR,YI,NZ,RZR,RZI,ASCLE,TOL,ELIM) +C***BEGIN PROLOGUE ZKSCL +C***REFER TO ZBESK +C +C SET K FUNCTIONS TO ZERO ON UNDERFLOW, CONTINUE RECURRENCE +C ON SCALED FUNCTIONS UNTIL TWO MEMBERS COME ON SCALE, THEN +C RETURN WITH MIN(NZ+2,N) VALUES SCALED BY 1/TOL. +C +C***ROUTINES CALLED ZUCHK,ZABS,ZLOG +C***END PROLOGUE ZKSCL +C COMPLEX CK,CS,CY,CZERO,RZ,S1,S2,Y,ZR,ZD,CELM + DOUBLE PRECISION ACS, AS, ASCLE, CKI, CKR, CSI, CSR, CYI, + * CYR, ELIM, FN, FNU, RZI, RZR, STR, S1I, S1R, S2I, + * S2R, TOL, YI, YR, ZEROI, ZEROR, ZRI, ZRR, ZABS, + * ZDR, ZDI, CELMR, ELM, HELIM, ALAS + INTEGER I, IC, IDUM, KK, N, NN, NW, NZ + DIMENSION YR(N), YI(N), CYR(2), CYI(2) + DATA ZEROR,ZEROI / 0.0D0 , 0.0D0 / +C + NZ = 0 + IC = 0 + NN = MIN0(2,N) + DO 10 I=1,NN + S1R = YR(I) + S1I = YI(I) + CYR(I) = S1R + CYI(I) = S1I + AS = ZABS(CMPLX(S1R,S1I,kind=KIND(1.0D0))) + ACS = -ZRR + DLOG(AS) + NZ = NZ + 1 + YR(I) = ZEROR + YI(I) = ZEROI + IF (ACS.LT.(-ELIM)) GO TO 10 + CALL ZLOG(S1R, S1I, CSR, CSI, IDUM) + CSR = CSR - ZRR + CSI = CSI - ZRI + STR = DEXP(CSR)/TOL + CSR = STR*DCOS(CSI) + CSI = STR*DSIN(CSI) + CALL ZUCHK(CSR, CSI, NW, ASCLE, TOL) + IF (NW.NE.0) GO TO 10 + YR(I) = CSR + YI(I) = CSI + IC = I + NZ = NZ - 1 + 10 CONTINUE + IF (N.EQ.1) RETURN + IF (IC.GT.1) GO TO 20 + YR(1) = ZEROR + YI(1) = ZEROI + NZ = 2 + 20 CONTINUE + IF (N.EQ.2) RETURN + IF (NZ.EQ.0) RETURN + FN = FNU + 1.0D0 + CKR = FN*RZR + CKI = FN*RZI + S1R = CYR(1) + S1I = CYI(1) + S2R = CYR(2) + S2I = CYI(2) + HELIM = 0.5D0*ELIM + ELM = DEXP(-ELIM) + CELMR = ELM + ZDR = ZRR + ZDI = ZRI +C +C FIND TWO CONSECUTIVE Y VALUES ON SCALE. SCALE RECURRENCE IF +C S2 GETS LARGER THAN EXP(ELIM/2) +C + DO 30 I=3,N + KK = I + CSR = S2R + CSI = S2I + S2R = CKR*CSR - CKI*CSI + S1R + S2I = CKI*CSR + CKR*CSI + S1I + S1R = CSR + S1I = CSI + CKR = CKR + RZR + CKI = CKI + RZI + AS = ZABS(CMPLX(S2R,S2I,kind=KIND(1.0D0))) + ALAS = DLOG(AS) + ACS = -ZDR + ALAS + NZ = NZ + 1 + YR(I) = ZEROR + YI(I) = ZEROI + IF (ACS.LT.(-ELIM)) GO TO 25 + CALL ZLOG(S2R, S2I, CSR, CSI, IDUM) + CSR = CSR - ZDR + CSI = CSI - ZDI + STR = DEXP(CSR)/TOL + CSR = STR*DCOS(CSI) + CSI = STR*DSIN(CSI) + CALL ZUCHK(CSR, CSI, NW, ASCLE, TOL) + IF (NW.NE.0) GO TO 25 + YR(I) = CSR + YI(I) = CSI + NZ = NZ - 1 + IF (IC.EQ.KK-1) GO TO 40 + IC = KK + GO TO 30 + 25 CONTINUE + IF(ALAS.LT.HELIM) GO TO 30 + ZDR = ZDR - ELIM + S1R = S1R*CELMR + S1I = S1I*CELMR + S2R = S2R*CELMR + S2I = S2I*CELMR + 30 CONTINUE + NZ = N + IF(IC.EQ.N) NZ=N-1 + GO TO 45 + 40 CONTINUE + NZ = KK - 2 + 45 CONTINUE + DO 50 I=1,NZ + YR(I) = ZEROR + YI(I) = ZEROI + 50 CONTINUE + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zlog.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zlog.f new file mode 100644 index 00000000..bb22cd01 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zlog.f @@ -0,0 +1,41 @@ + SUBROUTINE ZLOG(AR, AI, BR, BI, IERR) +C***BEGIN PROLOGUE ZLOG +C***REFER TO ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY +C +C DOUBLE PRECISION COMPLEX LOGARITHM B=CLOG(A) +C IERR=0,NORMAL RETURN IERR=1, Z=CMPLX(0.0,0.0) +C***ROUTINES CALLED ZABS +C***END PROLOGUE ZLOG + DOUBLE PRECISION AR, AI, BR, BI, ZM, DTHETA, DPI, DHPI + DOUBLE PRECISION ZABS + DATA DPI , DHPI / 3.141592653589793238462643383D+0, + 1 1.570796326794896619231321696D+0/ +C + IERR=0 + IF (AR.EQ.0.0D+0) GO TO 10 + IF (AI.EQ.0.0D+0) GO TO 20 + DTHETA = DATAN(AI/AR) + IF (DTHETA.LE.0.0D+0) GO TO 40 + IF (AR.LT.0.0D+0) DTHETA = DTHETA - DPI + GO TO 50 + 10 IF (AI.EQ.0.0D+0) GO TO 60 + BI = DHPI + BR = DLOG(DABS(AI)) + IF (AI.LT.0.0D+0) BI = -BI + RETURN + 20 IF (AR.GT.0.0D+0) GO TO 30 + BR = DLOG(DABS(AR)) + BI = DPI + RETURN + 30 BR = DLOG(AR) + BI = 0.0D+0 + RETURN + 40 IF (AR.LT.0.0D+0) DTHETA = DTHETA + DPI + 50 ZM = ZABS(CMPLX(AR,AI,kind=KIND(1.0D0))) + BR = DLOG(ZM) + BI = DTHETA + RETURN + 60 CONTINUE + IERR=1 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zmlri.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zmlri.f new file mode 100644 index 00000000..c112f79d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zmlri.f @@ -0,0 +1,206 @@ + SUBROUTINE ZMLRI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL) +C***BEGIN PROLOGUE ZMLRI +C***REFER TO ZBESI,ZBESK +C +C ZMLRI COMPUTES THE I BESSEL FUNCTION FOR RE(Z).GE.0.0 BY THE +C MILLER ALGORITHM NORMALIZED BY A NEUMANN SERIES. +C +C***ROUTINES CALLED DGAMLN,D1MACH,ZABS,ZEXP,ZLOG,ZMLT +C***END PROLOGUE ZMLRI +C COMPLEX CK,CNORM,CONE,CTWO,CZERO,PT,P1,P2,RZ,SUM,Y,Z + DOUBLE PRECISION ACK, AK, AP, AT, AZ, BK, CKI, CKR, CNORMI, + * CNORMR, CONEI, CONER, FKAP, FKK, FLAM, FNF, FNU, PTI, PTR, P1I, + * P1R, P2I, P2R, RAZ, RHO, RHO2, RZI, RZR, SCLE, STI, STR, SUMI, + * SUMR, TFNF, TOL, TST, YI, YR, ZEROI, ZEROR, ZI, ZR, DGAMLN, + * D1MACH, ZABS + INTEGER I, IAZ, IDUM, IFNU, INU, ITIME, K, KK, KM, KODE, M, N, NZ + DIMENSION YR(N), YI(N) + DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 / + SCLE = D1MACH(1)/TOL + NZ=0 + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + IAZ = INT(SNGL(AZ)) + IFNU = INT(SNGL(FNU)) + INU = IFNU + N - 1 + AT = DBLE(FLOAT(IAZ)) + 1.0D0 + RAZ = 1.0D0/AZ + STR = ZR*RAZ + STI = -ZI*RAZ + CKR = STR*AT*RAZ + CKI = STI*AT*RAZ + RZR = (STR+STR)*RAZ + RZI = (STI+STI)*RAZ + P1R = ZEROR + P1I = ZEROI + P2R = CONER + P2I = CONEI + ACK = (AT+1.0D0)*RAZ + RHO = ACK + DSQRT(ACK*ACK-1.0D0) + RHO2 = RHO*RHO + TST = (RHO2+RHO2)/((RHO2-1.0D0)*(RHO-1.0D0)) + TST = TST/TOL +C----------------------------------------------------------------------- +C COMPUTE RELATIVE TRUNCATION ERROR INDEX FOR SERIES +C----------------------------------------------------------------------- + AK = AT + DO 10 I=1,80 + PTR = P2R + PTI = P2I + P2R = P1R - (CKR*PTR-CKI*PTI) + P2I = P1I - (CKI*PTR+CKR*PTI) + P1R = PTR + P1I = PTI + CKR = CKR + RZR + CKI = CKI + RZI + AP = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) + IF (AP.GT.TST*AK*AK) THEN + GO TO 20 + END IF + AK = AK + 1.0D0 + 10 CONTINUE + GO TO 110 + 20 CONTINUE + I = I + 1 + K = 0 + IF (INU.LT.IAZ) GO TO 40 +C----------------------------------------------------------------------- +C COMPUTE RELATIVE TRUNCATION ERROR FOR RATIOS +C----------------------------------------------------------------------- + P1R = ZEROR + P1I = ZEROI + P2R = CONER + P2I = CONEI + AT = DBLE(FLOAT(INU)) + 1.0D0 + STR = ZR*RAZ + STI = -ZI*RAZ + CKR = STR*AT*RAZ + CKI = STI*AT*RAZ + ACK = AT*RAZ + TST = DSQRT(ACK/TOL) + ITIME = 1 + DO 30 K=1,80 + PTR = P2R + PTI = P2I + P2R = P1R - (CKR*PTR-CKI*PTI) + P2I = P1I - (CKR*PTI+CKI*PTR) + P1R = PTR + P1I = PTI + CKR = CKR + RZR + CKI = CKI + RZI + AP = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) + IF (AP.LT.TST) GO TO 30 + IF (ITIME.EQ.2) GO TO 40 + ACK = ZABS(CMPLX(CKR,CKI,kind=KIND(1.0D0))) + FLAM = ACK + DSQRT(ACK*ACK-1.0D0) + FKAP = AP/ZABS(CMPLX(P1R,P1I,kind=KIND(1.0D0))) + RHO = DMIN1(FLAM,FKAP) + TST = TST*DSQRT(RHO/(RHO*RHO-1.0D0)) + ITIME = 2 + 30 CONTINUE + GO TO 110 + 40 CONTINUE +C----------------------------------------------------------------------- +C BACKWARD RECURRENCE AND SUM NORMALIZING RELATION +C----------------------------------------------------------------------- + K = K + 1 + KK = MAX0(I+IAZ,K+INU) + FKK = DBLE(FLOAT(KK)) + P1R = ZEROR + P1I = ZEROI +C----------------------------------------------------------------------- +C SCALE P2 AND SUM BY SCLE +C----------------------------------------------------------------------- + P2R = SCLE + P2I = ZEROI + FNF = FNU - DBLE(FLOAT(IFNU)) + TFNF = FNF + FNF + BK = DGAMLN(FKK+TFNF+1.0D0,IDUM) - DGAMLN(FKK+1.0D0,IDUM) - + * DGAMLN(TFNF+1.0D0,IDUM) + BK = DEXP(BK) + SUMR = ZEROR + SUMI = ZEROI + KM = KK - INU + DO 50 I=1,KM + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) + P1R = PTR + P1I = PTI + AK = 1.0D0 - TFNF/(FKK+TFNF) + ACK = BK*AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0D0 + 50 CONTINUE + YR(N) = P2R + YI(N) = P2I + IF (N.EQ.1) GO TO 70 + DO 60 I=2,N + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) + P1R = PTR + P1I = PTI + AK = 1.0D0 - TFNF/(FKK+TFNF) + ACK = BK*AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0D0 + M = N - I + 1 + YR(M) = P2R + YI(M) = P2I + 60 CONTINUE + 70 CONTINUE + IF (IFNU.LE.0) GO TO 90 + DO 80 I=1,IFNU + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZR*PTI+RZI*PTR) + P1R = PTR + P1I = PTI + AK = 1.0D0 - TFNF/(FKK+TFNF) + ACK = BK*AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0D0 + 80 CONTINUE + 90 CONTINUE + PTR = ZR + PTI = ZI + IF (KODE.EQ.2) PTR = ZEROR + CALL ZLOG(RZR, RZI, STR, STI, IDUM) + P1R = -FNF*STR + PTR + P1I = -FNF*STI + PTI + AP = DGAMLN(1.0D0+FNF,IDUM) + PTR = P1R - AP + PTI = P1I +C----------------------------------------------------------------------- +C THE DIVISION CEXP(PT)/(SUM+P2) IS ALTERED TO AVOID OVERFLOW +C IN THE DENOMINATOR BY SQUARING LARGE QUANTITIES +C----------------------------------------------------------------------- + P2R = P2R + SUMR + P2I = P2I + SUMI + AP = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) + P1R = 1.0D0/AP + CALL ZEXP(PTR, PTI, STR, STI) + CKR = STR*P1R + CKI = STI*P1R + PTR = P2R*P1R + PTI = -P2I*P1R + CALL ZMLT(CKR, CKI, PTR, PTI, CNORMR, CNORMI) + DO 100 I=1,N + STR = YR(I)*CNORMR - YI(I)*CNORMI + YI(I) = YR(I)*CNORMI + YI(I)*CNORMR + YR(I) = STR + 100 CONTINUE + RETURN + 110 CONTINUE + NZ=-2 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zmlt.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zmlt.f new file mode 100644 index 00000000..3bde7d34 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zmlt.f @@ -0,0 +1,15 @@ + SUBROUTINE ZMLT(AR, AI, BR, BI, CR, CI) +C***BEGIN PROLOGUE ZMLT +C***REFER TO ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY +C +C DOUBLE PRECISION COMPLEX MULTIPLY, C=A*B. +C +C***ROUTINES CALLED (NONE) +C***END PROLOGUE ZMLT + DOUBLE PRECISION AR, AI, BR, BI, CR, CI, CA, CB + CA = AR*BR - AI*BI + CB = AR*BI + AI*BR + CR = CA + CI = CB + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zrati.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zrati.f new file mode 100644 index 00000000..b66bd201 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zrati.f @@ -0,0 +1,132 @@ + SUBROUTINE ZRATI(ZR, ZI, FNU, N, CYR, CYI, TOL) +C***BEGIN PROLOGUE ZRATI +C***REFER TO ZBESI,ZBESK,ZBESH +C +C ZRATI COMPUTES RATIOS OF I BESSEL FUNCTIONS BY BACKWARD +C RECURRENCE. THE STARTING INDEX IS DETERMINED BY FORWARD +C RECURRENCE AS DESCRIBED IN J. RES. OF NAT. BUR. OF STANDARDS-B, +C MATHEMATICAL SCIENCES, VOL 77B, P111-114, SEPTEMBER, 1973, +C BESSEL FUNCTIONS I AND J OF COMPLEX ARGUMENT AND INTEGER ORDER, +C BY D. J. SOOKNE. +C +C***ROUTINES CALLED ZABS,ZDIV +C***END PROLOGUE ZRATI +C COMPLEX Z,CY(1),CONE,CZERO,P1,P2,T1,RZ,PT,CDFNU + DOUBLE PRECISION AK, AMAGZ, AP1, AP2, ARG, AZ, CDFNUI, CDFNUR, + * CONEI, CONER, CYI, CYR, CZEROI, CZEROR, DFNU, FDNU, FLAM, FNU, + * FNUP, PTI, PTR, P1I, P1R, P2I, P2R, RAK, RAP1, RHO, RT2, RZI, + * RZR, TEST, TEST1, TOL, TTI, TTR, T1I, T1R, ZI, ZR, ZABS + INTEGER I, ID, IDNU, INU, ITIME, K, KK, MAGZ, N + DIMENSION CYR(N), CYI(N) + DATA CZEROR,CZEROI,CONER,CONEI,RT2/ + 1 0.0D0, 0.0D0, 1.0D0, 0.0D0, 1.41421356237309505D0 / + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + INU = INT(SNGL(FNU)) + IDNU = INU + N - 1 + MAGZ = INT(SNGL(AZ)) + AMAGZ = DBLE(FLOAT(MAGZ+1)) + FDNU = DBLE(FLOAT(IDNU)) + FNUP = DMAX1(AMAGZ,FDNU) + ID = IDNU - MAGZ - 1 + ITIME = 1 + K = 1 + PTR = 1.0D0/AZ + RZR = PTR*(ZR+ZR)*PTR + RZI = -PTR*(ZI+ZI)*PTR + T1R = RZR*FNUP + T1I = RZI*FNUP + P2R = -T1R + P2I = -T1I + P1R = CONER + P1I = CONEI + T1R = T1R + RZR + T1I = T1I + RZI + IF (ID.GT.0) ID = 0 + AP2 = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) + AP1 = ZABS(CMPLX(P1R,P1I,kind=KIND(1.0D0))) +C----------------------------------------------------------------------- +C THE OVERFLOW TEST ON K(FNU+I-1,Z) BEFORE THE CALL TO CBKNU +C GUARANTEES THAT P2 IS ON SCALE. SCALE TEST1 AND ALL SUBSEQUENT +C P2 VALUES BY AP1 TO ENSURE THAT AN OVERFLOW DOES NOT OCCUR +C PREMATURELY. +C----------------------------------------------------------------------- + ARG = (AP2+AP2)/(AP1*TOL) + TEST1 = DSQRT(ARG) + TEST = TEST1 + RAP1 = 1.0D0/AP1 + P1R = P1R*RAP1 + P1I = P1I*RAP1 + P2R = P2R*RAP1 + P2I = P2I*RAP1 + AP2 = AP2*RAP1 + 10 CONTINUE + K = K + 1 + AP1 = AP2 + PTR = P2R + PTI = P2I + P2R = P1R - (T1R*PTR-T1I*PTI) + P2I = P1I - (T1R*PTI+T1I*PTR) + P1R = PTR + P1I = PTI + T1R = T1R + RZR + T1I = T1I + RZI + AP2 = ZABS(CMPLX(P2R,P2I,kind=KIND(1.0D0))) + IF (AP1.LE.TEST) GO TO 10 + IF (ITIME.EQ.2) GO TO 20 + AK = ZABS(CMPLX(T1R,T1I,kind=KIND(1.0D0))*0.5D0) + FLAM = AK + DSQRT(AK*AK-1.0D0) + RHO = DMIN1(AP2/AP1,FLAM) + TEST = TEST1*DSQRT(RHO/(RHO*RHO-1.0D0)) + ITIME = 2 + GO TO 10 + 20 CONTINUE + KK = K + 1 - ID + AK = DBLE(FLOAT(KK)) + T1R = AK + T1I = CZEROI + DFNU = FNU + DBLE(FLOAT(N-1)) + P1R = 1.0D0/AP2 + P1I = CZEROI + P2R = CZEROR + P2I = CZEROI + DO 30 I=1,KK + PTR = P1R + PTI = P1I + RAP1 = DFNU + T1R + TTR = RZR*RAP1 + TTI = RZI*RAP1 + P1R = (PTR*TTR-PTI*TTI) + P2R + P1I = (PTR*TTI+PTI*TTR) + P2I + P2R = PTR + P2I = PTI + T1R = T1R - CONER + 30 CONTINUE + IF (P1R.NE.CZEROR .OR. P1I.NE.CZEROI) GO TO 40 + P1R = TOL + P1I = TOL + 40 CONTINUE + CALL ZDIV(P2R, P2I, P1R, P1I, CYR(N), CYI(N)) + IF (N.EQ.1) RETURN + K = N - 1 + AK = DBLE(FLOAT(K)) + T1R = AK + T1I = CZEROI + CDFNUR = FNU*RZR + CDFNUI = FNU*RZI + DO 60 I=2,N + PTR = CDFNUR + (T1R*RZR-T1I*RZI) + CYR(K+1) + PTI = CDFNUI + (T1R*RZI+T1I*RZR) + CYI(K+1) + AK = ZABS(CMPLX(PTR,PTI,kind=KIND(1.0D0))) + IF (AK.NE.CZEROR) GO TO 50 + PTR = TOL + PTI = TOL + AK = TOL*RT2 + 50 CONTINUE + RAK = CONER/AK + CYR(K) = RAK*PTR*RAK + CYI(K) = -RAK*PTI*RAK + T1R = T1R - CONER + K = K - 1 + 60 CONTINUE + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zs1s2.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zs1s2.f new file mode 100644 index 00000000..0a6da311 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zs1s2.f @@ -0,0 +1,51 @@ + SUBROUTINE ZS1S2(ZRR, ZRI, S1R, S1I, S2R, S2I, NZ, ASCLE, ALIM, + * IUF) +C***BEGIN PROLOGUE ZS1S2 +C***REFER TO ZBESK,ZAIRY +C +C ZS1S2 TESTS FOR A POSSIBLE UNDERFLOW RESULTING FROM THE +C ADDITION OF THE I AND K FUNCTIONS IN THE ANALYTIC CON- +C TINUATION FORMULA WHERE S1=K FUNCTION AND S2=I FUNCTION. +C ON KODE=1 THE I AND K FUNCTIONS ARE DIFFERENT ORDERS OF +C MAGNITUDE, BUT FOR KODE=2 THEY CAN BE OF THE SAME ORDER +C OF MAGNITUDE AND THE MAXIMUM MUST BE AT LEAST ONE +C PRECISION ABOVE THE UNDERFLOW LIMIT. +C +C***ROUTINES CALLED ZABS,ZEXP,ZLOG +C***END PROLOGUE ZS1S2 +C COMPLEX CZERO,C1,S1,S1D,S2,ZR + DOUBLE PRECISION AA, ALIM, ALN, ASCLE, AS1, AS2, C1I, C1R, S1DI, + * S1DR, S1I, S1R, S2I, S2R, ZEROI, ZEROR, ZRI, ZRR, ZABS + INTEGER IUF, IDUM, NZ + DATA ZEROR,ZEROI / 0.0D0 , 0.0D0 / + NZ = 0 + AS1 = ZABS(CMPLX(S1R,S1I,kind=KIND(1.0D0))) + AS2 = ZABS(CMPLX(S2R,S2I,kind=KIND(1.0D0))) + IF (S1R.EQ.0.0D0 .AND. S1I.EQ.0.0D0) GO TO 10 + IF (AS1.EQ.0.0D0) GO TO 10 + ALN = -ZRR - ZRR + DLOG(AS1) + S1DR = S1R + S1DI = S1I + S1R = ZEROR + S1I = ZEROI + AS1 = ZEROR + IF (ALN.LT.(-ALIM)) GO TO 10 + CALL ZLOG(S1DR, S1DI, C1R, C1I, IDUM) + C1R = C1R - ZRR - ZRR + C1I = C1I - ZRI - ZRI + CALL ZEXP(C1R, C1I, S1R, S1I) + AS1 = ZABS(CMPLX(S1R,S1I,kind=KIND(1.0D0))) + IUF = IUF + 1 + 10 CONTINUE + AA = DMAX1(AS1,AS2) + IF (AA.GT.ASCLE) THEN + RETURN + END IF + S1R = ZEROR + S1I = ZEROI + S2R = ZEROR + S2I = ZEROI + NZ = 1 + IUF = 0 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zseri.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zseri.f new file mode 100644 index 00000000..862fbf61 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zseri.f @@ -0,0 +1,195 @@ + SUBROUTINE ZSERI(ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, + * ALIM) +C***BEGIN PROLOGUE ZSERI +C***REFER TO ZBESI,ZBESK +C +C ZSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z).GE.0.0 BY +C MEANS OF THE POWER SERIES FOR LARGE CABS(Z) IN THE +C REGION CABS(Z).LE.2*SQRT(FNU+1). NZ=0 IS A NORMAL RETURN. +C NZ.GT.0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO +C DUE TO UNDERFLOW. NZ.LT.0 MEANS UNDERFLOW OCCURRED, BUT THE +C CONDITION CABS(Z).LE.2*SQRT(FNU+1) WAS VIOLATED AND THE +C COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ). +C +C***ROUTINES CALLED DGAMLN,D1MACH,ZUCHK,ZABS,ZDIV,ZLOG,ZMLT +C***END PROLOGUE ZSERI +C COMPLEX AK1,CK,COEF,CONE,CRSC,CSCL,CZ,CZERO,HZ,RZ,S1,S2,Y,Z + DOUBLE PRECISION AA, ACZ, AK, AK1I, AK1R, ALIM, ARM, ASCLE, ATOL, + * AZ, CKI, CKR, COEFI, COEFR, CONEI, CONER, CRSCR, CZI, CZR, DFNU, + * ELIM, FNU, FNUP, HZI, HZR, RAZ, RS, RTR1, RZI, RZR, S, SS, STI, + * STR, S1I, S1R, S2I, S2R, TOL, YI, YR, WI, WR, ZEROI, ZEROR, ZI, + * ZR, DGAMLN, D1MACH, ZABS + INTEGER I, IB, IDUM, IFLAG, IL, K, KODE, L, M, N, NN, NZ, NW + DIMENSION YR(N), YI(N), WR(2), WI(2) + DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 / +C + + NZ = 0 + AZ = ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + IF (AZ.EQ.0.0D0) GO TO 160 + ARM = 1.0D+3*D1MACH(1) + RTR1 = DSQRT(ARM) + CRSCR = 1.0D0 + IFLAG = 0 + IF (AZ.LT.ARM) THEN + GO TO 150 + END IF + HZR = 0.5D0*ZR + HZI = 0.5D0*ZI + CZR = ZEROR + CZI = ZEROI + IF (AZ.LE.RTR1) GO TO 10 + CALL ZMLT(HZR, HZI, HZR, HZI, CZR, CZI) + 10 CONTINUE + ACZ = ZABS(CMPLX(CZR,CZI,kind=KIND(1.0D0))) + NN = N + CALL ZLOG(HZR, HZI, CKR, CKI, IDUM) + 20 CONTINUE + DFNU = FNU + DBLE(FLOAT(NN-1)) + FNUP = DFNU + 1.0D0 +C----------------------------------------------------------------------- +C UNDERFLOW TEST +C----------------------------------------------------------------------- + AK1R = CKR*DFNU + AK1I = CKI*DFNU + AK = DGAMLN(FNUP,IDUM) + AK1R = AK1R - AK + IF (KODE.EQ.2) AK1R = AK1R - ZR + IF (AK1R.GT.(-ELIM)) GO TO 40 + 30 CONTINUE + NZ = NZ + 1 + YR(NN) = ZEROR + YI(NN) = ZEROI + IF (ACZ.GT.DFNU) GO TO 190 + NN = NN - 1 + IF (NN.EQ.0) RETURN + GO TO 20 + 40 CONTINUE + IF (AK1R.GT.(-ALIM)) GO TO 50 + IFLAG = 1 + SS = 1.0D0/TOL + CRSCR = TOL + ASCLE = ARM*SS + 50 CONTINUE + AA = DEXP(AK1R) + IF (IFLAG.EQ.1) AA = AA*SS + COEFR = AA*DCOS(AK1I) + COEFI = AA*DSIN(AK1I) + ATOL = TOL*ACZ/FNUP + IL = MIN0(2,NN) + DO 90 I=1,IL + DFNU = FNU + DBLE(FLOAT(NN-I)) + FNUP = DFNU + 1.0D0 + S1R = CONER + S1I = CONEI + IF (ACZ.LT.TOL*FNUP) GO TO 70 + AK1R = CONER + AK1I = CONEI + AK = FNUP + 2.0D0 + S = FNUP + AA = 2.0D0 + 60 CONTINUE + RS = 1.0D0/S + STR = AK1R*CZR - AK1I*CZI + STI = AK1R*CZI + AK1I*CZR + AK1R = STR*RS + AK1I = STI*RS + S1R = S1R + AK1R + S1I = S1I + AK1I + S = S + AK + AK = AK + 2.0D0 + AA = AA*ACZ*RS + IF (AA.GT.ATOL) GO TO 60 + 70 CONTINUE + S2R = S1R*COEFR - S1I*COEFI + S2I = S1R*COEFI + S1I*COEFR + WR(I) = S2R + WI(I) = S2I + IF (IFLAG.EQ.0) GO TO 80 + CALL ZUCHK(S2R, S2I, NW, ASCLE, TOL) + IF (NW.NE.0) GO TO 30 + 80 CONTINUE + M = NN - I + 1 + YR(M) = S2R*CRSCR + YI(M) = S2I*CRSCR + IF (I.EQ.IL) GO TO 90 + CALL ZDIV(COEFR, COEFI, HZR, HZI, STR, STI) + COEFR = STR*DFNU + COEFI = STI*DFNU + 90 CONTINUE + IF (NN.LE.2) THEN + RETURN + END IF + K = NN - 2 + AK = DBLE(FLOAT(K)) + RAZ = 1.0D0/AZ + STR = ZR*RAZ + STI = -ZI*RAZ + RZR = (STR+STR)*RAZ + RZI = (STI+STI)*RAZ + IF (IFLAG.EQ.1) GO TO 120 + IB = 3 + 100 CONTINUE + DO 110 I=IB,NN + YR(K) = (AK+FNU)*(RZR*YR(K+1)-RZI*YI(K+1)) + YR(K+2) + YI(K) = (AK+FNU)*(RZR*YI(K+1)+RZI*YR(K+1)) + YI(K+2) + AK = AK - 1.0D0 + K = K - 1 + 110 CONTINUE + RETURN +C----------------------------------------------------------------------- +C RECUR BACKWARD WITH SCALED VALUES +C----------------------------------------------------------------------- + 120 CONTINUE +C----------------------------------------------------------------------- +C EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE +C UNDERFLOW LIMIT = ASCLE = D1MACH(1)*SS*1.0D+3 +C----------------------------------------------------------------------- + S1R = WR(1) + S1I = WI(1) + S2R = WR(2) + S2I = WI(2) + DO 130 L=3,NN + CKR = S2R + CKI = S2I + S2R = S1R + (AK+FNU)*(RZR*CKR-RZI*CKI) + S2I = S1I + (AK+FNU)*(RZR*CKI+RZI*CKR) + S1R = CKR + S1I = CKI + CKR = S2R*CRSCR + CKI = S2I*CRSCR + YR(K) = CKR + YI(K) = CKI + AK = AK - 1.0D0 + K = K - 1 + IF (ZABS(CMPLX(CKR,CKI,kind=KIND(1.0D0))).GT.ASCLE) GO TO 140 + 130 CONTINUE + RETURN + 140 CONTINUE + IB = L + 1 + IF (IB.GT.NN) RETURN + GO TO 100 + 150 CONTINUE + NZ = N + IF (FNU.EQ.0.0D0) NZ = NZ - 1 + 160 CONTINUE + YR(1) = ZEROR + YI(1) = ZEROI + IF (FNU.NE.0.0D0) GO TO 170 + YR(1) = CONER + YI(1) = CONEI + 170 CONTINUE + IF (N.EQ.1) RETURN + DO 180 I=2,N + YR(I) = ZEROR + YI(I) = ZEROI + 180 CONTINUE + RETURN +C----------------------------------------------------------------------- +C RETURN WITH NZ.LT.0 IF CABS(Z*Z/4).GT.FNU+N-NZ-1 COMPLETE +C THE CALCULATION IN CBINU WITH N=N-IABS(NZ) +C----------------------------------------------------------------------- + 190 CONTINUE + NZ = -NZ + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zshch.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zshch.f new file mode 100644 index 00000000..168e62e5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zshch.f @@ -0,0 +1,22 @@ + SUBROUTINE ZSHCH(ZR, ZI, CSHR, CSHI, CCHR, CCHI) +C***BEGIN PROLOGUE ZSHCH +C***REFER TO ZBESK,ZBESH +C +C ZSHCH COMPUTES THE COMPLEX HYPERBOLIC FUNCTIONS CSH=SINH(X+I*Y) +C AND CCH=COSH(X+I*Y), WHERE I**2=-1. +C +C***ROUTINES CALLED (NONE) +C***END PROLOGUE ZSHCH +C + DOUBLE PRECISION CCHI, CCHR, CH, CN, CSHI, CSHR, SH, SN, ZI, ZR, + * DCOSH, DSINH + SH = DSINH(ZR) + CH = DCOSH(ZR) + SN = DSIN(ZI) + CN = DCOS(ZI) + CSHR = SH*CN + CSHI = CH*SN + CCHR = CH*CN + CCHI = SH*SN + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zsqrt.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zsqrt.f new file mode 100644 index 00000000..289545cd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zsqrt.f @@ -0,0 +1,45 @@ + SUBROUTINE ZSQRT(AR, AI, BR, BI) +C***BEGIN PROLOGUE ZSQRT +C***REFER TO ZBESH,ZBESI,ZBESJ,ZBESK,ZBESY,ZAIRY,ZBIRY +C +C DOUBLE PRECISION COMPLEX SQUARE ROOT, B=CSQRT(A) +C +C***ROUTINES CALLED ZABS +C***END PROLOGUE ZSQRT + DOUBLE PRECISION AR, AI, BR, BI, ZM, DTHETA, DPI, DRT + DOUBLE PRECISION ZABS + + DATA DRT , DPI / 7.071067811865475244008443621D-1, + 1 3.141592653589793238462643383D+0/ + ZM = ZABS(CMPLX(AR,AI,kind=KIND(1.0D0))) + ZM = DSQRT(ZM) + IF (AR.EQ.0.0D+0) GO TO 10 + IF (AI.EQ.0.0D+0) GO TO 20 + DTHETA = DATAN(AI/AR) + IF (DTHETA.LE.0.0D+0) GO TO 40 + IF (AR.LT.0.0D+0) DTHETA = DTHETA - DPI + GO TO 50 + 10 IF (AI.GT.0.0D+0) GO TO 60 + IF (AI.LT.0.0D+0) GO TO 70 + BR = 0.0D+0 + BI = 0.0D+0 + RETURN + 20 IF (AR.GT.0.0D+0) GO TO 30 + BR = 0.0D+0 + BI = DSQRT(DABS(AR)) + RETURN + 30 BR = DSQRT(AR) + BI = 0.0D+0 + RETURN + 40 IF (AR.LT.0.0D+0) DTHETA = DTHETA + DPI + 50 DTHETA = DTHETA*0.5D+0 + BR = ZM*DCOS(DTHETA) + BI = ZM*DSIN(DTHETA) + RETURN + 60 BR = ZM*DRT + BI = ZM*DRT + RETURN + 70 BR = ZM*DRT + BI = -ZM*DRT + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuchk.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuchk.f new file mode 100644 index 00000000..d15dc841 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuchk.f @@ -0,0 +1,28 @@ + SUBROUTINE ZUCHK(YR, YI, NZ, ASCLE, TOL) +C***BEGIN PROLOGUE ZUCHK +C***REFER TO ZSERI,ZUOIK,ZUNK1,ZUNK2,ZUNI1,ZUNI2,ZKSCL +C +C Y ENTERS AS A SCALED QUANTITY WHOSE MAGNITUDE IS GREATER THAN +C EXP(-ALIM)=ASCLE=1.0E+3*D1MACH(1)/TOL. THE TEST IS MADE TO SEE +C IF THE MAGNITUDE OF THE REAL OR IMAGINARY PART WOULD UNDERFLOW +C WHEN Y IS SCALED (BY TOL) TO ITS PROPER VALUE. Y IS ACCEPTED +C IF THE UNDERFLOW IS AT LEAST ONE PRECISION BELOW THE MAGNITUDE +C OF THE LARGEST COMPONENT; OTHERWISE THE PHASE ANGLE DOES NOT HAVE +C ABSOLUTE ACCURACY AND AN UNDERFLOW IS ASSUMED. +C +C***ROUTINES CALLED (NONE) +C***END PROLOGUE ZUCHK +C +C COMPLEX Y + DOUBLE PRECISION ASCLE, SS, ST, TOL, WR, WI, YR, YI + INTEGER NZ + NZ = 0 + WR = DABS(YR) + WI = DABS(YI) + ST = DMIN1(WR,WI) + IF (ST.GT.ASCLE) RETURN + SS = DMAX1(WR,WI) + ST = ST/TOL + IF (SS.LT.ST) NZ = 1 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunhj.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunhj.f new file mode 100644 index 00000000..9b4df7a1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunhj.f @@ -0,0 +1,714 @@ + SUBROUTINE ZUNHJ(ZR, ZI, FNU, IPMTR, TOL, PHIR, PHII, ARGR, ARGI, + * ZETA1R, ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI) +C***BEGIN PROLOGUE ZUNHJ +C***REFER TO ZBESI,ZBESK +C +C REFERENCES +C HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ AND I.A. +C STEGUN, AMS55, NATIONAL BUREAU OF STANDARDS, 1965, CHAPTER 9. +C +C ASYMPTOTICS AND SPECIAL FUNCTIONS BY F.W.J. OLVER, ACADEMIC +C PRESS, N.Y., 1974, PAGE 420 +C +C ABSTRACT +C ZUNHJ COMPUTES PARAMETERS FOR BESSEL FUNCTIONS C(FNU,Z) = +C J(FNU,Z), Y(FNU,Z) OR H(I,FNU,Z) I=1,2 FOR LARGE ORDERS FNU +C BY MEANS OF THE UNIFORM ASYMPTOTIC EXPANSION +C +C C(FNU,Z)=C1*PHI*( ASUM*AIRY(ARG) + C2*BSUM*DAIRY(ARG) ) +C +C FOR PROPER CHOICES OF C1, C2, AIRY AND DAIRY WHERE AIRY IS +C AN AIRY FUNCTION AND DAIRY IS ITS DERIVATIVE. +C +C (2/3)*FNU*ZETA**1.5 = ZETA1-ZETA2, +C +C ZETA1=0.5*FNU*CLOG((1+W)/(1-W)), ZETA2=FNU*W FOR SCALING +C PURPOSES IN AIRY FUNCTIONS FROM CAIRY OR CBIRY. +C +C MCONJ=SIGN OF AIMAG(Z), BUT IS AMBIGUOUS WHEN Z IS REAL AND +C MUST BE SPECIFIED. IPMTR=0 RETURNS ALL PARAMETERS. IPMTR= +C 1 COMPUTES ALL EXCEPT ASUM AND BSUM. +C +C***ROUTINES CALLED ZABS,ZDIV,ZLOG,ZSQRT,D1MACH +C***END PROLOGUE ZUNHJ +C COMPLEX ARG,ASUM,BSUM,CFNU,CONE,CR,CZERO,DR,P,PHI,PRZTH,PTFN, +C *RFN13,RTZTA,RZTH,SUMA,SUMB,TFN,T2,UP,W,W2,Z,ZA,ZB,ZC,ZETA,ZETA1, +C *ZETA2,ZTH + DOUBLE PRECISION ALFA, ANG, AP, AR, ARGI, ARGR, ASUMI, ASUMR, + * ATOL, AW2, AZTH, BETA, BR, BSUMI, BSUMR, BTOL, C, CONEI, CONER, + * CRI, CRR, DRI, DRR, EX1, EX2, FNU, FN13, FN23, GAMA, GPI, HPI, + * PHII, PHIR, PI, PP, PR, PRZTHI, PRZTHR, PTFNI, PTFNR, RAW, RAW2, + * RAZTH, RFNU, RFNU2, RFN13, RTZTI, RTZTR, RZTHI, RZTHR, STI, STR, + * SUMAI, SUMAR, SUMBI, SUMBR, TEST, TFNI, TFNR, THPI, TOL, TZAI, + * TZAR, T2I, T2R, UPI, UPR, WI, WR, W2I, W2R, ZAI, ZAR, ZBI, ZBR, + * ZCI, ZCR, ZEROI, ZEROR, ZETAI, ZETAR, ZETA1I, ZETA1R, ZETA2I, + * ZETA2R, ZI, ZR, ZTHI, ZTHR, ZABS, AC, D1MACH + INTEGER IAS, IBS, IPMTR, IS, J, JR, JU, K, KMAX, KP1, KS, L, LR, + * LRP1, L1, L2, M, IDUM + DIMENSION AR(14), BR(14), C(105), ALFA(180), BETA(210), GAMA(30), + * AP(30), PR(30), PI(30), UPR(14), UPI(14), CRR(14), CRI(14), + * DRR(14), DRI(14) + DATA AR(1), AR(2), AR(3), AR(4), AR(5), AR(6), AR(7), AR(8), + 1 AR(9), AR(10), AR(11), AR(12), AR(13), AR(14)/ + 2 1.00000000000000000D+00, 1.04166666666666667D-01, + 3 8.35503472222222222D-02, 1.28226574556327160D-01, + 4 2.91849026464140464D-01, 8.81627267443757652D-01, + 5 3.32140828186276754D+00, 1.49957629868625547D+01, + 6 7.89230130115865181D+01, 4.74451538868264323D+02, + 7 3.20749009089066193D+03, 2.40865496408740049D+04, + 8 1.98923119169509794D+05, 1.79190200777534383D+06/ + DATA BR(1), BR(2), BR(3), BR(4), BR(5), BR(6), BR(7), BR(8), + 1 BR(9), BR(10), BR(11), BR(12), BR(13), BR(14)/ + 2 1.00000000000000000D+00, -1.45833333333333333D-01, + 3 -9.87413194444444444D-02, -1.43312053915895062D-01, + 4 -3.17227202678413548D-01, -9.42429147957120249D-01, + 5 -3.51120304082635426D+00, -1.57272636203680451D+01, + 6 -8.22814390971859444D+01, -4.92355370523670524D+02, + 7 -3.31621856854797251D+03, -2.48276742452085896D+04, + 8 -2.04526587315129788D+05, -1.83844491706820990D+06/ + DATA C(1), C(2), C(3), C(4), C(5), C(6), C(7), C(8), C(9), C(10), + 1 C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18), + 2 C(19), C(20), C(21), C(22), C(23), C(24)/ + 3 1.00000000000000000D+00, -2.08333333333333333D-01, + 4 1.25000000000000000D-01, 3.34201388888888889D-01, + 5 -4.01041666666666667D-01, 7.03125000000000000D-02, + 6 -1.02581259645061728D+00, 1.84646267361111111D+00, + 7 -8.91210937500000000D-01, 7.32421875000000000D-02, + 8 4.66958442342624743D+00, -1.12070026162229938D+01, + 9 8.78912353515625000D+00, -2.36408691406250000D+00, + A 1.12152099609375000D-01, -2.82120725582002449D+01, + B 8.46362176746007346D+01, -9.18182415432400174D+01, + C 4.25349987453884549D+01, -7.36879435947963170D+00, + D 2.27108001708984375D-01, 2.12570130039217123D+02, + E -7.65252468141181642D+02, 1.05999045252799988D+03/ + DATA C(25), C(26), C(27), C(28), C(29), C(30), C(31), C(32), + 1 C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(40), + 2 C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48)/ + 3 -6.99579627376132541D+02, 2.18190511744211590D+02, + 4 -2.64914304869515555D+01, 5.72501420974731445D-01, + 5 -1.91945766231840700D+03, 8.06172218173730938D+03, + 6 -1.35865500064341374D+04, 1.16553933368645332D+04, + 7 -5.30564697861340311D+03, 1.20090291321635246D+03, + 8 -1.08090919788394656D+02, 1.72772750258445740D+00, + 9 2.02042913309661486D+04, -9.69805983886375135D+04, + A 1.92547001232531532D+05, -2.03400177280415534D+05, + B 1.22200464983017460D+05, -4.11926549688975513D+04, + C 7.10951430248936372D+03, -4.93915304773088012D+02, + D 6.07404200127348304D+00, -2.42919187900551333D+05, + E 1.31176361466297720D+06, -2.99801591853810675D+06/ + DATA C(49), C(50), C(51), C(52), C(53), C(54), C(55), C(56), + 1 C(57), C(58), C(59), C(60), C(61), C(62), C(63), C(64), + 2 C(65), C(66), C(67), C(68), C(69), C(70), C(71), C(72)/ + 3 3.76327129765640400D+06, -2.81356322658653411D+06, + 4 1.26836527332162478D+06, -3.31645172484563578D+05, + 5 4.52187689813627263D+04, -2.49983048181120962D+03, + 6 2.43805296995560639D+01, 3.28446985307203782D+06, + 7 -1.97068191184322269D+07, 5.09526024926646422D+07, + 8 -7.41051482115326577D+07, 6.63445122747290267D+07, + 9 -3.75671766607633513D+07, 1.32887671664218183D+07, + A -2.78561812808645469D+06, 3.08186404612662398D+05, + B -1.38860897537170405D+04, 1.10017140269246738D+02, + C -4.93292536645099620D+07, 3.25573074185765749D+08, + D -9.39462359681578403D+08, 1.55359689957058006D+09, + E -1.62108055210833708D+09, 1.10684281682301447D+09/ + DATA C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(80), + 1 C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88), + 2 C(89), C(90), C(91), C(92), C(93), C(94), C(95), C(96)/ + 3 -4.95889784275030309D+08, 1.42062907797533095D+08, + 4 -2.44740627257387285D+07, 2.24376817792244943D+06, + 5 -8.40054336030240853D+04, 5.51335896122020586D+02, + 6 8.14789096118312115D+08, -5.86648149205184723D+09, + 7 1.86882075092958249D+10, -3.46320433881587779D+10, + 8 4.12801855797539740D+10, -3.30265997498007231D+10, + 9 1.79542137311556001D+10, -6.56329379261928433D+09, + A 1.55927986487925751D+09, -2.25105661889415278D+08, + B 1.73951075539781645D+07, -5.49842327572288687D+05, + C 3.03809051092238427D+03, -1.46792612476956167D+10, + D 1.14498237732025810D+11, -3.99096175224466498D+11, + E 8.19218669548577329D+11, -1.09837515608122331D+12/ + DATA C(97), C(98), C(99), C(100), C(101), C(102), C(103), C(104), + 1 C(105)/ + 2 1.00815810686538209D+12, -6.45364869245376503D+11, + 3 2.87900649906150589D+11, -8.78670721780232657D+10, + 4 1.76347306068349694D+10, -2.16716498322379509D+09, + 5 1.43157876718888981D+08, -3.87183344257261262D+06, + 6 1.82577554742931747D+04/ + DATA ALFA(1), ALFA(2), ALFA(3), ALFA(4), ALFA(5), ALFA(6), + 1 ALFA(7), ALFA(8), ALFA(9), ALFA(10), ALFA(11), ALFA(12), + 2 ALFA(13), ALFA(14), ALFA(15), ALFA(16), ALFA(17), ALFA(18), + 3 ALFA(19), ALFA(20), ALFA(21), ALFA(22)/ + 4 -4.44444444444444444D-03, -9.22077922077922078D-04, + 5 -8.84892884892884893D-05, 1.65927687832449737D-04, + 6 2.46691372741792910D-04, 2.65995589346254780D-04, + 7 2.61824297061500945D-04, 2.48730437344655609D-04, + 8 2.32721040083232098D-04, 2.16362485712365082D-04, + 9 2.00738858762752355D-04, 1.86267636637545172D-04, + A 1.73060775917876493D-04, 1.61091705929015752D-04, + B 1.50274774160908134D-04, 1.40503497391269794D-04, + C 1.31668816545922806D-04, 1.23667445598253261D-04, + D 1.16405271474737902D-04, 1.09798298372713369D-04, + E 1.03772410422992823D-04, 9.82626078369363448D-05/ + DATA ALFA(23), ALFA(24), ALFA(25), ALFA(26), ALFA(27), ALFA(28), + 1 ALFA(29), ALFA(30), ALFA(31), ALFA(32), ALFA(33), ALFA(34), + 2 ALFA(35), ALFA(36), ALFA(37), ALFA(38), ALFA(39), ALFA(40), + 3 ALFA(41), ALFA(42), ALFA(43), ALFA(44)/ + 4 9.32120517249503256D-05, 8.85710852478711718D-05, + 5 8.42963105715700223D-05, 8.03497548407791151D-05, + 6 7.66981345359207388D-05, 7.33122157481777809D-05, + 7 7.01662625163141333D-05, 6.72375633790160292D-05, + 8 6.93735541354588974D-04, 2.32241745182921654D-04, + 9 -1.41986273556691197D-05, -1.16444931672048640D-04, + A -1.50803558053048762D-04, -1.55121924918096223D-04, + B -1.46809756646465549D-04, -1.33815503867491367D-04, + C -1.19744975684254051D-04, -1.06184319207974020D-04, + D -9.37699549891194492D-05, -8.26923045588193274D-05, + E -7.29374348155221211D-05, -6.44042357721016283D-05/ + DATA ALFA(45), ALFA(46), ALFA(47), ALFA(48), ALFA(49), ALFA(50), + 1 ALFA(51), ALFA(52), ALFA(53), ALFA(54), ALFA(55), ALFA(56), + 2 ALFA(57), ALFA(58), ALFA(59), ALFA(60), ALFA(61), ALFA(62), + 3 ALFA(63), ALFA(64), ALFA(65), ALFA(66)/ + 4 -5.69611566009369048D-05, -5.04731044303561628D-05, + 5 -4.48134868008882786D-05, -3.98688727717598864D-05, + 6 -3.55400532972042498D-05, -3.17414256609022480D-05, + 7 -2.83996793904174811D-05, -2.54522720634870566D-05, + 8 -2.28459297164724555D-05, -2.05352753106480604D-05, + 9 -1.84816217627666085D-05, -1.66519330021393806D-05, + A -1.50179412980119482D-05, -1.35554031379040526D-05, + B -1.22434746473858131D-05, -1.10641884811308169D-05, + C -3.54211971457743841D-04, -1.56161263945159416D-04, + D 3.04465503594936410D-05, 1.30198655773242693D-04, + E 1.67471106699712269D-04, 1.70222587683592569D-04/ + DATA ALFA(67), ALFA(68), ALFA(69), ALFA(70), ALFA(71), ALFA(72), + 1 ALFA(73), ALFA(74), ALFA(75), ALFA(76), ALFA(77), ALFA(78), + 2 ALFA(79), ALFA(80), ALFA(81), ALFA(82), ALFA(83), ALFA(84), + 3 ALFA(85), ALFA(86), ALFA(87), ALFA(88)/ + 4 1.56501427608594704D-04, 1.36339170977445120D-04, + 5 1.14886692029825128D-04, 9.45869093034688111D-05, + 6 7.64498419250898258D-05, 6.07570334965197354D-05, + 7 4.74394299290508799D-05, 3.62757512005344297D-05, + 8 2.69939714979224901D-05, 1.93210938247939253D-05, + 9 1.30056674793963203D-05, 7.82620866744496661D-06, + A 3.59257485819351583D-06, 1.44040049814251817D-07, + B -2.65396769697939116D-06, -4.91346867098485910D-06, + C -6.72739296091248287D-06, -8.17269379678657923D-06, + D -9.31304715093561232D-06, -1.02011418798016441D-05, + E -1.08805962510592880D-05, -1.13875481509603555D-05/ + DATA ALFA(89), ALFA(90), ALFA(91), ALFA(92), ALFA(93), ALFA(94), + 1 ALFA(95), ALFA(96), ALFA(97), ALFA(98), ALFA(99), ALFA(100), + 2 ALFA(101), ALFA(102), ALFA(103), ALFA(104), ALFA(105), + 3 ALFA(106), ALFA(107), ALFA(108), ALFA(109), ALFA(110)/ + 4 -1.17519675674556414D-05, -1.19987364870944141D-05, + 5 3.78194199201772914D-04, 2.02471952761816167D-04, + 6 -6.37938506318862408D-05, -2.38598230603005903D-04, + 7 -3.10916256027361568D-04, -3.13680115247576316D-04, + 8 -2.78950273791323387D-04, -2.28564082619141374D-04, + 9 -1.75245280340846749D-04, -1.25544063060690348D-04, + A -8.22982872820208365D-05, -4.62860730588116458D-05, + B -1.72334302366962267D-05, 5.60690482304602267D-06, + C 2.31395443148286800D-05, 3.62642745856793957D-05, + D 4.58006124490188752D-05, 5.24595294959114050D-05, + E 5.68396208545815266D-05, 5.94349820393104052D-05/ + DATA ALFA(111), ALFA(112), ALFA(113), ALFA(114), ALFA(115), + 1 ALFA(116), ALFA(117), ALFA(118), ALFA(119), ALFA(120), + 2 ALFA(121), ALFA(122), ALFA(123), ALFA(124), ALFA(125), + 3 ALFA(126), ALFA(127), ALFA(128), ALFA(129), ALFA(130)/ + 4 6.06478527578421742D-05, 6.08023907788436497D-05, + 5 6.01577894539460388D-05, 5.89199657344698500D-05, + 6 5.72515823777593053D-05, 5.52804375585852577D-05, + 7 5.31063773802880170D-05, 5.08069302012325706D-05, + 8 4.84418647620094842D-05, 4.60568581607475370D-05, + 9 -6.91141397288294174D-04, -4.29976633058871912D-04, + A 1.83067735980039018D-04, 6.60088147542014144D-04, + B 8.75964969951185931D-04, 8.77335235958235514D-04, + C 7.49369585378990637D-04, 5.63832329756980918D-04, + D 3.68059319971443156D-04, 1.88464535514455599D-04/ + DATA ALFA(131), ALFA(132), ALFA(133), ALFA(134), ALFA(135), + 1 ALFA(136), ALFA(137), ALFA(138), ALFA(139), ALFA(140), + 2 ALFA(141), ALFA(142), ALFA(143), ALFA(144), ALFA(145), + 3 ALFA(146), ALFA(147), ALFA(148), ALFA(149), ALFA(150)/ + 4 3.70663057664904149D-05, -8.28520220232137023D-05, + 5 -1.72751952869172998D-04, -2.36314873605872983D-04, + 6 -2.77966150694906658D-04, -3.02079514155456919D-04, + 7 -3.12594712643820127D-04, -3.12872558758067163D-04, + 8 -3.05678038466324377D-04, -2.93226470614557331D-04, + 9 -2.77255655582934777D-04, -2.59103928467031709D-04, + A -2.39784014396480342D-04, -2.20048260045422848D-04, + B -2.00443911094971498D-04, -1.81358692210970687D-04, + C -1.63057674478657464D-04, -1.45712672175205844D-04, + D -1.29425421983924587D-04, -1.14245691942445952D-04/ + DATA ALFA(151), ALFA(152), ALFA(153), ALFA(154), ALFA(155), + 1 ALFA(156), ALFA(157), ALFA(158), ALFA(159), ALFA(160), + 2 ALFA(161), ALFA(162), ALFA(163), ALFA(164), ALFA(165), + 3 ALFA(166), ALFA(167), ALFA(168), ALFA(169), ALFA(170)/ + 4 1.92821964248775885D-03, 1.35592576302022234D-03, + 5 -7.17858090421302995D-04, -2.58084802575270346D-03, + 6 -3.49271130826168475D-03, -3.46986299340960628D-03, + 7 -2.82285233351310182D-03, -1.88103076404891354D-03, + 8 -8.89531718383947600D-04, 3.87912102631035228D-06, + 9 7.28688540119691412D-04, 1.26566373053457758D-03, + A 1.62518158372674427D-03, 1.83203153216373172D-03, + B 1.91588388990527909D-03, 1.90588846755546138D-03, + C 1.82798982421825727D-03, 1.70389506421121530D-03, + D 1.55097127171097686D-03, 1.38261421852276159D-03/ + DATA ALFA(171), ALFA(172), ALFA(173), ALFA(174), ALFA(175), + 1 ALFA(176), ALFA(177), ALFA(178), ALFA(179), ALFA(180)/ + 2 1.20881424230064774D-03, 1.03676532638344962D-03, + 3 8.71437918068619115D-04, 7.16080155297701002D-04, + 4 5.72637002558129372D-04, 4.42089819465802277D-04, + 5 3.24724948503090564D-04, 2.20342042730246599D-04, + 6 1.28412898401353882D-04, 4.82005924552095464D-05/ + DATA BETA(1), BETA(2), BETA(3), BETA(4), BETA(5), BETA(6), + 1 BETA(7), BETA(8), BETA(9), BETA(10), BETA(11), BETA(12), + 2 BETA(13), BETA(14), BETA(15), BETA(16), BETA(17), BETA(18), + 3 BETA(19), BETA(20), BETA(21), BETA(22)/ + 4 1.79988721413553309D-02, 5.59964911064388073D-03, + 5 2.88501402231132779D-03, 1.80096606761053941D-03, + 6 1.24753110589199202D-03, 9.22878876572938311D-04, + 7 7.14430421727287357D-04, 5.71787281789704872D-04, + 8 4.69431007606481533D-04, 3.93232835462916638D-04, + 9 3.34818889318297664D-04, 2.88952148495751517D-04, + A 2.52211615549573284D-04, 2.22280580798883327D-04, + B 1.97541838033062524D-04, 1.76836855019718004D-04, + C 1.59316899661821081D-04, 1.44347930197333986D-04, + D 1.31448068119965379D-04, 1.20245444949302884D-04, + E 1.10449144504599392D-04, 1.01828770740567258D-04/ + DATA BETA(23), BETA(24), BETA(25), BETA(26), BETA(27), BETA(28), + 1 BETA(29), BETA(30), BETA(31), BETA(32), BETA(33), BETA(34), + 2 BETA(35), BETA(36), BETA(37), BETA(38), BETA(39), BETA(40), + 3 BETA(41), BETA(42), BETA(43), BETA(44)/ + 4 9.41998224204237509D-05, 8.74130545753834437D-05, + 5 8.13466262162801467D-05, 7.59002269646219339D-05, + 6 7.09906300634153481D-05, 6.65482874842468183D-05, + 7 6.25146958969275078D-05, 5.88403394426251749D-05, + 8 -1.49282953213429172D-03, -8.78204709546389328D-04, + 9 -5.02916549572034614D-04, -2.94822138512746025D-04, + A -1.75463996970782828D-04, -1.04008550460816434D-04, + B -5.96141953046457895D-05, -3.12038929076098340D-05, + C -1.26089735980230047D-05, -2.42892608575730389D-07, + D 8.05996165414273571D-06, 1.36507009262147391D-05, + E 1.73964125472926261D-05, 1.98672978842133780D-05/ + DATA BETA(45), BETA(46), BETA(47), BETA(48), BETA(49), BETA(50), + 1 BETA(51), BETA(52), BETA(53), BETA(54), BETA(55), BETA(56), + 2 BETA(57), BETA(58), BETA(59), BETA(60), BETA(61), BETA(62), + 3 BETA(63), BETA(64), BETA(65), BETA(66)/ + 4 2.14463263790822639D-05, 2.23954659232456514D-05, + 5 2.28967783814712629D-05, 2.30785389811177817D-05, + 6 2.30321976080909144D-05, 2.28236073720348722D-05, + 7 2.25005881105292418D-05, 2.20981015361991429D-05, + 8 2.16418427448103905D-05, 2.11507649256220843D-05, + 9 2.06388749782170737D-05, 2.01165241997081666D-05, + A 1.95913450141179244D-05, 1.90689367910436740D-05, + B 1.85533719641636667D-05, 1.80475722259674218D-05, + C 5.52213076721292790D-04, 4.47932581552384646D-04, + D 2.79520653992020589D-04, 1.52468156198446602D-04, + E 6.93271105657043598D-05, 1.76258683069991397D-05/ + DATA BETA(67), BETA(68), BETA(69), BETA(70), BETA(71), BETA(72), + 1 BETA(73), BETA(74), BETA(75), BETA(76), BETA(77), BETA(78), + 2 BETA(79), BETA(80), BETA(81), BETA(82), BETA(83), BETA(84), + 3 BETA(85), BETA(86), BETA(87), BETA(88)/ + 4 -1.35744996343269136D-05, -3.17972413350427135D-05, + 5 -4.18861861696693365D-05, -4.69004889379141029D-05, + 6 -4.87665447413787352D-05, -4.87010031186735069D-05, + 7 -4.74755620890086638D-05, -4.55813058138628452D-05, + 8 -4.33309644511266036D-05, -4.09230193157750364D-05, + 9 -3.84822638603221274D-05, -3.60857167535410501D-05, + A -3.37793306123367417D-05, -3.15888560772109621D-05, + B -2.95269561750807315D-05, -2.75978914828335759D-05, + C -2.58006174666883713D-05, -2.41308356761280200D-05, + D -2.25823509518346033D-05, -2.11479656768912971D-05, + E -1.98200638885294927D-05, -1.85909870801065077D-05/ + DATA BETA(89), BETA(90), BETA(91), BETA(92), BETA(93), BETA(94), + 1 BETA(95), BETA(96), BETA(97), BETA(98), BETA(99), BETA(100), + 2 BETA(101), BETA(102), BETA(103), BETA(104), BETA(105), + 3 BETA(106), BETA(107), BETA(108), BETA(109), BETA(110)/ + 4 -1.74532699844210224D-05, -1.63997823854497997D-05, + 5 -4.74617796559959808D-04, -4.77864567147321487D-04, + 6 -3.20390228067037603D-04, -1.61105016119962282D-04, + 7 -4.25778101285435204D-05, 3.44571294294967503D-05, + 8 7.97092684075674924D-05, 1.03138236708272200D-04, + 9 1.12466775262204158D-04, 1.13103642108481389D-04, + A 1.08651634848774268D-04, 1.01437951597661973D-04, + B 9.29298396593363896D-05, 8.40293133016089978D-05, + C 7.52727991349134062D-05, 6.69632521975730872D-05, + D 5.92564547323194704D-05, 5.22169308826975567D-05, + E 4.58539485165360646D-05, 4.01445513891486808D-05/ + DATA BETA(111), BETA(112), BETA(113), BETA(114), BETA(115), + 1 BETA(116), BETA(117), BETA(118), BETA(119), BETA(120), + 2 BETA(121), BETA(122), BETA(123), BETA(124), BETA(125), + 3 BETA(126), BETA(127), BETA(128), BETA(129), BETA(130)/ + 4 3.50481730031328081D-05, 3.05157995034346659D-05, + 5 2.64956119950516039D-05, 2.29363633690998152D-05, + 6 1.97893056664021636D-05, 1.70091984636412623D-05, + 7 1.45547428261524004D-05, 1.23886640995878413D-05, + 8 1.04775876076583236D-05, 8.79179954978479373D-06, + 9 7.36465810572578444D-04, 8.72790805146193976D-04, + A 6.22614862573135066D-04, 2.85998154194304147D-04, + B 3.84737672879366102D-06, -1.87906003636971558D-04, + C -2.97603646594554535D-04, -3.45998126832656348D-04, + D -3.53382470916037712D-04, -3.35715635775048757D-04/ + DATA BETA(131), BETA(132), BETA(133), BETA(134), BETA(135), + 1 BETA(136), BETA(137), BETA(138), BETA(139), BETA(140), + 2 BETA(141), BETA(142), BETA(143), BETA(144), BETA(145), + 3 BETA(146), BETA(147), BETA(148), BETA(149), BETA(150)/ + 4 -3.04321124789039809D-04, -2.66722723047612821D-04, + 5 -2.27654214122819527D-04, -1.89922611854562356D-04, + 6 -1.55058918599093870D-04, -1.23778240761873630D-04, + 7 -9.62926147717644187D-05, -7.25178327714425337D-05, + 8 -5.22070028895633801D-05, -3.50347750511900522D-05, + 9 -2.06489761035551757D-05, -8.70106096849767054D-06, + A 1.13698686675100290D-06, 9.16426474122778849D-06, + B 1.56477785428872620D-05, 2.08223629482466847D-05, + C 2.48923381004595156D-05, 2.80340509574146325D-05, + D 3.03987774629861915D-05, 3.21156731406700616D-05/ + DATA BETA(151), BETA(152), BETA(153), BETA(154), BETA(155), + 1 BETA(156), BETA(157), BETA(158), BETA(159), BETA(160), + 2 BETA(161), BETA(162), BETA(163), BETA(164), BETA(165), + 3 BETA(166), BETA(167), BETA(168), BETA(169), BETA(170)/ + 4 -1.80182191963885708D-03, -2.43402962938042533D-03, + 5 -1.83422663549856802D-03, -7.62204596354009765D-04, + 6 2.39079475256927218D-04, 9.49266117176881141D-04, + 7 1.34467449701540359D-03, 1.48457495259449178D-03, + 8 1.44732339830617591D-03, 1.30268261285657186D-03, + 9 1.10351597375642682D-03, 8.86047440419791759D-04, + A 6.73073208165665473D-04, 4.77603872856582378D-04, + B 3.05991926358789362D-04, 1.60315694594721630D-04, + C 4.00749555270613286D-05, -5.66607461635251611D-05, + D -1.32506186772982638D-04, -1.90296187989614057D-04/ + DATA BETA(171), BETA(172), BETA(173), BETA(174), BETA(175), + 1 BETA(176), BETA(177), BETA(178), BETA(179), BETA(180), + 2 BETA(181), BETA(182), BETA(183), BETA(184), BETA(185), + 3 BETA(186), BETA(187), BETA(188), BETA(189), BETA(190)/ + 4 -2.32811450376937408D-04, -2.62628811464668841D-04, + 5 -2.82050469867598672D-04, -2.93081563192861167D-04, + 6 -2.97435962176316616D-04, -2.96557334239348078D-04, + 7 -2.91647363312090861D-04, -2.83696203837734166D-04, + 8 -2.73512317095673346D-04, -2.61750155806768580D-04, + 9 6.38585891212050914D-03, 9.62374215806377941D-03, + A 7.61878061207001043D-03, 2.83219055545628054D-03, + B -2.09841352012720090D-03, -5.73826764216626498D-03, + C -7.70804244495414620D-03, -8.21011692264844401D-03, + D -7.65824520346905413D-03, -6.47209729391045177D-03/ + DATA BETA(191), BETA(192), BETA(193), BETA(194), BETA(195), + 1 BETA(196), BETA(197), BETA(198), BETA(199), BETA(200), + 2 BETA(201), BETA(202), BETA(203), BETA(204), BETA(205), + 3 BETA(206), BETA(207), BETA(208), BETA(209), BETA(210)/ + 4 -4.99132412004966473D-03, -3.45612289713133280D-03, + 5 -2.01785580014170775D-03, -7.59430686781961401D-04, + 6 2.84173631523859138D-04, 1.10891667586337403D-03, + 7 1.72901493872728771D-03, 2.16812590802684701D-03, + 8 2.45357710494539735D-03, 2.61281821058334862D-03, + 9 2.67141039656276912D-03, 2.65203073395980430D-03, + A 2.57411652877287315D-03, 2.45389126236094427D-03, + B 2.30460058071795494D-03, 2.13684837686712662D-03, + C 1.95896528478870911D-03, 1.77737008679454412D-03, + D 1.59690280765839059D-03, 1.42111975664438546D-03/ + DATA GAMA(1), GAMA(2), GAMA(3), GAMA(4), GAMA(5), GAMA(6), + 1 GAMA(7), GAMA(8), GAMA(9), GAMA(10), GAMA(11), GAMA(12), + 2 GAMA(13), GAMA(14), GAMA(15), GAMA(16), GAMA(17), GAMA(18), + 3 GAMA(19), GAMA(20), GAMA(21), GAMA(22)/ + 4 6.29960524947436582D-01, 2.51984209978974633D-01, + 5 1.54790300415655846D-01, 1.10713062416159013D-01, + 6 8.57309395527394825D-02, 6.97161316958684292D-02, + 7 5.86085671893713576D-02, 5.04698873536310685D-02, + 8 4.42600580689154809D-02, 3.93720661543509966D-02, + 9 3.54283195924455368D-02, 3.21818857502098231D-02, + A 2.94646240791157679D-02, 2.71581677112934479D-02, + B 2.51768272973861779D-02, 2.34570755306078891D-02, + C 2.19508390134907203D-02, 2.06210828235646240D-02, + D 1.94388240897880846D-02, 1.83810633800683158D-02, + E 1.74293213231963172D-02, 1.65685837786612353D-02/ + DATA GAMA(23), GAMA(24), GAMA(25), GAMA(26), GAMA(27), GAMA(28), + 1 GAMA(29), GAMA(30)/ + 2 1.57865285987918445D-02, 1.50729501494095594D-02, + 3 1.44193250839954639D-02, 1.38184805735341786D-02, + 4 1.32643378994276568D-02, 1.27517121970498651D-02, + 5 1.22761545318762767D-02, 1.18338262398482403D-02/ + DATA EX1, EX2, HPI, GPI, THPI / + 1 3.33333333333333333D-01, 6.66666666666666667D-01, + 2 1.57079632679489662D+00, 3.14159265358979324D+00, + 3 4.71238898038468986D+00/ + DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 / +C + RFNU = 1.0D0/FNU +C----------------------------------------------------------------------- +C OVERFLOW TEST (Z/FNU TOO SMALL) +C----------------------------------------------------------------------- + TEST = D1MACH(1)*1.0D+3 + AC = FNU*TEST + IF (DABS(ZR).GT.AC .OR. DABS(ZI).GT.AC) GO TO 15 + ZETA1R = 2.0D0*DABS(DLOG(TEST))+FNU + ZETA1I = 0.0D0 + ZETA2R = FNU + ZETA2I = 0.0D0 + PHIR = 1.0D0 + PHII = 0.0D0 + ARGR = 1.0D0 + ARGI = 0.0D0 + RETURN + 15 CONTINUE + ZBR = ZR*RFNU + ZBI = ZI*RFNU + RFNU2 = RFNU*RFNU +C----------------------------------------------------------------------- +C COMPUTE IN THE FOURTH QUADRANT +C----------------------------------------------------------------------- + FN13 = FNU**EX1 + FN23 = FN13*FN13 + RFN13 = 1.0D0/FN13 + W2R = CONER - ZBR*ZBR + ZBI*ZBI + W2I = CONEI - ZBR*ZBI - ZBR*ZBI + AW2 = ZABS(CMPLX(W2R,W2I,kind=KIND(1.0D0))) + IF (AW2.GT.0.25D0) GO TO 130 +C----------------------------------------------------------------------- +C POWER SERIES FOR CABS(W2).LE.0.25D0 +C----------------------------------------------------------------------- + K = 1 + PR(1) = CONER + PI(1) = CONEI + SUMAR = GAMA(1) + SUMAI = ZEROI + AP(1) = 1.0D0 + IF (AW2.LT.TOL) GO TO 20 + DO 10 K=2,30 + PR(K) = PR(K-1)*W2R - PI(K-1)*W2I + PI(K) = PR(K-1)*W2I + PI(K-1)*W2R + SUMAR = SUMAR + PR(K)*GAMA(K) + SUMAI = SUMAI + PI(K)*GAMA(K) + AP(K) = AP(K-1)*AW2 + IF (AP(K).LT.TOL) GO TO 20 + 10 CONTINUE + K = 30 + 20 CONTINUE + KMAX = K + ZETAR = W2R*SUMAR - W2I*SUMAI + ZETAI = W2R*SUMAI + W2I*SUMAR + ARGR = ZETAR*FN23 + ARGI = ZETAI*FN23 + CALL ZSQRT(SUMAR, SUMAI, ZAR, ZAI) + CALL ZSQRT(W2R, W2I, STR, STI) + ZETA2R = STR*FNU + ZETA2I = STI*FNU + STR = CONER + EX2*(ZETAR*ZAR-ZETAI*ZAI) + STI = CONEI + EX2*(ZETAR*ZAI+ZETAI*ZAR) + ZETA1R = STR*ZETA2R - STI*ZETA2I + ZETA1I = STR*ZETA2I + STI*ZETA2R + ZAR = ZAR + ZAR + ZAI = ZAI + ZAI + CALL ZSQRT(ZAR, ZAI, STR, STI) + PHIR = STR*RFN13 + PHII = STI*RFN13 + IF (IPMTR.EQ.1) GO TO 120 +C----------------------------------------------------------------------- +C SUM SERIES FOR ASUM AND BSUM +C----------------------------------------------------------------------- + SUMBR = ZEROR + SUMBI = ZEROI + DO 30 K=1,KMAX + SUMBR = SUMBR + PR(K)*BETA(K) + SUMBI = SUMBI + PI(K)*BETA(K) + 30 CONTINUE + ASUMR = ZEROR + ASUMI = ZEROI + BSUMR = SUMBR + BSUMI = SUMBI + L1 = 0 + L2 = 30 + BTOL = TOL*(DABS(BSUMR)+DABS(BSUMI)) + ATOL = TOL + PP = 1.0D0 + IAS = 0 + IBS = 0 + IF (RFNU2.LT.TOL) GO TO 110 + DO 100 IS=2,7 + ATOL = ATOL/RFNU2 + PP = PP*RFNU2 + IF (IAS.EQ.1) GO TO 60 + SUMAR = ZEROR + SUMAI = ZEROI + DO 40 K=1,KMAX + M = L1 + K + SUMAR = SUMAR + PR(K)*ALFA(M) + SUMAI = SUMAI + PI(K)*ALFA(M) + IF (AP(K).LT.ATOL) GO TO 50 + 40 CONTINUE + 50 CONTINUE + ASUMR = ASUMR + SUMAR*PP + ASUMI = ASUMI + SUMAI*PP + IF (PP.LT.TOL) IAS = 1 + 60 CONTINUE + IF (IBS.EQ.1) GO TO 90 + SUMBR = ZEROR + SUMBI = ZEROI + DO 70 K=1,KMAX + M = L2 + K + SUMBR = SUMBR + PR(K)*BETA(M) + SUMBI = SUMBI + PI(K)*BETA(M) + IF (AP(K).LT.ATOL) GO TO 80 + 70 CONTINUE + 80 CONTINUE + BSUMR = BSUMR + SUMBR*PP + BSUMI = BSUMI + SUMBI*PP + IF (PP.LT.BTOL) IBS = 1 + 90 CONTINUE + IF (IAS.EQ.1 .AND. IBS.EQ.1) GO TO 110 + L1 = L1 + 30 + L2 = L2 + 30 + 100 CONTINUE + 110 CONTINUE + ASUMR = ASUMR + CONER + PP = RFNU*RFN13 + BSUMR = BSUMR*PP + BSUMI = BSUMI*PP + 120 CONTINUE + RETURN +C----------------------------------------------------------------------- +C CABS(W2).GT.0.25D0 +C----------------------------------------------------------------------- + 130 CONTINUE + CALL ZSQRT(W2R, W2I, WR, WI) + IF (WR.LT.0.0D0) WR = 0.0D0 + IF (WI.LT.0.0D0) WI = 0.0D0 + STR = CONER + WR + STI = WI + CALL ZDIV(STR, STI, ZBR, ZBI, ZAR, ZAI) + CALL ZLOG(ZAR, ZAI, ZCR, ZCI, IDUM) + IF (ZCI.LT.0.0D0) ZCI = 0.0D0 + IF (ZCI.GT.HPI) ZCI = HPI + IF (ZCR.LT.0.0D0) ZCR = 0.0D0 + ZTHR = (ZCR-WR)*1.5D0 + ZTHI = (ZCI-WI)*1.5D0 + ZETA1R = ZCR*FNU + ZETA1I = ZCI*FNU + ZETA2R = WR*FNU + ZETA2I = WI*FNU + AZTH = ZABS(CMPLX(ZTHR,ZTHI,kind=KIND(1.0D0))) + ANG = THPI + IF (ZTHR.GE.0.0D0 .AND. ZTHI.LT.0.0D0) GO TO 140 + ANG = HPI + IF (ZTHR.EQ.0.0D0) GO TO 140 + ANG = DATAN(ZTHI/ZTHR) + IF (ZTHR.LT.0.0D0) ANG = ANG + GPI + 140 CONTINUE + PP = AZTH**EX2 + ANG = ANG*EX2 + ZETAR = PP*DCOS(ANG) + ZETAI = PP*DSIN(ANG) + IF (ZETAI.LT.0.0D0) ZETAI = 0.0D0 + ARGR = ZETAR*FN23 + ARGI = ZETAI*FN23 + CALL ZDIV(ZTHR, ZTHI, ZETAR, ZETAI, RTZTR, RTZTI) + CALL ZDIV(RTZTR, RTZTI, WR, WI, ZAR, ZAI) + TZAR = ZAR + ZAR + TZAI = ZAI + ZAI + CALL ZSQRT(TZAR, TZAI, STR, STI) + PHIR = STR*RFN13 + PHII = STI*RFN13 + IF (IPMTR.EQ.1) GO TO 120 + RAW = 1.0D0/DSQRT(AW2) + STR = WR*RAW + STI = -WI*RAW + TFNR = STR*RFNU*RAW + TFNI = STI*RFNU*RAW + RAZTH = 1.0D0/AZTH + STR = ZTHR*RAZTH + STI = -ZTHI*RAZTH + RZTHR = STR*RAZTH*RFNU + RZTHI = STI*RAZTH*RFNU + ZCR = RZTHR*AR(2) + ZCI = RZTHI*AR(2) + RAW2 = 1.0D0/AW2 + STR = W2R*RAW2 + STI = -W2I*RAW2 + T2R = STR*RAW2 + T2I = STI*RAW2 + STR = T2R*C(2) + C(3) + STI = T2I*C(2) + UPR(2) = STR*TFNR - STI*TFNI + UPI(2) = STR*TFNI + STI*TFNR + BSUMR = UPR(2) + ZCR + BSUMI = UPI(2) + ZCI + ASUMR = ZEROR + ASUMI = ZEROI + IF (RFNU.LT.TOL) GO TO 220 + PRZTHR = RZTHR + PRZTHI = RZTHI + PTFNR = TFNR + PTFNI = TFNI + UPR(1) = CONER + UPI(1) = CONEI + PP = 1.0D0 + BTOL = TOL*(DABS(BSUMR)+DABS(BSUMI)) + KS = 0 + KP1 = 2 + L = 3 + IAS = 0 + IBS = 0 + DO 210 LR=2,12,2 + LRP1 = LR + 1 +C----------------------------------------------------------------------- +C COMPUTE TWO ADDITIONAL CR, DR, AND UP FOR TWO MORE TERMS IN +C NEXT SUMA AND SUMB +C----------------------------------------------------------------------- + DO 160 K=LR,LRP1 + KS = KS + 1 + KP1 = KP1 + 1 + L = L + 1 + ZAR = C(L) + ZAI = ZEROI + DO 150 J=2,KP1 + L = L + 1 + STR = ZAR*T2R - T2I*ZAI + C(L) + ZAI = ZAR*T2I + ZAI*T2R + ZAR = STR + 150 CONTINUE + STR = PTFNR*TFNR - PTFNI*TFNI + PTFNI = PTFNR*TFNI + PTFNI*TFNR + PTFNR = STR + UPR(KP1) = PTFNR*ZAR - PTFNI*ZAI + UPI(KP1) = PTFNI*ZAR + PTFNR*ZAI + CRR(KS) = PRZTHR*BR(KS+1) + CRI(KS) = PRZTHI*BR(KS+1) + STR = PRZTHR*RZTHR - PRZTHI*RZTHI + PRZTHI = PRZTHR*RZTHI + PRZTHI*RZTHR + PRZTHR = STR + DRR(KS) = PRZTHR*AR(KS+2) + DRI(KS) = PRZTHI*AR(KS+2) + 160 CONTINUE + PP = PP*RFNU2 + IF (IAS.EQ.1) GO TO 180 + SUMAR = UPR(LRP1) + SUMAI = UPI(LRP1) + JU = LRP1 + DO 170 JR=1,LR + JU = JU - 1 + SUMAR = SUMAR + CRR(JR)*UPR(JU) - CRI(JR)*UPI(JU) + SUMAI = SUMAI + CRR(JR)*UPI(JU) + CRI(JR)*UPR(JU) + 170 CONTINUE + ASUMR = ASUMR + SUMAR + ASUMI = ASUMI + SUMAI + TEST = DABS(SUMAR) + DABS(SUMAI) + IF (PP.LT.TOL .AND. TEST.LT.TOL) IAS = 1 + 180 CONTINUE + IF (IBS.EQ.1) GO TO 200 + SUMBR = UPR(LR+2) + UPR(LRP1)*ZCR - UPI(LRP1)*ZCI + SUMBI = UPI(LR+2) + UPR(LRP1)*ZCI + UPI(LRP1)*ZCR + JU = LRP1 + DO 190 JR=1,LR + JU = JU - 1 + SUMBR = SUMBR + DRR(JR)*UPR(JU) - DRI(JR)*UPI(JU) + SUMBI = SUMBI + DRR(JR)*UPI(JU) + DRI(JR)*UPR(JU) + 190 CONTINUE + BSUMR = BSUMR + SUMBR + BSUMI = BSUMI + SUMBI + TEST = DABS(SUMBR) + DABS(SUMBI) + IF (PP.LT.BTOL .AND. TEST.LT.BTOL) IBS = 1 + 200 CONTINUE + IF (IAS.EQ.1 .AND. IBS.EQ.1) GO TO 220 + 210 CONTINUE + 220 CONTINUE + ASUMR = ASUMR + CONER + STR = -BSUMR*RFN13 + STI = -BSUMI*RFN13 + CALL ZDIV(STR, STI, RTZTR, RTZTI, BSUMR, BSUMI) + GO TO 120 + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuni1.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuni1.f new file mode 100644 index 00000000..f3a0f246 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuni1.f @@ -0,0 +1,204 @@ + SUBROUTINE ZUNI1(ZR, ZI, FNU, KODE, N, YR, YI, NZ, NLAST, FNUL, + * TOL, ELIM, ALIM) +C***BEGIN PROLOGUE ZUNI1 +C***REFER TO ZBESI,ZBESK +C +C ZUNI1 COMPUTES I(FNU,Z) BY MEANS OF THE UNIFORM ASYMPTOTIC +C EXPANSION FOR I(FNU,Z) IN -PI/3.LE.ARG Z.LE.PI/3. +C +C FNUL IS THE SMALLEST ORDER PERMITTED FOR THE ASYMPTOTIC +C EXPANSION. NLAST=0 MEANS ALL OF THE Y VALUES WERE SET. +C NLAST.NE.0 IS THE NUMBER LEFT TO BE COMPUTED BY ANOTHER +C FORMULA FOR ORDERS FNU TO FNU+NLAST-1 BECAUSE FNU+NLAST-1.LT.FNUL. +C Y(I)=CZERO FOR I=NLAST+1,N +C +C***ROUTINES CALLED ZUCHK,ZUNIK,ZUOIK,D1MACH,ZABS +C***END PROLOGUE ZUNI1 +C COMPLEX CFN,CONE,CRSC,CSCL,CSR,CSS,CWRK,CZERO,C1,C2,PHI,RZ,SUM,S1, +C *S2,Y,Z,ZETA1,ZETA2 + DOUBLE PRECISION ALIM, APHI, ASCLE, BRY, CONER, CRSC, + * CSCL, CSRR, CSSR, CWRKI, CWRKR, C1R, C2I, C2M, C2R, ELIM, FN, + * FNU, FNUL, PHII, PHIR, RAST, RS1, RZI, RZR, STI, STR, SUMI, + * SUMR, S1I, S1R, S2I, S2R, TOL, YI, YR, ZEROI, ZEROR, ZETA1I, + * ZETA1R, ZETA2I, ZETA2R, ZI, ZR, CYR, CYI, D1MACH, ZABS + INTEGER I, IFLAG, INIT, K, KODE, M, N, ND, NLAST, NN, NUF, NW, NZ + DIMENSION BRY(3), YR(N), YI(N), CWRKR(16), CWRKI(16), CSSR(3), + * CSRR(3), CYR(2), CYI(2) + DATA ZEROR,ZEROI,CONER / 0.0D0, 0.0D0, 1.0D0 / +C + NZ = 0 + ND = N + NLAST = 0 +C----------------------------------------------------------------------- +C COMPUTED VALUES WITH EXPONENTS BETWEEN ALIM AND ELIM IN MAG- +C NITUDE ARE SCALED TO KEEP INTERMEDIATE ARITHMETIC ON SCALE, +C EXP(ALIM)=EXP(ELIM)*TOL +C----------------------------------------------------------------------- + CSCL = 1.0D0/TOL + CRSC = TOL + CSSR(1) = CSCL + CSSR(2) = CONER + CSSR(3) = CRSC + CSRR(1) = CRSC + CSRR(2) = CONER + CSRR(3) = CSCL + BRY(1) = 1.0D+3*D1MACH(1)/TOL +C----------------------------------------------------------------------- +C CHECK FOR UNDERFLOW AND OVERFLOW ON FIRST MEMBER +C----------------------------------------------------------------------- + FN = DMAX1(FNU,1.0D0) + INIT = 0 + CALL ZUNIK(ZR, ZI, FN, 1, 1, TOL, INIT, PHIR, PHII, ZETA1R, + * ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI) + IF (KODE.EQ.1) GO TO 10 + STR = ZR + ZETA2R + STI = ZI + ZETA2I + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = -ZETA1R + STR + S1I = -ZETA1I + STI + GO TO 20 + 10 CONTINUE + S1R = -ZETA1R + ZETA2R + S1I = -ZETA1I + ZETA2I + 20 CONTINUE + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 130 + 30 CONTINUE + NN = MIN0(2,ND) + DO 80 I=1,NN + FN = FNU + DBLE(FLOAT(ND-I)) + INIT = 0 + CALL ZUNIK(ZR, ZI, FN, 1, 0, TOL, INIT, PHIR, PHII, ZETA1R, + * ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI) + IF (KODE.EQ.1) GO TO 40 + STR = ZR + ZETA2R + STI = ZI + ZETA2I + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = -ZETA1R + STR + S1I = -ZETA1I + STI + ZI + GO TO 50 + 40 CONTINUE + S1R = -ZETA1R + ZETA2R + S1I = -ZETA1I + ZETA2I + 50 CONTINUE +C----------------------------------------------------------------------- +C TEST FOR UNDERFLOW AND OVERFLOW +C----------------------------------------------------------------------- + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 110 + IF (I.EQ.1) IFLAG = 2 + IF (DABS(RS1).LT.ALIM) GO TO 60 +C----------------------------------------------------------------------- +C REFINE TEST AND SCALE +C----------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIR,PHII,kind=KIND(1.0D0))) + RS1 = RS1 + DLOG(APHI) + IF (DABS(RS1).GT.ELIM) GO TO 110 + IF (I.EQ.1) IFLAG = 1 + IF (RS1.LT.0.0D0) GO TO 60 + IF (I.EQ.1) IFLAG = 3 + 60 CONTINUE +C----------------------------------------------------------------------- +C SCALE S1 IF CABS(S1).LT.ASCLE +C----------------------------------------------------------------------- + S2R = PHIR*SUMR - PHII*SUMI + S2I = PHIR*SUMI + PHII*SUMR + STR = DEXP(S1R)*CSSR(IFLAG) + S1R = STR*DCOS(S1I) + S1I = STR*DSIN(S1I) + STR = S2R*S1R - S2I*S1I + S2I = S2R*S1I + S2I*S1R + S2R = STR + IF (IFLAG.NE.1) GO TO 70 + CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL) + IF (NW.NE.0) GO TO 110 + 70 CONTINUE + CYR(I) = S2R + CYI(I) = S2I + M = ND - I + 1 + YR(M) = S2R*CSRR(IFLAG) + YI(M) = S2I*CSRR(IFLAG) + 80 CONTINUE + IF (ND.LE.2) GO TO 100 + RAST = 1.0D0/ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + STR = ZR*RAST + STI = -ZI*RAST + RZR = (STR+STR)*RAST + RZI = (STI+STI)*RAST + BRY(2) = 1.0D0/BRY(1) + BRY(3) = D1MACH(2) + S1R = CYR(1) + S1I = CYI(1) + S2R = CYR(2) + S2I = CYI(2) + C1R = CSRR(IFLAG) + ASCLE = BRY(IFLAG) + K = ND - 2 + FN = DBLE(FLOAT(K)) + DO 90 I=3,ND + C2R = S2R + C2I = S2I + S2R = S1R + (FNU+FN)*(RZR*C2R-RZI*C2I) + S2I = S1I + (FNU+FN)*(RZR*C2I+RZI*C2R) + S1R = C2R + S1I = C2I + C2R = S2R*C1R + C2I = S2I*C1R + YR(K) = C2R + YI(K) = C2I + K = K - 1 + FN = FN - 1.0D0 + IF (IFLAG.GE.3) GO TO 90 + STR = DABS(C2R) + STI = DABS(C2I) + C2M = DMAX1(STR,STI) + IF (C2M.LE.ASCLE) GO TO 90 + IFLAG = IFLAG + 1 + ASCLE = BRY(IFLAG) + S1R = S1R*C1R + S1I = S1I*C1R + S2R = C2R + S2I = C2I + S1R = S1R*CSSR(IFLAG) + S1I = S1I*CSSR(IFLAG) + S2R = S2R*CSSR(IFLAG) + S2I = S2I*CSSR(IFLAG) + C1R = CSRR(IFLAG) + 90 CONTINUE + 100 CONTINUE + RETURN +C----------------------------------------------------------------------- +C SET UNDERFLOW AND UPDATE PARAMETERS +C----------------------------------------------------------------------- + 110 CONTINUE + IF (RS1.GT.0.0D0) GO TO 120 + YR(ND) = ZEROR + YI(ND) = ZEROI + NZ = NZ + 1 + ND = ND - 1 + IF (ND.EQ.0) GO TO 100 + CALL ZUOIK(ZR, ZI, FNU, KODE, 1, ND, YR, YI, NUF, TOL, ELIM, ALIM) + IF (NUF.LT.0) GO TO 120 + ND = ND - NUF + NZ = NZ + NUF + IF (ND.EQ.0) GO TO 100 + FN = FNU + DBLE(FLOAT(ND-1)) + IF (FN.GE.FNUL) GO TO 30 + NLAST = ND + RETURN + 120 CONTINUE + NZ = -1 + RETURN + 130 CONTINUE + IF (RS1.GT.0.0D0) GO TO 120 + NZ = N + DO 140 I=1,N + YR(I) = ZEROR + YI(I) = ZEROI + 140 CONTINUE + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuni2.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuni2.f new file mode 100644 index 00000000..9e5cfcdd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuni2.f @@ -0,0 +1,267 @@ + SUBROUTINE ZUNI2(ZR, ZI, FNU, KODE, N, YR, YI, NZ, NLAST, FNUL, + * TOL, ELIM, ALIM) +C***BEGIN PROLOGUE ZUNI2 +C***REFER TO ZBESI,ZBESK +C +C ZUNI2 COMPUTES I(FNU,Z) IN THE RIGHT HALF PLANE BY MEANS OF +C UNIFORM ASYMPTOTIC EXPANSION FOR J(FNU,ZN) WHERE ZN IS Z*I +C OR -Z*I AND ZN IS IN THE RIGHT HALF PLANE ALSO. +C +C FNUL IS THE SMALLEST ORDER PERMITTED FOR THE ASYMPTOTIC +C EXPANSION. NLAST=0 MEANS ALL OF THE Y VALUES WERE SET. +C NLAST.NE.0 IS THE NUMBER LEFT TO BE COMPUTED BY ANOTHER +C FORMULA FOR ORDERS FNU TO FNU+NLAST-1 BECAUSE FNU+NLAST-1.LT.FNUL. +C Y(I)=CZERO FOR I=NLAST+1,N +C +C***ROUTINES CALLED ZAIRY,ZUCHK,ZUNHJ,ZUOIK,D1MACH,ZABS +C***END PROLOGUE ZUNI2 +C COMPLEX AI,ARG,ASUM,BSUM,CFN,CI,CID,CIP,CONE,CRSC,CSCL,CSR,CSS, +C *CZERO,C1,C2,DAI,PHI,RZ,S1,S2,Y,Z,ZB,ZETA1,ZETA2,ZN + DOUBLE PRECISION AARG, AIC, AII, AIR, ALIM, ANG, APHI, ARGI, + * ARGR, ASCLE, ASUMI, ASUMR, BRY, BSUMI, BSUMR, CIDI, CIPI, CIPR, + * CONER, CRSC, CSCL, CSRR, CSSR, C1R, C2I, C2M, C2R, DAII, + * DAIR, ELIM, FN, FNU, FNUL, HPI, PHII, PHIR, RAST, RAZ, RS1, RZI, + * RZR, STI, STR, S1I, S1R, S2I, S2R, TOL, YI, YR, ZBI, ZBR, ZEROI, + * ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, ZI, ZNI, ZNR, ZR, CYR, + * CYI, D1MACH, ZABS, CAR, SAR + INTEGER I, IFLAG, IN, INU, J, K, KODE, N, NAI, ND, NDAI, NLAST, + * NN, NUF, NW, NZ, IDUM + DIMENSION BRY(3), YR(N), YI(N), CIPR(4), CIPI(4), CSSR(3), + * CSRR(3), CYR(2), CYI(2) + DATA ZEROR,ZEROI,CONER / 0.0D0, 0.0D0, 1.0D0 / + DATA CIPR(1),CIPI(1),CIPR(2),CIPI(2),CIPR(3),CIPI(3),CIPR(4), + * CIPI(4)/ 1.0D0,0.0D0, 0.0D0,1.0D0, -1.0D0,0.0D0, 0.0D0,-1.0D0/ + DATA HPI, AIC / + 1 1.57079632679489662D+00, 1.265512123484645396D+00/ +C + NZ = 0 + ND = N + NLAST = 0 +C----------------------------------------------------------------------- +C COMPUTED VALUES WITH EXPONENTS BETWEEN ALIM AND ELIM IN MAG- +C NITUDE ARE SCALED TO KEEP INTERMEDIATE ARITHMETIC ON SCALE, +C EXP(ALIM)=EXP(ELIM)*TOL +C----------------------------------------------------------------------- + CSCL = 1.0D0/TOL + CRSC = TOL + CSSR(1) = CSCL + CSSR(2) = CONER + CSSR(3) = CRSC + CSRR(1) = CRSC + CSRR(2) = CONER + CSRR(3) = CSCL + BRY(1) = 1.0D+3*D1MACH(1)/TOL +C----------------------------------------------------------------------- +C ZN IS IN THE RIGHT HALF PLANE AFTER ROTATION BY CI OR -CI +C----------------------------------------------------------------------- + ZNR = ZI + ZNI = -ZR + ZBR = ZR + ZBI = ZI + CIDI = -CONER + INU = INT(SNGL(FNU)) + ANG = HPI*(FNU-DBLE(FLOAT(INU))) + C2R = DCOS(ANG) + C2I = DSIN(ANG) + CAR = C2R + SAR = C2I + IN = INU + N - 1 + IN = MOD(IN,4) + 1 + STR = C2R*CIPR(IN) - C2I*CIPI(IN) + C2I = C2R*CIPI(IN) + C2I*CIPR(IN) + C2R = STR + IF (ZI.GT.0.0D0) GO TO 10 + ZNR = -ZNR + ZBI = -ZBI + CIDI = -CIDI + C2I = -C2I + 10 CONTINUE +C----------------------------------------------------------------------- +C CHECK FOR UNDERFLOW AND OVERFLOW ON FIRST MEMBER +C----------------------------------------------------------------------- + FN = DMAX1(FNU,1.0D0) + CALL ZUNHJ(ZNR, ZNI, FN, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R, + * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI) + IF (KODE.EQ.1) GO TO 20 + STR = ZBR + ZETA2R + STI = ZBI + ZETA2I + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = -ZETA1R + STR + S1I = -ZETA1I + STI + GO TO 30 + 20 CONTINUE + S1R = -ZETA1R + ZETA2R + S1I = -ZETA1I + ZETA2I + 30 CONTINUE + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 150 + 40 CONTINUE + NN = MIN0(2,ND) + DO 90 I=1,NN + FN = FNU + DBLE(FLOAT(ND-I)) + CALL ZUNHJ(ZNR, ZNI, FN, 0, TOL, PHIR, PHII, ARGR, ARGI, + * ZETA1R, ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI) + IF (KODE.EQ.1) GO TO 50 + STR = ZBR + ZETA2R + STI = ZBI + ZETA2I + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = -ZETA1R + STR + S1I = -ZETA1I + STI + DABS(ZI) + GO TO 60 + 50 CONTINUE + S1R = -ZETA1R + ZETA2R + S1I = -ZETA1I + ZETA2I + 60 CONTINUE +C----------------------------------------------------------------------- +C TEST FOR UNDERFLOW AND OVERFLOW +C----------------------------------------------------------------------- + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 120 + IF (I.EQ.1) IFLAG = 2 + IF (DABS(RS1).LT.ALIM) GO TO 70 +C----------------------------------------------------------------------- +C REFINE TEST AND SCALE +C----------------------------------------------------------------------- +C----------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIR,PHII,kind=KIND(1.0D0))) + AARG = ZABS(CMPLX(ARGR,ARGI,kind=KIND(1.0D0))) + RS1 = RS1 + DLOG(APHI) - 0.25D0*DLOG(AARG) - AIC + IF (DABS(RS1).GT.ELIM) GO TO 120 + IF (I.EQ.1) IFLAG = 1 + IF (RS1.LT.0.0D0) GO TO 70 + IF (I.EQ.1) IFLAG = 3 + 70 CONTINUE +C----------------------------------------------------------------------- +C SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR +C EXPONENT EXTREMES +C----------------------------------------------------------------------- + CALL ZAIRY(ARGR, ARGI, 0, 2, AIR, AII, NAI, IDUM) + CALL ZAIRY(ARGR, ARGI, 1, 2, DAIR, DAII, NDAI, IDUM) + STR = DAIR*BSUMR - DAII*BSUMI + STI = DAIR*BSUMI + DAII*BSUMR + STR = STR + (AIR*ASUMR-AII*ASUMI) + STI = STI + (AIR*ASUMI+AII*ASUMR) + S2R = PHIR*STR - PHII*STI + S2I = PHIR*STI + PHII*STR + STR = DEXP(S1R)*CSSR(IFLAG) + S1R = STR*DCOS(S1I) + S1I = STR*DSIN(S1I) + STR = S2R*S1R - S2I*S1I + S2I = S2R*S1I + S2I*S1R + S2R = STR + IF (IFLAG.NE.1) GO TO 80 + CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL) + IF (NW.NE.0) GO TO 120 + 80 CONTINUE + IF (ZI.LE.0.0D0) S2I = -S2I + STR = S2R*C2R - S2I*C2I + S2I = S2R*C2I + S2I*C2R + S2R = STR + CYR(I) = S2R + CYI(I) = S2I + J = ND - I + 1 + YR(J) = S2R*CSRR(IFLAG) + YI(J) = S2I*CSRR(IFLAG) + STR = -C2I*CIDI + C2I = C2R*CIDI + C2R = STR + 90 CONTINUE + IF (ND.LE.2) GO TO 110 + RAZ = 1.0D0/ZABS(CMPLX(ZR,ZI,kind=KIND(1.0D0))) + STR = ZR*RAZ + STI = -ZI*RAZ + RZR = (STR+STR)*RAZ + RZI = (STI+STI)*RAZ + BRY(2) = 1.0D0/BRY(1) + BRY(3) = D1MACH(2) + S1R = CYR(1) + S1I = CYI(1) + S2R = CYR(2) + S2I = CYI(2) + C1R = CSRR(IFLAG) + ASCLE = BRY(IFLAG) + K = ND - 2 + FN = DBLE(FLOAT(K)) + DO 100 I=3,ND + C2R = S2R + C2I = S2I + S2R = S1R + (FNU+FN)*(RZR*C2R-RZI*C2I) + S2I = S1I + (FNU+FN)*(RZR*C2I+RZI*C2R) + S1R = C2R + S1I = C2I + C2R = S2R*C1R + C2I = S2I*C1R + YR(K) = C2R + YI(K) = C2I + K = K - 1 + FN = FN - 1.0D0 + IF (IFLAG.GE.3) GO TO 100 + STR = DABS(C2R) + STI = DABS(C2I) + C2M = DMAX1(STR,STI) + IF (C2M.LE.ASCLE) GO TO 100 + IFLAG = IFLAG + 1 + ASCLE = BRY(IFLAG) + S1R = S1R*C1R + S1I = S1I*C1R + S2R = C2R + S2I = C2I + S1R = S1R*CSSR(IFLAG) + S1I = S1I*CSSR(IFLAG) + S2R = S2R*CSSR(IFLAG) + S2I = S2I*CSSR(IFLAG) + C1R = CSRR(IFLAG) + 100 CONTINUE + 110 CONTINUE + RETURN + 120 CONTINUE + IF (RS1.GT.0.0D0) GO TO 140 +C----------------------------------------------------------------------- +C SET UNDERFLOW AND UPDATE PARAMETERS +C----------------------------------------------------------------------- + YR(ND) = ZEROR + YI(ND) = ZEROI + NZ = NZ + 1 + ND = ND - 1 + IF (ND.EQ.0) GO TO 110 + CALL ZUOIK(ZR, ZI, FNU, KODE, 1, ND, YR, YI, NUF, TOL, ELIM, ALIM) + IF (NUF.LT.0) GO TO 140 + ND = ND - NUF + NZ = NZ + NUF + IF (ND.EQ.0) GO TO 110 + FN = FNU + DBLE(FLOAT(ND-1)) + IF (FN.LT.FNUL) GO TO 130 +C FN = CIDI +C J = NUF + 1 +C K = MOD(J,4) + 1 +C S1R = CIPR(K) +C S1I = CIPI(K) +C IF (FN.LT.0.0D0) S1I = -S1I +C STR = C2R*S1R - C2I*S1I +C C2I = C2R*S1I + C2I*S1R +C C2R = STR + IN = INU + ND - 1 + IN = MOD(IN,4) + 1 + C2R = CAR*CIPR(IN) - SAR*CIPI(IN) + C2I = CAR*CIPI(IN) + SAR*CIPR(IN) + IF (ZI.LE.0.0D0) C2I = -C2I + GO TO 40 + 130 CONTINUE + NLAST = ND + RETURN + 140 CONTINUE + NZ = -1 + RETURN + 150 CONTINUE + IF (RS1.GT.0.0D0) GO TO 140 + NZ = N + DO 160 I=1,N + YR(I) = ZEROR + YI(I) = ZEROI + 160 CONTINUE + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunik.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunik.f new file mode 100644 index 00000000..3e8293e3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunik.f @@ -0,0 +1,211 @@ + SUBROUTINE ZUNIK(ZRR, ZRI, FNU, IKFLG, IPMTR, TOL, INIT, PHIR, + * PHII, ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI) +C***BEGIN PROLOGUE ZUNIK +C***REFER TO ZBESI,ZBESK +C +C ZUNIK COMPUTES PARAMETERS FOR THE UNIFORM ASYMPTOTIC +C EXPANSIONS OF THE I AND K FUNCTIONS ON IKFLG= 1 OR 2 +C RESPECTIVELY BY +C +C W(FNU,ZR) = PHI*EXP(ZETA)*SUM +C +C WHERE ZETA=-ZETA1 + ZETA2 OR +C ZETA1 - ZETA2 +C +C THE FIRST CALL MUST HAVE INIT=0. SUBSEQUENT CALLS WITH THE +C SAME ZR AND FNU WILL RETURN THE I OR K FUNCTION ON IKFLG= +C 1 OR 2 WITH NO CHANGE IN INIT. CWRK IS A COMPLEX WORK +C ARRAY. IPMTR=0 COMPUTES ALL PARAMETERS. IPMTR=1 COMPUTES PHI, +C ZETA1,ZETA2. +C +C***ROUTINES CALLED ZDIV,ZLOG,ZSQRT,D1MACH +C***END PROLOGUE ZUNIK +C COMPLEX CFN,CON,CONE,CRFN,CWRK,CZERO,PHI,S,SR,SUM,T,T2,ZETA1, +C *ZETA2,ZN,ZR + DOUBLE PRECISION AC, C, CON, CONEI, CONER, CRFNI, CRFNR, CWRKI, + * CWRKR, FNU, PHII, PHIR, RFN, SI, SR, SRI, SRR, STI, STR, SUMI, + * SUMR, TEST, TI, TOL, TR, T2I, T2R, ZEROI, ZEROR, ZETA1I, ZETA1R, + * ZETA2I, ZETA2R, ZNI, ZNR, ZRI, ZRR, D1MACH + INTEGER I, IDUM, IKFLG, INIT, IPMTR, J, K, L + DIMENSION C(120), CWRKR(16), CWRKI(16), CON(2) + DATA ZEROR,ZEROI,CONER,CONEI / 0.0D0, 0.0D0, 1.0D0, 0.0D0 / + DATA CON(1), CON(2) / + 1 3.98942280401432678D-01, 1.25331413731550025D+00 / + DATA C(1), C(2), C(3), C(4), C(5), C(6), C(7), C(8), C(9), C(10), + 1 C(11), C(12), C(13), C(14), C(15), C(16), C(17), C(18), + 2 C(19), C(20), C(21), C(22), C(23), C(24)/ + 3 1.00000000000000000D+00, -2.08333333333333333D-01, + 4 1.25000000000000000D-01, 3.34201388888888889D-01, + 5 -4.01041666666666667D-01, 7.03125000000000000D-02, + 6 -1.02581259645061728D+00, 1.84646267361111111D+00, + 7 -8.91210937500000000D-01, 7.32421875000000000D-02, + 8 4.66958442342624743D+00, -1.12070026162229938D+01, + 9 8.78912353515625000D+00, -2.36408691406250000D+00, + A 1.12152099609375000D-01, -2.82120725582002449D+01, + B 8.46362176746007346D+01, -9.18182415432400174D+01, + C 4.25349987453884549D+01, -7.36879435947963170D+00, + D 2.27108001708984375D-01, 2.12570130039217123D+02, + E -7.65252468141181642D+02, 1.05999045252799988D+03/ + DATA C(25), C(26), C(27), C(28), C(29), C(30), C(31), C(32), + 1 C(33), C(34), C(35), C(36), C(37), C(38), C(39), C(40), + 2 C(41), C(42), C(43), C(44), C(45), C(46), C(47), C(48)/ + 3 -6.99579627376132541D+02, 2.18190511744211590D+02, + 4 -2.64914304869515555D+01, 5.72501420974731445D-01, + 5 -1.91945766231840700D+03, 8.06172218173730938D+03, + 6 -1.35865500064341374D+04, 1.16553933368645332D+04, + 7 -5.30564697861340311D+03, 1.20090291321635246D+03, + 8 -1.08090919788394656D+02, 1.72772750258445740D+00, + 9 2.02042913309661486D+04, -9.69805983886375135D+04, + A 1.92547001232531532D+05, -2.03400177280415534D+05, + B 1.22200464983017460D+05, -4.11926549688975513D+04, + C 7.10951430248936372D+03, -4.93915304773088012D+02, + D 6.07404200127348304D+00, -2.42919187900551333D+05, + E 1.31176361466297720D+06, -2.99801591853810675D+06/ + DATA C(49), C(50), C(51), C(52), C(53), C(54), C(55), C(56), + 1 C(57), C(58), C(59), C(60), C(61), C(62), C(63), C(64), + 2 C(65), C(66), C(67), C(68), C(69), C(70), C(71), C(72)/ + 3 3.76327129765640400D+06, -2.81356322658653411D+06, + 4 1.26836527332162478D+06, -3.31645172484563578D+05, + 5 4.52187689813627263D+04, -2.49983048181120962D+03, + 6 2.43805296995560639D+01, 3.28446985307203782D+06, + 7 -1.97068191184322269D+07, 5.09526024926646422D+07, + 8 -7.41051482115326577D+07, 6.63445122747290267D+07, + 9 -3.75671766607633513D+07, 1.32887671664218183D+07, + A -2.78561812808645469D+06, 3.08186404612662398D+05, + B -1.38860897537170405D+04, 1.10017140269246738D+02, + C -4.93292536645099620D+07, 3.25573074185765749D+08, + D -9.39462359681578403D+08, 1.55359689957058006D+09, + E -1.62108055210833708D+09, 1.10684281682301447D+09/ + DATA C(73), C(74), C(75), C(76), C(77), C(78), C(79), C(80), + 1 C(81), C(82), C(83), C(84), C(85), C(86), C(87), C(88), + 2 C(89), C(90), C(91), C(92), C(93), C(94), C(95), C(96)/ + 3 -4.95889784275030309D+08, 1.42062907797533095D+08, + 4 -2.44740627257387285D+07, 2.24376817792244943D+06, + 5 -8.40054336030240853D+04, 5.51335896122020586D+02, + 6 8.14789096118312115D+08, -5.86648149205184723D+09, + 7 1.86882075092958249D+10, -3.46320433881587779D+10, + 8 4.12801855797539740D+10, -3.30265997498007231D+10, + 9 1.79542137311556001D+10, -6.56329379261928433D+09, + A 1.55927986487925751D+09, -2.25105661889415278D+08, + B 1.73951075539781645D+07, -5.49842327572288687D+05, + C 3.03809051092238427D+03, -1.46792612476956167D+10, + D 1.14498237732025810D+11, -3.99096175224466498D+11, + E 8.19218669548577329D+11, -1.09837515608122331D+12/ + DATA C(97), C(98), C(99), C(100), C(101), C(102), C(103), C(104), + 1 C(105), C(106), C(107), C(108), C(109), C(110), C(111), + 2 C(112), C(113), C(114), C(115), C(116), C(117), C(118)/ + 3 1.00815810686538209D+12, -6.45364869245376503D+11, + 4 2.87900649906150589D+11, -8.78670721780232657D+10, + 5 1.76347306068349694D+10, -2.16716498322379509D+09, + 6 1.43157876718888981D+08, -3.87183344257261262D+06, + 7 1.82577554742931747D+04, 2.86464035717679043D+11, + 8 -2.40629790002850396D+12, 9.10934118523989896D+12, + 9 -2.05168994109344374D+13, 3.05651255199353206D+13, + A -3.16670885847851584D+13, 2.33483640445818409D+13, + B -1.23204913055982872D+13, 4.61272578084913197D+12, + C -1.19655288019618160D+12, 2.05914503232410016D+11, + D -2.18229277575292237D+10, 1.24700929351271032D+09/ + DATA C(119), C(120)/ + 1 -2.91883881222208134D+07, 1.18838426256783253D+05/ +C + IF (INIT.NE.0) GO TO 40 +C----------------------------------------------------------------------- +C INITIALIZE ALL VARIABLES +C----------------------------------------------------------------------- + RFN = 1.0D0/FNU +C----------------------------------------------------------------------- +C OVERFLOW TEST (ZR/FNU TOO SMALL) +C----------------------------------------------------------------------- + TEST = D1MACH(1)*1.0D+3 + AC = FNU*TEST + IF (DABS(ZRR).GT.AC .OR. DABS(ZRI).GT.AC) GO TO 15 + ZETA1R = 2.0D0*DABS(DLOG(TEST))+FNU + ZETA1I = 0.0D0 + ZETA2R = FNU + ZETA2I = 0.0D0 + PHIR = 1.0D0 + PHII = 0.0D0 + RETURN + 15 CONTINUE + TR = ZRR*RFN + TI = ZRI*RFN + SR = CONER + (TR*TR-TI*TI) + SI = CONEI + (TR*TI+TI*TR) + CALL ZSQRT(SR, SI, SRR, SRI) + STR = CONER + SRR + STI = CONEI + SRI + CALL ZDIV(STR, STI, TR, TI, ZNR, ZNI) + CALL ZLOG(ZNR, ZNI, STR, STI, IDUM) + ZETA1R = FNU*STR + ZETA1I = FNU*STI + ZETA2R = FNU*SRR + ZETA2I = FNU*SRI + CALL ZDIV(CONER, CONEI, SRR, SRI, TR, TI) + SRR = TR*RFN + SRI = TI*RFN + CALL ZSQRT(SRR, SRI, CWRKR(16), CWRKI(16)) + PHIR = CWRKR(16)*CON(IKFLG) + PHII = CWRKI(16)*CON(IKFLG) + IF (IPMTR.NE.0) RETURN + CALL ZDIV(CONER, CONEI, SR, SI, T2R, T2I) + CWRKR(1) = CONER + CWRKI(1) = CONEI + CRFNR = CONER + CRFNI = CONEI + AC = 1.0D0 + L = 1 + DO 20 K=2,15 + SR = ZEROR + SI = ZEROI + DO 10 J=1,K + L = L + 1 + STR = SR*T2R - SI*T2I + C(L) + SI = SR*T2I + SI*T2R + SR = STR + 10 CONTINUE + STR = CRFNR*SRR - CRFNI*SRI + CRFNI = CRFNR*SRI + CRFNI*SRR + CRFNR = STR + CWRKR(K) = CRFNR*SR - CRFNI*SI + CWRKI(K) = CRFNR*SI + CRFNI*SR + AC = AC*RFN + TEST = DABS(CWRKR(K)) + DABS(CWRKI(K)) + IF (AC.LT.TOL .AND. TEST.LT.TOL) GO TO 30 + 20 CONTINUE + K = 15 + 30 CONTINUE + INIT = K + 40 CONTINUE + IF (IKFLG.EQ.2) GO TO 60 +C----------------------------------------------------------------------- +C COMPUTE SUM FOR THE I FUNCTION +C----------------------------------------------------------------------- + SR = ZEROR + SI = ZEROI + DO 50 I=1,INIT + SR = SR + CWRKR(I) + SI = SI + CWRKI(I) + 50 CONTINUE + SUMR = SR + SUMI = SI + PHIR = CWRKR(16)*CON(1) + PHII = CWRKI(16)*CON(1) + RETURN + 60 CONTINUE +C----------------------------------------------------------------------- +C COMPUTE SUM FOR THE K FUNCTION +C----------------------------------------------------------------------- + SR = ZEROR + SI = ZEROI + TR = CONER + DO 70 I=1,INIT + SR = SR + TR*CWRKR(I) + SI = SI + TR*CWRKI(I) + TR = -TR + 70 CONTINUE + SUMR = SR + SUMI = SI + PHIR = CWRKR(16)*CON(2) + PHII = CWRKI(16)*CON(2) + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunk1.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunk1.f new file mode 100644 index 00000000..6b2418dd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunk1.f @@ -0,0 +1,426 @@ + SUBROUTINE ZUNK1(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM, + * ALIM) +C***BEGIN PROLOGUE ZUNK1 +C***REFER TO ZBESK +C +C ZUNK1 COMPUTES K(FNU,Z) AND ITS ANALYTIC CONTINUATION FROM THE +C RIGHT HALF PLANE TO THE LEFT HALF PLANE BY MEANS OF THE +C UNIFORM ASYMPTOTIC EXPANSION. +C MR INDICATES THE DIRECTION OF ROTATION FOR ANALYTIC CONTINUATION. +C NZ=-1 MEANS AN OVERFLOW WILL OCCUR +C +C***ROUTINES CALLED ZKSCL,ZS1S2,ZUCHK,ZUNIK,D1MACH,ZABS +C***END PROLOGUE ZUNK1 +C COMPLEX CFN,CK,CONE,CRSC,CS,CSCL,CSGN,CSPN,CSR,CSS,CWRK,CY,CZERO, +C *C1,C2,PHI,PHID,RZ,SUM,SUMD,S1,S2,Y,Z,ZETA1,ZETA1D,ZETA2,ZETA2D,ZR + DOUBLE PRECISION ALIM, ANG, APHI, ASC, ASCLE, BRY, CKI, CKR, + * CONER, CRSC, CSCL, CSGNI, CSPNI, CSPNR, CSR, CSRR, CSSR, + * CWRKI, CWRKR, CYI, CYR, C1I, C1R, C2I, C2M, C2R, ELIM, FMR, FN, + * FNF, FNU, PHIDI, PHIDR, PHII, PHIR, PI, RAST, RAZR, RS1, RZI, + * RZR, SGN, STI, STR, SUMDI, SUMDR, SUMI, SUMR, S1I, S1R, S2I, + * S2R, TOL, YI, YR, ZEROI, ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, + * ZET1DI, ZET1DR, ZET2DI, ZET2DR, ZI, ZR, ZRI, ZRR, D1MACH, ZABS + INTEGER I, IB, IFLAG, IFN, IL, INIT, INU, IUF, K, KDFLG, KFLAG, + * KK, KODE, MR, N, NW, NZ, INITD, IC, IPARD, J + DIMENSION BRY(3), INIT(2), YR(N), YI(N), SUMR(2), SUMI(2), + * ZETA1R(2), ZETA1I(2), ZETA2R(2), ZETA2I(2), CYR(2), CYI(2), + * CWRKR(16,3), CWRKI(16,3), CSSR(3), CSRR(3), PHIR(2), PHII(2) + DATA ZEROR,ZEROI,CONER / 0.0D0, 0.0D0, 1.0D0 / + DATA PI / 3.14159265358979324D0 / +C + KDFLG = 1 + NZ = 0 +C----------------------------------------------------------------------- +C EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION GREATER THAN +C THE UNDERFLOW LIMIT +C----------------------------------------------------------------------- + CSCL = 1.0D0/TOL + CRSC = TOL + CSSR(1) = CSCL + CSSR(2) = CONER + CSSR(3) = CRSC + CSRR(1) = CRSC + CSRR(2) = CONER + CSRR(3) = CSCL + BRY(1) = 1.0D+3*D1MACH(1)/TOL + BRY(2) = 1.0D0/BRY(1) + BRY(3) = D1MACH(2) + ZRR = ZR + ZRI = ZI + IF (ZR.GE.0.0D0) GO TO 10 + ZRR = -ZR + ZRI = -ZI + 10 CONTINUE + J = 2 + DO 70 I=1,N +C----------------------------------------------------------------------- +C J FLIP FLOPS BETWEEN 1 AND 2 IN J = 3 - J +C----------------------------------------------------------------------- + J = 3 - J + FN = FNU + DBLE(FLOAT(I-1)) + INIT(J) = 0 + CALL ZUNIK(ZRR, ZRI, FN, 2, 0, TOL, INIT(J), PHIR(J), PHII(J), + * ZETA1R(J), ZETA1I(J), ZETA2R(J), ZETA2I(J), SUMR(J), SUMI(J), + * CWRKR(1,J), CWRKI(1,J)) + IF (KODE.EQ.1) GO TO 20 + STR = ZRR + ZETA2R(J) + STI = ZRI + ZETA2I(J) + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = ZETA1R(J) - STR + S1I = ZETA1I(J) - STI + GO TO 30 + 20 CONTINUE + S1R = ZETA1R(J) - ZETA2R(J) + S1I = ZETA1I(J) - ZETA2I(J) + 30 CONTINUE + RS1 = S1R +C----------------------------------------------------------------------- +C TEST FOR UNDERFLOW AND OVERFLOW +C----------------------------------------------------------------------- + IF (DABS(RS1).GT.ELIM) GO TO 60 + IF (KDFLG.EQ.1) KFLAG = 2 + IF (DABS(RS1).LT.ALIM) GO TO 40 +C----------------------------------------------------------------------- +C REFINE TEST AND SCALE +C----------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIR(J),PHII(J),kind=KIND(1.0D0))) + RS1 = RS1 + DLOG(APHI) + IF (DABS(RS1).GT.ELIM) GO TO 60 + IF (KDFLG.EQ.1) KFLAG = 1 + IF (RS1.LT.0.0D0) GO TO 40 + IF (KDFLG.EQ.1) KFLAG = 3 + 40 CONTINUE +C----------------------------------------------------------------------- +C SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR +C EXPONENT EXTREMES +C----------------------------------------------------------------------- + S2R = PHIR(J)*SUMR(J) - PHII(J)*SUMI(J) + S2I = PHIR(J)*SUMI(J) + PHII(J)*SUMR(J) + STR = DEXP(S1R)*CSSR(KFLAG) + S1R = STR*DCOS(S1I) + S1I = STR*DSIN(S1I) + STR = S2R*S1R - S2I*S1I + S2I = S1R*S2I + S2R*S1I + S2R = STR + IF (KFLAG.NE.1) GO TO 50 + CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL) + IF (NW.NE.0) GO TO 60 + 50 CONTINUE + CYR(KDFLG) = S2R + CYI(KDFLG) = S2I + YR(I) = S2R*CSRR(KFLAG) + YI(I) = S2I*CSRR(KFLAG) + IF (KDFLG.EQ.2) GO TO 75 + KDFLG = 2 + GO TO 70 + 60 CONTINUE + IF (RS1.GT.0.0D0) GO TO 300 +C----------------------------------------------------------------------- +C FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW +C----------------------------------------------------------------------- + IF (ZR.LT.0.0D0) GO TO 300 + KDFLG = 1 + YR(I)=ZEROR + YI(I)=ZEROI + NZ=NZ+1 + IF (I.EQ.1) GO TO 70 + IF ((YR(I-1).EQ.ZEROR).AND.(YI(I-1).EQ.ZEROI)) GO TO 70 + YR(I-1)=ZEROR + YI(I-1)=ZEROI + NZ=NZ+1 + 70 CONTINUE + I = N + 75 CONTINUE + RAZR = 1.0D0/ZABS(CMPLX(ZRR,ZRI,kind=KIND(1.0D0))) + STR = ZRR*RAZR + STI = -ZRI*RAZR + RZR = (STR+STR)*RAZR + RZI = (STI+STI)*RAZR + CKR = FN*RZR + CKI = FN*RZI + IB = I + 1 + IF (N.LT.IB) GO TO 160 +C----------------------------------------------------------------------- +C TEST LAST MEMBER FOR UNDERFLOW AND OVERFLOW. SET SEQUENCE TO ZERO +C ON UNDERFLOW. +C----------------------------------------------------------------------- + FN = FNU + DBLE(FLOAT(N-1)) + IPARD = 1 + IF (MR.NE.0) IPARD = 0 + INITD = 0 + CALL ZUNIK(ZRR, ZRI, FN, 2, IPARD, TOL, INITD, PHIDR, PHIDI, + * ZET1DR, ZET1DI, ZET2DR, ZET2DI, SUMDR, SUMDI, CWRKR(1,3), + * CWRKI(1,3)) + IF (KODE.EQ.1) GO TO 80 + STR = ZRR + ZET2DR + STI = ZRI + ZET2DI + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = ZET1DR - STR + S1I = ZET1DI - STI + GO TO 90 + 80 CONTINUE + S1R = ZET1DR - ZET2DR + S1I = ZET1DI - ZET2DI + 90 CONTINUE + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 95 + IF (DABS(RS1).LT.ALIM) GO TO 100 +C---------------------------------------------------------------------------- +C REFINE ESTIMATE AND TEST +C------------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIDR,PHIDI,kind=KIND(1.0D0))) + RS1 = RS1+DLOG(APHI) + IF (DABS(RS1).LT.ELIM) GO TO 100 + 95 CONTINUE + IF (DABS(RS1).GT.0.0D0) GO TO 300 +C----------------------------------------------------------------------- +C FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW +C----------------------------------------------------------------------- + IF (ZR.LT.0.0D0) GO TO 300 + NZ = N + DO 96 I=1,N + YR(I) = ZEROR + YI(I) = ZEROI + 96 CONTINUE + RETURN +C--------------------------------------------------------------------------- +C FORWARD RECUR FOR REMAINDER OF THE SEQUENCE +C---------------------------------------------------------------------------- + 100 CONTINUE + S1R = CYR(1) + S1I = CYI(1) + S2R = CYR(2) + S2I = CYI(2) + C1R = CSRR(KFLAG) + ASCLE = BRY(KFLAG) + DO 120 I=IB,N + C2R = S2R + C2I = S2I + S2R = CKR*C2R - CKI*C2I + S1R + S2I = CKR*C2I + CKI*C2R + S1I + S1R = C2R + S1I = C2I + CKR = CKR + RZR + CKI = CKI + RZI + C2R = S2R*C1R + C2I = S2I*C1R + YR(I) = C2R + YI(I) = C2I + IF (KFLAG.GE.3) GO TO 120 + STR = DABS(C2R) + STI = DABS(C2I) + C2M = DMAX1(STR,STI) + IF (C2M.LE.ASCLE) GO TO 120 + KFLAG = KFLAG + 1 + ASCLE = BRY(KFLAG) + S1R = S1R*C1R + S1I = S1I*C1R + S2R = C2R + S2I = C2I + S1R = S1R*CSSR(KFLAG) + S1I = S1I*CSSR(KFLAG) + S2R = S2R*CSSR(KFLAG) + S2I = S2I*CSSR(KFLAG) + C1R = CSRR(KFLAG) + 120 CONTINUE + 160 CONTINUE + IF (MR.EQ.0) RETURN +C----------------------------------------------------------------------- +C ANALYTIC CONTINUATION FOR RE(Z).LT.0.0D0 +C----------------------------------------------------------------------- + NZ = 0 + FMR = DBLE(FLOAT(MR)) + SGN = -DSIGN(PI,FMR) +C----------------------------------------------------------------------- +C CSPN AND CSGN ARE COEFF OF K AND I FUNCTIONS RESP. +C----------------------------------------------------------------------- + CSGNI = SGN + INU = INT(SNGL(FNU)) + FNF = FNU - DBLE(FLOAT(INU)) + IFN = INU + N - 1 + ANG = FNF*SGN + CSPNR = DCOS(ANG) + CSPNI = DSIN(ANG) + IF (MOD(IFN,2).EQ.0) GO TO 170 + CSPNR = -CSPNR + CSPNI = -CSPNI + 170 CONTINUE + ASC = BRY(1) + IUF = 0 + KK = N + KDFLG = 1 + IB = IB - 1 + IC = IB - 1 + DO 270 K=1,N + FN = FNU + DBLE(FLOAT(KK-1)) +C----------------------------------------------------------------------- +C LOGIC TO SORT OUT CASES WHOSE PARAMETERS WERE SET FOR THE K +C FUNCTION ABOVE +C----------------------------------------------------------------------- + M=3 + IF (N.GT.2) GO TO 175 + 172 CONTINUE + INITD = INIT(J) + PHIDR = PHIR(J) + PHIDI = PHII(J) + ZET1DR = ZETA1R(J) + ZET1DI = ZETA1I(J) + ZET2DR = ZETA2R(J) + ZET2DI = ZETA2I(J) + SUMDR = SUMR(J) + SUMDI = SUMI(J) + M = J + J = 3 - J + GO TO 180 + 175 CONTINUE + IF ((KK.EQ.N).AND.(IB.LT.N)) GO TO 180 + IF ((KK.EQ.IB).OR.(KK.EQ.IC)) GO TO 172 + INITD = 0 + 180 CONTINUE + CALL ZUNIK(ZRR, ZRI, FN, 1, 0, TOL, INITD, PHIDR, PHIDI, + * ZET1DR, ZET1DI, ZET2DR, ZET2DI, SUMDR, SUMDI, + * CWRKR(1,M), CWRKI(1,M)) + IF (KODE.EQ.1) GO TO 200 + STR = ZRR + ZET2DR + STI = ZRI + ZET2DI + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = -ZET1DR + STR + S1I = -ZET1DI + STI + GO TO 210 + 200 CONTINUE + S1R = -ZET1DR + ZET2DR + S1I = -ZET1DI + ZET2DI + 210 CONTINUE +C----------------------------------------------------------------------- +C TEST FOR UNDERFLOW AND OVERFLOW +C----------------------------------------------------------------------- + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 260 + IF (KDFLG.EQ.1) IFLAG = 2 + IF (DABS(RS1).LT.ALIM) GO TO 220 +C----------------------------------------------------------------------- +C REFINE TEST AND SCALE +C----------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIDR,PHIDI,kind=KIND(1.0D0))) + RS1 = RS1 + DLOG(APHI) + IF (DABS(RS1).GT.ELIM) GO TO 260 + IF (KDFLG.EQ.1) IFLAG = 1 + IF (RS1.LT.0.0D0) GO TO 220 + IF (KDFLG.EQ.1) IFLAG = 3 + 220 CONTINUE + STR = PHIDR*SUMDR - PHIDI*SUMDI + STI = PHIDR*SUMDI + PHIDI*SUMDR + S2R = -CSGNI*STI + S2I = CSGNI*STR + STR = DEXP(S1R)*CSSR(IFLAG) + S1R = STR*DCOS(S1I) + S1I = STR*DSIN(S1I) + STR = S2R*S1R - S2I*S1I + S2I = S2R*S1I + S2I*S1R + S2R = STR + IF (IFLAG.NE.1) GO TO 230 + CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL) + IF (NW.EQ.0) GO TO 230 + S2R = ZEROR + S2I = ZEROI + 230 CONTINUE + CYR(KDFLG) = S2R + CYI(KDFLG) = S2I + C2R = S2R + C2I = S2I + S2R = S2R*CSRR(IFLAG) + S2I = S2I*CSRR(IFLAG) +C----------------------------------------------------------------------- +C ADD I AND K FUNCTIONS, K SEQUENCE IN Y(I), I=1,N +C----------------------------------------------------------------------- + S1R = YR(KK) + S1I = YI(KK) + IF (KODE.EQ.1) GO TO 250 + CALL ZS1S2(ZRR, ZRI, S1R, S1I, S2R, S2I, NW, ASC, ALIM, IUF) + NZ = NZ + NW + 250 CONTINUE + YR(KK) = S1R*CSPNR - S1I*CSPNI + S2R + YI(KK) = CSPNR*S1I + CSPNI*S1R + S2I + KK = KK - 1 + CSPNR = -CSPNR + CSPNI = -CSPNI + IF (C2R.NE.0.0D0 .OR. C2I.NE.0.0D0) GO TO 255 + KDFLG = 1 + GO TO 270 + 255 CONTINUE + IF (KDFLG.EQ.2) GO TO 275 + KDFLG = 2 + GO TO 270 + 260 CONTINUE + IF (RS1.GT.0.0D0) GO TO 300 + S2R = ZEROR + S2I = ZEROI + GO TO 230 + 270 CONTINUE + K = N + 275 CONTINUE + IL = N - K + IF (IL.EQ.0) RETURN +C----------------------------------------------------------------------- +C RECUR BACKWARD FOR REMAINDER OF I SEQUENCE AND ADD IN THE +C K FUNCTIONS, SCALING THE I SEQUENCE DURING RECURRENCE TO KEEP +C INTERMEDIATE ARITHMETIC ON SCALE NEAR EXPONENT EXTREMES. +C----------------------------------------------------------------------- + S1R = CYR(1) + S1I = CYI(1) + S2R = CYR(2) + S2I = CYI(2) + CSR = CSRR(IFLAG) + ASCLE = BRY(IFLAG) + FN = DBLE(FLOAT(INU+IL)) + DO 290 I=1,IL + C2R = S2R + C2I = S2I + S2R = S1R + (FN+FNF)*(RZR*C2R-RZI*C2I) + S2I = S1I + (FN+FNF)*(RZR*C2I+RZI*C2R) + S1R = C2R + S1I = C2I + FN = FN - 1.0D0 + C2R = S2R*CSR + C2I = S2I*CSR + CKR = C2R + CKI = C2I + C1R = YR(KK) + C1I = YI(KK) + IF (KODE.EQ.1) GO TO 280 + CALL ZS1S2(ZRR, ZRI, C1R, C1I, C2R, C2I, NW, ASC, ALIM, IUF) + NZ = NZ + NW + 280 CONTINUE + YR(KK) = C1R*CSPNR - C1I*CSPNI + C2R + YI(KK) = C1R*CSPNI + C1I*CSPNR + C2I + KK = KK - 1 + CSPNR = -CSPNR + CSPNI = -CSPNI + IF (IFLAG.GE.3) GO TO 290 + C2R = DABS(CKR) + C2I = DABS(CKI) + C2M = DMAX1(C2R,C2I) + IF (C2M.LE.ASCLE) GO TO 290 + IFLAG = IFLAG + 1 + ASCLE = BRY(IFLAG) + S1R = S1R*CSR + S1I = S1I*CSR + S2R = CKR + S2I = CKI + S1R = S1R*CSSR(IFLAG) + S1I = S1I*CSSR(IFLAG) + S2R = S2R*CSSR(IFLAG) + S2I = S2I*CSSR(IFLAG) + CSR = CSRR(IFLAG) + 290 CONTINUE + RETURN + 300 CONTINUE + NZ = -1 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunk2.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunk2.f new file mode 100644 index 00000000..6859f5ec --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zunk2.f @@ -0,0 +1,505 @@ + SUBROUTINE ZUNK2(ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, TOL, ELIM, + * ALIM) +C***BEGIN PROLOGUE ZUNK2 +C***REFER TO ZBESK +C +C ZUNK2 COMPUTES K(FNU,Z) AND ITS ANALYTIC CONTINUATION FROM THE +C RIGHT HALF PLANE TO THE LEFT HALF PLANE BY MEANS OF THE +C UNIFORM ASYMPTOTIC EXPANSIONS FOR H(KIND,FNU,ZN) AND J(FNU,ZN) +C WHERE ZN IS IN THE RIGHT HALF PLANE, KIND=(3-MR)/2, MR=+1 OR +C -1. HERE ZN=ZR*I OR -ZR*I WHERE ZR=Z IF Z IS IN THE RIGHT +C HALF PLANE OR ZR=-Z IF Z IS IN THE LEFT HALF PLANE. MR INDIC- +C ATES THE DIRECTION OF ROTATION FOR ANALYTIC CONTINUATION. +C NZ=-1 MEANS AN OVERFLOW WILL OCCUR +C +C***ROUTINES CALLED ZAIRY,ZKSCL,ZS1S2,ZUCHK,ZUNHJ,D1MACH,ZABS +C***END PROLOGUE ZUNK2 +C COMPLEX AI,ARG,ARGD,ASUM,ASUMD,BSUM,BSUMD,CFN,CI,CIP,CK,CONE,CRSC, +C *CR1,CR2,CS,CSCL,CSGN,CSPN,CSR,CSS,CY,CZERO,C1,C2,DAI,PHI,PHID,RZ, +C *S1,S2,Y,Z,ZB,ZETA1,ZETA1D,ZETA2,ZETA2D,ZN,ZR + DOUBLE PRECISION AARG, AIC, AII, AIR, ALIM, ANG, APHI, ARGDI, + * ARGDR, ARGI, ARGR, ASC, ASCLE, ASUMDI, ASUMDR, ASUMI, ASUMR, + * BRY, BSUMDI, BSUMDR, BSUMI, BSUMR, CAR, CIPI, CIPR, CKI, CKR, + * CONER, CRSC, CR1I, CR1R, CR2I, CR2R, CSCL, CSGNI, CSI, + * CSPNI, CSPNR, CSR, CSRR, CSSR, CYI, CYR, C1I, C1R, C2I, C2M, + * C2R, DAII, DAIR, ELIM, FMR, FN, FNF, FNU, HPI, PHIDI, PHIDR, + * PHII, PHIR, PI, PTI, PTR, RAST, RAZR, RS1, RZI, RZR, SAR, SGN, + * STI, STR, S1I, S1R, S2I, S2R, TOL, YI, YR, YY, ZBI, ZBR, ZEROI, + * ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, ZET1DI, ZET1DR, ZET2DI, + * ZET2DR, ZI, ZNI, ZNR, ZR, ZRI, ZRR, D1MACH, ZABS + INTEGER I, IB, IFLAG, IFN, IL, IN, INU, IUF, K, KDFLG, KFLAG, KK, + * KODE, MR, N, NAI, NDAI, NW, NZ, IDUM, J, IPARD, IC + DIMENSION BRY(3), YR(N), YI(N), ASUMR(2), ASUMI(2), BSUMR(2), + * BSUMI(2), PHIR(2), PHII(2), ARGR(2), ARGI(2), ZETA1R(2), + * ZETA1I(2), ZETA2R(2), ZETA2I(2), CYR(2), CYI(2), CIPR(4), + * CIPI(4), CSSR(3), CSRR(3) + DATA ZEROR,ZEROI,CONER,CR1R,CR1I,CR2R,CR2I / + 1 0.0D0, 0.0D0, 1.0D0, + 1 1.0D0,1.73205080756887729D0 , -0.5D0,-8.66025403784438647D-01 / + DATA HPI, PI, AIC / + 1 1.57079632679489662D+00, 3.14159265358979324D+00, + 1 1.26551212348464539D+00/ + DATA CIPR(1),CIPI(1),CIPR(2),CIPI(2),CIPR(3),CIPI(3),CIPR(4), + * CIPI(4) / + 1 1.0D0,0.0D0 , 0.0D0,-1.0D0 , -1.0D0,0.0D0 , 0.0D0,1.0D0 / +C + KDFLG = 1 + NZ = 0 +C----------------------------------------------------------------------- +C EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION GREATER THAN +C THE UNDERFLOW LIMIT +C----------------------------------------------------------------------- + CSCL = 1.0D0/TOL + CRSC = TOL + CSSR(1) = CSCL + CSSR(2) = CONER + CSSR(3) = CRSC + CSRR(1) = CRSC + CSRR(2) = CONER + CSRR(3) = CSCL + BRY(1) = 1.0D+3*D1MACH(1)/TOL + BRY(2) = 1.0D0/BRY(1) + BRY(3) = D1MACH(2) + ZRR = ZR + ZRI = ZI + IF (ZR.GE.0.0D0) GO TO 10 + ZRR = -ZR + ZRI = -ZI + 10 CONTINUE + YY = ZRI + ZNR = ZRI + ZNI = -ZRR + ZBR = ZRR + ZBI = ZRI + INU = INT(SNGL(FNU)) + FNF = FNU - DBLE(FLOAT(INU)) + ANG = -HPI*FNF + CAR = DCOS(ANG) + SAR = DSIN(ANG) + C2R = HPI*SAR + C2I = -HPI*CAR + KK = MOD(INU,4) + 1 + STR = C2R*CIPR(KK) - C2I*CIPI(KK) + STI = C2R*CIPI(KK) + C2I*CIPR(KK) + CSR = CR1R*STR - CR1I*STI + CSI = CR1R*STI + CR1I*STR + IF (YY.GT.0.0D0) GO TO 20 + ZNR = -ZNR + ZBI = -ZBI + 20 CONTINUE +C----------------------------------------------------------------------- +C K(FNU,Z) IS COMPUTED FROM H(2,FNU,-I*Z) WHERE Z IS IN THE FIRST +C QUADRANT. FOURTH QUADRANT VALUES (YY.LE.0.0E0) ARE COMPUTED BY +C CONJUGATION SINCE THE K FUNCTION IS REAL ON THE POSITIVE REAL AXIS +C----------------------------------------------------------------------- + J = 2 + DO 80 I=1,N +C----------------------------------------------------------------------- +C J FLIP FLOPS BETWEEN 1 AND 2 IN J = 3 - J +C----------------------------------------------------------------------- + J = 3 - J + FN = FNU + DBLE(FLOAT(I-1)) + CALL ZUNHJ(ZNR, ZNI, FN, 0, TOL, PHIR(J), PHII(J), ARGR(J), + * ARGI(J), ZETA1R(J), ZETA1I(J), ZETA2R(J), ZETA2I(J), ASUMR(J), + * ASUMI(J), BSUMR(J), BSUMI(J)) + IF (KODE.EQ.1) GO TO 30 + STR = ZBR + ZETA2R(J) + STI = ZBI + ZETA2I(J) + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = ZETA1R(J) - STR + S1I = ZETA1I(J) - STI + GO TO 40 + 30 CONTINUE + S1R = ZETA1R(J) - ZETA2R(J) + S1I = ZETA1I(J) - ZETA2I(J) + 40 CONTINUE +C----------------------------------------------------------------------- +C TEST FOR UNDERFLOW AND OVERFLOW +C----------------------------------------------------------------------- + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 70 + IF (KDFLG.EQ.1) KFLAG = 2 + IF (DABS(RS1).LT.ALIM) GO TO 50 +C----------------------------------------------------------------------- +C REFINE TEST AND SCALE +C----------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIR(J),PHII(J),kind=KIND(1.0D0))) + AARG = ZABS(CMPLX(ARGR(J),ARGI(J),kind=KIND(1.0D0))) + RS1 = RS1 + DLOG(APHI) - 0.25D0*DLOG(AARG) - AIC + IF (DABS(RS1).GT.ELIM) GO TO 70 + IF (KDFLG.EQ.1) KFLAG = 1 + IF (RS1.LT.0.0D0) GO TO 50 + IF (KDFLG.EQ.1) KFLAG = 3 + 50 CONTINUE +C----------------------------------------------------------------------- +C SCALE S1 TO KEEP INTERMEDIATE ARITHMETIC ON SCALE NEAR +C EXPONENT EXTREMES +C----------------------------------------------------------------------- + C2R = ARGR(J)*CR2R - ARGI(J)*CR2I + C2I = ARGR(J)*CR2I + ARGI(J)*CR2R + CALL ZAIRY(C2R, C2I, 0, 2, AIR, AII, NAI, IDUM) + CALL ZAIRY(C2R, C2I, 1, 2, DAIR, DAII, NDAI, IDUM) + STR = DAIR*BSUMR(J) - DAII*BSUMI(J) + STI = DAIR*BSUMI(J) + DAII*BSUMR(J) + PTR = STR*CR2R - STI*CR2I + PTI = STR*CR2I + STI*CR2R + STR = PTR + (AIR*ASUMR(J)-AII*ASUMI(J)) + STI = PTI + (AIR*ASUMI(J)+AII*ASUMR(J)) + PTR = STR*PHIR(J) - STI*PHII(J) + PTI = STR*PHII(J) + STI*PHIR(J) + S2R = PTR*CSR - PTI*CSI + S2I = PTR*CSI + PTI*CSR + STR = DEXP(S1R)*CSSR(KFLAG) + S1R = STR*DCOS(S1I) + S1I = STR*DSIN(S1I) + STR = S2R*S1R - S2I*S1I + S2I = S1R*S2I + S2R*S1I + S2R = STR + IF (KFLAG.NE.1) GO TO 60 + CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL) + IF (NW.NE.0) GO TO 70 + 60 CONTINUE + IF (YY.LE.0.0D0) S2I = -S2I + CYR(KDFLG) = S2R + CYI(KDFLG) = S2I + YR(I) = S2R*CSRR(KFLAG) + YI(I) = S2I*CSRR(KFLAG) + STR = CSI + CSI = -CSR + CSR = STR + IF (KDFLG.EQ.2) GO TO 85 + KDFLG = 2 + GO TO 80 + 70 CONTINUE + IF (RS1.GT.0.0D0) GO TO 320 +C----------------------------------------------------------------------- +C FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW +C----------------------------------------------------------------------- + IF (ZR.LT.0.0D0) GO TO 320 + KDFLG = 1 + YR(I)=ZEROR + YI(I)=ZEROI + NZ=NZ+1 + STR = CSI + CSI =-CSR + CSR = STR + IF (I.EQ.1) GO TO 80 + IF ((YR(I-1).EQ.ZEROR).AND.(YI(I-1).EQ.ZEROI)) GO TO 80 + YR(I-1)=ZEROR + YI(I-1)=ZEROI + NZ=NZ+1 + 80 CONTINUE + I = N + 85 CONTINUE + RAZR = 1.0D0/ZABS(CMPLX(ZRR,ZRI,kind=KIND(1.0D0))) + STR = ZRR*RAZR + STI = -ZRI*RAZR + RZR = (STR+STR)*RAZR + RZI = (STI+STI)*RAZR + CKR = FN*RZR + CKI = FN*RZI + IB = I + 1 + IF (N.LT.IB) GO TO 180 +C----------------------------------------------------------------------- +C TEST LAST MEMBER FOR UNDERFLOW AND OVERFLOW. SET SEQUENCE TO ZERO +C ON UNDERFLOW. +C----------------------------------------------------------------------- + FN = FNU + DBLE(FLOAT(N-1)) + IPARD = 1 + IF (MR.NE.0) IPARD = 0 + CALL ZUNHJ(ZNR, ZNI, FN, IPARD, TOL, PHIDR, PHIDI, ARGDR, ARGDI, + * ZET1DR, ZET1DI, ZET2DR, ZET2DI, ASUMDR, ASUMDI, BSUMDR, BSUMDI) + IF (KODE.EQ.1) GO TO 90 + STR = ZBR + ZET2DR + STI = ZBI + ZET2DI + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = ZET1DR - STR + S1I = ZET1DI - STI + GO TO 100 + 90 CONTINUE + S1R = ZET1DR - ZET2DR + S1I = ZET1DI - ZET2DI + 100 CONTINUE + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 105 + IF (DABS(RS1).LT.ALIM) GO TO 120 +C---------------------------------------------------------------------------- +C REFINE ESTIMATE AND TEST +C------------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIDR,PHIDI,kind=KIND(1.0D0))) + RS1 = RS1+DLOG(APHI) + IF (DABS(RS1).LT.ELIM) GO TO 120 + 105 CONTINUE + IF (RS1.GT.0.0D0) GO TO 320 +C----------------------------------------------------------------------- +C FOR ZR.LT.0.0, THE I FUNCTION TO BE ADDED WILL OVERFLOW +C----------------------------------------------------------------------- + IF (ZR.LT.0.0D0) GO TO 320 + NZ = N + DO 106 I=1,N + YR(I) = ZEROR + YI(I) = ZEROI + 106 CONTINUE + RETURN + 120 CONTINUE + S1R = CYR(1) + S1I = CYI(1) + S2R = CYR(2) + S2I = CYI(2) + C1R = CSRR(KFLAG) + ASCLE = BRY(KFLAG) + DO 130 I=IB,N + C2R = S2R + C2I = S2I + S2R = CKR*C2R - CKI*C2I + S1R + S2I = CKR*C2I + CKI*C2R + S1I + S1R = C2R + S1I = C2I + CKR = CKR + RZR + CKI = CKI + RZI + C2R = S2R*C1R + C2I = S2I*C1R + YR(I) = C2R + YI(I) = C2I + IF (KFLAG.GE.3) GO TO 130 + STR = DABS(C2R) + STI = DABS(C2I) + C2M = DMAX1(STR,STI) + IF (C2M.LE.ASCLE) GO TO 130 + KFLAG = KFLAG + 1 + ASCLE = BRY(KFLAG) + S1R = S1R*C1R + S1I = S1I*C1R + S2R = C2R + S2I = C2I + S1R = S1R*CSSR(KFLAG) + S1I = S1I*CSSR(KFLAG) + S2R = S2R*CSSR(KFLAG) + S2I = S2I*CSSR(KFLAG) + C1R = CSRR(KFLAG) + 130 CONTINUE + 180 CONTINUE + IF (MR.EQ.0) RETURN +C----------------------------------------------------------------------- +C ANALYTIC CONTINUATION FOR RE(Z).LT.0.0D0 +C----------------------------------------------------------------------- + NZ = 0 + FMR = DBLE(FLOAT(MR)) + SGN = -DSIGN(PI,FMR) +C----------------------------------------------------------------------- +C CSPN AND CSGN ARE COEFF OF K AND I FUNCIONS RESP. +C----------------------------------------------------------------------- + CSGNI = SGN + IF (YY.LE.0.0D0) CSGNI = -CSGNI + IFN = INU + N - 1 + ANG = FNF*SGN + CSPNR = DCOS(ANG) + CSPNI = DSIN(ANG) + IF (MOD(IFN,2).EQ.0) GO TO 190 + CSPNR = -CSPNR + CSPNI = -CSPNI + 190 CONTINUE +C----------------------------------------------------------------------- +C CS=COEFF OF THE J FUNCTION TO GET THE I FUNCTION. I(FNU,Z) IS +C COMPUTED FROM EXP(I*FNU*HPI)*J(FNU,-I*Z) WHERE Z IS IN THE FIRST +C QUADRANT. FOURTH QUADRANT VALUES (YY.LE.0.0E0) ARE COMPUTED BY +C CONJUGATION SINCE THE I FUNCTION IS REAL ON THE POSITIVE REAL AXIS +C----------------------------------------------------------------------- + CSR = SAR*CSGNI + CSI = CAR*CSGNI + IN = MOD(IFN,4) + 1 + C2R = CIPR(IN) + C2I = CIPI(IN) + STR = CSR*C2R + CSI*C2I + CSI = -CSR*C2I + CSI*C2R + CSR = STR + ASC = BRY(1) + IUF = 0 + KK = N + KDFLG = 1 + IB = IB - 1 + IC = IB - 1 + DO 290 K=1,N + FN = FNU + DBLE(FLOAT(KK-1)) +C----------------------------------------------------------------------- +C LOGIC TO SORT OUT CASES WHOSE PARAMETERS WERE SET FOR THE K +C FUNCTION ABOVE +C----------------------------------------------------------------------- + IF (N.GT.2) GO TO 175 + 172 CONTINUE + PHIDR = PHIR(J) + PHIDI = PHII(J) + ARGDR = ARGR(J) + ARGDI = ARGI(J) + ZET1DR = ZETA1R(J) + ZET1DI = ZETA1I(J) + ZET2DR = ZETA2R(J) + ZET2DI = ZETA2I(J) + ASUMDR = ASUMR(J) + ASUMDI = ASUMI(J) + BSUMDR = BSUMR(J) + BSUMDI = BSUMI(J) + J = 3 - J + GO TO 210 + 175 CONTINUE + IF ((KK.EQ.N).AND.(IB.LT.N)) GO TO 210 + IF ((KK.EQ.IB).OR.(KK.EQ.IC)) GO TO 172 + CALL ZUNHJ(ZNR, ZNI, FN, 0, TOL, PHIDR, PHIDI, ARGDR, + * ARGDI, ZET1DR, ZET1DI, ZET2DR, ZET2DI, ASUMDR, + * ASUMDI, BSUMDR, BSUMDI) + 210 CONTINUE + IF (KODE.EQ.1) GO TO 220 + STR = ZBR + ZET2DR + STI = ZBI + ZET2DI + RAST = FN/ZABS(CMPLX(STR,STI,kind=KIND(1.0D0))) + STR = STR*RAST*RAST + STI = -STI*RAST*RAST + S1R = -ZET1DR + STR + S1I = -ZET1DI + STI + GO TO 230 + 220 CONTINUE + S1R = -ZET1DR + ZET2DR + S1I = -ZET1DI + ZET2DI + 230 CONTINUE +C----------------------------------------------------------------------- +C TEST FOR UNDERFLOW AND OVERFLOW +C----------------------------------------------------------------------- + RS1 = S1R + IF (DABS(RS1).GT.ELIM) GO TO 280 + IF (KDFLG.EQ.1) IFLAG = 2 + IF (DABS(RS1).LT.ALIM) GO TO 240 +C----------------------------------------------------------------------- +C REFINE TEST AND SCALE +C----------------------------------------------------------------------- + APHI = ZABS(CMPLX(PHIDR,PHIDI,kind=KIND(1.0D0))) + AARG = ZABS(CMPLX(ARGDR,ARGDI,kind=KIND(1.0D0))) + RS1 = RS1 + DLOG(APHI) - 0.25D0*DLOG(AARG) - AIC + IF (DABS(RS1).GT.ELIM) GO TO 280 + IF (KDFLG.EQ.1) IFLAG = 1 + IF (RS1.LT.0.0D0) GO TO 240 + IF (KDFLG.EQ.1) IFLAG = 3 + 240 CONTINUE + CALL ZAIRY(ARGDR, ARGDI, 0, 2, AIR, AII, NAI, IDUM) + CALL ZAIRY(ARGDR, ARGDI, 1, 2, DAIR, DAII, NDAI, IDUM) + STR = DAIR*BSUMDR - DAII*BSUMDI + STI = DAIR*BSUMDI + DAII*BSUMDR + STR = STR + (AIR*ASUMDR-AII*ASUMDI) + STI = STI + (AIR*ASUMDI+AII*ASUMDR) + PTR = STR*PHIDR - STI*PHIDI + PTI = STR*PHIDI + STI*PHIDR + S2R = PTR*CSR - PTI*CSI + S2I = PTR*CSI + PTI*CSR + STR = DEXP(S1R)*CSSR(IFLAG) + S1R = STR*DCOS(S1I) + S1I = STR*DSIN(S1I) + STR = S2R*S1R - S2I*S1I + S2I = S2R*S1I + S2I*S1R + S2R = STR + IF (IFLAG.NE.1) GO TO 250 + CALL ZUCHK(S2R, S2I, NW, BRY(1), TOL) + IF (NW.EQ.0) GO TO 250 + S2R = ZEROR + S2I = ZEROI + 250 CONTINUE + IF (YY.LE.0.0D0) S2I = -S2I + CYR(KDFLG) = S2R + CYI(KDFLG) = S2I + C2R = S2R + C2I = S2I + S2R = S2R*CSRR(IFLAG) + S2I = S2I*CSRR(IFLAG) +C----------------------------------------------------------------------- +C ADD I AND K FUNCTIONS, K SEQUENCE IN Y(I), I=1,N +C----------------------------------------------------------------------- + S1R = YR(KK) + S1I = YI(KK) + IF (KODE.EQ.1) GO TO 270 + CALL ZS1S2(ZRR, ZRI, S1R, S1I, S2R, S2I, NW, ASC, ALIM, IUF) + NZ = NZ + NW + 270 CONTINUE + YR(KK) = S1R*CSPNR - S1I*CSPNI + S2R + YI(KK) = S1R*CSPNI + S1I*CSPNR + S2I + KK = KK - 1 + CSPNR = -CSPNR + CSPNI = -CSPNI + STR = CSI + CSI = -CSR + CSR = STR + IF (C2R.NE.0.0D0 .OR. C2I.NE.0.0D0) GO TO 255 + KDFLG = 1 + GO TO 290 + 255 CONTINUE + IF (KDFLG.EQ.2) GO TO 295 + KDFLG = 2 + GO TO 290 + 280 CONTINUE + IF (RS1.GT.0.0D0) GO TO 320 + S2R = ZEROR + S2I = ZEROI + GO TO 250 + 290 CONTINUE + K = N + 295 CONTINUE + IL = N - K + IF (IL.EQ.0) RETURN +C----------------------------------------------------------------------- +C RECUR BACKWARD FOR REMAINDER OF I SEQUENCE AND ADD IN THE +C K FUNCTIONS, SCALING THE I SEQUENCE DURING RECURRENCE TO KEEP +C INTERMEDIATE ARITHMETIC ON SCALE NEAR EXPONENT EXTREMES. +C----------------------------------------------------------------------- + S1R = CYR(1) + S1I = CYI(1) + S2R = CYR(2) + S2I = CYI(2) + CSR = CSRR(IFLAG) + ASCLE = BRY(IFLAG) + FN = DBLE(FLOAT(INU+IL)) + DO 310 I=1,IL + C2R = S2R + C2I = S2I + S2R = S1R + (FN+FNF)*(RZR*C2R-RZI*C2I) + S2I = S1I + (FN+FNF)*(RZR*C2I+RZI*C2R) + S1R = C2R + S1I = C2I + FN = FN - 1.0D0 + C2R = S2R*CSR + C2I = S2I*CSR + CKR = C2R + CKI = C2I + C1R = YR(KK) + C1I = YI(KK) + IF (KODE.EQ.1) GO TO 300 + CALL ZS1S2(ZRR, ZRI, C1R, C1I, C2R, C2I, NW, ASC, ALIM, IUF) + NZ = NZ + NW + 300 CONTINUE + YR(KK) = C1R*CSPNR - C1I*CSPNI + C2R + YI(KK) = C1R*CSPNI + C1I*CSPNR + C2I + KK = KK - 1 + CSPNR = -CSPNR + CSPNI = -CSPNI + IF (IFLAG.GE.3) GO TO 310 + C2R = DABS(CKR) + C2I = DABS(CKI) + C2M = DMAX1(C2R,C2I) + IF (C2M.LE.ASCLE) GO TO 310 + IFLAG = IFLAG + 1 + ASCLE = BRY(IFLAG) + S1R = S1R*CSR + S1I = S1I*CSR + S2R = CKR + S2I = CKI + S1R = S1R*CSSR(IFLAG) + S1I = S1I*CSSR(IFLAG) + S2R = S2R*CSSR(IFLAG) + S2I = S2I*CSSR(IFLAG) + CSR = CSRR(IFLAG) + 310 CONTINUE + RETURN + 320 CONTINUE + NZ = -1 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuoik.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuoik.f new file mode 100644 index 00000000..3715d6d4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zuoik.f @@ -0,0 +1,194 @@ + SUBROUTINE ZUOIK(ZR, ZI, FNU, KODE, IKFLG, N, YR, YI, NUF, TOL, + * ELIM, ALIM) +C***BEGIN PROLOGUE ZUOIK +C***REFER TO ZBESI,ZBESK,ZBESH +C +C ZUOIK COMPUTES THE LEADING TERMS OF THE UNIFORM ASYMPTOTIC +C EXPANSIONS FOR THE I AND K FUNCTIONS AND COMPARES THEM +C (IN LOGARITHMIC FORM) TO ALIM AND ELIM FOR OVER AND UNDERFLOW +C WHERE ALIM.LT.ELIM. IF THE MAGNITUDE, BASED ON THE LEADING +C EXPONENTIAL, IS LESS THAN ALIM OR GREATER THAN -ALIM, THEN +C THE RESULT IS ON SCALE. IF NOT, THEN A REFINED TEST USING OTHER +C MULTIPLIERS (IN LOGARITHMIC FORM) IS MADE BASED ON ELIM. HERE +C EXP(-ELIM)=SMALLEST MACHINE NUMBER*1.0E+3 AND EXP(-ALIM)= +C EXP(-ELIM)/TOL +C +C IKFLG=1 MEANS THE I SEQUENCE IS TESTED +C =2 MEANS THE K SEQUENCE IS TESTED +C NUF = 0 MEANS THE LAST MEMBER OF THE SEQUENCE IS ON SCALE +C =-1 MEANS AN OVERFLOW WOULD OCCUR +C IKFLG=1 AND NUF.GT.0 MEANS THE LAST NUF Y VALUES WERE SET TO ZERO +C THE FIRST N-NUF VALUES MUST BE SET BY ANOTHER ROUTINE +C IKFLG=2 AND NUF.EQ.N MEANS ALL Y VALUES WERE SET TO ZERO +C IKFLG=2 AND 0.LT.NUF.LT.N NOT CONSIDERED. Y MUST BE SET BY +C ANOTHER ROUTINE +C +C***ROUTINES CALLED ZUCHK,ZUNHJ,ZUNIK,D1MACH,ZABS,ZLOG +C***END PROLOGUE ZUOIK +C COMPLEX ARG,ASUM,BSUM,CWRK,CZ,CZERO,PHI,SUM,Y,Z,ZB,ZETA1,ZETA2,ZN, +C *ZR + DOUBLE PRECISION AARG, AIC, ALIM, APHI, ARGI, ARGR, ASUMI, ASUMR, + * ASCLE, AX, AY, BSUMI, BSUMR, CWRKI, CWRKR, CZI, CZR, ELIM, FNN, + * FNU, GNN, GNU, PHII, PHIR, RCZ, STR, STI, SUMI, SUMR, TOL, YI, + * YR, ZBI, ZBR, ZEROI, ZEROR, ZETA1I, ZETA1R, ZETA2I, ZETA2R, ZI, + * ZNI, ZNR, ZR, ZRI, ZRR, D1MACH, ZABS + INTEGER I, IDUM, IFORM, IKFLG, INIT, KODE, N, NN, NUF, NW + DIMENSION YR(N), YI(N), CWRKR(16), CWRKI(16) + DATA ZEROR,ZEROI / 0.0D0, 0.0D0 / + DATA AIC / 1.265512123484645396D+00 / + NUF = 0 + NN = N + ZRR = ZR + ZRI = ZI + IF (ZR.GE.0.0D0) GO TO 10 + ZRR = -ZR + ZRI = -ZI + 10 CONTINUE + ZBR = ZRR + ZBI = ZRI + AX = DABS(ZR)*1.7321D0 + AY = DABS(ZI) + IFORM = 1 + IF (AY.GT.AX) IFORM = 2 + GNU = DMAX1(FNU,1.0D0) + IF (IKFLG.EQ.1) GO TO 20 + FNN = DBLE(FLOAT(NN)) + GNN = FNU + FNN - 1.0D0 + GNU = DMAX1(GNN,FNN) + 20 CONTINUE +C----------------------------------------------------------------------- +C ONLY THE MAGNITUDE OF ARG AND PHI ARE NEEDED ALONG WITH THE +C REAL PARTS OF ZETA1, ZETA2 AND ZB. NO ATTEMPT IS MADE TO GET +C THE SIGN OF THE IMAGINARY PART CORRECT. +C----------------------------------------------------------------------- + IF (IFORM.EQ.2) GO TO 30 + INIT = 0 + CALL ZUNIK(ZRR, ZRI, GNU, IKFLG, 1, TOL, INIT, PHIR, PHII, + * ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI) + CZR = -ZETA1R + ZETA2R + CZI = -ZETA1I + ZETA2I + GO TO 50 + 30 CONTINUE + ZNR = ZRI + ZNI = -ZRR + IF (ZI.GT.0.0D0) GO TO 40 + ZNR = -ZNR + 40 CONTINUE + CALL ZUNHJ(ZNR, ZNI, GNU, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R, + * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI) + CZR = -ZETA1R + ZETA2R + CZI = -ZETA1I + ZETA2I + AARG = ZABS(CMPLX(ARGR,ARGI,kind=KIND(1.0D0))) + 50 CONTINUE + IF (KODE.EQ.1) GO TO 60 + CZR = CZR - ZBR + CZI = CZI - ZBI + 60 CONTINUE + IF (IKFLG.EQ.1) GO TO 70 + CZR = -CZR + CZI = -CZI + 70 CONTINUE + APHI = ZABS(CMPLX(PHIR,PHII,kind=KIND(1.0D0))) + RCZ = CZR +C----------------------------------------------------------------------- +C OVERFLOW TEST +C----------------------------------------------------------------------- + IF (RCZ.GT.ELIM) GO TO 210 + IF (RCZ.LT.ALIM) GO TO 80 + RCZ = RCZ + DLOG(APHI) + IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC + IF (RCZ.GT.ELIM) GO TO 210 + GO TO 130 + 80 CONTINUE +C----------------------------------------------------------------------- +C UNDERFLOW TEST +C----------------------------------------------------------------------- + IF (RCZ.LT.(-ELIM)) GO TO 90 + IF (RCZ.GT.(-ALIM)) GO TO 130 + RCZ = RCZ + DLOG(APHI) + IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC + IF (RCZ.GT.(-ELIM)) GO TO 110 + 90 CONTINUE + DO 100 I=1,NN + YR(I) = ZEROR + YI(I) = ZEROI + 100 CONTINUE + NUF = NN + RETURN + 110 CONTINUE + ASCLE = 1.0D+3*D1MACH(1)/TOL + CALL ZLOG(PHIR, PHII, STR, STI, IDUM) + CZR = CZR + STR + CZI = CZI + STI + IF (IFORM.EQ.1) GO TO 120 + CALL ZLOG(ARGR, ARGI, STR, STI, IDUM) + CZR = CZR - 0.25D0*STR - AIC + CZI = CZI - 0.25D0*STI + 120 CONTINUE + AX = DEXP(RCZ)/TOL + AY = CZI + CZR = AX*DCOS(AY) + CZI = AX*DSIN(AY) + CALL ZUCHK(CZR, CZI, NW, ASCLE, TOL) + IF (NW.NE.0) GO TO 90 + 130 CONTINUE + IF (IKFLG.EQ.2) RETURN + IF (N.EQ.1) RETURN +C----------------------------------------------------------------------- +C SET UNDERFLOWS ON I SEQUENCE +C----------------------------------------------------------------------- + 140 CONTINUE + GNU = FNU + DBLE(FLOAT(NN-1)) + IF (IFORM.EQ.2) GO TO 150 + INIT = 0 + CALL ZUNIK(ZRR, ZRI, GNU, IKFLG, 1, TOL, INIT, PHIR, PHII, + * ZETA1R, ZETA1I, ZETA2R, ZETA2I, SUMR, SUMI, CWRKR, CWRKI) + CZR = -ZETA1R + ZETA2R + CZI = -ZETA1I + ZETA2I + GO TO 160 + 150 CONTINUE + CALL ZUNHJ(ZNR, ZNI, GNU, 1, TOL, PHIR, PHII, ARGR, ARGI, ZETA1R, + * ZETA1I, ZETA2R, ZETA2I, ASUMR, ASUMI, BSUMR, BSUMI) + CZR = -ZETA1R + ZETA2R + CZI = -ZETA1I + ZETA2I + AARG = ZABS(CMPLX(ARGR,ARGI,kind=KIND(1.0D0))) + 160 CONTINUE + IF (KODE.EQ.1) GO TO 170 + CZR = CZR - ZBR + CZI = CZI - ZBI + 170 CONTINUE + APHI = ZABS(CMPLX(PHIR,PHII,kind=KIND(1.0D0))) + RCZ = CZR + IF (RCZ.LT.(-ELIM)) GO TO 180 + IF (RCZ.GT.(-ALIM)) RETURN + RCZ = RCZ + DLOG(APHI) + IF (IFORM.EQ.2) RCZ = RCZ - 0.25D0*DLOG(AARG) - AIC + IF (RCZ.GT.(-ELIM)) GO TO 190 + 180 CONTINUE + YR(NN) = ZEROR + YI(NN) = ZEROI + NN = NN - 1 + NUF = NUF + 1 + IF (NN.EQ.0) RETURN + GO TO 140 + 190 CONTINUE + ASCLE = 1.0D+3*D1MACH(1)/TOL + CALL ZLOG(PHIR, PHII, STR, STI, IDUM) + CZR = CZR + STR + CZI = CZI + STI + IF (IFORM.EQ.1) GO TO 200 + CALL ZLOG(ARGR, ARGI, STR, STI, IDUM) + CZR = CZR - 0.25D0*STR - AIC + CZI = CZI - 0.25D0*STI + 200 CONTINUE + AX = DEXP(RCZ)/TOL + AY = CZI + CZR = AX*DCOS(AY) + CZI = AX*DSIN(AY) + CALL ZUCHK(CZR, CZI, NW, ASCLE, TOL) + IF (NW.NE.0) GO TO 180 + RETURN + 210 CONTINUE + NUF = -1 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zwrsk.f b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zwrsk.f new file mode 100644 index 00000000..37cb8d8c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/amoslib/zwrsk.f @@ -0,0 +1,94 @@ + SUBROUTINE ZWRSK(ZRR, ZRI, FNU, KODE, N, YR, YI, NZ, CWR, CWI, + * TOL, ELIM, ALIM) +C***BEGIN PROLOGUE ZWRSK +C***REFER TO ZBESI,ZBESK +C +C ZWRSK COMPUTES THE I BESSEL FUNCTION FOR RE(Z).GE.0.0 BY +C NORMALIZING THE I FUNCTION RATIOS FROM ZRATI BY THE WRONSKIAN +C +C***ROUTINES CALLED D1MACH,ZBKNU,ZRATI,ZABS +C***END PROLOGUE ZWRSK +C COMPLEX CINU,CSCL,CT,CW,C1,C2,RCT,ST,Y,ZR + DOUBLE PRECISION ACT, ACW, ALIM, ASCLE, CINUI, CINUR, CSCLR, CTI, + * CTR, CWI, CWR, C1I, C1R, C2I, C2R, ELIM, FNU, PTI, PTR, RACT, + * STI, STR, TOL, YI, YR, ZRI, ZRR, ZABS, D1MACH + INTEGER I, KODE, N, NW, NZ + DIMENSION YR(N), YI(N), CWR(2), CWI(2) +C----------------------------------------------------------------------- +C I(FNU+I-1,Z) BY BACKWARD RECURRENCE FOR RATIOS +C Y(I)=I(FNU+I,Z)/I(FNU+I-1,Z) FROM CRATI NORMALIZED BY THE +C WRONSKIAN WITH K(FNU,Z) AND K(FNU+1,Z) FROM CBKNU. +C----------------------------------------------------------------------- + NZ = 0 + CALL ZBKNU(ZRR, ZRI, FNU, KODE, 2, CWR, CWI, NW, TOL, ELIM, ALIM) + IF (NW.NE.0) GO TO 50 + CALL ZRATI(ZRR, ZRI, FNU, N, YR, YI, TOL) +C----------------------------------------------------------------------- +C RECUR FORWARD ON I(FNU+1,Z) = R(FNU,Z)*I(FNU,Z), +C R(FNU+J-1,Z)=Y(J), J=1,...,N +C----------------------------------------------------------------------- + CINUR = 1.0D0 + CINUI = 0.0D0 + IF (KODE.EQ.1) GO TO 10 + CINUR = DCOS(ZRI) + CINUI = DSIN(ZRI) + 10 CONTINUE +C----------------------------------------------------------------------- +C ON LOW EXPONENT MACHINES THE K FUNCTIONS CAN BE CLOSE TO BOTH +C THE UNDER AND OVERFLOW LIMITS AND THE NORMALIZATION MUST BE +C SCALED TO PREVENT OVER OR UNDERFLOW. CUOIK HAS DETERMINED THAT +C THE RESULT IS ON SCALE. +C----------------------------------------------------------------------- + ACW = ZABS(CMPLX(CWR(2),CWI(2),kind=KIND(1.0D0))) + ASCLE = 1.0D+3*D1MACH(1)/TOL + CSCLR = 1.0D0 + IF (ACW.GT.ASCLE) GO TO 20 + CSCLR = 1.0D0/TOL + GO TO 30 + 20 CONTINUE + ASCLE = 1.0D0/ASCLE + IF (ACW.LT.ASCLE) GO TO 30 + CSCLR = TOL + 30 CONTINUE + C1R = CWR(1)*CSCLR + C1I = CWI(1)*CSCLR + C2R = CWR(2)*CSCLR + C2I = CWI(2)*CSCLR + STR = YR(1) + STI = YI(1) +C----------------------------------------------------------------------- +C CINU=CINU*(CONJG(CT)/CABS(CT))*(1.0D0/CABS(CT) PREVENTS +C UNDER- OR OVERFLOW PREMATURELY BY SQUARING CABS(CT) +C----------------------------------------------------------------------- + PTR = STR*C1R - STI*C1I + PTI = STR*C1I + STI*C1R + PTR = PTR + C2R + PTI = PTI + C2I + CTR = ZRR*PTR - ZRI*PTI + CTI = ZRR*PTI + ZRI*PTR + ACT = ZABS(CMPLX(CTR,CTI,kind=KIND(1.0D0))) + RACT = 1.0D0/ACT + CTR = CTR*RACT + CTI = -CTI*RACT + PTR = CINUR*RACT + PTI = CINUI*RACT + CINUR = PTR*CTR - PTI*CTI + CINUI = PTR*CTI + PTI*CTR + YR(1) = CINUR*CSCLR + YI(1) = CINUI*CSCLR + IF (N.EQ.1) RETURN + DO 40 I=2,N + PTR = STR*CINUR - STI*CINUI + CINUI = STR*CINUI + STI*CINUR + CINUR = PTR + STR = YR(I) + STI = YI(I) + YR(I) = CINUR*CSCLR + YI(I) = CINUI*CSCLR + 40 CONTINUE + RETURN + 50 CONTINUE + NZ = -1 + IF(NW.EQ.(-2)) NZ=-2 + RETURN + END diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/doc.go b/vendor/gonum.org/v1/gonum/mathext/internal/amos/doc.go new file mode 100644 index 00000000..45182541 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// package amos implements functions originally in the Netlab code by Donald Amos. +package amos // import "gonum.org/v1/gonum/mathext/internal/amos" diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/amos/origcode_test.go b/vendor/gonum.org/v1/gonum/mathext/internal/amos/origcode_test.go new file mode 100644 index 00000000..a7d8be8f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/amos/origcode_test.go @@ -0,0 +1,2276 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package amos + +import ( + "math" + "math/cmplx" +) + +// These routines are the versions directly modified from the Fortran code. +// They are used to ensure that code style improvements do not change the +// code output. + +func iabs(a int) int { + if a >= 0 { + return a + } + return -a +} + +func min0(a, b int) int { + if a < b { + return a + } + return b +} + +func max0(a, b int) int { + if a > b { + return a + } + return b +} + +func zairyOrig(ZR, ZI float64, ID, KODE int) (AIR, AII float64, NZ int) { + // zairy is adapted from the original Netlib code by Donald Amos. + // http://www.netlib.no/netlib/amos/zairy.f + + // Original comment: + /* + C***BEGIN PROLOGUE ZAIRY + C***DATE WRITTEN 830501 (YYMMDD) + C***REVISION DATE 890801 (YYMMDD) + C***CATEGORY NO. B5K + C***KEYWORDS AIRY FUNCTION,BESSEL FUNCTIONS OF ORDER ONE THIRD + C***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES + C***PURPOSE TO COMPUTE AIRY FUNCTIONS AI(Z) AND DAI(Z) FOR COMPLEX Z + C***DESCRIPTION + C + C ***A DOUBLE PRECISION ROUTINE*** + C ON KODE=1, ZAIRY COMPUTES THE COMPLEX AIRY FUNCTION AI(Z) OR + C ITS DERIVATIVE DAI(Z)/DZ ON ID=0 OR ID=1 RESPECTIVELY. ON + C KODE=2, A SCALING OPTION CEXP(ZTA)*AI(Z) OR CEXP(ZTA)* + C DAI(Z)/DZ IS PROVIDED TO REMOVE THE EXPONENTIAL DECAY IN + C -PI/31.0 FROM THE K BESSEL + C FUNCTIONS BY + C + C AI(Z)=C*SQRT(Z)*K(1/3,ZTA) , DAI(Z)=-C*Z*K(2/3,ZTA) + C C=1.0/(PI*SQRT(3.0)) + C ZTA=(2/3)*Z**(3/2) + C + C WITH THE POWER SERIES FOR CABS(Z)<=1.0. + C + C IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- + C MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z IS LARGE, LOSSES + C OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. CONSEQUENTLY, IF + C THE MAGNITUDE OF ZETA=(2/3)*Z**1.5 EXCEEDS U1=SQRT(0.5/UR), + C THEN LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR + C FLAG IERR=3 IS TRIGGERED WHERE UR=dmax(dmach[4),1.0D-18) IS + C DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. + C ALSO, if THE MAGNITUDE OF ZETA IS LARGER THAN U2=0.5/UR, THEN + C ALL SIGNIFICANCE IS LOST AND IERR=4. IN ORDER TO USE THE INT + C FUNCTION, ZETA MUST BE FURTHER RESTRICTED NOT TO EXCEED THE + C LARGEST INTEGER, U3=I1MACH(9). THUS, THE MAGNITUDE OF ZETA + C MUST BE RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, + C AND U3 ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE + C PRECISION ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE + C PRECISION ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMIT- + C ING IN THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT THE MAG- + C NITUDE OF Z CANNOT EXCEED 3.1E+4 IN SINGLE AND 2.1E+6 IN + C DOUBLE PRECISION ARITHMETIC. THIS ALSO MEANS THAT ONE CAN + C EXPECT TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, + C NO DIGITS IN SINGLE PRECISION AND ONLY 7 DIGITS IN DOUBLE + C PRECISION ARITHMETIC. SIMILAR CONSIDERATIONS HOLD FOR OTHER + C MACHINES. + C + C THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX + C BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P=MAX(UNIT + C ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- + C SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE + C ELEMENTARY FUNCTIONS. HERE, S=MAX(1,ABS(LOG10(CABS(Z))), + C ABS(LOG10(FNU))) APPROXIMATELY (I.E. S=MAX(1,ABS(EXPONENT OF + C CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY + C HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN + C ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY + C SEVERAL ORDERS OF MAGNITUDE. if ONE COMPONENT IS 10**K LARGER + C THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, + C 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS + C THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER + C COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY + C BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER + C COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE + C MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, + C THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, + C OR -PI/2+P. + C + C***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ + C AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF + C COMMERCE, 1955. + C + C COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT + C AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 + C + C A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX + C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- + C 1018, MAY, 1985 + C + C A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX + C ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. + C MATH. SOFTWARE, 1986 + */ + var AI, CONE, CSQ, CY, S1, S2, TRM1, TRM2, Z, ZTA, Z3 complex128 + var AA, AD, AK, ALIM, ATRM, AZ, AZ3, BK, + CC, CK, COEF, CONEI, CONER, CSQI, CSQR, C1, C2, DIG, + DK, D1, D2, ELIM, FID, FNU, PTR, RL, R1M5, SFAC, STI, STR, + S1I, S1R, S2I, S2R, TOL, TRM1I, TRM1R, TRM2I, TRM2R, TTH, ZEROI, + ZEROR, ZTAI, ZTAR, Z3I, Z3R, ALAZ, BB float64 + var IERR, IFLAG, K, K1, K2, MR, NN int + var tmp complex128 + + // Extra element for padding. + CYR := []float64{math.NaN(), 0} + CYI := []float64{math.NaN(), 0} + + _ = AI + _ = CONE + _ = CSQ + _ = CY + _ = S1 + _ = S2 + _ = TRM1 + _ = TRM2 + _ = Z + _ = ZTA + _ = Z3 + + TTH = 6.66666666666666667E-01 + C1 = 3.55028053887817240E-01 + C2 = 2.58819403792806799E-01 + COEF = 1.83776298473930683E-01 + ZEROR = 0 + ZEROI = 0 + CONER = 1 + CONEI = 0 + + NZ = 0 + if ID < 0 || ID > 1 { + IERR = 1 + } + if KODE < 1 || KODE > 2 { + IERR = 1 + } + if IERR != 0 { + return + } + AZ = zabs(complex(ZR, ZI)) + TOL = dmax(dmach[4], 1.0E-18) + FID = float64(ID) + if AZ > 1.0E0 { + goto Seventy + } + + // POWER SERIES FOR CABS(Z)<=1. + S1R = CONER + S1I = CONEI + S2R = CONER + S2I = CONEI + if AZ < TOL { + goto OneSeventy + } + AA = AZ * AZ + if AA < TOL/AZ { + goto Forty + } + TRM1R = CONER + TRM1I = CONEI + TRM2R = CONER + TRM2I = CONEI + ATRM = 1.0E0 + STR = ZR*ZR - ZI*ZI + STI = ZR*ZI + ZI*ZR + Z3R = STR*ZR - STI*ZI + Z3I = STR*ZI + STI*ZR + AZ3 = AZ * AA + AK = 2.0E0 + FID + BK = 3.0E0 - FID - FID + CK = 4.0E0 - FID + DK = 3.0E0 + FID + FID + D1 = AK * DK + D2 = BK * CK + AD = dmin(D1, D2) + AK = 24.0E0 + 9.0E0*FID + BK = 30.0E0 - 9.0E0*FID + for K = 1; K <= 25; K++ { + STR = (TRM1R*Z3R - TRM1I*Z3I) / D1 + TRM1I = (TRM1R*Z3I + TRM1I*Z3R) / D1 + TRM1R = STR + S1R = S1R + TRM1R + S1I = S1I + TRM1I + STR = (TRM2R*Z3R - TRM2I*Z3I) / D2 + TRM2I = (TRM2R*Z3I + TRM2I*Z3R) / D2 + TRM2R = STR + S2R = S2R + TRM2R + S2I = S2I + TRM2I + ATRM = ATRM * AZ3 / AD + D1 = D1 + AK + D2 = D2 + BK + AD = dmin(D1, D2) + if ATRM < TOL*AD { + goto Forty + } + AK = AK + 18.0E0 + BK = BK + 18.0E0 + } +Forty: + if ID == 1 { + goto Fifty + } + AIR = S1R*C1 - C2*(ZR*S2R-ZI*S2I) + AII = S1I*C1 - C2*(ZR*S2I+ZI*S2R) + if KODE == 1 { + return + } + tmp = zsqrt(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + ZTAR = TTH * (ZR*STR - ZI*STI) + ZTAI = TTH * (ZR*STI + ZI*STR) + tmp = zexp(complex(ZTAR, ZTAI)) + STR = real(tmp) + STI = imag(tmp) + PTR = AIR*STR - AII*STI + AII = AIR*STI + AII*STR + AIR = PTR + return + +Fifty: + AIR = -S2R * C2 + AII = -S2I * C2 + if AZ <= TOL { + goto Sixty + } + STR = ZR*S1R - ZI*S1I + STI = ZR*S1I + ZI*S1R + CC = C1 / (1.0E0 + FID) + AIR = AIR + CC*(STR*ZR-STI*ZI) + AII = AII + CC*(STR*ZI+STI*ZR) + +Sixty: + if KODE == 1 { + return + } + tmp = zsqrt(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + ZTAR = TTH * (ZR*STR - ZI*STI) + ZTAI = TTH * (ZR*STI + ZI*STR) + tmp = zexp(complex(ZTAR, ZTAI)) + STR = real(tmp) + STI = imag(tmp) + PTR = STR*AIR - STI*AII + AII = STR*AII + STI*AIR + AIR = PTR + return + + // CASE FOR CABS(Z)>1.0. +Seventy: + FNU = (1.0E0 + FID) / 3.0E0 + + /* + SET PARAMETERS RELATED TO MACHINE CONSTANTS. + TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0D-18. + ELIM IS THE APPROXIMATE EXPONENTIAL OVER-&&UNDERFLOW LIMIT. + EXP(-ELIM)EXP(ALIM)=EXP(ELIM)*TOL ARE INTERVALS NEAR + UNDERFLOW&&OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. + RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LA>=Z. + DIG = NUMBER OF BASE 10 DIGITS IN TOL = 10**(-DIG). + */ + K1 = imach[15] + K2 = imach[16] + R1M5 = dmach[5] + + K = min0(iabs(K1), iabs(K2)) + ELIM = 2.303E0 * (float64(K)*R1M5 - 3.0E0) + K1 = imach[14] - 1 + AA = R1M5 * float64(K1) + DIG = dmin(AA, 18.0E0) + AA = AA * 2.303E0 + ALIM = ELIM + dmax(-AA, -41.45E0) + RL = 1.2E0*DIG + 3.0E0 + ALAZ = dlog(AZ) + + // TEST FOR PROPER RANGE. + AA = 0.5E0 / TOL + BB = float64(float32(imach[9])) * 0.5E0 + AA = dmin(AA, BB) + AA = math.Pow(AA, TTH) + if AZ > AA { + goto TwoSixty + } + AA = dsqrt(AA) + if AZ > AA { + IERR = 3 + } + tmp = zsqrt(complex(ZR, ZI)) + CSQR = real(tmp) + CSQI = imag(tmp) + ZTAR = TTH * (ZR*CSQR - ZI*CSQI) + ZTAI = TTH * (ZR*CSQI + ZI*CSQR) + + // RE(ZTA)<=0 WHEN RE(Z)<0, ESPECIALLY WHEN IM(Z) IS SMALL. + IFLAG = 0 + SFAC = 1.0E0 + AK = ZTAI + if ZR >= 0.0E0 { + goto Eighty + } + BK = ZTAR + CK = -dabs(BK) + ZTAR = CK + ZTAI = AK + +Eighty: + if ZI != 0.0E0 { + goto Ninety + } + if ZR > 0.0E0 { + goto Ninety + } + ZTAR = 0.0E0 + ZTAI = AK +Ninety: + AA = ZTAR + if AA >= 0.0E0 && ZR > 0.0E0 { + goto OneTen + } + if KODE == 2 { + goto OneHundred + } + + // OVERFLOW TEST. + if AA > (-ALIM) { + goto OneHundred + } + AA = -AA + 0.25E0*ALAZ + IFLAG = 1 + SFAC = TOL + if AA > ELIM { + goto TwoSeventy + } + +OneHundred: + // CBKNU AND CACON return EXP(ZTA)*K(FNU,ZTA) ON KODE=2. + MR = 1 + if ZI < 0.0E0 { + MR = -1 + } + ZTAR, ZTAI, FNU, KODE, MR, _, CYR, CYI, NN, RL, TOL, ELIM, ALIM = zacaiOrig(ZTAR, ZTAI, FNU, KODE, MR, 1, CYR, CYI, NN, RL, TOL, ELIM, ALIM) + if NN < 0 { + goto TwoEighty + } + NZ = NZ + NN + goto OneThirty + +OneTen: + if KODE == 2 { + goto OneTwenty + } + + // UNDERFLOW TEST. + if AA < ALIM { + goto OneTwenty + } + AA = -AA - 0.25E0*ALAZ + IFLAG = 2 + SFAC = 1.0E0 / TOL + if AA < (-ELIM) { + goto TwoTen + } +OneTwenty: + ZTAR, ZTAI, FNU, KODE, _, CYR, CYI, NZ, TOL, ELIM, ALIM = zbknuOrig(ZTAR, ZTAI, FNU, KODE, 1, CYR, CYI, NZ, TOL, ELIM, ALIM) + +OneThirty: + S1R = CYR[1] * COEF + S1I = CYI[1] * COEF + if IFLAG != 0 { + goto OneFifty + } + if ID == 1 { + goto OneFourty + } + AIR = CSQR*S1R - CSQI*S1I + AII = CSQR*S1I + CSQI*S1R + return +OneFourty: + AIR = -(ZR*S1R - ZI*S1I) + AII = -(ZR*S1I + ZI*S1R) + return +OneFifty: + S1R = S1R * SFAC + S1I = S1I * SFAC + if ID == 1 { + goto OneSixty + } + STR = S1R*CSQR - S1I*CSQI + S1I = S1R*CSQI + S1I*CSQR + S1R = STR + AIR = S1R / SFAC + AII = S1I / SFAC + return +OneSixty: + STR = -(S1R*ZR - S1I*ZI) + S1I = -(S1R*ZI + S1I*ZR) + S1R = STR + AIR = S1R / SFAC + AII = S1I / SFAC + return +OneSeventy: + AA = 1.0E+3 * dmach[1] + S1R = ZEROR + S1I = ZEROI + if ID == 1 { + goto OneNinety + } + if AZ <= AA { + goto OneEighty + } + S1R = C2 * ZR + S1I = C2 * ZI +OneEighty: + AIR = C1 - S1R + AII = -S1I + return +OneNinety: + AIR = -C2 + AII = 0.0E0 + AA = dsqrt(AA) + if AZ <= AA { + goto TwoHundred + } + S1R = 0.5E0 * (ZR*ZR - ZI*ZI) + S1I = ZR * ZI +TwoHundred: + AIR = AIR + C1*S1R + AII = AII + C1*S1I + return +TwoTen: + NZ = 1 + AIR = ZEROR + AII = ZEROI + return +TwoSeventy: + NZ = 0 + IERR = 2 + return +TwoEighty: + if NN == (-1) { + goto TwoSeventy + } + NZ = 0 + IERR = 5 + return +TwoSixty: + IERR = 4 + NZ = 0 + return +} + +// sbknu computes the k bessel function in the right half z plane. +func zbknuOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL, ELIM, ALIM float64) (ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout, ELIMout, ALIMout float64) { + /* Old dimension comment. + DIMENSION YR(N), YI(N), CC(8), CSSR(3), CSRR(3), BRY(3), CYR(2), + * CYI(2) + */ + + // TODO(btracey): Find which of these are inputs/outputs/both and clean up + // the function call. + // YR and YI have length n (but n+1 with better indexing) + var AA, AK, ASCLE, A1, A2, BB, BK, CAZ, + CBI, CBR, CCHI, CCHR, CKI, CKR, COEFI, COEFR, CONEI, CONER, + CRSCR, CSCLR, CSHI, CSHR, CSI, CSR, CTWOR, + CZEROI, CZEROR, CZI, CZR, DNU, DNU2, DPI, ETEST, FC, FHS, + FI, FK, FKS, FMUI, FMUR, FPI, FR, G1, G2, HPI, PI, PR, PTI, + PTR, P1I, P1R, P2I, P2M, P2R, QI, QR, RAK, RCAZ, RTHPI, RZI, + RZR, R1, S, SMUI, SMUR, SPI, STI, STR, S1I, S1R, S2I, S2R, TM, + TTH, T1, T2, ELM, CELMR, ZDR, ZDI, AS, ALAS, HELIM float64 + + var I, IFLAG, INU, K, KFLAG, KK, KMAX, KODED, IDUM, J, IC, INUB, NW int + + var tmp complex128 + var CSSR, CSRR, BRY [4]float64 + var CYR, CYI [3]float64 + + KMAX = 30 + CZEROR = 0 + CZEROI = 0 + CONER = 1 + CONEI = 0 + CTWOR = 2 + R1 = 2 + + DPI = 3.14159265358979324E0 + RTHPI = 1.25331413731550025E0 + SPI = 1.90985931710274403E0 + HPI = 1.57079632679489662E0 + FPI = 1.89769999331517738E0 + TTH = 6.66666666666666666E-01 + + CC := [9]float64{math.NaN(), 5.77215664901532861E-01, -4.20026350340952355E-02, + -4.21977345555443367E-02, 7.21894324666309954E-03, + -2.15241674114950973E-04, -2.01348547807882387E-05, + 1.13302723198169588E-06, 6.11609510448141582E-09} + + CAZ = zabs(complex(ZR, ZI)) + CSCLR = 1.0E0 / TOL + CRSCR = TOL + CSSR[1] = CSCLR + CSSR[2] = 1.0E0 + CSSR[3] = CRSCR + CSRR[1] = CRSCR + CSRR[2] = 1.0E0 + CSRR[3] = CSCLR + BRY[1] = 1.0E+3 * dmach[1] / TOL + BRY[2] = 1.0E0 / BRY[1] + BRY[3] = dmach[2] + NZ = 0 + IFLAG = 0 + KODED = KODE + RCAZ = 1.0E0 / CAZ + STR = ZR * RCAZ + STI = -ZI * RCAZ + RZR = (STR + STR) * RCAZ + RZI = (STI + STI) * RCAZ + INU = int(float32(FNU + 0.5)) + DNU = FNU - float64(INU) + if dabs(DNU) == 0.5E0 { + goto OneTen + } + DNU2 = 0.0E0 + if dabs(DNU) > TOL { + DNU2 = DNU * DNU + } + if CAZ > R1 { + goto OneTen + } + + // SERIES FOR CABS(Z)<=R1. + FC = 1.0E0 + tmp = zlog(complex(RZR, RZI)) + SMUR = real(tmp) + SMUI = imag(tmp) + FMUR = SMUR * DNU + FMUI = SMUI * DNU + FMUR, FMUI, CSHR, CSHI, CCHR, CCHI = zshchOrig(FMUR, FMUI, CSHR, CSHI, CCHR, CCHI) + if DNU == 0.0E0 { + goto Ten + } + FC = DNU * DPI + FC = FC / dsin(FC) + SMUR = CSHR / DNU + SMUI = CSHI / DNU +Ten: + A2 = 1.0E0 + DNU + + // GAM(1-Z)*GAM(1+Z)=PI*Z/SIN(PI*Z), T1=1/GAM(1-DNU), T2=1/GAM(1+DNU). + T2 = dexp(-dgamln(A2, IDUM)) + T1 = 1.0E0 / (T2 * FC) + if dabs(DNU) > 0.1E0 { + goto Forty + } + + // SERIES FOR F0 TO RESOLVE INDETERMINACY FOR SMALL ABS(DNU). + AK = 1.0E0 + S = CC[1] + for K = 2; K <= 8; K++ { + AK = AK * DNU2 + TM = CC[K] * AK + S = S + TM + if dabs(TM) < TOL { + goto Thirty + } + } +Thirty: + G1 = -S + goto Fifty +Forty: + G1 = (T1 - T2) / (DNU + DNU) +Fifty: + G2 = (T1 + T2) * 0.5E0 + FR = FC * (CCHR*G1 + SMUR*G2) + FI = FC * (CCHI*G1 + SMUI*G2) + tmp = zexp(complex(FMUR, FMUI)) + STR = real(tmp) + STI = imag(tmp) + PR = 0.5E0 * STR / T2 + PI = 0.5E0 * STI / T2 + tmp = zdiv(complex(0.5, 0), complex(STR, STI)) + PTR = real(tmp) + PTI = imag(tmp) + QR = PTR / T1 + QI = PTI / T1 + S1R = FR + S1I = FI + S2R = PR + S2I = PI + AK = 1.0E0 + A1 = 1.0E0 + CKR = CONER + CKI = CONEI + BK = 1.0E0 - DNU2 + if INU > 0 || N > 1 { + goto Eighty + } + + // GENERATE K(FNU,Z), 0.0E0 <= FNU < 0.5E0 AND N=1. + if CAZ < TOL { + goto Seventy + } + tmp = zmlt(complex(ZR, ZI), complex(ZR, ZI)) + CZR = real(tmp) + CZI = imag(tmp) + CZR = 0.25E0 * CZR + CZI = 0.25E0 * CZI + T1 = 0.25E0 * CAZ * CAZ +Sixty: + FR = (FR*AK + PR + QR) / BK + FI = (FI*AK + PI + QI) / BK + STR = 1.0E0 / (AK - DNU) + PR = PR * STR + PI = PI * STR + STR = 1.0E0 / (AK + DNU) + QR = QR * STR + QI = QI * STR + STR = CKR*CZR - CKI*CZI + RAK = 1.0E0 / AK + CKI = (CKR*CZI + CKI*CZR) * RAK + CKR = STR * RAK + S1R = CKR*FR - CKI*FI + S1R + S1I = CKR*FI + CKI*FR + S1I + A1 = A1 * T1 * RAK + BK = BK + AK + AK + 1.0E0 + AK = AK + 1.0E0 + if A1 > TOL { + goto Sixty + } +Seventy: + YR[1] = S1R + YI[1] = S1I + if KODED == 1 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + tmp = zexp(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = zmlt(complex(S1R, S1I), complex(STR, STI)) + YR[1] = real(tmp) + YI[1] = imag(tmp) + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + + // GENERATE K(DNU,Z) AND K(DNU+1,Z) FOR FORWARD RECURRENCE. +Eighty: + if CAZ < TOL { + goto OneHundred + } + tmp = zmlt(complex(ZR, ZI), complex(ZR, ZI)) + CZR = real(tmp) + CZI = imag(tmp) + CZR = 0.25E0 * CZR + CZI = 0.25E0 * CZI + T1 = 0.25E0 * CAZ * CAZ +Ninety: + FR = (FR*AK + PR + QR) / BK + FI = (FI*AK + PI + QI) / BK + STR = 1.0E0 / (AK - DNU) + PR = PR * STR + PI = PI * STR + STR = 1.0E0 / (AK + DNU) + QR = QR * STR + QI = QI * STR + STR = CKR*CZR - CKI*CZI + RAK = 1.0E0 / AK + CKI = (CKR*CZI + CKI*CZR) * RAK + CKR = STR * RAK + S1R = CKR*FR - CKI*FI + S1R + S1I = CKR*FI + CKI*FR + S1I + STR = PR - FR*AK + STI = PI - FI*AK + S2R = CKR*STR - CKI*STI + S2R + S2I = CKR*STI + CKI*STR + S2I + A1 = A1 * T1 * RAK + BK = BK + AK + AK + 1.0E0 + AK = AK + 1.0E0 + if A1 > TOL { + goto Ninety + } +OneHundred: + KFLAG = 2 + A1 = FNU + 1.0E0 + AK = A1 * dabs(SMUR) + if AK > ALIM { + KFLAG = 3 + } + STR = CSSR[KFLAG] + P2R = S2R * STR + P2I = S2I * STR + tmp = zmlt(complex(P2R, P2I), complex(RZR, RZI)) + S2R = real(tmp) + S2I = imag(tmp) + S1R = S1R * STR + S1I = S1I * STR + if KODED == 1 { + goto TwoTen + } + tmp = zexp(complex(ZR, ZI)) + FR = real(tmp) + FI = imag(tmp) + tmp = zmlt(complex(S1R, S1I), complex(FR, FI)) + S1R = real(tmp) + S1I = imag(tmp) + tmp = zmlt(complex(S2R, S2I), complex(FR, FI)) + S2R = real(tmp) + S2I = imag(tmp) + goto TwoTen + + // IFLAG=0 MEANS NO UNDERFLOW OCCURRED + // IFLAG=1 MEANS AN UNDERFLOW OCCURRED- COMPUTATION PROCEEDS WITH + // KODED=2 AND A TEST FOR ON SCALE VALUES IS MADE DURING FORWARD RECURSION +OneTen: + tmp = zsqrt(complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = zdiv(complex(RTHPI, CZEROI), complex(STR, STI)) + COEFR = real(tmp) + COEFI = imag(tmp) + KFLAG = 2 + if KODED == 2 { + goto OneTwenty + } + if ZR > ALIM { + goto TwoNinety + } + + STR = dexp(-ZR) * CSSR[KFLAG] + STI = -STR * dsin(ZI) + STR = STR * dcos(ZI) + tmp = zmlt(complex(COEFR, COEFI), complex(STR, STI)) + COEFR = real(tmp) + COEFI = imag(tmp) +OneTwenty: + if dabs(DNU) == 0.5E0 { + goto ThreeHundred + } + // MILLER ALGORITHM FOR CABS(Z)>R1. + AK = dcos(DPI * DNU) + AK = dabs(AK) + if AK == CZEROR { + goto ThreeHundred + } + FHS = dabs(0.25E0 - DNU2) + if FHS == CZEROR { + goto ThreeHundred + } + + // COMPUTE R2=F(E). if CABS(Z)>=R2, USE FORWARD RECURRENCE TO + // DETERMINE THE BACKWARD INDEX K. R2=F(E) IS A STRAIGHT LINE ON + // 12<=E<=60. E IS COMPUTED FROM 2**(-E)=B**(1-I1MACH(14))= + // TOL WHERE B IS THE BASE OF THE ARITHMETIC. + T1 = float64(imach[14] - 1) + T1 = T1 * dmach[5] * 3.321928094E0 + T1 = dmax(T1, 12.0E0) + T1 = dmin(T1, 60.0E0) + T2 = TTH*T1 - 6.0E0 + if ZR != 0.0E0 { + goto OneThirty + } + T1 = HPI + goto OneFourty +OneThirty: + T1 = datan(ZI / ZR) + T1 = dabs(T1) +OneFourty: + if T2 > CAZ { + goto OneSeventy + } + // FORWARD RECURRENCE LOOP WHEN CABS(Z)>=R2. + ETEST = AK / (DPI * CAZ * TOL) + FK = CONER + if ETEST < CONER { + goto OneEighty + } + FKS = CTWOR + CKR = CAZ + CAZ + CTWOR + P1R = CZEROR + P2R = CONER + for I = 1; I <= KMAX; I++ { + AK = FHS / FKS + CBR = CKR / (FK + CONER) + PTR = P2R + P2R = CBR*P2R - P1R*AK + P1R = PTR + CKR = CKR + CTWOR + FKS = FKS + FK + FK + CTWOR + FHS = FHS + FK + FK + FK = FK + CONER + STR = dabs(P2R) * FK + if ETEST < STR { + goto OneSixty + } + } + goto ThreeTen +OneSixty: + FK = FK + SPI*T1*dsqrt(T2/CAZ) + FHS = dabs(0.25 - DNU2) + goto OneEighty +OneSeventy: + // COMPUTE BACKWARD INDEX K FOR CABS(Z) 0 || N > 1 { + goto TwoHundred + } + ZDR = ZR + ZDI = ZI + if IFLAG == 1 { + goto TwoSeventy + } + goto TwoFourty +TwoHundred: + // COMPUTE P1/P2=(P1/CABS(P2)*CONJG(P2)/CABS(P2) FOR SCALING. + TM = zabs(complex(P2R, P2I)) + PTR = 1.0E0 / TM + P1R = P1R * PTR + P1I = P1I * PTR + P2R = P2R * PTR + P2I = -P2I * PTR + tmp = zmlt(complex(P1R, P1I), complex(P2R, P2I)) + PTR = real(tmp) + PTI = imag(tmp) + STR = DNU + 0.5E0 - PTR + STI = -PTI + tmp = zdiv(complex(STR, STI), complex(ZR, ZI)) + STR = real(tmp) + STI = imag(tmp) + STR = STR + 1.0E0 + tmp = zmlt(complex(STR, STI), complex(S1R, S1I)) + S2R = real(tmp) + S2I = imag(tmp) + + // FORWARD RECURSION ON THE THREE TERM RECURSION WITH RELATION WITH + // SCALING NEAR EXPONENT EXTREMES ON KFLAG=1 OR KFLAG=3 +TwoTen: + STR = DNU + 1.0E0 + CKR = STR * RZR + CKI = STR * RZI + if N == 1 { + INU = INU - 1 + } + if INU > 0 { + goto TwoTwenty + } + if N > 1 { + goto TwoFifteen + } + S1R = S2R + S1I = S2I +TwoFifteen: + ZDR = ZR + ZDI = ZI + if IFLAG == 1 { + goto TwoSeventy + } + goto TwoFourty +TwoTwenty: + INUB = 1 + if IFLAG == 1 { + goto TwoSixtyOne + } +TwoTwentyFive: + P1R = CSRR[KFLAG] + ASCLE = BRY[KFLAG] + for I = INUB; I <= INU; I++ { + STR = S2R + STI = S2I + S2R = CKR*STR - CKI*STI + S1R + S2I = CKR*STI + CKI*STR + S1I + S1R = STR + S1I = STI + CKR = CKR + RZR + CKI = CKI + RZI + if KFLAG >= 3 { + continue + } + P2R = S2R * P1R + P2I = S2I * P1R + STR = dabs(P2R) + STI = dabs(P2I) + P2M = dmax(STR, STI) + if P2M <= ASCLE { + continue + } + KFLAG = KFLAG + 1 + ASCLE = BRY[KFLAG] + S1R = S1R * P1R + S1I = S1I * P1R + S2R = P2R + S2I = P2I + STR = CSSR[KFLAG] + S1R = S1R * STR + S1I = S1I * STR + S2R = S2R * STR + S2I = S2I * STR + P1R = CSRR[KFLAG] + } + if N != 1 { + goto TwoFourty + } + S1R = S2R + S1I = S2I +TwoFourty: + STR = CSRR[KFLAG] + YR[1] = S1R * STR + YI[1] = S1I * STR + if N == 1 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + YR[2] = S2R * STR + YI[2] = S2I * STR + if N == 2 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + KK = 2 +TwoFifty: + KK = KK + 1 + if KK > N { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + P1R = CSRR[KFLAG] + ASCLE = BRY[KFLAG] + for I = KK; I <= N; I++ { + P2R = S2R + P2I = S2I + S2R = CKR*P2R - CKI*P2I + S1R + S2I = CKI*P2R + CKR*P2I + S1I + S1R = P2R + S1I = P2I + CKR = CKR + RZR + CKI = CKI + RZI + P2R = S2R * P1R + P2I = S2I * P1R + YR[I] = P2R + YI[I] = P2I + if KFLAG >= 3 { + continue + } + STR = dabs(P2R) + STI = dabs(P2I) + P2M = dmax(STR, STI) + if P2M <= ASCLE { + continue + } + KFLAG = KFLAG + 1 + ASCLE = BRY[KFLAG] + S1R = S1R * P1R + S1I = S1I * P1R + S2R = P2R + S2I = P2I + STR = CSSR[KFLAG] + S1R = S1R * STR + S1I = S1I * STR + S2R = S2R * STR + S2I = S2I * STR + P1R = CSRR[KFLAG] + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + + // IFLAG=1 CASES, FORWARD RECURRENCE ON SCALED VALUES ON UNDERFLOW. +TwoSixtyOne: + HELIM = 0.5E0 * ELIM + ELM = dexp(-ELIM) + CELMR = ELM + ASCLE = BRY[1] + ZDR = ZR + ZDI = ZI + IC = -1 + J = 2 + for I = 1; I <= INU; I++ { + STR = S2R + STI = S2I + S2R = STR*CKR - STI*CKI + S1R + S2I = STI*CKR + STR*CKI + S1I + S1R = STR + S1I = STI + CKR = CKR + RZR + CKI = CKI + RZI + AS = zabs(complex(S2R, S2I)) + ALAS = dlog(AS) + P2R = -ZDR + ALAS + if P2R < (-ELIM) { + goto TwoSixtyThree + } + tmp = zlog(complex(S2R, S2I)) + STR = real(tmp) + STI = imag(tmp) + P2R = -ZDR + STR + P2I = -ZDI + STI + P2M = dexp(P2R) / TOL + P1R = P2M * dcos(P2I) + P1I = P2M * dsin(P2I) + P1R, P1I, NW, ASCLE, TOL = zuchkOrig(P1R, P1I, NW, ASCLE, TOL) + if NW != 0 { + goto TwoSixtyThree + } + J = 3 - J + CYR[J] = P1R + CYI[J] = P1I + if IC == (I - 1) { + goto TwoSixtyFour + } + IC = I + continue + TwoSixtyThree: + if ALAS < HELIM { + continue + } + ZDR = ZDR - ELIM + S1R = S1R * CELMR + S1I = S1I * CELMR + S2R = S2R * CELMR + S2I = S2I * CELMR + } + if N != 1 { + goto TwoSeventy + } + S1R = S2R + S1I = S2I + goto TwoSeventy +TwoSixtyFour: + KFLAG = 1 + INUB = I + 1 + S2R = CYR[J] + S2I = CYI[J] + J = 3 - J + S1R = CYR[J] + S1I = CYI[J] + if INUB <= INU { + goto TwoTwentyFive + } + if N != 1 { + goto TwoFourty + } + S1R = S2R + S1I = S2I + goto TwoFourty +TwoSeventy: + YR[1] = S1R + YI[1] = S1I + if N == 1 { + goto TwoEighty + } + YR[2] = S2R + YI[2] = S2I +TwoEighty: + ASCLE = BRY[1] + ZDR, ZDI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM = zksclOrig(ZDR, ZDI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM) + INU = N - NZ + if INU <= 0 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + KK = NZ + 1 + S1R = YR[KK] + S1I = YI[KK] + YR[KK] = S1R * CSRR[1] + YI[KK] = S1I * CSRR[1] + if INU == 1 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + KK = NZ + 2 + S2R = YR[KK] + S2I = YI[KK] + YR[KK] = S2R * CSRR[1] + YI[KK] = S2I * CSRR[1] + if INU == 2 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + T2 = FNU + float64(float32(KK-1)) + CKR = T2 * RZR + CKI = T2 * RZI + KFLAG = 1 + goto TwoFifty +TwoNinety: + + // SCALE BY dexp(Z), IFLAG = 1 CASES. + + KODED = 2 + IFLAG = 1 + KFLAG = 2 + goto OneTwenty + + // FNU=HALF ODD INTEGER CASE, DNU=-0.5 +ThreeHundred: + S1R = COEFR + S1I = COEFI + S2R = COEFR + S2I = COEFI + goto TwoTen + +ThreeTen: + NZ = -2 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM +} + +// SET K FUNCTIONS TO ZERO ON UNDERFLOW, CONTINUE RECURRENCE +// ON SCALED FUNCTIONS UNTIL TWO MEMBERS COME ON SCALE, THEN +// return WITH MIN(NZ+2,N) VALUES SCALED BY 1/TOL. +func zksclOrig(ZRR, ZRI, FNU float64, N int, YR, YI []float64, NZ int, RZR, RZI, ASCLE, TOL, ELIM float64) ( + ZRRout, ZRIout, FNUout float64, Nout int, YRout, YIout []float64, NZout int, RZRout, RZIout, ASCLEout, TOLout, ELIMout float64) { + var ACS, AS, CKI, CKR, CSI, CSR, FN, STR, S1I, S1R, S2I, + S2R, ZEROI, ZEROR, ZDR, ZDI, CELMR, ELM, HELIM, ALAS float64 + + var I, IC, KK, NN, NW int + var tmp complex128 + var CYR, CYI [3]float64 + // DIMENSION YR(N), YI(N), CYR(2), CYI(2) + ZEROR = 0 + ZEROI = 0 + NZ = 0 + IC = 0 + NN = min0(2, N) + for I = 1; I <= NN; I++ { + S1R = YR[I] + S1I = YI[I] + CYR[I] = S1R + CYI[I] = S1I + AS = zabs(complex(S1R, S1I)) + ACS = -ZRR + dlog(AS) + NZ = NZ + 1 + YR[I] = ZEROR + YI[I] = ZEROI + if ACS < (-ELIM) { + continue + } + + tmp = zlog(complex(S1R, S1I)) + CSR = real(tmp) + CSI = imag(tmp) + CSR = CSR - ZRR + CSI = CSI - ZRI + STR = dexp(CSR) / TOL + CSR = STR * dcos(CSI) + CSI = STR * dsin(CSI) + CSR, CSI, NW, ASCLE, TOL = zuchkOrig(CSR, CSI, NW, ASCLE, TOL) + if NW != 0 { + continue + } + YR[I] = CSR + YI[I] = CSI + IC = I + NZ = NZ - 1 + } + if N == 1 { + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM + } + if IC > 1 { + goto Twenty + } + YR[1] = ZEROR + YI[1] = ZEROI + NZ = 2 +Twenty: + if N == 2 { + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM + } + if NZ == 0 { + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM + } + FN = FNU + 1.0E0 + CKR = FN * RZR + CKI = FN * RZI + S1R = CYR[1] + S1I = CYI[1] + S2R = CYR[2] + S2I = CYI[2] + HELIM = 0.5E0 * ELIM + ELM = dexp(-ELIM) + CELMR = ELM + ZDR = ZRR + ZDI = ZRI + + // FIND TWO CONSECUTIVE Y VALUES ON SCALE. SCALE RECURRENCE IF + // S2 GETS LARGER THAN EXP(ELIM/2) + for I = 3; I <= N; I++ { + KK = I + CSR = S2R + CSI = S2I + S2R = CKR*CSR - CKI*CSI + S1R + S2I = CKI*CSR + CKR*CSI + S1I + S1R = CSR + S1I = CSI + CKR = CKR + RZR + CKI = CKI + RZI + AS = zabs(complex(S2R, S2I)) + ALAS = dlog(AS) + ACS = -ZDR + ALAS + NZ = NZ + 1 + YR[I] = ZEROR + YI[I] = ZEROI + if ACS < (-ELIM) { + goto TwentyFive + } + tmp = zlog(complex(S2R, S2I)) + CSR = real(tmp) + CSI = imag(tmp) + CSR = CSR - ZDR + CSI = CSI - ZDI + STR = dexp(CSR) / TOL + CSR = STR * dcos(CSI) + CSI = STR * dsin(CSI) + CSR, CSI, NW, ASCLE, TOL = zuchkOrig(CSR, CSI, NW, ASCLE, TOL) + if NW != 0 { + goto TwentyFive + } + YR[I] = CSR + YI[I] = CSI + NZ = NZ - 1 + if IC == KK-1 { + goto Forty + } + IC = KK + continue + TwentyFive: + if ALAS < HELIM { + continue + } + ZDR = ZDR - ELIM + S1R = S1R * CELMR + S1I = S1I * CELMR + S2R = S2R * CELMR + S2I = S2I * CELMR + } + NZ = N + if IC == N { + NZ = N - 1 + } + goto FourtyFive +Forty: + NZ = KK - 2 +FourtyFive: + for I = 1; I <= NZ; I++ { + YR[I] = ZEROR + YI[I] = ZEROI + } + return ZRR, ZRI, FNU, N, YR, YI, NZ, RZR, RZI, ASCLE, TOL, ELIM +} + +// Y ENTERS AS A SCALED QUANTITY WHOSE MAGNITUDE IS GREATER THAN +// EXP(-ALIM)=ASCLE=1.0E+3*dmach[1)/TOL. THE TEST IS MADE TO SEE +// if THE MAGNITUDE OF THE REAL OR IMAGINARY PART WOULD UNDERFLOW +// WHEN Y IS SCALED (BY TOL) TO ITS PROPER VALUE. Y IS ACCEPTED +// if THE UNDERFLOW IS AT LEAST ONE PRECISION BELOW THE MAGNITUDE +// OF THE LARGEST COMPONENT; OTHERWISE THE PHASE ANGLE DOES NOT HAVE +// ABSOLUTE ACCURACY AND AN UNDERFLOW IS ASSUMED. +func zuchkOrig(YR, YI float64, NZ int, ASCLE, TOL float64) (YRout, YIout float64, NZout int, ASCLEout, TOLout float64) { + var SS, ST, WR, WI float64 + NZ = 0 + WR = dabs(YR) + WI = dabs(YI) + ST = dmin(WR, WI) + if ST > ASCLE { + return YR, YI, NZ, ASCLE, TOL + } + SS = dmax(WR, WI) + ST = ST / TOL + if SS < ST { + NZ = 1 + } + return YR, YI, NZ, ASCLE, TOL +} + +// ZACAI APPLIES THE ANALYTIC CONTINUATION FORMULA +// +// K(FNU,ZN*EXP(MP))=K(FNU,ZN)*EXP(-MP*FNU) - MP*I(FNU,ZN) +// MP=PI*MR*CMPLX(0.0,1.0) +// +// TO CONTINUE THE K FUNCTION FROM THE RIGHT HALF TO THE LEFT +// HALF Z PLANE FOR USE WITH ZAIRY WHERE FNU=1/3 OR 2/3 AND N=1. +// ZACAI IS THE SAME AS ZACON WITH THE PARTS FOR LARGER ORDERS AND +// RECURRENCE REMOVED. A RECURSIVE CALL TO ZACON CAN RESULT if ZACON +// IS CALLED FROM ZAIRY. +func zacaiOrig(ZR, ZI, FNU float64, KODE, MR, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, MRout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { + var ARG, ASCLE, AZ, CSGNR, CSGNI, CSPNR, + CSPNI, C1R, C1I, C2R, C2I, DFNU, FMR, PI, + SGN, YY, ZNR, ZNI float64 + var INU, IUF, NN, NW int + CYR := []float64{math.NaN(), 0, 0} + CYI := []float64{math.NaN(), 0, 0} + + PI = math.Pi + NZ = 0 + ZNR = -ZR + ZNI = -ZI + AZ = zabs(complex(ZR, ZI)) + NN = N + DFNU = FNU + float64(float32(N-1)) + if AZ <= 2.0E0 { + goto Ten + } + if AZ*AZ*0.25 > DFNU+1.0E0 { + goto Twenty + } +Ten: + // POWER SERIES FOR THE I FUNCTION. + ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL, ELIM, ALIM = zseriOrig(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL, ELIM, ALIM) + goto Forty +Twenty: + if AZ < RL { + goto Thirty + } + // ASYMPTOTIC EXPANSION FOR LARGE Z FOR THE I FUNCTION. + ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM, ALIM = zasyiOrig(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, RL, TOL, ELIM, ALIM) + if NW < 0 { + goto Eighty + } + goto Forty +Thirty: + // MILLER ALGORITHM NORMALIZED BY THE SERIES FOR THE I FUNCTION + ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL = zmlriOrig(ZNR, ZNI, FNU, KODE, NN, YR, YI, NW, TOL) + if NW < 0 { + goto Eighty + } +Forty: + // ANALYTIC CONTINUATION TO THE LEFT HALF PLANE FOR THE K FUNCTION. + ZNR, ZNI, FNU, KODE, _, CYR, CYI, NW, TOL, ELIM, ALIM = zbknuOrig(ZNR, ZNI, FNU, KODE, 1, CYR, CYI, NW, TOL, ELIM, ALIM) + if NW != 0 { + goto Eighty + } + FMR = float64(float32(MR)) + SGN = -math.Copysign(PI, FMR) + CSGNR = 0.0E0 + CSGNI = SGN + if KODE == 1 { + goto Fifty + } + YY = -ZNI + CSGNR = -CSGNI * dsin(YY) + CSGNI = CSGNI * dcos(YY) +Fifty: + // CALCULATE CSPN=EXP(FNU*PI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE + // WHEN FNU IS LARGE + INU = int(float32(FNU)) + ARG = (FNU - float64(float32(INU))) * SGN + CSPNR = dcos(ARG) + CSPNI = dsin(ARG) + if INU%2 == 0 { + goto Sixty + } + CSPNR = -CSPNR + CSPNI = -CSPNI +Sixty: + C1R = CYR[1] + C1I = CYI[1] + C2R = YR[1] + C2I = YI[1] + if KODE == 1 { + goto Seventy + } + IUF = 0 + ASCLE = 1.0E+3 * dmach[1] / TOL + ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF = zs1s2Orig(ZNR, ZNI, C1R, C1I, C2R, C2I, NW, ASCLE, ALIM, IUF) + NZ = NZ + NW +Seventy: + YR[1] = CSPNR*C1R - CSPNI*C1I + CSGNR*C2R - CSGNI*C2I + YI[1] = CSPNR*C1I + CSPNI*C1R + CSGNR*C2I + CSGNI*C2R + return ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +Eighty: + NZ = -1 + if NW == -2 { + NZ = -2 + } + return ZR, ZI, FNU, KODE, MR, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +} + +// ZASYI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z)>=0.0 BY +// MEANS OF THE ASYMPTOTIC EXPANSION FOR LARGE CABS(Z) IN THE +// REGION CABS(Z)>MAX(RL,FNU*FNU/2). NZ=0 IS A NORMAL return. +// NZ<0 INDICATES AN OVERFLOW ON KODE=1. +func zasyiOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, RL, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, RLout, TOLout, ELIMout, ALIMout float64) { + var AA, AEZ, AK, AK1I, AK1R, ARG, ARM, ATOL, + AZ, BB, BK, CKI, CKR, CONEI, CONER, CS1I, CS1R, CS2I, CS2R, CZI, + CZR, DFNU, DKI, DKR, DNU2, EZI, EZR, FDN, PI, P1I, + P1R, RAZ, RTPI, RTR1, RZI, RZR, S, SGN, SQK, STI, STR, S2I, + S2R, TZI, TZR, ZEROI, ZEROR float64 + + var I, IB, IL, INU, J, JL, K, KODED, M, NN int + var tmp complex128 + + PI = math.Pi + RTPI = 0.159154943091895336E0 + ZEROR = 0 + ZEROI = 0 + CONER = 1 + CONEI = 0 + + NZ = 0 + AZ = zabs(complex(ZR, ZI)) + ARM = 1.0E3 * dmach[1] + RTR1 = dsqrt(ARM) + IL = min0(2, N) + DFNU = FNU + float64(float32(N-IL)) + + // OVERFLOW TEST + RAZ = 1.0E0 / AZ + STR = ZR * RAZ + STI = -ZI * RAZ + AK1R = RTPI * STR * RAZ + AK1I = RTPI * STI * RAZ + tmp = zsqrt(complex(AK1R, AK1I)) + AK1R = real(tmp) + AK1I = imag(tmp) + CZR = ZR + CZI = ZI + if KODE != 2 { + goto Ten + } + CZR = ZEROR + CZI = ZI +Ten: + if dabs(CZR) > ELIM { + goto OneHundred + } + DNU2 = DFNU + DFNU + KODED = 1 + if (dabs(CZR) > ALIM) && (N > 2) { + goto Twenty + } + KODED = 0 + tmp = zexp(complex(CZR, CZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = zmlt(complex(AK1R, AK1I), complex(STR, STI)) + AK1R = real(tmp) + AK1I = imag(tmp) +Twenty: + FDN = 0.0E0 + if DNU2 > RTR1 { + FDN = DNU2 * DNU2 + } + EZR = ZR * 8.0E0 + EZI = ZI * 8.0E0 + + // WHEN Z IS IMAGINARY, THE ERROR TEST MUST BE MADE RELATIVE TO THE + // FIRST RECIPROCAL POWER SINCE THIS IS THE LEADING TERM OF THE + // EXPANSION FOR THE IMAGINARY PART. + AEZ = 8.0E0 * AZ + S = TOL / AEZ + JL = int(float32(RL+RL)) + 2 + P1R = ZEROR + P1I = ZEROI + if ZI == 0.0E0 { + goto Thirty + } + + // CALCULATE EXP(PI*(0.5+FNU+N-IL)*I) TO MINIMIZE LOSSES OF + // SIGNIFICANCE WHEN FNU OR N IS LARGE + INU = int(float32(FNU)) + ARG = (FNU - float64(float32(INU))) * PI + INU = INU + N - IL + AK = -dsin(ARG) + BK = dcos(ARG) + if ZI < 0.0E0 { + BK = -BK + } + P1R = AK + P1I = BK + if INU%2 == 0 { + goto Thirty + } + P1R = -P1R + P1I = -P1I +Thirty: + for K = 1; K <= IL; K++ { + SQK = FDN - 1.0E0 + ATOL = S * dabs(SQK) + SGN = 1.0E0 + CS1R = CONER + CS1I = CONEI + CS2R = CONER + CS2I = CONEI + CKR = CONER + CKI = CONEI + AK = 0.0E0 + AA = 1.0E0 + BB = AEZ + DKR = EZR + DKI = EZI + // TODO(btracey): This loop is executed tens of thousands of times. Why? + // is that really necessary? + for J = 1; J <= JL; J++ { + tmp = zdiv(complex(CKR, CKI), complex(DKR, DKI)) + STR = real(tmp) + STI = imag(tmp) + CKR = STR * SQK + CKI = STI * SQK + CS2R = CS2R + CKR + CS2I = CS2I + CKI + SGN = -SGN + CS1R = CS1R + CKR*SGN + CS1I = CS1I + CKI*SGN + DKR = DKR + EZR + DKI = DKI + EZI + AA = AA * dabs(SQK) / BB + BB = BB + AEZ + AK = AK + 8.0E0 + SQK = SQK - AK + if AA <= ATOL { + goto Fifty + } + } + goto OneTen + Fifty: + S2R = CS1R + S2I = CS1I + if ZR+ZR >= ELIM { + goto Sixty + } + TZR = ZR + ZR + TZI = ZI + ZI + tmp = zexp(complex(-TZR, -TZI)) + STR = real(tmp) + STI = imag(tmp) + tmp = zmlt(complex(STR, STI), complex(P1R, P1I)) + STR = real(tmp) + STI = imag(tmp) + tmp = zmlt(complex(STR, STI), complex(CS2R, CS2I)) + STR = real(tmp) + STI = imag(tmp) + S2R = S2R + STR + S2I = S2I + STI + Sixty: + FDN = FDN + 8.0E0*DFNU + 4.0E0 + P1R = -P1R + P1I = -P1I + M = N - IL + K + YR[M] = S2R*AK1R - S2I*AK1I + YI[M] = S2R*AK1I + S2I*AK1R + } + if N <= 2 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM + } + NN = N + K = NN - 2 + AK = float64(float32(K)) + STR = ZR * RAZ + STI = -ZI * RAZ + RZR = (STR + STR) * RAZ + RZI = (STI + STI) * RAZ + IB = 3 + for I = IB; I <= NN; I++ { + YR[K] = (AK+FNU)*(RZR*YR[K+1]-RZI*YI[K+1]) + YR[K+2] + YI[K] = (AK+FNU)*(RZR*YI[K+1]+RZI*YR[K+1]) + YI[K+2] + AK = AK - 1.0E0 + K = K - 1 + } + if KODED == 0 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM + } + tmp = zexp(complex(CZR, CZI)) + CKR = real(tmp) + CKI = imag(tmp) + for I = 1; I <= NN; I++ { + STR = YR[I]*CKR - YI[I]*CKI + YI[I] = YR[I]*CKI + YI[I]*CKR + YR[I] = STR + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +OneHundred: + NZ = -1 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +OneTen: + NZ = -2 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, RL, TOL, ELIM, ALIM +} + +// ZMLRI COMPUTES THE I BESSEL FUNCTION FOR RE(Z)>=0.0 BY THE +// MILLER ALGORITHM NORMALIZED BY A NEUMANN SERIES. +func zmlriOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout float64) { + var ACK, AK, AP, AT, AZ, BK, CKI, CKR, CNORMI, + CNORMR, CONEI, CONER, FKAP, FKK, FLAM, FNF, PTI, PTR, P1I, + P1R, P2I, P2R, RAZ, RHO, RHO2, RZI, RZR, SCLE, STI, STR, SUMI, + SUMR, TFNF, TST, ZEROI, ZEROR float64 + var I, IAZ, IDUM, IFNU, INU, ITIME, K, KK, KM, M int + var tmp complex128 + ZEROR = 0 + ZEROI = 0 + CONER = 1 + CONEI = 0 + + SCLE = dmach[1] / TOL + NZ = 0 + AZ = zabs(complex(ZR, ZI)) + IAZ = int(float32(AZ)) + IFNU = int(float32(FNU)) + INU = IFNU + N - 1 + AT = float64(float32(IAZ)) + 1.0E0 + RAZ = 1.0E0 / AZ + STR = ZR * RAZ + STI = -ZI * RAZ + CKR = STR * AT * RAZ + CKI = STI * AT * RAZ + RZR = (STR + STR) * RAZ + RZI = (STI + STI) * RAZ + P1R = ZEROR + P1I = ZEROI + P2R = CONER + P2I = CONEI + ACK = (AT + 1.0E0) * RAZ + RHO = ACK + dsqrt(ACK*ACK-1.0E0) + RHO2 = RHO * RHO + TST = (RHO2 + RHO2) / ((RHO2 - 1.0E0) * (RHO - 1.0E0)) + TST = TST / TOL + + // COMPUTE RELATIVE TRUNCATION ERROR INDEX FOR SERIES. + //fmt.Println("before loop", P2R, P2I, CKR, CKI, RZR, RZI, TST, AK) + AK = AT + for I = 1; I <= 80; I++ { + PTR = P2R + PTI = P2I + P2R = P1R - (CKR*PTR - CKI*PTI) + P2I = P1I - (CKI*PTR + CKR*PTI) + P1R = PTR + P1I = PTI + CKR = CKR + RZR + CKI = CKI + RZI + AP = zabs(complex(P2R, P2I)) + if AP > TST*AK*AK { + goto Twenty + } + AK = AK + 1.0E0 + } + goto OneTen +Twenty: + I = I + 1 + K = 0 + if INU < IAZ { + goto Forty + } + // COMPUTE RELATIVE TRUNCATION ERROR FOR RATIOS. + P1R = ZEROR + P1I = ZEROI + P2R = CONER + P2I = CONEI + AT = float64(float32(INU)) + 1.0E0 + STR = ZR * RAZ + STI = -ZI * RAZ + CKR = STR * AT * RAZ + CKI = STI * AT * RAZ + ACK = AT * RAZ + TST = dsqrt(ACK / TOL) + ITIME = 1 + for K = 1; K <= 80; K++ { + PTR = P2R + PTI = P2I + P2R = P1R - (CKR*PTR - CKI*PTI) + P2I = P1I - (CKR*PTI + CKI*PTR) + P1R = PTR + P1I = PTI + CKR = CKR + RZR + CKI = CKI + RZI + AP = zabs(complex(P2R, P2I)) + if AP < TST { + continue + } + if ITIME == 2 { + goto Forty + } + ACK = zabs(complex(CKR, CKI)) + FLAM = ACK + dsqrt(ACK*ACK-1.0E0) + FKAP = AP / zabs(complex(P1R, P1I)) + RHO = dmin(FLAM, FKAP) + TST = TST * dsqrt(RHO/(RHO*RHO-1.0E0)) + ITIME = 2 + } + goto OneTen +Forty: + // BACKWARD RECURRENCE AND SUM NORMALIZING RELATION. + K = K + 1 + KK = max0(I+IAZ, K+INU) + FKK = float64(float32(KK)) + P1R = ZEROR + P1I = ZEROI + + // SCALE P2 AND SUM BY SCLE. + P2R = SCLE + P2I = ZEROI + FNF = FNU - float64(float32(IFNU)) + TFNF = FNF + FNF + BK = dgamln(FKK+TFNF+1.0E0, IDUM) - dgamln(FKK+1.0E0, IDUM) - dgamln(TFNF+1.0E0, IDUM) + BK = dexp(BK) + SUMR = ZEROR + SUMI = ZEROI + KM = KK - INU + for I = 1; I <= KM; I++ { + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) + P1R = PTR + P1I = PTI + AK = 1.0E0 - TFNF/(FKK+TFNF) + ACK = BK * AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0E0 + } + YR[N] = P2R + YI[N] = P2I + if N == 1 { + goto Seventy + } + for I = 2; I <= N; I++ { + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZI*PTR+RZR*PTI) + P1R = PTR + P1I = PTI + AK = 1.0E0 - TFNF/(FKK+TFNF) + ACK = BK * AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0E0 + M = N - I + 1 + YR[M] = P2R + YI[M] = P2I + } +Seventy: + if IFNU <= 0 { + goto Ninety + } + for I = 1; I <= IFNU; I++ { + PTR = P2R + PTI = P2I + P2R = P1R + (FKK+FNF)*(RZR*PTR-RZI*PTI) + P2I = P1I + (FKK+FNF)*(RZR*PTI+RZI*PTR) + P1R = PTR + P1I = PTI + AK = 1.0E0 - TFNF/(FKK+TFNF) + ACK = BK * AK + SUMR = SUMR + (ACK+BK)*P1R + SUMI = SUMI + (ACK+BK)*P1I + BK = ACK + FKK = FKK - 1.0E0 + } +Ninety: + PTR = ZR + PTI = ZI + if KODE == 2 { + PTR = ZEROR + } + tmp = zlog(complex(RZR, RZI)) + STR = real(tmp) + STI = imag(tmp) + P1R = -FNF*STR + PTR + P1I = -FNF*STI + PTI + AP = dgamln(1.0E0+FNF, IDUM) + PTR = P1R - AP + PTI = P1I + + // THE DIVISION CEXP(PT)/(SUM+P2) IS ALTERED TO AVOID OVERFLOW + // IN THE DENOMINATOR BY SQUARING LARGE QUANTITIES. + P2R = P2R + SUMR + P2I = P2I + SUMI + AP = zabs(complex(P2R, P2I)) + P1R = 1.0E0 / AP + tmp = zexp(complex(PTR, PTI)) + STR = real(tmp) + STI = imag(tmp) + CKR = STR * P1R + CKI = STI * P1R + PTR = P2R * P1R + PTI = -P2I * P1R + tmp = zmlt(complex(CKR, CKI), complex(PTR, PTI)) + CNORMR = real(tmp) + CNORMI = imag(tmp) + for I = 1; I <= N; I++ { + STR = YR[I]*CNORMR - YI[I]*CNORMI + YI[I] = YR[I]*CNORMI + YI[I]*CNORMR + YR[I] = STR + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL +OneTen: + NZ = -2 + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL +} + +// ZSERI COMPUTES THE I BESSEL FUNCTION FOR REAL(Z)>=0.0 BY +// MEANS OF THE POWER SERIES FOR LARGE CABS(Z) IN THE +// REGION CABS(Z)<=2*SQRT(FNU+1). NZ=0 IS A NORMAL return. +// NZ>0 MEANS THAT THE LAST NZ COMPONENTS WERE SET TO ZERO +// DUE TO UNDERFLOW. NZ<0 MEANS UNDERFLOW OCCURRED, BUT THE +// CONDITION CABS(Z)<=2*SQRT(FNU+1) WAS VIOLATED AND THE +// COMPUTATION MUST BE COMPLETED IN ANOTHER ROUTINE WITH N=N-ABS(NZ). +func zseriOrig(ZR, ZI, FNU float64, KODE, N int, YR, YI []float64, NZ int, TOL, ELIM, ALIM float64) ( + ZRout, ZIout, FNUout float64, KODEout, Nout int, YRout, YIout []float64, NZout int, TOLout, ELIMout, ALIMout float64) { + var AA, ACZ, AK, AK1I, AK1R, ARM, ASCLE, ATOL, + AZ, CKI, CKR, COEFI, COEFR, CONEI, CONER, CRSCR, CZI, CZR, DFNU, + FNUP, HZI, HZR, RAZ, RS, RTR1, RZI, RZR, S, SS, STI, + STR, S1I, S1R, S2I, S2R, ZEROI, ZEROR float64 + var I, IB, IDUM, IFLAG, IL, K, L, M, NN, NW int + var WR, WI [3]float64 + var tmp complex128 + + CONER = 1.0 + NZ = 0 + AZ = zabs(complex(ZR, ZI)) + if AZ == 0.0E0 { + goto OneSixty + } + // TODO(btracey) + // The original fortran line is "ARM = 1.0D+3*D1MACH(1)". Evidently, in Fortran + // this is interpreted as one to the power of +3*D1MACH(1). While it is possible + // this was intentional, it seems unlikely. + //ARM = 1.0E0 + 3*dmach[1] + //math.Pow(1, 3*dmach[1]) + ARM = 1000 * dmach[1] + RTR1 = dsqrt(ARM) + CRSCR = 1.0E0 + IFLAG = 0 + if AZ < ARM { + goto OneFifty + } + HZR = 0.5E0 * ZR + HZI = 0.5E0 * ZI + CZR = ZEROR + CZI = ZEROI + if AZ <= RTR1 { + goto Ten + } + tmp = zmlt(complex(HZR, HZI), complex(HZR, HZI)) + CZR = real(tmp) + CZI = imag(tmp) +Ten: + ACZ = zabs(complex(CZR, CZI)) + NN = N + tmp = zlog(complex(HZR, HZI)) + CKR = real(tmp) + CKI = imag(tmp) +Twenty: + DFNU = FNU + float64(float32(NN-1)) + FNUP = DFNU + 1.0E0 + + // UNDERFLOW TEST. + AK1R = CKR * DFNU + AK1I = CKI * DFNU + AK = dgamln(FNUP, IDUM) + AK1R = AK1R - AK + if KODE == 2 { + AK1R = AK1R - ZR + } + if AK1R > (-ELIM) { + goto Forty + } +Thirty: + NZ = NZ + 1 + YR[NN] = ZEROR + YI[NN] = ZEROI + if ACZ > DFNU { + goto OneNinety + } + NN = NN - 1 + if NN == 0 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + goto Twenty +Forty: + if AK1R > (-ALIM) { + goto Fifty + } + IFLAG = 1 + SS = 1.0E0 / TOL + CRSCR = TOL + ASCLE = ARM * SS +Fifty: + AA = dexp(AK1R) + if IFLAG == 1 { + AA = AA * SS + } + COEFR = AA * dcos(AK1I) + COEFI = AA * dsin(AK1I) + ATOL = TOL * ACZ / FNUP + IL = min0(2, NN) + for I = 1; I <= IL; I++ { + DFNU = FNU + float64(float32(NN-I)) + FNUP = DFNU + 1.0E0 + S1R = CONER + S1I = CONEI + if ACZ < TOL*FNUP { + goto Seventy + } + AK1R = CONER + AK1I = CONEI + AK = FNUP + 2.0E0 + S = FNUP + AA = 2.0E0 + Sixty: + RS = 1.0E0 / S + STR = AK1R*CZR - AK1I*CZI + STI = AK1R*CZI + AK1I*CZR + AK1R = STR * RS + AK1I = STI * RS + S1R = S1R + AK1R + S1I = S1I + AK1I + S = S + AK + AK = AK + 2.0E0 + AA = AA * ACZ * RS + if AA > ATOL { + goto Sixty + } + Seventy: + S2R = S1R*COEFR - S1I*COEFI + S2I = S1R*COEFI + S1I*COEFR + WR[I] = S2R + WI[I] = S2I + if IFLAG == 0 { + goto Eighty + } + S2R, S2I, NW, ASCLE, TOL = zuchkOrig(S2R, S2I, NW, ASCLE, TOL) + if NW != 0 { + goto Thirty + } + Eighty: + M = NN - I + 1 + YR[M] = S2R * CRSCR + YI[M] = S2I * CRSCR + if I == IL { + continue + } + tmp = zdiv(complex(COEFR, COEFI), complex(HZR, HZI)) + STR = real(tmp) + STI = imag(tmp) + COEFR = STR * DFNU + COEFI = STI * DFNU + } + if NN <= 2 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + K = NN - 2 + AK = float64(float32(K)) + RAZ = 1.0E0 / AZ + STR = ZR * RAZ + STI = -ZI * RAZ + RZR = (STR + STR) * RAZ + RZI = (STI + STI) * RAZ + if IFLAG == 1 { + goto OneTwenty + } + IB = 3 +OneHundred: + for I = IB; I <= NN; I++ { + YR[K] = (AK+FNU)*(RZR*YR[K+1]-RZI*YI[K+1]) + YR[K+2] + YI[K] = (AK+FNU)*(RZR*YI[K+1]+RZI*YR[K+1]) + YI[K+2] + AK = AK - 1.0E0 + K = K - 1 + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + + // RECUR BACKWARD WITH SCALED VALUES. +OneTwenty: + // EXP(-ALIM)=EXP(-ELIM)/TOL=APPROX. ONE PRECISION ABOVE THE + // UNDERFLOW LIMIT = ASCLE = dmach[1)*SS*1.0D+3. + S1R = WR[1] + S1I = WI[1] + S2R = WR[2] + S2I = WI[2] + for L = 3; L <= NN; L++ { + CKR = S2R + CKI = S2I + S2R = S1R + (AK+FNU)*(RZR*CKR-RZI*CKI) + S2I = S1I + (AK+FNU)*(RZR*CKI+RZI*CKR) + S1R = CKR + S1I = CKI + CKR = S2R * CRSCR + CKI = S2I * CRSCR + YR[K] = CKR + YI[K] = CKI + AK = AK - 1.0E0 + K = K - 1 + if zabs(complex(CKR, CKI)) > ASCLE { + goto OneFourty + } + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM +OneFourty: + IB = L + 1 + if IB > NN { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + goto OneHundred +OneFifty: + NZ = N + if FNU == 0.0E0 { + NZ = NZ - 1 + } +OneSixty: + YR[1] = ZEROR + YI[1] = ZEROI + if FNU != 0.0E0 { + goto OneSeventy + } + YR[1] = CONER + YI[1] = CONEI +OneSeventy: + if N == 1 { + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + } + for I = 2; I <= N; I++ { + YR[I] = ZEROR + YI[I] = ZEROI + } + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM + + // return WITH NZ<0 if CABS(Z*Z/4)>FNU+N-NZ-1 COMPLETE + // THE CALCULATION IN CBINU WITH N=N-IABS(NZ) + +OneNinety: + NZ = -NZ + return ZR, ZI, FNU, KODE, N, YR, YI, NZ, TOL, ELIM, ALIM +} + +// ZS1S2 TESTS FOR A POSSIBLE UNDERFLOW RESULTING FROM THE +// ADDITION OF THE I AND K FUNCTIONS IN THE ANALYTIC CON- +// TINUATION FORMULA WHERE S1=K FUNCTION AND S2=I FUNCTION. +// ON KODE=1 THE I AND K FUNCTIONS ARE DIFFERENT ORDERS OF +// MAGNITUDE, BUT FOR KODE=2 THEY CAN BE OF THE SAME ORDER +// OF MAGNITUDE AND THE MAXIMUM MUST BE AT LEAST ONE +// PRECISION ABOVE THE UNDERFLOW LIMIT. +func zs1s2Orig(ZRR, ZRI, S1R, S1I, S2R, S2I float64, NZ int, ASCLE, ALIM float64, IUF int) ( + ZRRout, ZRIout, S1Rout, S1Iout, S2Rout, S2Iout float64, NZout int, ASCLEout, ALIMout float64, IUFout int) { + var AA, ALN, AS1, AS2, C1I, C1R, S1DI, S1DR, ZEROI, ZEROR float64 + var tmp complex128 + + ZEROR = 0 + ZEROI = 0 + NZ = 0 + AS1 = zabs(complex(S1R, S1I)) + AS2 = zabs(complex(S2R, S2I)) + if S1R == 0.0E0 && S1I == 0.0E0 { + goto Ten + } + if AS1 == 0.0E0 { + goto Ten + } + ALN = -ZRR - ZRR + dlog(AS1) + S1DR = S1R + S1DI = S1I + S1R = ZEROR + S1I = ZEROI + AS1 = ZEROR + if ALN < (-ALIM) { + goto Ten + } + tmp = zlog(complex(S1DR, S1DI)) + C1R = real(tmp) + C1I = imag(tmp) + + C1R = C1R - ZRR - ZRR + C1I = C1I - ZRI - ZRI + tmp = zexp(complex(C1R, C1I)) + S1R = real(tmp) + S1I = imag(tmp) + AS1 = zabs(complex(S1R, S1I)) + IUF = IUF + 1 +Ten: + AA = dmax(AS1, AS2) + if AA > ASCLE { + return ZRR, ZRI, S1R, S1I, S2R, S2I, NZ, ASCLE, ALIM, IUF + } + S1R = ZEROR + S1I = ZEROI + S2R = ZEROR + S2I = ZEROI + NZ = 1 + IUF = 0 + return ZRR, ZRI, S1R, S1I, S2R, S2I, NZ, ASCLE, ALIM, IUF +} + +// ZSHCH COMPUTES THE COMPLEX HYPERBOLIC FUNCTIONS CSH=SINH(X+iY) AND +// CCH=COSH(X+I*Y), WHERE I**2=-1. +// TODO(btracey): use cmplx.Sinh and cmplx.Cosh. +func zshchOrig(ZR, ZI, CSHR, CSHI, CCHR, CCHI float64) (ZRout, ZIout, CSHRout, CSHIout, CCHRout, CCHIout float64) { + var CH, CN, SH, SN float64 + SH = math.Sinh(ZR) + CH = math.Cosh(ZR) + SN = dsin(ZI) + CN = dcos(ZI) + CSHR = SH * CN + CSHI = CH * SN + CCHR = CH * CN + CCHI = SH * SN + return ZR, ZI, CSHR, CSHI, CCHR, CCHI +} + +func dmax(a, b float64) float64 { + return math.Max(a, b) +} + +func dmin(a, b float64) float64 { + return math.Min(a, b) +} + +func dabs(a float64) float64 { + return math.Abs(a) +} + +func datan(a float64) float64 { + return math.Atan(a) +} + +func dtan(a float64) float64 { + return math.Tan(a) +} + +func dlog(a float64) float64 { + return math.Log(a) +} + +func dsin(a float64) float64 { + return math.Sin(a) +} + +func dcos(a float64) float64 { + return math.Cos(a) +} + +func dexp(a float64) float64 { + return math.Exp(a) +} + +func dsqrt(a float64) float64 { + return math.Sqrt(a) +} + +func zmlt(a, b complex128) complex128 { + return a * b +} + +func zdiv(a, b complex128) complex128 { + return a / b +} + +func zabs(a complex128) float64 { + return cmplx.Abs(a) +} + +func zsqrt(a complex128) complex128 { + return cmplx.Sqrt(a) +} + +func zexp(a complex128) complex128 { + return cmplx.Exp(a) +} + +func zlog(a complex128) complex128 { + return cmplx.Log(a) +} + +// Zshch computes the hyperbolic sin and cosine of the input z. +func Zshch(z complex128) (sinh, cosh complex128) { + return cmplx.Sinh(z), cmplx.Cosh(z) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/cephes.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/cephes.go new file mode 100644 index 00000000..22d26e87 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/cephes.go @@ -0,0 +1,28 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package cephes + +import "math" + +/* +Additional copyright information: + +Code in this package is adapted from the Cephes library (http://www.netlib.org/cephes/). +There is no explicit licence on Netlib, but the author has agreed to a BSD release. +See https://github.com/deepmind/torch-cephes/blob/master/LICENSE.txt and +https://lists.debian.org/debian-legal/2004/12/msg00295.html +*/ + +var ( + badParamOutOfBounds = "cephes: parameter out of bounds" + badParamFunctionSingularity = "cephes: function singularity" +) + +const ( + machEp = 1.0 / (1 << 53) + maxLog = 1024 * math.Ln2 + minLog = -1075 * math.Ln2 + maxIter = 2000 +) diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/doc.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/doc.go new file mode 100644 index 00000000..4fe18ba6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package cephes implements functions originally in the Netlib code by Stephen Mosher. +package cephes // import "gonum.org/v1/gonum/mathext/internal/cephes" diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/igam.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/igam.go new file mode 100644 index 00000000..0a9732e5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/igam.go @@ -0,0 +1,311 @@ +// Derived from SciPy's special/cephes/igam.c and special/cephes/igam.h +// https://github.com/scipy/scipy/blob/master/scipy/special/cephes/igam.c +// https://github.com/scipy/scipy/blob/master/scipy/special/cephes/igam.h +// Made freely available by Stephen L. Moshier without support or guarantee. + +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// Copyright ©1985, ©1987 by Stephen L. Moshier +// Portions Copyright ©2016 The gonum Authors. All rights reserved. + +package cephes + +import "math" + +const ( + igamDimK = 25 + igamDimN = 25 + igam = 1 + igamC = 0 + igamSmall = 20 + igamLarge = 200 + igamSmallRatio = 0.3 + igamLargeRatio = 4.5 +) + +var igamCoefs = [igamDimK][igamDimN]float64{ + {-3.3333333333333333e-1, 8.3333333333333333e-2, -1.4814814814814815e-2, 1.1574074074074074e-3, 3.527336860670194e-4, -1.7875514403292181e-4, 3.9192631785224378e-5, -2.1854485106799922e-6, -1.85406221071516e-6, 8.296711340953086e-7, -1.7665952736826079e-7, 6.7078535434014986e-9, 1.0261809784240308e-8, -4.3820360184533532e-9, 9.1476995822367902e-10, -2.551419399494625e-11, -5.8307721325504251e-11, 2.4361948020667416e-11, -5.0276692801141756e-12, 1.1004392031956135e-13, 3.3717632624009854e-13, -1.3923887224181621e-13, 2.8534893807047443e-14, -5.1391118342425726e-16, -1.9752288294349443e-15}, + {-1.8518518518518519e-3, -3.4722222222222222e-3, 2.6455026455026455e-3, -9.9022633744855967e-4, 2.0576131687242798e-4, -4.0187757201646091e-7, -1.8098550334489978e-5, 7.6491609160811101e-6, -1.6120900894563446e-6, 4.6471278028074343e-9, 1.378633446915721e-7, -5.752545603517705e-8, 1.1951628599778147e-8, -1.7543241719747648e-11, -1.0091543710600413e-9, 4.1627929918425826e-10, -8.5639070264929806e-11, 6.0672151016047586e-14, 7.1624989648114854e-12, -2.9331866437714371e-12, 5.9966963656836887e-13, -2.1671786527323314e-16, -4.9783399723692616e-14, 2.0291628823713425e-14, -4.13125571381061e-15}, + {4.1335978835978836e-3, -2.6813271604938272e-3, 7.7160493827160494e-4, 2.0093878600823045e-6, -1.0736653226365161e-4, 5.2923448829120125e-5, -1.2760635188618728e-5, 3.4235787340961381e-8, 1.3721957309062933e-6, -6.298992138380055e-7, 1.4280614206064242e-7, -2.0477098421990866e-10, -1.4092529910867521e-8, 6.228974084922022e-9, -1.3670488396617113e-9, 9.4283561590146782e-13, 1.2872252400089318e-10, -5.5645956134363321e-11, 1.1975935546366981e-11, -4.1689782251838635e-15, -1.0940640427884594e-12, 4.6622399463901357e-13, -9.905105763906906e-14, 1.8931876768373515e-17, 8.8592218725911273e-15}, + {6.4943415637860082e-4, 2.2947209362139918e-4, -4.6918949439525571e-4, 2.6772063206283885e-4, -7.5618016718839764e-5, -2.3965051138672967e-7, 1.1082654115347302e-5, -5.6749528269915966e-6, 1.4230900732435884e-6, -2.7861080291528142e-11, -1.6958404091930277e-7, 8.0994649053880824e-8, -1.9111168485973654e-8, 2.3928620439808118e-12, 2.0620131815488798e-9, -9.4604966618551322e-10, 2.1541049775774908e-10, -1.388823336813903e-14, -2.1894761681963939e-11, 9.7909989511716851e-12, -2.1782191880180962e-12, 6.2088195734079014e-17, 2.126978363279737e-13, -9.3446887915174333e-14, 2.0453671226782849e-14}, + {-8.618882909167117e-4, 7.8403922172006663e-4, -2.9907248030319018e-4, -1.4638452578843418e-6, 6.6414982154651222e-5, -3.9683650471794347e-5, 1.1375726970678419e-5, 2.5074972262375328e-10, -1.6954149536558306e-6, 8.9075075322053097e-7, -2.2929348340008049e-7, 2.956794137544049e-11, 2.8865829742708784e-8, -1.4189739437803219e-8, 3.4463580499464897e-9, -2.3024517174528067e-13, -3.9409233028046405e-10, 1.8602338968504502e-10, -4.356323005056618e-11, 1.2786001016296231e-15, 4.6792750266579195e-12, -2.1492464706134829e-12, 4.9088156148096522e-13, -6.3385914848915603e-18, -5.0453320690800944e-14}, + {-3.3679855336635815e-4, -6.9728137583658578e-5, 2.7727532449593921e-4, -1.9932570516188848e-4, 6.7977804779372078e-5, 1.419062920643967e-7, -1.3594048189768693e-5, 8.0184702563342015e-6, -2.2914811765080952e-6, -3.252473551298454e-10, 3.4652846491085265e-7, -1.8447187191171343e-7, 4.8240967037894181e-8, -1.7989466721743515e-14, -6.3061945000135234e-9, 3.1624176287745679e-9, -7.8409242536974293e-10, 5.1926791652540407e-15, 9.3589442423067836e-11, -4.5134262161632782e-11, 1.0799129993116827e-11, -3.661886712685252e-17, -1.210902069055155e-12, 5.6807435849905643e-13, -1.3249659916340829e-13}, + {5.3130793646399222e-4, -5.9216643735369388e-4, 2.7087820967180448e-4, 7.9023532326603279e-7, -8.1539693675619688e-5, 5.6116827531062497e-5, -1.8329116582843376e-5, -3.0796134506033048e-9, 3.4651553688036091e-6, -2.0291327396058604e-6, 5.7887928631490037e-7, 2.338630673826657e-13, -8.8286007463304835e-8, 4.7435958880408128e-8, -1.2545415020710382e-8, 8.6496488580102925e-14, 1.6846058979264063e-9, -8.5754928235775947e-10, 2.1598224929232125e-10, -7.6132305204761539e-16, -2.6639822008536144e-11, 1.3065700536611057e-11, -3.1799163902367977e-12, 4.7109761213674315e-18, 3.6902800842763467e-13}, + {3.4436760689237767e-4, 5.1717909082605922e-5, -3.3493161081142236e-4, 2.812695154763237e-4, -1.0976582244684731e-4, -1.2741009095484485e-7, 2.7744451511563644e-5, -1.8263488805711333e-5, 5.7876949497350524e-6, 4.9387589339362704e-10, -1.0595367014026043e-6, 6.1667143761104075e-7, -1.7562973359060462e-7, -1.2974473287015439e-12, 2.695423606288966e-8, -1.4578352908731271e-8, 3.887645959386175e-9, -3.8810022510194121e-17, -5.3279941738772867e-10, 2.7437977643314845e-10, -6.9957960920705679e-11, 2.5899863874868481e-17, 8.8566890996696381e-12, -4.403168815871311e-12, 1.0865561947091654e-12}, + {-6.5262391859530942e-4, 8.3949872067208728e-4, -4.3829709854172101e-4, -6.969091458420552e-7, 1.6644846642067548e-4, -1.2783517679769219e-4, 4.6299532636913043e-5, 4.5579098679227077e-9, -1.0595271125805195e-5, 6.7833429048651666e-6, -2.1075476666258804e-6, -1.7213731432817145e-11, 3.7735877416110979e-7, -2.1867506700122867e-7, 6.2202288040189269e-8, 6.5977038267330006e-16, -9.5903864974256858e-9, 5.2132144922808078e-9, -1.3991589583935709e-9, 5.382058999060575e-16, 1.9484714275467745e-10, -1.0127287556389682e-10, 2.6077347197254926e-11, -5.0904186999932993e-18, -3.3721464474854592e-12}, + {-5.9676129019274625e-4, -7.2048954160200106e-5, 6.7823088376673284e-4, -6.4014752602627585e-4, 2.7750107634328704e-4, 1.8197008380465151e-7, -8.4795071170685032e-5, 6.105192082501531e-5, -2.1073920183404862e-5, -8.8585890141255994e-10, 4.5284535953805377e-6, -2.8427815022504408e-6, 8.7082341778646412e-7, 3.6886101871706965e-12, -1.5344695190702061e-7, 8.862466778790695e-8, -2.5184812301826817e-8, -1.0225912098215092e-14, 3.8969470758154777e-9, -2.1267304792235635e-9, 5.7370135528051385e-10, -1.887749850169741e-19, -8.0931538694657866e-11, 4.2382723283449199e-11, -1.1002224534207726e-11}, + {1.3324454494800656e-3, -1.9144384985654775e-3, 1.1089369134596637e-3, 9.932404122642299e-7, -5.0874501293093199e-4, 4.2735056665392884e-4, -1.6858853767910799e-4, -8.1301893922784998e-9, 4.5284402370562147e-5, -3.127053674781734e-5, 1.044986828530338e-5, 4.8435226265680926e-11, -2.1482565873456258e-6, 1.329369701097492e-6, -4.0295693092101029e-7, -1.7567877666323291e-13, 7.0145043163668257e-8, -4.040787734999483e-8, 1.1474026743371963e-8, 3.9642746853563325e-18, -1.7804938269892714e-9, 9.7480262548731646e-10, -2.6405338676507616e-10, 5.794875163403742e-18, 3.7647749553543836e-11}, + {1.579727660730835e-3, 1.6251626278391582e-4, -2.0633421035543276e-3, 2.1389686185689098e-3, -1.0108559391263003e-3, -3.9912705529919201e-7, 3.6235025084764691e-4, -2.8143901463712154e-4, 1.0449513336495887e-4, 2.1211418491830297e-9, -2.5779417251947842e-5, 1.7281818956040463e-5, -5.6413773872904282e-6, -1.1024320105776174e-11, 1.1223224418895175e-6, -6.8693396379526735e-7, 2.0653236975414887e-7, 4.6714772409838506e-14, -3.5609886164949055e-8, 2.0470855345905963e-8, -5.8091738633283358e-9, -1.332821287582869e-16, 9.0354604391335133e-10, -4.9598782517330834e-10, 1.3481607129399749e-10}, + {-4.0725121195140166e-3, 6.4033628338080698e-3, -4.0410161081676618e-3, -2.183732802866233e-6, 2.1740441801254639e-3, -1.9700440518418892e-3, 8.3595469747962458e-4, 1.9445447567109655e-8, -2.5779387120421696e-4, 1.9009987368139304e-4, -6.7696499937438965e-5, -1.4440629666426572e-10, 1.5712512518742269e-5, -1.0304008744776893e-5, 3.304517767401387e-6, 7.9829760242325709e-13, -6.4097794149313004e-7, 3.8894624761300056e-7, -1.1618347644948869e-7, -2.816808630596451e-15, 1.9878012911297093e-8, -1.1407719956357511e-8, 3.2355857064185555e-9, 4.1759468293455945e-20, -5.0423112718105824e-10}, + {-5.9475779383993003e-3, -5.4016476789260452e-4, 8.7910413550767898e-3, -9.8576315587856125e-3, 5.0134695031021538e-3, 1.2807521786221875e-6, -2.0626019342754683e-3, 1.7109128573523058e-3, -6.7695312714133799e-4, -6.9011545676562133e-9, 1.8855128143995902e-4, -1.3395215663491969e-4, 4.6263183033528039e-5, 4.0034230613321351e-11, -1.0255652921494033e-5, 6.612086372797651e-6, -2.0913022027253008e-6, -2.0951775649603837e-13, 3.9756029041993247e-7, -2.3956211978815887e-7, 7.1182883382145864e-8, 8.925574873053455e-16, -1.2101547235064676e-8, 6.9350618248334386e-9, -1.9661464453856102e-9}, + {1.7402027787522711e-2, -2.9527880945699121e-2, 2.0045875571402799e-2, 7.0289515966903407e-6, -1.2375421071343148e-2, 1.1976293444235254e-2, -5.4156038466518525e-3, -6.3290893396418616e-8, 1.8855118129005065e-3, -1.473473274825001e-3, 5.5515810097708387e-4, 5.2406834412550662e-10, -1.4357913535784836e-4, 9.9181293224943297e-5, -3.3460834749478311e-5, -3.5755837291098993e-12, 7.1560851960630076e-6, -4.5516802628155526e-6, 1.4236576649271475e-6, 1.8803149082089664e-14, -2.6623403898929211e-7, 1.5950642189595716e-7, -4.7187514673841102e-8, -6.5107872958755177e-17, 7.9795091026746235e-9}, + {3.0249124160905891e-2, 2.4817436002649977e-3, -4.9939134373457022e-2, 5.9915643009307869e-2, -3.2483207601623391e-2, -5.7212968652103441e-6, 1.5085251778569354e-2, -1.3261324005088445e-2, 5.5515262632426148e-3, 3.0263182257030016e-8, -1.7229548406756723e-3, 1.2893570099929637e-3, -4.6845138348319876e-4, -1.830259937893045e-10, 1.1449739014822654e-4, -7.7378565221244477e-5, 2.5625836246985201e-5, 1.0766165333192814e-12, -5.3246809282422621e-6, 3.349634863064464e-6, -1.0381253128684018e-6, -5.608909920621128e-15, 1.9150821930676591e-7, -1.1418365800203486e-7, 3.3654425209171788e-8}, + {-9.9051020880159045e-2, 1.7954011706123486e-1, -1.2989606383463778e-1, -3.1478872752284357e-5, 9.0510635276848131e-2, -9.2828824411184397e-2, 4.4412112839877808e-2, 2.7779236316835888e-7, -1.7229543805449697e-2, 1.4182925050891573e-2, -5.6214161633747336e-3, -2.39598509186381e-9, 1.6029634366079908e-3, -1.1606784674435773e-3, 4.1001337768153873e-4, 1.8365800754090661e-11, -9.5844256563655903e-5, 6.3643062337764708e-5, -2.076250624489065e-5, -1.1806020912804483e-13, 4.2131808239120649e-6, -2.6262241337012467e-6, 8.0770620494930662e-7, 6.0125912123632725e-16, -1.4729737374018841e-7}, + {-1.9994542198219728e-1, -1.5056113040026424e-2, 3.6470239469348489e-1, -4.6435192311733545e-1, 2.6640934719197893e-1, 3.4038266027147191e-5, -1.3784338709329624e-1, 1.276467178337056e-1, -5.6213828755200985e-2, -1.753150885483011e-7, 1.9235592956768113e-2, -1.5088821281095315e-2, 5.7401854451350123e-3, 1.0622382710310225e-9, -1.5335082692563998e-3, 1.0819320643228214e-3, -3.7372510193945659e-4, -6.6170909729031985e-12, 8.4263617380909628e-5, -5.5150706827483479e-5, 1.7769536448348069e-5, 3.8827923210205533e-14, -3.53513697488768e-6, 2.1865832130045269e-6, -6.6812849447625594e-7}, + {7.2438608504029431e-1, -1.3918010932653375, 1.0654143352413968, 1.876173868950258e-4, -8.2705501176152696e-1, 8.9352433347828414e-1, -4.4971003995291339e-1, -1.6107401567546652e-6, 1.9235590165271091e-1, -1.6597702160042609e-1, 6.8882222681814333e-2, 1.3910091724608687e-8, -2.146911561508663e-2, 1.6228980898865892e-2, -5.9796016172584256e-3, -1.1287469112826745e-10, 1.5167451119784857e-3, -1.0478634293553899e-3, 3.5539072889126421e-4, 8.1704322111801517e-13, -7.7773013442452395e-5, 5.0291413897007722e-5, -1.6035083867000518e-5, 1.2469354315487605e-14, 3.1369106244517615e-6}, + {1.6668949727276811, 1.165462765994632e-1, -3.3288393225018906, 4.4692325482864037, -2.6977693045875807, -2.600667859891061e-4, 1.5389017615694539, -1.4937962361134612, 6.8881964633233148e-1, 1.3077482004552385e-6, -2.5762963325596288e-1, 2.1097676102125449e-1, -8.3714408359219882e-2, -7.7920428881354753e-9, 2.4267923064833599e-2, -1.7813678334552311e-2, 6.3970330388900056e-3, 4.9430807090480523e-11, -1.5554602758465635e-3, 1.0561196919903214e-3, -3.5277184460472902e-4, 9.3002334645022459e-14, 7.5285855026557172e-5, -4.8186515569156351e-5, 1.5227271505597605e-5}, + {-6.6188298861372935, 1.3397985455142589e+1, -1.0789350606845146e+1, -1.4352254537875018e-3, 9.2333694596189809, -1.0456552819547769e+1, 5.5105526029033471, 1.2024439690716742e-5, -2.5762961164755816, 2.3207442745387179, -1.0045728797216284, -1.0207833290021914e-7, 3.3975092171169466e-1, -2.6720517450757468e-1, 1.0235252851562706e-1, 8.4329730484871625e-10, -2.7998284958442595e-2, 2.0066274144976813e-2, -7.0554368915086242e-3, 1.9402238183698188e-12, 1.6562888105449611e-3, -1.1082898580743683e-3, 3.654545161310169e-4, -5.1290032026971794e-11, -7.6340103696869031e-5}, + {-1.7112706061976095e+1, -1.1208044642899116, 3.7131966511885444e+1, -5.2298271025348962e+1, 3.3058589696624618e+1, 2.4791298976200222e-3, -2.061089403411526e+1, 2.088672775145582e+1, -1.0045703956517752e+1, -1.2238783449063012e-5, 4.0770134274221141, -3.473667358470195, 1.4329352617312006, 7.1359914411879712e-8, -4.4797257159115612e-1, 3.4112666080644461e-1, -1.2699786326594923e-1, -2.8953677269081528e-10, 3.3125776278259863e-2, -2.3274087021036101e-2, 8.0399993503648882e-3, -1.177805216235265e-9, -1.8321624891071668e-3, 1.2108282933588665e-3, -3.9479941246822517e-4}, + {7.389033153567425e+1, -1.5680141270402273e+2, 1.322177542759164e+2, 1.3692876877324546e-2, -1.2366496885920151e+2, 1.4620689391062729e+2, -8.0365587724865346e+1, -1.1259851148881298e-4, 4.0770132196179938e+1, -3.8210340013273034e+1, 1.719522294277362e+1, 9.3519707955168356e-7, -6.2716159907747034, 5.1168999071852637, -2.0319658112299095, -4.9507215582761543e-9, 5.9626397294332597e-1, -4.4220765337238094e-1, 1.6079998700166273e-1, -2.4733786203223402e-8, -4.0307574759979762e-2, 2.7849050747097869e-2, -9.4751858992054221e-3, 6.419922235909132e-6, 2.1250180774699461e-3}, + {2.1216837098382522e+2, 1.3107863022633868e+1, -4.9698285932871748e+2, 7.3121595266969204e+2, -4.8213821720890847e+2, -2.8817248692894889e-2, 3.2616720302947102e+2, -3.4389340280087117e+2, 1.7195193870816232e+2, 1.4038077378096158e-4, -7.52594195897599e+1, 6.651969984520934e+1, -2.8447519748152462e+1, -7.613702615875391e-7, 9.5402237105304373, -7.5175301113311376, 2.8943997568871961, -4.6612194999538201e-7, -8.0615149598794088e-1, 5.8483006570631029e-1, -2.0845408972964956e-1, 1.4765818959305817e-4, 5.1000433863753019e-2, -3.3066252141883665e-2, 1.5109265210467774e-2}, + {-9.8959643098322368e+2, 2.1925555360905233e+3, -1.9283586782723356e+3, -1.5925738122215253e-1, 1.9569985945919857e+3, -2.4072514765081556e+3, 1.3756149959336496e+3, 1.2920735237496668e-3, -7.525941715948055e+2, 7.3171668742208716e+2, -3.4137023466220065e+2, -9.9857390260608043e-6, 1.3356313181291573e+2, -1.1276295161252794e+2, 4.6310396098204458e+1, -7.9237387133614756e-6, -1.4510726927018646e+1, 1.1111771248100563e+1, -4.1690817945270892, 3.1008219800117808e-3, 1.1220095449981468, -7.6052379926149916e-1, 3.6262236505085254e-1, 2.216867741940747e-1, 4.8683443692930507e-1}, +} + +// Igam computes the incomplete Gamma integral. +// Igam(a,x) = (1/ Γ(a)) \int_0^x e^{-t} t^{a-1} dt +// The input argument a must be positive and x must be non-negative or Igam +// will panic. +func Igam(a, x float64) float64 { + // The integral is evaluated by either a power series or continued fraction + // expansion, depending on the relative values of a and x. + // Sources: + // [1] "The Digital Library of Mathematical Functions", dlmf.nist.gov + // [2] Maddock et. al., "Incomplete Gamma Functions", + // http://www.boost.org/doc/libs/1_61_0/libs/math/doc/html/math_toolkit/sf_gamma/igamma.html + + // Check zero integration limit first + if x == 0 { + return 0 + } + + if x < 0 || a <= 0 { + panic(badParamOutOfBounds) + } + + // Asymptotic regime where a ~ x; see [2]. + absxmaA := math.Abs(x-a) / a + if (igamSmall < a && a < igamLarge && absxmaA < igamSmallRatio) || + (igamLarge < a && absxmaA < igamLargeRatio/math.Sqrt(a)) { + return asymptoticSeries(a, x, igam) + } + + if x > 1 && x > a { + return 1 - IgamC(a, x) + } + + return igamSeries(a, x) +} + +// IgamC computes the complemented incomplete Gamma integral. +// IgamC(a,x) = 1 - Igam(a,x) +// = (1/ Γ(a)) \int_0^\infty e^{-t} t^{a-1} dt +// The input argument a must be positive and x must be non-negative or +// IgamC will panic. +func IgamC(a, x float64) float64 { + // The integral is evaluated by either a power series or continued fraction + // expansion, depending on the relative values of a and x. + // Sources: + // [1] "The Digital Library of Mathematical Functions", dlmf.nist.gov + // [2] Maddock et. al., "Incomplete Gamma Functions", + // http://www.boost.org/doc/libs/1_61_0/libs/math/doc/html/math_toolkit/sf_gamma/igamma.html + + switch { + case x < 0, a <= 0: + panic(badParamOutOfBounds) + case x == 0: + return 1 + case math.IsInf(x, 0): + return 0 + } + + // Asymptotic regime where a ~ x; see [2]. + absxmaA := math.Abs(x-a) / a + if (igamSmall < a && a < igamLarge && absxmaA < igamSmallRatio) || + (igamLarge < a && absxmaA < igamLargeRatio/math.Sqrt(a)) { + return asymptoticSeries(a, x, igamC) + } + + // Everywhere else; see [2]. + if x > 1.1 { + if x < a { + return 1 - igamSeries(a, x) + } + return igamCContinuedFraction(a, x) + } else if x <= 0.5 { + if -0.4/math.Log(x) < a { + return 1 - igamSeries(a, x) + } + return igamCSeries(a, x) + } + + if x*1.1 < a { + return 1 - igamSeries(a, x) + } + return igamCSeries(a, x) +} + +// igamFac computes +// x^a * e^{-x} / Γ(a) +// corrected from (15) and (16) in [2] by replacing +// e^{x - a} +// with +// e^{a - x} +func igamFac(a, x float64) float64 { + if math.Abs(a-x) > 0.4*math.Abs(a) { + ax := a*math.Log(x) - x - lgam(a) + return math.Exp(ax) + } + + fac := a + lanczosG - 0.5 + res := math.Sqrt(fac/math.Exp(1)) / lanczosSumExpgScaled(a) + + if a < 200 && x < 200 { + res *= math.Exp(a-x) * math.Pow(x/fac, a) + } else { + num := x - a - lanczosG + 0.5 + res *= math.Exp(a*log1pmx(num/fac) + x*(0.5-lanczosG)/fac) + } + + return res +} + +// igamCContinuedFraction computes IgamC using DLMF 8.9.2. +func igamCContinuedFraction(a, x float64) float64 { + ax := igamFac(a, x) + if ax == 0 { + return 0 + } + + // Continued fraction + y := 1 - a + z := x + y + 1 + c := 0.0 + pkm2 := 1.0 + qkm2 := x + pkm1 := x + 1.0 + qkm1 := z * x + ans := pkm1 / qkm1 + + for i := 0; i < maxIter; i++ { + c += 1.0 + y += 1.0 + z += 2.0 + yc := y * c + pk := pkm1*z - pkm2*yc + qk := qkm1*z - qkm2*yc + var t float64 + if qk != 0 { + r := pk / qk + t = math.Abs((ans - r) / r) + ans = r + } else { + t = 1.0 + } + pkm2 = pkm1 + pkm1 = pk + qkm2 = qkm1 + qkm1 = qk + if math.Abs(pk) > big { + pkm2 *= biginv + pkm1 *= biginv + qkm2 *= biginv + qkm1 *= biginv + } + if t <= machEp { + break + } + } + + return ans * ax +} + +// igamSeries computes Igam using DLMF 8.11.4. +func igamSeries(a, x float64) float64 { + ax := igamFac(a, x) + if ax == 0 { + return 0 + } + + // Power series + r := a + c := 1.0 + ans := 1.0 + + for i := 0; i < maxIter; i++ { + r += 1.0 + c *= x / r + ans += c + if c <= machEp*ans { + break + } + } + + return ans * ax / a +} + +// igamCSeries computes IgamC using DLMF 8.7.3. This is related to the series +// in igamSeries but extra care is taken to avoid cancellation. +func igamCSeries(a, x float64) float64 { + fac := 1.0 + sum := 0.0 + + for n := 1; n < maxIter; n++ { + fac *= -x / float64(n) + term := fac / (a + float64(n)) + sum += term + if math.Abs(term) <= machEp*math.Abs(sum) { + break + } + } + + logx := math.Log(x) + term := -expm1(a*logx - lgam1p(a)) + return term - math.Exp(a*logx-lgam(a))*sum +} + +// asymptoticSeries computes Igam/IgamC using DLMF 8.12.3/8.12.4. +func asymptoticSeries(a, x float64, fun int) float64 { + maxpow := 0 + lambda := x / a + sigma := (x - a) / a + absoldterm := math.MaxFloat64 + etapow := [igamDimN]float64{1} + sum := 0.0 + afac := 1.0 + + var sgn float64 + if fun == igam { + sgn = -1 + } else { + sgn = 1 + } + + var eta float64 + if lambda > 1 { + eta = math.Sqrt(-2 * log1pmx(sigma)) + } else if lambda < 1 { + eta = -math.Sqrt(-2 * log1pmx(sigma)) + } else { + eta = 0 + } + res := 0.5 * math.Erfc(sgn*eta*math.Sqrt(a/2)) + + for k := 0; k < igamDimK; k++ { + ck := igamCoefs[k][0] + for n := 1; n < igamDimN; n++ { + if n > maxpow { + etapow[n] = eta * etapow[n-1] + maxpow++ + } + ckterm := igamCoefs[k][n] * etapow[n] + ck += ckterm + if math.Abs(ckterm) < machEp*math.Abs(ck) { + break + } + } + term := ck * afac + absterm := math.Abs(term) + if absterm > absoldterm { + break + } + sum += term + if absterm < machEp*math.Abs(sum) { + break + } + absoldterm = absterm + afac /= a + } + res += sgn * math.Exp(-0.5*a*eta*eta) * sum / math.Sqrt(2*math.Pi*a) + + return res +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/igami.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/igami.go new file mode 100644 index 00000000..5a8d9a91 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/igami.go @@ -0,0 +1,153 @@ +// Derived from SciPy's special/cephes/igami.c +// https://github.com/scipy/scipy/blob/master/scipy/special/cephes/igami.c +// Made freely available by Stephen L. Moshier without support or guarantee. + +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// Copyright ©1984, ©1987, ©1995 by Stephen L. Moshier +// Portions Copyright ©2017 The gonum Authors. All rights reserved. + +package cephes + +import "math" + +// IgamI computes the inverse of the incomplete Gamma function. That is, it +// returns the x such that: +// IgamC(a, x) = p +// The input argument a must be positive and p must be between 0 and 1 +// inclusive or IgamI will panic. IgamI should return a positive number, but +// can return 0 even with non-zero y due to underflow. +func IgamI(a, p float64) float64 { + // Bound the solution + x0 := math.MaxFloat64 + yl := 0.0 + x1 := 0.0 + yh := 1.0 + dithresh := 5.0 * machEp + + if p < 0 || p > 1 || a <= 0 { + panic(badParamOutOfBounds) + } + + if p == 0 { + return math.Inf(1) + } + + if p == 1 { + return 0.0 + } + + // Starting with the approximate value + // x = a y^3 + // where + // y = 1 - d - ndtri(p) sqrt(d) + // and + // d = 1/9a + // the routine performs up to 10 Newton iterations to find the root of + // IgamC(a, x) - p = 0 + d := 1.0 / (9.0 * a) + y := 1.0 - d - Ndtri(p)*math.Sqrt(d) + x := a * y * y * y + + lgm := lgam(a) + + for i := 0; i < 10; i++ { + if x > x0 || x < x1 { + break + } + + y = IgamC(a, x) + + if y < yl || y > yh { + break + } + + if y < p { + x0 = x + yl = y + } else { + x1 = x + yh = y + } + + // Compute the derivative of the function at this point + d = (a-1)*math.Log(x) - x - lgm + if d < -maxLog { + break + } + d = -math.Exp(d) + + // Compute the step to the next approximation of x + d = (y - p) / d + if math.Abs(d/x) < machEp { + return x + } + x = x - d + } + + d = 0.0625 + if x0 == math.MaxFloat64 { + if x <= 0 { + x = 1 + } + for x0 == math.MaxFloat64 { + x = (1 + d) * x + y = IgamC(a, x) + if y < p { + x0 = x + yl = y + break + } + d = d + d + } + } + + d = 0.5 + dir := 0 + for i := 0; i < 400; i++ { + x = x1 + d*(x0-x1) + y = IgamC(a, x) + + lgm = (x0 - x1) / (x1 + x0) + if math.Abs(lgm) < dithresh { + break + } + + lgm = (y - p) / p + if math.Abs(lgm) < dithresh { + break + } + + if x <= 0 { + break + } + + if y >= p { + x1 = x + yh = y + if dir < 0 { + dir = 0 + d = 0.5 + } else if dir > 1 { + d = 0.5*d + 0.5 + } else { + d = (p - yl) / (yh - yl) + } + dir++ + } else { + x0 = x + yl = y + if dir > 0 { + dir = 0 + d = 0.5 + } else if dir < -1 { + d = 0.5 * d + } else { + d = (p - yl) / (yh - yl) + } + dir-- + } + } + + return x +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/incbeta.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/incbeta.go new file mode 100644 index 00000000..cbe46c47 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/incbeta.go @@ -0,0 +1,312 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* + * Cephes Math Library, Release 2.3: March, 1995 + * Copyright 1984, 1995 by Stephen L. Moshier + */ + +package cephes + +import ( + "math" + + "gonum.org/v1/gonum/mathext/internal/gonum" +) + +const ( + maxGam = 171.624376956302725 + big = 4.503599627370496e15 + biginv = 2.22044604925031308085e-16 +) + +// Incbet computes the regularized incomplete beta function. +func Incbet(aa, bb, xx float64) float64 { + if aa <= 0 || bb <= 0 { + panic(badParamOutOfBounds) + } + if xx <= 0 || xx >= 1 { + if xx == 0 { + return 0 + } + if xx == 1 { + return 1 + } + panic(badParamOutOfBounds) + } + + var flag int + if bb*xx <= 1 && xx <= 0.95 { + t := pseries(aa, bb, xx) + return transformT(t, flag) + } + + w := 1 - xx + + // Reverse a and b if x is greater than the mean. + var a, b, xc, x float64 + if xx > aa/(aa+bb) { + flag = 1 + a = bb + b = aa + xc = xx + x = w + } else { + a = aa + b = bb + xc = w + x = xx + } + + if flag == 1 && (b*x) <= 1.0 && x <= 0.95 { + t := pseries(a, b, x) + return transformT(t, flag) + } + + // Choose expansion for better convergence. + y := x*(a+b-2.0) - (a - 1.0) + if y < 0.0 { + w = incbcf(a, b, x) + } else { + w = incbd(a, b, x) / xc + } + + // Multiply w by the factor + // x^a * (1-x)^b * Γ(a+b) / (a*Γ(a)*Γ(b)) + var t float64 + y = a * math.Log(x) + t = b * math.Log(xc) + if (a+b) < maxGam && math.Abs(y) < maxLog && math.Abs(t) < maxLog { + t = math.Pow(xc, b) + t *= math.Pow(x, a) + t /= a + t *= w + t *= 1.0 / gonum.Beta(a, b) + return transformT(t, flag) + } + + // Resort to logarithms. + y += t - gonum.Lbeta(a, b) + y += math.Log(w / a) + if y < minLog { + t = 0.0 + } else { + t = math.Exp(y) + } + + return transformT(t, flag) +} + +func transformT(t float64, flag int) float64 { + if flag == 1 { + if t <= machEp { + t = 1.0 - machEp + } else { + t = 1.0 - t + } + } + return t +} + +// incbcf returns the incomplete beta integral evaluated by a continued fraction +// expansion. +func incbcf(a, b, x float64) float64 { + var xk, pk, pkm1, pkm2, qk, qkm1, qkm2 float64 + var k1, k2, k3, k4, k5, k6, k7, k8 float64 + var r, t, ans, thresh float64 + var n int + + k1 = a + k2 = a + b + k3 = a + k4 = a + 1.0 + k5 = 1.0 + k6 = b - 1.0 + k7 = k4 + k8 = a + 2.0 + + pkm2 = 0.0 + qkm2 = 1.0 + pkm1 = 1.0 + qkm1 = 1.0 + ans = 1.0 + r = 1.0 + thresh = 3.0 * machEp + + for n = 0; n <= 300; n++ { + + xk = -(x * k1 * k2) / (k3 * k4) + pk = pkm1 + pkm2*xk + qk = qkm1 + qkm2*xk + pkm2 = pkm1 + pkm1 = pk + qkm2 = qkm1 + qkm1 = qk + + xk = (x * k5 * k6) / (k7 * k8) + pk = pkm1 + pkm2*xk + qk = qkm1 + qkm2*xk + pkm2 = pkm1 + pkm1 = pk + qkm2 = qkm1 + qkm1 = qk + + if qk != 0 { + r = pk / qk + } + if r != 0 { + t = math.Abs((ans - r) / r) + ans = r + } else { + t = 1.0 + } + + if t < thresh { + return ans + } + + k1 += 1.0 + k2 += 1.0 + k3 += 2.0 + k4 += 2.0 + k5 += 1.0 + k6 -= 1.0 + k7 += 2.0 + k8 += 2.0 + + if (math.Abs(qk) + math.Abs(pk)) > big { + pkm2 *= biginv + pkm1 *= biginv + qkm2 *= biginv + qkm1 *= biginv + } + if (math.Abs(qk) < biginv) || (math.Abs(pk) < biginv) { + pkm2 *= big + pkm1 *= big + qkm2 *= big + qkm1 *= big + } + } + + return ans +} + +// incbd returns the incomplete beta integral evaluated by a continued fraction +// expansion. +func incbd(a, b, x float64) float64 { + var xk, pk, pkm1, pkm2, qk, qkm1, qkm2 float64 + var k1, k2, k3, k4, k5, k6, k7, k8 float64 + var r, t, ans, z, thresh float64 + var n int + + k1 = a + k2 = b - 1.0 + k3 = a + k4 = a + 1.0 + k5 = 1.0 + k6 = a + b + k7 = a + 1.0 + k8 = a + 2.0 + + pkm2 = 0.0 + qkm2 = 1.0 + pkm1 = 1.0 + qkm1 = 1.0 + z = x / (1.0 - x) + ans = 1.0 + r = 1.0 + thresh = 3.0 * machEp + for n = 0; n <= 300; n++ { + + xk = -(z * k1 * k2) / (k3 * k4) + pk = pkm1 + pkm2*xk + qk = qkm1 + qkm2*xk + pkm2 = pkm1 + pkm1 = pk + qkm2 = qkm1 + qkm1 = qk + + xk = (z * k5 * k6) / (k7 * k8) + pk = pkm1 + pkm2*xk + qk = qkm1 + qkm2*xk + pkm2 = pkm1 + pkm1 = pk + qkm2 = qkm1 + qkm1 = qk + + if qk != 0 { + r = pk / qk + } + if r != 0 { + t = math.Abs((ans - r) / r) + ans = r + } else { + t = 1.0 + } + + if t < thresh { + return ans + } + + k1 += 1.0 + k2 -= 1.0 + k3 += 2.0 + k4 += 2.0 + k5 += 1.0 + k6 += 1.0 + k7 += 2.0 + k8 += 2.0 + + if (math.Abs(qk) + math.Abs(pk)) > big { + pkm2 *= biginv + pkm1 *= biginv + qkm2 *= biginv + qkm1 *= biginv + } + if (math.Abs(qk) < biginv) || (math.Abs(pk) < biginv) { + pkm2 *= big + pkm1 *= big + qkm2 *= big + qkm1 *= big + } + } + return ans +} + +// pseries returns the incomplete beta integral evaluated by a power series. Use +// when b*x is small and x not too close to 1. +func pseries(a, b, x float64) float64 { + var s, t, u, v, n, t1, z, ai float64 + ai = 1.0 / a + u = (1.0 - b) * x + v = u / (a + 1.0) + t1 = v + t = u + n = 2.0 + s = 0.0 + z = machEp * ai + for math.Abs(v) > z { + u = (n - b) * x / n + t *= u + v = t / (a + n) + s += v + n += 1.0 + } + s += t1 + s += ai + + u = a * math.Log(x) + if (a+b) < maxGam && math.Abs(u) < maxLog { + t = 1.0 / gonum.Beta(a, b) + s = s * t * math.Pow(x, a) + } else { + t = -gonum.Lbeta(a, b) + u + math.Log(s) + if t < minLog { + s = 0.0 + } else { + s = math.Exp(t) + } + } + return (s) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/incbi.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/incbi.go new file mode 100644 index 00000000..06037867 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/incbi.go @@ -0,0 +1,248 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* + * Cephes Math Library Release 2.4: March,1996 + * Copyright 1984, 1996 by Stephen L. Moshier + */ + +package cephes + +import "math" + +// Incbi computes the inverse of the regularized incomplete beta integral. +func Incbi(aa, bb, yy0 float64) float64 { + var a, b, y0, d, y, x, x0, x1, lgm, yp, di, dithresh, yl, yh, xt float64 + var i, rflg, dir, nflg int + + i = 0 + if yy0 <= 0 { + return (0.0) + } + if yy0 >= 1.0 { + return (1.0) + } + x0 = 0.0 + yl = 0.0 + x1 = 1.0 + yh = 1.0 + nflg = 0 + + if aa <= 1.0 || bb <= 1.0 { + dithresh = 1.0e-6 + rflg = 0 + a = aa + b = bb + y0 = yy0 + x = a / (a + b) + y = Incbet(a, b, x) + goto ihalve + } else { + dithresh = 1.0e-4 + } + // Approximation to inverse function + yp = -Ndtri(yy0) + + if yy0 > 0.5 { + rflg = 1 + a = bb + b = aa + y0 = 1.0 - yy0 + yp = -yp + } else { + rflg = 0 + a = aa + b = bb + y0 = yy0 + } + + lgm = (yp*yp - 3.0) / 6.0 + x = 2.0 / (1.0/(2.0*a-1.0) + 1.0/(2.0*b-1.0)) + d = yp*math.Sqrt(x+lgm)/x - (1.0/(2.0*b-1.0)-1.0/(2.0*a-1.0))*(lgm+5.0/6.0-2.0/(3.0*x)) + d = 2.0 * d + if d < minLog { + // mtherr("incbi", UNDERFLOW) + x = 0 + goto done + } + x = a / (a + b*math.Exp(d)) + y = Incbet(a, b, x) + yp = (y - y0) / y0 + if math.Abs(yp) < 0.2 { + goto newt + } + + /* Resort to interval halving if not close enough. */ +ihalve: + + dir = 0 + di = 0.5 + for i = 0; i < 100; i++ { + if i != 0 { + x = x0 + di*(x1-x0) + if x == 1.0 { + x = 1.0 - machEp + } + if x == 0.0 { + di = 0.5 + x = x0 + di*(x1-x0) + if x == 0.0 { + // mtherr("incbi", UNDERFLOW) + goto done + } + } + y = Incbet(a, b, x) + yp = (x1 - x0) / (x1 + x0) + if math.Abs(yp) < dithresh { + goto newt + } + yp = (y - y0) / y0 + if math.Abs(yp) < dithresh { + goto newt + } + } + if y < y0 { + x0 = x + yl = y + if dir < 0 { + dir = 0 + di = 0.5 + } else if dir > 3 { + di = 1.0 - (1.0-di)*(1.0-di) + } else if dir > 1 { + di = 0.5*di + 0.5 + } else { + di = (y0 - y) / (yh - yl) + } + dir += 1 + if x0 > 0.75 { + if rflg == 1 { + rflg = 0 + a = aa + b = bb + y0 = yy0 + } else { + rflg = 1 + a = bb + b = aa + y0 = 1.0 - yy0 + } + x = 1.0 - x + y = Incbet(a, b, x) + x0 = 0.0 + yl = 0.0 + x1 = 1.0 + yh = 1.0 + goto ihalve + } + } else { + x1 = x + if rflg == 1 && x1 < machEp { + x = 0.0 + goto done + } + yh = y + if dir > 0 { + dir = 0 + di = 0.5 + } else if dir < -3 { + di = di * di + } else if dir < -1 { + di = 0.5 * di + } else { + di = (y - y0) / (yh - yl) + } + dir -= 1 + } + } + // mtherr("incbi", PLOSS) + if x0 >= 1.0 { + x = 1.0 - machEp + goto done + } + if x <= 0.0 { + // mtherr("incbi", UNDERFLOW) + x = 0.0 + goto done + } + +newt: + if nflg > 0 { + goto done + } + nflg = 1 + lgm = lgam(a+b) - lgam(a) - lgam(b) + + for i = 0; i < 8; i++ { + /* Compute the function at this point. */ + if i != 0 { + y = Incbet(a, b, x) + } + if y < yl { + x = x0 + y = yl + } else if y > yh { + x = x1 + y = yh + } else if y < y0 { + x0 = x + yl = y + } else { + x1 = x + yh = y + } + if x == 1.0 || x == 0.0 { + break + } + /* Compute the derivative of the function at this point. */ + d = (a-1.0)*math.Log(x) + (b-1.0)*math.Log(1.0-x) + lgm + if d < minLog { + goto done + } + if d > maxLog { + break + } + d = math.Exp(d) + /* Compute the step to the next approximation of x. */ + d = (y - y0) / d + xt = x - d + if xt <= x0 { + y = (x - x0) / (x1 - x0) + xt = x0 + 0.5*y*(x-x0) + if xt <= 0.0 { + break + } + } + if xt >= x1 { + y = (x1 - x) / (x1 - x0) + xt = x1 - 0.5*y*(x1-x) + if xt >= 1.0 { + break + } + } + x = xt + if math.Abs(d/x) < 128.0*machEp { + goto done + } + } + /* Did not converge. */ + dithresh = 256.0 * machEp + goto ihalve + +done: + + if rflg > 0 { + if x <= machEp { + x = 1.0 - machEp + } else { + x = 1.0 - x + } + } + return (x) +} + +func lgam(a float64) float64 { + lg, _ := math.Lgamma(a) + return lg +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/lanczos.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/lanczos.go new file mode 100644 index 00000000..c32909b5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/lanczos.go @@ -0,0 +1,153 @@ +// Derived from SciPy's special/cephes/lanczos.c +// https://github.com/scipy/scipy/blob/master/scipy/special/cephes/lanczos.c + +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// Copyright ©2006 John Maddock +// Portions Copyright ©2003 Boost +// Portions Copyright ©2016 The gonum Authors. All rights reserved. + +package cephes + +// Optimal values for G for each N are taken from +// http://web.mala.bc.ca/pughg/phdThesis/phdThesis.pdf, +// as are the theoretical error bounds. + +// Constants calculated using the method described by Godfrey +// http://my.fit.edu/~gabdo/gamma.txt and elaborated by Toth at +// http://www.rskey.org/gamma.htm using NTL::RR at 1000 bit precision. + +var lanczosNum = [...]float64{ + 2.506628274631000270164908177133837338626, + 210.8242777515793458725097339207133627117, + 8071.672002365816210638002902272250613822, + 186056.2653952234950402949897160456992822, + 2876370.628935372441225409051620849613599, + 31426415.58540019438061423162831820536287, + 248874557.8620541565114603864132294232163, + 1439720407.311721673663223072794912393972, + 6039542586.35202800506429164430729792107, + 17921034426.03720969991975575445893111267, + 35711959237.35566804944018545154716670596, + 42919803642.64909876895789904700198885093, + 23531376880.41075968857200767445163675473, +} + +var lanczosDenom = [...]float64{ + 1, + 66, + 1925, + 32670, + 357423, + 2637558, + 13339535, + 45995730, + 105258076, + 150917976, + 120543840, + 39916800, + 0, +} + +var lanczosSumExpgScaledNum = [...]float64{ + 0.006061842346248906525783753964555936883222, + 0.5098416655656676188125178644804694509993, + 19.51992788247617482847860966235652136208, + 449.9445569063168119446858607650988409623, + 6955.999602515376140356310115515198987526, + 75999.29304014542649875303443598909137092, + 601859.6171681098786670226533699352302507, + 3481712.15498064590882071018964774556468, + 14605578.08768506808414169982791359218571, + 43338889.32467613834773723740590533316085, + 86363131.28813859145546927288977868422342, + 103794043.1163445451906271053616070238554, + 56906521.91347156388090791033559122686859, +} + +var lanczosSumExpgScaledDenom = [...]float64{ + 1, + 66, + 1925, + 32670, + 357423, + 2637558, + 13339535, + 45995730, + 105258076, + 150917976, + 120543840, + 39916800, + 0, +} + +var lanczosSumNear1D = [...]float64{ + 0.3394643171893132535170101292240837927725e-9, + -0.2499505151487868335680273909354071938387e-8, + 0.8690926181038057039526127422002498960172e-8, + -0.1933117898880828348692541394841204288047e-7, + 0.3075580174791348492737947340039992829546e-7, + -0.2752907702903126466004207345038327818713e-7, + -0.1515973019871092388943437623825208095123e-5, + 0.004785200610085071473880915854204301886437, + -0.1993758927614728757314233026257810172008, + 1.483082862367253753040442933770164111678, + -3.327150580651624233553677113928873034916, + 2.208709979316623790862569924861841433016, +} + +var lanczosSumNear2D = [...]float64{ + 0.1009141566987569892221439918230042368112e-8, + -0.7430396708998719707642735577238449585822e-8, + 0.2583592566524439230844378948704262291927e-7, + -0.5746670642147041587497159649318454348117e-7, + 0.9142922068165324132060550591210267992072e-7, + -0.8183698410724358930823737982119474130069e-7, + -0.4506604409707170077136555010018549819192e-5, + 0.01422519127192419234315002746252160965831, + -0.5926941084905061794445733628891024027949, + 4.408830289125943377923077727900630927902, + -9.8907772644920670589288081640128194231, + 6.565936202082889535528455955485877361223, +} + +const lanczosG = 6.024680040776729583740234375 + +func lanczosSum(x float64) float64 { + return ratevl(x, + lanczosNum[:], + len(lanczosNum)-1, + lanczosDenom[:], + len(lanczosDenom)-1) +} + +func lanczosSumExpgScaled(x float64) float64 { + return ratevl(x, + lanczosSumExpgScaledNum[:], + len(lanczosSumExpgScaledNum)-1, + lanczosSumExpgScaledDenom[:], + len(lanczosSumExpgScaledDenom)-1) +} + +func lanczosSumNear1(dx float64) float64 { + var result float64 + + for i, val := range lanczosSumNear1D { + k := float64(i + 1) + result += (-val * dx) / (k*dx + k*k) + } + + return result +} + +func lanczosSumNear2(dx float64) float64 { + var result float64 + x := dx + 2 + + for i, val := range lanczosSumNear2D { + k := float64(i + 1) + result += (-val * dx) / (x + k*x + k*k - 1) + } + + return result +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/ndtri.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/ndtri.go new file mode 100644 index 00000000..1b26abdc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/ndtri.go @@ -0,0 +1,150 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* + * Cephes Math Library Release 2.1: January, 1989 + * Copyright 1984, 1987, 1989 by Stephen L. Moshier + * Direct inquiries to 30 Frost Street, Cambridge, MA 02140 + */ + +package cephes + +import "math" + +// TODO(btracey): There is currently an implementation of this functionality +// in gonum/stat/distuv. Find out which implementation is better, and rectify +// by having distuv call this, or moving this implementation into +// gonum/mathext/internal/gonum. + +// math.Sqrt(2*pi) +const s2pi = 2.50662827463100050242E0 + +// approximation for 0 <= |y - 0.5| <= 3/8 +var P0 = [5]float64{ + -5.99633501014107895267E1, + 9.80010754185999661536E1, + -5.66762857469070293439E1, + 1.39312609387279679503E1, + -1.23916583867381258016E0, +} + +var Q0 = [8]float64{ + /* 1.00000000000000000000E0, */ + 1.95448858338141759834E0, + 4.67627912898881538453E0, + 8.63602421390890590575E1, + -2.25462687854119370527E2, + 2.00260212380060660359E2, + -8.20372256168333339912E1, + 1.59056225126211695515E1, + -1.18331621121330003142E0, +} + +// Approximation for interval z = math.Sqrt(-2 log y ) between 2 and 8 +// i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14. +var P1 = [9]float64{ + 4.05544892305962419923E0, + 3.15251094599893866154E1, + 5.71628192246421288162E1, + 4.40805073893200834700E1, + 1.46849561928858024014E1, + 2.18663306850790267539E0, + -1.40256079171354495875E-1, + -3.50424626827848203418E-2, + -8.57456785154685413611E-4, +} + +var Q1 = [8]float64{ + /* 1.00000000000000000000E0, */ + 1.57799883256466749731E1, + 4.53907635128879210584E1, + 4.13172038254672030440E1, + 1.50425385692907503408E1, + 2.50464946208309415979E0, + -1.42182922854787788574E-1, + -3.80806407691578277194E-2, + -9.33259480895457427372E-4, +} + +// Approximation for interval z = math.Sqrt(-2 log y ) between 8 and 64 +// i.e., y between exp(-32) = 1.27e-14 and exp(-2048) = 3.67e-890. +var P2 = [9]float64{ + 3.23774891776946035970E0, + 6.91522889068984211695E0, + 3.93881025292474443415E0, + 1.33303460815807542389E0, + 2.01485389549179081538E-1, + 1.23716634817820021358E-2, + 3.01581553508235416007E-4, + 2.65806974686737550832E-6, + 6.23974539184983293730E-9, +} + +var Q2 = [8]float64{ + /* 1.00000000000000000000E0, */ + 6.02427039364742014255E0, + 3.67983563856160859403E0, + 1.37702099489081330271E0, + 2.16236993594496635890E-1, + 1.34204006088543189037E-2, + 3.28014464682127739104E-4, + 2.89247864745380683936E-6, + 6.79019408009981274425E-9, +} + +// Ndtri returns the argument, x, for which the area under the +// Gaussian probability density function (integrated from +// minus infinity to x) is equal to y. +func Ndtri(y0 float64) float64 { + // For small arguments 0 < y < exp(-2), the program computes + // z = math.Sqrt( -2.0 * math.Log(y) ); then the approximation is + // x = z - math.Log(z)/z - (1/z) P(1/z) / Q(1/z). + // There are two rational functions P/Q, one for 0 < y < exp(-32) + // and the other for y up to exp(-2). For larger arguments, + // w = y - 0.5, and x/math.Sqrt(2pi) = w + w**3 R(w**2)/S(w**2)). + var x, y, z, y2, x0, x1 float64 + var code int + + if y0 <= 0.0 { + if y0 < 0 { + panic(badParamOutOfBounds) + } + return math.Inf(-1) + } + if y0 >= 1.0 { + if y0 > 1 { + panic(badParamOutOfBounds) + } + return math.Inf(1) + } + code = 1 + y = y0 + if y > (1.0 - 0.13533528323661269189) { /* 0.135... = exp(-2) */ + y = 1.0 - y + code = 0 + } + + if y > 0.13533528323661269189 { + y = y - 0.5 + y2 = y * y + x = y + y*(y2*polevl(y2, P0[:], 4)/p1evl(y2, Q0[:], 8)) + x = x * s2pi + return (x) + } + + x = math.Sqrt(-2.0 * math.Log(y)) + x0 = x - math.Log(x)/x + + z = 1.0 / x + if x < 8.0 { /* y > exp(-32) = 1.2664165549e-14 */ + x1 = z * polevl(z, P1[:], 8) / p1evl(z, Q1[:], 8) + } else { + x1 = z * polevl(z, P2[:], 8) / p1evl(z, Q2[:], 8) + } + x = x0 - x1 + if code != 0 { + x = -x + } + return (x) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/polevl.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/polevl.go new file mode 100644 index 00000000..5cbd8cbb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/polevl.go @@ -0,0 +1,82 @@ +// Derived from SciPy's special/cephes/polevl.h +// https://github.com/scipy/scipy/blob/master/scipy/special/cephes/polevl.h +// Made freely available by Stephen L. Moshier without support or guarantee. + +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// Copyright ©1984, ©1987, ©1988 by Stephen L. Moshier +// Portions Copyright ©2016 The gonum Authors. All rights reserved. + +package cephes + +import "math" + +// polevl evaluates a polynomial of degree N +// y = c_0 + c_1 x_1 + c_2 x_2^2 ... +// where the coefficients are stored in reverse order, i.e. coef[0] = c_n and +// coef[n] = c_0. +func polevl(x float64, coef []float64, n int) float64 { + ans := coef[0] + for i := 1; i <= n; i++ { + ans = ans*x + coef[i] + } + return ans +} + +// p1evl is the same as polevl, except c_n is assumed to be 1 and is not included +// in the slice. +func p1evl(x float64, coef []float64, n int) float64 { + ans := x + coef[0] + for i := 1; i <= n-1; i++ { + ans = ans*x + coef[i] + } + return ans +} + +// ratevl evaluates a rational function +func ratevl(x float64, num []float64, m int, denom []float64, n int) float64 { + // Source: Holin et. al., "Polynomial and Rational Function Evaluation", + // http://www.boost.org/doc/libs/1_61_0/libs/math/doc/html/math_toolkit/roots/rational.html + absx := math.Abs(x) + + var dir, idx int + var y float64 + if absx > 1 { + // Evaluate as a polynomial in 1/x + dir = -1 + idx = m + y = 1 / x + } else { + dir = 1 + idx = 0 + y = x + } + + // Evaluate the numerator + numAns := num[idx] + idx += dir + for i := 0; i < m; i++ { + numAns = numAns*y + num[idx] + idx += dir + } + + // Evaluate the denominator + if absx > 1 { + idx = n + } else { + idx = 0 + } + + denomAns := denom[idx] + idx += dir + for i := 0; i < n; i++ { + denomAns = denomAns*y + denom[idx] + idx += dir + } + + if absx > 1 { + pow := float64(n - m) + return math.Pow(x, pow) * numAns / denomAns + } + return numAns / denomAns +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/unity.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/unity.go new file mode 100644 index 00000000..1333dd1d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/unity.go @@ -0,0 +1,170 @@ +// Derived from SciPy's special/cephes/unity.c +// https://github.com/scipy/scipy/blob/master/scipy/special/cephes/unity.c +// Made freely available by Stephen L. Moshier without support or guarantee. + +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// Copyright ©1984, ©1996 by Stephen L. Moshier +// Portions Copyright ©2016 The gonum Authors. All rights reserved. + +package cephes + +import "math" + +// Relative error approximations for function arguments near unity. +// log1p(x) = log(1+x) +// expm1(x) = exp(x) - 1 +// cosm1(x) = cos(x) - 1 +// lgam1p(x) = lgam(1+x) + +const ( + invSqrt2 = 1 / math.Sqrt2 + pi4 = math.Pi / 4 + euler = 0.577215664901532860606512090082402431 // Euler constant +) + +// Coefficients for +// log(1+x) = x - \frac{x^2}{2} + \frac{x^3 lP(x)}{lQ(x)} +// for +// \frac{1}{\sqrt{2}} <= x < \sqrt{2} +// Theoretical peak relative error = 2.32e-20 +var lP = [...]float64{ + 4.5270000862445199635215E-5, + 4.9854102823193375972212E-1, + 6.5787325942061044846969E0, + 2.9911919328553073277375E1, + 6.0949667980987787057556E1, + 5.7112963590585538103336E1, + 2.0039553499201281259648E1, +} + +var lQ = [...]float64{ + 1.5062909083469192043167E1, + 8.3047565967967209469434E1, + 2.2176239823732856465394E2, + 3.0909872225312059774938E2, + 2.1642788614495947685003E2, + 6.0118660497603843919306E1, +} + +// log1p computes +// log(1 + x) +func log1p(x float64) float64 { + z := 1 + x + if z < invSqrt2 || z > math.Sqrt2 { + return math.Log(z) + } + z = x * x + z = -0.5*z + x*(z*polevl(x, lP[:], 6)/p1evl(x, lQ[:], 6)) + return x + z +} + +// log1pmx computes +// log(1 + x) - x +func log1pmx(x float64) float64 { + if math.Abs(x) < 0.5 { + xfac := x + res := 0.0 + + var term float64 + for n := 2; n < maxIter; n++ { + xfac *= -x + term = xfac / float64(n) + res += term + if math.Abs(term) < machEp*math.Abs(res) { + break + } + } + return res + } + return log1p(x) - x +} + +// Coefficients for +// e^x = 1 + \frac{2x eP(x^2)}{eQ(x^2) - eP(x^2)} +// for +// -0.5 <= x <= 0.5 +var eP = [...]float64{ + 1.2617719307481059087798E-4, + 3.0299440770744196129956E-2, + 9.9999999999999999991025E-1, +} + +var eQ = [...]float64{ + 3.0019850513866445504159E-6, + 2.5244834034968410419224E-3, + 2.2726554820815502876593E-1, + 2.0000000000000000000897E0, +} + +// expm1 computes +// expm1(x) = e^x - 1 +func expm1(x float64) float64 { + if math.IsInf(x, 0) { + if math.IsNaN(x) || x > 0 { + return x + } + return -1 + } + if x < -0.5 || x > 0.5 { + return math.Exp(x) - 1 + } + xx := x * x + r := x * polevl(xx, eP[:], 2) + r = r / (polevl(xx, eQ[:], 3) - r) + return r + r +} + +var coscof = [...]float64{ + 4.7377507964246204691685E-14, + -1.1470284843425359765671E-11, + 2.0876754287081521758361E-9, + -2.7557319214999787979814E-7, + 2.4801587301570552304991E-5, + -1.3888888888888872993737E-3, + 4.1666666666666666609054E-2, +} + +// cosm1 computes +// cosm1(x) = cos(x) - 1 +func cosm1(x float64) float64 { + if x < -pi4 || x > pi4 { + return math.Cos(x) - 1 + } + xx := x * x + xx = -0.5*xx + xx*xx*polevl(xx, coscof[:], 6) + return xx +} + +// lgam1pTayler computes +// lgam(x + 1) +//around x = 0 using its Taylor series. +func lgam1pTaylor(x float64) float64 { + if x == 0 { + return 0 + } + res := -euler * x + xfac := -x + for n := 2; n < 42; n++ { + nf := float64(n) + xfac *= -x + coeff := Zeta(nf, 1) * xfac / nf + res += coeff + if math.Abs(coeff) < machEp*math.Abs(res) { + break + } + } + + return res +} + +// lgam1p computes +// lgam(x + 1) +func lgam1p(x float64) float64 { + if math.Abs(x) <= 0.5 { + return lgam1pTaylor(x) + } else if math.Abs(x-1) < 0.5 { + return math.Log(x) + lgam1pTaylor(x-1) + } + return lgam(x + 1) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/cephes/zeta.go b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/zeta.go new file mode 100644 index 00000000..14a41b6f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/cephes/zeta.go @@ -0,0 +1,110 @@ +// Derived from SciPy's special/cephes/zeta.c +// https://github.com/scipy/scipy/blob/master/scipy/special/cephes/zeta.c +// Made freely available by Stephen L. Moshier without support or guarantee. + +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// Copyright ©1984, ©1987 by Stephen L. Moshier +// Portions Copyright ©2016 The gonum Authors. All rights reserved. + +package cephes + +import "math" + +// zetaCoegs are the expansion coefficients for Euler-Maclaurin summation +// formula: +// \frac{(2k)!}{B_{2k}} +// where +// B_{2k} +// are Bernoulli numbers. +var zetaCoefs = [...]float64{ + 12.0, + -720.0, + 30240.0, + -1209600.0, + 47900160.0, + -1.307674368e12 / 691, + 7.47242496e10, + -1.067062284288e16 / 3617, + 5.109094217170944e18 / 43867, + -8.028576626982912e20 / 174611, + 1.5511210043330985984e23 / 854513, + -1.6938241367317436694528e27 / 236364091, +} + +// Zeta computes the Riemann zeta function of two arguments. +// Zeta(x,q) = \sum_{k=0}^{\infty} (k+q)^{-x} +// Note that Zeta returns +Inf if x is 1 and will panic if x is less than 1, +// q is either zero or a negative integer, or q is negative and x is not an +// integer. +// +// Note that: +// zeta(x,1) = zetac(x) + 1 +func Zeta(x, q float64) float64 { + // REFERENCE: Gradshteyn, I. S., and I. M. Ryzhik, Tables of Integrals, Series, + // and Products, p. 1073; Academic Press, 1980. + if x == 1 { + return math.Inf(1) + } + + if x < 1 { + panic(badParamOutOfBounds) + } + + if q <= 0 { + if q == math.Floor(q) { + panic(badParamFunctionSingularity) + } + if x != math.Floor(x) { + panic(badParamOutOfBounds) // Because q^-x not defined + } + } + + // Asymptotic expansion: http://dlmf.nist.gov/25.11#E43 + if q > 1e8 { + return (1/(x-1) + 1/(2*q)) * math.Pow(q, 1-x) + } + + // The Euler-Maclaurin summation formula is used to obtain the expansion: + // Zeta(x,q) = \sum_{k=1}^n (k+q)^{-x} + \frac{(n+q)^{1-x}}{x-1} - \frac{1}{2(n+q)^x} + \sum_{j=1}^{\infty} \frac{B_{2j}x(x+1)...(x+2j)}{(2j)! (n+q)^{x+2j+1}} + // where + // B_{2j} + // are Bernoulli numbers. + // Permit negative q but continue sum until n+q > 9. This case should be + // handled by a reflection formula. If q<0 and x is an integer, there is a + // relation to the polyGamma function. + s := math.Pow(q, -x) + a := q + i := 0 + b := 0.0 + for i < 9 || a <= 9 { + i++ + a += 1.0 + b = math.Pow(a, -x) + s += b + if math.Abs(b/s) < machEp { + return s + } + } + + w := a + s += b * w / (x - 1) + s -= 0.5 * b + a = 1.0 + k := 0.0 + for _, coef := range zetaCoefs { + a *= x + k + b /= w + t := a * b / coef + s = s + t + t = math.Abs(t / s) + if t < machEp { + return s + } + k += 1.0 + a *= x + k + b /= w + k += 1.0 + } + return s +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/gonum/beta.go b/vendor/gonum.org/v1/gonum/mathext/internal/gonum/beta.go new file mode 100644 index 00000000..7038c08f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/gonum/beta.go @@ -0,0 +1,52 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum + +import ( + "math" +) + +// Beta returns the value of the complete beta function B(a, b). It is defined as +// Γ(a)Γ(b) / Γ(a+b) +// Special cases are: +// B(a,b) returns NaN if a or b is Inf +// B(a,b) returns NaN if a and b are 0 +// B(a,b) returns NaN if a or b is NaN +// B(a,b) returns NaN if a or b is < 0 +// B(a,b) returns +Inf if a xor b is 0. +// +// See http://mathworld.wolfram.com/BetaFunction.html for more detailed information. +func Beta(a, b float64) float64 { + return math.Exp(Lbeta(a, b)) +} + +// Lbeta returns the natural logarithm of the complete beta function B(a,b). +// Lbeta is defined as: +// Ln(Γ(a)Γ(b)/Γ(a+b)) +// Special cases are: +// Lbeta(a,b) returns NaN if a or b is Inf +// Lbeta(a,b) returns NaN if a and b are 0 +// Lbeta(a,b) returns NaN if a or b is NaN +// Lbeta(a,b) returns NaN if a or b is < 0 +// Lbeta(a,b) returns +Inf if a xor b is 0. +func Lbeta(a, b float64) float64 { + switch { + case math.IsInf(a, +1) || math.IsInf(b, +1): + return math.NaN() + case a == 0 && b == 0: + return math.NaN() + case a < 0 || b < 0: + return math.NaN() + case math.IsNaN(a) || math.IsNaN(b): + return math.NaN() + case a == 0 || b == 0: + return math.Inf(+1) + } + + la, _ := math.Lgamma(a) + lb, _ := math.Lgamma(b) + lab, _ := math.Lgamma(a + b) + return la + lb - lab +} diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/gonum/doc.go b/vendor/gonum.org/v1/gonum/mathext/internal/gonum/doc.go new file mode 100644 index 00000000..a726cfcb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/gonum/doc.go @@ -0,0 +1,7 @@ +// 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 contains functions implemented by the gonum team. It is here to +// avoid circular imports and/or double coding of functions. +package gonum // import "gonum.org/v1/gonum/mathext/internal/gonum" diff --git a/vendor/gonum.org/v1/gonum/mathext/internal/gonum/gonum.go b/vendor/gonum.org/v1/gonum/mathext/internal/gonum/gonum.go new file mode 100644 index 00000000..eae3e1c4 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/internal/gonum/gonum.go @@ -0,0 +1,5 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gonum diff --git a/vendor/gonum.org/v1/gonum/mathext/mvgamma.go b/vendor/gonum.org/v1/gonum/mathext/mvgamma.go new file mode 100644 index 00000000..c18b37ad --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/mvgamma.go @@ -0,0 +1,32 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import "math" + +const ( + logPi = 1.14472988584940017414342735135305871164729481 // http://oeis.org/A053510 +) + +// MvLgamma returns the log of the multivariate Gamma function. Dim +// must be greater than zero, and MvLgamma will return NaN if v < (dim-1)/2. +// +// See https://en.wikipedia.org/wiki/Multivariate_gamma_function for more +// information. +func MvLgamma(v float64, dim int) float64 { + if dim < 1 { + panic("mathext: negative dimension") + } + df := float64(dim) + if v < (df-1)*0.5 { + return math.NaN() + } + ans := df * (df - 1) * 0.25 * logPi + for i := 1; i <= dim; i++ { + lg, _ := math.Lgamma(v + float64(1-i)*0.5) + ans += lg + } + return ans +} diff --git a/vendor/gonum.org/v1/gonum/mathext/mvgamma_test.go b/vendor/gonum.org/v1/gonum/mathext/mvgamma_test.go new file mode 100644 index 00000000..f7d309c8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/mvgamma_test.go @@ -0,0 +1,27 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "math" + "testing" +) + +func TestMvLgamma(t *testing.T) { + // Values compared with scipy + for i, test := range []struct { + v float64 + dim int + ans float64 + }{ + {10, 5, 58.893841851237397}, + {3, 1, 0.69314718055994529}, + } { + ans := MvLgamma(test.v, test.dim) + if math.Abs(test.ans-ans) > 1e-14 { + t.Errorf("Case %v. got=%v want=%v.", i, ans, test.ans) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/mathext/roots.go b/vendor/gonum.org/v1/gonum/mathext/roots.go new file mode 100644 index 00000000..61ff12c6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/roots.go @@ -0,0 +1,178 @@ +// Derived from SciPy's special/c_misc/fsolve.c and special/c_misc/misc.h +// https://github.com/scipy/scipy/blob/master/scipy/special/c_misc/fsolve.c +// https://github.com/scipy/scipy/blob/master/scipy/special/c_misc/misc.h + +// 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 mathext + +import "math" + +type objectiveFunc func(float64, []float64) float64 + +type fSolveResult uint8 + +const ( + // An exact solution was found, in which case the first point on the + // interval is the value + fSolveExact fSolveResult = iota + 1 + // Interval width is less than the tolerance + fSolveConverged + // Root-finding didn't converge in a set number of iterations + fSolveMaxIterations +) + +const ( + machEp = 1.0 / (1 << 53) +) + +// falsePosition uses a combination of bisection and false position to find a +// root of a function within a given interval. This is guaranteed to converge, +// and always keeps a bounding interval, unlike Newton's method. Inputs are: +// x1, x2: initial bounding interval +// f1, f2: value of f() at x1 and x2 +// absErr, relErr: absolute and relative errors on the bounding interval +// bisectTil: if > 0.0, perform bisection until the width of the bounding +// interval is less than this +// f, fExtra: function to find root of is f(x, fExtra) +// Returns: +// result: whether an exact root was found, the process converged to a +// bounding interval small than the required error, or the max number +// of iterations was hit +// bestX: best root approximation +// bestF: function value at bestX +// errEst: error estimation +func falsePosition(x1, x2, f1, f2, absErr, relErr, bisectTil float64, f objectiveFunc, fExtra []float64) (fSolveResult, float64, float64, float64) { + // The false position steps are either unmodified, or modified with the + // Anderson-Bjorck method as appropriate. Theoretically, this has a "speed of + // convergence" of 1.7 (bisection is 1, Newton is 2). + // Note that this routine was designed initially to work with gammaincinv, so + // it may not be tuned right for other problems. Don't use it blindly. + + if f1*f2 >= 0 { + panic("Initial interval is not a bounding interval") + } + + const ( + maxIterations = 100 + bisectIter = 4 + bisectWidth = 4.0 + ) + + const ( + bisect = iota + 1 + falseP + ) + + var state uint8 + if bisectTil > 0 { + state = bisect + } else { + state = falseP + } + + gamma := 1.0 + + w := math.Abs(x2 - x1) + lastBisectWidth := w + + var nFalseP int + var x3, f3, bestX, bestF float64 + for i := 0; i < maxIterations; i++ { + switch state { + case bisect: + x3 = 0.5 * (x1 + x2) + if x3 == x1 || x3 == x2 { + // i.e., x1 and x2 are successive floating-point numbers + bestX = x3 + if x3 == x1 { + bestF = f1 + } else { + bestF = f2 + } + return fSolveConverged, bestX, bestF, w + } + + f3 = f(x3, fExtra) + if f3 == 0 { + return fSolveExact, x3, f3, w + } + + if f3*f2 < 0 { + x1 = x2 + f1 = f2 + } + x2 = x3 + f2 = f3 + w = math.Abs(x2 - x1) + lastBisectWidth = w + if bisectTil > 0 { + if w < bisectTil { + bisectTil = -1.0 + gamma = 1.0 + nFalseP = 0 + state = falseP + } + } else { + gamma = 1.0 + nFalseP = 0 + state = falseP + } + case falseP: + s12 := (f2 - gamma*f1) / (x2 - x1) + x3 = x2 - f2/s12 + f3 = f(x3, fExtra) + if f3 == 0 { + return fSolveExact, x3, f3, w + } + + nFalseP++ + if f3*f2 < 0 { + gamma = 1.0 + x1 = x2 + f1 = f2 + } else { + // Anderson-Bjorck method + g := 1.0 - f3/f2 + if g <= 0 { + g = 0.5 + } + gamma *= g + } + x2 = x3 + f2 = f3 + w = math.Abs(x2 - x1) + + // Sanity check. For every 4 false position checks, see if we really are + // decreasing the interval by comparing to what bisection would have + // achieved (or, rather, a bit more lenient than that -- interval + // decreased by 4 instead of by 16, as the fp could be decreasing gamma + // for a bit). Note that this should guarantee convergence, as it makes + // sure that we always end up decreasing the interval width with a + // bisection. + if nFalseP > bisectIter { + if w*bisectWidth > lastBisectWidth { + state = bisect + } + nFalseP = 0 + lastBisectWidth = w + } + } + + tol := absErr + relErr*math.Max(math.Max(math.Abs(x1), math.Abs(x2)), 1.0) + if w <= tol { + if math.Abs(f1) < math.Abs(f2) { + bestX = x1 + bestF = f1 + } else { + bestX = x2 + bestF = f2 + } + return fSolveConverged, bestX, bestF, w + } + } + + return fSolveMaxIterations, x3, f3, w +} diff --git a/vendor/gonum.org/v1/gonum/mathext/zeta.go b/vendor/gonum.org/v1/gonum/mathext/zeta.go new file mode 100644 index 00000000..920a7e6e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/zeta.go @@ -0,0 +1,20 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import "gonum.org/v1/gonum/mathext/internal/cephes" + +// Zeta computes the Riemann zeta function of two arguments. +// Zeta(x,q) = \sum_{k=0}^{\infty} (k+q)^{-x} +// Note that Zeta returns +Inf if x is 1 and will panic if x is less than 1, +// q is either zero or a negative integer, or q is negative and x is not an +// integer. +// +// See http://mathworld.wolfram.com/HurwitzZetaFunction.html +// or https://en.wikipedia.org/wiki/Multiple_zeta_function#Two_parameters_case +// for more detailed information. +func Zeta(x, q float64) float64 { + return cephes.Zeta(x, q) +} diff --git a/vendor/gonum.org/v1/gonum/mathext/zeta_test.go b/vendor/gonum.org/v1/gonum/mathext/zeta_test.go new file mode 100644 index 00000000..e415818f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/mathext/zeta_test.go @@ -0,0 +1,42 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mathext + +import ( + "math" + "testing" +) + +func TestZeta(t *testing.T) { + for i, test := range []struct { + x, q, want float64 + }{ + // Results computed using scipy.special.zeta + {1, 1, math.Inf(1)}, + {1.00001, 0.5, 100001.96352290553}, + {1.0001, 25, 9996.8017690244506}, + {1.001, 1, 1000.5772884760117}, + {1.01, 10, 97.773405639173305}, + {1.5, 2, 1.6123753486854886}, + {1.5, 20, 0.45287361712938717}, + {2, -0.7, 14.28618087263834}, + {2.5, 0.5, 6.2471106345688137}, + {5, 2.5, 0.013073166646113805}, + {7.5, 5, 7.9463377443314306e-06}, + {10, -0.5, 2048.0174503557578}, + {10, 0.5, 1024.0174503557578}, + {10, 7.5, 2.5578265694201971e-9}, + {12, 2.5, 1.7089167198843551e-5}, + {17, 0.5, 131072.00101513157}, + {20, -2.5, 2097152.0006014798}, + {20, 0.75, 315.3368689825316}, + {25, 0.25, 1125899906842624.0}, + {30, 1, 1.0000000009313275}, + } { + if got := Zeta(test.x, test.q); math.Abs(got-test.want) > 1e-10 { + t.Errorf("test %d Zeta(%g, %g) failed: got %g want %g", i, test.x, test.q, got, test.want) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/optimize/README.md b/vendor/gonum.org/v1/gonum/optimize/README.md new file mode 100644 index 00000000..0067895c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/README.md @@ -0,0 +1,3 @@ +# Gonum optimize [![GoDoc](https://godoc.org/gonum.org/v1/gonum/optimize?status.svg)](https://godoc.org/gonum.org/v1/gonum/optimize) + +Package optimize is an optimization package for the Go language. diff --git a/vendor/gonum.org/v1/gonum/optimize/backtracking.go b/vendor/gonum.org/v1/gonum/optimize/backtracking.go new file mode 100644 index 00000000..313077f3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/backtracking.go @@ -0,0 +1,82 @@ +// 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 optimize + +const ( + defaultBacktrackingContraction = 0.5 + defaultBacktrackingDecrease = 1e-4 + minimumBacktrackingStepSize = 1e-20 +) + +// Backtracking is a Linesearcher that uses backtracking to find a point that +// satisfies the Armijo condition with the given decrease factor. If the Armijo +// condition has not been met, the step size is decreased by ContractionFactor. +// +// The Armijo condition only requires the gradient at the beginning of each +// major iteration (not at successive step locations), and so Backtracking may +// be a good linesearch for functions with expensive gradients. Backtracking is +// not appropriate for optimizers that require the Wolfe conditions to be met, +// such as BFGS. +// +// Both DecreaseFactor and ContractionFactor must be between zero and one, and +// Backtracking will panic otherwise. If either DecreaseFactor or +// ContractionFactor are zero, it will be set to a reasonable default. +type Backtracking struct { + DecreaseFactor float64 // Constant factor in the sufficient decrease (Armijo) condition. + ContractionFactor float64 // Step size multiplier at each iteration (step *= ContractionFactor). + + stepSize float64 + initF float64 + initG float64 + + lastOp Operation +} + +func (b *Backtracking) Init(f, g float64, step float64) Operation { + if step <= 0 { + panic("backtracking: bad step size") + } + if g >= 0 { + panic("backtracking: initial derivative is non-negative") + } + + if b.ContractionFactor == 0 { + b.ContractionFactor = defaultBacktrackingContraction + } + if b.DecreaseFactor == 0 { + b.DecreaseFactor = defaultBacktrackingDecrease + } + if b.ContractionFactor <= 0 || b.ContractionFactor >= 1 { + panic("backtracking: ContractionFactor must be between 0 and 1") + } + if b.DecreaseFactor <= 0 || b.DecreaseFactor >= 1 { + panic("backtracking: DecreaseFactor must be between 0 and 1") + } + + b.stepSize = step + b.initF = f + b.initG = g + + b.lastOp = FuncEvaluation + return b.lastOp +} + +func (b *Backtracking) Iterate(f, _ float64) (Operation, float64, error) { + if b.lastOp != FuncEvaluation { + panic("backtracking: Init has not been called") + } + + if ArmijoConditionMet(f, b.initF, b.initG, b.stepSize, b.DecreaseFactor) { + b.lastOp = MajorIteration + return b.lastOp, b.stepSize, nil + } + b.stepSize *= b.ContractionFactor + if b.stepSize < minimumBacktrackingStepSize { + b.lastOp = NoOperation + return b.lastOp, b.stepSize, ErrLinesearcherFailure + } + b.lastOp = FuncEvaluation + return b.lastOp, b.stepSize, nil +} diff --git a/vendor/gonum.org/v1/gonum/optimize/bfgs.go b/vendor/gonum.org/v1/gonum/optimize/bfgs.go new file mode 100644 index 00000000..997d991b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/bfgs.go @@ -0,0 +1,160 @@ +// 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 optimize + +import ( + "math" + + "gonum.org/v1/gonum/mat" +) + +// BFGS implements the Broyden–Fletcher–Goldfarb–Shanno optimization method. It +// is a quasi-Newton method that performs successive rank-one updates to an +// estimate of the inverse Hessian of the objective function. It exhibits +// super-linear convergence when in proximity to a local minimum. It has memory +// cost that is O(n^2) relative to the input dimension. +type BFGS struct { + // Linesearcher selects suitable steps along the descent direction. + // Accepted steps should satisfy the strong Wolfe conditions. + // If Linesearcher == nil, an appropriate default is chosen. + Linesearcher Linesearcher + + ls *LinesearchMethod + + dim int + x mat.VecDense // Location of the last major iteration. + grad mat.VecDense // Gradient at the last major iteration. + s mat.VecDense // Difference between locations in this and the previous iteration. + y mat.VecDense // Difference between gradients in this and the previous iteration. + tmp mat.VecDense + + invHess *mat.SymDense + + first bool // Indicator of the first iteration. +} + +func (b *BFGS) Init(loc *Location) (Operation, error) { + if b.Linesearcher == nil { + b.Linesearcher = &Bisection{} + } + if b.ls == nil { + b.ls = &LinesearchMethod{} + } + b.ls.Linesearcher = b.Linesearcher + b.ls.NextDirectioner = b + + return b.ls.Init(loc) +} + +func (b *BFGS) Iterate(loc *Location) (Operation, error) { + return b.ls.Iterate(loc) +} + +func (b *BFGS) InitDirection(loc *Location, dir []float64) (stepSize float64) { + dim := len(loc.X) + b.dim = dim + b.first = true + + x := mat.NewVecDense(dim, loc.X) + grad := mat.NewVecDense(dim, loc.Gradient) + b.x.CloneVec(x) + b.grad.CloneVec(grad) + + b.y.Reset() + b.s.Reset() + b.tmp.Reset() + + if b.invHess == nil || cap(b.invHess.RawSymmetric().Data) < dim*dim { + b.invHess = mat.NewSymDense(dim, nil) + } else { + b.invHess = mat.NewSymDense(dim, b.invHess.RawSymmetric().Data[:dim*dim]) + } + // The values of the inverse Hessian are initialized in the first call to + // NextDirection. + + // Initial direction is just negative of the gradient because the Hessian + // is an identity matrix. + d := mat.NewVecDense(dim, dir) + d.ScaleVec(-1, grad) + return 1 / mat.Norm(d, 2) +} + +func (b *BFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) { + dim := b.dim + if len(loc.X) != dim { + panic("bfgs: unexpected size mismatch") + } + if len(loc.Gradient) != dim { + panic("bfgs: unexpected size mismatch") + } + if len(dir) != dim { + panic("bfgs: unexpected size mismatch") + } + + x := mat.NewVecDense(dim, loc.X) + grad := mat.NewVecDense(dim, loc.Gradient) + + // s = x_{k+1} - x_{k} + b.s.SubVec(x, &b.x) + // y = g_{k+1} - g_{k} + b.y.SubVec(grad, &b.grad) + + sDotY := mat.Dot(&b.s, &b.y) + + if b.first { + // Rescale the initial Hessian. + // From: Nocedal, J., Wright, S.: Numerical Optimization (2nd ed). + // Springer (2006), page 143, eq. 6.20. + yDotY := mat.Dot(&b.y, &b.y) + scale := sDotY / yDotY + for i := 0; i < dim; i++ { + for j := i; j < dim; j++ { + if i == j { + b.invHess.SetSym(i, i, scale) + } else { + b.invHess.SetSym(i, j, 0) + } + } + } + b.first = false + } + + if math.Abs(sDotY) != 0 { + // Update the inverse Hessian according to the formula + // + // B_{k+1}^-1 = B_k^-1 + // + (s_k^T y_k + y_k^T B_k^-1 y_k) / (s_k^T y_k)^2 * (s_k s_k^T) + // - (B_k^-1 y_k s_k^T + s_k y_k^T B_k^-1) / (s_k^T y_k). + // + // Note that y_k^T B_k^-1 y_k is a scalar, and that the third term is a + // rank-two update where B_k^-1 y_k is one vector and s_k is the other. + yBy := mat.Inner(&b.y, b.invHess, &b.y) + b.tmp.MulVec(b.invHess, &b.y) + scale := (1 + yBy/sDotY) / sDotY + b.invHess.SymRankOne(b.invHess, scale, &b.s) + b.invHess.RankTwo(b.invHess, -1/sDotY, &b.tmp, &b.s) + } + + // Update the stored BFGS data. + b.x.CopyVec(x) + b.grad.CopyVec(grad) + + // New direction is stored in dir. + d := mat.NewVecDense(dim, dir) + d.MulVec(b.invHess, grad) + d.ScaleVec(-1, d) + + return 1 +} + +func (*BFGS) Needs() struct { + Gradient bool + Hessian bool +} { + return struct { + Gradient bool + Hessian bool + }{true, false} +} diff --git a/vendor/gonum.org/v1/gonum/optimize/bisection.go b/vendor/gonum.org/v1/gonum/optimize/bisection.go new file mode 100644 index 00000000..6dfe8652 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/bisection.go @@ -0,0 +1,146 @@ +// 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 optimize + +import "math" + +const ( + defaultBisectionCurvature = 0.9 +) + +// Bisection is a Linesearcher that uses a bisection to find a point that +// satisfies the strong Wolfe conditions with the given curvature factor and +// a decrease factor of zero. +type Bisection struct { + // CurvatureFactor is the constant factor in the curvature condition. + // Smaller values result in a more exact line search. + // A set value must be in the interval (0, 1), otherwise Init will panic. + // If it is zero, it will be defaulted to 0.9. + CurvatureFactor float64 + + minStep float64 + maxStep float64 + currStep float64 + + initF float64 + minF float64 + maxF float64 + lastF float64 + + initGrad float64 + + lastOp Operation +} + +func (b *Bisection) Init(f, g float64, step float64) Operation { + if step <= 0 { + panic("bisection: bad step size") + } + if g >= 0 { + panic("bisection: initial derivative is non-negative") + } + + if b.CurvatureFactor == 0 { + b.CurvatureFactor = defaultBisectionCurvature + } + if b.CurvatureFactor <= 0 || b.CurvatureFactor >= 1 { + panic("bisection: CurvatureFactor not between 0 and 1") + } + + b.minStep = 0 + b.maxStep = math.Inf(1) + b.currStep = step + + b.initF = f + b.minF = f + b.maxF = math.NaN() + + b.initGrad = g + + // Only evaluate the gradient when necessary. + b.lastOp = FuncEvaluation + return b.lastOp +} + +func (b *Bisection) Iterate(f, g float64) (Operation, float64, error) { + if b.lastOp != FuncEvaluation && b.lastOp != GradEvaluation { + panic("bisection: Init has not been called") + } + minF := b.initF + if b.maxF < minF { + minF = b.maxF + } + if b.minF < minF { + minF = b.minF + } + if b.lastOp == FuncEvaluation { + // See if the function value is good enough to make progress. If it is, + // evaluate the gradient. If not, set it to the upper bound if the bound + // has not yet been found, otherwise iterate toward the minimum location. + if f <= minF { + b.lastF = f + b.lastOp = GradEvaluation + return b.lastOp, b.currStep, nil + } + if math.IsInf(b.maxStep, 1) { + b.maxStep = b.currStep + b.maxF = f + return b.nextStep((b.minStep + b.maxStep) / 2) + } + if b.minF <= b.maxF { + b.maxStep = b.currStep + b.maxF = f + } else { + b.minStep = b.currStep + b.minF = f + } + return b.nextStep((b.minStep + b.maxStep) / 2) + } + f = b.lastF + // The function value was lower. Check if this location is sufficient to + // converge the linesearch, otherwise iterate. + if StrongWolfeConditionsMet(f, g, minF, b.initGrad, b.currStep, 0, b.CurvatureFactor) { + b.lastOp = MajorIteration + return b.lastOp, b.currStep, nil + } + if math.IsInf(b.maxStep, 1) { + // The function value is lower. If the gradient is positive, an upper bound + // of the minimum been found. If the gradient is negative, search farther + // in that direction. + if g > 0 { + b.maxStep = b.currStep + b.maxF = f + return b.nextStep((b.minStep + b.maxStep) / 2) + } + b.minStep = b.currStep + b.minF = f + return b.nextStep(b.currStep * 2) + } + // The interval has been bounded, and we have found a new lowest value. Use + // the gradient to decide which direction. + if g < 0 { + b.minStep = b.currStep + b.minF = f + } else { + b.maxStep = b.currStep + b.maxF = f + } + return b.nextStep((b.minStep + b.maxStep) / 2) +} + +// nextStep checks if the new step is equal to the old step. +// This can happen if min and max are the same, or if the step size is infinity, +// both of which indicate the minimization must stop. If the steps are different, +// it sets the new step size and returns the evaluation type and the step. If the steps +// are the same, it returns an error. +func (b *Bisection) nextStep(step float64) (Operation, float64, error) { + if b.currStep == step { + b.lastOp = NoOperation + return b.lastOp, b.currStep, ErrLinesearcherFailure + } + b.currStep = step + b.lastOp = FuncEvaluation + return b.lastOp, b.currStep, nil +} diff --git a/vendor/gonum.org/v1/gonum/optimize/cg.go b/vendor/gonum.org/v1/gonum/optimize/cg.go new file mode 100644 index 00000000..88612d3f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/cg.go @@ -0,0 +1,313 @@ +package optimize + +import ( + "math" + + "gonum.org/v1/gonum/floats" +) + +const ( + iterationRestartFactor = 6 + angleRestartThreshold = -0.9 +) + +// CGVariant calculates the scaling parameter, β, used for updating the +// conjugate direction in the nonlinear conjugate gradient (CG) method. +type CGVariant interface { + // Init is called at the first iteration and provides a way to initialize + // any internal state. + Init(loc *Location) + // Beta returns the value of the scaling parameter that is computed + // according to the particular variant of the CG method. + Beta(grad, gradPrev, dirPrev []float64) float64 +} + +// CG implements the nonlinear conjugate gradient method for solving nonlinear +// unconstrained optimization problems. It is a line search method that +// generates the search directions d_k according to the formula +// d_{k+1} = -∇f_{k+1} + β_k*d_k, d_0 = -∇f_0. +// Variants of the conjugate gradient method differ in the choice of the +// parameter β_k. The conjugate gradient method usually requires fewer function +// evaluations than the gradient descent method and no matrix storage, but +// L-BFGS is usually more efficient. +// +// CG implements a restart strategy that takes the steepest descent direction +// (i.e., d_{k+1} = -∇f_{k+1}) whenever any of the following conditions holds: +// +// - A certain number of iterations has elapsed without a restart. This number +// is controllable via IterationRestartFactor and if equal to 0, it is set to +// a reasonable default based on the problem dimension. +// - The angle between the gradients at two consecutive iterations ∇f_k and +// ∇f_{k+1} is too large. +// - The direction d_{k+1} is not a descent direction. +// - β_k returned from CGVariant.Beta is equal to zero. +// +// The line search for CG must yield step sizes that satisfy the strong Wolfe +// conditions at every iteration, otherwise the generated search direction +// might fail to be a descent direction. The line search should be more +// stringent compared with those for Newton-like methods, which can be achieved +// by setting the gradient constant in the strong Wolfe conditions to a small +// value. +// +// See also William Hager, Hongchao Zhang, A survey of nonlinear conjugate +// gradient methods. Pacific Journal of Optimization, 2 (2006), pp. 35-58, and +// references therein. +type CG struct { + // Linesearcher must satisfy the strong Wolfe conditions at every iteration. + // If Linesearcher == nil, an appropriate default is chosen. + Linesearcher Linesearcher + // Variant implements the particular CG formula for computing β_k. + // If Variant is nil, an appropriate default is chosen. + Variant CGVariant + // InitialStep estimates the initial line search step size, because the CG + // method does not generate well-scaled search directions. + // If InitialStep is nil, an appropriate default is chosen. + InitialStep StepSizer + + // IterationRestartFactor determines the frequency of restarts based on the + // problem dimension. The negative gradient direction is taken whenever + // ceil(IterationRestartFactor*(problem dimension)) iterations have elapsed + // without a restart. For medium and large-scale problems + // IterationRestartFactor should be set to 1, low-dimensional problems a + // larger value should be chosen. Note that if the ceil function returns 1, + // CG will be identical to gradient descent. + // If IterationRestartFactor is 0, it will be set to 6. + // CG will panic if IterationRestartFactor is negative. + IterationRestartFactor float64 + // AngleRestartThreshold sets the threshold angle for restart. The method + // is restarted if the cosine of the angle between two consecutive + // gradients is smaller than or equal to AngleRestartThreshold, that is, if + // ∇f_k·∇f_{k+1} / (|∇f_k| |∇f_{k+1}|) <= AngleRestartThreshold. + // A value of AngleRestartThreshold closer to -1 (successive gradients in + // exact opposite directions) will tend to reduce the number of restarts. + // If AngleRestartThreshold is 0, it will be set to -0.9. + // CG will panic if AngleRestartThreshold is not in the interval [-1, 0]. + AngleRestartThreshold float64 + + ls *LinesearchMethod + + restartAfter int + iterFromRestart int + + dirPrev []float64 + gradPrev []float64 + gradPrevNorm float64 +} + +func (cg *CG) Init(loc *Location) (Operation, error) { + if cg.IterationRestartFactor < 0 { + panic("cg: IterationRestartFactor is negative") + } + if cg.AngleRestartThreshold < -1 || cg.AngleRestartThreshold > 0 { + panic("cg: AngleRestartThreshold not in [-1, 0]") + } + + if cg.Linesearcher == nil { + cg.Linesearcher = &MoreThuente{CurvatureFactor: 0.1} + } + if cg.Variant == nil { + cg.Variant = &HestenesStiefel{} + } + if cg.InitialStep == nil { + cg.InitialStep = &FirstOrderStepSize{} + } + + if cg.IterationRestartFactor == 0 { + cg.IterationRestartFactor = iterationRestartFactor + } + if cg.AngleRestartThreshold == 0 { + cg.AngleRestartThreshold = angleRestartThreshold + } + + if cg.ls == nil { + cg.ls = &LinesearchMethod{} + } + cg.ls.Linesearcher = cg.Linesearcher + cg.ls.NextDirectioner = cg + + return cg.ls.Init(loc) +} + +func (cg *CG) Iterate(loc *Location) (Operation, error) { + return cg.ls.Iterate(loc) +} + +func (cg *CG) InitDirection(loc *Location, dir []float64) (stepSize float64) { + dim := len(loc.X) + + cg.restartAfter = int(math.Ceil(cg.IterationRestartFactor * float64(dim))) + cg.iterFromRestart = 0 + + // The initial direction is always the negative gradient. + copy(dir, loc.Gradient) + floats.Scale(-1, dir) + + cg.dirPrev = resize(cg.dirPrev, dim) + copy(cg.dirPrev, dir) + cg.gradPrev = resize(cg.gradPrev, dim) + copy(cg.gradPrev, loc.Gradient) + cg.gradPrevNorm = floats.Norm(loc.Gradient, 2) + + cg.Variant.Init(loc) + return cg.InitialStep.Init(loc, dir) +} + +func (cg *CG) NextDirection(loc *Location, dir []float64) (stepSize float64) { + copy(dir, loc.Gradient) + floats.Scale(-1, dir) + + cg.iterFromRestart++ + var restart bool + if cg.iterFromRestart == cg.restartAfter { + // Restart because too many iterations have been taken without a restart. + restart = true + } + + gDot := floats.Dot(loc.Gradient, cg.gradPrev) + gNorm := floats.Norm(loc.Gradient, 2) + if gDot <= cg.AngleRestartThreshold*gNorm*cg.gradPrevNorm { + // Restart because the angle between the last two gradients is too large. + restart = true + } + + // Compute the scaling factor β_k even when restarting, because cg.Variant + // may be keeping an inner state that needs to be updated at every iteration. + beta := cg.Variant.Beta(loc.Gradient, cg.gradPrev, cg.dirPrev) + if beta == 0 { + // β_k == 0 means that the steepest descent direction will be taken, so + // indicate that the method is in fact being restarted. + restart = true + } + if !restart { + // The method is not being restarted, so update the descent direction. + floats.AddScaled(dir, beta, cg.dirPrev) + if floats.Dot(loc.Gradient, dir) >= 0 { + // Restart because the new direction is not a descent direction. + restart = true + copy(dir, loc.Gradient) + floats.Scale(-1, dir) + } + } + + // Get the initial line search step size from the StepSizer even if the + // method was restarted, because StepSizers need to see every iteration. + stepSize = cg.InitialStep.StepSize(loc, dir) + if restart { + // The method was restarted and since the steepest descent direction is + // not related to the previous direction, discard the estimated step + // size from cg.InitialStep and use step size of 1 instead. + stepSize = 1 + // Reset to 0 the counter of iterations taken since the last restart. + cg.iterFromRestart = 0 + } + + copy(cg.gradPrev, loc.Gradient) + copy(cg.dirPrev, dir) + cg.gradPrevNorm = gNorm + return stepSize +} + +func (*CG) Needs() struct { + Gradient bool + Hessian bool +} { + return struct { + Gradient bool + Hessian bool + }{true, false} +} + +// FletcherReeves implements the Fletcher-Reeves variant of the CG method that +// computes the scaling parameter β_k according to the formula +// β_k = |∇f_{k+1}|^2 / |∇f_k|^2. +type FletcherReeves struct { + prevNorm float64 +} + +func (fr *FletcherReeves) Init(loc *Location) { + fr.prevNorm = floats.Norm(loc.Gradient, 2) +} + +func (fr *FletcherReeves) Beta(grad, _, _ []float64) (beta float64) { + norm := floats.Norm(grad, 2) + beta = (norm / fr.prevNorm) * (norm / fr.prevNorm) + fr.prevNorm = norm + return beta +} + +// PolakRibierePolyak implements the Polak-Ribiere-Polyak variant of the CG +// method that computes the scaling parameter β_k according to the formula +// β_k = max(0, ∇f_{k+1}·y_k / |∇f_k|^2), +// where y_k = ∇f_{k+1} - ∇f_k. +type PolakRibierePolyak struct { + prevNorm float64 +} + +func (pr *PolakRibierePolyak) Init(loc *Location) { + pr.prevNorm = floats.Norm(loc.Gradient, 2) +} + +func (pr *PolakRibierePolyak) Beta(grad, gradPrev, _ []float64) (beta float64) { + norm := floats.Norm(grad, 2) + dot := floats.Dot(grad, gradPrev) + beta = (norm*norm - dot) / (pr.prevNorm * pr.prevNorm) + pr.prevNorm = norm + return math.Max(0, beta) +} + +// HestenesStiefel implements the Hestenes-Stiefel variant of the CG method +// that computes the scaling parameter β_k according to the formula +// β_k = max(0, ∇f_{k+1}·y_k / d_k·y_k), +// where y_k = ∇f_{k+1} - ∇f_k. +type HestenesStiefel struct { + y []float64 +} + +func (hs *HestenesStiefel) Init(loc *Location) { + hs.y = resize(hs.y, len(loc.Gradient)) +} + +func (hs *HestenesStiefel) Beta(grad, gradPrev, dirPrev []float64) (beta float64) { + floats.SubTo(hs.y, grad, gradPrev) + beta = floats.Dot(grad, hs.y) / floats.Dot(dirPrev, hs.y) + return math.Max(0, beta) +} + +// DaiYuan implements the Dai-Yuan variant of the CG method that computes the +// scaling parameter β_k according to the formula +// β_k = |∇f_{k+1}|^2 / d_k·y_k, +// where y_k = ∇f_{k+1} - ∇f_k. +type DaiYuan struct { + y []float64 +} + +func (dy *DaiYuan) Init(loc *Location) { + dy.y = resize(dy.y, len(loc.Gradient)) +} + +func (dy *DaiYuan) Beta(grad, gradPrev, dirPrev []float64) (beta float64) { + floats.SubTo(dy.y, grad, gradPrev) + norm := floats.Norm(grad, 2) + return norm * norm / floats.Dot(dirPrev, dy.y) +} + +// HagerZhang implements the Hager-Zhang variant of the CG method that computes the +// scaling parameter β_k according to the formula +// β_k = (y_k - 2 d_k |y_k|^2/(d_k·y_k))·∇f_{k+1} / (d_k·y_k), +// where y_k = ∇f_{k+1} - ∇f_k. +type HagerZhang struct { + y []float64 +} + +func (hz *HagerZhang) Init(loc *Location) { + hz.y = resize(hz.y, len(loc.Gradient)) +} + +func (hz *HagerZhang) Beta(grad, gradPrev, dirPrev []float64) (beta float64) { + floats.SubTo(hz.y, grad, gradPrev) + dirDotY := floats.Dot(dirPrev, hz.y) + gDotY := floats.Dot(grad, hz.y) + gDotDir := floats.Dot(grad, dirPrev) + yNorm := floats.Norm(hz.y, 2) + return (gDotY - 2*gDotDir*yNorm*yNorm/dirDotY) / dirDotY +} diff --git a/vendor/gonum.org/v1/gonum/optimize/convex/lp/convert.go b/vendor/gonum.org/v1/gonum/optimize/convex/lp/convert.go new file mode 100644 index 00000000..66ebe2ea --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/convex/lp/convert.go @@ -0,0 +1,137 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lp + +import ( + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +// TODO(btracey): Have some sort of preprocessing step for helping to fix A to make it +// full rank? +// TODO(btracey): Reduce rows? Get rid of all zeros, places where only one variable +// is there, etc. Could be implemented with a Reduce function. +// TODO(btracey): Provide method of artificial variables for help when problem +// is infeasible? +// TODO(btracey): Add an lp.Solve that solves an LP in non-standard form. + +// Convert converts a General-form LP into a standard form LP. +// The general form of an LP is: +// minimize c^T * x +// s.t G * x <= h +// A * x = b +// And the standard form is: +// minimize cNew^T * x +// s.t aNew * x = bNew +// x >= 0 +// If there are no constraints of the given type, the inputs may be nil. +func Convert(c []float64, g mat.Matrix, h []float64, a mat.Matrix, b []float64) (cNew []float64, aNew *mat.Dense, bNew []float64) { + nVar := len(c) + nIneq := len(h) + + // Check input sizes. + if g == nil { + if nIneq != 0 { + panic(badShape) + } + } else { + gr, gc := g.Dims() + if gr != nIneq { + panic(badShape) + } + if gc != nVar { + panic(badShape) + } + } + + nEq := len(b) + if a == nil { + if nEq != 0 { + panic(badShape) + } + } else { + ar, ac := a.Dims() + if ar != nEq { + panic(badShape) + } + if ac != nVar { + panic(badShape) + } + } + + // Convert the general form LP. + // Derivation: + // 0. Start with general form + // min. c^T * x + // s.t. G * x <= h + // A * x = b + // 1. Introduce slack variables for each constraint + // min. c^T * x + // s.t. G * x + s = h + // A * x = b + // s >= 0 + // 2. Add non-negativity constraints for x by splitting x + // into positive and negative components. + // x = xp - xn + // xp >= 0, xn >= 0 + // This makes the LP + // min. c^T * xp - c^T xn + // s.t. G * xp - G * xn + s = h + // A * xp - A * xn = b + // xp >= 0, xn >= 0, s >= 0 + // 3. Write the above in standard form: + // xt = [xp + // xn + // s ] + // min. [c^T, -c^T, 0] xt + // s.t. [G, -G, I] xt = h + // [A, -A, 0] xt = b + // x >= 0 + + // In summary: + // Original LP: + // min. c^T * x + // s.t. G * x <= h + // A * x = b + // Standard Form: + // xt = [xp; xn; s] + // min. [c^T, -c^T, 0] xt + // s.t. [G, -G, I] xt = h + // [A, -A, 0] xt = b + // x >= 0 + + // New size of x is [xp, xn, s] + nNewVar := nVar + nVar + nIneq + + // Construct cNew = [c; -c; 0] + cNew = make([]float64, nNewVar) + copy(cNew, c) + copy(cNew[nVar:], c) + floats.Scale(-1, cNew[nVar:2*nVar]) + + // New number of equality constraints is the number of total constraints. + nNewEq := nIneq + nEq + + // Construct bNew = [h, b]. + bNew = make([]float64, nNewEq) + copy(bNew, h) + copy(bNew[nIneq:], b) + + // Construct aNew = [G, -G, I; A, -A, 0]. + aNew = mat.NewDense(nNewEq, nNewVar, nil) + if nIneq != 0 { + aNew.Slice(0, nIneq, 0, nVar).(*mat.Dense).Copy(g) + aNew.Slice(0, nIneq, nVar, 2*nVar).(*mat.Dense).Scale(-1, g) + aView := aNew.Slice(0, nIneq, 2*nVar, 2*nVar+nIneq).(*mat.Dense) + for i := 0; i < nIneq; i++ { + aView.Set(i, i, 1) + } + } + if nEq != 0 { + aNew.Slice(nIneq, nIneq+nEq, 0, nVar).(*mat.Dense).Copy(a) + aNew.Slice(nIneq, nIneq+nEq, nVar, 2*nVar).(*mat.Dense).Scale(-1, a) + } + return cNew, aNew, bNew +} diff --git a/vendor/gonum.org/v1/gonum/optimize/convex/lp/doc.go b/vendor/gonum.org/v1/gonum/optimize/convex/lp/doc.go new file mode 100644 index 00000000..7b084247 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/convex/lp/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package lp implements routines to solve linear programming problems. +package lp // import "gonum.org/v1/gonum/optimize/convex/lp" diff --git a/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplex.go b/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplex.go new file mode 100644 index 00000000..eb7757ff --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplex.go @@ -0,0 +1,619 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// package lp implements routines for solving linear programs. +package lp + +import ( + "errors" + "fmt" + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +// TODO(btracey): Could have a solver structure with an abstract factorizer. With +// this transformation the same high-level code could handle both Dense and Sparse. +// TODO(btracey): Need to improve error handling. Only want to panic if condition number inf. +// TODO(btracey): Performance enhancements. There are currently lots of linear +// solves that can be improved by doing rank-one updates. For example, the swap +// step is just a rank-one update. +// TODO(btracey): Better handling on the linear solve errors. If the condition +// number is not inf and the equation solved "well", should keep moving. + +var ( + ErrBland = errors.New("lp: bland: all replacements are negative or cause ill-conditioned ab") + ErrInfeasible = errors.New("lp: problem is infeasible") + ErrLinSolve = errors.New("lp: linear solve failure") + ErrUnbounded = errors.New("lp: problem is unbounded") + ErrSingular = errors.New("lp: A is singular") + ErrZeroColumn = errors.New("lp: A has a column of all zeros") + ErrZeroRow = errors.New("lp: A has a row of all zeros") +) + +var ( + badShape = "lp: size mismatch" +) + +// TODO(btracey): Should these tolerances be part of a settings struct? + +const ( + // initPosTol is the tolerance on the initial condition being feasible. Strictly, + // the x should be positive, but instead it must be greater than -initPosTol. + initPosTol = 1e-13 + // blandNegTol is the tolerance on the value being greater than 0 in the bland test. + blandNegTol = 1e-14 + // rRoundTol is the tolerance for rounding values to zero when testing if + // constraints are met. + rRoundTol = 1e-13 + // dRoundTol is the tolerance for testing if values are zero for the problem + // being unbounded. + dRoundTol = 1e-13 + // phaseIZeroTol tests if the Phase I problem returned a feasible solution. + phaseIZeroTol = 1e-12 + // blandZeroTol is the tolerance on testing if the bland solution can move. + blandZeroTol = 1e-12 +) + +// Simplex solves a linear program in standard form using Danzig's Simplex +// algorithm. The standard form of a linear program is: +// minimize c^T x +// s.t. A*x = b +// x >= 0 . +// The input tol sets how close to the optimal solution is found (specifically, +// when the maximal reduced cost is below tol). An error will be returned if the +// problem is infeasible or unbounded. In rare cases, numeric errors can cause +// the Simplex to fail. In this case, an error will be returned along with the +// most recently found feasible solution. +// +// The Convert function can be used to transform a general LP into standard form. +// +// The input matrix A must have full rank and may not contain any columns with +// all zeros. Furthermore, len(c) must equal the number of columns of A, and len(b) +// must equal the number of rows of A. Simplex will panic if these conditions are +// not met. +// +// initialBasic can be used to set the initial set of indices for a feasible +// solution to the LP. If an initial feasible solution is not known, initialBasic +// may be nil. If initialBasic is non-nil, len(initialBasic) must equal the number +// of rows of A and must be an actual feasible solution to the LP, otherwise +// Simplex will panic. +// +// A description of the Simplex algorithm can be found in Ch. 8 of +// Strang, Gilbert. "Linear Algebra and Applications." Academic, New York (1976). +// For a detailed video introduction, see lectures 11-13 of UC Math 352 +// https://www.youtube.com/watch?v=ESzYPFkY3og&index=11&list=PLh464gFUoJWOmBYla3zbZbc4nv2AXez6X. +func Simplex(c []float64, A mat.Matrix, b []float64, tol float64, initialBasic []int) (optF float64, optX []float64, err error) { + ans, x, _, err := simplex(initialBasic, c, A, b, tol) + return ans, x, err +} + +func simplex(initialBasic []int, c []float64, A mat.Matrix, b []float64, tol float64) (float64, []float64, []int, error) { + err := verifyInputs(initialBasic, c, A, b) + if err != nil { + if err == ErrUnbounded { + return math.Inf(-1), nil, nil, ErrUnbounded + } + return math.NaN(), nil, nil, err + } + m, n := A.Dims() + + // There is at least one optimal solution to the LP which is at the intersection + // to a set of constraint boundaries. For a standard form LP with m variables + // and n equality constraints, at least m-n elements of x must equal zero + // at optimality. The Simplex algorithm solves the standard-form LP by starting + // at an initial constraint vertex and successively moving to adjacent constraint + // vertices. At every vertex, the set of non-zero x values is the "basic + // feasible solution". The list of non-zero x's are maintained in basicIdxs, + // the respective columns of A are in ab, and the actual non-zero values of + // x are in xb. + // + // The LP is equality constrained such that A * x = b. This can be expanded + // to + // ab * xb + an * xn = b + // where ab are the columns of a in the basic set, and an are all of the + // other columns. Since each element of xn is zero by definition, this means + // that for all feasible solutions xb = ab^-1 * b. + // + // Before the simplex algorithm can start, an initial feasible solution must + // be found. If initialBasic is non-nil a feasible solution has been supplied. + // Otherwise the "Phase I" problem must be solved to find an initial feasible + // solution. + + var basicIdxs []int // The indices of the non-zero x values. + var ab *mat.Dense // The subset of columns of A listed in basicIdxs. + var xb []float64 // The non-zero elements of x. xb = ab^-1 b + + if initialBasic != nil { + // InitialBasic supplied. Panic if incorrect length or infeasible. + if len(initialBasic) != m { + panic("lp: incorrect number of initial vectors") + } + ab = mat.NewDense(m, len(initialBasic), nil) + extractColumns(ab, A, initialBasic) + xb = make([]float64, m) + err = initializeFromBasic(xb, ab, b) + if err != nil { + panic(err) + } + basicIdxs = make([]int, len(initialBasic)) + copy(basicIdxs, initialBasic) + } else { + // No initial basis supplied. Solve the PhaseI problem. + basicIdxs, ab, xb, err = findInitialBasic(A, b) + if err != nil { + return math.NaN(), nil, nil, err + } + } + + // basicIdxs contains the indexes for an initial feasible solution, + // ab contains the extracted columns of A, and xb contains the feasible + // solution. All x not in the basic set are 0 by construction. + + // nonBasicIdx is the set of nonbasic variables. + nonBasicIdx := make([]int, 0, n-m) + inBasic := make(map[int]struct{}) + for _, v := range basicIdxs { + inBasic[v] = struct{}{} + } + for i := 0; i < n; i++ { + _, ok := inBasic[i] + if !ok { + nonBasicIdx = append(nonBasicIdx, i) + } + } + + // cb is the subset of c for the basic variables. an and cn + // are the equivalents to ab and cb but for the nonbasic variables. + cb := make([]float64, len(basicIdxs)) + for i, idx := range basicIdxs { + cb[i] = c[idx] + } + cn := make([]float64, len(nonBasicIdx)) + for i, idx := range nonBasicIdx { + cn[i] = c[idx] + } + an := mat.NewDense(m, len(nonBasicIdx), nil) + extractColumns(an, A, nonBasicIdx) + + bVec := mat.NewVecDense(len(b), b) + cbVec := mat.NewVecDense(len(cb), cb) + + // Temporary data needed each iteration. (Described later) + r := make([]float64, n-m) + move := make([]float64, m) + + // Solve the linear program starting from the initial feasible set. This is + // the "Phase 2" problem. + // + // Algorithm: + // 1) Compute the "reduced costs" for the non-basic variables. The reduced + // costs are the lagrange multipliers of the constraints. + // r = cn - an^T * ab^-T * cb + // 2) If all of the reduced costs are positive, no improvement is possible, + // and the solution is optimal (xn can only increase because of + // non-negativity constraints). Otherwise, the solution can be improved and + // one element will be exchanged in the basic set. + // 3) Choose the x_n with the most negative value of r. Call this value xe. + // This variable will be swapped into the basic set. + // 4) Increase xe until the next constraint boundary is met. This will happen + // when the first element in xb becomes 0. The distance xe can increase before + // a given element in xb becomes negative can be found from + // xb = Ab^-1 b - Ab^-1 An xn + // = Ab^-1 b - Ab^-1 Ae xe + // = bhat + d x_e + // xe = bhat_i / - d_i + // where Ae is the column of A corresponding to xe. + // The constraining basic index is the first index for which this is true, + // so remove the element which is min_i (bhat_i / -d_i), assuming d_i is negative. + // If no d_i is less than 0, then the problem is unbounded. + // 5) If the new xe is 0 (that is, bhat_i == 0), then this location is at + // the intersection of several constraints. Use the Bland rule instead + // of the rule in step 4 to avoid cycling. + for { + // Compute reduced costs -- r = cn - an^T ab^-T cb + var tmp mat.VecDense + err = tmp.SolveVec(ab.T(), cbVec) + if err != nil { + break + } + data := make([]float64, n-m) + tmp2 := mat.NewVecDense(n-m, data) + tmp2.MulVec(an.T(), &tmp) + floats.SubTo(r, cn, data) + + // Replace the most negative element in the simplex. If there are no + // negative entries then the optimal solution has been found. + minIdx := floats.MinIdx(r) + if r[minIdx] >= -tol { + break + } + + for i, v := range r { + if math.Abs(v) < rRoundTol { + r[i] = 0 + } + } + + // Compute the moving distance. + err = computeMove(move, minIdx, A, ab, xb, nonBasicIdx) + if err != nil { + if err == ErrUnbounded { + return math.Inf(-1), nil, nil, ErrUnbounded + } + break + } + + // Replace the basic index along the tightest constraint. + replace := floats.MinIdx(move) + if move[replace] <= 0 { + replace, minIdx, err = replaceBland(A, ab, xb, basicIdxs, nonBasicIdx, r, move) + if err != nil { + if err == ErrUnbounded { + return math.Inf(-1), nil, nil, ErrUnbounded + } + break + } + } + + // Replace the constrained basicIdx with the newIdx. + basicIdxs[replace], nonBasicIdx[minIdx] = nonBasicIdx[minIdx], basicIdxs[replace] + cb[replace], cn[minIdx] = cn[minIdx], cb[replace] + tmpCol1 := mat.Col(nil, replace, ab) + tmpCol2 := mat.Col(nil, minIdx, an) + ab.SetCol(replace, tmpCol2) + an.SetCol(minIdx, tmpCol1) + + // Compute the new xb. + xbVec := mat.NewVecDense(len(xb), xb) + err = xbVec.SolveVec(ab, bVec) + if err != nil { + break + } + } + // Found the optimum successfully or died trying. The basic variables get + // their values, and the non-basic variables are all zero. + opt := floats.Dot(cb, xb) + xopt := make([]float64, n) + for i, v := range basicIdxs { + xopt[v] = xb[i] + } + return opt, xopt, basicIdxs, err +} + +// computeMove computes how far can be moved replacing each index. The results +// are stored into move. +func computeMove(move []float64, minIdx int, A mat.Matrix, ab *mat.Dense, xb []float64, nonBasicIdx []int) error { + // Find ae. + col := mat.Col(nil, nonBasicIdx[minIdx], A) + aCol := mat.NewVecDense(len(col), col) + + // d = - Ab^-1 Ae + nb, _ := ab.Dims() + d := make([]float64, nb) + dVec := mat.NewVecDense(nb, d) + err := dVec.SolveVec(ab, aCol) + if err != nil { + return ErrLinSolve + } + floats.Scale(-1, d) + + for i, v := range d { + if math.Abs(v) < dRoundTol { + d[i] = 0 + } + } + + // If no di < 0, then problem is unbounded. + if floats.Min(d) >= 0 { + return ErrUnbounded + } + + // move = bhat_i / - d_i, assuming d is negative. + bHat := xb // ab^-1 b + for i, v := range d { + if v >= 0 { + move[i] = math.Inf(1) + } else { + move[i] = bHat[i] / math.Abs(v) + } + } + return nil +} + +// replaceBland uses the Bland rule to find the indices to swap if the minimum +// move is 0. The indices to be swapped are replace and minIdx (following the +// nomenclature in the main routine). +func replaceBland(A mat.Matrix, ab *mat.Dense, xb []float64, basicIdxs, nonBasicIdx []int, r, move []float64) (replace, minIdx int, err error) { + m, _ := A.Dims() + // Use the traditional bland rule, except don't replace a constraint which + // causes the new ab to be singular. + for i, v := range r { + if v > -blandNegTol { + continue + } + minIdx = i + err = computeMove(move, minIdx, A, ab, xb, nonBasicIdx) + if err != nil { + // Either unbounded or something went wrong. + return -1, -1, err + } + replace = floats.MinIdx(move) + if math.Abs(move[replace]) > blandZeroTol { + // Large enough that it shouldn't be a problem + return replace, minIdx, nil + } + // Find a zero index where replacement is non-singular. + biCopy := make([]int, len(basicIdxs)) + for replace, v := range move { + if v > blandZeroTol { + continue + } + copy(biCopy, basicIdxs) + biCopy[replace] = nonBasicIdx[minIdx] + abTmp := mat.NewDense(m, len(biCopy), nil) + extractColumns(abTmp, A, biCopy) + // If the condition number is reasonable, use this index. + if mat.Cond(abTmp, 1) < 1e16 { + return replace, minIdx, nil + } + } + } + return -1, -1, ErrBland +} + +func verifyInputs(initialBasic []int, c []float64, A mat.Matrix, b []float64) error { + m, n := A.Dims() + if len(c) != n { + panic("lp: c vector incorrect length") + } + if len(b) != m { + panic("lp: b vector incorrect length") + } + if len(c) != n { + panic("lp: c vector incorrect length") + } + if len(initialBasic) != 0 && len(initialBasic) != m { + panic("lp: initialBasic incorrect length") + } + + // Do some sanity checks so that ab does not become singular during the + // simplex solution. If the ZeroRow checks are removed then the code for + // finding a set of linearly indepent columns must be improved. + + // Check that if a row of A only has zero elements that corresponding + // element in b is zero, otherwise the problem is infeasible. + // Otherwise return ErrZeroRow. + for i := 0; i < m; i++ { + isZero := true + for j := 0; j < n; j++ { + if A.At(i, j) != 0 { + isZero = false + break + } + } + if isZero && b[i] != 0 { + // Infeasible + return ErrInfeasible + } else if isZero { + return ErrZeroRow + } + } + // Check that if a column only has zero elements that the respective C vector + // is positive (otherwise unbounded). Otherwise return ErrZeroColumn. + for j := 0; j < n; j++ { + isZero := true + for i := 0; i < m; i++ { + if A.At(i, j) != 0 { + isZero = false + break + } + } + if isZero && c[j] < 0 { + return ErrUnbounded + } else if isZero { + return ErrZeroColumn + } + } + return nil +} + +// initializeFromBasic initializes the basic feasible solution given a set of +// basic indices. It extracts the columns of A specified by basicIdxs and finds +// the x values at that location. These are stored into xb. +// +// If the columns of A are not linearly independent or if the initial set is not +// feasible, an error is returned. +func initializeFromBasic(xb []float64, ab *mat.Dense, b []float64) error { + m, _ := ab.Dims() + if len(xb) != m { + panic("simplex: bad xb length") + } + xbMat := mat.NewVecDense(m, xb) + + err := xbMat.SolveVec(ab, mat.NewVecDense(m, b)) + if err != nil { + return errors.New("lp: subcolumns of A for supplied initial basic singular") + } + // The solve ensures that the equality constraints are met (ab * xb = b). + // Thus, the solution is feasible if and only if all of the x's are positive. + allPos := true + for _, v := range xb { + if v < -initPosTol { + allPos = false + break + } + } + if !allPos { + return errors.New("lp: supplied subcolumns not a feasible solution") + } + return nil +} + +// extractColumns copies the columns specified by cols into the columns of dst. +func extractColumns(dst *mat.Dense, A mat.Matrix, cols []int) { + r, c := dst.Dims() + ra, _ := A.Dims() + if ra != r { + panic("simplex: row mismatch") + } + if c != len(cols) { + panic("simplex: column mismatch") + } + col := make([]float64, r) + for j, idx := range cols { + mat.Col(col, idx, A) + dst.SetCol(j, col) + } +} + +// findInitialBasic finds an initial basic solution, and returns the basic +// indices, ab, and xb. +func findInitialBasic(A mat.Matrix, b []float64) ([]int, *mat.Dense, []float64, error) { + m, n := A.Dims() + basicIdxs := findLinearlyIndependent(A) + if len(basicIdxs) != m { + return nil, nil, nil, ErrSingular + } + + // It may be that this linearly independent basis is also a feasible set. If + // so, the Phase I problem can be avoided. + ab := mat.NewDense(m, len(basicIdxs), nil) + extractColumns(ab, A, basicIdxs) + xb := make([]float64, m) + err := initializeFromBasic(xb, ab, b) + if err == nil { + return basicIdxs, ab, xb, nil + } + + // This set was not feasible. Instead the "Phase I" problem must be solved + // to find an initial feasible set of basis. + // + // Method: Construct an LP whose optimal solution is a feasible solution + // to the original LP. + // 1) Introduce an artificial variable x_{n+1}. + // 2) Let x_j be the most negative element of x_b (largest constraint violation). + // 3) Add the artificial variable to A with: + // a_{n+1} = b - \sum_{i in basicIdxs} a_i + a_j + // swap j with n+1 in the basicIdxs. + // 4) Define a new LP: + // minimize x_{n+1} + // subject to [A A_{n+1}][x_1 ... x_{n+1}] = b + // x, x_{n+1} >= 0 + // 5) Solve this LP. If x_{n+1} != 0, then the problem is infeasible, otherwise + // the found basis can be used as an initial basis for phase II. + // + // The extra column in Step 3 is defined such that the vector of 1s is an + // initial feasible solution. + + // Find the largest constraint violator. + // Compute a_{n+1} = b - \sum{i in basicIdxs}a_i + a_j. j is in basicIDx, so + // instead just subtract the basicIdx columns that are not minIDx. + minIdx := floats.MinIdx(xb) + aX1 := make([]float64, m) + copy(aX1, b) + col := make([]float64, m) + for i, v := range basicIdxs { + if i == minIdx { + continue + } + mat.Col(col, v, A) + floats.Sub(aX1, col) + } + + // Construct the new LP. + // aNew = [A, a_{n+1}] + // bNew = b + // cNew = 1 for x_{n+1} + aNew := mat.NewDense(m, n+1, nil) + aNew.Copy(A) + aNew.SetCol(n, aX1) + basicIdxs[minIdx] = n // swap minIdx with n in the basic set. + c := make([]float64, n+1) + c[n] = 1 + + // Solve the Phase I linear program. + _, xOpt, newBasic, err := simplex(basicIdxs, c, aNew, b, 1e-10) + if err != nil { + return nil, nil, nil, fmt.Errorf("lp: error finding feasible basis: %s", err) + } + + // The original LP is infeasible if the added variable has non-zero value + // in the optimal solution to the Phase I problem. + if math.Abs(xOpt[n]) > phaseIZeroTol { + return nil, nil, nil, ErrInfeasible + } + + // The basis found in Phase I is a feasible solution to the original LP if + // the added variable is not in the basis. + addedIdx := -1 + for i, v := range newBasic { + if v == n { + addedIdx = i + } + xb[i] = xOpt[v] + } + if addedIdx == -1 { + extractColumns(ab, A, newBasic) + return newBasic, ab, xb, nil + } + + // The value of the added variable is in the basis, but it has a zero value. + // See if exchanging another variable into the basic set finds a feasible + // solution. + basicMap := make(map[int]struct{}) + for _, v := range newBasic { + basicMap[v] = struct{}{} + } + var set bool + for i := range xOpt { + if _, inBasic := basicMap[i]; inBasic { + continue + } + newBasic[addedIdx] = i + if set { + mat.Col(col, i, A) + ab.SetCol(addedIdx, col) + } else { + extractColumns(ab, A, newBasic) + set = true + } + err := initializeFromBasic(xb, ab, b) + if err == nil { + return newBasic, ab, xb, nil + } + } + return nil, nil, nil, ErrInfeasible +} + +// findLinearlyIndependnt finds a set of linearly independent columns of A, and +// returns the column indexes of the linearly independent columns. +func findLinearlyIndependent(A mat.Matrix) []int { + m, n := A.Dims() + idxs := make([]int, 0, m) + columns := mat.NewDense(m, m, nil) + newCol := make([]float64, m) + // Walk in reverse order because slack variables are typically the last columns + // of A. + for i := n - 1; i >= 0; i-- { + if len(idxs) == m { + break + } + mat.Col(newCol, i, A) + columns.SetCol(len(idxs), newCol) + if len(idxs) == 0 { + // A column is linearly independent from the null set. + // If all-zero column of A are allowed, this code needs to be adjusted. + idxs = append(idxs, i) + continue + } + if mat.Cond(columns.Slice(0, m, 0, len(idxs)+1), 1) > 1e12 { + // Not linearly independent. + continue + } + idxs = append(idxs, i) + } + return idxs +} diff --git a/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplex_test.go b/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplex_test.go new file mode 100644 index 00000000..75c759b5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplex_test.go @@ -0,0 +1,269 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lp + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +const convergenceTol = 1e-10 + +func TestSimplex(t *testing.T) { + // First test specific inputs. These were collected from failures + // during randomized testing. + // TODO(btracey): Test specific problems with known solutions. + for _, test := range []struct { + A mat.Matrix + b []float64 + c []float64 + tol float64 + initialBasic []int + }{ + { + // Basic feasible LP + A: mat.NewDense(2, 4, []float64{ + -1, 2, 1, 0, + 3, 1, 0, 1, + }), + b: []float64{4, 9}, + c: []float64{-1, -2, 0, 0}, + //initialBasic: nil, + tol: 0, + }, + { + // Zero row that caused linear solver failure + A: mat.NewDense(3, 5, []float64{0.09917822373225804, 0, 0, -0.2588175087223661, -0.5935518220870567, 1.301111422556007, 0.12220247487326946, 0, 0, -1.9194869979254463, 0, 0, 0, 0, -0.8588221231396473}), + b: []float64{0, 0, 0}, + c: []float64{0, 0.598992624019304, 0, 0, 0}, + }, + { + // Case that caused linear solver failure + A: mat.NewDense(13, 26, []float64{-0.7001209024399848, -0.7027502615621812, -0, 0.7354444798695736, -0, 0.476457578966189, 0.7001209024399848, 0.7027502615621812, 0, -0.7354444798695736, 0, -0.476457578966189, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1.8446087238391438, -0, -0, 0.7705609478497938, -0, -0, -2.7311218710244463, 0, 0, -0.7705609478497938, 0, 0, 2.7311218710244463, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, 0.8332519091897401, 0.7762132098737671, -0, -0, -0.052470638647269585, 0, -0.8332519091897401, -0.7762132098737671, 0, 0, 0.052470638647269585, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.9898577208292023, 0.31653724289408824, -0, -0, 0.17797227766447388, 1.2702427184954932, -0.7998764021535656, -0.31653724289408824, 0, 0, -0.17797227766447388, -1.2702427184954932, 0.7998764021535656, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0, -0, -0, 0.4206278126213235, -0.7253374879437113, 0, 0, 0, 0, -0.4206278126213235, 0.7253374879437113, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0.7567988418466963, 0.3304567624749696, 0.8385927625193501, -0.0021606686026376387, -0, 0, 0.7567988418466963, -0.3304567624749696, -0.8385927625193501, 0.0021606686026376387, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2.230107839590404, -0.9897104202085316, -0, 0.24703471683023603, -0, -2.382860345431941, 0.6206871648345162, 0.9897104202085316, 0, -0.24703471683023603, 0, 2.382860345431941, -0.6206871648345162, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 1.4350469221322282, -0.9730343818431852, -0, 2.326429855201535, -0, -0.14347849887004038, -1.4350469221322282, 0.9730343818431852, 0, -2.326429855201535, 0, 0.14347849887004038, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0.7943912888763849, -0.13735037357335078, -0.5101161104860161, -0, -0, -1.4790634590370297, 0.050911195996747316, 0.13735037357335078, 0.5101161104860161, 0, 0, 1.4790634590370297, -0.050911195996747316, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, -0, -0.2515400440591492, 0.2058339272568599, -0, -0, -1.314023802253438, 0, 0.2515400440591492, -0.2058339272568599, 0, 0, 1.314023802253438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0.08279503413614919, -0.16669071891829756, -0, -0.6208413721884664, -0, -0.6348258970402827, -0.08279503413614919, 0.16669071891829756, 0, 0.6208413721884664, 0, 0.6348258970402827, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, -0, -0, 0.49634739711260845, -0, -0, -0, 0, 0, -0.49634739711260845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, -0.2797437186631715, -0.8356683570259136, 1.8970426594969672, -0.4095711945594497, 0.45831284820623924, -0.6109615338552246, 0.2797437186631715, 0.8356683570259136, -1.8970426594969672, 0.4095711945594497, -0.45831284820623924, 0.6109615338552246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1}), + b: []float64{-0.8446087238391436, 0, 1.9898577208292023, 0, 0, -2.230107839590404, 0, 0.20560871112361512, 0, 0, 0, 0, 0}, + c: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + }, + { + // Phase 1 of the above that panicked + A: mat.NewDense(26, 52, []float64{0.7001209024399848, -0, -0, -0.31653724289408824, -0, -0, 0.9897104202085316, -1.4350469221322282, 0.13735037357335078, -0, -0.08279503413614919, -0, 0.2797437186631715, -0.7001209024399848, 0, 0, 0.31653724289408824, 0, 0, -0.9897104202085316, 1.4350469221322282, -0.13735037357335078, 0, 0.08279503413614919, 0, -0.2797437186631715, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7027502615621812, -0, -0.8332519091897401, -0, -0, 0.7567988418466963, -0, 0.9730343818431852, 0.5101161104860161, 0.2515400440591492, 0.16669071891829756, -0, 0.8356683570259136, -0.7027502615621812, 0, 0.8332519091897401, 0, 0, -0.7567988418466963, 0, -0.9730343818431852, -0.5101161104860161, -0.2515400440591492, -0.16669071891829756, 0, -0.8356683570259136, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0.7705609478497938, -0.7762132098737671, -0, -0, -0.3304567624749696, -0.24703471683023603, -0, -0, -0.2058339272568599, -0, -0.49634739711260845, -1.8970426594969672, 0, 0.7705609478497938, 0.7762132098737671, 0, 0, 0.3304567624749696, 0.24703471683023603, 0, 0, 0.2058339272568599, 0, 0.49634739711260845, 1.8970426594969672, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7354444798695736, -0, -0, -0.17797227766447388, -0, -0.8385927625193501, -0, -2.326429855201535, -0, -0, 0.6208413721884664, -0, 0.4095711945594497, 0.7354444798695736, 0, 0, 0.17797227766447388, 0, 0.8385927625193501, 0, 2.326429855201535, 0, 0, -0.6208413721884664, 0, -0.4095711945594497, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1.2702427184954932, -0.4206278126213235, 0.0021606686026376387, 2.382860345431941, -0, 1.4790634590370297, -0, -0, -0, -0.45831284820623924, 0, 0, 0, 1.2702427184954932, 0.4206278126213235, -0.0021606686026376387, -2.382860345431941, 0, -1.4790634590370297, 0, 0, 0, 0.45831284820623924, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.476457578966189, 2.7311218710244463, 0.052470638647269585, 0.7998764021535656, 0.7253374879437113, -0, -0.6206871648345162, 0.14347849887004038, -0.050911195996747316, 1.314023802253438, 0.6348258970402827, -0, 0.6109615338552246, 0.476457578966189, -2.7311218710244463, -0.052470638647269585, -0.7998764021535656, -0.7253374879437113, 0, 0.6206871648345162, -0.14347849887004038, 0.050911195996747316, -1.314023802253438, -0.6348258970402827, 0, -0.6109615338552246, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7001209024399848, -0, -0, 0.31653724289408824, -0, -0, -0.9897104202085316, 1.4350469221322282, -0.13735037357335078, -0, 0.08279503413614919, -0, -0.2797437186631715, 0.7001209024399848, 0, 0, -0.31653724289408824, 0, 0, 0.9897104202085316, -1.4350469221322282, 0.13735037357335078, 0, -0.08279503413614919, 0, 0.2797437186631715, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.7027502615621812, -0, 0.8332519091897401, -0, -0, -0.7567988418466963, -0, -0.9730343818431852, -0.5101161104860161, -0.2515400440591492, -0.16669071891829756, -0, -0.8356683570259136, 0.7027502615621812, 0, -0.8332519091897401, 0, 0, 0.7567988418466963, 0, 0.9730343818431852, 0.5101161104860161, 0.2515400440591492, 0.16669071891829756, 0, 0.8356683570259136, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0.7705609478497938, 0.7762132098737671, -0, -0, 0.3304567624749696, 0.24703471683023603, -0, -0, 0.2058339272568599, -0, 0.49634739711260845, 1.8970426594969672, 0, -0.7705609478497938, -0.7762132098737671, 0, 0, -0.3304567624749696, -0.24703471683023603, 0, 0, -0.2058339272568599, 0, -0.49634739711260845, -1.8970426594969672, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.7354444798695736, -0, -0, 0.17797227766447388, -0, 0.8385927625193501, -0, 2.326429855201535, -0, -0, -0.6208413721884664, -0, -0.4095711945594497, -0.7354444798695736, 0, 0, -0.17797227766447388, 0, -0.8385927625193501, 0, -2.326429855201535, 0, 0, 0.6208413721884664, 0, 0.4095711945594497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, 1.2702427184954932, 0.4206278126213235, -0.0021606686026376387, -2.382860345431941, -0, -1.4790634590370297, -0, -0, -0, 0.45831284820623924, 0, 0, 0, -1.2702427184954932, -0.4206278126213235, 0.0021606686026376387, 2.382860345431941, 0, 1.4790634590370297, 0, 0, 0, -0.45831284820623924, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.476457578966189, -2.7311218710244463, -0.052470638647269585, -0.7998764021535656, -0.7253374879437113, -0, 0.6206871648345162, -0.14347849887004038, 0.050911195996747316, -1.314023802253438, -0.6348258970402827, -0, -0.6109615338552246, -0.476457578966189, 2.7311218710244463, 0.052470638647269585, 0.7998764021535656, 0.7253374879437113, 0, -0.6206871648345162, 0.14347849887004038, -0.050911195996747316, 1.314023802253438, 0.6348258970402827, 0, 0.6109615338552246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1.8446087238391438, 1, -0.9898577208292023, 1, 1, 2.230107839590404, 1, 0.7943912888763849, 1, 1, 1, 1, 1, -1.8446087238391438, -1, 0.9898577208292023, -1, -1, -2.230107839590404, -1, -0.7943912888763849, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + b: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + c: []float64{-0.8446087238391436, 0, 1.9898577208292023, 0, 0, -2.230107839590404, 0, 0.20560871112361512, 0, 0, 0, 0, 0, 0.8446087238391436, -0, -1.9898577208292023, -0, -0, 2.230107839590404, -0, -0.20560871112361512, -0, -0, -0, -0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + { + // Dense case that panicked. + A: mat.NewDense(6, 15, []float64{0.3279477313560112, 0.04126296122557327, 0.24121743535067522, -0.8676933623438741, -0.3279477313560112, -0.04126296122557327, -0.24121743535067522, 0.8676933623438741, 1, 0, 0, 0, 0, 0, 1.3702148909442915, 0.43713186538468607, 0.8613818492485417, -0.9298615442657688, -0.037784779008231184, -0.43713186538468607, -0.8613818492485417, 0.9298615442657688, 0.037784779008231184, 0, 1, 0, 0, 0, 0, 0.3478112701177931, -0, 0.748352668598051, -0.4294796840343912, -0, 0, -0.748352668598051, 0.4294796840343912, 0, 0, 0, 1, 0, 0, 0, -1, -0, 1.1913912184457485, 1.732132186658447, 0.4026384828544584, 0, -1.1913912184457485, -1.732132186658447, -0.4026384828544584, 0, 0, 0, 1, 0, 0, -0.4598555419763902, -0, 1.2088959976921831, -0.7297794575275871, 1.9835614149566971, 0, -1.2088959976921831, 0.7297794575275871, -1.9835614149566971, 0, 0, 0, 0, 1, 0, 0.5986809560819324, 0.19738159369304414, -1.0647198575836367, -0, -0.7264943883762761, -0.19738159369304414, 1.0647198575836367, 0, 0.7264943883762761, 0, 0, 0, 0, 0, 1, 0.36269644970561576}), + b: []float64{2.3702148909442915, 1.3478112701177931, 0, -0.4598555419763902, 1.5986809560819324, 1.3626964497056158}, + c: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + }, + { + A: mat.NewDense(6, 11, []float64{-0.036551083288733854, -0.8967234664797694, 0.036551083288733854, 0.8967234664797694, 1, 0, 0, 0, 0, 0, -0.719908817815329, -1.9043311904524263, -0, 1.9043311904524263, 0, 0, 1, 0, 0, 0, 0, -1.142213296802784, -0, 0.17584914855696687, 0, -0.17584914855696687, 0, 0, 1, 0, 0, 0, -0.5423586338987796, -0.21663357118058713, -0.4815354890024489, 0.21663357118058713, 0.4815354890024489, 0, 0, 0, 1, 0, 0, -0.6864090947259134, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0.4091621839837596, -1.1853040616164046, -0.11374085137543871, 1.1853040616164046, 0.11374085137543871, 0, 0, 0, 0, 0, 1, -1.7416078575675549}), + b: []float64{0.28009118218467105, -0.14221329680278405, 0.4576413661012204, 0.3135909052740866, 1.4091621839837596, -1.7416078575675549}, + c: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + initialBasic: []int{10, 8, 7, 6, 5, 4}, + }, + { + A: mat.NewDense(6, 10, []float64{-0.036551083288733854, -0.8967234664797694, 0.036551083288733854, 0.8967234664797694, 1, 0, 0, 0, 0, 0, -1.9043311904524263, -0, 1.9043311904524263, 0, 0, 1, 0, 0, 0, 0, -0, 0.17584914855696687, 0, -0.17584914855696687, 0, 0, 1, 0, 0, 0, -0.21663357118058713, -0.4815354890024489, 0.21663357118058713, 0.4815354890024489, 0, 0, 0, 1, 0, 0, -0, -0, 0, 0, 0, 0, 0, 0, 1, 0, -1.1853040616164046, -0.11374085137543871, 1.1853040616164046, 0.11374085137543871, 0, 0, 0, 0, 0, 1}), + b: []float64{0.28009118218467105, -0.14221329680278405, 0.4576413661012204, 0.3135909052740866, 1.4091621839837596, -1.7416078575675549}, + c: []float64{-1.1951160054922971, -1.354633418345746, 1.1951160054922971, 1.354633418345746, 0, 0, 0, 0, 0, 0}, + initialBasic: []int{0, 8, 7, 6, 5, 4}, + }, + { + A: mat.NewDense(6, 14, []float64{-0.4398035705048233, -0, -1.1190414559968929, -0, 0.4398035705048233, 0, 1.1190414559968929, 0, 1, 0, 0, 0, 0, 0, -0, 0.45892918156139395, -0, -0, 0, -0.45892918156139395, 0, 0, 0, 1, 0, 0, 0, 0, -0, -0, -0.3163051515958635, -0, 0, 0, 0.3163051515958635, 0, 0, 0, 1, 0, 0, 0, -0, -0, -1.8226051692445888, -0.8154477101733032, 0, 0, 1.8226051692445888, 0.8154477101733032, 0, 0, 0, 1, 0, 0, -0, 1.0020104354806922, -2.80863692523519, -0.8493721031516384, 0, -1.0020104354806922, 2.80863692523519, 0.8493721031516384, 0, 0, 0, 0, 1, 0, -0.8292937871394104, -1.4615144665021647, -0, -0, 0.8292937871394104, 1.4615144665021647, 0, 0, 0, 0, 0, 0, 0, 1}), + b: []float64{0, -1.0154749704172474, 0, 0, 0, -1.5002324315812783}, + c: []float64{1.0665389045026794, 0.097366273706136, 0, 2.7928153636989954, -1.0665389045026794, -0.097366273706136, -0, -2.7928153636989954, 0, 0, 0, 0, 0, 0}, + initialBasic: []int{5, 12, 11, 10, 0, 8}, + }, + { + // Bad Phase I setup. + A: mat.NewDense(6, 7, []float64{1.4009742075419371, 0, 0.05737255493210325, -2.5954004393412915, 0, 1.561789236911904, 0, 0.17152506517602673, 0, 0, 0, 0, 0, -0.3458126550149948, 1.900744052464951, -0.32773164134097343, -0.9648201331251137, 0, 0, 0, 0, -1.3229549190526497, 0.0692227703722903, 0, 0, -0.1024297720479933, 0.4550740188869777, 0, 0.013599438965679167, 0, 0, 0, 0, 0, -0.1164365105021209, 0, 0, 0.4077091957443405, 1.5682816151954875, 0.8411734682369051, 0.22379142247562167, 1.2206581060250778}), + b: []float64{0.3293809220378252, 0, -0.5688424847664554, 0, 0, 1.4832526082339592}, + c: []float64{0.5246370956983506, -0.36608819899109946, 1.5854141981237713, 0.5170486527020665, 0, 1.4006819866163691, 0.7733814538809437}, + }, + { + // The problem is feasible, but the PhaseI problem keeps the last + // variable in the basis. + A: mat.NewDense(2, 3, []float64{0.7171320440380402, 0, 0.22818288617480836, 0, -0.10030202006494793, -0.3282372661549324}), + b: []float64{0.8913013436978257, 0}, + c: []float64{0, 0, 1.16796158316812}, + initialBasic: nil, + }, + { + // Case where primal was returned as feasible, but the dual was returned + // as infeasible. This is the dual. + // Here, the phase I problem returns the value in the basis but equal + // to epsilon and not 0. + A: mat.NewDense(5, 11, []float64{0.48619717875196006, 0.5089083769874058, 1.4064796473022745, -0.48619717875196006, -0.5089083769874058, -1.4064796473022745, 1, 0, 0, 0, 0, 1.5169837857318682, -0, -0, -1.5169837857318682, 0, 0, 0, 1, 0, 0, 0, -1.3096160896447528, 0.12600426735917414, 0.296082394213142, 1.3096160896447528, -0.12600426735917414, -0.296082394213142, 0, 0, 1, 0, 0, -0, -0, 1.9870800277141467, 0, 0, -1.9870800277141467, 0, 0, 0, 1, 0, -0.3822356988571877, -0, -0.1793908926957139, 0.3822356988571877, 0, 0.1793908926957139, 0, 0, 0, 0, 1}), + b: []float64{0.6015865977347667, 0, -1.5648780993757594, 0, 0}, + c: []float64{-0.642801659201449, -0.5412741400343285, -1.4634460998530177, 0.642801659201449, 0.5412741400343285, 1.4634460998530177, 0, 0, 0, 0, 0}, + }, + { + // Caused linear solve error. The error is because replacing the minimum + // index in Bland causes the new basis to be singular. This + // necessitates the ending loop in bland over possible moves. + A: mat.NewDense(9, 23, []float64{-0.898219823758102, -0, -0, -0, 1.067555075209233, 1.581598470243863, -1.0656096883610071, 0.898219823758102, 0, 0, 0, -1.067555075209233, -1.581598470243863, 1.0656096883610071, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1.5657353278668433, 0.5798888118401012, -0, 0.14560553520321928, -0, -0, -0, 1.5657353278668433, -0.5798888118401012, 0, -0.14560553520321928, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -0, -0, -1.5572250142582087, -0, -0, -0, -0, 0, 0, 1.5572250142582087, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, -0, -0, -1.1266215512973428, -0, 1.0661059397023553, -0, 0, 0, 0, 1.1266215512973428, 0, -1.0661059397023553, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, -2.060232129551813, 1.756900609902372, -0, -0, -0, -0, 0, 2.060232129551813, -1.756900609902372, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.0628806512935949, -0, -0, 0.3306985942820342, -0, 0.5013194822231914, -0, -1.0628806512935949, 0, 0, -0.3306985942820342, 0, -0.5013194822231914, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0.02053916418367785, 2.0967009672108627, -0, 1.276296057052031, -0, -0.8396554873675388, -0, 0.02053916418367785, -2.0967009672108627, 0, -1.276296057052031, 0, 0.8396554873675388, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1.5173172721095745, -0, -0, -0, -0, -0.7781977786718928, -0.08927683907374018, 1.5173172721095745, 0, 0, 0, 0, 0.7781977786718928, 0.08927683907374018, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, -0, -0, -0, -0, 0.39773149008355624, -0, 0, 0, 0, 0, 0, -0.39773149008355624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + b: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0}, + c: []float64{0.24547850255842107, -0.9373919913433648, 0, 0, 0, 0.2961224049153204, 0, -0.24547850255842107, 0.9373919913433648, -0, -0, -0, -0.2961224049153204, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + { + // Caused error because ALL of the possible replacements in Bland cause. + // ab to be singular. This necessitates outer loop in bland over possible + // moves. + A: mat.NewDense(9, 23, []float64{0.6595219196440785, -0, -0, -1.8259394918781682, -0, -0, 0.005457361044175046, -0.6595219196440785, 0, 0, 1.8259394918781682, 0, 0, -0.005457361044175046, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, -0.10352878714214864, -0, -0, -0, -0, 0.5945016966696087, 0, 0.10352878714214864, 0, 0, 0, 0, -0.5945016966696087, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0.31734882842876444, -0, -0, -0, -0, -0, -0.716633126367685, -0.31734882842876444, 0, 0, 0, 0, 0, 0.716633126367685, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0.7769812182932578, -0, -0.17370050158829553, 0.19405062263734607, -0, 1.1472330031002533, -0.6776631768730962, 0.7769812182932578, 0, 0.17370050158829553, -0.19405062263734607, 0, -1.1472330031002533, 0.6776631768730962, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0.8285611486611473, -0, -0, -0, -0, -0, 0, -0.8285611486611473, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -2.088953453647358, 1.3286488791152795, -0, -0, -0, -0, 0.9147833235021142, 2.088953453647358, -1.3286488791152795, 0, 0, 0, 0, -0.9147833235021142, 0, 0, 0, 0, 0, 1, 0, 0, 0, -0, -0, -0, -0, 0.6560365621262937, -0, -0, 0, 0, 0, 0, -0.6560365621262937, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0.8957188338098074, -0, -0, -0, -0, -0, -0, -0.8957188338098074, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0.2761381891117365, -0, -0, -0, 1.1154921426237823, 0.06429872020552618, -0, 0.2761381891117365, 0, 0, 0, -1.1154921426237823, -0.06429872020552618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), + b: []float64{0, 0, 0, 0, 0.5046208538522362, 1.0859412982429362, -2.066283584195025, 0, -0.2604305274353169}, + c: []float64{0, 0, 0, 0, 0, 0, -0.05793762969330718, -0, -0, -0, -0, -0, -0, 0.05793762969330718, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + initialBasic: []int{22, 11, 7, 19, 18, 17, 16, 15, 14}, + }, + { + // Caused initial supplied basis of Phase I to be singular. + A: mat.NewDense(7, 11, []float64{0, 0, 0, 0, 0, 0.6667874223914787, -0.04779440888372957, -0.810020924434026, 0, 1.4190243477163373, 0, 0, 1.0452496826112936, 1.1966134226828076, 0, 0, 0, 0, -0.676136041089015, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2.123232807871834, 0.2795467733707712, 0.21997115467272987, 0, -0.1572003980840453, 0, 0, 0, 0, 0.5130196002804861, 0, -0.005957174211761673, 0.3262874931735277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.5582052881594286, 0, 0.3544026193217651, 0, -1.0761986709145068, 0, 0.2438593072108347, 0, 0, 0, 0, 1.387509848081664, 0, 0, 0.3958750570508226, 1.6281679612990678, 0, 0, -0.24638311667922103, 0, 0, 0, 0, 0, 0, -0.628850893994423}), + b: []float64{0.4135281763629115, 0, 0, 0, 0, 0, 0}, + c: []float64{0.5586772876113472, 0, 0.14261332948424457, 0, -0.016394076753000086, -0.506087285562544, 0, 0.37619482505459145, 1.2943822852419233, 0.5887960293578207, 0}, + }, + } { + testSimplex(t, test.initialBasic, test.c, test.A, test.b, convergenceTol) + } + + rnd := rand.New(rand.NewSource(1)) + // Randomized tests + testRandomSimplex(t, 20000, 0.7, 10, rnd) + testRandomSimplex(t, 20000, 0, 10, rnd) + testRandomSimplex(t, 200, 0, 100, rnd) + testRandomSimplex(t, 2, 0, 400, rnd) +} + +func testRandomSimplex(t *testing.T, nTest int, pZero float64, maxN int, rnd *rand.Rand) { + // Try a bunch of random LPs + for i := 0; i < nTest; i++ { + n := rnd.Intn(maxN) + 2 // n must be at least two. + m := rnd.Intn(n-1) + 1 // m must be between 1 and n + if m == 0 || n == 0 { + continue + } + randValue := func() float64 { + //var pZero float64 + v := rnd.Float64() + if v < pZero { + return 0 + } + return rnd.NormFloat64() + } + a := mat.NewDense(m, n, nil) + for i := 0; i < m; i++ { + for j := 0; j < n; j++ { + a.Set(i, j, randValue()) + } + } + b := make([]float64, m) + for i := range b { + b[i] = randValue() + } + + c := make([]float64, n) + for i := range c { + c[i] = randValue() + } + + testSimplex(t, nil, c, a, b, convergenceTol) + } +} + +func testSimplex(t *testing.T, initialBasic []int, c []float64, a mat.Matrix, b []float64, convergenceTol float64) error { + primalOpt, primalX, _, errPrimal := simplex(initialBasic, c, a, b, convergenceTol) + if errPrimal == nil { + // No error solving the simplex, check that the solution is feasible. + var bCheck mat.VecDense + bCheck.MulVec(a, mat.NewVecDense(len(primalX), primalX)) + if !mat.EqualApprox(&bCheck, mat.NewVecDense(len(b), b), 1e-10) { + t.Errorf("No error in primal but solution infeasible") + } + } + + primalInfeasible := errPrimal == ErrInfeasible + primalUnbounded := errPrimal == ErrUnbounded + primalBounded := errPrimal == nil + primalASingular := errPrimal == ErrSingular + primalZeroRow := errPrimal == ErrZeroRow + primalZeroCol := errPrimal == ErrZeroColumn + + primalBad := !primalInfeasible && !primalUnbounded && !primalBounded && !primalASingular && !primalZeroRow && !primalZeroCol + + // It's an error if it's not one of the known returned errors. If it's + // singular the problem is undefined and so the result cannot be compared + // to the dual. + if errPrimal == ErrSingular || primalBad { + if primalBad { + t.Errorf("non-known error returned: %s", errPrimal) + } + return errPrimal + } + + // Compare the result to the answer found from solving the dual LP. + + // Construct and solve the dual LP. + // Standard Form: + // minimize c^T * x + // subject to A * x = b, x >= 0 + // The dual of this problem is + // maximize -b^T * nu + // subject to A^T * nu + c >= 0 + // Which is + // minimize b^T * nu + // subject to -A^T * nu <= c + + negAT := &mat.Dense{} + negAT.Clone(a.T()) + negAT.Scale(-1, negAT) + cNew, aNew, bNew := Convert(b, negAT, c, nil, nil) + + dualOpt, dualX, _, errDual := simplex(nil, cNew, aNew, bNew, convergenceTol) + if errDual == nil { + // Check that the dual is feasible + var bCheck mat.VecDense + bCheck.MulVec(aNew, mat.NewVecDense(len(dualX), dualX)) + if !mat.EqualApprox(&bCheck, mat.NewVecDense(len(bNew), bNew), 1e-10) { + t.Errorf("No error in dual but solution infeasible") + } + } + + // Check about the zero status. + if errPrimal == ErrZeroRow || errPrimal == ErrZeroColumn { + return errPrimal + } + + // If the primal problem is feasible, then the primal and the dual should + // be the same answer. We have flopped the sign in the dual (minimizing + // b^T *nu instead of maximizing -b^T*nu), so flip it back. + if errPrimal == nil { + if errDual != nil { + t.Errorf("Primal feasible but dual errored: %s", errDual) + } + dualOpt *= -1 + if !floats.EqualWithinAbsOrRel(dualOpt, primalOpt, convergenceTol, convergenceTol) { + t.Errorf("Primal and dual value mismatch. Primal %v, dual %v.", primalOpt, dualOpt) + } + } + // If the primal problem is unbounded, then the dual should be infeasible. + if errPrimal == ErrUnbounded && errDual != ErrInfeasible { + t.Errorf("Primal unbounded but dual not infeasible. ErrDual = %s", errDual) + } + + // If the dual is unbounded, then the primal should be infeasible. + if errDual == ErrUnbounded && errPrimal != ErrInfeasible { + t.Errorf("Dual unbounded but primal not infeasible. ErrDual = %s", errPrimal) + } + + // If the primal is infeasible, then the dual should be either infeasible + // or unbounded. + if errPrimal == ErrInfeasible { + if errDual != ErrUnbounded && errDual != ErrInfeasible && errDual != ErrZeroColumn { + t.Errorf("Primal infeasible but dual not infeasible or unbounded: %s", errDual) + } + } + + return errPrimal +} diff --git a/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplexexample_test.go b/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplexexample_test.go new file mode 100644 index 00000000..b0daa314 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/convex/lp/simplexexample_test.go @@ -0,0 +1,29 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lp_test + +import ( + "fmt" + "log" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/optimize/convex/lp" +) + +func ExampleSimplex() { + c := []float64{-1, -2, 0, 0} + A := mat.NewDense(2, 4, []float64{-1, 2, 1, 0, 3, 1, 0, 1}) + b := []float64{4, 9} + + opt, x, err := lp.Simplex(c, A, b, 0, nil) + if err != nil { + log.Fatal(err) + } + fmt.Printf("opt: %v\n", opt) + fmt.Printf("x: %v\n", x) + // Output: + // opt: -8 + // x: [2 3 0 0] +} diff --git a/vendor/gonum.org/v1/gonum/optimize/doc.go b/vendor/gonum.org/v1/gonum/optimize/doc.go new file mode 100644 index 00000000..1b05a639 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/doc.go @@ -0,0 +1,6 @@ +// 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 optimize implements algorithms for finding the optimum value of functions. +package optimize // import "gonum.org/v1/gonum/optimize" diff --git a/vendor/gonum.org/v1/gonum/optimize/errors.go b/vendor/gonum.org/v1/gonum/optimize/errors.go new file mode 100644 index 00000000..07bf5df9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/errors.go @@ -0,0 +1,72 @@ +// 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 optimize + +import ( + "errors" + "fmt" + "math" +) + +var ( + // ErrZeroDimensional signifies an optimization was called with an input of length 0. + ErrZeroDimensional = errors.New("optimize: zero dimensional input") + + // ErrLinesearcherFailure signifies that a Linesearcher has iterated too + // many times. This may occur if the gradient tolerance is set too low. + ErrLinesearcherFailure = errors.New("linesearch: failed to converge") + + // ErrNonDescentDirection signifies that LinesearchMethod has received a + // search direction from a NextDirectioner in which the function is not + // decreasing. + ErrNonDescentDirection = errors.New("linesearch: non-descent search direction") + + // ErrNoProgress signifies that LinesearchMethod cannot make further + // progress because there is no change in location after Linesearcher step + // due to floating-point arithmetic. + ErrNoProgress = errors.New("linesearch: no change in location after Linesearcher step") + + // ErrLinesearcherBound signifies that a Linesearcher reached a step that + // lies out of allowed bounds. + ErrLinesearcherBound = errors.New("linesearch: step out of bounds") +) + +// ErrFunc is returned when an initial function value is invalid. The error +// state may be either +Inf or NaN. ErrFunc satisfies the error interface. +type ErrFunc float64 + +func (err ErrFunc) Error() string { + switch { + case math.IsInf(float64(err), 1): + return "optimize: initial function value is infinite" + case math.IsNaN(float64(err)): + return "optimize: initial function value is NaN" + default: + panic("optimize: bad ErrFunc") + } +} + +// ErrGrad is returned when an initial gradient is invalid. The error gradient +// may be either ±Inf or NaN. ErrGrad satisfies the error interface. +type ErrGrad struct { + Grad float64 // Grad is the invalid gradient value. + Index int // Index is the position at which the invalid gradient was found. +} + +func (err ErrGrad) Error() string { + switch { + case math.IsInf(err.Grad, 0): + return fmt.Sprintf("optimize: initial gradient is infinite at position %d", err.Index) + case math.IsNaN(err.Grad): + return fmt.Sprintf("optimize: initial gradient is NaN at position %d", err.Index) + default: + panic("optimize: bad ErrGrad") + } +} + +// List of shared panic strings +var ( + badProblem = "optimize: objective function is undefined" +) diff --git a/vendor/gonum.org/v1/gonum/optimize/functionconvergence.go b/vendor/gonum.org/v1/gonum/optimize/functionconvergence.go new file mode 100644 index 00000000..c532072d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functionconvergence.go @@ -0,0 +1,40 @@ +// 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 optimize + +import "math" + +// FunctionConverge tests for the convergence of function values. See comment +// in Settings. +type FunctionConverge struct { + Absolute float64 + Relative float64 + Iterations int + + best float64 + iter int +} + +func (fc *FunctionConverge) Init(f float64) { + fc.best = f + fc.iter = 0 +} + +func (fc *FunctionConverge) FunctionConverged(f float64) Status { + if fc.Iterations == 0 { + return NotTerminated + } + maxAbs := math.Max(math.Abs(f), math.Abs(fc.best)) + if f < fc.best && fc.best-f > fc.Relative*maxAbs+fc.Absolute { + fc.best = f + fc.iter = 0 + return NotTerminated + } + fc.iter++ + if fc.iter < fc.Iterations { + return NotTerminated + } + return FunctionConvergence +} diff --git a/vendor/gonum.org/v1/gonum/optimize/functions/doc.go b/vendor/gonum.org/v1/gonum/optimize/functions/doc.go new file mode 100644 index 00000000..3bdfe8bf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functions/doc.go @@ -0,0 +1,15 @@ +// 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 functions provides objective functions for testing optimization +// algorithms. +// +// We encourage outside contributions of additional test functions that exhibit +// properties not already covered in the testing suite or that have +// significance due to prior use as benchmark cases. +package functions // import "gonum.org/v1/gonum/optimize/functions" + +const ( + badInputDim = "functions: wrong input dimension" +) diff --git a/vendor/gonum.org/v1/gonum/optimize/functions/functions.go b/vendor/gonum.org/v1/gonum/optimize/functions/functions.go new file mode 100644 index 00000000..43a4c948 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functions/functions.go @@ -0,0 +1,1818 @@ +// 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 functions + +import ( + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +// Beale implements the Beale's function. +// +// Standard starting points: +// Easy: [1, 1] +// Hard: [1, 4] +// +// References: +// - Beale, E.: On an Iterative Method for Finding a Local Minimum of a +// Function of More than One Variable. Technical Report 25, Statistical +// Techniques Research Group, Princeton University (1958) +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type Beale struct{} + +func (Beale) Func(x []float64) float64 { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + + f1 := 1.5 - x[0]*(1-x[1]) + f2 := 2.25 - x[0]*(1-x[1]*x[1]) + f3 := 2.625 - x[0]*(1-x[1]*x[1]*x[1]) + return f1*f1 + f2*f2 + f3*f3 +} + +func (Beale) Grad(grad, x []float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + t1 := 1 - x[1] + t2 := 1 - x[1]*x[1] + t3 := 1 - x[1]*x[1]*x[1] + + f1 := 1.5 - x[0]*t1 + f2 := 2.25 - x[0]*t2 + f3 := 2.625 - x[0]*t3 + + grad[0] = -2 * (f1*t1 + f2*t2 + f3*t3) + grad[1] = 2 * x[0] * (f1 + 2*f2*x[1] + 3*f3*x[1]*x[1]) +} + +func (Beale) Hess(hess mat.MutableSymmetric, x []float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + if len(x) != hess.Symmetric() { + panic("incorrect size of the Hessian") + } + + t1 := 1 - x[1] + t2 := 1 - x[1]*x[1] + t3 := 1 - x[1]*x[1]*x[1] + f1 := 1.5 - x[1]*t1 + f2 := 2.25 - x[1]*t2 + f3 := 2.625 - x[1]*t3 + + h00 := 2 * (t1*t1 + t2*t2 + t3*t3) + h01 := 2 * (f1 + x[1]*(2*f2+3*x[1]*f3) - x[0]*(t1+x[1]*(2*t2+3*x[1]*t3))) + h11 := 2 * x[0] * (x[0] + 2*f2 + x[1]*(6*f3+x[0]*x[1]*(4+9*x[1]*x[1]))) + hess.SetSym(0, 0, h00) + hess.SetSym(0, 1, h01) + hess.SetSym(1, 1, h11) +} + +func (Beale) Minima() []Minimum { + return []Minimum{ + { + X: []float64{3, 0.5}, + F: 0, + Global: true, + }, + } +} + +// BiggsEXP2 implements the the Biggs' EXP2 function. +// +// Standard starting point: +// [1, 2] +// +// Reference: +// Biggs, M.C.: Minimization algorithms making use of non-quadratic properties +// of the objective function. IMA J Appl Math 8 (1971), 315-327; doi:10.1093/imamat/8.3.315 +type BiggsEXP2 struct{} + +func (BiggsEXP2) Func(x []float64) (sum float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + + for i := 1; i <= 10; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + f := math.Exp(-x[0]*z) - 5*math.Exp(-x[1]*z) - y + sum += f * f + } + return sum +} + +func (BiggsEXP2) Grad(grad, x []float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 10; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + f := math.Exp(-x[0]*z) - 5*math.Exp(-x[1]*z) - y + + dfdx0 := -z * math.Exp(-x[0]*z) + dfdx1 := 5 * z * math.Exp(-x[1]*z) + + grad[0] += 2 * f * dfdx0 + grad[1] += 2 * f * dfdx1 + } +} + +func (BiggsEXP2) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 10}, + F: 0, + Global: true, + }, + } +} + +// BiggsEXP3 implements the the Biggs' EXP3 function. +// +// Standard starting point: +// [1, 2, 1] +// +// Reference: +// Biggs, M.C.: Minimization algorithms making use of non-quadratic properties +// of the objective function. IMA J Appl Math 8 (1971), 315-327; doi:10.1093/imamat/8.3.315 +type BiggsEXP3 struct{} + +func (BiggsEXP3) Func(x []float64) (sum float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + + for i := 1; i <= 10; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + f := math.Exp(-x[0]*z) - x[2]*math.Exp(-x[1]*z) - y + sum += f * f + } + return sum +} + +func (BiggsEXP3) Grad(grad, x []float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 10; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + f := math.Exp(-x[0]*z) - x[2]*math.Exp(-x[1]*z) - y + + dfdx0 := -z * math.Exp(-x[0]*z) + dfdx1 := x[2] * z * math.Exp(-x[1]*z) + dfdx2 := -math.Exp(-x[1] * z) + + grad[0] += 2 * f * dfdx0 + grad[1] += 2 * f * dfdx1 + grad[2] += 2 * f * dfdx2 + } +} + +func (BiggsEXP3) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 10, 5}, + F: 0, + Global: true, + }, + } +} + +// BiggsEXP4 implements the the Biggs' EXP4 function. +// +// Standard starting point: +// [1, 2, 1, 1] +// +// Reference: +// Biggs, M.C.: Minimization algorithms making use of non-quadratic properties +// of the objective function. IMA J Appl Math 8 (1971), 315-327; doi:10.1093/imamat/8.3.315 +type BiggsEXP4 struct{} + +func (BiggsEXP4) Func(x []float64) (sum float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + + for i := 1; i <= 10; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + f := x[2]*math.Exp(-x[0]*z) - x[3]*math.Exp(-x[1]*z) - y + sum += f * f + } + return sum +} + +func (BiggsEXP4) Grad(grad, x []float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 10; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + f := x[2]*math.Exp(-x[0]*z) - x[3]*math.Exp(-x[1]*z) - y + + dfdx0 := -z * x[2] * math.Exp(-x[0]*z) + dfdx1 := z * x[3] * math.Exp(-x[1]*z) + dfdx2 := math.Exp(-x[0] * z) + dfdx3 := -math.Exp(-x[1] * z) + + grad[0] += 2 * f * dfdx0 + grad[1] += 2 * f * dfdx1 + grad[2] += 2 * f * dfdx2 + grad[3] += 2 * f * dfdx3 + } +} + +func (BiggsEXP4) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 10, 1, 5}, + F: 0, + Global: true, + }, + } +} + +// BiggsEXP5 implements the the Biggs' EXP5 function. +// +// Standard starting point: +// [1, 2, 1, 1, 1] +// +// Reference: +// Biggs, M.C.: Minimization algorithms making use of non-quadratic properties +// of the objective function. IMA J Appl Math 8 (1971), 315-327; doi:10.1093/imamat/8.3.315 +type BiggsEXP5 struct{} + +func (BiggsEXP5) Func(x []float64) (sum float64) { + if len(x) != 5 { + panic("dimension of the problem must be 5") + } + + for i := 1; i <= 11; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + 3*math.Exp(-4*z) + f := x[2]*math.Exp(-x[0]*z) - x[3]*math.Exp(-x[1]*z) + 3*math.Exp(-x[4]*z) - y + sum += f * f + } + return sum +} + +func (BiggsEXP5) Grad(grad, x []float64) { + if len(x) != 5 { + panic("dimension of the problem must be 5") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 11; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + 3*math.Exp(-4*z) + f := x[2]*math.Exp(-x[0]*z) - x[3]*math.Exp(-x[1]*z) + 3*math.Exp(-x[4]*z) - y + + dfdx0 := -z * x[2] * math.Exp(-x[0]*z) + dfdx1 := z * x[3] * math.Exp(-x[1]*z) + dfdx2 := math.Exp(-x[0] * z) + dfdx3 := -math.Exp(-x[1] * z) + dfdx4 := -3 * z * math.Exp(-x[4]*z) + + grad[0] += 2 * f * dfdx0 + grad[1] += 2 * f * dfdx1 + grad[2] += 2 * f * dfdx2 + grad[3] += 2 * f * dfdx3 + grad[4] += 2 * f * dfdx4 + } +} + +func (BiggsEXP5) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 10, 1, 5, 4}, + F: 0, + Global: true, + }, + } +} + +// BiggsEXP6 implements the the Biggs' EXP6 function. +// +// Standard starting point: +// [1, 2, 1, 1, 1, 1] +// +// References: +// - Biggs, M.C.: Minimization algorithms making use of non-quadratic +// properties of the objective function. IMA J Appl Math 8 (1971), 315-327; +// doi:10.1093/imamat/8.3.315 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type BiggsEXP6 struct{} + +func (BiggsEXP6) Func(x []float64) (sum float64) { + if len(x) != 6 { + panic("dimension of the problem must be 6") + } + + for i := 1; i <= 13; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + 3*math.Exp(-4*z) + f := x[2]*math.Exp(-x[0]*z) - x[3]*math.Exp(-x[1]*z) + x[5]*math.Exp(-x[4]*z) - y + sum += f * f + } + return sum +} + +func (BiggsEXP6) Grad(grad, x []float64) { + if len(x) != 6 { + panic("dimension of the problem must be 6") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 13; i++ { + z := float64(i) / 10 + y := math.Exp(-z) - 5*math.Exp(-10*z) + 3*math.Exp(-4*z) + f := x[2]*math.Exp(-x[0]*z) - x[3]*math.Exp(-x[1]*z) + x[5]*math.Exp(-x[4]*z) - y + + dfdx0 := -z * x[2] * math.Exp(-x[0]*z) + dfdx1 := z * x[3] * math.Exp(-x[1]*z) + dfdx2 := math.Exp(-x[0] * z) + dfdx3 := -math.Exp(-x[1] * z) + dfdx4 := -z * x[5] * math.Exp(-x[4]*z) + dfdx5 := math.Exp(-x[4] * z) + + grad[0] += 2 * f * dfdx0 + grad[1] += 2 * f * dfdx1 + grad[2] += 2 * f * dfdx2 + grad[3] += 2 * f * dfdx3 + grad[4] += 2 * f * dfdx4 + grad[5] += 2 * f * dfdx5 + } +} + +func (BiggsEXP6) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 10, 1, 5, 4, 3}, + F: 0, + Global: true, + }, + { + X: []float64{1.7114159947956764, 17.68319817846745, 1.1631436609697268, + 5.1865615510738605, 1.7114159947949301, 1.1631436609697998}, + F: 0.005655649925499929, + Global: false, + }, + { + // X: []float64{1.22755594752403, X[1] >> 0, 0.83270306333466, X[3] << 0, X[4] = X[0], X[5] = X[2]}, + X: []float64{1.22755594752403, 1000, 0.83270306333466, -1000, 1.22755594752403, 0.83270306333466}, + F: 0.306366772624790, + Global: false, + }, + } +} + +// Box3D implements the Box' three-dimensional function. +// +// Standard starting point: +// [0, 10, 20] +// +// References: +// - Box, M.J.: A comparison of several current optimization methods, and the +// use of transformations in constrained problems. Comput J 9 (1966), 67-77 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type Box3D struct{} + +func (Box3D) Func(x []float64) (sum float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + + for i := 1; i <= 10; i++ { + c := -float64(i) / 10 + y := math.Exp(c) - math.Exp(10*c) + f := math.Exp(c*x[0]) - math.Exp(c*x[1]) - x[2]*y + sum += f * f + } + return sum +} + +func (Box3D) Grad(grad, x []float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + grad[0] = 0 + grad[1] = 0 + grad[2] = 0 + for i := 1; i <= 10; i++ { + c := -float64(i) / 10 + y := math.Exp(c) - math.Exp(10*c) + f := math.Exp(c*x[0]) - math.Exp(c*x[1]) - x[2]*y + grad[0] += 2 * f * c * math.Exp(c*x[0]) + grad[1] += -2 * f * c * math.Exp(c*x[1]) + grad[2] += -2 * f * y + } +} + +func (Box3D) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 10, 1}, + F: 0, + Global: true, + }, + { + X: []float64{10, 1, -1}, + F: 0, + Global: true, + }, + { + // Any point at the line {a, a, 0}. + X: []float64{1, 1, 0}, + F: 0, + Global: true, + }, + } +} + +// BraninHoo implements the Branin-Hoo function. BraninHoo is a 2-dimensional +// test function with three global minima. It is typically evaluated in the domain +// x_0 ∈ [-5, 10], x_1 ∈ [0, 15]. +// f(x) = (x_1 - (5.1/(4π^2))*x_0^2 + (5/π)*x_0 - 6)^2 + 10*(1-1/(8π))cos(x_0) + 10 +// It has a minimum value of 0.397887 at x^* = {(-π, 12.275), (π, 2.275), (9.424778, 2.475)} +// +// Reference: +// https://www.sfu.ca/~ssurjano/branin.html (obtained June 2017) +type BraninHoo struct{} + +func (BraninHoo) Func(x []float64) float64 { + if len(x) != 2 { + panic("functions: dimension of the problem must be 2") + } + a, b, c, r, s, t := 1.0, 5.1/(4*math.Pi*math.Pi), 5/math.Pi, 6.0, 10.0, 1/(8*math.Pi) + + term := x[1] - b*x[0]*x[0] + c*x[0] - r + return a*term*term + s*(1-t)*math.Cos(x[0]) + s +} + +func (BraninHoo) Minima() []Minimum { + return []Minimum{ + { + X: []float64{-math.Pi, 12.275}, + F: 0.397887, + Global: true, + }, + { + X: []float64{math.Pi, 2.275}, + F: 0.397887, + Global: true, + }, + { + X: []float64{9.424778, 2.475}, + F: 0.397887, + Global: true, + }, + } +} + +// BrownBadlyScaled implements the Brown's badly scaled function. +// +// Standard starting point: +// [1, 1] +// +// References: +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type BrownBadlyScaled struct{} + +func (BrownBadlyScaled) Func(x []float64) float64 { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + + f1 := x[0] - 1e6 + f2 := x[1] - 2e-6 + f3 := x[0]*x[1] - 2 + return f1*f1 + f2*f2 + f3*f3 +} + +func (BrownBadlyScaled) Grad(grad, x []float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + f1 := x[0] - 1e6 + f2 := x[1] - 2e-6 + f3 := x[0]*x[1] - 2 + grad[0] = 2*f1 + 2*f3*x[1] + grad[1] = 2*f2 + 2*f3*x[0] +} + +func (BrownBadlyScaled) Hess(hess mat.MutableSymmetric, x []float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + if len(x) != hess.Symmetric() { + panic("incorrect size of the Hessian") + } + + h00 := 2 + 2*x[1]*x[1] + h01 := 4*x[0]*x[1] - 4 + h11 := 2 + 2*x[0]*x[0] + hess.SetSym(0, 0, h00) + hess.SetSym(0, 1, h01) + hess.SetSym(1, 1, h11) +} + +func (BrownBadlyScaled) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1e6, 2e-6}, + F: 0, + Global: true, + }, + } +} + +// BrownAndDennis implements the Brown and Dennis function. +// +// Standard starting point: +// [25, 5, -5, -1] +// +// References: +// - Brown, K.M., Dennis, J.E.: New computational algorithms for minimizing a +// sum of squares of nonlinear functions. Research Report Number 71-6, Yale +// University (1971) +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type BrownAndDennis struct{} + +func (BrownAndDennis) Func(x []float64) (sum float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + + for i := 1; i <= 20; i++ { + c := float64(i) / 5 + f1 := x[0] + c*x[1] - math.Exp(c) + f2 := x[2] + x[3]*math.Sin(c) - math.Cos(c) + f := f1*f1 + f2*f2 + sum += f * f + } + return sum +} + +func (BrownAndDennis) Grad(grad, x []float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 20; i++ { + c := float64(i) / 5 + f1 := x[0] + c*x[1] - math.Exp(c) + f2 := x[2] + x[3]*math.Sin(c) - math.Cos(c) + f := f1*f1 + f2*f2 + grad[0] += 4 * f * f1 + grad[1] += 4 * f * f1 * c + grad[2] += 4 * f * f2 + grad[3] += 4 * f * f2 * math.Sin(c) + } +} + +func (BrownAndDennis) Hess(hess mat.MutableSymmetric, x []float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + if len(x) != hess.Symmetric() { + panic("incorrect size of the Hessian") + } + + for i := 0; i < 4; i++ { + for j := i; j < 4; j++ { + hess.SetSym(i, j, 0) + } + } + for i := 1; i <= 20; i++ { + d1 := float64(i) / 5 + d2 := math.Sin(d1) + t1 := x[0] + d1*x[1] - math.Exp(d1) + t2 := x[2] + d2*x[3] - math.Cos(d1) + t := t1*t1 + t2*t2 + s3 := 2 * t1 * t2 + r1 := t + 2*t1*t1 + r2 := t + 2*t2*t2 + hess.SetSym(0, 0, hess.At(0, 0)+r1) + hess.SetSym(0, 1, hess.At(0, 1)+d1*r1) + hess.SetSym(1, 1, hess.At(1, 1)+d1*d1*r1) + hess.SetSym(0, 2, hess.At(0, 2)+s3) + hess.SetSym(1, 2, hess.At(1, 2)+d1*s3) + hess.SetSym(2, 2, hess.At(2, 2)+r2) + hess.SetSym(0, 3, hess.At(0, 3)+d2*s3) + hess.SetSym(1, 3, hess.At(1, 3)+d1*d2*s3) + hess.SetSym(2, 3, hess.At(2, 3)+d2*r2) + hess.SetSym(3, 3, hess.At(3, 3)+d2*d2*r2) + } + for i := 0; i < 4; i++ { + for j := i; j < 4; j++ { + hess.SetSym(i, j, 4*hess.At(i, j)) + } + } +} + +func (BrownAndDennis) Minima() []Minimum { + return []Minimum{ + { + X: []float64{-11.594439904762162, 13.203630051207202, -0.4034394881768612, 0.2367787744557347}, + F: 85822.20162635634, + Global: true, + }, + } +} + +// ExtendedPowellSingular implements the extended Powell's function. +// Its Hessian matrix is singular at the minimizer. +// +// Standard starting point: +// [3, -1, 0, 3, 3, -1, 0, 3, ..., 3, -1, 0, 3] +// +// References: +// - Spedicato E.: Computational experience with quasi-Newton algorithms for +// minimization problems of moderatly large size. Towards Global +// Optimization 2 (1978), 209-219 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type ExtendedPowellSingular struct{} + +func (ExtendedPowellSingular) Func(x []float64) (sum float64) { + if len(x)%4 != 0 { + panic("dimension of the problem must be a multiple of 4") + } + + for i := 0; i < len(x); i += 4 { + f1 := x[i] + 10*x[i+1] + f2 := x[i+2] - x[i+3] + t := x[i+1] - 2*x[i+2] + f3 := t * t + t = x[i] - x[i+3] + f4 := t * t + sum += f1*f1 + 5*f2*f2 + f3*f3 + 10*f4*f4 + } + return sum +} + +func (ExtendedPowellSingular) Grad(grad, x []float64) { + if len(x)%4 != 0 { + panic("dimension of the problem must be a multiple of 4") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := 0; i < len(x); i += 4 { + f1 := x[i] + 10*x[i+1] + f2 := x[i+2] - x[i+3] + t1 := x[i+1] - 2*x[i+2] + f3 := t1 * t1 + t2 := x[i] - x[i+3] + f4 := t2 * t2 + grad[i] = 2*f1 + 40*f4*t2 + grad[i+1] = 20*f1 + 4*f3*t1 + grad[i+2] = 10*f2 - 8*f3*t1 + grad[i+3] = -10*f2 - 40*f4*t2 + } +} + +func (ExtendedPowellSingular) Minima() []Minimum { + return []Minimum{ + { + X: []float64{0, 0, 0, 0}, + F: 0, + Global: true, + }, + { + X: []float64{0, 0, 0, 0, 0, 0, 0, 0}, + F: 0, + Global: true, + }, + { + X: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + F: 0, + Global: true, + }, + } +} + +// ExtendedRosenbrock implements the extended, multidimensional Rosenbrock +// function. +// +// Standard starting point: +// Easy: [-1.2, 1, -1.2, 1, ...] +// Hard: any point far from the minimum +// +// References: +// - Rosenbrock, H.H.: An Automatic Method for Finding the Greatest or Least +// Value of a Function. Computer J 3 (1960), 175-184 +// - http://en.wikipedia.org/wiki/Rosenbrock_function +type ExtendedRosenbrock struct{} + +func (ExtendedRosenbrock) Func(x []float64) (sum float64) { + for i := 0; i < len(x)-1; i++ { + a := 1 - x[i] + b := x[i+1] - x[i]*x[i] + sum += a*a + 100*b*b + } + return sum +} + +func (ExtendedRosenbrock) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + dim := len(x) + for i := range grad { + grad[i] = 0 + } + for i := 0; i < dim-1; i++ { + grad[i] -= 2 * (1 - x[i]) + grad[i] -= 400 * (x[i+1] - x[i]*x[i]) * x[i] + } + for i := 1; i < dim; i++ { + grad[i] += 200 * (x[i] - x[i-1]*x[i-1]) + } +} + +func (ExtendedRosenbrock) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{1, 1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{1, 1, 1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{-0.7756592265653526, 0.6130933654850433, + 0.38206284633839305, 0.14597201855219452}, + F: 3.701428610430017, + Global: false, + }, + { + X: []float64{1, 1, 1, 1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{-0.9620510206947502, 0.9357393959767103, + 0.8807136041943204, 0.7778776758544063, 0.6050936785926526}, + F: 3.930839434133027, + Global: false, + }, + { + X: []float64{-0.9865749795709938, 0.9833982288361819, 0.972106670053092, + 0.9474374368264362, 0.8986511848517299, 0.8075739520354182}, + F: 3.973940500930295, + Global: false, + }, + { + X: []float64{-0.9917225725614055, 0.9935553935033712, 0.992173321594692, + 0.9868987626903134, 0.975164756608872, 0.9514319827049906, 0.9052228177139495}, + F: 3.9836005364248543, + Global: false, + }, + { + X: []float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + F: 0, + Global: true, + }, + } +} + +// Gaussian implements the Gaussian function. +// The function has one global minimum and a number of false local minima +// caused by the finite floating point precision. +// +// Standard starting point: +// [0.4, 1, 0] +// +// Reference: +// More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained optimization +// software. ACM Trans Math Softw 7 (1981), 17-41 +type Gaussian struct{} + +func (Gaussian) y(i int) (yi float64) { + switch i { + case 1, 15: + yi = 0.0009 + case 2, 14: + yi = 0.0044 + case 3, 13: + yi = 0.0175 + case 4, 12: + yi = 0.0540 + case 5, 11: + yi = 0.1295 + case 6, 10: + yi = 0.2420 + case 7, 9: + yi = 0.3521 + case 8: + yi = 0.3989 + } + return yi +} + +func (g Gaussian) Func(x []float64) (sum float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + + for i := 1; i <= 15; i++ { + c := 0.5 * float64(8-i) + b := c - x[2] + d := b * b + e := math.Exp(-0.5 * x[1] * d) + f := x[0]*e - g.y(i) + sum += f * f + } + return sum +} + +func (g Gaussian) Grad(grad, x []float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + grad[0] = 0 + grad[1] = 0 + grad[2] = 0 + for i := 1; i <= 15; i++ { + c := 0.5 * float64(8-i) + b := c - x[2] + d := b * b + e := math.Exp(-0.5 * x[1] * d) + f := x[0]*e - g.y(i) + grad[0] += 2 * f * e + grad[1] -= f * e * d * x[0] + grad[2] += 2 * f * e * x[0] * x[1] * b + } +} + +func (Gaussian) Minima() []Minimum { + return []Minimum{ + { + X: []float64{0.398956137837997, 1.0000190844805048, 0}, + F: 1.12793276961912e-08, + Global: true, + }, + } +} + +// GulfResearchAndDevelopment implements the Gulf Research and Development function. +// +// Standard starting point: +// [5, 2.5, 0.15] +// +// References: +// - Cox, R.A.: Comparison of the performance of seven optimization algorithms +// on twelve unconstrained minimization problems. Ref. 1335CNO4, Gulf +// Research and Development Company, Pittsburg (1969) +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type GulfResearchAndDevelopment struct{} + +func (GulfResearchAndDevelopment) Func(x []float64) (sum float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + + for i := 1; i <= 99; i++ { + arg := float64(i) / 100 + r := math.Pow(-50*math.Log(arg), 2.0/3.0) + 25 - x[1] + t1 := math.Pow(math.Abs(r), x[2]) / x[0] + t2 := math.Exp(-t1) + t := t2 - arg + sum += t * t + } + return sum +} + +func (GulfResearchAndDevelopment) Grad(grad, x []float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 99; i++ { + arg := float64(i) / 100 + r := math.Pow(-50*math.Log(arg), 2.0/3.0) + 25 - x[1] + t1 := math.Pow(math.Abs(r), x[2]) / x[0] + t2 := math.Exp(-t1) + t := t2 - arg + s1 := t1 * t2 * t + grad[0] += s1 + grad[1] += s1 / r + grad[2] -= s1 * math.Log(math.Abs(r)) + } + grad[0] *= 2 / x[0] + grad[1] *= 2 * x[2] + grad[2] *= 2 +} + +func (GulfResearchAndDevelopment) Minima() []Minimum { + return []Minimum{ + { + X: []float64{50, 25, 1.5}, + F: 0, + Global: true, + }, + { + X: []float64{99.89529935174151, 60.61453902799833, 9.161242695144592}, + F: 32.8345, + Global: false, + }, + { + X: []float64{201.662589489426, 60.61633150468155, 10.224891158488965}, + F: 32.8345, + Global: false, + }, + } +} + +// HelicalValley implements the helical valley function of Fletcher and Powell. +// Function is not defined at x[0] = 0. +// +// Standard starting point: +// [-1, 0, 0] +// +// References: +// - Fletcher, R., Powell, M.J.D.: A rapidly convergent descent method for +// minimization. Comput J 6 (1963), 163-168 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type HelicalValley struct{} + +func (HelicalValley) Func(x []float64) float64 { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + if x[0] == 0 { + panic("function not defined at x[0] = 0") + } + + theta := 0.5 * math.Atan(x[1]/x[0]) / math.Pi + if x[0] < 0 { + theta += 0.5 + } + f1 := 10 * (x[2] - 10*theta) + f2 := 10 * (math.Hypot(x[0], x[1]) - 1) + f3 := x[2] + return f1*f1 + f2*f2 + f3*f3 +} + +func (HelicalValley) Grad(grad, x []float64) { + if len(x) != 3 { + panic("dimension of the problem must be 3") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + if x[0] == 0 { + panic("function not defined at x[0] = 0") + } + + theta := 0.5 * math.Atan(x[1]/x[0]) / math.Pi + if x[0] < 0 { + theta += 0.5 + } + h := math.Hypot(x[0], x[1]) + r := 1 / h + q := r * r / math.Pi + s := x[2] - 10*theta + grad[0] = 200 * (5*s*q*x[1] + (h-1)*r*x[0]) + grad[1] = 200 * (-5*s*q*x[0] + (h-1)*r*x[1]) + grad[2] = 2 * (100*s + x[2]) +} + +func (HelicalValley) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 0, 0}, + F: 0, + Global: true, + }, + } +} + +// Linear implements a linear function. +type Linear struct{} + +func (Linear) Func(x []float64) float64 { + return floats.Sum(x) +} + +func (Linear) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 1 + } +} + +// PenaltyI implements the first penalty function by Gill, Murray and Pitfield. +// +// Standard starting point: +// [1, ..., n] +// +// References: +// - Gill, P.E., Murray, W., Pitfield, R.A.: The implementation of two revised +// quasi-Newton algorithms for unconstrained optimization. Report NAC 11, +// National Phys Lab (1972), 82-83 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type PenaltyI struct{} + +func (PenaltyI) Func(x []float64) (sum float64) { + for _, v := range x { + sum += (v - 1) * (v - 1) + } + sum *= 1e-5 + + var s float64 + for _, v := range x { + s += v * v + } + sum += (s - 0.25) * (s - 0.25) + return sum +} + +func (PenaltyI) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + s := -0.25 + for _, v := range x { + s += v * v + } + for i, v := range x { + grad[i] = 2 * (2*s*v + 1e-5*(v-1)) + } +} + +func (PenaltyI) Minima() []Minimum { + return []Minimum{ + { + X: []float64{0.2500074995875379, 0.2500074995875379, 0.2500074995875379, 0.2500074995875379}, + F: 2.2499775008999372e-05, + Global: true, + }, + { + X: []float64{0.15812230111311634, 0.15812230111311634, 0.15812230111311634, + 0.15812230111311634, 0.15812230111311634, 0.15812230111311634, + 0.15812230111311634, 0.15812230111311634, 0.15812230111311634, 0.15812230111311634}, + F: 7.087651467090369e-05, + Global: true, + }, + } +} + +// PenaltyII implements the second penalty function by Gill, Murray and Pitfield. +// +// Standard starting point: +// [0.5, ..., 0.5] +// +// References: +// - Gill, P.E., Murray, W., Pitfield, R.A.: The implementation of two revised +// quasi-Newton algorithms for unconstrained optimization. Report NAC 11, +// National Phys Lab (1972), 82-83 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type PenaltyII struct{} + +func (PenaltyII) Func(x []float64) (sum float64) { + dim := len(x) + s := -1.0 + for i, v := range x { + s += float64(dim-i) * v * v + } + for i := 1; i < dim; i++ { + yi := math.Exp(float64(i+1)/10) + math.Exp(float64(i)/10) + f := math.Exp(x[i]/10) + math.Exp(x[i-1]/10) - yi + sum += f * f + } + for i := 1; i < dim; i++ { + f := math.Exp(x[i]/10) - math.Exp(-1.0/10) + sum += f * f + } + sum *= 1e-5 + sum += (x[0] - 0.2) * (x[0] - 0.2) + sum += s * s + return sum +} + +func (PenaltyII) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + dim := len(x) + s := -1.0 + for i, v := range x { + s += float64(dim-i) * v * v + } + for i, v := range x { + grad[i] = 4 * s * float64(dim-i) * v + } + for i := 1; i < dim; i++ { + yi := math.Exp(float64(i+1)/10) + math.Exp(float64(i)/10) + f := math.Exp(x[i]/10) + math.Exp(x[i-1]/10) - yi + grad[i] += 1e-5 * f * math.Exp(x[i]/10) / 5 + grad[i-1] += 1e-5 * f * math.Exp(x[i-1]/10) / 5 + } + for i := 1; i < dim; i++ { + f := math.Exp(x[i]/10) - math.Exp(-1.0/10) + grad[i] += 1e-5 * f * math.Exp(x[i]/10) / 5 + } + grad[0] += 2 * (x[0] - 0.2) +} + +func (PenaltyII) Minima() []Minimum { + return []Minimum{ + { + X: []float64{0.19999933335, 0.19131670128566283, 0.4801014860897, 0.5188454026659}, + F: 9.376293007355449e-06, + Global: true, + }, + { + X: []float64{0.19998360520892217, 0.010350644318663525, + 0.01960493546891094, 0.03208906550305253, 0.04993267593895693, + 0.07651399534454084, 0.11862407118600789, 0.1921448731780023, + 0.3473205862372022, 0.36916437893066273}, + F: 0.00029366053745674594, + Global: true, + }, + } +} + +// PowellBadlyScaled implements the Powell's badly scaled function. +// The function is very flat near the minimum. A satisfactory solution is one +// that gives f(x) ≅ 1e-13. +// +// Standard starting point: +// [0, 1] +// +// References: +// - Powell, M.J.D.: A Hybrid Method for Nonlinear Equations. Numerical +// Methods for Nonlinear Algebraic Equations, P. Rabinowitz (ed.), Gordon +// and Breach (1970) +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type PowellBadlyScaled struct{} + +func (PowellBadlyScaled) Func(x []float64) float64 { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + + f1 := 1e4*x[0]*x[1] - 1 + f2 := math.Exp(-x[0]) + math.Exp(-x[1]) - 1.0001 + return f1*f1 + f2*f2 +} + +func (PowellBadlyScaled) Grad(grad, x []float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + f1 := 1e4*x[0]*x[1] - 1 + f2 := math.Exp(-x[0]) + math.Exp(-x[1]) - 1.0001 + grad[0] = 2 * (1e4*f1*x[1] - f2*math.Exp(-x[0])) + grad[1] = 2 * (1e4*f1*x[0] - f2*math.Exp(-x[1])) +} + +func (PowellBadlyScaled) Hess(hess mat.MutableSymmetric, x []float64) { + if len(x) != 2 { + panic("dimension of the problem must be 2") + } + if len(x) != hess.Symmetric() { + panic("incorrect size of the Hessian") + } + + t1 := 1e4*x[0]*x[1] - 1 + s1 := math.Exp(-x[0]) + s2 := math.Exp(-x[1]) + t2 := s1 + s2 - 1.0001 + + h00 := 2 * (1e8*x[1]*x[1] + s1*(s1+t2)) + h01 := 2 * (1e4*(1+2*t1) + s1*s2) + h11 := 2 * (1e8*x[0]*x[0] + s2*(s2+t2)) + hess.SetSym(0, 0, h00) + hess.SetSym(0, 1, h01) + hess.SetSym(1, 1, h11) +} + +func (PowellBadlyScaled) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1.0981593296997149e-05, 9.106146739867375}, + F: 0, + Global: true, + }, + } +} + +// Trigonometric implements the trigonometric function. +// +// Standard starting point: +// [1/dim, ..., 1/dim] +// +// References: +// - Spedicato E.: Computational experience with quasi-Newton algorithms for +// minimization problems of moderatly large size. Towards Global +// Optimization 2 (1978), 209-219 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type Trigonometric struct{} + +func (Trigonometric) Func(x []float64) (sum float64) { + var s1 float64 + for _, v := range x { + s1 += math.Cos(v) + } + for i, v := range x { + f := float64(len(x)+i+1) - float64(i+1)*math.Cos(v) - math.Sin(v) - s1 + sum += f * f + } + return sum +} + +func (Trigonometric) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + var s1 float64 + for _, v := range x { + s1 += math.Cos(v) + } + + var s2 float64 + for i, v := range x { + f := float64(len(x)+i+1) - float64(i+1)*math.Cos(v) - math.Sin(v) - s1 + s2 += f + grad[i] = 2 * f * (float64(i+1)*math.Sin(v) - math.Cos(v)) + } + + for i, v := range x { + grad[i] += 2 * s2 * math.Sin(v) + } +} + +func (Trigonometric) Minima() []Minimum { + return []Minimum{ + { + X: []float64{0.04296456438227447, 0.043976287478192246, + 0.045093397949095684, 0.04633891624617569, 0.047744381782831, + 0.04935473251330618, 0.05123734850076505, 0.19520946391410446, + 0.1649776652761741, 0.06014857783799575}, + F: 0, + Global: true, + }, + { + // TODO(vladimir-ch): If we knew the location of this minimum more + // accurately, we could decrease defaultGradTol. + X: []float64{0.05515090434047145, 0.05684061730812344, + 0.05876400231100774, 0.060990608903034337, 0.06362621381044778, + 0.06684318087364617, 0.2081615177172172, 0.16436309604419047, + 0.08500689695564931, 0.09143145386293675}, + F: 2.795056121876575e-05, + Global: false, + }, + } +} + +// VariablyDimensioned implements a variably dimensioned function. +// +// Standard starting point: +// [..., (dim-i)/dim, ...], i=1,...,dim +// +// References: +// More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained optimization +// software. ACM Trans Math Softw 7 (1981), 17-41 +type VariablyDimensioned struct{} + +func (VariablyDimensioned) Func(x []float64) (sum float64) { + for _, v := range x { + t := v - 1 + sum += t * t + } + + var s float64 + for i, v := range x { + s += float64(i+1) * (v - 1) + } + s *= s + sum += s + s *= s + sum += s + return sum +} + +func (VariablyDimensioned) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + var s float64 + for i, v := range x { + s += float64(i+1) * (v - 1) + } + for i, v := range x { + grad[i] = 2 * (v - 1 + s*float64(i+1)*(1+2*s*s)) + } +} + +func (VariablyDimensioned) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{1, 1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{1, 1, 1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{1, 1, 1, 1, 1}, + F: 0, + Global: true, + }, + { + X: []float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + F: 0, + Global: true, + }, + } +} + +// Watson implements the Watson's function. +// Dimension of the problem should be 2 <= dim <= 31. For dim == 9, the problem +// of minimizing the function is very ill conditioned. +// +// Standard starting point: +// [0, ..., 0] +// +// References: +// - Kowalik, J.S., Osborne, M.R.: Methods for Unconstrained Optimization +// Problems. Elsevier North-Holland, New York, 1968 +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type Watson struct{} + +func (Watson) Func(x []float64) (sum float64) { + for i := 1; i <= 29; i++ { + d1 := float64(i) / 29 + + d2 := 1.0 + var s1 float64 + for j := 1; j < len(x); j++ { + s1 += float64(j) * d2 * x[j] + d2 *= d1 + } + + d2 = 1.0 + var s2 float64 + for _, v := range x { + s2 += d2 * v + d2 *= d1 + } + + t := s1 - s2*s2 - 1 + sum += t * t + } + t := x[1] - x[0]*x[0] - 1 + sum += x[0]*x[0] + t*t + return sum +} + +func (Watson) Grad(grad, x []float64) { + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + for i := range grad { + grad[i] = 0 + } + for i := 1; i <= 29; i++ { + d1 := float64(i) / 29 + + d2 := 1.0 + var s1 float64 + for j := 1; j < len(x); j++ { + s1 += float64(j) * d2 * x[j] + d2 *= d1 + } + + d2 = 1.0 + var s2 float64 + for _, v := range x { + s2 += d2 * v + d2 *= d1 + } + + t := s1 - s2*s2 - 1 + s3 := 2 * d1 * s2 + d2 = 2 / d1 + for j := range x { + grad[j] += d2 * (float64(j) - s3) * t + d2 *= d1 + } + } + t := x[1] - x[0]*x[0] - 1 + grad[0] += x[0] * (2 - 4*t) + grad[1] += 2 * t +} + +func (Watson) Hess(hess mat.MutableSymmetric, x []float64) { + dim := len(x) + if dim != hess.Symmetric() { + panic("incorrect size of the Hessian") + } + + for j := 0; j < dim; j++ { + for k := j; k < dim; k++ { + hess.SetSym(j, k, 0) + } + } + for i := 1; i <= 29; i++ { + d1 := float64(i) / 29 + d2 := 1.0 + var s1 float64 + for j := 1; j < dim; j++ { + s1 += float64(j) * d2 * x[j] + d2 *= d1 + } + + d2 = 1.0 + var s2 float64 + for _, v := range x { + s2 += d2 * v + d2 *= d1 + } + + t := s1 - s2*s2 - 1 + s3 := 2 * d1 * s2 + d2 = 2 / d1 + th := 2 * d1 * d1 * t + for j := 0; j < dim; j++ { + v := float64(j) - s3 + d3 := 1 / d1 + for k := 0; k <= j; k++ { + hess.SetSym(k, j, hess.At(k, j)+d2*d3*(v*(float64(k)-s3)-th)) + d3 *= d1 + } + d2 *= d1 + } + } + t1 := x[1] - x[0]*x[0] - 1 + hess.SetSym(0, 0, hess.At(0, 0)+8*x[0]*x[0]+2-4*t1) + hess.SetSym(0, 1, hess.At(0, 1)-4*x[0]) + hess.SetSym(1, 1, hess.At(1, 1)+2) +} + +func (Watson) Minima() []Minimum { + return []Minimum{ + { + X: []float64{-0.01572508644590686, 1.012434869244884, -0.23299162372002916, + 1.2604300800978554, -1.51372891341701, 0.9929964286340117}, + F: 0.0022876700535523838, + Global: true, + }, + { + X: []float64{-1.5307036521992127e-05, 0.9997897039319495, 0.01476396369355022, + 0.14634232829939883, 1.0008211030046426, -2.617731140519101, 4.104403164479245, + -3.1436122785568514, 1.0526264080103074}, + F: 1.399760138096796e-06, + Global: true, + }, + // TODO(vladimir-ch): More, Garbow, Hillstrom list just the value, but + // not the location. Our minimizers find a minimum, but the value is + // different. + // { + // // For dim == 12 + // F: 4.72238e-10, + // Global: true, + // }, + // TODO(vladimir-ch): netlib/uncon report a value of 2.48631d-20 for dim == 20. + } +} + +// Wood implements the Wood's function. +// +// Standard starting point: +// [-3, -1, -3, -1] +// +// References: +// - Colville, A.R.: A comparative study of nonlinear programming codes. +// Report 320-2949, IBM New York Scientific Center (1968) +// - More, J., Garbow, B.S., Hillstrom, K.E.: Testing unconstrained +// optimization software. ACM Trans Math Softw 7 (1981), 17-41 +type Wood struct{} + +func (Wood) Func(x []float64) (sum float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + + f1 := x[1] - x[0]*x[0] + f2 := 1 - x[0] + f3 := x[3] - x[2]*x[2] + f4 := 1 - x[2] + f5 := x[1] + x[3] - 2 + f6 := x[1] - x[3] + return 100*f1*f1 + f2*f2 + 90*f3*f3 + f4*f4 + 10*f5*f5 + 0.1*f6*f6 +} + +func (Wood) Grad(grad, x []float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + + f1 := x[1] - x[0]*x[0] + f2 := 1 - x[0] + f3 := x[3] - x[2]*x[2] + f4 := 1 - x[2] + f5 := x[1] + x[3] - 2 + f6 := x[1] - x[3] + grad[0] = -2 * (200*f1*x[0] + f2) + grad[1] = 2 * (100*f1 + 10*f5 + 0.1*f6) + grad[2] = -2 * (180*f3*x[2] + f4) + grad[3] = 2 * (90*f3 + 10*f5 - 0.1*f6) +} + +func (Wood) Hess(hess mat.MutableSymmetric, x []float64) { + if len(x) != 4 { + panic("dimension of the problem must be 4") + } + if len(x) != hess.Symmetric() { + panic("incorrect size of the Hessian") + } + + hess.SetSym(0, 0, 400*(3*x[0]*x[0]-x[1])+2) + hess.SetSym(0, 1, -400*x[0]) + hess.SetSym(1, 1, 220.2) + hess.SetSym(0, 2, 0) + hess.SetSym(1, 2, 0) + hess.SetSym(2, 2, 360*(3*x[2]*x[2]-x[3])+2) + hess.SetSym(0, 3, 0) + hess.SetSym(1, 3, 19.8) + hess.SetSym(2, 3, -360*x[2]) + hess.SetSym(3, 3, 200.2) +} + +func (Wood) Minima() []Minimum { + return []Minimum{ + { + X: []float64{1, 1, 1, 1}, + F: 0, + Global: true, + }, + } +} + +// ConcaveRight implements an univariate function that is concave to the right +// of the minimizer which is located at x=sqrt(2). +// +// References: +// More, J.J., and Thuente, D.J.: Line Search Algorithms with Guaranteed Sufficient Decrease. +// ACM Transactions on Mathematical Software 20(3) (1994), 286–307, eq. (5.1) +type ConcaveRight struct{} + +func (ConcaveRight) Func(x []float64) float64 { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + return -x[0] / (x[0]*x[0] + 2) +} + +func (ConcaveRight) Grad(grad, x []float64) { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + xSqr := x[0] * x[0] + grad[0] = (xSqr - 2) / (xSqr + 2) / (xSqr + 2) +} + +// ConcaveLeft implements an univariate function that is concave to the left of +// the minimizer which is located at x=399/250=1.596. +// +// References: +// More, J.J., and Thuente, D.J.: Line Search Algorithms with Guaranteed Sufficient Decrease. +// ACM Transactions on Mathematical Software 20(3) (1994), 286–307, eq. (5.2) +type ConcaveLeft struct{} + +func (ConcaveLeft) Func(x []float64) float64 { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + return math.Pow(x[0]+0.004, 4) * (x[0] - 1.996) +} + +func (ConcaveLeft) Grad(grad, x []float64) { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + grad[0] = math.Pow(x[0]+0.004, 3) * (5*x[0] - 7.98) +} + +// Plassmann implements an univariate oscillatory function where the value of L +// controls the number of oscillations. The value of Beta controls the size of +// the derivative at zero and the size of the interval where the strong Wolfe +// conditions can hold. For small values of Beta this function represents a +// difficult test problem for linesearchers also because the information based +// on the derivative is unreliable due to the oscillations. +// +// References: +// More, J.J., and Thuente, D.J.: Line Search Algorithms with Guaranteed Sufficient Decrease. +// ACM Transactions on Mathematical Software 20(3) (1994), 286–307, eq. (5.3) +type Plassmann struct { + L float64 // Number of oscillations for |x-1| ≥ Beta. + Beta float64 // Size of the derivative at zero, f'(0) = -Beta. +} + +func (f Plassmann) Func(x []float64) float64 { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + a := x[0] + b := f.Beta + l := f.L + r := 2 * (1 - b) / l / math.Pi * math.Sin(l*math.Pi/2*a) + switch { + case a <= 1-b: + r += 1 - a + case 1-b < a && a <= 1+b: + r += 0.5 * ((a-1)*(a-1)/b + b) + default: // a > 1+b + r += a - 1 + } + return r +} + +func (f Plassmann) Grad(grad, x []float64) { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + a := x[0] + b := f.Beta + l := f.L + grad[0] = (1 - b) * math.Cos(l*math.Pi/2*a) + switch { + case a <= 1-b: + grad[0]-- + case 1-b < a && a <= 1+b: + grad[0] += (a - 1) / b + default: // a > 1+b + grad[0]++ + } +} + +// YanaiOzawaKaneko is an univariate convex function where the values of Beta1 +// and Beta2 control the curvature around the minimum. Far away from the +// minimum the function approximates an absolute value function. Near the +// minimum, the function can either be sharply curved or flat, controlled by +// the parameter values. +// +// References: +// - More, J.J., and Thuente, D.J.: Line Search Algorithms with Guaranteed Sufficient Decrease. +// ACM Transactions on Mathematical Software 20(3) (1994), 286–307, eq. (5.4) +// - Yanai, H., Ozawa, M., and Kaneko, S.: Interpolation methods in one dimensional +// optimization. Computing 27 (1981), 155–163 +type YanaiOzawaKaneko struct { + Beta1 float64 + Beta2 float64 +} + +func (f YanaiOzawaKaneko) Func(x []float64) float64 { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + a := x[0] + b1 := f.Beta1 + b2 := f.Beta2 + g1 := math.Sqrt(1+b1*b1) - b1 + g2 := math.Sqrt(1+b2*b2) - b2 + return g1*math.Sqrt((a-1)*(a-1)+b2*b2) + g2*math.Sqrt(a*a+b1*b1) +} + +func (f YanaiOzawaKaneko) Grad(grad, x []float64) { + if len(x) != 1 { + panic("dimension of the problem must be 1") + } + if len(x) != len(grad) { + panic("incorrect size of the gradient") + } + a := x[0] + b1 := f.Beta1 + b2 := f.Beta2 + g1 := math.Sqrt(1+b1*b1) - b1 + g2 := math.Sqrt(1+b2*b2) - b2 + grad[0] = g1*(a-1)/math.Sqrt(b2*b2+(a-1)*(a-1)) + g2*a/math.Sqrt(b1*b1+a*a) +} diff --git a/vendor/gonum.org/v1/gonum/optimize/functions/functions_test.go b/vendor/gonum.org/v1/gonum/optimize/functions/functions_test.go new file mode 100644 index 00000000..0912ab96 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functions/functions_test.go @@ -0,0 +1,326 @@ +// 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 functions + +import "testing" + +func TestBeale(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 1}, + F: 14.203125, + Gradient: []float64{0, 27.75}, + }, + { + X: []float64{1, 4}, + F: 4624.453125, + Gradient: []float64{8813.25, 6585}, + }, + } + testFunction(Beale{}, tests, t) +} + +func TestBiggsEXP2(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 2}, + F: 32.26255055084012, + Gradient: []float64{8.308203800550878, -25.32607145221645}, + }, + } + testFunction(BiggsEXP2{}, tests, t) +} + +func TestBiggsEXP3(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 2, 1}, + F: 1.598844540607779, + Gradient: []float64{1.0633795027631927, -0.5196392672262664, -0.3180919155433357}, + }, + } + testFunction(BiggsEXP3{}, tests, t) +} + +func TestBiggsEXP4(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 2, 1, 1}, + F: 1.598844540607779, + Gradient: []float64{1.0633795027631927, -0.5196392672262664, + -0.44245622408151464, -0.3180919155433357}, + }, + } + testFunction(BiggsEXP4{}, tests, t) +} + +func TestBiggsEXP5(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 2, 1, 1, 1}, + F: 13.386420552801937, + Gradient: []float64{-6.54665204477596, 3.5259856535515293, + 14.36984212995392, -9.522506150695783, -19.639956134327882}, + }, + } + testFunction(BiggsEXP5{}, tests, t) +} + +func TestBiggsEXP6(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 2, 1, 1, 1, 1}, + F: 0.77907007565597, + Gradient: []float64{-0.149371887533426, -0.183163468182936, + -1.483958013575642, 1.428277503849742, -0.149371887533426, + -1.483958013575642}, + }, + } + testFunction(BiggsEXP6{}, tests, t) +} + +func TestBox3D(t *testing.T) { + tests := []funcTest{ + { + X: []float64{0, 10, 20}, + F: 1031.1538106093985, + Gradient: []float64{98.22343149849218, -2.11937420675874, 112.38817362220350}, + }, + } + testFunction(Box3D{}, tests, t) +} + +func TestBrownBadlyScaled(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 1}, + F: 999998000003, + Gradient: []float64{-2e+6, -4e-6}, + }, + } + testFunction(BrownBadlyScaled{}, tests, t) +} + +// TODO(vladimir-ch): The minimum of BrownAndDennis is not known accurately +// enough, which would force defaultGradTol to be unnecessarily large for the +// tests to pass. This is the only function that causes problems, so disable +// this test until the minimum is more accurate. +// func TestBrownAndDennis(t *testing.T) { +// tests := []funcTest{ +// { +// X: []float64{25, 5, -5, -1}, +// F: 7926693.33699744, +// Gradient: []float64{1149322.836365895, 1779291.674339785, -254579.585463521, -173400.429253115}, +// }, +// } +// testFunction(BrownAndDennis{}, tests, t) +// } + +func TestExtendedPowellSingular(t *testing.T) { + tests := []funcTest{ + { + X: []float64{3, -1, 0, 3}, + F: 95, + Gradient: []float64{-14, -144, -22, 30}, + }, + { + X: []float64{3, -1, 0, 3, 3, -1, 0, 3}, + F: 190, + Gradient: []float64{-14, -144, -22, 30, -14, -144, -22, 30}, + }, + } + testFunction(ExtendedPowellSingular{}, tests, t) +} + +func TestExtendedRosenbrock(t *testing.T) { + tests := []funcTest{ + { + X: []float64{-1.2, 1}, + F: 24.2, + Gradient: []float64{-215.6, -88}, + }, + { + X: []float64{-1.2, 1, -1.2}, + F: 508.2, + Gradient: []float64{-215.6, 792, -440}, + }, + { + X: []float64{-1.2, 1, -1.2, 1}, + F: 532.4, + Gradient: []float64{-215.6, 792, -655.6, -88}, + }, + } + testFunction(ExtendedRosenbrock{}, tests, t) +} + +func TestGaussian(t *testing.T) { + tests := []funcTest{ + { + X: []float64{0.4, 1, 0}, + F: 3.88810699116688e-06, + Gradient: []float64{7.41428466839991e-03, -7.44126392165149e-04, -5.30189685421989e-20}, + }, + } + testFunction(Gaussian{}, tests, t) +} + +func TestGulfResearchAndDevelopment(t *testing.T) { + tests := []funcTest{ + { + X: []float64{5, 2.5, 0.15}, + F: 12.11070582556949, + Gradient: []float64{2.0879783574289799, 0.0345792619697154, -39.6766801029386400}, + }, + } + testFunction(GulfResearchAndDevelopment{}, tests, t) +} + +func TestHelicalValley(t *testing.T) { + tests := []funcTest{ + { + X: []float64{-1, 0, 0}, + F: 2500, + Gradient: []float64{0, -1.59154943091895e+03, -1e+03}, + }, + } + testFunction(HelicalValley{}, tests, t) +} + +func TestPenaltyI(t *testing.T) { + tests := []funcTest{ + { + X: []float64{1, 2, 3, 4}, + F: 885.06264, + Gradient: []float64{119, 238.00002, 357.00004, 476.00006}, + }, + { + X: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + F: 148032.56535, + Gradient: []float64{1539, 3078.00002, 4617.00004, 6156.00006, + 7695.00008, 9234.0001, 10773.00012, 12312.00014, 13851.00016, 15390.00018}, + }, + } + testFunction(PenaltyI{}, tests, t) +} + +func TestPenaltyII(t *testing.T) { + tests := []funcTest{ + { + X: []float64{0.5, 0.5, 0.5, 0.5}, + F: 2.34000880546302, + Gradient: []float64{12.59999952896435, 8.99999885134508, + 5.99999776830493, 2.99999875380719}, + }, + { + X: []float64{0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, + F: 162.65277656596712, + Gradient: []float64{255.5999995289644, 229.4999988513451, + 203.9999977683049, 178.4999965713605, 152.9999952485322, + 127.4999937865809, 101.9999921708749, 76.4999903852436, + 50.9999884118158, 25.4999938418451}, + }, + } + testFunction(PenaltyII{}, tests, t) +} + +func TestPowelBadlyScaled(t *testing.T) { + tests := []funcTest{ + { + X: []float64{0, 1}, + F: 1.13526171734838, + Gradient: []float64{-2.00007355588823e+04, -2.70596990584991e-01}, + }, + } + testFunction(PowellBadlyScaled{}, tests, t) +} + +func TestTrigonometric(t *testing.T) { + tests := []funcTest{ + { + X: []float64{0.5, 0.5}, + F: 0.0126877761614045, + Gradient: []float64{-0.00840962732040673, -0.09606967736232540}, + }, + { + X: []float64{0.2, 0.2, 0.2, 0.2, 0.2}, + F: 0.0116573789904718, + Gradient: []float64{0.04568602319608119, -0.00896259022885634, + -0.04777056509084983, -0.07073790138989976, -0.07786459912600564}, + }, + { + X: []float64{0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1}, + F: 0.00707575946622261, + Gradient: []float64{0.03562782195259399, 0.01872017956076182, + 0.00380754216611998, -0.00911009023133202, -0.02003271763159338, + -0.02896034003466506, -0.03589295744054654, -0.04083056984923782, + -0.04377317726073873, -0.04472077967504980}, + }, + } + testFunction(Trigonometric{}, tests, t) +} + +func TestVariablyDimensioned(t *testing.T) { + tests := []funcTest{ + { + X: []float64{0.5, 0}, + F: 46.5625, + Gradient: []float64{-68.5, -137}, + }, + { + X: []float64{2.0 / 3, 1.0 / 3, 0}, + F: 497.60493827160514, + Gradient: []float64{-416.518518518519, -833.037037037037, -1249.555555555556}, + }, + { + X: []float64{0.75, 0.5, 0.25, 0}, + F: 3222.1875, + Gradient: []float64{-1703, -3406, -5109, -6812}, + }, + } + testFunction(VariablyDimensioned{}, tests, t) +} + +func TestWatson(t *testing.T) { + tests := []funcTest{ + { + X: []float64{0, 0}, + F: 30, + Gradient: []float64{0, -60}, + }, + { + X: []float64{0, 0, 0, 0, 0, 0}, + F: 30, + Gradient: []float64{0, -60, -60, -61.034482758620697, + -62.068965517241381, -63.114928861371936}, + }, + { + X: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0}, + F: 30, + Gradient: []float64{0, -60, -60, -61.034482758620697, + -62.068965517241381, -63.114928861371936, -64.172372791012350, + -65.241283655050239, -66.321647802373235}, + }, + { + X: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + F: 30, + Gradient: []float64{0, -60, -60, -61.034482758620697, + -62.068965517241381, -63.114928861371936, -64.172372791012350, + -65.241283655050239, -66.321647802373235, -67.413448880864095, + -68.516667837400661, -69.631282933991471}, + }, + } + testFunction(Watson{}, tests, t) +} + +func TestWood(t *testing.T) { + tests := []funcTest{ + { + X: []float64{-3, -1, -3, -1}, + F: 19192, + Gradient: []float64{-12008, -2080, -10808, -1880}, + }, + } + testFunction(Wood{}, tests, t) +} diff --git a/vendor/gonum.org/v1/gonum/optimize/functions/minsurf.go b/vendor/gonum.org/v1/gonum/optimize/functions/minsurf.go new file mode 100644 index 00000000..d975bfdb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functions/minsurf.go @@ -0,0 +1,252 @@ +// 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 functions + +import ( + "fmt" + "math" +) + +// MinimalSurface implements a finite element approximation to a minimal +// surface problem: determine the surface with minimal area and given boundary +// values in a unit square centered at the origin. +// +// References: +// Averick, M.B., Carter, R.G., Moré, J.J., Xue, G.-L.: The Minpack-2 Test +// Problem Collection. Preprint MCS-P153-0692, Argonne National Laboratory (1992) +type MinimalSurface struct { + bottom, top []float64 + left, right []float64 + origin, step [2]float64 +} + +// NewMinimalSurface creates a new discrete minimal surface problem and +// precomputes its boundary values. The problem is discretized on a rectilinear +// grid with nx×ny nodes which means that the problem dimension is (nx-2)(ny-2). +func NewMinimalSurface(nx, ny int) *MinimalSurface { + ms := &MinimalSurface{ + bottom: make([]float64, nx), + top: make([]float64, nx), + left: make([]float64, ny), + right: make([]float64, ny), + origin: [2]float64{-0.5, -0.5}, + step: [2]float64{1 / float64(nx-1), 1 / float64(ny-1)}, + } + + ms.initBoundary(ms.bottom, ms.origin[0], ms.origin[1], ms.step[0], 0) + startY := ms.origin[1] + float64(ny-1)*ms.step[1] + ms.initBoundary(ms.top, ms.origin[0], startY, ms.step[0], 0) + ms.initBoundary(ms.left, ms.origin[0], ms.origin[1], 0, ms.step[1]) + startX := ms.origin[0] + float64(nx-1)*ms.step[0] + ms.initBoundary(ms.right, startX, ms.origin[1], 0, ms.step[1]) + + return ms +} + +// Func returns the area of the surface represented by the vector x. +func (ms *MinimalSurface) Func(x []float64) (area float64) { + nx, ny := ms.Dims() + if len(x) != (nx-2)*(ny-2) { + panic("functions: problem size mismatch") + } + + hx, hy := ms.Steps() + for j := 0; j < ny-1; j++ { + for i := 0; i < nx-1; i++ { + vLL := ms.at(i, j, x) + vLR := ms.at(i+1, j, x) + vUL := ms.at(i, j+1, x) + vUR := ms.at(i+1, j+1, x) + + dvLdx := (vLR - vLL) / hx + dvLdy := (vUL - vLL) / hy + dvUdx := (vUR - vUL) / hx + dvUdy := (vUR - vLR) / hy + + fL := math.Sqrt(1 + dvLdx*dvLdx + dvLdy*dvLdy) + fU := math.Sqrt(1 + dvUdx*dvUdx + dvUdy*dvUdy) + area += fL + fU + } + } + area *= 0.5 * hx * hy + return area +} + +// Grad evaluates the area gradient of the surface represented by the vector. +func (ms *MinimalSurface) Grad(grad, x []float64) { + nx, ny := ms.Dims() + if len(x) != (nx-2)*(ny-2) { + panic("functions: problem size mismatch") + } + if grad != nil && len(x) != len(grad) { + panic("functions: unexpected size mismatch") + } + + for i := range grad { + grad[i] = 0 + } + hx, hy := ms.Steps() + for j := 0; j < ny-1; j++ { + for i := 0; i < nx-1; i++ { + vLL := ms.at(i, j, x) + vLR := ms.at(i+1, j, x) + vUL := ms.at(i, j+1, x) + vUR := ms.at(i+1, j+1, x) + + dvLdx := (vLR - vLL) / hx + dvLdy := (vUL - vLL) / hy + dvUdx := (vUR - vUL) / hx + dvUdy := (vUR - vLR) / hy + + fL := math.Sqrt(1 + dvLdx*dvLdx + dvLdy*dvLdy) + fU := math.Sqrt(1 + dvUdx*dvUdx + dvUdy*dvUdy) + + if grad != nil { + if i > 0 { + if j > 0 { + grad[ms.index(i, j)] -= (dvLdx/hx + dvLdy/hy) / fL + } + if j < ny-2 { + grad[ms.index(i, j+1)] += (dvLdy/hy)/fL - (dvUdx/hx)/fU + } + } + if i < nx-2 { + if j > 0 { + grad[ms.index(i+1, j)] += (dvLdx/hx)/fL - (dvUdy/hy)/fU + } + if j < ny-2 { + grad[ms.index(i+1, j+1)] += (dvUdx/hx + dvUdy/hy) / fU + } + } + } + } + + } + cellSize := 0.5 * hx * hy + for i := range grad { + grad[i] *= cellSize + } +} + +// InitX returns a starting location for the minimization problem. Length of +// the returned slice is (nx-2)(ny-2). +func (ms *MinimalSurface) InitX() []float64 { + nx, ny := ms.Dims() + x := make([]float64, (nx-2)*(ny-2)) + for j := 1; j < ny-1; j++ { + for i := 1; i < nx-1; i++ { + x[ms.index(i, j)] = (ms.left[j] + ms.bottom[i]) / 2 + } + } + return x +} + +// ExactX returns the exact solution to the _continuous_ minimization problem +// projected on the interior nodes of the grid. Length of the returned slice is +// (nx-2)(ny-2). +func (ms *MinimalSurface) ExactX() []float64 { + nx, ny := ms.Dims() + v := make([]float64, (nx-2)*(ny-2)) + for j := 1; j < ny-1; j++ { + for i := 1; i < nx-1; i++ { + v[ms.index(i, j)] = ms.ExactSolution(ms.x(i), ms.y(j)) + } + } + return v +} + +// ExactSolution returns the value of the exact solution to the minimal surface +// problem at (x,y). The exact solution is +// F_exact(x,y) = U^2(x,y) - V^2(x,y), +// where U and V are the unique solutions to the equations +// x = u + uv^2 - u^3/3, +// y = -v - u^2v + v^3/3. +func (ms *MinimalSurface) ExactSolution(x, y float64) float64 { + var u = [2]float64{x, -y} + var f [2]float64 + var jac [2][2]float64 + for k := 0; k < 100; k++ { + f[0] = u[0] + u[0]*u[1]*u[1] - u[0]*u[0]*u[0]/3 - x + f[1] = -u[1] - u[0]*u[0]*u[1] + u[1]*u[1]*u[1]/3 - y + fNorm := math.Hypot(f[0], f[1]) + if fNorm < 1e-13 { + break + } + jac[0][0] = 1 + u[1]*u[1] - u[0]*u[0] + jac[0][1] = 2 * u[0] * u[1] + jac[1][0] = -2 * u[0] * u[1] + jac[1][1] = -1 - u[0]*u[0] + u[1]*u[1] + det := jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0] + u[0] -= (jac[1][1]*f[0] - jac[0][1]*f[1]) / det + u[1] -= (jac[0][0]*f[1] - jac[1][0]*f[0]) / det + } + return u[0]*u[0] - u[1]*u[1] +} + +// Dims returns the size of the underlying rectilinear grid. +func (ms *MinimalSurface) Dims() (nx, ny int) { + return len(ms.bottom), len(ms.left) +} + +// Steps returns the spatial step sizes of the underlying rectilinear grid. +func (ms *MinimalSurface) Steps() (hx, hy float64) { + return ms.step[0], ms.step[1] +} + +func (ms *MinimalSurface) x(i int) float64 { + return ms.origin[0] + float64(i)*ms.step[0] +} + +func (ms *MinimalSurface) y(j int) float64 { + return ms.origin[1] + float64(j)*ms.step[1] +} + +func (ms *MinimalSurface) at(i, j int, x []float64) float64 { + nx, ny := ms.Dims() + if i < 0 || i >= nx { + panic(fmt.Sprintf("node [%v,%v] not on grid", i, j)) + } + if j < 0 || j >= ny { + panic(fmt.Sprintf("node [%v,%v] not on grid", i, j)) + } + + if i == 0 { + return ms.left[j] + } + if j == 0 { + return ms.bottom[i] + } + if i == nx-1 { + return ms.right[j] + } + if j == ny-1 { + return ms.top[i] + } + return x[ms.index(i, j)] +} + +// index maps an interior grid node (i, j) to a one-dimensional index and +// returns it. +func (ms *MinimalSurface) index(i, j int) int { + nx, ny := ms.Dims() + if i <= 0 || i >= nx-1 { + panic(fmt.Sprintf("[%v,%v] is not an interior node", i, j)) + } + if j <= 0 || j >= ny-1 { + panic(fmt.Sprintf("[%v,%v] is not an interior node", i, j)) + } + + return i - 1 + (j-1)*(nx-2) +} + +// initBoundary initializes with the exact solution the boundary b whose i-th +// element b[i] is located at [startX+i×hx, startY+i×hy]. +func (ms *MinimalSurface) initBoundary(b []float64, startX, startY, hx, hy float64) { + for i := range b { + x := startX + float64(i)*hx + y := startY + float64(i)*hy + b[i] = ms.ExactSolution(x, y) + } +} diff --git a/vendor/gonum.org/v1/gonum/optimize/functions/minsurf_test.go b/vendor/gonum.org/v1/gonum/optimize/functions/minsurf_test.go new file mode 100644 index 00000000..2f123545 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functions/minsurf_test.go @@ -0,0 +1,48 @@ +// 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 functions + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/diff/fd" + "gonum.org/v1/gonum/floats" +) + +func TestMinimalSurface(t *testing.T) { + for _, size := range [][2]int{ + {20, 30}, + {30, 30}, + {50, 40}, + } { + f := NewMinimalSurface(size[0], size[1]) + x0 := f.InitX() + grad := make([]float64, len(x0)) + f.Grad(grad, x0) + fdGrad := fd.Gradient(nil, f.Func, x0, &fd.Settings{Formula: fd.Central}) + + // Test that the numerical and analytical gradients agree. + dist := floats.Distance(grad, fdGrad, math.Inf(1)) + if dist > 1e-9 { + t.Errorf("grid %v x %v: numerical and analytical gradient do not match. |fdGrad - grad|_∞ = %v", + size[0], size[1], dist) + } + + // Test that the gradient at the minimum is small enough. + // In some sense this test is not completely correct because ExactX + // returns the exact solution to the continuous problem projected on the + // grid, not the exact solution to the discrete problem which we are + // solving. This is the reason why a relatively loose tolerance 1e-4 + // must be used. + xSol := f.ExactX() + f.Grad(grad, xSol) + norm := floats.Norm(grad, math.Inf(1)) + if norm > 1e-4 { + t.Errorf("grid %v x %v: gradient at the minimum not small enough. |grad|_∞ = %v", + size[0], size[1], norm) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/optimize/functions/validate.go b/vendor/gonum.org/v1/gonum/optimize/functions/validate.go new file mode 100644 index 00000000..e7c5fee7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functions/validate.go @@ -0,0 +1,127 @@ +// 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 functions + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/diff/fd" + "gonum.org/v1/gonum/floats" +) + +// function represents an objective function. +type function interface { + Func(x []float64) float64 +} + +type gradient interface { + Grad(grad, x []float64) +} + +// minimumer is an objective function that can also provide information about +// its minima. +type minimumer interface { + function + + // Minima returns _known_ minima of the function. + Minima() []Minimum +} + +// Minimum represents information about an optimal location of a function. +type Minimum struct { + // X is the location of the minimum. X may not be nil. + X []float64 + // F is the value of the objective function at X. + F float64 + // Global indicates if the location is a global minimum. + Global bool +} + +type funcTest struct { + X []float64 + + // F is the expected function value at X. + F float64 + // Gradient is the expected gradient at X. If nil, it is not evaluated. + Gradient []float64 +} + +// TODO(vladimir-ch): Decide and implement an exported testing function: +// func Test(f Function, ??? ) ??? { +// } + +const ( + defaultTol = 1e-12 + defaultGradTol = 1e-9 + defaultFDGradTol = 1e-5 +) + +// testFunction checks that the function can evaluate itself (and its gradient) +// correctly. +func testFunction(f function, ftests []funcTest, t *testing.T) { + // Make a copy of tests because we may append to the slice. + tests := make([]funcTest, len(ftests)) + copy(tests, ftests) + + // Get information about the function. + fMinima, isMinimumer := f.(minimumer) + fGradient, isGradient := f.(gradient) + + // If the function is a Minimumer, append its minima to the tests. + if isMinimumer { + for _, minimum := range fMinima.Minima() { + // Allocate gradient only if the function can evaluate it. + var grad []float64 + if isGradient { + grad = make([]float64, len(minimum.X)) + } + tests = append(tests, funcTest{ + X: minimum.X, + F: minimum.F, + Gradient: grad, + }) + } + } + + for i, test := range tests { + F := f.Func(test.X) + + // Check that the function value is as expected. + if math.Abs(F-test.F) > defaultTol { + t.Errorf("Test #%d: function value given by Func is incorrect. Want: %v, Got: %v", + i, test.F, F) + } + + if test.Gradient == nil { + continue + } + + // Evaluate the finite difference gradient. + fdGrad := fd.Gradient(nil, f.Func, test.X, &fd.Settings{ + Formula: fd.Central, + Step: 1e-6, + }) + + // Check that the finite difference and expected gradients match. + if !floats.EqualApprox(fdGrad, test.Gradient, defaultFDGradTol) { + dist := floats.Distance(fdGrad, test.Gradient, math.Inf(1)) + t.Errorf("Test #%d: numerical and expected gradients do not match. |fdGrad - WantGrad|_∞ = %v", + i, dist) + } + + // If the function is a Gradient, check that it computes the gradient correctly. + if isGradient { + grad := make([]float64, len(test.Gradient)) + fGradient.Grad(grad, test.X) + + if !floats.EqualApprox(grad, test.Gradient, defaultGradTol) { + dist := floats.Distance(grad, test.Gradient, math.Inf(1)) + t.Errorf("Test #%d: gradient given by Grad is incorrect. |grad - WantGrad|_∞ = %v", + i, dist) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/optimize/functions/vlse.go b/vendor/gonum.org/v1/gonum/optimize/functions/vlse.go new file mode 100644 index 00000000..83fab95f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/functions/vlse.go @@ -0,0 +1,325 @@ +// 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 functions + +import "math" + +// This file implements functions from the Virtual Library of Simulation Experiments. +// https://www.sfu.ca/~ssurjano/optimization.html +// In many cases gradients and Hessians have been added. In some cases, these +// are not defined at certain points or manifolds. The gradient in these locations +// has been set to 0. + +// Ackley implements the Ackley function, a function of arbitrary dimension that +// has many local minima. It has a single global minimum of 0 at 0. Its typical +// domain is the hypercube of [-32.768, 32.768]^d. +// f(x) = -20 * exp(-0.2 sqrt(1/d sum_i x_i^2)) - exp(1/d sum_i cos(2π x_i)) + 20 + exp(1) +// where d is the input dimension. +// +// Reference: +// https://www.sfu.ca/~ssurjano/ackley.html (obtained June 2017) +type Ackley struct{} + +func (Ackley) Func(x []float64) float64 { + var ss, sc float64 + for _, v := range x { + ss += v * v + sc += math.Cos(2 * math.Pi * v) + } + id := 1 / float64(len(x)) + return -20*math.Exp(-0.2*math.Sqrt(id*ss)) - math.Exp(id*sc) + 20 + math.E +} + +// Bukin6 implements Bukin's 6th function. The function is two-dimensional, with +// the typical domain as x_0 ∈ [-15, -5], x_1 ∈ [-3, 3]. The function has a unique +// global minimum at [-10, 1], and many local minima. +// f(x) = 100 * sqrt(|x_1 - 0.01*x_0^2|) + 0.01*|x_0+10| +// Reference: +// https://www.sfu.ca/~ssurjano/bukin6.html (obtained June 2017) +type Bukin6 struct{} + +func (Bukin6) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + return 100*math.Sqrt(math.Abs(x[1]-0.01*x[0]*x[0])) + 0.01*math.Abs(x[0]+10) +} + +// CrossInTray implements the cross-in-tray function. The cross-in-tray function +// is a two-dimensional function with many local minima, and four global minima +// at (±1.3491, ±1.3491). The function is typically evaluated in the square +// [-10,10]^2. +// f(x) = -0.001(|sin(x_0)sin(x_1)exp(|100-sqrt((x_0^2+x_1^2)/π)|)|+1)^0.1 +// Reference: +// https://www.sfu.ca/~ssurjano/crossit.html (obtained June 2017) +type CrossInTray struct{} + +func (CrossInTray) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + exp := math.Abs(100 - math.Sqrt((x0*x0+x1*x1)/math.Pi)) + return -0.0001 * math.Pow(math.Abs(math.Sin(x0)*math.Sin(x1)*math.Exp(exp))+1, 0.1) +} + +// DropWave implements the drop-wave function, a two-dimensional function with +// many local minima and one global minimum at 0. The function is typically evaluated +// in the square [-5.12, 5.12]^2. +// f(x) = - (1+cos(12*sqrt(x0^2+x1^2))) / (0.5*(x0^2+x1^2)+2) +// Reference: +// https://www.sfu.ca/~ssurjano/drop.html (obtained June 2017) +type DropWave struct{} + +func (DropWave) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + num := 1 + math.Cos(12*math.Sqrt(x0*x0+x1*x1)) + den := 0.5*(x0*x0+x1*x1) + 2 + return -num / den +} + +// Eggholder implements the Eggholder function, a two-dimensional function with +// many local minima and one global minimum at [512, 404.2319]. The function +// is typically evaluated in the square [-512, 512]^2. +// f(x) = -(x_1+47)*sin(sqrt(|x_1+x_0/2+47|))-x_1*sin(sqrt(|x_0-(x_1+47)|)) +// Reference: +// https://www.sfu.ca/~ssurjano/egg.html (obtained June 2017) +type Eggholder struct{} + +func (Eggholder) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + return -(x1+47)*math.Sin(math.Sqrt(math.Abs(x1+x0/2+47))) - + x0*math.Sin(math.Sqrt(math.Abs(x0-x1-47))) +} + +// GramacyLee implements the Gramacy-Lee function, a one-dimensional function +// with many local minima. The function is typically evaluated on the domain [0.5, 2.5]. +// f(x) = sin(10πx)/(2x) + (x-1)^4 +// Reference: +// https://www.sfu.ca/~ssurjano/grlee12.html (obtained June 2017) +type GramacyLee struct{} + +func (GramacyLee) Func(x []float64) float64 { + if len(x) != 1 { + panic(badInputDim) + } + x0 := x[0] + return math.Sin(10*math.Pi*x0)/(2*x0) + math.Pow(x0-1, 4) +} + +// Griewank implements the Griewank function, a function of arbitrary dimension that +// has many local minima. It has a single global minimum of 0 at 0. Its typical +// domain is the hypercube of [-600, 600]^d. +// f(x) = \sum_i x_i^2/4000 - \prod_i cos(x_i/sqrt(i)) + 1 +// where d is the input dimension. +// +// Reference: +// https://www.sfu.ca/~ssurjano/griewank.html (obtained June 2017) +type Griewank struct{} + +func (Griewank) Func(x []float64) float64 { + var ss float64 + pc := 1.0 + for i, v := range x { + ss += v * v + pc *= math.Cos(v / math.Sqrt(float64(i+1))) + } + return ss/4000 - pc + 1 +} + +// HolderTable implements the Holder table function. The Holder table function +// is a two-dimensional function with many local minima, and four global minima +// at (±8.05502, ±9.66459). The function is typically evaluated in the square [-10,10]^2. +// f(x) = -|sin(x_0)cos(x1)exp(|1-sqrt(x_0^2+x1^2)/π|)| +// Reference: +// https://www.sfu.ca/~ssurjano/holder.html (obtained June 2017) +type HolderTable struct{} + +func (HolderTable) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + return -math.Abs(math.Sin(x0) * math.Cos(x1) * math.Exp(math.Abs(1-math.Sqrt(x0*x0+x1*x1)/math.Pi))) +} + +// Langermann2 implements the two-dimensional version of the Langermann function. +// The Langermann function has many local minima. The function is typically +// evaluated in the square [0,10]^2. +// f(x) = \sum_1^5 c_i exp(-(1/π)\sum_{j=1}^2(x_j-A_{ij})^2) * cos(π\sum_{j=1}^2 (x_j - A_{ij})^2) +// c = [5]float64{1,2,5,2,3} +// A = [5][2]float64{{3,5},{5,2},{2,1},{1,4},{7,9}} +// Reference: +// https://www.sfu.ca/~ssurjano/langer.html (obtained June 2017) +type Langermann2 struct{} + +func (Langermann2) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + var ( + c = [5]float64{1, 2, 5, 2, 3} + A = [5][2]float64{{3, 5}, {5, 2}, {2, 1}, {1, 4}, {7, 9}} + ) + var f float64 + for i, cv := range c { + var ss float64 + for j, av := range A[i] { + xja := x[j] - av + ss += xja * xja + } + f += cv * math.Exp(-(1/math.Pi)*ss) * math.Cos(math.Pi*ss) + } + return f +} + +// Levy implements the Levy function, a function of arbitrary dimension that +// has many local minima. It has a single global minimum of 0 at 1. Its typical +// domain is the hypercube of [-10, 10]^d. +// f(x) = sin^2(π*w_0) + \sum_{i=0}^{d-2}(w_i-1)^2*[1+10sin^2(π*w_i+1)] + +// (w_{d-1}-1)^2*[1+sin^2(2π*w_{d-1})] +// w_i = 1 + (x_i-1)/4 +// where d is the input dimension. +// +// Reference: +// https://www.sfu.ca/~ssurjano/levy.html (obtained June 2017) +type Levy struct{} + +func (Levy) Func(x []float64) float64 { + w1 := 1 + (x[0]-1)/4 + s1 := math.Sin(math.Pi * w1) + sum := s1 * s1 + for i := 0; i < len(x)-1; i++ { + wi := 1 + (x[i]-1)/4 + s := math.Sin(math.Pi*wi + 1) + sum += (wi - 1) * (wi - 1) * (1 + 10*s*s) + } + wd := 1 + (x[len(x)-1]-1)/4 + sd := math.Sin(2 * math.Pi * wd) + return sum + (wd-1)*(wd-1)*(1+sd*sd) +} + +// Levy13 implements the Levy-13 function, a two-dimensional function +// with many local minima. It has a single global minimum of 0 at 1. Its typical +// domain is the square [-10, 10]^2. +// f(x) = sin^2(3π*x_0) + (x_0-1)^2*[1+sin^2(3π*x_1)] + (x_1-1)^2*[1+sin^2(2π*x_1)] +// Reference: +// https://www.sfu.ca/~ssurjano/levy13.html (obtained June 2017) +type Levy13 struct{} + +func (Levy13) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + s0 := math.Sin(3 * math.Pi * x0) + s1 := math.Sin(3 * math.Pi * x1) + s2 := math.Sin(2 * math.Pi * x1) + return s0*s0 + (x0-1)*(x0-1)*(1+s1*s1) + (x1-1)*(x1-1)*(1+s2*s2) +} + +// Rastrigin implements the Rastrigen function, a function of arbitrary dimension +// that has many local minima. It has a single global minimum of 0 at 0. Its typical +// domain is the hypercube of [-5.12, 5.12]^d. +// f(x) = 10d + \sum_i [x_i^2 - 10cos(2π*x_i)] +// where d is the input dimension. +// +// Reference: +// https://www.sfu.ca/~ssurjano/rastr.html (obtained June 2017) +type Rastrigin struct{} + +func (Rastrigin) Func(x []float64) float64 { + sum := 10 * float64(len(x)) + for _, v := range x { + sum += v*v - 10*math.Cos(2*math.Pi*v) + } + return sum +} + +// Schaffer2 implements the second Schaffer function, a two-dimensional function +// with many local minima. It has a single global minimum of 0 at 0. Its typical +// domain is the square [-100, 100]^2. +// f(x) = 0.5 + (sin^2(x_0^2-x_1^2)-0.5) / (1+0.001*(x_0^2+x_1^2))^2 +// Reference: +// https://www.sfu.ca/~ssurjano/schaffer2.html (obtained June 2017) +type Schaffer2 struct{} + +func (Schaffer2) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + s := math.Sin(x0*x0 - x1*x1) + den := 1 + 0.001*(x0*x0+x1*x1) + return 0.5 + (s*s-0.5)/(den*den) +} + +// Schaffer4 implements the fourth Schaffer function, a two-dimensional function +// with many local minima. Its typical domain is the square [-100, 100]^2. +// f(x) = 0.5 + (cos(sin(|x_0^2-x_1^2|))-0.5) / (1+0.001*(x_0^2+x_1^2))^2 +// Reference: +// https://www.sfu.ca/~ssurjano/schaffer4.html (obtained June 2017) +type Schaffer4 struct{} + +func (Schaffer4) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + den := 1 + 0.001*(x0*x0+x1*x1) + return 0.5 + (math.Cos(math.Sin(math.Abs(x0*x0-x1*x1)))-0.5)/(den*den) +} + +// Schwefel implements the Schwefel function, a function of arbitrary dimension +// that has many local minima. Its typical domain is the hypercube of [-500, 500]^d. +// f(x) = 418.9829*d - \sum_i x_i*sin(sqrt(|x_i|)) +// where d is the input dimension. +// +// Reference: +// https://www.sfu.ca/~ssurjano/schwef.html (obtained June 2017) +type Schwefel struct{} + +func (Schwefel) Func(x []float64) float64 { + var sum float64 + for _, v := range x { + sum += v * math.Sin(math.Sqrt(math.Abs(v))) + } + return 418.9829*float64(len(x)) - sum +} + +// Shubert implements the Shubert function, a two-dimensional function +// with many local minima and many global minima. Its typical domain is the +// square [-10, 10]^2. +// f(x) = (sum_{i=1}^5 i cos((i+1)*x_0+i)) * (\sum_{i=1}^5 i cos((i+1)*x_1+i)) +// Reference: +// https://www.sfu.ca/~ssurjano/shubert.html (obtained June 2017) +type Shubert struct{} + +func (Shubert) Func(x []float64) float64 { + if len(x) != 2 { + panic(badInputDim) + } + x0 := x[0] + x1 := x[1] + var s0, s1 float64 + for i := 1.0; i <= 5.0; i++ { + s0 += i * math.Cos((i+1)*x0+i) + s1 += i * math.Cos((i+1)*x1+i) + } + return s0 * s1 +} diff --git a/vendor/gonum.org/v1/gonum/optimize/global.go b/vendor/gonum.org/v1/gonum/optimize/global.go new file mode 100644 index 00000000..9f73b753 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/global.go @@ -0,0 +1,239 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package optimize + +import ( + "math" + "sync" + "time" +) + +// GlobalMethod is a global optimizer. Typically will require more function +// evaluations and no sense of local convergence +type GlobalMethod interface { + // Global tells method the max number of tasks, method returns how many it wants. + // This is needed to sync the Global goroutines and inside goroutines. + InitGlobal(dim, tasks int) int + // Global method may assume that the same task id always has the same pointer with it. + IterateGlobal(task int, loc *Location) (Operation, error) + Needser + // Done communicates to the optimization method that the optimization has + // concluded to allow for shutdown. + Done() +} + +// Global uses a global optimizer to search for the global minimum of a +// function. A maximization problem can be transformed into a +// minimization problem by multiplying the function by -1. +// +// The first argument represents the problem to be minimized. Its fields are +// routines that evaluate the objective function, gradient, and other +// quantities related to the problem. The objective function, p.Func, must not +// be nil. The optimization method used may require other fields to be non-nil +// as specified by method.Needs. Global will panic if these are not met. The +// method can be determined automatically from the supplied problem which is +// described below. +// +// If p.Status is not nil, it is called before every evaluation. If the +// returned Status is not NotTerminated or the error is not nil, the +// optimization run is terminated. +// +// The third argument contains the settings for the minimization. The +// DefaultGlobalSettings function can be called for a Settings struct with the +// default values initialized. If settings == nil, the default settings are used. +// Global optimization methods typically do not make assumptions about the number +// and location of local minima. Thus, the only convergence metric used is the +// function values found at major iterations of the optimization. Bounds on the +// length of optimization are obeyed, such as the number of allowed function +// evaluations. +// +// The final argument is the optimization method to use. If method == nil, then +// an appropriate default is chosen based on the properties of the other arguments +// (dimension, gradient-free or gradient-based, etc.). +// +// If method implements Statuser, method.Status is called before every call +// to method.Iterate. If the returned Status is not NotTerminated or the +// error is non-nil, the optimization run is terminated. +// +// Global returns a Result struct and any error that occurred. See the +// documentation of Result for more information. +// +// Be aware that the default behavior of Global is to find the minimum. +// For certain functions and optimization methods, this process can take many +// function evaluations. If you would like to put limits on this, for example +// maximum runtime or maximum function evaluations, modify the Settings +// input struct. +// +// Something about Global cannot guarantee strict bounds on function evaluations, +// iterations, etc. in the precense of concurrency. +func Global(p Problem, dim int, settings *Settings, method GlobalMethod) (*Result, error) { + startTime := time.Now() + if method == nil { + method = &GuessAndCheck{} + } + if settings == nil { + settings = DefaultSettingsGlobal() + } + stats := &Stats{} + err := checkOptimization(p, dim, method, settings.Recorder) + if err != nil { + return nil, err + } + + optLoc := newLocation(dim, method) + optLoc.F = math.Inf(1) + + if settings.FunctionConverge != nil { + settings.FunctionConverge.Init(optLoc.F) + } + + stats.Runtime = time.Since(startTime) + + // Send initial location to Recorder + if settings.Recorder != nil { + err = settings.Recorder.Record(optLoc, InitIteration, stats) + if err != nil { + return nil, err + } + } + + // Run optimization + var status Status + status, err = minimizeGlobal(&p, method, settings, stats, optLoc, startTime) + + // Cleanup and collect results + if settings.Recorder != nil && err == nil { + err = settings.Recorder.Record(optLoc, PostIteration, stats) + } + stats.Runtime = time.Since(startTime) + return &Result{ + Location: *optLoc, + Stats: *stats, + Status: status, + }, err +} + +func minimizeGlobal(p *Problem, method GlobalMethod, settings *Settings, stats *Stats, optLoc *Location, startTime time.Time) (status Status, err error) { + dim := len(optLoc.X) + statuser, _ := method.(Statuser) + gs := &globalStatus{ + mux: &sync.RWMutex{}, + stats: stats, + status: NotTerminated, + p: p, + startTime: startTime, + optLoc: optLoc, + settings: settings, + statuser: statuser, + } + + nTasks := settings.Concurrent + nTasks = method.InitGlobal(dim, nTasks) + + // Launch optimization workers + var wg sync.WaitGroup + for task := 0; task < nTasks; task++ { + wg.Add(1) + go func(task int) { + defer wg.Done() + loc := newLocation(dim, method) + x := make([]float64, dim) + globalWorker(task, method, gs, loc, x) + }(task) + } + wg.Wait() + method.Done() + return gs.status, gs.err +} + +type globalStatus struct { + mux *sync.RWMutex + stats *Stats + status Status + p *Problem + startTime time.Time + optLoc *Location + settings *Settings + statuser Statuser + err error +} + +func globalWorker(task int, m GlobalMethod, g *globalStatus, loc *Location, x []float64) { + for { + // Find Evaluation location + op, err := m.IterateGlobal(task, loc) + if err != nil { + // TODO(btracey): Figure out how to handle errors properly. Shut + // everything down? Pass to globalStatus so it can shut everything down? + g.mux.Lock() + g.err = err + g.status = Failure + g.mux.Unlock() + break + } + + // Evaluate location and/or update stats. + status := g.globalOperation(op, loc, x) + if status != NotTerminated { + break + } + } +} + +// globalOperation updates handles the status received by an individual worker. +// It uses a mutex to protect updates where necessary. +func (g *globalStatus) globalOperation(op Operation, loc *Location, x []float64) Status { + // Do a quick check to see if one of the other workers converged in the meantime. + var status Status + var err error + g.mux.RLock() + status = g.status + g.mux.RUnlock() + if status != NotTerminated { + return status + } + switch op { + case NoOperation: + case InitIteration: + panic("optimize: Method returned InitIteration") + case PostIteration: + panic("optimize: Method returned PostIteration") + case MajorIteration: + g.mux.Lock() + g.stats.MajorIterations++ + copyLocation(g.optLoc, loc) + g.mux.Unlock() + + g.mux.RLock() + status = checkConvergence(g.optLoc, g.settings, false) + g.mux.RUnlock() + default: // Any of the Evaluation operations. + status, err = evaluate(g.p, loc, op, x) + g.mux.Lock() + updateStats(g.stats, op) + g.mux.Unlock() + } + + g.mux.Lock() + status, err = iterCleanup(status, err, g.stats, g.settings, g.statuser, g.startTime, loc, op) + // Update the termination status if it hasn't already terminated. + if g.status == NotTerminated { + g.status = status + g.err = err + } + g.mux.Unlock() + + return status +} + +func DefaultSettingsGlobal() *Settings { + return &Settings{ + FunctionThreshold: math.Inf(-1), + FunctionConverge: &FunctionConverge{ + Absolute: 1e-10, + Iterations: 100, + }, + } +} diff --git a/vendor/gonum.org/v1/gonum/optimize/gradientdescent.go b/vendor/gonum.org/v1/gonum/optimize/gradientdescent.go new file mode 100644 index 00000000..292bf5c9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/gradientdescent.go @@ -0,0 +1,63 @@ +// 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 optimize + +import "gonum.org/v1/gonum/floats" + +// GradientDescent implements the steepest descent optimization method that +// performs successive steps along the direction of the negative gradient. +type GradientDescent struct { + // Linesearcher selects suitable steps along the descent direction. + // If Linesearcher is nil, a reasonable default will be chosen. + Linesearcher Linesearcher + // StepSizer determines the initial step size along each direction. + // If StepSizer is nil, a reasonable default will be chosen. + StepSizer StepSizer + + ls *LinesearchMethod +} + +func (g *GradientDescent) Init(loc *Location) (Operation, error) { + if g.Linesearcher == nil { + g.Linesearcher = &Backtracking{} + } + if g.StepSizer == nil { + g.StepSizer = &QuadraticStepSize{} + } + + if g.ls == nil { + g.ls = &LinesearchMethod{} + } + g.ls.Linesearcher = g.Linesearcher + g.ls.NextDirectioner = g + + return g.ls.Init(loc) +} + +func (g *GradientDescent) Iterate(loc *Location) (Operation, error) { + return g.ls.Iterate(loc) +} + +func (g *GradientDescent) InitDirection(loc *Location, dir []float64) (stepSize float64) { + copy(dir, loc.Gradient) + floats.Scale(-1, dir) + return g.StepSizer.Init(loc, dir) +} + +func (g *GradientDescent) NextDirection(loc *Location, dir []float64) (stepSize float64) { + copy(dir, loc.Gradient) + floats.Scale(-1, dir) + return g.StepSizer.StepSize(loc, dir) +} + +func (*GradientDescent) Needs() struct { + Gradient bool + Hessian bool +} { + return struct { + Gradient bool + Hessian bool + }{true, false} +} diff --git a/vendor/gonum.org/v1/gonum/optimize/guessandcheck.go b/vendor/gonum.org/v1/gonum/optimize/guessandcheck.go new file mode 100644 index 00000000..e08fc4c6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/guessandcheck.go @@ -0,0 +1,60 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package optimize + +import ( + "math" + "sync" + + "gonum.org/v1/gonum/stat/distmv" +) + +// GuessAndCheck is a global optimizer that evaluates the function at random +// locations. Not a good optimizer, but useful for comparison and debugging. +type GuessAndCheck struct { + Rander distmv.Rander + + eval []bool + + mux *sync.Mutex + bestF float64 + bestX []float64 +} + +func (g *GuessAndCheck) Needs() struct{ Gradient, Hessian bool } { + return struct{ Gradient, Hessian bool }{false, false} +} + +func (g *GuessAndCheck) Done() { + // No cleanup needed +} + +func (g *GuessAndCheck) InitGlobal(dim, tasks int) int { + g.eval = make([]bool, tasks) + g.bestF = math.Inf(1) + g.bestX = resize(g.bestX, dim) + g.mux = &sync.Mutex{} + return tasks +} + +func (g *GuessAndCheck) IterateGlobal(task int, loc *Location) (Operation, error) { + // Task is true if it contains a new function evaluation. + if g.eval[task] { + g.eval[task] = false + g.mux.Lock() + if loc.F < g.bestF { + g.bestF = loc.F + copy(g.bestX, loc.X) + } else { + loc.F = g.bestF + copy(loc.X, g.bestX) + } + g.mux.Unlock() + return MajorIteration, nil + } + g.eval[task] = true + g.Rander.Rand(loc.X) + return FuncEvaluation, nil +} diff --git a/vendor/gonum.org/v1/gonum/optimize/guessandcheck_test.go b/vendor/gonum.org/v1/gonum/optimize/guessandcheck_test.go new file mode 100644 index 00000000..d906f907 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/guessandcheck_test.go @@ -0,0 +1,34 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package optimize + +import ( + "testing" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/optimize/functions" + "gonum.org/v1/gonum/stat/distmv" +) + +func TestGuessAndCheck(t *testing.T) { + dim := 3000 + problem := Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + } + mu := make([]float64, dim) + sigma := mat.NewSymDense(dim, nil) + for i := 0; i < dim; i++ { + sigma.SetSym(i, i, 1) + } + d, ok := distmv.NewNormal(mu, sigma, nil) + if !ok { + panic("bad test") + } + Global(problem, dim, nil, &GuessAndCheck{Rander: d}) + settings := DefaultSettingsGlobal() + settings.Concurrent = 5 + settings.MajorIterations = 15 + Global(problem, dim, settings, &GuessAndCheck{Rander: d}) +} diff --git a/vendor/gonum.org/v1/gonum/optimize/interfaces.go b/vendor/gonum.org/v1/gonum/optimize/interfaces.go new file mode 100644 index 00000000..12544610 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/interfaces.go @@ -0,0 +1,130 @@ +// 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 optimize + +// A Method can optimize an objective function. +// +// It uses a reverse-communication interface between the optimization method +// and the caller. Method acts as a client that asks the caller to perform +// needed operations via Operation returned from Init and Iterate methods. +// This provides independence of the optimization algorithm on user-supplied +// data and their representation, and enables automation of common operations +// like checking for (various types of) convergence and maintaining statistics. +// +// A Method can command an Evaluation, a MajorIteration or NoOperation operations. +// +// An evaluation operation is one or more of the Evaluation operations +// (FuncEvaluation, GradEvaluation, etc.) which can be combined with +// the bitwise or operator. In an evaluation operation, the requested fields of +// Problem will be evaluated at the point specified in Location.X. +// The corresponding fields of Location will be filled with the results that +// can be retrieved upon the next call to Iterate. The Method interface +// requires that entries of Location are not modified aside from the commanded +// evaluations. Thus, the type implementing Method may use multiple Operations +// to set the Location fields at a particular x value. +// +// Instead of an Evaluation, a Method may declare MajorIteration. In +// a MajorIteration, the values in the fields of Location are treated as +// a potential optimizer. The convergence of the optimization routine +// (GradientThreshold, etc.) is checked at this new best point. In +// a MajorIteration, the fields of Location must be valid and consistent. +// +// A Method must not return InitIteration and PostIteration operations. These are +// reserved for the clients to be passed to Recorders. A Method must also not +// combine the Evaluation operations with the Iteration operations. +type Method interface { + // Init initializes the method based on the initial data in loc, updates it + // and returns the first operation to be carried out by the caller. + // The initial location must be valid as specified by Needs. + Init(loc *Location) (Operation, error) + + // Iterate retrieves data from loc, performs one iteration of the method, + // updates loc and returns the next operation. + Iterate(loc *Location) (Operation, error) + + Needser +} + +type Needser interface { + // Needs specifies information about the objective function needed by the + // optimizer beyond just the function value. The information is used + // internally for initialization and must match evaluation types returned + // by Init and Iterate during the optimization process. + Needs() struct { + Gradient bool + Hessian bool + } +} + +// Statuser can report the status and any error. It is intended for methods as +// an additional error reporting mechanism apart from the errors returned from +// Init and Iterate. +type Statuser interface { + Status() (Status, error) +} + +// Linesearcher is a type that can perform a line search. It tries to find an +// (approximate) minimum of the objective function along the search direction +// dir_k starting at the most recent location x_k, i.e., it tries to minimize +// the function +// φ(step) := f(x_k + step * dir_k) where step > 0. +// Typically, a Linesearcher will be used in conjunction with LinesearchMethod +// for performing gradient-based optimization through sequential line searches. +type Linesearcher interface { + // Init initializes the Linesearcher and a new line search. Value and + // derivative contain φ(0) and φ'(0), respectively, and step contains the + // first trial step length. It returns an Operation that must be one of + // FuncEvaluation, GradEvaluation, FuncEvaluation|GradEvaluation. The + // caller must evaluate φ(step), φ'(step), or both, respectively, and pass + // the result to Linesearcher in value and derivative arguments to Iterate. + Init(value, derivative float64, step float64) Operation + + // Iterate takes in the values of φ and φ' evaluated at the previous step + // and returns the next operation. + // + // If op is one of FuncEvaluation, GradEvaluation, + // FuncEvaluation|GradEvaluation, the caller must evaluate φ(step), + // φ'(step), or both, respectively, and pass the result to Linesearcher in + // value and derivative arguments on the next call to Iterate. + // + // If op is MajorIteration, a sufficiently accurate minimum of φ has been + // found at the previous step and the line search has concluded. Init must + // be called again to initialize a new line search. + // + // If err is nil, op must not specify another operation. If err is not nil, + // the values of op and step are undefined. + Iterate(value, derivative float64) (op Operation, step float64, err error) +} + +// NextDirectioner implements a strategy for computing a new line search +// direction at each major iteration. Typically, a NextDirectioner will be +// used in conjunction with LinesearchMethod for performing gradient-based +// optimization through sequential line searches. +type NextDirectioner interface { + // InitDirection initializes the NextDirectioner at the given starting location, + // putting the initial direction in place into dir, and returning the initial + // step size. InitDirection must not modify Location. + InitDirection(loc *Location, dir []float64) (step float64) + + // NextDirection updates the search direction and step size. Location is + // the location seen at the conclusion of the most recent linesearch. The + // next search direction is put in place into dir, and the next step size + // is returned. NextDirection must not modify Location. + NextDirection(loc *Location, dir []float64) (step float64) +} + +// StepSizer can set the next step size of the optimization given the last Location. +// Returned step size must be positive. +type StepSizer interface { + Init(loc *Location, dir []float64) float64 + StepSize(loc *Location, dir []float64) float64 +} + +// A Recorder can record the progress of the optimization, for example to print +// the progress to StdOut or to a log file. A Recorder must not modify any data. +type Recorder interface { + Init() error + Record(*Location, Operation, *Stats) error +} diff --git a/vendor/gonum.org/v1/gonum/optimize/lbfgs.go b/vendor/gonum.org/v1/gonum/optimize/lbfgs.go new file mode 100644 index 00000000..5c549377 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/lbfgs.go @@ -0,0 +1,167 @@ +// 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 optimize + +import ( + "gonum.org/v1/gonum/floats" +) + +// LBFGS implements the limited-memory BFGS method for gradient-based +// unconstrained minimization. +// +// It stores a modified version of the inverse Hessian approximation H +// implicitly from the last Store iterations while the normal BFGS method +// stores and manipulates H directly as a dense matrix. Therefore LBFGS is more +// appropriate than BFGS for large problems as the cost of LBFGS scales as +// O(Store * dim) while BFGS scales as O(dim^2). The "forgetful" nature of +// LBFGS may also make it perform better than BFGS for functions with Hessians +// that vary rapidly spatially. +type LBFGS struct { + // Linesearcher selects suitable steps along the descent direction. + // Accepted steps should satisfy the strong Wolfe conditions. + // If Linesearcher is nil, a reasonable default will be chosen. + Linesearcher Linesearcher + // Store is the size of the limited-memory storage. + // If Store is 0, it will be defaulted to 15. + Store int + + ls *LinesearchMethod + + dim int // Dimension of the problem + x []float64 // Location at the last major iteration + grad []float64 // Gradient at the last major iteration + + // History + oldest int // Index of the oldest element of the history + y [][]float64 // Last Store values of y + s [][]float64 // Last Store values of s + rho []float64 // Last Store values of rho + a []float64 // Cache of Hessian updates +} + +func (l *LBFGS) Init(loc *Location) (Operation, error) { + if l.Linesearcher == nil { + l.Linesearcher = &Bisection{} + } + if l.Store == 0 { + l.Store = 15 + } + + if l.ls == nil { + l.ls = &LinesearchMethod{} + } + l.ls.Linesearcher = l.Linesearcher + l.ls.NextDirectioner = l + + return l.ls.Init(loc) +} + +func (l *LBFGS) Iterate(loc *Location) (Operation, error) { + return l.ls.Iterate(loc) +} + +func (l *LBFGS) InitDirection(loc *Location, dir []float64) (stepSize float64) { + dim := len(loc.X) + l.dim = dim + l.oldest = 0 + + l.a = resize(l.a, l.Store) + l.rho = resize(l.rho, l.Store) + l.y = l.initHistory(l.y) + l.s = l.initHistory(l.s) + + l.x = resize(l.x, dim) + copy(l.x, loc.X) + + l.grad = resize(l.grad, dim) + copy(l.grad, loc.Gradient) + + copy(dir, loc.Gradient) + floats.Scale(-1, dir) + return 1 / floats.Norm(dir, 2) +} + +func (l *LBFGS) initHistory(hist [][]float64) [][]float64 { + c := cap(hist) + if c < l.Store { + n := make([][]float64, l.Store-c) + hist = append(hist[:c], n...) + } + hist = hist[:l.Store] + for i := range hist { + hist[i] = resize(hist[i], l.dim) + for j := range hist[i] { + hist[i][j] = 0 + } + } + return hist +} + +func (l *LBFGS) NextDirection(loc *Location, dir []float64) (stepSize float64) { + // Uses two-loop correction as described in + // Nocedal, J., Wright, S.: Numerical Optimization (2nd ed). Springer (2006), chapter 7, page 178. + + if len(loc.X) != l.dim { + panic("lbfgs: unexpected size mismatch") + } + if len(loc.Gradient) != l.dim { + panic("lbfgs: unexpected size mismatch") + } + if len(dir) != l.dim { + panic("lbfgs: unexpected size mismatch") + } + + y := l.y[l.oldest] + floats.SubTo(y, loc.Gradient, l.grad) + s := l.s[l.oldest] + floats.SubTo(s, loc.X, l.x) + sDotY := floats.Dot(s, y) + l.rho[l.oldest] = 1 / sDotY + + l.oldest = (l.oldest + 1) % l.Store + + copy(l.x, loc.X) + copy(l.grad, loc.Gradient) + copy(dir, loc.Gradient) + + // Start with the most recent element and go backward, + for i := 0; i < l.Store; i++ { + idx := l.oldest - i - 1 + if idx < 0 { + idx += l.Store + } + l.a[idx] = l.rho[idx] * floats.Dot(l.s[idx], dir) + floats.AddScaled(dir, -l.a[idx], l.y[idx]) + } + + // Scale the initial Hessian. + gamma := sDotY / floats.Dot(y, y) + floats.Scale(gamma, dir) + + // Start with the oldest element and go forward. + for i := 0; i < l.Store; i++ { + idx := i + l.oldest + if idx >= l.Store { + idx -= l.Store + } + beta := l.rho[idx] * floats.Dot(l.y[idx], dir) + floats.AddScaled(dir, l.a[idx]-beta, l.s[idx]) + } + + // dir contains H^{-1} * g, so flip the direction for minimization. + floats.Scale(-1, dir) + + return 1 +} + +func (*LBFGS) Needs() struct { + Gradient bool + Hessian bool +} { + return struct { + Gradient bool + Hessian bool + }{true, false} +} diff --git a/vendor/gonum.org/v1/gonum/optimize/linesearch.go b/vendor/gonum.org/v1/gonum/optimize/linesearch.go new file mode 100644 index 00000000..37ccb90e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/linesearch.go @@ -0,0 +1,218 @@ +// 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 optimize + +import ( + "math" + + "gonum.org/v1/gonum/floats" +) + +// LinesearchMethod represents an abstract optimization method in which a +// function is optimized through successive line search optimizations. +type LinesearchMethod struct { + // NextDirectioner specifies the search direction of each linesearch. + NextDirectioner NextDirectioner + // Linesearcher performs a linesearch along the search direction. + Linesearcher Linesearcher + + x []float64 // Starting point for the current iteration. + dir []float64 // Search direction for the current iteration. + + first bool // Indicator of the first iteration. + nextMajor bool // Indicates that MajorIteration must be commanded at the next call to Iterate. + eval Operation // Indicator of valid fields in Location. + + lastStep float64 // Step taken from x in the previous call to Iterate. + lastOp Operation // Operation returned from the previous call to Iterate. +} + +func (ls *LinesearchMethod) Init(loc *Location) (Operation, error) { + if loc.Gradient == nil { + panic("linesearch: gradient is nil") + } + + dim := len(loc.X) + ls.x = resize(ls.x, dim) + ls.dir = resize(ls.dir, dim) + + ls.first = true + ls.nextMajor = false + + // Indicate that all fields of loc are valid. + ls.eval = FuncEvaluation | GradEvaluation + if loc.Hessian != nil { + ls.eval |= HessEvaluation + } + + ls.lastStep = math.NaN() + ls.lastOp = NoOperation + + return ls.initNextLinesearch(loc) +} + +func (ls *LinesearchMethod) Iterate(loc *Location) (Operation, error) { + switch ls.lastOp { + case NoOperation: + // TODO(vladimir-ch): Either Init has not been called, or the caller is + // trying to resume the optimization run after Iterate previously + // returned with an error. Decide what is the proper thing to do. See also #125. + + case MajorIteration: + // The previous updated location did not converge the full + // optimization. Initialize a new Linesearch. + return ls.initNextLinesearch(loc) + + default: + // Update the indicator of valid fields of loc. + ls.eval |= ls.lastOp + + if ls.nextMajor { + ls.nextMajor = false + + // Linesearcher previously finished, and the invalid fields of loc + // have now been validated. Announce MajorIteration. + ls.lastOp = MajorIteration + return ls.lastOp, nil + } + } + + // Continue the linesearch. + + f := math.NaN() + if ls.eval&FuncEvaluation != 0 { + f = loc.F + } + projGrad := math.NaN() + if ls.eval&GradEvaluation != 0 { + projGrad = floats.Dot(loc.Gradient, ls.dir) + } + op, step, err := ls.Linesearcher.Iterate(f, projGrad) + if err != nil { + return ls.error(err) + } + + switch op { + case MajorIteration: + // Linesearch has been finished. + + ls.lastOp = complementEval(loc, ls.eval) + if ls.lastOp == NoOperation { + // loc is complete, MajorIteration can be declared directly. + ls.lastOp = MajorIteration + } else { + // Declare MajorIteration on the next call to Iterate. + ls.nextMajor = true + } + + case FuncEvaluation, GradEvaluation, FuncEvaluation | GradEvaluation: + if step != ls.lastStep { + // We are moving to a new location, and not, say, evaluating extra + // information at the current location. + + // Compute the next evaluation point and store it in loc.X. + floats.AddScaledTo(loc.X, ls.x, step, ls.dir) + if floats.Equal(ls.x, loc.X) { + // Step size has become so small that the next evaluation point is + // indistinguishable from the starting point for the current + // iteration due to rounding errors. + return ls.error(ErrNoProgress) + } + ls.lastStep = step + ls.eval = NoOperation // Indicate all invalid fields of loc. + } + ls.lastOp = op + + default: + panic("linesearch: Linesearcher returned invalid operation") + } + + return ls.lastOp, nil +} + +func (ls *LinesearchMethod) error(err error) (Operation, error) { + ls.lastOp = NoOperation + return ls.lastOp, err +} + +// initNextLinesearch initializes the next linesearch using the previous +// complete location stored in loc. It fills loc.X and returns an evaluation +// to be performed at loc.X. +func (ls *LinesearchMethod) initNextLinesearch(loc *Location) (Operation, error) { + copy(ls.x, loc.X) + + var step float64 + if ls.first { + ls.first = false + step = ls.NextDirectioner.InitDirection(loc, ls.dir) + } else { + step = ls.NextDirectioner.NextDirection(loc, ls.dir) + } + + projGrad := floats.Dot(loc.Gradient, ls.dir) + if projGrad >= 0 { + return ls.error(ErrNonDescentDirection) + } + + op := ls.Linesearcher.Init(loc.F, projGrad, step) + switch op { + case FuncEvaluation, GradEvaluation, FuncEvaluation | GradEvaluation: + default: + panic("linesearch: Linesearcher returned invalid operation") + } + + floats.AddScaledTo(loc.X, ls.x, step, ls.dir) + if floats.Equal(ls.x, loc.X) { + // Step size is so small that the next evaluation point is + // indistinguishable from the starting point for the current iteration + // due to rounding errors. + return ls.error(ErrNoProgress) + } + + ls.lastStep = step + ls.eval = NoOperation // Invalidate all fields of loc. + + ls.lastOp = op + return ls.lastOp, nil +} + +// ArmijoConditionMet returns true if the Armijo condition (aka sufficient +// decrease) has been met. Under normal conditions, the following should be +// true, though this is not enforced: +// - initGrad < 0 +// - step > 0 +// - 0 < decrease < 1 +func ArmijoConditionMet(currObj, initObj, initGrad, step, decrease float64) bool { + return currObj <= initObj+decrease*step*initGrad +} + +// StrongWolfeConditionsMet returns true if the strong Wolfe conditions have been met. +// The strong Wolfe conditions ensure sufficient decrease in the function +// value, and sufficient decrease in the magnitude of the projected gradient. +// Under normal conditions, the following should be true, though this is not +// enforced: +// - initGrad < 0 +// - step > 0 +// - 0 <= decrease < curvature < 1 +func StrongWolfeConditionsMet(currObj, currGrad, initObj, initGrad, step, decrease, curvature float64) bool { + if currObj > initObj+decrease*step*initGrad { + return false + } + return math.Abs(currGrad) < curvature*math.Abs(initGrad) +} + +// WeakWolfeConditionsMet returns true if the weak Wolfe conditions have been met. +// The weak Wolfe conditions ensure sufficient decrease in the function value, +// and sufficient decrease in the value of the projected gradient. Under normal +// conditions, the following should be true, though this is not enforced: +// - initGrad < 0 +// - step > 0 +// - 0 <= decrease < curvature< 1 +func WeakWolfeConditionsMet(currObj, currGrad, initObj, initGrad, step, decrease, curvature float64) bool { + if currObj > initObj+decrease*step*initGrad { + return false + } + return currGrad >= curvature*initGrad +} diff --git a/vendor/gonum.org/v1/gonum/optimize/linesearcher_test.go b/vendor/gonum.org/v1/gonum/optimize/linesearcher_test.go new file mode 100644 index 00000000..f1def408 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/linesearcher_test.go @@ -0,0 +1,136 @@ +// 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 optimize + +import ( + "fmt" + "math" + "reflect" + "testing" + + "gonum.org/v1/gonum/optimize/functions" +) + +func TestMoreThuente(t *testing.T) { + d := 0.001 + c := 0.001 + ls := &MoreThuente{ + DecreaseFactor: d, + CurvatureFactor: c, + } + testLinesearcher(t, ls, d, c, true) +} + +func TestBisection(t *testing.T) { + c := 0.1 + ls := &Bisection{ + CurvatureFactor: c, + } + testLinesearcher(t, ls, 0, c, true) +} + +func TestBacktracking(t *testing.T) { + d := 0.001 + ls := &Backtracking{ + DecreaseFactor: d, + } + testLinesearcher(t, ls, d, 0, false) +} + +type funcGrader interface { + Func([]float64) float64 + Grad([]float64, []float64) +} + +type linesearcherTest struct { + name string + f func(float64) float64 + g func(float64) float64 +} + +func newLinesearcherTest(name string, fg funcGrader) linesearcherTest { + grad := make([]float64, 1) + return linesearcherTest{ + name: name, + f: func(x float64) float64 { + return fg.Func([]float64{x}) + }, + g: func(x float64) float64 { + fg.Grad(grad, []float64{x}) + return grad[0] + }, + } +} + +func testLinesearcher(t *testing.T, ls Linesearcher, decrease, curvature float64, strongWolfe bool) { + for i, prob := range []linesearcherTest{ + newLinesearcherTest("Concave-to-the-right function", functions.ConcaveRight{}), + newLinesearcherTest("Concave-to-the-left function", functions.ConcaveLeft{}), + newLinesearcherTest("Plassmann wiggly function (l=39, beta=0.01)", functions.Plassmann{39, 0.01}), + newLinesearcherTest("Yanai-Ozawa-Kaneko function (beta1=0.001, beta2=0.001)", functions.YanaiOzawaKaneko{0.001, 0.001}), + newLinesearcherTest("Yanai-Ozawa-Kaneko function (beta1=0.01, beta2=0.001)", functions.YanaiOzawaKaneko{0.01, 0.001}), + newLinesearcherTest("Yanai-Ozawa-Kaneko function (beta1=0.001, beta2=0.01)", functions.YanaiOzawaKaneko{0.001, 0.01}), + } { + for _, initStep := range []float64{0.001, 0.1, 1, 10, 1000} { + prefix := fmt.Sprintf("test %d (%v started from %v)", i, prob.name, initStep) + + f0 := prob.f(0) + g0 := prob.g(0) + if g0 >= 0 { + panic("bad test function") + } + + op := ls.Init(f0, g0, initStep) + if !op.isEvaluation() { + t.Errorf("%v: Linesearcher.Init returned non-evaluating operation %v", prefix, op) + continue + } + + var ( + err error + k int + f, g float64 + step float64 + ) + loop: + for { + switch op { + case MajorIteration: + if f > f0+step*decrease*g0 { + t.Errorf("%v: %v found step %v that does not satisfy the sufficient decrease condition", + prefix, reflect.TypeOf(ls), step) + } + if strongWolfe && math.Abs(g) > curvature*(-g0) { + t.Errorf("%v: %v found step %v that does not satisfy the curvature condition", + prefix, reflect.TypeOf(ls), step) + } + break loop + case FuncEvaluation: + f = prob.f(step) + case GradEvaluation: + g = prob.g(step) + case FuncEvaluation | GradEvaluation: + f = prob.f(step) + g = prob.g(step) + default: + t.Errorf("%v: Linesearcher returned an invalid operation %v", prefix, op) + break loop + } + + k++ + if k == 1000 { + t.Errorf("%v: %v did not finish", prefix, reflect.TypeOf(ls)) + break + } + + op, step, err = ls.Iterate(f, g) + if err != nil { + t.Errorf("%v: %v failed at step %v with %v", prefix, reflect.TypeOf(ls), step, err) + break + } + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/optimize/local.go b/vendor/gonum.org/v1/gonum/optimize/local.go new file mode 100644 index 00000000..241e80fe --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/local.go @@ -0,0 +1,225 @@ +// 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 optimize + +import ( + "math" + "time" +) + +// Local finds a local minimum of a minimization problem using a sequential +// algorithm. A maximization problem can be transformed into a minimization +// problem by multiplying the function by -1. +// +// The first argument represents the problem to be minimized. Its fields are +// routines that evaluate the objective function, gradient, and other +// quantities related to the problem. The objective function, p.Func, must not +// be nil. The optimization method used may require other fields to be non-nil +// as specified by method.Needs. Local will panic if these are not met. The +// method can be determined automatically from the supplied problem which is +// described below. +// +// If p.Status is not nil, it is called before every evaluation. If the +// returned Status is not NotTerminated or the error is not nil, the +// optimization run is terminated. +// +// The second argument is the initial location at which to start the minimization. +// The initial location must be supplied, and must have a length equal to the +// problem dimension. +// +// The third argument contains the settings for the minimization. It is here that +// gradient tolerance, etc. are specified. The DefaultSettings function +// can be called for a Settings struct with the default values initialized. +// If settings == nil, the default settings are used. See the documentation +// for the Settings structure for more information. The optimization Method used +// may also contain settings, see documentation for the appropriate optimizer. +// +// The final argument is the optimization method to use. If method == nil, then +// an appropriate default is chosen based on the properties of the other arguments +// (dimension, gradient-free or gradient-based, etc.). The optimization +// methods in this package are designed such that reasonable defaults occur +// if options are not specified explicitly. For example, the code +// method := &optimize.BFGS{} +// creates a pointer to a new BFGS struct. When Local is called, the settings +// in the method will be populated with default values. The methods are also +// designed such that they can be reused in future calls to Local. +// +// If method implements Statuser, method.Status is called before every call +// to method.Iterate. If the returned Status is not NotTerminated or the +// error is non-nil, the optimization run is terminated. +// +// Local returns a Result struct and any error that occurred. See the +// documentation of Result for more information. +// +// Be aware that the default behavior of Local is to find the minimum. +// For certain functions and optimization methods, this process can take many +// function evaluations. If you would like to put limits on this, for example +// maximum runtime or maximum function evaluations, modify the Settings +// input struct. +func Local(p Problem, initX []float64, settings *Settings, method Method) (*Result, error) { + startTime := time.Now() + dim := len(initX) + if method == nil { + method = getDefaultMethod(&p) + } + if settings == nil { + settings = DefaultSettings() + } + + stats := &Stats{} + + err := checkOptimization(p, dim, method, settings.Recorder) + if err != nil { + return nil, err + } + + optLoc, err := getStartingLocation(&p, method, initX, stats, settings) + if err != nil { + return nil, err + } + + if settings.FunctionConverge != nil { + settings.FunctionConverge.Init(optLoc.F) + } + + stats.Runtime = time.Since(startTime) + + // Send initial location to Recorder + if settings.Recorder != nil { + err = settings.Recorder.Record(optLoc, InitIteration, stats) + if err != nil { + return nil, err + } + } + + // Check if the starting location satisfies the convergence criteria. + status := checkConvergence(optLoc, settings, true) + + // Run optimization + if status == NotTerminated && err == nil { + // The starting location is not good enough, we need to perform a + // minimization. The optimal location will be stored in-place in + // optLoc. + status, err = minimize(&p, method, settings, stats, optLoc, startTime) + } + + // Cleanup and collect results + if settings.Recorder != nil && err == nil { + // Send the optimal location to Recorder. + err = settings.Recorder.Record(optLoc, PostIteration, stats) + } + stats.Runtime = time.Since(startTime) + return &Result{ + Location: *optLoc, + Stats: *stats, + Status: status, + }, err +} + +func minimize(p *Problem, method Method, settings *Settings, stats *Stats, optLoc *Location, startTime time.Time) (status Status, err error) { + loc := &Location{} + copyLocation(loc, optLoc) + x := make([]float64, len(loc.X)) + + statuser, _ := method.(Statuser) + + var op Operation + op, err = method.Init(loc) + if err != nil { + status = Failure + return + } + + for { + // Sequentially call method.Iterate, performing the operations it has + // commanded, until convergence. + + switch op { + case NoOperation: + case InitIteration: + panic("optimize: Method returned InitIteration") + case PostIteration: + panic("optimize: Method returned PostIteration") + case MajorIteration: + copyLocation(optLoc, loc) + stats.MajorIterations++ + status = checkConvergence(optLoc, settings, true) + default: // Any of the Evaluation operations. + status, err = evaluate(p, loc, op, x) + updateStats(stats, op) + } + + status, err = iterCleanup(status, err, stats, settings, statuser, startTime, loc, op) + if status != NotTerminated || err != nil { + return + } + + op, err = method.Iterate(loc) + if err != nil { + status = Failure + return + } + } +} + +func getDefaultMethod(p *Problem) Method { + if p.Grad != nil { + return &BFGS{} + } + return &NelderMead{} +} + +// getStartingLocation allocates and initializes the starting location for the minimization. +func getStartingLocation(p *Problem, method Method, initX []float64, stats *Stats, settings *Settings) (*Location, error) { + dim := len(initX) + loc := newLocation(dim, method) + copy(loc.X, initX) + + if settings.UseInitialData { + loc.F = settings.InitialValue + if loc.Gradient != nil { + initG := settings.InitialGradient + if initG == nil { + panic("optimize: initial gradient is nil") + } + if len(initG) != dim { + panic("optimize: initial gradient size mismatch") + } + copy(loc.Gradient, initG) + } + if loc.Hessian != nil { + initH := settings.InitialHessian + if initH == nil { + panic("optimize: initial Hessian is nil") + } + if initH.Symmetric() != dim { + panic("optimize: initial Hessian size mismatch") + } + loc.Hessian.CopySym(initH) + } + } else { + eval := FuncEvaluation + if loc.Gradient != nil { + eval |= GradEvaluation + } + if loc.Hessian != nil { + eval |= HessEvaluation + } + x := make([]float64, len(loc.X)) + evaluate(p, loc, eval, x) + updateStats(stats, eval) + } + + if math.IsInf(loc.F, 1) || math.IsNaN(loc.F) { + return loc, ErrFunc(loc.F) + } + for i, v := range loc.Gradient { + if math.IsInf(v, 0) || math.IsNaN(v) { + return loc, ErrGrad{Grad: v, Index: i} + } + } + + return loc, nil +} diff --git a/vendor/gonum.org/v1/gonum/optimize/local_example_test.go b/vendor/gonum.org/v1/gonum/optimize/local_example_test.go new file mode 100644 index 00000000..64940388 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/local_example_test.go @@ -0,0 +1,43 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package optimize_test + +import ( + "fmt" + "log" + + "gonum.org/v1/gonum/optimize" + "gonum.org/v1/gonum/optimize/functions" +) + +func ExampleLocal() { + p := optimize.Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + } + + x := []float64{1.3, 0.7, 0.8, 1.9, 1.2} + settings := optimize.DefaultSettings() + settings.Recorder = nil + settings.GradientThreshold = 1e-12 + settings.FunctionConverge = nil + + result, err := optimize.Local(p, x, settings, &optimize.BFGS{}) + if err != nil { + log.Fatal(err) + } + if err = result.Status.Err(); err != nil { + log.Fatal(err) + } + fmt.Printf("result.Status: %v\n", result.Status) + fmt.Printf("result.X: %v\n", result.X) + fmt.Printf("result.F: %v\n", result.F) + fmt.Printf("result.Stats.FuncEvaluations: %d\n", result.Stats.FuncEvaluations) + // Output: + // result.Status: GradientThreshold + // result.X: [1 1 1 1 1] + // result.F: 0 + // result.Stats.FuncEvaluations: 35 +} diff --git a/vendor/gonum.org/v1/gonum/optimize/minimize.go b/vendor/gonum.org/v1/gonum/optimize/minimize.go new file mode 100644 index 00000000..b5373e72 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/minimize.go @@ -0,0 +1,202 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package optimize + +import ( + "fmt" + "math" + "time" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +// newLocation allocates a new locatian structure of the appropriate size. It +// allocates memory based on the dimension and the values in Needs. The initial +// function value is set to math.Inf(1). +func newLocation(dim int, method Needser) *Location { + // TODO(btracey): combine this with Local. + loc := &Location{ + X: make([]float64, dim), + } + loc.F = math.Inf(1) + if method.Needs().Gradient { + loc.Gradient = make([]float64, dim) + } + if method.Needs().Hessian { + loc.Hessian = mat.NewSymDense(dim, nil) + } + return loc +} + +func copyLocation(dst, src *Location) { + dst.X = resize(dst.X, len(src.X)) + copy(dst.X, src.X) + + dst.F = src.F + + dst.Gradient = resize(dst.Gradient, len(src.Gradient)) + copy(dst.Gradient, src.Gradient) + + if src.Hessian != nil { + if dst.Hessian == nil || dst.Hessian.Symmetric() != len(src.X) { + dst.Hessian = mat.NewSymDense(len(src.X), nil) + } + dst.Hessian.CopySym(src.Hessian) + } +} + +func checkOptimization(p Problem, dim int, method Needser, recorder Recorder) error { + if p.Func == nil { + panic(badProblem) + } + if dim <= 0 { + panic("optimize: impossible problem dimension") + } + if err := p.satisfies(method); err != nil { + return err + } + if p.Status != nil { + _, err := p.Status() + if err != nil { + return err + } + } + if recorder != nil { + err := recorder.Init() + if err != nil { + return err + } + } + return nil +} + +// evaluate evaluates the routines specified by the Operation at loc.X, and stores +// the answer into loc. loc.X is copied into x before +// evaluating in order to prevent the routines from modifying it. +func evaluate(p *Problem, loc *Location, op Operation, x []float64) (Status, error) { + if !op.isEvaluation() { + panic(fmt.Sprintf("optimize: invalid evaluation %v", op)) + } + if p.Status != nil { + status, err := p.Status() + if err != nil || status != NotTerminated { + return status, err + } + } + copy(x, loc.X) + if op&FuncEvaluation != 0 { + loc.F = p.Func(x) + } + if op&GradEvaluation != 0 { + p.Grad(loc.Gradient, x) + } + if op&HessEvaluation != 0 { + p.Hess(loc.Hessian, x) + } + return NotTerminated, nil +} + +// checkConvergence returns NotTerminated if the Location does not satisfy the +// convergence criteria given by settings. Otherwise a corresponding status is +// returned. +// Unlike checkLimits, checkConvergence is called only at MajorIterations. +// +// If local is true, gradient convergence is also checked. +func checkConvergence(loc *Location, settings *Settings, local bool) Status { + if local && loc.Gradient != nil { + norm := floats.Norm(loc.Gradient, math.Inf(1)) + if norm < settings.GradientThreshold { + return GradientThreshold + } + } + if loc.F < settings.FunctionThreshold { + return FunctionThreshold + } + if settings.FunctionConverge != nil { + return settings.FunctionConverge.FunctionConverged(loc.F) + } + return NotTerminated +} + +// updateStats updates the statistics based on the operation. +func updateStats(stats *Stats, op Operation) { + if op&FuncEvaluation != 0 { + stats.FuncEvaluations++ + } + if op&GradEvaluation != 0 { + stats.GradEvaluations++ + } + if op&HessEvaluation != 0 { + stats.HessEvaluations++ + } +} + +// checkLimits returns NotTerminated status if the various limits given by +// settings have not been reached. Otherwise it returns a corresponding status. +// Unlike checkConvergence, checkLimits is called by Local and Global at _every_ +// iteration. +func checkLimits(loc *Location, stats *Stats, settings *Settings) Status { + // Check the objective function value for negative infinity because it + // could break the linesearches and -inf is the best we can do anyway. + if math.IsInf(loc.F, -1) { + return FunctionNegativeInfinity + } + + if settings.MajorIterations > 0 && stats.MajorIterations >= settings.MajorIterations { + return IterationLimit + } + + if settings.FuncEvaluations > 0 && stats.FuncEvaluations >= settings.FuncEvaluations { + return FunctionEvaluationLimit + } + + if settings.GradEvaluations > 0 && stats.GradEvaluations >= settings.GradEvaluations { + return GradientEvaluationLimit + } + + if settings.HessEvaluations > 0 && stats.HessEvaluations >= settings.HessEvaluations { + return HessianEvaluationLimit + } + + // TODO(vladimir-ch): It would be nice to update Runtime here. + if settings.Runtime > 0 && stats.Runtime >= settings.Runtime { + return RuntimeLimit + } + + return NotTerminated +} + +// TODO(btracey): better name +func iterCleanup(status Status, err error, stats *Stats, settings *Settings, statuser Statuser, startTime time.Time, loc *Location, op Operation) (Status, error) { + if status != NotTerminated || err != nil { + return status, err + } + + if settings.Recorder != nil { + stats.Runtime = time.Since(startTime) + err = settings.Recorder.Record(loc, op, stats) + if err != nil { + if status == NotTerminated { + status = Failure + } + return status, err + } + } + + stats.Runtime = time.Since(startTime) + status = checkLimits(loc, stats, settings) + if status != NotTerminated { + return status, nil + } + + if statuser != nil { + status, err = statuser.Status() + if err != nil || status != NotTerminated { + return status, err + } + } + return status, nil +} diff --git a/vendor/gonum.org/v1/gonum/optimize/morethuente.go b/vendor/gonum.org/v1/gonum/optimize/morethuente.go new file mode 100644 index 00000000..ec23167b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/morethuente.go @@ -0,0 +1,385 @@ +// 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 optimize + +import "math" + +// MoreThuente is a Linesearcher that finds steps that satisfy both the +// sufficient decrease and curvature conditions (the strong Wolfe conditions). +// +// References: +// - More, J.J. and D.J. Thuente: Line Search Algorithms with Guaranteed Sufficient +// Decrease. ACM Transactions on Mathematical Software 20(3) (1994), 286-307 +type MoreThuente struct { + // DecreaseFactor is the constant factor in the sufficient decrease + // (Armijo) condition. + // It must be in the interval [0, 1). The default value is 0. + DecreaseFactor float64 + // CurvatureFactor is the constant factor in the Wolfe conditions. Smaller + // values result in a more exact line search. + // A set value must be in the interval (0, 1). If it is zero, it will be + // defaulted to 0.9. + CurvatureFactor float64 + // StepTolerance sets the minimum acceptable width for the linesearch + // interval. If the relative interval length is less than this value, + // ErrLinesearcherFailure is returned. + // It must be non-negative. If it is zero, it will be defaulted to 1e-10. + StepTolerance float64 + + // MinimumStep is the minimum step that the linesearcher will take. + // It must be non-negative and less than MaximumStep. Defaults to no + // minimum (a value of 0). + MinimumStep float64 + // MaximumStep is the maximum step that the linesearcher will take. + // It must be greater than MinimumStep. If it is zero, it will be defaulted + // to 1e20. + MaximumStep float64 + + bracketed bool // Indicates if a minimum has been bracketed. + fInit float64 // Function value at step = 0. + gInit float64 // Derivative value at step = 0. + + // When stage is 1, the algorithm updates the interval given by x and y + // so that it contains a minimizer of the modified function + // psi(step) = f(step) - f(0) - DecreaseFactor * step * f'(0). + // When stage is 2, the interval is updated so that it contains a minimizer + // of f. + stage int + + step float64 // Current step. + lower, upper float64 // Lower and upper bounds on the next step. + x float64 // Endpoint of the interval with a lower function value. + fx, gx float64 // Data at x. + y float64 // The other endpoint. + fy, gy float64 // Data at y. + width [2]float64 // Width of the interval at two previous iterations. +} + +const ( + mtMinGrowthFactor float64 = 1.1 + mtMaxGrowthFactor float64 = 4 +) + +func (mt *MoreThuente) Init(f, g float64, step float64) Operation { + // Based on the original Fortran code that is available, for example, from + // http://ftp.mcs.anl.gov/pub/MINPACK-2/csrch/ + // as part of + // MINPACK-2 Project. November 1993. + // Argonne National Laboratory and University of Minnesota. + // Brett M. Averick, Richard G. Carter, and Jorge J. Moré. + + if g >= 0 { + panic("morethuente: initial derivative is non-negative") + } + if step <= 0 { + panic("morethuente: invalid initial step") + } + + if mt.CurvatureFactor == 0 { + mt.CurvatureFactor = 0.9 + } + if mt.StepTolerance == 0 { + mt.StepTolerance = 1e-10 + } + if mt.MaximumStep == 0 { + mt.MaximumStep = 1e20 + } + + if mt.MinimumStep < 0 { + panic("morethuente: minimum step is negative") + } + if mt.MaximumStep <= mt.MinimumStep { + panic("morethuente: maximum step is not greater than minimum step") + } + if mt.DecreaseFactor < 0 || mt.DecreaseFactor >= 1 { + panic("morethuente: invalid decrease factor") + } + if mt.CurvatureFactor <= 0 || mt.CurvatureFactor >= 1 { + panic("morethuente: invalid curvature factor") + } + if mt.StepTolerance <= 0 { + panic("morethuente: step tolerance is not positive") + } + + if step < mt.MinimumStep { + step = mt.MinimumStep + } + if step > mt.MaximumStep { + step = mt.MaximumStep + } + + mt.bracketed = false + mt.stage = 1 + mt.fInit = f + mt.gInit = g + + mt.x, mt.fx, mt.gx = 0, f, g + mt.y, mt.fy, mt.gy = 0, f, g + + mt.lower = 0 + mt.upper = step + mtMaxGrowthFactor*step + + mt.width[0] = mt.MaximumStep - mt.MinimumStep + mt.width[1] = 2 * mt.width[0] + + mt.step = step + return FuncEvaluation | GradEvaluation +} + +func (mt *MoreThuente) Iterate(f, g float64) (Operation, float64, error) { + if mt.stage == 0 { + panic("morethuente: Init has not been called") + } + + gTest := mt.DecreaseFactor * mt.gInit + fTest := mt.fInit + mt.step*gTest + + if mt.bracketed { + if mt.step <= mt.lower || mt.step >= mt.upper || mt.upper-mt.lower <= mt.StepTolerance*mt.upper { + // step contains the best step found (see below). + return NoOperation, mt.step, ErrLinesearcherFailure + } + } + if mt.step == mt.MaximumStep && f <= fTest && g <= gTest { + return NoOperation, mt.step, ErrLinesearcherBound + } + if mt.step == mt.MinimumStep && (f > fTest || g >= gTest) { + return NoOperation, mt.step, ErrLinesearcherFailure + } + + // Test for convergence. + if f <= fTest && math.Abs(g) <= mt.CurvatureFactor*(-mt.gInit) { + mt.stage = 0 + return MajorIteration, mt.step, nil + } + + if mt.stage == 1 && f <= fTest && g >= 0 { + mt.stage = 2 + } + + if mt.stage == 1 && f <= mt.fx && f > fTest { + // Lower function value but the decrease is not sufficient . + + // Compute values and derivatives of the modified function at step, x, y. + fm := f - mt.step*gTest + fxm := mt.fx - mt.x*gTest + fym := mt.fy - mt.y*gTest + gm := g - gTest + gxm := mt.gx - gTest + gym := mt.gy - gTest + // Update x, y and step. + mt.nextStep(fxm, gxm, fym, gym, fm, gm) + // Recover values and derivates of the non-modified function at x and y. + mt.fx = fxm + mt.x*gTest + mt.fy = fym + mt.y*gTest + mt.gx = gxm + gTest + mt.gy = gym + gTest + } else { + // Update x, y and step. + mt.nextStep(mt.fx, mt.gx, mt.fy, mt.gy, f, g) + } + + if mt.bracketed { + // Monitor the length of the bracketing interval. If the interval has + // not been reduced sufficiently after two steps, use bisection to + // force its length to zero. + width := mt.y - mt.x + if math.Abs(width) >= 2.0/3*mt.width[1] { + mt.step = mt.x + 0.5*width + } + mt.width[0], mt.width[1] = math.Abs(width), mt.width[0] + } + + if mt.bracketed { + mt.lower = math.Min(mt.x, mt.y) + mt.upper = math.Max(mt.x, mt.y) + } else { + mt.lower = mt.step + mtMinGrowthFactor*(mt.step-mt.x) + mt.upper = mt.step + mtMaxGrowthFactor*(mt.step-mt.x) + } + + // Force the step to be in [MinimumStep, MaximumStep]. + mt.step = math.Max(mt.MinimumStep, math.Min(mt.step, mt.MaximumStep)) + + if mt.bracketed { + if mt.step <= mt.lower || mt.step >= mt.upper || mt.upper-mt.lower <= mt.StepTolerance*mt.upper { + // If further progress is not possible, set step to the best step + // obtained during the search. + mt.step = mt.x + } + } + + return FuncEvaluation | GradEvaluation, mt.step, nil +} + +// nextStep computes the next safeguarded step and updates the interval that +// contains a step that satisfies the sufficient decrease and curvature +// conditions. +func (mt *MoreThuente) nextStep(fx, gx, fy, gy, f, g float64) { + x := mt.x + y := mt.y + step := mt.step + + gNeg := g < 0 + if gx < 0 { + gNeg = !gNeg + } + + var next float64 + var bracketed bool + switch { + case f > fx: + // A higher function value. The minimum is bracketed between x and step. + // We want the next step to be closer to x because the function value + // there is lower. + + theta := 3*(fx-f)/(step-x) + gx + g + s := math.Max(math.Abs(gx), math.Abs(g)) + s = math.Max(s, math.Abs(theta)) + gamma := s * math.Sqrt((theta/s)*(theta/s)-(gx/s)*(g/s)) + if step < x { + gamma *= -1 + } + p := gamma - gx + theta + q := gamma - gx + gamma + g + r := p / q + stpc := x + r*(step-x) + stpq := x + gx/((fx-f)/(step-x)+gx)/2*(step-x) + + if math.Abs(stpc-x) < math.Abs(stpq-x) { + // The cubic step is closer to x than the quadratic step. + // Take the cubic step. + next = stpc + } else { + // If f is much larger than fx, then the quadratic step may be too + // close to x. Therefore heuristically take the average of the + // cubic and quadratic steps. + next = stpc + (stpq-stpc)/2 + } + bracketed = true + + case gNeg: + // A lower function value and derivatives of opposite sign. The minimum + // is bracketed between x and step. If we choose a step that is far + // from step, the next iteration will also likely fall in this case. + + theta := 3*(fx-f)/(step-x) + gx + g + s := math.Max(math.Abs(gx), math.Abs(g)) + s = math.Max(s, math.Abs(theta)) + gamma := s * math.Sqrt((theta/s)*(theta/s)-(gx/s)*(g/s)) + if step > x { + gamma *= -1 + } + p := gamma - g + theta + q := gamma - g + gamma + gx + r := p / q + stpc := step + r*(x-step) + stpq := step + g/(g-gx)*(x-step) + + if math.Abs(stpc-step) > math.Abs(stpq-step) { + // The cubic step is farther from x than the quadratic step. + // Take the cubic step. + next = stpc + } else { + // Take the quadratic step. + next = stpq + } + bracketed = true + + case math.Abs(g) < math.Abs(gx): + // A lower function value, derivatives of the same sign, and the + // magnitude of the derivative decreases. Extrapolate function values + // at x and step so that the next step lies between step and y. + + theta := 3*(fx-f)/(step-x) + gx + g + s := math.Max(math.Abs(gx), math.Abs(g)) + s = math.Max(s, math.Abs(theta)) + gamma := s * math.Sqrt(math.Max(0, (theta/s)*(theta/s)-(gx/s)*(g/s))) + if step > x { + gamma *= -1 + } + p := gamma - g + theta + q := gamma + gx - g + gamma + r := p / q + var stpc float64 + switch { + case r < 0 && gamma != 0: + stpc = step + r*(x-step) + case step > x: + stpc = mt.upper + default: + stpc = mt.lower + } + stpq := step + g/(g-gx)*(x-step) + + if mt.bracketed { + // We are extrapolating so be cautious and take the step that + // is closer to step. + if math.Abs(stpc-step) < math.Abs(stpq-step) { + next = stpc + } else { + next = stpq + } + // Modify next if it is close to or beyond y. + if step > x { + next = math.Min(step+2.0/3*(y-step), next) + } else { + next = math.Max(step+2.0/3*(y-step), next) + } + } else { + // Minimum has not been bracketed so take the larger step... + if math.Abs(stpc-step) > math.Abs(stpq-step) { + next = stpc + } else { + next = stpq + } + // ...but within reason. + next = math.Max(mt.lower, math.Min(next, mt.upper)) + } + + default: + // A lower function value, derivatives of the same sign, and the + // magnitude of the derivative does not decrease. The function seems to + // decrease rapidly in the direction of the step. + + switch { + case mt.bracketed: + theta := 3*(f-fy)/(y-step) + gy + g + s := math.Max(math.Abs(gy), math.Abs(g)) + s = math.Max(s, math.Abs(theta)) + gamma := s * math.Sqrt((theta/s)*(theta/s)-(gy/s)*(g/s)) + if step > y { + gamma *= -1 + } + p := gamma - g + theta + q := gamma - g + gamma + gy + r := p / q + next = step + r*(y-step) + case step > x: + next = mt.upper + default: + next = mt.lower + } + } + + if f > fx { + // x is still the best step. + mt.y = step + mt.fy = f + mt.gy = g + } else { + // step is the new best step. + if gNeg { + mt.y = x + mt.fy = fx + mt.gy = gx + } + mt.x = step + mt.fx = f + mt.gx = g + } + mt.bracketed = bracketed + mt.step = next +} diff --git a/vendor/gonum.org/v1/gonum/optimize/neldermead.go b/vendor/gonum.org/v1/gonum/optimize/neldermead.go new file mode 100644 index 00000000..18964773 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/neldermead.go @@ -0,0 +1,314 @@ +// 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 optimize + +import ( + "sort" + + "gonum.org/v1/gonum/floats" +) + +// nmIterType is a Nelder-Mead evaluation kind +type nmIterType int + +const ( + nmReflected = iota + nmExpanded + nmContractedInside + nmContractedOutside + nmInitialize + nmShrink + nmMajor +) + +type nmVertexSorter struct { + vertices [][]float64 + values []float64 +} + +func (n nmVertexSorter) Len() int { + return len(n.values) +} + +func (n nmVertexSorter) Less(i, j int) bool { + return n.values[i] < n.values[j] +} + +func (n nmVertexSorter) Swap(i, j int) { + n.values[i], n.values[j] = n.values[j], n.values[i] + n.vertices[i], n.vertices[j] = n.vertices[j], n.vertices[i] +} + +// NelderMead is an implementation of the Nelder-Mead simplex algorithm for +// gradient-free nonlinear optimization (not to be confused with Danzig's +// simplex algorithm for linear programming). The implementation follows the +// algorithm described in +// +// http://epubs.siam.org/doi/pdf/10.1137/S1052623496303470 +// +// If an initial simplex is provided, it is used and initLoc is ignored. If +// InitialVertices and InitialValues are both nil, an initial simplex will be +// generated automatically using the initial location as one vertex, and each +// additional vertex as SimplexSize away in one dimension. +// +// If the simplex update parameters (Reflection, etc.) +// are zero, they will be set automatically based on the dimension according to +// the recommendations in +// +// http://www.webpages.uidaho.edu/~fuchang/res/ANMS.pdf +type NelderMead struct { + InitialVertices [][]float64 + InitialValues []float64 + Reflection float64 // Reflection parameter (>0) + Expansion float64 // Expansion parameter (>1) + Contraction float64 // Contraction parameter (>0, <1) + Shrink float64 // Shrink parameter (>0, <1) + SimplexSize float64 // size of auto-constructed initial simplex + + reflection float64 + expansion float64 + contraction float64 + shrink float64 + + vertices [][]float64 // location of the vertices sorted in ascending f + values []float64 // function values at the vertices sorted in ascending f + centroid []float64 // centroid of all but the worst vertex + + fillIdx int // index for filling the simplex during initialization and shrinking + lastIter nmIterType // Last iteration + reflectedPoint []float64 // Storage of the reflected point location + reflectedValue float64 // Value at the last reflection point +} + +func (n *NelderMead) Init(loc *Location) (Operation, error) { + dim := len(loc.X) + if cap(n.vertices) < dim+1 { + n.vertices = make([][]float64, dim+1) + } + n.vertices = n.vertices[:dim+1] + for i := range n.vertices { + n.vertices[i] = resize(n.vertices[i], dim) + } + n.values = resize(n.values, dim+1) + n.centroid = resize(n.centroid, dim) + n.reflectedPoint = resize(n.reflectedPoint, dim) + + if n.SimplexSize == 0 { + n.SimplexSize = 0.05 + } + + // Default parameter choices are chosen in a dimension-dependent way + // from http://www.webpages.uidaho.edu/~fuchang/res/ANMS.pdf + n.reflection = n.Reflection + if n.reflection == 0 { + n.reflection = 1 + } + n.expansion = n.Expansion + if n.expansion == 0 { + n.expansion = 1 + 2/float64(dim) + } + n.contraction = n.Contraction + if n.contraction == 0 { + n.contraction = 0.75 - 1/(2*float64(dim)) + } + n.shrink = n.Shrink + if n.shrink == 0 { + n.shrink = 1 - 1/float64(dim) + } + + if n.InitialVertices != nil { + // Initial simplex provided. Copy the locations and values, and sort them. + if len(n.InitialVertices) != dim+1 { + panic("neldermead: incorrect number of vertices in initial simplex") + } + if len(n.InitialValues) != dim+1 { + panic("neldermead: incorrect number of values in initial simplex") + } + for i := range n.InitialVertices { + if len(n.InitialVertices[i]) != dim { + panic("neldermead: vertex size mismatch") + } + copy(n.vertices[i], n.InitialVertices[i]) + } + copy(n.values, n.InitialValues) + sort.Sort(nmVertexSorter{n.vertices, n.values}) + computeCentroid(n.vertices, n.centroid) + return n.returnNext(nmMajor, loc) + } + + // No simplex provided. Begin initializing initial simplex. First simplex + // entry is the initial location, then step 1 in every direction. + copy(n.vertices[dim], loc.X) + n.values[dim] = loc.F + n.fillIdx = 0 + loc.X[n.fillIdx] += n.SimplexSize + n.lastIter = nmInitialize + return FuncEvaluation, nil +} + +// computeCentroid computes the centroid of all the simplex vertices except the +// final one +func computeCentroid(vertices [][]float64, centroid []float64) { + dim := len(centroid) + for i := range centroid { + centroid[i] = 0 + } + for i := 0; i < dim; i++ { + vertex := vertices[i] + for j, v := range vertex { + centroid[j] += v + } + } + for i := range centroid { + centroid[i] /= float64(dim) + } +} + +func (n *NelderMead) Iterate(loc *Location) (Operation, error) { + dim := len(loc.X) + switch n.lastIter { + case nmInitialize: + n.values[n.fillIdx] = loc.F + copy(n.vertices[n.fillIdx], loc.X) + n.fillIdx++ + if n.fillIdx == dim { + // Successfully finished building initial simplex. + sort.Sort(nmVertexSorter{n.vertices, n.values}) + computeCentroid(n.vertices, n.centroid) + return n.returnNext(nmMajor, loc) + } + copy(loc.X, n.vertices[dim]) + loc.X[n.fillIdx] += n.SimplexSize + return FuncEvaluation, nil + case nmMajor: + // Nelder Mead iterations start with Reflection step + return n.returnNext(nmReflected, loc) + case nmReflected: + n.reflectedValue = loc.F + switch { + case loc.F >= n.values[0] && loc.F < n.values[dim-1]: + n.replaceWorst(loc.X, loc.F) + return n.returnNext(nmMajor, loc) + case loc.F < n.values[0]: + return n.returnNext(nmExpanded, loc) + default: + if loc.F < n.values[dim] { + return n.returnNext(nmContractedOutside, loc) + } + return n.returnNext(nmContractedInside, loc) + } + case nmExpanded: + if loc.F < n.reflectedValue { + n.replaceWorst(loc.X, loc.F) + } else { + n.replaceWorst(n.reflectedPoint, n.reflectedValue) + } + return n.returnNext(nmMajor, loc) + case nmContractedOutside: + if loc.F <= n.reflectedValue { + n.replaceWorst(loc.X, loc.F) + return n.returnNext(nmMajor, loc) + } + n.fillIdx = 1 + return n.returnNext(nmShrink, loc) + case nmContractedInside: + if loc.F < n.values[dim] { + n.replaceWorst(loc.X, loc.F) + return n.returnNext(nmMajor, loc) + } + n.fillIdx = 1 + return n.returnNext(nmShrink, loc) + case nmShrink: + copy(n.vertices[n.fillIdx], loc.X) + n.values[n.fillIdx] = loc.F + n.fillIdx++ + if n.fillIdx != dim+1 { + return n.returnNext(nmShrink, loc) + } + sort.Sort(nmVertexSorter{n.vertices, n.values}) + computeCentroid(n.vertices, n.centroid) + return n.returnNext(nmMajor, loc) + default: + panic("unreachable") + } +} + +// returnNext updates the location based on the iteration type and the current +// simplex, and returns the next operation. +func (n *NelderMead) returnNext(iter nmIterType, loc *Location) (Operation, error) { + n.lastIter = iter + switch iter { + case nmMajor: + // Fill loc with the current best point and value, + // and command a convergence check. + copy(loc.X, n.vertices[0]) + loc.F = n.values[0] + return MajorIteration, nil + case nmReflected, nmExpanded, nmContractedOutside, nmContractedInside: + // x_new = x_centroid + scale * (x_centroid - x_worst) + var scale float64 + switch iter { + case nmReflected: + scale = n.reflection + case nmExpanded: + scale = n.reflection * n.expansion + case nmContractedOutside: + scale = n.reflection * n.contraction + case nmContractedInside: + scale = -n.contraction + } + dim := len(loc.X) + floats.SubTo(loc.X, n.centroid, n.vertices[dim]) + floats.Scale(scale, loc.X) + floats.Add(loc.X, n.centroid) + if iter == nmReflected { + copy(n.reflectedPoint, loc.X) + } + return FuncEvaluation, nil + case nmShrink: + // x_shrink = x_best + delta * (x_i + x_best) + floats.SubTo(loc.X, n.vertices[n.fillIdx], n.vertices[0]) + floats.Scale(n.shrink, loc.X) + floats.Add(loc.X, n.vertices[0]) + return FuncEvaluation, nil + default: + panic("unreachable") + } +} + +// replaceWorst removes the worst location in the simplex and adds the new +// {x, f} pair maintaining sorting. +func (n *NelderMead) replaceWorst(x []float64, f float64) { + dim := len(x) + if f >= n.values[dim] { + panic("increase in simplex value") + } + copy(n.vertices[dim], x) + n.values[dim] = f + + // Sort the newly-added value. + for i := dim - 1; i >= 0; i-- { + if n.values[i] < f { + break + } + n.vertices[i], n.vertices[i+1] = n.vertices[i+1], n.vertices[i] + n.values[i], n.values[i+1] = n.values[i+1], n.values[i] + } + + // Update the location of the centroid. Only one point has been replaced, so + // subtract the worst point and add the new one. + floats.AddScaled(n.centroid, -1/float64(dim), n.vertices[dim]) + floats.AddScaled(n.centroid, 1/float64(dim), x) +} + +func (*NelderMead) Needs() struct { + Gradient bool + Hessian bool +} { + return struct { + Gradient bool + Hessian bool + }{false, false} +} diff --git a/vendor/gonum.org/v1/gonum/optimize/newton.go b/vendor/gonum.org/v1/gonum/optimize/newton.go new file mode 100644 index 00000000..e87c269f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/newton.go @@ -0,0 +1,147 @@ +// 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 optimize + +import ( + "math" + + "gonum.org/v1/gonum/mat" +) + +const maxNewtonModifications = 20 + +// Newton implements a modified Newton's method for Hessian-based unconstrained +// minimization. It applies regularization when the Hessian is not positive +// definite, and it can converge to a local minimum from any starting point. +// +// Newton iteratively forms a quadratic model to the objective function f and +// tries to minimize this approximate model. It generates a sequence of +// locations x_k by means of +// solve H_k d_k = -∇f_k for d_k, +// x_{k+1} = x_k + α_k d_k, +// where H_k is the Hessian matrix of f at x_k and α_k is a step size found by +// a line search. +// +// Away from a minimizer H_k may not be positive definite and d_k may not be a +// descent direction. Newton implements a Hessian modification strategy that +// adds successively larger multiples of identity to H_k until it becomes +// positive definite. Note that the repeated trial factorization of the +// modified Hessian involved in this process can be computationally expensive. +// +// If the Hessian matrix cannot be formed explicitly or if the computational +// cost of its factorization is prohibitive, BFGS or L-BFGS quasi-Newton method +// can be used instead. +type Newton struct { + // Linesearcher is used for selecting suitable steps along the descent + // direction d. Accepted steps should satisfy at least one of the Wolfe, + // Goldstein or Armijo conditions. + // If Linesearcher == nil, an appropriate default is chosen. + Linesearcher Linesearcher + // Increase is the factor by which a scalar tau is successively increased + // so that (H + tau*I) is positive definite. Larger values reduce the + // number of trial Hessian factorizations, but also reduce the second-order + // information in H. + // Increase must be greater than 1. If Increase is 0, it is defaulted to 5. + Increase float64 + + ls *LinesearchMethod + + hess *mat.SymDense // Storage for a copy of the Hessian matrix. + chol mat.Cholesky // Storage for the Cholesky factorization. + tau float64 +} + +func (n *Newton) Init(loc *Location) (Operation, error) { + if n.Increase == 0 { + n.Increase = 5 + } + if n.Increase <= 1 { + panic("optimize: Newton.Increase must be greater than 1") + } + if n.Linesearcher == nil { + n.Linesearcher = &Bisection{} + } + if n.ls == nil { + n.ls = &LinesearchMethod{} + } + n.ls.Linesearcher = n.Linesearcher + n.ls.NextDirectioner = n + + return n.ls.Init(loc) +} + +func (n *Newton) Iterate(loc *Location) (Operation, error) { + return n.ls.Iterate(loc) +} + +func (n *Newton) InitDirection(loc *Location, dir []float64) (stepSize float64) { + dim := len(loc.X) + n.hess = resizeSymDense(n.hess, dim) + n.tau = 0 + return n.NextDirection(loc, dir) +} + +func (n *Newton) NextDirection(loc *Location, dir []float64) (stepSize float64) { + // This method implements Algorithm 3.3 (Cholesky with Added Multiple of + // the Identity) from Nocedal, Wright (2006), 2nd edition. + + dim := len(loc.X) + d := mat.NewVecDense(dim, dir) + grad := mat.NewVecDense(dim, loc.Gradient) + n.hess.CopySym(loc.Hessian) + + // Find the smallest diagonal entry of the Hessian. + minA := n.hess.At(0, 0) + for i := 1; i < dim; i++ { + a := n.hess.At(i, i) + if a < minA { + minA = a + } + } + // If the smallest diagonal entry is positive, the Hessian may be positive + // definite, and so first attempt to apply the Cholesky factorization to + // the un-modified Hessian. If the smallest entry is negative, use the + // final tau from the last iteration if regularization was needed, + // otherwise guess an appropriate value for tau. + if minA > 0 { + n.tau = 0 + } else if n.tau == 0 { + n.tau = -minA + 0.001 + } + + for k := 0; k < maxNewtonModifications; k++ { + if n.tau != 0 { + // Add a multiple of identity to the Hessian. + for i := 0; i < dim; i++ { + n.hess.SetSym(i, i, loc.Hessian.At(i, i)+n.tau) + } + } + // Try to apply the Cholesky factorization. + pd := n.chol.Factorize(n.hess) + if pd { + // Store the solution in d's backing array, dir. + n.chol.SolveVec(d, grad) + d.ScaleVec(-1, d) + return 1 + } + // Modified Hessian is not PD, so increase tau. + n.tau = math.Max(n.Increase*n.tau, 0.001) + } + + // Hessian modification failed to get a PD matrix. Return the negative + // gradient as the descent direction. + d.ScaleVec(-1, grad) + return 1 +} + +func (n *Newton) Needs() struct { + Gradient bool + Hessian bool +} { + return struct { + Gradient bool + Hessian bool + }{true, true} +} diff --git a/vendor/gonum.org/v1/gonum/optimize/printer.go b/vendor/gonum.org/v1/gonum/optimize/printer.go new file mode 100644 index 00000000..56800f3c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/printer.go @@ -0,0 +1,106 @@ +// 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 optimize + +import ( + "fmt" + "io" + "math" + "os" + "time" + + "gonum.org/v1/gonum/floats" +) + +var printerHeadings = [...]string{ + "Iter", + "Runtime", + "FuncEvals", + "Func", + "GradEvals", + "|Gradient|∞", + "HessEvals", +} + +const ( + printerBaseTmpl = "%9v %16v %9v %22v" // Base template for headings and values that are always printed. + printerGradTmpl = " %9v %22v" // Appended to base template when loc.Gradient != nil. + printerHessTmpl = " %9v" // Appended to base template when loc.Hessian != nil. +) + +// Printer writes column-format output to the specified writer as the optimization +// progresses. By default, it writes to os.Stdout. +type Printer struct { + Writer io.Writer + HeadingInterval int + ValueInterval time.Duration + + lastHeading int + lastValue time.Time +} + +func NewPrinter() *Printer { + return &Printer{ + Writer: os.Stdout, + HeadingInterval: 30, + ValueInterval: 500 * time.Millisecond, + } +} + +func (p *Printer) Init() error { + p.lastHeading = p.HeadingInterval // So the headings are printed the first time. + p.lastValue = time.Now().Add(-p.ValueInterval) // So the values are printed the first time. + return nil +} + +func (p *Printer) Record(loc *Location, op Operation, stats *Stats) error { + if op != MajorIteration && op != InitIteration && op != PostIteration { + return nil + } + + // Print values always on PostIteration or when ValueInterval has elapsed. + printValues := time.Since(p.lastValue) > p.ValueInterval || op == PostIteration + if !printValues { + // Return early if not printing anything. + return nil + } + + // Print heading when HeadingInterval lines have been printed, but never on PostIteration. + printHeading := p.lastHeading >= p.HeadingInterval && op != PostIteration + if printHeading { + p.lastHeading = 1 + } else { + p.lastHeading++ + } + + if printHeading { + headings := "\n" + fmt.Sprintf(printerBaseTmpl, printerHeadings[0], printerHeadings[1], printerHeadings[2], printerHeadings[3]) + if loc.Gradient != nil { + headings += fmt.Sprintf(printerGradTmpl, printerHeadings[4], printerHeadings[5]) + } + if loc.Hessian != nil { + headings += fmt.Sprintf(printerHessTmpl, printerHeadings[6]) + } + _, err := fmt.Fprintln(p.Writer, headings) + if err != nil { + return err + } + } + + values := fmt.Sprintf(printerBaseTmpl, stats.MajorIterations, stats.Runtime, stats.FuncEvaluations, loc.F) + if loc.Gradient != nil { + values += fmt.Sprintf(printerGradTmpl, stats.GradEvaluations, floats.Norm(loc.Gradient, math.Inf(1))) + } + if loc.Hessian != nil { + values += fmt.Sprintf(printerHessTmpl, stats.HessEvaluations) + } + _, err := fmt.Fprintln(p.Writer, values) + if err != nil { + return err + } + + p.lastValue = time.Now() + return nil +} diff --git a/vendor/gonum.org/v1/gonum/optimize/stepsizers.go b/vendor/gonum.org/v1/gonum/optimize/stepsizers.go new file mode 100644 index 00000000..487c158c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/stepsizers.go @@ -0,0 +1,185 @@ +// 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 optimize + +import ( + "math" + + "gonum.org/v1/gonum/floats" +) + +const ( + initialStepFactor = 1 + + quadraticMinimumStepSize = 1e-3 + quadraticMaximumStepSize = 1 + quadraticThreshold = 1e-12 + + firstOrderMinimumStepSize = quadraticMinimumStepSize + firstOrderMaximumStepSize = quadraticMaximumStepSize +) + +// ConstantStepSize is a StepSizer that returns the same step size for +// every iteration. +type ConstantStepSize struct { + Size float64 +} + +func (c ConstantStepSize) Init(_ *Location, _ []float64) float64 { + return c.Size +} + +func (c ConstantStepSize) StepSize(_ *Location, _ []float64) float64 { + return c.Size +} + +// QuadraticStepSize estimates the initial line search step size as the minimum +// of a quadratic that interpolates f(x_{k-1}), f(x_k) and ∇f_k⋅p_k. +// This is useful for line search methods that do not produce well-scaled +// descent directions, such as gradient descent or conjugate gradient methods. +// The step size is bounded away from zero. +type QuadraticStepSize struct { + // Threshold determines that the initial step size should be estimated by + // quadratic interpolation when the relative change in the objective + // function is larger than Threshold. Otherwise the initial step size is + // set to 2*previous step size. + // If Threshold is zero, it will be set to 1e-12. + Threshold float64 + // InitialStepFactor sets the step size for the first iteration to be InitialStepFactor / |g|_∞. + // If InitialStepFactor is zero, it will be set to one. + InitialStepFactor float64 + // MinStepSize is the lower bound on the estimated step size. + // MinStepSize times GradientAbsTol should always be greater than machine epsilon. + // If MinStepSize is zero, it will be set to 1e-3. + MinStepSize float64 + // MaxStepSize is the upper bound on the estimated step size. + // If MaxStepSize is zero, it will be set to 1. + MaxStepSize float64 + + fPrev float64 + dirPrevNorm float64 + projGradPrev float64 + xPrev []float64 +} + +func (q *QuadraticStepSize) Init(loc *Location, dir []float64) (stepSize float64) { + if q.Threshold == 0 { + q.Threshold = quadraticThreshold + } + if q.InitialStepFactor == 0 { + q.InitialStepFactor = initialStepFactor + } + if q.MinStepSize == 0 { + q.MinStepSize = quadraticMinimumStepSize + } + if q.MaxStepSize == 0 { + q.MaxStepSize = quadraticMaximumStepSize + } + if q.MaxStepSize <= q.MinStepSize { + panic("optimize: MinStepSize not smaller than MaxStepSize") + } + + gNorm := floats.Norm(loc.Gradient, math.Inf(1)) + stepSize = math.Max(q.MinStepSize, math.Min(q.InitialStepFactor/gNorm, q.MaxStepSize)) + + q.fPrev = loc.F + q.dirPrevNorm = floats.Norm(dir, 2) + q.projGradPrev = floats.Dot(loc.Gradient, dir) + q.xPrev = resize(q.xPrev, len(loc.X)) + copy(q.xPrev, loc.X) + return stepSize +} + +func (q *QuadraticStepSize) StepSize(loc *Location, dir []float64) (stepSize float64) { + stepSizePrev := floats.Distance(loc.X, q.xPrev, 2) / q.dirPrevNorm + projGrad := floats.Dot(loc.Gradient, dir) + + stepSize = 2 * stepSizePrev + if !floats.EqualWithinRel(q.fPrev, loc.F, q.Threshold) { + // Two consecutive function values are not relatively equal, so + // computing the minimum of a quadratic interpolant might make sense + + df := (loc.F - q.fPrev) / stepSizePrev + quadTest := df - q.projGradPrev + if quadTest > 0 { + // There is a chance of approximating the function well by a + // quadratic only if the finite difference (f_k-f_{k-1})/stepSizePrev + // is larger than ∇f_{k-1}⋅p_{k-1} + + // Set the step size to the minimizer of the quadratic function that + // interpolates f_{k-1}, ∇f_{k-1}⋅p_{k-1} and f_k + stepSize = -q.projGradPrev * stepSizePrev / quadTest / 2 + } + } + // Bound the step size to lie in [MinStepSize, MaxStepSize] + stepSize = math.Max(q.MinStepSize, math.Min(stepSize, q.MaxStepSize)) + + q.fPrev = loc.F + q.dirPrevNorm = floats.Norm(dir, 2) + q.projGradPrev = projGrad + copy(q.xPrev, loc.X) + return stepSize +} + +// FirstOrderStepSize estimates the initial line search step size based on the +// assumption that the first-order change in the function will be the same as +// that obtained at the previous iteration. That is, the initial step size s^0_k +// is chosen so that +// s^0_k ∇f_k⋅p_k = s_{k-1} ∇f_{k-1}⋅p_{k-1} +// This is useful for line search methods that do not produce well-scaled +// descent directions, such as gradient descent or conjugate gradient methods. +type FirstOrderStepSize struct { + // InitialStepFactor sets the step size for the first iteration to be InitialStepFactor / |g|_∞. + // If InitialStepFactor is zero, it will be set to one. + InitialStepFactor float64 + // MinStepSize is the lower bound on the estimated step size. + // MinStepSize times GradientAbsTol should always be greater than machine epsilon. + // If MinStepSize is zero, it will be set to 1e-3. + MinStepSize float64 + // MaxStepSize is the upper bound on the estimated step size. + // If MaxStepSize is zero, it will be set to 1. + MaxStepSize float64 + + dirPrevNorm float64 + projGradPrev float64 + xPrev []float64 +} + +func (fo *FirstOrderStepSize) Init(loc *Location, dir []float64) (stepSize float64) { + if fo.InitialStepFactor == 0 { + fo.InitialStepFactor = initialStepFactor + } + if fo.MinStepSize == 0 { + fo.MinStepSize = firstOrderMinimumStepSize + } + if fo.MaxStepSize == 0 { + fo.MaxStepSize = firstOrderMaximumStepSize + } + if fo.MaxStepSize <= fo.MinStepSize { + panic("optimize: MinStepSize not smaller than MaxStepSize") + } + + gNorm := floats.Norm(loc.Gradient, math.Inf(1)) + stepSize = math.Max(fo.MinStepSize, math.Min(fo.InitialStepFactor/gNorm, fo.MaxStepSize)) + + fo.dirPrevNorm = floats.Norm(dir, 2) + fo.projGradPrev = floats.Dot(loc.Gradient, dir) + fo.xPrev = resize(fo.xPrev, len(loc.X)) + copy(fo.xPrev, loc.X) + return stepSize +} + +func (fo *FirstOrderStepSize) StepSize(loc *Location, dir []float64) (stepSize float64) { + stepSizePrev := floats.Distance(loc.X, fo.xPrev, 2) / fo.dirPrevNorm + projGrad := floats.Dot(loc.Gradient, dir) + + stepSize = stepSizePrev * fo.projGradPrev / projGrad + stepSize = math.Max(fo.MinStepSize, math.Min(stepSize, fo.MaxStepSize)) + + fo.dirPrevNorm = floats.Norm(dir, 2) + fo.projGradPrev = floats.Dot(loc.Gradient, dir) + copy(fo.xPrev, loc.X) + return stepSize +} diff --git a/vendor/gonum.org/v1/gonum/optimize/termination.go b/vendor/gonum.org/v1/gonum/optimize/termination.go new file mode 100644 index 00000000..43c2df68 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/termination.go @@ -0,0 +1,119 @@ +// 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 optimize + +import "errors" + +// Status represents the status of the optimization. Programs +// should not rely on the underlying numeric value of the Status being constant. +type Status int + +const ( + NotTerminated Status = iota + Success + FunctionThreshold + FunctionConvergence + GradientThreshold + StepConvergence + FunctionNegativeInfinity + Failure + IterationLimit + RuntimeLimit + FunctionEvaluationLimit + GradientEvaluationLimit + HessianEvaluationLimit +) + +func (s Status) String() string { + return statuses[s].name +} + +// Early returns true if the status indicates the optimization ended before a +// minimum was found. As an example, if the maximum iterations was reached, a +// minimum was not found, but if the gradient norm was reached then a minimum +// was found. +func (s Status) Early() bool { + return statuses[s].early +} + +// Err returns the error associated with an early ending to the minimization. If +// Early returns false, Err will return nil. +func (s Status) Err() error { + return statuses[s].err +} + +var statuses = []struct { + name string + early bool + err error +}{ + { + name: "NotTerminated", + }, + { + name: "Success", + }, + { + name: "FunctionThreshold", + }, + { + name: "FunctionConvergence", + }, + { + name: "GradientThreshold", + }, + { + name: "StepConvergence", + }, + { + name: "FunctionNegativeInfinity", + }, + { + name: "Failure", + early: true, + err: errors.New("optimize: termination ended in failure"), + }, + { + name: "IterationLimit", + early: true, + err: errors.New("optimize: maximum number of major iterations reached"), + }, + { + name: "RuntimeLimit", + early: true, + err: errors.New("optimize: maximum runtime reached"), + }, + { + name: "FunctionEvaluationLimit", + early: true, + err: errors.New("optimize: maximum number of function evaluations reached"), + }, + { + name: "GradientEvaluationLimit", + early: true, + err: errors.New("optimize: maximum number of gradient evaluations reached"), + }, + { + name: "HessianEvaluationLimit", + early: true, + err: errors.New("optimize: maximum number of Hessian evaluations reached"), + }, +} + +// NewStatus returns a unique Status variable to represent a custom status. +// NewStatus is intended to be called only during package initialization, and +// calls to NewStatus are not thread safe. +// +// NewStatus takes in three arguments, the string that should be output from +// Status.String, a boolean if the status indicates early optimization conclusion, +// and the error to return from Err (if any). +func NewStatus(name string, early bool, err error) Status { + statuses = append(statuses, struct { + name string + early bool + err error + }{name, early, err}) + return Status(len(statuses) - 1) +} diff --git a/vendor/gonum.org/v1/gonum/optimize/types.go b/vendor/gonum.org/v1/gonum/optimize/types.go new file mode 100644 index 00000000..461693ff --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/types.go @@ -0,0 +1,262 @@ +// 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 optimize + +import ( + "errors" + "fmt" + "math" + "time" + + "gonum.org/v1/gonum/mat" +) + +const defaultGradientAbsTol = 1e-6 + +// Operation represents the set of operations commanded by Method at each +// iteration. It is a bitmap of various Iteration and Evaluation constants. +// Individual constants must NOT be combined together by the binary OR operator +// except for the Evaluation operations. +type Operation uint64 + +// Supported Operations. +const ( + // NoOperation specifies that no evaluation or convergence check should + // take place. + NoOperation Operation = 0 + // InitIteration is sent to Recorder to indicate the initial location. + // All fields of the location to record must be valid. + // Method must not return it. + InitIteration Operation = 1 << (iota - 1) + // PostIteration is sent to Recorder to indicate the final location + // reached during an optimization run. + // All fields of the location to record must be valid. + // Method must not return it. + PostIteration + // MajorIteration indicates that the next candidate location for + // an optimum has been found and convergence should be checked. + MajorIteration + // FuncEvaluation specifies that the objective function + // should be evaluated. + FuncEvaluation + // GradEvaluation specifies that the gradient + // of the objective function should be evaluated. + GradEvaluation + // HessEvaluation specifies that the Hessian + // of the objective function should be evaluated. + HessEvaluation + + // Mask for the evaluating operations. + evalMask = FuncEvaluation | GradEvaluation | HessEvaluation +) + +func (op Operation) isEvaluation() bool { + return op&evalMask != 0 && op&^evalMask == 0 +} + +func (op Operation) String() string { + if op&evalMask != 0 { + return fmt.Sprintf("Evaluation(Func: %t, Grad: %t, Hess: %t, Extra: 0b%b)", + op&FuncEvaluation != 0, + op&GradEvaluation != 0, + op&HessEvaluation != 0, + op&^(evalMask)) + } + s, ok := operationNames[op] + if ok { + return s + } + return fmt.Sprintf("Operation(%d)", op) +} + +var operationNames = map[Operation]string{ + NoOperation: "NoOperation", + InitIteration: "InitIteration", + MajorIteration: "MajorIteration", + PostIteration: "PostIteration", +} + +// Location represents a location in the optimization procedure. +type Location struct { + X []float64 + F float64 + Gradient []float64 + Hessian *mat.SymDense +} + +// Result represents the answer of an optimization run. It contains the optimum +// location as well as the Status at convergence and Statistics taken during the +// run. +type Result struct { + Location + Stats + Status Status +} + +// Stats contains the statistics of the run. +type Stats struct { + MajorIterations int // Total number of major iterations + FuncEvaluations int // Number of evaluations of Func + GradEvaluations int // Number of evaluations of Grad + HessEvaluations int // Number of evaluations of Hess + Runtime time.Duration // Total runtime of the optimization +} + +// complementEval returns an evaluating operation that evaluates fields of loc +// not evaluated by eval. +func complementEval(loc *Location, eval Operation) (complEval Operation) { + if eval&FuncEvaluation == 0 { + complEval = FuncEvaluation + } + if loc.Gradient != nil && eval&GradEvaluation == 0 { + complEval |= GradEvaluation + } + if loc.Hessian != nil && eval&HessEvaluation == 0 { + complEval |= HessEvaluation + } + return complEval +} + +// Problem describes the optimization problem to be solved. +type Problem struct { + // Func evaluates the objective function at the given location. Func + // must not modify x. + Func func(x []float64) float64 + + // Grad evaluates the gradient at x and stores the result in-place in grad. + // Grad must not modify x. + Grad func(grad []float64, x []float64) + + // Hess evaluates the Hessian at x and stores the result in-place in hess. + // Hess must not modify x. + Hess func(hess mat.MutableSymmetric, x []float64) + + // Status reports the status of the objective function being optimized and any + // error. This can be used to terminate early, for example when the function is + // not able to evaluate itself. The user can use one of the pre-provided Status + // constants, or may call NewStatus to create a custom Status value. + Status func() (Status, error) +} + +// TODO(btracey): Think about making this an exported function when the +// constraint interface is designed. +func (p Problem) satisfies(method Needser) error { + if method.Needs().Gradient && p.Grad == nil { + return errors.New("optimize: problem does not provide needed Grad function") + } + if method.Needs().Hessian && p.Hess == nil { + return errors.New("optimize: problem does not provide needed Hess function") + } + return nil +} + +// Settings represents settings of the optimization run. It contains initial +// settings, convergence information, and Recorder information. In general, users +// should use DefaultSettings rather than constructing a Settings literal. +// +// If UseInitData is true, InitialValue, InitialGradient and InitialHessian +// specify function information at the initial location. +// +// If Recorder is nil, no information will be recorded. +type Settings struct { + UseInitialData bool // Use supplied information about the conditions at the initial x. + InitialValue float64 // Function value at the initial x. + InitialGradient []float64 // Gradient at the initial x. + InitialHessian *mat.SymDense // Hessian at the initial x. + + // FunctionThreshold is the threshold for acceptably small values of the + // objective function. FunctionThreshold status is returned if + // the objective function is less than this value. + // The default value is -inf. + FunctionThreshold float64 + + // GradientThreshold determines the accuracy to which the minimum is found. + // GradientThreshold status is returned if the infinity norm of + // the gradient is less than this value. + // Has no effect if gradient information is not used. + // The default value is 1e-6. + GradientThreshold float64 + + // FunctionConverge tests that the function value decreases by a + // significant amount over the specified number of iterations. + // + // If f < f_best and + // f_best - f > FunctionConverge.Relative * maxabs(f, f_best) + FunctionConverge.Absolute + // then a significant decrease has occurred, and f_best is updated. + // + // If there is no significant decrease for FunctionConverge.Iterations + // major iterations, FunctionConvergence status is returned. + // + // If this is nil or if FunctionConverge.Iterations == 0, it has no effect. + FunctionConverge *FunctionConverge + + // MajorIterations is the maximum number of iterations allowed. + // IterationLimit status is returned if the number of major iterations + // equals or exceeds this value. + // If it equals zero, this setting has no effect. + // The default value is 0. + MajorIterations int + + // Runtime is the maximum runtime allowed. RuntimeLimit status is returned + // if the duration of the run is longer than this value. Runtime is only + // checked at iterations of the Method. + // If it equals zero, this setting has no effect. + // The default value is 0. + Runtime time.Duration + + // FuncEvaluations is the maximum allowed number of function evaluations. + // FunctionEvaluationLimit status is returned if the total number of calls + // to Func equals or exceeds this number. + // If it equals zero, this setting has no effect. + // The default value is 0. + FuncEvaluations int + + // GradEvaluations is the maximum allowed number of gradient evaluations. + // GradientEvaluationLimit status is returned if the total number of calls + // to Grad equals or exceeds this number. + // If it equals zero, this setting has no effect. + // The default value is 0. + GradEvaluations int + + // HessEvaluations is the maximum allowed number of Hessian evaluations. + // HessianEvaluationLimit status is returned if the total number of calls + // to Hess equals or exceeds this number. + // If it equals zero, this setting has no effect. + // The default value is 0. + HessEvaluations int + + Recorder Recorder + + // Concurrent represents how many concurrent evaluations are possible. + Concurrent int +} + +// DefaultSettings returns a new Settings struct containing the default settings. +func DefaultSettings() *Settings { + return &Settings{ + GradientThreshold: defaultGradientAbsTol, + FunctionThreshold: math.Inf(-1), + FunctionConverge: &FunctionConverge{ + Absolute: 1e-10, + Iterations: 20, + }, + } +} + +// resize takes x and returns a slice of length dim. It returns a resliced x +// if cap(x) >= dim, and a new slice otherwise. +func resize(x []float64, dim int) []float64 { + if dim > cap(x) { + return make([]float64, dim) + } + return x[:dim] +} + +func resizeSymDense(m *mat.SymDense, dim int) *mat.SymDense { + if m == nil || cap(m.RawSymmetric().Data) < dim*dim { + return mat.NewSymDense(dim, nil) + } + return mat.NewSymDense(dim, m.RawSymmetric().Data[:dim*dim]) +} diff --git a/vendor/gonum.org/v1/gonum/optimize/unconstrained_test.go b/vendor/gonum.org/v1/gonum/optimize/unconstrained_test.go new file mode 100644 index 00000000..a8cb373f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/optimize/unconstrained_test.go @@ -0,0 +1,1305 @@ +// 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 optimize + +import ( + "fmt" + "math" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/optimize/functions" +) + +type unconstrainedTest struct { + // name is the name of the test. + name string + // p is the optimization problem to be solved. + p Problem + // x is the initial guess. + x []float64 + // gradTol is the absolute gradient tolerance for the test. If gradTol == 0, + // the default value of 1e-12 will be used. + gradTol float64 + // fAbsTol is the absolute function convergence for the test. If fAbsTol == 0, + // the default value of 1e-12 will be used. + fAbsTol float64 + // fIter is the number of iterations for function convergence. If fIter == 0, + // the default value of 20 will be used. + fIter int + // long indicates that the test takes long time to finish and will be + // excluded if testing.Short returns true. + long bool +} + +func (t unconstrainedTest) String() string { + dim := len(t.x) + if dim <= 10 { + // Print the initial X only for small-dimensional problems. + return fmt.Sprintf("F: %v\nDim: %v\nInitial X: %v\nGradientThreshold: %v", + t.name, dim, t.x, t.gradTol) + } + return fmt.Sprintf("F: %v\nDim: %v\nGradientThreshold: %v", + t.name, dim, t.gradTol) +} + +var gradFreeTests = []unconstrainedTest{ + { + name: "Beale", + p: Problem{ + Func: functions.Beale{}.Func, + }, + x: []float64{1, 1}, + }, + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + }, + x: []float64{1, 2, 1, 1, 1, 1}, + }, + { + name: "BrownAndDennis", + p: Problem{ + Func: functions.BrownAndDennis{}.Func, + }, + x: []float64{25, 5, -5, -1}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + }, + x: []float64{-10, 10}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + }, + x: []float64{-5, 4, 16, 3}, + }, +} + +var gradientDescentTests = []unconstrainedTest{ + { + name: "Beale", + p: Problem{ + Func: functions.Beale{}.Func, + Grad: functions.Beale{}.Grad, + }, + x: []float64{1, 1}, + }, + { + name: "Beale", + p: Problem{ + Func: functions.Beale{}.Func, + Grad: functions.Beale{}.Grad, + }, + x: []float64{3.00001, 0.50001}, + }, + { + name: "BiggsEXP2", + p: Problem{ + Func: functions.BiggsEXP2{}.Func, + Grad: functions.BiggsEXP2{}.Grad, + }, + x: []float64{1, 2}, + }, + { + name: "BiggsEXP2", + p: Problem{ + Func: functions.BiggsEXP2{}.Func, + Grad: functions.BiggsEXP2{}.Grad, + }, + x: []float64{1.00001, 10.00001}, + }, + { + name: "BiggsEXP3", + p: Problem{ + Func: functions.BiggsEXP3{}.Func, + Grad: functions.BiggsEXP3{}.Grad, + }, + x: []float64{1, 2, 1}, + }, + { + name: "BiggsEXP3", + p: Problem{ + Func: functions.BiggsEXP3{}.Func, + Grad: functions.BiggsEXP3{}.Grad, + }, + x: []float64{1.00001, 10.00001, 3.00001}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{-1.2, 1}, + gradTol: 1e-10, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1.00001, 1.00001}, + gradTol: 1e-10, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{-1.2, 1, -1.2}, + gradTol: 1e-10, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{-120, 100, 50}, + long: true, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1, 1, 1}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1.00001, 1.00001, 1.00001}, + gradTol: 1e-8, + }, + { + name: "Gaussian", + p: Problem{ + Func: functions.Gaussian{}.Func, + Grad: functions.Gaussian{}.Grad, + }, + x: []float64{0.4, 1, 0}, + gradTol: 1e-9, + }, + { + name: "Gaussian", + p: Problem{ + Func: functions.Gaussian{}.Func, + Grad: functions.Gaussian{}.Grad, + }, + x: []float64{0.3989561, 1.0000191, 0}, + gradTol: 1e-9, + }, + { + name: "HelicalValley", + p: Problem{ + Func: functions.HelicalValley{}.Func, + Grad: functions.HelicalValley{}.Grad, + }, + x: []float64{-1, 0, 0}, + }, + { + name: "HelicalValley", + p: Problem{ + Func: functions.HelicalValley{}.Func, + Grad: functions.HelicalValley{}.Grad, + }, + x: []float64{1.00001, 0.00001, 0.00001}, + }, + { + name: "Trigonometric", + p: Problem{ + Func: functions.Trigonometric{}.Func, + Grad: functions.Trigonometric{}.Grad, + }, + x: []float64{0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1}, + gradTol: 1e-7, + }, + { + name: "Trigonometric", + p: Problem{ + Func: functions.Trigonometric{}.Func, + Grad: functions.Trigonometric{}.Grad, + }, + x: []float64{0.042964, 0.043976, 0.045093, 0.046338, 0.047744, + 0.049354, 0.051237, 0.195209, 0.164977, 0.060148}, + gradTol: 1e-8, + }, + newVariablyDimensioned(2, 0), + { + name: "VariablyDimensioned", + p: Problem{ + Func: functions.VariablyDimensioned{}.Func, + Grad: functions.VariablyDimensioned{}.Grad, + }, + x: []float64{1.00001, 1.00001}, + }, + newVariablyDimensioned(10, 0), + { + name: "VariablyDimensioned", + p: Problem{ + Func: functions.VariablyDimensioned{}.Func, + Grad: functions.VariablyDimensioned{}.Grad, + }, + x: []float64{1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001, 1.00001}, + }, +} + +var cgTests = []unconstrainedTest{ + { + name: "BiggsEXP4", + p: Problem{ + Func: functions.BiggsEXP4{}.Func, + Grad: functions.BiggsEXP4{}.Grad, + }, + x: []float64{1, 2, 1, 1}, + }, + { + name: "BiggsEXP4", + p: Problem{ + Func: functions.BiggsEXP4{}.Func, + Grad: functions.BiggsEXP4{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001}, + }, + { + name: "BiggsEXP5", + p: Problem{ + Func: functions.BiggsEXP5{}.Func, + Grad: functions.BiggsEXP5{}.Grad, + }, + x: []float64{1, 2, 1, 1, 1}, + gradTol: 1e-7, + }, + { + name: "BiggsEXP5", + p: Problem{ + Func: functions.BiggsEXP5{}.Func, + Grad: functions.BiggsEXP5{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001}, + }, + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1, 2, 1, 1, 1, 1}, + gradTol: 1e-7, + }, + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001}, + gradTol: 1e-8, + }, + { + name: "Box3D", + p: Problem{ + Func: functions.Box3D{}.Func, + Grad: functions.Box3D{}.Grad, + }, + x: []float64{0, 10, 20}, + }, + { + name: "Box3D", + p: Problem{ + Func: functions.Box3D{}.Func, + Grad: functions.Box3D{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001}, + }, + { + name: "Box3D", + p: Problem{ + Func: functions.Box3D{}.Func, + Grad: functions.Box3D{}.Grad, + }, + x: []float64{100.00001, 100.00001, 0.00001}, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{3, -1, 0, 3}, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{0.00001, 0.00001, 0.00001, 0.00001}, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{3, -1, 0, 3, 3, -1, 0, 3}, + gradTol: 1e-8, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{-1.2, 1, -1.2, 1}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1e4, 1e4}, + gradTol: 1e-10, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1.00001, 1.00001, 1.00001, 1.00001}, + gradTol: 1e-10, + }, + { + name: "PenaltyI", + p: Problem{ + Func: functions.PenaltyI{}.Func, + Grad: functions.PenaltyI{}.Grad, + }, + x: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + gradTol: 1e-9, + }, + { + name: "PenaltyI", + p: Problem{ + Func: functions.PenaltyI{}.Func, + Grad: functions.PenaltyI{}.Grad, + }, + x: []float64{0.250007, 0.250007, 0.250007, 0.250007}, + gradTol: 1e-10, + }, + { + name: "PenaltyI", + p: Problem{ + Func: functions.PenaltyI{}.Func, + Grad: functions.PenaltyI{}.Grad, + }, + x: []float64{0.1581, 0.1581, 0.1581, 0.1581, 0.1581, 0.1581, + 0.1581, 0.1581, 0.1581, 0.1581}, + gradTol: 1e-10, + }, + { + name: "PenaltyII", + p: Problem{ + Func: functions.PenaltyII{}.Func, + Grad: functions.PenaltyII{}.Grad, + }, + x: []float64{0.5, 0.5, 0.5, 0.5}, + gradTol: 1e-8, + }, + { + name: "PenaltyII", + p: Problem{ + Func: functions.PenaltyII{}.Func, + Grad: functions.PenaltyII{}.Grad, + }, + x: []float64{0.19999, 0.19131, 0.4801, 0.51884}, + gradTol: 1e-8, + }, + { + name: "PenaltyII", + p: Problem{ + Func: functions.PenaltyII{}.Func, + Grad: functions.PenaltyII{}.Grad, + }, + x: []float64{0.19998, 0.01035, 0.01960, 0.03208, 0.04993, 0.07651, + 0.11862, 0.19214, 0.34732, 0.36916}, + gradTol: 1e-6, + }, + { + name: "PowellBadlyScaled", + p: Problem{ + Func: functions.PowellBadlyScaled{}.Func, + Grad: functions.PowellBadlyScaled{}.Grad, + }, + x: []float64{1.09815e-05, 9.10614}, + gradTol: 1e-8, + }, + newVariablyDimensioned(100, 1e-10), + newVariablyDimensioned(1000, 1e-7), + newVariablyDimensioned(10000, 1e-4), + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{0, 0, 0, 0, 0, 0}, + gradTol: 1e-6, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{-0.01572, 1.01243, -0.23299, 1.26043, -1.51372, 0.99299}, + gradTol: 1e-6, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + gradTol: 1e-6, + long: true, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{-1.53070e-05, 0.99978, 0.01476, 0.14634, 1.00082, + -2.61773, 4.10440, -3.14361, 1.05262}, + gradTol: 1e-6, + }, + { + name: "Wood", + p: Problem{ + Func: functions.Wood{}.Func, + Grad: functions.Wood{}.Grad, + }, + x: []float64{-3, -1, -3, -1}, + gradTol: 1e-6, + }, +} + +var quasiNewtonTests = []unconstrainedTest{ + { + name: "BiggsEXP4", + p: Problem{ + Func: functions.BiggsEXP4{}.Func, + Grad: functions.BiggsEXP4{}.Grad, + }, + x: []float64{1, 2, 1, 1}, + }, + { + name: "BiggsEXP4", + p: Problem{ + Func: functions.BiggsEXP4{}.Func, + Grad: functions.BiggsEXP4{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001}, + }, + { + name: "BiggsEXP5", + p: Problem{ + Func: functions.BiggsEXP5{}.Func, + Grad: functions.BiggsEXP5{}.Grad, + }, + x: []float64{1, 2, 1, 1, 1}, + gradTol: 1e-10, + }, + { + name: "BiggsEXP5", + p: Problem{ + Func: functions.BiggsEXP5{}.Func, + Grad: functions.BiggsEXP5{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001}, + }, + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1, 2, 1, 1, 1, 1}, + gradTol: 1e-8, + }, + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001}, + gradTol: 1e-8, + }, + { + name: "Box3D", + p: Problem{ + Func: functions.Box3D{}.Func, + Grad: functions.Box3D{}.Grad, + }, + x: []float64{0, 10, 20}, + }, + { + name: "Box3D", + p: Problem{ + Func: functions.Box3D{}.Func, + Grad: functions.Box3D{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001}, + }, + { + name: "Box3D", + p: Problem{ + Func: functions.Box3D{}.Func, + Grad: functions.Box3D{}.Grad, + }, + x: []float64{100.00001, 100.00001, 0.00001}, + }, + { + name: "BrownBadlyScaled", + p: Problem{ + Func: functions.BrownBadlyScaled{}.Func, + Grad: functions.BrownBadlyScaled{}.Grad, + }, + x: []float64{1, 1}, + }, + { + name: "BrownBadlyScaled", + p: Problem{ + Func: functions.BrownBadlyScaled{}.Func, + Grad: functions.BrownBadlyScaled{}.Grad, + }, + x: []float64{1.000001e6, 2.01e-6}, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{3, -1, 0, 3}, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{0.00001, 0.00001, 0.00001, 0.00001}, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{3, -1, 0, 3, 3, -1, 0, 3}, + }, + { + name: "ExtendedPowellSingular", + p: Problem{ + Func: functions.ExtendedPowellSingular{}.Func, + Grad: functions.ExtendedPowellSingular{}.Grad, + }, + x: []float64{0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001, 0.00001}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{-1.2, 1, -1.2, 1}, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1.00001, 1.00001, 1.00001, 1.00001}, + }, + { + name: "Gaussian", + p: Problem{ + Func: functions.Gaussian{}.Func, + Grad: functions.Gaussian{}.Grad, + }, + x: []float64{0.4, 1, 0}, + gradTol: 1e-11, + }, + { + name: "GulfResearchAndDevelopment", + p: Problem{ + Func: functions.GulfResearchAndDevelopment{}.Func, + Grad: functions.GulfResearchAndDevelopment{}.Grad, + }, + x: []float64{5, 2.5, 0.15}, + }, + { + name: "GulfResearchAndDevelopment", + p: Problem{ + Func: functions.GulfResearchAndDevelopment{}.Func, + Grad: functions.GulfResearchAndDevelopment{}.Grad, + }, + x: []float64{50.00001, 25.00001, 1.50001}, + }, + { + name: "GulfResearchAndDevelopment", + p: Problem{ + Func: functions.GulfResearchAndDevelopment{}.Func, + Grad: functions.GulfResearchAndDevelopment{}.Grad, + }, + x: []float64{99.89529, 60.61453, 9.16124}, + }, + { + name: "GulfResearchAndDevelopment", + p: Problem{ + Func: functions.GulfResearchAndDevelopment{}.Func, + Grad: functions.GulfResearchAndDevelopment{}.Grad, + }, + x: []float64{201.66258, 60.61633, 10.22489}, + }, + { + name: "PenaltyI", + p: Problem{ + Func: functions.PenaltyI{}.Func, + Grad: functions.PenaltyI{}.Grad, + }, + x: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + }, + { + name: "PenaltyI", + p: Problem{ + Func: functions.PenaltyI{}.Func, + Grad: functions.PenaltyI{}.Grad, + }, + x: []float64{0.250007, 0.250007, 0.250007, 0.250007}, + gradTol: 1e-9, + }, + { + name: "PenaltyI", + p: Problem{ + Func: functions.PenaltyI{}.Func, + Grad: functions.PenaltyI{}.Grad, + }, + x: []float64{0.1581, 0.1581, 0.1581, 0.1581, 0.1581, 0.1581, + 0.1581, 0.1581, 0.1581, 0.1581}, + }, + { + name: "PenaltyII", + p: Problem{ + Func: functions.PenaltyII{}.Func, + Grad: functions.PenaltyII{}.Grad, + }, + x: []float64{0.5, 0.5, 0.5, 0.5}, + gradTol: 1e-10, + }, + { + name: "PenaltyII", + p: Problem{ + Func: functions.PenaltyII{}.Func, + Grad: functions.PenaltyII{}.Grad, + }, + x: []float64{0.19999, 0.19131, 0.4801, 0.51884}, + gradTol: 1e-10, + }, + { + name: "PenaltyII", + p: Problem{ + Func: functions.PenaltyII{}.Func, + Grad: functions.PenaltyII{}.Grad, + }, + x: []float64{0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5}, + gradTol: 1e-9, + }, + { + name: "PenaltyII", + p: Problem{ + Func: functions.PenaltyII{}.Func, + Grad: functions.PenaltyII{}.Grad, + }, + x: []float64{0.19998, 0.01035, 0.01960, 0.03208, 0.04993, 0.07651, + 0.11862, 0.19214, 0.34732, 0.36916}, + gradTol: 1e-9, + }, + { + name: "PowellBadlyScaled", + p: Problem{ + Func: functions.PowellBadlyScaled{}.Func, + Grad: functions.PowellBadlyScaled{}.Grad, + }, + x: []float64{0, 1}, + }, + { + name: "PowellBadlyScaled", + p: Problem{ + Func: functions.PowellBadlyScaled{}.Func, + Grad: functions.PowellBadlyScaled{}.Grad, + }, + x: []float64{1.09815e-05, 9.10614}, + gradTol: 1e-10, + }, + newVariablyDimensioned(100, 1e-10), + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{0, 0, 0, 0, 0, 0}, + gradTol: 1e-7, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{-0.01572, 1.01243, -0.23299, 1.26043, -1.51372, 0.99299}, + gradTol: 1e-7, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0}, + gradTol: 1e-8, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + }, + x: []float64{-1.53070e-05, 0.99978, 0.01476, 0.14634, 1.00082, + -2.61773, 4.10440, -3.14361, 1.05262}, + gradTol: 1e-8, + }, +} + +var bfgsTests = []unconstrainedTest{ + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1, 2, 1, 1, 1, 1}, + gradTol: 1e-10, + }, + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001}, + gradTol: 1e-10, + }, + { + name: "BrownAndDennis", + p: Problem{ + Func: functions.BrownAndDennis{}.Func, + Grad: functions.BrownAndDennis{}.Grad, + }, + x: []float64{25, 5, -5, -1}, + gradTol: 1e-5, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1e5, 1e5}, + gradTol: 1e-10, + }, + { + name: "Gaussian", + p: Problem{ + Func: functions.Gaussian{}.Func, + Grad: functions.Gaussian{}.Grad, + }, + x: []float64{0.398, 1, 0}, + gradTol: 1e-11, + }, + { + name: "Wood", + p: Problem{ + Func: functions.Wood{}.Func, + Grad: functions.Wood{}.Grad, + }, + x: []float64{-3, -1, -3, -1}, + }, +} + +var lbfgsTests = []unconstrainedTest{ + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1, 2, 1, 1, 1, 1}, + gradTol: 1e-8, + }, + { + name: "BiggsEXP6", + p: Problem{ + Func: functions.BiggsEXP6{}.Func, + Grad: functions.BiggsEXP6{}.Grad, + }, + x: []float64{1.00001, 10.00001, 1.00001, 5.00001, 4.00001, 3.00001}, + gradTol: 1e-8, + }, + { + name: "ExtendedRosenbrock", + p: Problem{ + Func: functions.ExtendedRosenbrock{}.Func, + Grad: functions.ExtendedRosenbrock{}.Grad, + }, + x: []float64{1e7, 1e6}, + gradTol: 1e-10, + }, + { + name: "Gaussian", + p: Problem{ + Func: functions.Gaussian{}.Func, + Grad: functions.Gaussian{}.Grad, + }, + x: []float64{0.398, 1, 0}, + gradTol: 1e-10, + }, + newVariablyDimensioned(1000, 1e-8), + newVariablyDimensioned(10000, 1e-5), +} + +var newtonTests = []unconstrainedTest{ + { + name: "Beale", + p: Problem{ + Func: functions.Beale{}.Func, + Grad: functions.Beale{}.Grad, + Hess: functions.Beale{}.Hess, + }, + x: []float64{1, 1}, + }, + { + name: "BrownAndDennis", + p: Problem{ + Func: functions.BrownAndDennis{}.Func, + Grad: functions.BrownAndDennis{}.Grad, + Hess: functions.BrownAndDennis{}.Hess, + }, + x: []float64{25, 5, -5, -1}, + gradTol: 1e-10, + }, + { + name: "BrownBadlyScaled", + p: Problem{ + Func: functions.BrownBadlyScaled{}.Func, + Grad: functions.BrownBadlyScaled{}.Grad, + Hess: functions.BrownBadlyScaled{}.Hess, + }, + x: []float64{1, 1}, + }, + { + name: "PowellBadlyScaled", + p: Problem{ + Func: functions.PowellBadlyScaled{}.Func, + Grad: functions.PowellBadlyScaled{}.Grad, + Hess: functions.PowellBadlyScaled{}.Hess, + }, + x: []float64{0, 1}, + gradTol: 1e-10, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + Hess: functions.Watson{}.Hess, + }, + x: []float64{0, 0, 0, 0, 0, 0}, + }, + { + name: "Watson", + p: Problem{ + Func: functions.Watson{}.Func, + Grad: functions.Watson{}.Grad, + Hess: functions.Watson{}.Hess, + }, + x: []float64{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + }, + { + name: "Wood", + p: Problem{ + Func: functions.Wood{}.Func, + Grad: functions.Wood{}.Grad, + Hess: functions.Wood{}.Hess, + }, + x: []float64{-3, -1, -3, -1}, + }, +} + +func newVariablyDimensioned(dim int, gradTol float64) unconstrainedTest { + x := make([]float64, dim) + for i := range x { + x[i] = float64(dim-i-1) / float64(dim) + } + return unconstrainedTest{ + name: "VariablyDimensioned", + p: Problem{ + Func: functions.VariablyDimensioned{}.Func, + Grad: functions.VariablyDimensioned{}.Grad, + }, + x: x, + gradTol: gradTol, + } +} + +func TestLocal(t *testing.T) { + var tests []unconstrainedTest + // Mix of functions with and without Grad method. + tests = append(tests, gradFreeTests...) + tests = append(tests, gradientDescentTests...) + testLocal(t, tests, nil) +} + +func TestNelderMead(t *testing.T) { + var tests []unconstrainedTest + // Mix of functions with and without Grad method. + tests = append(tests, gradFreeTests...) + tests = append(tests, gradientDescentTests...) + testLocal(t, tests, &NelderMead{}) +} + +func TestGradientDescent(t *testing.T) { + testLocal(t, gradientDescentTests, &GradientDescent{}) +} + +func TestGradientDescentBacktracking(t *testing.T) { + testLocal(t, gradientDescentTests, &GradientDescent{ + Linesearcher: &Backtracking{ + DecreaseFactor: 0.1, + }, + }) +} + +func TestGradientDescentBisection(t *testing.T) { + testLocal(t, gradientDescentTests, &GradientDescent{ + Linesearcher: &Bisection{}, + }) +} + +func TestCG(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{}) +} + +func TestFletcherReevesQuadStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &FletcherReeves{}, + InitialStep: &QuadraticStepSize{}, + }) +} + +func TestFletcherReevesFirstOrderStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &FletcherReeves{}, + InitialStep: &FirstOrderStepSize{}, + }) +} + +func TestHestenesStiefelQuadStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &HestenesStiefel{}, + InitialStep: &QuadraticStepSize{}, + }) +} + +func TestHestenesStiefelFirstOrderStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &HestenesStiefel{}, + InitialStep: &FirstOrderStepSize{}, + }) +} + +func TestPolakRibiereQuadStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &PolakRibierePolyak{}, + InitialStep: &QuadraticStepSize{}, + }) +} + +func TestPolakRibiereFirstOrderStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &PolakRibierePolyak{}, + InitialStep: &FirstOrderStepSize{}, + }) +} + +func TestDaiYuanQuadStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &DaiYuan{}, + InitialStep: &QuadraticStepSize{}, + }) +} + +func TestDaiYuanFirstOrderStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &DaiYuan{}, + InitialStep: &FirstOrderStepSize{}, + }) +} + +func TestHagerZhangQuadStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &HagerZhang{}, + InitialStep: &QuadraticStepSize{}, + }) +} + +func TestHagerZhangFirstOrderStep(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, cgTests...) + testLocal(t, tests, &CG{ + Variant: &HagerZhang{}, + InitialStep: &FirstOrderStepSize{}, + }) +} + +func TestBFGS(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, quasiNewtonTests...) + tests = append(tests, bfgsTests...) + testLocal(t, tests, &BFGS{}) +} + +func TestLBFGS(t *testing.T) { + var tests []unconstrainedTest + tests = append(tests, gradientDescentTests...) + tests = append(tests, quasiNewtonTests...) + tests = append(tests, lbfgsTests...) + testLocal(t, tests, &LBFGS{}) +} + +func TestNewton(t *testing.T) { + testLocal(t, newtonTests, &Newton{}) +} + +func testLocal(t *testing.T, tests []unconstrainedTest, method Method) { + for _, test := range tests { + if test.long && testing.Short() { + continue + } + + settings := DefaultSettings() + settings.Recorder = nil + if method != nil && method.Needs().Gradient { + // Turn off function convergence checks for gradient-based methods. + settings.FunctionConverge = nil + } else { + if test.fIter == 0 { + test.fIter = 20 + } + settings.FunctionConverge.Iterations = test.fIter + if test.fAbsTol == 0 { + test.fAbsTol = 1e-12 + } + settings.FunctionConverge.Absolute = test.fAbsTol + } + if test.gradTol == 0 { + test.gradTol = 1e-12 + } + settings.GradientThreshold = test.gradTol + + result, err := Local(test.p, test.x, settings, method) + if err != nil { + t.Errorf("error finding minimum (%v) for:\n%v", err, test) + continue + } + if result == nil { + t.Errorf("nil result without error for:\n%v", test) + continue + } + + // Check that the function value at the found optimum location is + // equal to result.F. + optF := test.p.Func(result.X) + if optF != result.F { + t.Errorf("Function value at the optimum location %v not equal to the returned value %v for:\n%v", + optF, result.F, test) + } + if result.Gradient != nil { + // Evaluate the norm of the gradient at the found optimum location. + g := make([]float64, len(test.x)) + test.p.Grad(g, result.X) + + if !floats.Equal(result.Gradient, g) { + t.Errorf("Gradient at the optimum location not equal to the returned value for:\n%v", test) + } + + optNorm := floats.Norm(g, math.Inf(1)) + // Check that the norm of the gradient at the found optimum location is + // smaller than the tolerance. + if optNorm >= settings.GradientThreshold { + t.Errorf("Norm of the gradient at the optimum location %v not smaller than tolerance %v for:\n%v", + optNorm, settings.GradientThreshold, test) + } + } + + if method == nil { + // The tests below make sense only if the method used is known. + continue + } + + if !method.Needs().Gradient && !method.Needs().Hessian { + // Gradient-free tests can correctly terminate only with + // FunctionConvergence status. + if result.Status != FunctionConvergence { + t.Errorf("Status not %v, %v instead", FunctionConvergence, result.Status) + } + } + + // We are going to restart the solution using known initial data, so + // evaluate them. + settings.UseInitialData = true + settings.InitialValue = test.p.Func(test.x) + if method.Needs().Gradient { + settings.InitialGradient = resize(settings.InitialGradient, len(test.x)) + test.p.Grad(settings.InitialGradient, test.x) + } + if method.Needs().Hessian { + settings.InitialHessian = mat.NewSymDense(len(test.x), nil) + test.p.Hess(settings.InitialHessian, test.x) + } + + // Rerun the test again to make sure that it gets the same answer with + // the same starting condition. Moreover, we are using the initial data. + result2, err2 := Local(test.p, test.x, settings, method) + if err2 != nil { + t.Errorf("error finding minimum second time (%v) for:\n%v", err2, test) + continue + } + if result2 == nil { + t.Errorf("second time nil result without error for:\n%v", test) + continue + } + + // At the moment all the optimizers are deterministic, so check that we + // get _exactly_ the same answer second time as well. + if result.F != result2.F || !floats.Equal(result.X, result2.X) { + t.Errorf("Different minimum second time for:\n%v", test) + } + + // Check that providing initial data reduces the number of evaluations exactly by one. + if result.FuncEvaluations != result2.FuncEvaluations+1 { + t.Errorf("Providing initial data does not reduce the number of Func calls for:\n%v", test) + continue + } + if method.Needs().Gradient { + if result.GradEvaluations != result2.GradEvaluations+1 { + t.Errorf("Providing initial data does not reduce the number of Grad calls for:\n%v", test) + continue + } + } + if method.Needs().Hessian { + if result.HessEvaluations != result2.HessEvaluations+1 { + t.Errorf("Providing initial data does not reduce the number of Hess calls for:\n%v", test) + continue + } + } + } +} + +func TestIssue76(t *testing.T) { + p := Problem{ + Func: functions.BrownAndDennis{}.Func, + Grad: functions.BrownAndDennis{}.Grad, + } + // Location very close to the minimum. + x := []float64{-11.594439904886773, 13.203630051265385, -0.40343948776868443, 0.2367787746745986} + s := &Settings{ + FunctionThreshold: math.Inf(-1), + GradientThreshold: 1e-14, + MajorIterations: 1000000, + } + m := &GradientDescent{ + Linesearcher: &Backtracking{}, + } + // We are not interested in the error, only in the returned status. + r, _ := Local(p, x, s, m) + // With the above stringent tolerance, the optimizer will never + // successfully reach the minimum. Check if it terminated in a finite + // number of steps. + if r.Status == IterationLimit { + t.Error("Issue https://github.com/gonum/optimize/issues/76 not fixed") + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/README.md b/vendor/gonum.org/v1/gonum/stat/README.md new file mode 100644 index 00000000..31615b05 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/README.md @@ -0,0 +1,3 @@ +# Gonum stat [![GoDoc](https://godoc.org/gonum.org/v1/gonum/stat?status.svg)](https://godoc.org/gonum.org/v1/gonum/stat) + +Package stat is a statistics package for the Go language. diff --git a/vendor/gonum.org/v1/gonum/stat/appengine_test.go b/vendor/gonum.org/v1/gonum/stat/appengine_test.go new file mode 100644 index 00000000..bb2b93c7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/appengine_test.go @@ -0,0 +1,9 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build noasm appengine + +package stat + +func init() { appengine = true } diff --git a/vendor/gonum.org/v1/gonum/stat/boston_data_test.go b/vendor/gonum.org/v1/gonum/stat/boston_data_test.go new file mode 100644 index 00000000..e85a505f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/boston_data_test.go @@ -0,0 +1,531 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat_test + +import "gonum.org/v1/gonum/mat" + +// Boston Housing Data of Harrison and Rubinfeld (1978) +// http://dx.doi.org/10.1016/0095-0696(78)90006-2 +// http://lib.stat.cmu.edu/datasets/boston +// Columns are; +// per capita crime rate by town, +// proportion of non-retail business acres per town, +// nitric oxide concentration (parts per 10 million), +// weighted distances to Boston employment centers, +// index of accessibility to radial highways, +// pupil-teacher ratio by town, +// proportion of blacks by town, +// average number of rooms per dwelling, +// proportion of owner-occupied units built prior to 1940, +// full-value property-tax rate per $10000, +// median value of owner-occupied homes in $1000s. +var bostonData = mat.NewDense(506, 11, []float64{ + 0.00632, 2.31000, 0.53800, 4.09000, 1.00000, 15.30000, 396.90000, 6.57500, 65.20000, 296.00000, 24.00000, + 0.02731, 7.07000, 0.46900, 4.96710, 2.00000, 17.80000, 396.90000, 6.42100, 78.90000, 242.00000, 21.60000, + 0.02729, 7.07000, 0.46900, 4.96710, 2.00000, 17.80000, 392.83000, 7.18500, 61.10000, 242.00000, 34.70000, + 0.03237, 2.18000, 0.45800, 6.06220, 3.00000, 18.70000, 394.63000, 6.99800, 45.80000, 222.00000, 33.40000, + 0.06905, 2.18000, 0.45800, 6.06220, 3.00000, 18.70000, 396.90000, 7.14700, 54.20000, 222.00000, 36.20000, + 0.02985, 2.18000, 0.45800, 6.06220, 3.00000, 18.70000, 394.12000, 6.43000, 58.70000, 222.00000, 28.70000, + 0.08829, 7.87000, 0.52400, 5.56050, 5.00000, 15.20000, 395.60000, 6.01200, 66.60000, 311.00000, 22.90000, + 0.14455, 7.87000, 0.52400, 5.95050, 5.00000, 15.20000, 396.90000, 6.17200, 96.10000, 311.00000, 27.10000, + 0.21124, 7.87000, 0.52400, 6.08210, 5.00000, 15.20000, 386.63000, 5.63100, 100.00000, 311.00000, 16.50000, + 0.17004, 7.87000, 0.52400, 6.59210, 5.00000, 15.20000, 386.71000, 6.00400, 85.90000, 311.00000, 18.90000, + 0.22489, 7.87000, 0.52400, 6.34670, 5.00000, 15.20000, 392.52000, 6.37700, 94.30000, 311.00000, 15.00000, + 0.11747, 7.87000, 0.52400, 6.22670, 5.00000, 15.20000, 396.90000, 6.00900, 82.90000, 311.00000, 18.90000, + 0.09378, 7.87000, 0.52400, 5.45090, 5.00000, 15.20000, 390.50000, 5.88900, 39.00000, 311.00000, 21.70000, + 0.62976, 8.14000, 0.53800, 4.70750, 4.00000, 21.00000, 396.90000, 5.94900, 61.80000, 307.00000, 20.40000, + 0.63796, 8.14000, 0.53800, 4.46190, 4.00000, 21.00000, 380.02000, 6.09600, 84.50000, 307.00000, 18.20000, + 0.62739, 8.14000, 0.53800, 4.49860, 4.00000, 21.00000, 395.62000, 5.83400, 56.50000, 307.00000, 19.90000, + 1.05393, 8.14000, 0.53800, 4.49860, 4.00000, 21.00000, 386.85000, 5.93500, 29.30000, 307.00000, 23.10000, + 0.78420, 8.14000, 0.53800, 4.25790, 4.00000, 21.00000, 386.75000, 5.99000, 81.70000, 307.00000, 17.50000, + 0.80271, 8.14000, 0.53800, 3.79650, 4.00000, 21.00000, 288.99000, 5.45600, 36.60000, 307.00000, 20.20000, + 0.72580, 8.14000, 0.53800, 3.79650, 4.00000, 21.00000, 390.95000, 5.72700, 69.50000, 307.00000, 18.20000, + 1.25179, 8.14000, 0.53800, 3.79790, 4.00000, 21.00000, 376.57000, 5.57000, 98.10000, 307.00000, 13.60000, + 0.85204, 8.14000, 0.53800, 4.01230, 4.00000, 21.00000, 392.53000, 5.96500, 89.20000, 307.00000, 19.60000, + 1.23247, 8.14000, 0.53800, 3.97690, 4.00000, 21.00000, 396.90000, 6.14200, 91.70000, 307.00000, 15.20000, + 0.98843, 8.14000, 0.53800, 4.09520, 4.00000, 21.00000, 394.54000, 5.81300, 100.00000, 307.00000, 14.50000, + 0.75026, 8.14000, 0.53800, 4.39960, 4.00000, 21.00000, 394.33000, 5.92400, 94.10000, 307.00000, 15.60000, + 0.84054, 8.14000, 0.53800, 4.45460, 4.00000, 21.00000, 303.42000, 5.59900, 85.70000, 307.00000, 13.90000, + 0.67191, 8.14000, 0.53800, 4.68200, 4.00000, 21.00000, 376.88000, 5.81300, 90.30000, 307.00000, 16.60000, + 0.95577, 8.14000, 0.53800, 4.45340, 4.00000, 21.00000, 306.38000, 6.04700, 88.80000, 307.00000, 14.80000, + 0.77299, 8.14000, 0.53800, 4.45470, 4.00000, 21.00000, 387.94000, 6.49500, 94.40000, 307.00000, 18.40000, + 1.00245, 8.14000, 0.53800, 4.23900, 4.00000, 21.00000, 380.23000, 6.67400, 87.30000, 307.00000, 21.00000, + 1.13081, 8.14000, 0.53800, 4.23300, 4.00000, 21.00000, 360.17000, 5.71300, 94.10000, 307.00000, 12.70000, + 1.35472, 8.14000, 0.53800, 4.17500, 4.00000, 21.00000, 376.73000, 6.07200, 100.00000, 307.00000, 14.50000, + 1.38799, 8.14000, 0.53800, 3.99000, 4.00000, 21.00000, 232.60000, 5.95000, 82.00000, 307.00000, 13.20000, + 1.15172, 8.14000, 0.53800, 3.78720, 4.00000, 21.00000, 358.77000, 5.70100, 95.00000, 307.00000, 13.10000, + 1.61282, 8.14000, 0.53800, 3.75980, 4.00000, 21.00000, 248.31000, 6.09600, 96.90000, 307.00000, 13.50000, + 0.06417, 5.96000, 0.49900, 3.36030, 5.00000, 19.20000, 396.90000, 5.93300, 68.20000, 279.00000, 18.90000, + 0.09744, 5.96000, 0.49900, 3.37790, 5.00000, 19.20000, 377.56000, 5.84100, 61.40000, 279.00000, 20.00000, + 0.08014, 5.96000, 0.49900, 3.93420, 5.00000, 19.20000, 396.90000, 5.85000, 41.50000, 279.00000, 21.00000, + 0.17505, 5.96000, 0.49900, 3.84730, 5.00000, 19.20000, 393.43000, 5.96600, 30.20000, 279.00000, 24.70000, + 0.02763, 2.95000, 0.42800, 5.40110, 3.00000, 18.30000, 395.63000, 6.59500, 21.80000, 252.00000, 30.80000, + 0.03359, 2.95000, 0.42800, 5.40110, 3.00000, 18.30000, 395.62000, 7.02400, 15.80000, 252.00000, 34.90000, + 0.12744, 6.91000, 0.44800, 5.72090, 3.00000, 17.90000, 385.41000, 6.77000, 2.90000, 233.00000, 26.60000, + 0.14150, 6.91000, 0.44800, 5.72090, 3.00000, 17.90000, 383.37000, 6.16900, 6.60000, 233.00000, 25.30000, + 0.15936, 6.91000, 0.44800, 5.72090, 3.00000, 17.90000, 394.46000, 6.21100, 6.50000, 233.00000, 24.70000, + 0.12269, 6.91000, 0.44800, 5.72090, 3.00000, 17.90000, 389.39000, 6.06900, 40.00000, 233.00000, 21.20000, + 0.17142, 6.91000, 0.44800, 5.10040, 3.00000, 17.90000, 396.90000, 5.68200, 33.80000, 233.00000, 19.30000, + 0.18836, 6.91000, 0.44800, 5.10040, 3.00000, 17.90000, 396.90000, 5.78600, 33.30000, 233.00000, 20.00000, + 0.22927, 6.91000, 0.44800, 5.68940, 3.00000, 17.90000, 392.74000, 6.03000, 85.50000, 233.00000, 16.60000, + 0.25387, 6.91000, 0.44800, 5.87000, 3.00000, 17.90000, 396.90000, 5.39900, 95.30000, 233.00000, 14.40000, + 0.21977, 6.91000, 0.44800, 6.08770, 3.00000, 17.90000, 396.90000, 5.60200, 62.00000, 233.00000, 19.40000, + 0.08873, 5.64000, 0.43900, 6.81470, 4.00000, 16.80000, 395.56000, 5.96300, 45.70000, 243.00000, 19.70000, + 0.04337, 5.64000, 0.43900, 6.81470, 4.00000, 16.80000, 393.97000, 6.11500, 63.00000, 243.00000, 20.50000, + 0.05360, 5.64000, 0.43900, 6.81470, 4.00000, 16.80000, 396.90000, 6.51100, 21.10000, 243.00000, 25.00000, + 0.04981, 5.64000, 0.43900, 6.81470, 4.00000, 16.80000, 396.90000, 5.99800, 21.40000, 243.00000, 23.40000, + 0.01360, 4.00000, 0.41000, 7.31970, 3.00000, 21.10000, 396.90000, 5.88800, 47.60000, 469.00000, 18.90000, + 0.01311, 1.22000, 0.40300, 8.69660, 5.00000, 17.90000, 395.93000, 7.24900, 21.90000, 226.00000, 35.40000, + 0.02055, 0.74000, 0.41000, 9.18760, 2.00000, 17.30000, 396.90000, 6.38300, 35.70000, 313.00000, 24.70000, + 0.01432, 1.32000, 0.41100, 8.32480, 5.00000, 15.10000, 392.90000, 6.81600, 40.50000, 256.00000, 31.60000, + 0.15445, 5.13000, 0.45300, 7.81480, 8.00000, 19.70000, 390.68000, 6.14500, 29.20000, 284.00000, 23.30000, + 0.10328, 5.13000, 0.45300, 6.93200, 8.00000, 19.70000, 396.90000, 5.92700, 47.20000, 284.00000, 19.60000, + 0.14932, 5.13000, 0.45300, 7.22540, 8.00000, 19.70000, 395.11000, 5.74100, 66.20000, 284.00000, 18.70000, + 0.17171, 5.13000, 0.45300, 6.81850, 8.00000, 19.70000, 378.08000, 5.96600, 93.40000, 284.00000, 16.00000, + 0.11027, 5.13000, 0.45300, 7.22550, 8.00000, 19.70000, 396.90000, 6.45600, 67.80000, 284.00000, 22.20000, + 0.12650, 5.13000, 0.45300, 7.98090, 8.00000, 19.70000, 395.58000, 6.76200, 43.40000, 284.00000, 25.00000, + 0.01951, 1.38000, 0.41610, 9.22290, 3.00000, 18.60000, 393.24000, 7.10400, 59.50000, 216.00000, 33.00000, + 0.03584, 3.37000, 0.39800, 6.61150, 4.00000, 16.10000, 396.90000, 6.29000, 17.80000, 337.00000, 23.50000, + 0.04379, 3.37000, 0.39800, 6.61150, 4.00000, 16.10000, 396.90000, 5.78700, 31.10000, 337.00000, 19.40000, + 0.05789, 6.07000, 0.40900, 6.49800, 4.00000, 18.90000, 396.21000, 5.87800, 21.40000, 345.00000, 22.00000, + 0.13554, 6.07000, 0.40900, 6.49800, 4.00000, 18.90000, 396.90000, 5.59400, 36.80000, 345.00000, 17.40000, + 0.12816, 6.07000, 0.40900, 6.49800, 4.00000, 18.90000, 396.90000, 5.88500, 33.00000, 345.00000, 20.90000, + 0.08826, 10.81000, 0.41300, 5.28730, 4.00000, 19.20000, 383.73000, 6.41700, 6.60000, 305.00000, 24.20000, + 0.15876, 10.81000, 0.41300, 5.28730, 4.00000, 19.20000, 376.94000, 5.96100, 17.50000, 305.00000, 21.70000, + 0.09164, 10.81000, 0.41300, 5.28730, 4.00000, 19.20000, 390.91000, 6.06500, 7.80000, 305.00000, 22.80000, + 0.19539, 10.81000, 0.41300, 5.28730, 4.00000, 19.20000, 377.17000, 6.24500, 6.20000, 305.00000, 23.40000, + 0.07896, 12.83000, 0.43700, 4.25150, 5.00000, 18.70000, 394.92000, 6.27300, 6.00000, 398.00000, 24.10000, + 0.09512, 12.83000, 0.43700, 4.50260, 5.00000, 18.70000, 383.23000, 6.28600, 45.00000, 398.00000, 21.40000, + 0.10153, 12.83000, 0.43700, 4.05220, 5.00000, 18.70000, 373.66000, 6.27900, 74.50000, 398.00000, 20.00000, + 0.08707, 12.83000, 0.43700, 4.09050, 5.00000, 18.70000, 386.96000, 6.14000, 45.80000, 398.00000, 20.80000, + 0.05646, 12.83000, 0.43700, 5.01410, 5.00000, 18.70000, 386.40000, 6.23200, 53.70000, 398.00000, 21.20000, + 0.08387, 12.83000, 0.43700, 4.50260, 5.00000, 18.70000, 396.06000, 5.87400, 36.60000, 398.00000, 20.30000, + 0.04113, 4.86000, 0.42600, 5.40070, 4.00000, 19.00000, 396.90000, 6.72700, 33.50000, 281.00000, 28.00000, + 0.04462, 4.86000, 0.42600, 5.40070, 4.00000, 19.00000, 395.63000, 6.61900, 70.40000, 281.00000, 23.90000, + 0.03659, 4.86000, 0.42600, 5.40070, 4.00000, 19.00000, 396.90000, 6.30200, 32.20000, 281.00000, 24.80000, + 0.03551, 4.86000, 0.42600, 5.40070, 4.00000, 19.00000, 390.64000, 6.16700, 46.70000, 281.00000, 22.90000, + 0.05059, 4.49000, 0.44900, 4.77940, 3.00000, 18.50000, 396.90000, 6.38900, 48.00000, 247.00000, 23.90000, + 0.05735, 4.49000, 0.44900, 4.43770, 3.00000, 18.50000, 392.30000, 6.63000, 56.10000, 247.00000, 26.60000, + 0.05188, 4.49000, 0.44900, 4.42720, 3.00000, 18.50000, 395.99000, 6.01500, 45.10000, 247.00000, 22.50000, + 0.07151, 4.49000, 0.44900, 3.74760, 3.00000, 18.50000, 395.15000, 6.12100, 56.80000, 247.00000, 22.20000, + 0.05660, 3.41000, 0.48900, 3.42170, 2.00000, 17.80000, 396.90000, 7.00700, 86.30000, 270.00000, 23.60000, + 0.05302, 3.41000, 0.48900, 3.41450, 2.00000, 17.80000, 396.06000, 7.07900, 63.10000, 270.00000, 28.70000, + 0.04684, 3.41000, 0.48900, 3.09230, 2.00000, 17.80000, 392.18000, 6.41700, 66.10000, 270.00000, 22.60000, + 0.03932, 3.41000, 0.48900, 3.09210, 2.00000, 17.80000, 393.55000, 6.40500, 73.90000, 270.00000, 22.00000, + 0.04203, 15.04000, 0.46400, 3.66590, 4.00000, 18.20000, 395.01000, 6.44200, 53.60000, 270.00000, 22.90000, + 0.02875, 15.04000, 0.46400, 3.66590, 4.00000, 18.20000, 396.33000, 6.21100, 28.90000, 270.00000, 25.00000, + 0.04294, 15.04000, 0.46400, 3.61500, 4.00000, 18.20000, 396.90000, 6.24900, 77.30000, 270.00000, 20.60000, + 0.12204, 2.89000, 0.44500, 3.49520, 2.00000, 18.00000, 357.98000, 6.62500, 57.80000, 276.00000, 28.40000, + 0.11504, 2.89000, 0.44500, 3.49520, 2.00000, 18.00000, 391.83000, 6.16300, 69.60000, 276.00000, 21.40000, + 0.12083, 2.89000, 0.44500, 3.49520, 2.00000, 18.00000, 396.90000, 8.06900, 76.00000, 276.00000, 38.70000, + 0.08187, 2.89000, 0.44500, 3.49520, 2.00000, 18.00000, 393.53000, 7.82000, 36.90000, 276.00000, 43.80000, + 0.06860, 2.89000, 0.44500, 3.49520, 2.00000, 18.00000, 396.90000, 7.41600, 62.50000, 276.00000, 33.20000, + 0.14866, 8.56000, 0.52000, 2.77780, 5.00000, 20.90000, 394.76000, 6.72700, 79.90000, 384.00000, 27.50000, + 0.11432, 8.56000, 0.52000, 2.85610, 5.00000, 20.90000, 395.58000, 6.78100, 71.30000, 384.00000, 26.50000, + 0.22876, 8.56000, 0.52000, 2.71470, 5.00000, 20.90000, 70.80000, 6.40500, 85.40000, 384.00000, 18.60000, + 0.21161, 8.56000, 0.52000, 2.71470, 5.00000, 20.90000, 394.47000, 6.13700, 87.40000, 384.00000, 19.30000, + 0.13960, 8.56000, 0.52000, 2.42100, 5.00000, 20.90000, 392.69000, 6.16700, 90.00000, 384.00000, 20.10000, + 0.13262, 8.56000, 0.52000, 2.10690, 5.00000, 20.90000, 394.05000, 5.85100, 96.70000, 384.00000, 19.50000, + 0.17120, 8.56000, 0.52000, 2.21100, 5.00000, 20.90000, 395.67000, 5.83600, 91.90000, 384.00000, 19.50000, + 0.13117, 8.56000, 0.52000, 2.12240, 5.00000, 20.90000, 387.69000, 6.12700, 85.20000, 384.00000, 20.40000, + 0.12802, 8.56000, 0.52000, 2.43290, 5.00000, 20.90000, 395.24000, 6.47400, 97.10000, 384.00000, 19.80000, + 0.26363, 8.56000, 0.52000, 2.54510, 5.00000, 20.90000, 391.23000, 6.22900, 91.20000, 384.00000, 19.40000, + 0.10793, 8.56000, 0.52000, 2.77780, 5.00000, 20.90000, 393.49000, 6.19500, 54.40000, 384.00000, 21.70000, + 0.10084, 10.01000, 0.54700, 2.67750, 6.00000, 17.80000, 395.59000, 6.71500, 81.60000, 432.00000, 22.80000, + 0.12329, 10.01000, 0.54700, 2.35340, 6.00000, 17.80000, 394.95000, 5.91300, 92.90000, 432.00000, 18.80000, + 0.22212, 10.01000, 0.54700, 2.54800, 6.00000, 17.80000, 396.90000, 6.09200, 95.40000, 432.00000, 18.70000, + 0.14231, 10.01000, 0.54700, 2.25650, 6.00000, 17.80000, 388.74000, 6.25400, 84.20000, 432.00000, 18.50000, + 0.17134, 10.01000, 0.54700, 2.46310, 6.00000, 17.80000, 344.91000, 5.92800, 88.20000, 432.00000, 18.30000, + 0.13158, 10.01000, 0.54700, 2.73010, 6.00000, 17.80000, 393.30000, 6.17600, 72.50000, 432.00000, 21.20000, + 0.15098, 10.01000, 0.54700, 2.74740, 6.00000, 17.80000, 394.51000, 6.02100, 82.60000, 432.00000, 19.20000, + 0.13058, 10.01000, 0.54700, 2.47750, 6.00000, 17.80000, 338.63000, 5.87200, 73.10000, 432.00000, 20.40000, + 0.14476, 10.01000, 0.54700, 2.75920, 6.00000, 17.80000, 391.50000, 5.73100, 65.20000, 432.00000, 19.30000, + 0.06899, 25.65000, 0.58100, 2.25770, 2.00000, 19.10000, 389.15000, 5.87000, 69.70000, 188.00000, 22.00000, + 0.07165, 25.65000, 0.58100, 2.19740, 2.00000, 19.10000, 377.67000, 6.00400, 84.10000, 188.00000, 20.30000, + 0.09299, 25.65000, 0.58100, 2.08690, 2.00000, 19.10000, 378.09000, 5.96100, 92.90000, 188.00000, 20.50000, + 0.15038, 25.65000, 0.58100, 1.94440, 2.00000, 19.10000, 370.31000, 5.85600, 97.00000, 188.00000, 17.30000, + 0.09849, 25.65000, 0.58100, 2.00630, 2.00000, 19.10000, 379.38000, 5.87900, 95.80000, 188.00000, 18.80000, + 0.16902, 25.65000, 0.58100, 1.99290, 2.00000, 19.10000, 385.02000, 5.98600, 88.40000, 188.00000, 21.40000, + 0.38735, 25.65000, 0.58100, 1.75720, 2.00000, 19.10000, 359.29000, 5.61300, 95.60000, 188.00000, 15.70000, + 0.25915, 21.89000, 0.62400, 1.78830, 4.00000, 21.20000, 392.11000, 5.69300, 96.00000, 437.00000, 16.20000, + 0.32543, 21.89000, 0.62400, 1.81250, 4.00000, 21.20000, 396.90000, 6.43100, 98.80000, 437.00000, 18.00000, + 0.88125, 21.89000, 0.62400, 1.97990, 4.00000, 21.20000, 396.90000, 5.63700, 94.70000, 437.00000, 14.30000, + 0.34006, 21.89000, 0.62400, 2.11850, 4.00000, 21.20000, 395.04000, 6.45800, 98.90000, 437.00000, 19.20000, + 1.19294, 21.89000, 0.62400, 2.27100, 4.00000, 21.20000, 396.90000, 6.32600, 97.70000, 437.00000, 19.60000, + 0.59005, 21.89000, 0.62400, 2.32740, 4.00000, 21.20000, 385.76000, 6.37200, 97.90000, 437.00000, 23.00000, + 0.32982, 21.89000, 0.62400, 2.46990, 4.00000, 21.20000, 388.69000, 5.82200, 95.40000, 437.00000, 18.40000, + 0.97617, 21.89000, 0.62400, 2.34600, 4.00000, 21.20000, 262.76000, 5.75700, 98.40000, 437.00000, 15.60000, + 0.55778, 21.89000, 0.62400, 2.11070, 4.00000, 21.20000, 394.67000, 6.33500, 98.20000, 437.00000, 18.10000, + 0.32264, 21.89000, 0.62400, 1.96690, 4.00000, 21.20000, 378.25000, 5.94200, 93.50000, 437.00000, 17.40000, + 0.35233, 21.89000, 0.62400, 1.84980, 4.00000, 21.20000, 394.08000, 6.45400, 98.40000, 437.00000, 17.10000, + 0.24980, 21.89000, 0.62400, 1.66860, 4.00000, 21.20000, 392.04000, 5.85700, 98.20000, 437.00000, 13.30000, + 0.54452, 21.89000, 0.62400, 1.66870, 4.00000, 21.20000, 396.90000, 6.15100, 97.90000, 437.00000, 17.80000, + 0.29090, 21.89000, 0.62400, 1.61190, 4.00000, 21.20000, 388.08000, 6.17400, 93.60000, 437.00000, 14.00000, + 1.62864, 21.89000, 0.62400, 1.43940, 4.00000, 21.20000, 396.90000, 5.01900, 100.00000, 437.00000, 14.40000, + 3.32105, 19.58000, 0.87100, 1.32160, 5.00000, 14.70000, 396.90000, 5.40300, 100.00000, 403.00000, 13.40000, + 4.09740, 19.58000, 0.87100, 1.41180, 5.00000, 14.70000, 396.90000, 5.46800, 100.00000, 403.00000, 15.60000, + 2.77974, 19.58000, 0.87100, 1.34590, 5.00000, 14.70000, 396.90000, 4.90300, 97.80000, 403.00000, 11.80000, + 2.37934, 19.58000, 0.87100, 1.41910, 5.00000, 14.70000, 172.91000, 6.13000, 100.00000, 403.00000, 13.80000, + 2.15505, 19.58000, 0.87100, 1.51660, 5.00000, 14.70000, 169.27000, 5.62800, 100.00000, 403.00000, 15.60000, + 2.36862, 19.58000, 0.87100, 1.46080, 5.00000, 14.70000, 391.71000, 4.92600, 95.70000, 403.00000, 14.60000, + 2.33099, 19.58000, 0.87100, 1.52960, 5.00000, 14.70000, 356.99000, 5.18600, 93.80000, 403.00000, 17.80000, + 2.73397, 19.58000, 0.87100, 1.52570, 5.00000, 14.70000, 351.85000, 5.59700, 94.90000, 403.00000, 15.40000, + 1.65660, 19.58000, 0.87100, 1.61800, 5.00000, 14.70000, 372.80000, 6.12200, 97.30000, 403.00000, 21.50000, + 1.49632, 19.58000, 0.87100, 1.59160, 5.00000, 14.70000, 341.60000, 5.40400, 100.00000, 403.00000, 19.60000, + 1.12658, 19.58000, 0.87100, 1.61020, 5.00000, 14.70000, 343.28000, 5.01200, 88.00000, 403.00000, 15.30000, + 2.14918, 19.58000, 0.87100, 1.62320, 5.00000, 14.70000, 261.95000, 5.70900, 98.50000, 403.00000, 19.40000, + 1.41385, 19.58000, 0.87100, 1.74940, 5.00000, 14.70000, 321.02000, 6.12900, 96.00000, 403.00000, 17.00000, + 3.53501, 19.58000, 0.87100, 1.74550, 5.00000, 14.70000, 88.01000, 6.15200, 82.60000, 403.00000, 15.60000, + 2.44668, 19.58000, 0.87100, 1.73640, 5.00000, 14.70000, 88.63000, 5.27200, 94.00000, 403.00000, 13.10000, + 1.22358, 19.58000, 0.60500, 1.87730, 5.00000, 14.70000, 363.43000, 6.94300, 97.40000, 403.00000, 41.30000, + 1.34284, 19.58000, 0.60500, 1.75730, 5.00000, 14.70000, 353.89000, 6.06600, 100.00000, 403.00000, 24.30000, + 1.42502, 19.58000, 0.87100, 1.76590, 5.00000, 14.70000, 364.31000, 6.51000, 100.00000, 403.00000, 23.30000, + 1.27346, 19.58000, 0.60500, 1.79840, 5.00000, 14.70000, 338.92000, 6.25000, 92.60000, 403.00000, 27.00000, + 1.46336, 19.58000, 0.60500, 1.97090, 5.00000, 14.70000, 374.43000, 7.48900, 90.80000, 403.00000, 50.00000, + 1.83377, 19.58000, 0.60500, 2.04070, 5.00000, 14.70000, 389.61000, 7.80200, 98.20000, 403.00000, 50.00000, + 1.51902, 19.58000, 0.60500, 2.16200, 5.00000, 14.70000, 388.45000, 8.37500, 93.90000, 403.00000, 50.00000, + 2.24236, 19.58000, 0.60500, 2.42200, 5.00000, 14.70000, 395.11000, 5.85400, 91.80000, 403.00000, 22.70000, + 2.92400, 19.58000, 0.60500, 2.28340, 5.00000, 14.70000, 240.16000, 6.10100, 93.00000, 403.00000, 25.00000, + 2.01019, 19.58000, 0.60500, 2.04590, 5.00000, 14.70000, 369.30000, 7.92900, 96.20000, 403.00000, 50.00000, + 1.80028, 19.58000, 0.60500, 2.42590, 5.00000, 14.70000, 227.61000, 5.87700, 79.20000, 403.00000, 23.80000, + 2.30040, 19.58000, 0.60500, 2.10000, 5.00000, 14.70000, 297.09000, 6.31900, 96.10000, 403.00000, 23.80000, + 2.44953, 19.58000, 0.60500, 2.26250, 5.00000, 14.70000, 330.04000, 6.40200, 95.20000, 403.00000, 22.30000, + 1.20742, 19.58000, 0.60500, 2.42590, 5.00000, 14.70000, 292.29000, 5.87500, 94.60000, 403.00000, 17.40000, + 2.31390, 19.58000, 0.60500, 2.38870, 5.00000, 14.70000, 348.13000, 5.88000, 97.30000, 403.00000, 19.10000, + 0.13914, 4.05000, 0.51000, 2.59610, 5.00000, 16.60000, 396.90000, 5.57200, 88.50000, 296.00000, 23.10000, + 0.09178, 4.05000, 0.51000, 2.64630, 5.00000, 16.60000, 395.50000, 6.41600, 84.10000, 296.00000, 23.60000, + 0.08447, 4.05000, 0.51000, 2.70190, 5.00000, 16.60000, 393.23000, 5.85900, 68.70000, 296.00000, 22.60000, + 0.06664, 4.05000, 0.51000, 3.13230, 5.00000, 16.60000, 390.96000, 6.54600, 33.10000, 296.00000, 29.40000, + 0.07022, 4.05000, 0.51000, 3.55490, 5.00000, 16.60000, 393.23000, 6.02000, 47.20000, 296.00000, 23.20000, + 0.05425, 4.05000, 0.51000, 3.31750, 5.00000, 16.60000, 395.60000, 6.31500, 73.40000, 296.00000, 24.60000, + 0.06642, 4.05000, 0.51000, 2.91530, 5.00000, 16.60000, 391.27000, 6.86000, 74.40000, 296.00000, 29.90000, + 0.05780, 2.46000, 0.48800, 2.82900, 3.00000, 17.80000, 396.90000, 6.98000, 58.40000, 193.00000, 37.20000, + 0.06588, 2.46000, 0.48800, 2.74100, 3.00000, 17.80000, 395.56000, 7.76500, 83.30000, 193.00000, 39.80000, + 0.06888, 2.46000, 0.48800, 2.59790, 3.00000, 17.80000, 396.90000, 6.14400, 62.20000, 193.00000, 36.20000, + 0.09103, 2.46000, 0.48800, 2.70060, 3.00000, 17.80000, 394.12000, 7.15500, 92.20000, 193.00000, 37.90000, + 0.10008, 2.46000, 0.48800, 2.84700, 3.00000, 17.80000, 396.90000, 6.56300, 95.60000, 193.00000, 32.50000, + 0.08308, 2.46000, 0.48800, 2.98790, 3.00000, 17.80000, 391.00000, 5.60400, 89.80000, 193.00000, 26.40000, + 0.06047, 2.46000, 0.48800, 3.27970, 3.00000, 17.80000, 387.11000, 6.15300, 68.80000, 193.00000, 29.60000, + 0.05602, 2.46000, 0.48800, 3.19920, 3.00000, 17.80000, 392.63000, 7.83100, 53.60000, 193.00000, 50.00000, + 0.07875, 3.44000, 0.43700, 3.78860, 5.00000, 15.20000, 393.87000, 6.78200, 41.10000, 398.00000, 32.00000, + 0.12579, 3.44000, 0.43700, 4.56670, 5.00000, 15.20000, 382.84000, 6.55600, 29.10000, 398.00000, 29.80000, + 0.08370, 3.44000, 0.43700, 4.56670, 5.00000, 15.20000, 396.90000, 7.18500, 38.90000, 398.00000, 34.90000, + 0.09068, 3.44000, 0.43700, 6.47980, 5.00000, 15.20000, 377.68000, 6.95100, 21.50000, 398.00000, 37.00000, + 0.06911, 3.44000, 0.43700, 6.47980, 5.00000, 15.20000, 389.71000, 6.73900, 30.80000, 398.00000, 30.50000, + 0.08664, 3.44000, 0.43700, 6.47980, 5.00000, 15.20000, 390.49000, 7.17800, 26.30000, 398.00000, 36.40000, + 0.02187, 2.93000, 0.40100, 6.21960, 1.00000, 15.60000, 393.37000, 6.80000, 9.90000, 265.00000, 31.10000, + 0.01439, 2.93000, 0.40100, 6.21960, 1.00000, 15.60000, 376.70000, 6.60400, 18.80000, 265.00000, 29.10000, + 0.01381, 0.46000, 0.42200, 5.64840, 4.00000, 14.40000, 394.23000, 7.87500, 32.00000, 255.00000, 50.00000, + 0.04011, 1.52000, 0.40400, 7.30900, 2.00000, 12.60000, 396.90000, 7.28700, 34.10000, 329.00000, 33.30000, + 0.04666, 1.52000, 0.40400, 7.30900, 2.00000, 12.60000, 354.31000, 7.10700, 36.60000, 329.00000, 30.30000, + 0.03768, 1.52000, 0.40400, 7.30900, 2.00000, 12.60000, 392.20000, 7.27400, 38.30000, 329.00000, 34.60000, + 0.03150, 1.47000, 0.40300, 7.65340, 3.00000, 17.00000, 396.90000, 6.97500, 15.30000, 402.00000, 34.90000, + 0.01778, 1.47000, 0.40300, 7.65340, 3.00000, 17.00000, 384.30000, 7.13500, 13.90000, 402.00000, 32.90000, + 0.03445, 2.03000, 0.41500, 6.27000, 2.00000, 14.70000, 393.77000, 6.16200, 38.40000, 348.00000, 24.10000, + 0.02177, 2.03000, 0.41500, 6.27000, 2.00000, 14.70000, 395.38000, 7.61000, 15.70000, 348.00000, 42.30000, + 0.03510, 2.68000, 0.41610, 5.11800, 4.00000, 14.70000, 392.78000, 7.85300, 33.20000, 224.00000, 48.50000, + 0.02009, 2.68000, 0.41610, 5.11800, 4.00000, 14.70000, 390.55000, 8.03400, 31.90000, 224.00000, 50.00000, + 0.13642, 10.59000, 0.48900, 3.94540, 4.00000, 18.60000, 396.90000, 5.89100, 22.30000, 277.00000, 22.60000, + 0.22969, 10.59000, 0.48900, 4.35490, 4.00000, 18.60000, 394.87000, 6.32600, 52.50000, 277.00000, 24.40000, + 0.25199, 10.59000, 0.48900, 4.35490, 4.00000, 18.60000, 389.43000, 5.78300, 72.70000, 277.00000, 22.50000, + 0.13587, 10.59000, 0.48900, 4.23920, 4.00000, 18.60000, 381.32000, 6.06400, 59.10000, 277.00000, 24.40000, + 0.43571, 10.59000, 0.48900, 3.87500, 4.00000, 18.60000, 396.90000, 5.34400, 100.00000, 277.00000, 20.00000, + 0.17446, 10.59000, 0.48900, 3.87710, 4.00000, 18.60000, 393.25000, 5.96000, 92.10000, 277.00000, 21.70000, + 0.37578, 10.59000, 0.48900, 3.66500, 4.00000, 18.60000, 395.24000, 5.40400, 88.60000, 277.00000, 19.30000, + 0.21719, 10.59000, 0.48900, 3.65260, 4.00000, 18.60000, 390.94000, 5.80700, 53.80000, 277.00000, 22.40000, + 0.14052, 10.59000, 0.48900, 3.94540, 4.00000, 18.60000, 385.81000, 6.37500, 32.30000, 277.00000, 28.10000, + 0.28955, 10.59000, 0.48900, 3.58750, 4.00000, 18.60000, 348.93000, 5.41200, 9.80000, 277.00000, 23.70000, + 0.19802, 10.59000, 0.48900, 3.94540, 4.00000, 18.60000, 393.63000, 6.18200, 42.40000, 277.00000, 25.00000, + 0.04560, 13.89000, 0.55000, 3.11210, 5.00000, 16.40000, 392.80000, 5.88800, 56.00000, 276.00000, 23.30000, + 0.07013, 13.89000, 0.55000, 3.42110, 5.00000, 16.40000, 392.78000, 6.64200, 85.10000, 276.00000, 28.70000, + 0.11069, 13.89000, 0.55000, 2.88930, 5.00000, 16.40000, 396.90000, 5.95100, 93.80000, 276.00000, 21.50000, + 0.11425, 13.89000, 0.55000, 3.36330, 5.00000, 16.40000, 393.74000, 6.37300, 92.40000, 276.00000, 23.00000, + 0.35809, 6.20000, 0.50700, 2.86170, 8.00000, 17.40000, 391.70000, 6.95100, 88.50000, 307.00000, 26.70000, + 0.40771, 6.20000, 0.50700, 3.04800, 8.00000, 17.40000, 395.24000, 6.16400, 91.30000, 307.00000, 21.70000, + 0.62356, 6.20000, 0.50700, 3.27210, 8.00000, 17.40000, 390.39000, 6.87900, 77.70000, 307.00000, 27.50000, + 0.61470, 6.20000, 0.50700, 3.27210, 8.00000, 17.40000, 396.90000, 6.61800, 80.80000, 307.00000, 30.10000, + 0.31533, 6.20000, 0.50400, 2.89440, 8.00000, 17.40000, 385.05000, 8.26600, 78.30000, 307.00000, 44.80000, + 0.52693, 6.20000, 0.50400, 2.89440, 8.00000, 17.40000, 382.00000, 8.72500, 83.00000, 307.00000, 50.00000, + 0.38214, 6.20000, 0.50400, 3.21570, 8.00000, 17.40000, 387.38000, 8.04000, 86.50000, 307.00000, 37.60000, + 0.41238, 6.20000, 0.50400, 3.21570, 8.00000, 17.40000, 372.08000, 7.16300, 79.90000, 307.00000, 31.60000, + 0.29819, 6.20000, 0.50400, 3.37510, 8.00000, 17.40000, 377.51000, 7.68600, 17.00000, 307.00000, 46.70000, + 0.44178, 6.20000, 0.50400, 3.37510, 8.00000, 17.40000, 380.34000, 6.55200, 21.40000, 307.00000, 31.50000, + 0.53700, 6.20000, 0.50400, 3.67150, 8.00000, 17.40000, 378.35000, 5.98100, 68.10000, 307.00000, 24.30000, + 0.46296, 6.20000, 0.50400, 3.67150, 8.00000, 17.40000, 376.14000, 7.41200, 76.90000, 307.00000, 31.70000, + 0.57529, 6.20000, 0.50700, 3.83840, 8.00000, 17.40000, 385.91000, 8.33700, 73.30000, 307.00000, 41.70000, + 0.33147, 6.20000, 0.50700, 3.65190, 8.00000, 17.40000, 378.95000, 8.24700, 70.40000, 307.00000, 48.30000, + 0.44791, 6.20000, 0.50700, 3.65190, 8.00000, 17.40000, 360.20000, 6.72600, 66.50000, 307.00000, 29.00000, + 0.33045, 6.20000, 0.50700, 3.65190, 8.00000, 17.40000, 376.75000, 6.08600, 61.50000, 307.00000, 24.00000, + 0.52058, 6.20000, 0.50700, 4.14800, 8.00000, 17.40000, 388.45000, 6.63100, 76.50000, 307.00000, 25.10000, + 0.51183, 6.20000, 0.50700, 4.14800, 8.00000, 17.40000, 390.07000, 7.35800, 71.60000, 307.00000, 31.50000, + 0.08244, 4.93000, 0.42800, 6.18990, 6.00000, 16.60000, 379.41000, 6.48100, 18.50000, 300.00000, 23.70000, + 0.09252, 4.93000, 0.42800, 6.18990, 6.00000, 16.60000, 383.78000, 6.60600, 42.20000, 300.00000, 23.30000, + 0.11329, 4.93000, 0.42800, 6.33610, 6.00000, 16.60000, 391.25000, 6.89700, 54.30000, 300.00000, 22.00000, + 0.10612, 4.93000, 0.42800, 6.33610, 6.00000, 16.60000, 394.62000, 6.09500, 65.10000, 300.00000, 20.10000, + 0.10290, 4.93000, 0.42800, 7.03550, 6.00000, 16.60000, 372.75000, 6.35800, 52.90000, 300.00000, 22.20000, + 0.12757, 4.93000, 0.42800, 7.03550, 6.00000, 16.60000, 374.71000, 6.39300, 7.80000, 300.00000, 23.70000, + 0.20608, 5.86000, 0.43100, 7.95490, 7.00000, 19.10000, 372.49000, 5.59300, 76.50000, 330.00000, 17.60000, + 0.19133, 5.86000, 0.43100, 7.95490, 7.00000, 19.10000, 389.13000, 5.60500, 70.20000, 330.00000, 18.50000, + 0.33983, 5.86000, 0.43100, 8.05550, 7.00000, 19.10000, 390.18000, 6.10800, 34.90000, 330.00000, 24.30000, + 0.19657, 5.86000, 0.43100, 8.05550, 7.00000, 19.10000, 376.14000, 6.22600, 79.20000, 330.00000, 20.50000, + 0.16439, 5.86000, 0.43100, 7.82650, 7.00000, 19.10000, 374.71000, 6.43300, 49.10000, 330.00000, 24.50000, + 0.19073, 5.86000, 0.43100, 7.82650, 7.00000, 19.10000, 393.74000, 6.71800, 17.50000, 330.00000, 26.20000, + 0.14030, 5.86000, 0.43100, 7.39670, 7.00000, 19.10000, 396.28000, 6.48700, 13.00000, 330.00000, 24.40000, + 0.21409, 5.86000, 0.43100, 7.39670, 7.00000, 19.10000, 377.07000, 6.43800, 8.90000, 330.00000, 24.80000, + 0.08221, 5.86000, 0.43100, 8.90670, 7.00000, 19.10000, 386.09000, 6.95700, 6.80000, 330.00000, 29.60000, + 0.36894, 5.86000, 0.43100, 8.90670, 7.00000, 19.10000, 396.90000, 8.25900, 8.40000, 330.00000, 42.80000, + 0.04819, 3.64000, 0.39200, 9.22030, 1.00000, 16.40000, 392.89000, 6.10800, 32.00000, 315.00000, 21.90000, + 0.03548, 3.64000, 0.39200, 9.22030, 1.00000, 16.40000, 395.18000, 5.87600, 19.10000, 315.00000, 20.90000, + 0.01538, 3.75000, 0.39400, 6.33610, 3.00000, 15.90000, 386.34000, 7.45400, 34.20000, 244.00000, 44.00000, + 0.61154, 3.97000, 0.64700, 1.80100, 5.00000, 13.00000, 389.70000, 8.70400, 86.90000, 264.00000, 50.00000, + 0.66351, 3.97000, 0.64700, 1.89460, 5.00000, 13.00000, 383.29000, 7.33300, 100.00000, 264.00000, 36.00000, + 0.65665, 3.97000, 0.64700, 2.01070, 5.00000, 13.00000, 391.93000, 6.84200, 100.00000, 264.00000, 30.10000, + 0.54011, 3.97000, 0.64700, 2.11210, 5.00000, 13.00000, 392.80000, 7.20300, 81.80000, 264.00000, 33.80000, + 0.53412, 3.97000, 0.64700, 2.13980, 5.00000, 13.00000, 388.37000, 7.52000, 89.40000, 264.00000, 43.10000, + 0.52014, 3.97000, 0.64700, 2.28850, 5.00000, 13.00000, 386.86000, 8.39800, 91.50000, 264.00000, 48.80000, + 0.82526, 3.97000, 0.64700, 2.07880, 5.00000, 13.00000, 393.42000, 7.32700, 94.50000, 264.00000, 31.00000, + 0.55007, 3.97000, 0.64700, 1.93010, 5.00000, 13.00000, 387.89000, 7.20600, 91.60000, 264.00000, 36.50000, + 0.76162, 3.97000, 0.64700, 1.98650, 5.00000, 13.00000, 392.40000, 5.56000, 62.80000, 264.00000, 22.80000, + 0.78570, 3.97000, 0.64700, 2.13290, 5.00000, 13.00000, 384.07000, 7.01400, 84.60000, 264.00000, 30.70000, + 0.57834, 3.97000, 0.57500, 2.42160, 5.00000, 13.00000, 384.54000, 8.29700, 67.00000, 264.00000, 50.00000, + 0.54050, 3.97000, 0.57500, 2.87200, 5.00000, 13.00000, 390.30000, 7.47000, 52.60000, 264.00000, 43.50000, + 0.09065, 6.96000, 0.46400, 3.91750, 3.00000, 18.60000, 391.34000, 5.92000, 61.50000, 223.00000, 20.70000, + 0.29916, 6.96000, 0.46400, 4.42900, 3.00000, 18.60000, 388.65000, 5.85600, 42.10000, 223.00000, 21.10000, + 0.16211, 6.96000, 0.46400, 4.42900, 3.00000, 18.60000, 396.90000, 6.24000, 16.30000, 223.00000, 25.20000, + 0.11460, 6.96000, 0.46400, 3.91750, 3.00000, 18.60000, 394.96000, 6.53800, 58.70000, 223.00000, 24.40000, + 0.22188, 6.96000, 0.46400, 4.36650, 3.00000, 18.60000, 390.77000, 7.69100, 51.80000, 223.00000, 35.20000, + 0.05644, 6.41000, 0.44700, 4.07760, 4.00000, 17.60000, 396.90000, 6.75800, 32.90000, 254.00000, 32.40000, + 0.09604, 6.41000, 0.44700, 4.26730, 4.00000, 17.60000, 396.90000, 6.85400, 42.80000, 254.00000, 32.00000, + 0.10469, 6.41000, 0.44700, 4.78720, 4.00000, 17.60000, 389.25000, 7.26700, 49.00000, 254.00000, 33.20000, + 0.06127, 6.41000, 0.44700, 4.86280, 4.00000, 17.60000, 393.45000, 6.82600, 27.60000, 254.00000, 33.10000, + 0.07978, 6.41000, 0.44700, 4.14030, 4.00000, 17.60000, 396.90000, 6.48200, 32.10000, 254.00000, 29.10000, + 0.21038, 3.33000, 0.44290, 4.10070, 5.00000, 14.90000, 396.90000, 6.81200, 32.20000, 216.00000, 35.10000, + 0.03578, 3.33000, 0.44290, 4.69470, 5.00000, 14.90000, 387.31000, 7.82000, 64.50000, 216.00000, 45.40000, + 0.03705, 3.33000, 0.44290, 5.24470, 5.00000, 14.90000, 392.23000, 6.96800, 37.20000, 216.00000, 35.40000, + 0.06129, 3.33000, 0.44290, 5.21190, 5.00000, 14.90000, 377.07000, 7.64500, 49.70000, 216.00000, 46.00000, + 0.01501, 1.21000, 0.40100, 5.88500, 1.00000, 13.60000, 395.52000, 7.92300, 24.80000, 198.00000, 50.00000, + 0.00906, 2.97000, 0.40000, 7.30730, 1.00000, 15.30000, 394.72000, 7.08800, 20.80000, 285.00000, 32.20000, + 0.01096, 2.25000, 0.38900, 7.30730, 1.00000, 15.30000, 394.72000, 6.45300, 31.90000, 300.00000, 22.00000, + 0.01965, 1.76000, 0.38500, 9.08920, 1.00000, 18.20000, 341.60000, 6.23000, 31.50000, 241.00000, 20.10000, + 0.03871, 5.32000, 0.40500, 7.31720, 6.00000, 16.60000, 396.90000, 6.20900, 31.30000, 293.00000, 23.20000, + 0.04590, 5.32000, 0.40500, 7.31720, 6.00000, 16.60000, 396.90000, 6.31500, 45.60000, 293.00000, 22.30000, + 0.04297, 5.32000, 0.40500, 7.31720, 6.00000, 16.60000, 371.72000, 6.56500, 22.90000, 293.00000, 24.80000, + 0.03502, 4.95000, 0.41100, 5.11670, 4.00000, 19.20000, 396.90000, 6.86100, 27.90000, 245.00000, 28.50000, + 0.07886, 4.95000, 0.41100, 5.11670, 4.00000, 19.20000, 396.90000, 7.14800, 27.70000, 245.00000, 37.30000, + 0.03615, 4.95000, 0.41100, 5.11670, 4.00000, 19.20000, 396.90000, 6.63000, 23.40000, 245.00000, 27.90000, + 0.08265, 13.92000, 0.43700, 5.50270, 4.00000, 16.00000, 396.90000, 6.12700, 18.40000, 289.00000, 23.90000, + 0.08199, 13.92000, 0.43700, 5.50270, 4.00000, 16.00000, 396.90000, 6.00900, 42.30000, 289.00000, 21.70000, + 0.12932, 13.92000, 0.43700, 5.96040, 4.00000, 16.00000, 396.90000, 6.67800, 31.10000, 289.00000, 28.60000, + 0.05372, 13.92000, 0.43700, 5.96040, 4.00000, 16.00000, 392.85000, 6.54900, 51.00000, 289.00000, 27.10000, + 0.14103, 13.92000, 0.43700, 6.32000, 4.00000, 16.00000, 396.90000, 5.79000, 58.00000, 289.00000, 20.30000, + 0.06466, 2.24000, 0.40000, 7.82780, 5.00000, 14.80000, 368.24000, 6.34500, 20.10000, 358.00000, 22.50000, + 0.05561, 2.24000, 0.40000, 7.82780, 5.00000, 14.80000, 371.58000, 7.04100, 10.00000, 358.00000, 29.00000, + 0.04417, 2.24000, 0.40000, 7.82780, 5.00000, 14.80000, 390.86000, 6.87100, 47.40000, 358.00000, 24.80000, + 0.03537, 6.09000, 0.43300, 5.49170, 7.00000, 16.10000, 395.75000, 6.59000, 40.40000, 329.00000, 22.00000, + 0.09266, 6.09000, 0.43300, 5.49170, 7.00000, 16.10000, 383.61000, 6.49500, 18.40000, 329.00000, 26.40000, + 0.10000, 6.09000, 0.43300, 5.49170, 7.00000, 16.10000, 390.43000, 6.98200, 17.70000, 329.00000, 33.10000, + 0.05515, 2.18000, 0.47200, 4.02200, 7.00000, 18.40000, 393.68000, 7.23600, 41.10000, 222.00000, 36.10000, + 0.05479, 2.18000, 0.47200, 3.37000, 7.00000, 18.40000, 393.36000, 6.61600, 58.10000, 222.00000, 28.40000, + 0.07503, 2.18000, 0.47200, 3.09920, 7.00000, 18.40000, 396.90000, 7.42000, 71.90000, 222.00000, 33.40000, + 0.04932, 2.18000, 0.47200, 3.18270, 7.00000, 18.40000, 396.90000, 6.84900, 70.30000, 222.00000, 28.20000, + 0.49298, 9.90000, 0.54400, 3.31750, 4.00000, 18.40000, 396.90000, 6.63500, 82.50000, 304.00000, 22.80000, + 0.34940, 9.90000, 0.54400, 3.10250, 4.00000, 18.40000, 396.24000, 5.97200, 76.70000, 304.00000, 20.30000, + 2.63548, 9.90000, 0.54400, 2.51940, 4.00000, 18.40000, 350.45000, 4.97300, 37.80000, 304.00000, 16.10000, + 0.79041, 9.90000, 0.54400, 2.64030, 4.00000, 18.40000, 396.90000, 6.12200, 52.80000, 304.00000, 22.10000, + 0.26169, 9.90000, 0.54400, 2.83400, 4.00000, 18.40000, 396.30000, 6.02300, 90.40000, 304.00000, 19.40000, + 0.26938, 9.90000, 0.54400, 3.26280, 4.00000, 18.40000, 393.39000, 6.26600, 82.80000, 304.00000, 21.60000, + 0.36920, 9.90000, 0.54400, 3.60230, 4.00000, 18.40000, 395.69000, 6.56700, 87.30000, 304.00000, 23.80000, + 0.25356, 9.90000, 0.54400, 3.94500, 4.00000, 18.40000, 396.42000, 5.70500, 77.70000, 304.00000, 16.20000, + 0.31827, 9.90000, 0.54400, 3.99860, 4.00000, 18.40000, 390.70000, 5.91400, 83.20000, 304.00000, 17.80000, + 0.24522, 9.90000, 0.54400, 4.03170, 4.00000, 18.40000, 396.90000, 5.78200, 71.70000, 304.00000, 19.80000, + 0.40202, 9.90000, 0.54400, 3.53250, 4.00000, 18.40000, 395.21000, 6.38200, 67.20000, 304.00000, 23.10000, + 0.47547, 9.90000, 0.54400, 4.00190, 4.00000, 18.40000, 396.23000, 6.11300, 58.80000, 304.00000, 21.00000, + 0.16760, 7.38000, 0.49300, 4.54040, 5.00000, 19.60000, 396.90000, 6.42600, 52.30000, 287.00000, 23.80000, + 0.18159, 7.38000, 0.49300, 4.54040, 5.00000, 19.60000, 396.90000, 6.37600, 54.30000, 287.00000, 23.10000, + 0.35114, 7.38000, 0.49300, 4.72110, 5.00000, 19.60000, 396.90000, 6.04100, 49.90000, 287.00000, 20.40000, + 0.28392, 7.38000, 0.49300, 4.72110, 5.00000, 19.60000, 391.13000, 5.70800, 74.30000, 287.00000, 18.50000, + 0.34109, 7.38000, 0.49300, 4.72110, 5.00000, 19.60000, 396.90000, 6.41500, 40.10000, 287.00000, 25.00000, + 0.19186, 7.38000, 0.49300, 5.41590, 5.00000, 19.60000, 393.68000, 6.43100, 14.70000, 287.00000, 24.60000, + 0.30347, 7.38000, 0.49300, 5.41590, 5.00000, 19.60000, 396.90000, 6.31200, 28.90000, 287.00000, 23.00000, + 0.24103, 7.38000, 0.49300, 5.41590, 5.00000, 19.60000, 396.90000, 6.08300, 43.70000, 287.00000, 22.20000, + 0.06617, 3.24000, 0.46000, 5.21460, 4.00000, 16.90000, 382.44000, 5.86800, 25.80000, 430.00000, 19.30000, + 0.06724, 3.24000, 0.46000, 5.21460, 4.00000, 16.90000, 375.21000, 6.33300, 17.20000, 430.00000, 22.60000, + 0.04544, 3.24000, 0.46000, 5.87360, 4.00000, 16.90000, 368.57000, 6.14400, 32.20000, 430.00000, 19.80000, + 0.05023, 6.06000, 0.43790, 6.64070, 1.00000, 16.90000, 394.02000, 5.70600, 28.40000, 304.00000, 17.10000, + 0.03466, 6.06000, 0.43790, 6.64070, 1.00000, 16.90000, 362.25000, 6.03100, 23.30000, 304.00000, 19.40000, + 0.05083, 5.19000, 0.51500, 6.45840, 5.00000, 20.20000, 389.71000, 6.31600, 38.10000, 224.00000, 22.20000, + 0.03738, 5.19000, 0.51500, 6.45840, 5.00000, 20.20000, 389.40000, 6.31000, 38.50000, 224.00000, 20.70000, + 0.03961, 5.19000, 0.51500, 5.98530, 5.00000, 20.20000, 396.90000, 6.03700, 34.50000, 224.00000, 21.10000, + 0.03427, 5.19000, 0.51500, 5.23110, 5.00000, 20.20000, 396.90000, 5.86900, 46.30000, 224.00000, 19.50000, + 0.03041, 5.19000, 0.51500, 5.61500, 5.00000, 20.20000, 394.81000, 5.89500, 59.60000, 224.00000, 18.50000, + 0.03306, 5.19000, 0.51500, 4.81220, 5.00000, 20.20000, 396.14000, 6.05900, 37.30000, 224.00000, 20.60000, + 0.05497, 5.19000, 0.51500, 4.81220, 5.00000, 20.20000, 396.90000, 5.98500, 45.40000, 224.00000, 19.00000, + 0.06151, 5.19000, 0.51500, 4.81220, 5.00000, 20.20000, 396.90000, 5.96800, 58.50000, 224.00000, 18.70000, + 0.01301, 1.52000, 0.44200, 7.03790, 1.00000, 15.50000, 394.74000, 7.24100, 49.30000, 284.00000, 32.70000, + 0.02498, 1.89000, 0.51800, 6.26690, 1.00000, 15.90000, 389.96000, 6.54000, 59.70000, 422.00000, 16.50000, + 0.02543, 3.78000, 0.48400, 5.73210, 5.00000, 17.60000, 396.90000, 6.69600, 56.40000, 370.00000, 23.90000, + 0.03049, 3.78000, 0.48400, 6.46540, 5.00000, 17.60000, 387.97000, 6.87400, 28.10000, 370.00000, 31.20000, + 0.03113, 4.39000, 0.44200, 8.01360, 3.00000, 18.80000, 385.64000, 6.01400, 48.50000, 352.00000, 17.50000, + 0.06162, 4.39000, 0.44200, 8.01360, 3.00000, 18.80000, 364.61000, 5.89800, 52.30000, 352.00000, 17.20000, + 0.01870, 4.15000, 0.42900, 8.53530, 4.00000, 17.90000, 392.43000, 6.51600, 27.70000, 351.00000, 23.10000, + 0.01501, 2.01000, 0.43500, 8.34400, 4.00000, 17.00000, 390.94000, 6.63500, 29.70000, 280.00000, 24.50000, + 0.02899, 1.25000, 0.42900, 8.79210, 1.00000, 19.70000, 389.85000, 6.93900, 34.50000, 335.00000, 26.60000, + 0.06211, 1.25000, 0.42900, 8.79210, 1.00000, 19.70000, 396.90000, 6.49000, 44.40000, 335.00000, 22.90000, + 0.07950, 1.69000, 0.41100, 10.71030, 4.00000, 18.30000, 370.78000, 6.57900, 35.90000, 411.00000, 24.10000, + 0.07244, 1.69000, 0.41100, 10.71030, 4.00000, 18.30000, 392.33000, 5.88400, 18.50000, 411.00000, 18.60000, + 0.01709, 2.02000, 0.41000, 12.12650, 5.00000, 17.00000, 384.46000, 6.72800, 36.10000, 187.00000, 30.10000, + 0.04301, 1.91000, 0.41300, 10.58570, 4.00000, 22.00000, 382.80000, 5.66300, 21.90000, 334.00000, 18.20000, + 0.10659, 1.91000, 0.41300, 10.58570, 4.00000, 22.00000, 376.04000, 5.93600, 19.50000, 334.00000, 20.60000, + 8.98296, 18.10000, 0.77000, 2.12220, 24.00000, 20.20000, 377.73000, 6.21200, 97.40000, 666.00000, 17.80000, + 3.84970, 18.10000, 0.77000, 2.50520, 24.00000, 20.20000, 391.34000, 6.39500, 91.00000, 666.00000, 21.70000, + 5.20177, 18.10000, 0.77000, 2.72270, 24.00000, 20.20000, 395.43000, 6.12700, 83.40000, 666.00000, 22.70000, + 4.26131, 18.10000, 0.77000, 2.50910, 24.00000, 20.20000, 390.74000, 6.11200, 81.30000, 666.00000, 22.60000, + 4.54192, 18.10000, 0.77000, 2.51820, 24.00000, 20.20000, 374.56000, 6.39800, 88.00000, 666.00000, 25.00000, + 3.83684, 18.10000, 0.77000, 2.29550, 24.00000, 20.20000, 350.65000, 6.25100, 91.10000, 666.00000, 19.90000, + 3.67822, 18.10000, 0.77000, 2.10360, 24.00000, 20.20000, 380.79000, 5.36200, 96.20000, 666.00000, 20.80000, + 4.22239, 18.10000, 0.77000, 1.90470, 24.00000, 20.20000, 353.04000, 5.80300, 89.00000, 666.00000, 16.80000, + 3.47428, 18.10000, 0.71800, 1.90470, 24.00000, 20.20000, 354.55000, 8.78000, 82.90000, 666.00000, 21.90000, + 4.55587, 18.10000, 0.71800, 1.61320, 24.00000, 20.20000, 354.70000, 3.56100, 87.90000, 666.00000, 27.50000, + 3.69695, 18.10000, 0.71800, 1.75230, 24.00000, 20.20000, 316.03000, 4.96300, 91.40000, 666.00000, 21.90000, + 13.52220, 18.10000, 0.63100, 1.51060, 24.00000, 20.20000, 131.42000, 3.86300, 100.00000, 666.00000, 23.10000, + 4.89822, 18.10000, 0.63100, 1.33250, 24.00000, 20.20000, 375.52000, 4.97000, 100.00000, 666.00000, 50.00000, + 5.66998, 18.10000, 0.63100, 1.35670, 24.00000, 20.20000, 375.33000, 6.68300, 96.80000, 666.00000, 50.00000, + 6.53876, 18.10000, 0.63100, 1.20240, 24.00000, 20.20000, 392.05000, 7.01600, 97.50000, 666.00000, 50.00000, + 9.23230, 18.10000, 0.63100, 1.16910, 24.00000, 20.20000, 366.15000, 6.21600, 100.00000, 666.00000, 50.00000, + 8.26725, 18.10000, 0.66800, 1.12960, 24.00000, 20.20000, 347.88000, 5.87500, 89.60000, 666.00000, 50.00000, + 11.10810, 18.10000, 0.66800, 1.17420, 24.00000, 20.20000, 396.90000, 4.90600, 100.00000, 666.00000, 13.80000, + 18.49820, 18.10000, 0.66800, 1.13700, 24.00000, 20.20000, 396.90000, 4.13800, 100.00000, 666.00000, 13.80000, + 19.60910, 18.10000, 0.67100, 1.31630, 24.00000, 20.20000, 396.90000, 7.31300, 97.90000, 666.00000, 15.00000, + 15.28800, 18.10000, 0.67100, 1.34490, 24.00000, 20.20000, 363.02000, 6.64900, 93.30000, 666.00000, 13.90000, + 9.82349, 18.10000, 0.67100, 1.35800, 24.00000, 20.20000, 396.90000, 6.79400, 98.80000, 666.00000, 13.30000, + 23.64820, 18.10000, 0.67100, 1.38610, 24.00000, 20.20000, 396.90000, 6.38000, 96.20000, 666.00000, 13.10000, + 17.86670, 18.10000, 0.67100, 1.38610, 24.00000, 20.20000, 393.74000, 6.22300, 100.00000, 666.00000, 10.20000, + 88.97620, 18.10000, 0.67100, 1.41650, 24.00000, 20.20000, 396.90000, 6.96800, 91.90000, 666.00000, 10.40000, + 15.87440, 18.10000, 0.67100, 1.51920, 24.00000, 20.20000, 396.90000, 6.54500, 99.10000, 666.00000, 10.90000, + 9.18702, 18.10000, 0.70000, 1.58040, 24.00000, 20.20000, 396.90000, 5.53600, 100.00000, 666.00000, 11.30000, + 7.99248, 18.10000, 0.70000, 1.53310, 24.00000, 20.20000, 396.90000, 5.52000, 100.00000, 666.00000, 12.30000, + 20.08490, 18.10000, 0.70000, 1.43950, 24.00000, 20.20000, 285.83000, 4.36800, 91.20000, 666.00000, 8.80000, + 16.81180, 18.10000, 0.70000, 1.42610, 24.00000, 20.20000, 396.90000, 5.27700, 98.10000, 666.00000, 7.20000, + 24.39380, 18.10000, 0.70000, 1.46720, 24.00000, 20.20000, 396.90000, 4.65200, 100.00000, 666.00000, 10.50000, + 22.59710, 18.10000, 0.70000, 1.51840, 24.00000, 20.20000, 396.90000, 5.00000, 89.50000, 666.00000, 7.40000, + 14.33370, 18.10000, 0.70000, 1.58950, 24.00000, 20.20000, 372.92000, 4.88000, 100.00000, 666.00000, 10.20000, + 8.15174, 18.10000, 0.70000, 1.72810, 24.00000, 20.20000, 396.90000, 5.39000, 98.90000, 666.00000, 11.50000, + 6.96215, 18.10000, 0.70000, 1.92650, 24.00000, 20.20000, 394.43000, 5.71300, 97.00000, 666.00000, 15.10000, + 5.29305, 18.10000, 0.70000, 2.16780, 24.00000, 20.20000, 378.38000, 6.05100, 82.50000, 666.00000, 23.20000, + 11.57790, 18.10000, 0.70000, 1.77000, 24.00000, 20.20000, 396.90000, 5.03600, 97.00000, 666.00000, 9.70000, + 8.64476, 18.10000, 0.69300, 1.79120, 24.00000, 20.20000, 396.90000, 6.19300, 92.60000, 666.00000, 13.80000, + 13.35980, 18.10000, 0.69300, 1.78210, 24.00000, 20.20000, 396.90000, 5.88700, 94.70000, 666.00000, 12.70000, + 8.71675, 18.10000, 0.69300, 1.72570, 24.00000, 20.20000, 391.98000, 6.47100, 98.80000, 666.00000, 13.10000, + 5.87205, 18.10000, 0.69300, 1.67680, 24.00000, 20.20000, 396.90000, 6.40500, 96.00000, 666.00000, 12.50000, + 7.67202, 18.10000, 0.69300, 1.63340, 24.00000, 20.20000, 393.10000, 5.74700, 98.90000, 666.00000, 8.50000, + 38.35180, 18.10000, 0.69300, 1.48960, 24.00000, 20.20000, 396.90000, 5.45300, 100.00000, 666.00000, 5.00000, + 9.91655, 18.10000, 0.69300, 1.50040, 24.00000, 20.20000, 338.16000, 5.85200, 77.80000, 666.00000, 6.30000, + 25.04610, 18.10000, 0.69300, 1.58880, 24.00000, 20.20000, 396.90000, 5.98700, 100.00000, 666.00000, 5.60000, + 14.23620, 18.10000, 0.69300, 1.57410, 24.00000, 20.20000, 396.90000, 6.34300, 100.00000, 666.00000, 7.20000, + 9.59571, 18.10000, 0.69300, 1.63900, 24.00000, 20.20000, 376.11000, 6.40400, 100.00000, 666.00000, 12.10000, + 24.80170, 18.10000, 0.69300, 1.70280, 24.00000, 20.20000, 396.90000, 5.34900, 96.00000, 666.00000, 8.30000, + 41.52920, 18.10000, 0.69300, 1.60740, 24.00000, 20.20000, 329.46000, 5.53100, 85.40000, 666.00000, 8.50000, + 67.92080, 18.10000, 0.69300, 1.42540, 24.00000, 20.20000, 384.97000, 5.68300, 100.00000, 666.00000, 5.00000, + 20.71620, 18.10000, 0.65900, 1.17810, 24.00000, 20.20000, 370.22000, 4.13800, 100.00000, 666.00000, 11.90000, + 11.95110, 18.10000, 0.65900, 1.28520, 24.00000, 20.20000, 332.09000, 5.60800, 100.00000, 666.00000, 27.90000, + 7.40389, 18.10000, 0.59700, 1.45470, 24.00000, 20.20000, 314.64000, 5.61700, 97.90000, 666.00000, 17.20000, + 14.43830, 18.10000, 0.59700, 1.46550, 24.00000, 20.20000, 179.36000, 6.85200, 100.00000, 666.00000, 27.50000, + 51.13580, 18.10000, 0.59700, 1.41300, 24.00000, 20.20000, 2.60000, 5.75700, 100.00000, 666.00000, 15.00000, + 14.05070, 18.10000, 0.59700, 1.52750, 24.00000, 20.20000, 35.05000, 6.65700, 100.00000, 666.00000, 17.20000, + 18.81100, 18.10000, 0.59700, 1.55390, 24.00000, 20.20000, 28.79000, 4.62800, 100.00000, 666.00000, 17.90000, + 28.65580, 18.10000, 0.59700, 1.58940, 24.00000, 20.20000, 210.97000, 5.15500, 100.00000, 666.00000, 16.30000, + 45.74610, 18.10000, 0.69300, 1.65820, 24.00000, 20.20000, 88.27000, 4.51900, 100.00000, 666.00000, 7.00000, + 18.08460, 18.10000, 0.67900, 1.83470, 24.00000, 20.20000, 27.25000, 6.43400, 100.00000, 666.00000, 7.20000, + 10.83420, 18.10000, 0.67900, 1.81950, 24.00000, 20.20000, 21.57000, 6.78200, 90.80000, 666.00000, 7.50000, + 25.94060, 18.10000, 0.67900, 1.64750, 24.00000, 20.20000, 127.36000, 5.30400, 89.10000, 666.00000, 10.40000, + 73.53410, 18.10000, 0.67900, 1.80260, 24.00000, 20.20000, 16.45000, 5.95700, 100.00000, 666.00000, 8.80000, + 11.81230, 18.10000, 0.71800, 1.79400, 24.00000, 20.20000, 48.45000, 6.82400, 76.50000, 666.00000, 8.40000, + 11.08740, 18.10000, 0.71800, 1.85890, 24.00000, 20.20000, 318.75000, 6.41100, 100.00000, 666.00000, 16.70000, + 7.02259, 18.10000, 0.71800, 1.87460, 24.00000, 20.20000, 319.98000, 6.00600, 95.30000, 666.00000, 14.20000, + 12.04820, 18.10000, 0.61400, 1.95120, 24.00000, 20.20000, 291.55000, 5.64800, 87.60000, 666.00000, 20.80000, + 7.05042, 18.10000, 0.61400, 2.02180, 24.00000, 20.20000, 2.52000, 6.10300, 85.10000, 666.00000, 13.40000, + 8.79212, 18.10000, 0.58400, 2.06350, 24.00000, 20.20000, 3.65000, 5.56500, 70.60000, 666.00000, 11.70000, + 15.86030, 18.10000, 0.67900, 1.90960, 24.00000, 20.20000, 7.68000, 5.89600, 95.40000, 666.00000, 8.30000, + 12.24720, 18.10000, 0.58400, 1.99760, 24.00000, 20.20000, 24.65000, 5.83700, 59.70000, 666.00000, 10.20000, + 37.66190, 18.10000, 0.67900, 1.86290, 24.00000, 20.20000, 18.82000, 6.20200, 78.70000, 666.00000, 10.90000, + 7.36711, 18.10000, 0.67900, 1.93560, 24.00000, 20.20000, 96.73000, 6.19300, 78.10000, 666.00000, 11.00000, + 9.33889, 18.10000, 0.67900, 1.96820, 24.00000, 20.20000, 60.72000, 6.38000, 95.60000, 666.00000, 9.50000, + 8.49213, 18.10000, 0.58400, 2.05270, 24.00000, 20.20000, 83.45000, 6.34800, 86.10000, 666.00000, 14.50000, + 10.06230, 18.10000, 0.58400, 2.08820, 24.00000, 20.20000, 81.33000, 6.83300, 94.30000, 666.00000, 14.10000, + 6.44405, 18.10000, 0.58400, 2.20040, 24.00000, 20.20000, 97.95000, 6.42500, 74.80000, 666.00000, 16.10000, + 5.58107, 18.10000, 0.71300, 2.31580, 24.00000, 20.20000, 100.19000, 6.43600, 87.90000, 666.00000, 14.30000, + 13.91340, 18.10000, 0.71300, 2.22220, 24.00000, 20.20000, 100.63000, 6.20800, 95.00000, 666.00000, 11.70000, + 11.16040, 18.10000, 0.74000, 2.12470, 24.00000, 20.20000, 109.85000, 6.62900, 94.60000, 666.00000, 13.40000, + 14.42080, 18.10000, 0.74000, 2.00260, 24.00000, 20.20000, 27.49000, 6.46100, 93.30000, 666.00000, 9.60000, + 15.17720, 18.10000, 0.74000, 1.91420, 24.00000, 20.20000, 9.32000, 6.15200, 100.00000, 666.00000, 8.70000, + 13.67810, 18.10000, 0.74000, 1.82060, 24.00000, 20.20000, 68.95000, 5.93500, 87.90000, 666.00000, 8.40000, + 9.39063, 18.10000, 0.74000, 1.81720, 24.00000, 20.20000, 396.90000, 5.62700, 93.90000, 666.00000, 12.80000, + 22.05110, 18.10000, 0.74000, 1.86620, 24.00000, 20.20000, 391.45000, 5.81800, 92.40000, 666.00000, 10.50000, + 9.72418, 18.10000, 0.74000, 2.06510, 24.00000, 20.20000, 385.96000, 6.40600, 97.20000, 666.00000, 17.10000, + 5.66637, 18.10000, 0.74000, 2.00480, 24.00000, 20.20000, 395.69000, 6.21900, 100.00000, 666.00000, 18.40000, + 9.96654, 18.10000, 0.74000, 1.97840, 24.00000, 20.20000, 386.73000, 6.48500, 100.00000, 666.00000, 15.40000, + 12.80230, 18.10000, 0.74000, 1.89560, 24.00000, 20.20000, 240.52000, 5.85400, 96.60000, 666.00000, 10.80000, + 10.67180, 18.10000, 0.74000, 1.98790, 24.00000, 20.20000, 43.06000, 6.45900, 94.80000, 666.00000, 11.80000, + 6.28807, 18.10000, 0.74000, 2.07200, 24.00000, 20.20000, 318.01000, 6.34100, 96.40000, 666.00000, 14.90000, + 9.92485, 18.10000, 0.74000, 2.19800, 24.00000, 20.20000, 388.52000, 6.25100, 96.60000, 666.00000, 12.60000, + 9.32909, 18.10000, 0.71300, 2.26160, 24.00000, 20.20000, 396.90000, 6.18500, 98.70000, 666.00000, 14.10000, + 7.52601, 18.10000, 0.71300, 2.18500, 24.00000, 20.20000, 304.21000, 6.41700, 98.30000, 666.00000, 13.00000, + 6.71772, 18.10000, 0.71300, 2.32360, 24.00000, 20.20000, 0.32000, 6.74900, 92.60000, 666.00000, 13.40000, + 5.44114, 18.10000, 0.71300, 2.35520, 24.00000, 20.20000, 355.29000, 6.65500, 98.20000, 666.00000, 15.20000, + 5.09017, 18.10000, 0.71300, 2.36820, 24.00000, 20.20000, 385.09000, 6.29700, 91.80000, 666.00000, 16.10000, + 8.24809, 18.10000, 0.71300, 2.45270, 24.00000, 20.20000, 375.87000, 7.39300, 99.30000, 666.00000, 17.80000, + 9.51363, 18.10000, 0.71300, 2.49610, 24.00000, 20.20000, 6.68000, 6.72800, 94.10000, 666.00000, 14.90000, + 4.75237, 18.10000, 0.71300, 2.43580, 24.00000, 20.20000, 50.92000, 6.52500, 86.50000, 666.00000, 14.10000, + 4.66883, 18.10000, 0.71300, 2.58060, 24.00000, 20.20000, 10.48000, 5.97600, 87.90000, 666.00000, 12.70000, + 8.20058, 18.10000, 0.71300, 2.77920, 24.00000, 20.20000, 3.50000, 5.93600, 80.30000, 666.00000, 13.50000, + 7.75223, 18.10000, 0.71300, 2.78310, 24.00000, 20.20000, 272.21000, 6.30100, 83.70000, 666.00000, 14.90000, + 6.80117, 18.10000, 0.71300, 2.71750, 24.00000, 20.20000, 396.90000, 6.08100, 84.40000, 666.00000, 20.00000, + 4.81213, 18.10000, 0.71300, 2.59750, 24.00000, 20.20000, 255.23000, 6.70100, 90.00000, 666.00000, 16.40000, + 3.69311, 18.10000, 0.71300, 2.56710, 24.00000, 20.20000, 391.43000, 6.37600, 88.40000, 666.00000, 17.70000, + 6.65492, 18.10000, 0.71300, 2.73440, 24.00000, 20.20000, 396.90000, 6.31700, 83.00000, 666.00000, 19.50000, + 5.82115, 18.10000, 0.71300, 2.80160, 24.00000, 20.20000, 393.82000, 6.51300, 89.90000, 666.00000, 20.20000, + 7.83932, 18.10000, 0.65500, 2.96340, 24.00000, 20.20000, 396.90000, 6.20900, 65.40000, 666.00000, 21.40000, + 3.16360, 18.10000, 0.65500, 3.06650, 24.00000, 20.20000, 334.40000, 5.75900, 48.20000, 666.00000, 19.90000, + 3.77498, 18.10000, 0.65500, 2.87150, 24.00000, 20.20000, 22.01000, 5.95200, 84.70000, 666.00000, 19.00000, + 4.42228, 18.10000, 0.58400, 2.54030, 24.00000, 20.20000, 331.29000, 6.00300, 94.50000, 666.00000, 19.10000, + 15.57570, 18.10000, 0.58000, 2.90840, 24.00000, 20.20000, 368.74000, 5.92600, 71.00000, 666.00000, 19.10000, + 13.07510, 18.10000, 0.58000, 2.82370, 24.00000, 20.20000, 396.90000, 5.71300, 56.70000, 666.00000, 20.10000, + 4.34879, 18.10000, 0.58000, 3.03340, 24.00000, 20.20000, 396.90000, 6.16700, 84.00000, 666.00000, 19.90000, + 4.03841, 18.10000, 0.53200, 3.09930, 24.00000, 20.20000, 395.33000, 6.22900, 90.70000, 666.00000, 19.60000, + 3.56868, 18.10000, 0.58000, 2.89650, 24.00000, 20.20000, 393.37000, 6.43700, 75.00000, 666.00000, 23.20000, + 4.64689, 18.10000, 0.61400, 2.53290, 24.00000, 20.20000, 374.68000, 6.98000, 67.60000, 666.00000, 29.80000, + 8.05579, 18.10000, 0.58400, 2.42980, 24.00000, 20.20000, 352.58000, 5.42700, 95.40000, 666.00000, 13.80000, + 6.39312, 18.10000, 0.58400, 2.20600, 24.00000, 20.20000, 302.76000, 6.16200, 97.40000, 666.00000, 13.30000, + 4.87141, 18.10000, 0.61400, 2.30530, 24.00000, 20.20000, 396.21000, 6.48400, 93.60000, 666.00000, 16.70000, + 15.02340, 18.10000, 0.61400, 2.10070, 24.00000, 20.20000, 349.48000, 5.30400, 97.30000, 666.00000, 12.00000, + 10.23300, 18.10000, 0.61400, 2.17050, 24.00000, 20.20000, 379.70000, 6.18500, 96.70000, 666.00000, 14.60000, + 14.33370, 18.10000, 0.61400, 1.95120, 24.00000, 20.20000, 383.32000, 6.22900, 88.00000, 666.00000, 21.40000, + 5.82401, 18.10000, 0.53200, 3.42420, 24.00000, 20.20000, 396.90000, 6.24200, 64.70000, 666.00000, 23.00000, + 5.70818, 18.10000, 0.53200, 3.33170, 24.00000, 20.20000, 393.07000, 6.75000, 74.90000, 666.00000, 23.70000, + 5.73116, 18.10000, 0.53200, 3.41060, 24.00000, 20.20000, 395.28000, 7.06100, 77.00000, 666.00000, 25.00000, + 2.81838, 18.10000, 0.53200, 4.09830, 24.00000, 20.20000, 392.92000, 5.76200, 40.30000, 666.00000, 21.80000, + 2.37857, 18.10000, 0.58300, 3.72400, 24.00000, 20.20000, 370.73000, 5.87100, 41.90000, 666.00000, 20.60000, + 3.67367, 18.10000, 0.58300, 3.99170, 24.00000, 20.20000, 388.62000, 6.31200, 51.90000, 666.00000, 21.20000, + 5.69175, 18.10000, 0.58300, 3.54590, 24.00000, 20.20000, 392.68000, 6.11400, 79.80000, 666.00000, 19.10000, + 4.83567, 18.10000, 0.58300, 3.15230, 24.00000, 20.20000, 388.22000, 5.90500, 53.20000, 666.00000, 20.60000, + 0.15086, 27.74000, 0.60900, 1.82090, 4.00000, 20.10000, 395.09000, 5.45400, 92.70000, 711.00000, 15.20000, + 0.18337, 27.74000, 0.60900, 1.75540, 4.00000, 20.10000, 344.05000, 5.41400, 98.30000, 711.00000, 7.00000, + 0.20746, 27.74000, 0.60900, 1.82260, 4.00000, 20.10000, 318.43000, 5.09300, 98.00000, 711.00000, 8.10000, + 0.10574, 27.74000, 0.60900, 1.86810, 4.00000, 20.10000, 390.11000, 5.98300, 98.80000, 711.00000, 13.60000, + 0.11132, 27.74000, 0.60900, 2.10990, 4.00000, 20.10000, 396.90000, 5.98300, 83.50000, 711.00000, 20.10000, + 0.17331, 9.69000, 0.58500, 2.38170, 6.00000, 19.20000, 396.90000, 5.70700, 54.00000, 391.00000, 21.80000, + 0.27957, 9.69000, 0.58500, 2.38170, 6.00000, 19.20000, 396.90000, 5.92600, 42.60000, 391.00000, 24.50000, + 0.17899, 9.69000, 0.58500, 2.79860, 6.00000, 19.20000, 393.29000, 5.67000, 28.80000, 391.00000, 23.10000, + 0.28960, 9.69000, 0.58500, 2.79860, 6.00000, 19.20000, 396.90000, 5.39000, 72.90000, 391.00000, 19.70000, + 0.26838, 9.69000, 0.58500, 2.89270, 6.00000, 19.20000, 396.90000, 5.79400, 70.60000, 391.00000, 18.30000, + 0.23912, 9.69000, 0.58500, 2.40910, 6.00000, 19.20000, 396.90000, 6.01900, 65.30000, 391.00000, 21.20000, + 0.17783, 9.69000, 0.58500, 2.39990, 6.00000, 19.20000, 395.77000, 5.56900, 73.50000, 391.00000, 17.50000, + 0.22438, 9.69000, 0.58500, 2.49820, 6.00000, 19.20000, 396.90000, 6.02700, 79.70000, 391.00000, 16.80000, + 0.06263, 11.93000, 0.57300, 2.47860, 1.00000, 21.00000, 391.99000, 6.59300, 69.10000, 273.00000, 22.40000, + 0.04527, 11.93000, 0.57300, 2.28750, 1.00000, 21.00000, 396.90000, 6.12000, 76.70000, 273.00000, 20.60000, + 0.06076, 11.93000, 0.57300, 2.16750, 1.00000, 21.00000, 396.90000, 6.97600, 91.00000, 273.00000, 23.90000, + 0.10959, 11.93000, 0.57300, 2.38890, 1.00000, 21.00000, 393.45000, 6.79400, 89.30000, 273.00000, 22.00000, + 0.04741, 11.93000, 0.57300, 2.50500, 1.00000, 21.00000, 396.90000, 6.03000, 80.80000, 273.00000, 11.90000, +}) diff --git a/vendor/gonum.org/v1/gonum/stat/car_data_test.go b/vendor/gonum.org/v1/gonum/stat/car_data_test.go new file mode 100644 index 00000000..a3cdabb2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/car_data_test.go @@ -0,0 +1,406 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat_test + +import "gonum.org/v1/gonum/mat" + +// ASA Car Exposition Data of Ramos and Donoho (1983) +// http://lib.stat.cmu.edu/datasets/cars.desc +// http://lib.stat.cmu.edu/datasets/cars.data +// Columns are: displacement, horsepower, weight, acceleration, MPG. +var carData = mat.NewDense(392, 5, []float64{ + 307.0, 130.0, 3504.0, 12.0, 18.0, + 350.0, 165.0, 3693.0, 11.5, 15.0, + 318.0, 150.0, 3436.0, 11.0, 18.0, + 304.0, 150.0, 3433.0, 12.0, 16.0, + 302.0, 140.0, 3449.0, 10.5, 17.0, + 429.0, 198.0, 4341.0, 10.0, 15.0, + 454.0, 220.0, 4354.0, 9.0, 14.0, + 440.0, 215.0, 4312.0, 8.5, 14.0, + 455.0, 225.0, 4425.0, 10.0, 14.0, + 390.0, 190.0, 3850.0, 8.5, 15.0, + 383.0, 170.0, 3563.0, 10.0, 15.0, + 340.0, 160.0, 3609.0, 8.0, 14.0, + 400.0, 150.0, 3761.0, 9.5, 15.0, + 455.0, 225.0, 3086.0, 10.0, 14.0, + 113.0, 95.0, 2372.0, 15.0, 24.0, + 198.0, 95.0, 2833.0, 15.5, 22.0, + 199.0, 97.0, 2774.0, 15.5, 18.0, + 200.0, 85.0, 2587.0, 16.0, 21.0, + 97.0, 88.0, 2130.0, 14.5, 27.0, + 97.0, 46.0, 1835.0, 20.5, 26.0, + 110.0, 87.0, 2672.0, 17.5, 25.0, + 107.0, 90.0, 2430.0, 14.5, 24.0, + 104.0, 95.0, 2375.0, 17.5, 25.0, + 121.0, 113.0, 2234.0, 12.5, 26.0, + 199.0, 90.0, 2648.0, 15.0, 21.0, + 360.0, 215.0, 4615.0, 14.0, 10.0, + 307.0, 200.0, 4376.0, 15.0, 10.0, + 318.0, 210.0, 4382.0, 13.5, 11.0, + 304.0, 193.0, 4732.0, 18.5, 9.0, + 97.0, 88.0, 2130.0, 14.5, 27.0, + 140.0, 90.0, 2264.0, 15.5, 28.0, + 113.0, 95.0, 2228.0, 14.0, 25.0, + 232.0, 100.0, 2634.0, 13.0, 19.0, + 225.0, 105.0, 3439.0, 15.5, 16.0, + 250.0, 100.0, 3329.0, 15.5, 17.0, + 250.0, 88.0, 3302.0, 15.5, 19.0, + 232.0, 100.0, 3288.0, 15.5, 18.0, + 350.0, 165.0, 4209.0, 12.0, 14.0, + 400.0, 175.0, 4464.0, 11.5, 14.0, + 351.0, 153.0, 4154.0, 13.5, 14.0, + 318.0, 150.0, 4096.0, 13.0, 14.0, + 383.0, 180.0, 4955.0, 11.5, 12.0, + 400.0, 170.0, 4746.0, 12.0, 13.0, + 400.0, 175.0, 5140.0, 12.0, 13.0, + 258.0, 110.0, 2962.0, 13.5, 18.0, + 140.0, 72.0, 2408.0, 19.0, 22.0, + 250.0, 100.0, 3282.0, 15.0, 19.0, + 250.0, 88.0, 3139.0, 14.5, 18.0, + 122.0, 86.0, 2220.0, 14.0, 23.0, + 116.0, 90.0, 2123.0, 14.0, 28.0, + 79.0, 70.0, 2074.0, 19.5, 30.0, + 88.0, 76.0, 2065.0, 14.5, 30.0, + 71.0, 65.0, 1773.0, 19.0, 31.0, + 72.0, 69.0, 1613.0, 18.0, 35.0, + 97.0, 60.0, 1834.0, 19.0, 27.0, + 91.0, 70.0, 1955.0, 20.5, 26.0, + 113.0, 95.0, 2278.0, 15.5, 24.0, + 97.5, 80.0, 2126.0, 17.0, 25.0, + 97.0, 54.0, 2254.0, 23.5, 23.0, + 140.0, 90.0, 2408.0, 19.5, 20.0, + 122.0, 86.0, 2226.0, 16.5, 21.0, + 350.0, 165.0, 4274.0, 12.0, 13.0, + 400.0, 175.0, 4385.0, 12.0, 14.0, + 318.0, 150.0, 4135.0, 13.5, 15.0, + 351.0, 153.0, 4129.0, 13.0, 14.0, + 304.0, 150.0, 3672.0, 11.5, 17.0, + 429.0, 208.0, 4633.0, 11.0, 11.0, + 350.0, 155.0, 4502.0, 13.5, 13.0, + 350.0, 160.0, 4456.0, 13.5, 12.0, + 400.0, 190.0, 4422.0, 12.5, 13.0, + 70.0, 97.0, 2330.0, 13.5, 19.0, + 304.0, 150.0, 3892.0, 12.5, 15.0, + 307.0, 130.0, 4098.0, 14.0, 13.0, + 302.0, 140.0, 4294.0, 16.0, 13.0, + 318.0, 150.0, 4077.0, 14.0, 14.0, + 121.0, 112.0, 2933.0, 14.5, 18.0, + 121.0, 76.0, 2511.0, 18.0, 22.0, + 120.0, 87.0, 2979.0, 19.5, 21.0, + 96.0, 69.0, 2189.0, 18.0, 26.0, + 122.0, 86.0, 2395.0, 16.0, 22.0, + 97.0, 92.0, 2288.0, 17.0, 28.0, + 120.0, 97.0, 2506.0, 14.5, 23.0, + 98.0, 80.0, 2164.0, 15.0, 28.0, + 97.0, 88.0, 2100.0, 16.5, 27.0, + 350.0, 175.0, 4100.0, 13.0, 13.0, + 304.0, 150.0, 3672.0, 11.5, 14.0, + 350.0, 145.0, 3988.0, 13.0, 13.0, + 302.0, 137.0, 4042.0, 14.5, 14.0, + 318.0, 150.0, 3777.0, 12.5, 15.0, + 429.0, 198.0, 4952.0, 11.5, 12.0, + 400.0, 150.0, 4464.0, 12.0, 13.0, + 351.0, 158.0, 4363.0, 13.0, 13.0, + 318.0, 150.0, 4237.0, 14.5, 14.0, + 440.0, 215.0, 4735.0, 11.0, 13.0, + 455.0, 225.0, 4951.0, 11.0, 12.0, + 360.0, 175.0, 3821.0, 11.0, 13.0, + 225.0, 105.0, 3121.0, 16.5, 18.0, + 250.0, 100.0, 3278.0, 18.0, 16.0, + 232.0, 100.0, 2945.0, 16.0, 18.0, + 250.0, 88.0, 3021.0, 16.5, 18.0, + 198.0, 95.0, 2904.0, 16.0, 23.0, + 97.0, 46.0, 1950.0, 21.0, 26.0, + 400.0, 150.0, 4997.0, 14.0, 11.0, + 400.0, 167.0, 4906.0, 12.5, 12.0, + 360.0, 170.0, 4654.0, 13.0, 13.0, + 350.0, 180.0, 4499.0, 12.5, 12.0, + 232.0, 100.0, 2789.0, 15.0, 18.0, + 97.0, 88.0, 2279.0, 19.0, 20.0, + 140.0, 72.0, 2401.0, 19.5, 21.0, + 108.0, 94.0, 2379.0, 16.5, 22.0, + 70.0, 90.0, 2124.0, 13.5, 18.0, + 122.0, 85.0, 2310.0, 18.5, 19.0, + 155.0, 107.0, 2472.0, 14.0, 21.0, + 98.0, 90.0, 2265.0, 15.5, 26.0, + 350.0, 145.0, 4082.0, 13.0, 15.0, + 400.0, 230.0, 4278.0, 9.5, 16.0, + 68.0, 49.0, 1867.0, 19.5, 29.0, + 116.0, 75.0, 2158.0, 15.5, 24.0, + 114.0, 91.0, 2582.0, 14.0, 20.0, + 121.0, 112.0, 2868.0, 15.5, 19.0, + 318.0, 150.0, 3399.0, 11.0, 15.0, + 121.0, 110.0, 2660.0, 14.0, 24.0, + 156.0, 122.0, 2807.0, 13.5, 20.0, + 350.0, 180.0, 3664.0, 11.0, 11.0, + 198.0, 95.0, 3102.0, 16.5, 20.0, + 232.0, 100.0, 2901.0, 16.0, 19.0, + 250.0, 100.0, 3336.0, 17.0, 15.0, + 79.0, 67.0, 1950.0, 19.0, 31.0, + 122.0, 80.0, 2451.0, 16.5, 26.0, + 71.0, 65.0, 1836.0, 21.0, 32.0, + 140.0, 75.0, 2542.0, 17.0, 25.0, + 250.0, 100.0, 3781.0, 17.0, 16.0, + 258.0, 110.0, 3632.0, 18.0, 16.0, + 225.0, 105.0, 3613.0, 16.5, 18.0, + 302.0, 140.0, 4141.0, 14.0, 16.0, + 350.0, 150.0, 4699.0, 14.5, 13.0, + 318.0, 150.0, 4457.0, 13.5, 14.0, + 302.0, 140.0, 4638.0, 16.0, 14.0, + 304.0, 150.0, 4257.0, 15.5, 14.0, + 98.0, 83.0, 2219.0, 16.5, 29.0, + 79.0, 67.0, 1963.0, 15.5, 26.0, + 97.0, 78.0, 2300.0, 14.5, 26.0, + 76.0, 52.0, 1649.0, 16.5, 31.0, + 83.0, 61.0, 2003.0, 19.0, 32.0, + 90.0, 75.0, 2125.0, 14.5, 28.0, + 90.0, 75.0, 2108.0, 15.5, 24.0, + 116.0, 75.0, 2246.0, 14.0, 26.0, + 120.0, 97.0, 2489.0, 15.0, 24.0, + 108.0, 93.0, 2391.0, 15.5, 26.0, + 79.0, 67.0, 2000.0, 16.0, 31.0, + 225.0, 95.0, 3264.0, 16.0, 19.0, + 250.0, 105.0, 3459.0, 16.0, 18.0, + 250.0, 72.0, 3432.0, 21.0, 15.0, + 250.0, 72.0, 3158.0, 19.5, 15.0, + 400.0, 170.0, 4668.0, 11.5, 16.0, + 350.0, 145.0, 4440.0, 14.0, 15.0, + 318.0, 150.0, 4498.0, 14.5, 16.0, + 351.0, 148.0, 4657.0, 13.5, 14.0, + 231.0, 110.0, 3907.0, 21.0, 17.0, + 250.0, 105.0, 3897.0, 18.5, 16.0, + 258.0, 110.0, 3730.0, 19.0, 15.0, + 225.0, 95.0, 3785.0, 19.0, 18.0, + 231.0, 110.0, 3039.0, 15.0, 21.0, + 262.0, 110.0, 3221.0, 13.5, 20.0, + 302.0, 129.0, 3169.0, 12.0, 13.0, + 97.0, 75.0, 2171.0, 16.0, 29.0, + 140.0, 83.0, 2639.0, 17.0, 23.0, + 232.0, 100.0, 2914.0, 16.0, 20.0, + 140.0, 78.0, 2592.0, 18.5, 23.0, + 134.0, 96.0, 2702.0, 13.5, 24.0, + 90.0, 71.0, 2223.0, 16.5, 25.0, + 119.0, 97.0, 2545.0, 17.0, 24.0, + 171.0, 97.0, 2984.0, 14.5, 18.0, + 90.0, 70.0, 1937.0, 14.0, 29.0, + 232.0, 90.0, 3211.0, 17.0, 19.0, + 115.0, 95.0, 2694.0, 15.0, 23.0, + 120.0, 88.0, 2957.0, 17.0, 23.0, + 121.0, 98.0, 2945.0, 14.5, 22.0, + 121.0, 115.0, 2671.0, 13.5, 25.0, + 91.0, 53.0, 1795.0, 17.5, 33.0, + 107.0, 86.0, 2464.0, 15.5, 28.0, + 116.0, 81.0, 2220.0, 16.9, 25.0, + 140.0, 92.0, 2572.0, 14.9, 25.0, + 98.0, 79.0, 2255.0, 17.7, 26.0, + 101.0, 83.0, 2202.0, 15.3, 27.0, + 305.0, 140.0, 4215.0, 13.0, 17.5, + 318.0, 150.0, 4190.0, 13.0, 16.0, + 304.0, 120.0, 3962.0, 13.9, 15.5, + 351.0, 152.0, 4215.0, 12.8, 14.5, + 225.0, 100.0, 3233.0, 15.4, 22.0, + 250.0, 105.0, 3353.0, 14.5, 22.0, + 200.0, 81.0, 3012.0, 17.6, 24.0, + 232.0, 90.0, 3085.0, 17.6, 22.5, + 85.0, 52.0, 2035.0, 22.2, 29.0, + 98.0, 60.0, 2164.0, 22.1, 24.5, + 90.0, 70.0, 1937.0, 14.2, 29.0, + 91.0, 53.0, 1795.0, 17.4, 33.0, + 225.0, 100.0, 3651.0, 17.7, 20.0, + 250.0, 78.0, 3574.0, 21.0, 18.0, + 250.0, 110.0, 3645.0, 16.2, 18.5, + 258.0, 95.0, 3193.0, 17.8, 17.5, + 97.0, 71.0, 1825.0, 12.2, 29.5, + 85.0, 70.0, 1990.0, 17.0, 32.0, + 97.0, 75.0, 2155.0, 16.4, 28.0, + 140.0, 72.0, 2565.0, 13.6, 26.5, + 130.0, 102.0, 3150.0, 15.7, 20.0, + 318.0, 150.0, 3940.0, 13.2, 13.0, + 120.0, 88.0, 3270.0, 21.9, 19.0, + 156.0, 108.0, 2930.0, 15.5, 19.0, + 168.0, 120.0, 3820.0, 16.7, 16.5, + 350.0, 180.0, 4380.0, 12.1, 16.5, + 350.0, 145.0, 4055.0, 12.0, 13.0, + 302.0, 130.0, 3870.0, 15.0, 13.0, + 318.0, 150.0, 3755.0, 14.0, 13.0, + 98.0, 68.0, 2045.0, 18.5, 31.5, + 111.0, 80.0, 2155.0, 14.8, 30.0, + 79.0, 58.0, 1825.0, 18.6, 36.0, + 122.0, 96.0, 2300.0, 15.5, 25.5, + 85.0, 70.0, 1945.0, 16.8, 33.5, + 305.0, 145.0, 3880.0, 12.5, 17.5, + 260.0, 110.0, 4060.0, 19.0, 17.0, + 318.0, 145.0, 4140.0, 13.7, 15.5, + 302.0, 130.0, 4295.0, 14.9, 15.0, + 250.0, 110.0, 3520.0, 16.4, 17.5, + 231.0, 105.0, 3425.0, 16.9, 20.5, + 225.0, 100.0, 3630.0, 17.7, 19.0, + 250.0, 98.0, 3525.0, 19.0, 18.5, + 400.0, 180.0, 4220.0, 11.1, 16.0, + 350.0, 170.0, 4165.0, 11.4, 15.5, + 400.0, 190.0, 4325.0, 12.2, 15.5, + 351.0, 149.0, 4335.0, 14.5, 16.0, + 97.0, 78.0, 1940.0, 14.5, 29.0, + 151.0, 88.0, 2740.0, 16.0, 24.5, + 97.0, 75.0, 2265.0, 18.2, 26.0, + 140.0, 89.0, 2755.0, 15.8, 25.5, + 98.0, 63.0, 2051.0, 17.0, 30.5, + 98.0, 83.0, 2075.0, 15.9, 33.5, + 97.0, 67.0, 1985.0, 16.4, 30.0, + 97.0, 78.0, 2190.0, 14.1, 30.5, + 146.0, 97.0, 2815.0, 14.5, 22.0, + 121.0, 110.0, 2600.0, 12.8, 21.5, + 80.0, 110.0, 2720.0, 13.5, 21.5, + 90.0, 48.0, 1985.0, 21.5, 43.1, + 98.0, 66.0, 1800.0, 14.4, 36.1, + 78.0, 52.0, 1985.0, 19.4, 32.8, + 85.0, 70.0, 2070.0, 18.6, 39.4, + 91.0, 60.0, 1800.0, 16.4, 36.1, + 260.0, 110.0, 3365.0, 15.5, 19.9, + 318.0, 140.0, 3735.0, 13.2, 19.4, + 302.0, 139.0, 3570.0, 12.8, 20.2, + 231.0, 105.0, 3535.0, 19.2, 19.2, + 200.0, 95.0, 3155.0, 18.2, 20.5, + 200.0, 85.0, 2965.0, 15.8, 20.2, + 140.0, 88.0, 2720.0, 15.4, 25.1, + 225.0, 100.0, 3430.0, 17.2, 20.5, + 232.0, 90.0, 3210.0, 17.2, 19.4, + 231.0, 105.0, 3380.0, 15.8, 20.6, + 200.0, 85.0, 3070.0, 16.7, 20.8, + 225.0, 110.0, 3620.0, 18.7, 18.6, + 258.0, 120.0, 3410.0, 15.1, 18.1, + 305.0, 145.0, 3425.0, 13.2, 19.2, + 231.0, 165.0, 3445.0, 13.4, 17.7, + 302.0, 139.0, 3205.0, 11.2, 18.1, + 318.0, 140.0, 4080.0, 13.7, 17.5, + 98.0, 68.0, 2155.0, 16.5, 30.0, + 134.0, 95.0, 2560.0, 14.2, 27.5, + 119.0, 97.0, 2300.0, 14.7, 27.2, + 105.0, 75.0, 2230.0, 14.5, 30.9, + 134.0, 95.0, 2515.0, 14.8, 21.1, + 156.0, 105.0, 2745.0, 16.7, 23.2, + 151.0, 85.0, 2855.0, 17.6, 23.8, + 119.0, 97.0, 2405.0, 14.9, 23.9, + 131.0, 103.0, 2830.0, 15.9, 20.3, + 163.0, 125.0, 3140.0, 13.6, 17.0, + 121.0, 115.0, 2795.0, 15.7, 21.6, + 163.0, 133.0, 3410.0, 15.8, 16.2, + 89.0, 71.0, 1990.0, 14.9, 31.5, + 98.0, 68.0, 2135.0, 16.6, 29.5, + 231.0, 115.0, 3245.0, 15.4, 21.5, + 200.0, 85.0, 2990.0, 18.2, 19.8, + 140.0, 88.0, 2890.0, 17.3, 22.3, + 232.0, 90.0, 3265.0, 18.2, 20.2, + 225.0, 110.0, 3360.0, 16.6, 20.6, + 305.0, 130.0, 3840.0, 15.4, 17.0, + 302.0, 129.0, 3725.0, 13.4, 17.6, + 351.0, 138.0, 3955.0, 13.2, 16.5, + 318.0, 135.0, 3830.0, 15.2, 18.2, + 350.0, 155.0, 4360.0, 14.9, 16.9, + 351.0, 142.0, 4054.0, 14.3, 15.5, + 267.0, 125.0, 3605.0, 15.0, 19.2, + 360.0, 150.0, 3940.0, 13.0, 18.5, + 89.0, 71.0, 1925.0, 14.0, 31.9, + 86.0, 65.0, 1975.0, 15.2, 34.1, + 98.0, 80.0, 1915.0, 14.4, 35.7, + 121.0, 80.0, 2670.0, 15.0, 27.4, + 183.0, 77.0, 3530.0, 20.1, 25.4, + 350.0, 125.0, 3900.0, 17.4, 23.0, + 141.0, 71.0, 3190.0, 24.8, 27.2, + 260.0, 90.0, 3420.0, 22.2, 23.9, + 105.0, 70.0, 2200.0, 13.2, 34.2, + 105.0, 70.0, 2150.0, 14.9, 34.5, + 85.0, 65.0, 2020.0, 19.2, 31.8, + 91.0, 69.0, 2130.0, 14.7, 37.3, + 151.0, 90.0, 2670.0, 16.0, 28.4, + 173.0, 115.0, 2595.0, 11.3, 28.8, + 173.0, 115.0, 2700.0, 12.9, 26.8, + 151.0, 90.0, 2556.0, 13.2, 33.5, + 98.0, 76.0, 2144.0, 14.7, 41.5, + 89.0, 60.0, 1968.0, 18.8, 38.1, + 98.0, 70.0, 2120.0, 15.5, 32.1, + 86.0, 65.0, 2019.0, 16.4, 37.2, + 151.0, 90.0, 2678.0, 16.5, 28.0, + 140.0, 88.0, 2870.0, 18.1, 26.4, + 151.0, 90.0, 3003.0, 20.1, 24.3, + 225.0, 90.0, 3381.0, 18.7, 19.1, + 97.0, 78.0, 2188.0, 15.8, 34.3, + 134.0, 90.0, 2711.0, 15.5, 29.8, + 120.0, 75.0, 2542.0, 17.5, 31.3, + 119.0, 92.0, 2434.0, 15.0, 37.0, + 108.0, 75.0, 2265.0, 15.2, 32.2, + 86.0, 65.0, 2110.0, 17.9, 46.6, + 156.0, 105.0, 2800.0, 14.4, 27.9, + 85.0, 65.0, 2110.0, 19.2, 40.8, + 90.0, 48.0, 2085.0, 21.7, 44.3, + 90.0, 48.0, 2335.0, 23.7, 43.4, + 121.0, 67.0, 2950.0, 19.9, 36.4, + 146.0, 67.0, 3250.0, 21.8, 30.0, + 91.0, 67.0, 1850.0, 13.8, 44.6, + 97.0, 67.0, 2145.0, 18.0, 33.8, + 89.0, 62.0, 1845.0, 15.3, 29.8, + 168.0, 132.0, 2910.0, 11.4, 32.7, + 70.0, 100.0, 2420.0, 12.5, 23.7, + 122.0, 88.0, 2500.0, 15.1, 35.0, + 107.0, 72.0, 2290.0, 17.0, 32.4, + 135.0, 84.0, 2490.0, 15.7, 27.2, + 151.0, 84.0, 2635.0, 16.4, 26.6, + 156.0, 92.0, 2620.0, 14.4, 25.8, + 173.0, 110.0, 2725.0, 12.6, 23.5, + 135.0, 84.0, 2385.0, 12.9, 30.0, + 79.0, 58.0, 1755.0, 16.9, 39.1, + 86.0, 64.0, 1875.0, 16.4, 39.0, + 81.0, 60.0, 1760.0, 16.1, 35.1, + 97.0, 67.0, 2065.0, 17.8, 32.3, + 85.0, 65.0, 1975.0, 19.4, 37.0, + 89.0, 62.0, 2050.0, 17.3, 37.7, + 91.0, 68.0, 1985.0, 16.0, 34.1, + 105.0, 63.0, 2215.0, 14.9, 34.7, + 98.0, 65.0, 2045.0, 16.2, 34.4, + 98.0, 65.0, 2380.0, 20.7, 29.9, + 105.0, 74.0, 2190.0, 14.2, 33.0, + 107.0, 75.0, 2210.0, 14.4, 33.7, + 108.0, 75.0, 2350.0, 16.8, 32.4, + 119.0, 100.0, 2615.0, 14.8, 32.9, + 120.0, 74.0, 2635.0, 18.3, 31.6, + 141.0, 80.0, 3230.0, 20.4, 28.1, + 145.0, 76.0, 3160.0, 19.6, 30.7, + 168.0, 116.0, 2900.0, 12.6, 25.4, + 146.0, 120.0, 2930.0, 13.8, 24.2, + 231.0, 110.0, 3415.0, 15.8, 22.4, + 350.0, 105.0, 3725.0, 19.0, 26.6, + 200.0, 88.0, 3060.0, 17.1, 20.2, + 225.0, 85.0, 3465.0, 16.6, 17.6, + 112.0, 88.0, 2605.0, 19.6, 28.0, + 112.0, 88.0, 2640.0, 18.6, 27.0, + 112.0, 88.0, 2395.0, 18.0, 34.0, + 112.0, 85.0, 2575.0, 16.2, 31.0, + 135.0, 84.0, 2525.0, 16.0, 29.0, + 151.0, 90.0, 2735.0, 18.0, 27.0, + 140.0, 92.0, 2865.0, 16.4, 24.0, + 105.0, 74.0, 1980.0, 15.3, 36.0, + 91.0, 68.0, 2025.0, 18.2, 37.0, + 91.0, 68.0, 1970.0, 17.6, 31.0, + 105.0, 63.0, 2125.0, 14.7, 38.0, + 98.0, 70.0, 2125.0, 17.3, 36.0, + 120.0, 88.0, 2160.0, 14.5, 36.0, + 107.0, 75.0, 2205.0, 14.5, 36.0, + 108.0, 70.0, 2245.0, 16.9, 34.0, + 91.0, 67.0, 1965.0, 15.0, 38.0, + 91.0, 67.0, 1965.0, 15.7, 32.0, + 91.0, 67.0, 1995.0, 16.2, 38.0, + 181.0, 110.0, 2945.0, 16.4, 25.0, + 262.0, 85.0, 3015.0, 17.0, 38.0, + 156.0, 92.0, 2585.0, 14.5, 26.0, + 232.0, 112.0, 2835.0, 14.7, 22.0, + 144.0, 96.0, 2665.0, 13.9, 32.0, + 135.0, 84.0, 2370.0, 13.0, 36.0, + 151.0, 90.0, 2950.0, 17.3, 27.0, + 140.0, 86.0, 2790.0, 15.6, 27.0, + 97.0, 52.0, 2130.0, 24.6, 44.0, + 135.0, 84.0, 2295.0, 11.6, 32.0, + 120.0, 79.0, 2625.0, 18.6, 28.0, + 119.0, 82.0, 2720.0, 19.4, 31.0, +}) diff --git a/vendor/gonum.org/v1/gonum/stat/cca_example_test.go b/vendor/gonum.org/v1/gonum/stat/cca_example_test.go new file mode 100644 index 00000000..f053e5ad --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/cca_example_test.go @@ -0,0 +1,165 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat_test + +import ( + "fmt" + "log" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +// symView is a helper for getting a View of a SymDense. +type symView struct { + sym *mat.SymDense + + i, j, r, c int +} + +func (s symView) Dims() (r, c int) { return s.r, s.c } + +func (s symView) At(i, j int) float64 { + if i < 0 || s.r <= i { + panic("i out of bounds") + } + if j < 0 || s.c <= j { + panic("j out of bounds") + } + return s.sym.At(s.i+i, s.j+j) +} + +func (s symView) T() mat.Matrix { return mat.Transpose{s} } + +func ExampleCC() { + // This example is directly analogous to Example 3.5 on page 87 of + // Koch, Inge. Analysis of multivariate and high-dimensional data. + // Vol. 32. Cambridge University Press, 2013. ISBN: 9780521887939 + + // bostonData is the Boston Housing Data of Harrison and Rubinfeld (1978) + n, _ := bostonData.Dims() + var xd, yd = 7, 4 + // The variables (columns) of bostonData can be partitioned into two sets: + // those that deal with environmental/social variables (xdata), and those + // that contain information regarding the individual (ydata). Because the + // variables can be naturally partitioned in this way, these data are + // appropriate for canonical correlation analysis. The columns (variables) + // of xdata are, in order: + // per capita crime rate by town, + // proportion of non-retail business acres per town, + // nitric oxide concentration (parts per 10 million), + // weighted distances to Boston employment centres, + // index of accessibility to radial highways, + // pupil-teacher ratio by town, and + // proportion of blacks by town. + xdata := bostonData.Slice(0, n, 0, xd) + + // The columns (variables) of ydata are, in order: + // average number of rooms per dwelling, + // proportion of owner-occupied units built prior to 1940, + // full-value property-tax rate per $10000, and + // median value of owner-occupied homes in $1000s. + ydata := bostonData.Slice(0, n, xd, xd+yd) + + // For comparison, calculate the correlation matrix for the original data. + var cor mat.SymDense + stat.CorrelationMatrix(&cor, bostonData, nil) + + // Extract just those correlations that are between xdata and ydata. + var corRaw = symView{sym: &cor, i: 0, j: xd, r: xd, c: yd} + + // Note that the strongest correlation between individual variables is 0.91 + // between the 5th variable of xdata (index of accessibility to radial + // highways) and the 3rd variable of ydata (full-value property-tax rate per + // $10000). + fmt.Printf("corRaw = %.4f", mat.Formatted(corRaw, mat.Prefix(" "))) + + // Calculate the canonical correlations. + var cc stat.CC + err := cc.CanonicalCorrelations(xdata, ydata, nil) + if err != nil { + log.Fatal(err) + } + + // Unpack cc. + ccors := cc.CorrsTo(nil) + pVecs := cc.LeftTo(nil, true) + qVecs := cc.RightTo(nil, true) + phiVs := cc.LeftTo(nil, false) + psiVs := cc.RightTo(nil, false) + + // Canonical Correlation Matrix, or the correlations between the sphered + // data. + var corSph mat.Dense + corSph.Clone(pVecs) + col := make([]float64, xd) + for j := 0; j < yd; j++ { + mat.Col(col, j, &corSph) + floats.Scale(ccors[j], col) + corSph.SetCol(j, col) + } + corSph.Product(&corSph, qVecs.T()) + fmt.Printf("\n\ncorSph = %.4f", mat.Formatted(&corSph, mat.Prefix(" "))) + + // Canonical Correlations. Note that the first canonical correlation is + // 0.95, stronger than the greatest correlation in the original data, and + // much stronger than the greatest correlation in the sphered data. + fmt.Printf("\n\nccors = %.4f", ccors) + + // Left and right eigenvectors of the canonical correlation matrix. + fmt.Printf("\n\npVecs = %.4f", mat.Formatted(pVecs, mat.Prefix(" "))) + fmt.Printf("\n\nqVecs = %.4f", mat.Formatted(qVecs, mat.Prefix(" "))) + + // Canonical Correlation Transforms. These can be useful as they represent + // the canonical variables as linear combinations of the original variables. + fmt.Printf("\n\nphiVs = %.4f", mat.Formatted(phiVs, mat.Prefix(" "))) + fmt.Printf("\n\npsiVs = %.4f", mat.Formatted(psiVs, mat.Prefix(" "))) + + // Output: + // corRaw = ⎡-0.2192 0.3527 0.5828 -0.3883⎤ + // ⎢-0.3917 0.6448 0.7208 -0.4837⎥ + // ⎢-0.3022 0.7315 0.6680 -0.4273⎥ + // ⎢ 0.2052 -0.7479 -0.5344 0.2499⎥ + // ⎢-0.2098 0.4560 0.9102 -0.3816⎥ + // ⎢-0.3555 0.2615 0.4609 -0.5078⎥ + // ⎣ 0.1281 -0.2735 -0.4418 0.3335⎦ + // + // corSph = ⎡ 0.0118 0.0525 0.2300 -0.1363⎤ + // ⎢-0.1810 0.3213 0.3814 -0.1412⎥ + // ⎢ 0.0166 0.2241 0.0104 -0.2235⎥ + // ⎢ 0.0346 -0.5481 -0.0034 -0.1994⎥ + // ⎢ 0.0303 -0.0956 0.7152 0.2039⎥ + // ⎢-0.0298 -0.0022 0.0739 -0.3703⎥ + // ⎣-0.1226 -0.0746 -0.3899 0.1541⎦ + // + // ccors = [0.9451 0.6787 0.5714 0.2010] + // + // pVecs = ⎡-0.2574 0.0158 0.2122 -0.0946⎤ + // ⎢-0.4837 0.3837 0.1474 0.6597⎥ + // ⎢-0.0801 0.3494 0.3287 -0.2862⎥ + // ⎢ 0.1278 -0.7337 0.4851 0.2248⎥ + // ⎢-0.6969 -0.4342 -0.3603 0.0291⎥ + // ⎢-0.0991 0.0503 0.6384 0.1022⎥ + // ⎣ 0.4260 0.0323 -0.2290 0.6419⎦ + // + // qVecs = ⎡ 0.0182 -0.1583 -0.0067 -0.9872⎤ + // ⎢-0.2348 0.9483 -0.1462 -0.1554⎥ + // ⎢-0.9701 -0.2406 -0.0252 0.0209⎥ + // ⎣ 0.0593 -0.1330 -0.9889 0.0291⎦ + // + // phiVs = ⎡-0.0027 0.0093 0.0490 -0.0155⎤ + // ⎢-0.0429 -0.0242 0.0361 0.1839⎥ + // ⎢-1.2248 5.6031 5.8094 -4.7927⎥ + // ⎢-0.0044 -0.3424 0.4470 0.1150⎥ + // ⎢-0.0742 -0.1193 -0.1116 0.0022⎥ + // ⎢-0.0233 0.1046 0.3853 -0.0161⎥ + // ⎣ 0.0001 0.0005 -0.0030 0.0082⎦ + // + // psiVs = ⎡ 0.0302 -0.3002 0.0878 -1.9583⎤ + // ⎢-0.0065 0.0392 -0.0118 -0.0061⎥ + // ⎢-0.0052 -0.0046 -0.0023 0.0008⎥ + // ⎣ 0.0020 0.0037 -0.1293 0.1038⎦ +} diff --git a/vendor/gonum.org/v1/gonum/stat/cca_test.go b/vendor/gonum.org/v1/gonum/stat/cca_test.go new file mode 100644 index 00000000..117ae5f2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/cca_test.go @@ -0,0 +1,191 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat_test + +import ( + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +func TestCanonicalCorrelations(t *testing.T) { +tests: + for i, test := range []struct { + xdata mat.Matrix + ydata mat.Matrix + weights []float64 + wantCorrs []float64 + wantpVecs *mat.Dense + wantqVecs *mat.Dense + wantphiVs *mat.Dense + wantpsiVs *mat.Dense + epsilon float64 + }{ + // Test results verified using R. + { // Truncated iris data, Sepal vs Petal measurements. + xdata: mat.NewDense(10, 2, []float64{ + 5.1, 3.5, + 4.9, 3.0, + 4.7, 3.2, + 4.6, 3.1, + 5.0, 3.6, + 5.4, 3.9, + 4.6, 3.4, + 5.0, 3.4, + 4.4, 2.9, + 4.9, 3.1, + }), + ydata: mat.NewDense(10, 2, []float64{ + 1.4, 0.2, + 1.4, 0.2, + 1.3, 0.2, + 1.5, 0.2, + 1.4, 0.2, + 1.7, 0.4, + 1.4, 0.3, + 1.5, 0.2, + 1.4, 0.2, + 1.5, 0.1, + }), + wantCorrs: []float64{0.7250624174504773, 0.5547679185730191}, + wantpVecs: mat.NewDense(2, 2, []float64{ + 0.0765914610875867, 0.9970625597666721, + 0.9970625597666721, -0.0765914610875868, + }), + wantqVecs: mat.NewDense(2, 2, []float64{ + 0.3075184850910837, 0.9515421069649439, + 0.9515421069649439, -0.3075184850910837, + }), + wantphiVs: mat.NewDense(2, 2, []float64{ + -1.9794877596804641, 5.2016325219025124, + 4.5211829944066553, -2.7263663170835697, + }), + wantpsiVs: mat.NewDense(2, 2, []float64{ + -0.0613084818030103, 10.8514169865438941, + 12.7209032660734298, -7.6793888180353775, + }), + epsilon: 1e-12, + }, + // Test results compared to those results presented in examples by + // Koch, Inge. Analysis of multivariate and high-dimensional data. + // Vol. 32. Cambridge University Press, 2013. ISBN: 9780521887939 + { // ASA Car Exposition Data of Ramos and Donoho (1983) + // Displacement, Horsepower, Weight + xdata: carData.Slice(0, 392, 0, 3), + // Acceleration, MPG + ydata: carData.Slice(0, 392, 3, 5), + wantCorrs: []float64{0.8782187384352336, 0.6328187219216761}, + wantpVecs: mat.NewDense(3, 2, []float64{ + 0.3218296374829181, 0.3947540257657075, + 0.4162807660635797, 0.7573719053303306, + 0.8503740401982725, -0.5201509936144236, + }), + wantqVecs: mat.NewDense(2, 2, []float64{ + -0.5161984172278830, -0.8564690269072364, + -0.8564690269072364, 0.5161984172278830, + }), + wantphiVs: mat.NewDense(3, 2, []float64{ + 0.0025033152994308, 0.0047795464118615, + 0.0201923608080173, 0.0409150208725958, + -0.0000247374128745, -0.0026766435161875, + }), + wantpsiVs: mat.NewDense(2, 2, []float64{ + -0.1666196759760772, -0.3637393866139658, + -0.0915512109649727, 0.1077863777929168, + }), + epsilon: 1e-12, + }, + // Test results compared to those results presented in examples by + // Koch, Inge. Analysis of multivariate and high-dimensional data. + // Vol. 32. Cambridge University Press, 2013. ISBN: 9780521887939 + { // Boston Housing Data of Harrison and Rubinfeld (1978) + // Per capita crime rate by town, + // Proportion of non-retail business acres per town, + // Nitric oxide concentration (parts per 10 million), + // Weighted distances to Boston employment centres, + // Index of accessibility to radial highways, + // Pupil-teacher ratio by town, Proportion of blacks by town + xdata: bostonData.Slice(0, 506, 0, 7), + // Average number of rooms per dwelling, + // Proportion of owner-occupied units built prior to 1940, + // Full-value property-tax rate per $10000, + // Median value of owner-occupied homes in $1000s + ydata: bostonData.Slice(0, 506, 7, 11), + wantCorrs: []float64{0.9451239443886021, 0.6786622733370654, 0.5714338361583764, 0.2009739704710440}, + wantpVecs: mat.NewDense(7, 4, []float64{ + -0.2574391924541903, 0.0158477516621194, 0.2122169934631024, -0.0945733803894706, + -0.4836594430018478, 0.3837101908138468, 0.1474448317415911, 0.6597324886718275, + -0.0800776365873296, 0.3493556742809252, 0.3287336458109373, -0.2862040444334655, + 0.1277586360386374, -0.7337427663667596, 0.4851134819037011, 0.2247964865970192, + -0.6969432006136684, -0.4341748776002893, -0.3602872887636357, 0.0290661608626292, + -0.0990903250057199, 0.0503411215453873, 0.6384330631742202, 0.1022367136218303, + 0.4260459963765036, 0.0323334351308141, -0.2289527516030810, 0.6419232947608805, + }), + wantqVecs: mat.NewDense(4, 4, []float64{ + 0.0181660502363264, -0.1583489460479038, -0.0066723577642883, -0.9871935400650649, + -0.2347699045986119, 0.9483314614936594, -0.1462420505631345, -0.1554470767919033, + -0.9700704038477141, -0.2406071741000039, -0.0251838984227037, 0.0209134074358349, + 0.0593000682318482, -0.1330460003097728, -0.9889057151969489, 0.0291161494720761, + }), + wantphiVs: mat.NewDense(7, 4, []float64{ + -0.0027462234108197, 0.0093444513500898, 0.0489643932714296, -0.0154967189805819, + -0.0428564455279537, -0.0241708702119420, 0.0360723472093996, 0.1838983230588095, + -1.2248435648802380, 5.6030921364723980, 5.8094144583797025, -4.7926812190419676, + -0.0043684825094649, -0.3424101164977618, 0.4469961215717917, 0.1150161814353696, + -0.0741534069521954, -0.1193135794923700, -0.1115518305471460, 0.0021638758323088, + -0.0233270323101624, 0.1046330818178399, 0.3853045975077387, -0.0160927870102877, + 0.0001293051387859, 0.0004540746921446, -0.0030296315865440, 0.0081895477974654, + }), + wantpsiVs: mat.NewDense(4, 4, []float64{ + 0.0301593362017375, -0.3002219289647127, 0.0878217377593682, -1.9583226531517062, + -0.0065483104073892, 0.0392212086716247, -0.0117570776209991, -0.0061113064481860, + -0.0052075523350125, -0.0045770200452960, -0.0022762313289592, 0.0008441873006821, + 0.0020111735096327, 0.0037352799829930, -0.1292578071621794, 0.1037709056329765, + }), + epsilon: 1e-12, + }, + } { + var cc stat.CC + var corrs []float64 + var pVecs, qVecs *mat.Dense + var phiVs, psiVs *mat.Dense + for j := 0; j < 2; j++ { + err := cc.CanonicalCorrelations(test.xdata, test.ydata, test.weights) + if err != nil { + t.Errorf("%d use %d: unexpected error: %v", i, j, err) + continue tests + } + + corrs = cc.CorrsTo(corrs) + pVecs = cc.LeftTo(pVecs, true) + qVecs = cc.RightTo(qVecs, true) + phiVs = cc.LeftTo(phiVs, false) + psiVs = cc.RightTo(psiVs, false) + + if !floats.EqualApprox(corrs, test.wantCorrs, test.epsilon) { + t.Errorf("%d use %d: unexpected variance result got:%v, want:%v", + i, j, corrs, test.wantCorrs) + } + if !mat.EqualApprox(pVecs, test.wantpVecs, test.epsilon) { + t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", + i, j, mat.Formatted(pVecs), mat.Formatted(test.wantpVecs)) + } + if !mat.EqualApprox(qVecs, test.wantqVecs, test.epsilon) { + t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", + i, j, mat.Formatted(qVecs), mat.Formatted(test.wantqVecs)) + } + if !mat.EqualApprox(phiVs, test.wantphiVs, test.epsilon) { + t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", + i, j, mat.Formatted(phiVs), mat.Formatted(test.wantphiVs)) + } + if !mat.EqualApprox(psiVs, test.wantpsiVs, test.epsilon) { + t.Errorf("%d use %d: unexpected CCA result got:\n%v\nwant:\n%v", + i, j, mat.Formatted(psiVs), mat.Formatted(test.wantpsiVs)) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/combin/combin.go b/vendor/gonum.org/v1/gonum/stat/combin/combin.go new file mode 100644 index 00000000..d4e1f6e6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/combin/combin.go @@ -0,0 +1,181 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package combin + +import "math" + +const ( + badNegInput = "combin: negative input" + badSetSize = "combin: n < k" + badInput = "combin: wrong input slice length" +) + +// Binomial returns the binomial coefficient of (n,k), also commonly referred to +// as "n choose k". +// +// The binomial coefficient, C(n,k), is the number of unordered combinations of +// k elements in a set that is n elements big, and is defined as +// +// C(n,k) = n!/((n-k)!k!) +// +// n and k must be non-negative with n >= k, otherwise Binomial will panic. +// No check is made for overflow. +func Binomial(n, k int) int { + if n < 0 || k < 0 { + panic(badNegInput) + } + if n < k { + panic(badSetSize) + } + // (n,k) = (n, n-k) + if k > n/2 { + k = n - k + } + b := 1 + for i := 1; i <= k; i++ { + b = (n - k + i) * b / i + } + return b +} + +// GeneralizedBinomial returns the generalized binomial coefficient of (n, k), +// defined as +// Γ(n+1) / (Γ(k+1) Γ(n-k+1)) +// where Γ is the Gamma function. GeneralizedBinomial is useful for continuous +// relaxations of the binomial coefficient, or when the binomial coefficient value +// may overflow int. In the latter case, one may use math/big for an exact +// computation. +// +// n and k must be non-negative with n >= k, otherwise GeneralizedBinomial will panic. +func GeneralizedBinomial(n, k float64) float64 { + return math.Exp(LogGeneralizedBinomial(n, k)) +} + +// LogGeneralizedBinomial returns the log of the generalized binomial coefficient. +// See GeneralizedBinomial for more information. +func LogGeneralizedBinomial(n, k float64) float64 { + if n < 0 || k < 0 { + panic(badNegInput) + } + if n < k { + panic(badSetSize) + } + a, _ := math.Lgamma(n + 1) + b, _ := math.Lgamma(k + 1) + c, _ := math.Lgamma(n - k + 1) + return a - b - c +} + +// CombinationGenerator generates combinations iteratively. Combinations may be +// called to generate all combinations collectively. +type CombinationGenerator struct { + n int + k int + previous []int + remaining int +} + +// NewCombinationGenerator returns a CombinationGenerator for generating the +// combinations of k elements from a set of size n. +// +// n and k must be non-negative with n >= k, otherwise NewCombinationGenerator +// will panic. +func NewCombinationGenerator(n, k int) *CombinationGenerator { + return &CombinationGenerator{ + n: n, + k: k, + remaining: Binomial(n, k), + } +} + +// Next advances the iterator if there are combinations remaining to be generated, +// and returns false if all combinations have been generated. Next must be called +// to initialize the first value before calling Combination or Combination will +// panic. The value returned by Combination is only changed during calls to Next. +func (c *CombinationGenerator) Next() bool { + if c.remaining <= 0 { + // Next is called before combination, so c.remaining is set to zero before + // Combination is called. Thus, Combination cannot panic on zero, and a + // second sentinel value is needed. + c.remaining = -1 + return false + } + if c.previous == nil { + c.previous = make([]int, c.k) + for i := range c.previous { + c.previous[i] = i + } + } else { + nextCombination(c.previous, c.n, c.k) + } + c.remaining-- + return true +} + +// Combination generates the next combination. If next is non-nil, it must have +// length k and the result will be stored in-place into combination. If combination +// is nil a new slice will be allocated and returned. If all of the combinations +// have already been constructed (Next() returns false), Combination will panic. +// +// Next must be called to initialize the first value before calling Combination +// or Combination will panic. The value returned by Combination is only changed +// during calls to Next. +func (c *CombinationGenerator) Combination(combination []int) []int { + if c.remaining == -1 { + panic("combin: all combinations have been generated") + } + if c.previous == nil { + panic("combin: Combination called before Next") + } + if combination == nil { + combination = make([]int, c.k) + } + if len(combination) != c.k { + panic(badInput) + } + copy(combination, c.previous) + return combination +} + +// Combinations generates all of the combinations of k elements from a +// set of size n. The returned slice has length Binomial(n,k) and each inner slice +// has length k. +// +// n and k must be non-negative with n >= k, otherwise Combinations will panic. +// +// CombinationGenerator may alternatively be used to generate the combinations +// iteratively instead of collectively. +func Combinations(n, k int) [][]int { + combins := Binomial(n, k) + data := make([][]int, combins) + if len(data) == 0 { + return data + } + data[0] = make([]int, k) + for i := range data[0] { + data[0][i] = i + } + for i := 1; i < combins; i++ { + next := make([]int, k) + copy(next, data[i-1]) + nextCombination(next, n, k) + data[i] = next + } + return data +} + +// nextCombination generates the combination after s, overwriting the input value. +func nextCombination(s []int, n, k int) { + for j := k - 1; j >= 0; j-- { + if s[j] == n+j-k { + continue + } + s[j]++ + for l := j + 1; l < k; l++ { + s[l] = s[j] + l - j + } + break + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/combin/combin_test.go b/vendor/gonum.org/v1/gonum/stat/combin/combin_test.go new file mode 100644 index 00000000..8226a675 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/combin/combin_test.go @@ -0,0 +1,181 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package combin + +import ( + "math/big" + "testing" + + "gonum.org/v1/gonum/floats" +) + +// intSosMatch returns true if the two slices of slices are equal. +func intSosMatch(a, b [][]int) bool { + if len(a) != len(b) { + return false + } + for i, s := range a { + if len(s) != len(b[i]) { + return false + } + for j, v := range s { + if v != b[i][j] { + return false + } + } + } + return true +} + +var binomialTests = []struct { + n, k, ans int +}{ + {0, 0, 1}, + {5, 0, 1}, + {5, 1, 5}, + {5, 2, 10}, + {5, 3, 10}, + {5, 4, 5}, + {5, 5, 1}, + + {6, 0, 1}, + {6, 1, 6}, + {6, 2, 15}, + {6, 3, 20}, + {6, 4, 15}, + {6, 5, 6}, + {6, 6, 1}, + + {20, 0, 1}, + {20, 1, 20}, + {20, 2, 190}, + {20, 3, 1140}, + {20, 4, 4845}, + {20, 5, 15504}, + {20, 6, 38760}, + {20, 7, 77520}, + {20, 8, 125970}, + {20, 9, 167960}, + {20, 10, 184756}, + {20, 11, 167960}, + {20, 12, 125970}, + {20, 13, 77520}, + {20, 14, 38760}, + {20, 15, 15504}, + {20, 16, 4845}, + {20, 17, 1140}, + {20, 18, 190}, + {20, 19, 20}, + {20, 20, 1}, +} + +func TestBinomial(t *testing.T) { + for cas, test := range binomialTests { + ans := Binomial(test.n, test.k) + if ans != test.ans { + t.Errorf("Case %v: Binomial mismatch. Got %v, want %v.", cas, ans, test.ans) + } + } + var ( + n = 61 + want big.Int + got big.Int + ) + for k := 0; k <= n; k++ { + want.Binomial(int64(n), int64(k)) + got.SetInt64(int64(Binomial(n, k))) + if want.Cmp(&got) != 0 { + t.Errorf("Case n=%v,k=%v: Binomial mismatch for large n. Got %v, want %v.", n, k, got, want) + } + } +} + +func TestGeneralizedBinomial(t *testing.T) { + for cas, test := range binomialTests { + ans := GeneralizedBinomial(float64(test.n), float64(test.k)) + if !floats.EqualWithinAbsOrRel(ans, float64(test.ans), 1e-14, 1e-14) { + t.Errorf("Case %v: Binomial mismatch. Got %v, want %v.", cas, ans, test.ans) + } + } +} + +func TestCombinations(t *testing.T) { + for cas, test := range []struct { + n, k int + data [][]int + }{ + { + n: 1, + k: 1, + data: [][]int{{0}}, + }, + { + n: 2, + k: 1, + data: [][]int{{0}, {1}}, + }, + { + n: 2, + k: 2, + data: [][]int{{0, 1}}, + }, + { + n: 3, + k: 1, + data: [][]int{{0}, {1}, {2}}, + }, + { + n: 3, + k: 2, + data: [][]int{{0, 1}, {0, 2}, {1, 2}}, + }, + { + n: 3, + k: 3, + data: [][]int{{0, 1, 2}}, + }, + { + n: 4, + k: 1, + data: [][]int{{0}, {1}, {2}, {3}}, + }, + { + n: 4, + k: 2, + data: [][]int{{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}}, + }, + { + n: 4, + k: 3, + data: [][]int{{0, 1, 2}, {0, 1, 3}, {0, 2, 3}, {1, 2, 3}}, + }, + { + n: 4, + k: 4, + data: [][]int{{0, 1, 2, 3}}, + }, + } { + data := Combinations(test.n, test.k) + if !intSosMatch(data, test.data) { + t.Errorf("Cas %v: Generated combinations mismatch. Got %v, want %v.", cas, data, test.data) + } + } +} + +func TestCombinationGenerator(t *testing.T) { + for n := 0; n <= 10; n++ { + for k := 1; k <= n; k++ { + combinations := Combinations(n, k) + cg := NewCombinationGenerator(n, k) + genCombs := make([][]int, 0, len(combinations)) + for cg.Next() { + genCombs = append(genCombs, cg.Combination(nil)) + } + if !intSosMatch(combinations, genCombs) { + t.Errorf("Combinations and generated combinations do not match. n = %v, k = %v", n, k) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/combin/doc.go b/vendor/gonum.org/v1/gonum/stat/combin/doc.go new file mode 100644 index 00000000..935ccdb8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/combin/doc.go @@ -0,0 +1,7 @@ +// 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 combin implements routines involving combinatorics (permutations, +// combinations, etc.). +package combin // import "gonum.org/v1/gonum/stat/combin" diff --git a/vendor/gonum.org/v1/gonum/stat/distmat/doc.go b/vendor/gonum.org/v1/gonum/stat/distmat/doc.go new file mode 100644 index 00000000..baca067d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmat/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package distmat provides probability distributions over matrices. +package distmat // import "gonum.org/v1/gonum/stat/distmat" diff --git a/vendor/gonum.org/v1/gonum/stat/distmat/general.go b/vendor/gonum.org/v1/gonum/stat/distmat/general.go new file mode 100644 index 00000000..21bbc95d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmat/general.go @@ -0,0 +1,7 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmat + +var badDim = "distmat: dimension mismatch" diff --git a/vendor/gonum.org/v1/gonum/stat/distmat/wishart.go b/vendor/gonum.org/v1/gonum/stat/distmat/wishart.go new file mode 100644 index 00000000..97992ce0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmat/wishart.go @@ -0,0 +1,209 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmat + +import ( + "math" + "math/rand" + "sync" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/mathext" + "gonum.org/v1/gonum/stat/distuv" +) + +// Wishart is a distribution over d×d positive symmetric definite matrices. It +// is parametrized by a scalar degrees of freedom parameter ν and a d×d positive +// definite matrix V. +// +// The Wishart PDF is given by +// p(X) = [|X|^((ν-d-1)/2) * exp(-tr(V^-1 * X)/2)] / [2^(ν*d/2) * |V|^(ν/2) * Γ_d(ν/2)] +// where X is a d×d PSD matrix, ν > d-1, |·| denotes the determinant, tr is the +// trace and Γ_d is the multivariate gamma function. +// +// See https://en.wikipedia.org/wiki/Wishart_distribution for more information. +type Wishart struct { + nu float64 + src *rand.Rand + + dim int + cholv mat.Cholesky + logdetv float64 + upper mat.TriDense + + once sync.Once + v *mat.SymDense // only stored if needed +} + +// NewWishart returns a new Wishart distribution with the given shape matrix and +// degrees of freedom parameter. NewWishart returns whether the creation was +// successful. +// +// NewWishart panics if nu <= d - 1 where d is the order of v. +func NewWishart(v mat.Symmetric, nu float64, src *rand.Rand) (*Wishart, bool) { + dim := v.Symmetric() + if nu <= float64(dim-1) { + panic("wishart: nu must be greater than dim-1") + } + var chol mat.Cholesky + ok := chol.Factorize(v) + if !ok { + return nil, false + } + + var u mat.TriDense + chol.UTo(&u) + + w := &Wishart{ + nu: nu, + src: src, + + dim: dim, + cholv: chol, + logdetv: chol.LogDet(), + upper: u, + } + return w, true +} + +// MeanSym returns the mean matrix of the distribution as a symmetric matrix. +// If x is nil, a new matrix is allocated and returned. If x is not nil, the +// result is stored in-place into x and MeanSym will panic if the order of x +// is not equal to the order of the receiver. +func (w *Wishart) MeanSym(x *mat.SymDense) *mat.SymDense { + if x == nil { + x = mat.NewSymDense(w.dim, nil) + } + d := x.Symmetric() + if d != w.dim { + panic(badDim) + } + w.setV() + x.CopySym(w.v) + x.ScaleSym(w.nu, x) + return x +} + +// ProbSym returns the probability of the symmetric matrix x. If x is not positive +// definite (the Cholesky decomposition fails), it has 0 probability. +func (w *Wishart) ProbSym(x mat.Symmetric) float64 { + return math.Exp(w.LogProbSym(x)) +} + +// LogProbSym returns the log of the probability of the input symmetric matrix. +// +// LogProbSym returns -∞ if the input matrix is not positive definite (the Cholesky +// decomposition fails). +func (w *Wishart) LogProbSym(x mat.Symmetric) float64 { + dim := x.Symmetric() + if dim != w.dim { + panic(badDim) + } + var chol mat.Cholesky + ok := chol.Factorize(x) + if !ok { + return math.Inf(-1) + } + return w.logProbSymChol(&chol) +} + +// LogProbSymChol returns the log of the probability of the input symmetric matrix +// given its Cholesky decomposition. +func (w *Wishart) LogProbSymChol(cholX *mat.Cholesky) float64 { + dim := cholX.Size() + if dim != w.dim { + panic(badDim) + } + return w.logProbSymChol(cholX) +} + +func (w *Wishart) logProbSymChol(cholX *mat.Cholesky) float64 { + // The PDF is + // p(X) = [|X|^((ν-d-1)/2) * exp(-tr(V^-1 * X)/2)] / [2^(ν*d/2) * |V|^(ν/2) * Γ_d(ν/2)] + // The LogPDF is thus + // (ν-d-1)/2 * log(|X|) - tr(V^-1 * X)/2 - (ν*d/2)*log(2) - ν/2 * log(|V|) - log(Γ_d(ν/2)) + logdetx := cholX.LogDet() + + // Compute tr(V^-1 * X), using the fact that X = U^T * U. + var u mat.TriDense + cholX.UTo(&u) + + var vinvx mat.Dense + err := w.cholv.Solve(&vinvx, u.T()) + if err != nil { + return math.Inf(-1) + } + vinvx.Mul(&vinvx, &u) + tr := mat.Trace(&vinvx) + + fnu := float64(w.nu) + fdim := float64(w.dim) + + return 0.5*((fnu-fdim-1)*logdetx-tr-fnu*fdim*math.Ln2-fnu*w.logdetv) - mathext.MvLgamma(0.5*fnu, w.dim) +} + +// RandSym generates a random symmetric matrix from the distribution. +func (w *Wishart) RandSym(x *mat.SymDense) *mat.SymDense { + if x == nil { + x = &mat.SymDense{} + } + var c mat.Cholesky + w.RandChol(&c) + c.To(x) + return x +} + +// RandChol generates the Cholesky decomposition of a random matrix from the distribution. +func (w *Wishart) RandChol(c *mat.Cholesky) *mat.Cholesky { + // TODO(btracey): Modify the code if the underlying data from c is exposed + // to avoid the dim^2 allocation here. + + // Use the Bartlett Decomposition, which says that + // X ~ L A A^T L^T + // Where A is a lower triangular matrix in which the diagonal of A is + // generated from the square roots of χ^2 random variables, and the + // off-diagonals are generated from standard normal variables. + // The above gives the cholesky decomposition of X, where L_x = L A. + // + // mat64 works with the upper triagular decomposition, so we would like to do + // the same. We can instead say that + // U_x = L_x^T = (L * A)^T = A^T * L^T = A^T * U + // Instead, generate A^T, by using the procedure above, except as an upper + // triangular matrix. + norm := distuv.Normal{ + Mu: 0, + Sigma: 1, + Source: w.src, + } + + t := mat.NewTriDense(w.dim, mat.Upper, nil) + for i := 0; i < w.dim; i++ { + v := distuv.ChiSquared{ + K: w.nu - float64(i), + Src: w.src, + }.Rand() + t.SetTri(i, i, math.Sqrt(v)) + } + for i := 0; i < w.dim; i++ { + for j := i + 1; j < w.dim; j++ { + t.SetTri(i, j, norm.Rand()) + } + } + + t.MulTri(t, &w.upper) + if c == nil { + c = &mat.Cholesky{} + } + c.SetFromU(t) + return c +} + +// setV computes and stores the covariance matrix of the distribution. +func (w *Wishart) setV() { + w.once.Do(func() { + w.v = mat.NewSymDense(w.dim, nil) + w.cholv.To(w.v) + }) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmat/wishart_test.go b/vendor/gonum.org/v1/gonum/stat/distmat/wishart_test.go new file mode 100644 index 00000000..96350c64 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmat/wishart_test.go @@ -0,0 +1,129 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmat + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +func TestWishart(t *testing.T) { + for c, test := range []struct { + v *mat.SymDense + nu float64 + xs []*mat.SymDense + lps []float64 + }{ + // Logprob data compared with scipy. + { + v: mat.NewSymDense(2, []float64{1, 0, 0, 1}), + nu: 4, + xs: []*mat.SymDense{ + mat.NewSymDense(2, []float64{0.9, 0.1, 0.1, 0.9}), + }, + lps: []float64{-4.2357432031863409}, + }, + { + v: mat.NewSymDense(2, []float64{0.8, -0.2, -0.2, 0.7}), + nu: 5, + xs: []*mat.SymDense{ + mat.NewSymDense(2, []float64{0.9, 0.1, 0.1, 0.9}), + mat.NewSymDense(2, []float64{0.3, -0.1, -0.1, 0.7}), + }, + lps: []float64{-4.2476495605333575, -4.9993285370378633}, + }, + { + v: mat.NewSymDense(3, []float64{0.8, 0.3, 0.1, 0.3, 0.7, -0.1, 0.1, -0.1, 7}), + nu: 5, + xs: []*mat.SymDense{ + mat.NewSymDense(3, []float64{1, 0.2, -0.3, 0.2, 0.6, -0.2, -0.3, -0.2, 6}), + }, + lps: []float64{-11.010982249229421}, + }, + } { + w, ok := NewWishart(test.v, test.nu, nil) + if !ok { + panic("bad test") + } + for i, x := range test.xs { + lp := w.LogProbSym(x) + + var chol mat.Cholesky + ok := chol.Factorize(x) + if !ok { + panic("bad test") + } + lpc := w.LogProbSymChol(&chol) + + if math.Abs(lp-lpc) > 1e-14 { + t.Errorf("Case %d, test %d: probability mismatch between chol and not", c, i) + } + if !floats.EqualWithinAbsOrRel(lp, test.lps[i], 1e-14, 1e-14) { + t.Errorf("Case %d, test %d: got %v, want %v", c, i, lp, test.lps[i]) + } + } + + ch := w.RandChol(nil) + w.RandChol(ch) + + s := w.RandSym(nil) + w.RandSym(s) + + } +} + +func TestWishartRand(t *testing.T) { + for c, test := range []struct { + v *mat.SymDense + nu float64 + samples int + tol float64 + }{ + { + v: mat.NewSymDense(2, []float64{0.8, -0.2, -0.2, 0.7}), + nu: 5, + samples: 30000, + tol: 3e-2, + }, + { + v: mat.NewSymDense(3, []float64{0.8, 0.3, 0.1, 0.3, 0.7, -0.1, 0.1, -0.1, 7}), + nu: 5, + samples: 30000, + tol: 3e-2, + }, + { + v: mat.NewSymDense(4, []float64{ + 0.8, 0.3, 0.1, -0.2, + 0.3, 0.7, -0.1, 0.4, + 0.1, -0.1, 7, 1, + -0.2, -0.1, 1, 6}), + nu: 6, + samples: 30000, + tol: 1e-1, + }, + } { + rnd := rand.New(rand.NewSource(1)) + dim := test.v.Symmetric() + w, ok := NewWishart(test.v, test.nu, rnd) + if !ok { + panic("bad test") + } + mean := mat.NewSymDense(dim, nil) + x := mat.NewSymDense(dim, nil) + for i := 0; i < test.samples; i++ { + w.RandSym(x) + x.ScaleSym(1/float64(test.samples), x) + mean.AddSym(mean, x) + } + trueMean := w.MeanSym(nil) + if !mat.EqualApprox(trueMean, mean, test.tol) { + t.Errorf("Case %d: Mismatch between estimated and true mean. Got\n%0.4v\nWant\n%0.4v\n", c, mat.Formatted(mean), mat.Formatted(trueMean)) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/dirichlet.go b/vendor/gonum.org/v1/gonum/stat/distmv/dirichlet.go new file mode 100644 index 00000000..fbf2128f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/dirichlet.go @@ -0,0 +1,144 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat/distuv" +) + +// Dirichlet implements the Dirichlet probability distribution. +// +// The Dirichlet distribution is a continuous probability distribution that +// generates elements over the probability simplex, i.e. ||x||_1 = 1. The Dirichlet +// distribution is the conjugate prior to the categorical distribution and the +// multivariate version of the beta distribution. The probability of a point x is +// 1/Beta(α) \prod_i x_i^(α_i - 1) +// where Beta(α) is the multivariate Beta function (see the mathext package). +// +// For more information see https://en.wikipedia.org/wiki/Dirichlet_distribution +type Dirichlet struct { + alpha []float64 + dim int + src *rand.Rand + + lbeta float64 + sumAlpha float64 +} + +// NewDirichlet creates a new dirichlet distribution with the given parameters alpha. +// NewDirichlet will panic if len(alpha) == 0, or if any alpha is <= 0. +func NewDirichlet(alpha []float64, src *rand.Rand) *Dirichlet { + dim := len(alpha) + if dim == 0 { + panic(badZeroDimension) + } + for _, v := range alpha { + if v <= 0 { + panic("dirichlet: non-positive alpha") + } + } + a := make([]float64, len(alpha)) + copy(a, alpha) + d := &Dirichlet{ + alpha: a, + dim: dim, + src: src, + } + d.lbeta, d.sumAlpha = d.genLBeta(a) + return d +} + +// CovarianceMatrix returns the covariance matrix of the distribution. Upon +// return, the value at element {i, j} of the covariance matrix is equal to +// the covariance of the i^th and j^th variables. +// covariance(i, j) = E[(x_i - E[x_i])(x_j - E[x_j])] +// If the input matrix is nil a new matrix is allocated, otherwise the result +// is stored in-place into the input. +func (d *Dirichlet) CovarianceMatrix(cov *mat.SymDense) *mat.SymDense { + if cov == nil { + cov = mat.NewSymDense(d.Dim(), nil) + } else if cov.Symmetric() == 0 { + *cov = *(cov.GrowSquare(d.dim).(*mat.SymDense)) + } else if cov.Symmetric() != d.dim { + panic("normal: input matrix size mismatch") + } + scale := 1 / (d.sumAlpha * d.sumAlpha * (d.sumAlpha + 1)) + for i := 0; i < d.dim; i++ { + ai := d.alpha[i] + v := ai * (d.sumAlpha - ai) * scale + cov.SetSym(i, i, v) + for j := i + 1; j < d.dim; j++ { + aj := d.alpha[j] + v := -ai * aj * scale + cov.SetSym(i, j, v) + } + } + return cov +} + +// genLBeta computes the generalized LBeta function. +func (d *Dirichlet) genLBeta(alpha []float64) (lbeta, sumAlpha float64) { + for _, alpha := range d.alpha { + lg, _ := math.Lgamma(alpha) + lbeta += lg + sumAlpha += alpha + } + lg, _ := math.Lgamma(sumAlpha) + return lbeta - lg, sumAlpha +} + +// Dim returns the dimension of the distribution. +func (d *Dirichlet) Dim() int { + return d.dim +} + +// LogProb computes the log of the pdf of the point x. +// +// It does not check that ||x||_1 = 1. +func (d *Dirichlet) LogProb(x []float64) float64 { + dim := d.dim + if len(x) != dim { + panic(badSizeMismatch) + } + var lprob float64 + for i, x := range x { + lprob += (d.alpha[i] - 1) * math.Log(x) + } + lprob -= d.lbeta + return lprob +} + +// Mean returns the mean of the probability distribution at x. If the +// input argument is nil, a new slice will be allocated, otherwise the result +// will be put in-place into the receiver. +func (d *Dirichlet) Mean(x []float64) []float64 { + x = reuseAs(x, d.dim) + copy(x, d.alpha) + floats.Scale(1/d.sumAlpha, x) + return x +} + +// Prob computes the value of the probability density function at x. +func (d *Dirichlet) Prob(x []float64) float64 { + return math.Exp(d.LogProb(x)) +} + +// Rand generates a random number according to the distributon. +// If the input slice is nil, new memory is allocated, otherwise the result is stored +// in place. +func (d *Dirichlet) Rand(x []float64) []float64 { + x = reuseAs(x, d.dim) + for i := range x { + x[i] = distuv.Gamma{Alpha: d.alpha[i], Beta: 1, Source: d.src}.Rand() + } + sum := floats.Sum(x) + floats.Scale(1/sum, x) + return x +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/dirichlet_test.go b/vendor/gonum.org/v1/gonum/stat/distmv/dirichlet_test.go new file mode 100644 index 00000000..43f77007 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/dirichlet_test.go @@ -0,0 +1,67 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/mat" +) + +func TestDirichlet(t *testing.T) { + // Data from Scipy. + for cas, test := range []struct { + Dir *Dirichlet + x []float64 + prob float64 + }{ + { + NewDirichlet([]float64{1, 1, 1}, nil), + []float64{0.2, 0.3, 0.5}, + 2.0, + }, + { + NewDirichlet([]float64{0.6, 10, 8.7}, nil), + []float64{0.2, 0.3, 0.5}, + 0.24079612737071665, + }, + } { + p := test.Dir.Prob(test.x) + if math.Abs(p-test.prob) > 1e-14 { + t.Errorf("Probablility mismatch. Case %v. Got %v, want %v", cas, p, test.prob) + } + } + + rnd := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + Dir *Dirichlet + }{ + { + NewDirichlet([]float64{1, 1, 1}, rnd), + }, + { + NewDirichlet([]float64{2, 3}, rnd), + }, + { + NewDirichlet([]float64{0.2, 0.3}, rnd), + }, + { + NewDirichlet([]float64{0.2, 4}, rnd), + }, + { + NewDirichlet([]float64{0.1, 4, 20}, rnd), + }, + } { + const n = 1e5 + d := test.Dir + dim := d.Dim() + x := mat.NewDense(n, dim, nil) + generateSamples(x, d) + checkMean(t, cas, x, d, 1e-2) + checkCov(t, cas, x, d, 1e-2) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/doc.go b/vendor/gonum.org/v1/gonum/stat/distmv/doc.go new file mode 100644 index 00000000..c126be97 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package distmv provides multivariate random distribution types. +package distmv // import "gonum.org/v1/gonum/stat/distmv" diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/general.go b/vendor/gonum.org/v1/gonum/stat/distmv/general.go new file mode 100644 index 00000000..f473efdf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/general.go @@ -0,0 +1,30 @@ +// 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 distmv + +var ( + badQuantile = "distmv: quantile not between 0 and 1" + badReceiver = "distmv: input slice is not nil or the correct length" + badSizeMismatch = "distmv: size mismatch" + badZeroDimension = "distmv: zero dimensional input" + nonPosDimension = "distmv: non-positive dimension input" +) + +const logTwoPi = 1.8378770664093454835606594728112352797227949472755668 + +// useAs gets a slice of size n. If len(x) == n, x is returned, if len(x) == 0 +// then a slice is returned of length n. +func reuseAs(x []float64, n int) []float64 { + if len(x) == n { + return x + } + if len(x) == 0 { + if cap(x) >= n { + return x[:n] + } + return make([]float64, n) + } + panic(badReceiver) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/general_test.go b/vendor/gonum.org/v1/gonum/stat/distmv/general_test.go new file mode 100644 index 00000000..05e65f7b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/general_test.go @@ -0,0 +1,96 @@ +// 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 distmv + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +type prober interface { + Prob(x []float64) float64 + LogProb(x []float64) float64 +} + +type probCase struct { + dist prober + loc []float64 + logProb float64 +} + +func testProbability(t *testing.T, cases []probCase) { + for _, test := range cases { + logProb := test.dist.LogProb(test.loc) + if math.Abs(logProb-test.logProb) > 1e-14 { + t.Errorf("LogProb mismatch: want: %v, got: %v", test.logProb, logProb) + } + prob := test.dist.Prob(test.loc) + if math.Abs(prob-math.Exp(test.logProb)) > 1e-14 { + t.Errorf("Prob mismatch: want: %v, got: %v", math.Exp(test.logProb), prob) + } + } +} + +func generateSamples(x *mat.Dense, r Rander) { + n, _ := x.Dims() + for i := 0; i < n; i++ { + r.Rand(x.RawRowView(i)) + } +} + +type Meaner interface { + Mean([]float64) []float64 +} + +func checkMean(t *testing.T, cas int, x *mat.Dense, m Meaner, tol float64) { + mean := m.Mean(nil) + + // Check that the answer is identical when using nil or non-nil. + mean2 := make([]float64, len(mean)) + m.Mean(mean2) + if !floats.Equal(mean, mean2) { + t.Errorf("Mean mismatch when providing nil and slice. Case %v", cas) + } + + // Check that the mean matches the samples. + r, _ := x.Dims() + col := make([]float64, r) + meanEst := make([]float64, len(mean)) + for i := range meanEst { + meanEst[i] = stat.Mean(mat.Col(col, i, x), nil) + } + if !floats.EqualApprox(mean, meanEst, tol) { + t.Errorf("Returned mean and sample mean mismatch. Case %v. Empirical %v, returned %v", cas, meanEst, mean) + } +} + +type Cover interface { + CovarianceMatrix(*mat.SymDense) *mat.SymDense +} + +func checkCov(t *testing.T, cas int, x *mat.Dense, c Cover, tol float64) { + cov := c.CovarianceMatrix(nil) + n := cov.Symmetric() + cov2 := mat.NewSymDense(n, nil) + c.CovarianceMatrix(cov2) + if !mat.Equal(cov, cov2) { + t.Errorf("Cov mismatch when providing nil and matrix. Case %v", cas) + } + var cov3 mat.SymDense + c.CovarianceMatrix(&cov3) + if !mat.Equal(cov, &cov3) { + t.Errorf("Cov mismatch when providing zero matrix. Case %v", cas) + } + + // Check that the covariance matrix matches the samples + covEst := stat.CovarianceMatrix(nil, x, nil) + if !mat.EqualApprox(covEst, cov, tol) { + t.Errorf("Return cov and sample cov mismatch. Cas %v.\nGot:\n%0.4v\nWant:\n%0.4v", cas, mat.Formatted(cov), mat.Formatted(covEst)) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/interfaces.go b/vendor/gonum.org/v1/gonum/stat/distmv/interfaces.go new file mode 100644 index 00000000..57411933 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/interfaces.go @@ -0,0 +1,33 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +// Quantiler returns the multi-dimensional inverse cumulative distribution function. +// len(x) must equal len(p), and if x is non-nil, len(x) must also equal len(p). +// If x is nil, a new slice will be allocated and returned, otherwise the quantile +// will be stored in-place into x. All of the values of p must be between 0 and 1, +// or Quantile will panic. +type Quantiler interface { + Quantile(x, p []float64) []float64 +} + +// LogProber computes the log of the probability of the point x. +type LogProber interface { + LogProb(x []float64) float64 +} + +// Rander generates a random number according to the distributon. +// If the input is non-nil, len(x) must equal len(p) and the dimension of the distribution, +// otherwise Quantile will panic. +// If the input is nil, a new slice will be allocated and returned. +type Rander interface { + Rand(x []float64) []float64 +} + +// RandLogProber is both a Rander and a LogProber. +type RandLogProber interface { + Rander + LogProber +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/normal.go b/vendor/gonum.org/v1/gonum/stat/distmv/normal.go new file mode 100644 index 00000000..1d5098fd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/normal.go @@ -0,0 +1,345 @@ +// 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 distmv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" + "gonum.org/v1/gonum/stat/distuv" +) + +var ( + badInputLength = "distmv: input slice length mismatch" +) + +// Normal is a multivariate normal distribution (also known as the multivariate +// Gaussian distribution). Its pdf in k dimensions is given by +// (2 π)^(-k/2) |Σ|^(-1/2) exp(-1/2 (x-μ)'Σ^-1(x-μ)) +// where μ is the mean vector and Σ the covariance matrix. Σ must be symmetric +// and positive definite. Use NewNormal to construct. +type Normal struct { + mu []float64 + + sigma mat.SymDense + + chol mat.Cholesky + lower mat.TriDense + logSqrtDet float64 + dim int + + src *rand.Rand +} + +// NewNormal creates a new Normal with the given mean and covariance matrix. +// NewNormal panics if len(mu) == 0, or if len(mu) != sigma.N. If the covariance +// matrix is not positive-definite, the returned boolean is false. +func NewNormal(mu []float64, sigma mat.Symmetric, src *rand.Rand) (*Normal, bool) { + if len(mu) == 0 { + panic(badZeroDimension) + } + dim := sigma.Symmetric() + if dim != len(mu) { + panic(badSizeMismatch) + } + n := &Normal{ + src: src, + dim: dim, + mu: make([]float64, dim), + } + copy(n.mu, mu) + ok := n.chol.Factorize(sigma) + if !ok { + return nil, false + } + n.sigma = *mat.NewSymDense(dim, nil) + n.sigma.CopySym(sigma) + n.chol.LTo(&n.lower) + n.logSqrtDet = 0.5 * n.chol.LogDet() + return n, true +} + +// NewNormalChol creates a new Normal distribution with the given mean and +// covariance matrix represented by its Cholesky decomposition. NewNormalChol +// panics if len(mu) is not equal to chol.Size(). +func NewNormalChol(mu []float64, chol *mat.Cholesky, src *rand.Rand) *Normal { + dim := len(mu) + if dim != chol.Size() { + panic(badSizeMismatch) + } + n := &Normal{ + src: src, + dim: dim, + mu: make([]float64, dim), + } + n.chol.Clone(chol) + copy(n.mu, mu) + chol.LTo(&n.lower) + n.logSqrtDet = 0.5 * n.chol.LogDet() + return n +} + +// NewNormalPrecision creates a new Normal distribution with the given mean and +// precision matrix (inverse of the covariance matrix). NewNormalPrecision +// panics if len(mu) is not equal to prec.Symmetric(). If the precision matrix +// is not positive-definite, NewNormalPrecision returns nil for norm and false +// for ok. +func NewNormalPrecision(mu []float64, prec *mat.SymDense, src *rand.Rand) (norm *Normal, ok bool) { + if len(mu) == 0 { + panic(badZeroDimension) + } + dim := prec.Symmetric() + if dim != len(mu) { + panic(badSizeMismatch) + } + // TODO(btracey): Computing a matrix inverse is generally numerically instable. + // This only has to compute the inverse of a positive definite matrix, which + // is much better, but this still loses precision. It is worth considering if + // instead the precision matrix should be stored explicitly and used instead + // of the Cholesky decomposition of the covariance matrix where appropriate. + var chol mat.Cholesky + ok = chol.Factorize(prec) + if !ok { + return nil, false + } + var sigma mat.SymDense + chol.InverseTo(&sigma) + return NewNormal(mu, &sigma, src) +} + +// ConditionNormal returns the Normal distribution that is the receiver conditioned +// on the input evidence. The returned multivariate normal has dimension +// n - len(observed), where n is the dimension of the original receiver. The updated +// mean and covariance are +// mu = mu_un + sigma_{ob,un}^T * sigma_{ob,ob}^-1 (v - mu_ob) +// sigma = sigma_{un,un} - sigma_{ob,un}^T * sigma_{ob,ob}^-1 * sigma_{ob,un} +// where mu_un and mu_ob are the original means of the unobserved and observed +// variables respectively, sigma_{un,un} is the unobserved subset of the covariance +// matrix, sigma_{ob,ob} is the observed subset of the covariance matrix, and +// sigma_{un,ob} are the cross terms. The elements of x_2 have been observed with +// values v. The dimension order is preserved during conditioning, so if the value +// of dimension 1 is observed, the returned normal represents dimensions {0, 2, ...} +// of the original Normal distribution. +// +// ConditionNormal returns {nil, false} if there is a failure during the update. +// Mathematically this is impossible, but can occur with finite precision arithmetic. +func (n *Normal) ConditionNormal(observed []int, values []float64, src *rand.Rand) (*Normal, bool) { + if len(observed) == 0 { + panic("normal: no observed value") + } + if len(observed) != len(values) { + panic(badInputLength) + } + for _, v := range observed { + if v < 0 || v >= n.Dim() { + panic("normal: observed value out of bounds") + } + } + + _, mu1, sigma11 := studentsTConditional(observed, values, math.Inf(1), n.mu, &n.sigma) + if mu1 == nil { + return nil, false + } + return NewNormal(mu1, sigma11, src) +} + +// CovarianceMatrix returns the covariance matrix of the distribution. Upon +// return, the value at element {i, j} of the covariance matrix is equal to +// the covariance of the i^th and j^th variables. +// covariance(i, j) = E[(x_i - E[x_i])(x_j - E[x_j])] +// If the input matrix is nil a new matrix is allocated, otherwise the result +// is stored in-place into the input. +func (n *Normal) CovarianceMatrix(s *mat.SymDense) *mat.SymDense { + if s == nil { + s = mat.NewSymDense(n.Dim(), nil) + } + sn := s.Symmetric() + if sn != n.Dim() { + panic("normal: input matrix size mismatch") + } + s.CopySym(&n.sigma) + return s +} + +// Dim returns the dimension of the distribution. +func (n *Normal) Dim() int { + return n.dim +} + +// Entropy returns the differential entropy of the distribution. +func (n *Normal) Entropy() float64 { + return float64(n.dim)/2*(1+logTwoPi) + n.logSqrtDet +} + +// LogProb computes the log of the pdf of the point x. +func (n *Normal) LogProb(x []float64) float64 { + dim := n.dim + if len(x) != dim { + panic(badSizeMismatch) + } + c := -0.5*float64(dim)*logTwoPi - n.logSqrtDet + dst := stat.Mahalanobis(mat.NewVecDense(dim, x), mat.NewVecDense(dim, n.mu), &n.chol) + return c - 0.5*dst*dst +} + +// MarginalNormal returns the marginal distribution of the given input variables. +// That is, MarginalNormal returns +// p(x_i) = \int_{x_o} p(x_i | x_o) p(x_o) dx_o +// where x_i are the dimensions in the input, and x_o are the remaining dimensions. +// See https://en.wikipedia.org/wiki/Marginal_distribution for more information. +// +// The input src is passed to the call to NewNormal. +func (n *Normal) MarginalNormal(vars []int, src *rand.Rand) (*Normal, bool) { + newMean := make([]float64, len(vars)) + for i, v := range vars { + newMean[i] = n.mu[v] + } + var s mat.SymDense + s.SubsetSym(&n.sigma, vars) + return NewNormal(newMean, &s, src) +} + +// MarginalNormalSingle returns the marginal of the given input variable. +// That is, MarginalNormal returns +// p(x_i) = \int_{x_¬i} p(x_i | x_¬i) p(x_¬i) dx_¬i +// where i is the input index. +// See https://en.wikipedia.org/wiki/Marginal_distribution for more information. +// +// The input src is passed to the constructed distuv.Normal. +func (n *Normal) MarginalNormalSingle(i int, src *rand.Rand) distuv.Normal { + return distuv.Normal{ + Mu: n.mu[i], + Sigma: math.Sqrt(n.sigma.At(i, i)), + Source: src, + } +} + +// Mean returns the mean of the probability distribution at x. If the +// input argument is nil, a new slice will be allocated, otherwise the result +// will be put in-place into the receiver. +func (n *Normal) Mean(x []float64) []float64 { + x = reuseAs(x, n.dim) + copy(x, n.mu) + return x +} + +// Prob computes the value of the probability density function at x. +func (n *Normal) Prob(x []float64) float64 { + return math.Exp(n.LogProb(x)) +} + +// Quantile returns the multi-dimensional inverse cumulative distribution function. +// If x is nil, a new slice will be allocated and returned. If x is non-nil, +// len(x) must equal len(p) and the quantile will be stored in-place into x. +// All of the values of p must be between 0 and 1, inclusive, or Quantile will panic. +func (n *Normal) Quantile(x, p []float64) []float64 { + dim := n.Dim() + if len(p) != dim { + panic(badInputLength) + } + if x == nil { + x = make([]float64, dim) + } + if len(x) != len(p) { + panic(badInputLength) + } + + // Transform to a standard normal and then transform to a multivariate Gaussian. + tmp := make([]float64, len(x)) + for i, v := range p { + tmp[i] = distuv.UnitNormal.Quantile(v) + } + n.TransformNormal(x, tmp) + return x +} + +// Rand generates a random number according to the distributon. +// If the input slice is nil, new memory is allocated, otherwise the result is stored +// in place. +func (n *Normal) Rand(x []float64) []float64 { + x = reuseAs(x, n.dim) + tmp := make([]float64, n.dim) + if n.src == nil { + for i := range x { + tmp[i] = rand.NormFloat64() + } + } else { + for i := range x { + tmp[i] = n.src.NormFloat64() + } + } + n.transformNormal(x, tmp) + return x +} + +// ScoreInput returns the gradient of the log-probability with respect to the +// input x. That is, ScoreInput computes +// ∇_x log(p(x)) +// If score is nil, a new slice will be allocated and returned. If score is of +// length the dimension of Normal, then the result will be put in-place into score. +// If neither of these is true, ScoreInput will panic. +func (n *Normal) ScoreInput(score, x []float64) []float64 { + // Normal log probability is + // c - 0.5*(x-μ)' Σ^-1 (x-μ). + // So the derivative is just + // -Σ^-1 (x-μ). + if len(x) != n.Dim() { + panic(badInputLength) + } + if score == nil { + score = make([]float64, len(x)) + } + if len(score) != len(x) { + panic(badSizeMismatch) + } + tmp := make([]float64, len(x)) + copy(tmp, x) + floats.Sub(tmp, n.mu) + + n.chol.SolveVec(mat.NewVecDense(len(score), score), mat.NewVecDense(len(tmp), tmp)) + floats.Scale(-1, score) + return score +} + +// SetMean changes the mean of the normal distribution. SetMean panics if len(mu) +// does not equal the dimension of the normal distribution. +func (n *Normal) SetMean(mu []float64) { + if len(mu) != n.Dim() { + panic(badSizeMismatch) + } + copy(n.mu, mu) +} + +// TransformNormal transforms the vector, normal, generated from a standard +// multidimensional normal into a vector that has been generated under the +// distribution of the receiver. +// +// If dst is non-nil, the result will be stored into dst, otherwise a new slice +// will be allocated. TransformNormal will panic if the length of normal is not +// the dimension of the receiver, or if dst is non-nil and len(dist) != len(normal). +func (n *Normal) TransformNormal(dst, normal []float64) []float64 { + if len(normal) != n.dim { + panic(badInputLength) + } + dst = reuseAs(dst, n.dim) + if len(dst) != len(normal) { + panic(badInputLength) + } + n.transformNormal(dst, normal) + return dst +} + +// transformNormal performs the same operation as TransformNormal except no +// safety checks are performed and both input slices must be non-nil. +func (n *Normal) transformNormal(dst, normal []float64) []float64 { + srcVec := mat.NewVecDense(n.dim, normal) + dstVec := mat.NewVecDense(n.dim, dst) + dstVec.MulVec(&n.lower, srcVec) + floats.Add(dst, n.mu) + return dst +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/normal_test.go b/vendor/gonum.org/v1/gonum/stat/distmv/normal_test.go new file mode 100644 index 00000000..88ac12b9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/normal_test.go @@ -0,0 +1,573 @@ +// 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 distmv + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/diff/fd" + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +type mvTest struct { + Mu []float64 + Sigma *mat.SymDense + Loc []float64 + Logprob float64 + Prob float64 +} + +func TestNormProbs(t *testing.T) { + dist1, ok := NewNormal([]float64{0, 0}, mat.NewSymDense(2, []float64{1, 0, 0, 1}), nil) + if !ok { + t.Errorf("bad test") + } + dist2, ok := NewNormal([]float64{6, 7}, mat.NewSymDense(2, []float64{8, 2, 0, 4}), nil) + if !ok { + t.Errorf("bad test") + } + testProbability(t, []probCase{ + { + dist: dist1, + loc: []float64{0, 0}, + logProb: -1.837877066409345, + }, + { + dist: dist2, + loc: []float64{6, 7}, + logProb: -3.503979321496947, + }, + { + dist: dist2, + loc: []float64{1, 2}, + logProb: -7.075407892925519, + }, + }) +} + +func TestNewNormalChol(t *testing.T) { + for _, test := range []struct { + mean []float64 + cov *mat.SymDense + }{ + { + mean: []float64{2, 3}, + cov: mat.NewSymDense(2, []float64{1, 0.1, 0.1, 1}), + }, + } { + var chol mat.Cholesky + ok := chol.Factorize(test.cov) + if !ok { + panic("bad test") + } + n := NewNormalChol(test.mean, &chol, nil) + // Generate a random number and calculate probability to ensure things + // have been set properly. See issue #426. + x := n.Rand(nil) + _ = n.Prob(x) + } +} + +func TestNormRand(t *testing.T) { + for _, test := range []struct { + mean []float64 + cov []float64 + }{ + { + mean: []float64{0, 0}, + cov: []float64{ + 1, 0, + 0, 1, + }, + }, + { + mean: []float64{0, 0}, + cov: []float64{ + 1, 0.9, + 0.9, 1, + }, + }, + { + mean: []float64{6, 7}, + cov: []float64{ + 5, 0.9, + 0.9, 2, + }, + }, + } { + dim := len(test.mean) + cov := mat.NewSymDense(dim, test.cov) + n, ok := NewNormal(test.mean, cov, nil) + if !ok { + t.Errorf("bad covariance matrix") + } + + nSamples := 1000000 + samps := mat.NewDense(nSamples, dim, nil) + for i := 0; i < nSamples; i++ { + n.Rand(samps.RawRowView(i)) + } + estMean := make([]float64, dim) + for i := range estMean { + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) + } + if !floats.EqualApprox(estMean, test.mean, 1e-2) { + t.Errorf("Mean mismatch: want: %v, got %v", test.mean, estMean) + } + estCov := stat.CovarianceMatrix(nil, samps, nil) + if !mat.EqualApprox(estCov, cov, 1e-2) { + t.Errorf("Cov mismatch: want: %v, got %v", cov, estCov) + } + } +} + +func TestNormalQuantile(t *testing.T) { + for _, test := range []struct { + mean []float64 + cov []float64 + }{ + { + mean: []float64{6, 7}, + cov: []float64{ + 5, 0.9, + 0.9, 2, + }, + }, + } { + dim := len(test.mean) + cov := mat.NewSymDense(dim, test.cov) + n, ok := NewNormal(test.mean, cov, nil) + if !ok { + t.Errorf("bad covariance matrix") + } + + nSamples := 1000000 + rnd := rand.New(rand.NewSource(1)) + samps := mat.NewDense(nSamples, dim, nil) + tmp := make([]float64, dim) + for i := 0; i < nSamples; i++ { + for j := range tmp { + tmp[j] = rnd.Float64() + } + n.Quantile(samps.RawRowView(i), tmp) + } + estMean := make([]float64, dim) + for i := range estMean { + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) + } + if !floats.EqualApprox(estMean, test.mean, 1e-2) { + t.Errorf("Mean mismatch: want: %v, got %v", test.mean, estMean) + } + estCov := stat.CovarianceMatrix(nil, samps, nil) + if !mat.EqualApprox(estCov, cov, 1e-2) { + t.Errorf("Cov mismatch: want: %v, got %v", cov, estCov) + } + } +} + +func TestConditionNormal(t *testing.T) { + // Uncorrelated values shouldn't influence the updated values. + for _, test := range []struct { + mu []float64 + sigma *mat.SymDense + observed []int + values []float64 + + newMu []float64 + newSigma *mat.SymDense + }{ + { + mu: []float64{2, 3}, + sigma: mat.NewSymDense(2, []float64{2, 0, 0, 5}), + observed: []int{0}, + values: []float64{10}, + + newMu: []float64{3}, + newSigma: mat.NewSymDense(1, []float64{5}), + }, + { + mu: []float64{2, 3}, + sigma: mat.NewSymDense(2, []float64{2, 0, 0, 5}), + observed: []int{1}, + values: []float64{10}, + + newMu: []float64{2}, + newSigma: mat.NewSymDense(1, []float64{2}), + }, + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0, 0, 0, 5, 0, 0, 0, 10}), + observed: []int{1}, + values: []float64{10}, + + newMu: []float64{2, 4}, + newSigma: mat.NewSymDense(2, []float64{2, 0, 0, 10}), + }, + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0, 0, 0, 5, 0, 0, 0, 10}), + observed: []int{0, 1}, + values: []float64{10, 15}, + + newMu: []float64{4}, + newSigma: mat.NewSymDense(1, []float64{10}), + }, + { + mu: []float64{2, 3, 4, 5}, + sigma: mat.NewSymDense(4, []float64{2, 0.5, 0, 0, 0.5, 5, 0, 0, 0, 0, 10, 2, 0, 0, 2, 3}), + observed: []int{0, 1}, + values: []float64{10, 15}, + + newMu: []float64{4, 5}, + newSigma: mat.NewSymDense(2, []float64{10, 2, 2, 3}), + }, + } { + normal, ok := NewNormal(test.mu, test.sigma, nil) + if !ok { + t.Fatalf("Bad test, original sigma not positive definite") + } + newNormal, ok := normal.ConditionNormal(test.observed, test.values, nil) + if !ok { + t.Fatalf("Bad test, update failure") + } + + if !floats.EqualApprox(test.newMu, newNormal.mu, 1e-12) { + t.Errorf("Updated mean mismatch. Want %v, got %v.", test.newMu, newNormal.mu) + } + + var sigma mat.SymDense + newNormal.chol.To(&sigma) + if !mat.EqualApprox(test.newSigma, &sigma, 1e-12) { + t.Errorf("Updated sigma mismatch\n.Want:\n% v\nGot:\n% v\n", test.newSigma, sigma) + } + } + + // Test bivariate case where the update rule is analytic + for _, test := range []struct { + mu []float64 + std []float64 + rho float64 + value float64 + }{ + { + mu: []float64{2, 3}, + std: []float64{3, 5}, + rho: 0.9, + value: 1000, + }, + { + mu: []float64{2, 3}, + std: []float64{3, 5}, + rho: -0.9, + value: 1000, + }, + } { + std := test.std + rho := test.rho + sigma := mat.NewSymDense(2, []float64{std[0] * std[0], std[0] * std[1] * rho, std[0] * std[1] * rho, std[1] * std[1]}) + normal, ok := NewNormal(test.mu, sigma, nil) + if !ok { + t.Fatalf("Bad test, original sigma not positive definite") + } + newNormal, ok := normal.ConditionNormal([]int{1}, []float64{test.value}, nil) + if !ok { + t.Fatalf("Bad test, update failed") + } + var newSigma mat.SymDense + newNormal.chol.To(&newSigma) + trueMean := test.mu[0] + rho*(std[0]/std[1])*(test.value-test.mu[1]) + if math.Abs(trueMean-newNormal.mu[0]) > 1e-14 { + t.Errorf("Mean mismatch. Want %v, got %v", trueMean, newNormal.mu[0]) + } + trueVar := (1 - rho*rho) * std[0] * std[0] + if math.Abs(trueVar-newSigma.At(0, 0)) > 1e-14 { + t.Errorf("Std mismatch. Want %v, got %v", trueMean, newNormal.mu[0]) + } + } + + // Test via sampling. + for _, test := range []struct { + mu []float64 + sigma *mat.SymDense + observed []int + unobserved []int + value []float64 + }{ + // The indices in unobserved must be in ascending order for this test. + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + + observed: []int{0}, + unobserved: []int{1, 2}, + value: []float64{1.9}, + }, + { + mu: []float64{2, 3, 4, 5}, + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + + observed: []int{0, 3}, + unobserved: []int{1, 2}, + value: []float64{1.9, 2.9}, + }, + } { + totalSamp := 4000000 + var nSamp int + samples := mat.NewDense(totalSamp, len(test.mu), nil) + normal, ok := NewNormal(test.mu, test.sigma, nil) + if !ok { + t.Errorf("bad test") + } + sample := make([]float64, len(test.mu)) + for i := 0; i < totalSamp; i++ { + normal.Rand(sample) + isClose := true + for i, v := range test.observed { + if math.Abs(sample[v]-test.value[i]) > 1e-1 { + isClose = false + break + } + } + if isClose { + samples.SetRow(nSamp, sample) + nSamp++ + } + } + + if nSamp < 100 { + t.Errorf("bad test, not enough samples") + continue + } + samples = samples.Slice(0, nSamp, 0, len(test.mu)).(*mat.Dense) + + // Compute mean and covariance matrix. + estMean := make([]float64, len(test.mu)) + for i := range estMean { + estMean[i] = stat.Mean(mat.Col(nil, i, samples), nil) + } + estCov := stat.CovarianceMatrix(nil, samples, nil) + + // Compute update rule. + newNormal, ok := normal.ConditionNormal(test.observed, test.value, nil) + if !ok { + t.Fatalf("Bad test, update failure") + } + + var subEstMean []float64 + for _, v := range test.unobserved { + + subEstMean = append(subEstMean, estMean[v]) + } + subEstCov := mat.NewSymDense(len(test.unobserved), nil) + for i := 0; i < len(test.unobserved); i++ { + for j := i; j < len(test.unobserved); j++ { + subEstCov.SetSym(i, j, estCov.At(test.unobserved[i], test.unobserved[j])) + } + } + + for i, v := range subEstMean { + if math.Abs(newNormal.mu[i]-v) > 5e-2 { + t.Errorf("Mean mismatch. Want %v, got %v.", newNormal.mu[i], v) + } + } + var sigma mat.SymDense + newNormal.chol.To(&sigma) + if !mat.EqualApprox(&sigma, subEstCov, 1e-1) { + t.Errorf("Covariance mismatch. Want:\n%0.8v\nGot:\n%0.8v\n", subEstCov, sigma) + } + } +} + +func TestCovarianceMatrix(t *testing.T) { + for _, test := range []struct { + mu []float64 + sigma *mat.SymDense + }{ + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{1, 0.5, 3, 0.5, 8, -1, 3, -1, 15}), + }, + } { + normal, ok := NewNormal(test.mu, test.sigma, nil) + if !ok { + t.Fatalf("Bad test, covariance matrix not positive definite") + } + cov := normal.CovarianceMatrix(nil) + if !mat.EqualApprox(cov, test.sigma, 1e-14) { + t.Errorf("Covariance mismatch with nil input") + } + dim := test.sigma.Symmetric() + cov = mat.NewSymDense(dim, nil) + normal.CovarianceMatrix(cov) + if !mat.EqualApprox(cov, test.sigma, 1e-14) { + t.Errorf("Covariance mismatch with supplied input") + } + } +} + +func TestMarginal(t *testing.T) { + for _, test := range []struct { + mu []float64 + sigma *mat.SymDense + marginal []int + }{ + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + marginal: []int{0}, + }, + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + marginal: []int{0, 2}, + }, + { + mu: []float64{2, 3, 4, 5}, + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + + marginal: []int{0, 3}, + }, + } { + normal, ok := NewNormal(test.mu, test.sigma, nil) + if !ok { + t.Fatalf("Bad test, covariance matrix not positive definite") + } + marginal, ok := normal.MarginalNormal(test.marginal, nil) + if !ok { + t.Fatalf("Bad test, marginal matrix not positive definite") + } + dim := normal.Dim() + nSamples := 1000000 + samps := mat.NewDense(nSamples, dim, nil) + for i := 0; i < nSamples; i++ { + normal.Rand(samps.RawRowView(i)) + } + estMean := make([]float64, dim) + for i := range estMean { + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) + } + for i, v := range test.marginal { + if math.Abs(marginal.mu[i]-estMean[v]) > 1e-2 { + t.Errorf("Mean mismatch: want: %v, got %v", estMean[v], marginal.mu[i]) + } + } + + marginalCov := marginal.CovarianceMatrix(nil) + estCov := stat.CovarianceMatrix(nil, samps, nil) + for i, v1 := range test.marginal { + for j, v2 := range test.marginal { + c := marginalCov.At(i, j) + ec := estCov.At(v1, v2) + if math.Abs(c-ec) > 5e-2 { + t.Errorf("Cov mismatch element i = %d, j = %d: want: %v, got %v", i, j, c, ec) + } + } + } + } +} + +func TestMarginalSingle(t *testing.T) { + for _, test := range []struct { + mu []float64 + sigma *mat.SymDense + }{ + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + }, + { + mu: []float64{2, 3, 4, 5}, + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + }, + } { + normal, ok := NewNormal(test.mu, test.sigma, nil) + if !ok { + t.Fatalf("Bad test, covariance matrix not positive definite") + } + for i, mean := range test.mu { + norm := normal.MarginalNormalSingle(i, nil) + if norm.Mean() != mean { + t.Errorf("Mean mismatch nil Sigma, idx %v: want %v, got %v.", i, mean, norm.Mean()) + } + std := math.Sqrt(test.sigma.At(i, i)) + if math.Abs(norm.StdDev()-std) > 1e-14 { + t.Errorf("StdDev mismatch nil Sigma, idx %v: want %v, got %v.", i, std, norm.StdDev()) + } + } + } + + // Test matching with TestMarginal. + rnd := rand.New(rand.NewSource(1)) + for cas := 0; cas < 10; cas++ { + dim := rnd.Intn(10) + 1 + mu := make([]float64, dim) + for i := range mu { + mu[i] = rnd.Float64() + } + x := make([]float64, dim*dim) + for i := range x { + x[i] = rnd.Float64() + } + matrix := mat.NewDense(dim, dim, x) + var sigma mat.SymDense + sigma.SymOuterK(1, matrix) + + normal, ok := NewNormal(mu, &sigma, nil) + if !ok { + t.Fatal("bad test") + } + for i := 0; i < dim; i++ { + single := normal.MarginalNormalSingle(i, nil) + mult, ok := normal.MarginalNormal([]int{i}, nil) + if !ok { + t.Fatal("bad test") + } + if math.Abs(single.Mean()-mult.Mean(nil)[0]) > 1e-14 { + t.Errorf("Mean mismatch") + } + if math.Abs(single.Variance()-mult.CovarianceMatrix(nil).At(0, 0)) > 1e-14 { + t.Errorf("Variance mismatch") + } + } + } +} + +func TestNormalScoreInput(t *testing.T) { + for cas, test := range []struct { + mu []float64 + sigma *mat.SymDense + x []float64 + }{ + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + x: []float64{1, 3.1, -2}, + }, + { + mu: []float64{2, 3, 4, 5}, + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + x: []float64{1, 3.1, -2, 5}, + }, + } { + normal, ok := NewNormal(test.mu, test.sigma, nil) + if !ok { + t.Fatalf("Bad test, covariance matrix not positive definite") + } + x := make([]float64, len(test.x)) + copy(x, test.x) + score := normal.ScoreInput(nil, x) + if !floats.Equal(x, test.x) { + t.Errorf("x modified during call to ScoreInput") + } + scoreFD := fd.Gradient(nil, normal.LogProb, x, nil) + if !floats.EqualApprox(score, scoreFD, 1e-4) { + t.Errorf("Case %d: derivative mismatch. Got %v, want %v", cas, score, scoreFD) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/normalbench_test.go b/vendor/gonum.org/v1/gonum/stat/distmv/normalbench_test.go new file mode 100644 index 00000000..a8890439 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/normalbench_test.go @@ -0,0 +1,73 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +import ( + "log" + "math/rand" + "testing" + + "gonum.org/v1/gonum/mat" +) + +func BenchmarkMarginalNormal10(b *testing.B) { + sz := 10 + rnd := rand.New(rand.NewSource(1)) + normal := randomNormal(sz, rnd) + _ = normal.CovarianceMatrix(nil) // pre-compute sigma + b.ResetTimer() + for i := 0; i < b.N; i++ { + marg, ok := normal.MarginalNormal([]int{1}, nil) + if !ok { + b.Error("bad test") + } + _ = marg + } +} + +func BenchmarkMarginalNormalReset10(b *testing.B) { + sz := 10 + rnd := rand.New(rand.NewSource(1)) + normal := randomNormal(sz, rnd) + b.ResetTimer() + for i := 0; i < b.N; i++ { + marg, ok := normal.MarginalNormal([]int{1}, nil) + if !ok { + b.Error("bad test") + } + _ = marg + } +} + +func BenchmarkMarginalNormalSingle10(b *testing.B) { + sz := 10 + rnd := rand.New(rand.NewSource(1)) + normal := randomNormal(sz, rnd) + b.ResetTimer() + for i := 0; i < b.N; i++ { + marg := normal.MarginalNormalSingle(1, nil) + _ = marg + } +} + +func randomNormal(sz int, rnd *rand.Rand) *Normal { + mu := make([]float64, sz) + for i := range mu { + mu[i] = rnd.Float64() + } + data := make([]float64, sz*sz) + for i := range data { + data[i] = rnd.Float64() + } + dM := mat.NewDense(sz, sz, data) + var sigma mat.SymDense + sigma.SymOuterK(1, dM) + + normal, ok := NewNormal(mu, &sigma, nil) + if !ok { + log.Fatal("bad test, not pos def") + } + return normal +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/statdist.go b/vendor/gonum.org/v1/gonum/stat/distmv/statdist.go new file mode 100644 index 00000000..9a2f3bd7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/statdist.go @@ -0,0 +1,320 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +import ( + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +// Bhattacharyya is a type for computing the Bhattacharyya distance between +// probability distributions. +// +// The Bhattacharyya distance is defined as +// D_B = -ln(BC(l,r)) +// BC = \int_-∞^∞ (p(x)q(x))^(1/2) dx +// Where BC is known as the Bhattacharyya coefficient. +// The Bhattacharyya distance is related to the Hellinger distance by +// H = sqrt(1-BC) +// For more information, see +// https://en.wikipedia.org/wiki/Bhattacharyya_distance +type Bhattacharyya struct{} + +// DistNormal computes the Bhattacharyya distance between normal distributions l and r. +// The dimensions of the input distributions must match or DistNormal will panic. +// +// For Normal distributions, the Bhattacharyya distance is +// Σ = (Σ_l + Σ_r)/2 +// D_B = (1/8)*(μ_l - μ_r)^T*Σ^-1*(μ_l - μ_r) + (1/2)*ln(det(Σ)/(det(Σ_l)*det(Σ_r))^(1/2)) +func (Bhattacharyya) DistNormal(l, r *Normal) float64 { + dim := l.Dim() + if dim != r.Dim() { + panic(badSizeMismatch) + } + + var sigma mat.SymDense + sigma.AddSym(&l.sigma, &r.sigma) + sigma.ScaleSym(0.5, &sigma) + + var chol mat.Cholesky + chol.Factorize(&sigma) + + mahalanobis := stat.Mahalanobis(mat.NewVecDense(dim, l.mu), mat.NewVecDense(dim, r.mu), &chol) + mahalanobisSq := mahalanobis * mahalanobis + + dl := l.chol.LogDet() + dr := r.chol.LogDet() + ds := chol.LogDet() + + return 0.125*mahalanobisSq + 0.5*ds - 0.25*dl - 0.25*dr +} + +// DistUniform computes the Bhattacharyya distance between uniform distributions l and r. +// The dimensions of the input distributions must match or DistUniform will panic. +func (Bhattacharyya) DistUniform(l, r *Uniform) float64 { + if len(l.bounds) != len(r.bounds) { + panic(badSizeMismatch) + } + // BC = \int \sqrt(p(x)q(x)), which for uniform distributions is a constant + // over the volume where both distributions have positive probability. + // Compute the overlap and the value of sqrt(p(x)q(x)). The entropy is the + // negative log probability of the distribution (use instead of LogProb so + // it is not necessary to construct an x value). + // + // BC = volume * sqrt(p(x)q(x)) + // logBC = log(volume) + 0.5*(logP + logQ) + // D_B = -logBC + return -unifLogVolOverlap(l.bounds, r.bounds) + 0.5*(l.Entropy()+r.Entropy()) +} + +// unifLogVolOverlap computes the log of the volume of the hyper-rectangle where +// both uniform distributions have positive probability. +func unifLogVolOverlap(b1, b2 []Bound) float64 { + var logVolOverlap float64 + for dim, v1 := range b1 { + v2 := b2[dim] + // If the surfaces don't overlap, then the volume is 0 + if v1.Max <= v2.Min || v2.Max <= v1.Min { + return math.Inf(-1) + } + vol := math.Min(v1.Max, v2.Max) - math.Max(v1.Min, v2.Min) + logVolOverlap += math.Log(vol) + } + return logVolOverlap +} + +// CrossEntropy is a type for computing the cross-entropy between probability +// distributions. +// +// The cross-entropy is defined as +// - \int_x l(x) log(r(x)) dx = KL(l || r) + H(l) +// where KL is the Kullback-Leibler divergence and H is the entropy. +// For more information, see +// https://en.wikipedia.org/wiki/Cross_entropy +type CrossEntropy struct{} + +// DistNormal returns the cross-entropy between normal distributions l and r. +// The dimensions of the input distributions must match or DistNormal will panic. +func (CrossEntropy) DistNormal(l, r *Normal) float64 { + if l.Dim() != r.Dim() { + panic(badSizeMismatch) + } + kl := KullbackLeibler{}.DistNormal(l, r) + return kl + l.Entropy() +} + +// Hellinger is a type for computing the Hellinger distance between probability +// distributions. +// +// The Hellinger distance is defined as +// H^2(l,r) = 1/2 * int_x (\sqrt(l(x)) - \sqrt(r(x)))^2 dx +// and is bounded between 0 and 1. +// The Hellinger distance is related to the Bhattacharyya distance by +// H^2 = 1 - exp(-Db) +// For more information, see +// https://en.wikipedia.org/wiki/Hellinger_distance +type Hellinger struct{} + +// DistNormal returns the Hellinger distance between normal distributions l and r. +// The dimensions of the input distributions must match or DistNormal will panic. +// +// See the documentation of Bhattacharyya.DistNormal for the formula for Normal +// distributions. +func (Hellinger) DistNormal(l, r *Normal) float64 { + if l.Dim() != r.Dim() { + panic(badSizeMismatch) + } + db := Bhattacharyya{}.DistNormal(l, r) + bc := math.Exp(-db) + return math.Sqrt(1 - bc) +} + +// KullbackLiebler is a type for computing the Kullback-Leibler divergence from l to r. +// +// The Kullback-Liebler divergence is defined as +// D_KL(l || r ) = \int_x p(x) log(p(x)/q(x)) dx +// Note that the Kullback-Liebler divergence is not symmetric with respect to +// the order of the input arguments. +type KullbackLeibler struct{} + +// DistNormal returns the KullbackLeibler distance between normal distributions l and r. +// The dimensions of the input distributions must match or DistNormal will panic. +// +// For two normal distributions, the KL divergence is computed as +// D_KL(l || r) = 0.5*[ln(|Σ_r|) - ln(|Σ_l|) + (μ_l - μ_r)^T*Σ_r^-1*(μ_l - μ_r) + tr(Σ_r^-1*Σ_l)-d] +func (KullbackLeibler) DistNormal(l, r *Normal) float64 { + dim := l.Dim() + if dim != r.Dim() { + panic(badSizeMismatch) + } + + mahalanobis := stat.Mahalanobis(mat.NewVecDense(dim, l.mu), mat.NewVecDense(dim, r.mu), &r.chol) + mahalanobisSq := mahalanobis * mahalanobis + + // TODO(btracey): Optimize where there is a SolveCholeskySym + // TODO(btracey): There may be a more efficient way to just compute the trace + // Compute tr(Σ_r^-1*Σ_l) using the fact that Σ_l = U^T * U + var u mat.TriDense + l.chol.UTo(&u) + var m mat.Dense + err := r.chol.Solve(&m, u.T()) + if err != nil { + return math.NaN() + } + m.Mul(&m, &u) + tr := mat.Trace(&m) + + return r.logSqrtDet - l.logSqrtDet + 0.5*(mahalanobisSq+tr-float64(l.dim)) +} + +// DistUniform returns the KullbackLeibler distance between uniform distributions +// l and r. The dimensions of the input distributions must match or DistUniform +// will panic. +func (KullbackLeibler) DistUniform(l, r *Uniform) float64 { + bl := l.Bounds(nil) + br := r.Bounds(nil) + if len(bl) != len(br) { + panic(badSizeMismatch) + } + + // The KL is ∞ if l is not completely contained within r, because then + // r(x) is zero when l(x) is non-zero for some x. + contained := true + for i, v := range bl { + if v.Min < br[i].Min || br[i].Max < v.Max { + contained = false + break + } + } + if !contained { + return math.Inf(1) + } + + // The KL divergence is finite. + // + // KL defines 0*ln(0) = 0, so there is no contribution to KL where l(x) = 0. + // Inside the region, l(x) and r(x) are constant (uniform distribution), and + // this constant is integrated over l(x), which integrates out to one. + // The entropy is -log(p(x)). + logPx := -l.Entropy() + logQx := -r.Entropy() + return logPx - logQx +} + +// Renyi is a type for computing the Rényi divergence of order α from l to r. +// +// The Rényi divergence with α > 0, α ≠ 1 is defined as +// D_α(l || r) = 1/(α-1) log(\int_-∞^∞ l(x)^α r(x)^(1-α)dx) +// The Rényi divergence has special forms for α = 0 and α = 1. This type does +// not implement α = ∞. For α = 0, +// D_0(l || r) = -log \int_-∞^∞ r(x)1{p(x)>0} dx +// that is, the negative log probability under r(x) that l(x) > 0. +// When α = 1, the Rényi divergence is equal to the Kullback-Leibler divergence. +// The Rényi divergence is also equal to half the Bhattacharyya distance when α = 0.5. +// +// The parameter α must be in 0 ≤ α < ∞ or the distance functions will panic. +type Renyi struct { + Alpha float64 +} + +// DistNormal returns the Rényi divergence between normal distributions l and r. +// The dimensions of the input distributions must match or DistNormal will panic. +// +// For two normal distributions, the Rényi divergence is computed as +// Σ_α = (1-α) Σ_l + αΣ_r +// D_α(l||r) = α/2 * (μ_l - μ_r)'*Σ_α^-1*(μ_l - μ_r) + 1/(2(α-1))*ln(|Σ_λ|/(|Σ_l|^(1-α)*|Σ_r|^α)) +// +// For a more nicely formatted version of the formula, see Eq. 15 of +// Kolchinsky, Artemy, and Brendan D. Tracey. "Estimating Mixture Entropy +// with Pairwise Distances." arXiv preprint arXiv:1706.02419 (2017). +// Note that the this formula is for Chernoff divergence, which differs from +// Rényi divergence by a factor of 1-α. Also be aware that most sources in +// the literature report this formula incorrectly. +func (renyi Renyi) DistNormal(l, r *Normal) float64 { + if renyi.Alpha < 0 { + panic("renyi: alpha < 0") + } + dim := l.Dim() + if dim != r.Dim() { + panic(badSizeMismatch) + } + if renyi.Alpha == 0 { + return 0 + } + if renyi.Alpha == 1 { + return KullbackLeibler{}.DistNormal(l, r) + } + + logDetL := l.chol.LogDet() + logDetR := r.chol.LogDet() + + // Σ_α = (1-α)Σ_l + αΣ_r. + sigA := mat.NewSymDense(dim, nil) + for i := 0; i < dim; i++ { + for j := i; j < dim; j++ { + v := (1-renyi.Alpha)*l.sigma.At(i, j) + renyi.Alpha*r.sigma.At(i, j) + sigA.SetSym(i, j, v) + } + } + + var chol mat.Cholesky + ok := chol.Factorize(sigA) + if !ok { + return math.NaN() + } + logDetA := chol.LogDet() + + mahalanobis := stat.Mahalanobis(mat.NewVecDense(dim, l.mu), mat.NewVecDense(dim, r.mu), &chol) + mahalanobisSq := mahalanobis * mahalanobis + + return (renyi.Alpha/2)*mahalanobisSq + 1/(2*(1-renyi.Alpha))*(logDetA-(1-renyi.Alpha)*logDetL-renyi.Alpha*logDetR) +} + +// Wasserstein is a type for computing the Wasserstein distance between two +// probability distributions. +// +// The Wasserstein distance is defined as +// W(l,r) := inf 𝔼(||X-Y||_2^2)^1/2 +// For more information, see +// https://en.wikipedia.org/wiki/Wasserstein_metric +type Wasserstein struct{} + +// DistNormal returns the Wasserstein distance between normal distributions l and r. +// The dimensions of the input distributions must match or DistNormal will panic. +// +// The Wasserstein distance for Normal distributions is +// d^2 = ||m_l - m_r||_2^2 + Tr(Σ_l + Σ_r - 2(Σ_l^(1/2)*Σ_r*Σ_l^(1/2))^(1/2)) +// For more information, see +// http://djalil.chafai.net/blog/2010/04/30/wasserstein-distance-between-two-gaussians/ +func (Wasserstein) DistNormal(l, r *Normal) float64 { + dim := l.Dim() + if dim != r.Dim() { + panic(badSizeMismatch) + } + + d := floats.Distance(l.mu, r.mu, 2) + d = d * d + + // Compute Σ_l^(1/2) + var ssl mat.SymDense + ssl.PowPSD(&l.sigma, 0.5) + // Compute Σ_l^(1/2)*Σ_r*Σ_l^(1/2) + var mean mat.Dense + mean.Mul(&ssl, &r.sigma) + mean.Mul(&mean, &ssl) + + // Reinterpret as symdense, and take Σ^(1/2) + meanSym := mat.NewSymDense(dim, mean.RawMatrix().Data) + ssl.PowPSD(meanSym, 0.5) + + tr := mat.Trace(&r.sigma) + tl := mat.Trace(&l.sigma) + tm := mat.Trace(&ssl) + + return d + tl + tr - 2*tm +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/statdist_test.go b/vendor/gonum.org/v1/gonum/stat/distmv/statdist_test.go new file mode 100644 index 00000000..a3d1d9c2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/statdist_test.go @@ -0,0 +1,329 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +func TestBhattacharyyaNormal(t *testing.T) { + for cas, test := range []struct { + am, bm []float64 + ac, bc *mat.SymDense + samples int + tol float64 + }{ + { + am: []float64{2, 3}, + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), + bm: []float64{-1, 1}, + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + samples: 100000, + tol: 1e-2, + }, + } { + rnd := rand.New(rand.NewSource(1)) + a, ok := NewNormal(test.am, test.ac, rnd) + if !ok { + panic("bad test") + } + b, ok := NewNormal(test.bm, test.bc, rnd) + if !ok { + panic("bad test") + } + want := bhattacharyyaSample(a.Dim(), test.samples, a, b) + got := Bhattacharyya{}.DistNormal(a, b) + if math.Abs(want-got) > test.tol { + t.Errorf("Bhattacharyya mismatch, case %d: got %v, want %v", cas, got, want) + } + + // Bhattacharyya should by symmetric + got2 := Bhattacharyya{}.DistNormal(b, a) + if math.Abs(got-got2) > 1e-14 { + t.Errorf("Bhattacharyya distance not symmetric") + } + } +} + +func TestBhattacharyyaUniform(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + a, b *Uniform + samples int + tol float64 + }{ + { + a: NewUniform([]Bound{{-3, 2}, {-5, 8}}, rnd), + b: NewUniform([]Bound{{-4, 1}, {-7, 10}}, rnd), + samples: 100000, + tol: 1e-2, + }, + { + a: NewUniform([]Bound{{-3, 2}, {-5, 8}}, rnd), + b: NewUniform([]Bound{{-5, -4}, {-7, 10}}, rnd), + samples: 100000, + tol: 1e-2, + }, + } { + a, b := test.a, test.b + want := bhattacharyyaSample(a.Dim(), test.samples, a, b) + got := Bhattacharyya{}.DistUniform(a, b) + if math.Abs(want-got) > test.tol { + t.Errorf("Bhattacharyya mismatch, case %d: got %v, want %v", cas, got, want) + } + // Bhattacharyya should by symmetric + got2 := Bhattacharyya{}.DistUniform(b, a) + if math.Abs(got-got2) > 1e-14 { + t.Errorf("Bhattacharyya distance not symmetric") + } + } +} + +// bhattacharyyaSample finds an estimate of the Bhattacharyya coefficient through +// sampling. +func bhattacharyyaSample(dim, samples int, l RandLogProber, r LogProber) float64 { + lBhatt := make([]float64, samples) + x := make([]float64, dim) + for i := 0; i < samples; i++ { + // Do importance sampling over a: \int sqrt(a*b)/a * a dx + l.Rand(x) + pa := l.LogProb(x) + pb := r.LogProb(x) + lBhatt[i] = 0.5*pb - 0.5*pa + } + logBc := floats.LogSumExp(lBhatt) - math.Log(float64(samples)) + return -logBc +} + +func TestCrossEntropyNormal(t *testing.T) { + for cas, test := range []struct { + am, bm []float64 + ac, bc *mat.SymDense + samples int + tol float64 + }{ + { + am: []float64{2, 3}, + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), + bm: []float64{-1, 1}, + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + samples: 100000, + tol: 1e-2, + }, + } { + rnd := rand.New(rand.NewSource(1)) + a, ok := NewNormal(test.am, test.ac, rnd) + if !ok { + panic("bad test") + } + b, ok := NewNormal(test.bm, test.bc, rnd) + if !ok { + panic("bad test") + } + var ce float64 + x := make([]float64, a.Dim()) + for i := 0; i < test.samples; i++ { + a.Rand(x) + ce -= b.LogProb(x) + } + ce /= float64(test.samples) + got := CrossEntropy{}.DistNormal(a, b) + if math.Abs(ce-got) > test.tol { + t.Errorf("CrossEntropy mismatch, case %d: got %v, want %v", cas, got, ce) + } + } +} + +func TestHellingerNormal(t *testing.T) { + for cas, test := range []struct { + am, bm []float64 + ac, bc *mat.SymDense + samples int + tol float64 + }{ + { + am: []float64{2, 3}, + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), + bm: []float64{-1, 1}, + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + samples: 100000, + tol: 5e-1, + }, + } { + rnd := rand.New(rand.NewSource(1)) + a, ok := NewNormal(test.am, test.ac, rnd) + if !ok { + panic("bad test") + } + b, ok := NewNormal(test.bm, test.bc, rnd) + if !ok { + panic("bad test") + } + lAitchEDoubleHockeySticks := make([]float64, test.samples) + x := make([]float64, a.Dim()) + for i := 0; i < test.samples; i++ { + // Do importance sampling over a: \int (\sqrt(a)-\sqrt(b))^2/a * a dx + a.Rand(x) + pa := a.LogProb(x) + pb := b.LogProb(x) + d := math.Exp(0.5*pa) - math.Exp(0.5*pb) + d = d * d + lAitchEDoubleHockeySticks[i] = math.Log(d) - pa + } + want := math.Sqrt(0.5 * math.Exp(floats.LogSumExp(lAitchEDoubleHockeySticks)-math.Log(float64(test.samples)))) + got := Hellinger{}.DistNormal(a, b) + if math.Abs(want-got) > test.tol { + t.Errorf("Hellinger mismatch, case %d: got %v, want %v", cas, got, want) + } + } +} + +func TestKullbackLeiblerNormal(t *testing.T) { + for cas, test := range []struct { + am, bm []float64 + ac, bc *mat.SymDense + samples int + tol float64 + }{ + { + am: []float64{2, 3}, + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), + bm: []float64{-1, 1}, + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + samples: 10000, + tol: 1e-2, + }, + } { + rnd := rand.New(rand.NewSource(1)) + a, ok := NewNormal(test.am, test.ac, rnd) + if !ok { + panic("bad test") + } + b, ok := NewNormal(test.bm, test.bc, rnd) + if !ok { + panic("bad test") + } + want := klSample(a.Dim(), test.samples, a, b) + got := KullbackLeibler{}.DistNormal(a, b) + if !floats.EqualWithinAbsOrRel(want, got, test.tol, test.tol) { + t.Errorf("Case %d, KL mismatch: got %v, want %v", cas, got, want) + } + } +} + +func TestKullbackLeiblerUniform(t *testing.T) { + rnd := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + a, b *Uniform + samples int + tol float64 + }{ + { + a: NewUniform([]Bound{{-5, 2}, {-7, 12}}, rnd), + b: NewUniform([]Bound{{-4, 1}, {-7, 10}}, rnd), + samples: 100000, + tol: 1e-2, + }, + { + a: NewUniform([]Bound{{-5, 2}, {-7, 12}}, rnd), + b: NewUniform([]Bound{{-9, -6}, {-7, 10}}, rnd), + samples: 100000, + tol: 1e-2, + }, + } { + a, b := test.a, test.b + want := klSample(a.Dim(), test.samples, a, b) + got := KullbackLeibler{}.DistUniform(a, b) + if math.Abs(want-got) > test.tol { + t.Errorf("Kullback-Leibler mismatch, case %d: got %v, want %v", cas, got, want) + } + } +} + +// klSample finds an estimate of the Kullback-Leibler divergence through sampling. +func klSample(dim, samples int, l RandLogProber, r LogProber) float64 { + var klmc float64 + x := make([]float64, dim) + for i := 0; i < samples; i++ { + l.Rand(x) + pa := l.LogProb(x) + pb := r.LogProb(x) + klmc += pa - pb + } + return klmc / float64(samples) +} + +func TestRenyiNormal(t *testing.T) { + for cas, test := range []struct { + am, bm []float64 + ac, bc *mat.SymDense + alpha float64 + samples int + tol float64 + }{ + { + am: []float64{2, 3}, + ac: mat.NewSymDense(2, []float64{3, -1, -1, 2}), + bm: []float64{-1, 1}, + bc: mat.NewSymDense(2, []float64{1.5, 0.2, 0.2, 0.9}), + alpha: 0.3, + samples: 10000, + tol: 1e-2, + }, + } { + rnd := rand.New(rand.NewSource(1)) + a, ok := NewNormal(test.am, test.ac, rnd) + if !ok { + panic("bad test") + } + b, ok := NewNormal(test.bm, test.bc, rnd) + if !ok { + panic("bad test") + } + want := renyiSample(a.Dim(), test.samples, test.alpha, a, b) + got := Renyi{Alpha: test.alpha}.DistNormal(a, b) + if !floats.EqualWithinAbsOrRel(want, got, test.tol, test.tol) { + t.Errorf("Case %d: Renyi sampling mismatch: got %v, want %v", cas, got, want) + } + + // Compare with Bhattacharyya. + want = 2 * Bhattacharyya{}.DistNormal(a, b) + got = Renyi{Alpha: 0.5}.DistNormal(a, b) + if math.Abs(want-got) > 1e-10 { + t.Errorf("Case %d: Renyi mismatch with Bhattacharyya: got %v, want %v", cas, got, want) + } + + // Compare with KL in both directions. + want = KullbackLeibler{}.DistNormal(a, b) + got = Renyi{Alpha: 0.9999999}.DistNormal(a, b) // very close to 1 but not equal to 1. + if math.Abs(want-got) > 1e-6 { + t.Errorf("Case %d: Renyi mismatch with KL(a||b): got %v, want %v", cas, got, want) + } + want = KullbackLeibler{}.DistNormal(b, a) + got = Renyi{Alpha: 0.9999999}.DistNormal(b, a) // very close to 1 but not equal to 1. + if math.Abs(want-got) > 1e-6 { + t.Errorf("Case %d: Renyi mismatch with KL(b||a): got %v, want %v", cas, got, want) + } + } +} + +// renyiSample finds an estimate of the Rényi divergence through sampling. +// Note that this sampling procedure only works if l has broader support than r. +func renyiSample(dim, samples int, alpha float64, l RandLogProber, r LogProber) float64 { + rmcs := make([]float64, samples) + x := make([]float64, dim) + for i := 0; i < samples; i++ { + l.Rand(x) + pa := l.LogProb(x) + pb := r.LogProb(x) + rmcs[i] = (alpha-1)*pa + (1-alpha)*pb + } + return 1 / (alpha - 1) * (floats.LogSumExp(rmcs) - math.Log(float64(samples))) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/studentst.go b/vendor/gonum.org/v1/gonum/stat/distmv/studentst.go new file mode 100644 index 00000000..041b1369 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/studentst.go @@ -0,0 +1,354 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +import ( + "math" + "math/rand" + "sort" + + "golang.org/x/tools/container/intsets" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat/distuv" +) + +// StudentsT is a multivariate Student's T distribution. It is a distribution over +// ℝ^n with the probability density +// p(y) = (Γ((ν+n)/2) / Γ(ν/2)) * (νπ)^(-n/2) * |Ʃ|^(-1/2) * +// (1 + 1/ν * (y-μ)^T * Ʃ^-1 * (y-μ))^(-(ν+n)/2) +// where ν is a scalar greater than 2, μ is a vector in ℝ^n, and Ʃ is an n×n +// symmetric positive definite matrix. +// +// In this distribution, ν sets the spread of the distribution, similar to +// the degrees of freedom in a univariate Student's T distribution. As ν → ∞, +// the distribution approaches a multi-variate normal distribution. +// μ is the mean of the distribution, and the covariance is ν/(ν-2)*Ʃ. +// +// See https://en.wikipedia.org/wiki/Student%27s_t-distribution and +// http://users.isy.liu.se/en/rt/roth/student.pdf for more information. +type StudentsT struct { + nu float64 + mu []float64 + src *rand.Rand + + sigma mat.SymDense // only stored if needed + + chol mat.Cholesky + lower mat.TriDense + logSqrtDet float64 + dim int +} + +// NewStudentsT creates a new StudentsT with the given nu, mu, and sigma +// parameters. +// +// NewStudentsT panics if len(mu) == 0, or if len(mu) != sigma.Symmetric(). If +// the covariance matrix is not positive-definite, nil is returned and ok is false. +func NewStudentsT(mu []float64, sigma mat.Symmetric, nu float64, src *rand.Rand) (dist *StudentsT, ok bool) { + if len(mu) == 0 { + panic(badZeroDimension) + } + dim := sigma.Symmetric() + if dim != len(mu) { + panic(badSizeMismatch) + } + + s := &StudentsT{ + nu: nu, + mu: make([]float64, dim), + dim: dim, + src: src, + } + copy(s.mu, mu) + + ok = s.chol.Factorize(sigma) + if !ok { + return nil, false + } + s.sigma = *mat.NewSymDense(dim, nil) + s.sigma.CopySym(sigma) + s.chol.LTo(&s.lower) + s.logSqrtDet = 0.5 * s.chol.LogDet() + return s, true +} + +// ConditionStudentsT returns the Student's T distribution that is the receiver +// conditioned on the input evidence, and the success of the operation. +// The returned Student's T has dimension +// n - len(observed), where n is the dimension of the original receiver. +// The dimension order is preserved during conditioning, so if the value +// of dimension 1 is observed, the returned normal represents dimensions {0, 2, ...} +// of the original Student's T distribution. +// +// ok indicates whether there was a failure during the update. If ok is false +// the operation failed and dist is not usable. +// Mathematically this is impossible, but can occur with finite precision arithmetic. +func (s *StudentsT) ConditionStudentsT(observed []int, values []float64, src *rand.Rand) (dist *StudentsT, ok bool) { + if len(observed) == 0 { + panic("studentst: no observed value") + } + if len(observed) != len(values) { + panic(badInputLength) + } + + for _, v := range observed { + if v < 0 || v >= s.dim { + panic("studentst: observed value out of bounds") + } + } + + newNu, newMean, newSigma := studentsTConditional(observed, values, s.nu, s.mu, &s.sigma) + if newMean == nil { + return nil, false + } + + return NewStudentsT(newMean, newSigma, newNu, src) + +} + +// studentsTConditional updates a Student's T distribution based on the observed samples +// (see documentation for the public function). The Gaussian conditional update +// is treated as a special case when nu == math.Inf(1). +func studentsTConditional(observed []int, values []float64, nu float64, mu []float64, sigma mat.Symmetric) (newNu float64, newMean []float64, newSigma *mat.SymDense) { + dim := len(mu) + ob := len(observed) + + unobserved := findUnob(observed, dim) + + unob := len(unobserved) + if unob == 0 { + panic("stat: all dimensions observed") + } + + mu1 := make([]float64, unob) + for i, v := range unobserved { + mu1[i] = mu[v] + } + mu2 := make([]float64, ob) // really v - mu2 + for i, v := range observed { + mu2[i] = values[i] - mu[v] + } + + var sigma11, sigma22 mat.SymDense + sigma11.SubsetSym(sigma, unobserved) + sigma22.SubsetSym(sigma, observed) + + sigma21 := mat.NewDense(ob, unob, nil) + for i, r := range observed { + for j, c := range unobserved { + v := sigma.At(r, c) + sigma21.Set(i, j, v) + } + } + + var chol mat.Cholesky + ok := chol.Factorize(&sigma22) + if !ok { + return math.NaN(), nil, nil + } + + // Compute mu_1 + sigma_{2,1}^T * sigma_{2,2}^-1 (v - mu_2). + v := mat.NewVecDense(ob, mu2) + var tmp, tmp2 mat.VecDense + err := chol.SolveVec(&tmp, v) + if err != nil { + return math.NaN(), nil, nil + } + tmp2.MulVec(sigma21.T(), &tmp) + + for i := range mu1 { + mu1[i] += tmp2.At(i, 0) + } + + // Compute tmp4 = sigma_{2,1}^T * sigma_{2,2}^-1 * sigma_{2,1}. + // TODO(btracey): Should this be a method of SymDense? + var tmp3, tmp4 mat.Dense + err = chol.Solve(&tmp3, sigma21) + if err != nil { + return math.NaN(), nil, nil + } + tmp4.Mul(sigma21.T(), &tmp3) + + // Compute sigma_{1,1} - tmp4 + // TODO(btracey): If tmp4 can constructed with a method, then this can be + // replaced with SubSym. + for i := 0; i < len(unobserved); i++ { + for j := i; j < len(unobserved); j++ { + v := sigma11.At(i, j) + sigma11.SetSym(i, j, v-tmp4.At(i, j)) + } + } + + // The computed variables are accurate for a Normal. + if math.IsInf(nu, 1) { + return nu, mu1, &sigma11 + } + + // Compute beta = (v - mu_2)^T * sigma_{2,2}^-1 * (v - mu_2)^T + beta := mat.Dot(v, &tmp) + + // Scale the covariance matrix + sigma11.ScaleSym((nu+beta)/(nu+float64(ob)), &sigma11) + + return nu + float64(ob), mu1, &sigma11 +} + +// findUnob returns the unobserved variables (the complementary set to observed). +// findUnob panics if any value repeated in observed. +func findUnob(observed []int, dim int) (unobserved []int) { + var setOb intsets.Sparse + for _, v := range observed { + setOb.Insert(v) + } + var setAll intsets.Sparse + for i := 0; i < dim; i++ { + setAll.Insert(i) + } + var setUnob intsets.Sparse + setUnob.Difference(&setAll, &setOb) + unobserved = setUnob.AppendTo(nil) + sort.Ints(unobserved) + return unobserved +} + +// CovarianceMatrix returns the covariance matrix of the distribution. Upon +// return, the value at element {i, j} of the covariance matrix is equal to +// the covariance of the i^th and j^th variables. +// covariance(i, j) = E[(x_i - E[x_i])(x_j - E[x_j])] +// If the input matrix is nil a new matrix is allocated, otherwise the result +// is stored in-place into the input. +func (st *StudentsT) CovarianceMatrix(s *mat.SymDense) *mat.SymDense { + if s == nil { + s = mat.NewSymDense(st.dim, nil) + } + sn := s.Symmetric() + if sn != st.dim { + panic("normal: input matrix size mismatch") + } + s.CopySym(&st.sigma) + s.ScaleSym(st.nu/(st.nu-2), s) + return s +} + +// Dim returns the dimension of the distribution. +func (s *StudentsT) Dim() int { + return s.dim +} + +// LogProb computes the log of the pdf of the point x. +func (s *StudentsT) LogProb(y []float64) float64 { + if len(y) != s.dim { + panic(badInputLength) + } + + nu := s.nu + n := float64(s.dim) + lg1, _ := math.Lgamma((nu + n) / 2) + lg2, _ := math.Lgamma(nu / 2) + + t1 := lg1 - lg2 - n/2*math.Log(nu*math.Pi) - s.logSqrtDet + + shift := make([]float64, len(y)) + copy(shift, y) + floats.Sub(shift, s.mu) + + x := mat.NewVecDense(s.dim, shift) + + var tmp mat.VecDense + s.chol.SolveVec(&tmp, x) + + dot := mat.Dot(&tmp, x) + + return t1 - ((nu+n)/2)*math.Log(1+dot/nu) +} + +// MarginalStudentsT returns the marginal distribution of the given input variables, +// and the success of the operation. +// That is, MarginalStudentsT returns +// p(x_i) = \int_{x_o} p(x_i | x_o) p(x_o) dx_o +// where x_i are the dimensions in the input, and x_o are the remaining dimensions. +// See https://en.wikipedia.org/wiki/Marginal_distribution for more information. +// +// The input src is passed to the created StudentsT. +// +// ok indicates whether there was a failure during the marginalization. If ok is false +// the operation failed and dist is not usable. +// Mathematically this is impossible, but can occur with finite precision arithmetic. +func (s *StudentsT) MarginalStudentsT(vars []int, src *rand.Rand) (dist *StudentsT, ok bool) { + newMean := make([]float64, len(vars)) + for i, v := range vars { + newMean[i] = s.mu[v] + } + var newSigma mat.SymDense + newSigma.SubsetSym(&s.sigma, vars) + return NewStudentsT(newMean, &newSigma, s.nu, src) +} + +// MarginalStudentsT returns the marginal distribution of the given input variable. +// That is, MarginalStudentsT returns +// p(x_i) = \int_{x_o} p(x_i | x_o) p(x_o) dx_o +// where i is the input index, and x_o are the remaining dimensions. +// See https://en.wikipedia.org/wiki/Marginal_distribution for more information. +// +// The input src is passed to the call to NewStudentsT. +func (s *StudentsT) MarginalStudentsTSingle(i int, src *rand.Rand) distuv.StudentsT { + return distuv.StudentsT{ + Mu: s.mu[i], + Sigma: math.Sqrt(s.sigma.At(i, i)), + Nu: s.nu, + Src: src, + } +} + +// TODO(btracey): Implement marginal single. Need to modify univariate StudentsT +// to be three-parameter. + +// Mean returns the mean of the probability distribution at x. If the +// input argument is nil, a new slice will be allocated, otherwise the result +// will be put in-place into the receiver. +func (s *StudentsT) Mean(x []float64) []float64 { + x = reuseAs(x, s.dim) + copy(x, s.mu) + return x +} + +// Prob computes the value of the probability density function at x. +func (s *StudentsT) Prob(y []float64) float64 { + return math.Exp(s.LogProb(y)) +} + +// Rand generates a random number according to the distributon. +// If the input slice is nil, new memory is allocated, otherwise the result is stored +// in place. +func (s *StudentsT) Rand(x []float64) []float64 { + // If Y is distributed according to N(0,Sigma), and U is chi^2 with + // parameter ν, then + // X = mu + Y * sqrt(nu / U) + // X is distributed according to this distribution. + + // Generate Y. + x = reuseAs(x, s.dim) + tmp := make([]float64, s.dim) + if s.src == nil { + for i := range x { + tmp[i] = rand.NormFloat64() + } + } else { + for i := range x { + tmp[i] = s.src.NormFloat64() + } + } + xVec := mat.NewVecDense(s.dim, x) + tmpVec := mat.NewVecDense(s.dim, tmp) + xVec.MulVec(&s.lower, tmpVec) + + u := distuv.ChiSquared{K: s.nu, Src: s.src}.Rand() + floats.Scale(math.Sqrt(s.nu/u), x) + + floats.Add(x, s.mu) + return x +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/studentst_test.go b/vendor/gonum.org/v1/gonum/stat/distmv/studentst_test.go new file mode 100644 index 00000000..b21a07f8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/studentst_test.go @@ -0,0 +1,265 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distmv + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +func TestStudentTProbs(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for _, test := range []struct { + nu float64 + mu []float64 + sigma *mat.SymDense + + x [][]float64 + probs []float64 + }{ + { + nu: 3, + mu: []float64{0, 0}, + sigma: mat.NewSymDense(2, []float64{1, 0, 0, 1}), + + x: [][]float64{ + {0, 0}, + {1, -1}, + {3, 4}, + {-1, -2}, + }, + // Outputs compared with WolframAlpha. + probs: []float64{ + 0.159154943091895335768883, + 0.0443811199724279860006777747927, + 0.0005980371870904696541052658, + 0.01370560783418571283428283, + }, + }, + { + nu: 4, + mu: []float64{2, -3}, + sigma: mat.NewSymDense(2, []float64{8, -1, -1, 5}), + + x: [][]float64{ + {0, 0}, + {1, -1}, + {3, 4}, + {-1, -2}, + {2, -3}, + }, + // Outputs compared with WolframAlpha. + probs: []float64{ + 0.007360810111491788657953608191001, + 0.0143309905845607117740440592999, + 0.0005307774290578041397794096037035009801668903, + 0.0115657422475668739943625904793879, + 0.0254851872062589062995305736215, + }, + }, + } { + s, ok := NewStudentsT(test.mu, test.sigma, test.nu, src) + if !ok { + t.Fatal("bad test") + } + for i, x := range test.x { + xcpy := make([]float64, len(x)) + copy(xcpy, x) + p := s.Prob(x) + if !floats.Same(x, xcpy) { + t.Errorf("X modified during call to prob, %v, %v", x, xcpy) + } + if !floats.EqualWithinAbsOrRel(p, test.probs[i], 1e-10, 1e-10) { + t.Errorf("Probability mismatch. X = %v. Got %v, want %v.", x, p, test.probs[i]) + } + } + } +} + +func TestStudentsTRand(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for cas, test := range []struct { + mean []float64 + cov *mat.SymDense + nu float64 + tolcov float64 + }{ + { + mean: []float64{0, 0}, + cov: mat.NewSymDense(2, []float64{1, 0, 0, 1}), + nu: 4, + tolcov: 1e-2, + }, + { + mean: []float64{3, 4}, + cov: mat.NewSymDense(2, []float64{5, 1.2, 1.2, 6}), + nu: 8, + tolcov: 1e-2, + }, + { + mean: []float64{3, 4, -2}, + cov: mat.NewSymDense(3, []float64{5, 1.2, -0.8, 1.2, 6, 0.4, -0.8, 0.4, 2}), + nu: 8, + tolcov: 1e-2, + }, + } { + s, ok := NewStudentsT(test.mean, test.cov, test.nu, src) + if !ok { + t.Fatal("bad test") + } + const nSamples = 1e6 + dim := len(test.mean) + samps := mat.NewDense(nSamples, dim, nil) + for i := 0; i < nSamples; i++ { + s.Rand(samps.RawRowView(i)) + } + estMean := make([]float64, dim) + for i := range estMean { + estMean[i] = stat.Mean(mat.Col(nil, i, samps), nil) + } + mean := s.Mean(nil) + if !floats.EqualApprox(estMean, mean, 1e-2) { + t.Errorf("Mean mismatch: want: %v, got %v", test.mean, estMean) + } + cov := s.CovarianceMatrix(nil) + estCov := stat.CovarianceMatrix(nil, samps, nil) + if !mat.EqualApprox(estCov, cov, test.tolcov) { + t.Errorf("Case %d: Cov mismatch: want: %v, got %v", cas, cov, estCov) + } + } +} + +func TestStudentsTConditional(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for _, test := range []struct { + mean []float64 + cov *mat.SymDense + nu float64 + + idx []int + value []float64 + tolcov float64 + }{ + { + mean: []float64{3, 4, -2}, + cov: mat.NewSymDense(3, []float64{5, 1.2, -0.8, 1.2, 6, 0.4, -0.8, 0.4, 2}), + nu: 8, + idx: []int{0}, + value: []float64{6}, + + tolcov: 1e-2, + }, + } { + s, ok := NewStudentsT(test.mean, test.cov, test.nu, src) + if !ok { + t.Fatal("bad test") + } + + sUp, ok := s.ConditionStudentsT(test.idx, test.value, src) + if !ok { + t.Error("unexpected failure of ConditionStudentsT") + } + + // Compute the other values by hand the inefficient way to compare + newNu := test.nu + float64(len(test.idx)) + if newNu != sUp.nu { + t.Errorf("Updated nu mismatch. Got %v, want %v", s.nu, newNu) + } + dim := len(test.mean) + unob := findUnob(test.idx, dim) + ob := test.idx + + muUnob := make([]float64, len(unob)) + for i, v := range unob { + muUnob[i] = test.mean[v] + } + muOb := make([]float64, len(ob)) + for i, v := range ob { + muOb[i] = test.mean[v] + } + + var sig11, sig22 mat.SymDense + sig11.SubsetSym(&s.sigma, unob) + sig22.SubsetSym(&s.sigma, ob) + + sig12 := mat.NewDense(len(unob), len(ob), nil) + for i := range unob { + for j := range ob { + sig12.Set(i, j, s.sigma.At(unob[i], ob[j])) + } + } + + shift := make([]float64, len(ob)) + copy(shift, test.value) + floats.Sub(shift, muOb) + + newMu := make([]float64, len(muUnob)) + newMuVec := mat.NewVecDense(len(muUnob), newMu) + shiftVec := mat.NewVecDense(len(shift), shift) + var tmp mat.VecDense + tmp.SolveVec(&sig22, shiftVec) + newMuVec.MulVec(sig12, &tmp) + floats.Add(newMu, muUnob) + + if !floats.EqualApprox(newMu, sUp.mu, 1e-10) { + t.Errorf("Mu mismatch. Got %v, want %v", sUp.mu, newMu) + } + + var tmp2 mat.Dense + tmp2.Solve(&sig22, sig12.T()) + + var tmp3 mat.Dense + tmp3.Mul(sig12, &tmp2) + tmp3.Sub(&sig11, &tmp3) + + dot := mat.Dot(shiftVec, &tmp) + tmp3.Scale((test.nu+dot)/(test.nu+float64(len(ob))), &tmp3) + if !mat.EqualApprox(&tmp3, &sUp.sigma, 1e-10) { + t.Errorf("Sigma mismatch") + } + } +} + +func TestStudentsTMarginalSingle(t *testing.T) { + for _, test := range []struct { + mu []float64 + sigma *mat.SymDense + nu float64 + }{ + { + mu: []float64{2, 3, 4}, + sigma: mat.NewSymDense(3, []float64{2, 0.5, 3, 0.5, 1, 0.6, 3, 0.6, 10}), + nu: 5, + }, + { + mu: []float64{2, 3, 4, 5}, + sigma: mat.NewSymDense(4, []float64{2, 0.5, 3, 0.1, 0.5, 1, 0.6, 0.2, 3, 0.6, 10, 0.3, 0.1, 0.2, 0.3, 3}), + nu: 6, + }, + } { + studentst, ok := NewStudentsT(test.mu, test.sigma, test.nu, nil) + if !ok { + t.Fatalf("Bad test, covariance matrix not positive definite") + } + for i, mean := range test.mu { + st := studentst.MarginalStudentsTSingle(i, nil) + if st.Mean() != mean { + t.Errorf("Mean mismatch nil Sigma, idx %v: want %v, got %v.", i, mean, st.Mean()) + } + std := math.Sqrt(test.sigma.At(i, i)) + if math.Abs(st.Sigma-std) > 1e-14 { + t.Errorf("StdDev mismatch nil Sigma, idx %v: want %v, got %v.", i, std, st.StdDev()) + } + if st.Nu != test.nu { + t.Errorf("Nu mismatch nil Sigma, idx %v: want %v, got %v ", i, test.nu, st.Nu) + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/uniform.go b/vendor/gonum.org/v1/gonum/stat/distmv/uniform.go new file mode 100644 index 00000000..c28a0232 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/uniform.go @@ -0,0 +1,196 @@ +// 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 distmv + +import ( + "math" + "math/rand" +) + +type Bound struct { + Min float64 + Max float64 +} + +// Uniform represents a multivariate uniform distribution. +type Uniform struct { + bounds []Bound + dim int + src *rand.Rand +} + +// NewUniform creates a new uniform distribution with the given bounds. +func NewUniform(bnds []Bound, src *rand.Rand) *Uniform { + dim := len(bnds) + if dim == 0 { + panic(badZeroDimension) + } + for _, b := range bnds { + if b.Max < b.Min { + panic("uniform: maximum less than minimum") + } + } + u := &Uniform{ + bounds: make([]Bound, dim), + dim: dim, + src: src, + } + for i, b := range bnds { + u.bounds[i].Min = b.Min + u.bounds[i].Max = b.Max + } + return u +} + +// NewUnitUniform creates a new Uniform distribution over the dim-dimensional +// unit hypercube. That is, a uniform distribution where each dimension has +// Min = 0 and Max = 1. +func NewUnitUniform(dim int, src *rand.Rand) *Uniform { + if dim <= 0 { + panic(nonPosDimension) + } + bounds := make([]Bound, dim) + for i := range bounds { + bounds[i].Min = 0 + bounds[i].Max = 1 + } + return &Uniform{ + bounds: bounds, + dim: dim, + src: src, + } +} + +// Bounds returns the bounds on the variables of the distribution. If the input +// is nil, a new slice is allocated and returned. If the input is non-nil, then +// the bounds are stored in-place into the input argument, and Bounds will panic +// if len(bounds) != u.Dim(). +func (u *Uniform) Bounds(bounds []Bound) []Bound { + if bounds == nil { + bounds = make([]Bound, u.Dim()) + } + if len(bounds) != u.Dim() { + panic(badInputLength) + } + copy(bounds, u.bounds) + return bounds +} + +// CDF returns the multidimensional cumulative distribution function of the +// probability distribution at the point x. If p is non-nil, the CDF is stored +// in-place into the first argument, otherwise a new slice is allocated and +// returned. +// +// CDF will panic if len(x) is not equal to the dimension of the distribution, +// or if p is non-nil and len(p) is not equal to the dimension of the distribution. +func (u *Uniform) CDF(p, x []float64) []float64 { + if len(x) != u.dim { + panic(badSizeMismatch) + } + if p == nil { + p = make([]float64, u.dim) + } + if len(p) != u.dim { + panic(badSizeMismatch) + } + for i, v := range x { + if v < u.bounds[i].Min { + p[i] = 0 + } else if v > u.bounds[i].Max { + p[i] = 1 + } else { + p[i] = (v - u.bounds[i].Min) / (u.bounds[i].Max - u.bounds[i].Min) + } + } + return p +} + +// Dim returns the dimension of the distribution. +func (u *Uniform) Dim() int { + return u.dim +} + +// Entropy returns the differential entropy of the distribution. +func (u *Uniform) Entropy() float64 { + // Entropy is log of the volume. + var logVol float64 + for _, b := range u.bounds { + logVol += math.Log(b.Max - b.Min) + } + return logVol +} + +// LogProb computes the log of the pdf of the point x. +func (u *Uniform) LogProb(x []float64) float64 { + dim := u.dim + if len(x) != dim { + panic(badSizeMismatch) + } + var logprob float64 + for i, b := range u.bounds { + if x[i] < b.Min || x[i] > b.Max { + return math.Inf(-1) + } + logprob -= math.Log(b.Max - b.Min) + } + return logprob +} + +// Mean returns the mean of the probability distribution at x. If the +// input argument is nil, a new slice will be allocated, otherwise the result +// will be put in-place into the receiver. +func (u *Uniform) Mean(x []float64) []float64 { + x = reuseAs(x, u.dim) + for i, b := range u.bounds { + x[i] = (b.Max + b.Min) / 2 + } + return x +} + +// Prob computes the value of the probability density function at x. +func (u *Uniform) Prob(x []float64) float64 { + return math.Exp(u.LogProb(x)) +} + +// Rand generates a random number according to the distributon. +// If the input slice is nil, new memory is allocated, otherwise the result is stored +// in place. +func (u *Uniform) Rand(x []float64) []float64 { + x = reuseAs(x, u.dim) + if u.src == nil { + for i, b := range u.bounds { + x[i] = rand.Float64()*(b.Max-b.Min) + b.Min + } + return x + } + for i, b := range u.bounds { + x[i] = rand.Float64()*(b.Max-b.Min) + b.Min + } + return x +} + +// Quantile returns the multi-dimensional inverse cumulative distribution function. +// len(x) must equal len(p), and if x is non-nil, len(x) must also equal len(p). +// If x is nil, a new slice will be allocated and returned, otherwise the quantile +// will be stored in-place into x. All of the values of p must be between 0 and 1, +// or Quantile will panic. +func (u *Uniform) Quantile(x, p []float64) []float64 { + if len(p) != u.dim { + panic(badSizeMismatch) + } + if x == nil { + x = make([]float64, u.dim) + } + if len(x) != u.dim { + panic(badSizeMismatch) + } + for i, v := range p { + if v < 0 || v > 1 { + panic(badQuantile) + } + x[i] = v*(u.bounds[i].Max-u.bounds[i].Min) + u.bounds[i].Min + } + return x +} diff --git a/vendor/gonum.org/v1/gonum/stat/distmv/uniform_test.go b/vendor/gonum.org/v1/gonum/stat/distmv/uniform_test.go new file mode 100644 index 00000000..c52e09a9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distmv/uniform_test.go @@ -0,0 +1,31 @@ +// 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 distmv + +import ( + "math" + "testing" +) + +func TestUniformEntropy(t *testing.T) { + for _, test := range []struct { + Uniform *Uniform + Entropy float64 + }{ + { + NewUniform([]Bound{{0, 1}, {0, 1}}, nil), + 0, + }, + { + NewUniform([]Bound{{-1, 3}, {2, 8}, {-5, -3}}, nil), + math.Log(48), + }, + } { + ent := test.Uniform.Entropy() + if math.Abs(ent-test.Entropy) > 1e-14 { + t.Errorf("Entropy mismatch. Got %v, want %v", ent, test.Entropy) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/bernoulli.go b/vendor/gonum.org/v1/gonum/stat/distuv/bernoulli.go new file mode 100644 index 00000000..c03578f1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/bernoulli.go @@ -0,0 +1,131 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math" + "math/rand" +) + +// Bernoulli represents a random variable whose value is 1 with probability p and +// value of zero with probability 1-P. The value of P must be between 0 and 1. +// More information at https://en.wikipedia.org/wiki/Bernoulli_distribution. +type Bernoulli struct { + P float64 + Source *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (b Bernoulli) CDF(x float64) float64 { + if x < 0 { + return 0 + } + if x < 1 { + return 1 - b.P + } + return 1 +} + +// Entropy returns the entropy of the distribution. +func (b Bernoulli) Entropy() float64 { + if b.P == 0 { + return 0 + } + if b.P == 1 { + return 1 + } + q := 1 - b.P + return -b.P*math.Log(b.P) - q*math.Log(q) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (b Bernoulli) ExKurtosis() float64 { + pq := b.P * (1 - b.P) + return (1 - 6*pq) / pq +} + +// LogProb computes the natural logarithm of the value of the probability density function at x. +func (b Bernoulli) LogProb(x float64) float64 { + if x == 0 { + return math.Log(1 - b.P) + } + if x == 1 { + return math.Log(b.P) + } + return math.Inf(-1) +} + +// Mean returns the mean of the probability distribution. +func (b Bernoulli) Mean() float64 { + return b.P +} + +// Median returns the median of the probability distribution. +func (b Bernoulli) Median() float64 { + p := b.P + switch { + case p < 0.5: + return 0 + case p > 0.5: + return 1 + default: + return 0.5 + } +} + +// NumParameters returns the number of parameters in the distribution. +func (Bernoulli) NumParameters() int { + return 1 +} + +// Prob computes the value of the probability distribution at x. +func (b Bernoulli) Prob(x float64) float64 { + return math.Exp(b.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (b Bernoulli) Quantile(p float64) float64 { + if p < 0 || 1 < p { + panic(badPercentile) + } + if p < 1-b.P { + return 0 + } + return 1 +} + +// Rand returns a random sample drawn from the distribution. +func (b Bernoulli) Rand() float64 { + var rnd float64 + if b.Source == nil { + rnd = rand.Float64() + } else { + rnd = b.Source.Float64() + } + if rnd < b.P { + return 1 + } + return 0 +} + +// Skewness returns the skewness of the distribution. +func (b Bernoulli) Skewness() float64 { + return (1 - 2*b.P) / math.Sqrt(b.P*(1-b.P)) +} + +// StdDev returns the standard deviation of the probability distribution. +func (b Bernoulli) StdDev() float64 { + return math.Sqrt(b.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (b Bernoulli) Survival(x float64) float64 { + return 1 - b.CDF(x) +} + +// Variance returns the variance of the probability distribution. +func (b Bernoulli) Variance() float64 { + return b.P * (1 - b.P) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/bernoulli_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/bernoulli_test.go new file mode 100644 index 00000000..107135ec --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/bernoulli_test.go @@ -0,0 +1,23 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import "testing" + +func TestBernoulli(t *testing.T) { + for i, dist := range []Bernoulli{ + { + P: 0.5, + }, + { + P: 0.9, + }, + { + P: 0.2, + }, + } { + testFullDist(t, dist, i, false) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/beta.go b/vendor/gonum.org/v1/gonum/stat/distuv/beta.go new file mode 100644 index 00000000..7c456009 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/beta.go @@ -0,0 +1,126 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/mathext" +) + +// Beta implements the Beta distribution, a two-parameter continuous distribution +// with support between 0 and 1. +// +// The beta distribution has density function +// x^(α-1) * (1-x)^(β-1) * Γ(α+β) / (Γ(α)*Γ(β)) +// +// For more information, see https://en.wikipedia.org/wiki/Beta_distribution +type Beta struct { + // Alpha is the left shape parameter of the distribution. Alpha must be greater + // than 0. + Alpha float64 + // Beta is the right shape parameter of the distribution. Beta must be greater + // than 0. + Beta float64 + + Source *rand.Rand +} + +// CDF computes the value of the cumulative distribution function at x. +func (b Beta) CDF(x float64) float64 { + if x <= 0 { + return 0 + } + if x >= 1 { + return 1 + } + return mathext.RegIncBeta(b.Alpha, b.Beta, x) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (b Beta) ExKurtosis() float64 { + num := 6 * ((b.Alpha-b.Beta)*(b.Alpha-b.Beta)*(b.Alpha+b.Beta+1) - b.Alpha*b.Beta*(b.Alpha+b.Beta+2)) + den := b.Alpha * b.Beta * (b.Alpha + b.Beta + 2) * (b.Alpha + b.Beta + 3) + return num / den +} + +// LogProb computes the natural logarithm of the value of the probability +// density function at x. +func (b Beta) LogProb(x float64) float64 { + if x < 0 || x > 1 { + return math.Inf(-1) + } + + if b.Alpha <= 0 || b.Beta <= 0 { + panic("beta: negative parameters") + } + + lab, _ := math.Lgamma(b.Alpha + b.Beta) + la, _ := math.Lgamma(b.Alpha) + lb, _ := math.Lgamma(b.Beta) + return lab - la - lb + (b.Alpha-1)*math.Log(x) + (b.Beta-1)*math.Log(1-x) +} + +// Mean returns the mean of the probability distribution. +func (b Beta) Mean() float64 { + return b.Alpha / (b.Alpha + b.Beta) +} + +// Mode returns the mode of the distribution. +// +// Mode returns NaN if either parameter is less than or equal to 1 as a special case. +func (b Beta) Mode() float64 { + if b.Alpha <= 1 || b.Beta <= 1 { + return math.NaN() + } + return (b.Alpha - 1) / (b.Alpha + b.Beta - 2) +} + +// NumParameters returns the number of parameters in the distribution. +func (b Beta) NumParameters() int { + return 2 +} + +// Prob computes the value of the probability density function at x. +func (b Beta) Prob(x float64) float64 { + return math.Exp(b.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative distribution function. +func (b Beta) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + return mathext.InvRegIncBeta(b.Alpha, b.Beta, p) +} + +// Rand returns a random sample drawn from the distribution. +func (b Beta) Rand() float64 { + ga := Gamma{Alpha: b.Alpha, Beta: 1, Source: b.Source}.Rand() + gb := Gamma{Alpha: b.Beta, Beta: 1, Source: b.Source}.Rand() + return ga / (ga + gb) +} + +// StdDev returns the standard deviation of the probability distribution. +func (b Beta) StdDev() float64 { + return math.Sqrt(b.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (b Beta) Survival(x float64) float64 { + switch { + case x <= 0: + return 1 + case x >= 1: + return 0 + } + return mathext.RegIncBeta(b.Beta, b.Alpha, 1-x) +} + +// Variance returns the variance of the probability distribution. +func (b Beta) Variance() float64 { + return b.Alpha * b.Beta / ((b.Alpha + b.Beta) * (b.Alpha + b.Beta) * (b.Alpha + b.Beta + 1)) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/beta_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/beta_test.go new file mode 100644 index 00000000..ffa1c25b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/beta_test.go @@ -0,0 +1,61 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math" + "math/rand" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestBetaProb(t *testing.T) { + // Values a comparison with scipy + for _, test := range []struct { + x, alpha, beta, want float64 + }{ + {0.1, 2, 0.5, 0.079056941504209499}, + {0.5, 1, 5.1, 0.29740426605235754}, + {0.1, 0.5, 0.5, 1.0610329539459691}, + {1, 0.5, 0.5, math.Inf(1)}, + {-1, 0.5, 0.5, 0}, + } { + pdf := Beta{Alpha: test.alpha, Beta: test.beta}.Prob(test.x) + if !floats.EqualWithinAbsOrRel(pdf, test.want, 1e-10, 1e-10) { + t.Errorf("Pdf mismatch. Got %v, want %v", pdf, test.want) + } + } +} + +func TestBetaRand(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for i, b := range []Beta{ + {Alpha: 0.5, Beta: 0.5, Source: src}, + {Alpha: 5, Beta: 1, Source: src}, + {Alpha: 2, Beta: 2, Source: src}, + {Alpha: 2, Beta: 5, Source: src}, + } { + testBeta(t, b, i) + } +} + +func testBeta(t *testing.T, b Beta, i int) { + tol := 1e-2 + const n = 5e4 + const bins = 10 + x := make([]float64, n) + generateSamples(x, b) + sort.Float64s(x) + + testRandLogProbContinuous(t, i, 0, x, b, tol, bins) + checkMean(t, i, x, b, tol) + checkVarAndStd(t, i, x, b, tol) + checkExKurtosis(t, i, x, b, 5e-2) + checkProbContinuous(t, i, x, b, 1e-3) + checkQuantileCDFSurvival(t, i, x, b, tol) + checkProbQuantContinuous(t, i, x, b, tol) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/categorical.go b/vendor/gonum.org/v1/gonum/stat/distuv/categorical.go new file mode 100644 index 00000000..d2053e93 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/categorical.go @@ -0,0 +1,184 @@ +// 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 distuv + +import ( + "math" + "math/rand" +) + +// Categorical is an extension of the Bernoulli distribution where x takes +// values {0, 1, ..., len(w)-1} where w is the weight vector. Categorical must +// be initialized with NewCategorical. +type Categorical struct { + weights []float64 + + // heap is a weight heap. + // + // It keeps a heap-organised sum of remaining + // index weights that are available to be taken + // from. + // + // Each element holds the sum of weights for + // the corresponding index, plus the sum of + // of its children's weights; the children + // of an element i can be found at positions + // 2*(i+1)-1 and 2*(i+1). The root of the + // weight heap is at element 0. + // + // See comments in container/heap for an + // explanation of the layout of a heap. + heap []float64 + + src *rand.Rand +} + +// NewCategorical constructs a new categorical distribution where the probability +// that x equals i is proportional to w[i]. All of the weights must be +// nonnegative, and at least one of the weights must be positive. +func NewCategorical(w []float64, src *rand.Rand) Categorical { + c := Categorical{ + weights: make([]float64, len(w)), + heap: make([]float64, len(w)), + src: src, + } + c.ReweightAll(w) + return c +} + +// CDF computes the value of the cumulative density function at x. +func (c Categorical) CDF(x float64) float64 { + var cdf float64 + for i, w := range c.weights { + if x < float64(i) { + break + } + cdf += w + } + return cdf / c.heap[0] +} + +// Entropy returns the entropy of the distribution. +func (c Categorical) Entropy() float64 { + var ent float64 + for _, w := range c.weights { + if w == 0 { + continue + } + p := w / c.heap[0] + ent += p * math.Log(p) + } + return -ent +} + +// Len returns the number of values x could possibly take (the length of the +// initial supplied weight vector). +func (c Categorical) Len() int { + return len(c.weights) +} + +// Mean returns the mean of the probability distribution. +func (c Categorical) Mean() float64 { + var mean float64 + for i, v := range c.weights { + mean += float64(i) * v + } + return mean / c.heap[0] +} + +// Prob computes the value of the probability density function at x. +func (c Categorical) Prob(x float64) float64 { + xi := int(x) + if float64(xi) != x { + return 0 + } + if xi < 0 || xi > len(c.weights)-1 { + return 0 + } + return c.weights[xi] / c.heap[0] +} + +// LogProb computes the natural logarithm of the value of the probability density function at x. +func (c Categorical) LogProb(x float64) float64 { + return math.Log(c.Prob(x)) +} + +// Rand returns a random draw from the categorical distribution. +func (c Categorical) Rand() float64 { + var r float64 + if c.src == nil { + r = c.heap[0] * rand.Float64() + } else { + r = c.heap[0] * c.src.Float64() + } + i := 1 + last := -1 + left := len(c.weights) + for { + if r -= c.weights[i-1]; r <= 0 { + break // Fall within item i-1. + } + i <<= 1 // Move to left child. + if d := c.heap[i-1]; r > d { + r -= d + // If enough r to pass left child, + // move to right child state will + // be caught at break above. + i++ + } + if i == last || left < 0 { + panic("categorical: bad sample") + } + last = i + left-- + } + return float64(i - 1) +} + +// Reweight sets the weight of item idx to w. The input weight must be +// non-negative, and after reweighting at least one of the weights must be +// positive. +func (c Categorical) Reweight(idx int, w float64) { + if w < 0 { + panic("categorical: negative weight") + } + w, c.weights[idx] = c.weights[idx]-w, w + idx++ + for idx > 0 { + c.heap[idx-1] -= w + idx >>= 1 + } + if c.heap[0] <= 0 { + panic("categorical: sum of the weights non-positive") + } +} + +// ReweightAll resets the weights of the distribution. ReweightAll panics if +// len(w) != c.Len. All of the weights must be nonnegative, and at least one of +// the weights must be positive. +func (c Categorical) ReweightAll(w []float64) { + if len(w) != c.Len() { + panic("categorical: length of the slices do not match") + } + for _, v := range w { + if v < 0 { + panic("categorical: negative weight") + } + } + copy(c.weights, w) + c.reset() +} + +func (c Categorical) reset() { + copy(c.heap, c.weights) + for i := len(c.heap) - 1; i > 0; i-- { + // Sometimes 1-based counting makes sense. + c.heap[((i+1)>>1)-1] += c.heap[i] + } + // TODO(btracey): Renormalization for weird weights? + if c.heap[0] <= 0 { + panic("categorical: sum of the weights non-positive") + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/categorical_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/categorical_test.go new file mode 100644 index 00000000..decd181d --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/categorical_test.go @@ -0,0 +1,196 @@ +// 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 distuv + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestCategoricalProb(t *testing.T) { + for _, test := range [][]float64{ + {1, 2, 3, 0}, + } { + dist := NewCategorical(test, nil) + norm := make([]float64, len(test)) + floats.Scale(1/floats.Sum(norm), norm) + for i, v := range norm { + p := dist.Prob(float64(i)) + if math.Abs(p-v) > 1e-14 { + t.Errorf("Probability mismatch element %d", i) + } + p = dist.Prob(float64(i) + 0.5) + if p != 0 { + t.Errorf("Non-zero probability for non-integer x") + } + } + p := dist.Prob(-1) + if p != 0 { + t.Errorf("Non-zero probability for -1") + } + p = dist.Prob(float64(len(test))) + if p != 0 { + t.Errorf("Non-zero probability for len(test)") + } + } +} + +func TestCategoricalRand(t *testing.T) { + for _, test := range [][]float64{ + {1, 2, 3, 0}, + } { + dist := NewCategorical(test, nil) + nSamples := 2000000 + counts := sampleCategorical(t, dist, nSamples) + + probs := make([]float64, len(test)) + for i := range probs { + probs[i] = dist.Prob(float64(i)) + } + same := samedDistCategorical(dist, counts, probs, 1e-2) + if !same { + t.Errorf("Probability mismatch. Want %v, got %v", probs, counts) + } + + dist.Reweight(len(test)-1, 10) + counts = sampleCategorical(t, dist, nSamples) + probs = make([]float64, len(test)) + for i := range probs { + probs[i] = dist.Prob(float64(i)) + } + same = samedDistCategorical(dist, counts, probs, 1e-2) + if !same { + t.Errorf("Probability mismatch after Reweight. Want %v, got %v", probs, counts) + } + + w := make([]float64, len(test)) + for i := range w { + w[i] = rand.Float64() + } + + dist.ReweightAll(w) + counts = sampleCategorical(t, dist, nSamples) + probs = make([]float64, len(test)) + for i := range probs { + probs[i] = dist.Prob(float64(i)) + } + same = samedDistCategorical(dist, counts, probs, 1e-2) + if !same { + t.Errorf("Probability mismatch after ReweightAll. Want %v, got %v", probs, counts) + } + } +} + +func sampleCategorical(t *testing.T, dist Categorical, nSamples int) []float64 { + counts := make([]float64, dist.Len()) + for i := 0; i < nSamples; i++ { + v := dist.Rand() + if float64(int(v)) != v { + t.Fatalf("Random number is not an integer") + } + counts[int(v)]++ + } + sum := floats.Sum(counts) + floats.Scale(1/sum, counts) + return counts +} + +func samedDistCategorical(dist Categorical, counts, probs []float64, tol float64) bool { + same := true + for i, prob := range probs { + if prob == 0 && counts[i] != 0 { + same = false + break + } + if !floats.EqualWithinAbsOrRel(prob, counts[i], tol, tol) { + same = false + break + } + } + return same +} + +func TestCategoricalCDF(t *testing.T) { + for _, test := range [][]float64{ + {1, 2, 3, 0, 4}, + } { + c := make([]float64, len(test)) + copy(c, test) + floats.Scale(1/floats.Sum(c), c) + sum := make([]float64, len(test)) + floats.CumSum(sum, c) + + dist := NewCategorical(test, nil) + cdf := dist.CDF(-0.5) + if cdf != 0 { + t.Errorf("CDF of negative number not zero") + } + for i := range c { + cdf := dist.CDF(float64(i)) + if math.Abs(cdf-sum[i]) > 1e-14 { + t.Errorf("CDF mismatch %v. Want %v, got %v.", float64(i), sum[i], cdf) + } + cdfp := dist.CDF(float64(i) + 0.5) + if cdfp != cdf { + t.Errorf("CDF mismatch for non-integer input") + } + } + } +} + +func TestCategoricalEntropy(t *testing.T) { + for _, test := range []struct { + weights []float64 + entropy float64 + }{ + { + weights: []float64{1, 1}, + entropy: math.Ln2, + }, + { + weights: []float64{1, 1, 1, 1}, + entropy: math.Log(4), + }, + { + weights: []float64{0, 0, 1, 1, 0, 0}, + entropy: math.Ln2, + }, + } { + dist := NewCategorical(test.weights, nil) + entropy := dist.Entropy() + if math.IsNaN(entropy) || math.Abs(entropy-test.entropy) > 1e-14 { + t.Errorf("Entropy mismatch. Want %v, got %v.", test.entropy, entropy) + } + } +} + +func TestCategoricalMean(t *testing.T) { + for _, test := range []struct { + weights []float64 + mean float64 + }{ + { + weights: []float64{10, 0, 0, 0}, + mean: 0, + }, + { + weights: []float64{0, 10, 0, 0}, + mean: 1, + }, + { + weights: []float64{1, 2, 3, 4}, + mean: 2, + }, + } { + dist := NewCategorical(test.weights, nil) + mean := dist.Mean() + if math.IsNaN(mean) || math.Abs(mean-test.mean) > 1e-14 { + t.Errorf("Entropy mismatch. Want %v, got %v.", test.mean, mean) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/chisquared.go b/vendor/gonum.org/v1/gonum/stat/distuv/chisquared.go new file mode 100644 index 00000000..2c9827b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/chisquared.go @@ -0,0 +1,99 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/mathext" +) + +// ChiSquared implements the χ² distribution, a one parameter distribution +// with support on the positive numbers. +// +// The density function is given by +// 1/(2^{k/2} * Γ(k/2)) * x^{k/2 - 1} * e^{-x/2} +// It is a special case of the Gamma distribution, Γ(k/2, 1/2). +// +// For more information, see https://en.wikipedia.org/wiki/Chi-squared_distribution. +type ChiSquared struct { + // K is the shape parameter, corresponding to the degrees of freedom. Must + // be greater than 0. + K float64 + + Src *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (c ChiSquared) CDF(x float64) float64 { + return mathext.GammaInc(c.K/2, x/2) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (c ChiSquared) ExKurtosis() float64 { + return 12 / c.K +} + +// LogProb computes the natural logarithm of the value of the probability +// density function at x. +func (c ChiSquared) LogProb(x float64) float64 { + if x < 0 { + return math.Inf(-1) + } + lg, _ := math.Lgamma(c.K / 2) + return (c.K/2-1)*math.Log(x) - x/2 - (c.K/2)*math.Ln2 - lg +} + +// Mean returns the mean of the probability distribution. +func (c ChiSquared) Mean() float64 { + return c.K +} + +// Mode returns the mode of the distribution. +func (c ChiSquared) Mode() float64 { + return math.Min(c.K-2, 0) +} + +// NumParameters returns the number of parameters in the distribution. +func (c ChiSquared) NumParameters() int { + return 1 +} + +// Prob computes the value of the probability density function at x. +func (c ChiSquared) Prob(x float64) float64 { + return math.Exp(c.LogProb(x)) +} + +// Rand returns a random sample drawn from the distribution. +func (c ChiSquared) Rand() float64 { + return Gamma{c.K / 2, 0.5, c.Src}.Rand() +} + +// Quantile returns the inverse of the cumulative distribution function. +func (c ChiSquared) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + return mathext.GammaIncInv(0.5*c.K, p) * 2 +} + +// StdDev returns the standard deviation of the probability distribution. +func (c ChiSquared) StdDev() float64 { + return math.Sqrt(c.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (c ChiSquared) Survival(x float64) float64 { + if x < 0 { + return 1 + } + return mathext.GammaIncComp(0.5*c.K, 0.5*x) +} + +// Variance returns the variance of the probability distribution. +func (c ChiSquared) Variance() float64 { + return 2 * c.K +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/chisquared_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/chisquared_test.go new file mode 100644 index 00000000..56941cd0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/chisquared_test.go @@ -0,0 +1,78 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math/rand" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestChiSquaredProb(t *testing.T) { + for _, test := range []struct { + x, k, want float64 + }{ + {10, 3, 0.0085003666025203432}, + {2.3, 3, 0.19157345407042367}, + {0.8, 0.2, 0.080363259903912673}, + } { + pdf := ChiSquared{test.k, nil}.Prob(test.x) + if !floats.EqualWithinAbsOrRel(pdf, test.want, 1e-10, 1e-10) { + t.Errorf("Pdf mismatch, x = %v, K = %v. Got %v, want %v", test.x, test.k, pdf, test.want) + } + } +} + +func TestChiSquaredCDF(t *testing.T) { + for _, test := range []struct { + x, k, want float64 + }{ + // Values calculated with scipy.stats.chi2.cdf + {0, 1, 0}, + {0.01, 5, 5.3002700426865167e-07}, + {0.05, 3, 0.002929332764619924}, + {0.5, 2, 0.22119921692859512}, + {0.95, 3, 0.1866520918701263}, + {0.99, 5, 0.036631697220869196}, + {1, 1, 0.68268949213708596}, + {1.5, 4, 0.17335853270322427}, + {10, 10, 0.55950671493478743}, + {25, 15, 0.95005656637357172}, + } { + cdf := ChiSquared{test.k, nil}.CDF(test.x) + if !floats.EqualWithinAbsOrRel(cdf, test.want, 1e-10, 1e-10) { + t.Errorf("CDF mismatch, x = %v, K = %v. Got %v, want %v", test.x, test.k, cdf, test.want) + } + } +} + +func TestChiSquared(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for i, b := range []ChiSquared{ + {3, src}, + {1.5, src}, + {0.9, src}, + } { + testChiSquared(t, b, i) + } +} + +func testChiSquared(t *testing.T, c ChiSquared, i int) { + tol := 1e-2 + const n = 1e5 + const bins = 50 + x := make([]float64, n) + generateSamples(x, c) + sort.Float64s(x) + + testRandLogProbContinuous(t, i, 0, x, c, tol, bins) + checkMean(t, i, x, c, tol) + checkVarAndStd(t, i, x, c, tol) + checkExKurtosis(t, i, x, c, 7e-2) + checkProbContinuous(t, i, x, c, 1e-3) + checkQuantileCDFSurvival(t, i, x, c, 1e-2) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/constants.go b/vendor/gonum.org/v1/gonum/stat/distuv/constants.go new file mode 100644 index 00000000..9de7d4dc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/constants.go @@ -0,0 +1,24 @@ +// 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 distuv + +const ( + // oneOverRoot2Pi is the value of 1/(2Pi)^(1/2) + // http://www.wolframalpha.com/input/?i=1%2F%282+*+pi%29%5E%281%2F2%29 + oneOverRoot2Pi = 0.39894228040143267793994605993438186847585863116493465766592582967065792589930183850125233390730693643030255886263518268 + + //LogRoot2Pi is the value of log(sqrt(2*Pi)) + logRoot2Pi = 0.91893853320467274178032973640561763986139747363778341281715154048276569592726039769474329863595419762200564662463433744 + negLogRoot2Pi = -logRoot2Pi + log2Pi = 1.8378770664093454835606594728112352797227949472755668 + ln2 = 0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057068573368552023 + + // Euler–Mascheroni constant. + eulerGamma = 0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495146314472498070824809605 +) + +const ( + panicNameMismatch = "parameter name mismatch" +) diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/distribution_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/distribution_test.go new file mode 100644 index 00000000..722c438a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/distribution_test.go @@ -0,0 +1,293 @@ +// 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 distuv + +import ( + "math" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/integrate/quad" + "gonum.org/v1/gonum/stat" +) + +type meaner interface { + Mean() float64 +} + +type quantiler interface { + Quantile(float64) float64 +} + +type medianer interface { + quantiler + Median() float64 +} + +type varStder interface { + StdDev() float64 + Variance() float64 +} + +type entropyer interface { + LogProber + Entropy() float64 +} + +type exKurtosiser interface { + ExKurtosis() float64 + Mean() float64 +} + +type skewnesser interface { + StdDev() float64 + Mean() float64 + Skewness() float64 +} + +type cumulanter interface { + Quantiler + CDF(x float64) float64 + Survival(x float64) float64 +} + +func generateSamples(x []float64, r Rander) { + for i := range x { + x[i] = r.Rand() + } +} + +type probLogprober interface { + Prob(x float64) float64 + LogProb(x float64) float64 +} + +type cumulantProber interface { + cumulanter + probLogprober +} + +func checkMean(t *testing.T, i int, x []float64, m meaner, tol float64) { + mean := stat.Mean(x, nil) + if !floats.EqualWithinAbsOrRel(mean, m.Mean(), tol, tol) { + t.Errorf("Mean mismatch case %v: want: %v, got: %v", i, mean, m.Mean()) + } +} + +func checkMedian(t *testing.T, i int, x []float64, m medianer, tol float64) { + median := stat.Quantile(0.5, stat.Empirical, x, nil) + if !floats.EqualWithinAbsOrRel(median, m.Median(), tol, tol) { + t.Errorf("Median mismatch case %v: want: %v, got: %v", i, median, m.Median()) + } +} + +func checkVarAndStd(t *testing.T, i int, x []float64, v varStder, tol float64) { + variance := stat.Variance(x, nil) + if !floats.EqualWithinAbsOrRel(variance, v.Variance(), tol, tol) { + t.Errorf("Variance mismatch case %v: want: %v, got: %v", i, variance, v.Variance()) + } + std := math.Sqrt(variance) + if !floats.EqualWithinAbsOrRel(std, v.StdDev(), tol, tol) { + t.Errorf("StdDev mismatch case %v: want: %v, got: %v", i, std, v.StdDev()) + } +} + +func checkEntropy(t *testing.T, i int, x []float64, e entropyer, tol float64) { + tmp := make([]float64, len(x)) + for i, v := range x { + tmp[i] = -e.LogProb(v) + } + entropy := stat.Mean(tmp, nil) + if !floats.EqualWithinAbsOrRel(entropy, e.Entropy(), tol, tol) { + t.Errorf("Entropy mismatch case %v: want: %v, got: %v", i, entropy, e.Entropy()) + } +} + +func checkExKurtosis(t *testing.T, i int, x []float64, e exKurtosiser, tol float64) { + mean := e.Mean() + tmp := make([]float64, len(x)) + for i, x := range x { + tmp[i] = math.Pow(x-mean, 4) + } + variance := stat.Variance(x, nil) + mu4 := stat.Mean(tmp, nil) + kurtosis := mu4/(variance*variance) - 3 + if !floats.EqualWithinAbsOrRel(kurtosis, e.ExKurtosis(), tol, tol) { + t.Errorf("ExKurtosis mismatch case %v: want: %v, got: %v", i, kurtosis, e.ExKurtosis()) + } +} + +func checkSkewness(t *testing.T, i int, x []float64, s skewnesser, tol float64) { + mean := s.Mean() + std := s.StdDev() + tmp := make([]float64, len(x)) + for i, v := range x { + tmp[i] = math.Pow(v-mean, 3) + } + mu3 := stat.Mean(tmp, nil) + skewness := mu3 / math.Pow(std, 3) + if !floats.EqualWithinAbsOrRel(skewness, s.Skewness(), tol, tol) { + t.Errorf("Skewness mismatch case %v: want: %v, got: %v", i, skewness, s.Skewness()) + } +} + +func checkQuantileCDFSurvival(t *testing.T, i int, xs []float64, c cumulanter, tol float64) { + // Quantile, CDF, and survival check. + for i, p := range []float64{0.1, 0.25, 0.5, 0.75, 0.9} { + x := c.Quantile(p) + cdf := c.CDF(x) + estCDF := stat.CDF(x, stat.Empirical, xs, nil) + if !floats.EqualWithinAbsOrRel(cdf, estCDF, tol, tol) { + t.Errorf("CDF mismatch case %v: want: %v, got: %v", i, estCDF, cdf) + } + if !floats.EqualWithinAbsOrRel(cdf, p, tol, tol) { + t.Errorf("Quantile/CDF mismatch case %v: want: %v, got: %v", i, p, cdf) + } + if math.Abs(1-cdf-c.Survival(x)) > 1e-14 { + t.Errorf("Survival/CDF mismatch case %v: want: %v, got: %v", i, 1-cdf, c.Survival(x)) + } + } +} + +func checkProbContinuous(t *testing.T, i int, x []float64, p probLogprober, tol float64) { + // Check that the PDF is consistent (integrates to 1). + q := quad.Fixed(p.Prob, math.Inf(-1), math.Inf(1), 1000000, nil, 0) + if math.Abs(q-1) > tol { + t.Errorf("Probability distribution doesn't integrate to 1. Case %v: Got %v", i, q) + } + + // Check that PDF and LogPDF are consistent. + for i, v := range x { + if math.Abs(math.Log(p.Prob(v))-p.LogProb(v)) > 1e-14 { + t.Errorf("Prob and LogProb mismatch case %v at %v: want %v, got %v", i, v, math.Log(v), p.LogProb(v)) + break + } + } +} + +// checkProbQuantContinuous checks that the Prob, Rand, and Quantile are all consistent. +// checkProbContinuous only checks that Prob is a valid distribution (integrates +// to 1 and greater than 0). However, this is also true if the PDF of a different +// distribution is used. This checks that PDF is also consistent with the +// CDF implementation and the random samples. +func checkProbQuantContinuous(t *testing.T, i int, xs []float64, c cumulantProber, tol float64) { + ps := make([]float64, 101) + floats.Span(ps, 0, 1) + + var xp, x float64 + for i, p := range ps { + x = c.Quantile(p) + if p == 0 { + xp = x + if floats.Min(xs) < x { + t.Errorf("Sample of x less than Quantile(0). Case %v.", i) + break + } + continue + } + if p == 1 { + if floats.Max(xs) > x { + t.Errorf("Sample of x greater than Quantile(1). Case %v.", i) + break + } + } + + // The integral of the PDF between xp and x should be the difference in + // the quantiles. + q := quad.Fixed(c.Prob, xp, x, 1000, nil, 0) + if math.Abs(q-(p-ps[i-1])) > 1e-5 { + t.Errorf("Integral of PDF doesn't match quantile. Case %v. Want %v, got %v.", i, p-ps[i-1], q) + break + } + + pEst := stat.CDF(x, stat.Empirical, xs, nil) + if math.Abs(pEst-p) > tol { + t.Errorf("Empirical CDF doesn't match quantile. Case %v.", i) + } + xp = x + } +} + +// checkProbDiscrete confirms that PDF and Rand are consistent for discrete distributions. +func checkProbDiscrete(t *testing.T, i int, xs []float64, p probLogprober, tol float64) { + // Make a map of all of the unique samples. + m := make(map[float64]int) + for _, v := range xs { + m[v]++ + } + for x, count := range m { + prob := float64(count) / float64(len(xs)) + if math.Abs(prob-p.Prob(x)) > tol { + t.Errorf("PDF mismatch case %v at %v: want %v, got %v", i, x, prob, p.Prob(x)) + } + if math.Abs(math.Log(p.Prob(x))-p.LogProb(x)) > 1e-14 { + t.Errorf("Prob and LogProb mismatch case %v at %v: want %v, got %v", i, x, math.Log(x), p.LogProb(x)) + } + } +} + +// dist is a type that implements the standard set of routines. +type fullDist interface { + CDF(x float64) float64 + Entropy() float64 + ExKurtosis() float64 + LogProb(x float64) float64 + Mean() float64 + Median() float64 + NumParameters() int + Prob(x float64) float64 + Quantile(p float64) float64 + Rand() float64 + Skewness() float64 + StdDev() float64 + Survival(x float64) float64 + Variance() float64 +} + +// testFullDist tests all of the functions of a fullDist. +func testFullDist(t *testing.T, f fullDist, i int, continuous bool) { + tol := 1e-2 + const n = 1e6 + x := make([]float64, n) + generateSamples(x, f) + sort.Float64s(x) + + checkMean(t, i, x, f, tol) + checkVarAndStd(t, i, x, f, tol) + checkEntropy(t, i, x, f, tol) + checkExKurtosis(t, i, x, f, tol) + checkSkewness(t, i, x, f, tol) + if continuous { + // In a discrete distribution, the median may not have positive probability. + checkMedian(t, i, x, f, tol) + // In a discrete distribution, the CDF and Quantile may not be perfect mappings. + checkQuantileCDFSurvival(t, i, x, f, tol) + // Integrate over the PDF + checkProbContinuous(t, i, x, f, 1e-10) + checkProbQuantContinuous(t, i, x, f, tol) + } else { + // Check against empirical PDF. + checkProbDiscrete(t, i, x, f, tol) + } +} + +// testRandLogProb tests that LogProb and Rand give consistent results. This +// can be used when the distribution does not implement CDF. +func testRandLogProbContinuous(t *testing.T, i int, min float64, x []float64, f LogProber, tol float64, bins int) { + for cdf := 1 / float64(bins); cdf <= 1-1/float64(bins); cdf += 1 / float64(bins) { + // Get the estimated CDF from the samples + pt := stat.Quantile(cdf, stat.Empirical, x, nil) + + prob := func(x float64) float64 { + return math.Exp(f.LogProb(x)) + } + // Integrate the PDF to find the CDF + estCDF := quad.Fixed(prob, min, pt, 1000, nil, 0) + if !floats.EqualWithinAbsOrRel(cdf, estCDF, tol, tol) { + t.Errorf("Mismatch between integral of PDF and empirical CDF. Case %v. Want %v, got %v", i, cdf, estCDF) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/doc.go b/vendor/gonum.org/v1/gonum/stat/distuv/doc.go new file mode 100644 index 00000000..bdf073f5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package distuv provides univariate random distribution types. +package distuv // import "gonum.org/v1/gonum/stat/distuv" diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/exponential.go b/vendor/gonum.org/v1/gonum/stat/distuv/exponential.go new file mode 100644 index 00000000..c29f9fef --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/exponential.go @@ -0,0 +1,259 @@ +// 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 distuv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/stat" +) + +// Exponential represents the exponential distribution (https://en.wikipedia.org/wiki/Exponential_distribution). +type Exponential struct { + Rate float64 + Source *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (e Exponential) CDF(x float64) float64 { + if x < 0 { + return 0 + } + return 1 - math.Exp(-e.Rate*x) +} + +// ConjugateUpdate updates the parameters of the distribution from the sufficient +// statistics of a set of samples. The sufficient statistics, suffStat, have been +// observed with nSamples observations. The prior values of the distribution are those +// currently in the distribution, and have been observed with priorStrength samples. +// +// For the exponential distribution, the sufficient statistic is the inverse of +// the mean of the samples. +// The prior is having seen priorStrength[0] samples with inverse mean Exponential.Rate +// As a result of this function, Exponential.Rate is updated based on the weighted +// samples, and priorStrength is modified to include the new number of samples observed. +// +// This function panics if len(suffStat) != 1 or len(priorStrength) != 1. +func (e *Exponential) ConjugateUpdate(suffStat []float64, nSamples float64, priorStrength []float64) { + if len(suffStat) != 1 { + panic("exponential: incorrect suffStat length") + } + if len(priorStrength) != 1 { + panic("exponential: incorrect priorStrength length") + } + + totalSamples := nSamples + priorStrength[0] + + totalSum := nSamples / suffStat[0] + if !(priorStrength[0] == 0) { + totalSum += priorStrength[0] / e.Rate + } + e.Rate = totalSamples / totalSum + priorStrength[0] = totalSamples +} + +// Entropy returns the entropy of the distribution. +func (e Exponential) Entropy() float64 { + return 1 - math.Log(e.Rate) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (Exponential) ExKurtosis() float64 { + return 6 +} + +// Fit sets the parameters of the probability distribution from the +// data samples x with relative weights w. +// If weights is nil, then all the weights are 1. +// If weights is not nil, then the len(weights) must equal len(samples). +func (e *Exponential) Fit(samples, weights []float64) { + suffStat := make([]float64, e.NumSuffStat()) + nSamples := e.SuffStat(suffStat, samples, weights) + e.ConjugateUpdate(suffStat, nSamples, make([]float64, e.NumSuffStat())) +} + +// LogProb computes the natural logarithm of the value of the probability density function at x. +func (e Exponential) LogProb(x float64) float64 { + if x < 0 { + return math.Inf(-1) + } + return math.Log(e.Rate) - e.Rate*x +} + +// Mean returns the mean of the probability distribution. +func (e Exponential) Mean() float64 { + return 1 / e.Rate +} + +// Median returns the median of the probability distribution. +func (e Exponential) Median() float64 { + return math.Ln2 / e.Rate +} + +// Mode returns the mode of the probability distribution. +func (Exponential) Mode() float64 { + return 0 +} + +// NumParameters returns the number of parameters in the distribution. +func (Exponential) NumParameters() int { + return 1 +} + +// NumSuffStat returns the number of sufficient statistics for the distribution. +func (Exponential) NumSuffStat() int { + return 1 +} + +// Prob computes the value of the probability density function at x. +func (e Exponential) Prob(x float64) float64 { + return math.Exp(e.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (e Exponential) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + return -math.Log(1-p) / e.Rate +} + +// Rand returns a random sample drawn from the distribution. +func (e Exponential) Rand() float64 { + var rnd float64 + if e.Source == nil { + rnd = rand.ExpFloat64() + } else { + rnd = e.Source.ExpFloat64() + } + return rnd / e.Rate +} + +// Score returns the score function with respect to the parameters of the +// distribution at the input location x. The score function is the derivative +// of the log-likelihood at x with respect to the parameters +// (∂/∂θ) log(p(x;θ)) +// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise +// Score will panic, and the derivative is stored in-place into deriv. If deriv +// is nil a new slice will be allocated and returned. +// +// The order is [∂LogProb / ∂Rate]. +// +// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29. +// +// Special cases: +// Score(0) = [NaN] +func (e Exponential) Score(deriv []float64, x float64) []float64 { + if deriv == nil { + deriv = make([]float64, e.NumParameters()) + } + if len(deriv) != e.NumParameters() { + panic(badLength) + } + if x > 0 { + deriv[0] = 1/e.Rate - x + return deriv + } + if x < 0 { + deriv[0] = 0 + return deriv + } + deriv[0] = math.NaN() + return deriv +} + +// ScoreInput returns the score function with respect to the input of the +// distribution at the input location specified by x. The score function is the +// derivative of the log-likelihood +// (d/dx) log(p(x)) . +// Special cases: +// ScoreInput(0) = NaN +func (e Exponential) ScoreInput(x float64) float64 { + if x > 0 { + return -e.Rate + } + if x < 0 { + return 0 + } + return math.NaN() +} + +// Skewness returns the skewness of the distribution. +func (Exponential) Skewness() float64 { + return 2 +} + +// StdDev returns the standard deviation of the probability distribution. +func (e Exponential) StdDev() float64 { + return 1 / e.Rate +} + +// SuffStat computes the sufficient statistics of set of samples to update +// the distribution. The sufficient statistics are stored in place, and the +// effective number of samples are returned. +// +// The exponential distribution has one sufficient statistic, the average rate +// of the samples. +// +// If weights is nil, the weights are assumed to be 1, otherwise panics if +// len(samples) != len(weights). Panics if len(suffStat) != NumSuffStat(). +func (Exponential) SuffStat(suffStat, samples, weights []float64) (nSamples float64) { + if len(weights) != 0 && len(samples) != len(weights) { + panic(badLength) + } + + if len(suffStat) != (Exponential{}).NumSuffStat() { + panic(badSuffStat) + } + + if len(weights) == 0 { + nSamples = float64(len(samples)) + } else { + nSamples = floats.Sum(weights) + } + + mean := stat.Mean(samples, weights) + suffStat[0] = 1 / mean + return nSamples +} + +// Survival returns the survival function (complementary CDF) at x. +func (e Exponential) Survival(x float64) float64 { + if x < 0 { + return 1 + } + return math.Exp(-e.Rate * x) +} + +// setParameters modifies the parameters of the distribution. +func (e *Exponential) setParameters(p []Parameter) { + if len(p) != e.NumParameters() { + panic("exponential: incorrect number of parameters to set") + } + if p[0].Name != "Rate" { + panic("exponential: " + panicNameMismatch) + } + e.Rate = p[0].Value +} + +// Variance returns the variance of the probability distribution. +func (e Exponential) Variance() float64 { + return 1 / (e.Rate * e.Rate) +} + +// parameters returns the parameters of the distribution. +func (e Exponential) parameters(p []Parameter) []Parameter { + nParam := e.NumParameters() + if p == nil { + p = make([]Parameter, nParam) + } else if len(p) != nParam { + panic("exponential: improper parameter length") + } + p[0].Name = "Rate" + p[0].Value = e.Rate + return p +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/exponential_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/exponential_test.go new file mode 100644 index 00000000..9c389702 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/exponential_test.go @@ -0,0 +1,71 @@ +// 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 distuv + +import ( + "math" + "testing" +) + +func TestExponentialProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: 1, + cumProb: 0, + logProb: 0, + }, + { + loc: -1, + prob: 0, + cumProb: 0, + logProb: math.Inf(-1), + }, + { + loc: 1, + prob: 1 / (math.E), + cumProb: 0.6321205588285576784044762298385391325541888689682321654921631983025385042551001966428527256540803563, + logProb: -1, + }, + { + loc: 20, + prob: math.Exp(-20), + cumProb: 0.999999997938846377561442172034059619844179023624192724400896307027755338370835976215440646720089072, + logProb: -20, + }, + } + testDistributionProbs(t, Exponential{Rate: 1}, "Exponential", pts) +} + +func TestExponentialFitPrior(t *testing.T) { + testConjugateUpdate(t, func() ConjugateUpdater { return &Exponential{Rate: 13.7} }) +} + +func TestExponentialScore(t *testing.T) { + for _, test := range []*Exponential{ + { + Rate: 1, + }, + { + Rate: 0.35, + }, + { + Rate: 4.6, + }, + } { + testDerivParam(t, test) + } +} + +func TestExponentialFitPanic(t *testing.T) { + e := Exponential{Rate: 2} + defer func() { + r := recover() + if r != nil { + t.Errorf("unexpected panic for Fit call: %v", r) + } + }() + e.Fit(make([]float64, 10), nil) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/f.go b/vendor/gonum.org/v1/gonum/stat/distuv/f.go new file mode 100644 index 00000000..6e689e6e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/f.go @@ -0,0 +1,132 @@ +// 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 distuv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/mathext" +) + +// F implements the F-distribution, a two-parameter continuous distribution +// with support over the positive real numbers. +// +// The F-distribution has density function +// sqrt(((d1*x)^d1) * d2^d2 / ((d1*x+d2)^(d1+d2))) / (x * B(d1/2,d2/2)) +// where B is the beta function. +// +// For more information, see https://en.wikipedia.org/wiki/F-distribution +type F struct { + D1 float64 // Degrees of freedom for the numerator + D2 float64 // Degrees of freedom for the denominator + Source *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (f F) CDF(x float64) float64 { + return mathext.RegIncBeta(f.D1/2, f.D2/2, f.D1*x/(f.D1*x+f.D2)) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +// +// ExKurtosis returns NaN if the D2 parameter is less or equal to 8. +func (f F) ExKurtosis() float64 { + if f.D2 <= 8 { + return math.NaN() + } + return (12 / (f.D2 - 6)) * ((5*f.D2-22)/(f.D2-8) + ((f.D2-4)/f.D1)*((f.D2-2)/(f.D2-8))*((f.D2-2)/(f.D1+f.D2-2))) +} + +// LogProb computes the natural logarithm of the value of the probability +// density function at x. +func (f F) LogProb(x float64) float64 { + return 0.5*(f.D1*math.Log(f.D1*x)+f.D2*math.Log(f.D2)-(f.D1+f.D2)*math.Log(f.D1*x+f.D2)) - math.Log(x) - mathext.Lbeta(f.D1/2, f.D2/2) +} + +// Mean returns the mean of the probability distribution. +// +// Mean returns NaN if the D2 parameter is less than or equal to 2. +func (f F) Mean() float64 { + if f.D2 <= 2 { + return math.NaN() + } + return f.D2 / (f.D2 - 2) +} + +// Mode returns the mode of the distribution. +// +// Mode returns NaN if the D1 parameter is less than or equal to 2. +func (f F) Mode() float64 { + if f.D1 <= 2 { + return math.NaN() + } + return ((f.D1 - 2) / f.D1) * (f.D2 / (f.D2 + 2)) +} + +// NumParameters returns the number of parameters in the distribution. +func (f F) NumParameters() int { + return 2 +} + +// Prob computes the value of the probability density function at x. +func (f F) Prob(x float64) float64 { + return math.Exp(f.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative distribution function. +func (f F) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + y := mathext.InvRegIncBeta(0.5*f.D1, 0.5*f.D2, p) + return f.D2 * y / (f.D1 * (1 - y)) +} + +// Rand returns a random sample drawn from the distribution. +func (f F) Rand() float64 { + u1 := ChiSquared{f.D1, f.Source}.Rand() + u2 := ChiSquared{f.D2, f.Source}.Rand() + return (u1 / f.D1) / (u2 / f.D2) +} + +// Skewness returns the skewness of the distribution. +// +// Skewness returns NaN if the D2 parameter is less than or equal to 6. +func (f F) Skewness() float64 { + if f.D2 <= 6 { + return math.NaN() + } + num := (2*f.D1 + f.D2 - 2) * math.Sqrt(8*(f.D2-4)) + den := (f.D2 - 6) * math.Sqrt(f.D1*(f.D1+f.D2-2)) + return num / den +} + +// StdDev returns the standard deviation of the probability distribution. +// +// StdDev returns NaN if the D2 parameter is less than or equal to 4. +func (f F) StdDev() float64 { + if f.D2 <= 4 { + return math.NaN() + } + return math.Sqrt(f.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (f F) Survival(x float64) float64 { + return 1 - f.CDF(x) +} + +// Variance returns the variance of the probability distribution. +// +// Variance returns NaN if the D2 parameter is less than or equal to 4. +func (f F) Variance() float64 { + if f.D2 <= 4 { + return math.NaN() + } + num := 2 * f.D2 * f.D2 * (f.D1 + f.D2 - 2) + den := f.D1 * (f.D2 - 2) * (f.D2 - 2) * (f.D2 - 4) + return num / den +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/f_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/f_test.go new file mode 100644 index 00000000..7e5dfbea --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/f_test.go @@ -0,0 +1,89 @@ +// 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 distuv + +import ( + "math/rand" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestFProb(t *testing.T) { + for _, test := range []struct { + x, d1, d2, want float64 + }{ + // Values calculated with scipy.stats.f + {0.0001, 4, 6, 0.00053315559110558126}, + {0.1, 1, 1, 0.91507658371794609}, + {0.5, 11, 7, 0.66644660411410883}, + {0.9, 20, 15, 0.88293424959522437}, + {1, 1, 1, 0.15915494309189535}, + {2, 15, 12, 0.16611971273429088}, + {5, 4, 8, 0.013599775603702537}, + {10, 12, 9, 0.00032922887567957289}, + {100, 7, 7, 6.08037637806889e-08}, + {1000, 2, 1, 1.1171959870312232e-05}, + } { + pdf := F{test.d1, test.d2, nil}.Prob(test.x) + if !floats.EqualWithinAbsOrRel(pdf, test.want, 1e-10, 1e-10) { + t.Errorf("Prob mismatch, x = %v, d1 = %v, d2 = %v. Got %v, want %v", test.x, test.d1, test.d2, pdf, test.want) + } + } +} + +func TestFCDF(t *testing.T) { + for _, test := range []struct { + x, d1, d2, want float64 + }{ + // Values calculated with scipy.stats.f + {0.0001, 4, 6, 2.6660741629519019e-08}, + {0.1, 1, 1, 0.19498222904213672}, + {0.5, 11, 7, 0.14625028471336987}, + {0.9, 20, 15, 0.40567939897287852}, + {1, 1, 1, 0.50000000000000011}, + {2, 15, 12, 0.8839384428956264}, + {5, 4, 8, 0.97429642410900219}, + {10, 12, 9, 0.99915733385467187}, + {100, 7, 7, 0.99999823560259171}, + {1000, 2, 1, 0.97764490829950534}, + } { + cdf := F{test.d1, test.d2, nil}.CDF(test.x) + if !floats.EqualWithinAbsOrRel(cdf, test.want, 1e-10, 1e-10) { + t.Errorf("CDF mismatch, x = %v, d1 = %v, d2 = %v. Got %v, want %v", test.x, test.d1, test.d2, cdf, test.want) + } + } +} + +func TestF(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for i, b := range []F{ + {13, 16, src}, + {42, 31, src}, + {77, 92, src}, + } { + testF(t, b, i) + } +} + +func testF(t *testing.T, f F, i int) { + const ( + tol = 1e-2 + n = 1e5 + bins = 50 + ) + x := make([]float64, n) + generateSamples(x, f) + sort.Float64s(x) + + testRandLogProbContinuous(t, i, 0, x, f, tol, bins) + checkProbContinuous(t, i, x, f, 1e-3) + checkMean(t, i, x, f, tol) + checkVarAndStd(t, i, x, f, tol) + checkExKurtosis(t, i, x, f, 1e-1) + checkSkewness(t, i, x, f, 5e-2) + checkQuantileCDFSurvival(t, i, x, f, 5e-3) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/gamma.go b/vendor/gonum.org/v1/gonum/stat/distuv/gamma.go new file mode 100644 index 00000000..650ad6c8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/gamma.go @@ -0,0 +1,244 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/mathext" +) + +// Gamma implements the Gamma distribution, a two-parameter continuous distribution +// with support over the positive real numbers. +// +// The gamma distribution has density function +// β^α / Γ(α) x^(α-1)e^(-βx) +// +// For more information, see https://en.wikipedia.org/wiki/Gamma_distribution +type Gamma struct { + // Alpha is the shape parameter of the distribution. Alpha must be greater + // than 0. If Alpha == 1, this is equivalent to an exponential distribution. + Alpha float64 + // Beta is the rate parameter of the distribution. Beta must be greater than 0. + // If Beta == 2, this is equivalent to a Chi-Squared distribution. + Beta float64 + + Source *rand.Rand +} + +// CDF computes the value of the cumulative distribution function at x. +func (g Gamma) CDF(x float64) float64 { + if x < 0 { + return 0 + } + return mathext.GammaInc(g.Alpha, g.Beta*x) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (g Gamma) ExKurtosis() float64 { + return 6 / g.Alpha +} + +// LogProb computes the natural logarithm of the value of the probability +// density function at x. +func (g Gamma) LogProb(x float64) float64 { + if x <= 0 { + return math.Inf(-1) + } + a := g.Alpha + b := g.Beta + lg, _ := math.Lgamma(a) + return a*math.Log(b) - lg + (a-1)*math.Log(x) - b*x +} + +// Mean returns the mean of the probability distribution. +func (g Gamma) Mean() float64 { + return g.Alpha / g.Beta +} + +// Mode returns the mode of the normal distribution. +// +// The mode is NaN in the special case where the Alpha (shape) parameter +// is less than 1. +func (g Gamma) Mode() float64 { + if g.Alpha < 1 { + return math.NaN() + } + return (g.Alpha - 1) / g.Beta +} + +// NumParameters returns the number of parameters in the distribution. +func (Gamma) NumParameters() int { + return 2 +} + +// Prob computes the value of the probability density function at x. +func (g Gamma) Prob(x float64) float64 { + return math.Exp(g.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative distribution function. +func (g Gamma) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + return mathext.GammaIncInv(g.Alpha, p) / g.Beta +} + +// Rand returns a random sample drawn from the distribution. +// +// Rand panics if either alpha or beta is <= 0. +func (g Gamma) Rand() float64 { + if g.Beta <= 0 { + panic("gamma: beta <= 0") + } + + unifrnd := rand.Float64 + exprnd := rand.ExpFloat64 + normrnd := rand.NormFloat64 + if g.Source != nil { + unifrnd = g.Source.Float64 + exprnd = g.Source.ExpFloat64 + normrnd = g.Source.NormFloat64 + } + + a := g.Alpha + b := g.Beta + switch { + case a <= 0: + panic("gamma: alpha < 0") + case a == 1: + // Generate from exponential + return exprnd() / b + case a < 0.3: + // Generate using + // Liu, Chuanhai, Martin, Ryan and Syring, Nick. "Simulating from a + // gamma distribution with small shape parameter" + // https://arxiv.org/abs/1302.1884 + // use this reference: http://link.springer.com/article/10.1007/s00180-016-0692-0 + + // Algorithm adjusted to work in log space as much as possible. + lambda := 1/a - 1 + lw := math.Log(a) - 1 - math.Log(1-a) + lr := -math.Log(1 + math.Exp(lw)) + lc, _ := math.Lgamma(a + 1) + for { + e := exprnd() + var z float64 + if e >= -lr { + z = e + lr + } else { + z = -exprnd() / lambda + } + lh := lc - z - math.Exp(-z/a) + var lEta float64 + if z >= 0 { + lEta = lc - z + } else { + lEta = lc + lw + math.Log(lambda) + lambda*z + } + if lh-lEta > -exprnd() { + return math.Exp(-z/a) / b + } + } + case a >= 0.3 && a < 1: + // Generate using: + // Kundu, Debasis, and Rameshwar D. Gupta. "A convenient way of generating + // gamma random variables using generalized exponential distribution." + // Computational Statistics & Data Analysis 51.6 (2007): 2796-2802. + + // TODO(btracey): Change to using Algorithm 3 if we can find the bug in + // the implementation below. + + // Algorithm 2. + alpha := g.Alpha + a := math.Pow(1-expNegOneHalf, alpha) / (math.Pow(1-expNegOneHalf, alpha) + alpha*math.Exp(-1)/math.Pow(2, alpha)) + b := math.Pow(1-expNegOneHalf, alpha) + alpha/math.E/math.Pow(2, alpha) + var x float64 + for { + u := unifrnd() + if u <= a { + x = -2 * math.Log(1-math.Pow(u*b, 1/alpha)) + } else { + x = -math.Log(math.Pow(2, alpha) / alpha * b * (1 - u)) + } + v := unifrnd() + if x <= 1 { + if v <= math.Pow(x, alpha-1)*math.Exp(-x/2)/(math.Pow(2, alpha-1)*math.Pow(1-math.Exp(-x/2), alpha-1)) { + break + } + } else { + if v <= math.Pow(x, alpha-1) { + break + } + } + } + return x / g.Beta + + /* + // Algorithm 3. + d := 1.0334 - 0.0766*math.Exp(2.2942*alpha) + a := math.Pow(2, alpha) * math.Pow(1-math.Exp(-d/2), alpha) + b := alpha * math.Pow(d, alpha-1) * math.Exp(-d) + c := a + b + var x float64 + for { + u := unifrnd() + if u <= a/(a+b) { + x = -2 * math.Log(1-math.Pow(c*u, 1/a)/2) + } else { + x = -math.Log(c * (1 - u) / (alpha * math.Pow(d, alpha-1))) + } + v := unifrnd() + if x <= d { + if v <= (math.Pow(x, alpha-1)*math.Exp(-x/2))/(math.Pow(2, alpha-1)*math.Pow(1-math.Exp(-x/2), alpha-1)) { + break + } + } else { + if v <= math.Pow(d/x, 1-alpha) { + break + } + } + } + return x / g.Beta + */ + case a > 1: + // Generate using: + // Marsaglia, George, and Wai Wan Tsang. "A simple method for generating + // gamma variables." ACM Transactions on Mathematical Software (TOMS) + // 26.3 (2000): 363-372. + d := a - 1.0/3 + c := 1 / (3 * math.Sqrt(d)) + for { + u := -exprnd() + x := normrnd() + v := 1 + x*c + v = v * v * v + if u < 0.5*x*x+d*(1-v+math.Log(v)) { + return d * v / b + } + } + } + panic("unreachable") +} + +// Survival returns the survival function (complementary CDF) at x. +func (g Gamma) Survival(x float64) float64 { + if x < 0 { + return 1 + } + return mathext.GammaIncComp(g.Alpha, g.Beta*x) +} + +// StdDev returns the standard deviation of the probability distribution. +func (g Gamma) StdDev() float64 { + return math.Sqrt(g.Variance()) +} + +// Variance returns the variance of the probability distribution. +func (g Gamma) Variance() float64 { + return g.Alpha / g.Beta / g.Beta +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/gamma_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/gamma_test.go new file mode 100644 index 00000000..6a1a9bf7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/gamma_test.go @@ -0,0 +1,63 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math/rand" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestGamma(t *testing.T) { + // Values a comparison with scipy + for _, test := range []struct { + x, alpha, want float64 + }{ + {0.9, 0.1, 0.046986817861555757}, + {0.9, 0.01, 0.0045384353289090401}, + {0.45, 0.01, 0.014137035997241795}, + } { + pdf := Gamma{Alpha: test.alpha, Beta: 1}.Prob(test.x) + if !floats.EqualWithinAbsOrRel(pdf, test.want, 1e-10, 1e-10) { + t.Errorf("Pdf mismatch. Got %v, want %v", pdf, test.want) + } + } + src := rand.New(rand.NewSource(1)) + for i, g := range []Gamma{ + + {Alpha: 0.5, Beta: 0.8, Source: src}, + {Alpha: 0.9, Beta: 6, Source: src}, + {Alpha: 0.9, Beta: 500, Source: src}, + + {Alpha: 1, Beta: 1, Source: src}, + + {Alpha: 1.6, Beta: 0.4, Source: src}, + {Alpha: 2.6, Beta: 1.5, Source: src}, + {Alpha: 5.6, Beta: 0.5, Source: src}, + {Alpha: 30, Beta: 1.7, Source: src}, + {Alpha: 30.2, Beta: 1.7, Source: src}, + } { + testGamma(t, g, i) + } +} + +func testGamma(t *testing.T, f Gamma, i int) { + // TODO(btracey): Replace this when Gamma implements FullDist. + tol := 1e-2 + const n = 1e5 + const bins = 50 + x := make([]float64, n) + generateSamples(x, f) + sort.Float64s(x) + + testRandLogProbContinuous(t, i, 0, x, f, tol, bins) + checkMean(t, i, x, f, tol) + checkVarAndStd(t, i, x, f, 2e-2) + checkExKurtosis(t, i, x, f, 2e-1) + checkProbContinuous(t, i, x, f, 1e-3) + checkQuantileCDFSurvival(t, i, x, f, 5e-2) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/general.go b/vendor/gonum.org/v1/gonum/stat/distuv/general.go new file mode 100644 index 00000000..3d9cb865 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/general.go @@ -0,0 +1,24 @@ +// 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 distuv + +import "math" + +// Parameter represents a parameter of a probability distribution +type Parameter struct { + Name string + Value float64 +} + +var ( + badPercentile = "distuv: percentile out of bounds" + badLength = "distuv: slice length mismatch" + badSuffStat = "distuv: wrong suffStat length" + badNoSamples = "distuv: must have at least one sample" +) + +var ( + expNegOneHalf = math.Exp(-0.5) +) diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/general_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/general_test.go new file mode 100644 index 00000000..63a89dd0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/general_test.go @@ -0,0 +1,204 @@ +// 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 distuv + +import ( + "fmt" + "math" + "testing" + + "gonum.org/v1/gonum/diff/fd" + "gonum.org/v1/gonum/floats" +) + +type univariateProbPoint struct { + loc float64 + logProb float64 + cumProb float64 + prob float64 +} + +type UniProbDist interface { + Prob(float64) float64 + CDF(float64) float64 + LogProb(float64) float64 + Quantile(float64) float64 + Survival(float64) float64 +} + +func absEq(a, b float64) bool { + // This is expressed as the inverse to catch the + // case a = Inf and b = Inf of the same sign. + return !(math.Abs(a-b) > 1e-14) +} + +// TODO: Implement a better test for Quantile +func testDistributionProbs(t *testing.T, dist UniProbDist, name string, pts []univariateProbPoint) { + for _, pt := range pts { + logProb := dist.LogProb(pt.loc) + if !absEq(logProb, pt.logProb) { + t.Errorf("Log probability doesnt match for "+name+". Expected %v. Found %v", pt.logProb, logProb) + } + prob := dist.Prob(pt.loc) + if !absEq(prob, pt.prob) { + t.Errorf("Probability doesn't match for "+name+". Expected %v. Found %v", pt.prob, prob) + } + cumProb := dist.CDF(pt.loc) + if !absEq(cumProb, pt.cumProb) { + t.Errorf("Cumulative Probability doesn't match for "+name+". Expected %v. Found %v", pt.cumProb, cumProb) + } + if !absEq(dist.Survival(pt.loc), 1-pt.cumProb) { + t.Errorf("Survival doesn't match for %v. Expected %v, Found %v", name, 1-pt.cumProb, dist.Survival(pt.loc)) + } + if pt.prob != 0 { + if math.Abs(dist.Quantile(pt.cumProb)-pt.loc) > 1e-4 { + fmt.Println("true =", pt.loc) + fmt.Println("calculated=", dist.Quantile(pt.cumProb)) + t.Errorf("Quantile doesn't match for "+name+", loc = %v", pt.loc) + } + } + } +} + +type ConjugateUpdater interface { + NumParameters() int + parameters([]Parameter) []Parameter + + NumSuffStat() int + SuffStat([]float64, []float64, []float64) float64 + ConjugateUpdate([]float64, float64, []float64) + + Rand() float64 +} + +func testConjugateUpdate(t *testing.T, newFittable func() ConjugateUpdater) { + for i, test := range []struct { + samps []float64 + weights []float64 + }{ + { + samps: randn(newFittable(), 10), + weights: nil, + }, + { + samps: randn(newFittable(), 10), + weights: ones(10), + }, + { + samps: randn(newFittable(), 10), + weights: randn(&Exponential{Rate: 1}, 10), + }, + } { + // ensure that conjugate produces the same result both incrementally and all at once + incDist := newFittable() + stats := make([]float64, incDist.NumSuffStat()) + prior := make([]float64, incDist.NumParameters()) + for j := range test.samps { + var incWeights, allWeights []float64 + if test.weights != nil { + incWeights = test.weights[j : j+1] + allWeights = test.weights[0 : j+1] + } + nsInc := incDist.SuffStat(stats, test.samps[j:j+1], incWeights) + incDist.ConjugateUpdate(stats, nsInc, prior) + + allDist := newFittable() + nsAll := allDist.SuffStat(stats, test.samps[0:j+1], allWeights) + allDist.ConjugateUpdate(stats, nsAll, make([]float64, allDist.NumParameters())) + if !parametersEqual(incDist.parameters(nil), allDist.parameters(nil), 1e-12) { + t.Errorf("prior doesn't match after incremental update for (%d, %d). Incremental is %v, all at once is %v", i, j, incDist, allDist) + } + + if test.weights == nil { + onesDist := newFittable() + nsOnes := onesDist.SuffStat(stats, test.samps[0:j+1], ones(j+1)) + onesDist.ConjugateUpdate(stats, nsOnes, make([]float64, onesDist.NumParameters())) + if !parametersEqual(onesDist.parameters(nil), incDist.parameters(nil), 1e-14) { + t.Errorf("nil and uniform weighted prior doesn't match for incremental update for (%d, %d). Uniform weighted is %v, nil is %v", i, j, onesDist, incDist) + } + if !parametersEqual(onesDist.parameters(nil), allDist.parameters(nil), 1e-14) { + t.Errorf("nil and uniform weighted prior doesn't match for all at once update for (%d, %d). Uniform weighted is %v, nil is %v", i, j, onesDist, incDist) + } + } + } + } +} + +// randn generates a specified number of random samples +func randn(dist Rander, n int) []float64 { + x := make([]float64, n) + for i := range x { + x[i] = dist.Rand() + } + return x +} + +func ones(n int) []float64 { + x := make([]float64, n) + for i := range x { + x[i] = 1 + } + return x +} + +func parametersEqual(p1, p2 []Parameter, tol float64) bool { + for i, p := range p1 { + if p.Name != p2[i].Name { + return false + } + if math.Abs(p.Value-p2[i].Value) > tol { + return false + } + } + return true +} + +type derivParamTester interface { + LogProb(x float64) float64 + Score(deriv []float64, x float64) []float64 + Quantile(p float64) float64 + NumParameters() int + parameters([]Parameter) []Parameter + setParameters([]Parameter) +} + +func testDerivParam(t *testing.T, d derivParamTester) { + // Tests that the derivative matches for a number of different quantiles + // along the distribution. + nTest := 10 + quantiles := make([]float64, nTest) + floats.Span(quantiles, 0.1, 0.9) + + deriv := make([]float64, d.NumParameters()) + fdDeriv := make([]float64, d.NumParameters()) + + initParams := d.parameters(nil) + init := make([]float64, d.NumParameters()) + for i, v := range initParams { + init[i] = v.Value + } + for _, v := range quantiles { + d.setParameters(initParams) + x := d.Quantile(v) + d.Score(deriv, x) + f := func(p []float64) float64 { + params := d.parameters(nil) + for i, v := range p { + params[i].Value = v + } + d.setParameters(params) + return d.LogProb(x) + } + fd.Gradient(fdDeriv, f, init, nil) + if !floats.EqualApprox(deriv, fdDeriv, 1e-6) { + t.Fatal("Derivative mismatch. Want", fdDeriv, ", got", deriv, ".") + } + d.setParameters(initParams) + d2 := d.Score(nil, x) + if !floats.EqualApprox(d2, deriv, 1e-14) { + t.Errorf("Derivative mismatch when input nil Want %v, got %v", d2, deriv) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/interfaces.go b/vendor/gonum.org/v1/gonum/stat/distuv/interfaces.go new file mode 100644 index 00000000..b2eb80ba --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/interfaces.go @@ -0,0 +1,22 @@ +// 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 distuv + +type LogProber interface { + LogProb(float64) float64 +} + +type Rander interface { + Rand() float64 +} + +type RandLogProber interface { + Rander + LogProber +} + +type Quantiler interface { + Quantile(p float64) float64 +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/laplace.go b/vendor/gonum.org/v1/gonum/stat/distuv/laplace.go new file mode 100644 index 00000000..716d79f6 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/laplace.go @@ -0,0 +1,251 @@ +// 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 distuv + +import ( + "math" + "math/rand" + "sort" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/stat" +) + +// Laplace represents the Laplace distribution (https://en.wikipedia.org/wiki/Laplace_distribution). +type Laplace struct { + Mu float64 // Mean of the Laplace distribution + Scale float64 // Scale of the Laplace distribution + Source *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (l Laplace) CDF(x float64) float64 { + if x < l.Mu { + return 0.5 * math.Exp((x-l.Mu)/l.Scale) + } + return 1 - 0.5*math.Exp(-(x-l.Mu)/l.Scale) +} + +// Entropy returns the entropy of the distribution. +func (l Laplace) Entropy() float64 { + return 1 + math.Log(2*l.Scale) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (l Laplace) ExKurtosis() float64 { + return 3 +} + +// Fit sets the parameters of the probability distribution from the +// data samples x with relative weights w. +// If weights is nil, then all the weights are 1. +// If weights is not nil, then the len(weights) must equal len(samples). +// +// Note: Laplace distribution has no FitPrior because it has no sufficient +// statistics. +func (l *Laplace) Fit(samples, weights []float64) { + if len(samples) != len(weights) { + panic(badLength) + } + + if len(samples) == 0 { + panic(badNoSamples) + } + if len(samples) == 1 { + l.Mu = samples[0] + l.Scale = 0 + return + } + + var ( + sortedSamples []float64 + sortedWeights []float64 + ) + if sort.Float64sAreSorted(samples) { + sortedSamples = samples + sortedWeights = weights + } else { + // Need to copy variables so the input variables aren't effected by the sorting + sortedSamples = make([]float64, len(samples)) + copy(sortedSamples, samples) + sortedWeights := make([]float64, len(samples)) + copy(sortedWeights, weights) + + stat.SortWeighted(sortedSamples, sortedWeights) + } + + // The (weighted) median of the samples is the maximum likelihood estimate + // of the mean parameter + // TODO: Rethink quantile type when stat has more options + l.Mu = stat.Quantile(0.5, stat.Empirical, sortedSamples, sortedWeights) + + sumWeights := floats.Sum(weights) + + // The scale parameter is the average absolute distance + // between the sample and the mean + absError := stat.MomentAbout(1, samples, l.Mu, weights) + + l.Scale = absError / sumWeights +} + +// LogProb computes the natural logarithm of the value of the probability density +// function at x. +func (l Laplace) LogProb(x float64) float64 { + return -math.Ln2 - math.Log(l.Scale) - math.Abs(x-l.Mu)/l.Scale +} + +// MarshalParameters implements the ParameterMarshaler interface +func (l Laplace) MarshalParameters(p []Parameter) { + if len(p) != l.NumParameters() { + panic(badLength) + } + p[0].Name = "Mu" + p[0].Value = l.Mu + p[1].Name = "Scale" + p[1].Value = l.Scale +} + +// Mean returns the mean of the probability distribution. +func (l Laplace) Mean() float64 { + return l.Mu +} + +// Median returns the median of the LaPlace distribution. +func (l Laplace) Median() float64 { + return l.Mu +} + +// Mode returns the mode of the LaPlace distribution. +func (l Laplace) Mode() float64 { + return l.Mu +} + +// NumParameters returns the number of parameters in the distribution. +func (l Laplace) NumParameters() int { + return 2 +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (l Laplace) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + if p < 0.5 { + return l.Mu + l.Scale*math.Log(1+2*(p-0.5)) + } + return l.Mu - l.Scale*math.Log(1-2*(p-0.5)) +} + +// Prob computes the value of the probability density function at x. +func (l Laplace) Prob(x float64) float64 { + return math.Exp(l.LogProb(x)) +} + +// Rand returns a random sample drawn from the distribution. +func (l Laplace) Rand() float64 { + var rnd float64 + if l.Source == nil { + rnd = rand.Float64() + } else { + rnd = l.Source.Float64() + } + u := rnd - 0.5 + if u < 0 { + return l.Mu + l.Scale*math.Log(1+2*u) + } + return l.Mu - l.Scale*math.Log(1-2*u) +} + +// Score returns the score function with respect to the parameters of the +// distribution at the input location x. The score function is the derivative +// of the log-likelihood at x with respect to the parameters +// (∂/∂θ) log(p(x;θ)) +// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise +// Score will panic, and the derivative is stored in-place into deriv. If deriv +// is nil a new slice will be allocated and returned. +// +// The order is [∂LogProb / ∂Mu, ∂LogProb / ∂Scale]. +// +// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29. +// +// Special cases: +// Score(0) = [0, -0.5/l.Scale] +func (l Laplace) Score(deriv []float64, x float64) []float64 { + if deriv == nil { + deriv = make([]float64, l.NumParameters()) + } + if len(deriv) != l.NumParameters() { + panic(badLength) + } + diff := x - l.Mu + if diff > 0 { + deriv[0] = 1 / l.Scale + } else if diff < 0 { + deriv[0] = -1 / l.Scale + } else if diff == 0 { + deriv[0] = 0 + } else { + // must be NaN + deriv[0] = math.NaN() + } + + deriv[1] = math.Abs(diff)/(l.Scale*l.Scale) - 0.5/(l.Scale) + return deriv +} + +// ScoreInput returns the score function with respect to the input of the +// distribution at the input location specified by x. The score function is the +// derivative of the log-likelihood +// (d/dx) log(p(x)) . +// Special cases: +// ScoreInput(l.Mu) = 0 +func (l Laplace) ScoreInput(x float64) float64 { + diff := x - l.Mu + if diff == 0 { + return 0 + } + if diff > 0 { + return -1 / l.Scale + } + return 1 / l.Scale +} + +// Skewness returns the skewness of the distribution. +func (Laplace) Skewness() float64 { + return 0 +} + +// StdDev returns the standard deviation of the distribution. +func (l Laplace) StdDev() float64 { + return math.Sqrt2 * l.Scale +} + +// Survival returns the survival function (complementary CDF) at x. +func (l Laplace) Survival(x float64) float64 { + if x < l.Mu { + return 1 - 0.5*math.Exp((x-l.Mu)/l.Scale) + } + return 0.5 * math.Exp(-(x-l.Mu)/l.Scale) +} + +// UnmarshalParameters implements the ParameterMarshaler interface +func (l *Laplace) UnmarshalParameters(p []Parameter) { + if len(p) != l.NumParameters() { + panic(badLength) + } + if p[0].Name != "Mu" { + panic("laplace: " + panicNameMismatch) + } + if p[1].Name != "Scale" { + panic("laplace: " + panicNameMismatch) + } + l.Mu = p[0].Value + l.Scale = p[1].Value +} + +// Variance returns the variance of the probability distribution. +func (l Laplace) Variance() float64 { + return 2 * l.Scale * l.Scale +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/laplace_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/laplace_test.go new file mode 100644 index 00000000..0cbb2594 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/laplace_test.go @@ -0,0 +1,58 @@ +// 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 distuv + +import ( + "math" + "testing" +) + +func TestLaplaceProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: 0.5, + cumProb: 0.5, + logProb: math.Log(0.5), + }, + { + loc: -1, + prob: 1 / (2 * math.E), + cumProb: 0.1839397205857211607977618850807304337229055655158839172539184008487307478724499016785736371729598219, + logProb: math.Log(1 / (2 * math.E)), + }, + { + loc: 1, + prob: 1 / (2 * math.E), + cumProb: 0.8160602794142788392022381149192695662770944344841160827460815991512692521275500983214263628270401781, + logProb: math.Log(1 / (2 * math.E)), + }, + { + loc: -7, + prob: 1 / (2 * math.Pow(math.E, 7)), + cumProb: 0.0004559409827772581040015680422046413132368622637180269204080667109447399446551532646631395032324502210, + logProb: math.Log(1 / (2 * math.Pow(math.E, 7))), + }, + { + loc: 7, + prob: 1 / (2 * math.Pow(math.E, 7)), + cumProb: 0.9995440590172227418959984319577953586867631377362819730795919332890552600553448467353368604967675498, + logProb: math.Log(1 / (2 * math.Pow(math.E, 7))), + }, + { + loc: -20, + prob: math.Exp(-20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869), + cumProb: 1.030576811219278913982970190077910488187903637799551846486122330814582011892279676639955463952790684 * 1e-9, + logProb: -20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869, + }, + { + loc: 20, + prob: math.Exp(-20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869), + cumProb: 0.999999998969423188780721086017029809922089511812096362200448153513877669185417988107720323360044536, + logProb: -20.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641869, + }, + } + testDistributionProbs(t, Laplace{Mu: 0, Scale: 1}, "Laplace", pts) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/lognormal.go b/vendor/gonum.org/v1/gonum/stat/distuv/lognormal.go new file mode 100644 index 00000000..e13afce5 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/lognormal.go @@ -0,0 +1,112 @@ +// 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 distuv + +import ( + "math" + "math/rand" +) + +// LogNormal represents a random variable whose log is normally distributed. +// The probability density function is given by +// 1/(x σ √2π) exp(-(ln(x)-μ)^2)/(2σ^2)) +type LogNormal struct { + Mu float64 + Sigma float64 + Source *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (l LogNormal) CDF(x float64) float64 { + return 0.5 + 0.5*math.Erf((math.Log(x)-l.Mu)/(math.Sqrt2*l.Sigma)) +} + +// Entropy returns the differential entropy of the distribution. +func (l LogNormal) Entropy() float64 { + return 0.5 + 0.5*math.Log(2*math.Pi*l.Sigma*l.Sigma) + l.Mu +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (l LogNormal) ExKurtosis() float64 { + s2 := l.Sigma * l.Sigma + return math.Exp(4*s2) + 2*math.Exp(3*s2) + 3*math.Exp(2*s2) - 6 +} + +// LogProb computes the natural logarithm of the value of the probability density function at x. +func (l LogNormal) LogProb(x float64) float64 { + if x < 0 { + return math.Inf(-1) + } + logx := math.Log(x) + normdiff := (logx - l.Mu) / l.Sigma + return -0.5*normdiff*normdiff - logx - math.Log(l.Sigma) - logRoot2Pi +} + +// Mean returns the mean of the probability distribution. +func (l LogNormal) Mean() float64 { + return math.Exp(l.Mu + 0.5*l.Sigma*l.Sigma) +} + +// Median returns the median of the probability distribution. +func (l LogNormal) Median() float64 { + return math.Exp(l.Mu) +} + +// Mode returns the mode of the probability distribution. +func (l LogNormal) Mode() float64 { + return l.Mu +} + +// NumParameters returns the number of parameters in the distribution. +func (LogNormal) NumParameters() int { + return 2 +} + +// Prob computes the value of the probability density function at x. +func (l LogNormal) Prob(x float64) float64 { + return math.Exp(l.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (l LogNormal) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + // Formula from http://www.math.uah.edu/stat/special/LogNormal.html. + return math.Exp(l.Mu + l.Sigma*UnitNormal.Quantile(p)) +} + +// Rand returns a random sample drawn from the distribution. +func (l LogNormal) Rand() float64 { + var rnd float64 + if l.Source == nil { + rnd = rand.NormFloat64() + } else { + rnd = l.Source.NormFloat64() + } + return math.Exp(rnd*l.Sigma + l.Mu) +} + +// Skewness returns the skewness of the distribution. +func (l LogNormal) Skewness() float64 { + s2 := l.Sigma * l.Sigma + return (math.Exp(s2) + 2) * math.Sqrt(math.Exp(s2)-1) +} + +// StdDev returns the standard deviation of the probability distribution. +func (l LogNormal) StdDev() float64 { + return math.Sqrt(l.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (l LogNormal) Survival(x float64) float64 { + return 0.5 * (1 - math.Erf((math.Log(x)-l.Mu)/(math.Sqrt2*l.Sigma))) +} + +// Variance returns the variance of the probability distribution. +func (l LogNormal) Variance() float64 { + s2 := l.Sigma * l.Sigma + return (math.Exp(s2) - 1) * math.Exp(2*l.Mu+s2) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/lognormal_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/lognormal_test.go new file mode 100644 index 00000000..a4dc19ad --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/lognormal_test.go @@ -0,0 +1,44 @@ +// 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 distuv + +import ( + "sort" + "testing" +) + +func TestLognormal(t *testing.T) { + for i, dist := range []LogNormal{ + { + Mu: 0.1, + Sigma: 0.3, + }, + { + Mu: 0.01, + Sigma: 0.01, + }, + { + Mu: 2, + Sigma: 0.01, + }, + } { + f := dist + tol := 1e-2 + const n = 1e5 + x := make([]float64, n) + generateSamples(x, f) + sort.Float64s(x) + + checkMean(t, i, x, f, tol) + checkVarAndStd(t, i, x, f, tol) + checkEntropy(t, i, x, f, tol) + checkExKurtosis(t, i, x, f, 2e-1) + checkSkewness(t, i, x, f, 5e-2) + checkMedian(t, i, x, f, tol) + checkQuantileCDFSurvival(t, i, x, f, tol) + checkProbContinuous(t, i, x, f, 1e-10) + checkProbQuantContinuous(t, i, x, f, tol) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/norm.go b/vendor/gonum.org/v1/gonum/stat/distuv/norm.go new file mode 100644 index 00000000..05b86bdd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/norm.go @@ -0,0 +1,254 @@ +// 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 distuv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mathext" + "gonum.org/v1/gonum/stat" +) + +// UnitNormal is an instantiation of the normal distribution with Mu = 0 and Sigma = 1. +var UnitNormal = Normal{Mu: 0, Sigma: 1} + +// Normal respresents a normal (Gaussian) distribution (https://en.wikipedia.org/wiki/Normal_distribution). +type Normal struct { + Mu float64 // Mean of the normal distribution + Sigma float64 // Standard deviation of the normal distribution + Source *rand.Rand + + // Needs to be Mu and Sigma and not Mean and StdDev because Normal has functions + // Mean and StdDev +} + +// CDF computes the value of the cumulative density function at x. +func (n Normal) CDF(x float64) float64 { + return 0.5 * (1 + math.Erf((x-n.Mu)/(n.Sigma*math.Sqrt2))) +} + +// ConjugateUpdate updates the parameters of the distribution from the sufficient +// statistics of a set of samples. The sufficient statistics, suffStat, have been +// observed with nSamples observations. The prior values of the distribution are those +// currently in the distribution, and have been observed with priorStrength samples. +// +// For the normal distribution, the sufficient statistics are the mean and +// uncorrected standard deviation of the samples. +// The prior is having seen strength[0] samples with mean Normal.Mu +// and strength[1] samples with standard deviation Normal.Sigma. As a result of +// this function, Normal.Mu and Normal.Sigma are updated based on the weighted +// samples, and strength is modified to include the new number of samples observed. +// +// This function panics if len(suffStat) != 2 or len(priorStrength) != 2. +func (n *Normal) ConjugateUpdate(suffStat []float64, nSamples float64, priorStrength []float64) { + + // TODO: Support prior strength with math.Inf(1) to allow updating with + // a known mean/standard deviation + + totalMeanSamples := nSamples + priorStrength[0] + totalSum := suffStat[0]*nSamples + n.Mu*priorStrength[0] + + totalVarianceSamples := nSamples + priorStrength[1] + // sample variance + totalVariance := nSamples * suffStat[1] * suffStat[1] + // add prior variance + totalVariance += priorStrength[1] * n.Sigma * n.Sigma + // add cross variance from the difference of the means + meanDiff := (suffStat[0] - n.Mu) + totalVariance += priorStrength[0] * nSamples * meanDiff * meanDiff / totalMeanSamples + + n.Mu = totalSum / totalMeanSamples + n.Sigma = math.Sqrt(totalVariance / totalVarianceSamples) + floats.AddConst(nSamples, priorStrength) +} + +// Entropy returns the differential entropy of the distribution. +func (n Normal) Entropy() float64 { + return 0.5 * (log2Pi + 1 + 2*math.Log(n.Sigma)) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (Normal) ExKurtosis() float64 { + return 0 +} + +// Fit sets the parameters of the probability distribution from the +// data samples x with relative weights w. If weights is nil, then all the weights +// are 1. If weights is not nil, then the len(weights) must equal len(samples). +func (n *Normal) Fit(samples, weights []float64) { + suffStat := make([]float64, n.NumSuffStat()) + nSamples := n.SuffStat(suffStat, samples, weights) + n.ConjugateUpdate(suffStat, nSamples, make([]float64, n.NumSuffStat())) +} + +// LogProb computes the natural logarithm of the value of the probability density function at x. +func (n Normal) LogProb(x float64) float64 { + return negLogRoot2Pi - math.Log(n.Sigma) - (x-n.Mu)*(x-n.Mu)/(2*n.Sigma*n.Sigma) +} + +// Mean returns the mean of the probability distribution. +func (n Normal) Mean() float64 { + return n.Mu +} + +// Median returns the median of the normal distribution. +func (n Normal) Median() float64 { + return n.Mu +} + +// Mode returns the mode of the normal distribution. +func (n Normal) Mode() float64 { + return n.Mu +} + +// NumParameters returns the number of parameters in the distribution. +func (Normal) NumParameters() int { + return 2 +} + +// NumSuffStat returns the number of sufficient statistics for the distribution. +func (Normal) NumSuffStat() int { + return 2 +} + +// Prob computes the value of the probability density function at x. +func (n Normal) Prob(x float64) float64 { + return math.Exp(n.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (n Normal) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + return n.Mu + n.Sigma*mathext.NormalQuantile(p) +} + +// Rand returns a random sample drawn from the distribution. +func (n Normal) Rand() float64 { + var rnd float64 + if n.Source == nil { + rnd = rand.NormFloat64() + } else { + rnd = n.Source.NormFloat64() + } + return rnd*n.Sigma + n.Mu +} + +// Score returns the score function with respect to the parameters of the +// distribution at the input location x. The score function is the derivative +// of the log-likelihood at x with respect to the parameters +// (∂/∂θ) log(p(x;θ)) +// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise +// Score will panic, and the derivative is stored in-place into deriv. If deriv +// is nil a new slice will be allocated and returned. +// +// The order is [∂LogProb / ∂Mu, ∂LogProb / ∂Sigma]. +// +// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29. +func (n Normal) Score(deriv []float64, x float64) []float64 { + if deriv == nil { + deriv = make([]float64, n.NumParameters()) + } + if len(deriv) != n.NumParameters() { + panic(badLength) + } + deriv[0] = (x - n.Mu) / (n.Sigma * n.Sigma) + deriv[1] = 1 / n.Sigma * (-1 + ((x-n.Mu)/n.Sigma)*((x-n.Mu)/n.Sigma)) + return deriv +} + +// ScoreInput returns the score function with respect to the input of the +// distribution at the input location specified by x. The score function is the +// derivative of the log-likelihood +// (d/dx) log(p(x)) . +func (n Normal) ScoreInput(x float64) float64 { + return -(1 / (2 * n.Sigma * n.Sigma)) * 2 * (x - n.Mu) +} + +// Skewness returns the skewness of the distribution. +func (Normal) Skewness() float64 { + return 0 +} + +// StdDev returns the standard deviation of the probability distribution. +func (n Normal) StdDev() float64 { + return n.Sigma +} + +// SuffStat computes the sufficient statistics of a set of samples to update +// the distribution. The sufficient statistics are stored in place, and the +// effective number of samples are returned. +// +// The normal distribution has two sufficient statistics, the mean of the samples +// and the standard deviation of the samples. +// +// If weights is nil, the weights are assumed to be 1, otherwise panics if +// len(samples) != len(weights). Panics if len(suffStat) != NumSuffStat(). +func (Normal) SuffStat(suffStat, samples, weights []float64) (nSamples float64) { + lenSamp := len(samples) + if len(weights) != 0 && len(samples) != len(weights) { + panic(badLength) + } + if len(suffStat) != (Normal{}).NumSuffStat() { + panic(badSuffStat) + } + + if len(weights) == 0 { + nSamples = float64(lenSamp) + } else { + nSamples = floats.Sum(weights) + } + + mean := stat.Mean(samples, weights) + suffStat[0] = mean + + // Use Moment and not StdDev because we want it to be uncorrected + variance := stat.MomentAbout(2, samples, mean, weights) + suffStat[1] = math.Sqrt(variance) + return nSamples +} + +// Survival returns the survival function (complementary CDF) at x. +func (n Normal) Survival(x float64) float64 { + return 0.5 * (1 - math.Erf((x-n.Mu)/(n.Sigma*math.Sqrt2))) +} + +// setParameters modifies the parameters of the distribution. +func (n *Normal) setParameters(p []Parameter) { + if len(p) != n.NumParameters() { + panic("normal: incorrect number of parameters to set") + } + if p[0].Name != "Mu" { + panic("normal: " + panicNameMismatch) + } + if p[1].Name != "Sigma" { + panic("normal: " + panicNameMismatch) + } + n.Mu = p[0].Value + n.Sigma = p[1].Value +} + +// Variance returns the variance of the probability distribution. +func (n Normal) Variance() float64 { + return n.Sigma * n.Sigma +} + +// parameters returns the parameters of the distribution. +func (n Normal) parameters(p []Parameter) []Parameter { + nParam := n.NumParameters() + if p == nil { + p = make([]Parameter, nParam) + } else if len(p) != nParam { + panic("normal: improper parameter length") + } + p[0].Name = "Mu" + p[0].Value = n.Mu + p[1].Name = "Sigma" + p[1].Value = n.Sigma + return p +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/norm_example_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/norm_example_test.go new file mode 100644 index 00000000..b913282f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/norm_example_test.go @@ -0,0 +1,35 @@ +// 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 distuv_test + +import ( + "fmt" + + "gonum.org/v1/gonum/stat" + "gonum.org/v1/gonum/stat/distuv" +) + +func ExampleNormal() { + // Create a normal distribution + dist := distuv.Normal{ + Mu: 2, + Sigma: 5, + } + + data := make([]float64, 1e5) + + // Draw some random values from the standard normal distribution + for i := range data { + data[i] = dist.Rand() + } + + mean, std := stat.MeanStdDev(data, nil) + meanErr := stat.StdErr(std, float64(len(data))) + + fmt.Printf("mean= %1.1f ± %0.1v\n", mean, meanErr) + + // Output: + // mean= 2.0 ± 0.02 +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/norm_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/norm_test.go new file mode 100644 index 00000000..0179e173 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/norm_test.go @@ -0,0 +1,171 @@ +// 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 distuv + +import ( + "math" + "testing" + + "gonum.org/v1/gonum/floats" +) + +// TestNormalProbs tests LogProb, Prob, CumProb, and Quantile +func TestNormalProbs(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: oneOverRoot2Pi, + cumProb: 0.5, + logProb: -0.91893853320467274178032973640561763986139747363778341281715, + }, + { + loc: -1, + prob: 0.2419707245191433497978301929355606548286719707374350254875550842811000635700832945083112946939424047, + cumProb: 0.158655253931457051414767454367962077522087033273395609012605, + logProb: math.Log(0.2419707245191433497978301929355606548286719707374350254875550842811000635700832945083112946939424047), + }, + { + loc: 1, + prob: 0.2419707245191433497978301929355606548286719707374350254875550842811000635700832945083112946939424047, + cumProb: 0.841344746068542948585232545632037922477912966726604390987394, + logProb: math.Log(0.2419707245191433497978301929355606548286719707374350254875550842811000635700832945083112946939424047), + }, + { + loc: -7, + prob: 9.134720408364593342868613916794233023000190834851937054490546361277622761970225469305158915808284566e-12, + cumProb: 1.279812543885835004383623690780832998032844154198717929e-12, + logProb: math.Log(9.134720408364593342868613916794233023000190834851937054490546361277622761970225469305158915808284566e-12), + }, + { + loc: 7, + prob: 9.134720408364593342868613916794233023000190834851937054490546361277622761970225469305158915808284566e-12, + cumProb: 0.99999999999872018745611416499561637630921916700196715584580, + logProb: math.Log(9.134720408364593342868613916794233023000190834851937054490546361277622761970225469305158915808284566e-12), + }, + } + testDistributionProbs(t, Normal{Mu: 0, Sigma: 1}, "normal", pts) + + pts = []univariateProbPoint{ + { + loc: 2, + prob: 0.07978845608028653558798921198687637369517172623298693153318516593413158517986036770025046678146138729, + cumProb: 0.5, + logProb: math.Log(0.07978845608028653558798921198687637369517172623298693153318516593413158517986036770025046678146138729), + }, + { + loc: -3, + prob: 0.04839414490382866995956603858711213096573439414748700509751101685622001271401665890166225893878848095, + cumProb: 0.158655253931457051414767454367962077522087033273395609012605, + logProb: math.Log(0.04839414490382866995956603858711213096573439414748700509751101685622001271401665890166225893878848095), + }, + { + loc: 7, + prob: 0.04839414490382866995956603858711213096573439414748700509751101685622001271401665890166225893878848095, + cumProb: 0.841344746068542948585232545632037922477912966726604390987394, + logProb: math.Log(0.04839414490382866995956603858711213096573439414748700509751101685622001271401665890166225893878848095), + }, + { + loc: -33, + prob: 1.826944081672918668573722783358846604600038166970387410898109272255524552394045093861031783161656913e-12, + cumProb: 1.279812543885835004383623690780832998032844154198717929e-12, + logProb: math.Log(1.826944081672918668573722783358846604600038166970387410898109272255524552394045093861031783161656913e-12), + }, + { + loc: 37, + prob: 1.826944081672918668573722783358846604600038166970387410898109272255524552394045093861031783161656913e-12, + cumProb: 0.99999999999872018745611416499561637630921916700196715584580, + logProb: math.Log(1.826944081672918668573722783358846604600038166970387410898109272255524552394045093861031783161656913e-12), + }, + } + testDistributionProbs(t, Normal{Mu: 2, Sigma: 5}, "normal", pts) +} + +func TestNormFitPrior(t *testing.T) { + testConjugateUpdate(t, func() ConjugateUpdater { return &Normal{Mu: -10, Sigma: 6} }) +} + +func TestNormScore(t *testing.T) { + for _, test := range []*Normal{ + { + Mu: 0, + Sigma: 1, + }, + { + Mu: 0.32238, + Sigma: 13.69, + }, + } { + testDerivParam(t, test) + } +} + +func TestNormalQuantile(t *testing.T) { + // Values from https://www.johndcook.com/blog/normal_cdf_inverse/ + p := []float64{ + 0.0000001, + 0.00001, + 0.001, + 0.05, + 0.15, + 0.25, + 0.35, + 0.45, + 0.55, + 0.65, + 0.75, + 0.85, + 0.95, + 0.999, + 0.99999, + 0.9999999, + } + ans := []float64{ + -5.199337582187471, + -4.264890793922602, + -3.090232306167813, + -1.6448536269514729, + -1.0364333894937896, + -0.6744897501960817, + -0.38532046640756773, + -0.12566134685507402, + 0.12566134685507402, + 0.38532046640756773, + 0.6744897501960817, + 1.0364333894937896, + 1.6448536269514729, + 3.090232306167813, + 4.264890793922602, + 5.199337582187471, + } + for i, v := range p { + got := UnitNormal.Quantile(v) + if !floats.EqualWithinAbsOrRel(got, ans[i], 1e-10, 1e-10) { + t.Errorf("Quantile mismatch. Case %d, want: %v, got: %v", i, ans[i], got) + } + } +} + +func TestNormFitPanic(t *testing.T) { + n := Normal{Mu: 0, Sigma: 1} + defer func() { + r := recover() + if r != nil { + t.Errorf("unexpected panic for Fit call: %v", r) + } + }() + n.Fit(make([]float64, 10), nil) +} + +func BenchmarkNormalQuantile(b *testing.B) { + n := Normal{Mu: 2, Sigma: 3.1} + ps := make([]float64, 1000) // ensure there are small values + floats.Span(ps, 0, 1) + for i := 0; i < b.N; i++ { + for _, v := range ps { + x := n.Quantile(v) + _ = x + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/studentst.go b/vendor/gonum.org/v1/gonum/stat/distuv/studentst.go new file mode 100644 index 00000000..84b6b6e2 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/studentst.go @@ -0,0 +1,160 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/mathext" +) + +const logPi = 1.1447298858494001741 // http://oeis.org/A053510 + +// StudentsT implements the three-parameter Student's T distribution, a distribution +// over the real numbers. +// +// The Student's T distribution has density function +// Γ((ν+1)/2) / (sqrt(νπ) Γ(ν/2) σ) (1 + 1/ν * ((x-μ)/σ)^2)^(-(ν+1)/2) +// +// The Student's T distribution approaches the normal distribution as ν → ∞. +// +// For more information, see https://en.wikipedia.org/wiki/Student%27s_t-distribution, +// specifically https://en.wikipedia.org/wiki/Student%27s_t-distribution#Non-standardized_Student.27s_t-distribution . +// +// The standard Student's T distribution is with Mu = 0, and Sigma = 1. +type StudentsT struct { + // Mu is the location parameter of the distribution, and the mean of the + // distribution + Mu float64 + + // Sigma is the scale parameter of the distribution. It is related to the + // standard deviation by std = Sigma * sqrt(Nu/(Nu-2)) + Sigma float64 + + // Nu is the shape prameter of the distribution, representing the number of + // degrees of the distribution, and one less than the number of observations + // from a Normal distribution. + Nu float64 + + Src *rand.Rand +} + +// CDF computes the value of the cumulative distribution function at x. +func (s StudentsT) CDF(x float64) float64 { + // transform to standard normal + y := (x - s.Mu) / s.Sigma + if y == 0 { + return 0.5 + } + // For t > 0 + // F(y) = 1 - 0.5 * I_t(y)(nu/2, 1/2) + // t(y) = nu/(y^2 + nu) + // and 1 - F(y) for t < 0 + t := s.Nu / (y*y + s.Nu) + if y > 0 { + return 1 - 0.5*mathext.RegIncBeta(0.5*s.Nu, 0.5, t) + } + return 0.5 * mathext.RegIncBeta(s.Nu/2, 0.5, t) +} + +// LogProb computes the natural logarithm of the value of the probability +// density function at x. +func (s StudentsT) LogProb(x float64) float64 { + g1, _ := math.Lgamma((s.Nu + 1) / 2) + g2, _ := math.Lgamma(s.Nu / 2) + z := (x - s.Mu) / s.Sigma + return g1 - g2 - 0.5*math.Log(s.Nu) - 0.5*logPi - math.Log(s.Sigma) - ((s.Nu+1)/2)*math.Log(1+z*z/s.Nu) +} + +// Mean returns the mean of the probability distribution. +func (s StudentsT) Mean() float64 { + return s.Mu +} + +// Mode returns the mode of the distribution. +func (s StudentsT) Mode() float64 { + return s.Mu +} + +// NumParameters returns the number of parameters in the distribution. +func (StudentsT) NumParameters() int { + return 3 +} + +// Prob computes the value of the probability density function at x. +func (s StudentsT) Prob(x float64) float64 { + return math.Exp(s.LogProb(x)) +} + +// Quantile returns the inverse of the cumulative distribution function. +func (s StudentsT) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + // F(x) = 1 - 0.5 * I_t(x)(nu/2, 1/2) + // t(x) = nu/(t^2 + nu) + if p == 0.5 { + return s.Mu + } + var y float64 + if p > 0.5 { + // Know t > 0 + t := mathext.InvRegIncBeta(s.Nu/2, 0.5, 2*(1-p)) + y = math.Sqrt(s.Nu * (1 - t) / t) + } else { + t := mathext.InvRegIncBeta(s.Nu/2, 0.5, 2*p) + y = -math.Sqrt(s.Nu * (1 - t) / t) + } + // Convert out of standard normal + return y*s.Sigma + s.Mu +} + +// Rand returns a random sample drawn from the distribution. +func (s StudentsT) Rand() float64 { + // http://www.math.uah.edu/stat/special/Student.html + n := Normal{0, 1, s.Src}.Rand() + c := Gamma{s.Nu / 2, 0.5, s.Src}.Rand() + z := n / math.Sqrt(c/s.Nu) + return z*s.Sigma + s.Mu +} + +// StdDev returns the standard deviation of the probability distribution. +// +// The standard deviation is undefined for ν <= 1, and this returns math.NaN(). +func (s StudentsT) StdDev() float64 { + return math.Sqrt(s.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (s StudentsT) Survival(x float64) float64 { + // transform to standard normal + y := (x - s.Mu) / s.Sigma + if y == 0 { + return 0.5 + } + // For t > 0 + // F(y) = 1 - 0.5 * I_t(y)(nu/2, 1/2) + // t(y) = nu/(y^2 + nu) + // and 1 - F(y) for t < 0 + t := s.Nu / (y*y + s.Nu) + if y > 0 { + return 0.5 * mathext.RegIncBeta(s.Nu/2, 0.5, t) + } + return 1 - 0.5*mathext.RegIncBeta(s.Nu/2, 0.5, t) +} + +// Variance returns the variance of the probability distribution. +// +// The variance is undefined for ν <= 1, and this returns math.NaN(). +func (s StudentsT) Variance() float64 { + if s.Nu < 1 { + return math.NaN() + } + if s.Nu <= 2 { + return math.Inf(1) + } + return s.Sigma * s.Sigma * s.Nu / (s.Nu - 2) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/studentst_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/studentst_test.go new file mode 100644 index 00000000..d3ad225b --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/studentst_test.go @@ -0,0 +1,83 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package distuv + +import ( + "math" + "math/rand" + "sort" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestStudentsTProb(t *testing.T) { + for _, test := range []struct { + x, mu, sigma, nu, want float64 + }{ + // Values comparison with scipy. + {0.01, 0, 1, 2.74, 0.364778548181318}, + {-0.01, 0, 1, 2.74, 0.364778548181318}, + {0.4, 0, 1, 1.6, 0.30376391362582678}, + {-0.4, 0, 1, 1.6, 0.30376391362582678}, + {0.2, 15, 5, 10, 0.0024440848858034393}, + } { + pdf := StudentsT{test.mu, test.sigma, test.nu, nil}.Prob(test.x) + if !floats.EqualWithinAbsOrRel(pdf, test.want, 1e-10, 1e-10) { + t.Errorf("Pdf mismatch, x = %v, Nu = %v. Got %v, want %v", test.x, test.nu, pdf, test.want) + } + } +} + +func TestStudentsT(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for i, b := range []StudentsT{ + {0, 1, 3.3, src}, + {0, 1, 7.2, src}, + {0, 1, 12, src}, + {0.9, 0.8, 6, src}, + } { + testStudentsT(t, b, i) + } +} + +func testStudentsT(t *testing.T, c StudentsT, i int) { + tol := 1e-2 + const n = 1e5 + const bins = 50 + x := make([]float64, n) + generateSamples(x, c) + sort.Float64s(x) + + testRandLogProbContinuous(t, i, math.Inf(-1), x, c, tol, bins) + checkMean(t, i, x, c, tol) + if c.Nu > 2 { + checkVarAndStd(t, i, x, c, 5e-2) + } + checkProbContinuous(t, i, x, c, 1e-3) + checkQuantileCDFSurvival(t, i, x, c, tol) + checkProbQuantContinuous(t, i, x, c, tol) +} + +func TestStudentsTQuantile(t *testing.T) { + nSteps := 101 + probs := make([]float64, nSteps) + floats.Span(probs, 0, 1) + for i, b := range []StudentsT{ + {0, 1, 3.3, nil}, + {0, 1, 7.2, nil}, + {0, 1, 12, nil}, + {0.9, 0.8, 6, nil}, + } { + for _, p := range probs { + x := b.Quantile(p) + p2 := b.CDF(x) + if !floats.EqualWithinAbsOrRel(p, p2, 1e-10, 1e-10) { + t.Errorf("mismatch between CDF and Quantile. Case %v. Want %v, got %v", i, p, p2) + break + } + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/triangle.go b/vendor/gonum.org/v1/gonum/stat/distuv/triangle.go new file mode 100644 index 00000000..157b9ea1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/triangle.go @@ -0,0 +1,192 @@ +// 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 distuv + +import ( + "math" + "math/rand" +) + +// Triangle represents a triangle distribution (https://en.wikipedia.org/wiki/Triangular_distribution). +type Triangle struct { + a, b, c float64 + Source *rand.Rand +} + +// NewTriangle constructs a new triangle distribution with lower limit a, upper limit b, and mode c. +// Constraints are a < b and a ≤ c ≤ b. +// This distribution is uncommon in nature, but may be useful for simulation. +func NewTriangle(a, b, c float64) Triangle { + checkTriangleParameters(a, b, c) + return Triangle{a, b, c, nil} +} + +func checkTriangleParameters(a, b, c float64) { + if a >= b { + panic("triangle: constraint of a < b violated") + } + if a > c { + panic("triangle: constraint of a <= c violated") + } + if c > b { + panic("triangle: constraint of c <= b violated") + } +} + +// CDF computes the value of the cumulative density function at x. +func (t Triangle) CDF(x float64) float64 { + switch { + case x <= t.a: + return 0 + case x <= t.c: + d := x - t.a + return (d * d) / ((t.b - t.a) * (t.c - t.a)) + case x < t.b: + d := t.b - x + return 1 - (d*d)/((t.b-t.a)*(t.b-t.c)) + default: + return 1 + } +} + +// Entropy returns the entropy of the distribution. +func (t Triangle) Entropy() float64 { + return 0.5 + math.Log(t.b-t.a) - math.Ln2 +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (Triangle) ExKurtosis() float64 { + return -3.0 / 5.0 +} + +// Fit is not appropriate for Triangle, because the distribution is generally used when there is little data. + +// LogProb computes the natural logarithm of the value of the probability density function at x. +func (t Triangle) LogProb(x float64) float64 { + return math.Log(t.Prob(x)) +} + +// Mean returns the mean of the probability distribution. +func (t Triangle) Mean() float64 { + return (t.a + t.b + t.c) / 3 +} + +// Median returns the median of the probability distribution. +func (t Triangle) Median() float64 { + if t.c >= (t.a+t.b)/2 { + return t.a + math.Sqrt((t.b-t.a)*(t.c-t.a)/2) + } + return t.b - math.Sqrt((t.b-t.a)*(t.b-t.c)/2) +} + +// Mode returns the mode of the probability distribution. +func (t Triangle) Mode() float64 { + return t.c +} + +// NumParameters returns the number of parameters in the distribution. +func (Triangle) NumParameters() int { + return 3 +} + +// Prob computes the value of the probability density function at x. +func (t Triangle) Prob(x float64) float64 { + switch { + case x < t.a: + return 0 + case x < t.c: + return 2 * (x - t.a) / ((t.b - t.a) * (t.c - t.a)) + case x == t.c: + return 2 / (t.b - t.a) + case x <= t.b: + return 2 * (t.b - x) / ((t.b - t.a) * (t.b - t.c)) + default: + return 0 + } +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (t Triangle) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + + f := (t.c - t.a) / (t.b - t.a) + + if p < f { + return t.a + math.Sqrt(p*(t.b-t.a)*(t.c-t.a)) + } + return t.b - math.Sqrt((1-p)*(t.b-t.a)*(t.b-t.c)) +} + +// Rand returns a random sample drawn from the distribution. +func (t Triangle) Rand() float64 { + var rnd float64 + if t.Source == nil { + rnd = rand.Float64() + } else { + rnd = t.Source.Float64() + } + + return t.Quantile(rnd) +} + +// Skewness returns the skewness of the distribution. +func (t Triangle) Skewness() float64 { + n := math.Sqrt2 * (t.a + t.b - 2*t.c) * (2*t.a - t.b - t.c) * (t.a - 2*t.b + t.c) + d := 5 * math.Pow(t.a*t.a+t.b*t.b+t.c*t.c-t.a*t.b-t.a*t.c-t.b*t.c, 3.0/2.0) + + return n / d +} + +// StdDev returns the standard deviation of the probability distribution. +func (t Triangle) StdDev() float64 { + return math.Sqrt(t.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (t Triangle) Survival(x float64) float64 { + return 1 - t.CDF(x) +} + +// MarshalParameters implements the ParameterMarshaler interface +func (t Triangle) MarshalParameters(p []Parameter) { + if len(p) != t.NumParameters() { + panic("triangle: improper parameter length") + } + p[0].Name = "A" + p[0].Value = t.a + p[1].Name = "B" + p[1].Value = t.b + p[2].Name = "C" + p[2].Value = t.c +} + +// UnmarshalParameters implements the ParameterMarshaler interface +func (t *Triangle) UnmarshalParameters(p []Parameter) { + if len(p) != t.NumParameters() { + panic("triangle: incorrect number of parameters to set") + } + if p[0].Name != "A" { + panic("triangle: " + panicNameMismatch) + } + if p[1].Name != "B" { + panic("triangle: " + panicNameMismatch) + } + if p[2].Name != "C" { + panic("triangle: " + panicNameMismatch) + } + + checkTriangleParameters(p[0].Value, p[1].Value, p[2].Value) + + t.a = p[0].Value + t.b = p[1].Value + t.c = p[2].Value +} + +// Variance returns the variance of the probability distribution. +func (t Triangle) Variance() float64 { + return (t.a*t.a + t.b*t.b + t.c*t.c - t.a*t.b - t.a*t.c - t.b*t.c) / 18 +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/triangle_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/triangle_test.go new file mode 100644 index 00000000..c18ea939 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/triangle_test.go @@ -0,0 +1,101 @@ +// 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 distuv + +import ( + "math" + "math/rand" + "sort" + "testing" +) + +func TestTriangleConstraint(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Errorf("The constraints were violated, but not caught") + } + }() + + // test b < a + NewTriangle(3, 1, 2) + // test c > b + NewTriangle(1, 2, 3) +} + +func TestTriangle(t *testing.T) { + src := rand.New(rand.NewSource(1)) + for i, test := range []struct { + a, b, c float64 + }{ + { + a: 0.0, + b: 1.0, + c: 0.5, + }, + { + a: 0.1, + b: 0.3, + c: 0.2, + }, + { + a: 1.0, + b: 2.0, + c: 1.5, + }, + { + a: 0.0, + b: 1.0, + c: 0.0, + }, + } { + f := NewTriangle(test.a, test.b, test.c) + f.Source = src + tol := 1e-2 + const n = 1e5 + x := make([]float64, n) + generateSamples(x, f) + sort.Float64s(x) + + checkMean(t, i, x, f, tol) + checkVarAndStd(t, i, x, f, tol) + checkEntropy(t, i, x, f, tol) + checkExKurtosis(t, i, x, f, tol) + checkSkewness(t, i, x, f, 5e-2) + checkMedian(t, i, x, f, tol) + checkQuantileCDFSurvival(t, i, x, f, tol) + checkProbContinuous(t, i, x, f, 1e-10) + checkProbQuantContinuous(t, i, x, f, tol) + } +} + +func TestTriangleProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0.5, + prob: 0, + cumProb: 0, + logProb: math.Inf(-1), + }, + { + loc: 1, + prob: 0, + cumProb: 0, + logProb: math.Inf(-1), + }, + { + loc: 2, + prob: 1.0, + cumProb: 0.5, + logProb: 0, + }, + { + loc: 3, + prob: 0, + cumProb: 1, + logProb: math.Inf(-1), + }, + } + testDistributionProbs(t, NewTriangle(1, 3, 2), "Standard 1,2,3 Triangle", pts) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/uniform.go b/vendor/gonum.org/v1/gonum/stat/distuv/uniform.go new file mode 100644 index 00000000..0c6c41b7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/uniform.go @@ -0,0 +1,158 @@ +// 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 distuv + +import ( + "math" + "math/rand" +) + +// UnitUniform is an instantiation of the uniform distribution with Min = 0 +// and Max = 1. +var UnitUniform = Uniform{Min: 0, Max: 1} + +// Uniform represents a continuous uniform distribution (https://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29). +type Uniform struct { + Min float64 + Max float64 + Source *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (u Uniform) CDF(x float64) float64 { + if x < u.Min { + return 0 + } + if x > u.Max { + return 1 + } + return (x - u.Min) / (u.Max - u.Min) +} + +// Uniform doesn't have any of the DLogProbD? because the derivative is 0 everywhere +// except where it's undefined + +// Entropy returns the entropy of the distribution. +func (u Uniform) Entropy() float64 { + return math.Log(u.Max - u.Min) +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (Uniform) ExKurtosis() float64 { + return -6.0 / 5.0 +} + +// Uniform doesn't have Fit because it's a bad idea to fit a uniform from data. + +// LogProb computes the natural logarithm of the value of the probability density function at x. +func (u Uniform) LogProb(x float64) float64 { + if x < u.Min { + return math.Inf(-1) + } + if x > u.Max { + return math.Inf(-1) + } + return -math.Log(u.Max - u.Min) +} + +// MarshalParameters implements the ParameterMarshaler interface +func (u Uniform) MarshalParameters(p []Parameter) { + if len(p) != u.NumParameters() { + panic("uniform: improper parameter length") + } + p[0].Name = "Min" + p[0].Value = u.Min + p[1].Name = "Max" + p[1].Value = u.Max +} + +// Mean returns the mean of the probability distribution. +func (u Uniform) Mean() float64 { + return (u.Max + u.Min) / 2 +} + +// Median returns the median of the probability distribution. +func (u Uniform) Median() float64 { + return (u.Max + u.Min) / 2 +} + +// Uniform doesn't have a mode because it's any value in the distribution + +// NumParameters returns the number of parameters in the distribution. +func (Uniform) NumParameters() int { + return 2 +} + +// Prob computes the value of the probability density function at x. +func (u Uniform) Prob(x float64) float64 { + if x < u.Min { + return 0 + } + if x > u.Max { + return 0 + } + return 1 / (u.Max - u.Min) +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (u Uniform) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + return p*(u.Max-u.Min) + u.Min +} + +// Rand returns a random sample drawn from the distribution. +func (u Uniform) Rand() float64 { + var rnd float64 + if u.Source == nil { + rnd = rand.Float64() + } else { + rnd = u.Source.Float64() + } + return rnd*(u.Max-u.Min) + u.Min +} + +// Skewness returns the skewness of the distribution. +func (Uniform) Skewness() float64 { + return 0 +} + +// StdDev returns the standard deviation of the probability distribution. +func (u Uniform) StdDev() float64 { + return math.Sqrt(u.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (u Uniform) Survival(x float64) float64 { + if x < u.Min { + return 1 + } + if x > u.Max { + return 0 + } + return (u.Max - x) / (u.Max - u.Min) +} + +// UnmarshalParameters implements the ParameterMarshaler interface +func (u *Uniform) UnmarshalParameters(p []Parameter) { + if len(p) != u.NumParameters() { + panic("uniform: incorrect number of parameters to set") + } + if p[0].Name != "Min" { + panic("uniform: " + panicNameMismatch) + } + if p[1].Name != "Max" { + panic("uniform: " + panicNameMismatch) + } + + u.Min = p[0].Value + u.Max = p[1].Value +} + +// Variance returns the variance of the probability distribution. +func (u Uniform) Variance() float64 { + return 1.0 / 12.0 * (u.Max - u.Min) * (u.Max - u.Min) +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/weibull.go b/vendor/gonum.org/v1/gonum/stat/distuv/weibull.go new file mode 100644 index 00000000..72f7f97a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/weibull.go @@ -0,0 +1,247 @@ +// 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 distuv + +import ( + "math" + "math/cmplx" + "math/rand" +) + +// Weibull distribution. Valid range for x is [0,+∞). +type Weibull struct { + // Shape parameter of the distribution. A value of 1 represents + // the exponential distribution. A value of 2 represents the + // Rayleigh distribution. Valid range is (0,+∞). + K float64 + // Scale parameter of the distribution. Valid range is (0,+∞). + Lambda float64 + // Source of random numbers + Source *rand.Rand +} + +// CDF computes the value of the cumulative density function at x. +func (w Weibull) CDF(x float64) float64 { + if x < 0 { + return 0 + } else { + return 1 - cmplx.Abs(cmplx.Exp(w.LogCDF(x))) + } +} + +// Entropy returns the entropy of the distribution. +func (w Weibull) Entropy() float64 { + return eulerGamma*(1-1/w.K) + math.Log(w.Lambda/w.K) + 1 +} + +// ExKurtosis returns the excess kurtosis of the distribution. +func (w Weibull) ExKurtosis() float64 { + return (-6*w.gammaIPow(1, 4) + 12*w.gammaIPow(1, 2)*math.Gamma(1+2/w.K) - 3*w.gammaIPow(2, 2) - 4*math.Gamma(1+1/w.K)*math.Gamma(1+3/w.K) + math.Gamma(1+4/w.K)) / math.Pow(math.Gamma(1+2/w.K)-w.gammaIPow(1, 2), 2) +} + +// gammIPow is a shortcut for computing the gamma function to a power. +func (w Weibull) gammaIPow(i, pow float64) float64 { + return math.Pow(math.Gamma(1+i/w.K), pow) +} + +// LogCDF computes the value of the log of the cumulative density function at x. +func (w Weibull) LogCDF(x float64) complex128 { + if x < 0 { + return 0 + } else { + return cmplx.Log(-1) + complex(-math.Pow(x/w.Lambda, w.K), 0) + } +} + +// LogProb computes the natural logarithm of the value of the probability +// density function at x. Zero is returned if x is less than zero. +// +// Special cases occur when x == 0, and the result depends on the shape +// parameter as follows: +// If 0 < K < 1, LogProb returns +Inf. +// If K == 1, LogProb returns 0. +// If K > 1, LogProb returns -Inf. +func (w Weibull) LogProb(x float64) float64 { + if x < 0 { + return 0 + } else { + return math.Log(w.K) - math.Log(w.Lambda) + (w.K-1)*(math.Log(x)-math.Log(w.Lambda)) - math.Pow(x/w.Lambda, w.K) + } +} + +// Survival returns the log of the survival function (complementary CDF) at x. +func (w Weibull) LogSurvival(x float64) float64 { + if x < 0 { + return 0 + } else { + return -math.Pow(x/w.Lambda, w.K) + } +} + +// Mean returns the mean of the probability distribution. +func (w Weibull) Mean() float64 { + return w.Lambda * math.Gamma(1+1/w.K) +} + +// Median returns the median of the normal distribution. +func (w Weibull) Median() float64 { + return w.Lambda * math.Pow(ln2, 1/w.K) +} + +// Mode returns the mode of the normal distribution. +// +// The mode is NaN in the special case where the K (shape) parameter +// is less than 1. +func (w Weibull) Mode() float64 { + if w.K > 1 { + return w.Lambda * math.Pow((w.K-1)/w.K, 1/w.K) + } else if w.K == 1 { + return 0 + } else { + return math.NaN() + } +} + +// NumParameters returns the number of parameters in the distribution. +func (Weibull) NumParameters() int { + return 2 +} + +// Prob computes the value of the probability density function at x. +func (w Weibull) Prob(x float64) float64 { + if x < 0 { + return 0 + } else { + return math.Exp(w.LogProb(x)) + } +} + +// Quantile returns the inverse of the cumulative probability distribution. +func (w Weibull) Quantile(p float64) float64 { + if p < 0 || p > 1 { + panic(badPercentile) + } + return w.Lambda * math.Pow(-math.Log(1-p), 1/w.K) +} + +// Rand returns a random sample drawn from the distribution. +func (w Weibull) Rand() float64 { + var rnd float64 + if w.Source == nil { + rnd = rand.Float64() + } else { + rnd = w.Source.Float64() + } + return w.Quantile(rnd) +} + +// Score returns the score function with respect to the parameters of the +// distribution at the input location x. The score function is the derivative +// of the log-likelihood at x with respect to the parameters +// (∂/∂θ) log(p(x;θ)) +// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise +// Score will panic, and the derivative is stored in-place into deriv. If deriv +// is nil a new slice will be allocated and returned. +// +// The order is [∂LogProb / ∂K, ∂LogProb / ∂λ]. +// +// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29. +// +// Special cases: +// Score(0) = [NaN, NaN] +func (w Weibull) Score(deriv []float64, x float64) []float64 { + if deriv == nil { + deriv = make([]float64, w.NumParameters()) + } + if len(deriv) != w.NumParameters() { + panic(badLength) + } + if x > 0 { + deriv[0] = 1/w.K + math.Log(x) - math.Log(w.Lambda) - (math.Log(x)-math.Log(w.Lambda))*math.Pow(x/w.Lambda, w.K) + deriv[1] = (w.K * (math.Pow(x/w.Lambda, w.K) - 1)) / w.Lambda + return deriv + } + if x < 0 { + deriv[0] = 0 + deriv[1] = 0 + return deriv + } + deriv[0] = math.NaN() + deriv[0] = math.NaN() + return deriv +} + +// ScoreInput returns the score function with respect to the input of the +// distribution at the input location specified by x. The score function is the +// derivative of the log-likelihood +// (d/dx) log(p(x)) . +// +// Special cases: +// ScoreInput(0) = NaN +func (w Weibull) ScoreInput(x float64) float64 { + if x > 0 { + return (-w.K*math.Pow(x/w.Lambda, w.K) + w.K - 1) / x + } + if x < 0 { + return 0 + } + return math.NaN() +} + +// Skewness returns the skewness of the distribution. +func (w Weibull) Skewness() float64 { + stdDev := w.StdDev() + firstGamma, firstGammaSign := math.Lgamma(1 + 3/w.K) + logFirst := firstGamma + 3*(math.Log(w.Lambda)-math.Log(stdDev)) + logSecond := math.Log(3) + math.Log(w.Mean()) + 2*math.Log(stdDev) - 3*math.Log(stdDev) + logThird := 3 * (math.Log(w.Mean()) - math.Log(stdDev)) + return float64(firstGammaSign)*math.Exp(logFirst) - math.Exp(logSecond) - math.Exp(logThird) +} + +// StdDev returns the standard deviation of the probability distribution. +func (w Weibull) StdDev() float64 { + return math.Sqrt(w.Variance()) +} + +// Survival returns the survival function (complementary CDF) at x. +func (w Weibull) Survival(x float64) float64 { + return math.Exp(w.LogSurvival(x)) +} + +// setParameters modifies the parameters of the distribution. +func (w *Weibull) setParameters(p []Parameter) { + if len(p) != w.NumParameters() { + panic("weibull: incorrect number of parameters to set") + } + if p[0].Name != "K" { + panic("weibull: " + panicNameMismatch) + } + if p[1].Name != "λ" { + panic("weibull: " + panicNameMismatch) + } + w.K = p[0].Value + w.Lambda = p[1].Value +} + +// Variance returns the variance of the probability distribution. +func (w Weibull) Variance() float64 { + return math.Pow(w.Lambda, 2) * (math.Gamma(1+2/w.K) - w.gammaIPow(1, 2)) +} + +// parameters returns the parameters of the distribution. +func (w Weibull) parameters(p []Parameter) []Parameter { + nParam := w.NumParameters() + if p == nil { + p = make([]Parameter, nParam) + } else if len(p) != nParam { + panic("weibull: improper parameter length") + } + p[0].Name = "K" + p[0].Value = w.K + p[1].Name = "λ" + p[1].Value = w.Lambda + return p + +} diff --git a/vendor/gonum.org/v1/gonum/stat/distuv/weibull_test.go b/vendor/gonum.org/v1/gonum/stat/distuv/weibull_test.go new file mode 100644 index 00000000..cd78f49f --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/distuv/weibull_test.go @@ -0,0 +1,209 @@ +// 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 distuv + +import ( + "math" + "testing" +) + +func TestHalfKStandardWeibullProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: math.Inf(1), + cumProb: 0, + logProb: math.Inf(1), + }, + { + loc: -1, + prob: 0, + cumProb: 0, + logProb: 0, + }, + { + loc: 1, + prob: 0.183939720585721, + cumProb: 0.632120558828558, + logProb: -1.693147180559950, + }, + { + loc: 20, + prob: 0.001277118038048, + cumProb: 0.988577109006533, + logProb: -6.663149272336520, + }, + } + testDistributionProbs(t, Weibull{K: 0.5, Lambda: 1}, "0.5K Standard Weibull", pts) +} + +func TestExponentialStandardWeibullProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: 1, + cumProb: 0, + logProb: math.Inf(1), + }, + { + loc: -1, + prob: 0, + cumProb: 0, + logProb: 0, + }, + { + loc: 1, + prob: 0.367879441171442, + cumProb: 0.632120558828558, + logProb: -1.0, + }, + { + loc: 20, + prob: 0.000000002061154, + cumProb: 0.999999997938846, + logProb: -20.0, + }, + } + testDistributionProbs(t, Weibull{K: 1, Lambda: 1}, "1K (Exponential) Standard Weibull", pts) +} + +func TestRayleighStandardWeibullProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: 0, + cumProb: 0, + logProb: math.Inf(-1), + }, + { + loc: -1, + prob: 0, + cumProb: 0, + logProb: 0, + }, + { + loc: 1, + prob: 0.735758882342885, + cumProb: 0.632120558828558, + logProb: -0.306852819440055, + }, + { + loc: 20, + prob: 0, + cumProb: 1, + logProb: -396.31112054588607, + }, + } + testDistributionProbs(t, Weibull{K: 2, Lambda: 1}, "2K (Rayleigh) Standard Weibull", pts) +} + +func TestFiveKStandardWeibullProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: 0, + cumProb: 0, + logProb: math.Inf(-1), + }, + { + loc: -1, + prob: 0, + cumProb: 0, + logProb: 0, + }, + { + loc: 1, + prob: 1.839397205857210, + cumProb: 0.632120558828558, + logProb: 0.609437912434100, + }, + { + loc: 20, + prob: 0, + cumProb: 1, + logProb: -3199986.4076329935, + }, + } + testDistributionProbs(t, Weibull{K: 5, Lambda: 1}, "5K Standard Weibull", pts) +} + +func TestScaledUpHalfKStandardWeibullProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: math.Inf(1), + cumProb: 0, + logProb: math.Inf(1), + }, + { + loc: -1, + prob: 0, + cumProb: 0, + logProb: 0, + }, + { + loc: 1, + prob: 0.180436508682207, + cumProb: 0.558022622759326, + logProb: -1.712376315541750, + }, + { + loc: 20, + prob: 0.002369136850928, + cumProb: 0.974047406098605, + logProb: -6.045229588092130, + }, + } + testDistributionProbs(t, Weibull{K: 0.5, Lambda: 1.5}, "0.5K 1.5λ Weibull", pts) +} + +func TestScaledDownHalfKStandardWeibullProb(t *testing.T) { + pts := []univariateProbPoint{ + { + loc: 0, + prob: math.Inf(1), + cumProb: 0, + logProb: math.Inf(1), + }, + { + loc: -1, + prob: 0, + cumProb: 0, + logProb: 0, + }, + { + loc: 1, + prob: 0.171909491538362, + cumProb: 0.756883265565786, + logProb: -1.760787152653070, + }, + { + loc: 20, + prob: 0.000283302579100, + cumProb: 0.998208237166091, + logProb: -8.168995047393730, + }, + } + testDistributionProbs(t, Weibull{K: 0.5, Lambda: 0.5}, "0.5K 0.5λ Weibull", pts) +} + +func TestWeibullScore(t *testing.T) { + for _, test := range []*Weibull{ + { + K: 1, + Lambda: 1, + }, + { + K: 2, + Lambda: 3.6, + }, + { + K: 3.4, + Lambda: 8, + }, + } { + testDerivParam(t, test) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/doc.go b/vendor/gonum.org/v1/gonum/stat/doc.go new file mode 100644 index 00000000..0225eef9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package stat provides generalized statistical functions. +package stat // import "gonum.org/v1/gonum/stat" diff --git a/vendor/gonum.org/v1/gonum/stat/faithful_test.go b/vendor/gonum.org/v1/gonum/stat/faithful_test.go new file mode 100644 index 00000000..981eff1c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/faithful_test.go @@ -0,0 +1,81 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat + +// faithful is the faithful data set from R. +var faithful = struct{ waiting, eruptions []float64 }{ + waiting: []float64{ + 79, 54, 74, 62, 85, 55, 88, 85, + 51, 85, 54, 84, 78, 47, 83, 52, + 62, 84, 52, 79, 51, 47, 78, 69, + 74, 83, 55, 76, 78, 79, 73, 77, + 66, 80, 74, 52, 48, 80, 59, 90, + 80, 58, 84, 58, 73, 83, 64, 53, + 82, 59, 75, 90, 54, 80, 54, 83, + 71, 64, 77, 81, 59, 84, 48, 82, + 60, 92, 78, 78, 65, 73, 82, 56, + 79, 71, 62, 76, 60, 78, 76, 83, + 75, 82, 70, 65, 73, 88, 76, 80, + 48, 86, 60, 90, 50, 78, 63, 72, + 84, 75, 51, 82, 62, 88, 49, 83, + 81, 47, 84, 52, 86, 81, 75, 59, + 89, 79, 59, 81, 50, 85, 59, 87, + 53, 69, 77, 56, 88, 81, 45, 82, + 55, 90, 45, 83, 56, 89, 46, 82, + 51, 86, 53, 79, 81, 60, 82, 77, + 76, 59, 80, 49, 96, 53, 77, 77, + 65, 81, 71, 70, 81, 93, 53, 89, + 45, 86, 58, 78, 66, 76, 63, 88, + 52, 93, 49, 57, 77, 68, 81, 81, + 73, 50, 85, 74, 55, 77, 83, 83, + 51, 78, 84, 46, 83, 55, 81, 57, + 76, 84, 77, 81, 87, 77, 51, 78, + 60, 82, 91, 53, 78, 46, 77, 84, + 49, 83, 71, 80, 49, 75, 64, 76, + 53, 94, 55, 76, 50, 82, 54, 75, + 78, 79, 78, 78, 70, 79, 70, 54, + 86, 50, 90, 54, 54, 77, 79, 64, + 75, 47, 86, 63, 85, 82, 57, 82, + 67, 74, 54, 83, 73, 73, 88, 80, + 71, 83, 56, 79, 78, 84, 58, 83, + 43, 60, 75, 81, 46, 90, 46, 74, + }, + eruptions: []float64{ + 3.600, 1.800, 3.333, 2.283, 4.533, 2.883, 4.700, 3.600, + 1.950, 4.350, 1.833, 3.917, 4.200, 1.750, 4.700, 2.167, + 1.750, 4.800, 1.600, 4.250, 1.800, 1.750, 3.450, 3.067, + 4.533, 3.600, 1.967, 4.083, 3.850, 4.433, 4.300, 4.467, + 3.367, 4.033, 3.833, 2.017, 1.867, 4.833, 1.833, 4.783, + 4.350, 1.883, 4.567, 1.750, 4.533, 3.317, 3.833, 2.100, + 4.633, 2.000, 4.800, 4.716, 1.833, 4.833, 1.733, 4.883, + 3.717, 1.667, 4.567, 4.317, 2.233, 4.500, 1.750, 4.800, + 1.817, 4.400, 4.167, 4.700, 2.067, 4.700, 4.033, 1.967, + 4.500, 4.000, 1.983, 5.067, 2.017, 4.567, 3.883, 3.600, + 4.133, 4.333, 4.100, 2.633, 4.067, 4.933, 3.950, 4.517, + 2.167, 4.000, 2.200, 4.333, 1.867, 4.817, 1.833, 4.300, + 4.667, 3.750, 1.867, 4.900, 2.483, 4.367, 2.100, 4.500, + 4.050, 1.867, 4.700, 1.783, 4.850, 3.683, 4.733, 2.300, + 4.900, 4.417, 1.700, 4.633, 2.317, 4.600, 1.817, 4.417, + 2.617, 4.067, 4.250, 1.967, 4.600, 3.767, 1.917, 4.500, + 2.267, 4.650, 1.867, 4.167, 2.800, 4.333, 1.833, 4.383, + 1.883, 4.933, 2.033, 3.733, 4.233, 2.233, 4.533, 4.817, + 4.333, 1.983, 4.633, 2.017, 5.100, 1.800, 5.033, 4.000, + 2.400, 4.600, 3.567, 4.000, 4.500, 4.083, 1.800, 3.967, + 2.200, 4.150, 2.000, 3.833, 3.500, 4.583, 2.367, 5.000, + 1.933, 4.617, 1.917, 2.083, 4.583, 3.333, 4.167, 4.333, + 4.500, 2.417, 4.000, 4.167, 1.883, 4.583, 4.250, 3.767, + 2.033, 4.433, 4.083, 1.833, 4.417, 2.183, 4.800, 1.833, + 4.800, 4.100, 3.966, 4.233, 3.500, 4.366, 2.250, 4.667, + 2.100, 4.350, 4.133, 1.867, 4.600, 1.783, 4.367, 3.850, + 1.933, 4.500, 2.383, 4.700, 1.867, 3.833, 3.417, 4.233, + 2.400, 4.800, 2.000, 4.150, 1.867, 4.267, 1.750, 4.483, + 4.000, 4.117, 4.083, 4.267, 3.917, 4.550, 4.083, 2.417, + 4.183, 2.217, 4.450, 1.883, 1.850, 4.283, 3.950, 2.333, + 4.150, 2.350, 4.933, 2.900, 4.583, 3.833, 2.083, 4.367, + 2.133, 4.350, 2.200, 4.450, 3.567, 4.500, 4.150, 3.817, + 3.917, 4.450, 2.000, 4.283, 4.767, 4.533, 1.850, 4.250, + 1.983, 2.250, 4.750, 4.117, 2.150, 4.417, 1.817, 4.467, + }, +} diff --git a/vendor/gonum.org/v1/gonum/stat/moments_bench_test.go b/vendor/gonum.org/v1/gonum/stat/moments_bench_test.go new file mode 100644 index 00000000..6df41394 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/moments_bench_test.go @@ -0,0 +1,611 @@ +// 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. + +// a set of benchmarks to evaluate the performance of the various +// moment statistics: Mean, Variance, StdDev, MeanVariance, MeanStdDev, +// Covariance, Correlation, Skew, ExKurtosis, Moment, MomentAbout, ... +// +// It tests both weighted and unweighted versions by using a slice of +// all ones. + +package stat + +import ( + "math/rand" + "testing" +) + +const ( + small = 10 + medium = 1000 + large = 100000 + huge = 10000000 +) + +// tests for unweighted versions + +func RandomSlice(l int) []float64 { + s := make([]float64, l) + for i := range s { + s[i] = rand.Float64() + } + return s +} + +func benchmarkMean(b *testing.B, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + Mean(s, wts) + } +} + +func BenchmarkMeanSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkMean(b, s, nil) +} + +func BenchmarkMeanMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkMean(b, s, nil) +} + +func BenchmarkMeanLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkMean(b, s, nil) +} + +func BenchmarkMeanHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkMean(b, s, nil) +} + +func BenchmarkMeanSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkMean(b, s, wts) +} + +func BenchmarkMeanMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkMean(b, s, wts) +} + +func BenchmarkMeanLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkMean(b, s, wts) +} + +func BenchmarkMeanHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkMean(b, s, wts) +} + +func benchmarkVariance(b *testing.B, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + Variance(s, wts) + } +} + +func BenchmarkVarianceSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkVariance(b, s, nil) +} + +func BenchmarkVarianceMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkVariance(b, s, nil) +} + +func BenchmarkVarianceLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkVariance(b, s, nil) +} + +func BenchmarkVarianceHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkVariance(b, s, nil) +} + +func BenchmarkVarianceSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkVariance(b, s, wts) +} + +func BenchmarkVarianceMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkVariance(b, s, wts) +} + +func BenchmarkVarianceLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkVariance(b, s, wts) +} + +func BenchmarkVarianceHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkVariance(b, s, wts) +} + +func benchmarkStdDev(b *testing.B, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + StdDev(s, wts) + } +} + +func BenchmarkStdDevSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkStdDev(b, s, nil) +} + +func BenchmarkStdDevMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkStdDev(b, s, nil) +} + +func BenchmarkStdDevLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkStdDev(b, s, nil) +} + +func BenchmarkStdDevHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkStdDev(b, s, nil) +} + +func BenchmarkStdDevSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkStdDev(b, s, wts) +} + +func BenchmarkStdDevMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkStdDev(b, s, wts) +} + +func BenchmarkStdDevLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkStdDev(b, s, wts) +} + +func BenchmarkStdDevHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkStdDev(b, s, wts) +} + +func benchmarkMeanVariance(b *testing.B, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + MeanVariance(s, wts) + } +} + +func BenchmarkMeanVarianceSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkMeanVariance(b, s, nil) +} + +func BenchmarkMeanVarianceMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkMeanVariance(b, s, nil) +} + +func BenchmarkMeanVarianceLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkMeanVariance(b, s, nil) +} + +func BenchmarkMeanVarianceHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkMeanVariance(b, s, nil) +} + +func BenchmarkMeanVarianceSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkMeanVariance(b, s, wts) +} + +func BenchmarkMeanVarianceMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkMeanVariance(b, s, wts) +} + +func BenchmarkMeanVarianceLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkMeanVariance(b, s, wts) +} + +func BenchmarkMeanVarianceHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkMeanVariance(b, s, wts) +} + +func benchmarkMeanStdDev(b *testing.B, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + MeanStdDev(s, wts) + } +} + +func BenchmarkMeanStdDevSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkMeanStdDev(b, s, nil) +} + +func BenchmarkMeanStdDevMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkMeanStdDev(b, s, nil) +} + +func BenchmarkMeanStdDevLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkMeanStdDev(b, s, nil) +} + +func BenchmarkMeanStdDevHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkMeanStdDev(b, s, nil) +} + +func BenchmarkMeanStdDevSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkMeanStdDev(b, s, wts) +} + +func BenchmarkMeanStdDevMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkMeanStdDev(b, s, wts) +} + +func BenchmarkMeanStdDevLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkMeanStdDev(b, s, wts) +} + +func BenchmarkMeanStdDevHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkMeanStdDev(b, s, wts) +} + +func benchmarkCovariance(b *testing.B, s1, s2, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + Covariance(s1, s2, wts) + } +} + +func BenchmarkCovarianceSmall(b *testing.B) { + s1 := RandomSlice(small) + s2 := RandomSlice(small) + benchmarkCovariance(b, s1, s2, nil) +} + +func BenchmarkCovarianceMedium(b *testing.B) { + s1 := RandomSlice(medium) + s2 := RandomSlice(medium) + benchmarkCovariance(b, s1, s2, nil) +} + +func BenchmarkCovarianceLarge(b *testing.B) { + s1 := RandomSlice(large) + s2 := RandomSlice(large) + benchmarkCovariance(b, s1, s2, nil) +} + +func BenchmarkCovarianceHuge(b *testing.B) { + s1 := RandomSlice(huge) + s2 := RandomSlice(huge) + benchmarkCovariance(b, s1, s2, nil) +} + +func BenchmarkCovarianceSmallWeighted(b *testing.B) { + s1 := RandomSlice(small) + s2 := RandomSlice(small) + wts := RandomSlice(small) + benchmarkCovariance(b, s1, s2, wts) +} + +func BenchmarkCovarianceMediumWeighted(b *testing.B) { + s1 := RandomSlice(medium) + s2 := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkCovariance(b, s1, s2, wts) +} + +func BenchmarkCovarianceLargeWeighted(b *testing.B) { + s1 := RandomSlice(large) + s2 := RandomSlice(large) + wts := RandomSlice(large) + benchmarkCovariance(b, s1, s2, wts) +} + +func BenchmarkCovarianceHugeWeighted(b *testing.B) { + s1 := RandomSlice(huge) + s2 := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkCovariance(b, s1, s2, wts) +} + +func benchmarkCorrelation(b *testing.B, s1, s2, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + Correlation(s1, s2, wts) + } +} + +func BenchmarkCorrelationSmall(b *testing.B) { + s1 := RandomSlice(small) + s2 := RandomSlice(small) + benchmarkCorrelation(b, s1, s2, nil) +} + +func BenchmarkCorrelationMedium(b *testing.B) { + s1 := RandomSlice(medium) + s2 := RandomSlice(medium) + benchmarkCorrelation(b, s1, s2, nil) +} + +func BenchmarkCorrelationLarge(b *testing.B) { + s1 := RandomSlice(large) + s2 := RandomSlice(large) + benchmarkCorrelation(b, s1, s2, nil) +} + +func BenchmarkCorrelationHuge(b *testing.B) { + s1 := RandomSlice(huge) + s2 := RandomSlice(huge) + benchmarkCorrelation(b, s1, s2, nil) +} + +func BenchmarkCorrelationSmallWeighted(b *testing.B) { + s1 := RandomSlice(small) + s2 := RandomSlice(small) + wts := RandomSlice(small) + benchmarkCorrelation(b, s1, s2, wts) +} + +func BenchmarkCorrelationMediumWeighted(b *testing.B) { + s1 := RandomSlice(medium) + s2 := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkCorrelation(b, s1, s2, wts) +} + +func BenchmarkCorrelationLargeWeighted(b *testing.B) { + s1 := RandomSlice(large) + s2 := RandomSlice(large) + wts := RandomSlice(large) + benchmarkCorrelation(b, s1, s2, wts) +} + +func BenchmarkCorrelationHugeWeighted(b *testing.B) { + s1 := RandomSlice(huge) + s2 := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkCorrelation(b, s1, s2, wts) +} + +func benchmarkSkew(b *testing.B, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + Skew(s, wts) + } +} + +func BenchmarkSkewSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkSkew(b, s, nil) +} + +func BenchmarkSkewMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkSkew(b, s, nil) +} + +func BenchmarkSkewLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkSkew(b, s, nil) +} + +func BenchmarkSkewHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkSkew(b, s, nil) +} + +func BenchmarkSkewSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkSkew(b, s, wts) +} + +func BenchmarkSkewMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkSkew(b, s, wts) +} + +func BenchmarkSkewLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkSkew(b, s, wts) +} + +func BenchmarkSkewHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkSkew(b, s, wts) +} + +func benchmarkExKurtosis(b *testing.B, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + ExKurtosis(s, wts) + } +} + +func BenchmarkExKurtosisSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkExKurtosis(b, s, nil) +} + +func BenchmarkExKurtosisMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkExKurtosis(b, s, nil) +} + +func BenchmarkExKurtosisLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkExKurtosis(b, s, nil) +} + +func BenchmarkExKurtosisHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkExKurtosis(b, s, nil) +} + +func BenchmarkExKurtosisSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkExKurtosis(b, s, wts) +} + +func BenchmarkExKurtosisMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkExKurtosis(b, s, wts) +} + +func BenchmarkExKurtosisLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkExKurtosis(b, s, wts) +} + +func BenchmarkExKurtosisHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkExKurtosis(b, s, wts) +} + +func benchmarkMoment(b *testing.B, n float64, s, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + Moment(n, s, wts) + } +} + +func BenchmarkMomentSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkMoment(b, 5, s, nil) +} + +func BenchmarkMomentMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkMoment(b, 5, s, nil) +} + +func BenchmarkMomentLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkMoment(b, 5, s, nil) +} + +func BenchmarkMomentHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkMoment(b, 5, s, nil) +} + +func BenchmarkMomentSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkMoment(b, 5, s, wts) +} + +func BenchmarkMomentMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkMoment(b, 5, s, wts) +} + +func BenchmarkMomentLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkMoment(b, 5, s, wts) +} + +func BenchmarkMomentHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkMoment(b, 5, s, wts) +} + +func benchmarkMomentAbout(b *testing.B, n float64, s []float64, mean float64, wts []float64) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + MomentAbout(n, s, mean, wts) + } +} + +func BenchmarkMomentAboutSmall(b *testing.B) { + s := RandomSlice(small) + benchmarkMomentAbout(b, 5, s, 0, nil) +} + +func BenchmarkMomentAboutMedium(b *testing.B) { + s := RandomSlice(medium) + benchmarkMomentAbout(b, 5, s, 0, nil) +} + +func BenchmarkMomentAboutLarge(b *testing.B) { + s := RandomSlice(large) + benchmarkMomentAbout(b, 5, s, 0, nil) +} + +func BenchmarkMomentAboutHuge(b *testing.B) { + s := RandomSlice(huge) + benchmarkMomentAbout(b, 5, s, 0, nil) +} + +func BenchmarkMomentAboutSmallWeighted(b *testing.B) { + s := RandomSlice(small) + wts := RandomSlice(small) + benchmarkMomentAbout(b, 5, s, 0, wts) +} + +func BenchmarkMomentAboutMediumWeighted(b *testing.B) { + s := RandomSlice(medium) + wts := RandomSlice(medium) + benchmarkMomentAbout(b, 5, s, 0, wts) +} + +func BenchmarkMomentAboutLargeWeighted(b *testing.B) { + s := RandomSlice(large) + wts := RandomSlice(large) + benchmarkMomentAbout(b, 5, s, 0, wts) +} + +func BenchmarkMomentAboutHugeWeighted(b *testing.B) { + s := RandomSlice(huge) + wts := RandomSlice(huge) + benchmarkMomentAbout(b, 5, s, 0, wts) +} diff --git a/vendor/gonum.org/v1/gonum/stat/pca_cca.go b/vendor/gonum.org/v1/gonum/stat/pca_cca.go new file mode 100644 index 00000000..59e742eb --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/pca_cca.go @@ -0,0 +1,315 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat + +import ( + "errors" + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +// PC is a type for computing and extracting the principal components of a +// matrix. The results of the principal components analysis are only valid +// if the call to PrincipalComponents was successful. +type PC struct { + n, d int + weights []float64 + svd *mat.SVD + ok bool +} + +// PrincipalComponents performs a weighted principal components analysis on the +// matrix of the input data which is represented as an n×d matrix a where each +// row is an observation and each column is a variable. +// +// PrincipalComponents centers the variables but does not scale the variance. +// +// The weights slice is used to weight the observations. If weights is nil, each +// weight is considered to have a value of one, otherwise the length of weights +// must match the number of observations or PrincipalComponents will panic. +// +// PrincipalComponents returns whether the analysis was successful. +func (c *PC) PrincipalComponents(a mat.Matrix, weights []float64) (ok bool) { + c.n, c.d = a.Dims() + if weights != nil && len(weights) != c.n { + panic("stat: len(weights) != observations") + } + + c.svd, c.ok = svdFactorizeCentered(c.svd, a, weights) + if c.ok { + c.weights = append(c.weights[:0], weights...) + } + return c.ok +} + +// VectorsTo returns the component direction vectors of a principal components +// analysis. The vectors are returned in the columns of a d×min(n, d) matrix. +// If dst is not nil it must either be zero-sized or be a d×min(n, d) matrix. +// dst will be used as the destination for the direction vector data. If dst +// is nil, a new mat.Dense is allocated for the destination. +func (c *PC) VectorsTo(dst *mat.Dense) *mat.Dense { + if !c.ok { + panic("stat: use of unsuccessful principal components analysis") + } + + if dst != nil { + if d, n := dst.Dims(); !dst.IsZero() && (d != c.d || n != min(c.n, c.d)) { + panic(mat.ErrShape) + } + } + return c.svd.VTo(dst) +} + +// VarsTo returns the column variances of the principal component scores, +// b * vecs, where b is a matrix with centered columns. Variances are returned +// in descending order. +// If dst is not nil it is used to store the variances and returned. +// Vars will panic if the receiver has not successfully performed a principal +// components analysis or dst is not nil and the length of dst is not min(n, d). +func (c *PC) VarsTo(dst []float64) []float64 { + if !c.ok { + panic("stat: use of unsuccessful principal components analysis") + } + if dst != nil && len(dst) != min(c.n, c.d) { + panic("stat: length of slice does not match analysis") + } + + dst = c.svd.Values(dst) + var f float64 + if c.weights == nil { + f = 1 / float64(c.n-1) + } else { + f = 1 / (floats.Sum(c.weights) - 1) + } + for i, v := range dst { + dst[i] = f * v * v + } + return dst +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +// CC is a type for computing the canonical correlations of a pair of matrices. +// The results of the canonical correlation analysis are only valid +// if the call to CanonicalCorrelations was successful. +type CC struct { + // n is the number of observations used to + // construct the canonical correlations. + n int + + // xd and yd are used for size checks. + xd, yd int + + x, y, c *mat.SVD + ok bool +} + +// CanonicalCorrelations returns a CC which can provide the results of canonical +// correlation analysis of the input data x and y, columns of which should be +// interpretable as two sets of measurements on the same observations (rows). +// These observations are optionally weighted by weights. +// +// Canonical correlation analysis finds associations between two sets of +// variables on the same observations by finding linear combinations of the two +// sphered datasets that maximize the correlation between them. +// +// Some notation: let Xc and Yc denote the centered input data matrices x +// and y (column means subtracted from each column), let Sx and Sy denote the +// sample covariance matrices within x and y respectively, and let Sxy denote +// the covariance matrix between x and y. The sphered data can then be expressed +// as Xc * Sx^{-1/2} and Yc * Sy^{-1/2} respectively, and the correlation matrix +// between the sphered data is called the canonical correlation matrix, +// Sx^{-1/2} * Sxy * Sy^{-1/2}. In cases where S^{-1/2} is ambiguous for some +// covariance matrix S, S^{-1/2} is taken to be E * D^{-1/2} * E^T where S can +// be eigendecomposed as S = E * D * E^T. +// +// The canonical correlations are the correlations between the corresponding +// pairs of canonical variables and can be obtained with c.Corrs(). Canonical +// variables can be obtained by projecting the sphered data into the left and +// right eigenvectors of the canonical correlation matrix, and these +// eigenvectors can be obtained with c.Left(m, true) and c.Right(m, true) +// respectively. The canonical variables can also be obtained directly from the +// centered raw data by using the back-transformed eigenvectors which can be +// obtained with c.Left(m, false) and c.Right(m, false) respectively. +// +// The first pair of left and right eigenvectors of the canonical correlation +// matrix can be interpreted as directions into which the respective sphered +// data can be projected such that the correlation between the two projections +// is maximized. The second pair and onwards solve the same optimization but +// under the constraint that they are uncorrelated (orthogonal in sphered space) +// to previous projections. +// +// CanonicalCorrelations will panic if the inputs x and y do not have the same +// number of rows. +// +// The slice weights is used to weight the observations. If weights is nil, each +// weight is considered to have a value of one, otherwise the length of weights +// must match the number of observations (rows of both x and y) or +// CanonicalCorrelations will panic. +// +// More details can be found at +// https://en.wikipedia.org/wiki/Canonical_correlation +// or in Chapter 3 of +// Koch, Inge. Analysis of multivariate and high-dimensional data. +// Vol. 32. Cambridge University Press, 2013. ISBN: 9780521887939 +func (c *CC) CanonicalCorrelations(x, y mat.Matrix, weights []float64) error { + var yn int + c.n, c.xd = x.Dims() + yn, c.yd = y.Dims() + if c.n != yn { + panic("stat: unequal number of observations") + } + if weights != nil && len(weights) != c.n { + panic("stat: len(weights) != observations") + } + + // Center and factorize x and y. + c.x, c.ok = svdFactorizeCentered(c.x, x, weights) + if !c.ok { + return errors.New("stat: failed to factorize x") + } + c.y, c.ok = svdFactorizeCentered(c.y, y, weights) + if !c.ok { + return errors.New("stat: failed to factorize y") + } + xu := c.x.UTo(nil) + xv := c.x.VTo(nil) + yu := c.y.UTo(nil) + yv := c.y.VTo(nil) + + // Calculate and factorise the canonical correlation matrix. + var ccor mat.Dense + ccor.Product(xv, xu.T(), yu, yv.T()) + if c.c == nil { + c.c = &mat.SVD{} + } + c.ok = c.c.Factorize(&ccor, mat.SVDThin) + if !c.ok { + return errors.New("stat: failed to factorize ccor") + } + return nil +} + +// CorrsTo returns the canonical correlations, using dst if it is not nil. +// If dst is not nil and len(dst) does not match the number of columns in +// the y input matrix, Corrs will panic. +func (c *CC) CorrsTo(dst []float64) []float64 { + if !c.ok { + panic("stat: canonical correlations missing or invalid") + } + + if dst != nil && len(dst) != c.yd { + panic("stat: length of destination does not match input dimension") + } + return c.c.Values(dst) +} + +// LeftTo returns the left eigenvectors of the canonical correlation matrix if +// spheredSpace is true. If spheredSpace is false it returns these eigenvectors +// back-transformed to the original data space. +// If dst is not nil it must either be zero-sized or be an xd×yd matrix where xd +// and yd are the number of variables in the input x and y matrices. dst will +// be used as the destination for the vector data. If dst is nil, a new +// mat.Dense is allocated for the destination. +func (c *CC) LeftTo(dst *mat.Dense, spheredSpace bool) *mat.Dense { + if !c.ok || c.n < 2 { + panic("stat: canonical correlations missing or invalid") + } + + if dst != nil { + if d, n := dst.Dims(); !dst.IsZero() && (n != c.yd || d != c.xd) { + panic(mat.ErrShape) + } + } + dst = c.c.UTo(dst) + if spheredSpace { + return dst + } + + xs := c.x.Values(nil) + xv := c.x.VTo(nil) + + scaleColsReciSqrt(xv, xs) + + dst.Product(xv, xv.T(), dst) + dst.Scale(math.Sqrt(float64(c.n-1)), dst) + return dst +} + +// RightTo returns the right eigenvectors of the canonical correlation matrix if +// spheredSpace is true. If spheredSpace is false it returns these eigenvectors +// back-transformed to the original data space. +// If dst is not nil it must either be zero-sized or be an yd×yd matrix where yd +// is the number of variables in the input y matrix. dst will +// be used as the destination for the vector data. If dst is nil, a new +// mat.Dense is allocated for the destination. +func (c *CC) RightTo(dst *mat.Dense, spheredSpace bool) *mat.Dense { + if !c.ok || c.n < 2 { + panic("stat: canonical correlations missing or invalid") + } + + if dst != nil { + if d, n := dst.Dims(); (n != 0 || d != 0) && (n != c.yd || d != c.yd) { + panic(mat.ErrShape) + } + } + dst = c.c.VTo(dst) + if spheredSpace { + return dst + } + + ys := c.y.Values(nil) + yv := c.y.VTo(nil) + + scaleColsReciSqrt(yv, ys) + + dst.Product(yv, yv.T(), dst) + dst.Scale(math.Sqrt(float64(c.n-1)), dst) + return dst +} + +func svdFactorizeCentered(work *mat.SVD, m mat.Matrix, weights []float64) (svd *mat.SVD, ok bool) { + n, d := m.Dims() + centered := mat.NewDense(n, d, nil) + col := make([]float64, n) + for j := 0; j < d; j++ { + mat.Col(col, j, m) + floats.AddConst(-Mean(col, weights), col) + centered.SetCol(j, col) + } + for i, w := range weights { + floats.Scale(math.Sqrt(w), centered.RawRowView(i)) + } + if work == nil { + work = &mat.SVD{} + } + ok = work.Factorize(centered, mat.SVDThin) + return work, ok +} + +// scaleColsReciSqrt scales the columns of cols +// by the reciprocal square-root of vals. +func scaleColsReciSqrt(cols *mat.Dense, vals []float64) { + if cols == nil { + panic("stat: input nil") + } + n, d := cols.Dims() + if len(vals) != d { + panic("stat: input length mismatch") + } + col := make([]float64, n) + for j := 0; j < d; j++ { + mat.Col(col, j, cols) + floats.Scale(math.Sqrt(1/vals[j]), col) + cols.SetCol(j, col) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/pca_example_test.go b/vendor/gonum.org/v1/gonum/stat/pca_example_test.go new file mode 100644 index 00000000..b434a91a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/pca_example_test.go @@ -0,0 +1,60 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat_test + +import ( + "fmt" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +func ExamplePC() { + // iris is a truncated sample of the Fisher's Iris dataset. + n := 10 + d := 4 + iris := mat.NewDense(n, d, []float64{ + 5.1, 3.5, 1.4, 0.2, + 4.9, 3.0, 1.4, 0.2, + 4.7, 3.2, 1.3, 0.2, + 4.6, 3.1, 1.5, 0.2, + 5.0, 3.6, 1.4, 0.2, + 5.4, 3.9, 1.7, 0.4, + 4.6, 3.4, 1.4, 0.3, + 5.0, 3.4, 1.5, 0.2, + 4.4, 2.9, 1.4, 0.2, + 4.9, 3.1, 1.5, 0.1, + }) + + // Calculate the principal component direction vectors + // and variances. + var pc stat.PC + ok := pc.PrincipalComponents(iris, nil) + if !ok { + return + } + fmt.Printf("variances = %.4f\n\n", pc.VarsTo(nil)) + + // Project the data onto the first 2 principal components. + k := 2 + var proj mat.Dense + proj.Mul(iris, pc.VectorsTo(nil).Slice(0, d, 0, k)) + + fmt.Printf("proj = %.4f", mat.Formatted(&proj, mat.Prefix(" "))) + + // Output: + // variances = [0.1666 0.0207 0.0079 0.0019] + // + // proj = ⎡-6.1686 1.4659⎤ + // ⎢-5.6767 1.6459⎥ + // ⎢-5.6699 1.3642⎥ + // ⎢-5.5643 1.3816⎥ + // ⎢-6.1734 1.3309⎥ + // ⎢-6.7278 1.4021⎥ + // ⎢-5.7743 1.1498⎥ + // ⎢-6.0466 1.4714⎥ + // ⎢-5.2709 1.3570⎥ + // ⎣-5.7533 1.6207⎦ +} diff --git a/vendor/gonum.org/v1/gonum/stat/pca_test.go b/vendor/gonum.org/v1/gonum/stat/pca_test.go new file mode 100644 index 00000000..6af1b8c0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/pca_test.go @@ -0,0 +1,188 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat + +import ( + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +var appengine bool + +func TestPrincipalComponents(t *testing.T) { + if appengine { + t.Skip("non-asm implementation fails test") + } +tests: + for i, test := range []struct { + data mat.Matrix + weights []float64 + wantVecs *mat.Dense + wantVars []float64 + epsilon float64 + }{ + // Test results verified using R. + { + data: mat.NewDense(3, 3, []float64{ + 1, 2, 3, + 4, 5, 6, + 7, 8, 9, + }), + wantVecs: mat.NewDense(3, 3, []float64{ + 0.5773502691896258, 0.8164965809277261, 0, + 0.577350269189626, -0.4082482904638632, -0.7071067811865476, + 0.5773502691896258, -0.4082482904638631, 0.7071067811865475, + }), + wantVars: []float64{27, 0, 0}, + epsilon: 1e-12, + }, + { // Truncated iris data. + data: mat.NewDense(10, 4, []float64{ + 5.1, 3.5, 1.4, 0.2, + 4.9, 3.0, 1.4, 0.2, + 4.7, 3.2, 1.3, 0.2, + 4.6, 3.1, 1.5, 0.2, + 5.0, 3.6, 1.4, 0.2, + 5.4, 3.9, 1.7, 0.4, + 4.6, 3.4, 1.4, 0.3, + 5.0, 3.4, 1.5, 0.2, + 4.4, 2.9, 1.4, 0.2, + 4.9, 3.1, 1.5, 0.1, + }), + wantVecs: mat.NewDense(4, 4, []float64{ + -0.6681110197952722, 0.7064764857539533, -0.14026590216895132, -0.18666578956412125, + -0.7166344774801547, -0.6427036135482664, -0.135650285905254, 0.23444848208629923, + -0.164411275166307, 0.11898477441068218, 0.9136367900709548, 0.35224901970831746, + -0.11415613655453069, -0.2714141920887426, 0.35664028439226514, -0.8866286823515034, + }), + wantVars: []float64{0.1665786313282786, 0.02065509475412993, 0.007944620317765855, 0.0019327647109368329}, + epsilon: 1e-12, + }, + { // Truncated iris data to form wide matrix. + data: mat.NewDense(3, 4, []float64{ + 5.1, 3.5, 1.4, 0.2, + 4.9, 3.0, 1.4, 0.2, + 4.7, 3.2, 1.3, 0.2, + }), + wantVecs: mat.NewDense(4, 3, []float64{ + -0.5705187254552365, -0.7505979435049239, 0.08084520834544455, + -0.8166537769529318, 0.5615147645527523, -0.032338083338177705, + -0.08709186238359454, -0.3482870890450082, -0.22636658336724505, + 0, 0, -0.9701425001453315, + }), + wantVars: []float64{0.0844692361537822, 0.022197430512884326, 0}, + epsilon: 1e-12, + }, + { // Truncated iris data transposed to check for operation on fat input. + data: mat.NewDense(10, 4, []float64{ + 5.1, 3.5, 1.4, 0.2, + 4.9, 3.0, 1.4, 0.2, + 4.7, 3.2, 1.3, 0.2, + 4.6, 3.1, 1.5, 0.2, + 5.0, 3.6, 1.4, 0.2, + 5.4, 3.9, 1.7, 0.4, + 4.6, 3.4, 1.4, 0.3, + 5.0, 3.4, 1.5, 0.2, + 4.4, 2.9, 1.4, 0.2, + 4.9, 3.1, 1.5, 0.1, + }).T(), + wantVecs: mat.NewDense(10, 4, []float64{ + -0.3366602459946619, -0.1373634006401213, 0.3465102523547623, -0.10290179303893479, + -0.31381852053861975, 0.5197145790632827, 0.5567296129086686, -0.15923062170153618, + -0.30857197637565165, -0.07670930360819002, 0.36159923003337235, 0.3342301027853355, + -0.29527124351656137, 0.16885455995353074, -0.5056204762881208, 0.32580913261444344, + -0.3327611073694004, -0.39365834489416474, 0.04900050959307464, 0.46812879383236555, + -0.34445484362044815, -0.2985206914561878, -0.1009714701361799, -0.16803618186050803, + -0.2986246350957691, -0.4222037823717799, -0.11838613462182519, -0.580283530375069, + -0.325911246223126, 0.024366468758217238, -0.12082035131864265, 0.16756027181337868, + -0.2814284432361538, 0.240812316260054, -0.24061437569068145, -0.365034616264623, + -0.31906138507685167, 0.4423912824105986, -0.2906412122303604, 0.027551046870337714, + }), + wantVars: []float64{41.8851906634233, 0.07762619213464989, 0.010516477775373585, 0}, + epsilon: 1e-12, + }, + { // Truncated iris data unitary weights. + data: mat.NewDense(10, 4, []float64{ + 5.1, 3.5, 1.4, 0.2, + 4.9, 3.0, 1.4, 0.2, + 4.7, 3.2, 1.3, 0.2, + 4.6, 3.1, 1.5, 0.2, + 5.0, 3.6, 1.4, 0.2, + 5.4, 3.9, 1.7, 0.4, + 4.6, 3.4, 1.4, 0.3, + 5.0, 3.4, 1.5, 0.2, + 4.4, 2.9, 1.4, 0.2, + 4.9, 3.1, 1.5, 0.1, + }), + weights: []float64{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + wantVecs: mat.NewDense(4, 4, []float64{ + -0.6681110197952722, 0.7064764857539533, -0.14026590216895132, -0.18666578956412125, + -0.7166344774801547, -0.6427036135482664, -0.135650285905254, 0.23444848208629923, + -0.164411275166307, 0.11898477441068218, 0.9136367900709548, 0.35224901970831746, + -0.11415613655453069, -0.2714141920887426, 0.35664028439226514, -0.8866286823515034, + }), + wantVars: []float64{0.1665786313282786, 0.02065509475412993, 0.007944620317765855, 0.0019327647109368329}, + epsilon: 1e-12, + }, + { // Truncated iris data non-unitary weights. + data: mat.NewDense(10, 4, []float64{ + 5.1, 3.5, 1.4, 0.2, + 4.9, 3.0, 1.4, 0.2, + 4.7, 3.2, 1.3, 0.2, + 4.6, 3.1, 1.5, 0.2, + 5.0, 3.6, 1.4, 0.2, + 5.4, 3.9, 1.7, 0.4, + 4.6, 3.4, 1.4, 0.3, + 5.0, 3.4, 1.5, 0.2, + 4.4, 2.9, 1.4, 0.2, + 4.9, 3.1, 1.5, 0.1, + }), + weights: []float64{2, 3, 1, 1, 1, 1, 1, 1, 1, 2}, + wantVecs: mat.NewDense(4, 4, []float64{ + -0.618936145422414, 0.763069301531647, 0.124857741232537, 0.138035623677211, + -0.763958271606519, -0.603881770702898, 0.118267155321333, -0.194184052457746, + -0.143552119754944, 0.090014599564871, -0.942209377020044, -0.289018426115945, + -0.112599271966947, -0.212012782487076, -0.287515067921680, 0.927203898682805, + }), + wantVars: []float64{0.129621985550623, 0.022417487771598, 0.006454461065715, 0.002495076601075}, + epsilon: 1e-12, + }, + } { + var pc PC + var vecs *mat.Dense + var vars []float64 + for j := 0; j < 2; j++ { + ok := pc.PrincipalComponents(test.data, test.weights) + vecs = pc.VectorsTo(vecs) + vars = pc.VarsTo(vars) + if !ok { + t.Errorf("unexpected SVD failure for test %d use %d", i, j) + continue tests + } + if !mat.EqualApprox(vecs, test.wantVecs, test.epsilon) { + t.Errorf("%d use %d: unexpected PCA result got:\n%v\nwant:\n%v", + i, j, mat.Formatted(vecs), mat.Formatted(test.wantVecs)) + } + if !approxEqual(vars, test.wantVars, test.epsilon) { + t.Errorf("%d use %d: unexpected variance result got:%v, want:%v", + i, j, vars, test.wantVars) + } + } + } +} + +func approxEqual(a, b []float64, epsilon float64) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if !floats.EqualWithinAbsOrRel(v, b[i], epsilon, epsilon) { + return false + } + } + return true +} diff --git a/vendor/gonum.org/v1/gonum/stat/roc.go b/vendor/gonum.org/v1/gonum/stat/roc.go new file mode 100644 index 00000000..73584b61 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/roc.go @@ -0,0 +1,121 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat + +import "sort" + +// ROC returns paired false positive rate (FPR) and true positive rate +// (TPR) values corresponding to n cutoffs spanning the relative +// (or receiver) operator characteristic (ROC) curve obtained when y is +// treated as a binary classifier for classes with weights. +// +// Cutoffs are equally spaced from eps less than the minimum value of y +// to the maximum value of y, including both endpoints meaning that the +// resulting ROC curve will always begin at (0,0) and end at (1,1). +// +// The input y must be sorted, and SortWeightedLabeled can be used in +// order to sort y together with classes and weights. +// +// For a given cutoff value, observations corresponding to entries in y +// greater than the cutoff value are classified as false, while those +// below (or equal to) the cutoff value are classified as true. These +// assigned class labels are compared with the true values in the classes +// slice and used to calculate the FPR and TPR. +// +// If weights is nil, all weights are treated as 1. +// +// When n is zero all possible cutoffs are calculated, resulting +// in fpr and tpr having length one greater than the number of unique +// values in y. When n is greater than one fpr and tpr will be returned +// with length n. ROC will panic if n is equal to one or less than 0. +// +// More details about ROC curves are available at +// https://en.wikipedia.org/wiki/Receiver_operating_characteristic +func ROC(n int, y []float64, classes []bool, weights []float64) (tpr, fpr []float64) { + if len(y) != len(classes) { + panic("stat: slice length mismatch") + } + if weights != nil && len(y) != len(weights) { + panic("stat: slice length mismatch") + } + if !sort.Float64sAreSorted(y) { + panic("stat: input must be sorted") + } + + var incWidth, tol float64 + if n == 0 { + if len(y) == 0 { + return nil, nil + } + tpr = make([]float64, len(y)+1) + fpr = make([]float64, len(y)+1) + } else { + if n < 2 { + panic("stat: cannot calculate fewer than 2 points on a ROC curve") + } + if len(y) == 0 { + return nil, nil + } + tpr = make([]float64, n) + fpr = make([]float64, n) + incWidth = (y[len(y)-1] - y[0]) / float64(n-1) + tol = y[0] + incWidth + if incWidth == 0 { + tpr[n-1] = 1 + fpr[n-1] = 1 + return + } + } + + var bin int = 1 // the initial bin is known to have 0 fpr and 0 tpr + var nPos, nNeg float64 + for i, u := range classes { + var posWeight, negWeight float64 = 0, 1 + if weights != nil { + negWeight = weights[i] + } + if u { + posWeight, negWeight = negWeight, posWeight + } + nPos += posWeight + nNeg += negWeight + tpr[bin] += posWeight + fpr[bin] += negWeight + + // Assess if the bin needs to be updated. If n is zero, + // the bin is always updated, unless consecutive y values + // are equal. Otherwise, the bin must be updated until it + // matches the next y value (skipping empty bins). + if n == 0 { + if i != (len(y)-1) && y[i] != y[i+1] { + bin++ + tpr[bin] = tpr[bin-1] + fpr[bin] = fpr[bin-1] + } + } else { + for i != (len(y)-1) && y[i+1] > tol { + tol += incWidth + bin++ + tpr[bin] = tpr[bin-1] + fpr[bin] = fpr[bin-1] + } + } + } + if n == 0 { + tpr = tpr[:(bin + 1)] + fpr = fpr[:(bin + 1)] + } + + invNeg := 1 / nNeg + invPos := 1 / nPos + for i := range tpr { + tpr[i] *= invPos + fpr[i] *= invNeg + } + tpr[len(tpr)-1] = 1 + fpr[len(fpr)-1] = 1 + + return tpr, fpr +} diff --git a/vendor/gonum.org/v1/gonum/stat/roc_example_test.go b/vendor/gonum.org/v1/gonum/stat/roc_example_test.go new file mode 100644 index 00000000..9dce80b1 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/roc_example_test.go @@ -0,0 +1,56 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat_test + +import ( + "fmt" + + "gonum.org/v1/gonum/integrate" + "gonum.org/v1/gonum/stat" +) + +func ExampleROC_weighted() { + y := []float64{0, 3, 5, 6, 7.5, 8} + classes := []bool{true, false, true, false, false, false} + weights := []float64{4, 1, 6, 3, 2, 2} + + tpr, fpr := stat.ROC(0, y, classes, weights) + fmt.Printf("true positive rate: %v\n", tpr) + fmt.Printf("false positive rate: %v\n", fpr) + + // Output: + // true positive rate: [0 0.4 0.4 1 1 1 1] + // false positive rate: [0 0 0.125 0.125 0.5 0.75 1] +} + +func ExampleROC_unweighted() { + y := []float64{0, 3, 5, 6, 7.5, 8} + classes := []bool{true, false, true, false, false, false} + + tpr, fpr := stat.ROC(0, y, classes, nil) + fmt.Printf("true positive rate: %v\n", tpr) + fmt.Printf("false positive rate: %v\n", fpr) + + // Output: + // true positive rate: [0 0.5 0.5 1 1 1 1] + // false positive rate: [0 0 0.25 0.25 0.5 0.75 1] +} + +func ExampleROC_aUC() { + y := []float64{0.1, 0.35, 0.4, 0.8} + classes := []bool{true, false, true, false} + + tpr, fpr := stat.ROC(0, y, classes, nil) + // compute Area Under Curve + auc := integrate.Trapezoidal(fpr, tpr) + fmt.Printf("true positive rate: %v\n", tpr) + fmt.Printf("false positive rate: %v\n", fpr) + fmt.Printf("auc: %v\n", auc) + + // Output: + // true positive rate: [0 0.5 0.5 1 1] + // false positive rate: [0 0 0.5 0.5 1] + // auc: 0.75 +} diff --git a/vendor/gonum.org/v1/gonum/stat/roc_test.go b/vendor/gonum.org/v1/gonum/stat/roc_test.go new file mode 100644 index 00000000..99fdae13 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/roc_test.go @@ -0,0 +1,178 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stat + +import ( + "testing" + + "gonum.org/v1/gonum/floats" +) + +// Test cases where calculated manually. +func TestROC(t *testing.T) { + cases := []struct { + y []float64 + c []bool + w []float64 + n int + wantTPR []float64 + wantFPR []float64 + }{ + { + y: []float64{0, 3, 5, 6, 7.5, 8}, + c: []bool{true, false, true, false, false, false}, + wantTPR: []float64{0, 0.5, 0.5, 1, 1, 1, 1}, + wantFPR: []float64{0, 0, 0.25, 0.25, 0.5, 0.75, 1}, + }, + { + y: []float64{0, 3, 5, 6, 7.5, 8}, + c: []bool{true, false, true, false, false, false}, + w: []float64{4, 1, 6, 3, 2, 2}, + wantTPR: []float64{0, 0.4, 0.4, 1, 1, 1, 1}, + wantFPR: []float64{0, 0, 0.125, 0.125, 0.5, 0.75, 1}, + }, + { + y: []float64{0, 3, 5, 6, 7.5, 8}, + c: []bool{true, false, true, false, false, false}, + n: int(5), + wantTPR: []float64{0, 0.5, 0.5, 1, 1}, + wantFPR: []float64{0, 0, 0.25, 0.5, 1}, + }, + { + y: []float64{0, 3, 5, 6, 7.5, 8}, + c: []bool{true, false, true, false, false, false}, + n: int(9), + wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 1, 1, 1, 1}, + wantFPR: []float64{0, 0, 0, 0.25, 0.25, 0.25, 0.5, 0.5, 1}, + }, + { + y: []float64{0, 3, 5, 6, 7.5, 8}, + c: []bool{true, false, true, false, false, false}, + w: []float64{4, 1, 6, 3, 2, 2}, + n: int(5), + wantTPR: []float64{0, 0.4, 0.4, 1, 1}, + wantFPR: []float64{0, 0, 0.125, 0.5, 1}, + }, + { + y: []float64{0, 3, 5, 6, 7.5, 8}, + c: []bool{true, false, true, false, false, false}, + w: []float64{4, 1, 6, 3, 2, 2}, + n: int(9), + wantTPR: []float64{0, 0.4, 0.4, 0.4, 0.4, 1, 1, 1, 1}, + wantFPR: []float64{0, 0, 0, 0.125, 0.125, 0.125, 0.5, 0.5, 1}, + }, + { + y: []float64{0, 3, 6, 6, 6, 8}, + c: []bool{true, false, true, false, false, false}, + wantTPR: []float64{0, 0.5, 0.5, 1, 1}, + wantFPR: []float64{0, 0, 0.25, 0.75, 1}, + }, + { + y: []float64{0, 3, 6, 6, 6, 8}, + c: []bool{true, false, true, false, false, false}, + w: []float64{4, 1, 6, 3, 2, 2}, + wantTPR: []float64{0, 0.4, 0.4, 1, 1}, + wantFPR: []float64{0, 0, 0.125, 0.75, 1}, + }, + { + y: []float64{0, 3, 6, 6, 6, 8}, + c: []bool{true, false, true, false, false, false}, + n: int(5), + wantTPR: []float64{0, 0.5, 0.5, 1, 1}, + wantFPR: []float64{0, 0, 0.25, 0.75, 1}, + }, + { + y: []float64{0, 3, 6, 6, 6, 8}, + c: []bool{true, false, true, false, false, false}, + n: int(9), + wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 1, 1}, + wantFPR: []float64{0, 0, 0, 0.25, 0.25, 0.25, 0.75, 0.75, 1}, + }, + { + y: []float64{0, 3, 6, 6, 6, 8}, + c: []bool{true, false, true, false, false, false}, + w: []float64{4, 1, 6, 3, 2, 2}, + n: int(5), + wantTPR: []float64{0, 0.4, 0.4, 1, 1}, + wantFPR: []float64{0, 0, 0.125, 0.75, 1}, + }, + { + y: []float64{0, 3, 6, 6, 6, 8}, + c: []bool{true, false, true, false, false, false}, + w: []float64{4, 1, 6, 3, 2, 2}, + n: int(9), + wantTPR: []float64{0, 0.4, 0.4, 0.4, 0.4, 0.4, 1, 1, 1}, + wantFPR: []float64{0, 0, 0, 0.125, 0.125, 0.125, 0.75, 0.75, 1}, + }, + { + y: []float64{1, 2}, + c: []bool{true, true}, + wantTPR: []float64{0, 0.5, 1}, + wantFPR: []float64{0, 0, 1}, + }, + { + y: []float64{1, 2}, + c: []bool{true, true}, + n: int(2), + wantTPR: []float64{0, 1}, + wantFPR: []float64{0, 1}, + }, + { + y: []float64{1, 2}, + c: []bool{true, true}, + n: int(7), + wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 0.5, 1}, + wantFPR: []float64{0, 0, 0, 0, 0, 0, 1}, + }, + { + y: []float64{1}, + c: []bool{true}, + wantTPR: []float64{0, 1}, + wantFPR: []float64{0, 1}, + }, + { + y: []float64{1}, + c: []bool{true}, + n: int(2), + wantTPR: []float64{0, 1}, + wantFPR: []float64{0, 1}, + }, + { + y: []float64{1}, + c: []bool{false}, + wantTPR: []float64{0, 1}, + wantFPR: []float64{0, 1}, + }, + { + y: []float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 10}, + c: []bool{true, false, true, true, false, false, true}, + n: int(5), + wantTPR: []float64{0, 0.75, 0.75, 0.75, 1}, + wantFPR: []float64{0, 1, 1, 1, 1}, + }, + { + y: []float64{}, + c: []bool{}, + wantTPR: nil, + wantFPR: nil, + }, + { + y: []float64{}, + c: []bool{}, + n: int(5), + wantTPR: nil, + wantFPR: nil, + }, + } + for i, test := range cases { + gotTPR, gotFPR := ROC(test.n, test.y, test.c, test.w) + if !floats.Same(gotTPR, test.wantTPR) { + t.Errorf("%d: unexpected TPR got:%v want:%v", i, gotTPR, test.wantTPR) + } + if !floats.Same(gotFPR, test.wantFPR) { + t.Errorf("%d: unexpected FPR got:%v want:%v", i, gotFPR, test.wantFPR) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/samplemv/doc.go b/vendor/gonum.org/v1/gonum/stat/samplemv/doc.go new file mode 100644 index 00000000..ab4f37cc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/samplemv/doc.go @@ -0,0 +1,11 @@ +// 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 samplemv implements advanced sampling routines from explicit and implicit +// probability distributions. +// +// Each sampling routine is implemented as a stateless function with a +// complementary wrapper type. The wrapper types allow the sampling routines +// to implement interfaces. +package samplemv // import "gonum.org/v1/gonum/stat/samplemv" diff --git a/vendor/gonum.org/v1/gonum/stat/samplemv/metropolishastings.go b/vendor/gonum.org/v1/gonum/stat/samplemv/metropolishastings.go new file mode 100644 index 00000000..d4d210e8 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/samplemv/metropolishastings.go @@ -0,0 +1,221 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package samplemv + +import ( + "math" + "math/rand" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat/distmv" +) + +var _ Sampler = MetropolisHastingser{} + +// MHProposal defines a proposal distribution for Metropolis Hastings. +type MHProposal interface { + // ConditionalLogProb returns the probability of the first argument + // conditioned on being at the second argument. + // p(x|y) + // ConditionalLogProb panics if the input slices are not the same length. + ConditionalLogProb(x, y []float64) (prob float64) + + // ConditionalRand generates a new random location conditioned being at the + // location y. If the first argument is nil, a new slice is allocated and + // returned. Otherwise, the random location is stored in-place into the first + // argument, and ConditionalRand will panic if the input slice lengths differ. + ConditionalRand(x, y []float64) []float64 +} + +// MetropolisHastingser is a wrapper around the MetropolisHastings sampling type. +// +// BurnIn sets the number of samples to discard before keeping the first sample. +// A properly set BurnIn rate will decorrelate the sampling chain from the initial +// location. The proper BurnIn value will depend on the mixing time of the +// Markov chain defined by the target and proposal distributions. +// +// Rate sets the number of samples to discard in between each kept sample. A +// higher rate will better approximate independently and identically distributed +// samples, while a lower rate will keep more information (at the cost of +// higher correlation between samples). If Rate is 0 it is defaulted to 1. +// +// The initial value is NOT changed during calls to Sample. +type MetropolisHastingser struct { + Initial []float64 + Target distmv.LogProber + Proposal MHProposal + Src *rand.Rand + + BurnIn int + Rate int +} + +// Sample generates rows(batch) samples using the Metropolis Hastings sample +// generation method. The initial location is NOT updated during the call to Sample. +// +// The number of columns in batch must equal len(m.Initial), otherwise Sample +// will panic. +func (m MetropolisHastingser) Sample(batch *mat.Dense) { + burnIn := m.BurnIn + rate := m.Rate + if rate == 0 { + rate = 1 + } + r, c := batch.Dims() + if len(m.Initial) != c { + panic("metropolishastings: length mismatch") + } + + // Use the optimal size for the temporary memory to allow the fewest calls + // to MetropolisHastings. The case where tmp shadows samples must be + // aligned with the logic after burn-in so that tmp does not shadow samples + // during the rate portion. + tmp := batch + if rate > r { + tmp = mat.NewDense(rate, c, nil) + } + rTmp, _ := tmp.Dims() + + // Perform burn-in. + remaining := burnIn + initial := make([]float64, c) + copy(initial, m.Initial) + for remaining != 0 { + newSamp := min(rTmp, remaining) + MetropolisHastings(tmp.Slice(0, newSamp, 0, c).(*mat.Dense), initial, m.Target, m.Proposal, m.Src) + copy(initial, tmp.RawRowView(newSamp-1)) + remaining -= newSamp + } + + if rate == 1 { + MetropolisHastings(batch, initial, m.Target, m.Proposal, m.Src) + return + } + + if rTmp <= r { + tmp = mat.NewDense(rate, c, nil) + } + + // Take a single sample from the chain. + MetropolisHastings(batch.Slice(0, 1, 0, c).(*mat.Dense), initial, m.Target, m.Proposal, m.Src) + + copy(initial, batch.RawRowView(0)) + // For all of the other samples, first generate Rate samples and then actually + // accept the last one. + for i := 1; i < r; i++ { + MetropolisHastings(tmp, initial, m.Target, m.Proposal, m.Src) + v := tmp.RawRowView(rate - 1) + batch.SetRow(i, v) + copy(initial, v) + } +} + +// MetropolisHastings generates rows(batch) samples using the Metropolis Hastings +// algorithm (http://en.wikipedia.org/wiki/Metropolis%E2%80%93Hastings_algorithm), +// with the given target and proposal distributions, starting at the initial location +// and storing the results in-place into samples. If src != nil, it will be used to generate random +// numbers, otherwise rand.Float64 will be used. +// +// Metropolis-Hastings is a Markov-chain Monte Carlo algorithm that generates +// samples according to the distribution specified by target by using the Markov +// chain implicitly defined by the proposal distribution. At each +// iteration, a proposal point is generated randomly from the current location. +// This proposal point is accepted with probability +// p = min(1, (target(new) * proposal(current|new)) / (target(current) * proposal(new|current))) +// If the new location is accepted, it is stored into batch and becomes the +// new current location. If it is rejected, the current location remains and +// is stored into samples. Thus, a location is stored into batch at every iteration. +// +// The samples in Metropolis Hastings are correlated with one another through the +// Markov chain. As a result, the initial value can have a significant influence +// on the early samples, and so, typically, the first samples generated by the chain +// are ignored. This is known as "burn-in", and can be accomplished with slicing. +// The best choice for burn-in length will depend on the sampling and target +// distributions. +// +// Many choose to have a sampling "rate" where a number of samples +// are ignored in between each kept sample. This helps decorrelate +// the samples from one another, but also reduces the number of available samples. +// A sampling rate can be implemented with successive calls to MetropolisHastings. +func MetropolisHastings(batch *mat.Dense, initial []float64, target distmv.LogProber, proposal MHProposal, src *rand.Rand) { + f64 := rand.Float64 + if src != nil { + f64 = src.Float64 + } + if len(initial) == 0 { + panic("metropolishastings: zero length initial") + } + r, _ := batch.Dims() + current := make([]float64, len(initial)) + copy(current, initial) + proposed := make([]float64, len(initial)) + currentLogProb := target.LogProb(initial) + for i := 0; i < r; i++ { + proposal.ConditionalRand(proposed, current) + proposedLogProb := target.LogProb(proposed) + probTo := proposal.ConditionalLogProb(proposed, current) + probBack := proposal.ConditionalLogProb(current, proposed) + + accept := math.Exp(proposedLogProb + probBack - probTo - currentLogProb) + if accept > f64() { + copy(current, proposed) + currentLogProb = proposedLogProb + } + batch.SetRow(i, current) + } +} + +// ProposalNormal is a sampling distribution for Metropolis-Hastings. It has a +// fixed covariance matrix and changes the mean based on the current sampling +// location. +type ProposalNormal struct { + normal *distmv.Normal +} + +// NewProposalNormal constructs a new ProposalNormal for use as a proposal +// distribution for Metropolis-Hastings. ProposalNormal is a multivariate normal +// distribution (implemented by distmv.Normal) where the covariance matrix is fixed +// and the mean of the distribution changes. +// +// NewProposalNormal returns {nil, false} if the covariance matrix is not positive-definite. +func NewProposalNormal(sigma *mat.SymDense, src *rand.Rand) (*ProposalNormal, bool) { + mu := make([]float64, sigma.Symmetric()) + normal, ok := distmv.NewNormal(mu, sigma, src) + if !ok { + return nil, false + } + p := &ProposalNormal{ + normal: normal, + } + return p, true +} + +// ConditionalLogProb returns the probability of the first argument conditioned on +// being at the second argument. +// p(x|y) +// ConditionalLogProb panics if the input slices are not the same length or +// are not equal to the dimension of the covariance matrix. +func (p *ProposalNormal) ConditionalLogProb(x, y []float64) (prob float64) { + // Either SetMean or LogProb will panic if the slice lengths are innaccurate. + p.normal.SetMean(y) + return p.normal.LogProb(x) +} + +// ConditionalRand generates a new random location conditioned being at the +// location y. If the first argument is nil, a new slice is allocated and +// returned. Otherwise, the random location is stored in-place into the first +// argument, and ConditionalRand will panic if the input slice lengths differ or +// if they are not equal to the dimension of the covariance matrix. +func (p *ProposalNormal) ConditionalRand(x, y []float64) []float64 { + if x == nil { + x = make([]float64, p.normal.Dim()) + } + if len(x) != len(y) { + panic(badLengthMismatch) + } + p.normal.SetMean(y) + p.normal.Rand(x) + return x +} diff --git a/vendor/gonum.org/v1/gonum/stat/samplemv/sample_test.go b/vendor/gonum.org/v1/gonum/stat/samplemv/sample_test.go new file mode 100644 index 00000000..9a3764de --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/samplemv/sample_test.go @@ -0,0 +1,280 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +package samplemv + +import ( + "fmt" + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" + "gonum.org/v1/gonum/stat/distmv" +) + +type lhDist interface { + Quantile(x, p []float64) []float64 + CDF(p, x []float64) []float64 + Dim() int +} + +func TestLatinHypercube(t *testing.T) { + for _, nSamples := range []int{1, 2, 5, 10, 20} { + for _, dist := range []lhDist{ + distmv.NewUniform([]distmv.Bound{{0, 3}}, nil), + distmv.NewUniform([]distmv.Bound{{0, 3}, {-1, 5}, {-4, -1}}, nil), + } { + dim := dist.Dim() + batch := mat.NewDense(nSamples, dim, nil) + LatinHypercube(batch, dist, nil) + // Latin hypercube should have one entry per hyperrow. + present := make([][]bool, nSamples) + for i := range present { + present[i] = make([]bool, dim) + } + cdf := make([]float64, dim) + for i := 0; i < nSamples; i++ { + dist.CDF(cdf, batch.RawRowView(i)) + for j := 0; j < dim; j++ { + p := cdf[j] + quadrant := int(math.Floor(p * float64(nSamples))) + present[quadrant][j] = true + } + } + allPresent := true + for i := 0; i < nSamples; i++ { + for j := 0; j < dim; j++ { + if !present[i][j] { + allPresent = false + } + } + } + if !allPresent { + t.Errorf("All quadrants not present") + } + } + } +} + +func TestImportance(t *testing.T) { + // Test by finding the expected value of a multi-variate normal. + dim := 3 + target, ok := randomNormal(dim) + if !ok { + t.Fatal("bad test, sigma not pos def") + } + + muImp := make([]float64, dim) + sigmaImp := mat.NewSymDense(dim, nil) + for i := 0; i < dim; i++ { + sigmaImp.SetSym(i, i, 3) + } + proposal, ok := distmv.NewNormal(muImp, sigmaImp, nil) + if !ok { + t.Fatal("bad test, sigma not pos def") + } + + nSamples := 100000 + batch := mat.NewDense(nSamples, dim, nil) + weights := make([]float64, nSamples) + Importance(batch, weights, target, proposal) + + compareNormal(t, target, batch, weights, 5e-2, 5e-2) +} + +func TestRejection(t *testing.T) { + // Test by finding the expected value of a uniform. + dim := 3 + bounds := make([]distmv.Bound, dim) + for i := 0; i < dim; i++ { + min := rand.NormFloat64() + max := rand.NormFloat64() + if min > max { + min, max = max, min + } + bounds[i].Min = min + bounds[i].Max = max + } + target := distmv.NewUniform(bounds, nil) + mu := target.Mean(nil) + + muImp := make([]float64, dim) + sigmaImp := mat.NewSymDense(dim, nil) + for i := 0; i < dim; i++ { + sigmaImp.SetSym(i, i, 6) + } + proposal, ok := distmv.NewNormal(muImp, sigmaImp, nil) + if !ok { + t.Fatal("bad test, sigma not pos def") + } + + nSamples := 1000 + batch := mat.NewDense(nSamples, dim, nil) + weights := make([]float64, nSamples) + _, ok = Rejection(batch, target, proposal, 1000, nil) + if !ok { + t.Error("Bad test, nan samples") + } + + for i := 0; i < dim; i++ { + col := mat.Col(nil, i, batch) + ev := stat.Mean(col, weights) + if math.Abs(ev-mu[i]) > 1e-2 { + t.Errorf("Mean mismatch: Want %v, got %v", mu[i], ev) + } + } +} + +func TestMetropolisHastings(t *testing.T) { + // Test by finding the expected value of a normal distribution. + dim := 3 + target, ok := randomNormal(dim) + if !ok { + t.Fatal("bad test, sigma not pos def") + } + + sigmaImp := mat.NewSymDense(dim, nil) + for i := 0; i < dim; i++ { + sigmaImp.SetSym(i, i, 0.25) + } + proposal, ok := NewProposalNormal(sigmaImp, nil) + if !ok { + t.Fatal("bad test, sigma not pos def") + } + + nSamples := 100000 + burnin := 5000 + batch := mat.NewDense(nSamples, dim, nil) + initial := make([]float64, dim) + MetropolisHastings(batch, initial, target, proposal, nil) + batch = batch.Slice(burnin, nSamples, 0, dim).(*mat.Dense) + + compareNormal(t, target, batch, nil, 5e-1, 5e-1) +} + +// randomNormal constructs a random Normal distribution. +func randomNormal(dim int) (*distmv.Normal, bool) { + data := make([]float64, dim*dim) + for i := range data { + data[i] = rand.Float64() + } + a := mat.NewDense(dim, dim, data) + var sigma mat.SymDense + sigma.SymOuterK(1, a) + mu := make([]float64, dim) + for i := range mu { + mu[i] = rand.NormFloat64() + } + return distmv.NewNormal(mu, &sigma, nil) +} + +func compareNormal(t *testing.T, want *distmv.Normal, batch *mat.Dense, weights []float64, meanTol, covTol float64) { + dim := want.Dim() + mu := want.Mean(nil) + sigma := want.CovarianceMatrix(nil) + n, _ := batch.Dims() + if weights == nil { + weights = make([]float64, n) + for i := range weights { + weights[i] = 1 + } + } + for i := 0; i < dim; i++ { + col := mat.Col(nil, i, batch) + ev := stat.Mean(col, weights) + if math.Abs(ev-mu[i]) > meanTol { + t.Errorf("Mean mismatch: Want %v, got %v", mu[i], ev) + } + } + + cov := stat.CovarianceMatrix(nil, batch, weights) + if !mat.EqualApprox(cov, sigma, covTol) { + t.Errorf("Covariance matrix mismatch") + } +} + +func TestMetropolisHastingser(t *testing.T) { + for seed, test := range []struct { + dim, burnin, rate, samples int + }{ + {3, 10, 1, 1}, + {3, 10, 2, 1}, + {3, 10, 1, 2}, + {3, 10, 3, 2}, + {3, 10, 7, 4}, + {3, 10, 7, 4}, + + {3, 11, 51, 103}, + {3, 11, 103, 51}, + {3, 51, 11, 103}, + {3, 51, 103, 11}, + {3, 103, 11, 51}, + {3, 103, 51, 11}, + } { + dim := test.dim + + initial := make([]float64, dim) + target, ok := randomNormal(dim) + if !ok { + t.Fatal("bad test, sigma not pos def") + } + + sigmaImp := mat.NewSymDense(dim, nil) + for i := 0; i < dim; i++ { + sigmaImp.SetSym(i, i, 0.25) + } + proposal, ok := NewProposalNormal(sigmaImp, nil) + if !ok { + t.Fatal("bad test, sigma not pos def") + } + + // Test the Metropolis Hastingser by generating all the samples, then generating + // the same samples with a burnin and rate. + rand.Seed(int64(seed)) + mh := MetropolisHastingser{ + Initial: initial, + Target: target, + Proposal: proposal, + Src: nil, + BurnIn: 0, + Rate: 0, + } + samples := test.samples + burnin := test.burnin + rate := test.rate + fullBatch := mat.NewDense(1+burnin+rate*(samples-1), dim, nil) + mh.Sample(fullBatch) + mh = MetropolisHastingser{ + Initial: initial, + Target: target, + Proposal: proposal, + Src: nil, + BurnIn: burnin, + Rate: rate, + } + rand.Seed(int64(seed)) + batch := mat.NewDense(samples, dim, nil) + mh.Sample(batch) + + same := true + count := burnin + for i := 0; i < samples; i++ { + if !floats.Equal(batch.RawRowView(i), fullBatch.RawRowView(count)) { + fmt.Println("sample ", i, "is different") + same = false + break + } + count += rate + } + + if !same { + fmt.Printf("%v\n", mat.Formatted(batch)) + fmt.Printf("%v\n", mat.Formatted(fullBatch)) + + t.Errorf("sampling mismatch: dim = %v, burnin = %v, rate = %v, samples = %v", dim, burnin, rate, samples) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/samplemv/samplemv.go b/vendor/gonum.org/v1/gonum/stat/samplemv/samplemv.go new file mode 100644 index 00000000..5b72ca3c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/samplemv/samplemv.go @@ -0,0 +1,274 @@ +// Copyright ©2016 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package samplemv + +import ( + "errors" + "math" + "math/rand" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat/distmv" +) + +var ( + badLengthMismatch = "samplemv: slice length mismatch" +) + +var ( + _ Sampler = LatinHypercuber{} + _ Sampler = (*Rejectioner)(nil) + _ Sampler = IIDer{} + + _ WeightedSampler = SampleUniformWeighted{} + _ WeightedSampler = Importancer{} +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +// Sampler generates a batch of samples according to the rule specified by the +// implementing type. The number of samples generated is equal to rows(batch), +// and the samples are stored in-place into the input. +type Sampler interface { + Sample(batch *mat.Dense) +} + +// WeightedSampler generates a batch of samples and their relative weights +// according to the rule specified by the implementing type. The number of samples +// generated is equal to rows(batch), and the samples and weights +// are stored in-place into the inputs. The length of weights must equal +// rows(batch), otherwise SampleWeighted will panic. +type WeightedSampler interface { + SampleWeighted(batch *mat.Dense, weights []float64) +} + +// SampleUniformWeighted wraps a Sampler type to create a WeightedSampler where all +// weights are equal. +type SampleUniformWeighted struct { + Sampler +} + +// SampleWeighted generates rows(batch) samples from the embedded Sampler type +// and sets all of the weights equal to 1. If rows(batch) and len(weights) +// of weights are not equal, SampleWeighted will panic. +func (w SampleUniformWeighted) SampleWeighted(batch *mat.Dense, weights []float64) { + r, _ := batch.Dims() + if r != len(weights) { + panic(badLengthMismatch) + } + w.Sample(batch) + for i := range weights { + weights[i] = 1 + } +} + +// LatinHypercuber is a wrapper around the LatinHypercube sampling generation +// method. +type LatinHypercuber struct { + Q distmv.Quantiler + Src *rand.Rand +} + +// Sample generates rows(batch) samples using the LatinHypercube generation +// procedure. +func (l LatinHypercuber) Sample(batch *mat.Dense) { + LatinHypercube(batch, l.Q, l.Src) +} + +// LatinHypercube generates rows(batch) samples using Latin hypercube sampling +// from the given distribution. If src is not nil, it will be used to generate +// random numbers, otherwise rand.Float64 will be used. +// +// Latin hypercube sampling divides the cumulative distribution function into equally +// spaced bins and guarantees that one sample is generated per bin. Within each bin, +// the location is randomly sampled. The distmv.NewUnitUniform function can be used +// for easy sampling from the unit hypercube. +func LatinHypercube(batch *mat.Dense, q distmv.Quantiler, src *rand.Rand) { + r, c := batch.Dims() + var f64 func() float64 + var perm func(int) []int + if src != nil { + f64 = src.Float64 + perm = src.Perm + } else { + f64 = rand.Float64 + perm = rand.Perm + } + r64 := float64(r) + for i := 0; i < c; i++ { + p := perm(r) + for j := 0; j < r; j++ { + v := f64()/r64 + float64(j)/r64 + batch.Set(p[j], i, v) + } + } + p := make([]float64, c) + for i := 0; i < r; i++ { + copy(p, batch.RawRowView(i)) + q.Quantile(batch.RawRowView(i), p) + } +} + +// Importancer is a wrapper around the Importance sampling generation method. +type Importancer struct { + Target distmv.LogProber + Proposal distmv.RandLogProber +} + +// SampleWeighted generates rows(batch) samples using the Importance sampling +// generation procedure. +func (l Importancer) SampleWeighted(batch *mat.Dense, weights []float64) { + Importance(batch, weights, l.Target, l.Proposal) +} + +// Importance sampling generates rows(batch) samples from the proposal distribution, +// and stores the locations and importance sampling weights in place. +// +// Importance sampling is a variance reduction technique where samples are +// generated from a proposal distribution, q(x), instead of the target distribution +// p(x). This allows relatively unlikely samples in p(x) to be generated more frequently. +// +// The importance sampling weight at x is given by p(x)/q(x). To reduce variance, +// a good proposal distribution will bound this sampling weight. This implies the +// support of q(x) should be at least as broad as p(x), and q(x) should be "fatter tailed" +// than p(x). +// +// If weights is nil, the weights are not stored. The length of weights must equal +// the length of batch, otherwise Importance will panic. +func Importance(batch *mat.Dense, weights []float64, target distmv.LogProber, proposal distmv.RandLogProber) { + r, _ := batch.Dims() + if r != len(weights) { + panic(badLengthMismatch) + } + for i := 0; i < r; i++ { + v := batch.RawRowView(i) + proposal.Rand(v) + weights[i] = math.Exp(target.LogProb(v) - proposal.LogProb(v)) + } +} + +// ErrRejection is returned when the constant in Rejection is not sufficiently high. +var ErrRejection = errors.New("rejection: acceptance ratio above 1") + +// Rejectioner is a wrapper around the Rejection sampling generation procedure. +// If the rejection sampling fails during the call to Sample, all samples will +// be set to math.NaN() and a call to Err will return a non-nil value. +type Rejectioner struct { + C float64 + Target distmv.LogProber + Proposal distmv.RandLogProber + Src *rand.Rand + + err error + proposed int +} + +// Err returns nil if the most recent call to sample was successful, and returns +// ErrRejection if it was not. +func (r *Rejectioner) Err() error { + return r.err +} + +// Proposed returns the number of samples proposed during the most recent call to +// Sample. +func (r *Rejectioner) Proposed() int { + return r.proposed +} + +// Sample generates rows(batch) using the Rejection sampling generation procedure. +// Rejection sampling may fail if the constant is insufficiently high, as described +// in the function comment for Rejection. If the generation fails, the samples +// are set to math.NaN(), and a call to Err will return a non-nil value. +func (r *Rejectioner) Sample(batch *mat.Dense) { + r.err = nil + r.proposed = 0 + proposed, ok := Rejection(batch, r.Target, r.Proposal, r.C, r.Src) + if !ok { + r.err = ErrRejection + } + r.proposed = proposed +} + +// Rejection generates rows(batch) samples using the rejection sampling algorithm and +// stores them in place into samples. +// Sampling continues until batch is filled. Rejection returns the total number of proposed +// locations and a boolean indicating if the rejection sampling assumption is +// violated (see details below). If the returned boolean is false, all elements +// of samples are set to NaN. If src != nil, it will be used to generate random +// numbers, otherwise rand.Float64 will be used. +// +// Rejection sampling generates points from the target distribution by using +// the proposal distribution. At each step of the algorithm, the proposaed point +// is accepted with probability +// p = target(x) / (proposal(x) * c) +// where target(x) is the probability of the point according to the target distribution +// and proposal(x) is the probability according to the proposal distribution. +// The constant c must be chosen such that target(x) < proposal(x) * c for all x. +// The expected number of proposed samples is len(samples) * c. +// +// Target may return the true (log of) the probablity of the location, or it may return +// a value that is proportional to the probability (logprob + constant). This is +// useful for cases where the probability distribution is only known up to a normalization +// constant. +func Rejection(batch *mat.Dense, target distmv.LogProber, proposal distmv.RandLogProber, c float64, src *rand.Rand) (nProposed int, ok bool) { + if c < 1 { + panic("rejection: acceptance constant must be greater than 1") + } + f64 := rand.Float64 + if src != nil { + f64 = src.Float64 + } + r, dim := batch.Dims() + v := make([]float64, dim) + var idx int + for { + nProposed++ + proposal.Rand(v) + qx := proposal.LogProb(v) + px := target.LogProb(v) + accept := math.Exp(px-qx) / c + if accept > 1 { + // Invalidate the whole result and return a failure. + for i := 0; i < r; i++ { + for j := 0; j < dim; j++ { + batch.Set(i, j, math.NaN()) + } + } + return nProposed, false + } + if accept > f64() { + batch.SetRow(idx, v) + idx++ + if idx == r { + break + } + } + } + return nProposed, true +} + +// IIDer is a wrapper around the IID sample generation method. +type IIDer struct { + Dist distmv.Rander +} + +// Sample generates a set of identically and independently distributed samples. +func (iid IIDer) Sample(batch *mat.Dense) { + IID(batch, iid.Dist) +} + +// IID generates a set of independently and identically distributed samples from +// the input distribution. +func IID(batch *mat.Dense, d distmv.Rander) { + r, _ := batch.Dims() + for i := 0; i < r; i++ { + d.Rand(batch.RawRowView(i)) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/doc.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/doc.go new file mode 100644 index 00000000..9beb4ddc --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/doc.go @@ -0,0 +1,11 @@ +// 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 sampleuv implements advanced sampling routines from explicit and implicit +// probability distributions. +// +// Each sampling routine is implemented as a stateless function with a +// complementary wrapper type. The wrapper types allow the sampling routines +// to implement interfaces. +package sampleuv // import "gonum.org/v1/gonum/stat/sampleuv" diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/example_burnin_test.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/example_burnin_test.go new file mode 100644 index 00000000..db1d1c31 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/example_burnin_test.go @@ -0,0 +1,39 @@ +// 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 sampleuv + +import "gonum.org/v1/gonum/stat/distuv" + +type ProposalDist struct { + Sigma float64 +} + +func (p ProposalDist) ConditionalRand(y float64) float64 { + return distuv.Normal{Mu: y, Sigma: p.Sigma}.Rand() +} + +func (p ProposalDist) ConditionalLogProb(x, y float64) float64 { + return distuv.Normal{Mu: y, Sigma: p.Sigma}.LogProb(x) +} + +func ExampleMetropolisHastings_burnin() { + n := 1000 // The number of samples to generate. + burnin := 50 // Number of samples to ignore at the start. + var initial float64 + // target is the distribution from which we would like to sample. + target := distuv.Weibull{K: 5, Lambda: 0.5} + // proposal is the proposal distribution. Here, we are choosing + // a tight Gaussian distribution around the current location. In + // typical problems, if Sigma is too small, it takes a lot of samples + // to move around the distribution. If Sigma is too large, it can be hard + // to find acceptable samples. + proposal := ProposalDist{Sigma: 0.2} + + samples := make([]float64, n+burnin) + MetropolisHastings(samples, initial, target, proposal, nil) + + // Remove the initial samples through slicing. + samples = samples[burnin:] +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/example_rate_test.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/example_rate_test.go new file mode 100644 index 00000000..86917998 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/example_rate_test.go @@ -0,0 +1,49 @@ +// 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 sampleuv + +import "gonum.org/v1/gonum/stat/distuv" + +func max(a, b int) int { + if a < b { + return b + } + return a +} + +func ExampleMetropolisHastings_samplingRate() { + // See Burnin example for a description of these quantities. + n := 1000 + burnin := 300 + var initial float64 + target := distuv.Weibull{K: 5, Lambda: 0.5} + proposal := ProposalDist{Sigma: 0.2} + + // Successive samples are correlated with one another through the + // Markov Chain defined by the proposal distribution. To get less + // correlated samples, one may use a sampling rate, in which only + // one sample from every few is accepted from the chain. This can + // be accomplished through a for loop. + rate := 50 + + tmp := make([]float64, max(rate, burnin)) + + // First deal with burnin. + tmp = tmp[:burnin] + MetropolisHastings(tmp, initial, target, proposal, nil) + // The final sample in tmp in the final point in the chain. + // Use it as the new initial location. + initial = tmp[len(tmp)-1] + + // Now, generate samples by using one every rate samples. + tmp = tmp[:rate] + samples := make([]float64, n) + samples[0] = initial + for i := 1; i < len(samples); i++ { + MetropolisHastings(tmp, initial, target, proposal, nil) + initial = tmp[len(tmp)-1] + samples[i] = initial + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/sample.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/sample.go new file mode 100644 index 00000000..1d836390 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/sample.go @@ -0,0 +1,393 @@ +// 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 sampleuv + +import ( + "errors" + "math" + "math/rand" + + "gonum.org/v1/gonum/stat/distuv" +) + +var ( + badLengthMismatch = "sample: slice length mismatch" +) + +var ( + _ Sampler = LatinHypercuber{} + _ Sampler = MetropolisHastingser{} + _ Sampler = (*Rejectioner)(nil) + _ Sampler = IIDer{} + + _ WeightedSampler = SampleUniformWeighted{} + _ WeightedSampler = Importancer{} +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +// Sampler generates a batch of samples according to the rule specified by the +// implementing type. The number of samples generated is equal to len(batch), +// and the samples are stored in-place into the input. +type Sampler interface { + Sample(batch []float64) +} + +// WeightedSampler generates a batch of samples and their relative weights +// according to the rule specified by the implementing type. The number of samples +// generated is equal to len(batch), and the samples and weights +// are stored in-place into the inputs. The length of weights must equal +// len(batch), otherwise SampleWeighted will panic. +type WeightedSampler interface { + SampleWeighted(batch, weights []float64) +} + +// SampleUniformWeighted wraps a Sampler type to create a WeightedSampler where all +// weights are equal. +type SampleUniformWeighted struct { + Sampler +} + +// SampleWeighted generates len(batch) samples from the embedded Sampler type +// and sets all of the weights equal to 1. If len(batch) and len(weights) +// are not equal, SampleWeighted will panic. +func (w SampleUniformWeighted) SampleWeighted(batch, weights []float64) { + if len(batch) != len(weights) { + panic(badLengthMismatch) + } + w.Sample(batch) + for i := range weights { + weights[i] = 1 + } +} + +// LatinHypercuber is a wrapper around the LatinHypercube sampling generation +// method. +type LatinHypercuber struct { + Q distuv.Quantiler + Src *rand.Rand +} + +// Sample generates len(batch) samples using the LatinHypercube generation +// procedure. +func (l LatinHypercuber) Sample(batch []float64) { + LatinHypercube(batch, l.Q, l.Src) +} + +// LatinHypercube generates len(batch) samples using Latin hypercube sampling +// from the given distribution. If src != nil, it will be used to generate +// random numbers, otherwise rand.Float64 will be used. +// +// Latin hypercube sampling divides the cumulative distribution function into equally +// spaced bins and guarantees that one sample is generated per bin. Within each bin, +// the location is randomly sampled. The distuv.UnitUniform variable can be used +// for easy generation from the unit interval. +func LatinHypercube(batch []float64, q distuv.Quantiler, src *rand.Rand) { + n := len(batch) + var perm []int + var f64 func() float64 + if src != nil { + f64 = src.Float64 + perm = src.Perm(n) + } else { + f64 = rand.Float64 + perm = rand.Perm(n) + } + for i := range batch { + v := f64()/float64(n) + float64(i)/float64(n) + batch[perm[i]] = q.Quantile(v) + } +} + +// Importancer is a wrapper around the Importance sampling generation method. +type Importancer struct { + Target distuv.LogProber + Proposal distuv.RandLogProber +} + +// Sample generates len(batch) samples using the Importance sampling generation +// procedure. +func (l Importancer) SampleWeighted(batch, weights []float64) { + Importance(batch, weights, l.Target, l.Proposal) +} + +// Importance sampling generates len(batch) samples from the proposal distribution, +// and stores the locations and importance sampling weights in place. +// +// Importance sampling is a variance reduction technique where samples are +// generated from a proposal distribution, q(x), instead of the target distribution +// p(x). This allows relatively unlikely samples in p(x) to be generated more frequently. +// +// The importance sampling weight at x is given by p(x)/q(x). To reduce variance, +// a good proposal distribution will bound this sampling weight. This implies the +// support of q(x) should be at least as broad as p(x), and q(x) should be "fatter tailed" +// than p(x). +// +// If weights is nil, the weights are not stored. The length of weights must equal +// the length of batch, otherwise Importance will panic. +func Importance(batch, weights []float64, target distuv.LogProber, proposal distuv.RandLogProber) { + if len(batch) != len(weights) { + panic(badLengthMismatch) + } + for i := range batch { + v := proposal.Rand() + batch[i] = v + weights[i] = math.Exp(target.LogProb(v) - proposal.LogProb(v)) + } +} + +// ErrRejection is returned when the constant in Rejection is not sufficiently high. +var ErrRejection = errors.New("rejection: acceptance ratio above 1") + +// Rejectioner is a wrapper around the Rejection sampling generation procedure. +// If the rejection sampling fails during the call to Sample, all samples will +// be set to math.NaN() and a call to Err will return a non-nil value. +type Rejectioner struct { + C float64 + Target distuv.LogProber + Proposal distuv.RandLogProber + Src *rand.Rand + + err error + proposed int +} + +// Err returns nil if the most recent call to sample was successful, and returns +// ErrRejection if it was not. +func (r *Rejectioner) Err() error { + return r.err +} + +// Proposed returns the number of samples proposed during the most recent call to +// Sample. +func (r *Rejectioner) Proposed() int { + return r.proposed +} + +// Sample generates len(batch) using the Rejection sampling generation procedure. +// Rejection sampling may fail if the constant is insufficiently high, as described +// in the function comment for Rejection. If the generation fails, the samples +// are set to math.NaN(), and a call to Err will return a non-nil value. +func (r *Rejectioner) Sample(batch []float64) { + r.err = nil + r.proposed = 0 + proposed, ok := Rejection(batch, r.Target, r.Proposal, r.C, r.Src) + if !ok { + r.err = ErrRejection + } + r.proposed = proposed +} + +// Rejection generates len(batch) samples using the rejection sampling algorithm +// and stores them in place into samples. Sampling continues until batch is +// filled. Rejection returns the total number of proposed locations and a boolean +// indicating if the rejection sampling assumption is violated (see details +// below). If the returned boolean is false, all elements of samples are set to +// NaN. If src is not nil, it will be used to generate random numbers, otherwise +// rand.Float64 will be used. +// +// Rejection sampling generates points from the target distribution by using +// the proposal distribution. At each step of the algorithm, the proposed point +// is accepted with probability +// p = target(x) / (proposal(x) * c) +// where target(x) is the probability of the point according to the target distribution +// and proposal(x) is the probability according to the proposal distribution. +// The constant c must be chosen such that target(x) < proposal(x) * c for all x. +// The expected number of proposed samples is len(samples) * c. +// +// Target may return the true (log of) the probablity of the location, or it may return +// a value that is proportional to the probability (logprob + constant). This is +// useful for cases where the probability distribution is only known up to a normalization +// constant. +func Rejection(batch []float64, target distuv.LogProber, proposal distuv.RandLogProber, c float64, src *rand.Rand) (nProposed int, ok bool) { + if c < 1 { + panic("rejection: acceptance constant must be greater than 1") + } + f64 := rand.Float64 + if src != nil { + f64 = src.Float64 + } + var idx int + for { + nProposed++ + v := proposal.Rand() + qx := proposal.LogProb(v) + px := target.LogProb(v) + accept := math.Exp(px-qx) / c + if accept > 1 { + // Invalidate the whole result and return a failure. + for i := range batch { + batch[i] = math.NaN() + } + return nProposed, false + } + if accept > f64() { + batch[idx] = v + idx++ + if idx == len(batch) { + break + } + } + } + return nProposed, true +} + +// MHProposal defines a proposal distribution for Metropolis Hastings. +type MHProposal interface { + // ConditionalDist returns the probability of the first argument conditioned on + // being at the second argument + // p(x|y) + ConditionalLogProb(x, y float64) (prob float64) + + // ConditionalRand generates a new random location conditioned being at the + // location y. + ConditionalRand(y float64) (x float64) +} + +// MetropolisHastingser is a wrapper around the MetropolisHastings sampling type. +// +// BurnIn sets the number of samples to discard before keeping the first sample. +// A properly set BurnIn rate will decorrelate the sampling chain from the initial +// location. The proper BurnIn value will depend on the mixing time of the +// Markov chain defined by the target and proposal distributions. +// +// Rate sets the number of samples to discard in between each kept sample. A +// higher rate will better approximate independently and identically distributed +// samples, while a lower rate will keep more information (at the cost of +// higher correlation between samples). If Rate is 0 it is defaulted to 1. +// +// The initial value is NOT changed during calls to Sample. +type MetropolisHastingser struct { + Initial float64 + Target distuv.LogProber + Proposal MHProposal + Src *rand.Rand + + BurnIn int + Rate int +} + +// Sample generates len(batch) samples using the Metropolis Hastings sample +// generation method. The initial location is NOT updated during the call to Sample. +func (m MetropolisHastingser) Sample(batch []float64) { + burnIn := m.BurnIn + rate := m.Rate + if rate == 0 { + rate = 1 + } + + // Use the optimal size for the temporary memory to allow the fewest calls + // to MetropolisHastings. The case where tmp shadows samples must be + // aligned with the logic after burn-in so that tmp does not shadow samples + // during the rate portion. + tmp := batch + if rate > len(batch) { + tmp = make([]float64, rate) + } + + // Perform burn-in. + remaining := burnIn + initial := m.Initial + for remaining != 0 { + newSamp := min(len(tmp), remaining) + MetropolisHastings(tmp[newSamp:], initial, m.Target, m.Proposal, m.Src) + initial = tmp[newSamp-1] + remaining -= newSamp + } + + if rate == 1 { + MetropolisHastings(batch, initial, m.Target, m.Proposal, m.Src) + return + } + + if len(tmp) <= len(batch) { + tmp = make([]float64, rate) + } + + // Take a single sample from the chain + MetropolisHastings(batch[0:1], initial, m.Target, m.Proposal, m.Src) + initial = batch[0] + + // For all of the other samples, first generate Rate samples and then actually + // accept the last one. + for i := 1; i < len(batch); i++ { + MetropolisHastings(tmp, initial, m.Target, m.Proposal, m.Src) + v := tmp[rate-1] + batch[i] = v + initial = v + } +} + +// MetropolisHastings generates len(batch) samples using the Metropolis Hastings +// algorithm (http://en.wikipedia.org/wiki/Metropolis%E2%80%93Hastings_algorithm), +// with the given target and proposal distributions, starting at the initial location +// and storing the results in-place into samples. If src != nil, it will be used to generate random +// numbers, otherwise rand.Float64 will be used. +// +// Metropolis-Hastings is a Markov-chain Monte Carlo algorithm that generates +// samples according to the distribution specified by target by using the Markov +// chain implicitly defined by the proposal distribution. At each +// iteration, a proposal point is generated randomly from the current location. +// This proposal point is accepted with probability +// p = min(1, (target(new) * proposal(current|new)) / (target(current) * proposal(new|current))) +// If the new location is accepted, it is stored into batch and becomes the +// new current location. If it is rejected, the current location remains and +// is stored into samples. Thus, a location is stored into batch at every iteration. +// +// The samples in Metropolis Hastings are correlated with one another through the +// Markov chain. As a result, the initial value can have a significant influence +// on the early samples, and so, typically, the first samples generated by the chain +// are ignored. This is known as "burn-in", and can be accomplished with slicing. +// The best choice for burn-in length will depend on the sampling and target +// distributions. +// +// Many choose to have a sampling "rate" where a number of samples +// are ignored in between each kept sample. This helps decorrelate +// the samples from one another, but also reduces the number of available samples. +// A sampling rate can be implemented with successive calls to MetropolisHastings. +func MetropolisHastings(batch []float64, initial float64, target distuv.LogProber, proposal MHProposal, src *rand.Rand) { + f64 := rand.Float64 + if src != nil { + f64 = src.Float64 + } + current := initial + currentLogProb := target.LogProb(initial) + for i := range batch { + proposed := proposal.ConditionalRand(current) + proposedLogProb := target.LogProb(proposed) + probTo := proposal.ConditionalLogProb(proposed, current) + probBack := proposal.ConditionalLogProb(current, proposed) + + accept := math.Exp(proposedLogProb + probBack - probTo - currentLogProb) + if accept > f64() { + current = proposed + currentLogProb = proposedLogProb + } + batch[i] = current + } +} + +// IIDer is a wrapper around the IID sample generation method. +type IIDer struct { + Dist distuv.Rander +} + +// Sample generates a set of identically and independently distributed samples. +func (iid IIDer) Sample(batch []float64) { + IID(batch, iid.Dist) +} + +// IID generates a set of independently and identically distributed samples from +// the input distribution. +func IID(batch []float64, d distuv.Rander) { + for i := range batch { + batch[i] = d.Rand() + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/sample_test.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/sample_test.go new file mode 100644 index 00000000..49965ec0 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/sample_test.go @@ -0,0 +1,99 @@ +// 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 sampleuv + +import ( + "math" + "sort" + "testing" + + "gonum.org/v1/gonum/stat" + "gonum.org/v1/gonum/stat/distuv" +) + +type lhDist interface { + Quantile(float64) float64 + CDF(float64) float64 +} + +func TestLatinHypercube(t *testing.T) { + for _, nSamples := range []int{1, 2, 5, 10, 20} { + samples := make([]float64, nSamples) + for _, dist := range []lhDist{ + distuv.Uniform{Min: 0, Max: 1}, + distuv.Uniform{Min: 0, Max: 10}, + distuv.Normal{Mu: 5, Sigma: 3}, + } { + LatinHypercube(samples, dist, nil) + sort.Float64s(samples) + for i, v := range samples { + p := dist.CDF(v) + if p < float64(i)/float64(nSamples) || p > float64(i+1)/float64(nSamples) { + t.Errorf("probability out of bounds") + } + } + } + } +} + +func TestImportance(t *testing.T) { + // Test by finding the expected value of a Normal. + trueMean := 3.0 + target := distuv.Normal{Mu: trueMean, Sigma: 2} + proposal := distuv.Normal{Mu: 0, Sigma: 5} + nSamples := 100000 + x := make([]float64, nSamples) + weights := make([]float64, nSamples) + Importance(x, weights, target, proposal) + ev := stat.Mean(x, weights) + if math.Abs(ev-trueMean) > 1e-2 { + t.Errorf("Mean mismatch: Want %v, got %v", trueMean, ev) + } +} + +func TestRejection(t *testing.T) { + // Test by finding the expected value of a Normal. + trueMean := 3.0 + target := distuv.Normal{Mu: trueMean, Sigma: 2} + proposal := distuv.Normal{Mu: 0, Sigma: 5} + + nSamples := 20000 + x := make([]float64, nSamples) + Rejection(x, target, proposal, 100, nil) + ev := stat.Mean(x, nil) + if math.Abs(ev-trueMean) > 2e-2 { + t.Errorf("Mean mismatch: Want %v, got %v", trueMean, ev) + } +} + +type condNorm struct { + Sigma float64 +} + +func (c condNorm) ConditionalRand(y float64) float64 { + return distuv.Normal{Mu: y, Sigma: c.Sigma}.Rand() +} + +func (c condNorm) ConditionalLogProb(x, y float64) float64 { + return distuv.Normal{Mu: y, Sigma: c.Sigma}.LogProb(x) +} + +func TestMetropolisHastings(t *testing.T) { + // Test by finding the expected value of a Normal. + trueMean := 3.0 + target := distuv.Normal{Mu: trueMean, Sigma: 2} + proposal := condNorm{Sigma: 5} + + burnin := 500 + nSamples := 100000 + burnin + x := make([]float64, nSamples) + MetropolisHastings(x, 100, target, proposal, nil) + // Remove burnin + x = x[burnin:] + ev := stat.Mean(x, nil) + if math.Abs(ev-trueMean) > 1e-2 { + t.Errorf("Mean mismatch: Want %v, got %v", trueMean, ev) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/weighted.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/weighted.go new file mode 100644 index 00000000..006cafdd --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/weighted.go @@ -0,0 +1,138 @@ +// Copyright ©2015 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 sampleuv + +import ( + "math/rand" + + "gonum.org/v1/gonum/floats" +) + +// Weighted provides sampling without replacement from a collection of items with +// non-uniform probability. +type Weighted struct { + weights []float64 + // heap is a weight heap. + // + // It keeps a heap-organised sum of remaining + // index weights that are available to be taken + // from. + // + // Each element holds the sum of weights for + // the corresponding index, plus the sum of + // of its children's weights; the children + // of an element i can be found at positions + // 2*(i+1)-1 and 2*(i+1). The root of the + // weight heap is at element 0. + // + // See comments in container/heap for an + // explanation of the layout of a heap. + heap []float64 + src *rand.Rand +} + +// NewWeighted returns a Weighted for the weights w. If src is nil, rand.Rand is +// used as the random source. +// +// Note that sampling from weights with a high variance or overall low absolute +// value sum may result in problems with numerical stability. +func NewWeighted(w []float64, src *rand.Rand) Weighted { + s := Weighted{ + weights: make([]float64, len(w)), + heap: make([]float64, len(w)), + src: src, + } + s.ReweightAll(w) + return s +} + +// Len returns the number of items held by the Weighted, including items +// already taken. +func (s Weighted) Len() int { return len(s.weights) } + +// Take returns an index from the Weighted with probability proportional +// to the weight of the item. The weight of the item is then set to zero. +// Take returns false if there are no items remaining. +func (s Weighted) Take() (idx int, ok bool) { + const small = 1e-12 + if floats.EqualWithinAbsOrRel(s.heap[0], 0, small, small) { + return -1, false + } + + var r float64 + if s.src == nil { + r = s.heap[0] * rand.Float64() + } else { + r = s.heap[0] * s.src.Float64() + } + i := 1 + last := -1 + left := len(s.weights) + for { + if r -= s.weights[i-1]; r <= 0 { + break // Fall within item i-1. + } + i <<= 1 // Move to left child. + if d := s.heap[i-1]; r > d { + r -= d + // If enough r to pass left child + // move to right child state will + // be caught at break above. + i++ + } + if i == last || left < 0 { + // No progression. + return -1, false + } + last = i + left-- + } + + w, idx := s.weights[i-1], i-1 + + s.weights[i-1] = 0 + for i > 0 { + s.heap[i-1] -= w + // The following condition is necessary to + // handle floating point error. If we see + // a heap value below zero, we know we need + // to rebuild it. + if s.heap[i-1] < 0 { + s.reset() + return idx, true + } + i >>= 1 + } + + return idx, true +} + +// Reweight sets the weight of item idx to w. +func (s Weighted) Reweight(idx int, w float64) { + w, s.weights[idx] = s.weights[idx]-w, w + idx++ + for idx > 0 { + s.heap[idx-1] -= w + idx >>= 1 + } +} + +// ReweightAll sets the weight of all items in the Weighted. ReweightAll +// panics if len(w) != s.Len. +func (s Weighted) ReweightAll(w []float64) { + if len(w) != s.Len() { + panic("floats: length of the slices do not match") + } + copy(s.weights, w) + s.reset() +} + +func (s Weighted) reset() { + copy(s.heap, s.weights) + for i := len(s.heap) - 1; i > 0; i-- { + // Sometimes 1-based counting makes sense. + s.heap[((i+1)>>1)-1] += s.heap[i] + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/weighted_test.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/weighted_test.go new file mode 100644 index 00000000..ad2799f9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/weighted_test.go @@ -0,0 +1,267 @@ +// Copyright ©2015 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 sampleuv + +import ( + "flag" + "math/rand" + "reflect" + "testing" + "time" + + "gonum.org/v1/gonum/floats" +) + +var prob = flag.Bool("prob", false, "enables probabilistic testing of the random weighted sampler") + +const sigChi2 = 16.92 // p = 0.05 df = 9 + +var ( + newExp = func() []float64 { + return []float64{1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, 1 << 8, 1 << 9} + } + exp = newExp() + + obt = []float64{973, 1937, 3898, 7897, 15769, 31284, 62176, 125408, 250295, 500363} +) + +func newTestWeighted() Weighted { + weights := make([]float64, len(obt)) + for i := range weights { + weights[i] = float64(int(1) << uint(i)) + } + return NewWeighted(weights, nil) +} + +func TestWeightedUnseeded(t *testing.T) { + rand.Seed(0) + + want := Weighted{ + weights: []float64{1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, 1 << 8, 1 << 9}, + heap: []float64{ + exp[0] + exp[1] + exp[3] + exp[4] + exp[7] + exp[8] + exp[9] + exp[2] + exp[5] + exp[6], + exp[1] + exp[3] + exp[4] + exp[7] + exp[8] + exp[9], + exp[2] + exp[5] + exp[6], + exp[3] + exp[7] + exp[8], + exp[4] + exp[9], + exp[5], + exp[6], + exp[7], + exp[8], + exp[9], + }, + } + + ts := newTestWeighted() + if !reflect.DeepEqual(ts, want) { + t.Fatalf("unexpected new Weighted value:\ngot: %#v\nwant:%#v", ts, want) + } + + f := make([]float64, len(obt)) + for i := 0; i < 1e6; i++ { + item, ok := newTestWeighted().Take() + if !ok { + t.Fatal("Weighted unexpectedly empty") + } + f[item]++ + } + + exp := newExp() + fac := floats.Sum(f) / floats.Sum(exp) + for i := range f { + exp[i] *= fac + } + + if !reflect.DeepEqual(f, obt) { + t.Fatalf("unexpected selection:\ngot: %#v\nwant:%#v", f, obt) + } + + // Check that this is within statistical expectations - we know this is true for this set. + X := chi2(f, exp) + if X >= sigChi2 { + t.Errorf("H₀: d(Sample) = d(Expect), H₁: d(S) ≠ d(Expect). df = %d, p = 0.05, X² threshold = %.2f, X² = %f", len(f)-1, sigChi2, X) + } +} + +func TestWeightedTimeSeeded(t *testing.T) { + if !*prob { + t.Skip("probabilistic testing not requested") + } + t.Log("Note: This test is stochastic and is expected to fail with probability ≈ 0.05.") + + rand.Seed(time.Now().Unix()) + + f := make([]float64, len(obt)) + for i := 0; i < 1e6; i++ { + item, ok := newTestWeighted().Take() + if !ok { + t.Fatal("Weighted unexpectedly empty") + } + f[item]++ + } + + exp := newExp() + fac := floats.Sum(f) / floats.Sum(exp) + for i := range f { + exp[i] *= fac + } + + // Check that our obtained values are within statistical expectations for p = 0.05. + // This will not be true approximately 1 in 20 tests. + X := chi2(f, exp) + if X >= sigChi2 { + t.Errorf("H₀: d(Sample) = d(Expect), H₁: d(S) ≠ d(Expect). df = %d, p = 0.05, X² threshold = %.2f, X² = %f", len(f)-1, sigChi2, X) + } +} + +func TestWeightZero(t *testing.T) { + rand.Seed(0) + + want := Weighted{ + weights: []float64{1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 0, 1 << 7, 1 << 8, 1 << 9}, + heap: []float64{ + exp[0] + exp[1] + exp[3] + exp[4] + exp[7] + exp[8] + exp[9] + exp[2] + exp[5], + exp[1] + exp[3] + exp[4] + exp[7] + exp[8] + exp[9], + exp[2] + exp[5], + exp[3] + exp[7] + exp[8], + exp[4] + exp[9], + exp[5], + 0, + exp[7], + exp[8], + exp[9], + }, + } + + ts := newTestWeighted() + ts.Reweight(6, 0) + if !reflect.DeepEqual(ts, want) { + t.Fatalf("unexpected new Weighted value:\ngot: %#v\nwant:%#v", ts, want) + } + + f := make([]float64, len(obt)) + for i := 0; i < 1e6; i++ { + ts := newTestWeighted() + ts.Reweight(6, 0) + item, ok := ts.Take() + if !ok { + t.Fatal("Weighted unexpectedly empty") + } + f[item]++ + } + + exp := newExp() + fac := floats.Sum(f) / floats.Sum(exp) + for i := range f { + exp[i] *= fac + } + + if f[6] != 0 { + t.Errorf("unexpected selection rate for zero-weighted item: got: %v want:%v", f[6], 0) + } + if reflect.DeepEqual(f[:6], obt[:6]) { + t.Fatalf("unexpected selection: too few elements chosen in range:\ngot: %v\nwant:%v", + f[:6], obt[:6]) + } + if reflect.DeepEqual(f[7:], obt[7:]) { + t.Fatalf("unexpected selection: too few elements chosen in range:\ngot: %v\nwant:%v", + f[7:], obt[7:]) + } +} + +func TestWeightIncrease(t *testing.T) { + rand.Seed(0) + + want := Weighted{ + weights: []float64{1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 9 * 2, 1 << 7, 1 << 8, 1 << 9}, + heap: []float64{ + exp[0] + exp[1] + exp[3] + exp[4] + exp[7] + exp[8] + exp[9] + exp[2] + exp[5] + exp[9]*2, + exp[1] + exp[3] + exp[4] + exp[7] + exp[8] + exp[9], + exp[2] + exp[5] + exp[9]*2, + exp[3] + exp[7] + exp[8], + exp[4] + exp[9], + exp[5], + exp[9] * 2, + exp[7], + exp[8], + exp[9], + }, + } + + ts := newTestWeighted() + ts.Reweight(6, ts.weights[len(ts.weights)-1]*2) + if !reflect.DeepEqual(ts, want) { + t.Fatalf("unexpected new Weighted value:\ngot: %#v\nwant:%#v", ts, want) + } + + f := make([]float64, len(obt)) + for i := 0; i < 1e6; i++ { + ts := newTestWeighted() + ts.Reweight(6, ts.weights[len(ts.weights)-1]*2) + item, ok := ts.Take() + if !ok { + t.Fatal("Weighted unexpectedly empty") + } + f[item]++ + } + + exp := newExp() + fac := floats.Sum(f) / floats.Sum(exp) + for i := range f { + exp[i] *= fac + } + + if f[6] < f[9] { + t.Errorf("unexpected selection rate for re-weighted item: got: %v want:%v", f[6], f[9]) + } + if reflect.DeepEqual(f[:6], obt[:6]) { + t.Fatalf("unexpected selection: too many elements chosen in range:\ngot: %v\nwant:%v", + f[:6], obt[:6]) + } + if reflect.DeepEqual(f[7:], obt[7:]) { + t.Fatalf("unexpected selection: too many elements chosen in range:\ngot: %v\nwant:%v", + f[7:], obt[7:]) + } +} + +func chi2(ob, ex []float64) (sum float64) { + for i := range ob { + x := ob[i] - ex[i] + sum += (x * x) / ex[i] + } + + return sum +} + +func TestWeightedNoResample(t *testing.T) { + const ( + tries = 10 + n = 10e4 + ) + ts := NewWeighted(make([]float64, n), nil) + w := make([]float64, n) + for i := 0; i < tries; i++ { + for j := range w { + w[j] = rand.Float64() * n + } + ts.ReweightAll(w) + taken := make(map[int]struct{}) + var c int + for { + item, ok := ts.Take() + if !ok { + if c != n { + t.Errorf("unexpected number of items: got: %d want: %d", c, int(n)) + } + break + } + c++ + if _, exists := taken[item]; exists { + t.Errorf("unexpected duplicate sample for item: %d", item) + } + taken[item] = struct{}{} + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/withoutreplacement.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/withoutreplacement.go new file mode 100644 index 00000000..9fbc543c --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/withoutreplacement.go @@ -0,0 +1,59 @@ +// 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 sampleuv + +import ( + "math/rand" + "sort" +) + +// WithoutReplacement samples len(idxs) integers from [0, n) without replacement. +// That is, upon return the elements of idxs will be unique integers. If source +// is non-nil it will be used to generate random numbers, otherwise the default +// source from the math/rand package will be used. +// +// WithoutReplacement will panic if len(idxs) > n. +func WithoutReplacement(idxs []int, n int, src *rand.Rand) { + if len(idxs) == 0 { + panic("withoutreplacement: zero length input") + } + if len(idxs) > n { + panic("withoutreplacement: impossible size inputs") + } + + // There are two algorithms. One is to generate a random permutation + // and take the first len(idxs) elements. The second is to generate + // individual random numbers for each element and check uniqueness. The first + // method scales as O(n), and the second scales as O(len(idxs)^2). Choose + // the algorithm accordingly. + if n < len(idxs)*len(idxs) { + var perm []int + if src != nil { + perm = src.Perm(n) + } else { + perm = rand.Perm(n) + } + copy(idxs, perm) + } + + // Instead, generate the random numbers directly. + sorted := make([]int, 0, len(idxs)) + for i := range idxs { + var r int + if src != nil { + r = src.Intn(n - i) + } else { + r = rand.Intn(n - i) + } + for _, v := range sorted { + if r >= v { + r++ + } + } + idxs[i] = r + sorted = append(sorted, r) + sort.Ints(sorted) + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/sampleuv/withoutreplacement_test.go b/vendor/gonum.org/v1/gonum/stat/sampleuv/withoutreplacement_test.go new file mode 100644 index 00000000..fca5d7d3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/sampleuv/withoutreplacement_test.go @@ -0,0 +1,65 @@ +// 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 sampleuv + +import ( + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func TestWithoutReplacement(t *testing.T) { + for cas, test := range []struct { + N int + K int + Src *rand.Rand + Trials int + Tol float64 + }{ + { + // Test with perm and source. + N: 10, K: 5, Src: rand.New(rand.NewSource(1)), + Trials: 100000, Tol: 1e-3, + }, + { + // Test without perm and with source. + N: 10, K: 3, Src: rand.New(rand.NewSource(1)), + Trials: 100000, Tol: 1e-3, + }, + } { + dist := make([]float64, test.N) + for trial := 0; trial < test.Trials; trial++ { + idxs := make([]int, test.K) + WithoutReplacement(idxs, test.N, test.Src) + + allDiff := true + for i := 0; i < len(idxs); i++ { + v := idxs[i] + for j := i + 1; j < len(idxs); j++ { + if v == idxs[j] { + allDiff = false + break + } + } + } + if !allDiff { + t.Errorf("Cas %d: Repeat in sampling. Idxs =%v", cas, idxs) + } + for _, v := range idxs { + dist[v]++ + } + } + div := 1 / (float64(test.Trials) * float64(test.K)) + floats.Scale(div, dist) + want := make([]float64, test.N) + for i := range want { + want[i] = 1 / float64(test.N) + } + if !floats.EqualApprox(want, dist, test.Tol) { + t.Errorf("Cas %d: biased sampling. Want = %v, got = %v", cas, want, dist) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/spatial/doc.go b/vendor/gonum.org/v1/gonum/stat/spatial/doc.go new file mode 100644 index 00000000..139d22d9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/spatial/doc.go @@ -0,0 +1,6 @@ +// Copyright ©2017 The gonum Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package spatial provides spatial statistical functions. +package spatial // import "gonum.org/v1/gonum/stat/spatial" diff --git a/vendor/gonum.org/v1/gonum/stat/spatial/spatial.go b/vendor/gonum.org/v1/gonum/stat/spatial/spatial.go new file mode 100644 index 00000000..a45fe422 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/spatial/spatial.go @@ -0,0 +1,162 @@ +// 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 spatial + +import ( + "math" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat" +) + +// TODO(kortschak): Implement weighted routines. + +// GetisOrdGStar returns the Local Getis-Ord G*i statistic for element of of the +// weighted data using the provided locality matrix. The returned value is a z-score. +// +// G^*_i = num_i / den_i +// +// num_i = \sum_j (w_{ij} x_j) - \bar X \sum_j w_{ij} +// den_i = S \sqrt(((n \sum_j w_{ij}^2 - (\sum_j w_{ij})^2))/(n - 1)) +// \bar X = (\sum_j x_j) / n +// S = \sqrt((\sum_j x_j^2)/n - (\bar X)^2) +// +// GetisOrdGStar will panic if locality is not a square matrix with dimensions the +// same as the length of data or if i is not a valid index into data. +// +// See doi.org/10.1111%2Fj.1538-4632.1995.tb00912.x. +// +// Weighted Getis-Ord G*i is not currently implemented and GetisOrdGStar will +// panic if weights is not nil. +func GetisOrdGStar(i int, data, weights []float64, locality mat.Matrix) float64 { + if weights != nil { + panic("spatial: weighted data not yet implemented") + } + r, c := locality.Dims() + if r != len(data) || c != len(data) { + panic("spatial: data length mismatch") + } + + n := float64(len(data)) + mean, std := stat.MeanStdDev(data, weights) + var dwd, dww, sw float64 + if doer, ok := locality.(mat.RowNonZeroDoer); ok { + doer.DoRowNonZero(i, func(_, j int, w float64) { + sw += w + dwd += w * data[j] + dww += w * w + }) + } else { + for j, v := range data { + w := locality.At(i, j) + sw += w + dwd += w * v + dww += w * w + } + } + s := std * math.Sqrt((n-1)/n) + + return (dwd - mean*sw) / (s * math.Sqrt((n*dww-sw*sw)/(n-1))) +} + +// GlobalMoransI performs Global Moran's I calculation of spatial autocorrelation +// for the given data using the provided locality matrix. GlobalMoransI returns +// Moran's I, Var(I) and the z-score associated with those values. +// GlobalMoransI will panic if locality is not a square matrix with dimensions the +// same as the length of data. +// +// See https://doi.org/10.1111%2Fj.1538-4632.2007.00708.x. +// +// Weighted Global Moran's I is not currently implemented and GlobalMoransI will +// panic if weights is not nil. +func GlobalMoransI(data, weights []float64, locality mat.Matrix) (i, v, z float64) { + if weights != nil { + panic("spatial: weighted data not yet implemented") + } + if r, c := locality.Dims(); r != len(data) || c != len(data) { + panic("spatial: data length mismatch") + } + mean := stat.Mean(data, nil) + + doer, isDoer := locality.(mat.RowNonZeroDoer) + + // Calculate Moran's I for the data. + var num, den, sum float64 + for i, xi := range data { + zi := xi - mean + den += zi * zi + if isDoer { + doer.DoRowNonZero(i, func(_, j int, w float64) { + sum += w + zj := data[j] - mean + num += w * zi * zj + }) + } else { + for j, xj := range data { + w := locality.At(i, j) + sum += w + zj := xj - mean + num += w * zi * zj + } + } + } + i = (float64(len(data)) / sum) * (num / den) + + // Calculate Moran's E(I) for the data. + e := -1 / float64(len(data)-1) + + // Calculate Moran's Var(I) for the data. + // http://pro.arcgis.com/en/pro-app/tool-reference/spatial-statistics/h-how-spatial-autocorrelation-moran-s-i-spatial-st.htm + // http://pro.arcgis.com/en/pro-app/tool-reference/spatial-statistics/h-global-morans-i-additional-math.htm + var s0, s1, s2 float64 + var var2, var4 float64 + for i, v := range data { + v -= mean + v *= v + var2 += v + var4 += v * v + + var p2 float64 + if isDoer { + doer.DoRowNonZero(i, func(i, j int, wij float64) { + wji := locality.At(j, i) + + s0 += wij + + v := wij + wji + s1 += v * v + + p2 += v + }) + } else { + for j := range data { + wij := locality.At(i, j) + wji := locality.At(j, i) + + s0 += wij + + v := wij + wji + s1 += v * v + + p2 += v + } + } + s2 += p2 * p2 + } + s1 *= 0.5 + + n := float64(len(data)) + a := n * ((n*n-3*n+3)*s1 - n*s2 + 3*s0*s0) + c := (n - 1) * (n - 2) * (n - 3) * s0 * s0 + d := var4 / (var2 * var2) + b := d * ((n*n-n)*s1 - 2*n*s2 + 6*s0*s0) + + v = (a-b)/c - e*e + + // Calculate z-score associated with Moran's I for the data. + z = (i - e) / math.Sqrt(v) + + return i, v, z +} diff --git a/vendor/gonum.org/v1/gonum/stat/spatial/spatial_areal_example_test.go b/vendor/gonum.org/v1/gonum/stat/spatial/spatial_areal_example_test.go new file mode 100644 index 00000000..1f849292 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/spatial/spatial_areal_example_test.go @@ -0,0 +1,74 @@ +// 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 spatial_test + +import ( + "fmt" + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat/spatial" +) + +// Euclid is a mat.Matrix whose elements refects the Euclidean +// distance between a series of unit-separated points strided +// to be arranged in an x by y grid. +type Euclid struct{ x, y int } + +func (e Euclid) Dims() (r, c int) { return e.x * e.y, e.x * e.y } +func (e Euclid) At(i, j int) float64 { + d := e.x * e.y + if i < 0 || d <= i || j < 0 || d <= j { + panic("bounds error") + } + if i == j { + return 0 + } + x := float64(j%e.x - i%e.x) + y := float64(j/e.x - i/e.x) + return 1 / math.Hypot(x, y) +} +func (e Euclid) T() mat.Matrix { return mat.Transpose{e} } + +func ExampleGlobalMoransI_areal() { + locality := Euclid{10, 10} + + data1 := []float64{ + 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, + 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, + } + i1, _, z1 := spatial.GlobalMoransI(data1, nil, locality) + + data2 := []float64{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + } + i2, _, z2 := spatial.GlobalMoransI(data2, nil, locality) + + fmt.Printf("%v scattered points Moran's I=%.4v z-score=%.4v\n", floats.Sum(data1), i1, z1) + fmt.Printf("%v clustered points Moran's I=%.4v z-score=%.4v\n", floats.Sum(data2), i2, z2) + + // Output: + // + // 24 scattered points Moran's I=-0.02999 z-score=-1.913 + // 24 clustered points Moran's I=0.09922 z-score=10.52 +} diff --git a/vendor/gonum.org/v1/gonum/stat/spatial/spatial_example_test.go b/vendor/gonum.org/v1/gonum/stat/spatial/spatial_example_test.go new file mode 100644 index 00000000..e5281a7e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/spatial/spatial_example_test.go @@ -0,0 +1,142 @@ +// 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 spatial_test + +import ( + "fmt" + + "gonum.org/v1/gonum/mat" + "gonum.org/v1/gonum/stat/spatial" +) + +func ExampleGlobalMoransI_linear() { + data := []float64{0, 0, 0, 1, 1, 1, 0, 1, 0, 0} + + // The locality here describes spatial neighbor + // relationships. + locality := mat.NewDense(10, 10, []float64{ + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + }) + + i, _, z := spatial.GlobalMoransI(data, nil, locality) + + fmt.Printf("Moran's I=%.4v z-score=%.4v\n", i, z) + + // Output: + // + // Moran's I=0.1111 z-score=0.6335 +} + +func ExampleGlobalMoransI_banded() { + data := []float64{0, 0, 0, 1, 1, 1, 0, 1, 0, 0} + + // The locality here describes spatial neighbor + // relationships. + // This example uses the band matrix representation + // to improve time and space efficiency. + locality := mat.NewBandDense(10, 10, 1, 1, []float64{ + 0, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 1, + 1, 0, 0, + }) + + i, _, z := spatial.GlobalMoransI(data, nil, locality) + + fmt.Printf("Moran's I=%.4v z-score=%.4v\n", i, z) + + // Output: + // + // Moran's I=0.1111 z-score=0.6335 +} + +func ExampleGetisOrdGStar() { + data := []float64{0, 0, 0, 1, 1, 1, 0, 1, 0, 0} + + // The locality here describes spatial neighbor + // relationships including self. + locality := mat.NewDense(10, 10, []float64{ + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + }) + + for i, v := range data { + fmt.Printf("v=%v G*i=% .4v\n", v, spatial.GetisOrdGStar(i, data, nil, locality)) + } + + // Output: + // + // v=0 G*i=-1.225 + // v=0 G*i=-1.604 + // v=0 G*i=-0.2673 + // v=1 G*i= 1.069 + // v=1 G*i= 2.405 + // v=1 G*i= 1.069 + // v=0 G*i= 1.069 + // v=1 G*i=-0.2673 + // v=0 G*i=-0.2673 + // v=0 G*i=-1.225 +} + +func ExampleGetisOrd_band() { + data := []float64{0, 0, 0, 1, 1, 1, 0, 1, 0, 0} + + // The locality here describes spatial neighbor + // relationships including self. + // This example uses the band matrix representation + // to improve time and space efficiency. + locality := mat.NewBandDense(10, 10, 1, 1, []float64{ + 0, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + 1, 1, 0, + }) + + for i, v := range data { + fmt.Printf("v=%v G*i=% .4v\n", v, spatial.GetisOrdGStar(i, data, nil, locality)) + } + + // Output: + // + // v=0 G*i=-1.225 + // v=0 G*i=-1.604 + // v=0 G*i=-0.2673 + // v=1 G*i= 1.069 + // v=1 G*i= 2.405 + // v=1 G*i= 1.069 + // v=0 G*i= 1.069 + // v=1 G*i=-0.2673 + // v=0 G*i=-0.2673 + // v=0 G*i=-1.225 +} diff --git a/vendor/gonum.org/v1/gonum/stat/spatial/spatial_test.go b/vendor/gonum.org/v1/gonum/stat/spatial/spatial_test.go new file mode 100644 index 00000000..f91edfdf --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/spatial/spatial_test.go @@ -0,0 +1,293 @@ +// 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 spatial + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +func simpleAdjacency(n, wide int, diag bool) mat.Matrix { + m := mat.NewDense(n, n, nil) + for i := 0; i < n; i++ { + for j := 1; j <= wide; j++ { + if j > i { + continue + } + m.Set(i-j, i, 1) + m.Set(i, i-j, 1) + } + if diag { + m.Set(i, i, 1) + } + } + return m +} + +func simpleAdjacencyBand(n, wide int, diag bool) mat.Matrix { + m := mat.NewBandDense(n, n, wide, wide, nil) + for i := 0; i < n; i++ { + for j := 1; j <= wide; j++ { + if j > i { + continue + } + m.SetBand(i-j, i, 1) + m.SetBand(i, i-j, 1) + } + if diag { + m.SetBand(i, i, 1) + } + } + return m +} + +var spatialTests = []struct { + from, to float64 + n, wide int + fn func(float64, int, *rand.Rand) float64 + locality func(n, wide int, diag bool) mat.Matrix + + // Values for MoranI and z-score are obtained from + // an R reference implementation. + wantMoranI float64 + wantZ float64 + + // The value for expected number of significant + // segments is obtained from visual inspection + // of the plotted data. + wantSegs int +}{ + // Dense matrix locality. + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(_ float64, _ int, rnd *rand.Rand) float64 { + return rnd.Float64() + }, + locality: simpleAdjacency, + + wantMoranI: -0.0019631298955953233, + wantZ: -0.03039477405151108, + wantSegs: 0, + }, + { + from: -math.Pi / 2, to: 3 * math.Pi / 2, n: 1000, wide: 1, + fn: func(x float64, _ int, _ *rand.Rand) float64 { + y := math.Sin(x) + if math.Abs(y) > 0.5 { + y *= 1/math.Abs(y) - 1 + } + return y * math.Sin(x*2) + }, + locality: simpleAdjacency, + + wantMoranI: 1.0008149537991464, + wantZ: 31.648547078779092, + wantSegs: 4, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(_ float64, _ int, rnd *rand.Rand) float64 { + return rnd.NormFloat64() + }, + locality: simpleAdjacency, + + wantMoranI: 0.031195199553564902, + wantZ: 1.0171161514080056, + wantSegs: 0, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(x float64, _ int, rnd *rand.Rand) float64 { + if rnd.Float64() < 0.5 { + return rnd.NormFloat64() + 5 + } + return rnd.NormFloat64() + }, + locality: simpleAdjacency, + + wantMoranI: -0.016245135637562223, + wantZ: -0.48157993864993476, + wantSegs: 0, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(x float64, i int, rnd *rand.Rand) float64 { + if i%2 == 0 { + return rnd.NormFloat64() + 5 + } + return rnd.NormFloat64() + }, + locality: simpleAdjacency, + + wantMoranI: -0.8565268969272998, + wantZ: -27.027057520918113, + wantSegs: 0, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(_ float64, i int, _ *rand.Rand) float64 { + return float64(i % 2) + }, + locality: simpleAdjacency, + + wantMoranI: -1, + wantZ: -31.559531064275987, + wantSegs: 0, + }, + + // Band matrix locality. + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(_ float64, _ int, rnd *rand.Rand) float64 { + return rnd.Float64() + }, + locality: simpleAdjacencyBand, + + wantMoranI: -0.0019631298955953233, + wantZ: -0.03039477405151108, + wantSegs: 0, + }, + { + from: -math.Pi / 2, to: 3 * math.Pi / 2, n: 1000, wide: 1, + fn: func(x float64, _ int, _ *rand.Rand) float64 { + y := math.Sin(x) + if math.Abs(y) > 0.5 { + y *= 1/math.Abs(y) - 1 + } + return y * math.Sin(x*2) + }, + locality: simpleAdjacencyBand, + + wantMoranI: 1.0008149537991464, + wantZ: 31.648547078779092, + wantSegs: 4, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(_ float64, _ int, rnd *rand.Rand) float64 { + return rnd.NormFloat64() + }, + locality: simpleAdjacencyBand, + + wantMoranI: 0.031195199553564902, + wantZ: 1.0171161514080056, + wantSegs: 0, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(x float64, _ int, rnd *rand.Rand) float64 { + if rnd.Float64() < 0.5 { + return rnd.NormFloat64() + 5 + } + return rnd.NormFloat64() + }, + locality: simpleAdjacencyBand, + + wantMoranI: -0.016245135637562223, + wantZ: -0.48157993864993476, + wantSegs: 0, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(x float64, i int, rnd *rand.Rand) float64 { + if i%2 == 0 { + return rnd.NormFloat64() + 5 + } + return rnd.NormFloat64() + }, + locality: simpleAdjacencyBand, + + wantMoranI: -0.8565268969272998, + wantZ: -27.027057520918113, + wantSegs: 0, + }, + { + from: 0, to: 1, n: 1000, wide: 1, + fn: func(_ float64, i int, _ *rand.Rand) float64 { + return float64(i % 2) + }, + locality: simpleAdjacencyBand, + + wantMoranI: -1, + wantZ: -31.559531064275987, + wantSegs: 0, + }, +} + +func TestGetisOrd(t *testing.T) { + for ti, test := range spatialTests { + rnd := rand.New(rand.NewSource(1)) + data := make([]float64, test.n) + step := (test.to - test.from) / float64(test.n) + for i := range data { + data[i] = test.fn(test.from+step*float64(i), i, rnd) + } + locality := test.locality(test.n, test.wide, true) + + nseg := getisOrdSegments(data, nil, locality) + if nseg != test.wantSegs { + t.Errorf("unexpected number of significant segments for test %d: got:%d want:%d", + ti, nseg, test.wantSegs) + } + } +} + +// getisOrdSegments returns the number of contiguously significant G*i segemtns in +// data. This allows an intuitive validation of the function in lieu of a reference +// implementation. +func getisOrdSegments(data, weight []float64, locality mat.Matrix) int { + const thresh = 2 + var nseg int + segstart := -1 + for i := range data { + gi := GetisOrdGStar(i, data, weight, locality) + if segstart != -1 { + if math.Abs(gi) < thresh { + // Filter short segments. + if i-segstart < 5 { + segstart = -1 + continue + } + + segstart = -1 + nseg++ + } + continue + } + if math.Abs(gi) >= thresh { + segstart = i + } + } + if segstart != -1 && len(data)-segstart >= 5 { + nseg++ + } + return nseg +} + +func TestGlobalMoransI(t *testing.T) { + const tol = 1e-14 + for ti, test := range spatialTests { + rnd := rand.New(rand.NewSource(1)) + data := make([]float64, test.n) + step := (test.to - test.from) / float64(test.n) + for i := range data { + data[i] = test.fn(test.from+step*float64(i), i, rnd) + } + locality := test.locality(test.n, test.wide, false) + + gotI, _, gotZ := GlobalMoransI(data, nil, locality) + + if !floats.EqualWithinAbsOrRel(gotI, test.wantMoranI, tol, tol) { + t.Errorf("unexpected Moran's I value for test %d: got:%v want:%v", ti, gotI, test.wantMoranI) + } + if !floats.EqualWithinAbsOrRel(gotZ, test.wantZ, tol, tol) { + t.Errorf("unexpected Moran's I z-score for test %d: got:%v want:%v", ti, gotZ, test.wantZ) + } + } +} diff --git a/vendor/gonum.org/v1/gonum/stat/stat.go b/vendor/gonum.org/v1/gonum/stat/stat.go new file mode 100644 index 00000000..11b90e91 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/stat.go @@ -0,0 +1,1160 @@ +// 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 stat + +import ( + "math" + "sort" + + "gonum.org/v1/gonum/floats" +) + +// CumulantKind specifies the behavior for calculating the empirical CDF or Quantile +type CumulantKind int + +const ( + // Constant values should match the R nomenclature. See + // https://en.wikipedia.org/wiki/Quantile#Estimating_the_quantiles_of_a_population + + // Empirical treats the distribution as the actual empirical distribution. + Empirical CumulantKind = 1 +) + +// bhattacharyyaCoeff computes the Bhattacharyya Coefficient for probability distributions given by: +// \sum_i \sqrt{p_i q_i} +// +// It is assumed that p and q have equal length. +func bhattacharyyaCoeff(p, q []float64) float64 { + var bc float64 + for i, a := range p { + bc += math.Sqrt(a * q[i]) + } + return bc +} + +// Bhattacharyya computes the distance between the probability distributions p and q given by: +// -\ln ( \sum_i \sqrt{p_i q_i} ) +// +// The lengths of p and q must be equal. It is assumed that p and q sum to 1. +func Bhattacharyya(p, q []float64) float64 { + if len(p) != len(q) { + panic("stat: slice length mismatch") + } + bc := bhattacharyyaCoeff(p, q) + return -math.Log(bc) +} + +// CDF returns the empirical cumulative distribution function value of x, that is +// the fraction of the samples less than or equal to q. The +// exact behavior is determined by the CumulantKind. CDF is theoretically +// the inverse of the Quantile function, though it may not be the actual inverse +// for all values q and CumulantKinds. +// +// The x data must be sorted in increasing order. If weights is nil then all +// of the weights are 1. If weights is not nil, then len(x) must equal len(weights). +// +// CumulantKind behaviors: +// - Empirical: Returns the lowest fraction for which q is greater than or equal +// to that fraction of samples +func CDF(q float64, c CumulantKind, x, weights []float64) float64 { + if weights != nil && len(x) != len(weights) { + panic("stat: slice length mismatch") + } + if floats.HasNaN(x) { + return math.NaN() + } + if !sort.Float64sAreSorted(x) { + panic("x data are not sorted") + } + + if q < x[0] { + return 0 + } + if q >= x[len(x)-1] { + return 1 + } + + var sumWeights float64 + if weights == nil { + sumWeights = float64(len(x)) + } else { + sumWeights = floats.Sum(weights) + } + + // Calculate the index + switch c { + case Empirical: + // Find the smallest value that is greater than that percent of the samples + var w float64 + for i, v := range x { + if v > q { + return w / sumWeights + } + if weights == nil { + w++ + } else { + w += weights[i] + } + } + panic("impossible") + default: + panic("stat: bad cumulant kind") + } +} + +// ChiSquare computes the chi-square distance between the observed frequences 'obs' and +// expected frequences 'exp' given by: +// \sum_i (obs_i-exp_i)^2 / exp_i +// +// The lengths of obs and exp must be equal. +func ChiSquare(obs, exp []float64) float64 { + if len(obs) != len(exp) { + panic("stat: slice length mismatch") + } + var result float64 + for i, a := range obs { + b := exp[i] + if a == 0 && b == 0 { + continue + } + result += (a - b) * (a - b) / b + } + return result +} + +// CircularMean returns the circular mean of the dataset. +// atan2(\sum_i w_i * sin(alpha_i), \sum_i w_i * cos(alpha_i)) +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func CircularMean(x, weights []float64) float64 { + if weights != nil && len(x) != len(weights) { + panic("stat: slice length mismatch") + } + + var aX, aY float64 + if weights != nil { + for i, v := range x { + aX += weights[i] * math.Cos(v) + aY += weights[i] * math.Sin(v) + } + } else { + for _, v := range x { + aX += math.Cos(v) + aY += math.Sin(v) + } + } + + return math.Atan2(aY, aX) +} + +// Correlation returns the weighted correlation between the samples of x and y +// with the given means. +// sum_i {w_i (x_i - meanX) * (y_i - meanY)} / (stdX * stdY) +// The lengths of x and y must be equal. If weights is nil then all of the +// weights are 1. If weights is not nil, then len(x) must equal len(weights). +func Correlation(x, y, weights []float64) float64 { + // This is a two-pass corrected implementation. It is an adaptation of the + // algorithm used in the MeanVariance function, which applies a correction + // to the typical two pass approach. + + if len(x) != len(y) { + panic("stat: slice length mismatch") + } + xu := Mean(x, weights) + yu := Mean(y, weights) + var ( + sxx float64 + syy float64 + sxy float64 + xcompensation float64 + ycompensation float64 + ) + if weights == nil { + for i, xv := range x { + yv := y[i] + xd := xv - xu + yd := yv - yu + sxx += xd * xd + syy += yd * yd + sxy += xd * yd + xcompensation += xd + ycompensation += yd + } + // xcompensation and ycompensation are from Chan, et. al. + // referenced in the MeanVariance function. They are analogous + // to the second term in (1.7) in that paper. + sxx -= xcompensation * xcompensation / float64(len(x)) + syy -= ycompensation * ycompensation / float64(len(x)) + + return (sxy - xcompensation*ycompensation/float64(len(x))) / math.Sqrt(sxx*syy) + + } + + var sumWeights float64 + for i, xv := range x { + w := weights[i] + yv := y[i] + xd := xv - xu + wxd := w * xd + yd := yv - yu + wyd := w * yd + sxx += wxd * xd + syy += wyd * yd + sxy += wxd * yd + xcompensation += wxd + ycompensation += wyd + sumWeights += w + } + // xcompensation and ycompensation are from Chan, et. al. + // referenced in the MeanVariance function. They are analogous + // to the second term in (1.7) in that paper, except they use + // the sumWeights instead of the sample count. + sxx -= xcompensation * xcompensation / sumWeights + syy -= ycompensation * ycompensation / sumWeights + + return (sxy - xcompensation*ycompensation/sumWeights) / math.Sqrt(sxx*syy) +} + +// Covariance returns the weighted covariance between the samples of x and y. +// sum_i {w_i (x_i - meanX) * (y_i - meanY)} / (sum_j {w_j} - 1) +// The lengths of x and y must be equal. If weights is nil then all of the +// weights are 1. If weights is not nil, then len(x) must equal len(weights). +func Covariance(x, y, weights []float64) float64 { + // This is a two-pass corrected implementation. It is an adaptation of the + // algorithm used in the MeanVariance function, which applies a correction + // to the typical two pass approach. + + if len(x) != len(y) { + panic("stat: slice length mismatch") + } + xu := Mean(x, weights) + yu := Mean(y, weights) + var ( + ss float64 + xcompensation float64 + ycompensation float64 + ) + if weights == nil { + for i, xv := range x { + yv := y[i] + xd := xv - xu + yd := yv - yu + ss += xd * yd + xcompensation += xd + ycompensation += yd + } + // xcompensation and ycompensation are from Chan, et. al. + // referenced in the MeanVariance function. They are analogous + // to the second term in (1.7) in that paper. + return (ss - xcompensation*ycompensation/float64(len(x))) / float64(len(x)-1) + } + + var sumWeights float64 + + for i, xv := range x { + w := weights[i] + yv := y[i] + wxd := w * (xv - xu) + yd := (yv - yu) + ss += wxd * yd + xcompensation += wxd + ycompensation += w * yd + sumWeights += w + } + // xcompensation and ycompensation are from Chan, et. al. + // referenced in the MeanVariance function. They are analogous + // to the second term in (1.7) in that paper, except they use + // the sumWeights instead of the sample count. + return (ss - xcompensation*ycompensation/sumWeights) / (sumWeights - 1) +} + +// CrossEntropy computes the cross-entropy between the two distributions specified +// in p and q. +func CrossEntropy(p, q []float64) float64 { + if len(p) != len(q) { + panic("stat: slice length mismatch") + } + var ce float64 + for i, v := range p { + if v != 0 { + ce -= v * math.Log(q[i]) + } + } + return ce +} + +// Entropy computes the Shannon entropy of a distribution or the distance between +// two distributions. The natural logarithm is used. +// - sum_i (p_i * log_e(p_i)) +func Entropy(p []float64) float64 { + var e float64 + for _, v := range p { + if v != 0 { // Entropy needs 0 * log(0) == 0 + e -= v * math.Log(v) + } + } + return e +} + +// ExKurtosis returns the population excess kurtosis of the sample. +// The kurtosis is defined by the 4th moment of the mean divided by the squared +// variance. The excess kurtosis subtracts 3.0 so that the excess kurtosis of +// the normal distribution is zero. +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func ExKurtosis(x, weights []float64) float64 { + mean, std := MeanStdDev(x, weights) + if weights == nil { + var e float64 + for _, v := range x { + z := (v - mean) / std + e += z * z * z * z + } + mul, offset := kurtosisCorrection(float64(len(x))) + return e*mul - offset + } + + var ( + e float64 + sumWeights float64 + ) + for i, v := range x { + z := (v - mean) / std + e += weights[i] * z * z * z * z + sumWeights += weights[i] + } + mul, offset := kurtosisCorrection(sumWeights) + return e*mul - offset +} + +// n is the number of samples +// see https://en.wikipedia.org/wiki/Kurtosis +func kurtosisCorrection(n float64) (mul, offset float64) { + return ((n + 1) / (n - 1)) * (n / (n - 2)) * (1 / (n - 3)), 3 * ((n - 1) / (n - 2)) * ((n - 1) / (n - 3)) +} + +// GeometricMean returns the weighted geometric mean of the dataset +// \prod_i {x_i ^ w_i} +// This only applies with positive x and positive weights. If weights is nil +// then all of the weights are 1. If weights is not nil, then len(x) must equal +// len(weights). +func GeometricMean(x, weights []float64) float64 { + if weights == nil { + var s float64 + for _, v := range x { + s += math.Log(v) + } + s /= float64(len(x)) + return math.Exp(s) + } + if len(x) != len(weights) { + panic("stat: slice length mismatch") + } + var ( + s float64 + sumWeights float64 + ) + for i, v := range x { + s += weights[i] * math.Log(v) + sumWeights += weights[i] + } + s /= sumWeights + return math.Exp(s) +} + +// HarmonicMean returns the weighted harmonic mean of the dataset +// \sum_i {w_i} / ( sum_i {w_i / x_i} ) +// This only applies with positive x and positive weights. +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func HarmonicMean(x, weights []float64) float64 { + if weights != nil && len(x) != len(weights) { + panic("stat: slice length mismatch") + } + // TODO: Fix this to make it more efficient and avoid allocation + + // This can be numerically unstable (for example if x is very small) + // W = \sum_i {w_i} + // hm = exp(log(W) - log(\sum_i w_i / x_i)) + + logs := make([]float64, len(x)) + var W float64 + for i := range x { + if weights == nil { + logs[i] = -math.Log(x[i]) + W++ + continue + } + logs[i] = math.Log(weights[i]) - math.Log(x[i]) + W += weights[i] + } + + // Sum all of the logs + v := floats.LogSumExp(logs) // this computes log(\sum_i { w_i / x_i}) + return math.Exp(math.Log(W) - v) +} + +// Hellinger computes the distance between the probability distributions p and q given by: +// \sqrt{ 1 - \sum_i \sqrt{p_i q_i} } +// +// The lengths of p and q must be equal. It is assumed that p and q sum to 1. +func Hellinger(p, q []float64) float64 { + if len(p) != len(q) { + panic("stat: slice length mismatch") + } + bc := bhattacharyyaCoeff(p, q) + return math.Sqrt(1 - bc) +} + +// Histogram sums up the weighted number of data points in each bin. +// The weight of data point x[i] will be placed into count[j] if +// dividers[j] <= x < dividers[j+1]. The "span" function in the floats package can assist +// with bin creation. +// +// The following conditions on the inputs apply: +// - The count variable must either be nil or have length of one less than dividers. +// - The values in dividers must be sorted (use the sort package). +// - The x values must be sorted. +// - If weights is nil then all of the weights are 1. +// - If weights is not nil, then len(x) must equal len(weights). +func Histogram(count, dividers, x, weights []float64) []float64 { + if weights != nil && len(x) != len(weights) { + panic("stat: slice length mismatch") + } + if count == nil { + count = make([]float64, len(dividers)-1) + } + if len(dividers) < 2 { + panic("histogram: fewer than two dividers") + } + if len(count) != len(dividers)-1 { + panic("histogram: bin count mismatch") + } + if !sort.Float64sAreSorted(dividers) { + panic("histogram: dividers are not sorted") + } + if !sort.Float64sAreSorted(x) { + panic("histogram: x data are not sorted") + } + for i := range count { + count[i] = 0 + } + if len(x) == 0 { + return count + } + if x[0] < dividers[0] { + panic("histogram: minimum x value is less than lowest divider") + } + if x[len(x)-1] >= dividers[len(dividers)-1] { + panic("histogram: minimum x value is greater than highest divider") + } + + idx := 0 + comp := dividers[idx+1] + if weights == nil { + for _, v := range x { + if v < comp { + // Still in the current bucket + count[idx]++ + continue + } + // Find the next divider where v is less than the divider + for j := idx + 1; j < len(dividers); j++ { + if v < dividers[j+1] { + idx = j + comp = dividers[j+1] + break + } + } + count[idx]++ + } + return count + } + + for i, v := range x { + if v < comp { + // Still in the current bucket + count[idx] += weights[i] + continue + } + // Need to find the next divider where v is less than the divider. + for j := idx + 1; j < len(count); j++ { + if v < dividers[j+1] { + idx = j + comp = dividers[j+1] + break + } + } + count[idx] += weights[i] + } + return count +} + +// JensenShannon computes the JensenShannon divergence between the distributions +// p and q. The Jensen-Shannon divergence is defined as +// m = 0.5 * (p + q) +// JS(p, q) = 0.5 ( KL(p, m) + KL(q, m) ) +// Unlike Kullback-Liebler, the Jensen-Shannon distance is symmetric. The value +// is between 0 and ln(2). +func JensenShannon(p, q []float64) float64 { + if len(p) != len(q) { + panic("stat: slice length mismatch") + } + var js float64 + for i, v := range p { + qi := q[i] + m := 0.5 * (v + qi) + if v != 0 { + // add kl from p to m + js += 0.5 * v * (math.Log(v) - math.Log(m)) + } + if qi != 0 { + // add kl from q to m + js += 0.5 * qi * (math.Log(qi) - math.Log(m)) + } + } + return js +} + +// KolmogorovSmirnov computes the largest distance between two empirical CDFs. +// Each dataset x and y consists of sample locations and counts, xWeights and +// yWeights, respectively. +// +// x and y may have different lengths, though len(x) must equal len(xWeights), and +// len(y) must equal len(yWeights). Both x and y must be sorted. +// +// Special cases are: +// = 0 if len(x) == len(y) == 0 +// = 1 if len(x) == 0, len(y) != 0 or len(x) != 0 and len(y) == 0 +func KolmogorovSmirnov(x, xWeights, y, yWeights []float64) float64 { + if xWeights != nil && len(x) != len(xWeights) { + panic("stat: slice length mismatch") + } + if yWeights != nil && len(y) != len(yWeights) { + panic("stat: slice length mismatch") + } + if len(x) == 0 || len(y) == 0 { + if len(x) == 0 && len(y) == 0 { + return 0 + } + return 1 + } + + if floats.HasNaN(x) { + return math.NaN() + } + if floats.HasNaN(y) { + return math.NaN() + } + + if !sort.Float64sAreSorted(x) { + panic("x data are not sorted") + } + if !sort.Float64sAreSorted(y) { + panic("y data are not sorted") + } + + xWeightsNil := xWeights == nil + yWeightsNil := yWeights == nil + + var ( + maxDist float64 + xSum, ySum float64 + xCdf, yCdf float64 + xIdx, yIdx int + ) + + if xWeightsNil { + xSum = float64(len(x)) + } else { + xSum = floats.Sum(xWeights) + } + + if yWeightsNil { + ySum = float64(len(y)) + } else { + ySum = floats.Sum(yWeights) + } + + xVal := x[0] + yVal := y[0] + + // Algorithm description: + // The goal is to find the maximum difference in the empirical CDFs for the + // two datasets. The CDFs are piecewise-constant, and thus the distance + // between the CDFs will only change at the values themselves. + // + // To find the maximum distance, step through the data in ascending order + // of value between the two datasets. At each step, compute the empirical CDF + // and compare the local distance with the maximum distance. + // Due to some corner cases, equal data entries must be tallied simultaneously. + for { + switch { + case xVal < yVal: + xVal, xCdf, xIdx = updateKS(xIdx, xCdf, xSum, x, xWeights, xWeightsNil) + case yVal < xVal: + yVal, yCdf, yIdx = updateKS(yIdx, yCdf, ySum, y, yWeights, yWeightsNil) + case xVal == yVal: + newX := x[xIdx] + newY := y[yIdx] + if newX < newY { + xVal, xCdf, xIdx = updateKS(xIdx, xCdf, xSum, x, xWeights, xWeightsNil) + } else if newY < newX { + yVal, yCdf, yIdx = updateKS(yIdx, yCdf, ySum, y, yWeights, yWeightsNil) + } else { + // Update them both, they'll be equal next time and the right + // thing will happen + xVal, xCdf, xIdx = updateKS(xIdx, xCdf, xSum, x, xWeights, xWeightsNil) + yVal, yCdf, yIdx = updateKS(yIdx, yCdf, ySum, y, yWeights, yWeightsNil) + } + default: + panic("unreachable") + } + + dist := math.Abs(xCdf - yCdf) + if dist > maxDist { + maxDist = dist + } + + // Both xCdf and yCdf will equal 1 at the end, so if we have reached the + // end of either sample list, the distance is as large as it can be. + if xIdx == len(x) || yIdx == len(y) { + return maxDist + } + } +} + +// updateKS gets the next data point from one of the set. In doing so, it combines +// the weight of all the data points of equal value. Upon return, val is the new +// value of the data set, newCdf is the total combined CDF up until this point, +// and newIdx is the index of the next location in that sample to examine. +func updateKS(idx int, cdf, sum float64, values, weights []float64, isNil bool) (val, newCdf float64, newIdx int) { + // Sum up all the weights of consecutive values that are equal + if isNil { + newCdf = cdf + 1/sum + } else { + newCdf = cdf + weights[idx]/sum + } + newIdx = idx + 1 + for { + if newIdx == len(values) { + return values[newIdx-1], newCdf, newIdx + } + if values[newIdx-1] != values[newIdx] { + return values[newIdx], newCdf, newIdx + } + if isNil { + newCdf += 1 / sum + } else { + newCdf += weights[newIdx] / sum + } + newIdx++ + } +} + +// KullbackLeibler computes the Kullback-Leibler distance between the +// distributions p and q. The natural logarithm is used. +// sum_i(p_i * log(p_i / q_i)) +// Note that the Kullback-Leibler distance is not symmetric; +// KullbackLeibler(p,q) != KullbackLeibler(q,p) +func KullbackLeibler(p, q []float64) float64 { + if len(p) != len(q) { + panic("stat: slice length mismatch") + } + var kl float64 + for i, v := range p { + if v != 0 { // Entropy needs 0 * log(0) == 0 + kl += v * (math.Log(v) - math.Log(q[i])) + } + } + return kl +} + +// LinearRegression computes the best-fit line +// y = alpha + beta*x +// to the data in x and y with the given weights. If origin is true, the +// regression is forced to pass through the origin. +// +// Specifically, LinearRegression computes the values of alpha and +// beta such that the total residual +// \sum_i w[i]*(y[i] - alpha - beta*x[i])^2 +// is minimized. If origin is true, then alpha is forced to be zero. +// +// The lengths of x and y must be equal. If weights is nil then all of the +// weights are 1. If weights is not nil, then len(x) must equal len(weights). +func LinearRegression(x, y, weights []float64, origin bool) (alpha, beta float64) { + if len(x) != len(y) { + panic("stat: slice length mismatch") + } + if weights != nil && len(weights) != len(x) { + panic("stat: slice length mismatch") + } + + w := 1.0 + if origin { + var x2Sum, xySum float64 + for i, xi := range x { + if weights != nil { + w = weights[i] + } + yi := y[i] + xySum += w * xi * yi + x2Sum += w * xi * xi + } + beta = xySum / x2Sum + + return 0, beta + } + + beta = Covariance(x, y, weights) / Variance(x, weights) + alpha = Mean(y, weights) - beta*Mean(x, weights) + return alpha, beta +} + +// RSquared returns the coefficient of determination defined as +// R^2 = 1 - \sum_i w[i]*(y[i] - alpha - beta*x[i])^2 / \sum_i w[i]*(y[i] - mean(y))^2 +// for the line +// y = alpha + beta*x +// and the data in x and y with the given weights. +// +// The lengths of x and y must be equal. If weights is nil then all of the +// weights are 1. If weights is not nil, then len(x) must equal len(weights). +func RSquared(x, y, weights []float64, alpha, beta float64) float64 { + if len(x) != len(y) { + panic("stat: slice length mismatch") + } + if weights != nil && len(weights) != len(x) { + panic("stat: slice length mismatch") + } + + w := 1.0 + yMean := Mean(y, weights) + var res, tot, d float64 + for i, xi := range x { + if weights != nil { + w = weights[i] + } + yi := y[i] + fi := alpha + beta*xi + d = yi - fi + res += w * d * d + d = yi - yMean + tot += w * d * d + } + return 1 - res/tot +} + +// RSquaredFrom returns the coefficient of determination defined as +// R^2 = 1 - \sum_i w[i]*(estimate[i] - value[i])^2 / \sum_i w[i]*(value[i] - mean(values))^2 +// and the data in estimates and values with the given weights. +// +// The lengths of estimates and values must be equal. If weights is nil then +// all of the weights are 1. If weights is not nil, then len(values) must +// equal len(weights). +func RSquaredFrom(estimates, values, weights []float64) float64 { + if len(estimates) != len(values) { + panic("stat: slice length mismatch") + } + if weights != nil && len(weights) != len(values) { + panic("stat: slice length mismatch") + } + + w := 1.0 + mean := Mean(values, weights) + var res, tot, d float64 + for i, val := range values { + if weights != nil { + w = weights[i] + } + d = val - estimates[i] + res += w * d * d + d = val - mean + tot += w * d * d + } + return 1 - res/tot +} + +// RNoughtSquared returns the coefficient of determination defined as +// R₀^2 = \sum_i w[i]*(beta*x[i])^2 / \sum_i w[i]*y[i]^2 +// for the line +// y = beta*x +// and the data in x and y with the given weights. RNoughtSquared should +// only be used for best-fit lines regressed through the origin. +// +// The lengths of x and y must be equal. If weights is nil then all of the +// weights are 1. If weights is not nil, then len(x) must equal len(weights). +func RNoughtSquared(x, y, weights []float64, beta float64) float64 { + if len(x) != len(y) { + panic("stat: slice length mismatch") + } + if weights != nil && len(weights) != len(x) { + panic("stat: slice length mismatch") + } + + w := 1.0 + var ssr, tot float64 + for i, xi := range x { + if weights != nil { + w = weights[i] + } + fi := beta * xi + ssr += w * fi * fi + yi := y[i] + tot += w * yi * yi + } + return ssr / tot +} + +// Mean computes the weighted mean of the data set. +// sum_i {w_i * x_i} / sum_i {w_i} +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func Mean(x, weights []float64) float64 { + if weights == nil { + return floats.Sum(x) / float64(len(x)) + } + if len(x) != len(weights) { + panic("stat: slice length mismatch") + } + var ( + sumValues float64 + sumWeights float64 + ) + for i, w := range weights { + sumValues += w * x[i] + sumWeights += w + } + return sumValues / sumWeights +} + +// Mode returns the most common value in the dataset specified by x and the +// given weights. Strict float64 equality is used when comparing values, so users +// should take caution. If several values are the mode, any of them may be returned. +func Mode(x, weights []float64) (val float64, count float64) { + if weights != nil && len(x) != len(weights) { + panic("stat: slice length mismatch") + } + if len(x) == 0 { + return 0, 0 + } + m := make(map[float64]float64) + if weights == nil { + for _, v := range x { + m[v]++ + } + } else { + for i, v := range x { + m[v] += weights[i] + } + } + var ( + maxCount float64 + max float64 + ) + for val, count := range m { + if count > maxCount { + maxCount = count + max = val + } + } + return max, maxCount +} + +// Moment computes the weighted n^th moment of the samples, +// E[(x - μ)^N] +// No degrees of freedom correction is done. +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func Moment(moment float64, x, weights []float64) float64 { + mean := Mean(x, weights) + if weights == nil { + var m float64 + for _, v := range x { + m += math.Pow(v-mean, moment) + } + return m / float64(len(x)) + } + var ( + m float64 + sumWeights float64 + ) + for i, v := range x { + m += weights[i] * math.Pow(v-mean, moment) + sumWeights += weights[i] + } + return m / sumWeights +} + +// MomentAbout computes the weighted n^th weighted moment of the samples about +// the given mean \mu, +// E[(x - μ)^N] +// No degrees of freedom correction is done. +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func MomentAbout(moment float64, x []float64, mean float64, weights []float64) float64 { + if weights == nil { + var m float64 + for _, v := range x { + m += math.Pow(v-mean, moment) + } + m /= float64(len(x)) + return m + } + if len(weights) != len(x) { + panic("stat: slice length mismatch") + } + var ( + m float64 + sumWeights float64 + ) + for i, v := range x { + m += weights[i] * math.Pow(v-mean, moment) + sumWeights += weights[i] + } + return m / sumWeights +} + +// Quantile returns the sample of x such that x is greater than or +// equal to the fraction p of samples. The exact behavior is determined by the +// CumulantKind, and p should be a number between 0 and 1. Quantile is theoretically +// the inverse of the CDF function, though it may not be the actual inverse +// for all values p and CumulantKinds. +// +// The x data must be sorted in increasing order. If weights is nil then all +// of the weights are 1. If weights is not nil, then len(x) must equal len(weights). +// +// CumulantKind behaviors: +// - Empirical: Returns the lowest value q for which q is greater than or equal +// to the fraction p of samples +func Quantile(p float64, c CumulantKind, x, weights []float64) float64 { + if !(p >= 0 && p <= 1) { + panic("stat: percentile out of bounds") + } + + if weights != nil && len(x) != len(weights) { + panic("stat: slice length mismatch") + } + if floats.HasNaN(x) { + return math.NaN() // This is needed because the algorithm breaks otherwise + } + if !sort.Float64sAreSorted(x) { + panic("x data are not sorted") + } + + var sumWeights float64 + if weights == nil { + sumWeights = float64(len(x)) + } else { + sumWeights = floats.Sum(weights) + } + switch c { + case Empirical: + var cumsum float64 + fidx := p * sumWeights + for i := range x { + if weights == nil { + cumsum++ + } else { + cumsum += weights[i] + } + if cumsum >= fidx { + return x[i] + } + } + panic("impossible") + default: + panic("stat: bad cumulant kind") + } +} + +// Skew computes the skewness of the sample data. +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func Skew(x, weights []float64) float64 { + + mean, std := MeanStdDev(x, weights) + if weights == nil { + var s float64 + for _, v := range x { + z := (v - mean) / std + s += z * z * z + } + return s * skewCorrection(float64(len(x))) + } + var ( + s float64 + sumWeights float64 + ) + for i, v := range x { + z := (v - mean) / std + s += weights[i] * z * z * z + sumWeights += weights[i] + } + return s * skewCorrection(sumWeights) +} + +// From: http://www.amstat.org/publications/jse/v19n2/doane.pdf page 7 +func skewCorrection(n float64) float64 { + return (n / (n - 1)) * (1 / (n - 2)) +} + +// SortWeighted rearranges the data in x along with their corresponding +// weights so that the x data are sorted. The data is sorted in place. +// Weights may be nil, but if weights is non-nil then it must have the same +// length as x. +func SortWeighted(x, weights []float64) { + if weights == nil { + sort.Float64s(x) + return + } + if len(x) != len(weights) { + panic("stat: slice length mismatch") + } + sort.Sort(weightSorter{ + x: x, + w: weights, + }) +} + +type weightSorter struct { + x []float64 + w []float64 +} + +func (w weightSorter) Len() int { return len(w.x) } +func (w weightSorter) Less(i, j int) bool { return w.x[i] < w.x[j] } +func (w weightSorter) Swap(i, j int) { + w.x[i], w.x[j] = w.x[j], w.x[i] + w.w[i], w.w[j] = w.w[j], w.w[i] +} + +// SortWeightedLabeled rearranges the data in x along with their +// corresponding weights and boolean labels so that the x data are sorted. +// The data is sorted in place. Weights and labels may be nil, if either +// is non-nil it must have the same length as x. +func SortWeightedLabeled(x []float64, labels []bool, weights []float64) { + if labels == nil { + SortWeighted(x, weights) + return + } + if weights == nil { + if len(x) != len(labels) { + panic("stat: slice length mismatch") + } + sort.Sort(labelSorter{ + x: x, + l: labels, + }) + return + } + if len(x) != len(labels) || len(x) != len(weights) { + panic("stat: slice length mismatch") + } + sort.Sort(weightLabelSorter{ + x: x, + l: labels, + w: weights, + }) +} + +type labelSorter struct { + x []float64 + l []bool +} + +func (a labelSorter) Len() int { return len(a.x) } +func (a labelSorter) Less(i, j int) bool { return a.x[i] < a.x[j] } +func (a labelSorter) Swap(i, j int) { + a.x[i], a.x[j] = a.x[j], a.x[i] + a.l[i], a.l[j] = a.l[j], a.l[i] +} + +type weightLabelSorter struct { + x []float64 + l []bool + w []float64 +} + +func (a weightLabelSorter) Len() int { return len(a.x) } +func (a weightLabelSorter) Less(i, j int) bool { return a.x[i] < a.x[j] } +func (a weightLabelSorter) Swap(i, j int) { + a.x[i], a.x[j] = a.x[j], a.x[i] + a.l[i], a.l[j] = a.l[j], a.l[i] + a.w[i], a.w[j] = a.w[j], a.w[i] +} + +// StdDev returns the sample standard deviation. +func StdDev(x, weights []float64) float64 { + _, std := MeanStdDev(x, weights) + return std +} + +// MeanStdDev returns the sample mean and standard deviation +func MeanStdDev(x, weights []float64) (mean, std float64) { + mean, variance := MeanVariance(x, weights) + return mean, math.Sqrt(variance) +} + +// StdErr returns the standard error in the mean with the given values. +func StdErr(std, sampleSize float64) float64 { + return std / math.Sqrt(sampleSize) +} + +// StdScore returns the standard score (a.k.a. z-score, z-value) for the value x +// with the givem mean and standard deviation, i.e. +// (x - mean) / std +func StdScore(x, mean, std float64) float64 { + return (x - mean) / std +} + +// Variance computes the weighted sample variance: +// \sum_i w_i (x_i - mean)^2 / (sum_i w_i - 1) +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func Variance(x, weights []float64) float64 { + _, variance := MeanVariance(x, weights) + return variance +} + +// MeanVariance computes the sample mean and variance, where the mean and variance are +// \sum_i w_i * x_i / (sum_i w_i) +// \sum_i w_i (x_i - mean)^2 / (sum_i w_i - 1) +// respectively. +// If weights is nil then all of the weights are 1. If weights is not nil, then +// len(x) must equal len(weights). +func MeanVariance(x, weights []float64) (mean, variance float64) { + + // This uses the corrected two-pass algorithm (1.7), from "Algorithms for computing + // the sample variance: Analysis and recommendations" by Chan, Tony F., Gene H. Golub, + // and Randall J. LeVeque. + + // note that this will panic if the slice lengths do not match + mean = Mean(x, weights) + var ( + ss float64 + compensation float64 + ) + if weights == nil { + for _, v := range x { + d := v - mean + ss += d * d + compensation += d + } + variance = (ss - compensation*compensation/float64(len(x))) / float64(len(x)-1) + return + } + + var sumWeights float64 + for i, v := range x { + w := weights[i] + d := v - mean + wd := w * d + ss += wd * d + compensation += wd + sumWeights += w + } + variance = (ss - compensation*compensation/sumWeights) / (sumWeights - 1) + return +} diff --git a/vendor/gonum.org/v1/gonum/stat/stat_test.go b/vendor/gonum.org/v1/gonum/stat/stat_test.go new file mode 100644 index 00000000..bdb24dd3 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/stat_test.go @@ -0,0 +1,1569 @@ +// 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 stat + +import ( + "fmt" + "math" + "reflect" + "testing" + + "gonum.org/v1/gonum/floats" +) + +func ExampleCircularMean() { + x := []float64{0, 0.25 * math.Pi, 0.75 * math.Pi} + weights := []float64{1, 2, 2.5} + cmean := CircularMean(x, weights) + + fmt.Printf("The circular mean is %.5f.\n", cmean) + // Output: + // The circular mean is 1.37037. +} + +func TestCircularMean(t *testing.T) { + for i, test := range []struct { + x []float64 + wts []float64 + ans float64 + }{ + // Values compared against scipy. + { + x: []float64{0, 2 * math.Pi}, + ans: 0, + }, + { + x: []float64{0, 0.5 * math.Pi}, + ans: 0.78539816339744, + }, + { + x: []float64{-1.5 * math.Pi, 0.5 * math.Pi, 2.5 * math.Pi}, + wts: []float64{1, 2, 3}, + ans: 0.5 * math.Pi, + }, + { + x: []float64{0, 0.5 * math.Pi}, + wts: []float64{1, 2}, + ans: 1.10714871779409, + }, + } { + c := CircularMean(test.x, test.wts) + if math.Abs(c-test.ans) > 1e-14 { + t.Errorf("Circular mean mismatch case %d: Expected %v, Found %v", i, test.ans, c) + } + } + if !Panics(func() { CircularMean(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("CircularMean did not panic with x, wts length mismatch") + } +} + +func ExampleCorrelation() { + x := []float64{8, -3, 7, 8, -4} + y := []float64{10, 5, 6, 3, -1} + w := []float64{2, 1.5, 3, 3, 2} + + fmt.Println("Correlation computes the degree to which two datasets move together") + fmt.Println("about their mean. For example, x and y above move similarly.") + + c := Correlation(x, y, w) + fmt.Printf("Correlation is %.5f\n", c) + + // Output: + // Correlation computes the degree to which two datasets move together + // about their mean. For example, x and y above move similarly. + // Correlation is 0.59915 +} + +func TestCorrelation(t *testing.T) { + for i, test := range []struct { + x []float64 + y []float64 + w []float64 + ans float64 + }{ + { + x: []float64{8, -3, 7, 8, -4}, + y: []float64{8, -3, 7, 8, -4}, + w: nil, + ans: 1, + }, + { + x: []float64{8, -3, 7, 8, -4}, + y: []float64{8, -3, 7, 8, -4}, + w: []float64{1, 1, 1, 1, 1}, + ans: 1, + }, + { + x: []float64{8, -3, 7, 8, -4}, + y: []float64{8, -3, 7, 8, -4}, + w: []float64{1, 6, 7, 0.8, 2.1}, + ans: 1, + }, + { + x: []float64{8, -3, 7, 8, -4}, + y: []float64{10, 15, 4, 5, -1}, + w: nil, + ans: 0.0093334660769059, + }, + { + x: []float64{8, -3, 7, 8, -4}, + y: []float64{10, 15, 4, 5, -1}, + w: nil, + ans: 0.0093334660769059, + }, + { + x: []float64{8, -3, 7, 8, -4}, + y: []float64{10, 15, 4, 5, -1}, + w: []float64{1, 3, 1, 2, 2}, + ans: -0.13966633352689, + }, + } { + c := Correlation(test.x, test.y, test.w) + if math.Abs(test.ans-c) > 1e-14 { + t.Errorf("Correlation mismatch case %d. Expected %v, Found %v", i, test.ans, c) + } + } + if !Panics(func() { Correlation(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) { + t.Errorf("Correlation did not panic with length mismatch") + } + if !Panics(func() { Correlation(make([]float64, 2), make([]float64, 3), nil) }) { + t.Errorf("Correlation did not panic with length mismatch") + } + if !Panics(func() { Correlation(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Correlation did not panic with weights length mismatch") + } +} + +func ExampleCovariance() { + fmt.Println("Covariance computes the degree to which datasets move together") + fmt.Println("about their mean.") + x := []float64{8, -3, 7, 8, -4} + y := []float64{10, 2, 2, 4, 1} + cov := Covariance(x, y, nil) + fmt.Printf("Cov = %.4f\n", cov) + fmt.Println("If datasets move perfectly together, the variance equals the covariance") + y2 := []float64{12, 1, 11, 12, 0} + cov2 := Covariance(x, y2, nil) + varX := Variance(x, nil) + fmt.Printf("Cov2 is %.4f, VarX is %.4f", cov2, varX) + // Output: + // Covariance computes the degree to which datasets move together + // about their mean. + // Cov = 13.8000 + // If datasets move perfectly together, the variance equals the covariance + // Cov2 is 37.7000, VarX is 37.7000 +} + +func TestCovariance(t *testing.T) { + for i, test := range []struct { + p []float64 + q []float64 + weights []float64 + ans float64 + }{ + { + p: []float64{0.75, 0.1, 0.05}, + q: []float64{0.5, 0.25, 0.25}, + ans: 0.05625, + }, + { + p: []float64{1, 2, 3}, + q: []float64{2, 4, 6}, + ans: 2, + }, + { + p: []float64{1, 2, 3}, + q: []float64{1, 4, 9}, + ans: 4, + }, + { + p: []float64{1, 2, 3}, + q: []float64{1, 4, 9}, + weights: []float64{1, 1.5, 1}, + ans: 3.2, + }, + { + p: []float64{1, 4, 9}, + q: []float64{1, 4, 9}, + weights: []float64{1, 1.5, 1}, + ans: 13.142857142857146, + }, + } { + c := Covariance(test.p, test.q, test.weights) + if math.Abs(c-test.ans) > 1e-14 { + t.Errorf("Covariance mismatch case %d: Expected %v, Found %v", i, test.ans, c) + } + } + + // test the panic states + if !Panics(func() { Covariance(make([]float64, 2), make([]float64, 3), nil) }) { + t.Errorf("Covariance did not panic with x, y length mismatch") + } + if !Panics(func() { Covariance(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Covariance did not panic with x, weights length mismatch") + } + +} + +func TestCrossEntropy(t *testing.T) { + for i, test := range []struct { + p []float64 + q []float64 + ans float64 + }{ + { + p: []float64{0.75, 0.1, 0.05}, + q: []float64{0.5, 0.25, 0.25}, + ans: 0.7278045395879426, + }, + { + p: []float64{0.75, 0.1, 0.05, 0, 0, 0}, + q: []float64{0.5, 0.25, 0.25, 0, 0, 0}, + ans: 0.7278045395879426, + }, + { + p: []float64{0.75, 0.1, 0.05, 0, 0, 0.1}, + q: []float64{0.5, 0.25, 0.25, 0, 0, 0}, + ans: math.Inf(1), + }, + { + p: nil, + q: nil, + ans: 0, + }, + } { + c := CrossEntropy(test.p, test.q) + if math.Abs(c-test.ans) > 1e-14 { + t.Errorf("Cross entropy mismatch case %d: Expected %v, Found %v", i, test.ans, c) + } + } + if !Panics(func() { CrossEntropy(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("CrossEntropy did not panic with p, q length mismatch") + } +} + +func ExampleEntropy() { + + p := []float64{0.05, 0.1, 0.9, 0.05} + entP := Entropy(p) + + q := []float64{0.2, 0.4, 0.25, 0.15} + entQ := Entropy(q) + + r := []float64{0.2, 0, 0, 0.5, 0, 0.2, 0.1, 0, 0, 0} + entR := Entropy(r) + + s := []float64{0, 0, 1, 0} + entS := Entropy(s) + + fmt.Println("Entropy is a measure of the amount of uncertainty in a distribution") + fmt.Printf("The second bin of p is very likely to occur. It's entropy is %.4f\n", entP) + fmt.Printf("The distribution of q is more spread out. It's entropy is %.4f\n", entQ) + fmt.Println("Adding buckets with zero probability does not change the entropy.") + fmt.Printf("The entropy of r is: %.4f\n", entR) + fmt.Printf("A distribution with no uncertainty has entropy %.4f\n", entS) + // Output: + // Entropy is a measure of the amount of uncertainty in a distribution + // The second bin of p is very likely to occur. It's entropy is 0.6247 + // The distribution of q is more spread out. It's entropy is 1.3195 + // Adding buckets with zero probability does not change the entropy. + // The entropy of r is: 1.2206 + // A distribution with no uncertainty has entropy 0.0000 +} + +func ExampleExKurtosis() { + fmt.Println(`Kurtosis is a measure of the 'peakedness' of a distribution, and the +excess kurtosis is the kurtosis above or below that of the standard normal +distribution`) + x := []float64{5, 4, -3, -2} + kurt := ExKurtosis(x, nil) + fmt.Printf("ExKurtosis = %.5f\n", kurt) + weights := []float64{1, 2, 3, 5} + wKurt := ExKurtosis(x, weights) + fmt.Printf("Weighted ExKurtosis is %.4f", wKurt) + // Output: + // Kurtosis is a measure of the 'peakedness' of a distribution, and the + // excess kurtosis is the kurtosis above or below that of the standard normal + // distribution + // ExKurtosis = -5.41200 + // Weighted ExKurtosis is -0.6779 +} + +func TestExKurtosis(t *testing.T) { + // the example does a good job, this just has to cover the panic + if !Panics(func() { ExKurtosis(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("ExKurtosis did not panic with x, weights length mismatch") + } +} + +func ExampleGeometricMean() { + x := []float64{8, 2, 9, 15, 4} + weights := []float64{2, 2, 6, 7, 1} + mean := Mean(x, weights) + gmean := GeometricMean(x, weights) + + logx := make([]float64, len(x)) + for i, v := range x { + logx[i] = math.Log(v) + } + expMeanLog := math.Exp(Mean(logx, weights)) + fmt.Printf("The arithmetic mean is %.4f, but the geometric mean is %.4f.\n", mean, gmean) + fmt.Printf("The exponential of the mean of the logs is %.4f\n", expMeanLog) + // Output: + // The arithmetic mean is 10.1667, but the geometric mean is 8.7637. + // The exponential of the mean of the logs is 8.7637 +} + +func TestGeometricMean(t *testing.T) { + for i, test := range []struct { + x []float64 + wts []float64 + ans float64 + }{ + { + x: []float64{2, 8}, + ans: 4, + }, + { + x: []float64{3, 81}, + wts: []float64{2, 1}, + ans: 9, + }, + } { + c := GeometricMean(test.x, test.wts) + if math.Abs(c-test.ans) > 1e-14 { + t.Errorf("Geometric mean mismatch case %d: Expected %v, Found %v", i, test.ans, c) + } + } + if !Panics(func() { GeometricMean(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("GeometricMean did not panic with x, wts length mismatch") + } +} + +func ExampleHarmonicMean() { + x := []float64{8, 2, 9, 15, 4} + weights := []float64{2, 2, 6, 7, 1} + mean := Mean(x, weights) + hmean := HarmonicMean(x, weights) + + fmt.Printf("The arithmetic mean is %.5f, but the harmonic mean is %.4f.\n", mean, hmean) + // Output: + // The arithmetic mean is 10.16667, but the harmonic mean is 6.8354. +} + +func TestHarmonicMean(t *testing.T) { + for i, test := range []struct { + x []float64 + wts []float64 + ans float64 + }{ + { + x: []float64{.5, .125}, + ans: .2, + }, + { + x: []float64{.5, .125}, + wts: []float64{2, 1}, + ans: .25, + }, + } { + c := HarmonicMean(test.x, test.wts) + if math.Abs(c-test.ans) > 1e-14 { + t.Errorf("Harmonic mean mismatch case %d: Expected %v, Found %v", i, test.ans, c) + } + } + if !Panics(func() { HarmonicMean(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("HarmonicMean did not panic with x, wts length mismatch") + } +} + +func TestHistogram(t *testing.T) { + for i, test := range []struct { + x []float64 + weights []float64 + dividers []float64 + ans []float64 + }{ + { + x: []float64{1, 3, 5, 6, 7, 8}, + dividers: []float64{0, 2, 4, 6, 7, 9}, + ans: []float64{1, 1, 1, 1, 2}, + }, + { + x: []float64{1, 3, 5, 6, 7, 8}, + dividers: []float64{1, 2, 4, 6, 7, 9}, + weights: []float64{1, 2, 1, 1, 1, 2}, + ans: []float64{1, 2, 1, 1, 3}, + }, + { + x: []float64{1, 8}, + dividers: []float64{0, 2, 4, 6, 7, 9}, + weights: []float64{1, 2}, + ans: []float64{1, 0, 0, 0, 2}, + }, + { + x: []float64{1, 8}, + dividers: []float64{0, 2, 4, 6, 7, 9}, + ans: []float64{1, 0, 0, 0, 1}, + }, + { + x: []float64{}, + dividers: []float64{1, 3}, + ans: []float64{0}, + }, + } { + hist := Histogram(nil, test.dividers, test.x, test.weights) + if !floats.Equal(hist, test.ans) { + t.Errorf("Hist mismatch case %d. Expected %v, Found %v", i, test.ans, hist) + } + // Test with non-zero values + Histogram(hist, test.dividers, test.x, test.weights) + if !floats.Equal(hist, test.ans) { + t.Errorf("Hist mismatch case %d. Expected %v, Found %v", i, test.ans, hist) + } + } + // panic cases + for _, test := range []struct { + name string + x []float64 + weights []float64 + dividers []float64 + count []float64 + }{ + { + name: "len(x) != len(weights)", + x: []float64{1, 3, 5, 6, 7, 8}, + weights: []float64{1, 1, 1, 1}, + }, + { + name: "len(count) != len(dividers) - 1", + x: []float64{1, 3, 5, 6, 7, 8}, + dividers: []float64{1, 4, 9}, + count: make([]float64, 6), + }, + { + name: "dividers not sorted", + x: []float64{1, 3, 5, 6, 7, 8}, + dividers: []float64{0, -1, 0}, + }, + { + name: "x not sorted", + x: []float64{1, 5, 2, 9, 7, 8}, + dividers: []float64{1, 4, 9}, + }, + { + name: "fewer than 2 dividers", + x: []float64{1, 2, 3}, + dividers: []float64{5}, + }, + { + name: "x too large", + x: []float64{1, 2, 3}, + dividers: []float64{1, 3}, + }, + { + name: "x too small", + x: []float64{1, 2, 3}, + dividers: []float64{2, 3}, + }, + } { + if !Panics(func() { Histogram(test.count, test.dividers, test.x, test.weights) }) { + t.Errorf("Histogram did not panic when %s", test.name) + } + } +} + +func ExampleHistogram() { + x := make([]float64, 101) + for i := range x { + x[i] = 1.1 * float64(i) // x data ranges from 0 to 110 + } + dividers := []float64{0, 7, 20, 100, 1000} + fmt.Println(`Histogram counts the amount of data in the bins specified by +the dividers. In this data set, there are 7 data points less than 7 (between dividers[0] +and dividers[1]), 12 data points between 7 and 20 (dividers[1] and dividers[2]), +and 0 data points above 1000. Since dividers has length 5, there will be 4 bins.`) + hist := Histogram(nil, dividers, x, nil) + fmt.Printf("Hist = %v\n", hist) + + fmt.Println() + fmt.Println("For ease, the floats Span function can be used to set the dividers") + nBins := 10 + dividers = make([]float64, nBins+1) + min := floats.Min(x) + max := floats.Max(x) + // Increase the maximum divider so that the maximum value of x is contained + // within the last bucket. + max += 1 + floats.Span(dividers, min, max) + // Span includes the min and the max. Trim the dividers to create 10 buckets + hist = Histogram(nil, dividers, x, nil) + fmt.Printf("Hist = %v\n", hist) + fmt.Println() + fmt.Println(`Histogram also works with weighted data, and allows reusing of +the count field in order to avoid extra garbage`) + weights := make([]float64, len(x)) + for i := range weights { + weights[i] = float64(i + 1) + } + Histogram(hist, dividers, x, weights) + fmt.Printf("Weighted Hist = %v\n", hist) + + // Output: + // Histogram counts the amount of data in the bins specified by + // the dividers. In this data set, there are 7 data points less than 7 (between dividers[0] + // and dividers[1]), 12 data points between 7 and 20 (dividers[1] and dividers[2]), + // and 0 data points above 1000. Since dividers has length 5, there will be 4 bins. + // Hist = [7 12 72 10] + // + // For ease, the floats Span function can be used to set the dividers + // Hist = [11 10 10 10 10 10 10 10 10 10] + // + // Histogram also works with weighted data, and allows reusing of + // the count field in order to avoid extra garbage + // Weighted Hist = [66 165 265 365 465 565 665 765 865 965] +} + +func TestJensenShannon(t *testing.T) { + for i, test := range []struct { + p []float64 + q []float64 + }{ + { + p: []float64{0.5, 0.1, 0.3, 0.1}, + q: []float64{0.1, 0.4, 0.25, 0.25}, + }, + { + p: []float64{0.4, 0.6, 0.0}, + q: []float64{0.2, 0.2, 0.6}, + }, + { + p: []float64{0.1, 0.1, 0.0, 0.8}, + q: []float64{0.6, 0.3, 0.0, 0.1}, + }, + { + p: []float64{0.5, 0.1, 0.3, 0.1}, + q: []float64{0.5, 0, 0.25, 0.25}, + }, + { + p: []float64{0.5, 0.1, 0, 0.4}, + q: []float64{0.1, 0.4, 0.25, 0.25}, + }, + } { + + m := make([]float64, len(test.p)) + p := test.p + q := test.q + floats.Add(m, p) + floats.Add(m, q) + floats.Scale(0.5, m) + + js1 := 0.5*KullbackLeibler(p, m) + 0.5*KullbackLeibler(q, m) + js2 := JensenShannon(p, q) + + if math.IsNaN(js2) { + t.Errorf("In case %v, JS distance is NaN", i) + } + + if math.Abs(js1-js2) > 1e-14 { + t.Errorf("JS mismatch case %v. Expected %v, found %v.", i, js1, js2) + } + } + if !Panics(func() { JensenShannon(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("JensenShannon did not panic with p, q length mismatch") + } +} + +func TestKolmogorovSmirnov(t *testing.T) { + for i, test := range []struct { + x []float64 + xWeights []float64 + y []float64 + yWeights []float64 + dist float64 + }{ + + { + dist: 0, + }, + { + x: []float64{1}, + dist: 1, + }, + { + y: []float64{1}, + dist: 1, + }, + { + x: []float64{1}, + xWeights: []float64{8}, + dist: 1, + }, + { + y: []float64{1}, + yWeights: []float64{8}, + dist: 1, + }, + { + x: []float64{1}, + xWeights: []float64{8}, + y: []float64{1}, + yWeights: []float64{8}, + dist: 0, + }, + { + x: []float64{1, 1, 1}, + xWeights: []float64{2, 3, 7}, + y: []float64{1}, + yWeights: []float64{8}, + dist: 0, + }, + { + x: []float64{1, 1, 1, 1, 1}, + y: []float64{1, 1, 1}, + yWeights: []float64{2, 5, 2}, + dist: 0, + }, + + { + x: []float64{1, 2, 3}, + y: []float64{1, 2, 3}, + dist: 0, + }, + { + x: []float64{1, 2, 3}, + y: []float64{1, 2, 3}, + yWeights: []float64{1, 1, 1}, + dist: 0, + }, + + { + x: []float64{1, 2, 3}, + xWeights: []float64{1, 1, 1}, + y: []float64{1, 2, 3}, + yWeights: []float64{1, 1, 1}, + dist: 0, + }, + { + x: []float64{1, 2}, + xWeights: []float64{2, 5}, + y: []float64{1, 1, 2, 2, 2, 2, 2}, + dist: 0, + }, + { + x: []float64{1, 1, 2, 2, 2, 2, 2}, + y: []float64{1, 2}, + yWeights: []float64{2, 5}, + dist: 0, + }, + { + x: []float64{1, 1, 2, 2, 2}, + xWeights: []float64{0.5, 1.5, 1, 2, 2}, + y: []float64{1, 2}, + yWeights: []float64{2, 5}, + dist: 0, + }, + { + x: []float64{1, 2, 3, 4}, + y: []float64{5, 6}, + dist: 1, + }, + { + x: []float64{5, 6}, + y: []float64{1, 2, 3, 4}, + dist: 1, + }, + { + x: []float64{5, 6}, + xWeights: []float64{8, 7}, + y: []float64{1, 2, 3, 4}, + dist: 1, + }, + { + x: []float64{5, 6}, + xWeights: []float64{8, 7}, + y: []float64{1, 2, 3, 4}, + yWeights: []float64{9, 2, 1, 6}, + dist: 1, + }, + { + x: []float64{-4, 5, 6}, + xWeights: []float64{0, 8, 7}, + y: []float64{1, 2, 3, 4}, + yWeights: []float64{9, 2, 1, 6}, + dist: 1, + }, + { + x: []float64{-4, -2, -2, 5, 6}, + xWeights: []float64{0, 0, 0, 8, 7}, + y: []float64{1, 2, 3, 4}, + yWeights: []float64{9, 2, 1, 6}, + dist: 1, + }, + { + x: []float64{1, 2, 3}, + y: []float64{1, 1, 3}, + dist: 1.0 / 3.0, + }, + { + x: []float64{1, 2, 3}, + y: []float64{1, 3}, + yWeights: []float64{2, 1}, + dist: 1.0 / 3.0, + }, + { + x: []float64{1, 2, 3}, + xWeights: []float64{2, 2, 2}, + y: []float64{1, 3}, + yWeights: []float64{2, 1}, + dist: 1.0 / 3.0, + }, + { + x: []float64{2, 3, 4}, + y: []float64{1, 5}, + dist: 1.0 / 2.0, + }, + { + x: []float64{1, 2, math.NaN()}, + y: []float64{1, 1, 3}, + dist: math.NaN(), + }, + { + x: []float64{1, 2, 3}, + y: []float64{1, 1, math.NaN()}, + dist: math.NaN(), + }, + } { + dist := KolmogorovSmirnov(test.x, test.xWeights, test.y, test.yWeights) + if math.Abs(dist-test.dist) > 1e-14 && !(math.IsNaN(test.dist) && math.IsNaN(dist)) { + t.Errorf("Distance mismatch case %v: Expected: %v, Found: %v", i, test.dist, dist) + } + } + // panic cases + for _, test := range []struct { + name string + x []float64 + xWeights []float64 + y []float64 + yWeights []float64 + }{ + { + name: "len(x) != len(xWeights)", + x: []float64{1, 3, 5, 6, 7, 8}, + xWeights: []float64{1, 1, 1, 1}, + }, + { + name: "len(y) != len(yWeights)", + x: []float64{1, 3, 5, 6, 7, 8}, + y: []float64{1, 3, 5, 6, 7, 8}, + yWeights: []float64{1, 1, 1, 1}, + }, + { + name: "x not sorted", + x: []float64{10, 3, 5, 6, 7, 8}, + y: []float64{1, 3, 5, 6, 7, 8}, + }, + { + name: "y not sorted", + x: []float64{1, 3, 5, 6, 7, 8}, + y: []float64{10, 3, 5, 6, 7, 8}, + }, + } { + if !Panics(func() { KolmogorovSmirnov(test.x, test.xWeights, test.y, test.yWeights) }) { + t.Errorf("KolmogorovSmirnov did not panic when %s", test.name) + } + } +} + +func ExampleKullbackLeibler() { + + p := []float64{0.05, 0.1, 0.9, 0.05} + q := []float64{0.2, 0.4, 0.25, 0.15} + s := []float64{0, 0, 1, 0} + + klPQ := KullbackLeibler(p, q) + klPS := KullbackLeibler(p, s) + klPP := KullbackLeibler(p, p) + + fmt.Println("Kullback-Leibler is one measure of the difference between two distributions") + fmt.Printf("The K-L distance between p and q is %.4f\n", klPQ) + fmt.Println("It is impossible for s and p to be the same distribution, because") + fmt.Println("the first bucket has zero probability in s and non-zero in p. Thus,") + fmt.Printf("the K-L distance between them is %.4f\n", klPS) + fmt.Printf("The K-L distance between identical distributions is %.4f\n", klPP) + + // Kullback-Leibler is one measure of the difference between two distributions + // The K-L distance between p and q is 0.8900 + // It is impossible for s and p to be the same distribution, because + // the first bucket has zero probability in s and non-zero in p. Thus, + // the K-L distance between them is +Inf + // The K-L distance between identical distributions is 0.0000 +} + +func TestKullbackLeibler(t *testing.T) { + if !Panics(func() { KullbackLeibler(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("KullbackLeibler did not panic with p, q length mismatch") + } +} + +var linearRegressionTests = []struct { + name string + + x, y []float64 + weights []float64 + origin bool + + alpha float64 + beta float64 + r float64 + + tol float64 +}{ + { + name: "faithful", + + x: faithful.waiting, + y: faithful.eruptions, + + // Values calculated by R using lm(eruptions ~ waiting, data=faithful). + alpha: -1.87402, + beta: 0.07563, + r: 0.8114608, + + tol: 1e-5, + }, + { + name: "faithful through origin", + + x: faithful.waiting, + y: faithful.eruptions, + origin: true, + + // Values calculated by R using lm(eruptions ~ waiting - 1, data=faithful). + alpha: 0, + beta: 0.05013, + r: 0.9726036, + + tol: 1e-5, + }, + { + name: "faithful explicit weights", + + x: faithful.waiting, + y: faithful.eruptions, + weights: func() []float64 { + w := make([]float64, len(faithful.eruptions)) + for i := range w { + w[i] = 1 + } + return w + }(), + + // Values calculated by R using lm(eruptions ~ waiting, data=faithful). + alpha: -1.87402, + beta: 0.07563, + r: 0.8114608, + + tol: 1e-5, + }, + { + name: "faithful non-uniform weights", + + x: faithful.waiting, + y: faithful.eruptions, + weights: faithful.waiting, // Just an arbitrary set of non-uniform weights. + + // Values calculated by R using lm(eruptions ~ waiting, data=faithful, weights=faithful$waiting). + alpha: -1.79268, + beta: 0.07452, + r: 0.7840372, + + tol: 1e-5, + }, +} + +func TestLinearRegression(t *testing.T) { + for _, test := range linearRegressionTests { + alpha, beta := LinearRegression(test.x, test.y, test.weights, test.origin) + var r float64 + if test.origin { + r = RNoughtSquared(test.x, test.y, test.weights, beta) + } else { + r = RSquared(test.x, test.y, test.weights, alpha, beta) + ests := make([]float64, len(test.y)) + for i, x := range test.x { + ests[i] = alpha + beta*x + } + rvals := RSquaredFrom(ests, test.y, test.weights) + if r != rvals { + t.Errorf("%s: RSquared and RSquaredFrom mismatch: %v != %v", test.name, r, rvals) + } + } + if !floats.EqualWithinAbsOrRel(alpha, test.alpha, test.tol, test.tol) { + t.Errorf("%s: unexpected alpha estimate: want:%v got:%v", test.name, test.alpha, alpha) + } + if !floats.EqualWithinAbsOrRel(beta, test.beta, test.tol, test.tol) { + t.Errorf("%s: unexpected beta estimate: want:%v got:%v", test.name, test.beta, beta) + } + if !floats.EqualWithinAbsOrRel(r, test.r, test.tol, test.tol) { + t.Errorf("%s: unexpected r estimate: want:%v got:%v", test.name, test.r, r) + } + } +} + +func TestChiSquare(t *testing.T) { + for i, test := range []struct { + p []float64 + q []float64 + res float64 + }{ + { + p: []float64{16, 18, 16, 14, 12, 12}, + q: []float64{16, 16, 16, 16, 16, 8}, + res: 3.5, + }, + { + p: []float64{16, 18, 16, 14, 12, 12}, + q: []float64{8, 20, 20, 16, 12, 12}, + res: 9.25, + }, + { + p: []float64{40, 60, 30, 45}, + q: []float64{50, 50, 50, 50}, + res: 12.5, + }, + { + p: []float64{40, 60, 30, 45, 0, 0}, + q: []float64{50, 50, 50, 50, 0, 0}, + res: 12.5, + }, + } { + resultpq := ChiSquare(test.p, test.q) + + if math.Abs(resultpq-test.res) > 1e-10 { + t.Errorf("ChiSquare distance mismatch in case %d. Expected %v, Found %v", i, test.res, resultpq) + } + } + if !Panics(func() { ChiSquare(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("ChiSquare did not panic with length mismatch") + } +} + +// Panics returns true if the called function panics during evaluation. +func Panics(fun func()) (b bool) { + defer func() { + err := recover() + if err != nil { + b = true + } + }() + fun() + return +} + +func TestBhattacharyya(t *testing.T) { + for i, test := range []struct { + p []float64 + q []float64 + res float64 + }{ + { + p: []float64{0.5, 0.1, 0.3, 0.1}, + q: []float64{0.1, 0.4, 0.25, 0.25}, + res: 0.15597338718671386, + }, + { + p: []float64{0.4, 0.6, 0.0}, + q: []float64{0.2, 0.2, 0.6}, + res: 0.46322207765351153, + }, + { + p: []float64{0.1, 0.1, 0.0, 0.8}, + q: []float64{0.6, 0.3, 0.0, 0.1}, + res: 0.3552520032137785, + }, + } { + resultpq := Bhattacharyya(test.p, test.q) + resultqp := Bhattacharyya(test.q, test.p) + + if math.Abs(resultpq-test.res) > 1e-10 { + t.Errorf("Bhattacharyya distance mismatch in case %d. Expected %v, Found %v", i, test.res, resultpq) + } + if math.Abs(resultpq-resultqp) > 1e-10 { + t.Errorf("Bhattacharyya distance is assymmetric in case %d.", i) + } + } + // Bhattacharyya should panic if the inputs have different length + if !Panics(func() { Bhattacharyya(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Bhattacharyya did not panic with length mismatch") + } +} + +func TestHellinger(t *testing.T) { + for i, test := range []struct { + p []float64 + q []float64 + res float64 + }{ + { + p: []float64{0.5, 0.1, 0.3, 0.1}, + q: []float64{0.1, 0.4, 0.25, 0.25}, + res: 0.3800237367441919, + }, + { + p: []float64{0.4, 0.6, 0.0}, + q: []float64{0.2, 0.2, 0.6}, + res: 0.6088900771170487, + }, + { + p: []float64{0.1, 0.1, 0.0, 0.8}, + q: []float64{0.6, 0.3, 0.0, 0.1}, + res: 0.5468118803484205, + }, + } { + resultpq := Hellinger(test.p, test.q) + resultqp := Hellinger(test.q, test.p) + + if math.Abs(resultpq-test.res) > 1e-10 { + t.Errorf("Hellinger distance mismatch in case %d. Expected %v, Found %v", i, test.res, resultpq) + } + if math.Abs(resultpq-resultqp) > 1e-10 { + t.Errorf("Hellinger distance is assymmetric in case %d.", i) + } + } + if !Panics(func() { Hellinger(make([]float64, 2), make([]float64, 3)) }) { + t.Errorf("Hellinger did not panic with length mismatch") + } +} + +func ExampleMean() { + x := []float64{8.2, -6, 5, 7} + mean := Mean(x, nil) + fmt.Printf("The mean of the samples is %.4f\n", mean) + w := []float64{2, 6, 3, 5} + weightedMean := Mean(x, w) + fmt.Printf("The weighted mean of the samples is %.4f\n", weightedMean) + x2 := []float64{8.2, 8.2, -6, -6, -6, -6, -6, -6, 5, 5, 5, 7, 7, 7, 7, 7} + mean2 := Mean(x2, nil) + fmt.Printf("The mean of x2 is %.4f\n", mean2) + fmt.Println("The weights act as if there were more samples of that number") + // Output: + // The mean of the samples is 3.5500 + // The weighted mean of the samples is 1.9000 + // The mean of x2 is 1.9000 + // The weights act as if there were more samples of that number +} +func TestMean(t *testing.T) { + if !Panics(func() { Mean(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Mean did not panic with x, weights length mismatch") + } +} + +func TestMode(t *testing.T) { + for i, test := range []struct { + x []float64 + weights []float64 + ans float64 + count float64 + }{ + {}, + { + x: []float64{1, 6, 1, 9, -2}, + ans: 1, + count: 2, + }, + { + x: []float64{1, 6, 1, 9, -2}, + weights: []float64{1, 7, 3, 5, 0}, + ans: 6, + count: 7, + }, + } { + m, count := Mode(test.x, test.weights) + if test.ans != m { + t.Errorf("Mode mismatch case %d. Expected %v, found %v", i, test.ans, m) + } + if test.count != count { + t.Errorf("Mode count mismatch case %d. Expected %v, found %v", i, test.count, count) + } + } + if !Panics(func() { Mode(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Mode did not panic with x, weights length mismatch") + } +} + +func TestMoment(t *testing.T) { + for i, test := range []struct { + x []float64 + weights []float64 + moment float64 + ans float64 + }{ + { + x: []float64{6, 2, 4, 8, 10}, + moment: 5, + ans: 0, + }, + { + x: []float64{6, 2, 4, 8, 10}, + weights: []float64{1, 2, 2, 2, 1}, + moment: 5, + ans: 121.875, + }, + } { + m := Moment(test.moment, test.x, test.weights) + if math.Abs(test.ans-m) > 1e-14 { + t.Errorf("Moment mismatch case %d. Expected %v, found %v", i, test.ans, m) + } + } + if !Panics(func() { Moment(1, make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Moment did not panic with x, weights length mismatch") + } +} + +func TestMomentAbout(t *testing.T) { + for i, test := range []struct { + x []float64 + weights []float64 + moment float64 + mean float64 + ans float64 + }{ + { + x: []float64{6, 2, 4, 8, 9}, + mean: 3, + moment: 5, + ans: 2.2288e3, + }, + { + x: []float64{6, 2, 4, 8, 9}, + weights: []float64{1, 2, 2, 2, 1}, + mean: 3, + moment: 5, + ans: 1.783625e3, + }, + } { + m := MomentAbout(test.moment, test.x, test.mean, test.weights) + if math.Abs(test.ans-m) > 1e-14 { + t.Errorf("MomentAbout mismatch case %d. Expected %v, found %v", i, test.ans, m) + } + } + if !Panics(func() { MomentAbout(1, make([]float64, 3), 0, make([]float64, 2)) }) { + t.Errorf("MomentAbout did not panic with x, weights length mismatch") + } +} + +func TestCDF(t *testing.T) { + cumulantKinds := []CumulantKind{Empirical} + for i, test := range []struct { + q []float64 + x []float64 + weights []float64 + ans [][]float64 + }{ + {}, + { + q: []float64{0, 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1}, + x: []float64{1, 2, 3, 4, 5}, + ans: [][]float64{{0, 0, 0.2, 0.2, 0.4, 0.6, 0.6, 0.8, 1, 1}}, + }, + { + q: []float64{0, 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1}, + x: []float64{1, 2, 3, 4, 5}, + weights: []float64{1, 1, 1, 1, 1}, + ans: [][]float64{{0, 0, 0.2, 0.2, 0.4, 0.6, 0.6, 0.8, 1, 1}}, + }, + { + q: []float64{0, 0.9, 1}, + x: []float64{math.NaN()}, + ans: [][]float64{{math.NaN(), math.NaN(), math.NaN()}}, + }, + } { + copyX := make([]float64, len(test.x)) + copy(copyX, test.x) + var copyW []float64 + if test.weights != nil { + copyW = make([]float64, len(test.weights)) + copy(copyW, test.weights) + } + for j, q := range test.q { + for k, kind := range cumulantKinds { + v := CDF(q, kind, test.x, test.weights) + if !floats.Equal(copyX, test.x) && !math.IsNaN(v) { + t.Errorf("x changed for case %d kind %d percentile %v", i, k, q) + } + if !floats.Equal(copyW, test.weights) { + t.Errorf("x changed for case %d kind %d percentile %v", i, k, q) + } + if v != test.ans[k][j] && !(math.IsNaN(v) && math.IsNaN(test.ans[k][j])) { + t.Errorf("mismatch case %d kind %d percentile %v. Expected: %v, found: %v", i, k, q, test.ans[k][j], v) + } + } + } + } + + // these test cases should all result in a panic + for i, test := range []struct { + name string + q float64 + kind CumulantKind + x []float64 + weights []float64 + }{ + { + name: "len(x) != len(weights)", + q: 1.5, + kind: Empirical, + x: []float64{1, 2, 3, 4, 5}, + weights: []float64{1, 2, 3}, + }, + { + name: "unsorted x", + q: 1.5, + kind: Empirical, + x: []float64{3, 2, 1}, + }, + { + name: "unknown CumulantKind", + q: 1.5, + kind: CumulantKind(1000), // bogus + x: []float64{1, 2, 3}, + }, + } { + if !Panics(func() { CDF(test.q, test.kind, test.x, test.weights) }) { + t.Errorf("did not panic as expected with %s for case %d kind %d percentile %v x %v weights %v", test.name, i, test.kind, test.q, test.x, test.weights) + } + } + +} + +func TestQuantile(t *testing.T) { + cumulantKinds := []CumulantKind{Empirical} + for i, test := range []struct { + p []float64 + x []float64 + w []float64 + ans [][]float64 + }{ + { + p: []float64{0, 0.05, 0.1, 0.15, 0.45, 0.5, 0.55, 0.85, 0.9, 0.95, 1}, + x: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + w: nil, + ans: [][]float64{{1, 1, 1, 2, 5, 5, 6, 9, 9, 10, 10}}, + }, + { + p: []float64{0, 0.05, 0.1, 0.15, 0.45, 0.5, 0.55, 0.85, 0.9, 0.95, 1}, + x: []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + w: []float64{3, 3, 3, 3, 3, 3, 3, 3, 3, 3}, + ans: [][]float64{{1, 1, 1, 2, 5, 5, 6, 9, 9, 10, 10}}, + }, + { + p: []float64{0.5}, + x: []float64{1, 2, 3, 4, 5, 6, 7, 8, math.NaN(), 10}, + ans: [][]float64{{math.NaN()}}, + }, + } { + copyX := make([]float64, len(test.x)) + copy(copyX, test.x) + var copyW []float64 + if test.w != nil { + copyW = make([]float64, len(test.w)) + copy(copyW, test.w) + } + for j, p := range test.p { + for k, kind := range cumulantKinds { + v := Quantile(p, kind, test.x, test.w) + if !floats.Same(copyX, test.x) { + t.Errorf("x changed for case %d kind %d percentile %v", i, k, p) + } + if !floats.Same(copyW, test.w) { + t.Errorf("x changed for case %d kind %d percentile %v", i, k, p) + } + if v != test.ans[k][j] && !(math.IsNaN(v) && math.IsNaN(test.ans[k][j])) { + t.Errorf("mismatch case %d kind %d percentile %v. Expected: %v, found: %v", i, k, p, test.ans[k][j], v) + } + } + } + } + // panic cases + for _, test := range []struct { + name string + p float64 + c CumulantKind + x []float64 + w []float64 + }{ + { + name: "p < 0", + c: Empirical, + p: -1, + }, + { + name: "p > 1", + c: Empirical, + p: 2, + }, + { + name: "p is NaN", + c: Empirical, + p: math.NaN(), + }, + { + name: "len(x) != len(weights)", + c: Empirical, + p: .5, + x: make([]float64, 4), + w: make([]float64, 2), + }, + { + name: "x not sorted", + c: Empirical, + p: .5, + x: []float64{3, 2, 1}, + }, + { + name: "CumulantKind is unknown", + c: CumulantKind(1000), + p: .5, + x: []float64{1, 2, 3}, + }, + } { + if !Panics(func() { Quantile(test.p, test.c, test.x, test.w) }) { + t.Errorf("Quantile did not panic when %s", test.name) + } + } +} + +func ExampleStdDev() { + x := []float64{8, 2, -9, 15, 4} + stdev := StdDev(x, nil) + fmt.Printf("The standard deviation of the samples is %.4f\n", stdev) + + weights := []float64{2, 2, 6, 7, 1} + weightedStdev := StdDev(x, weights) + fmt.Printf("The weighted standard deviation of the samples is %.4f\n", weightedStdev) + // Output: + // The standard deviation of the samples is 8.8034 + // The weighted standard deviation of the samples is 10.5733 +} + +func ExampleStdErr() { + x := []float64{8, 2, -9, 15, 4} + weights := []float64{2, 2, 6, 7, 1} + mean := Mean(x, weights) + stdev := StdDev(x, weights) + nSamples := floats.Sum(weights) + stdErr := StdErr(stdev, nSamples) + fmt.Printf("The standard deviation is %.4f and there are %g samples, so the mean\nis likely %.4f ± %.4f.", stdev, nSamples, mean, stdErr) + // Output: + // The standard deviation is 10.5733 and there are 18 samples, so the mean + // is likely 4.1667 ± 2.4921. +} + +func TestSkew(t *testing.T) { + for i, test := range []struct { + x []float64 + weights []float64 + ans float64 + }{ + { + x: []float64{8, 3, 7, 8, 4}, + weights: nil, + ans: -0.581456499151665, + }, + { + x: []float64{8, 3, 7, 8, 4}, + weights: []float64{1, 1, 1, 1, 1}, + ans: -0.581456499151665, + }, + { + x: []float64{8, 3, 7, 8, 4}, + weights: []float64{2, 1, 2, 1, 1}, + ans: -1.12066646837198, + }, + } { + skew := Skew(test.x, test.weights) + if math.Abs(skew-test.ans) > 1e-14 { + t.Errorf("Skew mismatch case %d. Expected %v, Found %v", i, test.ans, skew) + } + } + if !Panics(func() { Skew(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Skew did not panic with x, weights length mismatch") + } +} + +func TestSortWeighted(t *testing.T) { + for i, test := range []struct { + x []float64 + w []float64 + ansx []float64 + answ []float64 + }{ + { + x: []float64{8, 3, 7, 8, 4}, + ansx: []float64{3, 4, 7, 8, 8}, + }, + { + x: []float64{8, 3, 7, 8, 4}, + w: []float64{.5, 1, 1, .5, 1}, + ansx: []float64{3, 4, 7, 8, 8}, + answ: []float64{1, 1, 1, .5, .5}, + }, + } { + SortWeighted(test.x, test.w) + if !floats.Same(test.x, test.ansx) { + t.Errorf("SortWeighted mismatch case %d. Expected x %v, Found x %v", i, test.ansx, test.x) + } + if !(test.w == nil) && !floats.Same(test.w, test.answ) { + t.Errorf("SortWeighted mismatch case %d. Expected w %v, Found w %v", i, test.answ, test.w) + } + } + if !Panics(func() { SortWeighted(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("SortWeighted did not panic with x, weights length mismatch") + } +} + +func TestSortWeightedLabeled(t *testing.T) { + for i, test := range []struct { + x []float64 + l []bool + w []float64 + ansx []float64 + ansl []bool + answ []float64 + }{ + { + x: []float64{8, 3, 7, 8, 4}, + ansx: []float64{3, 4, 7, 8, 8}, + }, + { + x: []float64{8, 3, 7, 8, 4}, + w: []float64{.5, 1, 1, .5, 1}, + ansx: []float64{3, 4, 7, 8, 8}, + answ: []float64{1, 1, 1, .5, .5}, + }, + { + x: []float64{8, 3, 7, 8, 4}, + l: []bool{false, false, true, false, true}, + ansx: []float64{3, 4, 7, 8, 8}, + ansl: []bool{false, true, true, false, false}, + }, + { + x: []float64{8, 3, 7, 8, 4}, + l: []bool{false, false, true, false, true}, + w: []float64{.5, 1, 1, .5, 1}, + ansx: []float64{3, 4, 7, 8, 8}, + ansl: []bool{false, true, true, false, false}, + answ: []float64{1, 1, 1, .5, .5}, + }, + } { + SortWeightedLabeled(test.x, test.l, test.w) + if !floats.Same(test.x, test.ansx) { + t.Errorf("SortWeightedLabelled mismatch case %d. Expected x %v, Found x %v", i, test.ansx, test.x) + } + if (test.l != nil) && !reflect.DeepEqual(test.l, test.ansl) { + t.Errorf("SortWeightedLabelled mismatch case %d. Expected l %v, Found l %v", i, test.ansl, test.l) + } + if (test.w != nil) && !floats.Same(test.w, test.answ) { + t.Errorf("SortWeightedLabelled mismatch case %d. Expected w %v, Found w %v", i, test.answ, test.w) + } + } + if !Panics(func() { SortWeightedLabeled(make([]float64, 3), make([]bool, 2), make([]float64, 3)) }) { + t.Errorf("SortWeighted did not panic with x, labels length mismatch") + } + if !Panics(func() { SortWeightedLabeled(make([]float64, 3), make([]bool, 2), nil) }) { + t.Errorf("SortWeighted did not panic with x, labels length mismatch") + } + if !Panics(func() { SortWeightedLabeled(make([]float64, 3), make([]bool, 3), make([]float64, 2)) }) { + t.Errorf("SortWeighted did not panic with x, weights length mismatch") + } + if !Panics(func() { SortWeightedLabeled(make([]float64, 3), nil, make([]float64, 2)) }) { + t.Errorf("SortWeighted did not panic with x, weights length mismatch") + } +} + +func TestVariance(t *testing.T) { + for i, test := range []struct { + x []float64 + weights []float64 + ans float64 + }{ + { + x: []float64{8, -3, 7, 8, -4}, + weights: nil, + ans: 37.7, + }, + { + x: []float64{8, -3, 7, 8, -4}, + weights: []float64{1, 1, 1, 1, 1}, + ans: 37.7, + }, + { + x: []float64{8, 3, 7, 8, 4}, + weights: []float64{2, 1, 2, 1, 1}, + ans: 4.2857142857142865, + }, + { + x: []float64{1, 4, 9}, + weights: []float64{1, 1.5, 1}, + ans: 13.142857142857146, + }, + { + x: []float64{1, 2, 3}, + weights: []float64{1, 1.5, 1}, + ans: .8, + }, + } { + variance := Variance(test.x, test.weights) + if math.Abs(variance-test.ans) > 1e-14 { + t.Errorf("Variance mismatch case %d. Expected %v, Found %v", i, test.ans, variance) + } + } + if !Panics(func() { Variance(make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Variance did not panic with x, weights length mismatch") + } + +} + +func ExampleVariance() { + x := []float64{8, 2, -9, 15, 4} + variance := Variance(x, nil) + fmt.Printf("The variance of the samples is %.4f\n", variance) + + weights := []float64{2, 2, 6, 7, 1} + weightedVariance := Variance(x, weights) + fmt.Printf("The weighted variance of the samples is %.4f\n", weightedVariance) + // Output: + // The variance of the samples is 77.5000 + // The weighted variance of the samples is 111.7941 +} + +func TestStdScore(t *testing.T) { + for i, test := range []struct { + x float64 + u float64 + s float64 + z float64 + }{ + { + x: 4, + u: -6, + s: 5, + z: 2, + }, + { + x: 1, + u: 0, + s: 1, + z: 1, + }, + } { + z := StdScore(test.x, test.u, test.s) + if math.Abs(z-test.z) > 1e-14 { + t.Errorf("StdScore mismatch case %d. Expected %v, Found %v", i, test.z, z) + } + } + +} diff --git a/vendor/gonum.org/v1/gonum/stat/statmat.go b/vendor/gonum.org/v1/gonum/stat/statmat.go new file mode 100644 index 00000000..1f9bd794 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/statmat.go @@ -0,0 +1,146 @@ +// 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 stat + +import ( + "math" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +// CovarianceMatrix returns the covariance matrix (also known as the +// variance-covariance matrix) calculated from a matrix of data, x, using +// a two-pass algorithm. +// +// If weights is not nil the weighted covariance of x is calculated. weights +// must have length equal to the number of rows in input data matrix and +// must not contain negative elements. +// If cov is not nil it must either be zero-sized or have the same number of +// columns as the input data matrix. cov will be used as the destination for +// the covariance data. If cov is nil, a new mat.SymDense is allocated for +// the destination. +func CovarianceMatrix(cov *mat.SymDense, x mat.Matrix, weights []float64) *mat.SymDense { + // This is the matrix version of the two-pass algorithm. It doesn't use the + // additional floating point error correction that the Covariance function uses + // to reduce the impact of rounding during centering. + + r, c := x.Dims() + + if cov == nil { + cov = mat.NewSymDense(c, nil) + } else if n := cov.Symmetric(); n != c && n != 0 { + panic(mat.ErrShape) + } + + var xt mat.Dense + xt.Clone(x.T()) + // Subtract the mean of each of the columns. + for i := 0; i < c; i++ { + v := xt.RawRowView(i) + // This will panic with ErrShape if len(weights) != len(v), so + // we don't have to check the size later. + mean := Mean(v, weights) + floats.AddConst(-mean, v) + } + + if weights == nil { + // Calculate the normalization factor + // scaled by the sample size. + cov.SymOuterK(1/(float64(r)-1), &xt) + return cov + } + + // Multiply by the sqrt of the weights, so that multiplication is symmetric. + sqrtwts := make([]float64, r) + for i, w := range weights { + if w < 0 { + panic("stat: negative covariance matrix weights") + } + sqrtwts[i] = math.Sqrt(w) + } + // Weight the rows. + for i := 0; i < c; i++ { + v := xt.RawRowView(i) + floats.Mul(v, sqrtwts) + } + + // Calculate the normalization factor + // scaled by the weighted sample size. + cov.SymOuterK(1/(floats.Sum(weights)-1), &xt) + return cov +} + +// CorrelationMatrix returns the correlation matrix calculated from a matrix +// of data, x, using a two-pass algorithm. +// +// If weights is not nil the weighted correlation of x is calculated. weights +// must have length equal to the number of rows in input data matrix and +// must not contain negative elements. +// If corr is not nil it must either be zero-sized or have the same number of +// columns as the input data matrix. corr will be used as the destination for +// the correlation data. If corr is nil, a new mat.SymDense is allocated for +// the destination. +func CorrelationMatrix(corr *mat.SymDense, x mat.Matrix, weights []float64) *mat.SymDense { + // This will panic if the sizes don't match, or if weights is the wrong size. + corr = CovarianceMatrix(corr, x, weights) + covToCorr(corr) + return corr +} + +// covToCorr converts a covariance matrix to a correlation matrix. +func covToCorr(c *mat.SymDense) { + r := c.Symmetric() + + s := make([]float64, r) + for i := 0; i < r; i++ { + s[i] = 1 / math.Sqrt(c.At(i, i)) + } + for i, sx := range s { + // Ensure that the diagonal has exactly ones. + c.SetSym(i, i, 1) + for j := i + 1; j < r; j++ { + v := c.At(i, j) + c.SetSym(i, j, v*sx*s[j]) + } + } +} + +// corrToCov converts a correlation matrix to a covariance matrix. +// The input sigma should be vector of standard deviations corresponding +// to the covariance. It will panic if len(sigma) is not equal to the +// number of rows in the correlation matrix. +func corrToCov(c *mat.SymDense, sigma []float64) { + r, _ := c.Dims() + + if r != len(sigma) { + panic(mat.ErrShape) + } + for i, sx := range sigma { + // Ensure that the diagonal has exactly sigma squared. + c.SetSym(i, i, sx*sx) + for j := i + 1; j < r; j++ { + v := c.At(i, j) + c.SetSym(i, j, v*sx*sigma[j]) + } + } +} + +// Mahalanobis computes the Mahalanobis distance +// D = sqrt((x-y)^T * Σ^-1 * (x-y)) +// between the vectors x and y given the cholesky decomposition of Σ. +// Mahalanobis returns NaN if the linear solve fails. +// +// See https://en.wikipedia.org/wiki/Mahalanobis_distance for more information. +func Mahalanobis(x, y *mat.VecDense, chol *mat.Cholesky) float64 { + var diff mat.VecDense + diff.SubVec(x, y) + var tmp mat.VecDense + err := chol.SolveVec(&tmp, &diff) + if err != nil { + return math.NaN() + } + return math.Sqrt(mat.Dot(&tmp, &diff)) +} diff --git a/vendor/gonum.org/v1/gonum/stat/statmat_test.go b/vendor/gonum.org/v1/gonum/stat/statmat_test.go new file mode 100644 index 00000000..5ac809ef --- /dev/null +++ b/vendor/gonum.org/v1/gonum/stat/statmat_test.go @@ -0,0 +1,463 @@ +// 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 stat + +import ( + "math" + "math/rand" + "testing" + + "gonum.org/v1/gonum/floats" + "gonum.org/v1/gonum/mat" +) + +func TestCovarianceMatrix(t *testing.T) { + // An alternative way to test this is to call the Variance and + // Covariance functions and ensure that the results are identical. + for i, test := range []struct { + data *mat.Dense + weights []float64 + ans *mat.Dense + }{ + { + data: mat.NewDense(5, 2, []float64{ + -2, -4, + -1, 2, + 0, 0, + 1, -2, + 2, 4, + }), + weights: nil, + ans: mat.NewDense(2, 2, []float64{ + 2.5, 3, + 3, 10, + }), + }, { + data: mat.NewDense(3, 2, []float64{ + 1, 1, + 2, 4, + 3, 9, + }), + weights: []float64{ + 1, + 1.5, + 1, + }, + ans: mat.NewDense(2, 2, []float64{ + .8, 3.2, + 3.2, 13.142857142857146, + }), + }, + } { + // Make a copy of the data to check that it isn't changing. + r := test.data.RawMatrix() + d := make([]float64, len(r.Data)) + copy(d, r.Data) + + w := make([]float64, len(test.weights)) + if test.weights != nil { + copy(w, test.weights) + } + for _, cov := range []*mat.SymDense{nil, {}} { + c := CovarianceMatrix(cov, test.data, test.weights) + if !mat.Equal(c, test.ans) { + t.Errorf("%d: expected cov %v, found %v", i, test.ans, c) + } + if !floats.Equal(d, r.Data) { + t.Errorf("%d: data was modified during execution", i) + } + if !floats.Equal(w, test.weights) { + t.Errorf("%d: weights was modified during execution", i) + } + + // compare with call to Covariance + _, cols := c.Dims() + for ci := 0; ci < cols; ci++ { + for cj := 0; cj < cols; cj++ { + x := mat.Col(nil, ci, test.data) + y := mat.Col(nil, cj, test.data) + cov := Covariance(x, y, test.weights) + if math.Abs(cov-c.At(ci, cj)) > 1e-14 { + t.Errorf("CovMat does not match at (%v, %v). Want %v, got %v.", ci, cj, cov, c.At(ci, cj)) + } + } + } + } + + } + if !Panics(func() { CovarianceMatrix(nil, mat.NewDense(5, 2, nil), []float64{}) }) { + t.Errorf("CovarianceMatrix did not panic with weight size mismatch") + } + if !Panics(func() { CovarianceMatrix(mat.NewSymDense(1, nil), mat.NewDense(5, 2, nil), nil) }) { + t.Errorf("CovarianceMatrix did not panic with preallocation size mismatch") + } + if !Panics(func() { CovarianceMatrix(nil, mat.NewDense(2, 2, []float64{1, 2, 3, 4}), []float64{1, -1}) }) { + t.Errorf("CovarianceMatrix did not panic with negative weights") + } +} + +func TestCorrelationMatrix(t *testing.T) { + for i, test := range []struct { + data *mat.Dense + weights []float64 + ans *mat.Dense + }{ + { + data: mat.NewDense(3, 3, []float64{ + 1, 2, 3, + 3, 4, 5, + 5, 6, 7, + }), + weights: nil, + ans: mat.NewDense(3, 3, []float64{ + 1, 1, 1, + 1, 1, 1, + 1, 1, 1, + }), + }, + { + data: mat.NewDense(5, 2, []float64{ + -2, -4, + -1, 2, + 0, 0, + 1, -2, + 2, 4, + }), + weights: nil, + ans: mat.NewDense(2, 2, []float64{ + 1, 0.6, + 0.6, 1, + }), + }, { + data: mat.NewDense(3, 2, []float64{ + 1, 1, + 2, 4, + 3, 9, + }), + weights: []float64{ + 1, + 1.5, + 1, + }, + ans: mat.NewDense(2, 2, []float64{ + 1, 0.9868703275903379, + 0.9868703275903379, 1, + }), + }, + } { + // Make a copy of the data to check that it isn't changing. + r := test.data.RawMatrix() + d := make([]float64, len(r.Data)) + copy(d, r.Data) + + w := make([]float64, len(test.weights)) + if test.weights != nil { + copy(w, test.weights) + } + for _, corr := range []*mat.SymDense{nil, {}} { + c := CorrelationMatrix(corr, test.data, test.weights) + if !mat.Equal(c, test.ans) { + t.Errorf("%d: expected corr %v, found %v", i, test.ans, c) + } + if !floats.Equal(d, r.Data) { + t.Errorf("%d: data was modified during execution", i) + } + if !floats.Equal(w, test.weights) { + t.Errorf("%d: weights was modified during execution", i) + } + + // compare with call to Covariance + _, cols := c.Dims() + for ci := 0; ci < cols; ci++ { + for cj := 0; cj < cols; cj++ { + x := mat.Col(nil, ci, test.data) + y := mat.Col(nil, cj, test.data) + corr := Correlation(x, y, test.weights) + if math.Abs(corr-c.At(ci, cj)) > 1e-14 { + t.Errorf("CorrMat does not match at (%v, %v). Want %v, got %v.", ci, cj, corr, c.At(ci, cj)) + } + } + } + } + + } + if !Panics(func() { CorrelationMatrix(nil, mat.NewDense(5, 2, nil), []float64{}) }) { + t.Errorf("CorrelationMatrix did not panic with weight size mismatch") + } + if !Panics(func() { CorrelationMatrix(mat.NewSymDense(1, nil), mat.NewDense(5, 2, nil), nil) }) { + t.Errorf("CorrelationMatrix did not panic with preallocation size mismatch") + } + if !Panics(func() { CorrelationMatrix(nil, mat.NewDense(2, 2, []float64{1, 2, 3, 4}), []float64{1, -1}) }) { + t.Errorf("CorrelationMatrix did not panic with negative weights") + } +} + +func TestCorrCov(t *testing.T) { + // test both Cov2Corr and Cov2Corr + for i, test := range []struct { + data *mat.Dense + weights []float64 + }{ + { + data: mat.NewDense(3, 3, []float64{ + 1, 2, 3, + 3, 4, 5, + 5, 6, 7, + }), + weights: nil, + }, + { + data: mat.NewDense(5, 2, []float64{ + -2, -4, + -1, 2, + 0, 0, + 1, -2, + 2, 4, + }), + weights: nil, + }, { + data: mat.NewDense(3, 2, []float64{ + 1, 1, + 2, 4, + 3, 9, + }), + weights: []float64{ + 1, + 1.5, + 1, + }, + }, + } { + corr := CorrelationMatrix(nil, test.data, test.weights) + cov := CovarianceMatrix(nil, test.data, test.weights) + + r := cov.Symmetric() + + // Get the diagonal elements from cov to determine the sigmas. + sigmas := make([]float64, r) + for i := range sigmas { + sigmas[i] = math.Sqrt(cov.At(i, i)) + } + + covFromCorr := mat.NewSymDense(corr.Symmetric(), nil) + covFromCorr.CopySym(corr) + corrToCov(covFromCorr, sigmas) + + corrFromCov := mat.NewSymDense(cov.Symmetric(), nil) + corrFromCov.CopySym(cov) + covToCorr(corrFromCov) + + if !mat.EqualApprox(corr, corrFromCov, 1e-14) { + t.Errorf("%d: corrToCov did not match direct Correlation calculation. Want: %v, got: %v. ", i, corr, corrFromCov) + } + if !mat.EqualApprox(cov, covFromCorr, 1e-14) { + t.Errorf("%d: covToCorr did not match direct Covariance calculation. Want: %v, got: %v. ", i, cov, covFromCorr) + } + + if !Panics(func() { corrToCov(mat.NewSymDense(2, nil), []float64{}) }) { + t.Errorf("CorrelationMatrix did not panic with sigma size mismatch") + } + } +} + +func TestMahalanobis(t *testing.T) { + // Comparison with scipy. + for cas, test := range []struct { + x, y *mat.VecDense + Sigma *mat.SymDense + ans float64 + }{ + { + x: mat.NewVecDense(3, []float64{1, 2, 3}), + y: mat.NewVecDense(3, []float64{0.8, 1.1, -1}), + Sigma: mat.NewSymDense(3, + []float64{ + 0.8, 0.3, 0.1, + 0.3, 0.7, -0.1, + 0.1, -0.1, 7}), + ans: 1.9251757377680914, + }, + } { + var chol mat.Cholesky + ok := chol.Factorize(test.Sigma) + if !ok { + panic("bad test") + } + ans := Mahalanobis(test.x, test.y, &chol) + if math.Abs(ans-test.ans) > 1e-14 { + t.Errorf("Cas %d: got %v, want %v", cas, ans, test.ans) + } + } +} + +// benchmarks + +func randMat(r, c int) mat.Matrix { + x := make([]float64, r*c) + for i := range x { + x[i] = rand.Float64() + } + return mat.NewDense(r, c, x) +} + +func benchmarkCovarianceMatrix(b *testing.B, m mat.Matrix) { + b.ResetTimer() + for i := 0; i < b.N; i++ { + CovarianceMatrix(nil, m, nil) + } +} +func benchmarkCovarianceMatrixWeighted(b *testing.B, m mat.Matrix) { + r, _ := m.Dims() + wts := make([]float64, r) + for i := range wts { + wts[i] = 0.5 + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + CovarianceMatrix(nil, m, wts) + } +} +func benchmarkCovarianceMatrixInPlace(b *testing.B, m mat.Matrix) { + _, c := m.Dims() + res := mat.NewSymDense(c, nil) + b.ResetTimer() + for i := 0; i < b.N; i++ { + CovarianceMatrix(res, m, nil) + } +} + +func BenchmarkCovarianceMatrixSmallxSmall(b *testing.B) { + // 10 * 10 elements + x := randMat(small, small) + benchmarkCovarianceMatrix(b, x) +} +func BenchmarkCovarianceMatrixSmallxMedium(b *testing.B) { + // 10 * 1000 elements + x := randMat(small, medium) + benchmarkCovarianceMatrix(b, x) +} + +func BenchmarkCovarianceMatrixMediumxSmall(b *testing.B) { + // 1000 * 10 elements + x := randMat(medium, small) + benchmarkCovarianceMatrix(b, x) +} +func BenchmarkCovarianceMatrixMediumxMedium(b *testing.B) { + // 1000 * 1000 elements + x := randMat(medium, medium) + benchmarkCovarianceMatrix(b, x) +} + +func BenchmarkCovarianceMatrixLargexSmall(b *testing.B) { + // 1e5 * 10 elements + x := randMat(large, small) + benchmarkCovarianceMatrix(b, x) +} + +func BenchmarkCovarianceMatrixHugexSmall(b *testing.B) { + // 1e7 * 10 elements + x := randMat(huge, small) + benchmarkCovarianceMatrix(b, x) +} + +func BenchmarkCovarianceMatrixSmallxSmallWeighted(b *testing.B) { + // 10 * 10 elements + x := randMat(small, small) + benchmarkCovarianceMatrixWeighted(b, x) +} +func BenchmarkCovarianceMatrixSmallxMediumWeighted(b *testing.B) { + // 10 * 1000 elements + x := randMat(small, medium) + benchmarkCovarianceMatrixWeighted(b, x) +} + +func BenchmarkCovarianceMatrixMediumxSmallWeighted(b *testing.B) { + // 1000 * 10 elements + x := randMat(medium, small) + benchmarkCovarianceMatrixWeighted(b, x) +} +func BenchmarkCovarianceMatrixMediumxMediumWeighted(b *testing.B) { + // 1000 * 1000 elements + x := randMat(medium, medium) + benchmarkCovarianceMatrixWeighted(b, x) +} + +func BenchmarkCovarianceMatrixLargexSmallWeighted(b *testing.B) { + // 1e5 * 10 elements + x := randMat(large, small) + benchmarkCovarianceMatrixWeighted(b, x) +} + +func BenchmarkCovarianceMatrixHugexSmallWeighted(b *testing.B) { + // 1e7 * 10 elements + x := randMat(huge, small) + benchmarkCovarianceMatrixWeighted(b, x) +} + +func BenchmarkCovarianceMatrixSmallxSmallInPlace(b *testing.B) { + // 10 * 10 elements + x := randMat(small, small) + benchmarkCovarianceMatrixInPlace(b, x) +} +func BenchmarkCovarianceMatrixSmallxMediumInPlace(b *testing.B) { + // 10 * 1000 elements + x := randMat(small, medium) + benchmarkCovarianceMatrixInPlace(b, x) +} + +func BenchmarkCovarianceMatrixMediumxSmallInPlace(b *testing.B) { + // 1000 * 10 elements + x := randMat(medium, small) + benchmarkCovarianceMatrixInPlace(b, x) +} +func BenchmarkCovarianceMatrixMediumxMediumInPlace(b *testing.B) { + // 1000 * 1000 elements + x := randMat(medium, medium) + benchmarkCovarianceMatrixInPlace(b, x) +} + +func BenchmarkCovarianceMatrixLargexSmallInPlace(b *testing.B) { + // 1e5 * 10 elements + x := randMat(large, small) + benchmarkCovarianceMatrixInPlace(b, x) +} + +func BenchmarkCovarianceMatrixHugexSmallInPlace(b *testing.B) { + // 1e7 * 10 elements + x := randMat(huge, small) + benchmarkCovarianceMatrixInPlace(b, x) +} + +func BenchmarkCovToCorr(b *testing.B) { + // generate a 10x10 covariance matrix + m := randMat(small, small) + c := CovarianceMatrix(nil, m, nil) + cc := mat.NewSymDense(c.Symmetric(), nil) + b.ResetTimer() + for i := 0; i < b.N; i++ { + b.StopTimer() + cc.CopySym(c) + b.StartTimer() + covToCorr(cc) + } +} + +func BenchmarkCorrToCov(b *testing.B) { + // generate a 10x10 correlation matrix + m := randMat(small, small) + c := CorrelationMatrix(nil, m, nil) + cc := mat.NewSymDense(c.Symmetric(), nil) + sigma := make([]float64, small) + for i := range sigma { + sigma[i] = 2 + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + b.StopTimer() + cc.CopySym(c) + b.StartTimer() + corrToCov(cc, sigma) + } +} diff --git a/vendor/gonum.org/v1/gonum/unit/autogen.go b/vendor/gonum.org/v1/gonum/unit/autogen.go new file mode 100644 index 00000000..829c7318 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/autogen.go @@ -0,0 +1,363 @@ +// 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 ignore + +package main + +import ( + "bytes" + "go/format" + "log" + "os" + "path/filepath" + "strings" + "text/template" +) + +type Unit struct { + Name string + Receiver string + Offset int // From normal (for example, mass base unit is kg, not kg) + PrintString string // print string for the unit (kg for mass) + ExtraConstant []Constant + Suffix string + Singular string + TypeComment string // Text to comment the type + Dimensions []Dimension + ErForm string //For Xxxer interface +} + +type Dimension struct { + Name string + Power int +} + +const ( + TimeName string = "TimeDim" + LengthName string = "LengthDim" + MassName string = "MassDim" +) + +type Constant struct { + Name string + Value string +} + +type Prefix struct { + Name string + Power int +} + +var Prefixes = []Prefix{ + { + Name: "Yotta", + Power: 24, + }, + { + Name: "Zetta", + Power: 21, + }, + { + Name: "Exa", + Power: 18, + }, + { + Name: "Peta", + Power: 15, + }, + { + Name: "Tera", + Power: 12, + }, + { + Name: "Giga", + Power: 9, + }, + { + Name: "Mega", + Power: 6, + }, + { + Name: "Kilo", + Power: 3, + }, + { + Name: "Hecto", + Power: 2, + }, + { + Name: "Deca", + Power: 1, + }, + { + Name: "", + Power: 0, + }, + { + Name: "Deci", + Power: -1, + }, + { + Name: "Centi", + Power: -2, + }, + { + Name: "Milli", + Power: -3, + }, + { + Name: "Micro", + Power: -6, + }, + { + Name: "Nano", + Power: -9, + }, + { + Name: "Pico", + Power: -12, + }, + { + Name: "Femto", + Power: -15, + }, + { + Name: "Atto", + Power: -18, + }, + { + Name: "Zepto", + Power: -21, + }, + { + Name: "Yocto", + Power: -24, + }, +} + +var Units = []Unit{ + { + Name: "Mass", + Receiver: "m", + Offset: -3, + PrintString: "kg", + Suffix: "gram", + Singular: "Gram", + TypeComment: "Mass represents a mass in kilograms", + Dimensions: []Dimension{ + { + Name: MassName, + Power: 1, + }, + }, + }, + { + Name: "Length", + Receiver: "l", + PrintString: "m", + Suffix: "meter", + Singular: "Meter", + TypeComment: "Length represents a length in meters", + Dimensions: []Dimension{ + { + Name: LengthName, + Power: 1, + }, + }, + }, + { + Name: "Time", + Receiver: "t", + PrintString: "s", + Suffix: "second", + Singular: "Second", + TypeComment: "Time represents a time in seconds", + ExtraConstant: []Constant{ + { + Name: "Hour", + Value: "3600", + }, + { + Name: "Minute", + Value: "60", + }, + }, + Dimensions: []Dimension{ + { + Name: TimeName, + Power: 1, + }, + }, + ErForm: "Timer", + }, +} + +var gopath string +var unitPkgPath string + +func init() { + gopath = os.Getenv("GOPATH") + if gopath == "" { + log.Fatal("no gopath") + } + + unitPkgPath = filepath.Join(gopath, "src", "gonum.org", "v1", "gonum", "unit") +} + +// Generate generates a file for each of the units +func main() { + for _, unit := range Units { + generate(unit) + } +} + +const headerTemplate = `// Code generated by "go generate gonum.org/v1/gonum/unit”; 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 unit + +import ( + "errors" + "fmt" + "math" +) + +// {{.TypeComment}} +type {{.Name}} float64 +` + +var header = template.Must(template.New("header").Parse(headerTemplate)) + +const constTemplate = ` +const( + {{$unit := .Unit}} + {{range $unit.ExtraConstant}} {{.Name}} {{$unit.Name}} = {{.Value}} + {{end}} + {{$prefixes := .Prefixes}} + {{range $prefixes}} {{if .Name}} {{.Name}}{{$unit.Suffix}} {{else}} {{$unit.Singular}} {{end}} {{$unit.Name}} = {{if .Power}} 1e{{.Power}} {{else}} 1.0 {{end}} + {{end}} +) +` + +var prefix = template.Must(template.New("prefix").Parse(constTemplate)) + +const methodTemplate = ` +// Unit converts the {{.Name}} to a *Unit +func ({{.Receiver}} {{.Name}}) Unit() *Unit { + return New(float64({{.Receiver}}), Dimensions{ + {{range .Dimensions}} {{.Name}}: {{.Power}}, + {{end}} + }) +} + +// {{.Name}} allows {{.Name}} to implement a {{if .ErForm}}{{.ErForm}}{{else}}{{.Name}}er{{end}} interface +func ({{.Receiver}} {{.Name}}) {{.Name}}() {{.Name}} { + return {{.Receiver}} +} + +// From converts the unit into the receiver. From returns an +// error if there is a mismatch in dimension +func ({{.Receiver}} *{{.Name}}) From(u Uniter) error { + if !DimensionsMatch(u, {{.Singular}}){ + *{{.Receiver}} = {{.Name}}(math.NaN()) + return errors.New("Dimension mismatch") + } + *{{.Receiver}} = {{.Name}}(u.Unit().Value()) + return nil +} +` + +var methods = template.Must(template.New("methods").Parse(methodTemplate)) + +const formatTemplate = ` +func ({{.Receiver}} {{.Name}}) Format(fs fmt.State, c rune) { + switch c { + case 'v': + if fs.Flag('#') { + fmt.Fprintf(fs, "%T(%v)", {{.Receiver}}, float64({{.Receiver}})) + return + } + fallthrough + case 'e', 'E', 'f', 'F', 'g', 'G': + p, pOk := fs.Precision() + w, wOk := fs.Width() + switch { + case pOk && wOk: + fmt.Fprintf(fs, "%*.*"+string(c), w, p, float64({{.Receiver}})) + case pOk: + fmt.Fprintf(fs, "%.*"+string(c), p, float64({{.Receiver}})) + case wOk: + fmt.Fprintf(fs, "%*"+string(c), w, float64({{.Receiver}})) + default: + fmt.Fprintf(fs, "%"+string(c), float64({{.Receiver}})) + } + fmt.Fprint(fs, " {{.PrintString}}") + default: + fmt.Fprintf(fs, "%%!%c(%T=%g {{.PrintString}})", c, {{.Receiver}}, float64({{.Receiver}})) + } +} +` + +var form = template.Must(template.New("format").Parse(formatTemplate)) + +func generate(unit Unit) { + lowerName := strings.ToLower(unit.Name) + filename := filepath.Join(unitPkgPath, lowerName+".go") + f, err := os.Create(filename) + if err != nil { + log.Fatal(err) + } + defer f.Close() + + // Need to define new prefixes because text/template can't do math. + // Need to do math because kilogram = 1 not 10^3 + + prefixes := make([]Prefix, len(Prefixes)) + for i, p := range Prefixes { + prefixes[i].Name = p.Name + prefixes[i].Power = p.Power + unit.Offset + } + + data := struct { + Prefixes []Prefix + Unit Unit + }{ + prefixes, + unit, + } + + buf := bytes.NewBuffer(make([]byte, 0)) + + err = header.Execute(buf, unit) + if err != nil { + log.Fatal(err) + } + + err = prefix.Execute(buf, data) + if err != nil { + log.Fatal(err) + } + + err = methods.Execute(buf, unit) + if err != nil { + log.Fatal(err) + } + + err = form.Execute(buf, unit) + if err != nil { + log.Fatal(err) + } + + b, err := format.Source(buf.Bytes()) + if err != nil { + f.Write(buf.Bytes()) // This is here to debug bad format + log.Fatalf("error formatting: %s", err) + } + + f.Write(b) +} diff --git a/vendor/gonum.org/v1/gonum/unit/consts.go b/vendor/gonum.org/v1/gonum/unit/consts.go new file mode 100644 index 00000000..908d478e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/consts.go @@ -0,0 +1,29 @@ +// 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 unit + +const ( + Yotta = 1e24 + Zetta = 1e21 + Exa = 1e18 + Peta = 1e15 + Tera = 1e12 + Giga = 1e9 + Mega = 1e6 + Kilo = 1e3 + Hecto = 1e2 + Deca = 1e1 + + Deci = 1e-1 + Centi = 1e-2 + Milli = 1e-3 + Micro = 1e-6 + Nano = 1e-9 + Pico = 1e-12 + Femto = 1e-15 + Atto = 1e-18 + Zepto = 1e-21 + Yocto = 1e-24 +) diff --git a/vendor/gonum.org/v1/gonum/unit/dimless.go b/vendor/gonum.org/v1/gonum/unit/dimless.go new file mode 100644 index 00000000..5c6ce36e --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/dimless.go @@ -0,0 +1,66 @@ +// 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. + +package unit + +import ( + "errors" + "fmt" + "math" +) + +// Dimless represents a dimensionless constant +type Dimless float64 + +const ( + One Dimless = 1.0 +) + +// Unit converts the Dimless to a unit +func (d Dimless) Unit() *Unit { + return New(float64(d), Dimensions{}) +} + +// Dimless allows Dimless to implement a Dimlesser interface +func (d Dimless) Dimless() Dimless { + return d +} + +// From converts the unit to a dimless. Returns an error if there +// is a mismatch in dimension +func (d *Dimless) From(u *Unit) error { + if !DimensionsMatch(u, One) { + (*d) = Dimless(math.NaN()) + return errors.New("Dimension mismatch") + } + (*d) = Dimless(u.Unit().Value()) + return nil +} + +func (d Dimless) Format(fs fmt.State, c rune) { + switch c { + case 'v': + if fs.Flag('#') { + fmt.Fprintf(fs, "%T(%v)", d, float64(d)) + return + } + fallthrough + case 'e', 'E', 'f', 'F', 'g', 'G': + p, pOk := fs.Precision() + w, wOk := fs.Width() + switch { + case pOk && wOk: + fmt.Fprintf(fs, "%*.*"+string(c), w, p, float64(d)) + case pOk: + fmt.Fprintf(fs, "%.*"+string(c), p, float64(d)) + case wOk: + fmt.Fprintf(fs, "%*"+string(c), w, float64(d)) + default: + fmt.Fprintf(fs, "%"+string(c), float64(d)) + } + default: + fmt.Fprintf(fs, "%%!%c(%T=%g)", c, d, float64(d)) + return + } +} diff --git a/vendor/gonum.org/v1/gonum/unit/doc.go b/vendor/gonum.org/v1/gonum/unit/doc.go new file mode 100644 index 00000000..97ca4386 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/doc.go @@ -0,0 +1,83 @@ +// 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 go run autogen.go + +// Package unit provides a set of types and constants that facilitate +// the use of the International System of Units (SI). +// +// Unit provides two main functionalities. +// +// 1) +// It provides a number of types representing either an SI base unit +// or a common combination of base units, named for the unit it +// represents (Length, Mass, Pressure, etc.). Each type has +// a float64 as the underlying unit, and its value represents the +// number of that underlying unit (Kilogram, Meter, Pascal, etc.). +// For example, +// height := 1.6 * unit.Meter +// acc := unit.Acceleration(9.8) +// creates a variable named 'height' with a value of 1.6 meters, and +// a variable named 'acc' with a value of 9.8 meters per second squared. +// These types can be used to add compile-time safety to code. For +// example, +// func UnitDensity(t unit.Temperature, pressure unit.Pressure) (unit.Density){ +// ... +// } +// func main(){ +// t := 300 * unit.Kelvin +// p := 5 * unit.Bar +// rho := UnitDensity(p, t) // compile-time error +// } +// gives a compile-time error (temperature type does not match pressure type) +// while the corresponding code using float64 runs without error. +// func Float64Density(temperature, pressure float64) (float64){ +// ... +// } +// func main(){ +// t := 300.0 // degrees kelvin +// p := 50000.0 // Pascals +// rho := Float64Density(p, t) // no error +// } +// Many types have constants defined representing named SI units (Meter, +// Kilogram, etc. ) or SI derived units (Bar, Hz, etc.). The Unit package +// additionally provides untyped constants for SI prefixes, so the following +// are all equivalent. +// l := 0.001 * unit.Meter +// k := 1 * unit.Milli * unit.Meter +// j := unit.Length(0.001) +// +// 2) +// Unit provides the type "Unit", meant to represent a general dimensional +// value. unit.Unit can be used to help prevent errors of dimensionality +// when multiplying or dividing dimensional numbers. This package also +// provides the "Uniter" interface which is satisfied by any type which can +// be converted to a unit. New varibles of type Unit can be created with +// the New function and the Dimensions map. For example, the code +// acc := New(9.81, Dimensions{LengthDim:1, TimeDim: -2}) +// creates a variable "acc" which has a value of 9.81 m/s^2. Methods of +// unit can be used to modify this value, for example: +// acc.Mul(1.0 * unit.Kilogram).Mul(1 * unit.Meter) +// To convert the unit back into a typed float64 value, the From methods +// of the dimensional types should be used. From will return an error if the +// dimensions do not match. +// var energy unit.Energy +// err := (*energy).From(acc) +// Domain-specific problems may need custom dimensions, and for this purpose +// NewDimension should be used to help avoid accidental overlap between +// packages. For example, results from a blood test may be measured in +// "White blood cells per slide". In this case, NewDimension should be +// used to create a 'WhiteBloodCell' dimension. NewDimension takes in a +// string which will be used for printing that dimension, and will return +// a unique dimension number. NewDimension should not be +// used, however, to create the unit of 'Slide', because in this case slide +// is just a measurement of area. Instead, a constant could be defined. +// const Slide unit.Area = 0.001875 // m^2 +// Please note that Unit cannot catch all errors related to dimensionality. +// Different physical ideas are sometimes expressed with the same dimensions +// and Unit is incapable of catching these mismatches. For example, energy and +// torque are both expressed as force times distance (Newton-meters in SI), +// but it is wrong to say that a torque of 10 N-m is the same as 10 J, even +// though the dimensions agree. +package unit // import "gonum.org/v1/gonum/unit" diff --git a/vendor/gonum.org/v1/gonum/unit/length.go b/vendor/gonum.org/v1/gonum/unit/length.go new file mode 100644 index 00000000..f7ffde23 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/length.go @@ -0,0 +1,90 @@ +// Code generated by "go generate gonum.org/v1/gonum/unit”; 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 unit + +import ( + "errors" + "fmt" + "math" +) + +// Length represents a length in meters +type Length float64 + +const ( + Yottameter Length = 1e24 + Zettameter Length = 1e21 + Exameter Length = 1e18 + Petameter Length = 1e15 + Terameter Length = 1e12 + Gigameter Length = 1e9 + Megameter Length = 1e6 + Kilometer Length = 1e3 + Hectometer Length = 1e2 + Decameter Length = 1e1 + Meter Length = 1.0 + Decimeter Length = 1e-1 + Centimeter Length = 1e-2 + Millimeter Length = 1e-3 + Micrometer Length = 1e-6 + Nanometer Length = 1e-9 + Picometer Length = 1e-12 + Femtometer Length = 1e-15 + Attometer Length = 1e-18 + Zeptometer Length = 1e-21 + Yoctometer Length = 1e-24 +) + +// Unit converts the Length to a *Unit +func (l Length) Unit() *Unit { + return New(float64(l), Dimensions{ + LengthDim: 1, + }) +} + +// Length allows Length to implement a Lengther interface +func (l Length) Length() Length { + return l +} + +// From converts the unit into the receiver. From returns an +// error if there is a mismatch in dimension +func (l *Length) From(u Uniter) error { + if !DimensionsMatch(u, Meter) { + *l = Length(math.NaN()) + return errors.New("Dimension mismatch") + } + *l = Length(u.Unit().Value()) + return nil +} + +func (l Length) Format(fs fmt.State, c rune) { + switch c { + case 'v': + if fs.Flag('#') { + fmt.Fprintf(fs, "%T(%v)", l, float64(l)) + return + } + fallthrough + case 'e', 'E', 'f', 'F', 'g', 'G': + p, pOk := fs.Precision() + w, wOk := fs.Width() + switch { + case pOk && wOk: + fmt.Fprintf(fs, "%*.*"+string(c), w, p, float64(l)) + case pOk: + fmt.Fprintf(fs, "%.*"+string(c), p, float64(l)) + case wOk: + fmt.Fprintf(fs, "%*"+string(c), w, float64(l)) + default: + fmt.Fprintf(fs, "%"+string(c), float64(l)) + } + fmt.Fprint(fs, " m") + default: + fmt.Fprintf(fs, "%%!%c(%T=%g m)", c, l, float64(l)) + } +} diff --git a/vendor/gonum.org/v1/gonum/unit/mass.go b/vendor/gonum.org/v1/gonum/unit/mass.go new file mode 100644 index 00000000..2b127046 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/mass.go @@ -0,0 +1,90 @@ +// Code generated by "go generate gonum.org/v1/gonum/unit”; 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 unit + +import ( + "errors" + "fmt" + "math" +) + +// Mass represents a mass in kilograms +type Mass float64 + +const ( + Yottagram Mass = 1e21 + Zettagram Mass = 1e18 + Exagram Mass = 1e15 + Petagram Mass = 1e12 + Teragram Mass = 1e9 + Gigagram Mass = 1e6 + Megagram Mass = 1e3 + Kilogram Mass = 1.0 + Hectogram Mass = 1e-1 + Decagram Mass = 1e-2 + Gram Mass = 1e-3 + Decigram Mass = 1e-4 + Centigram Mass = 1e-5 + Milligram Mass = 1e-6 + Microgram Mass = 1e-9 + Nanogram Mass = 1e-12 + Picogram Mass = 1e-15 + Femtogram Mass = 1e-18 + Attogram Mass = 1e-21 + Zeptogram Mass = 1e-24 + Yoctogram Mass = 1e-27 +) + +// Unit converts the Mass to a *Unit +func (m Mass) Unit() *Unit { + return New(float64(m), Dimensions{ + MassDim: 1, + }) +} + +// Mass allows Mass to implement a Masser interface +func (m Mass) Mass() Mass { + return m +} + +// From converts the unit into the receiver. From returns an +// error if there is a mismatch in dimension +func (m *Mass) From(u Uniter) error { + if !DimensionsMatch(u, Gram) { + *m = Mass(math.NaN()) + return errors.New("Dimension mismatch") + } + *m = Mass(u.Unit().Value()) + return nil +} + +func (m Mass) Format(fs fmt.State, c rune) { + switch c { + case 'v': + if fs.Flag('#') { + fmt.Fprintf(fs, "%T(%v)", m, float64(m)) + return + } + fallthrough + case 'e', 'E', 'f', 'F', 'g', 'G': + p, pOk := fs.Precision() + w, wOk := fs.Width() + switch { + case pOk && wOk: + fmt.Fprintf(fs, "%*.*"+string(c), w, p, float64(m)) + case pOk: + fmt.Fprintf(fs, "%.*"+string(c), p, float64(m)) + case wOk: + fmt.Fprintf(fs, "%*"+string(c), w, float64(m)) + default: + fmt.Fprintf(fs, "%"+string(c), float64(m)) + } + fmt.Fprint(fs, " kg") + default: + fmt.Fprintf(fs, "%%!%c(%T=%g kg)", c, m, float64(m)) + } +} diff --git a/vendor/gonum.org/v1/gonum/unit/time.go b/vendor/gonum.org/v1/gonum/unit/time.go new file mode 100644 index 00000000..ef70fb8a --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/time.go @@ -0,0 +1,93 @@ +// Code generated by "go generate gonum.org/v1/gonum/unit”; 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 unit + +import ( + "errors" + "fmt" + "math" +) + +// Time represents a time in seconds +type Time float64 + +const ( + Hour Time = 3600 + Minute Time = 60 + + Yottasecond Time = 1e24 + Zettasecond Time = 1e21 + Exasecond Time = 1e18 + Petasecond Time = 1e15 + Terasecond Time = 1e12 + Gigasecond Time = 1e9 + Megasecond Time = 1e6 + Kilosecond Time = 1e3 + Hectosecond Time = 1e2 + Decasecond Time = 1e1 + Second Time = 1.0 + Decisecond Time = 1e-1 + Centisecond Time = 1e-2 + Millisecond Time = 1e-3 + Microsecond Time = 1e-6 + Nanosecond Time = 1e-9 + Picosecond Time = 1e-12 + Femtosecond Time = 1e-15 + Attosecond Time = 1e-18 + Zeptosecond Time = 1e-21 + Yoctosecond Time = 1e-24 +) + +// Unit converts the Time to a *Unit +func (t Time) Unit() *Unit { + return New(float64(t), Dimensions{ + TimeDim: 1, + }) +} + +// Time allows Time to implement a Timer interface +func (t Time) Time() Time { + return t +} + +// From converts the unit into the receiver. From returns an +// error if there is a mismatch in dimension +func (t *Time) From(u Uniter) error { + if !DimensionsMatch(u, Second) { + *t = Time(math.NaN()) + return errors.New("Dimension mismatch") + } + *t = Time(u.Unit().Value()) + return nil +} + +func (t Time) Format(fs fmt.State, c rune) { + switch c { + case 'v': + if fs.Flag('#') { + fmt.Fprintf(fs, "%T(%v)", t, float64(t)) + return + } + fallthrough + case 'e', 'E', 'f', 'F', 'g', 'G': + p, pOk := fs.Precision() + w, wOk := fs.Width() + switch { + case pOk && wOk: + fmt.Fprintf(fs, "%*.*"+string(c), w, p, float64(t)) + case pOk: + fmt.Fprintf(fs, "%.*"+string(c), p, float64(t)) + case wOk: + fmt.Fprintf(fs, "%*"+string(c), w, float64(t)) + default: + fmt.Fprintf(fs, "%"+string(c), float64(t)) + } + fmt.Fprint(fs, " s") + default: + fmt.Fprintf(fs, "%%!%c(%T=%g s)", c, t, float64(t)) + } +} diff --git a/vendor/gonum.org/v1/gonum/unit/unit_test.go b/vendor/gonum.org/v1/gonum/unit/unit_test.go new file mode 100644 index 00000000..258df365 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/unit_test.go @@ -0,0 +1,352 @@ +// 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. + +package unit + +import ( + "fmt" + "math" + "testing" +) + +var formatTests = []struct { + unit Uniter + format string + expect string +}{ + {New(9.81, Dimensions{MassDim: 1, TimeDim: -2}), "%f", "9.810000 kg s^-2"}, + {New(9.81, Dimensions{MassDim: 1, TimeDim: -2}), "%1.f", "10 kg s^-2"}, + {New(9.81, Dimensions{MassDim: 1, TimeDim: -2}), "%.1f", "9.8 kg s^-2"}, + {New(9.81, Dimensions{MassDim: 1, TimeDim: -2, LengthDim: 0}), "%f", "9.810000 kg s^-2"}, + {New(6.62606957e-34, Dimensions{MassDim: 2, TimeDim: -1}), "%e", "6.626070e-34 kg^2 s^-1"}, + {New(6.62606957e-34, Dimensions{MassDim: 2, TimeDim: -1}), "%.3e", "6.626e-34 kg^2 s^-1"}, + {New(6.62606957e-34, Dimensions{MassDim: 2, TimeDim: -1}), "%v", "6.62606957e-34 kg^2 s^-1"}, + {New(6.62606957e-34, Dimensions{MassDim: 2, TimeDim: -1}), "%s", "%!s(*Unit=6.62606957e-34 kg^2 s^-1)"}, + {Dimless(math.E), "%v", "2.718281828459045"}, + {Dimless(math.E), "%#v", "unit.Dimless(2.718281828459045)"}, + {Dimless(math.E), "%s", "%!s(unit.Dimless=2.718281828459045)"}, + {Mass(1), "%v", "1 kg"}, + {Mass(1), "%#v", "unit.Mass(1)"}, + {Mass(1), "%s", "%!s(unit.Mass=1 kg)"}, + {Length(1.61619926e-35), "%v", "1.61619926e-35 m"}, + {Length(1.61619926e-35), "%#v", "unit.Length(1.61619926e-35)"}, + {Length(1.61619926e-35), "%s", "%!s(unit.Length=1.61619926e-35 m)"}, + {Time(15.2), "%v", "15.2 s"}, + {Time(15.2), "%#v", "unit.Time(15.2)"}, + {Time(15.2), "%s", "%!s(unit.Time=15.2 s)"}, +} + +func TestFormat(t *testing.T) { + for _, ts := range formatTests { + if r := fmt.Sprintf(ts.format, ts.unit); r != ts.expect { + t.Errorf("Format %q: got: %q expected: %q", ts.format, r, ts.expect) + } + } +} + +func TestGoStringFormat(t *testing.T) { + expect1 := `&unit.Unit{dimensions:unit.Dimensions{4:2, 6:-1}, formatted:"", value:6.62606957e-34}` + expect2 := `&unit.Unit{dimensions:unit.Dimensions{6:-1, 4:2}, formatted:"", value:6.62606957e-34}` + if r := fmt.Sprintf("%#v", New(6.62606957e-34, Dimensions{MassDim: 2, TimeDim: -1})); r != expect1 && r != expect2 { + t.Errorf("Format %q: got: %q expected: %q", "%#v", r, expect1) + } +} + +var initializationTests = []struct { + unit *Unit + expValue float64 + expMap map[Dimension]int +}{ + {New(9.81, Dimensions{MassDim: 1, TimeDim: -2}), 9.81, Dimensions{MassDim: 1, TimeDim: -2}}, + {New(9.81, Dimensions{MassDim: 1, TimeDim: -2, LengthDim: 0, CurrentDim: 0}), 9.81, Dimensions{MassDim: 1, TimeDim: -2}}, +} + +func TestInitialization(t *testing.T) { + for _, ts := range initializationTests { + if ts.expValue != ts.unit.value { + t.Errorf("Value wrong on initialization: got: %v expected: %v", ts.unit.value, ts.expValue) + } + if len(ts.expMap) != len(ts.unit.dimensions) { + t.Errorf("Map mismatch: got: %#v expected: %#v", ts.unit.dimensions, ts.expMap) + } + for key, val := range ts.expMap { + if ts.unit.dimensions[key] != val { + t.Errorf("Map mismatch: got: %#v expected: %#v", ts.unit.dimensions, ts.expMap) + } + } + } +} + +var dimensionEqualityTests = []struct { + name string + a Uniter + b Uniter + shouldMatch bool +}{ + {"same_empty", New(1.0, Dimensions{}), New(1.0, Dimensions{}), true}, + {"same_one", New(1.0, Dimensions{TimeDim: 1}), New(1.0, Dimensions{TimeDim: 1}), true}, + {"same_mult", New(1.0, Dimensions{TimeDim: 1, LengthDim: -2}), New(1.0, Dimensions{TimeDim: 1, LengthDim: -2}), true}, + {"diff_one_empty", New(1.0, Dimensions{}), New(1.0, Dimensions{TimeDim: 1, LengthDim: -2}), false}, + {"diff_same_dim", New(1.0, Dimensions{TimeDim: 1}), New(1.0, Dimensions{TimeDim: 2}), false}, + {"diff_same_pow", New(1.0, Dimensions{LengthDim: 1}), New(1.0, Dimensions{TimeDim: 1}), false}, + {"diff_numdim", New(1.0, Dimensions{TimeDim: 1, LengthDim: 2}), New(1.0, Dimensions{TimeDim: 2}), false}, + {"diff_one_same_dim", New(1.0, Dimensions{LengthDim: 1, TimeDim: 1}), New(1.0, Dimensions{LengthDim: 1, TimeDim: 2}), false}, +} + +func TestDimensionEquality(t *testing.T) { + for _, ts := range dimensionEqualityTests { + if DimensionsMatch(ts.a, ts.b) != ts.shouldMatch { + t.Errorf("Dimension comparison incorrect for case %s. got: %v, expected: %v", ts.name, !ts.shouldMatch, ts.shouldMatch) + } + } +} + +type UnitStructer interface { + UnitStruct() *UnitStruct +} + +type UnitStruct struct { + current int + length int + luminosity int + mass int + temperature int + time int + chemamt int // For mol + value float64 +} + +// Check if the dimensions of two units are the same +func DimensionsMatchStruct(aU, bU UnitStructer) bool { + a := aU.UnitStruct() + b := bU.UnitStruct() + if a.length != b.length { + return false + } + if a.time != b.time { + return false + } + if a.mass != b.mass { + return false + } + if a.current != b.current { + return false + } + if a.temperature != b.temperature { + return false + } + if a.luminosity != b.luminosity { + return false + } + if a.chemamt != b.chemamt { + return false + } + return true +} + +func (u *UnitStruct) UnitStruct() *UnitStruct { + return u +} + +func (u *UnitStruct) Add(aU UnitStructer) *UnitStruct { + a := aU.UnitStruct() + if !DimensionsMatchStruct(a, u) { + panic("dimension mismatch") + } + u.value += a.value + return u +} + +func (u *UnitStruct) Mul(aU UnitStructer) *UnitStruct { + a := aU.UnitStruct() + u.length += a.length + u.time += a.time + u.mass += a.mass + u.current += a.current + u.temperature += a.temperature + u.luminosity += a.luminosity + u.chemamt += a.chemamt + u.value *= a.value + return u +} + +var u3 *UnitStruct + +func BenchmarkAddStruct(b *testing.B) { + u1 := &UnitStruct{current: 1, chemamt: 5, value: 10} + u2 := &UnitStruct{current: 1, chemamt: 5, value: 100} + for i := 0; i < b.N; i++ { + u2.Add(u1) + } +} + +func BenchmarkMulStruct(b *testing.B) { + u1 := &UnitStruct{current: 1, chemamt: 5, value: 10} + u2 := &UnitStruct{mass: 1, time: 1, value: 100} + for i := 0; i < b.N; i++ { + u2.Mul(u1) + } +} + +type UnitMapper interface { + UnitMap() *UnitMap +} + +type dimensionMap int + +const ( + LengthB dimensionMap = iota + TimeB + MassB + CurrentB + TemperatureB + LuminosityB + ChemAmtB +) + +type UnitMap struct { + dimension map[dimensionMap]int + value float64 +} + +// Check if the dimensions of two units are the same +func DimensionsMatchMap(aU, bU UnitMapper) bool { + a := aU.UnitMap() + b := bU.UnitMap() + if len(a.dimension) != len(b.dimension) { + panic("Unequal dimension") + } + for key, dimA := range a.dimension { + dimB, ok := b.dimension[key] + if !ok || dimA != dimB { + panic("Unequal dimension") + } + } + return true +} + +func (u *UnitMap) UnitMap() *UnitMap { + return u +} + +func (u *UnitMap) Add(aU UnitMapper) *UnitMap { + a := aU.UnitMap() + if !DimensionsMatchMap(a, u) { + panic("dimension mismatch") + } + u.value += a.value + return u +} + +func (u *UnitMap) Mul(aU UnitMapper) *UnitMap { + a := aU.UnitMap() + for key, val := range a.dimension { + u.dimension[key] += val + } + u.value *= a.value + return u +} + +var sink float64 + +func BenchmarkAddFloat(b *testing.B) { + sink = 0 + c := 10.0 + for i := 0; i < b.N; i++ { + sink += c + } +} + +func BenchmarkMulFloat(b *testing.B) { + sink = 0 + c := 10.0 + for i := 0; i < b.N; i++ { + sink *= c + } +} + +func BenchmarkAddMapSmall(b *testing.B) { + u1 := &UnitMap{value: 10} + u1.dimension = make(map[dimensionMap]int) + u1.dimension[CurrentB] = 1 + u1.dimension[ChemAmtB] = 5 + + u2 := &UnitMap{value: 10} + u2.dimension = make(map[dimensionMap]int) + u2.dimension[CurrentB] = 1 + u2.dimension[ChemAmtB] = 5 + for i := 0; i < b.N; i++ { + u2.Add(u1) + } +} + +func BenchmarkMulMapSmallDiff(b *testing.B) { + u1 := &UnitMap{value: 10} + u1.dimension = make(map[dimensionMap]int) + u1.dimension[LengthB] = 1 + + u2 := &UnitMap{value: 10} + u2.dimension = make(map[dimensionMap]int) + u2.dimension[MassB] = 1 + for i := 0; i < b.N; i++ { + u2.Mul(u1) + } +} + +func BenchmarkMulMapSmallSame(b *testing.B) { + u1 := &UnitMap{value: 10} + u1.dimension = make(map[dimensionMap]int) + u1.dimension[LengthB] = 1 + + u2 := &UnitMap{value: 10} + u2.dimension = make(map[dimensionMap]int) + u2.dimension[LengthB] = 2 + for i := 0; i < b.N; i++ { + u2.Mul(u1) + } +} + +func BenchmarkMulMapLargeDiff(b *testing.B) { + u1 := &UnitMap{value: 10} + u1.dimension = make(map[dimensionMap]int) + u1.dimension[LengthB] = 1 + u1.dimension[MassB] = 1 + u1.dimension[ChemAmtB] = 1 + u1.dimension[TemperatureB] = 1 + u1.dimension[LuminosityB] = 1 + u1.dimension[TimeB] = 1 + u1.dimension[CurrentB] = 1 + + u2 := &UnitMap{value: 10} + u2.dimension = make(map[dimensionMap]int) + u2.dimension[MassB] = 1 + for i := 0; i < b.N; i++ { + u2.Mul(u1) + } +} + +func BenchmarkMulMapLargeSame(b *testing.B) { + u1 := &UnitMap{value: 10} + u1.dimension = make(map[dimensionMap]int) + u1.dimension[LengthB] = 2 + u1.dimension[MassB] = 2 + u1.dimension[ChemAmtB] = 2 + u1.dimension[TemperatureB] = 2 + u1.dimension[LuminosityB] = 2 + u1.dimension[TimeB] = 2 + u1.dimension[CurrentB] = 2 + + u2 := &UnitMap{value: 10} + u2.dimension = make(map[dimensionMap]int) + u2.dimension[LengthB] = 3 + u2.dimension[MassB] = 3 + u2.dimension[ChemAmtB] = 3 + u2.dimension[TemperatureB] = 3 + u2.dimension[LuminosityB] = 3 + u2.dimension[TimeB] = 3 + u2.dimension[CurrentB] = 3 + for i := 0; i < b.N; i++ { + u2.Mul(u1) + } +} diff --git a/vendor/gonum.org/v1/gonum/unit/unitexample_test.go b/vendor/gonum.org/v1/gonum/unit/unitexample_test.go new file mode 100644 index 00000000..d81faae7 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/unitexample_test.go @@ -0,0 +1,29 @@ +// 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 unit_test + +import ( + "fmt" + + "gonum.org/v1/gonum/unit" +) + +func ExampleNew() { + // Create an acceleration of 3 m/s^2 + accel := unit.New(3.0, unit.Dimensions{unit.LengthDim: 1, unit.TimeDim: -2}) + fmt.Println(accel) + + // Output: 3 m s^-2 +} + +func ExampleNewDimension() { + // Create a "trees" dimension + // Typically, this should be used within an init function + treeDim := unit.NewDimension("tree") + countPerArea := unit.New(0.1, unit.Dimensions{treeDim: 1, unit.LengthDim: -2}) + fmt.Println(countPerArea) + + // Output: 0.1 tree m^-2 +} diff --git a/vendor/gonum.org/v1/gonum/unit/unittype.go b/vendor/gonum.org/v1/gonum/unit/unittype.go new file mode 100644 index 00000000..21311fd9 --- /dev/null +++ b/vendor/gonum.org/v1/gonum/unit/unittype.go @@ -0,0 +1,342 @@ +// 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. + +package unit + +import ( + "bytes" + "fmt" + "sort" +) + +// Uniter is a type that can be converted to a Unit. +type Uniter interface { + Unit() *Unit +} + +// Dimension is a type representing an SI base dimension or a distinct +// orthogonal dimension. Non-SI dimensions can be created using the NewDimension +// function, typically within an init function. +type Dimension int + +// String returns the string for the dimension. +func (d Dimension) String() string { + switch { + case d == reserved: + return "reserved" + case d < Dimension(len(symbols)): + return symbols[d] + default: + panic("unit: illegal dimension") + } +} + +const ( + // SI Base Units + reserved Dimension = iota + CurrentDim + LengthDim + LuminousIntensityDim + MassDim + TemperatureDim + TimeDim + // Other common SI Dimensions + AngleDim // e.g. radians +) + +var ( + symbols = []string{ + CurrentDim: "A", + LengthDim: "m", + LuminousIntensityDim: "cd", + MassDim: "kg", + TemperatureDim: "K", + TimeDim: "s", + AngleDim: "rad", + } + + // dimensions guarantees there aren't two identical symbols + // SI symbol list from http://lamar.colostate.edu/~hillger/basic.htm + dimensions = map[string]Dimension{ + "A": CurrentDim, + "m": LengthDim, + "cd": LuminousIntensityDim, + "kg": MassDim, + "K": TemperatureDim, + "s": TimeDim, + "rad": AngleDim, + + // Reserve common SI symbols + // base units + "mol": reserved, + // prefixes + "Y": reserved, + "Z": reserved, + "E": reserved, + "P": reserved, + "T": reserved, + "G": reserved, + "M": reserved, + "k": reserved, + "h": reserved, + "da": reserved, + "d": reserved, + "c": reserved, + "μ": reserved, + "n": reserved, + "p": reserved, + "f": reserved, + "a": reserved, + "z": reserved, + "y": reserved, + // SI Derived units with special symbols + "sr": reserved, + "F": reserved, + "C": reserved, + "S": reserved, + "H": reserved, + "V": reserved, + "Ω": reserved, + "J": reserved, + "N": reserved, + "Hz": reserved, + "lx": reserved, + "lm": reserved, + "Wb": reserved, + "W": reserved, + "Pa": reserved, + "Bq": reserved, + "Gy": reserved, + "Sv": reserved, + "kat": reserved, + // Units in use with SI + "ha": reserved, + "L": reserved, + "l": reserved, + // Units in Use Temporarily with SI + "bar": reserved, + "b": reserved, + "Ci": reserved, + "R": reserved, + "rd": reserved, + "rem": reserved, + } +) + +// Dimensions represent the dimensionality of the unit in powers +// of that dimension. If a key is not present, the power of that +// dimension is zero. Dimensions is used in conjunction with New. +type Dimensions map[Dimension]int + +func (d Dimensions) String() string { + // Map iterates randomly, but print should be in a fixed order. Can't use + // dimension number, because for user-defined dimension that number may + // not be fixed from run to run. + atoms := make(unitPrinters, 0, len(d)) + for dimension, power := range d { + if power != 0 { + atoms = append(atoms, atom{dimension, power}) + } + } + sort.Sort(atoms) + var b bytes.Buffer + for i, a := range atoms { + if i > 0 { + b.WriteByte(' ') + } + fmt.Fprintf(&b, "%s", a.Dimension) + if a.pow != 1 { + fmt.Fprintf(&b, "^%d", a.pow) + } + } + + return b.String() +} + +type atom struct { + Dimension + pow int +} + +type unitPrinters []atom + +func (u unitPrinters) Len() int { + return len(u) +} + +func (u unitPrinters) Less(i, j int) bool { + // Order first by positive powers, then by name. + if u[i].pow*u[j].pow < 0 { + return u[i].pow > 0 + } + return u[i].String() < u[j].String() +} + +func (u unitPrinters) Swap(i, j int) { + u[i], u[j] = u[j], u[i] +} + +// NewDimension creates a new orthogonal dimension with the given symbol, and +// returns the value of that dimension. The input symbol must not overlap with +// any of the any of the SI base units or other symbols of common use in SI ("kg", +// "J", etc.), and must not overlap with any other dimensions created by calls +// to NewDimension. The SymbolExists function can check if the symbol exists. +// NewDimension will panic if the input symbol matches an existing symbol. +// +// NewDimension should only be called for unit types that are actually orthogonal +// to the base dimensions defined in this package. Please see the package-level +// documentation for further explanation. +func NewDimension(symbol string) Dimension { + _, ok := dimensions[symbol] + if ok { + panic("unit: dimension string \"" + symbol + "\" already used") + } + d := Dimension(len(symbols)) + symbols = append(symbols, symbol) + dimensions[symbol] = d + return d +} + +// SymoblExists returns whether the given symbol is already in use. +func SymbolExists(symbol string) bool { + _, ok := dimensions[symbol] + return ok +} + +// Unit represents a dimensional value. The dimensions will typically be in SI +// units, but can also include dimensions created with NewDimension. The Unit type +// is most useful for ensuring dimensional consistency when manipulating types +// with different units, for example, by multiplying an acceleration with a +// mass to get a force. Please see the package documentation for further explanation. +type Unit struct { + dimensions Dimensions + formatted string + value float64 +} + +// New creates a new variable of type Unit which has the value and dimensions +// specified by the inputs. The built-in dimensions are always in SI units +// (meters, kilograms, etc.). +func New(value float64, d Dimensions) *Unit { + u := &Unit{ + dimensions: make(map[Dimension]int), + value: value, + } + for key, val := range d { + if val != 0 { + u.dimensions[key] = val + } + } + return u +} + +// DimensionsMatch checks if the dimensions of two Uniters are the same. +func DimensionsMatch(a, b Uniter) bool { + aUnit := a.Unit() + bUnit := b.Unit() + if len(aUnit.dimensions) != len(bUnit.dimensions) { + return false + } + for key, val := range aUnit.dimensions { + if bUnit.dimensions[key] != val { + return false + } + } + return true +} + +// Add adds the function argument to the receiver. Panics if the units of +// the receiver and the argument don't match. +func (u *Unit) Add(uniter Uniter) *Unit { + a := uniter.Unit() + if !DimensionsMatch(u, a) { + panic("unit: mismatched dimensions in addition") + } + u.value += a.value + return u +} + +// Unit implements the Uniter interface +func (u *Unit) Unit() *Unit { + return u +} + +// Mul multiply the receiver by the input changing the dimensions +// of the receiver as appropriate. The input is not changed. +func (u *Unit) Mul(uniter Uniter) *Unit { + a := uniter.Unit() + for key, val := range a.dimensions { + if d := u.dimensions[key]; d == -val { + delete(u.dimensions, key) + } else { + u.dimensions[key] = d + val + } + } + u.formatted = "" + u.value *= a.value + return u +} + +// Div divides the receiver by the argument changing the +// dimensions of the receiver as appropriate. +func (u *Unit) Div(uniter Uniter) *Unit { + a := uniter.Unit() + u.value /= a.value + for key, val := range a.dimensions { + if d := u.dimensions[key]; d == val { + delete(u.dimensions, key) + } else { + u.dimensions[key] = d - val + } + } + u.formatted = "" + return u +} + +// Value return the raw value of the unit as a float64. Use of this +// method is, in general, not recommended, though it can be useful +// for printing. Instead, the From type of a specific dimension +// should be used to guarantee dimension consistency. +func (u *Unit) Value() float64 { + return u.value +} + +// Format makes Unit satisfy the fmt.Formatter interface. The unit is formatted +// with dimensions appended. If the power if the dimension is not zero or one, +// symbol^power is appended, if the power is one, just the symbol is appended +// and if the power is zero, nothing is appended. Dimensions are appended +// in order by symbol name with positive powers ahead of negative powers. +func (u *Unit) Format(fs fmt.State, c rune) { + if u == nil { + fmt.Fprint(fs, "") + } + switch c { + case 'v': + if fs.Flag('#') { + fmt.Fprintf(fs, "&%#v", *u) + return + } + fallthrough + case 'e', 'E', 'f', 'F', 'g', 'G': + p, pOk := fs.Precision() + w, wOk := fs.Width() + switch { + case pOk && wOk: + fmt.Fprintf(fs, "%*.*"+string(c), w, p, u.value) + case pOk: + fmt.Fprintf(fs, "%.*"+string(c), p, u.value) + case wOk: + fmt.Fprintf(fs, "%*"+string(c), w, u.value) + default: + fmt.Fprintf(fs, "%"+string(c), u.value) + } + default: + fmt.Fprintf(fs, "%%!%c(*Unit=%g)", c, u) + return + } + if u.formatted == "" && len(u.dimensions) > 0 { + u.formatted = u.dimensions.String() + } + fmt.Fprintf(fs, " %s", u.formatted) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 3fe19d2b..7067e25f 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1113,6 +1113,12 @@ "revision": "505032a0737bf9d1007ff782db67a4e41eac71f7", "revisionTime": "2018-06-28T04:47:44Z" }, + { + "checksumSHA1": "db1fjQUFM01O5HhI1zzREmB9ARQ=", + "path": "gonum.org/v1/gonum/stat", + "revision": "d7342e68fbbe64d7dbbdc0feb4ecf60500444cdc", + "revisionTime": "2017-08-28T20:52:35Z" + }, { "checksumSHA1": "AvVpgwhxhJgjoSledwDtYrEKVE4=", "origin": "github.com/Loopring/relay-lib/vendor/google.golang.org/genproto/googleapis/rpc/status",